Page 1 of 1

Spawning a script?

Posted: Fri Sep 13, 2013 6:48 am
by Hustin
It's too bad this doesn't work as it would allow making the alcove's behavior entirely self-contained. It doesn't blow up, though; it simply never triggers the script. Am I doing something wrong?

If I put fill() in a script that's in the editor it works, though. Weird...

The only other way I can think of that would allow making everything self-contained would be to attach the behavior to a special monster's onDie(), then spawn it and quickly kill it. That seems like a real hack, though...
SpoilerShow

Code: Select all

defineObject
{
  name = "fountain_alcove",
  class = "Alcove",
  anchorPos = vec(0, 0.2, 0.38),
  targetPos = vec(0, 0.2, 0.38),
  targetSize = vec(0.75, 0.15, 0.75),
  placement = "wall",
  replacesWall = false,
  editorIcon = 92,
  onInsertItem = function(self, item)
    i, j = string.find(item.name, "_key")
    k, m = string.find(item.name, "_gem")

    if (item.name == "flask") and (self:getItemCount() == 0) then

      f = findEntity("fountain_alcove_script")
      t = findEntity("fountain_alcove_timer")
      if f == nil then

        hudPrint("spawning script")

        spawn("script_entity", party.level, party.x, party.y, 0, "fountain_alcove_script")
          :setSource("function fill()\
            hudPrint(\"fill()\")\
            for e in allEntities(party.level) do\
              if e.name == \"fountain_alcove\" then\
                for i in e:containedItems() do\
                  if i.name == \"flask\" then\
                    i:destroy()\
                    e:addItem(spawn(\"water_flask\"))\
                  end\
                end\
              end\
            end\
          end")
      end

      if t == nil then
        hudPrint("spawning timer")
        spawn("timer", party.level, party.x, party.y, 0, "fountain_alcove_timer")
          :setTimerInterval(1)
          :addConnector("activate", "fountain_alcove_script", "fill")
          :addConnector("activate", "fountain_alcove_timer", "deactivate")
      end

      f = findEntity("fountain_alcove_script")
      t = findEntity("fountain_alcove_timer")

      hudPrint("activating timer")

      t:deactivate()
      t:activate()
    end

    return (((i ~= nil) and (j == string.len(item.name))) or
            ((k ~= nil) and (m == string.len(item.name))) or
            (item.name == "rock") or
            (item.name == "quartz") or
            (item.name == "flask") or
            (item.name == "water_flask") or
            (item.name == "shuriken"))
           and (self:getItemCount() == 0)
  end,
}
This works if I make sure 0,0,1 is not accessible and not within earshot of any fountains, but it's a hack...
SpoilerShow

Code: Select all

cloneObject
{
  name = "fountain_alcove_trigger_monster",
  baseObject = "snail",
  healthIncrement = 1,
  onDie = function(self)
    hudPrint("fill()")
    for e in allEntities(party.level) do
      if e.name == "fountain_alcove" then
        for i in e:containedItems() do
          if i.name == "flask" then
            i:destroy()
            e:addItem(spawn("water_flask"))
          end
        end
      end
    end
    t = findEntity("fountain_alcove_timer")
    if t ~= nil then
      t:deactivate()
    end
    return true
  end
}

