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.


Topics - MetalZelda

Pages: [1] 2 3 4
1
Development / Removing a sprite created through sol.sprite.create ?
« on: October 08, 2017, 05:18:54 pm »
Hi

I'm having troubble with cutscenes and sprites management.
I am currently making sage cutscenes with as inspiration ALTTP, but, after a while, the crystal around the sage needs to be removed



The sprite creation is a bit different because the cutscene starts immediately after the boss died, a surface fades to accomplish the black background, a menu handles the whole cutscene (mostly to overwrite and avoid pausing / moving, doing actions during cutscene)

Sprites are created in this order

black surface
Link sprite
Sage sprite
Crystal sprite

All created by sol.surface / sprite.create

But, calling

Code: [Select]
sprite:remove()
this happen

Code: [Select]
Error: In timer callback: [string "maps/cutscene_data/SageScene_0.lua"]:95: attempt to call method 'remove' (a nil value)
I can't use map entities because the menu is started above everything on the map, entities are not visible during the cutscene because of the background surface
Which confuse me a bit, we can't remove a sprite ?

2
Development / [SOLVED] Trouble porting a script
« on: June 25, 2017, 04:40:28 pm »
Hello.

So, I am porting a RUBY script to lua.
This script will allow easier pause menu creation, replacing cursor position by user defined positions. Like so

Code: Lua
  1. local elements = {
  2.   config = {save = true},
  3.   {"rupee_bag", 68, 78, "info"},
  4.   {"bomb_bag", 68, 104, "info"},
  5.   {"quiver", 68, 130, "info"},
  6.   {"deku_nuts_bag", 68, 156, "info"},
  7.   {"bombchu_bag", 68, 182, "info"},
  8.   {"sword", 217, 84, "action"},
  9.   {"tunic", 209, 180, "action", variant = "_1"},
  10.   {"tunic", 233, 180, "action", variant = "_2"},
  11.   {"tunic", 257, 180, "action", variant = "_3"},
  12.   {"glove", 209, 132, "info"},
  13.   {"shield", 233, 132, "info"},
  14.   {"climb_ring", 257, 132, "info"},
  15.   {"sword_biggoron", 249, 84, "action"},
  16. }

The 2nd and 3rd index is used to place an item on the X and Y axis, as well as the cursor

This is the RUBY script I'm trying to port

Code: Ruby
  1. # Initialize variables for the weightings on the vertical and horizontal
  2.       # directions
  3.                         wv, wh = 0, 0
  4.       # The weightings for the secondary and primary axis relative to input
  5.                         w1, w2 = 1, 2
  6.       # Initialize a variable for the direction and get the direction
  7.       # pressed by the user
  8.       input_dir = 0
  9.       input_dir = 2 if Input.repeat?(Input::DOWN)
  10.       input_dir = 4 if Input.repeat?(Input::LEFT)
  11.       input_dir = 6 if Input.repeat?(Input::RIGHT)
  12.       input_dir = 8 if Input.repeat?(Input::UP)
  13.       # Do nothing if no button was pressed
  14.       return if input_dir == 0
  15.       #get the item
  16.       item = self.item
  17.       #if the item is left toggle and the input direction is left
  18.       if item == :left_toggle && input_dir == 4
  19.         #move to the left window
  20.         return $scene.move_window(6)
  21.       #elsif the item is right toggle and the input direction is right
  22.       elsif item == :right_toggle && input_dir == 6
  23.         #move to the right window
  24.         return $scene.move_window(4)
  25.       end
  26.       # Setup the weightings for each direction
  27.                         if  (input_dir == 2 or input_dir == 8)
  28.                                 wv, wh = w1, w2
  29.                         elsif (input_dir == 4 or input_dir == 6)
  30.                                 wv, wh = w2, w1
  31.                         end
  32.       # Get the xy position of the current item
  33.                         cxy = @xy_pos[@index]
  34.       # Create default value for the closest item's distance (absurdly large)
  35.       closest_index = -1
  36.                         closest_distance = 9999999
  37.       # Loop through every item
  38.                         for i in 0...@xy_pos.size
  39.                                 # Skip if it is the old item or is in the opposite direction
  40.                                 if @index == i or
  41.                                    (input_dir == 2 and @xy_pos[i][1] < cxy[1]) or
  42.                                    (input_dir == 4 and @xy_pos[i][0] > cxy[0]) or
  43.                                    (input_dir == 6 and @xy_pos[i][0] < cxy[0]) or
  44.                                    (input_dir == 8 and @xy_pos[i][1] > cxy[1])
  45.                                         next
  46.                                 end
  47.         # Get the distance from the last highlighted item to this tested one
  48.                                 dist_h = (@xy_pos[i][0] - cxy[0]).abs
  49.                                 dist_v = (@xy_pos[i][1] - cxy[1]).abs
  50.         # If it is really against the primary axis
  51.         if (wh == w1 and w2 * dist_h < dist_v) or
  52.             (wv == w1 and w2 * dist_v < dist_h)
  53.           next
  54.         end
  55.         # Get the distance multiplied with their weightings
  56.                                 dist = dist_h * wh + dist_v * wv
  57.         # Set at closest item if appropriate
  58.                                 if (dist < closest_distance)
  59.                                         closest_distance = dist
  60.                                         closest_index = i
  61.                                 end
  62.                         end
  63.       # Do nothing if nothing was selected
  64.       return if closest_index == -1
  65.       @index = closest_index
  66.       #move cursor
  67.       move_cursor

@xy_pos is already defined in the elements variable, @cxy is the current cursor position, they are already defined

The only problem, RUBY have a skip iterator whereas I can't find the closest thing for lua

This is my attempt in Lua, which still fails, the cursor will still highlight the current item forever

