Page 4 of 6

Re: Spike trap script help

Posted: Tue Apr 28, 2015 7:14 am
by alois
Did you try with x.name == "dungeon_pit" (with the underscore)?

Alois :)

Re: Spike trap script help

Posted: Tue Apr 28, 2015 7:45 am
by Killcannon
I did just to be sure, the thing is I named the pits "dungeonpit1" "2..3...4...5..etc" I even tried indexing them in a table like I did for my others like this:
SpoilerShow
local pit = {"dungeonpit1",
"dungeonpit2",
"dungeonpit3",
"dungeonpit4",
"dungeonpit5",
"dungeonpit6",
"dungeonpit7",
"dungeonpit8",
"dungeonpit9",
"dungeonpit10",
"dungeonpit11",
"dungeonpit12",
"dungeonpit13",
"dungeonpit14",
"dungeonpit15"}
When I do that Line 15 if pit:isOpen() then has an issue providing an "attempt to call method 'isOpen' (A nil value) which is probably because it's checking every pit at the same time and not just the one the party is on. I was trying the following instead, but IIRC it was also giving me an error somewhere.

Code: Select all

	for x = 1,15 do
		local pit = findEntity("dungeonpit"..x)


Re: Spike trap script help

Posted: Tue Apr 28, 2015 8:01 am
by Isaac
Here is what it is (probably)...

The scripts I wrote don't look for the object.id, they look for a match in the object.name.... is it a pit?
There should only be one pit per cell, one pit to find. It searches for a pit, and doesn't care what the id string of the pit happens to be.

Code: Select all

function teleport(caller)
local pit
for x in entitiesAt(caller.level, caller.x, caller.y) do

--Here. This should probably be the default name for a pit of the tile-set you are using.
if x.name == "dungeonpit" then 

pit = x
end 
If you have it set to match for "dungeonpit", then it's looking for a defined object of the kind "dungeonpit". When it doesn't find it, the variable x is assigned nil, and the variable pit is assigned x [nil] and why the variable pit has no isOpen() method.

Re: Spike trap script help

Posted: Tue Apr 28, 2015 3:18 pm
by alois
Be careful that "entity.name" and "entity.id" are two different things. For example, you may have a torch (name = torch) whose id is (for example) "torch_10" because it is the tenth torch spawned in the dungeon. Thus: "dungeonpit1" is the id of the pit (and if you look for findEntity("dungeonpit1") you are going to find the one and only entity with that id since ids are unique in the dungeon), while "dungeonpit" is the name of a generic "dungonpit"; if you are using standard assets, the "name" of the entity should be "dungeon_pit". Another possibilty is to do the following:

Code: Select all

if (string.find(x.id,"dungoenpit")) then pit = x end
In this way, you are going to retrieve the pit-entity at the location of the party. Finally (and this is easier!), you can do the following: write down the (x,y) location of the pits; for example: (2,3), (4,5), (10,13) and so on, and then call the pit at (X,Y) as "dungeonpitXY" (padding zeroes); in the example before: "dungeonpit0203", "dungeonpit"0405", "dungeonpit1013". Then do the following:

Code: Select all

if (party.x < 10) then
     tail = "0" .. party.x
else
    tail = tostring(party.x)
end
if (party.y < 10) then
     tail = tail .. "0" .. party.y
else
     tail = tail .. tostring(party.y)
end
local pit = findEntity("dungeonpit .. tail)
if (pit:isOpen()) then
   -- your code here
end
Alois :)

Re: Spike trap script help

