Original art

Started by Diarandor, February 06, 2016, 03:02:41 PM

Previous topic - Next topic
Thanks again for the feedback! I named the song "Castle Theme", not very original XD ;D it can be downloaded from the sample quest repo, but Christopho renamed it to castle.ogg, I think. A few days ago I asked to E. Dueñas if he could remake the song with real instruments and improve it, but he has not answered yet... :(
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Hi, I made an experimental rain script that now has 2 modes: "rain" and "storm", but future versions may include "snow" and "hail". Using custom entities for the drops is probably a bad idea since it might run slow for slow computers, but for now it is ok since I am just testing.
Link: https://youtu.be/nDjgBTQbBug
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

I like it a lot, it's superb, but the use of custom entities isn't recommended, we should wait set_pixel(), I already planned to port one of the most advanced weather script made for RPG Maker

Quote from: MetalZelda on February 12, 2017, 08:16:33 PM
I like it a lot, it's superb, but the use of custom entities isn't recommended, we should wait set_pixel(), I already planned to port one of the most advanced weather script made for RPG Maker

Yeah, you are right. I have tested this script with a map of Mercuris Chest and it runs too slow (with big maps it becomes very slow), which is really bad; so the script is useless as it is. I may try to use a surface and draw the sprites above it, but I am not sure if this will work as it should... Maybe you are right, and we should wait for that new feature "set_pixel()", I don't know.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

It is good for small maps. Are you gonna post it?
Solarus Works on ReactOS Opensource Windows OS

https://www.reactos.org/forum/viewtopic.php?f=2&t=14759&p=120616#p120616

February 13, 2017, 12:32:56 PM #65 Last Edit: February 13, 2017, 12:34:40 PM by MetalZelda
Quote from: Diarandor on February 12, 2017, 08:43:54 PM
Quote from: MetalZelda on February 12, 2017, 08:16:33 PM
I like it a lot, it's superb, but the use of custom entities isn't recommended, we should wait set_pixel(), I already planned to port one of the most advanced weather script made for RPG Maker

Yeah, you are right. I have tested this script with a map of Mercuris Chest and it runs too slow (with big maps it becomes very slow), which is really bad; so the script is useless as it is. I may try to use a surface and draw the sprites above it, but I am not sure if this will work as it should... Maybe you are right, and we should wait for that new feature "set_pixel()", I don't know.

https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script

The clock script for my project is also a reconversion of a RPG Maker script, as well as the tone system, so porting this script to Solarus might not be hard, the only thing needed here is surface:set_pixel()

You can see how set_pixel is used here
https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script#L2304

At least my first try with this would be only to get rain, snow and rain droplets to work, other things can be omnitted

Quote from: MetalZelda on February 13, 2017, 12:32:56 PM
https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script

The clock script for my project is also a reconversion of a RPG Maker script, as well as the tone system, so porting this script to Solarus might not be hard, the only thing needed here is surface:set_pixel()

You can see how set_pixel is used here
https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script#L2304

At least my first try with this would be only to get rain, snow and rain droplets to work, other things can be omnitted

Well, actually it was not my intention to "port" things from RPG Maker, this was intended to be something different and better. Yes, I don't hide that I really hate RPG Maker! (RPG Maker is too expensive, it has too many limitations, it is annoying to use if you know programming, their community is our rival 8) heheh, and that engine and its graphics are not free!)
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

February 13, 2017, 12:58:37 PM #67 Last Edit: February 13, 2017, 01:00:43 PM by Diarandor
Quote from: zutokaza on February 13, 2017, 06:28:26 AM
It is good for small maps. Are you gonna post it?

Ok, sorry, I intended to post it later when it worked better. Here you have my current script (a working one), but not the last version if I update it later. (You will need the multi_events script that Christopho made.) Put my script in a file "scripts/weather/rain_manager.lua" or a similar place.
Code (Lua) Select

-- Rain manager script.
--[[
To add this script to your game, call from game_manager script:
    require("scripts/weather/rain_manager")

The functions here defined are:
    game:get_rain_type(world)
    game:set_rain_type(world, rain_type)

Rain types: nil (no rain), "rain", "storm".
--]]

-- This script requires the multi_event script:
require("scripts/multi_events")
local rain_manager = {}

local game_meta = sol.main.get_metatable("game")
local map_meta = sol.main.get_metatable("map")


-- Default settings. Change these for testing.
local rain_enabled = true -- Do not change this property, unless you are testing.
-- local lightning_enabled = true
local rain_speed = 100 -- Default drop speed 100.
local storm_speed = 300 -- Default drop speed 300.
local drop_speed -- Local variable to store the speed.
local drop_max_distance = 300 -- Max possible distance for drop movements.
local rain_drop_delay = 10 -- Delay between drops for rain, in milliseconds.
local storm_drop_delay = 5 -- Delay between drops for storms, in milliseconds.
local min_lightning_delay = 2000
local max_lightning_delay = 10000
local drop_sprite_id = "weather/rain"
local thunder_sounds = {"thunder1", "thunder2", "thunder3", "thunder_far", "thunder_double"}
local flash_surface -- Surface to draw the lightning flash.
local draw_flash_surface = false -- Used by the lightning menu.
local timers = {}


-- Initialize rain on maps when necessary.
game_meta:register_event("on_map_changed", function(game)
    local map = game:get_map()
    rain_manager:update_rain(map)
end)

-- Get the raining state for a given world.
function game_meta:get_rain_type(world)
  local rain_type = nil
  if world then
    rain_type = self:get_value("rain_state_" .. world)
  end
  return rain_enabled and rain_type
end
-- Set the raining state for a given world.
function game_meta:set_rain_type(world, rain_type)
  -- Update savegame variable.
  self:set_value("rain_state_" .. world, rain_type)
  -- Check if rain is necessary: if we are in that world and rain is needed. 
  local current_world = self:get_map():get_world()
  local rain_needed = (current_world == world) and rain_enabled and rain_type
  if (not rain_needed) then return end -- Do nothing if rain is not needed!
  -- We need to start the rain in the current map.
  local map = self:get_map()
  rain_manager:update_rain(map)
end

-- Define on_draw event for the rain_manager menu (if it is initialized).
function rain_manager:on_draw(dst_surface)
  if draw_flash_surface then
    flash_surface:draw(dst_surface) -- Draw lightning flash if necessary.
  end
end

-- Create rain if necessary when entering a new map.
function rain_manager:update_rain(map)
  -- Get rain state in this world.
  local world = map:get_world()
  local rain_type = map:get_game():get_rain_type(world)
  -- Start rain if necessary.
  if rain_type == "rain" then
    self:start_rain(map)
  elseif rain_type == "storm" then
    self:start_storm(map)
  end
end

-- Define function to create splash effects.
-- If no parameters x, y are given, the position is random.
local function create_drop_splash(map, x, y)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local cx, cy, cw, ch = camera:get_bounding_box()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize parameters.
  local x = x or cx + cw * math.random()
  local y = y or cy + ch * math.random()
  local layer = max_layer
  while map:get_ground(x,y,layer) == "empty" and layer > min_layer do
    layer = layer - 1 -- Draw the splash at the lower layer we can.
  end
  -- Do not draw splash over some bad grounds: "hole" and "lava".
  local ground = map:get_ground(x, y, layer)
  if ground ~= "hole" and ground ~= "lava" then
    drop_properties.x = x
    drop_properties.y = y
    drop_properties.layer = layer
    local drop_splash = map:create_custom_entity(drop_properties)
    local splash_sprite = drop_splash:get_sprite()
    splash_sprite:set_animation("drop_splash")
    splash_sprite:set_direction(0)
    function splash_sprite:on_animation_finished() drop_splash:remove() end
  end
end

-- Define function to create drops.
-- If no parameters x, y are given, the position is random.
local function create_drop(map, x, y)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local cx, cy, cw, ch = camera:get_bounding_box()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize parameters.
  drop_properties.x = x or cx + cw * math.random() + 30
  drop_properties.y = y or cy + ch * math.random() - 100
  drop_properties.layer = max_layer
  local drop = map:create_custom_entity(drop_properties)
  local m = sol.movement.create("straight")
  m:set_angle(7 * math.pi / 5)
  m:set_speed(drop_speed)
  local random_max_distance = math.random(1, drop_max_distance)
  m:set_max_distance(random_max_distance)
  m:set_ignore_obstacles()
  function m:on_finished()
    local x, y = drop:get_position()
    create_drop_splash(map, x, y)
    drop:remove()
  end
  function m:on_obstacle_reached()
    local x, y = drop:get_position()
    create_drop_splash(map, x, y)
    drop:remove()
  end
  m:start(drop)
end

-- Stop rain effects for the current map.
function rain_manager:stop()
  -- Stop rain timers if already started.
  for k, timer in pairs(timers) do
    timer:stop()
    timers[k] = nil
  end
end

-- Start rain in the current map.
function rain_manager:start_rain(map)
  local max_layer = map:get_max_layer()
  local min_layer = map:get_min_layer()
  local camera = map:get_camera()
  local drop_properties = {direction = 0, x = 0, y = 0, layer = max_layer,
    width = 16, height = 16, sprite = drop_sprite_id}
  -- Initialize drop speed.
  drop_speed = rain_speed
  -- Initialize random seed for positions.
  math.randomseed(os.time())

  -- Stop rain timers if already started.
  self:stop()
  -- Start timer to draw rain drops.
  timers["drop_timer"] = sol.timer.start(map, rain_drop_delay, function()
    -- Create drops on random positions.
    create_drop(map)
    -- Repeat loop.
    return true
  end)
end

-- Start lighnings in the current map.
local function create_lightnings(map)
  -- Play thunder sound after a random delay.
  local lightning_delay = math.random(min_lightning_delay, max_lightning_delay)
  timers["lightning_timer"] = sol.timer.start(map, lightning_delay, function()
    -- Create lightning flash.
    draw_flash_surface = true
    sol.timer.start(map, 150, function()
      draw_flash_surface = false -- Stop drawing lightning flash.
    end)
    -- Play random thunder sound after a delay.
    local thunder_delay = math.random(200, 1500)
    sol.timer.start(map, thunder_delay, function()
      local random_index = math.random(1, #thunder_sounds)
      local sound_id = thunder_sounds[random_index]
      sol.audio.play_sound(sound_id)
    end)
    -- Prepare next lightning.
    create_lightnings(map)
  end)
end

-- Start storm in the current map.
function rain_manager:start_storm(map)
  -- Initialize drop speed.
  drop_speed = storm_speed
  -- Initialize random seed for positions.
  math.randomseed(os.time())
  -- Stop rain timers if already started.
  self:stop()
  -- Create lightning surface.
  local camera = map:get_camera()
  local cx, cy, cw, ch = camera:get_bounding_box()
  flash_surface = sol.surface.create(cw, ch)
  flash_surface:fill_color({255, 255, 100})
  flash_surface:set_opacity(170)
  -- Initialize menu to draw lightning surface.
  sol.menu.start(map, rain_manager)

  -- Start timer to draw rain drops.
  timers["drop_timer"] = sol.timer.start(map, storm_drop_delay, function()
    -- Create drops on random positions.
    create_drop(map)
    -- Repeat loop.
    return true
  end)
  -- Start lightning effects.
  create_lightnings(map)
end

-- Return rain manager.
return rain_manager


Other required files:
-Sound files: I made 5 thunder sounds that you can download from the solarus-free-resource-pack repo or from my diarandor-art repo, in github. These can be replaced by other files if you want your custom thunder sounds.
-Rain sprite: put the png and dat files in "sprites/weather". The files are attached.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Quote from: Diarandor on February 13, 2017, 12:49:09 PM
Quote from: MetalZelda on February 13, 2017, 12:32:56 PM
https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script

The clock script for my project is also a reconversion of a RPG Maker script, as well as the tone system, so porting this script to Solarus might not be hard, the only thing needed here is surface:set_pixel()

You can see how set_pixel is used here
https://github.com/MetalES/Project-Zelda/blob/master/%5BTODO%5D%20Port%20Weather%20Script#L2304

At least my first try with this would be only to get rain, snow and rain droplets to work, other things can be omnitted

Well, actually it was not my intention to "port" things from RPG Maker, this was intended to be something different and better. Yes, I don't hide that I really hate RPG Maker! (RPG Maker is too expensive, it has too many limitations, it is annoying to use if you know programming, their community is our rival 8) heheh, and that engine and its graphics are not free!)

Oh, I don't like RPG Maker in term of it's limitations eigher, but the scripting community is fantastic and most of the time it's easy to adapt a script from RUBY to Lua (At least RGSS1).
The clock script and the tone calculation is RPG Maker's code rewritten in pure Lua  ;D

Yet, this is not RPG Maker hate, the script is a nice base to start with, pretty sure something incredible can be achieved if rewritten correctly.

Hey listen!

A new remastered/enhanced version of Eldran is in progress! This might be the final version for this hero, and the one that will be used in the project CoS. In this first video I show some of the new animations for "stopped", "walking", "carrying", "carrying_walking" and "lifting". The remaining animations will be shown in the next videos.  ;D
https://youtu.be/fZhthAIhldk
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."


The colors were chosen by Neovyse, and he also gave me wise advices of how to improve these animations. The final result is awesome, but it has been many hours of work (almost every pixel has been redrawn from scratch).
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

New testing video with new remastered animations for our hero Eldran!
The new remastered animations include "grabbing", "pushing", "pulling", "jumping", "plunging" (not shown in the video) and "swimming". In addition, a new "sleeping" animation in a confortable bed is shown.

Eldran Link here: https://youtu.be/LIAuW8O1jtY

More animations coming in a few weeks!
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

A few more animations are finished for the remastered Eldran. These include "sword_loading_stopped", "sword_loading_walking" and "sword_brandish". Link here:
https://youtu.be/ar3OJIuHJac
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

That sleep animation in your previous update reminded me of Secret of Mana and sequels. I really like this remastered version. You did a great job on the animation improvements.