⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 creature.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
Item *Creature::getItemAtLocation(int location) {  int i;  for(i = 0; i < Character::INVENTORY_COUNT; i++) {    if((1 << i) == location) {      if(equipped[i] < MAX_INVENTORY_SIZE) {        return getInventory(equipped[i]);      } else {        return NULL;      }    }  }  return NULL;}// calculate the aggregate values based on equipped itemsvoid Creature::recalcAggregateValues() {  // calculate the armor (0-100, 100-total protection)  armor = (monster ? monster->getBaseArmor() : 0);  for(int i = 0; i < Character::INVENTORY_COUNT; i++) {    if(equipped[i] != MAX_INVENTORY_SIZE) {      Item *item = inventory[equipped[i]];      if(item->getRpgItem()->getType() == RpgItem::ARMOR) {        armor += item->getRpgItem()->getAction();      }    }  }  armor += bonusArmor;}Item *Creature::getBestWeapon(float dist) {  Item *item = getItemAtLocation(Character::INVENTORY_RIGHT_HAND);  if(item && item->getRpgItem()->getDistance() >= dist) return item;  item = getItemAtLocation(Character::INVENTORY_LEFT_HAND);  if(item && item->getRpgItem()->getDistance() >= dist) return item;  item = getItemAtLocation(Character::INVENTORY_WEAPON_RANGED);  if(item && item->getRpgItem()->getDistance() >= dist) return item;  return NULL;}// return the initiative for a battle round (0-10), the lower the faster the attack// the method can return negative numbers if the weapon skill is very high (-10 to 10)int Creature::getInitiative(Item *weapon, Spell *spell) {  // use the speed skill  float speed = getSkill(Constants::SPEED);  // roll for half the luck  speed += (getSkill(Constants::LUCK / 2) * rand()/RAND_MAX);  if(spell) {    speed -= spell->getSpeed();    speed += getSkill(spell->getSchool()->getSkill());  } else if(weapon) {    // add weapon speed (bare hand attack is the fastest, unless weapon skill is very good)    speed -= weapon->getRpgItem()->getSpeed();    if(weapon->getRpgItem()->getSkill() > -1)      speed += getSkill(weapon->getRpgItem()->getSkill());  }  // at this point a score of 150 is the fastest and 0 is the slowest  // convert to 0-10 and flip (so 10 is the slowest)  return(10 - (int)(speed / 15.0f));}// return number of projectiles that can be launched simultaniously// it is a function of speed, level, and weapon skill// this method returns a number from 1-10int Creature::getMaxProjectileCount(Item *item) {  int n = (int)((double)(getSkill(Constants::SPEED) +                          (getLevel() * 10) +                          getSkill(item->getRpgItem()->getSkill())) / 30.0f);  if(n <= 0) n = 1;  return n;}// roll the die for the toHit number. returns a value between 0(total miss) - 100(best hit)int Creature::getToHit(Item *weapon) {  float tohit = getSkill(Constants::COORDINATION) + getSkill(Constants::LUCK) / 2;  if(weapon && weapon->getRpgItem()->getSkill() > -1) {    tohit += getSkill(weapon->getRpgItem()->getSkill());  } else {    tohit += getSkill(Constants::HAND_TO_HAND_COMBAT);  }  // so far the max score is 250  // tohit = 75% of tohit + (rand(25% of tohit))  float score = (0.75f * tohit) + ((0.25f * tohit) * rand()/RAND_MAX);  // convert to 0-100 value  return(int)(score / 2.5f);}// return the damage as:// rand(weapon + power + (skill - 50 % weapon))int Creature::getDamage(Item *weapon) {  float damage = 0.0f;  float baseDamage = (weapon ? weapon->getRpgItem()->getAction() :                       (getSkill(Constants::POWER) / 10));  damage = baseDamage;  damage += (float)getSkill(Constants::POWER) / 10.0f;  float skill = (weapon && weapon->getRpgItem()->getSkill() > -1 ?                 getSkill(weapon->getRpgItem()->getSkill()) :                 getSkill(Constants::HAND_TO_HAND_COMBAT));  damage = damage + (damage * ((skill - 50) / 100.0f) );  return(int)(damage * rand()/RAND_MAX);}/** take some damage*/bool Creature::takeDamage(int damage, int effect_type) {  hp -= damage;  // if creature dies start effect at its location  if(hp > 0) startEffect(effect_type);  else if(effect_type != Constants::EFFECT_GLOW) {    scourge->getMap()->startEffect(getX(), getY(), getZ(),                                    effect_type, (Constants::DAMAGE_DURATION * 4),                                    getShape()->getWidth(), getShape()->getDepth());  }  return(hp <= 0);}void Creature::startEffect(int effect_type, int duration) {  // show an effect  if(isEffectOn() && effect_type == getEffectType()) {    return;  }  effect->deleteParticles();  resetDamageEffect();  setEffectType(effect_type);  effectDuration = duration;  // need to do this to make sure effect shows up  scourge->getMap()->refresh();}/**   Get the total value of armor worn and roll for the skill of each piece.   Monsters' base armor is not rolled (ie. they're experts in using their natural armor.) */int Creature::getSkillModifiedArmor() {  // calculate the armor (0-100, 100-total protection)  int armor = (monster ? monster->getBaseArmor() : 0);  armor += bonusArmor;  for(int i = 0; i < Character::INVENTORY_COUNT; i++) {    if(equipped[i] != MAX_INVENTORY_SIZE) {      Item *item = inventory[equipped[i]];      if(item->getRpgItem()->getType() == RpgItem::ARMOR) {        int skill_index = (item->getRpgItem()->getSkill() > -1 ?                            item->getRpgItem()->getSkill() :                            Constants::HAND_DEFEND);        float skill = (float)getSkill(skill_index);        int value = item->getRpgItem()->getAction();        // add (value + ((skill-50)% of value)) to armor        armor += value + (int)( (float)value * ((skill - 50.0f) / 100.0f) );      }    }  }  return armor;}// add exp after killing a creature// only called for charactersint Creature::addExperience(Creature *creature_killed) {  int n = creature_killed->level - getLevel();  if( n < 1 ) n = 1;  float m = (float)(creature_killed->getMonster()->getHp()) / 2.0f;  int delta = n * 10 * (int)((m * rand()/RAND_MAX) + m);  return addExperience(delta);}// add n exp points// only called for charactersint Creature::addExperience(int delta) {  exp += delta;  // level up? (mark as state, with graphic over character)  if(exp >= expOfNextLevel && !getStateMod(Constants::leveled)) {    setStateMod(Constants::leveled, true);    availableSkillPoints = character->getSkillBonus();  }  return delta;}// add money after a creature is killedint Creature::addMoney(Creature *creature_killed) {  int n = creature_killed->level - getLevel();  if( n < 1 ) n = 1;  // fixme: use creature_killed->getMonster()->getMoney() instead of 100.0f  long delta = (long)n * (int)(50.0f * rand()/RAND_MAX);  money += delta;  return money;}void Creature::monsterInit() {  // equip starting inventory  for(int i = 0; i < getMonster()->getStartingItemCount(); i++) {    addInventory(scourge->newItem(getMonster()->getStartingItem(i)));    equipInventory(inventory_count - 1);  }  // add spells  for(int i = 0; i < getMonster()->getStartingSpellCount(); i++) {    addSpell(getMonster()->getStartingSpell(i));  }  // set some skills  for(int i = 0; i < Constants::SKILL_COUNT; i++) {    setSkill(i, (int)((float)(10 * level) * rand()/RAND_MAX));  }  // add some hp  //startingHp = hp = 4 + (int)((float)(10.0f * level) * rand()/RAND_MAX);  //startingMp = mp = 4 + (int)((float)(4.0f * level) * rand()/RAND_MAX);  startingHp = hp = monster->getHp() + (int)((float)(10.0f * level) * rand()/RAND_MAX);  startingMp = mp = monster->getMp() + (int)((float)(4.0f * level) * rand()/RAND_MAX);}// only for characters: leveling upbool Creature::incSkillMod(int index) {  if(!availableSkillPoints ||      getSkill(index) + skillMod[index] >= character->getMaxSkillLevel(index)) return false;  availableSkillPoints--;  skillMod[index]++;  return true;}bool Creature::decSkillMod(int index) {  if(!skillMod[index]) return false;  availableSkillPoints++;  skillMod[index]--;  return true;}void Creature::applySkillMod() {  for(int i = 0; i < Constants::SKILL_COUNT; i++) {    setSkill(i, getSkill(i) + skillMod[i]);    skillMod[i] = 0;  }  level++;  hp += character->getStartingHp();  mp += character->getStartingMp();  setStateMod(Constants::leveled, false);  availableSkillPoints = 0;  calculateExpOfNextLevel();}int Creature::getMaxHp() {  if(isMonster()) {    return monster->getHp(); // FIXME: incorrect, see monsterInit()  } else {    return(character->getStartingHp() * getLevel());  }}int Creature::getMaxMp() {  if(isMonster()) {    return monster->getMp(); // FIXME: incorrect, see monsterInit()  } else {    return(character->getStartingMp() * getLevel());  }}float Creature::getTargetAngle() {  if(!targetCreature) return -1.0f;  return Util::getAngle(getX(), getY(), getShape()->getWidth(), getShape()->getDepth(),                        getTargetCreature()->getX(), getTargetCreature()->getY(),                         getTargetCreature()->getShape()->getWidth(),                         getTargetCreature()->getShape()->getHeight());}// FIXME: O(n) but there aren't that many spells...bool Creature::isSpellMemorized(Spell *spell) {  for(int i = 0; i < (int)spells.size(); i++) {    if(spells[i] == spell) return true;  }  return false;}// FIXME: O(n) but there aren't that many spells...// return true if spell was added, false if creature already had this spellbool Creature::addSpell(Spell *spell) {   for(vector<Spell*>::iterator e = spells.begin(); e != spells.end(); ++e) {    Spell *thisSpell = *e;    if(thisSpell == spell) return false;  }  spells.push_back(spell);   return true;}void Creature::cancelTarget() {  setTargetCreature(NULL);  setTargetItem(0, 0, 0, NULL);  setDistanceRange(0, 0);  if(preActionTargetCreature) setTargetCreature(preActionTargetCreature);  preActionTargetCreature = NULL;  setAction(Constants::ACTION_NO_ACTION);  if(isMonster()) setMotion(Constants::MOTION_LOITER);     }void Creature::followTarget() {  setSelXY(getTargetX(),           getTargetY(),           true);}// FIXME: make this more intelligent: potions, spells, scrolls, etc.void Creature::decideMonsterAction() {  if(!isMonster()) return;  // does monster need to be healed?  // increase MP, AC or skill (via potion)?  Creature *p = scourge->getParty()->getClosestPlayer(getX(), getY(),                                                       getShape()->getWidth(),                                                      getShape()->getDepth(),                                                      20);  if(p) {    float dist = Constants::distance(getX(),  getY(),                                      getShape()->getWidth(), getShape()->getDepth(),                                     p->getX(), p->getY(),                                     p->getShape()->getWidth(),                                      p->getShape()->getDepth());        // can monster use magic?    if(getSpellCount()) {      /*                      FIXME:                                    Other considerations:        -heal other monsters (by spell)?        -attack by spell?        -group attack vs. single target?                For now, just assume that monsters only know attack spells         where the target can be a single creature. Later when spell        casting is smarter (by monsters) we'll need to implement some        way to classify spells (attack, help (hp+,ac+,etc.), group vs.         single target, etc.)      */      for(int i = 0; i < getSpellCount(); i++) {        Spell *spell = getSpell(i);        if(spell->getMp() < getMp()) {          if((spell->getDistance() == 1 && dist <= Constants::MIN_DISTANCE) ||             (spell->getDistance() > 1 && dist > Constants::MIN_DISTANCE)) {            setAction(Constants::ACTION_CAST_SPELL,                       NULL,                      spell);            setMotion(Constants::MOTION_MOVE_TOWARDS);            setTargetCreature(p);            return;          }        }      }    }    // attack with item    setMotion(Constants::MOTION_MOVE_TOWARDS);    setTargetCreature(p);    //setDistanceRange(0, Constants::MIN_DISTANCE);  }}float Creature::getDistanceToTarget() {  if(!hasTarget()) return 0.0f;  if(getTargetCreature()) {    return Constants::distance(getX(),  getY(),                                getShape()->getWidth(), getShape()->getDepth(),                               getTargetCreature()->getX(), getTargetCreature()->getY(),                               getTargetCreature()->getShape()->getWidth(),                                getTargetCreature()->getShape()->getDepth());  } else if(getTargetItem()) {    return Constants::distance(getX(),  getY(),                                getShape()->getWidth(), getShape()->getDepth(),                               getTargetX(), getTargetY(),                               getTargetItem()->getShape()->getWidth(),                                getTargetItem()->getShape()->getDepth());  } else {    return Constants::distance(getX(),  getY(),                                getShape()->getWidth(), getShape()->getDepth(),                               getTargetX(), getTargetY(), 1, 1);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -