Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - wizard_wizzle (aka ZeldaHistorian)

#21
Development / Thought experiment: Beamos
July 29, 2015, 03:58:13 AM
Hi all!

I'd really like to include beamos in my game, and I think other people might too - but it's a little too high level to wrap my head around. So, I thought I'd present the idea to the community and see what we can come up with!

The beamos statue is easy, you'd want a sprite with 8 directions so it can follow the hero, then just check and see when the hero is too close and start firing a beam. The beam itself is where it gets tricky! My thought is that the beam would an enemy breed of its own which is generated by the beamos statue (probably in a continuous stream). What I'm thinking of is an 8x8 sprite that can be created over and over again so that the beam can go in any direction. They move toward the hero in a line (somehow) and terminate being generated after a certain time. I'm not entirely sure how to implement this though...

Maybe I'm over (or under) thinking this and there's a better way? Let's brainstorm! :)
#22
Bugs & Feature requests / Segmentation fault?
July 06, 2015, 04:41:33 AM
I have a new bug that's popped up in my game, and I'm not sure if it's an engine problem or something else. I have the following code in one of my dungeons, and when it gets to this point in the game, it crashes with a Segmentation Fault:

for enemy in map:get_entities("keese") do
  enemy.on_dead = function()
    if not map:has_entities("keese_rupees") and not game:get_value("b1119") then
      chest_rupees:set_enabled(true)
      bridge_rupees:set_enabled(true)
      sol.audio.play_sound("chest_appears")
    end
  end
end


I haven't changed anything with this code recently, and the fault would've just started appearing in Solarus 1.4.2. Any ideas?
#23
Development / Side scrolling functionality
June 25, 2015, 04:24:13 AM
As a proof-of-concept, I've been figuring out how to build side-scrolling functionality with Solarus (like the sections of Link's Awakening). I can get jumping, gravity and movement pretty well down, but the part I can't figure out is enemy collisions.

I'd like to have it work like Mario where if you jump on certain enemy's heads, they are hurt, but I can't figure out how to detect that the hero has touched only the top of the enemy. If the hero touched the side of the enemy, the hero should be hurt.

I'm guessing that this can't be accomplished with the built-in enemy class, but even with a custom entity and add_collision_test(), I don't see how to detect what was touching what.

EDIT (1/18/21): Don't use this - it's old and there are much better versions out there now. Check out the one PhoenixII54 posted on 1/18/21.
https://gitlab.com/zeldaforce/zelda-alttd/-/blob/dev/data/scripts/maps/sideview_manager.lua
#24
Development / Item is not saved
June 09, 2015, 03:03:56 AM
Occasionally  I've gotten error messages like the following while running my game:

Error: In on_started: [string "items/arrow.lua"]:13: Item 'bow' is not saved
Error: In on_started: [string "hud/rupees.lua"]:26: Item 'rupee_bag' is not saved

It doesn't seem to happen all of the time, and sometimes the "Item" mentioned is different. These items are calling self:set_savegame_variable() in their on_created() functions. Is there something else I'm doing wrong?
#25
Development / Collision tests and movement
April 10, 2015, 05:01:22 PM
I have the snippet of code below where I'm essentially trying to re-create block pushing in a custom entity (in order to additional functionality for the block). The problem I'm having having is that the block doesn't start moving until after the hero has stopped pushing and has moved away from the block - rather than actually pushing the block. Is this the expected behavior and I'm doing something wrong? Is there a way to have the movement start as the hero is pushing?

  self:add_collision_test("touching", function(self, other)

    if other:get_type() == "hero" then
      local m = sol.movement.create("path")
      m:set_ignore_obstacles(true)
      m:set_snap_to_grid(true)

      if other:get_direction() == 0 then m:set_path({0,0})
      elseif other:get_direction() == 1 then m:set_path({2,2})
      elseif other:get_direction() == 2 then m:set_path({4,4})
      elseif other:get_direction() == 3 then m:set_path({6,6}) end
      m:start(self)
#26
Development / Hookshot
February 17, 2015, 04:20:07 AM
Is it defined in the API what entities the hookshot attaches to? What's the best way to force the hookshot to attach to a tile or entity, or is this even possible?
#27
How would someone recommend implementing moving platforms (over water or holes only) in Solarus? I've tried a dynamic tile with movement applied, but I can only get it to traverse what the hero could and not water. I've tried a custom entity, but I can't get it to be traversable by the hero - if the platform sits on water, the hero just jumps into the water rather than walking on the platform. I'm probably just doing something wrong, but was hoping for some direction either way.
#28
Development / Quicksand custom entity
January 19, 2015, 04:38:08 PM
I'm looking to make a custom entity which behaves like quicksand (think Link to the Past's desert temple) - when the hero approaches it, he's slowly dragged into the center, then when he reached the center, he sinks (behavior like a hole, probably). I can't seem to figure it out. Any thoughts?

