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

Messages - wizard_wizzle (aka ZeldaHistorian)

#166
Development / Re: Carrying custom entities
September 22, 2015, 01:21:55 AM
What I guess I don't understand is why we need an entirely different tunic animation set just for this script? This will make implementing into other people's project much more difficult. Can't hero:set_carrying() just use hero:set_animation("carrying_stopped") that already exists in the default tunic?

On another note, I'm still not getting a HUD action icon or the ability to throw once the object is picked up (with no error). Actually, it appears that the action icon is broken entirely - it will "flip" when interacting with something, but doesn't show an actual icon.

I committed the changes thus far to my repository, so you can take a look at it if you'd like.
#167
Development / Re: Carrying custom entities
September 21, 2015, 12:37:12 AM
I don't understand - I need a whole new tunic for this? I didn't see anything in the repository.
#168
Development / Re: Carrying custom entities
September 20, 2015, 11:05:32 PM
Now the hero disappears.


Error: Cannot find quest file 'sprites/tunic1.dat'
Fatal: Invalid direction 2 for sprite 'tunic1' in animation 'stopped_with_shield'
Error: In hero animation callback: [string "scripts/quest_manager.lua"]:163: Internal error: Invalid direction 2 for sprite 'tunic1' in animation 'stopped_with_shield'
Fatal: Invalid direction 3 for sprite 'tunic1' in animation 'stopped_with_shield'


I believe that should be 'sprites/hero/tunic1.dat' (at least in my quest is would be), but I'm not sure where in the code it's referring.
#169
Development / Re: Carrying custom entities
September 20, 2015, 04:26:26 PM
I followed the instructions you posted here exactly, so keep that in mind as we debug :)

Look like you'll definitely need to add something to the HUD - I picked the object up and the action icon disappeared from the HUD and I was not able to throw it.  Here's each error line and the line it references:

Error: In on_animation_finished: [string "scripts/hud/action_icon.lua"]:65: attempt to perform arithmetic on a nil value
    self.icon_region_y = 24 * effects_indexes[self.effect_displayed]

Error: In on_animation_finished: [string "scripts/hud/attack_icon.lua"]:63: attempt to perform arithmetic on a nil value
      self.icon_region_y = 24 * effects_indexes[self.effect_displayed]

Error: In hero animation callback: [string "scripts/quest_manager.lua"]:163: attempt to index global 'hero' (a nil value)
    hero():set_tunic_sprite_id(hero_tunic_sprites_id)        changed to:
    self:get_game():get_hero():set_tunic_sprite_id(hero_tunic_sprites_id)
#170
Development / Re: Carrying custom entities
September 18, 2015, 12:03:51 AM
I might be able to use it in my game - I was thinking about swapping out one of my minibosses for Smasher from Link's Awakening, that would require picking up a large metal ball and throwing it at the enemy to do damage.

Even if I don't use it for my game, I'm happy to test and provide whatever feedback I can!
#171
Development / Re: Scrolling credits
September 06, 2015, 08:34:04 PM
I was attempting to write each line to "surface" with line:draw_region(0, 0, text_width, text_height, surface, text_x, text_y), and then draw just the surface. I thought this was similar to how HUD items were drawn, but I probably didn't implement it correctly.
#172
Development / Re: Scrolling credits
September 06, 2015, 04:51:14 PM
Getting closer! I appreciate and agree with your comments on structure. I'm having issues with the movement and the drawing itself though - nothing is actually showing on screen. I know that the text_line creation loop works because of a print statement I put in. Any thoughts on fine tuning?


local map = ...
local i = 0
local j = 0
local line = {}
local camera_x, camera_y, camera_width, camera_height = map:get_camera_position()
local surface = sol.surface.create(camera_width, camera_height)
local m = sol.movement.create("target")

local credits = { "Thank you for playing!" , "" , "CREDITS", "" ,
  "Solarus Engine: created by Christopho" , "" ,
  "Maps:", "ZeldaHistorian", "Renkineko (Lost Woods)"
}

function map:start_line(text_line)
  line[i] = sol.text_surface.create()
  line[i]:set_text(text_line)
print(line[i]:get_text())
  m:set_xy(camera_height, camera_width/2)
  m:set_target(0, camera_width/2) -- Move from the bottom to the top of the screen
  m:set_speed(16)

  function m:on_position_changed()
    local text_x, text_y = self:get_xy()
    local text_width, text_height = line[i]:get_size()
    line[i]:draw_region(0, 0, text_width, text_height, surface, text_x, text_y)
    if text_x < 50 then
      line[i]:fade_out() -- Fade out line and destroy movement when at top of screen
      sol.timer.start(self, 1000, function() self:stop() end)
    end
  end

  m:start(line[i])
end

function map:on_started(destination)
  map:get_game():set_hud_enabled(false)
  map:get_hero():set_position(-100, -100)
  map:get_hero():freeze()
  sol.timer.start(self, 4000, function()
    i = i + 1
    self:start_line(credits[i])
    return true
  end)