Code: Lua
  1. function submenu:set_cursor_position(command)
  2.   local width = sol.video.get_quest_size()
  3.   width = width / 2 - 160
  4.  
  5.   local current_x = self.cursor_position.x
  6.   local current_y = self.cursor_position.y
  7.        
  8.   -- Create default value for the closest item's distance
  9.   local closest_index = -1
  10.   local closest_distance = 320
  11.        
  12.   -- Initialize variables for the weightings on the vertical and horizontal direction
  13.   local wv, wh = 0, 0
  14.        
  15.   -- The weightings for the secondary and primary axis relative to input
  16.   local w1, w2 = 1, 2
  17.        
  18.   -- Setup the weightings for each direction
  19.   if (command == "down" or command == "up") then
  20.     wv, wh = w1, w2
  21.   elseif (command == "left" or command == "right") then
  22.         wv, wh = w2, w1
  23.   end
  24.  
  25.   for i = 1, #self.items do
  26.     local item = self.items[i]
  27.         local item_x = item.x
  28.         local item_y = item.y
  29.         local current_item_index = self:find_item(self:find_item_axis(self.cursor_position.x, self.cursor_position.y))
  30.        
  31.         --  Skip if it is the old item or is in the opposite direction
  32.         if current_item_index == i or (command == "down" and item_y < current_y) or (command == "left" and item_x > current_x) or (command == "right" and item_x < current_x) or (command == "up" and item_y > current_y) then
  33.           -- tried goto
  34.         end
  35.        
  36.         -- Get the distance of the current item and the new one
  37.         local dist_h = math.abs(item_x - current_x)
  38.         local dist_v = math.abs(item_y - current_y)
  39.                
  40.         if (wh == w1 and w2 * dist_h < dist_v) or (wv == w1 and w2 * dist_v < dist_h) then
  41.           goto matched
  42.         end
  43.        
  44.         ::matched::
  45.     -- # Get the distance multiplied with their weightings
  46.         local dist = (dist_h * wh + dist_v * wv)
  47.                  
  48.         -- # Set at closest item if appropriate
  49.         if (dist < closest_distance) then
  50.           closest_distance = dist
  51.           closest_index = i
  52.         end
  53.   end
  54.        
  55.   local item = self.items[closest_index]
  56.   local x = item.x
  57.   local y = item.y - 5 
  58.        
  59.   self.cursor_position = {x = x, y = y + 5}
  60.   self.cursor_sprite_x = x + width
  61.   self.cursor_sprite_y = y
  62.   self.game:set_custom_command_effect("action", item.effect)
  63.  
  64.   local caption_item = item.item .. "_" .. self.game:get_item(item.item):get_variant()
  65.   if item.item == "tunic" then
  66.     caption_item = "tunic_" .. self:get_tunic_variant()
  67.   end
  68.  
  69.   self:set_caption(self.caption_text_keys[caption_item])  
  70.   self.game:set_value("equipment_last_index", position)
  71. end
  72.  
  73.  

Is there a Lua equivalent of "next" ?

Next = https://www.tutorialspoint.com/ruby/ruby_loops.htm
Jumps to the next iteration of the most internal loop. Terminates execution of a block if called within a block (with yield or call returning nil).

3
Your scripts / [Cursor] Majora's Mask / Project Zelda Engine cursor
« on: June 25, 2017, 12:59:44 pm »
This is a straight port of a RUBY script. Made by MaximusMaxy, from Project Zelda Engine
This script allow to have an animated cursor for your pause menu, like Majora's Mask, of course, it can be adapted for other stuffs

This is an alternative solution for avoiding a spriteset creation (frame by frame cursor animation), this script calculate the animation for you.

You need:

