Ask a simple question, get a simple answer

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
minmay
Posts: 2671
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay » Tue Mar 24, 2015 6:40 pm

petri wrote:
BuzzJ wrote:Is there a simple way to make an object or several spawn on the same tile as the party when an (here unspecified) event occurs? Where defining the location of the party is not necessary?
Something like this perhaps?

Code: Select all

party.party:spawn("dagger")
I think you meant

Code: Select all

party:spawn("dagger")
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.

User avatar
Duncan1246
Posts: 404
Joined: Mon Jan 19, 2015 7:42 pm

Re: Ask a simple question, get a simple answer

Post by Duncan1246 » Thu Mar 26, 2015 11:27 pm

Hello,
I think I have seen the answer somewhere, but I can't find it now. I want to retrieve four objects previously spawned to move (or destroy) them. I know theirs positions, but not their id (spawn). I tried "EntitiesAt" but nothing happens... Perhaps it's necessary to store id on spam, but is ugly... Using floor triggers? Some help please
Duncan
The Blue Monastery (LOG1)
download at:http://www.nexusmods.com/grimrock/mods/399/?

Finisterrae(LOG2)
download at:http://www.nexusmods.com/legendofgrimrock2/mods/61/?

User avatar
Isaac
Posts: 2972
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac » Thu Mar 26, 2015 11:58 pm

Duncan1246 wrote:Hello,
I think I have seen the answer somewhere, but I can't find it now. I want to retrieve four objects previously spawned to move (or destroy) them. I know theirs positions, but not their id (spawn). I tried "EntitiesAt" but nothing happens... Perhaps it's necessary to store id on spam, but is ugly... Using floor triggers? Some help please
Duncan
If you know what they are, you can compare by name instead of id. Use entitiesAt() to loop though the contents of the cell, or use the contents() method if the objects are on [in] a surface component.

This should work, unless you have a pile of like objects, and are wanting a specific one.

User avatar
JKos
Posts: 464
Joined: Wed Sep 12, 2012 10:03 pm
Location: Finland
Contact:

Re: Ask a simple question, get a simple answer

Post by JKos » Fri Mar 27, 2015 4:48 pm

Is there a way to unlink a monster from monster group? We have MonsterMoveComponent.onUnlinkMonsterGroup(self) hook so I guess it's possible, but I can't figure out how the unlinking can be done. I can make a monster to step out from the group by calling monster:moveForward() for example, but it still moves with the group.

I need this for Turn undead and Charm monster spells.
- LoG Framework 2http://sites.google.com/site/jkoslog2 Define hooks in runtime by entity.name or entity.id + multiple hooks support.
- cloneObject viewtopic.php?f=22&t=8450

User avatar
Duncan1246
Posts: 404
Joined: Mon Jan 19, 2015 7:42 pm

Re: Ask a simple question, get a simple answer

Post by Duncan1246 » Fri Mar 27, 2015 6:59 pm

Isaac wrote:
Duncan1246 wrote:Hello,
I think I have seen the answer somewhere, but I can't find it now. I want to retrieve four objects previously spawned to move (or destroy) them. I know theirs positions, but not their id (spawn). I tried "EntitiesAt" but nothing happens... Perhaps it's necessary to store id on spam, but is ugly... Using floor triggers? Some help please
Duncan
If you know what they are, you can compare by name instead of id. Use entitiesAt() to loop though the contents of the cell, or use the contents() method if the objects are on [in] a surface component.

This should work, unless you have a pile of like objects, and are wanting a specific one.
Thanks Isaac, Ihave tried entitiesAt but my syntax was a joke... So, this time it works like this:

Code: Select all

function makeessence()
	for px=2,4,2 do
			for py=16,18,2 do
				for e in party.map:entitiesAt(px,py) do	
					if e.name=="power_gem" then
					e:setPosition(3,17,1,0,party.level)
					end
				end
			end
	end
end
The Blue Monastery (LOG1)
download at:http://www.nexusmods.com/grimrock/mods/399/?

Finisterrae(LOG2)
download at:http://www.nexusmods.com/legendofgrimrock2/mods/61/?

User avatar
Isaac
Posts: 2972
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac » Fri Mar 27, 2015 11:19 pm

Duncan1246 wrote:...
You are using the loops for a single value each. You do not need a nested loop for that.

You could try this script for the same effect:
Place either your timer, or trigger/switch ~or even your calling script on to the specific tile that you wish to check for your items;
and connect it to this script.

Code: Select all

dest = {3,17,0,0,1} --=-----------------------------------------[Destination for setPosition(), to move your item]
item =  "power_gem_item"

function itemChk(ift)
	for x in ift.go.map:entitiesAt(ift.go.x, ift.go.y) do
		if x.name == item then
			x:setPosition(unpack(dest))
		end
	end		
end	
Or...
SpoilerShow
If it suits your situation, here is an alternate script, that automatically checks the floor on its own; via pressure plate.

Code: Select all

dest = {16,15,0,0,1} --=-----------------------------------------[Destination for setPosition()]
item =  "power_gem_item"
trigger = "dungeon_pressure_plate"

