• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ How to make monster attack only player with storage

GhostWD

I'm in love with the var_dump()
Joined
Jan 25, 2009
Messages
185
Solutions
6
Reaction score
29
Hi there,
I've got problem to solve, idk how to refere to attacker at isTarget method in monster.cpp

Code:
bool Monster::isTarget(Creature* creature)
{
    if(creature->isSagaMonster()){
        return (!creature->isRemoved() && creature->isAttackable() && (creature->isSagaMonster() && [b]getStorage(8000, creature->sagaNumber)[/b]) && creature->getZone() != ZONE_PROTECTION
            && canSeeCreature(creature) && creature->getPosition().z == getPosition().z);
    }else{
    return (!creature->isRemoved() && creature->isAttackable() && creature->getZone() != ZONE_PROTECTION
            && canSeeCreature(creature) && creature->getPosition().z == getPosition().z);
    }
}
Bolded code must check if player(attacker) have storage value if yes = true

Thank's in advance for helping with that! :)

Ok i have better approache to this problem when i will be back at home i will edit this post with results



Code:
bool Monster::isOpponent(const Creature* creature)
{


    std::string keyes = "8000";
    std::string valueses = "1";
    //std::string value = sagaNumber();
    // && creature->getStorage("8000", value)

    if(!creature->getStorage(keyes, valueses)){
      
        return false;
      
    }

    if(creature->getStorage(keyes, valueses)){
            std::string keyes  = "8000";
    std::string valueses = "1";
        return (isSummon() && master->getPlayer() && creature != master) || ((creature->getPlayer()
        && !creature->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters) && creature->getStorage(keyes , valueses)) ||
        (creature->getMaster() && creature->getPlayerMaster()));
      
    }

    return (isSummon() && master->getPlayer() && creature != master) || ((creature->getPlayer()
        && !creature->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters)) ||
        (creature->getMaster() && creature->getPlayerMaster()));


getstorage func is 

bool Creature::getStorage(const std::string& key, std::string& value) const
{
    StorageMap::const_iterator it = storageMap.find(key);
    if(it != storageMap.end())
    {
        value = it->second;
        return true;
    }

    value = "-1";
    return false;
}



}

now i've got this code and when player with storage 8000, 1 is in range of mobster it's attacked by him and even if storage 8000 is ~= 1 still attacking exception is if player have storage 8000, -1 then monster is not attacking(like i want too make for other values than 1) TFS 0.4
 
Last edited:
Solution
*BuMp*

edit@

ok got it: TFS 0.4 BACKUP FILES BEFORE EDITING!!
C++:
CHANGE isOpponent and monsterThink METHOD IN MONSTER.CPP TO :