-> a cursor png (1 part or 4 sides) which you should save in /sprites/menus/src/pause_submenus/cursor.png (You can change the file bellow
-> using 4 side cursor ? Just set use_rotation to false
-> Using 1 part cursor ? Set use_rotation to true

What can you do ?

-> You can modify the radius of the circle (minimum, maximum)
-> You can modify the speed of the animation (speed, where 1 = super slow and 9 = 1 lightyear per sanic)
-> Disable the rotation system and only keep the offset system
-> Disable the fading animation that occurs when the animation is drawn

Code: Lua
  1. function submenu:create_cursor()
  2.   -- Set the minimum and maximum radius of the rotation
  3.   local minimum, maximum = 10, 12
  4.  
  5.   -- Speed of the animation (1 = slow, 9 = fast)
  6.   local speed = 5
  7.  
  8.   -- Use the rotation system or just the zoom ? (true = use the rotation, false = just the zoom)
  9.   local use_rotation = true
  10.  
  11.   -- Use the fading option
  12.   local use_fade = true
  13.  
  14.   -- Cursor file
  15.   local cursor = sol.surface.create("menus/src/pause_submenus/cursor.png")
  16.   local cursor_width, cursor_height = cursor:get_size()
  17.  
  18.   -- Determine the region parts depending on use_rotation state
  19.   if not use_rotation then
  20.     cursor_width = cursor_width / 2
  21.     cursor_height = cursor_height / 2
  22.   end
  23.  
  24.   -- Don't touch this
  25.   local count = 0
  26.  
  27.   function submenu:draw_cursor(dst_surface, x, y)
  28.     -- Increment the rotation
  29.     count = (count + speed) % 360
  30.  
  31.     -- Compute the sin and cos of the rotation
  32.     local sin = math.sin(count * math.pi / 180)
  33.     local cos = math.cos(count * math.pi / 180)
  34.  
  35.     -- Compute the zoom scaling
  36.     local offset = minimum + (maximum - minimum) / 2 + (maximum - minimum) / 2 * sin
  37.        
  38.         -- Update the cursor opacity
  39.         if use_fade then
  40.           cursor:set_opacity(205 - (0.5 + sin) * 100)
  41.         end
  42.        
  43.         -- Not using the rotation system, no rotation
  44.         if not use_rotation then
  45.           cos, sin = 1, 1
  46.         end
  47.        
  48.         local rotation_w = use_rotation and 0 or cursor_width
  49.         local rotation_h = use_rotation and 0 or cursor_height
  50.  
  51.         -- Draw the cursors
  52.         -- Upper Right
  53.     cursor:draw_region(rotation_w, 0, cursor_width, cursor_height, dst_surface, x + (sin * offset), y + (cos * -offset))
  54.        
  55.         -- Lower Left
  56.     cursor:draw_region(0, rotation_h, cursor_width, cursor_height, dst_surface, x + (sin * -offset), y + (cos * offset))
  57.        
  58.         -- Lower Right
  59.     cursor:draw_region(rotation_w, rotation_h, cursor_width, cursor_height, dst_surface, x + (cos * offset), y + (sin * offset))
  60.        
  61.         -- Upper Left
  62.     cursor:draw_region(0, 0, cursor_width, cursor_height, dst_surface, x + (cos * -offset), y + (sin * -offset))
  63.   end
  64. end
  65. submenu:create_cursor()

This is plug and play, at least if you use the MoS submenu system, you just have to call submenu:draw_cursor(dst_surface, x, y) in yout submenu script

You can also delete the rotation system for a zooming cursor, all you need to zoom is the local "offset"

4
Development / [FIXED] Simulating a command when the hero is frozen ?
« on: June 18, 2017, 11:42:51 pm »
Hello

I ran out with a problem

I am working on cutscenes, that imply the hero to be frozen AND execute basic actions when the cutscene is active
the problem is, you can't simulate a command when the hero is frozen, I've tried to unfreeze him before the action occurs but when loading a spin attack from simulated command and if the player mispress the attack button, the animation is cancelled and the hero can move on it's own depending on the rules given (hero:unfreeze before the action or handling the command)

If the attack command is not pressed then the animation will play fine

I've tried to start a dummy menu like so, I also tried using sol.main:on_key_pressed, same

In this event, your input should do nothing except if a dialog is active ...
Code: Lua
  1. function dummy:on_key_pressed(key)
  2.   return not game:is_dialog_active()
  3. end

But no matter what, even if I delete hero:freeze(), this prevent the hero from moving, but we can still cancel the simulated input, even if this rule (key_pressed) or on_command_pressed has been defined to prevent any input to interrupt the action

Anyone help ?

You can reproduce it simply

Code: Lua
  1. game:simulate_command_pressed("attack")
  2. sol.timer.start(1500, function()
  3.   game:simulate_command_released("attack")
  4. end)
  5.  

5
General discussion / Tunics id that impact the player stats ?
« on: May 15, 2017, 12:09:02 pm »
Hey

I've planned some things with my project which include Link skins.
By skins, i already planned

- Regular Link (Parallel Worlds skin)
- ALTTP Link
- AST Female Link
- AST Male Link
- Eldran (Male / female)

https://cloud.githubusercontent.com/assets/28355478/26052240/1c231a6a-3965-11e7-8723-116a956cda03.png

With this idea come the thing of giving stats to the player, such as

- Normal for regular Link (1 attack, 1 defence)
- Defensive for Female Link (0.5 attack, 2 defence)
- Attacks for Male Link (2 attack, 0.5 defence)
- Damage and Defence for ALTTP Link (2 attack, 2 defence)
- Still not decided for Eldran (maybe attack, defence, speed and swim ability)

Starting stats are 1 attack / 1 defence, of course, abilities (sword / shield) will modify these values

What do you all think of this ? Do you think that this could be something useful ?
Of course, the skins will need to be unlocked by doing quests or depending on the progression the player made

6
Development / Speed depending on a fixed duration ?
« on: May 04, 2017, 11:38:37 pm »
hi

So while working on some stuffs, primarly cutscenes, something gets my attention.
Let's assume that the hero is at a fixed point (let's say X 100 Y 200)
The camera in situation 1 will be set at X 300 Y 200
The camera in situation 2 will be set at X 800 Y 150
These camera have as target, the hero

so, if we set a speed in the most basic way, let's say 500 and start the movement on the camera, the arrival time will not be the same. This is what leads me to this thread

Is there any calculation that will allow the camera in both situation 1 and 2 that will allow the camera to arrive to the hero at, let's say, 2 seconds, with speed calculated by this arrival time ?

I already know that the calculation will include the default speed (500) and the target arrival time (2000 ms)

Any help will be appreciated

7
Development / Count how many file exists with a certain prefix ?
« on: March 10, 2017, 05:42:24 pm »
Greetings.

Recently i've been working on the final title screen based on RPG / Zelda BOTW.
And so comes this idea of unlimited saves number.



however, i wanna display all files stats here, i already know how to do it, the problem is, the menu is a scroll type menu, with as max_position, the number of saves, however, I can't figure out how to count how many files with "save" prefix exists, if anyone have a clue, i'll gladly take it

8
Your scripts / fog: Add fog to your map !
« on: February 07, 2017, 11:41:33 pm »
**Better Map Fog
Creation Date: Feb. 7 2016
Credits needed: You're free to decide by yourself.
Version: 1.3
Script needed:Multiple events by Christopho -> http://forum.solarus-games.org/index.php/topic,784.0.html

Version Changelog

Code: [Select]
--1.0--
Initial code
Can draw and move a surface, as well as setting the opacity
Method: Using map.dat

Code: [Select]
--1.1--
Bugfix: Strange behaviour on movement (movement not stopped, cutted surface), use a² = b² + c² and then root square it for surface's diagonal movement
Added: Opacity modulation
Method: Same as 1.0


Code: [Select]
--1.2--
Code has been revamped, data is loaded through a Lua file
Added: Surface coloration
Added: Surface blend mode modifer
Method: Parsing from maps/lib/fog_config.lua

Code: [Select]
--1.3--
Bugfix: Error when going on a map where there is no fog data

You might remember my very old map script that wander around the Development section, I've decided to update it, simpler, cleaner yet it is more efficient.
My idea for this update is straightly taken from RPG Maker, you know, there is a GUI that allows you to select your fog, movement and opacity, and The Legend of Zelda: Minish Cap (Fire Cave Dungeon) this simply is the same idea, but instead, it is in pure Lua.