Posted: Tue Apr 28, 2015 7:38 pm
by Killcannon
Be careful that "entity.name" and "entity.id" are two different things. For example, you may have a torch (name = torch) whose id is (for example) "torch_10" because it is the tenth torch spawned in the dungeon. Thus: "dungeonpit1" is the id of the pit (and if you look for findEntity("dungeonpit1") you are going to find the one and only entity with that id since ids are unique in the dungeon), while "dungeonpit" is the name of a generic "dungonpit"; if you are using standard assets, the "name" of the entity should be "dungeon_pit".
The scripts I wrote don't look for the object.id, they look for a match in the object.name.... is it a pit?
There should only be one pit per cell, one pit to find. It searches for a pit, and doesn't care what the id string of the pit happens to be.
Oh! Okay now that makes a ton of sense and explains why it wasn't working with "dungeon_pit" simply because I'm not using default assets for this particular room. Now of course this presents another problem, I have two very similar traps using completely different assets that can be ran using the same script. So for this case I probably should use Alois's code to find the pits for the script:

Code: Select all

if (string.find(x.id,"dungoenpit")) then pit = x end
This brings up a question as well could I possibly in the future when doing this write something like this when calling the entity.names of multiple different assets:

Code: Select all

if x.name == {"dm_floor_pit", "dungeon_pit", "spiked_pit"} then

Re: Spike trap script help

Posted: Tue Apr 28, 2015 7:51 pm
by Isaac
Killcannon wrote:This brings up a question as well could I possibly in the future when doing this write something like this when calling the entity.names of multiple different assets:

Code: Select all

if x.name == {"dm_floor_pit", "dungeon_pit", "spiked_pit"} then
That won't work as typed. It's comparing a string to a table; (not to the specific strings in the table).

If that's what you want, then this will perform it:

Code: Select all

if x.name == "dm_floor_pit" or x.name ==  "dungeon_pit" or x.name ==  "spiked_pit" then
Alternatively, if you had a long list of pit styles, you could use that table as follows:

Code: Select all

    local pits =  {"dm_floor_pit", "dungeon_pit", "spiked_pit"}
    for count = 1,#pits do
       if x.name == pits[count] then
          --instructions...
       end
    end

With correction by alois.
[Good catch, I missed it each time I read the script. :? ]

Note:
The scripts in the demo map search the (specific) cell of the connected trigger plate for pit entities, there should only ever be one pit in the cell to find. Once found, it has the (possibly auto-generated) id of the pit.

Re: Spike trap script help

Posted: Wed Apr 29, 2015 8:22 am
by alois
Just a minor correction in the script above by Isaac (there are two "x"'s)

Code: Select all

local pits =  {"dm_floor_pit", "dungeon_pit", "spiked_pit"}
for count = 1,#pits do
   if x.name == pits[count] then
      --instructions...
   end
end
Alois :)

Re: Spike trap script help

Posted: Thu Apr 30, 2015 1:25 am
by Killcannon
Woot! It works beautifully! Thank you guys so much for your vast help! It's been immense and I appreciate everything that's been done for me. I cannot express enough how much I truly appreciate all the effort you have put in to help me understand and learn how to accomplish my goals. <3 Now, I just need this script to do one more thing. I need it to differentiate between the party and the monsters. ^.~ This one I think I can figure out on my own. <3

I do have other questions though unrelated to this script should I ask them in this thread or just make a new one?

Re: Spike trap script help

Posted: Mon May 04, 2015 6:41 am
by Killcannon
Right so I got a few more questions on problems with some scripts that I've not been able to solve so far. I do apologize in advance too for the multiple problems in a single post; they've been building up as I move from one problem and work on another while researching for a solution to the others. These are ones I've yet to be able to solve in the last few days.


I'm working on a 'gas chamber' sort of trap using lightning bold/shock spells. The problem is it's telling me that it cannot find the object for the spell. From my research here on the forums; you should be able to simply spawn the default spells without having to define them in the script. I guess this is either no longer true or I've missed something in my reading. Where have I gone wrong?
SpoilerShow
function gaschamber()
for i = -1, 1 do
for j = -2, 2 do
if chamberlever:getLeverState() == "activated" then
spawn("lightning bolt", 1, 19 + i, 15 + i, 0)
else
spawn("shock", 1, 19 + j, 15 + j, 0)
end
end
end
end
Another problem I'm facing is if I want a special pit trap to kill only monsters that pass over it when it's open. I have it working for the previous trap that everyone helped me with but for some reason the copied version isn't working. - note the script isn't producing any errors; the monsters I've tested simply fail to die when stepping onto the triggering tile. I also did test and party damage is working fine; it's just not working for monsters.
SpoilerShow
local pit
for x in entitiesAt(caller.level, caller.x, caller.y) do
if x.name == "dm_floor_pit" or x.name == "dungeon_pit" then
pit = x
end

