//********************************************************************* // realmResistPet //********************************************************************* bool Creature::checkResistPet(Creature *pet, bool& resistPet, bool& immunePet, bool& vulnPet) { if(!pet->isPet()) return(false); bstring realm = getRealmSpellName(pet->getAsConstMonster()->getBaseRealm()); resistPet = isEffected("resist-" + realm); immunePet = isEffected("immune-" + realm); vulnPet = isEffected("vuln-" + realm); return(true); }
int Creature::checkRealmResist(int dmg, Realm realm) const { bstring resistEffect = "resist-" + getRealmSpellName(realm); if(isEffected(resistEffect)) dmg /= 2; bstring immuneEffect = "immune-" + getRealmSpellName(realm); if(isEffected(immuneEffect)) dmg = 1; bstring vulnEffect = "vuln-" + getRealmSpellName(realm); if(isEffected(vulnEffect)) dmg = dmg + (dmg / 2); return(dmg); }
int Creature::displayFlags() const { int flags = 0; if(isEffected("detect-invisible")) flags |= INV; if(isEffected("detect-magic")) flags |= MAG; if(isEffected("true-sight")) flags |= MIST; if(isPlayer()) { if(cClass == CreatureClass::BUILDER) flags |= ISBD; if(cClass == CreatureClass::CARETAKER) flags |= ISCT; if(isDm()) flags |= ISDM; if(flagIsSet(P_NO_NUMBERS)) flags |= NONUM; } return(flags); }
void emitStatement(refObject term, set wraps) // PRE EMIT. Write an open brace if needed. { void preEmit(int hook) { if (isInSet(hook, wraps)) { writeChar(target, '{'); }} // POST EMIT. Write a close brace if needed. void postEmit(int hook) { if (isInSet(hook, wraps)) { writeChar(target, '}'); }} // Dispatch to an appropriate case based on TERM's outer hook. if (isPair(term)) { switch (toHook(car(term))) // Write C code for a CASE clause. { case caseHook: { refObject subterm; preEmit(caseHook); term = cdr(term); writeFormat(target, "switch"); writeChar(target, '('); emitExpression(car(term), 13); writeChar(target, ')'); writeChar(target, '{'); term = cdr(term); while (cdr(term) != nil) { emitLabels(car(term)); term = cdr(term); subterm = car(term); if (isEffected(subterm)) { emitStatement(subterm, withSet); } writeFormat(target, "break"); writeChar(target, ';'); term = cdr(term); } subterm = car(term); if (isEffected(subterm)) { writeFormat(target, "default"); writeChar(target, ':'); emitStatement(subterm, withSet); } writeChar(target, '}'); postEmit(caseHook); break; } // Write C code for an IF clause. case ifHook: { refObject subterm; preEmit(ifHook); term = cdr(term); while (true) { writeFormat(target, "if"); writeChar(target, '('); emitExpression(car(term), 13); writeChar(target, ')'); term = cdr(term); subterm = car(term); if (isEffected(subterm)) { emitStatement(subterm, ifLastWithSet); } else { writeChar(target, ';'); } term = cdr(term); if (cdr(term) == nil) { subterm = car(term); if (isEffected(subterm)) { writeFormat(target, "else"); writeBlank(target); if (isCar(subterm, ifHook)) { term = cdr(subterm); } else { emitStatement(subterm, lastWithSet); break; }} else { break; }} else { writeFormat(target, "else"); writeBlank(target); }} postEmit(ifHook); break; } // Write C code for a LAST clause. case lastHook: { refObject subterm; preEmit(lastHook); term = cdr(term); while (term != nil) { subterm = car(term); if (isEffected(subterm)) { emitStatement(subterm, withSet); } term = cdr(term); } postEmit(lastHook); break; } // Write C code for a WHILE clause. case whileHook: { preEmit(whileHook); term = cdr(term); writeFormat(target, "while"); writeChar(target, '('); emitExpression(car(term), 13); writeChar(target, ')'); term = cadr(term); if (isEffected(term)) { emitStatement(term, lastWithSet); } else { writeChar(target, ';'); } postEmit(whileHook); break; } // Write C code for a WITH clause. case withHook: { refObject frame; preEmit(withHook); term = cdr(term); frame = car(term); term = cdr(term); if (frame == nil) { emitVariableDeclarations(term); emitFunctionDefinitions(true, term); emitVariableDefinitions(nil, term); term = car(lastPair(term)); if (isEffected(term)) { emitStatement(term, withSet); }} else { emitFrameDeclaration(frame, term); emitVariableDeclarations(term); emitFunctionDefinitions(true, term); emitFramePush(frame, frameLength(term)); emitFrameInitialization(frame, term); emitVariableDefinitions(frame, term); term = car(lastPair(term)); if (isEffected(term)) { emitStatement(term, withSet); } emitFramePop(frame); } postEmit(withHook); break; } // Other TERMs become C expressions. default: { if (isEffected(term)) { emitExpression(term, 13); writeChar(target, ';'); } break; }}} else { if (isEffected(term)) { emitExpression(term, 13); writeChar(target, ';'); }}}
int Player::displayCreature(Creature* target) { int percent=0, align=0, rank=0, chance=0, flags = displayFlags(); Player *pTarget = target->getAsPlayer(); Monster *mTarget = target->getAsMonster(); std::ostringstream oStr; bstring str = ""; bool space=false; if(mTarget) { oStr << "You see " << mTarget->getCrtStr(this, flags, 1) << ".\n"; if(mTarget->getDescription() != "") oStr << mTarget->getDescription() << "\n"; else oStr << "There is nothing special about " << mTarget->getCrtStr(this, flags, 0) << ".\n"; if(mTarget->getMobTrade()) { rank = mTarget->getSkillLevel()/10; oStr << "^y" << mTarget->getCrtStr(this, flags | CAP, 0) << " is a " << get_trade_string(mTarget->getMobTrade()) << ". " << mTarget->upHisHer() << " skill level: " << get_skill_string(rank) << ".^x\n"; } } else if(pTarget) { oStr << "You see " << pTarget->fullName() << " the " << gConfig->getRace(pTarget->getDisplayRace())->getAdjective(); // will they see through the illusion? if(willIgnoreIllusion() && pTarget->getDisplayRace() != pTarget->getRace()) oStr << " (" << gConfig->getRace(pTarget->getRace())->getAdjective() << ")"; oStr << " " << pTarget->getTitle() << ".\n"; if(gConfig->getCalendar()->isBirthday(pTarget)) { oStr << "^yToday is " << pTarget->getCName() << "'s birthday! " << pTarget->upHeShe() << " is " << pTarget->getAge() << " years old.^x\n"; } if(pTarget->description != "") oStr << pTarget->description << "\n"; } if(target->isEffected("vampirism")) { chance = intelligence.getCur()/10 + piety.getCur()/10; // vampires and werewolves can sense each other if(isEffected("vampirism") || isEffected("lycanthropy")) chance = 101; if(chance > mrand(0,100)) { switch(mrand(1,4)) { case 1: oStr << target->upHeShe() << " looks awfully pale.\n"; break; case 2: oStr << target->upHeShe() << " has an unearthly presence.\n"; break; case 3: oStr << target->upHeShe() << " has hypnotic eyes.\n"; break; default: oStr << target->upHeShe() << " looks rather pale.\n"; } } } if(target->isEffected("lycanthropy")) { chance = intelligence.getCur()/10 + piety.getCur()/10; // vampires and werewolves can sense each other if(isEffected("vampirism") || isEffected("lycanthropy")) chance = 101; if(chance > mrand(0,100)) { switch(mrand(1,3)) { case 1: oStr << target->upHeShe() << " looks awfully shaggy.\n"; break; case 2: oStr << target->upHeShe() << " has a feral presence.\n"; break; default: oStr << target->upHeShe() << " looks rather shaggy.\n"; } } } if(target->isEffected("slow")) oStr << target->upHeShe() << " is moving very slowly.\n"; else if(target->isEffected("haste")) oStr << target->upHeShe() << " is moving unnaturally quick.\n"; if((cClass == CreatureClass::CLERIC && deity == JAKAR && level >=7) || isCt()) oStr << "^y" << target->getCrtStr(this, flags | CAP, 0 ) << " is carrying " << target->coins[GOLD] << " gold coin" << (target->coins[GOLD] != 1 ? "s" : "") << ".^x\n"; if(isEffected("know-aura") || cClass==CreatureClass::PALADIN) { space = true; oStr << target->getCrtStr(this, flags | CAP, 0) << " "; align = target->getAdjustedAlignment(); switch(align) { case BLOODRED: oStr << "has a blood red aura."; break; case REDDISH: oStr << "has a reddish aura."; break; case PINKISH: oStr << "has a pinkish aura."; break; case NEUTRAL: oStr << "has a grey aura."; break; case LIGHTBLUE: oStr << "has a light blue aura."; break; case BLUISH: oStr << "has a bluish aura."; break; case ROYALBLUE: oStr << "has a royal blue aura."; break; default: oStr << "has a grey aura."; break; } } if(mTarget && mTarget->getRace()) { if(space) oStr << " "; space = true; oStr << mTarget->upHeShe() << " is ^W" << gConfig->getRace(mTarget->getRace())->getAdjective().toLower() << "^x."; } if(target->getSize() != NO_SIZE) { if(space) oStr << " "; space = true; oStr << target->upHeShe() << " is ^W" << getSizeName(target->getSize()) << "^x."; } if(space) oStr << "\n"; if(target->hp.getCur() > 0 && target->hp.getMax()) percent = (100 * (target->hp.getCur())) / (target->hp.getMax()); else percent = -1; if(!(mTarget && mTarget->flagIsSet(M_UNKILLABLE))) { oStr << target->upHeShe(); if(percent >= 100 || !target->hp.getMax()) oStr << " is in excellent condition.\n"; else if(percent >= 90) oStr << " has a few scratches.\n"; else if(percent >= 75) oStr << " has some small wounds and bruises.\n"; else if(percent >= 60) oStr << " is wincing in pain.\n"; else if(percent >= 35) oStr << " has quite a few wounds.\n"; else if(percent >= 20) oStr << " has some big nasty wounds and scratches.\n"; else if(percent >= 10) oStr << " is bleeding awfully from big wounds.\n"; else if(percent >= 5) oStr << " is barely clinging to life.\n"; else if(percent >= 0) oStr << " is nearly dead.\n"; } if(pTarget) { if(pTarget->isEffected("mist")) { oStr << pTarget->upHeShe() << "%s is currently in mist form.\n"; printColor("%s", oStr.str().c_str()); return(0); } if(pTarget->flagIsSet(P_UNCONSCIOUS)) oStr << pTarget->getName() << " is " << (pTarget->flagIsSet(P_SLEEPING) ? "sleeping" : "unconscious") << ".\n"; if(pTarget->isEffected("petrification")) oStr << pTarget->getName() << " is petrified.\n"; if(pTarget->isBraindead()) oStr << pTarget->getName() << "%M is currently brain dead.\n"; } else { if(mTarget->isEnemy(this)) oStr << mTarget->upHeShe() << " looks very angry at you.\n"; else if(mTarget->getPrimeFaction() != "") oStr << mTarget->upHeShe() << " " << getFactionMessage(mTarget->getPrimeFaction()) << ".\n"; Creature* firstEnm = nullptr; if((firstEnm = mTarget->getTarget(false)) != nullptr) { if(firstEnm == this) { if( !mTarget->flagIsSet(M_HIDDEN) && !(mTarget->isInvisible() && isEffected("detect-invisible"))) oStr << mTarget->upHeShe() << " is attacking you.\n"; } else oStr << mTarget->upHeShe() << " is attacking " << firstEnm->getName() << ".\n"; /// print all the enemies if a CT or DM is looking if(isCt()) oStr << mTarget->threatTable; } oStr << consider(mTarget); // pet code if(mTarget->isPet() && mTarget->getMaster() == this) { str = mTarget->listObjects(this, true); oStr << mTarget->upHeShe() << " "; if(str == "") oStr << "isn't holding anything.\n"; else oStr << "is carrying: " << str << ".\n"; } } printColor("%s", oStr.str().c_str()); target->printEquipList(this); return(0); }
bool Creature::doFlee(bool magicTerror) { Monster* mThis = getAsMonster(); Player* pThis = getAsPlayer(); BaseRoom* oldRoom = getRoomParent(), *newRoom=0; UniqueRoom* uRoom=0; Exit* exit=0; unsigned int n=0; if(isEffected("fear")) magicTerror = true; exit = getFleeableExit(); if(!exit) { printColor("You couldn't find any place to run to!\n"); if(pThis) pThis->setFleeing(false); return(0); } newRoom = getFleeableRoom(exit); if(!newRoom) { printColor("You failed to escape!\n"); return(0); } switch(mrand(1,10)) { case 1: print("You run like a chicken.\n"); break; case 2: print("You flee in terror.\n"); break; case 3: print("You run screaming in horror.\n"); break; case 4: print("You flee aimlessly in any direction you can.\n"); break; case 5: print("You run screaming for your mommy.\n"); break; case 6: print("You run as your life flashes before your eyes.\n"); break; case 7: print("Your heart throbs as you attempt to escape death.\n"); break; case 8: print("Colors and sounds mingle as you frantically flee.\n"); break; case 9: print("Fear of death grips you as you flee in panic.\n"); break; case 10: print("You run like a coward.\n"); break; default: print("You run like a chicken.\n"); break; } broadcast(getSock(), oldRoom, "%M flees to the %s^x.", this, exit->getCName()); if(mThis) { mThis->diePermCrt(); if(exit->doEffectDamage(this)) return(2); mThis->deleteFromRoom(); mThis->addToRoom(newRoom); } else if(pThis) { pThis->dropWeapons(); pThis->checkDarkness(); unhide(); if(magicTerror) printColor("^rYou flee from unnatural fear!\n"); Move::track(getUniqueRoomParent(), ¤tLocation.mapmarker, exit, pThis, false); if(pThis->flagIsSet(P_ALIASING)) { pThis->getAlias()->deleteFromRoom(); pThis->getAlias()->addToRoom(newRoom); } Move::update(pThis); pThis->statistics.flee(); if(cClass == CreatureClass::PALADIN && deity != GRADIUS && !magicTerror && level >= 10) { n = level * 8; n = MIN<long>(experience, n); print("You lose %d experience for your cowardly retreat.\n", n); experience -= n; } if(exit->doEffectDamage(this)) return(2); pThis->deleteFromRoom(); pThis->addToRoom(newRoom); for(Monster* pet : pThis->pets) { if(pet && inSameRoom(pThis)) broadcast(getSock(), oldRoom, "%M flees to the %s^x with its master.", pet, exit->getCName()); } } exit->checkReLock(this, false); broadcast(getSock(), newRoom, "%M just fled rapidly into the room.", this); if(pThis) { pThis->doPetFollow(); uRoom = newRoom->getAsUniqueRoom(); if(uRoom) pThis->checkTraps(uRoom); if(Move::usePortal(pThis, oldRoom, exit)) Move::deletePortal(oldRoom, exit); } return(1); }
bool Creature::canFleeToExit(const Exit *exit, bool skipScary, bool blinking) { Player *pThis = getAsPlayer(); // flags both players and mobs have to obey if(!canEnter(exit, false, blinking) || exit->flagIsSet(X_SECRET) || exit->isConcealed(this) || exit->flagIsSet(X_DESCRIPTION_ONLY) || exit->flagIsSet(X_NO_FLEE) || exit->flagIsSet(X_TO_STORAGE_ROOM) || exit->flagIsSet(X_TO_BOUND_ROOM) || exit->flagIsSet(X_TOLL_TO_PASS) || exit->flagIsSet(X_WATCHER_UNLOCK) ) return(false); if(pThis) { if( (( getRoomParent()->flagIsSet(R_NO_FLEE) || getRoomParent()->flagIsSet(R_LIMBO) ) && inCombat()) || (exit->flagIsSet(X_DIFFICULT_CLIMB) && !isEffected("levitate")) || ( ( exit->flagIsSet(X_NEEDS_CLIMBING_GEAR) || exit->flagIsSet(X_CLIMBING_GEAR_TO_REPEL) || exit->flagIsSet(X_DIFFICULT_CLIMB) ) && !isEffected("levitate") ) ) return(false); int chance=0, *scary; // should we skip checking for scary exits? skipScary = skipScary || fd == -1 || exit->target.mapmarker.getArea() || isEffected("fear"); // are they scared of going in that direction if(!skipScary && pThis->scared_of) { scary = pThis->scared_of; while(*scary) { if(exit->target.room.id && *scary == exit->target.room.id) { // oldPrint(fd, "Scared of going %s^x!\n", exit->getCName()); // there is a chance we will flee to this exit anyway chance = 65 + bonus((int) dexterity.getCur()) * 5; if(getRoomParent()->flagIsSet(R_DIFFICULT_TO_MOVE) || getRoomParent()->flagIsSet(R_DIFFICULT_FLEE)) chance /=2; if(mrand(1,100) < chance) return(false); // success; means that the player is now scared of this room if(inUniqueRoom() && fd > -1) { scary = pThis->scared_of; { int roomNum = getUniqueRoomParent()->info.id; if(scary) { int size = 0; while(*scary) { size++; if(*scary == roomNum) break; scary++; } if(!*scary) { // LEAK: Next line reported to be leaky: 10 count pThis->scared_of = (int *) realloc(pThis->scared_of, (size + 2) * sizeof(int)); (pThis->scared_of)[size] = roomNum; (pThis->scared_of)[size + 1] = 0; } } else { // LEAK: Next line reported to be leaky: 10 count pThis->scared_of = (int *) malloc(sizeof(int) * 2); (pThis->scared_of)[0] = roomNum; (pThis->scared_of)[1] = 0; } } } return(true); } scary++; } } } return(true); }
bool Creature::canFlee(bool displayFail, bool checkTimer) { bool crtInRoom=false; long t=0; int i=0; if(isMonster()) { if(!flagIsSet(M_WILL_FLEE) || flagIsSet(M_DM_FOLLOW)) return(false); if(hp.getCur() > hp.getMax()/5) return(false); if(flagIsSet(M_PERMENANT_MONSTER)) return(false); } else { //Player* pThis = getPlayer(); if(!ableToDoCommand()) return(false); if(flagIsSet(P_SITTING)) { if(displayFail) print("You have to stand up first.\n"); return(false); } if(isEffected("hold-person")) { if(displayFail) print("You are unable to move right now.\n"); return(false); } // blah blah re-submit if( (cClass == CreatureClass::BERSERKER || cClass == CreatureClass::CLERIC) && isEffected("berserk") ) { if(displayFail) printColor("^rYour lust for battle prevents you from fleeing!\n"); return(false); } if(checkTimer && !isEffected("fear") && !isStaff()) { t = time(0); i = MAX(getLTAttack(), MAX(lasttime[LT_SPELL].ltime,lasttime[LT_READ_SCROLL].ltime)) + 3L; if(t < i) { if(displayFail) pleaseWait(i-t); return(false); } } // confusion and drunkenness overrides following checks if(isEffected("confusion") || isEffected("drunkenness")) return(true); // players can only flee if someone/something else is in the room for(Monster* mons : getConstRoomParent()->monsters) { if(!mons->isPet()) { crtInRoom = true; break; } } if(!crtInRoom) { for(Player* ply : getConstRoomParent()->players) { if(ply == this) continue; if(!ply->isStaff()) { crtInRoom = true; break; } } } if( !crtInRoom && !checkStaff("There's nothing to flee from!\n") ) { getAsPlayer()->setFleeing(false); return(false); } } return(true); }