Exemple #1
0
void BTPc::updateSkills()
{
 BTJobList &jobList = BTGame::getGame()->getJobList();
 for (int i = 0; i < jobList[job]->skill.size(); ++i)
 {
  int value = jobList[job]->skill[i]->value;
  if ((jobList[job]->skill[i]->modifier >= 0) && (stat[jobList[job]->skill[i]->modifier] > 14))
   value += stat[jobList[job]->skill[i]->modifier] - 14;
  if (getSkill(jobList[job]->skill[i]->skill) == 0)
  {
   setSkill(jobList[job]->skill[i]->skill, value, value);
   if (jobList[job]->skill[i]->improve > 0)
   {
    for (int sk = 0; sk < skill.size(); ++sk)
    {
     if (skill[sk]->skill == jobList[job]->skill[i]->skill)
     {
      for (int k = 2; k <= level; ++k)
      {
       if ((k % jobList[job]->skill[i]->improveLevel) == 0)
       {
        unsigned int increase = BTDice(1, jobList[job]->skill[i]->improve).roll();
        if ((jobList[job]->skill[i]->modifier >= 0) && (stat[jobList[job]->skill[i]->modifier] > 14))
         increase += stat[jobList[job]->skill[i]->modifier] - 14;
        skill[sk]->value += increase;
        skill[sk]->history.push_back(increase);
       }
      }
      break;
     }
    }
   }
  }
 }
}
Exemple #2
0
int BTPc::incrementStat()
{
 int s = 0;
 int i = 0; 
 for (; i < BT_STATS; ++i)
 {
  if (stat[i] < BTSTAT_MAX)
   ++s;
 }
 if (s == 0)
  return -1;
 if (s != 1)
  s = BTDice(1, s, 0).roll();
 for (i = 0; i < BT_STATS; ++i)
 {
  if (stat[i] < BTSTAT_MAX)
  {
   --s;
   if (0 == s)
   {
    ++stat[i];
    if (statMax[i] < BTSTAT_MAX)
     ++statMax[i];
    if ((i == BTSTAT_LK) && (stat[i] > 14))
     ++save;
    if ((i == BTSTAT_DX) && (stat[i] > 14))
     ++ac;
    return i;
   }
  }
 }
 return -1; // Can't get here
}
Exemple #3
0
bool BTPc::savingThrow(int difficulty /*= BTSAVE_DIFFICULTY*/) const
{
 int roll = BTDice(1, 20, save).roll();
 if (roll == 20 + save)
  return true;
 else if (roll == 1 + save)
  return false;
 else
  return (roll >= difficulty);
}
Exemple #4
0
bool BTPc::drainItem(BTDisplay &d, int amount)
{
 BTFactory<BTItem> &itemList = BTGame::getGame()->getItemList();
 int numItems = 0;
 for (numItems = 0; numItems < BT_ITEMS; ++numItems)
 {
  if (BTITEM_NONE == item[numItems].id)
   break;
 }
 if (numItems == 0)
  return false;
 int i = BTDice(1, numItems, -1).roll();
 if ((item[i].equipped == BTITEM_EQUIPPED) && (BTITEM_ARROW != itemList[item[i].id].getType()) && (BTITEM_BOW != itemList[item[i].id].getType()) && (BTITEM_THROWNWEAPON != itemList[item[i].id].getType()) && (BTITEMCAST_NONE != itemList[item[i].id].getSpellCast()) && (0 < item[i].charges))
 {
  takeItemCharge(d, i, amount);
  return true;
 }
 return false;
}
Exemple #5
0
void BTPc::changeJob(int newJob)
{
 XMLVector<BTJob*> &jobList = BTGame::getGame()->getJobList();
 toHit += jobList[newJob]->toHit - jobList[job]->toHit - ((level - 1) / jobList[job]->improveToHit);
 save += jobList[newJob]->save - jobList[job]->save - ((level - 1) / jobList[job]->improveSave);
 ac += jobList[newJob]->ac - jobList[job]->ac;
 if (jobList[job]->improveAc != 0)
  ac -= ((level - 1) / jobList[job]->improveAc);
 job = newJob;
 if (gender == BTGENDER_FEMALE)
  picture = jobList[newJob]->femalePicture;
 else
  picture = jobList[newJob]->malePicture;
 int moreHp = BTDice(1, jobList[job]->hp).roll() + ((stat[BTSTAT_CN] > 14) ? stat[BTSTAT_CN] - 14 : 0);
 hp += moreHp;
 maxHp += moreHp;
 {
  for (int i = 0; i < skill.size(); ++i)
  {
   skill[i]->history.clear();
  }
 }
 for (int k = 0; k < jobList[newJob]->skill.size(); ++k)
 {
  bool found(false);
  for (int i = 0; i < skill.size(); ++i)
  {
   if (skill[i]->skill == jobList[newJob]->skill[k]->skill)
   {
    if ((jobList[newJob]->skill[k]->value == 0) && (jobList[newJob]->skill[k]->improve == 0))
    {
     skill.erase(skill.begin() + i);
    }
    else
    {
     skill[i]->value = jobList[newJob]->skill[k]->value;
     if ((jobList[newJob]->skill[k]->modifier >= 0) && (stat[jobList[newJob]->skill[k]->modifier] > 14))
      skill[i]->value += stat[jobList[newJob]->skill[k]->modifier] - 14;
    }
    found = true;
    break;
   }
  }
  if ((!found) && ((jobList[newJob]->skill[k]->value != 0) || (jobList[newJob]->skill[k]->improve != 0)))
  {
   BTSkillValue *value = new BTSkillValue;
   value->skill = jobList[newJob]->skill[k]->skill;
   value->value = jobList[newJob]->skill[k]->value;
   if ((jobList[newJob]->skill[k]->modifier >= 0) && (stat[jobList[newJob]->skill[k]->modifier] > 14))
    value->value += stat[jobList[newJob]->skill[k]->modifier] - 14;
   skill.push_back(value);
  }
 }
 if (jobList[newJob]->spells)
 {
  int moreSp = BTDice(1, 4).roll() + ((stat[BTSTAT_IQ] > 14) ? stat[BTSTAT_IQ] - 14 : 0);
  if (maxSp == 0)
   moreSp = BTDice(1, 8, 9).roll() + ((stat[BTSTAT_IQ] > 14) ? stat[BTSTAT_IQ] - 14 : 0);
  sp += moreSp;
  maxSp += moreSp;
 }
 maxLevel = level = 1;
 xp = 0;
}
Exemple #6
0
bool BTPc::advanceLevel()
{
 BTJobList &jobList = BTGame::getGame()->getJobList();
 BTXpChartList &xpChartList = BTGame::getGame()->getXpChartList();
 if (jobList[job]->xpChart != -1)
 {
  if (xp >= xpChartList[jobList[job]->xpChart]->getXpNeeded(level))
  {
   ++level;
   if (((level - 1) % jobList[job]->improveToHit) == 0)
    ++toHit;
   if ((jobList[job]->improveRateAttacks) && (level - 1 < ((jobList[job]->maxRateAttacks - 1) * jobList[job]->improveRateAttacks) + 1) && (((level - 1) % jobList[job]->improveRateAttacks) == 0))
   {
    ++rateAttacks;
   }
   if (((level - 1) % jobList[job]->improveSave) == 0)
    ++save;
   if ((jobList[job]->improveAc) && (((level - 1) % jobList[job]->improveAc) == 0))
    ++ac;
   if (level > maxLevel)
   {
    int moreHp = BTDice(1, jobList[job]->hp).roll() + ((stat[BTSTAT_CN] > 14) ? stat[BTSTAT_CN] - 14 : 0);
    hp += moreHp;
    maxHp += moreHp;
    for (int i = 0; i < jobList[job]->skill.size(); ++i)
    {
     if ((jobList[job]->skill[i]->improve > 0) && ((level % jobList[job]->skill[i]->improveLevel) == 0))
     {
      for (int k = 0; k < skill.size(); ++k)
      {
       if (skill[k]->skill == jobList[job]->skill[i]->skill)
       {
        unsigned int increase = BTDice(1, jobList[job]->skill[i]->improve).roll();
        if ((jobList[job]->skill[i]->modifier >= 0) && (stat[jobList[job]->skill[i]->modifier] > 14))
         increase += stat[jobList[job]->skill[i]->modifier] - 14;
        skill[k]->value += increase;
        skill[k]->history.push_back(increase);
        break;
       }
      }
     }
    }
    if (jobList[job]->spells)
    {
     int moreSp = BTDice(1, 4).roll() + ((stat[BTSTAT_IQ] > 14) ? stat[BTSTAT_IQ] - 14 : 0);
     sp += moreSp;
     maxSp += moreSp;
    }
    maxLevel = level;
   }
   else
   {
    for (int k = 0; k < skill.size(); ++k)
    {
     if (skill[k]->history.size() >= level - 1)
     {
      skill[k]->value += skill[k]->history[level - 2];
     }
    }
   }
   return true;
  }
 }
 return false;
}
Exemple #7
0
std::string BTCombatant::attack(BTCombatant *defender, bool melee, const std::string &cause, const std::string &effect, const BTDice &damageDice, IShort chanceXSpecial, IShort xSpecial, int &numAttacksLeft, int &activeNum, int toHitBonus /*= 0*/)
{
 int hits = 0;
 int totalDamage = 0;
 bool dead = false;
 bool totalDrain = false;
 BitField finalSpecial;
 while ((defender->isAlive()) && (numAttacksLeft > 0))
 {
  int roll = BTDice(1, 20).roll();
  if ((1 != roll) && ((20 == roll) || (roll + toHit + toHitBonus >= defender->ac)))
  {
   ++hits;
   int damage = 0;
   BitField special;
   damage = damageDice.roll();
   for (int i = 0; i < dmgBonus.size(); i++)
    damage += dmgBonus[i]->apply(melee);
   if ((BTEXTRADAMAGE_NONE != xSpecial) && (BTDice(1, 100).roll() <= chanceXSpecial))
    special.set(xSpecial);
   if (damage < 0)
    damage = 0;
   totalDamage += damage;
   if (defender->takeHP(damage))
   {
    dead = true;
    defender->deactivate(activeNum);
   }
   else
   {
    useAutoCombatSkill(melee, special);
    int maxSpecial = special.getMaxSet();
    if (maxSpecial > -1)
    {
     std::string specialText;
     for (int i = 0; i <= maxSpecial; ++i)
     {
      if (!special.isSet(i))
       continue;
      if (defender->savingThrow(BTSAVE_DIFFICULTY))
      {
       special.clear(i);
       continue;
      }
      switch(i)
      {
       case BTEXTRADAMAGE_POISON:
        defender->status.set(BTSTATUS_POISONED);
        break;
       case BTEXTRADAMAGE_LEVELDRAIN:
        if (defender->drainLevel())
        {
         totalDrain = true;
         defender->deactivate(activeNum);
        }
        break;
       case BTEXTRADAMAGE_INSANITY:
        defender->status.set(BTSTATUS_INSANE);
        break;
       case BTEXTRADAMAGE_AGED:
        if (defender->age())
        {
         defender->deactivate(activeNum);
        }
        break;
       case BTEXTRADAMAGE_POSSESSION:
        defender->status.set(BTSTATUS_POSSESSED);
        break;
       case BTEXTRADAMAGE_PARALYSIS:
        defender->status.set(BTSTATUS_PARALYZED);
        break;
       case BTEXTRADAMAGE_STONED:
        defender->status.set(BTSTATUS_STONED);
        defender->deactivate(activeNum);
        break;
       case BTEXTRADAMAGE_CRITICALHIT:
        defender->status.set(BTSTATUS_DEAD);
        defender->deactivate(activeNum);
        break;
       case BTEXTRADAMAGE_ITEMZOT:
        if (!defender->drainItem(5))
        {
         special.clear(BTEXTRADAMAGE_ITEMZOT);
        }
        break;
       case BTEXTRADAMAGE_POINTPHAZE:
        if (!defender->takeSP(5))
        {
         special.clear(BTEXTRADAMAGE_POINTPHAZE);
        }
        break;
       default:
        break;
      }
     }
     finalSpecial |= special;
    }
   }
  }
  --numAttacksLeft;
 }
 std::string text = getName();
 text += " ";
 text += cause;
 text += " ";
 std::string defenderName;
 text += defenderName = defender->getName();
 if (0 < hits)
 {
  text += " ";
  text += effect;
  text += " ";
  char tmp[20];
  if (hits > 1)
  {
   sprintf(tmp, "%d", hits);
   text += tmp;
   text += " times ";
  }
  text += "for ";
  sprintf(tmp, "%d", totalDamage);
  text += tmp;
  text += " points of damage";
  if (dead)
  {
   text += ", killing ";
   text += genderPronouns[defender->getGender()];
  }
  else
  {
   int maxSpecial = finalSpecial.getMaxSet();
   if (maxSpecial > -1)
   {
    std::string specialText;
    for (int i = 0; i <= maxSpecial; ++i)
    {
     if (!finalSpecial.isSet(i))
      continue;
     if ((specialText == "") || (maxSpecial == i))
      specialText += " and";
     else
      specialText += ",";
     switch(i)
     {
      case BTEXTRADAMAGE_POISON:
       specialText += " poisons";
       break;
      case BTEXTRADAMAGE_LEVELDRAIN:
       specialText += " drains a level from ";
       specialText += defenderName;
       if (totalDrain)
       {
        specialText += " totally draining ";
        specialText += genderPronouns[defender->getGender()];
       }
       break;
      case BTEXTRADAMAGE_INSANITY:
       specialText += " inflicts insanity";
       break;
      case BTEXTRADAMAGE_AGED:
       specialText += " withers ";
        specialText += genderPronouns[defender->getGender()];
       break;
      case BTEXTRADAMAGE_POSSESSION:
       specialText += " possesses";
       break;
      case BTEXTRADAMAGE_PARALYSIS:
       specialText += " paralyzes";
       break;
      case BTEXTRADAMAGE_STONED:
       specialText += " stones";
       break;
      case BTEXTRADAMAGE_CRITICALHIT:
       specialText += " critically hits";
       break;
      case BTEXTRADAMAGE_ITEMZOT:
       specialText += " drains an item";
       break;
      case BTEXTRADAMAGE_POINTPHAZE:
       specialText += " absorbs spell points";
       break;
      default:
       break;
     }
    }
    text += specialText;
   }
  }
  if (defender->isAlive())
   text += ".";
  else
   text += "!";
 }
 else
  text += ", but misses!";
 return text;
}
Exemple #8
0
void BTCombatant::rollInitiative()
{
 initiative = BTDice(1, 20).roll() + (level / 2);
}