Solarus-Games English Forum

Solarus => Development => Topic started by: DementedKirby on July 29, 2015, 08:04:52 PM

Title: Any way to use an item during swimming?
Post by: DementedKirby on July 29, 2015, 08:04:52 PM
I'm trying to develop a system for the Iron Boots item (like in Ocarina of Time) and I'm able to get it working with sensors because items can't be used during swimming. Is the nullification of item use during swimming hardcoded in Solarus's engine or is there a way to set an item that it can only be used when swimming?
Title: Re: Any way to use an item during swimming?
Post by: Diarandor on July 29, 2015, 08:48:33 PM
If I am not wrong, it should be possible and not too hard (although I haven't tried that yet). I would use the event game:on_command_pressed (or game:on_key_pressed) to activate the item. You need to check that the item is assigned to the command (or key) you have pressed, and also if the hero is swimming (use something like "if hero:get_state() == "swimming" then ..."). Maybe you need to do something more, but you should be able to handle this (with a lot of work).

You should start by studying the scripts related to the hud (of Solarus dx for instance), which is used to display the selected items. Also, you will find functions for custom states or commands of the hero (which are independent of the engine) defined there that you may need to use. (It took me a lot of time to understand all of that, but it's really important.)
Title: Re: Any way to use an item during swimming?
Post by: DementedKirby on July 29, 2015, 09:28:56 PM
Actually, to get it to work is a lot easier than that. All I have to do is get the item to work when the hero is swimming. But with everything you told me I guess I have an idea:

If hero is not swimming and item is pressed then an error sound occurs else
If do what the item is supposed to do.

Actually, the difficulty in making an Iron Boots comes not from coding but level design. All you have to do is make sure that wherever you have deep water, it's on the intermediate level and the "floor" beneath the water be low layer. All the Iron Boots do is send the hero to the bottom layer (beneath the water). What I'm doing is making the hero speed 44 (half of normal), maintaining the same x & y, and just changing the layer to 0. That makes it appear that you're slow because of moving underwater. After that, a boolean is stored. When that Boolean is true and the boots are used again, all you do is the same exact thing just change the hero to layer 1 and store the Boolean as false. And he's back to the surface of the water swimming. Super easy. All I have to do is make sure that the hero can only use the boots when swimming - and to use them at all when swimming, lol. So basically, what the item does is this:

--when item is used and hero is neither swimming nor the iron_boots bool is true:
sol.audio.play_sound("error") else
--when item is used if swimming state is true:
hero:set_walking_speed(44)
local x, y, layer = hero:get_position()
hero:set_position(x,y,0)
game:set_value("iron_boots",true) else
--when the bool is true and the item is used:
hero:set_walking_speed(88)
local x2, y2, layer2 = hero:get_position()
hero:set_position(x2,y2,1)
game:set_value("iron_boots",false) else
--this makes the hero appear to be walking underwater (you have to use the underwater tile that's transluscent)


That's the basic concept. Again, I got it to work with sensors placed on the water to make the hero walk underwater and then underwater to return the hero swimming to the surface. It's as simple as changing the hero's layer. Which is why the difficulty is in the level programming. You may want to make the hero teleport to a "new place" that represents what's the beneath the water's surface or simply make the bottom of the water and have it show through a translucent water tile. The possibilities are endless. So again, all I have to do is get the item to work when the hero is swimming.

What I was able to test with the sensor (each sensor only changed the layer) is that swimming is dependent on the layer. Changing the layer when in water or underwater makes the hero swim or walk underwater depending on the layer of the water. Doesn't that blow your mind? Think of all the possibilities of the douchiness of a more difficult Water Temple? That's what I'm currently designing right now, lol.

UPDATE:
Here's what I'm gonna try:
function game:on_command_pressed("item_1")
   if game:get_item_assigned(1) == "iron_boots" then
      if hero:get_state() == "swimming" then
         hero:set_walking_speed(44)
         local x, y, layer = hero:get_position()
         hero:set_position(x, y, 0)
         game:set_value("iron_boots", true)
      else if game:get_value("iron_boots") == true then
         hero:set_walking_speed(88)
         local x2, y2, layer2 = hero:get_position()
         hero:set_position(x2, y2, 1)
         game:set_value("iron_boots", false)
    else
      sol.audio.play_sound("error")
end


And hopefully it's gonna work, lol.