function itemChk(ift)
	for x in ift.go.map:entitiesAt(ift.go.x, ift.go.y) do
		if x.name == item then
			x:setPosition(unpack(dest))
		end
	end		
end	

function _setup() --=--------------------------------------------[Places floor_trigger & timer check tile for items.]
	local ti = spawn("timer", self.go.level, self.go.x, self.go.y, self.go.facing, self.go.elevation)
			ti.timer:setTimerInterval(2)
			ti.timer:addConnector("onActivate", self.go.id, "itemChk")
			ti.timer:stop()
	local tr = ti:spawn(trigger).floortrigger
			tr:addConnector("onActivate", ti.id, "start")
			tr:addConnector("onDeactivate", ti.id, "stop")
			tr:setTriggeredByParty(false)
			tr:setTriggeredByMonster(false)
			tr:setTriggeredByItem(true)
			tr:setTriggeredByDigging(false)
			tr:setDisableSelf(false)
end		

_setup()	

--[[
 The way this works is to spawn a timer and floor_trigger on the tile where you place the script object.
 At runtime, any item placed on the ground will activate the timer to check that tile for the target item.
 The timer remains on until the items are removed.
--]]

User avatar
Duncan1246
Posts: 404
Joined: Mon Jan 19, 2015 7:42 pm

Re: Ask a simple question, get a simple answer

Post by Duncan1246 » Sat Mar 28, 2015 1:11 am

You are using the loops for a single value each. You do not need a nested loop for that.

You could try this script for the same effect:
Place either your timer, or trigger/switch ~or even your calling script on to the specific tile that you wish to check for your items;
and connect it to this script.
Thanks for your help.
I understand the idea, but I have four locations to check, so I can't put the script on it. You means that my script is more CPU consuming than 4 floortriggers plus a timer? A silly ask: what is ift in your script? I don't see where are ift values??
Duncan
The Blue Monastery (LOG1)
download at:http://www.nexusmods.com/grimrock/mods/399/?

Finisterrae(LOG2)
download at:http://www.nexusmods.com/legendofgrimrock2/mods/61/?

User avatar
Isaac
Posts: 2972
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac » Sat Mar 28, 2015 4:15 am

Duncan1246 wrote:
You are using the loops for a single value each. You do not need a nested loop for that.

You could try this script for the same effect:
Place either your timer, or trigger/switch ~or even your calling script on to the specific tile that you wish to check for your items;
and connect it to this script.
Thanks for your help.
I understand the idea, but I have four locations to check, so I can't put the script on it. You means that my script is more CPU consuming than 4 floortriggers plus a timer? A silly ask: what is ift in your script? I don't see where are ift values??
Duncan
I think any performance gain is negligible; it's just that it's more complicated than it needs to be, and so is harder to read than seems necessary. Loops are useful for their incrementing value, and this pair of loops only runs once each for fixed values that could be static variables.

To check four locations, just call the short version of the script from those four locations; either with triggers, switches, timers, or scripts*. The itemchk function takes its search tile from the location of the calling object; be it a plate/floor trigger, wall button, lever or script object.

ift originally meant 'Item Floor Trigger', but stopped meaning just that, so I shortened it. The ift variable is reference to whatever calls the itemChk function.

*Calling via script would be done like this: my_script.script.itemChk(self)

minmay
Posts: 2671
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay » Sat Mar 28, 2015 6:00 am

Isaac wrote:Loops are useful for their incrementing value, and this pair of loops only runs once each for fixed values that could be static variables.
Uh, each loop runs twice, for a total of four iterations of the inner loop. Unrolling them would result in:

Code: Select all

for e in party.map:entitiesAt(2,16) do   
  if e.name=="power_gem" then
    e:setPosition(3,17,1,0,party.level)
  end
end
for e in party.map:entitiesAt(2,18) do   
  if e.name=="power_gem" then
    e:setPosition(3,17,1,0,party.level)
  end
end
for e in party.map:entitiesAt(4,16) do   
  if e.name=="power_gem" then
    e:setPosition(3,17,1,0,party.level)
  end
end
for e in party.map:entitiesAt(4,18) do   
  if e.name=="power_gem" then
    e:setPosition(3,17,1,0,party.level)
  end
end
I'd much rather read the loops. A table of positions or something is probably better from a flexibility perspective of course.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.

User avatar
Isaac
Posts: 2972
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac » Sat Mar 28, 2015 6:21 am

minmay wrote:
Isaac wrote:Loops are useful for their incrementing value, and this pair of loops only runs once each for fixed values that could be static variables.
Uh, each loop runs twice, for a total of four iterations of the inner loop.
Does it? Maybe I missed it; I guess I thought that the loops were using stepping 2, and that a loop like 16,18,2 would only run once, and be at 18. Image

*Yep, it runs twice, and I should have known it. It shows the downside of reading and posting scripts at 4AM. :D
Off by 1 errors have their own special sting to them; when you realize you've made one.
Last edited by Isaac on Sat Mar 28, 2015 6:54 am, edited 5 times in total.

Post Reply