chooses a different, random beam flavour (which undoudtedly needs to have their relative weights changed after playtesting) for each square it passes through, but in the future it might do things like bounce off walls at weird angles or animate weapons left laying on the ground.
Added CLOUD_CHAOS, though it doesn't do anything yet.
Monsters which are marked summoned or otherwise given ENCH_ABJ can also be marked with the type of summoning that happened, which is stored in the until-now-unused ENCH_SUMMON. This is useful for figuring out if a monster has ENCH_ABJ but isn't really summoned (like fire vortices created by Fire Storm or dancing weapons created by Tukima's Dance) so that they won't be affected by abjuration. It's also currently used to do a different "dissapears in a puff of smoke" messages for summoned monsters based on the summoning type, so that monsters summoned by Shadow Creature "dissolve into shadows" and don't leave behind any clouds, and temporary god gift monsters from good gods "dissolve into sparkling lights". In the future it might be used to do temporarily animated corpses, which turn back into a corpse when killed or when the animation runs out.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7778 c06c8d41-db1a-0410-9941-cceddc491573
AYU5OVG2HZO46KDAPKUWAVHS5HTYFKUWIMIRMTHAXVVFEDJE7YPAC 433PR5ZCMUQOBYD3CVSBY3DOCP4NBS5TFSMWFVB2MGREG4VK2EEQC G6AT74PNGPB5ZEITF4EXNTAB7MNZFWKRE7KT7DUV4TSWVHQGYDJQC U5BUJF7RAD3Z44WG5LE3NLVSFZALT5W6MHKQ3BSVAJ4NZ7PU7Q5QC 56D656WZS2LWVTXGWPR5FFJ7MDHP25XGPTBMYM4NHT4TKSJILX3QC SH5BS5AJPUFPXQHM5MZPIY3CCVT4EAIRLSAQWZYL5WX2J7FPBSQQC 53BVN4ZHKGUAJE53HM6FC6GKUGXOU5QBUT7CLXV2ONS6S5NPW55AC LACOILN7WCNIM3GTLY56TQOMC3MFPW2XX3RHDWXRSMBQQPI4AQXQC EJYL6BLIGHOMKK35VYL2X2MT2HILY2XGKIP4NYU6Q7R5YTYEAT5QC 44XY2RJGTBXIDIRRI4TAH7ZPS7F6ZNKTY2HNTRDQLB5BAUYAGQXQC LLA7OZDQJ3S2YKGNNDD6K3VP3FPMQLZX3IUO4WDJQVJHGKGCCUZQC SM6YRPYZS6LMDQA6X3VAOK2PGMUFKPD7JMWJISOQSMX2CBR4ISPAC CDFS7Z74W5HKPQIHQICOG442KQFXUSBGGLDDQLE3MG74T44YU6AQC T4FNOPMWYYJHJBTTY33PB43HTJPKEC46L62YERTWIX73HYZSELXQC CCRQESB4ADT4WA7FGLNZZXAJ6G5QMCTYCZIWORBN45P6ZPILC34AC KVTA7IUBD2O7ZEUU5T5VP7D3XVLFLYICXUPP5WCPAODBXKK4DNNQC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC NYURIMPCM2RADLMIQSN76OPKXQSK4XBLFNXD2OO53KGZI3MA6AQAC UKBVBVJK23OUOOKQJRGLZWEZYED5KZ4NLODW6U67UEBYCFWGGQOAC WT66JDIRTLLP37SHTV4GI3V64JFJ4D25LNRLGCHFG6CLEFKJ3QGQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 3DQXSE4YGFBBDUWK4YEOFWW4UPWILWELFSLP37SL6BERGAZJC5YAC K7J2IGELTIQL5KAMBV62MFVIVMEZEWCOLZ7GHFXHYPANYIF7BRZAC DZD6YG52TXNI4CJ2FRGFULBH6G5MDLRVQV3X3V35AW533Z3TVBKAC 4SWAT5KCKQV527NKELAXFQ5XA4Q5HONQXD4VBXMUZNPVPQKPCPNAC YF6CE2VBFK6K4V34PKBVYVQUTJRDDDCF2M5RMUGW6V6N2M4SUPLAC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC VQZEJTCSRZ5RVLCCKUCIS3IVZPFYRC26I74X4WIJAPEY7NYID2UQC XWEI2LM5HPH3F4Y5TS7B6FWXQLERWJP2MHW36KGYW5TIAOORHYUAC BMGB25AWEDOAWKDB7H22R6D4SL32CSBSOBWBIEN3GFGDLEDGEWJAC JBB7GZTVO3UJSPFVELSP4WPJZ5SC5LY36FJJ7WF2BJGZTVPNIV3AC 5ETBQI75XWCYG5UALQR6TKD7FCJYTCVQEN64D6OHXVOGO3QB3AKAC CUM44NOPIB7LGTRY2O2R5MYXAB27R3TFM6LUBEQHZFXLZWJ55QZAC JYEEOUYQ7ZPKOGWUV7VCORBVSOLF2UCBFBH3TR75RGOSS6PNKYUAC 52OLLMBMDNX2WBYVSBDJVRC45QCXDIG4XQENYJAECOVG6ICAKVLAC 7PRZJ6KZLG26YVTAMXT7YOTQLWZHGWGRTKXZZ52P4XYCQD4GT5WQC GMCNF7YBSN7WQJNHSF3RV2NTHTVP4TABCNP7S26UEIHPAKNCPWGAC KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC BNRY5YIXLFE2TDNU2JQHWWXJQVWNSEWQ52DU7XUWIT5DZWKGBDDAC BFCFMN2BXNLXJCYYCL2V2XTDQQNM3PJPSRB6CU76FM3332NC7GMAC 2YL37AGHLFOMIF3GCTVQGGV2RNNWETWM6ZMUHO3QEWDVBFFSFAKQC BYURAML2EPTULHH22Q5RPXYGDEYAJYESR6C72UMNPPYHTCJZUPFAC MSMWAL6JZAWNGZXCNXPATUMAU6TVXBWWFY666P7UBSZ5LPYJYUCQC C5VA63WAQRWPENIMXRPUPZLZJMC77PL2B3A77HYFWDCZU5QDG7VQC Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC 2TFYJ7D72JY4DYQW3GSPEONA2WYIVHAJXTIQ2QRDIWF65XN2QFGAC QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC B62ICMDTN5V7R7RBL4JALFVKEMVOOVLRSJASRNYS6CGFWBEEF5JQC DOZORMA366M4HB5JKSS27BMCR6ET7QNZNND2B7KV3NVEEPR5H7EAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC P5KSBMFHDCAFUGHSOCLDG7J7XKCGJBCSDICYOMOYCEBBBXM55CEAC 542UIZKI65UDRNEMGFFDBWYD5XC7AYLTZ3JZQRR2GHYJALD3YY6QC PDOFPXD2X6VI23AHKCGQ5RVDBG74CNP2E3YOHKXLOARHHBXEK3HQC V7IKAPO5OY7CJTT62GMHQOD3EQW42FTTY3KDBOTJUODPS5WMBCHAC OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC 2SMZGNBB352OJBIT2UE3NONODTTMV3FJJFBQUN4VNLLNYJKTJKBQC 4LNIHTHZTCOEZEHZ4GW6WCZH4UCDWKK5UVUKEDODEBBS4YH2KONQC GPEJOT73KMACP33IPAKFR5ROGHCOIP22VXZMQNYTGLEA2OSZUM2AC KPSCSVGHKEQ4ENM3QQU2U3GYMV52NDFO5L6ML7YDPUKV3365OA3QC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC 5V47S4NNTHWTSAHV3YLO2VGH7JTUIYJ3GBPDN5ZM4UQALT2ZEXDQC QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC UAJN2CFA2QHYDHW2UFAVPPHDQFCD54RKM6V2UC4AMEDJUBBLNWIQC 33ZMPQC6OXTESW7SRW765GRNJUEJRSYONRVZVIEUDAUEJ2PPMB4AC X4OCLD5YEXCYVQNMOQORLIO72AKUEMT3BT6FB3TW2HARKN5X7MEQC 5XSXMOBGXFLTIQE6WDXWWFVDOTUPZSIQ2FWT3YI5QMVU6D76IUYQC JZTWTPXIUEVACX5B6FYQRVRJD3KQN653C4G4GXT2VSMX4EP7WS3AC Q652MJM34TH2ZV6CPA2RERMJMDMK2TQEAALRMXK2G6Y25UWKRJ3QC AIVXE6QBRVCZAASKQRZO6LBDGTYEYSSD2DZCWRX4VLSKE3GCNIDAC ZP2KE7A2LE7Z2S7AC45WE4CXDSEVDTWIMV2EM4IBUKXYJIDU6R7QC HFEFKHVV2ULXS6ZEFNX6ZXXUJKME5L2PITQ3VRTKMRUOU3DHXXWQC EHL7B5UIYYHSFX3KXQ43C4GNFJSEUEXFF7U3IL7XU6E5R675WS7AC ATDAT2AONG2BDLZFBJZB4WVNRUFQAU7RDIVUBAZ6STAV62NX5R4AC PR42BCP5BPRFD2MP5H6CIJP7E57Q6TKL6SOXZWFKMFVR2OZWHT7AC 5FHWTG7M6FW4B3I33YI7QSM3OZIB6ZGC6TI6JISSLY5Y43HI56VAC F2MGW5DMHF7AF7R7KX3H6BYJGZ57CVTDCZWUHSFJXS52IVOC3NZQC 25CH7HH4LKXFIZ75YNMXS3TSXO6O27DYSOPLOD45K4OCNFWLS4LQC FLAGBNUNSIQNFDN53CDWABJRTTFWDL4PG34AI474ZKPXDEPYHOAQC LY7DLLD7IKL6ZQPVROLDJ46XRM5CMAAEBRFDKJ4M53CPC5GFCGSQC S34LKQDIQJLIWVIPASOJBBZ6ZCXDHP5KPS7TRBZJSCDRVNCLK6UAC AS2IQQJNNCEQNXXKTGYHLB7RO3ZKCF4F7GK6FJH66BOOKDDRGNIQC WA2OSEGWVCESURYWNERNYWQKHE6SU4XQ4Q4HJY5B6ZPGNFUKQEEQC ZGUJWUFJ4NFFJ6PGXLFGQWCWBCZHPWGWI44NJHJEVPRG5L36PADQC GVW4OBPGXY2Q75HB7QHADZIOHKL22FI2BSJ2TM4K5SBJENBFTQKAC TQLWCGVXVZ75H7MDBJD3DJDUFNW62WOAEDJUVKCHQTAXKBP47CSAC OFH2B2UZBK43QLFQBZ54FOCFLFNE54BZVDNCEUGDTBCUGNVZULIQC PI5BATR2SER3RFE76IUGHM2AGXVFOUM3PLU7WC2K2Q2BA5K2E73QC BJPPSWEN35BG4KP3XTXPDMAJ2GAUMHXKHCNALAZ4B4OS6B3KDSUQC UZ5623MOLKBTGBSRBJ4OBOEI4IEZSPV3NCV2DRMUZ3CHHJQVHIIAC LT7MICXP753TFF6I4LTWHZWCYEXO3LBRQ3H2TOXZFBXVHZTIYGNQC 4CIYU7SAAGQJ6BH2WWS4EJWUS6GX25IV24GLYSPGDNWNASVJSIYAC OYANFNGKCXG2NLQMYW4TNFU3LFK3533XQ3HFGI3LNMY4JGMDMK5QC 2SNCC2NXKFVBYTWH7THU2QELHONTOBRNCWH6FWYORKKCWZAXTTVAC SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC HAM54HXIO2245W6REO4RZDY2QMIH476AWWJSMYAMSYYNEBBJSHWAC RDZUMV3A5TREQHLPPJWDWVXBNIOWC3CQJJ35TYFBQQVQNTU7SPXQC int bow_brand = SPWPN_NORMAL;const int ammo_brand = get_ammo_brand(item);const bool poison = (ammo_brand == SPMSL_POISONED);
int bow_brand = SPWPN_NORMAL;const int ammo_brand = get_ammo_brand(item);bool poison = (ammo_brand == SPMSL_POISONED);
}bool mons_clonable(const monsters* mon, bool needs_adjacent){// No uniques, pandemonium lords or player ghosts. Also, figuring// out the name for the clone of a named monster isn't worth it.if (mons_is_unique(mon->type) || mon->is_named() || mon->ghost.get())return (false);if (needs_adjacent){// Is there space for the clone?bool square_found = false;for (int i = 0; i < 8; i++){const coord_def p = mon->pos() + Compass[i];if (in_bounds(p) && p != you.pos() && mgrd(p) == NON_MONSTER&& monster_habitable_grid(mon, grd(p))){square_found = true;break;}}if (!square_found)return (false);}// Is the monster carrying an artefact?for (int i = 0; i < NUM_MONSTER_SLOTS; i++){const int index = mon->inv[i];if (index == NON_ITEM)continue;if (is_artefact(mitm[index]))return (false);}return (true);}int clone_mons(const monsters* orig, bool quiet, bool* obvious,coord_def pos){// Is there an open slot in menv?int midx = NON_MONSTER;for (int i = 0; i < MAX_MONSTERS; i++)if (menv[i].type == -1){midx = i;break;}if (midx == NON_MONSTER)return (NON_MONSTER);if (!in_bounds(pos)){// Find an adjacent square.int squares = 0;for (int i = 0; i < 8; i++){const coord_def p = orig->pos() + Compass[i];if (in_bounds(p) && p != you.pos() && mgrd(p) == NON_MONSTER&& monster_habitable_grid(orig, grd(p))){if (one_chance_in(++squares))pos = p;}}if (squares == 0)return (NON_MONSTER);}ASSERT(mgrd(pos) == NON_MONSTER && you.pos() != pos);monsters &mon(menv[midx]);mon = *orig;mon.position = pos;mgrd(pos) = midx;// Duplicate objects, or unequip them if they can't be duplicated.for (int i = 0; i < NUM_MONSTER_SLOTS; i++){const int old_index = orig->inv[i];if (old_index == NON_ITEM)continue;const int new_index = get_item_slot(0);if (new_index == NON_ITEM){mon.unequip(mitm[old_index], i, 0, true);mon.inv[i] = NON_ITEM;continue;}mon.inv[i] = new_index;mitm[new_index] = mitm[old_index];}bool _obvious;if (obvious == NULL)obvious = &_obvious;*obvious = false;if (you.can_see(orig) && you.can_see(&mon)){if (!quiet)simple_monster_message(orig, " is duplicated!");*obvious = true;}mark_interesting_monst(&mon, mon.behaviour);if (you.can_see(&mon)){seen_monster(&mon);viewwindow(true, false);}return (midx);
int corpse_class = mons_species(monster->type);
bool force = false;int corpse_class = mons_species(monster->type);// If this was a corpse that was temporarily animated then turn the// monster back into a corpse.if (mons_class_is_zombified(monster->type)&& (summon_type == SPELL_ANIMATE_DEAD|| summon_type == SPELL_ANIMATE_SKELETON|| summon_type == MON_SUMM_ANIMATE)){force = true;corpse_class = mons_zombie_base(monster);}
const bool poison = (mons_corpse_effect(monster->type) == CE_POISONOUS
if (force && !silent){if (you.can_see(monster))simple_monster_message(monster, " turns back into a corpse!");elsemprf("%s appears out of nowhere!",mitm[o].name(DESC_CAP_A).c_str());}const bool poison = (mons_corpse_effect(corpse_class) == CE_POISONOUS
}void _monster_die_cloud(const monsters* monster, bool corpse, bool silent,bool summoned, int summon_type){// Chaos spawn always leave behind a cloud of chaos.if (monster->type == MONS_CHAOS_SPAWN){summoned = true;corpse = false;}if (!summoned)return;std::string prefix;std::string msg = " disappears in a puff of smoke!";cloud_type cloud = random_smoke_type();int dur = 1 + random2(3);if (corpse){if (mons_weight(mons_species(monster->type)) == 0)return;prefix = "'s corpse";}switch(summon_type){case SPELL_SHADOW_CREATURES:msg = " disolves into shadows!";cloud = CLOUD_NONE;break;case MON_SUMM_CHAOS:msg = " degenerates into a cloud of primal chaos!";cloud = CLOUD_CHAOS;break;case MON_SUMM_WRATH:case MON_SUMM_AID:if (is_good_god(monster->god)){msg = " disolves into sparkling lights!";cloud = CLOUD_NONE;}break;}if (monster->god == GOD_XOM && one_chance_in(10)|| cloud != CLOUD_NONE && monster->type == MONS_CHAOS_SPAWN){msg = " degenerates into a cloud of primal chaos!";cloud = CLOUD_CHAOS;}if (mons_is_holy(monster) && summon_type != SPELL_SHADOW_CREATURES&& summon_type != MON_SUMM_CHAOS){msg = " disolves into sparkling lights!";cloud = CLOUD_NONE;}if (!silent)simple_monster_message(monster, (prefix + msg).c_str());if (cloud != CLOUD_NONE)place_cloud( cloud, monster->pos(), dur,monster->kill_alignment() );
if (!silent){simple_monster_message( monster," disappears in a puff of smoke!" );}place_cloud( random_smoke_type(),monster->pos(), 1 + random2(3),monster->kill_alignment() );
if (!wizard)_monster_die_cloud(monster, false, silent, summoned,summon_type);
if (monster->has_ench(ENCH_ABJ)){if (mons_weight(mons_species(monster->type))){simple_monster_message(monster,"'s corpse disappears in a puff of smoke!");place_cloud( random_smoke_type(),monster->pos(), 1 + random2(3),monster->kill_alignment() );}}else{
_monster_die_cloud(monster, true, silent, summoned, summon_type);if (!summoned)
abjuration_duration(abj), pos(p), foe(mfoe), flags(monflags),god(which_god), number(monnumber), colour(moncolour),
abjuration_duration(abj), summon_type(0), pos(p), foe(mfoe),flags(monflags), god(which_god), number(monnumber), colour(moncolour),power(monpower), proximity(prox), level_type(ltype), map_mask(0){}mgen_data(monster_type mt,beh_type beh,int abj,int st,const coord_def &p = coord_def(-1, -1),unsigned short mfoe = MHITNOT,unsigned monflags = 0,god_type which_god = GOD_NO_GOD,monster_type base = MONS_PROGRAM_BUG,int monnumber = 0,int moncolour = BLACK,int monpower = you.your_level,proximity_type prox = PROX_ANYWHERE,level_area_type ltype = you.level_type): cls(mt), base_type(base), behaviour(beh),abjuration_duration(abj), summon_type(st), pos(p), foe(mfoe),flags(monflags), god(which_god), number(monnumber), colour(moncolour),
};// Non-spell "summoning" types to give to monsters::mark_summoned(), or as// the fourth paramater of mgen_data's second constructor.//// Negative values since spells are non-negative.enum mon_summon_type{MON_SUMM_CLONE = -10000, // Cloned from another monsterMON_SUMM_ANIMATE, // Item/feature/substance which was animatedMON_SUMM_CHAOS, // Was made from pure chaosMON_SUMM_MISCAST, // Spell miscastMON_SUMM_ZOT, // Zot trapMON_SUMM_WRATH, // Divine wrathMON_SUMM_AID // Divine aid
return (m->has_ench(ENCH_ABJ));
const mon_enchant abj = m->get_ench(ENCH_ABJ);if (abj.ench == ENCH_NONE){if (duration != NULL)*duration = -1;if (summon_type != NULL)*summon_type = 0;return (false);}if (duration != NULL)*duration = abj.duration;const mon_enchant summ = m->get_ench(ENCH_SUMMON);if (summ.ench == ENCH_NONE){if (summon_type != NULL)*summon_type = 0;return (true);}if (summon_type != NULL)*summon_type = summ.degree;switch(summ.degree){// Temporarily dancing weapons are really there.case SPELL_TUKIMAS_DANCE:// A corpse/skeleton which was temporarily animated.case SPELL_ANIMATE_DEAD:case SPELL_ANIMATE_SKELETON:// Fire vortices are made from real fire.case SPELL_FIRE_STORM:// Clones aren't really summoned (though their equipment might be).case MON_SUMM_CLONE:// Some object which was animated, and thus not really summoned.case MON_SUMM_ANIMATE:return (false);}return (true);
std::string setup_chaos_ammo(bolt &pbolt, item_def ammo){ASSERT(!is_artefact(ammo));const bool poisoned = (get_ammo_brand(ammo) == SPMSL_POISONED);// Don't choose BEAM_POISON or BEAM_HEALING if we have poisoned ammo.const int pois_weight = poisoned ? 0 : 10;const int heal_weight = poisoned ? 0 : 10;
const beam_type flavour = static_cast<beam_type>(random_choose_weighted( pois_weight, BEAM_POISON,heal_weight, BEAM_HEALING,10, BEAM_FIRE,10, BEAM_COLD,10, BEAM_ELECTRICITY,10, BEAM_NEG,10, BEAM_ACID,10, BEAM_HELLFIRE,10, BEAM_NAPALM,10, BEAM_HELLFROST,10, BEAM_SLOW,10, BEAM_HASTE,10, BEAM_PARALYSIS,10, BEAM_CONFUSION,10, BEAM_INVISIBILITY,10, BEAM_POLYMORPH,10, BEAM_BANISH,10, BEAM_DISINTEGRATION,0 ));std::string name;int colour;if (poisoned)name = "poison ";switch(flavour){case BEAM_POISON:name += "poison";colour = EC_POISON;break;case BEAM_HEALING:name += "healing";colour = EC_HEAL;break;case BEAM_FIRE:name += "flame";colour = EC_FIRE;break;case BEAM_COLD:name += "frost";colour = EC_ICE;break;case BEAM_ELECTRICITY:name += "lightning";colour = EC_ELECTRICITY;break;case BEAM_NEG:name += "negative energy";colour = EC_NECRO;break;case BEAM_ACID:name += "acid";colour = YELLOW;break;case BEAM_HELLFIRE:name += "hellfire";colour = EC_FIRE;break;case BEAM_NAPALM:name += "sticky fire";colour = EC_FIRE;break;case BEAM_HELLFROST:name += "hellfrost";colour = EC_ICE;break;case BEAM_SLOW:name += "slowing";colour = EC_ENCHANT;break;case BEAM_HASTE:name += "hasting";colour = EC_ENCHANT;break;case BEAM_PARALYSIS:name += "paralysis";colour = EC_ENCHANT;break;case BEAM_CONFUSION:name += "confusion";colour = EC_ENCHANT;break;case BEAM_INVISIBILITY:name += "invisibility";colour = EC_ENCHANT;break;case BEAM_POLYMORPH:name += "polymorphing";colour = EC_MUTAGENIC;break;case BEAM_BANISH:name += "banishment";colour = EC_WARP;break;case BEAM_DISINTEGRATION:name += "disintegration";colour = EC_DEATH;break;default:ASSERT(!"Invalid chaos ammo flavour.");break;}pbolt.name = "bolt of ";pbolt.name += name;pbolt.flavour = flavour;pbolt.colour = colour;pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT);// Get name for a plain arrow/bolt/dart/needle.ammo.special = 0;std::string ammo_name = ammo.name(DESC_NOCAP_A);ammo_name += " of ";ammo_name += name;return ammo_name;}
// Default to whatever colour magic is today.if (colour == -1)colour = element_colour(EC_MAGIC);
}static beam_type _chaos_beam_flavour(){const beam_type flavour = static_cast<beam_type>(random_choose_weighted(10, BEAM_FIRE,10, BEAM_COLD,10, BEAM_ELECTRICITY,10, BEAM_POISON,10, BEAM_NEG,10, BEAM_ACID,10, BEAM_HELLFIRE,10, BEAM_NAPALM,10, BEAM_HELLFROST,10, BEAM_SLOW,10, BEAM_HASTE,10, BEAM_HEALING,10, BEAM_PARALYSIS,10, BEAM_CONFUSION,10, BEAM_INVISIBILITY,10, BEAM_POLYMORPH,10, BEAM_BANISH,10, BEAM_DISINTEGRATION,0 ));return (flavour);
// Random beams: randomize before affect().bool random_beam = false;if (pbolt.flavour == BEAM_RANDOM){random_beam = true;pbolt.flavour = static_cast<beam_type>(random_range(BEAM_FIRE, BEAM_ACID));}
if (random_beam){pbolt.flavour = BEAM_RANDOM;pbolt.effect_known = false;}
// Actually draw the beam/missile/whatever,// if the player can see the cell.
// Reset chaos beams so that it won't be considered an invisible// enchantment beam for the purposes of animation.if (pbolt.real_flavour == BEAM_CHAOS)pbolt.flavour = pbolt.real_flavour;// Actually draw the beam/missile/whatever, if the player can see// the cell.
// Random beams: randomize before affect().if (beam.flavour == BEAM_RANDOM){random_beam = true;
// Random/chaos beams: randomize before affect().if (beam.real_flavour == BEAM_RANDOM)
flavour(BEAM_MAGIC), drop_item(false), item(NULL), source(),target(), pos(), damage(0,0), ench_power(0), hit(0),thrower(KILL_MISC), ex_size(0), beam_source(MHITNOT), name(),is_beam(false), is_explosion(false), is_big_cloud(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),
flavour(BEAM_MAGIC), real_flavour(BEAM_MAGIC), drop_item(false),item(NULL), source(), target(), pos(), damage(0,0),ench_power(0), hit(0), thrower(KILL_MISC), ex_size(0),beam_source(MHITNOT), name(), is_beam(false),is_explosion(false), is_big_cloud(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),