defineObject
{
  name = "fountain_alcove",
  class = "Alcove",
  anchorPos = vec(0, 0.2, 0.38),
  targetPos = vec(0, 0.2, 0.38),
  targetSize = vec(0.75, 0.15, 0.75),
  placement = "wall",
  replacesWall = false,
  editorIcon = 92,
  onInsertItem = function(self, item)
    i, j = string.find(item.name, "_key")
    k, m = string.find(item.name, "_gem")

    if (item.name == "flask") and (self:getItemCount() == 0) then

      f = findEntity("fountain_alcove_trigger1")
      g = findEntity("fountain_alcove_trigger2n")
      t = findEntity("fountain_alcove_timer")
      if f == nil then

        hudPrint("spawning trigger 1")

        spawn("fountain_alcove_trigger_monster", 1, 0, 0, 0, "fountain_alcove_trigger1")
      end

      if g == nil then

        hudPrint("spawning trigger 2")

        spawn("spawner", 1, 0, 0, 0, "fountain_alcove_trigger2n")
          :setSpawnedEntity("fireball_greater")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 1, "fountain_alcove_trigger2e")
          :setSpawnedEntity("fireball_greater")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 2, "fountain_alcove_trigger2s")
          :setSpawnedEntity("fireball_greater")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 3, "fountain_alcove_trigger2w")
          :setSpawnedEntity("fireball_greater")
          :setCoolDown(0)
      end

      if t == nil then

        hudPrint("spawning timer")

        spawn("timer", 1, 0, 0, 0, "fountain_alcove_timer")
          :setTimerInterval(0.05)
          :addConnector("activate", "fountain_alcove_trigger2n", "activate")
          :addConnector("activate", "fountain_alcove_trigger2e", "activate")
          :addConnector("activate", "fountain_alcove_trigger2s", "activate")
          :addConnector("activate", "fountain_alcove_trigger2w", "activate")
      end

      t = findEntity("fountain_alcove_timer")

      hudPrint("activating timer")

      t:deactivate()
      t:activate()
    end

    return (((i ~= nil) and (j == string.len(item.name))) or
            ((k ~= nil) and (m == string.len(item.name))) or
            (item.name == "rock") or
            (item.name == "quartz") or
            (item.name == "flask") or
            (item.name == "water_flask") or
            (item.name == "shuriken"))
           and (self:getItemCount() == 0)
  end,
}
Edit: a refined version that eliminates sound issues.
SpoilerShow

Code: Select all

defineSpell
{
  name = "silent_killer",
  uiName = "Silent Killer",
  skill = "spellcraft",
  level = 7,
  runes = nil,
  manaCost = 22,
  onCast = function(champ, x, y, direction, skill)
    damageTile(1, 0, 0, 0, 64, "physical", 10000)
  end
}

defineSound{
  name = "silent_killer",
  filename = "assets/samples/magic/fireburst_01.wav",
  loop = false,
  volume = 0,
  minDistance = 1,
  maxDistance = 1,
}

defineObject{
  name = "silent_killer",
  class = "BurstSpell",
  particleSystem = "glitter_silver",
  lightColor = vec(0, 0, 0),
  lightBrightness = 0,
  lightRange = 0,
  sound = "silent_killer",
  attackPower = 10000,
  damageType = "physical",
  tags = { "spell" },
}

cloneObject
{
  name = "fountain_alcove_trigger_monster",
  baseObject = "snail",
  healthIncrement = 1,
  health = 1,
  moveSound = "",
  attackSound = "",
  hitSound = "",
  dieSound = "",
  hitEffect = "",
  onDie = function(self)
    hudPrint("fill()")
    for e in allEntities(party.level) do
      if e.name == "fountain_alcove" then
        for i in e:containedItems() do
          if i.name == "flask" then
            i:destroy()
            e:addItem(spawn("water_flask"))
          end
        end
      end
    end
    t = findEntity("fountain_alcove_timer")
    if t ~= nil then
      t:deactivate()
    end
    return true
  end
}

