valuation is shopping.cc. It currently only reflects missiles that are blocked with the shield. They could also reflect the brand effects of blocked melee weapons, but I'm not sure if that's a good idea.
drop_item and the item to be dropped have been moved from fire_beam()'s parameters into the bolt structure, along with the beam's remaining range. Seems to work fine, but it might still lead to some buggyness.
The game now distinguishes between killing yourself by hitting yourself with a beam bounced off a wall versus other forms of self targeting.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7705 c06c8d41-db1a-0410-9941-cceddc491573
CDFS7Z74W5HKPQIHQICOG442KQFXUSBGGLDDQLE3MG74T44YU6AQC ZUKTDWZ4R5VZLWO22E3RWAGTUF4HZ6DUXY65VLWQZVAFYJZGZP4QC 3USQPDXQMQUTNA3EZJUQ4NJMNPNF3IA7GVMOVG56P2XSVBWDHLXAC TO74NQE4DXNBFQ3OOVHUSWKUCDSEUWLXVUAZF3XJU5TU7BDRPNUAC QZM4EDMUKU7QWQKWXHTRINNWH3GQQ6RSAX7WIX6PQAEM5V2Y2BQQC VVVOUK7QZU3NNYAI6SJNWM5ZK7362HIXXSQI5BKVMHHL2CXMYXMQC 5FHWTG7M6FW4B3I33YI7QSM3OZIB6ZGC6TI6JISSLY5Y43HI56VAC BYURAML2EPTULHH22Q5RPXYGDEYAJYESR6C72UMNPPYHTCJZUPFAC JDIK6Y6PQBNY4C7XGSTUDWNDHP3KUEV54SGWOBLVUHNE4H674TEQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 3DQXSE4YGFBBDUWK4YEOFWW4UPWILWELFSLP37SL6BERGAZJC5YAC 5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC FA2V3G4NYTWJWUT7EWH75L3YOUX6YVOZ5LNRSFLO2XF273JKSUTAC AMAPVOFKH3YS5VCVOG2YNHXNDAZATMXFUL6ODZUIOF5OYYKBVKGAC W74555HMPXUQ72AGKBXC5P3STMMX5DZAW6ZESUDLNVJBCAG43PLAC TQLWCGVXVZ75H7MDBJD3DJDUFNW62WOAEDJUVKCHQTAXKBP47CSAC 32PXX2XJVV7YSLLYNAVS7RYKYRAOQ565TZMTITSEPSSXOYPB5M2AC DS2GZKISEP2DM2VU6EJ525Q7W3WVOKJXG5PY2OY4VNFCLBHVVOTAC GDMMLW5HKFUFEVA7BKREZGIAHV3KAXN2I7DY55RQFHXS5NVAAZZQC SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC DGF6PWWASI5CEJBNZ3S5IU2PTM5CSKUUQXQPZ6A26XFPZIHKGJ5AC NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC Q3DNEB5OOJ34P5ML4CMK3L6SCP7RLW7DDOZEG24KZBX3C7BJRQDAC MDAJYB6STTZPNHRQ2X66MMMSONMKXTESLHJSFPGN7H3D3TOVBAVAC SRQJVKQVUY7QGCEBA2VQTWEJ7ADIUSY7L46HJQSQNM5DXYRRH5KAC RR2J4VLJCZSAKY3HNS334KI4YUAPOMSETO2HGCGEEIUCUJAYAGSQC H7BW6SEIQ57X6V4BM2RX54W42W6BH5XJBAS6FYCYKLQQG43ZMU4QC 3KAINFIXO7WNWGUGZB43EUNFRS2ZPBLQZDTY456QACMRHYIJ7WDAC KAL42YT6OQXFPMKKKHE2NQM47W5KMLSRI6KWFRTJFAO4WKP4MMLAC VNHFP63ZLLZU3A3PLXP4BITX57DUIYDHFOHQYK3BOBHV3S64G26QC 2SNCC2NXKFVBYTWH7THU2QELHONTOBRNCWH6FWYORKKCWZAXTTVAC TX3LTXGB7TJ2QHLW2TEW6XTCTOW5A3KTZGBPBRTDTUYOZFFT3NLAC PR42BCP5BPRFD2MP5H6CIJP7E57Q6TKL6SOXZWFKMFVR2OZWHT7AC PONOTAV3NEDNVGEJNPMLC5AY2BPV5E3ZHWDLNQCKCEBVKPBIY7QQC 5DMO2DEV7IK3MJG274EUNZBGQ7EBZWC2WTSKAEGPDMILX7BXYG3AC FUEEIUKGHHFPIRZCN3N753GONWAZTWQ2ZWR53IBJAAZ6FZUNGOMAC FLAGBNUNSIQNFDN53CDWABJRTTFWDL4PG34AI474ZKPXDEPYHOAQC 2TZT4GURBCNHSVOXO5ZMN7XEIO3K4GWJCDPVSYUCMVZ6UFDL4DIQC GT7BSR54BVJKHUCLEBTELGBMNBFFDQW52EVC4XKVEMUVG2UGZMDAC TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC OFH2B2UZBK43QLFQBZ54FOCFLFNE54BZVDNCEUGDTBCUGNVZULIQC QNKMXCJSGRBEPE6ZNPEXU5EQIOME6EI4DECVC56GLOBCMGWWE6MQC 25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC AIVXE6QBRVCZAASKQRZO6LBDGTYEYSSD2DZCWRX4VLSKE3GCNIDAC SUWIERONPDATHPDMZRYO6GYIXSW6XIS5V5MK5IV23DWQH2LL7VIAC AS2IQQJNNCEQNXXKTGYHLB7RO3ZKCF4F7GK6FJH66BOOKDDRGNIQC OHJE4HQ2B3HVV4BOPBRFKO6HBRTLZEI74P5PLJF5GLSRD2MFWXHQC JJULXW764V5C2HJKZNWQAEWB6QM5YZADD7ZCE35LYTBFEM6PMYCAC GVCGKTH5IJ4VSQEIN4CRC7ZFVZW26JPIYNCPTO7GY66CSZZEW3ZQC FCPBRFLI4FHMB3Q4AFIYPG22ALFOLIYFBODHNCW5O6PVMMD65YDQC 7YUGK5Q64KG5O7GJGTUBRRLHAHBCJ5YOE23YUPT6UBKUSB67CYAQC PI5BATR2SER3RFE76IUGHM2AGXVFOUM3PLU7WC2K2Q2BA5K2E73QC UAJN2CFA2QHYDHW2UFAVPPHDQFCD54RKM6V2UC4AMEDJUBBLNWIQC ZGUJWUFJ4NFFJ6PGXLFGQWCWBCZHPWGWI44NJHJEVPRG5L36PADQC O7S3ILRELHICJXXTDGMF7KPPZWYHPYCNDPV2I77FZXXH4I454B4QC 4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC GSJA56E3ORVIBCBA6T6WU2HE4DCLJ6NZPW76O7L54N4CYPKLJOWQC 5K2ANIEXD3CPJM4XNKNPZINP2G4NT7SJBKRN62WNBUKJXFERTILQC RWCCZ64BG3HSOTM54ANIGENC3F3AIR42LJFRYSAKMCPCIUSOZY5QC K33CV7EYR37TTSEXQWQ6QPHSEUFO545AIPUZOA2C47QTUCUWFPAAC YX2LDGNQNB6AQRKAVXNYQ473X6EVPQEBT5AJKBIIWFIMS3U2BNQQC UZ5623MOLKBTGBSRBJ4OBOEI4IEZSPV3NCV2DRMUZ3CHHJQVHIIAC NRMSQFTORG3GC7HQBIN5DHB5GLWXM6IQO6PTXD4C7LBQWJIHYIGAC YMLVBQ6M27MECUVMU3BQP3WSGR7GW4XJMQIHLGHHWMVXHMMIXOYAC bool is_shield(const item_def &item);bool is_shield_incompatible(const item_def &weapon,const item_def *shield = NULL);// Only works for armour/weapons/missiles
needs_damage = true;break;case KILLED_BY_REFLECTION:needs_damage = true;if (terse)desc += "reflected bolt";else{desc += "Killed by a reflected ";if (auxkilldata.empty())desc += "bolt";elsedesc += auxkilldata;if (!death_source_name.empty() && !oneline && !semiverbose){desc += "\n";desc += " ";desc += "... reflected by ";desc += death_source_name;needs_damage = false;}}break;case KILLED_BY_BOUNCE:if (terse)desc += "bounced beam";else{desc += "Killed themselves with a bounced ";if (auxkilldata.empty())desc += "beam";elsedesc += auxkilldata;}
int affect(bolt &beam, const coord_def& p, item_def *item = NULL,bool affect_items = true);void beam_drop_object( bolt &beam, item_def *item, const coord_def& where );
int affect(bolt &beam, const coord_def& p = coord_def(),item_def *item = NULL, bool affect_items = true);void beam_drop_object( bolt &beam, item_def *item = NULL,const coord_def& where = coord_def() );
* 6. Decrease remaining range appropriately* 7. Check for early out due to aimed_at_feet* 8. Draw the beam* 9. Drop an object where the beam 'landed'*10. Beams explode where the beam 'landed'*11. If no message generated yet, send "nothing happens" (enchantments only)
* 6. If the beam was reflected during affect() then return, since* a recursive call to fire_beam() took care of the rest.* 7. Decrease remaining range appropriately* 8. Check for early out due to aimed_at_feet* 9. Draw the beam*10. Drop an object where the beam 'landed'*11. Beams explode where the beam 'landed'*12. If no message generated yet, send "nothing happens" (enchantments only)
const int reflections = pbolt.reflections;if (reflections == 0){// We aren't being recursively called.beam_message_cache.clear();pbolt.range_used = 0;}ASSERT(pbolt.range >= 0 && pbolt.range_used >=0);ASSERT(pbolt.range_used <= pbolt.range);ASSERT(!pbolt.drop_item || pbolt.item);ASSERT(!pbolt.dropped_item);if (pbolt.range == pbolt.range_used && pbolt.range > 0){#ifdef DEBUGmprf(MSGCH_DIAGNOSTICS, "fire_beam() called on already done beam ""'%s' (item = '%s')", pbolt.name.c_str(),pbolt.item ? pbolt.item->name(DESC_PLAIN).c_str() : "none");#endifreturn;}if (!pbolt.is_tracer && reflections == 0 && YOU_KILL(pbolt.thrower)){switch(pbolt.flavour){case BEAM_HELLFIRE:case BEAM_HELLFROST:did_god_conduct(DID_UNHOLY, 2 + random2(3), pbolt.effect_known);break;default:break;}}
// Conditions: beam is missile and not tracer.
#ifdef DEBUGif (!beam.drop_item)mprf(MSGCH_DIAGNOSTICS, "beam_drop_object() called when beam.drop_item ""is false (beam = %s, item = %s)", beam.name.c_str(),item->name(DESC_PLAIN).c_str());#endif
if (beam.dropped_item){#ifdef DEBUGmprf(MSGCH_DIAGNOSTICS, "beam_drop_object() called after object ""already dropped (beam = %s, item = %s)", beam.name.c_str(),item->name(DESC_PLAIN).c_str());#endifreturn;}coord_def p = _p;if (!in_bounds(p))p = beam.pos;// Conditions: beam is missile and not tracer.
copy_item_to_grid( *item, p, 1 );
if (copy_item_to_grid( *item, p, 1 ))beam.dropped_item = true;else{#ifdef DEBUGmprf(MSGCH_DIAGNOSTICS, "beam_drop_object() unable to drop ""object (beam = %s, item = %s)", beam.name.c_str(),item->name(DESC_PLAIN).c_str());#endif}
ouch(dam, NON_MONSTER, KILLED_BY_TARGETTING);
{if (beam.reflections > 0)ouch(dam, beam.reflector, KILLED_BY_REFLECTION,beam.name.c_str());else if (beam.bounces > 0)ouch(dam, NON_MONSTER, KILLED_BY_BOUNCE,beam.name.c_str());elseouch(dam, NON_MONSTER, KILLED_BY_TARGETTING);}
}static bool _beam_is_reflectable( const bolt &beam, const item_def *item ){if (beam.range_used >= beam.range)return (false);return (item && is_shield(*item) && shield_reflects(*item));}static void _ident_reflector(item_def *item){if (!is_artefact(*item))set_ident_flags(*item, ISFLAG_KNOW_TYPE);
beam.source = beam.pos;// Reset bounce_pos, so that if we somehow reflect again before reaching// the wall that we won't keep heading towards the wall.beam.bounce_pos.set(0, 0);if (beam.pos == you.pos())beam.reflector = NON_MONSTER;else if (mgrd(beam.pos) != NON_MONSTER)beam.reflector = mgrd(beam.pos);else{beam.reflector = -1;#ifdef DEBUGmprf(MSGCH_DIAGNOSTICS, "Bolt reflected by neither player nor ""monster (bolt = %s, item = %s)", beam.name.c_str(),beam.item ? beam.item->name(DESC_PLAIN).c_str() : "none");#endif}fire_beam(beam);}
mprf( "You block the %s.", beam.name.c_str() );
if (_beam_is_reflectable(beam, you.shield())){mprf( "Your %s reflects the %s!",you.shield()->name(DESC_PLAIN).c_str(),beam.name.c_str() );_ident_reflector(you.shield());_reflect_beam(beam);}elsemprf( "You block the %s.", beam.name.c_str() );
mprf("%s blocks the %s.",mon->name(DESC_CAP_THE).c_str(),beam.name.c_str());
item_def *shield = mon->mslot_item(MSLOT_SHIELD);if (_beam_is_reflectable(beam, shield)){if (you.can_see(mon)){mprf("%s reflects the %s off %s %s!",mon->name(DESC_CAP_THE).c_str(),beam.name.c_str(),mon->pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str(),shield->name(DESC_PLAIN).c_str());_ident_reflector(shield);}else if (see_grid(beam.pos))mprf("The %s bounces off of thin air!",beam.name.c_str());_reflect_beam(beam);}elsemprf("%s blocks the %s.",mon->name(DESC_CAP_THE).c_str(),beam.name.c_str());
aimed_at_spot(false),aux_source(), affects_nothing(false), obvious_effect(false),effect_known(true), fr_count(0), foe_count(0), fr_power(0),foe_power(0), fr_hurt(0), foe_hurt(0), fr_helped(0),foe_helped(0), is_tracer(false), aimed_at_feet(false),
aimed_at_spot(false), aux_source(), affects_nothing(false),effect_known(true), obvious_effect(false), fr_count(0),foe_count(0), fr_power(0), foe_power(0), fr_hurt(0),foe_hurt(0), fr_helped(0), foe_helped(0),dropped_item(false), item_pos(), item_index(NON_ITEM),range_used(0), is_tracer(false), aimed_at_feet(false),