Solarus-Games English Forum

Solarus => Development => Topic started by: Dragon_noir on May 25, 2015, 12:58:24 AM

Title: Shooting fire
Post by: Dragon_noir on May 25, 2015, 12:58:24 AM
Is it possible to make an item shoot fire (like the fire wand from alttp)?
Title: Re: Shooting fire
Post by: YoshiMario2000 on May 25, 2015, 02:44:38 AM
Potentially, I'd analyze the bow and change the sprites and change some of it's settings.
Title: Re: Shooting fire
Post by: Christopho on May 25, 2015, 08:51:59 AM
This might be possible but it was not tested. You can try map:create_fire() (http://www.solarus-games.org/doc/latest/lua_api_map.html#lua_api_map_create_fire) or use a custom entity for more control.
But in both cases, you need to be familiar with the scripting API.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 07:09:20 AM
So i was trying to create a fire wand and this is the code i have so far:


local item = ...
item.fire = nil

function item:on_created()

  item:set_savegame_variable("possesion_fire_wand")
  self:set_assignable(true)

end

function item:on_using()

  local movement = sol.movement.create("straight")
  local game = self:get_game()
  local map = self:get_map()
  local hero = item:get_map():get_entity("hero")
  local x, y, layer = hero:get_position()
  local direction = hero:get_direction()

  if direction == 0 then
    x = x + 16
    movement:set_angle(0)
  elseif direction == 1 then
    y = y - 16
    movement:set_angle(math.pi / 2)
  elseif direction == 2 then
    x = x - 16
    movement:set_angle(math.pi)
  elseif direction == 3 then
    y = y + 16
    movement:set_angle(3 * math.pi / 2)
  end

  if item.fire == nil or not self.fire:exists() then

      --sol.audio.play_sound("")
      --sol.audio.play_sound("magic_bar")
      --game:remove_magic()

      -- Create the fire.
      item.fire = map:create_fire{
name = "fire",
x = x,
y = y,
layer = layer,
      }
      self.created = true

  end
  movement:set_speed(120)
  movement:set_max_distance(160)
  self.fire:set_position(x, y, layer)
  movement:start(item.fire)
  item:set_finished()
end


The problem i seem to have, is that the animation of the fire is only 3 frames and disappears too fast.
Title: Re: Shooting fire
Post by: Christopho on May 26, 2015, 09:44:25 AM
Check the animations of sprite "entities/fire", and make sure that there is no obstacle that stops the fire too soon.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 02:31:42 PM
"Check the animations of sprite "entities/fire""

If i change the animation, it would also change it for other items using it, like the lamp, wouldn't it?

"and make sure that there is no obstacle that stops the fire too soon."

I tried it on an empty map and it only moves 32 pixels.

It just ends  the animation after it travels 32 pixels.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 02:34:57 PM
I also tried to loop the animation.

It now goes the distance (160) but the animation doesn't end.

And it messes up the lamp :(
Title: Re: Shooting fire
Post by: Christopho on May 26, 2015, 02:56:50 PM
Then you should probably try with a custom entity instead. You will have full control of the sprite, movement and collisions with other entities.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 03:21:19 PM
I don't really know how to code custom entities, and don't really understand the documentation :/

i tried this (in the fire wand script, instead of map:create fire()):

item.fire = map:create_custom_entity{
name = "fire",
x = x,
y = y,
layer = layer,
          direction(0)       
          sprite = "entities/fire2"
      }
      self.created = true



but i get an error:

Error: Failed to load script 'items/fire_wand': [string "items/fire_wand.lua"]:60: '}' expected (to close '{' at line 54) near 'sprite'
Error: In items/fire_wand: attempt to call a string value
Error: In on_started: [string "scripts/menus/pause_inventory.lua"]:41: Item 'fire_wand' is not saved
Error: In on_draw: [string "scripts/menus/pause_inventory.lua"]:203: Item 'fire_wand' is not saved
Title: Re: Shooting fire
Post by: Christopho on May 26, 2015, 03:29:48 PM
You have syntax errors in your Lua code. Again, you need to learn Lua before trying to write scripts. I cannot write them all for everyone :P
http://www.lua.org/pil/contents.html
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 03:51:11 PM
I've already been to the site but i can't learn by just reading about it. I learn by doing.

I know you can't write all the scripts for everyone :p.

But i did what the documentation said.

"direction (number): Direction of the custom entity, between 0 (East) and 3 (South). This direction will be applied to the entity's sprites if possible."

I know the error lies with the direction.

I tried : -direction(0)
             -direction = 0
             -direction = hero:get_direction()

As i said before i've only been trying to code for a coupe of months (March) I mostly used C#. I only know the basics of programming i just fail to use them correctly :(

edit: Nevermind i found the error. (stupid comma :p)
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 04:17:47 PM
Where can i find examples of custom entities scripts?
Title: Re: Shooting fire
Post by: Christopho on May 26, 2015, 05:03:25 PM
I only made a few for now, they are here: https://github.com/christopho/zelda_mercuris_chest/tree/master/data/entities
Maybe there are other examples from users on this forum.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 06:32:43 PM
Thanks those were helpfull.

It's kind of working now.

local item = ...
item_fire = nil

function item:on_created()

  item:set_savegame_variable("possesion_fire_wand")
  self:set_assignable(true)

end

function item:on_using()

  local movement = sol.movement.create("straight")
  local game = self:get_game()
  local map = self:get_map()
  local hero = item:get_map():get_entity("hero")
  local x, y, layer = hero:get_position()
  local direction = hero:get_direction()

  --hero:set_animation("ice_rod")

  if direction == 0 then
    x = x + 16
    movement:set_angle(0)
  elseif direction == 1 then
    y = y - 16
    movement:set_angle(math.pi / 2)
  elseif direction == 2 then
    x = x - 16
    movement:set_angle(math.pi)
  elseif direction == 3 then
    y = y + 16
    movement:set_angle(3 * math.pi / 2)
  end

  if item.fire == nil or not item.fire:exists() then

      --sol.audio.play_sound("")
      --sol.audio.play_sound("magic_bar")
      --game:remove_magic()

  item_fire = map:create_custom_entity{
name = "fire",
x = x,
y = y,
layer = layer,
    direction = direction,       
    sprite = "entities/fire2"
    }
      self.created = true

  end

  movement:set_speed(160)
  --movement:set_max_distance(320)
  item_fire:set_position(x, y, layer)
  movement:start(item_fire)

  item_fire:add_collision_test("sprite", function(item_fire, other)

    if other:get_type() == "enemy" then

      other:hurt(8)
  item_fire:remove()
 
    end
  end)
   

 
    sol.timer.start(1000, function()
  item_fire:remove()
    end)

  item:set_finished()
end


just a few bugs:

- Sometimes the fire doesn't disappear.
- The fire continues to go against diagonal walls (cliffs)
- This: movement:set_max_distance(), doesn't seem to work (makes no difference if the line of code is in the file or not.)
- I can't seem to be able to add an animation to the hero when i use the fire wand (even though it's in the assets).
Title: Re: Shooting fire
Post by: Christopho on May 26, 2015, 06:40:51 PM
The second problem is because the straight movement is smooth by default (is slides on diagonal walls). Call movement:set_smooth(false) to change that.
Title: Re: Shooting fire
Post by: Dragon_noir on May 26, 2015, 07:48:40 PM
Ok thanks :D

That part is working now.

Now i'm trying to add an animation but it doesn't work.
I've defined the animation in tunic1, but nothing happens

i've also added those lines of code to the file :


  local tunic = hero:get_tunic_sprite_id()
  hero:set_tunic_sprite_id(tunic)
  hero:set_animation("ice_rod")