This is what I have so far, which isn't even close to working:
local entity = ...
local map = entity:get_map()
local hero = map:get_entity("hero")

-- Quicksand: entity which slows the hero until
-- he finally falls in

function entity:on_created()
  self:create_sprite("entities/quicksand")
  self:set_size(32, 32)
  self:set_origin(16, 16)
  ex, ey, el = self:get_position()
  self:get_sprite():set_animation("quicksand")
end

function entity:on_update()
  self:add_collision_test("overlapping", function()
    if hero:get_walking_speed() >= 8 then hero:set_walking_speed(hero:get_walking_speed()-1) end
    m = sol.movement.create("target")
    m:set_target(ex, ey)
    m:start(hero)
  end)
end
#29
Bugs & Feature requests / cmake error on Ubuntu
August 23, 2014, 03:34:18 PM
When I go to compile solarus 1.3, I get a cmake error stating that OPENAL can't be found, but according to my system it's installed. Is something wrong with cmake or my system? I've compiled before, so unless something has changed, I'm confused  :-\

Error output:
CMake Error at /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:108 (message):
  Could NOT find OpenAL (missing: OPENAL_LIBRARY)
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:315 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-2.8/Modules/FindOpenAL.cmake:97 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:18 (find_package)


OPENAL installation:
sudo apt-get install libopenal*
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'libopenais2' for regex 'libopenal*'
Note, selecting 'libopenais-dev' for regex 'libopenal*'
Note, selecting 'libopenal0a' for regex 'libopenal*'
Note, selecting 'libopenal-dev' for regex 'libopenal*'
Note, selecting 'libopenal1' for regex 'libopenal*'
Note, selecting 'libopenafs-dev' for regex 'libopenal*'
Note, selecting 'libopenal-data' for regex 'libopenal*'
Note, selecting 'libopenais-legacy-dev' for regex 'libopenal*'
libopenafs-dev is already the newest version.
libopenal-data is already the newest version.
libopenal-dev is already the newest version.
libopenal1 is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.
#30
Your projects / Zelda: Book of Mudora
August 08, 2014, 01:53:58 AM
My full Zelda game, Book of Mudora, is done! The release includes Solarus 1.5(.1), the pre-release that Christopho posted to fix the software surface memory leak) for Windows, and other platforms are available at http://www.solarus-games.org/

Download: https://sites.google.com/site/zeldabom/download

Trailer: https://www.youtube.com/watch?v=wk13ltcilDM

Thanks everyone for your help, and enjoy!
#31
Development / Particle system
June 07, 2014, 07:55:06 AM
I've been playing around with the idea of creating a particle system in pure Lua that can run on the Solarus engine. Unfortunately, I'm pretty new to Lua and the draft that I'm working on now doesn't appear to be working. I think the idea behind it is sound, but I can't get it to display correctly so I can test it!

