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

Zothion

Veteran OT User
Joined
Apr 28, 2014
Messages
1,092
Reaction score
394
if i want to do something with a monster when it spawns, is there any other way than onCreatureAppear?
iright now i have script="spawn.lua" in the creatures xml files, and in spawn.lua
Code:
function onCreatureAppear(self, creature)
...
end
where self:getId() would return the monster unique id, so i could do like
global table[self:getId()] = {...} which is working for me, but when a monster with onCreatureAppear spawns it goes through every single other monster of that type also, so if i had like
Code:
function onCreatureAppear(self, creature)
print(self:getId())
end
it would print out the id of every single monster of that type, however with a
Code:
if table[self:getId] ~= nil then
return
but if i have say 1000 demons out on the map, and spawn another it would have to check table[self:getId] 1000 times, which doesnt seem good for performance..


is there any way to use a monsters unique id when it spawns other than using onCreatureAppear which iterates through all monsters of the same type?
 
Last edited:
for my testing right now im using
global.lua
Code:
t = {["Demon"] = {n = 10, x = 20}}
g = {}
and in spawn.lua
Code:
function onCreatureAppear(self, creature)
    print(os.time())
    if g[self:getId()] == nil then
        name = self:getName()
        id = self:getId()
        rand = {t[name].n, t[name].x}
        g[id] = {n = (math.random(rand[1], rand[2]))}
    end
    print(os.time())
    return
end
but it doesnt seem like it calls the onCreatureAppear when the server starts up and places creatures, so print_r(g) right after start would return empty, but if i use /m demon, it will then go through every single demon (cus onCreatureAppear) and check if g[self:getId()] == nil, which it is, and set all demons that havent had their id key in g set yet...
however if i go to a demon on the map, and kill it, when it respawns it will call onCreatureAppear and store information at their ids place in the global table...
so it seems like for some reason it doesnt call onCreatureAppear when spawning monsters on startup
using doCreatureSummon("demon", pos) does call it so it sets all the values, so it could be worked around by on startup force summon 1 of each creature and kill them just to set values i guess, but that still doesnt change the fact that onCreatureAppear calls all the demons in this case, which would be horrible for performance if i had several thousands creatures on the map and they kept getting killed..
 
To execute code once, when it has spawned. Just do:
Code:
if creature == self then
 
thanks, that improves it a little bit, but it still has to check self == creature for every single demon on the map :confused:

edit: it seems like it isnt THAT bad for performance due to how fast those checks are, but if theres a way to not go through each monster of the type that respawns it would be good :p
 
Last edited:
thanks, that improves it a little bit, but it still has to check self == creature for every single demon on the map :confused:

edit: it seems like it isnt THAT bad for performance due to how fast those checks are, but if theres a way to not go through each monster of the type that respawns it would be good :p
It does not go through all monsters of that type. Only in the monster's view range. Also the creature == self thing does not work for the monsters that spawn on startup.

The best approach is to create a monster event for spawn.
 
It does not go through all monsters of that type. Only in the monster's view range. Also the creature == self thing does not work for the monsters that spawn on startup.

The best approach is to create a monster event for spawn.
oh damn, you're right, which solves my concers about the performance it would have, however it creates a new issue with that the monsters spawned on startup cant get values set to them, unless i on startup iterate through all monsters and replace them, or i create a monster event for spawn as you said

i think im gonna have a look at https://otland.net/threads/creatureevent-onspawn-cid.134039/ and try to make it work for my 1.2

thanks @MatheusMkalo :)
 
oh damn, you're right, which solves my concers about the performance it would have, however it creates a new issue with that the monsters spawned on startup cant get values set to them, unless i on startup iterate through all monsters and replace them, or i create a monster event for spawn as you said

i think im gonna have a look at https://otland.net/threads/creatureevent-onspawn-cid.134039/ and try to make it work for my 1.2

thanks @MatheusMkalo :)
You can use this onCreatureAppear but it won't be the best approach.

On spawn.cpp change
Code:
spawnMonster(spawnId, sb.mType, sb.pos, sb.direction, true);

To:
Code:
spawnMonster(spawnId, sb.mType, sb.pos, sb.direction, false);

Then it will fire the event on startup but will fire more than once for each monster in the area.
 
You can use this onCreatureAppear but it won't be the best approach.

On spawn.cpp change
Code:
spawnMonster(spawnId, sb.mType, sb.pos, sb.direction, true);

To:
Code:
spawnMonster(spawnId, sb.mType, sb.pos, sb.direction, false);

Then it will fire the event on startup but will fire more than once for each monster in the area.
that would decrease startup performance yeah, but im not really concered about that at all so, so that fix will for perfectly for me.. thanks once again :)
 
Back
Top