end

function map:on_draw(dst_surface)
  surface:draw(dst_surface)
end
#173
Development / Scrolling credits
September 05, 2015, 01:10:34 AM
I'm trying to get a scrolling credits screen figured out, and I've hit a roadblock. How I'd like to do it is have a table with all of the credit text, then loop through each piece of text and display it on screen as it's own line, which would start at the bottom of the screen and slowly move up. My thought was to create a text surface for each line and apply a path movement north, then detect when it hits the top of the screen and destroy that surface. My problem is that I can't get the loop to create the surfaces and the separate loop to draw each surface working correctly. Help please?

Pseudo-code: Where should I put the code that turns text into text surfaces (in on_started right now)

local credits = { "Thank you for playing!" , "" , "CREDITS", "" }

function map:on_started(destination)
  map:get_game():set_hud_enabled(false)
  map:get_hero():set_position(-100, -100)
  map:get_hero():freeze()

  for i, line in ipairs(credits) do
    sol.timer.start(self, 4000, function()
      line_text = line
      line = sol.text_surface.create()
      line:set_text(line_text)
      local m = sol.movement.create("path")
      m:set_xy(camera_height, camera_width/2)
      m:set_path({2,2})
      m:set_loop(true)
      m:set_speed(32)
      m:start(line)
  end
end

function map:on_draw(dst_surface)
  for i, line in ipairs(credits) do
      local text_x, text_y = line:get_xy()
      if text_x < 100 then line:fade_out() end
      line:draw(dst_surface, text_x, text_y)
  end
end
#174
Your projects / Re: Zelda: Book of Mudora
September 01, 2015, 11:41:03 PM
Definitely - they're amazing! Thank you for everything you scripted!
#175
Your projects / Re: Zelda: Book of Mudora
September 01, 2015, 02:06:28 PM
I had skipped posting a version because, well, I'm not really sure :/ I included the description of everything in the last two releases for your browsing pleasure. Next stop - Solarus 1.5 and ZBOM 0.5, first full beta!

Anyway, current version is 0.47 and the download link is https://www.dropbox.com/s/lwdo70oqvan19cl/zbom-0.47.zip?dl=0


VERSION 0.47 released 01-SEP-15
  - Work on last two dungeons - Tower of Winds is fully playable, Interloper Sanctum is not
  - Allow ice cane to freeze water as well as lava
  - Enabled more waterway swimming and added a few secrets
  - Corrected behavior of ice cane and creating/pushing ice blocks (could still use a little tweaking)
  - Fully scripted bow/arrows to allow two different types of arrows and better behavior
  - Fully scripted hookshot to allow more configurable behavior
  - Starting to add more Hylian NPCs for North Hyrule and a few other areas

VERSION 0.46 released 17-AUG-15
  - Show temporary HUD popup when collectible is picked
  - Fully implemented red and blue tunics
  - Finished advanced maps for last two dungeons
  - Dynamically determine Book variant to give so dungeons can be truly done in any order
  - Implement shovel and soft soil
  - Implement ability to make and buy advanced potions
  - Additional or improved enemies
  - Additional heart pieces
  - Begin implementation of hammer
  - Optimization of scripts and sprites
  - Implement camera movement with control key
#176
Yes, for that particular effect I guess you're right. I need the get/set_pixel functions as well (hopefully) for some lighting effects, so let's home this is implemented soon!
#177
Development / Shaders?
August 27, 2015, 11:57:20 PM
Is there any information about what's currently available in the engine concerning shaders? I believe there was an experimental implementation, but I'm not sure if it was ever completed/tested/documented? If I can help in any way, I'm happy to do so!

I need to implement more advanced lighting in my game, and I'm getting to the point where I can't put it off much longer and need to come up with something. I would require multiple light points in an otherwise dark room, and thought shaders would be the only way to manage this. If anyone knows of another way, I would love to hear ideas! :)
#178
Should be easy enough to do as an overlay - basically using an animated sprite. I haven't tried an animated overlay before though.
#179
Development / Re: Custom code debugging
August 27, 2015, 05:39:32 AM
I didn't feel like creating these particular resources as sprites instead of tiles, haha. I got it to work (mostly) by looping through all dynamic tile entities in on_position_changed. I ended up having my block pushing code ignore obstacles to get this working, so now I just need to figure out why my code to check for a wall and not move the block is allowing me to push blocks into walls.


local entity = ...
local map = entity:get_map()
local pushing = false
local block_on_switch = false
local lava_crust, ice_patch

-- Ice block: special block made of ice that can fill an
-- ice pit, turn lava solid, and freeze water.

