• 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 [creaturescript] healthchange

BloodGauntlet

Member
Joined
Jul 27, 2016
Messages
45
Reaction score
18
The way I understand it this should run every time damage occurs? The script isn't running when damage is dealt and no errors are being thrown. I know it's just because of my general lack of understanding but if someone could explain, much thanks.

print_r is a custom function, valid code.

Code:
function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    local returnValues = {
        ["creature"] = creature,
        ["attacker"] = attacker,
        ["primaryDamage"] = primaryDamage,
        ["primaryType"] = primaryType,
        ["secondaryDamage"] = secondaryDamage,
        ["secondaryType"] = secondaryType,
        ["origin"] = origin
    }
    print_r(returnValues)
end
Code:
<event type="healthchange" name="damage" script="damage.lua"/>
 
Ok, this has got me pretty confused. I want to run this every time damage occurs because I want to specify how damage is calculated. Where exactly do I use Creature:registerEvent()? e.g, there is no condition other than healthchange I want to run the script so how do I register it? I'm hoping you post will help me understand the creature script system more.
 
creaturescripts are not working by default, they have to be registered for every player and monster in order if you want to use a global system with it
for players you can do this on login -> player:registerEvent("damage") ("damage" refers in this case to the event name set in the creaturescripts.xml file for this event)
for monsters you have to set the event in the xml file of it.
 
Great, registering it in login.lua makes sense, thank you. For monsters where do I register the event in the xml file? I checked specific creatures e.g, "demon.xml" and "monsters.xml" I looked for an event field but did not find any.

TFS 1.1
 
Great, registering it in login.lua makes sense, thank you. For monsters where do I register the event in the xml file? I checked specific creatures e.g, "demon.xml" and "monsters.xml" I looked for an event field but did not find any.

TFS 1.1

You can either add the event individually to each monster .xml file.
Or add the onSpawn code to your TFS sources which will register the event for every monster as they spawn.

events.xml
add:
Code:
<!-- Monster method -->
<event class="Monster" method="onSpawn" enabled="1" />

events/scripts/monster.lua
Code:
function Monster:onSpawn(pos, forced)
self:registerEvent("NameOfHeathChangeEventYouNeedToRegister")

return true
end

events.cpp
after:
Code:
playerOnTradeRequest = -1;
playerOnTradeAccept = -1;
playerOnGainExperience = -1;
playerOnLoseExperience = -1;
playerOnGainSkillTries = -1;

add:
Code:
// Monster
monsterOnSpawn = -1;


after:
Code:
} else if (methodName == "onGainSkillTries") {
playerOnGainSkillTries = event;
} else {
std::cout << "[Warning - Events::load] Unknown player method: " << methodName << std::endl;
}

add:
Code:
} else if (className == "Monster") {
if (methodName == "onSpawn") {
monsterOnSpawn = event;
} else {
std::cout << "[Warning - Events::load] Unknown monster method: " << methodName << std::endl;
}

after:
Code:
if (scriptInterface.protectedCall(L, 3, 1) != 0) {
LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(L));
} else {
tries = LuaScriptInterface::getNumber<uint64_t>(L, -1);
lua_pop(L, 1);
}

scriptInterface.resetScriptEnv();
}

add:
Code:
// Monster
bool Events::eventMonsterOnSpawn(Monster* monster, const Position& position, bool forced) {
// Monster:onSpawn(pos, forced)
if (monsterOnSpawn == -1) {
return true;
}

if (!scriptInterface.reserveScriptEnv()) {
std::cout << "[Error - Events::eventMonsterOnSpawn] Call stack overflow" << std::endl;
return false;
}

ScriptEnvironment* env = scriptInterface.getScriptEnv();
env->setScriptId(monsterOnSpawn, &scriptInterface);

lua_State* L = scriptInterface.getLuaState();
scriptInterface.pushFunction(monsterOnSpawn);

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

LuaScriptInterface::pushPosition(L, position);

LuaScriptInterface::pushBoolean(L, forced);

return scriptInterface.callFunction(3);
}

events.h

after:
Code:
void eventPlayerOnGainExperience(Player* player, Creature* source, uint64_t& exp, uint64_t rawExp);
void eventPlayerOnLoseExperience(Player* player, uint64_t& exp);
void eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t& tries);

add:
Code:
// Monster
bool eventMonsterOnSpawn(Monster* monster, const Position& pos, bool forced);

after:
Code:
int32_t playerOnTradeAccept;
int32_t playerOnGainExperience;
int32_t playerOnLoseExperience;
int32_t playerOnGainSkillTries;

add:
Code:
// Monster
int32_t monsterOnSpawn;

Pick your poison.
 
Haven't tested but maybe you can register the event ontarget combat and on area combat before creaturescripts are executed.

You can also create your own spawning system in Lua if you don't like source edits.
 
Back
Top Bottom