Scripting: item-check on tile

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Scripting: item-check on tile

Post by THOM »

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.. ??
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: Scripting: item-check on tile

Post by DesperateGames »

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.
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:

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.
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Scripting: item-check on tile

Post by THOM »

Hi DesperateGames, thanx for replying.
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.
I tried this, but I couldn't get a useful result. Maybe my scripting was wrong...

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
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.
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".
Simple tests had shown that the basic idea works and looks satisfying, but I cannot get it to run correct.
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: Scripting: item-check on tile

Post by DesperateGames »

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?

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
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Scripting: item-check on tile

Post by THOM »

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...
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: Scripting: item-check on tile

Post by DesperateGames »

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:

Code: Select all

[ ] Triggered by Party
[ ] Triggered by Monster
[x] Triggered by Item
[ ] Activate Once
[x] Silent
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 :?
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Scripting: item-check on tile

Post by THOM »

set exactly like that:

Code: Select all

    [ ] Triggered by Party
    [ ] Triggered by Monster
    [x] Triggered by Item
    [ ] Activate Once
    [x] Silent
Maybe "Event" has to be "any"??
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: Scripting: item-check on tile

Post by DesperateGames »

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. :oops:

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.
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Scripting: item-check on tile

Post by THOM »

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)

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... :roll:
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
DesperateGames
Posts: 90
Joined: Sun Oct 06, 2013 1:54 pm

Re: Scripting: item-check on tile

Post by DesperateGames »

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 ;)
Post Reply