function entity:on_created()
  self:set_size(16, 16)
  self:snap_to_grid()
  self:set_modified_ground("ice")
  self:set_traversable_by("hero", false)
  self:set_traversable_by("custom_entity", true) --to allow pushing block into pit
  self:create_sprite("entities/ice_block")

  self:add_collision_test("facing", function(self, other)
    if other:get_type() == "hero" and not pushing then
      pushing = true
      local m = sol.movement.create("path")
      m:set_ignore_obstacles(true)
      m:set_snap_to_grid(true)

      local sx, sy, sl = self:get_position()
      if other:get_direction() == 0 then
        if map:get_ground(sx+8,sy,sl) ~= "wall" and map:get_ground(sx+16,sy,sl) ~= "wall" then m:set_path({0,0}) end
      elseif other:get_direction() == 1 then
        if map:get_ground(sx,sy+8,sl) ~= "wall" and map:get_ground(sx,sy+16,sl) ~= "wall" then m:set_path({2,2}) end
      elseif other:get_direction() == 2 then
        if map:get_ground(sx-8,sy,sl) ~= "wall" and map:get_ground(sx-16,sy,sl) ~= "wall" then m:set_path({4,4}) end
      elseif other:get_direction() == 3 then
        if map:get_ground(sx,sy-8,sl) ~= "wall" and map:get_ground(sx,sy-16,sl) ~= "wall" then m:set_path({6,6}) end
      end
      m:start(self, function() pushing = false end)
    end
  end)

  self:add_collision_test("overlapping", function(self, other)
    if other:get_type() == "switch" then
      block_on_switch = true
      other:set_activated(true)
      if other:on_activated() ~= nil and not other.active then
        other:on_activated()
        other.active = true
      end
      sol.timer.start(map, 1000, function()
        if block_on_switch then
          return true
        else
          block_on_switch = false
          other:set_activated(false)
          if other:on_inactivated() ~= nil and other.active then
            other:on_inactivated()
            other.active = false
          end
        end
      end)
    elseif other:get_type() == "hole" then
      sol.audio.play_sound("hero_falls")
      self:remove()
    elseif other:get_type() == "fire" then
      sol.audio.play_sound("ice_melt")
      self:remove()
    elseif other:get_type() == "explosion" then
      sol.audio.play_sound("ice_melt")
      self:remove()
    else
      block_on_switch = false
    end
  end)

  local sx, sy, sl = self:get_position()
  self:on_position_changed(sx, sy, sl)
end

function entity:on_position_changed(x, y, layer)
  for e in map:get_entities("") do
    if e:get_type() == "dynamic_tile" then
      if self:overlaps(e) then --if block overlaps dynamic tile
        if map:get_ground(e:get_position()) == "lava" then
          self:remove()
  if map:get_hero():get_direction() == 0 then
            lava_crust = map:create_custom_entity({ x=x+8, y=y-16, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 1 then
            lava_crust = map:create_custom_entity({ x=x-16, y=y-48, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 2 then
            lava_crust = map:create_custom_entity({ x=x-40, y=y-16, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 3 then
            lava_crust = map:create_custom_entity({ x=x-16, y=y, layer=layer, width=32, height=32, direction=0 })
  end
          lava_crust = map:create_custom_entity({ x = x, y = y, layer = layer, width = 32, height = 32, direction = 0 })
          lava_crust:snap_to_grid()
          sol.audio.play_sound("freeze")
          lava_crust:create_sprite("entities/lava")
          lava_crust:set_modified_ground("traversable")
          lava_crust:set_traversable_by("hero", true)
          lava_crust:set_traversable_by("enemy", true)
          lava_crust:set_traversable_by("block", true)
  sol.timer.start(map, 15000, function() lava_crust:remove() end)
        elseif map:get_ground(e:get_position()) == "deep_water" then
          self:remove()
  if map:get_hero():get_direction() == 0 then
            ice_patch = map:create_custom_entity({ x=x+8, y=y-16, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 1 then
            ice_patch = map:create_custom_entity({ x=x-16, y=y-48, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 2 then
            ice_patch = map:create_custom_entity({ x=x-40, y=y-16, layer=layer, width=32, height=32, direction=0 })
  elseif map:get_hero():get_direction() == 3 then
            ice_patch = map:create_custom_entity({ x=x-16, y=y, layer=layer, width=32, height=32, direction=0 })
  end
          sol.audio.play_sound("freeze")
          ice_patch:create_sprite("entities/ice")
          ice_patch:set_modified_ground("ice")
          ice_patch:set_traversable_by("hero", true)
          ice_patch:set_traversable_by("enemy", true)
          ice_patch:set_traversable_by("block", true)
  sol.timer.start(map, 15000, function() ice_patch:remove() end)
        end
      end
    elseif e:get_type() == "wall" or e:get_type() == "hole" then
      e:stop_movement()
    end
  end
end

function entity:on_removed()
  self:get_sprite():set_animation("destroy")
end
#180
Development / Re: Custom code debugging
August 26, 2015, 01:09:08 AM
Using custom entities would make level design significantly harder for me since I couldn't place these graphically in the editor, so I likely won't go that route. Checking all entities instead of using a collision test did help the accuracy of the script a bit. I think I'll wait until those engine bugs are fixed and just not allow pushing blocks into those dynamic tiles for now. Thanks to both of you!