particles.lua (based off of a Love engine particle system, found at https://github.com/SimonLarsen/sienna/blob/master/particles.lua)
local particle_system = {}

function particle_system:new(game)
  local object = {}
  setmetatable(object, self)
  self.__index = self
  object:initialize(game)
  return object
end

function particle_system:initialize(game)
  self.game = game
  if not self.time then self.time = 1 end
  if not self.count then self.count = 5 end
  if not self.color then self.color = {255, 255, 255} end

  if self.type == "sparkle" then
    self.alive = true
    self.particles = {}
    for i=1, self.count do
      self.particles[i] = {}
      self.particles[i].x = x
      self.particles[i].xspeed = math.random(-100,100)
      self.particles[i].y = y
      self.particles[i].yspeed = math.random(-200,50) + (self.ysp or 0)
    end
    return self
  elseif self.type == "dust" then
    self.alive = true
    self.time = 0
    self.x = x
    self.y = y
    return self
  end
end

function particle_system:on_update()
  self.time = self.time - 1

  if self.type == "sparkle" then
    if self.time < 0 then
      self.alive = false
      return
    end
    for i,v in ipairs(self.particles) do
      v.x = v.x + v.xspeed*dt
      v.yspeed = v.yspeed + 500*dt
      v.y = v.y + v.yspeed*dt
    end
  elseif self.type == "dust" then
    if self.time > 0.25 then
      self.alive = false
      return
    end
  end
end

function particle_system:on_draw(dst_surface)
  if self.type == "sparkle" then
    for i,v in ipairs(self.particles) do
      dst_surface:fill_color(self.color, 0.5+v.x, 0.5+v.y, 1, 1)
    end
  elseif self.type == "dust" then
    dst_surface:fill_color(self.color, self.x-self.time*16, self.y-self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x+self.time*16, self.y-self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x-self.time*16, self.y+self.time*16, 1, 1)
    dst_surface:fill_color(self.color, self.x+self.time*16, self.y+self.time*16, 1, 1)
  else
    dst_surface:clear()
  end
end

function particle_system:set_type(type)
  self.type = type
end

function particle_system:set_position(x, y, layer)
  self.x = x
  self.y = y
  self.layer = layer or 1
end

function particle_system:set_particle_count(count)
  self.count = count
end

function particle_system:set_particle_color(color)
  self.color = color
end

function particle_system:set_decay_time(time)
  self.time = time
end

function particle_system:set_y_speed(ysp)
  self.ysp = ysp
end

return particle_system


An example map script:
local map = ...
local game = map:get_game()
local particle_system = require("particles")

function sensor:on_activated()
  local emitter = particle_system:new(game)
  emitter:set_type("sparkle")
  emitter:set_position(100, 100)
end

function map:on_update()
  if emitter ~= nil then emitter:on_update() end
end

function map:on_draw(dst_surface)
  if emitter ~= nil then emitter:on_draw(dst_surface) end
end


Any thoughts? Is this a lost cause or am I just way off base?
#32
Development / Referencing global timers
May 18, 2014, 09:07:11 PM
If I have a timer that I've declared in the "game" context, and my character moves to a different map while the timer is still active, I can't figure out how to reference that timer.


race_timer = sol.timer.start(game, 140000, end_race_lost)
race_timer:set_with_sound(true)


Timer declared as above. I know the timer is still active when the map changes because the sound still plays. I also have the time displayed on screen using race_timer:get_remaining_time(). When the hero changes maps, the timer display disappears.


  if race_timer ~= nil then
    function map:on_draw(dst_surface)
      local timer_icon = sol.surface.create("hud/timer.png")
      local timer_time = race_timer:get_remaining_time() / 1000
      local timer_text = sol.text_surface.create{
        font = "white_digits",
        horizontal_alignment = "left",
        vertical_alignment = "top",
      }
      timer_icon:draw(dst_surface, 20, 55)
      timer_text:set_text(timer_time)
      timer_text:draw(dst_surface, 40, 60)
    end
  end


The display is disappearing because the timer reference goes to nil, which I'm intentionally checking for. If I comment out the check, I get an error message of "attempt to index global 'race_timer' (a nil value), but the value shouldn't be nil since the timer is in a "game" context, right? Should I be referencing it a different way, or is this a bug in the engine?
#33
Development / Tips for cutscenes
April 23, 2014, 01:24:51 AM
I'm wondering if anyone has ideas on how to implement cutscenes in Solarus?

Unless I'm missing something in the documentation, it appears that the only option for moving the camera is with map:move_camera which always returns to the hero after the delay is completed - otherwise the engine always centers the camera on the hero.

Is there some trick to center the camera on a different entity, such as an NPC, so RPG-like cutscenes could be created? I even tried making the hero invisible, moving him to the area where the action was taking place and then moving him back and making him visible again after the scene was over, but I couldn't get it to work correctly.
#34
Development / HUD Script: Small Keys (ALBW Style)
March 19, 2014, 02:18:49 AM
If anyone's interested, I modified the small keys script provided by christopho in zsdx to display the keys in a manner more consistent with A Link Between Worlds rather than A Link to the Past. By that, I mean that keys are displayed as a number of small icons (consistent with the number of keys obtained) rather than a small key icon and a number.

-- Allows small keys to be displayed on maps with small keys enabled.
-- Done in ALBW style, a key icon is shown for each key obtained (no counter or icon)

local small_keys = {}

function small_keys:new(game)
  local object = {}
  setmetatable(object, self)
  self.__index = self

  object:initialize(game)
  return object
end

function small_keys:initialize(game)
  local nb_keys_displayed = 0

  self.game = game
  self.visible = false
  self.surface = sol.surface.create(80, 16)

  self:check()
  self:rebuild_surface()
end

function small_keys:check()
  local need_rebuild = false

  -- Check the number of small keys.
  if self.game:are_small_keys_enabled() then
    local nb_keys = self.game:get_num_small_keys()
    if nb_keys_displayed ~= nb_keys then
      need_rebuild = true
    end
  end

  local visible = self.game:are_small_keys_enabled()
  if visible ~= self.visible then
    self.visible = visible
    need_rebuild = true
  end

  -- Redraw the surface is something has changed.
  if need_rebuild then
    self:rebuild_surface()
  end

  -- Schedule the next check.
  sol.timer.start(self.game, 40, function()
    self:check()
  end)
end

function small_keys:rebuild_surface()
  self.surface:clear()
  if self.game:are_small_keys_enabled() then
    for i=0,self.game:get_num_small_keys()-1 do
      self.icon_img = sol.surface.create("hud/small_key.png")
      self.icon_img:draw(self.surface,i*14)
      if nb_keys_displayed ~= nil then
        nb_keys_displayed = nb_keys_displayed + 1
      else
        nb_keys_displayed = 1
      end
    end
  end
end

function small_keys:set_dst_position(x, y)
  self.dst_x = x
  self.dst_y = y
end

function small_keys:on_draw(dst_surface)
  if self.visible then
    local x, y = self.dst_x, self.dst_y
    local width, height = dst_surface:get_size()
    if x < 0 then
      x = width + x
    end
    if y < 0 then
      y = height + y
    end
    self.surface:draw(dst_surface, x, y)
  end
end

return small_keys


Feel free to use as you wish! I also modified hud/hud.lua to display the small keys at the bottom left above the rupees like they are in ALBW. The script also uses a small key icon of your choice in sprites/hud/small_key.png
#35
Development / Help: Enemy disappearing
March 19, 2014, 02:13:40 AM
Hoping for a little help on one of my bosses. For some reason he keeps disappearing when that's not what I'm intending with my script, so I must be missing something. It seems to happen primarily as he's finishing the "opening" phase.

Enemy script:
local enemy = ...

-- Gohma: Boss who has to be shot in the eye with an arrow to be hurt

function enemy:on_created()
  self:set_life(9)
  self:set_damage(2)
  self:create_sprite("enemies/gohma")
  self:set_hurt_style("boss")
  self:set_size(64, 32)
  self:set_origin(32, 29)
  self:set_attack_consequence("sword", "protected")
  self:get_sprite():set_animation("walking")
end

function enemy:check_action()
  local action = math.random(10)
  if self:get_life() > 6 then
    -- first phase: if less than three hits then mostly just move around (slowly), and create tektites
    local son_name = self:get_name().."_son"
    self:create_enemy{
      name = son_name,
      breed = "tektite_green",
      treasure_name = "heart"
    }
    if action >= 1 and action <= 7 then self:go(96) else self:blink() end
  elseif self:get_life() > 3 and self:get_life() <= 6 then
    -- second phase: if more than 3 but less than 6 hits then blink a lot more, and create tektites
    if action >= 1 and action <= 7 then self:blink() else self:go(96) end
    local son_name = self:get_name().."_son"
    self:create_enemy{
      name = son_name,
      breed = "tektite_green"
    }
  elseif self:get_life() < 3 and self:get_life() > 0 then
    -- final phase: if more than 6 hits then move a lot faster, and create tektites!
    if action >= 1 and action <= 6 then self:blink() else self:go(128) end
    local son_name = self:get_name().."_son"
    self:create_enemy{
      name = son_name,
      breed = "tektite_green"
    }
  end
  sol.timer.start(self, 100, function() self:open() end)
end

function enemy:go(speed)
  self:get_sprite():set_animation("walking")
  self:set_attack_consequence("arrow", 1)
  local m = sol.movement.create("random")
  m:set_speed(speed)
  m:set_max_distance(24)
  m:start(self)
end

function enemy:blink()
  self:set_attack_consequence("arrow", "protected")
  self:get_sprite():set_animation("blinking")
end

function enemy:open()
  self:set_attack_consequence("arrow", 1)
  self:get_sprite():set_animation("opening")
end

function enemy:on_restarted()
  self:get_sprite():set_animation("walking")
  self:check_action()
end

function enemy:on_obstacle_reached()
  self:check_action()
end

function enemy:on_animation_finished(sprite, animation)
  self:set_attack_consequence("arrow", "protected")
  if animation == "blinking" then
    self:get_sprite():set_animation("closed")
    sol.timer.start(self, random(6)*1000, function() self:open() end)
    self:go(64)
  elseif animation == "opening" then
    self:get_sprite():set_animation("walking")
    sol.timer.start(self, 1000, function() self:check_action() end)
  end
end


Sprite file:
animation{
  name = "walking",
  src_image = "enemies/gohma.png",
  frame_delay = 200,
  frame_to_loop_on = 0,
  directions = {
    { x = 0, y = 128, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 0, y = 64, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 0, y = 96, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 0, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
  },
}

animation{
  name = "shaking",
  src_image = "enemies/gohma.png",
  frame_delay = 100,
  frame_to_loop_on = 0,
  directions = {
    { x = 64, y = 128, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 64, y = 64, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 64, y = 96, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 64, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
  },
}

animation{
  name = "hurt",
  src_image = "enemies/gohma.png",
  frame_delay = 100,
  frame_to_loop_on = 0,
  directions = {
    { x = 256, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
  },
}

animation{
  name = "closed",
  src_image = "enemies/gohma.png",
  frame_delay = 200,
  frame_to_loop_on = 0,
  directions = {
    { x = 256, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
    { x = 256, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 4 },
  },
}

animation{
  name = "blinking",
  src_image = "enemies/gohma.png",
  frame_delay = 150,
  directions = {
    { x = 0, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 3 },
    { x = 0, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 3 },
    { x = 0, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 3 },
    { x = 0, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 3 },
  },
}

animation{
  name = "opening",
  src_image = "enemies/gohma.png",
  frame_delay = 150,
  directions = {
    { x = 128, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 128, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 128, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
    { x = 128, y = 0, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29, num_frames = 2 },
  },
}

animation{
  name = "immobilized",
  src_image = "enemies/gohma.png",
  directions = {
    { x = 0, y = 128, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29 },
    { x = 0, y = 64, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29 },
    { x = 0, y = 96, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29 },
    { x = 0, y = 32, frame_width = 64, frame_height = 32, origin_x = 32, origin_y = 29 },
  },
}
#36
Not sure if this is a bug in the engine or the fault of my script, but I get the error "Fatal: Non-empty stack after LuaContext::update()" when one of my enemies is on the screen after a few seconds. The enemy script is below:

local enemy = ...

-- Octorok: simple enemy who wanders and shoots rocks

local going_hero = false
local awaken = false
local timer

function enemy:on_created()
  self:set_life(1)
  self:set_damage(2)
  self:create_sprite("enemies/octorok_red")
  self:set_hurt_style("monster")
  self:set_pushed_back_when_hurt(true)
  self:set_push_hero_on_sword(false)
  self:set_size(16, 16)
  self:set_origin(8, 13)
end

function enemy:on_movement_changed(movement)
  local direction4 = movement:get_direction4()
  local sprite = self:get_sprite()
  sprite:set_direction(direction4)
end

function enemy:on_obstacle_reached(movement)
  if awaken and not going_hero then
    self:check_hero()
  end
end

function enemy:on_restarted()
  if not awaken then
    self:go_random()
  else
    self:go_hero()
  end
  self:check_hero()
end

function enemy:on_hurt()
  if timer ~= nil then
    timer:stop()
    timer = nil
  end
end

function enemy:check_hero()
  local hero = self:get_map():get_entity("hero")
  local _, _, layer = self:get_position()
  local _, _, hero_layer = hero:get_position()
  local near_hero = layer == hero_layer
    and self:get_distance(hero) < 100

  if awaken then
    if near_hero and not going_hero then
      self:go_hero()
    elseif not near_hero and going_hero then
      self:go_random()
    end
  elseif not awaken and near_hero then
    self:wake_up()
  end
  timer = sol.timer.start(self, 1000, function() self:check_hero() end)
end

function enemy:wake_up()
  self:stop_movement()
  local sprite = self:get_sprite()
  sprite:set_animation("shooting")
  local x, y, l = self:get_position()
  local sx, sy = 0
  if d == 0 then
    sx = x + 8
    sy = y
  end
  if d == 1 then
    sy = y - 8
    sx = x
  end
  if d == 2 then
    sx = x - 8
    sy = y
  end
  if d ==3 then
    sy = y +8
    sx = x
  end
  sol.timer.start(self, 1000, function()
    local rock = self:create_enemy{
      breed = "rock_small",
      x = sx,
      y = sy
    }
    rock:go(d)
    sol.timer.start(self, 2000, function()
      self:check_hero()
    end)
  end)
end

function enemy:go_random()
  local m = sol.movement.create("random")
  m:set_speed(32)
  m:start(self)
  d = m:get_direction4()
  going_hero = false
end

function enemy:go_hero()
  local m = sol.movement.create("target")
  m:set_speed(48)
  m:start(self)
  d = m:get_direction4()
  going_hero = true
end
#37
Bugs & Feature requests / Editor improvements
February 04, 2014, 05:34:36 AM
Christopho- mad props on the recent improvements to the editor - there are some great things there that really speed up development. Using the improved editor got me thinking of additional improvement potential, so I thought I'd post some here rather than making a bunch of issues on github (I can do that if you prefer).

  • A small "x" on each tab (for maps or whatever) to close it would be a huge time savings when you have several tabs open.
  • It would be nice (if possible) to have a small "play" button next to any drop-down selector for music. Sometimes I forget which music I want and being able to listed to several in the editor would be a great help. Or at least allow us to listen to the music when selecting it from the left pane?
  • When changing the id of an item in the left selector pane, the current id could be the default in the dialog.
  • Holding "control" and using the mouse wheel could zoom the view.
  • Making some tweaks to make the editor more friendly to smaller resolutions would be helpful - I have a machine running at 1024x768 and there are times when I can't see everything in a dialog box. One example is the new "destructible" dialog - would it be possible to lay things out differently so the dialog isn't so big?
#38
Development / Cryptic error
February 04, 2014, 05:17:40 AM
I was hoping I'd be able to get some help decrypting this error, because I don't understand why I'm getting one. I'm getting the following when I run my game:
Error: Failed to load script 'maps/1': [string "maps/1.lua"]:14: malformed number near '.0.shop_mushroom_done_dialog_finished'

The script around that line is:
  if destination == "main_entrance_shop" and game:get_value("i2021") == 10 then
    game:start_dialog("crista.0.shop_mushroom.7", crista.0.shop_mushroom_done_dialog_finished)
  end


And the function being called:
local function crista.0.shop_mushroom_done_dialog_finished()
  game:set_value("i3001", game:get_value("i3001")+1)
  hero:start_treasure("trading", 2)
end


I'm guessing it's related to changes in 1.2.0, since I don't recall having an error when running an earlier version.