monster_polymorph(), as it still doesn't do everything needed. Replace it with monsters::change_type(), split out from monsters::level_up_change(), which does do everything needed, and in a cleaner way. Unfortunately, it's still a hack, but it should be easier to deal with for now. Sorry for the mess.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3783 c06c8d41-db1a-0410-9941-cceddc491573
V7IKAPO5OY7CJTT62GMHQOD3EQW42FTTY3KDBOTJUODPS5WMBCHAC CWQITHQHCEGZLXYQ26OQ6PJSWPQ6Z2DBLARLGTV332LKSF7HSENQC Z75MWMOPGK3RC3ERIV5AW52CRJDTYWLXYGE6CHRF4MCB5EJ7WH6QC RIIO4BI64ECFXSRLBP3RA24QOPYXJVWMSFHLNTKUZS5YCLISLVJQC HOPP345EQLSF24XJYE3625VKU23PBKM5ZZKNCXBXUWYYORYPMDAAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC USSKCWQTF6BTE3SFLQVCT6RZHU2R7URWFC7EPO2EN3Z6U4IEQ7GQC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC VD5OPYZ3YO5L7GFKWPCMT3WXTDPUIIYGMJIOQEWNZLZSHH5L6RYQC LJ7HIRLTL5KHP3DJP57KRDH3PHZIS37HNC4SLZGK2ZQI2WTQBOPAC OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC 2SMZGNBB352OJBIT2UE3NONODTTMV3FJJFBQUN4VNLLNYJKTJKBQC 5ZYOO2RVGH53ONV4U5NO6MTINQXET6GV6TETPVCFAVOX44LDNR4QC BRGAZR5AXWC2IALBVXO5SB354IRQEIRHSK55RZPGFI4AGIOD4LUQC 4UXFU3FZOCBSLDQ4S7MJKAE2H7VUHCNRDQMIY6NJ3PHYXWNGISDQC 74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 5UC5TI7B6NWGIGN74QRBZKDBYUMHLM2ZO5ATXEZ6TZOGOLF3JX5QC CDKRLJIGVWQE2PMHCSLJBLYQEK7JYC4LQM7H2X3O6NMJMCCDRVIAC 7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC 5XSXMOBGXFLTIQE6WDXWWFVDOTUPZSIQ2FWT3YI5QMVU6D76IUYQC TVC7W7C2XKBQSD2IJFMWFVGXZAOD4EUOW43NAQTOF5KFMAUOJABQC // Turn an ordinary monster into a priestly monster.monster_change_type(mon, priest_type);
// Turn an ordinary monster into a priestly monster, using a// function normally used when going up an experience level.// This is a hack, but there seems to be no better way for now.mon->change_type(priest_type, true);
}// Change one monster type into another. This preserves as much as// possible between types, so, if the two types are radically different,// some special handling may be needed after calling this.void monster_change_type(monsters *monster, monster_type targetc){const unsigned long old_flags = monster->flags;const unsigned long old_exp = monster->experience;const int old_hp = monster->hit_points;const int old_hp_max = monster->max_hit_points;const char old_ench_countdown = monster->ench_countdown;const bool old_mon_caught = mons_is_caught(monster);/* deal with mons_sec */monster->type = targetc;monster->number = MONS_PROGRAM_BUG;mon_enchant abj = monster->get_ench(ENCH_ABJ);mon_enchant shifter = monster->get_ench(ENCH_GLOWING_SHAPESHIFTER,ENCH_SHAPESHIFTER);// Note: define_monster() will clear out all enchantments! -- bwrdefine_monster( monster_index(monster) );monster->flags = old_flags;monster->gain_exp(old_exp);monster->add_ench(abj);monster->add_ench(shifter);monster->ench_countdown = old_ench_countdown;if (mons_class_flag( monster->type, M_INVIS ))monster->add_ench(ENCH_INVIS);monster->hit_points = monster->max_hit_points* ((old_hp * 100) / old_hp_max) / 100;monster->fix_speed();if (old_mon_caught)monster->add_ench(ENCH_HELD);
// randomize things:monster->flags = 0L;monster->experience = 0L;
/* deal with mons_sec */monster->type = targetc;monster->number = MONS_PROGRAM_BUG;mon_enchant abj = monster->get_ench(ENCH_ABJ);mon_enchant shifter = monster->get_ench(ENCH_GLOWING_SHAPESHIFTER,ENCH_SHAPESHIFTER);
monster->hit_points = monster->max_hit_points* ((old_hp * 100) / old_hp_max) / 100+ random2(monster->max_hit_points);if (monster->hit_points > monster->max_hit_points)monster->hit_points = monster->max_hit_points;monster->speed_increment = 67 + random2(6);monster_drop_ething(monster);
mons_clear_trapping_net(monster);
const int net = get_trapping_net(monster->x, monster->y);if (net != NON_ITEM)remove_item_stationary(mitm[net]);
if (const monster_level_up *lup =monster_level_up_target(static_cast<monster_type>(type), hit_dice)){const monsterentry *orig = get_monster_data(type);// Ta-da!type = lup->after;
const monsterentry *orig = get_monster_data(type);// Ta-da!type = after;
const int minhp = dummy.max_hit_points;if (max_hit_points < minhp){hit_points += minhp - max_hit_points;max_hit_points = minhp;hit_points = std::min(hit_points, max_hit_points);}
hit_points += minhp - max_hit_points;max_hit_points = minhp;hit_points = std::min(hit_points, max_hit_points);