예제 #1
0
//*********************************************************************
//                      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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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, ';'); }}}
예제 #5
0
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);
}
예제 #6
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(), &currentLocation.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);
}
예제 #7
0
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);
}
예제 #8
0
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);
}