• 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!

Lua Function Monster onSelectTarget(self, target)

Marcelo Druida

Intermediate OT User
Joined
Nov 17, 2014
Messages
429
Solutions
1
Reaction score
134
Location
Brazil
Hello!

This code makes it possible to include some script when the monster sets a target.

monster.cpp

find:
bool Monster::selectTarget(Creature* creature)

replace:
Code:
bool Monster::selectTarget(Creature* creature)
{
    if (!isTarget(creature)) {
        return false;
    }

    auto it = std::find(targetList.begin(), targetList.end(), creature);
    if (it == targetList.end()) {
        //Target not found in our target list.
        return false;
    }

    if (isHostile() || isSummon()) {
        if (executeOnSelectTarget(creature) == 1){
            if (setAttackedCreature(creature) && !isSummon()) {
                    g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
            }
        }
        else
            return false;
    }
    return setFollowCreature(creature);
}

bool Monster::executeOnSelectTarget(Creature* creature){

    // onSelectTarget(self, target)
    if (mType->targetEvent != -1) {
        LuaScriptInterface* scriptInterface = mType->scriptInterface;

        if (!scriptInterface->reserveScriptEnv()) {
            std::cout << "[Error - Monster::onSelectTarget] Call stack overflow" << std::endl;
            return true;
        }

        ScriptEnvironment* env = scriptInterface->getScriptEnv();
        env->setScriptId(mType->targetEvent, scriptInterface);

        lua_State* L = scriptInterface->getLuaState();
        scriptInterface->pushFunction(mType->targetEvent);

        LuaScriptInterface::pushUserdata<Monster>(L, this);
        LuaScriptInterface::setMetatable(L, -1, "Monster");

        LuaScriptInterface::pushUserdata(L, creature);
        LuaScriptInterface::setCreatureMetatable(L, -1, creature);

        return (scriptInterface->callFunction(2));
    }
    return true;
}

monster.h
find:
bool selectTarget(Creature* creature);
add:
bool executeOnSelectTarget(Creature* creature);

monsters.cpp:
find:
Code:
    scriptInterface = nullptr;
    creatureAppearEvent = -1;
    creatureDisappearEvent = -1;
    creatureMoveEvent = -1;
    creatureSayEvent = -1;
    thinkEvent = -1;
add:
targetEvent = -1;

find:
mType->thinkEvent = scriptInterface->getEvent("onThink");
add:
mType->targetEvent = scriptInterface->getEvent("onSelectTarget");

monsters.h:

find:
int32_t thinkEvent;
add:
int32_t targetEvent;



Improvement:
If you want to set a global target event (all monsters will follow the rule):

monsters.cpp:

find:
Monsters::loadMonster

add:
before return true

Code:
  if (!scriptInterface) {
     scriptInterface.reset(new LuaScriptInterface("Monster Interface"));
     scriptInterface->initState();
   }

   if (scriptInterface->loadFile("data/monster/scripts/global.lua") == 0) {
     mType->scriptInterface = scriptInterface.get();
     mType->globalTargetEvent = scriptInterface->getEvent("onSelectTarget");
   }


find:
Code:
scriptInterface = nullptr;
creatureAppearEvent = -1;
creatureDisappearEvent = -1;
creatureMoveEvent = -1;
creatureSayEvent = -1;
thinkEvent = -1;
targetEvent = -1;

add:
globalTargetEvent = -1;



monsters.h

find:
int32_t thinkEvent;
add:
int32_t globalTargetEvent;


create monster/scripts/global.lua:
function onSelectTarget(self, target)
print(self:getName())
return true
end
 
Last edited:
TFS 1.2



little example:

Code:
function onSelectTarget(self, target)

-- race VENOM only attack players of lvl 100+
if self:getRace() == RACE_VENOM and target:getLevel() >= 100 then
      return true
end

return false
end

Tip: monster:getTargetList() may be useful
 
can addapt this code for tsf 0.3.6 pl1??? its a very good code, thanks very, very much :)
 
as default, TFS 1.x's npcs dont attack creatures, so no you cant
if you make NPCs attacking creatures and include LUA scripting onSelectTarget, then yes you can
 
TFS 1.2



little example:

Code:
function onSelectTarget(self, target)

-- race VENOM only attack players of lvl 100+
if self:getRace() == RACE_VENOM and target:getLevel() >= 100 then
      return true
end

return false
end

Tip: monster:getTargetList() may be useful
Wouldnt that allow the player to kill those monsters without being attacked?
 
Wouldnt that allow the player to kill those monsters without being attacked?
Good question! :D
I think this is more like a example script, but yeah. The player could kill these monsters without getting attack.
 
Wouldnt that allow the player to kill those monsters without being attacked?

You got the point.
Tbh I did not take advantage of this function. On the release I've just wrote some stupid code.
Would make sense if it only attacks <= 100

If any of you can suggest a better example I'd alter
 
You got the point.
Tbh I did not take advantage of this function. On the release I've just wrote some stupid code.
Would make sense if it only attacks <= 100

If any of you can suggest a better example I'd alter
I actually wanted to ask for a use case too :p
 
Back
Top