Scripting: item-check on tile
Scripting: item-check on tile
I am sure, I am not the first one with that question but I couldn't find a thread where it's discussed:
Is it possible to check, if a certain item is on a certain tile?
I have a special monster that can only be killed by a special bomb. Therefore the monster doesn't move, I am trying to script it like that:
- monster stands on an invisible pressure-plate
- party throws bomb at monster
- plate is activated and starts a script
But in this script I have to check, if it was the bomb, that activated the plate. But I cannot find a reference for that.. ??
Is it possible to check, if a certain item is on a certain tile?
I have a special monster that can only be killed by a special bomb. Therefore the monster doesn't move, I am trying to script it like that:
- monster stands on an invisible pressure-plate
- party throws bomb at monster
- plate is activated and starts a script
But in this script I have to check, if it was the bomb, that activated the plate. But I cannot find a reference for that.. ??
- DesperateGames
- Posts: 90
- Joined: Sun Oct 06, 2013 1:54 pm
Re: Scripting: item-check on tile
Normally you can use the EntitiesAt() function to go through all items on a certain tile
viewtopic.php?f=14&t=5672
The other thing is that I think the flying bomb would be regarded as a projectile and would not be picked up properly by the EntitiesAt-function. Maybe I'm wrong with this but I think it will not show up as a result in the collection, as it only returns monsters and items lying on the ground.
You could also look into hidden receptors in the grimrock editor. I know these work with bombs as I have used them in my dungeon in such way, but I think they won't work for your case because the monster will be standing in front of the hidden receptor and therefore the receptor will never be hit by a bomb .
At the moment I can think of the following workaround to get things working as you want them:
You could set up a custom OnDamage() Scripting hook for your boss monster. There you can check the amount of damage and the damage type (Physical, fire, frost, etc.). You can also decide in the hook, whether the damage will be ignored or dealt to the monster by the return value of the function. You define it in such a way that it is impossible for the player to regularly defeat the monster (for example, the monster only gets damaged if there is more than 999 fire damage being dealt to the monster). You then setup your special bomb in a way that it will be the only way of damaging (and insta-killing) the boss monster (e.g. dealing 10,000 fire damage). It is not a perfect approach, but it could work good enough to achieve what you want in your dungeon.
But there are two things that might prevent this from working properly: The EntitiesAt-function is buggy when the User uses MapMarkers on the Dungeon Map. Fortunately there is a fix for this, see here:EntitiesAt(level, x, y)
Returns an iterator for entities at x,y in a given level.
viewtopic.php?f=14&t=5672
The other thing is that I think the flying bomb would be regarded as a projectile and would not be picked up properly by the EntitiesAt-function. Maybe I'm wrong with this but I think it will not show up as a result in the collection, as it only returns monsters and items lying on the ground.
You could also look into hidden receptors in the grimrock editor. I know these work with bombs as I have used them in my dungeon in such way, but I think they won't work for your case because the monster will be standing in front of the hidden receptor and therefore the receptor will never be hit by a bomb .
At the moment I can think of the following workaround to get things working as you want them:
You could set up a custom OnDamage() Scripting hook for your boss monster. There you can check the amount of damage and the damage type (Physical, fire, frost, etc.). You can also decide in the hook, whether the damage will be ignored or dealt to the monster by the return value of the function. You define it in such a way that it is impossible for the player to regularly defeat the monster (for example, the monster only gets damaged if there is more than 999 fire damage being dealt to the monster). You then setup your special bomb in a way that it will be the only way of damaging (and insta-killing) the boss monster (e.g. dealing 10,000 fire damage). It is not a perfect approach, but it could work good enough to achieve what you want in your dungeon.
Re: Scripting: item-check on tile
Hi DesperateGames, thanx for replying.
What I scripted was
Simple tests had shown that the basic idea works and looks satisfying, but I cannot get it to run correct.
I tried this, but I couldn't get a useful result. Maybe my scripting was wrong...DesperateGames wrote:Normally you can use the EntitiesAt() function to go through all items on a certain tile
EntitiesAt(level, x, y)
Returns an iterator for entities at x,y in a given level.
What I scripted was
Code: Select all
function killMonster()
for i in entitiesAt(2,0,12) do
if i.name == "big_bomb"
then
spawn("fireburst", 2, 0, 12, 2)
monsterX:destroy()
big_bomb_1:destroy()
break
end
end
end
Yes, but therefore the bomb has to trigger a pressure-plate it has to fall on the ground. So it should be catched by "EntitiesAt".DesperateGames wrote: The other thing is that I think the flying bomb would be regarded as a projectile and would not be picked up properly by the EntitiesAt-function. Maybe I'm wrong with this but I think it will not show up as a result in the collection, as it only returns monsters and items lying on the ground.
Simple tests had shown that the basic idea works and looks satisfying, but I cannot get it to run correct.
- DesperateGames
- Posts: 90
- Joined: Sun Oct 06, 2013 1:54 pm
Re: Scripting: item-check on tile
Ah ok, I see now, I thought the bomb would be more like one of the regular bombs that would explode automatically when it touches the monster, therefore I assumed it would not be picked up by the entitiesAt function.
The script you posted looks good for me at the first glance, could you post the result / problem it is giving you? Does it create an error message, or does the bomb not disappear etc.?
Could you maybe add a print statement to see what items are being found on the pressure plate?
The script you posted looks good for me at the first glance, could you post the result / problem it is giving you? Does it create an error message, or does the bomb not disappear etc.?
Could you maybe add a print statement to see what items are being found on the pressure plate?
Code: Select all
function killMonster()
for i in entitiesAt(2,0,12) do
print (i.name)
if i.name == "big_bomb"
then
spawn("fireburst", 2, 0, 12, 2)
monsterX:destroy()
big_bomb_1:destroy()
break
end
end
end
Re: Scripting: item-check on tile
Interesting: I still have no solution but I found out, that the script is is only started once. If another item is on the plate before my bomb, nothing happens...
- DesperateGames
- Posts: 90
- Joined: Sun Oct 06, 2013 1:54 pm
Re: Scripting: item-check on tile
Well that is something at least
Just to make sure: Which values are currently checked in the checkboxes for the pressure plate behavior? I would try the following setup:
I assume that if "Triggered by Monster" would still be active, the pressure plate would not be working properly if the boss monster is still standing on it. But most likely you have tried this already....if this is not the issue, I would try connecting the pressure plate to a very simple script function that just executes a print statement like "plate pressed!" or something. From there I would try to extend the code of the function to get to the point where it is not executed only once to find out what is the problem here. If even the simple print function gets not triggered multiple times with the checkboxes of the pressure plate set as in the example above, well, then I'm confused
Just to make sure: Which values are currently checked in the checkboxes for the pressure plate behavior? I would try the following setup:
Code: Select all
[ ] Triggered by Party
[ ] Triggered by Monster
[x] Triggered by Item
[ ] Activate Once
[x] Silent
Re: Scripting: item-check on tile
set exactly like that:
Maybe "Event" has to be "any"??
Code: Select all
[ ] Triggered by Party
[ ] Triggered by Monster
[x] Triggered by Item
[ ] Activate Once
[x] Silent
- DesperateGames
- Posts: 90
- Joined: Sun Oct 06, 2013 1:54 pm
Re: Scripting: item-check on tile
Aaaaah, please forget all of the above, I just tried it in the dungeon editor: It seems that it is the default behavior of the pressure plate to only trigger when an item actually "pushes it down". Even event type "any" does not help. This means once an item is put on the (invisible) pressure plate, you need to remove it first, before the plate can be triggered again. Sorry for leading you in the wrong direction above, I remembered this wrong.
I guess you could still set up a timer that checks for the existence of the bomb on the tile frequently (every 100 milliseconds or so) and then trigger the explosion / the monster kill once the bomb is detected.
I guess you could still set up a timer that checks for the existence of the bomb on the tile frequently (every 100 milliseconds or so) and then trigger the explosion / the monster kill once the bomb is detected.
Re: Scripting: item-check on tile
I understand. Well - some things with this editor are a bit complicate...
I tried your timer-idea - and it seem to work. Buuuuut: Of course I want to destroy the bomb and scripted something - but all the time the game crashes (game, not editor). Message: attempt to index global 'dm_bomb_blue' (a nil value)
EDIT: got it: i:destroy() works again here...
I tried your timer-idea - and it seem to work. Buuuuut: Of course I want to destroy the bomb and scripted something - but all the time the game crashes (game, not editor). Message: attempt to index global 'dm_bomb_blue' (a nil value)
Code: Select all
function killMonster()
for i in entitiesAt(2,0,12) do
if i.name == "dm_bomb_blue"
then
spawn("fireburst", 2, 0, 12, 2)
cultist_lord:destroy()
timer_kill_cultist:deactivate()
dm_bomb_blue:destroy()
break
end
end
end
EDIT: got it: i:destroy() works again here...
- DesperateGames
- Posts: 90
- Joined: Sun Oct 06, 2013 1:54 pm
Re: Scripting: item-check on tile
The issue here is that dm_bomb_blue is just the general NAME of the item. Think of the .name more as the "type" of the item. In your case, you could either call
i:destroy()
as this should contain the instance of the bomb item anyway. Or, if you know the exact ID of the item (The text that is shown in the lower left corner in the editor when you hover above it with the mouse), you could call it by using the ID. The ID of the instance is different from the name, it should be dm_bomb_blue_1 if you have placed it with the editor. (_2 for the second bomb and so on) In case you have put the bomb into an alcove or on an altar, it is a bit difficult, because you can't know which ID the item will get, unless you spawn it yourself with a script that gives a predefined ID. In this case I would use the i:destroy() method and forget about it
i:destroy()
as this should contain the instance of the bomb item anyway. Or, if you know the exact ID of the item (The text that is shown in the lower left corner in the editor when you hover above it with the mouse), you could call it by using the ID. The ID of the instance is different from the name, it should be dm_bomb_blue_1 if you have placed it with the editor. (_2 for the second bomb and so on) In case you have put the bomb into an alcove or on an altar, it is a bit difficult, because you can't know which ID the item will get, unless you spawn it yourself with a script that gives a predefined ID. In this case I would use the i:destroy() method and forget about it