defineObject
{
  name = "fountain_alcove",
  class = "Alcove",
  anchorPos = vec(0, 0.2, 0.38),
  targetPos = vec(0, 0.2, 0.38),
  targetSize = vec(0.75, 0.15, 0.75),
  placement = "wall",
  replacesWall = false,
  editorIcon = 92,
  onInsertItem = function(self, item)
    i, j = string.find(item.name, "_key")
    k, m = string.find(item.name, "_gem")

    if (item.name == "flask") and (self:getItemCount() == 0) then

      f = findEntity("fountain_alcove_trigger1")
      g = findEntity("fountain_alcove_trigger2n")
      t = findEntity("fountain_alcove_timer")
      if f == nil then

        hudPrint("spawning trigger 1")

        spawn("fountain_alcove_trigger_monster", 1, 0, 0, 0, "fountain_alcove_trigger1")
      end

      if g == nil then

        hudPrint("spawning trigger 2")

        spawn("spawner", 1, 0, 0, 0, "fountain_alcove_trigger2n")
          :setSpawnedEntity("silent_killer")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 1, "fountain_alcove_trigger2e")
          :setSpawnedEntity("silent_killer")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 2, "fountain_alcove_trigger2s")
          :setSpawnedEntity("silent_killer")
          :setCoolDown(0)
        spawn("spawner", 1, 0, 0, 3, "fountain_alcove_trigger2w")
          :setSpawnedEntity("silent_killer")
          :setCoolDown(0)
      end

      if t == nil then

        hudPrint("spawning timer")

        spawn("timer", 1, 0, 0, 0, "fountain_alcove_timer")
          :setTimerInterval(0.05)
          :addConnector("activate", "fountain_alcove_trigger2n", "activate")
          :addConnector("activate", "fountain_alcove_trigger2e", "activate")
          :addConnector("activate", "fountain_alcove_trigger2s", "activate")
          :addConnector("activate", "fountain_alcove_trigger2w", "activate")
      end

      t = findEntity("fountain_alcove_timer")

      hudPrint("activating timer")

      t:deactivate()
      t:activate()
    end

    return (((i ~= nil) and (j == string.len(item.name))) or
            ((k ~= nil) and (m == string.len(item.name))) or
            (item.name == "rock") or
            (item.name == "quartz") or
            (item.name == "flask") or
            (item.name == "water_flask") or
            (item.name == "shuriken"))
           and (self:getItemCount() == 0)
  end,
}
Edit: Less hack-y (and maybe more reliable)solution that spawns a very fast and silent door instead. It also doesn't require that the area at 0, 0, 1 be empty, just inaccessible.
SpoilerShow

Code: Select all

defineSound{
  name = "silent",
  filename = "assets/samples/magic/fireburst_01.wav",
  loop = false,
  volume = 0,
  minDistance = 1,
  maxDistance = 1,
}

defineObject{
  name = "fountain_alcove_trigger_door",
  class = "Door",
  hidden = true,
  model = "assets/models/env/door_portcullis.fbx",
  doorFrameModel = "assets/models/env/dungeon_door_frame.fbx",
  pullChainModel = "assets/models/env/door_pullchain.fbx",
  pullChainAnim = "assets/animations/env/door_pullchain.fbx",
  openSound = "silent",
  closeSound = "silent",
  lockSound = "silent",
  killPillars = true,
  openVelocity = 100,
  closeVelocity = -100,
  closeAcceleration = -10,
  sparse = true,
  placement = "wall",
  editorIcon = 124,
  onOpen = function(self)
    hudPrint("fill()")
    for e in allEntities(party.level) do
      if e.name == "fountain_alcove" then
        for i in e:containedItems() do
          if i.name == "flask" then
            i:destroy()
            e:addItem(spawn("water_flask"))
          end
        end
      end
    end
    t = findEntity("fountain_alcove_timer")
    if t ~= nil then
      t:deactivate()
    end
    return true
  end,
}

defineObject
{
  name = "fountain_alcove",
  class = "Alcove",
  anchorPos = vec(0, 0.2, 0.38),
  targetPos = vec(0, 0.2, 0.38),
  targetSize = vec(0.75, 0.15, 0.75),
  placement = "wall",
  replacesWall = false,
  editorIcon = 92,
  onInsertItem = function(self, item)
    i, j = string.find(item.name, "_key")
    k, m = string.find(item.name, "_gem")

    if (item.name == "flask") and (self:getItemCount() == 0) then

      f = findEntity("fountain_alcove_trigger")
      t = findEntity("fountain_alcove_timer")
      if f == nil then

        hudPrint("spawning trigger")

        spawn("fountain_alcove_trigger_door", 1, 0, 0, 0, "fountain_alcove_trigger")
      end

      if t == nil then

        hudPrint("spawning timer")

        spawn("timer", 1, 0, 0, 0, "fountain_alcove_timer")
          :setTimerInterval(0.05)
          :addConnector("activate", "fountain_alcove_trigger", "open")
          :addConnector("activate", "fountain_alcove_trigger", "close")
      end

      t = findEntity("fountain_alcove_timer")

      hudPrint("activating timer")

      t:deactivate()
      t:activate()
    end

    return (((i ~= nil) and (j == string.len(item.name))) or
            ((k ~= nil) and (m == string.len(item.name))) or
            (item.name == "rock") or
            (item.name == "quartz") or
            (item.name == "flask") or
            (item.name == "water_flask") or
            (item.name == "shuriken"))
           and (self:getItemCount() == 0)
  end,
}