📄 creature.cpp
字号:
// try again if(!(selX == getX() && selY == getY()) && map->shapeFits(getShape(), selX, selY, -1) && moveRetrycount < MAX_MOVE_RETRY) { // don't keep trying forever moveRetrycount++; tx = ty = -1; } else { // if we can't get to the destination, stop trying // do this so the animation switches to "stand" stopMoving(); } //} } } return false;}void Creature::getFormationPosition(Sint16 *px, Sint16 *py, Sint16 *pz) { Sint16 dx = layout[formation][index][0]; Sint16 dy = -layout[formation][index][1]; // get the angle float angle = 0; if(next->getDir() == Constants::MOVE_RIGHT) angle = 270.0; else if(next->getDir() == Constants::MOVE_DOWN) angle = 180.0; else if(next->getDir() == Constants::MOVE_LEFT) angle = 90.0; // rotate points if(angle != 0) { Util::rotate(dx, dy, px, py, angle); } else { *px = dx; *py = dy; } // translate // *px = (*(px) * getShape()->getWidth()) + next->getX(); // *py = (-(*(py)) * getShape()->getDepth()) + next->getY(); if(next->getSelX() > -1) { *px = (*(px) * getShape()->getWidth()) + next->getSelX(); *py = (-(*(py)) * getShape()->getDepth()) + next->getSelY(); } else { *px = (*(px) * getShape()->getWidth()) + next->getX(); *py = (-(*(py)) * getShape()->getDepth()) + next->getY(); } *pz = next->getZ();}/** Used to move away from the player. Find the nearest corner of the map.*/void Creature::findCorner(Sint16 *px, Sint16 *py, Sint16 *pz) { if(getX() < scourge->getParty()->getPlayer()->getX() && getY() < scourge->getParty()->getPlayer()->getY()) { *px = *py = *pz = 0; return; } if(getX() >= scourge->getParty()->getPlayer()->getX() && getY() < scourge->getParty()->getPlayer()->getY()) { *px = MAP_WIDTH; *py = *pz = 0; return; } if(getX() < scourge->getParty()->getPlayer()->getX() && getY() >= scourge->getParty()->getPlayer()->getY()) { *px = *pz = 0; *py = MAP_DEPTH; return; } if(getX() >= scourge->getParty()->getPlayer()->getX() && getY() >= scourge->getParty()->getPlayer()->getY()) { *px = MAP_WIDTH; *py = MAP_DEPTH; *pz = 0; return; }}void Creature::setNext(Creature *next, int index) { this->next = next; this->index = index; // stand in formation Sint16 px, py, pz; getFormationPosition(&px, &py, &pz); if(px > -1) moveTo(px, py, pz);}void Creature::setNextDontMove(Creature *next, int index) { this->next = next; this->index = index;}bool Creature::addInventory(Item *item) { if(inventory_count < MAX_INVENTORY_SIZE) { inventory[inventory_count++] = item; inventoryWeight += item->getRpgItem()->getWeight(); if(item->getRpgItem()->getWeight() + inventoryWeight > getMaxInventoryWeight()) { char msg[80]; sprintf(msg, "%s is overloaded.", getName()); scourge->getMap()->addDescription(msg); setStateMod(Constants::overloaded, true); } // check if the mission is over if(!isMonster() && scourge->getCurrentMission() && scourge->getCurrentMission()->itemFound(item->getRpgItem())) { scourge->missionCompleted(); } return true; } else{ return false; }}int Creature::findInInventory(Item *item) { for(int i = 0; i < inventory_count; i++) { Item *invItem = inventory[i]; if(item == invItem) return i; } return -1;}Item *Creature::removeInventory(int index) { Item *item = NULL; if(index < inventory_count) { // drop item if carrying it doff(index); // drop from inventory item = inventory[index]; inventoryWeight -= item->getRpgItem()->getWeight(); if(getStateMod(Constants::overloaded) && inventoryWeight < getMaxInventoryWeight()) { char msg[80]; sprintf(msg, "%s is not overloaded anymore.", getName()); scourge->getMap()->addDescription(msg); setStateMod(Constants::overloaded, false); } for(int i = index; i < inventory_count - 1; i++) { inventory[i] = inventory[i + 1]; } inventory_count--; // adjust equipped indexes too for(int i = 0; i < Character::INVENTORY_COUNT; i++) { if(equipped[i] > index && equipped[i] < MAX_INVENTORY_SIZE) { equipped[i]--; } } recalcAggregateValues(); } return item;}bool Creature::eatDrink(int index){ return eatDrink(getInventory(index));}bool Creature::eatDrink(Item *item) { char msg[500]; char buff[200]; RpgItem * rpgItem = item->getRpgItem(); int type = rpgItem->getType(); //weight = item->getRpgItem()->getWeight(); int level = rpgItem->getLevel(); if(type == RpgItem::FOOD){ if(getHunger() == 10){ sprintf(msg, "%s is not hungry at the moment.", getName()); scourge->getMap()->addDescription(msg); return false; } // TODO : the quality member of rpgItem should indicate if the // food is totally healthy or roten or partially roten etc... // We eat the item and it gives us "level" hunger points back setHunger(getHunger() + level); strcpy(buff, rpgItem->getShortDesc()); buff[0] = tolower(buff[0]); sprintf(msg, "%s eats %s.", getName(), buff); scourge->getMap()->addDescription(msg); bool b = item->decrementCharges(); if(b) { sprintf(msg, "%s is used up.", item->getItemName()); scourge->getMap()->addDescription(msg); } return b; } else if(type == RpgItem::DRINK){ if(getThirst() == 10){ sprintf(msg, "%s is not thirsty at the moment.", getName()); scourge->getMap()->addDescription(msg); return false; } setThirst(getThirst() + level); strcpy(buff, rpgItem->getShortDesc()); buff[0] = tolower(buff[0]); sprintf(msg, "%s drinks %s.", getName(), buff); scourge->getMap()->addDescription(msg); // TODO : according to the alcool rate set drunk state or not bool b = item->decrementCharges(); if(b) { sprintf(msg, "%s is used up.", item->getItemName()); scourge->getMap()->addDescription(msg); } return b; } else if(type == RpgItem::POTION) { // It's a potion // Even if not thirsty, character will always drink a potion strcpy(buff, rpgItem->getShortDesc()); buff[0] = tolower(buff[0]); setThirst(getThirst() + level); sprintf(msg, "%s drinks from %s.", getName(), buff); scourge->getMap()->addDescription(msg); usePotion(item); bool b = item->decrementCharges(); if(b) { sprintf(msg, "%s is used up.", item->getItemName()); scourge->getMap()->addDescription(msg); } return b; } else { scourge->getMap()->addDescription("You cannot eat or drink that!", 1, 0.2f, 0.2f); return false; }}void Creature::usePotion(Item *item) { // nothing to do? if(item->getRpgItem()->getPotionSkill() == -1) return; int n; char msg[255]; int skill = item->getRpgItem()->getPotionSkill(); if(skill < 0) { switch(-skill - 2) { case Constants::HP: n = item->getRpgItem()->getAction(); if(n + getHp() > getMaxHp()) n = getMaxHp() - getHp(); setHp(getHp() + n); sprintf(msg, "%s heals %d points.", getName(), n); scourge->getMap()->addDescription(msg, 0.2f, 1, 1); startEffect(Constants::EFFECT_SWIRL, (Constants::DAMAGE_DURATION * 4)); return; case Constants::MP: n = item->getRpgItem()->getAction(); if(n + getMp() > getMaxMp()) n = getMaxMp() - getMp(); setMp(getMp() + n); sprintf(msg, "%s receives %d magic points.", getName(), n); scourge->getMap()->addDescription(msg, 0.2f, 1, 1); startEffect(Constants::EFFECT_SWIRL, (Constants::DAMAGE_DURATION * 4)); return; case Constants::AC: { bonusArmor += item->getRpgItem()->getAction(); recalcAggregateValues(); sprintf(msg, "%s feels impervious to damage!", getName()); scourge->getMap()->addDescription(msg, 0.2f, 1, 1); startEffect(Constants::EFFECT_SWIRL, (Constants::DAMAGE_DURATION * 4)); // add calendar event to remove armor bonus // (format : sec, min, hours, days, months, years) Date d(0, item->getRpgItem()->getPotionTime(), 0, 0, 0, 0); Event *e = new PotionExpirationEvent(scourge->getParty()->getCalendar()->getCurrentDate(), d, this, item->getRpgItem(), scourge, 1); scourge->getParty()->getCalendar()->scheduleEvent((Event*)e); // It's important to cast!! } return; default: cerr << "Implement me! (other potion skill boost)" << endl; return; } } else { skillBonus[skill] += item->getRpgItem()->getAction(); // recalcAggregateValues(); sprintf(msg, "%s feels at peace.", getName()); scourge->getMap()->addDescription(msg, 0.2f, 1, 1); startEffect(Constants::EFFECT_SWIRL, (Constants::DAMAGE_DURATION * 4)); // add calendar event to remove armor bonus // (format : sec, min, hours, days, months, years) Date d(0, item->getRpgItem()->getPotionTime(), 0, 0, 0, 0); Event *e = new PotionExpirationEvent(scourge->getParty()->getCalendar()->getCurrentDate(), d, this, item->getRpgItem(), scourge, 1); scourge->getParty()->getCalendar()->scheduleEvent((Event*)e); // It's important to cast!! }}void Creature::setAction(int action, Item *item, Spell *spell) { this->action = action; this->actionItem = item; this->actionSpell = spell; preActionTargetCreature = getTargetCreature(); // zero the clock setLastTurn(0); char msg[80]; switch(action) { case Constants::ACTION_EAT_DRINK: sprintf(msg, "%s will consume %s.", getName(), item->getItemName()); break; case Constants::ACTION_CAST_SPELL: sprintf(msg, "%s will cast %s.", getName(), spell->getName()); break; case Constants::ACTION_NO_ACTION: // no-op preActionTargetCreature = NULL; sprintf(msg, ""); break; default: cerr << "*** Error: unknown action " << action << endl; return; } if(strlen(msg)) scourge->getMap()->addDescription(msg, 1, 1, 0.5f);}void Creature::equipInventory(int index) { // doff if(doff(index)) return; // don // FIXME: take into account: two-handed weapons, race/class modifiers, min skill req-s., etc. Item *item = getInventory(index); for(int i = 0; i < Character::INVENTORY_COUNT; i++) { // if the slot is empty and the item can be worn here if(item->getRpgItem()->getEquip() & ( 1 << i ) && equipped[i] == MAX_INVENTORY_SIZE) { equipped[i] = index; recalcAggregateValues(); return; } }}int Creature::doff(int index) { // doff for(int i = 0; i < Character::INVENTORY_COUNT; i++) { if(equipped[i] == index) { equipped[i] = MAX_INVENTORY_SIZE; recalcAggregateValues(); return 1; } } return 0;}/** Get item at equipped index. (What is at equipped location?) */Item *Creature::getEquippedInventory(int index) { int n = equipped[index]; if(n < MAX_INVENTORY_SIZE) { return getInventory(n); } return NULL;}/** Get equipped index of inventory index. (Where is the item worn?)*/int Creature::getEquippedIndex(int index) { for(int i = 0; i < Character::INVENTORY_COUNT; i++) { if(equipped[i] == index) return i; } return -1;}bool Creature::isItemInInventory(Item *item) { for(int i = 0; i < inventory_count; i++) { if(inventory[i] == item || (inventory[i]->getRpgItem()->getType() == RpgItem::CONTAINER && inventory[i]->isContainedItem(item))) return true; } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -