void BTPc::deactivateItems(BTDisplay &d) { BTGame *game = BTGame::getGame(); BTParty &party = game->getParty(); int pc = party.find(this); BTFactory<BTItem> &itemList = game->getItemList(); BTFactory<BTSpell, BTSpell1> &spellList = game->getSpellList(); int numItems = 0; for (numItems = 0; numItems < BT_ITEMS; ++numItems) { if (BTITEM_NONE == item[numItems].id) break; if (BTITEM_EQUIPPED != item[numItems].equipped) continue; if (BTTIMESUSABLE_CONTINUOUS == item[numItems].charges) { int effectID = item[numItems].effectID; if (effectID != BTEFFECTID_NONE) { game->clearEffectsByEffectID(d, effectID); item[numItems].effectID = BTEFFECTID_NONE; } } } }
void BTPc::equip(BTDisplay &d, int index) { BTFactory<BTItem> &itemList = BTGame::getGame()->getItemList(); BTParty &party = BTGame::getGame()->getParty(); int pc = party.find(this); int type = itemList[item[index].id].getType(); for (int i = 0; i < BT_ITEMS; ++i) { if (BTITEM_NONE == item[i].id) break; if ((item[i].equipped == BTITEM_EQUIPPED) && (type == itemList[item[i].id].getType())) { unequip(d, i); } } ac += itemList[item[index].id].getArmorPlus(); toHit += itemList[item[index].id].getHitPlus(); item[index].equipped = BTITEM_EQUIPPED; if (BTTIMESUSABLE_CONTINUOUS == item[index].charges) { BTGame *game = BTGame::getGame(); BTFactory<BTSpell, BTSpell1> &spellList = BTGame::getGame()->getSpellList(); int spellCast = itemList[item[index].id].getSpellCast(); int effectID = item[index].effectID; if ((effectID != BTEFFECTID_NONE) && (!game->hasEffectID(effectID))) effectID = BTEFFECTID_NONE; if (effectID == BTEFFECTID_NONE) { item[index].effectID = effectID = game->nextEffectID(); spellList[spellCast].silentActivate(d, pc, effectID, level); } } }
void BTFacingIcon::draw(BTBackgroundAndScreen &d, unsigned long ticks) { bool oldActive = active; BTIcon::draw(d, ticks); if (active) { int xMult, yMult; SDL_Rect dst; BTGame *g = BTGame::getGame(); int newFacing = g->getFacing(); if (newFacing != facing) { d.getDisplay()->getMultiplier(xMult, yMult); dst.x = position.x * xMult; dst.y = position.y * yMult; dst.w = position.w * xMult; dst.h = position.h * yMult; if (dirAni[facing].animation) d.removeAnimation(&dirAni[facing]); d.clear(dst); if (animation.animation) d.drawImage(animation.animation->frame[animation.frame], animation.dst); else { d.drawImage(img, dst); } facing = newFacing; if ((NULL == dirImg[facing]) && (NULL == dirAni[facing].animation)) { const char *period = strrchr(image, '.'); std::string filename(image, period - image); filename.append(1, '0' + facing); filename += period; d.getDisplay()->loadImageOrAnimation(filename.c_str(), &dirImg[facing], &dirAni[facing].animation, false); } if (dirImg[facing]) d.drawImage(dirImg[facing], dst); else { IMG_SetAnimationState(&dirAni[facing], -1, 0); dirAni[facing].dst = dst; d.addAnimation(&dirAni[facing]); } } } else { if (oldActive) { d.removeAnimation(&dirAni[facing]); } facing = -1; } }
void BTPc::useAutoCombatSkill(bool melee, BitField &special) { BTGame *game = BTGame::getGame(); BTSkillList &skillList = game->getSkillList(); for (int i = 0; i < skillList.size(); ++i) { if ((skillList[i]->use == BTSKILLUSE_AUTOCOMBAT) || ((melee) && (skillList[i]->use == BTSKILLUSE_AUTOCOMBATMELEE)) || ((!melee) && (skillList[i]->use == BTSKILLUSE_AUTOCOMBATRANGED))) { if (((-1 == skillList[i]->after) || (combat.skillUsed == skillList[i]->after)) && (useSkill(i))) { special.set(skillList[i]->effect); } } } }
bool BTPc::equip(BTDisplay &d, int index) { BTItemSlotList &itemSlotList = BTGame::getGame()->getItemSlotList(); BTItemTypeList &itemTypeList = BTGame::getGame()->getItemTypeList(); BTFactory<BTItem> &itemList = BTGame::getGame()->getItemList(); BTParty &party = BTGame::getGame()->getParty(); int pc = party.find(this); int type = itemList[item[index].id].getType(); int itemSlot = itemTypeList[type]->itemSlot; int numberSlots = itemSlotList[itemSlot]->number; int usedSlots = 0; for (int i = 0; i < BT_ITEMS; ++i) { if (BTITEM_NONE == item[i].id) break; if ((item[i].equipped == BTITEM_EQUIPPED) && (itemSlot == itemTypeList[itemList[item[i].id].getType()]->itemSlot)) { if (numberSlots == 1) unequip(d, i); else usedSlots++; } } if (usedSlots >= numberSlots) return false; ac += itemList[item[index].id].getArmorPlus(); if (itemTypeList[itemList[item[index].id].getType()]->toHitBonus == BTTOHITBONUS_ALWAYS) toHit += itemList[item[index].id].getHitPlus(); item[index].equipped = BTITEM_EQUIPPED; if (BTTIMESUSABLE_CONTINUOUS == item[index].charges) { BTGame *game = BTGame::getGame(); BTFactory<BTSpell, BTSpell1> &spellList = BTGame::getGame()->getSpellList(); int spellCast = itemList[item[index].id].getSpellCast(); int effectID = item[index].effectID; if ((effectID != BTEFFECTID_NONE) && (!game->hasEffectID(effectID))) effectID = BTEFFECTID_NONE; if (effectID == BTEFFECTID_NONE) { item[index].effectID = effectID = game->nextEffectID(); spellList[spellCast].silentActivate(d, pc, effectID, level); } } return true; }
void BTParty::giveItem(int itemID, BTDisplay &d) { BTGame *game = BTGame::getGame(); int who = 0; int charges = game->getItemList()[itemID].getTimesUsable(); for (; who < size(); ++who) { if ((*this)[who]->giveItem(itemID, true, charges)) break; } char tmp[100]; if (who < size()) { snprintf(tmp, 100, "%s gets %s.", (*this)[who]->name, game->getItemList()[itemID].getName().c_str()); } else { snprintf(tmp, 100, "No one has room for %s!", game->getItemList()[itemID].getName().c_str()); } d.drawText(tmp); }
void BTPc::activateItems(BTDisplay &d) { BTGame *game = BTGame::getGame(); BTParty &party = game->getParty(); int pc = party.find(this); BTFactory<BTItem> &itemList = game->getItemList(); BTFactory<BTSpell, BTSpell1> &spellList = game->getSpellList(); int numItems = 0; for (numItems = 0; numItems < BT_ITEMS; ++numItems) { if (BTITEM_NONE == item[numItems].id) break; if (BTITEM_EQUIPPED != item[numItems].equipped) continue; if (BTTIMESUSABLE_CONTINUOUS == item[numItems].charges) { int spellCast = itemList[item[numItems].id].getSpellCast(); if (spellCast != BTITEMCAST_NONE) { int effectID = item[numItems].effectID; if ((effectID != BTEFFECTID_NONE) && (!game->hasEffectID(effectID))) effectID = BTEFFECTID_NONE; if (effectID == BTEFFECTID_NONE) { item[numItems].effectID = effectID = game->nextEffectID(); spellList[spellCast].silentActivate(d, pc, effectID, level); } } } } }
bool BTPc::hasTag(const std::string &t) const { BTGame *game = BTGame::getGame(); if (t[0] == '!') return !hasTag(t.c_str() + 1); bool answer = (std::find<>(tag.begin(), tag.end(), t) != tag.end()); if (answer) return answer; if (monster != BTMONSTER_NONE) { BTFactory<BTMonster> &monList = game->getMonsterList(); return monList[monster].hasTag(t); } else { if (0 == t.compare(genderNames[gender])) return true; if (0 == t.compare(game->getRaceList()[race]->name)) return true; if (0 == t.compare(game->getJobList()[job]->name)) return true; } return false; }
std::string BTPc::attack(BTCombatant *defender, int weapon, int &numAttacksLeft, int &activeNum) { BTGame *game = BTGame::getGame(); BTFactory<BTItem> &itemList = game->getItemList(); BTFactory<BTMonster> &monList = game->getMonsterList(); BTDice damageDice(1, 2); IShort chanceXSpecial(0); IShort xSpecial(BTEXTRADAMAGE_NONE); bool melee = true; if (-1 == weapon) { if (BTMONSTER_NONE != monster) { damageDice = monList[monster].getMeleeDamage(); chanceXSpecial = 100; xSpecial = monList[monster].getMeleeExtra(); } else { XMLVector<BTSkill*> &skill = game->getSkillList(); for (int i = 0; i < skill.size(); ++i) { if ((skill[i]->special == BTSKILLSPECIAL_BAREHANDS) && (hasSkillUse(i))) { BTDice *skillDice = skill[i]->getRoll(getSkill(i)); if (skillDice) damageDice = *skillDice; break; } } } } else { BTItem &itemWeapon = itemList[weapon]; damageDice = itemWeapon.getDamage(); chanceXSpecial = itemWeapon.getChanceXSpecial(); xSpecial = itemWeapon.getXSpecial(); if ((BTITEM_ARROW == itemWeapon.getType()) || (BTITEM_THROWNWEAPON == itemWeapon.getType())) melee = false; } if (stat[BTSTAT_ST] > 14) damageDice.setModifier(damageDice.getModifier() + stat[BTSTAT_ST] - 14); std::string cause; std::string effect; if (-1 == weapon) { if (BTMONSTER_NONE == monster) { cause = "punches at"; effect = "and strikes"; } else { cause = monList[monster].getMeleeMessage(); effect = "and hits"; } } else { BTItem &itemWeapon = itemList[weapon]; cause = itemWeapon.getCause(); effect = itemWeapon.getEffect(); if ((effect.length() >= 4) && (0 == strcmp(effect.c_str() + effect.length() - 4, " for"))) effect.resize(effect.length() - 4); } return BTCombatant::attack(defender, melee, cause, effect, damageDice, chanceXSpecial, xSpecial, numAttacksLeft, activeNum); }
bool BTParty::checkDead(BTDisplay &d) { int restDead = size(); int who; for (who = size() - 1; who >= 0; --who) { if (operator[](who)->status.isSet(BTSTATUS_DEAD)) { operator[](who)->initiative = BTINITIATIVE_INACTIVE; restDead = who; } else break; } if (restDead == 0) return true; BTGame *game = BTGame::getGame(); for (who = 0; who < restDead; ) { if (operator[](who)->status.isSet(BTSTATUS_DEAD)) { game->movedPlayer(d, who, size() - 1); BTPc *pc = operator[](who); pc->initiative = BTINITIATIVE_INACTIVE; erase(begin() + who); push_back(pc); --restDead; } else { operator[](who)->initiative = BTINITIATIVE_ACTIVE; ++who; } } int restStoned = restDead; for (who = restStoned - 1; who >= 0; --who) { if (operator[](who)->status.isSet(BTSTATUS_STONED)) { operator[](who)->initiative = BTINITIATIVE_INACTIVE; restStoned = who; } else break; } if (restStoned == 0) return true; for (who = 0; who < restStoned; ) { if (operator[](who)->status.isSet(BTSTATUS_STONED)) { game->movedPlayer(d, who, restStoned - 1); BTPc *pc = operator[](who); pc->initiative = BTINITIATIVE_INACTIVE; erase(begin() + who); if (size() == restStoned - 1) push_back(pc); else insert(begin() + restStoned, pc); --restStoned; } else { operator[](who)->initiative = BTINITIATIVE_ACTIVE; ++who; } } return false; }