The timer is in seconds.
* When I updated the script, I pasted it in with maxHealth set to 10; that needs to be maxHealth = nil ,or else every monster it spawns will have 10 hitpoints.
Passing arguments in lua [script] is pretty relaxed. Lua will pass along almost anything in the braces; just separate them by commas, and give raw strings quotes. For practical use though, the script function should [usually] expect what you send it, and in the case of the hooks, you don't have control of the arguments sent; you are limited to using what arguments the hook provides. In Grimrock 2, most functions [afaik] are given the script itself as the first argument; it's why you see most functions accepting (self,) as their first.
Also mistakes in the hooks very often crash the game, and sometimes lack any useful error message; you really need to be able to read it for errors, almost unaided. The scripting reference(s) tell what arguments the hooks support/or provide.
http://www.grimrock.net/modding/scripting-reference/
https://github.com/JKos/log2doc/wiki << better
Passing arguments with connectors is a bit of a hack, outside of using the first argument to know what connector triggered the script. Notice in my spawner script, that cSpawn accepts 'timer' as it's first argument; this is to be able to distinguish/ reference [,and stop] a calling timer.
*BTW: Function argument
names can be whatever [syntax legal] names you want; it is useful to make them descriptive, but this has no bearing on content. Calling it 'timer', doesn't mean that it is one. Labeling it what you know [or usually expect] it to be, makes it easy to use in the function.
It is
technically possible to store data arguments in the trigger's id string and parse them when it calls the function. Such arguments would need to be added to the id when hand-placed, or by the function that spawned the trigger; but it's a bit of a hack.
An often better option is to have the connector trigger a (proxy) function, one that then calls the intended function with the arguments. For instance, the proxy function could check the cell for monsters, then call the other function, and include the monster id (or ids) as arguments ~that you could not get from the trigger alone; this could let you know who stepped on the plate... this would let you extract the id of a dynamically spawned monster from a regular spawner object with a plate under it... and that could even allow one to assign an onDie() connector to whatever was spawned... because as soon as it spawns, it steps on the plate.
**Updated the script again; removed a no longer used condition check.
***Updated again... The original script was meant to disable itself, but then I got the idea to shut off the timer that called it; this has the unfortunate side effect of [predictably] stopping anything else the timer is connected to.
So here is the script again, but without the timer interaction:
Code: Select all
--custom_spawner script [connect trigger to cSpawn]
cooldown = 4 -- minimum time between spawns
monster = "crowern" -- monster name/kind
lootDrop = {100,"rock", } -- %100 chance to drop, Item; can be blank for no items: {}
level = 1 -- monster level
maxHealth = nil -- monster health (if changed)
spawnOnDeath = true -- whether to instantly spawn a new one when one of them dies
maxSpawns = 3 -- maximum monsters spawned ~before disabling self [ set to 0 for unlimited spawns]
exp = nil --Change experience point value
teleportEffect = true --Whether or not to display the teleport effect when spawning
--Auto-spawn option: See the last line of the script
--_________________________________________________________
spawned = 0
active = true
function cSpawn(timer,bypass)
if maxSpawns then
if maxSpawns > 0 and spawned >= maxSpawns then
maxSpawns = nil
return -- disable
end
if active or bypass then
for obj in self.go.map:entitiesAt(self.go.x,self.go.y) do
if obj.obstacle or obj.monster and obj.elevation == self.go.elevation then
return --cell is occupied, cancel spawn
end
end
active = false
local m = self.go:spawn(monster)
spawned = spawned +1
if teleportEffect and self.go.map:checkLineOfSight(self.go.x, self.go.y, party.x, party.y, party.elevation) then self.go:spawn('teleportation_effect') end
if level > 1 then m.monster:setLevel(level) end
if lootDrop then m.monster:setLootDrop(lootDrop) end
if maxHealth then m.monster:setHealth(maxHealth) end
if exp then m.monster:setExp(exp) end
if spawnOnDeath then m.monster:addConnector('onDie', self.go.id, 'respawn') end
delayedCall(self.go.id, cooldown, 'activate')
end
end
end
function activate() active = true end
function setMaxSpawns(self,number) if type(number) == "number" then maxSpawns = number spawned = 0 active = true else maxHealth = nil end end
function respawn() cSpawn(self, true) end
--[[Auto-spawn OPTION: If the cSpawn() call [below] is uncommented, (by deleting the two dashes on it's left),
then the script doesn't need a timer or trigger. It will spawn a monster on load, and if spawnOnDeath
is set to true, it will spawn another when that one is killed. --]]
--cSpawn()