bool Monster::isOpponent(const Creature* creature)
{


    std::string keyes = "8000";
    std::string valueses = "1";


    creature->getStorage(keyes, valueses);



    //std::string value = sagaNumber();
    // && creature->getStorage("8000", value)
    if(isSagaMonster() && valueses != sagaNumber()){
    
        return false;
    
    }

    if(isSagaMonster() && valueses == sagaNumber()){

        return (isSummon() && master->getPlayer() && creature != master) || ((creature->getPlayer()
        && !creature->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters)) ||
        (creature->getMaster()...
*BuMp*

edit@

ok got it: TFS 0.4 BACKUP FILES BEFORE EDITING!!
C++:
CHANGE isOpponent and monsterThink METHOD IN MONSTER.CPP TO :



bool Monster::isOpponent(const Creature* creature)
{


    std::string keyes = "8000";
    std::string valueses = "1";


    creature->getStorage(keyes, valueses);



    //std::string value = sagaNumber();
    // && creature->getStorage("8000", value)
    if(isSagaMonster() && valueses != sagaNumber()){
    
        return false;
    
    }

    if(isSagaMonster() && valueses == sagaNumber()){

        return (isSummon() && master->getPlayer() && creature != master) || ((creature->getPlayer()
        && !creature->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters)) ||
        (creature->getMaster() && creature->getPlayerMaster()));
    
    }

    return (isSummon() && master->getPlayer() && creature != master) || ((creature->getPlayer()
        && !creature->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters)) ||
        (creature->getMaster() && creature->getPlayerMaster()));
}

NEXT GO TO :

    if(teleportToMaster && doTeleportToMaster())
        teleportToMaster = false;

    addEventWalk();
    if(isSummon())

IN *****void Monster::onThink(uint32_t interval) *****METHOD


AND CHANGE TO :

    if(teleportToMaster && doTeleportToMaster())
        teleportToMaster = false;

    if(isSagaMonster()){
        eventWalk = 0;
    }else{
        addEventWalk();
    }

    if(isSummon())








--------------------------------------------------------------------------------------------------------------
SEARCH MONSTERS.CPP FOR :

                    if(readXMLString(tmpNode, "hostile", strValue))
                        mType->isHostile = booleanString(strValue);

CHANGE TO :



                    if(readXMLString(tmpNode, "hostile", strValue))
                        mType->isHostile = booleanString(strValue);

                    if(readXMLString(tmpNode, "sagamonster", strValue))
                        mType->isSagaMonster = booleanString(strValue);

                    if(readXMLString(tmpNode, "saganumber", strValue))
                        mType->sagaNumber = strValue;

--------------------------------------------------------------------------------------------------------------
SEARCH COMBAT.CPP FOR :

ReturnValue Combat::canDoCombat(const Creature* attacker, const Creature* target)

GOTO :

        if(!target->isAttackable())
            return RET_YOUMAYNOTATTACKTHISCREATURE;

CHANGE TO :

        std::string keyes = "8000";
        std::string valueses = "1";


        attacker->getStorage(keyes, valueses);

        if(!target->isAttackable() || (target->getMonster()->isSagaMonster() && valueses != target->getMonster()->sagaNumber()) )
            return RET_YOUMAYNOTATTACKTHISCREATURE;

--------------------------------------------------------------------------------------------------------------
NOW HEADER FILES

SEARCH MONSTER.H FOR :

        virtual const std::string& getName() const {return mType->name;}

AND ADD UNDER IT :

        virtual bool isSagaMonster() const {return mType->isSagaMonster;}
        const std::string sagaNumber() const {return mType->sagaNumber;}

--------------------------------------------------------------------------------------------------------------

INTO MONSTERS.H  :

ADD TO "

        bool isSummonable, isIllusionable, isConvinceable, isAttackable, isHostile, isLureable,
            isWalkable, canPushItems, canPushCreatures, pushable, hideName, hideHealth;

THIS :
        , isSagaMonster;

AND TO THIS :

        std::string name, nameDescription;

THIS :

, sagaNumber;

How to use?
in desired monster xml use flags <flag sagamonster="1"/> and <flag saganumber="2"/>
XML:
    <flags>
  <flag summonable="0"/>
      <flag attackable="1"/>
      <flag hostile="0"/>
      <flag sagamonster="1"/>      <---- that means its saga monster 1 = true, 0 = false
      <flag saganumber="2"/>     <---- this is storage 8000 value
      <flag illusionable="0"/>
      <flag convinceable="0"/>
      <flag pushable="0"/>
     <flag canpushitems="1"/>
      <flag staticattack="50"/>
      <flag lightlevel="0"/>
      <flag lightcolor="0"/>
      <flag targetdistance="1"/>
      <flag runonhealth="0"/>
    </flags>

How it works?
if monster is flaged as sagamonster it wont walk like other monsters when player is near them
and it checks if player got value from saganumber in 8000 storage if yes it will follow player if not it wont follow him and cant be attacked

WARNING!
note that you will must to add <flag sagamonster="0"/> to all non saga monsters the best way for this would be using program Ecobyte Replace Text

:D

firefun.dyn.pl
 
Last edited:
Solution
HI, how are U? i get this error, do u know how i solve it?
In static member function 'static ReturnValue Combat::canDoCombat(const Creature*, const Creature*)':
295 C:\Users\DEV-CPP\trunk\combat.cpp no matching function for call to 'Creature::getStorage(std::string&, std::string&) const'
note C:\Users\\DEV-CPP\trunk\creature.h:340 candidates are: virtual bool Creature::getStorage(uint32_t, std::string&) const
note C:\Users\\DEV-CPP\trunk\creature.h:340 *** [obj//combat.o] Error 1
 
Last edited:
change
std::string keyes = "8000";
to
uint32_t keyes = 8000;

It worked!! thx!!, but there is a bug, can it be fixed?
For example players needs storage 8000 in value 10, to be attacked and to attack the Demon.
If the player's storage is upgraded to 10 in front of a demon, the demon will not see the player and the player will be able to kill the demon without the demon seeing it.
1 - The player needs to exit and return to the demon screen to be updated. Is it possible to fix this bug?
2 - I also need to implement the anti-lure system (when the monster in the saga moves 10 sqms away from its respaw location, it is removed). Same as the anti-lire system, but monsters of the saga will be limited to 10sqm's
 
Last edited:
When normal monster with this lane:
<flag sagamonster="0"/>
Attack player.. server gonna crash :eek:
i remove this:

std::string keyes = "8000";
std::string valueses = "1";
attacker->getStorage(keyes, valueses);
if(!target->isAttackable() || (target->getMonster()->isSagaMonster() && valueses != target->getMonster()->sagaNumber()) )
return RET_YOUMAYNOTATTACKTHISCREATURE;

paste again this:

if(!target->isAttackable())
return RET_YOUMAYNOTATTACKTHISCREATURE;

This work with normal monster, but "saga" mosnter cannot attack player with needed storage.
Tfs 0.4 rev 3777
 
@GhostWD
Hello, I do not know how to speak English, so I'll use google translator, hahahaha, I've followed your tutorial, it worked fine, the monsters with the saga tag are all perfect, but all the other monsters and the players that attack me crash the server, and I put the tag on the monsters.
<flag sagamonster = "0" />
Would you help me?


TFS 0.4
 
Back
Top