Page 1 of 2

how to destroy item on an altar?

Posted: Thu Dec 25, 2014 4:22 pm
by bongobeat
Hello,

how can I destroy an item on an altar?

I ve trying the code bellow, but that don't work (that's log1 code)
the altar name is "altar_11", the code is part of a script, that spawn and destroy counter, trigger floor and remove a mine_floor
SpoilerShow

Code: Select all

function newcounter()
--spawn("counter",7,10,22,0,0,"counter_7_1")
--counter_7_1.counter:setValue(1)
--counter_7_1.counter:addConnector("onActivate", "script_entity_72", "toolate")
--spawn("floor_trigger",7,17,23,0,0,"floor_trigger_7_1")
--floor_trigger_7_1.floortrigger:setTriggeredByParty(true)
--floor_trigger_7_1.floortrigger:setTriggeredByMonster(false)
--floor_trigger_7_1.floortrigger:setTriggeredByItem(false)
--floor_trigger_7_1.floortrigger:setTriggeredByDigging(false)
--floor_trigger_7_1.floortrigger:setDisableSelf(false)
--floor_trigger_7_1.floortrigger:addConnector("onActivate", "counter_7_1", "decrement")
--	if findEntity("mine_floor_01_5") ~= nil then
--	mine_floor_01_5:destroy()
--	end
	if findEntity("altar_11") ~= nil then
	for i in altar_11:containedItems() do
	i:destroy()
	end
altar_11.surface:addItem(spawn("note_relic_stolen").item)
end


Re: how to destroy item on an altar?

Posted: Thu Dec 25, 2014 4:45 pm
by MrChoke
Try the code below

Code: Select all

function newcounter()
   if findEntity("altar_11") ~= nil then
       for ent in altar_11.surface:contents() do
          ent:destroy()
       end
   end
   altar_11.surface:addItem(spawn("note_relic_stolen").item)
end


Re: how to destroy item on an altar?

Posted: Thu Dec 25, 2014 9:02 pm
by bongobeat
thanks for help:

it does not work, I got an error "attempt to call local 'ent' (a number value) X"

Re: how to destroy item on an altar?

Posted: Fri Dec 26, 2014 3:03 am
by Eleven Warrior
Hi Bongo here is a Script you can have lots of item on a Alcove or Altar eg To open the door you may have to put 3 x rocks on it and then the door opens or anything you want to happen :) Have fun man.

Code: Select all

function getSurface(alcove)
      if type(alcove) == "string" then alcove = findEntity(alcove) end
      if alcove == nil then return nil end
      return alcove.surface or alcove.go.surface
    end
function destroyItems(alcove)
      local surf = getSurface(alcove)
      if surf == nil then return false end
      if surf:count()>0 then 
        local it = {}
        for _,i in surf:contents() do
          table.insert(it,i.go.id)
        end
        for i = 1,#it do
          findEntity(it[i]):destroy()
        end
      end
    end

function checkItems(alcove)  --- Connect Altar or Alcove to this function ---
      surf = getSurface(alcove)
      if surf == nil then return false end
      local ent,c
      local list = {"rock", "rock"} --- The list of Item required to do something ---

      table.sort(list)
      local inv = table.concat(list,",")
      local alcoved = {}
      for _,ent in surf:contents() do
        local count = ent:getStackSize()
        if count == 0 then count = 1 end
        for c = 1, count do
          table.insert(alcoved,ent.go.name)
        end
      end
      table.sort(alcoved)
      local alc = table.concat(alcoved,",")
      if inv == alc then

----------------------------------
-- Your  functions go here --
----------------------------------

dungeon_door_iron_barred_3.door:open()

        destroyItems(alcove) --- destroys the item ----
        return true
      end
      return false
    end

Re: how to destroy item on an altar?

Posted: Fri Dec 26, 2014 3:20 am
by MrChoke
bongobeat wrote:thanks for help:

it does not work, I got an error "attempt to call local 'ent' (a number value) X"
Sorry about that. The contents() function required a go param. This code works:

Code: Select all

function newcounter()
   if findEntity("altar_11") ~= nil then
       for i, ent in altar_11.surface:contents() do
          ent.go:destroy()
       end
   end
   altar_11.surface:addItem(spawn("note_relic_stolen").item)
end

Re: how to destroy item on an altar?

Posted: Fri Dec 26, 2014 4:22 pm
by bongobeat
MrChoke wrote:
bongobeat wrote:thanks for help:

it does not work, I got an error "attempt to call local 'ent' (a number value) X"
Sorry about that. The contents() function required a go param. This code works:

