git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2584 c06c8d41-db1a-0410-9941-cceddc491573
5UC5TI7B6NWGIGN74QRBZKDBYUMHLM2ZO5ATXEZ6TZOGOLF3JX5QC OONYLF4DAPLIYLBNNRW74IVT5BBTWI4XHQBXSNSPVRX3FTKJBTRAC 7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC C5VA63WAQRWPENIMXRPUPZLZJMC77PL2B3A77HYFWDCZU5QDG7VQC DOZORMA366M4HB5JKSS27BMCR6ET7QNZNND2B7KV3NVEEPR5H7EAC WZNB427K3EUNV3FMVXLQTM4UIHER4FIKQXWLUUXRNQC3OQ33VQYAC QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC 7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC MQ62OAMLGJVRW2QIL4PAZRAU6PC52ZVGY2FCOBIY6IWGQIHMU5CAC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC WT66JDIRTLLP37SHTV4GI3V64JFJ4D25LNRLGCHFG6CLEFKJ3QGQC OP6CTAKWCAU64JXQ3USQYR5E5IFHQHNCACII5UMVRXUTZXJQOAZAC QS3ZRS3E6KL3YJHPKYEWCWJYRBJSXD5OOYF6Y25HZVECGPJRDB5QC YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC static void give_monster_experience( int killer_index, int experience,bool victim_was_born_friendly ){if (killer_index < 0 || killer_index >= MAX_MONSTERS)return;monsters *mons = &menv[killer_index];if (!mons->alive())return;if (mons_friendly(mons) != victim_was_born_friendly)mons->gain_exp(experience);}
child->behaviour = parent->behaviour; /* Look at this! */child->foe = parent->foe;child->attitude = parent->attitude;child->colour = parent->colour;child->enchantments = parent->enchantments;child->ench_countdown = parent->ench_countdown;
#ifndef __MGROW_H__#define __MGROW_H__#include "AppHdr.h"#include "FixVec.h"// Monster level-up data.struct monster_level_up{monster_type before, after;int chance; // Chance in 1000 of the monster growing up,// defaults to 1000.bool adjust_hp; // If hp post growing up is less than minimum, adjust it.monster_level_up(monster_type _before, monster_type _after,int _chance = 1000, bool _adjust = true): before(_before), after(_after), chance(_chance), adjust_hp(_adjust){}};const int MAX_MONS_HD = 27;class mons_experience_levels{public:mons_experience_levels();unsigned operator [] (int xl) const{return mexp[xl];}private:FixedVector<unsigned, MAX_MONS_HD + 1> mexp;};#endif
/** File: mgrow.cc* Summary: Monster level-up code.** Modified for Crawl Reference by $Author: dshaligram $ on $Date: 2007-10-25T09:49:39.320031Z $*/#include "AppHdr.h"#include "enum.h"#include "mgrow.h"#include "mon-util.h"#include "monstuff.h"#include "stuff.h"// Base experience required by a monster to reach HD 1.const int monster_xp_base = 8;// Experience multiplier to determine the experience needed to gain levels.const int monster_xp_multiplier = 120;const mons_experience_levels mexplevs;// Monster growing-up sequences. You can specify a chance to indicate that// the monster only has a chance of changing type, otherwise the monster// will grow up when it reaches the HD of the target form.//// No special cases are in place: make sure source and target forms are similar.// If the target form requires special handling of some sort, add the handling// to level_up_change().//static const monster_level_up mon_grow[] ={monster_level_up(MONS_ORC, MONS_ORC_WARRIOR),monster_level_up(MONS_ORC_WARRIOR, MONS_ORC_KNIGHT),monster_level_up(MONS_ORC_KNIGHT, MONS_ORC_WARLORD),monster_level_up(MONS_ORC_PRIEST, MONS_ORC_HIGH_PRIEST),monster_level_up(MONS_ORC_WIZARD, MONS_ORC_SORCERER),monster_level_up(MONS_KOBOLD, MONS_BIG_KOBOLD),monster_level_up(MONS_UGLY_THING, MONS_VERY_UGLY_THING),monster_level_up(MONS_ANT_LARVA, MONS_GIANT_ANT),monster_level_up(MONS_KILLER_BEE_LARVA, MONS_KILLER_BEE),monster_level_up(MONS_CENTAUR, MONS_CENTAUR_WARRIOR),monster_level_up(MONS_YAKTAUR, MONS_YAKTAUR_CAPTAIN),monster_level_up(MONS_NAGA, MONS_NAGA_WARRIOR),monster_level_up(MONS_NAGA_MAGE, MONS_GREATER_NAGA),monster_level_up(MONS_DEEP_ELF_SOLDIER, MONS_DEEP_ELF_FIGHTER),monster_level_up(MONS_DEEP_ELF_FIGHTER, MONS_DEEP_ELF_KNIGHT),// deep elf magi can become either conjurers or summoners.monster_level_up(MONS_DEEP_ELF_MAGE, MONS_DEEP_ELF_SUMMONER, 500),monster_level_up(MONS_DEEP_ELF_MAGE, MONS_DEEP_ELF_CONJURER),monster_level_up(MONS_DEEP_ELF_PRIEST, MONS_DEEP_ELF_HIGH_PRIEST),};mons_experience_levels::mons_experience_levels(){int experience = monster_xp_base;for (int i = 1; i <= MAX_MONS_HD; ++i){mexp[i] = experience;int delta =(monster_xp_base + experience) * 2 * monster_xp_multiplier/ 500;delta =std::min(std::max(delta, monster_xp_base * monster_xp_multiplier / 100),3000);experience += delta;}}static const monster_level_up *monster_level_up_target(monster_type type, int hit_dice){for (unsigned i = 0; i < ARRAYSIZE(mon_grow); ++i){const monster_level_up &mlup(mon_grow[i]);if (mlup.before == type){const monsterentry *me = get_monster_data(mlup.after);if (static_cast<int>(me->hpdice[0]) == hit_dice&& random2(1000) < mlup.chance){return (&mlup);}}}return (NULL);}bool monsters::level_up_change(){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;// Initialise a dummy monster to save work.monsters dummy;dummy.type = type;define_monster(dummy);colour = dummy.colour;speed = dummy.speed;spells = dummy.spells;fix_speed();const monsterentry *m = get_monster_data(type);ac += m->AC - orig->AC;ev += m->ev - orig->ev;if (lup->adjust_hp){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);}}return (true);}return (false);}bool monsters::level_up(){if (hit_dice >= MAX_MONS_HD)return (false);++hit_dice;// A little maxhp boost.if (max_hit_points < 1000){int hpboost = hit_dice > 3? max_hit_points / 8 : max_hit_points / 4;if (hpboost < 2)hpboost = 2;if (hpboost > 20)hpboost = 20;max_hit_points += hpboost;hit_points += hpboost;hit_points = std::min(hit_points, max_hit_points);}level_up_change();return (true);}void monsters::init_experience(){if (experience || !alive())return;hit_dice = std::max(hit_dice, 1);experience = mexplevs[std::min(hit_dice, MAX_MONS_HD)];}void monsters::gain_exp(int exp){if (!alive())return;init_experience();if (hit_dice >= MAX_MONS_HD)return;// Only natural monsters can level-up.if (holiness() != MH_NATURAL)return;// Avoid wrap-around.if (experience + exp < experience)return;experience += exp;const monsters mcopy(*this);int levels_gained = 0;// Monsters can gain a maximum of two levels from one kill.while (hit_dice < MAX_MONS_HD&& experience >= mexplevs[hit_dice + 1]&& level_up()&& ++levels_gained < 2);if (levels_gained){if (mons_intel(type) >= I_NORMAL)simple_monster_message(&mcopy, " looks more experienced.");elsesimple_monster_message(&mcopy, " looks stronger.");}if (hit_dice < MAX_MONS_HD && experience >= mexplevs[hit_dice + 1])experience = (mexplevs[hit_dice] + mexplevs[hit_dice + 1]) / 2;}