Page 55 of 396

Re: Ask a simple question, get a simple answer

Posted: Tue Mar 24, 2015 6:40 pm
by minmay
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")

Re: Ask a simple question, get a simple answer

Posted: Thu Mar 26, 2015 11:27 pm
by Duncan1246
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

Re: Ask a simple question, get a simple answer

Posted: Thu Mar 26, 2015 11:58 pm
by Isaac
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.

Re: Ask a simple question, get a simple answer

Posted: Fri Mar 27, 2015 4:48 pm
by JKos
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.

Re: Ask a simple question, get a simple answer

Posted: Fri Mar 27, 2015 6:59 pm
by Duncan1246
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

Re: Ask a simple question, get a simple answer

Posted: Fri Mar 27, 2015 11:19 pm
by Isaac
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.
--]]

Re: Ask a simple question, get a simple answer

Posted: Sat Mar 28, 2015 1:11 am
by Duncan1246
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

Re: Ask a simple question, get a simple answer

Posted: Sat Mar 28, 2015 4:15 am
by Isaac
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)

Re: Ask a simple question, get a simple answer

Posted: Sat Mar 28, 2015 6:00 am
by minmay
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.

Re: Ask a simple question, get a simple answer

Posted: Sat Mar 28, 2015 6:21 am
by Isaac
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.