Code: Select all

function newcounter()
   if findEntity("altar_11") ~= nil then
       for i, ent in altar_11.surface:contents() do
          ent.go:destroy()
       end
   end
   altar_11.surface:addItem(spawn("note_relic_stolen").item)
end
works well now, thanks :D

Re: how to destroy item on an altar?

Posted: Fri Dec 26, 2014 4:26 pm
by bongobeat
Eleven Warrior wrote:Hi Bongo here is a Script you can have lots of item on a Alcove or Altar eg To open the door you may have to put 3 x rocks on it and then the door opens or anything you want to happen :) Have fun man.

Code: Select all

function getSurface(alcove)
      if type(alcove) == "string" then alcove = findEntity(alcove) end
      if alcove == nil then return nil end
      return alcove.surface or alcove.go.surface
    end
function destroyItems(alcove)
      local surf = getSurface(alcove)
      if surf == nil then return false end
      if surf:count()>0 then 
        local it = {}
        for _,i in surf:contents() do
          table.insert(it,i.go.id)
        end
        for i = 1,#it do
          findEntity(it[i]):destroy()
        end
      end
    end

function checkItems(alcove)  --- Connect Altar or Alcove to this function ---
      surf = getSurface(alcove)
      if surf == nil then return false end
      local ent,c
      local list = {"rock", "rock"} --- The list of Item required to do something ---

      table.sort(list)
      local inv = table.concat(list,",")
      local alcoved = {}
      for _,ent in surf:contents() do
        local count = ent:getStackSize()
        if count == 0 then count = 1 end
        for c = 1, count do
          table.insert(alcoved,ent.go.name)
        end
      end
      table.sort(alcoved)
      local alc = table.concat(alcoved,",")
      if inv == alc then

----------------------------------
-- Your  functions go here --
----------------------------------

dungeon_door_iron_barred_3.door:open()

        destroyItems(alcove) --- destroys the item ----
        return true
      end
      return false
    end
Hey Eleven,
thanks for it :D

Re: how to destroy item on an altar?

Posted: Wed Jan 07, 2015 12:01 am
by bongobeat
Hey all,

I have 2 issues while trying to destroy items on an altar:

I have defined the mine_weight_platform as an altar:
SpoilerShow

Code: Select all

defineObject{
	name = "mine_counterweight_platform_alcove_lower",
	baseObject = "base_altar",
	components = {
		{
			class = "Model",
			model = "assets/models/env/mine_counterweight_platform_01.fbx",
			staticShadow = true,
			offset = vec(0, -0.4, 0),
		},
		{
			class = "Surface",
			offset = vec(0, 0.5, 0),
			size = vec(1, 1, 1),
			--debugDraw = true,
		},
	},
	minimalSaveState = true,
	automapIcon = 152,
}
then I call this script with a button (to test)
it (should) destroy items, destroy the altar, and spawn another type of altar
SpoilerShow

Code: Select all

function newplatform()
--
  if findEntity("platform_low_22_1") ~= nil then
       for i, ent in platform_low_22_1.surface:contents() do
          ent.go:destroy()
       end
   end
--
	if findEntity("platform_low_22_1") ~= nil then
	platform_low_22_1:destroy()
	end
spawn("mine_counterweight_platform_alcove",22,17,17,0,0,"platform_22_1")
--
end
I don't understand, sometimes there are items remaining on the altars, I thought that all items would be destroyed?!

I have placed 17 rocks on the altar: after calling the script, all rocks were destroyed.
I have placed 2 boulders (it is the boulder from dungeon master set), only one seems to be destroyed, I can't tell, because if I click I got the error message below.
I have placed 2 boulders, 2 meteorites, 17 rocks, seems that the meteorite and the rocks were not destroyed.
and if I click on the new altar I got this error message (except for the rock):
SpoilerShow
Image
I'm going crazy :x

please can someone help?

Re: how to destroy item on an altar?

Posted: Wed Jan 07, 2015 12:17 am
by minmay
You should not destroy items on a surface while iterating over that surface's contents. This is what is causing your problem. Call ent.go:destroyDelayed() instead of ent.go:destroy(), and the items will be destroyed later on the frame, after the loop has finished.

Generally when using an iterator you should assume that changing the state of the array or table you're iterating over is unsafe and you shouldn't do it, unless you wrote the iterator yourself.

Re: how to destroy item on an altar?

Posted: Wed Jan 07, 2015 11:04 am
by bongobeat
thanks :D

well I started to think of another way with this platform, without destroying the items and the altar.
But now it works great with your help.