end
if pit:isOpen() then
if entity.class == "monster" then
damageTile(caller.level, caller.x, caller.y, 0, 6, "poison", 9001)
end
end
end
The last one is a bit tricky. I've setup an Alcove that will only accept certain items. Followed by a script that will check if the items are there then open a door. What I want is to be able to have the script check to make sure the right item is in the right alcove. This way instead of having 3 different alcoves defined as seen below. I can have 1 with multiple different items allowed in it; but I'm scratching my head as to how to do so.
SpoilerShow
defineObject{
name = "lightning_hook_alcove",
class = "Alcove",
anchorPos = vec(0, 1.50, -0.1),
targetPos = vec(0, 1.50, -0.1),
targetSize = vec(0.6, 0.5, 0.6),
placement = "wall",
replacesWall = false,
editorIcon = 92,
model = "assets/models/env/metal_hooks_wall.fbx",
onInsertItem = function(self, item)
local allowed = {"lightning_blade", "lightning_blade_empty"}
for i = 1, #allowed do
if item.name == allowed then
return item.name == allowed and self:getItemCount() == 0
end
end
end

}

defineObject{
name = "fire_hook_alcove",
class = "Alcove",
anchorPos = vec(0, 1.50, -0.1),
targetPos = vec(0, 1.50, -0.1),
targetSize = vec(0.6, 0.5, 0.6),
placement = "wall",
replacesWall = false,
editorIcon = 92,
model = "assets/models/env/metal_hooks_wall.fbx",
onInsertItem = function(self, item)
local allowed = {"fire_blade", "fire_blade_empty"}
for i = 1, #allowed do
if item.name == allowed then
return item.name == allowed and self:getItemCount() == 0
end
end
end
}

defineObject{
name = "nex_hook_alcove",
class = "Alcove",
anchorPos = vec(0, 1.50, -0.1),
targetPos = vec(0, 1.50, -0.1),
targetSize = vec(0.6, 0.5, 0.6),
placement = "wall",
replacesWall = false,
editorIcon = 92,
model = "assets/models/env/metal_hooks_wall.fbx",
onInsertItem = function(self, item)
local allowed = {"nex_sword"}
for i = 1, #allowed do
if item.name == allowed then
return item.name == allowed and self:getItemCount() == 0
end
end
end
}


Here's the script thus far:

SpoilerShow
function doorcombo()

local wardenapt = "dm_door_black_1"

wephld = {{"lightning_hook_alcove_1", 1},
{"fire_hook_alcove_1", 1},
{"fire_hook_alcove_2", 1}}


for i = 1, #wephld do
findEntity(wardenapt):close()
if findEntity(wephld[1]):getItemCount() == wephld[2] then
findEntity(wardenapt):open()
else
return nil
end
end
end

Re: Spike trap script help

Posted: Wed May 06, 2015 3:52 am
by Killcannon
So! I figured out the issue I was having with the electric chamber script! This is what I got, I'm sure there's a better way to do this;; but it does what I want. ^.^
SpoilerShow
function gaschamber()

local coords = {}

if chamberlever:getLeverState() == "activated" then
coords = {xcoord = {-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,1,1,1,1,1,2,2,2,2,2},ycoord = {-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,1,2,-2,-1,0,1,2,-2,-1,0,1,2}}
else
coords = {xcoord = {-1,-1,-1,0,0,1,1,1},ycoord = {-1,0,1,-1,1,-1,0,1}}
end

local coord_pairs = math.min(#coords["xcoord"],#coords["ycoord"])

for i = 1,coord_pairs do
spawn("shockburst", 1, 19 + coords["xcoord"], 15 + coords["ycoord"], 0)

end
end