**Documentation and technical presentation
In older version, fogs were drawn using a menu, and constantly cleaned and redrawn on each map changes.
Plus, you had to call a function to declare this fog, this was very annoying.
This method is way simpler, as it use the default map functions, no need to call a function to draw a fog anymore.

** Script calls
In order to make this script to work, you need:

1. A map metatable script
This is my map_metatable.lua header
Code: Lua
  1.   --
  2.   local map_metatable = sol.main.get_metatable("map")
  3.   require("scripts/fog")(map_metatable)
  4.   --
  A child's play !

2. This script (See bellow) that you place in the /script folder (create it if it doesn't exist)
3. The "fog_config.lua" sccript in /maps/lib/ 

** Known bug
All fixed.

** How to use:
  //The best is to have a map metatable
 
  This is my map_metatable.lua header to load this script.
  --
  local map_metatable = sol.main.get_metatable("map")
  require("scripts/fog")(map_metatable)
  --
 
  See ? It's child's play!

** I want to draw a fog, teach me, master

This is the base that you need to learn in order to draw a fog / move it / play with it's opacity

Code: Lua
  1. ["map_id"]= {
  2.   fog                     = "fog",
  3.   fog_speed               = speed,
  4.   fog_angle               = angle,
  5.   fog_opacity             = opacity,
  6.   fog_depth               = use_depth,
  7.   fog_detph_multiplier    = depth_multiplier,
  8.   fog_opacity_range       = opacity_range,
  9.   fog_opacity_wait_time   = opacity_wait_time,
  10.   fog_opacity_update_time = opacity_update_time,
  11.   fog_color = {r, g, b, a},
  12.   fog_blend_mode = "blend_mode",
  13. },
  14.        
  15. Description
  16.        
  17. "map_id"        (String)     = The id of your map, shorter, it's file name
  18. "fog"           (String)     = The fog bitmap located in /sprites/fogs{
  19. speed           (Integer)    = The speed of your fog (0 = static, 999 = very fast, don't go above 999 or else it will crash)
  20. angle           (Integer)    = Number between 0 and 7 where 0 = east and 7 = south-east (counter clockwise)
  21. opacity         (Integer)    = The opacity of your fog, must be a valid number between 0 and 255
  22.  
  23. --Optionnal
  24. use_depth (Boolean) = Use a depth effect (optionnal), value must be booleans (true or false) or nil
  25. depth_multiplier (Integer) = By default the depth multiply the movement by 1.5 to simulate faster fog movement when you move around, you can change this value (optionnal), value can be decimals and negative.
  26. opacity_range (Table) = Range that determine the maximum and minimum opacity, must be a table value, with 2 values (minimum and maximum opacity)
  27. opacity_wait_time (Integer) = Waiting time before the transition between max / min opacity and vice versa
  28. opacity_update_time (Integer) = Waiting time between opacity +/-1
  29. color  (Table) = Color (red, green, blue and alpha (transparency), values must be between 0 and 255)
  30. blend_mode (String) = Set the fog's blend mode, see Solarus' method of applying blend modes for surfaces (http://www.solarus-games.org/doc/latest/lua_api_drawable.html#lua_api_drawable_set_blend_mode)
  31.  
   
Example, I wanna display a fog in the map with the id "Dungeon7"
Code: Lua
  1. ["Dungeon7"]= {
  2.   fog = "forest_fog",
  3.   fog_speed = 10,
  4.   fog_angle = 3,
  5.   fog_opacity = 75,
  6. },
   
Another example: I want to draw a static image on the map with the id "forest"
Code: Lua
  1. ["forest"]= {
  2.   fog = "forest_cloud",
  3.   fog_speed = 0,
  4.   fog_angle = 0,
  5.   fog_opacity = 75,
  6. },

You can even use the Depth multiplier, if you don't set any value to it through fog_depth_multiplier, it's default value will be 1.5, yet you can specify your own value, even negative
Code: Lua
  1. ["forest"]= {
  2.   fog = "forest_cloud",
  3.   fog_speed = 0,
  4.   fog_angle = 0,
  5.   fog_opacity = 75,
  6.   fog_depth = true
  7. },
   
Now, let's assume we're on a Fire Temple, we want a foggy thing with changing opacity, you can even use the Fog depth.
We can change the Opacity
   
Code: Lua
  1. ["FireTemple_Room8"]= {
  2.   fog = "fire_fog",
  3.   fog_speed = 0,
  4.   fog_angle = 0,
  5.   fog_opacity = 75,
  6.   fog_opacity_range = {50, 110},
  7.   fog_opacity_wait_time = 1000,
  8.   fog_opacity_update_time = 10,
  9. },
The opacity will change each 10ms (1 frame)
When the max or minimum opacity has been reached, defined in fog_opacity_range, the script will pause for 1000 ms (1 sec) before resumine
   
Remember, this happen only in maps/lib/fog_config.lua
So, if you want to declare a fog
   
Code: Lua
  1. local fogs = {
  2.   ["FireTemple_Room8"]= {
  3.     fog = "fire_fog",
  4.     fog_speed = 0,
  5.     fog_angle = 0,
  6.     fog_opacity = 75,
  7.     fog_opacity_range = {50, 110},
  8.     fog_opacity_wait_time = 1000,
  9.     fog_opacity_update_time = 10,
  10.   },
  11.  
  12.   ["forest"]= {
  13.     fog = "forest_cloud",
  14.     fog_speed = 0,
  15.     fog_angle = 0,
  16.     fog_opacity = 75,
  17.   },
  18. }
  19.  
  20. return fogs


**The Script
Code: Lua
  1. return function(map)
  2. --[[
  3. ** Better map fog script
  4. ** Creation Date: Feb. 7 2016
  5. ** Credits needed: You're free to decibe by yourself.
  6.  
  7. ** Script depencies:
  8.   Multi events by Christopho (http://forum.solarus-games.org/index.php/topic,784.0.html)
  9.  
  10. ** What you need:
  11.   Create a folder in /sprites called "fogs" and place your fogs bitmap here.
  12.   Create a file called fog_config.lua in the "maps/lib" folder, and in this file, copy/paste this
  13.  
  14.  
  15.   local fogs = {
  16.  
  17.   }
  18.   return fogs
  19.  
  20.   This is the base of this script,
  21.  
  22. ** How to use:
  23.   //The best is to have a map metatable
  24.  
  25.   This is my map_metatable.lua header
  26.   --
  27.   local map_metatable = sol.main.get_metatable("map")
  28.   require("scripts/fog_manager")(map_metatable)
  29.   --
  30.  
  31.   See ? It's child's play!
  32.  
  33. ** Tutorial: Displaying a fog
  34.  
  35.   This is the whole things you need to know about this script.
  36.        
  37.         ["map_id"]= {
  38.           fog                     = "fog",
  39.           fog_speed               = speed,
  40.           fog_angle               = angle,
  41.           fog_opacity             = opacity,
  42.           fog_depth               = use_depth,
  43.           fog_detph_multiplier    = depth_multiplier,
  44.           fog_opacity_range       = {opacity_range},
  45.           fog_opacity_wait_time   = opacity_wait_time,
  46.           fog_opacity_update_time = opacity_update_time,
  47.           fog_color               = {r, g, b, a}
  48.         },
  49.        
  50.         Description
  51.        
  52.                                 "map_id"            (String)     = The id of your map, shorter, it's file name
  53.                                 "fog"               (String)     = The fog bitmap located in /sprites/fogs{
  54.                             speed               (Integer)    = The speed of your fog (0 = static, 999 = very fast, don't go above 999 or else it will crash)
  55.                     angle               (Integer)    = Number between 0 and 7 where 0 = east and 7 = south-east (counter clockwise)
  56.                     opacity             (Integer)    = The opacity of your fog, must be a valid number between 0 and 255
  57.         (Optionnal) use_depth           (Boolean)    = Use a depth effect (optionnal), value must be booleans (true or false) or nil
  58.         (Optionnal) depth_multiplier    (Integer)    = By default the depth multiply the movement by 1.5 to simulate faster fog movement when you move around, you can change this value (optionnal), value can be decimals and negative.
  59.         (Optionnal) opacity_range       (Table)      = Range that determine the maximum and minimum opacity, must be a table value, with 2 values (minimum and maximum opacity)
  60.         (Optionnal) opacity_wait_time   (Integer)    = Waiting time before the transition between max / min opacity and vice versa
  61.         (Optionnal) opacity_update_time (Integer)    = Waiting time between opacity +/-1
  62.         (Optionnal) color               (Table)      = Color (red, green, blue and alpha (transparency), values must be between 0 and 255)
  63.     (Optionnal) blend_mode          (String)     = Set the fog's blend mode, see Solarus' method of applying blend modes for surfaces (http://www.solarus-games.org/doc/latest/lua_api_drawable.html#lua_api_drawable_set_blend_mode)
  64.  
  65.        
  66.         Example, I wanna display a fog in the map with the id "Dungeon7"
  67.         ["Dungeon7"]= {
  68.           fog                     = "forest_fog",
  69.           fog_speed               = 10,
  70.           fog_angle               = 3,
  71.           fog_opacity             = 75,
  72.         },
  73.        
  74.         Another example: I want to draw a static image on the map with the id "forest"
  75.         ["forest"]= {
  76.           fog                     = "forest_cloud",
  77.           fog_speed               = 0,
  78.           fog_angle               = 0,
  79.           fog_opacity             = 75,
  80.         },
  81.        
  82.         You can even use the Depth multiplier, if you don't set any value to it through fog_detph_multiplier, it's default value will be 1.5, yet you can specify
  83.         your own value, even negative
  84.         ["forest"]= {
  85.           fog                     = "forest_cloud",
  86.           fog_speed               = 0,
  87.           fog_angle               = 0,
  88.           fog_opacity             = 75,
  89.           fog_depth               = true
  90.         },
  91.        
  92.         Now, let's assume we're on a Fire Temple, we want a foggy thing with changing opacity, you can even use the Fog depth.
  93.         We can change the Opacity
  94.        
  95.         ["FireTemple_Room8"]= {
  96.           fog                     = "fire_fog",
  97.           fog_speed               = 0,
  98.           fog_angle               = 0,
  99.           fog_opacity             = 75,
  100.           fog_opacity_range       = {50, 110}
  101.           fog_opacity_wait_time   = 1000
  102.           fog_opacity_update_time = 10
  103.         },
  104.        
  105.         Remember, this happen only in maps/lib/fog_config.lua
  106.        
  107.         So, if you want to declare a fog
  108.        
  109.         local fogs = {
  110.           ["FireTemple_Room8"]= {
  111.             fog                     = "fire_fog",
  112.             fog_speed               = 0,
  113.             fog_angle               = 0,
  114.             fog_opacity             = 75,
  115.             fog_opacity_range       = {50, 110}
  116.             fog_opacity_wait_time   = 1000
  117.             fog_opacity_update_time = 10
  118.           },
  119.        
  120.        
  121.         }
  122.        
  123.         return fogs
  124. ]]
  125.  
  126.   local movement
  127.   local opacity_state = 0
  128.   local fog_data = require("maps/lib/fog_config")
  129.  
  130.   local function load_map(map_id)
  131.     local fog = {}
  132.            
  133.     -- This map was not found while parsing the fog config
  134.     if fog_data[map_id] == nil then
  135.       return
  136.     end
  137.  
  138.     local map = fog_data[map_id]
  139.         if map ~= nil then
  140.           fog[1] = {
  141.                 fog                   = map.fog,
  142.         fog_speed             = map.fog_speed,
  143.                 fog_angle             = map.fog_angle,
  144.                 fog_opacity           = map.fog_opacity,
  145.                 fog_depth             = map.fog_depth,
  146.                 fog_depth_multiplier  = map.fog_detph_multiplier,
  147.                 fog_opacity_range     = map.fog_opacity_range,
  148.                 fog_opacity_wait_time = map.fog_opacity_wait_time,
  149.                 fog_opacity_update    = map.fog_opacity_update_time,
  150.                 fog_color             = map.fog_color,
  151.                 fog_blend_mode        = map.fog_blend_mode
  152.           }
  153.         end
  154.        
  155.     return fog
  156.   end
  157.  
  158.   local function update_opacity_surface(map)
  159.     -- No opacity range, no need to continue
  160.     if map.fog_opacity_r == nil then
  161.           return
  162.         end
  163.        
  164.     local minimum, maximum = map.fog_opacity_r[1], map.fog_opacity_r[2]
  165.         sol.timer.start(map, map.fog_opacity_u, function()
  166.           local opacity = map.fog:get_opacity()
  167.           local new_opacity = opacity_state == 0 and 1 or -1
  168.          
  169.           if opacity == (opacity_state == 0 and maximum or minimum) then
  170.                 sol.timer.start(map, map.fog_opacity_w, function()
  171.                   opacity_state = opacity_state == 0 and 1 or 0
  172.                   update_opacity_surface(map)
  173.                 end)
  174.             return
  175.           end
  176.                
  177.           map.fog:set_opacity(opacity + new_opacity)
  178.                
  179.           return opacity ~= (opacity_state == 0 and maximum or minimum)
  180.         end)
  181.   end
  182.  
  183.   -- Update the movement
  184.   local function compute_movement(map)
  185.     map.fog:set_opacity(map.fog_opacity)
  186.         local fog_size_x, fog_size_y = map.fog:get_size()
  187.        
  188.         -- No speed, no need to continue
  189.         if map.fog_speed == 0 then
  190.           return
  191.         end
  192.        
  193.     local fog_angle = map.fog_angle
  194.         -- Get the Max movement in order to determine the max distance
  195.         -- Diagonal is determined by Pythagorean theorem a² = b² + c²
  196.         local diagonal = math.sqrt((fog_size_x * fog_size_x) + (fog_size_y * fog_size_y))
  197.         local angle = {
  198.           fog_size_x,
  199.           fog_size_y,
  200.           fog_size_x,
  201.           fog_size_y,
  202.         }
  203.        
  204.         local max_distance =  fog_angle > 0 and angle[fog_angle / 2] or 0
  205.         if fog_angle % 2 ~= 0 then
  206.           max_distance = diagonal
  207.         end
  208.  
  209.         function restart_overlay_movement()
  210.           movement = sol.movement.create("straight")
  211.           movement:set_speed(map.fog_speed)
  212.           movement:set_max_distance(max_distance)
  213.           movement:set_angle(fog_angle * math.pi / 4)
  214.           movement:start(map.fog, function()
  215.                 map.fog:set_xy(0, 0)
  216.                 restart_overlay_movement()
  217.           end)
  218.     end
  219.         restart_overlay_movement()
  220.   end
  221.  
  222.   map:register_event("on_started", function(map)
  223.     local data = load_map(map:get_id())
  224.        
  225.         if movement ~= nil then
  226.           movement:stop()
  227.         end
  228.  
  229.         if data == nil then
  230.           return
  231.         end
  232.        
  233.     for _, fog in ipairs(data) do
  234.           map.fog           = sol.surface.create("fogs/".. fog.fog ..".png")
  235.           map.fog_speed     = fog.fog_speed
  236.           map.fog_opacity   = fog.fog_opacity
  237.           map.fog_angle     = fog.fog_angle
  238.           map.fog_depth     = fog.fog_depth
  239.           map.fog_depth_mvt = fog.fog_depth_multiplier ~= nil and fog.fog_depth_multiplier or 1.5
  240.           map.fog_opacity_r = fog.fog_opacity_range
  241.           map.fog_opacity_w = fog.fog_opacity_wait_time
  242.           map.fog_opacity_u = fog.fog_opacity_update
  243.          
  244.           if fog.fog_blend_mode ~= nil then
  245.             map.fog:set_blend_mode(fog.fog_blend_mode)
  246.           end
  247.          
  248.           if fog.fog_color ~= nil then
  249.             map.fog:fill_color(fog.fog_color)
  250.           end
  251.          
  252.           break
  253.         end
  254.        
  255.        
  256.  
  257.         compute_movement(map)
  258.         update_opacity_surface(map)
  259.   end)
  260.  
  261.   map:register_event("on_draw", function(map, dst_surface)
  262.     local scr_x, scr_y = dst_surface:get_size()
  263.        
  264.     if map.fog ~= nil then
  265.           local x, y = map:get_camera():get_bounding_box()
  266.           local overlay_width, overlay_height = map.fog:get_size()
  267.          
  268.           if map.fog_depth ~= nil then
  269.             x, y = -math.floor(x * map.fog_depth_mvt), -math.floor(y * map.fog_depth_mvt)
  270.           else
  271.             x, y = -math.floor(x), -math.floor(y)
  272.           end
  273.  
  274.           x = x % overlay_width  - 2 * overlay_width
  275.           y = y % overlay_height - 2 * overlay_height
  276.          
  277.           local dst_y = y
  278.           while dst_y < scr_y + overlay_height do
  279.             local dst_x = x
  280.             while dst_x < scr_x + overlay_width do
  281.               map.fog:draw(dst_surface, dst_x, dst_y)
  282.                   dst_x = dst_x + overlay_width
  283.             end
  284.             dst_y = dst_y + overlay_height
  285.           end
  286.     end
  287.   end)
  288. end

Small example, Cloud.

Code: [Select]
  fog = "overworld_smallcloud",
  fog_speed = 10,
  fog_angle = 3,
  fog_opacity = 75,

This is how it will looks (minus the tone)



NO ! NO !



Another example: a static image

Parameters

Code: [Select]
  fog = "forest",
  fog_angle = 0,
  fog_speed = 0,
  fog_opacity = 150,



 
Code: Lua
  1.  ["normal/Dungeon/GoronSanctuary/boss/boss"] = {
  2.     fog                     = "fire_mist",
  3.         fog_speed               = 10,
  4.         fog_angle               = 7,
  5.         fog_opacity             = 70,
  6.         fog_depth               = true,
  7.         fog_detph_multiplier    = nil,
  8.         fog_opacity_range       = {40, 110},
  9.         fog_opacity_wait_time   = 1000,
  10.         fog_opacity_update_time = 10
  11.   },

Give this !
https://www.youtube.com/watch?v=36m3gcFFWao

Code: Lua
  1.   ["normal/Dungeon/GoronSanctuary/boss/boss"] = {
  2.     fog                     = "fire_mist",
  3.         fog_speed               = 10,
  4.         fog_angle               = 7,
  5.         fog_opacity             = 70,
  6.         fog_depth               = true,
  7.         fog_detph_multiplier    = nil,
  8.         fog_opacity_range       = {40, 110},
  9.         fog_opacity_wait_time   = 1000,
  10.         fog_opacity_update_time = 10,
  11.         fog_color               = {255, 0, 0, 150},
  12.   },

Give this :
https://www.youtube.com/watch?v=yia2Xy_U3_g

9
Bugs & Feature requests / Freeze when using movement:set_path()
« on: January 20, 2017, 02:28:23 pm »
Hello

I was modifying a platform script (from Diarandor I guess), which was a simple platform script, and I decided to modify it so it allow custom movement, path movement, and in the future circular movement

Code: Lua
  1. local entity = ...
  2. local hero = entity:get_map():get_entity("hero")
  3.  
  4. -- Platform
  5. -- changes:
  6.  
  7. -- size              -> Entity size
  8. -- time_stopped      -> self.time_stopped
  9. -- speed             -> self.speed
  10. -- directionnal path -> self.path
  11.  
  12. --todo
  13. --entity.movement_type (path / circular / straight / target)
  14.  
  15. -- And anything related to these movement
  16.  
  17. function entity:on_created()
  18.   local size_x, size_y = self:get_size()
  19.   self:set_size(size_x, size_y)
  20.   self:set_origin(size_x / 2, size_y / 2)
  21.   self:set_can_traverse("jumper", true)
  22.   self:set_can_traverse_ground("hole", true)
  23.   self:set_can_traverse_ground("deep_water", true)
  24.   self:set_can_traverse_ground("lava", true)
  25.   self:set_can_traverse_ground("traversable", true)
  26.   self:set_can_traverse_ground("shallow_water", false)
  27.   self:set_can_traverse_ground("wall", false)
  28.   self:set_modified_ground("traversable")
  29.   self:set_layer_independent_collisions(false)
  30.  
  31.   self:start_movement()
  32. end
  33.  
  34. function entity:start_movement()
  35.   local m = sol.movement.create("path")
  36.   m:set_path(self.path)
  37.   m:set_speed(self.speed)
  38.   m:set_loop(true)
  39.   m:start(self)
  40.  
  41.   self:add_collision_test("touching", function(_, other)
  42.     if other:get_type() == "wall" or (other:get_type() == "custom_entity" and other:get_model() == "object/platform/limit") then
  43.       self:on_obstacle_reached(m)
  44.     end
  45.   end)
  46. end
  47.  
  48. function entity:on_obstacle_reached(movement)
  49.   -- Reverse the movement, reverse the table
  50.   for i = 1, math.floor(#self.path / 2) do
  51.     local tmp = self.path[i]
  52.     self.path[i] = self.path[#tbl - i + 1]
  53.     self.path[#self.path - i + 1] = tmp
  54.   end
  55.  
  56.   --Make the platform turn back.
  57.   movement:stop()
  58.   movement = sol.movement.create("path")    
  59.   movement:set_path(self.path)
  60.   movement:set_speed(self.speed)
  61.   movement:set_loop(true)
  62.  
  63.   sol.timer.start(self, self.time_stopped, function()
  64.     movement:start(self)
  65.   end)
  66. end
  67.  
  68. function entity:on_position_changed()
  69.   -- Moves the hero if located over the platform.
  70.   if not self:is_on_platform(hero) then return end
  71.     local hx, hy, hl = hero:get_position()
  72.     local direction4 = self:get_direction()
  73.     local dx, dy = 0, 0 --Variables for the translation.
  74.     if direction4 == 0 then dx = 1
  75.     elseif direction4 == 1 then dy = -1
  76.     elseif direction4 == 2 then dx = -1
  77.     elseif direction4 == 3 then dy = 1
  78.     end
  79.     if not hero:test_obstacles(dx, dy, hl) then hero:set_position(hx + dx, hy + dy, hl) end
  80. end
  81.  
  82. function entity:on_movement_changed(movement)
  83.   --Change direction of the sprite when the movement changes.
  84.   local direction4 = movement:get_direction4()
  85.   self:set_direction(direction4)
  86. end
  87.  
  88. function entity:is_on_platform(other_entity)
  89.   --Returns true if other_entity is on the platform.
  90.   local ox, oy, ol = other_entity:get_position()
  91.   local ex, ey, el = self:get_position()
  92.   if ol ~= el then return false end
  93.   local sx, sy = self:get_size()
  94.   if math.abs(ox - ex) < sx/2 -1 and math.abs(oy - ey) < sy/2 -1 then return true end
  95.   return false
  96. end
  97.  

Everything works fine, the entity's movement, speed and delay is now customizable from the map script

However

This is the script call in the map script, the platform is respectively named "platform0" and tried to test a simple squarishpath

Code: Lua
  1. local platform0 = map:get_entity("platform0")
  2. platform0.path = {0, 0, 0, 0, 6, 6, 6, 6, 4, 4, 4, 4, 2, 2, 2, 2}
  3. platform0.speed = 60
  4. platform0.time_stopped = 1000

Running the game, no errors whatsoever, but as soon as the map is loaded, the game freeze, the only way to quit the game is by force closing it.

What's wrong ?

10
Bugs & Feature requests / can we extend on_command_pressed(command) ?
« on: January 16, 2017, 02:04:09 pm »
Hello,

My question concerns on_command_pressed(command) and custom inputs.

The advantage with on_command_pressed is that it englobe both keyboard and joypad bindings with ease, so it is not necessary to have in each menu that need to check a custom input such functions (on_joypad_*_pressed/moved), the command customisation menu is an exception.

Is it possible to do a such thing ? for example, let's say that I implemented a new input "minimap" and I wanna add it as a build-in command for on_command_pressed(command)

Want an example, well

This is the command table of my game

Code: Lua
  1. -- Group all key bindings, build in and custom. This is used in the Option submenu, File selection screen
  2. -- This also get the savegame values of bindings.
  3. game.command= {
  4. --  Command           Keyboard           Joypad
  5.   {"right"  , "_keyboard_right" , "_joypad_right"},
  6.   {"up"     , "_keyboard_up"    , "_joypad_up_key"},
  7.   {"left"   , "_keyboard_left"  , "_joypad_left_key"},
  8.   {"down"   , "_keyboard_down"  , "_joypad_down_key"},
  9.        
  10.   {"item_1" , "_keyboard_item_1", "_joypad_item_1"},
  11.   {"item_2" , "_keyboard_item_2", "_joypad_item_2"},
  12.    
  13.   {"attack" , "_keyboard_attack", "_joypad_attack"},
  14.   {"action" , "_keyboard_action", "_joypad_action"},
  15.   {"pause"  , "_keyboard_pause" , "_joypad_pause"},
  16.        
  17.   {"shield" , "keyboard_shield" , "joypad_shield"},
  18.   {"minimap", "keyboard_minimap", "joypad_minimap"},
  19.   {"camera" , "keyboard_camera" , "joypad_camera"},
  20.   {"items"  , "keyboard_items"  , "joypad_items"}
  21. }

Something like this for a command

Code: Lua
  1.   function menu:on_command_pressed(command)
  2.     if command == "minimap" then
  3.       -- Run the code
  4.     end
  5.   end
  6.  

Is more efficient than this

Code: Lua
  1.   function menu:on_key_pressed(key)
  2.     if key== game:get_value("keyboard_minimap") then
  3.       -- Run the code
  4.     end
  5.   end
  6.  
  7.  function menu:on_joypad_hat_moved(hat, state)
  8.     C/C
  9.   end
  10.  
  11.  function menu:on_joypad_button_pressed(key)
  12.     C/P
  13.   end
  14.  
  15.  function menu:on_joypad_axis_moved(axis, state)
  16.    C/P
  17.   end
  18.  

11
Development / Custom sword ?
« on: January 11, 2017, 04:38:08 pm »
Hello.

So, Diarandor, I see that you use a custom sword for your project that I personnaly like since I want to be as close as Wind Waker / Minish Cap styled gameplay, I am currently reworking the hero's abilities for my project, the shield is being totally custom as well (Mirror Shield need other stuffs).

But, shield is simple to make,it's just something that you constantly synchronise on the hero and cancel when the hero state change or if the input is released, a simple function can handle enemy collision related stuffs, on a sword, it is different, I need some advice on many things such as the sword tapping and the spin attack related thing, are you using a timer in on_command_pressed or something like that ?

12
Bugs & Feature requests / surface:fade_in/out issue ?
« on: January 05, 2017, 12:11:00 am »
Hello.

When fading a surface by using fade in or fade out, our goal is to have the surface's opacity to 255 or 0, but the opacity, is never at 0 or 255, is this intentionnal ?

13
Development / Avoid pickables to be ... picked ?
« on: December 28, 2016, 01:00:51 am »
Hi.

So today I was working on streams (fan & water stream), so it implied also reworking an item: the Roc's Cape.
The roc's cape is a simple, yet complex item, script-wise.

The Hero's sprite coordinate are always changing while using the roc's cape, but it's collision stays (see bellow) on ground, which means, teleporters and switches are disabled if the player use this item, as well as being invincible to avoid any collision with enemies.



All works fine, but picking an item while flying is weird, and there is no pickable:set_obtainable(boolean) or whatever to avoid the hero to pick any items

Any workaround or solution ?

14
Bugs & Feature requests / text:set_horizontal/vertical_alignment() issue ?
« on: December 26, 2016, 02:43:48 pm »
Hi.

When I was working on some scripts something went wrong.
I am using different surfaces to display a text, but this surface change it's alignement depending on the content itself.

However ...

The text surface is created in on_started, like so

Code: Lua
  1. self.text = sol.text_surface.create( blablabla )
  2.  

There is a problem if I'm trying to change the text alignment on another function, for instance, in on_command_pressed()

Code: Lua
  1. self.text:set_horizontal_alignment("left")

An error occurs

Code: [Select]
calling set_horizontal_alignment on bad self (string expected, got userdata))
However, self.text:get_horizontal_alignment() works ...

15
Bugs & Feature requests / Dungeon map scaling issue ?
« on: December 10, 2016, 02:47:21 pm »
Hi.

So, while making dungeon minimap for the pause menu, I ran into a problem.
The map background is a placeholder from BoM

If I set the scale of the dungeon floor to the size of the map (for testing if scaling is right), the placement of bitmaps and the position of things can be wrong.

Here, I placed Link at coordinate 0, 0 (8, 13) and the map location on this world is set to 0, 0



You might see that here, the scaling is correct, I purposely show the configuration file so you might be able to reproduce it all by yourself

But, if I set the width / height of the minimap scaling to the size of the room, this happen



Link's position is still 8, 13 and map coordinate in the world is still 0, 0.

I use the MoS and BoM menu, both are similar. So you might be able to reproduce this bug.

My guess is, the faulty part is on map_submenu:to_dungeon_minimap_coordinates(x, y)


Pages: [1] 2 3 4