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 - Diarandor

#676
I made a new cool video showing the new enemies: yellow and red slimes. These have electric and fire attacks, respectively, and will be added to the sample quest someday.
https://www.youtube.com/watch?v=pJLJKSFsh-Y&feature=youtu.be
#677
Hi! One of the many things I will be working on is the creation of new free enemies with original art and fully scripted. I will keep adding them to the sample quest, and many of them are planned to be used in the project Children of Solarus. Some of my current work is here:
https://github.com/Bertram25/ChildrenOfSolarus/issues/29

Feedback wanted: If you have some cool and original idea of some type of enemy you want, then post it here. If I like the idea, I might make them when I get free time (but please, be patient). If the behavior is a bit complicated I might not do it, because I prefer to focus more on making free art than coding strange things, so think of basic stuff (no bosses or similar things); but also try to think of enemies with different and new original behaviors too, so that we will have more variety of enemies. Try to give as much details as possible, for the graphic part and also the behavior of the enemy.

Here you can also share your own original enemies, with both sprites and code, and maybe a link to some video to show them in action.
Quest makers, I challenge you to make something cool and post it here!!! hehehe! :D
#678
Game art & music / Did you know about ZREO?
July 28, 2016, 07:18:36 AM
Greetings!

I'm pretty sure that many of you have already heard about ZREO ("Zelda Reorchestrated"), which is a team of many people that make covers and orchestrated versions of the music of Zelda games. I thought they deserved to be mentioned here since we all are Zelda fans here. If you are interested, you can listen to their music in their official website and their youtube channel:

http://www.zreomusic.com/
https://www.youtube.com/user/ZREOTeam/
https://twitter.com/zreomusic
#679
Game art & music / Re: Original art
July 26, 2016, 09:47:14 AM
Another character that may appear in the project "Children of Solarus" is the astrologer-magician:
https://www.youtube.com/watch?v=7dw59QQrzL8
Note that this is just a test map, as usually, and this character is still unfinished (some directions and animations are still remaining work to do).

EDIT: the missing directions are now finished. I will not make the walking animations since we probably will not need them.
http://diarandor.deviantart.com/art/Astrologer1-v1-0-624445650
#680
Development / Re: [Test]Reworked items
July 25, 2016, 12:14:49 AM
hero_metatable.lua
Code (Lua) Select

-- Define/redefine functions of the hero metatable.
local hero_meta = sol.main.get_metatable("hero")

-- Functions to get/set the index of the hero.
function hero_meta:get_index() return self:get_game():get_hero_index() end
function hero_meta:set_index(index) self:get_game():set_hero_index(index) end

-- Define a function to change to carrying state. (The same functions are defined for npc_heroes.)
function hero_meta:set_carrying(boolean)
  if boolean then
    self:set_fixed_animations("carrying_stopped", "carrying_walking")
    self:set_animation("carrying_stopped")
  else
    self:set_fixed_animations(nil, nil)
    if self:is_walking() then self:set_animation("walking")
    else self:set_animation("stopped") end
  end
end

-- Make carried entities follow the hero when the position changes.
function hero_meta:on_position_changed()
  if self.custom_carry then -- There is a carried item.
    local x, y, layer = self:get_position()
    if self.custom_carry.set_position then
      self.custom_carry:set_position(x, y+2, layer)
    end
  end
end 

-- Throw the carried entities when hurt.   
function hero_meta:on_taking_damage(damage)
  self:get_game():remove_life(damage) -- Remove life.
  if self.custom_carry then
    self:start_throw() -- Throw carried entity.
  end
end
   
-- Throw generic portable entities.
-- Display the throwing animation of the hero and throw the portable entity.
function hero_meta:start_throw()
  -- State changes and properties. Get direction to throw.
  local game = self:get_game()
  local animation = self:get_animation()
  local direction = self:get_direction()
  if animation == "carrying_stopped" or animation == "hurt" then direction = nil end
  local portable = self.custom_carry
  self.custom_carry = nil
  self:freeze()
  -- Change animation set of hero to stop carrying. Start animation throw of the hero.
  self:set_animation("throw", function()
    game:clear_interaction() -- Restart hero interaction.
    self:set_carrying(false)
    self:unfreeze()
  end)
  game:set_custom_command_effect("action", nil)
  game:set_custom_command_effect("attack", nil)
  local carrier = self -- Used to make platform inertia if carrier is on platform.
  -- Throw the portable entity.
  portable:set_position(self:get_position())
  local args = {falling_direction = direction, carrier = carrier}
  portable:throw(args)
end

-- Function to know if the hero is walking.
function hero_meta:is_walking()
  local m = self:get_movement()
  return m and m.get_speed and m:get_speed() > 0
end

-- Function to set a fixed direction for the hero (or nil to disable it).
function hero_meta:set_fixed_direction(direction)
  self.fixed_direction = direction
  if direction then self:get_sprite("tunic"):set_direction(direction) end
end
-- Function to get a fixed direction for the hero.
function hero_meta:get_fixed_direction()
  return self.fixed_direction
end
-- Function to set fixed stopped/walking animations for the hero (or nil to disable it).
function hero_meta:set_fixed_animations(stopped_animation, walking_animation)
  self.fixed_stopped_animation = stopped_animation
  self.fixed_walking_animation = walking_animation
  -- Initialize fixed animations if necessary.
  if self:get_state() == "free" then
    if self:is_walking() then self:set_animation(walking_animation or "walking")
    else self:set_animation(stopped_animation or "stopped") end
  end
end
-- Function to get fixed stopped/walking animations for the hero.
function hero_meta:get_fixed_animations()
  return self.fixed_stopped_animation, self.fixed_walking_animation
end

-- Functions to enable/disable pushing ability for the hero.
-- TODO: change this if necessary for a built-in function when it is done.
do
  local pushing_animation
  function hero_meta:get_pushing_animation() return pushing_animation end
  function hero_meta:set_pushing_animation(animation) pushing_animation = animation end
end

-- Initialize events to fix direction and animation for the tunic sprite of the hero.
-- To do it, we redefine the on_created and set_tunic_sprite_id events using the hero metatable.
do
  local function initialize_fixing_functions(hero)
    -- Define events for the tunic sprite.
    local sprite = hero:get_sprite("tunic")
    function sprite:on_animation_changed(animation)
      local fixed_stopped_animation = hero.fixed_stopped_animation
      local fixed_walking_animation = hero.fixed_walking_animation
      local tunic_animation = sprite:get_animation()
      if tunic_animation == "stopped" and fixed_stopped_animation ~= nil then
        if fixed_stopped_animation ~= tunic_animation then
          sprite:set_animation(fixed_stopped_animation)
        end
      elseif tunic_animation == "walking" and fixed_walking_animation ~= nil then
        if fixed_walking_animation ~= tunic_animation then
          sprite:set_animation(fixed_walking_animation)
        end
      elseif tunic_animation == "pushing" then
        local pushing_animation = hero:get_pushing_animation()
        if pushing_animation then hero:set_animation(pushing_animation) end
      end
    end
    function sprite:on_direction_changed(animation, direction)
      local fixed_direction = hero.fixed_direction
      local tunic_direction = sprite:get_direction()
      if fixed_direction ~= nil and fixed_direction ~= tunic_direction then
        sprite:set_direction(fixed_direction)
      end
    end
  end
  -- Initialize fixing functions when the hero is created.
  function hero_meta:on_created()
    initialize_fixing_functions(self)
  end
  -- Initialize fixing functions for the new sprite when the sprite is replaced for a new one.
  local old_set_tunic = hero_meta.set_tunic_sprite_id -- Redefine this function.
  function hero_meta:set_tunic_sprite_id(sprite_id)
    old_set_tunic(self, sprite_id)
    initialize_fixing_functions(self)
  end
end

-- TODO: delete next function after issue #827 is fixed.
-- Call this function to notify the engine that the ground under hero has changed.
-- Necessary after calling hero:unfreeze(), unless some entity has modified the ground below.
function hero_meta:refresh_ground_below()
  -- Create custom entity with traversable ground that under the hero.
  local x,y,layer = self:get_position()
  local tile = self:get_map():create_custom_entity({x=x,y=y,layer=layer,direction=0,width=8,height=8})
  tile:set_origin(4, 4)
  tile:set_modified_ground("traversable")
  tile:remove()
end

-- End of the script. Kill the local variable.
hero_meta = nil
#681
Development / Re: [Test]Reworked items
July 25, 2016, 12:14:39 AM
I am posting all the code from my following scripts: "sword.lua", "enemy_metatable.lua", "hero_metatable.lua".
These files include the code I needed to make the custom sword. Take the code that you need.

Sword.lua
Code (Lua) Select

local item = ...

local use_builtin_sword -- = true -- Change this to switch between built-in and custom sword.

local loading_sword_time = 300 -- Do not change this unless you know what you are doing.
local inverted_direction = false -- Possible values: false (normal), true (inverted).
local invert_sword_direction_ability = true -- Enable this to allow direction change.
local sword_command_released -- Used to start loading_sword state if necessary.
local sword_command_pressed_times = 0 -- Used to know if the command has been pressed during an attack.
local sword_state -- Possible states: nil, "brandish", "loading", "loaded", "tapping", "spin".
local sword -- Custom entity sword.
local list_hit_entities = {} -- List of entities hit on the current attack.

-- TODO: remove this function and variable (here and later) when the built-in one is done.
function item:is_being_used() return sword_state ~= nil end

-- Return state of the sword.
function item:get_state() return sword_state end

function item:on_created()
  self:set_savegame_variable("possession_sword")
  self:set_variant(1)
  self:set_assignable(true)
  -- Enable/disable the built-in sword if necessary, just for testing.
  local sword_ability = use_builtin_sword and 1 or 0
  self:get_game():set_ability("sword", sword_ability)
end

-- Define the damage of the sword.
function item:get_damage()
  return self:get_variant() + 1
end

function item:on_variant_changed(variant)
  -- Define this to create several sword variants.
end

function item:on_obtained()
  local hero_index = item:get_game():get_hero():get_index()
  local inventory = item:get_game():get_inventory()
  inventory:add_item(hero_index, item)
end

-- Program sword attack, to replace the built-in one.
function item:on_using()
  local map = self:get_map()
  local game = map:get_game()
  local hero = map:get_hero()

  -- Do not use if there is bad ground below.
  if not map:is_solid_ground(hero:get_ground_position()) then return end
 
  -- Use built-in sword if enabled, or custom sword otherwise.
  if self:get_game():get_ability("sword") > 0 then
    hero:start_attack()
    return
  end
   
  -- Do nothing if game is suspended.
  if game:is_suspended() then return end
  -- Freeze hero and save state.
  if self:is_being_used() then
    sword_command_pressed_times = sword_command_pressed_times + 1
    return
  end
  hero:freeze() -- This is necessary, at least for the custom slot 0.
  if not sword_state then sword_state = "brandish" end
  sword_command_released = false
  -- Do not allow to push walls/blocks. Use sword tapping animation instead.
  hero:set_pushing_animation("sword_tapping")
  -- Remove fixed animations (used if jumping).
  hero:set_fixed_animations(nil, nil)
 
  -- Create custom entity sword.
  local x, y, layer = hero:get_position()
  local dir = hero:get_direction()
  local properties = {name = "sword", x = x, y = y, layer = layer, direction = dir, width = 16, height = 16}
  sword = map:create_custom_entity(properties) 
  local sword_sprite = sword:create_sprite("main_heroes/sword", "sword")
  sword_sprite:set_animation("sword")
  sword_sprite:set_direction(dir)
 
  -- Synchronize sword sprite with hero tunic sprite.
  local hero_tunic_sprite = hero:get_sprite("tunic")
  sword_sprite:synchronize(hero_tunic_sprite)

  -- To draw the sword above the hero, set position at "y -> y+2" and shift sprite by "y -> y-2".
  sword:set_drawn_in_y_order(true)
  local old_set_position = sword.set_position
  function sword:set_position(x, y, layer)
    old_set_position(self, x, y + 2, layer)
  end
  sword:set_position(x, y, layer) -- Update position.
  sword_sprite:set_xy(0, -2) -- Update sprite shift to (0 , -2).
  function sword:set_xy(x, y)
    for _, s in sword:get_sprites() do
      s:set_xy(x, y - 2)
    end
  end
   
  -- Start sword animation on hero. The direction changes on each attack.
  local tunic_animation = inverted_direction and "sword_inverted" or "sword"
  if invert_sword_direction_ability then
    -- Change direction for next attack if needed.
    inverted_direction = (not inverted_direction)
  end
  hero_tunic_sprite:set_animation(tunic_animation)
  sword_sprite:set_animation(tunic_animation)
 
  -- Stop using sword if there is bad ground under the hero.
  sol.timer.start(item, 5, function()
    if not self:get_map():is_solid_ground(hero:get_ground_position()) then
      self:finish_using()
    end
    return true
  end)

  -- Check if the sword command is being hold all the time.
  sol.timer.start(item, 1, function()
    local command = self:get_command()
    if not command or not game:is_command_pressed(command) then
      -- Notify that the sword button was released.
      sword_command_released = true
      return
    end
    return true
  end)
 
  -- Stop sword_loading and sword_tapping animations if the command is released.
  sol.timer.start(item, 1, function()
    if sword_state == "loading" or sword_state == "tapping" then
      if sword_command_released == true then
        -- Finish using sword.
        self:finish_using()
        return
      end
    end
    return true
  end)
 
  -- Synchronize shifts of sprites: used in case the sword is used while jumping.
  local ox, oy = sword:get_origin()
  sol.timer.start(item, 10, function()
    local _, h = hero_tunic_sprite:get_xy()
    sword:set_xy(0, h)
    return true
  end)
 
  -- Synchronize sword sprite with hero tunic sprite for tapping animation (the built-in synchronization
  -- does not work correctly for some unknown reason. TODO: should I open an issue for this? Nope...
  sol.timer.start(item, 1, function()
    if hero:get_state() == "pushing" and sword_state ~= "tapping" then
      -- Start tapping state. Stop timers. Destroy electricity sprite if any.
      sol.timer.stop_all(self)
      sword_state = "tapping"
      local electricity = sword:get_sprite("electricity")
      if electricity then sword:remove_sprite(electricity) end
      -- Select correct shifting for each direction of the sword_tapping animation.
      local dir = hero:get_direction()
      local sx, sy = 0, 0 -- Shifts.
      if dir == 0 or dir == 2 then sy = -2 end -- These shifts are ok.
      sword_sprite:set_xy(sx, sy)
      -- Start timer for the sound.
      sword_sprite:set_animation("sword_tapping")
      local tapping_time = sword_sprite:get_frame_delay() * sword_sprite:get_num_frames()
      sol.timer.start(item, tapping_time, function()
        sol.audio.play_sound("sword_tapping")
        return true
      end)
      -- Update animation frames (the built-in synchronization does not work here).
      sol.timer.start(item, 1, function()
        if hero:get_state() ~= "pushing" then
          -- Finish using sword after finishing tapping.
          self:finish_using()
          return
        end
        -- Update animation frame.
        local frame = hero:get_sprite("tunic"):get_frame()
        sword_sprite:set_animation("sword_tapping")
        sword_sprite:set_frame(frame)
        return true
      end)
    end
    return true
  end)
 
  -- Start sword loading state when necessary.
  local attack_duration = hero_tunic_sprite:get_num_frames()*hero_tunic_sprite:get_frame_delay()
  sol.timer.start(item, attack_duration, function() 
    -- Do not start loading sword if the sword command was released during the attack.
    if sword_command_released == true then
      self:finish_using()
      return
    end
    -- Start loading sword if necessary. Fix direction and loading animations.
    sword_state = "loading"
    hero:set_fixed_animations("sword_loading_stopped", "sword_loading_walking")
    hero:set_fixed_direction(dir)
    hero:set_animation("sword_loading_stopped")
    sword_sprite:set_animation("sword_loading_stopped")
    hero:unfreeze() -- Allow the hero to walk.
    -- Check if the command button is being pressed enough time to load the sword.
    -- Also, update position and animation.
    local loaded_time = 0
    local is_loading_finished = false
    local is_spin_attack_prepared = false
    sol.timer.start(item, 1, function()
      local command = self:get_command()
      if not command or not game:is_command_pressed(command) then
        if is_spin_attack_prepared then item:start_spin_attack(sword)
        else self:finish_using() end
        return false
      end
      if not is_loading_finished then
        loaded_time = loaded_time + 1
        if loaded_time == loading_sword_time then
          is_loading_finished = true
          sword_state = "loaded"
          -- Create electricity sprite when the sword has loaded.
          local electricity_sprite = sword:create_sprite("main_heroes/sword_electricity", "electricity")
          electricity_sprite:synchronize(sword_sprite)
          electricity_sprite:set_direction(dir)
          electricity_sprite:set_xy(0, -2)
          sol.timer.start(item, 1000, function()
            sol.audio.play_sound("sword_spin_attack_load")
            is_spin_attack_prepared = true
          end)
        end
      end
      local sword_animation = sword_sprite:get_animation()
      local new_sword_animation = hero:is_walking() and "sword_loading_walking" or "sword_loading_stopped"
      -- Update sword loading animation: stopped or walking.
      if sword_animation ~= new_sword_animation then sword_sprite:set_animation(new_sword_animation) end
      -- Update position.
      sword:set_position(hero:get_position())
      return true
    end)
  end)
 
  -- Play sword sound.
  sol.audio.play_sound("sword1")
  -- Add collision test to the sword. (Used to hit enemies, cut plants, etc.)
  sword:add_collision_test("sprite", function(entity, other_entity, sprite, other_sprite)
    item:on_collision(entity, other_entity, sprite, other_sprite) 
  end)
end

function item:on_collision(entity, other_entity, sprite, other_sprite)
  -- If the entity has an event for collision with sword, call it.
  local map = self:get_map()
  local hero = map:get_hero()
  if other_entity == hero then return end -- Do not check collisions with the hero.
  -- Do nothing if no consequence is defined.
  if other_entity.receive_attack_consequence == nil then return end
  -- Check if the entity was hit before. In that case do nothing.
  if item:has_hit(other_entity) then return false end
  -- Otherwise, hit the entity and add entity to the hit list.
  list_hit_entities[#list_hit_entities] = other_entity
  local reaction
  if other_entity.get_attack_consequence_sprite then
    reaction = other_entity:get_attack_consequence_sprite(other_sprite, "sword", reaction)
  elseif other_entity.get_attack_consequence then
    reaction = other_entity:get_attack_consequence("sword", reaction)
  end
  other_entity:receive_attack_consequence("sword", reaction)
  -- If the animation is sword_loading (stopped or walking), finish using sword after the hit.
  local state = self:get_state()
  if state == "loading" or state == "loaded" then
    item:finish_using()
  end
end

-- Check if an entity has been hit in the current sword attack.
function item:has_hit(entity)
  for _, e in pairs(list_hit_entities) do if entity == e then return true end end
  return false
end

function item:finish_using()
  -- Stop all timers (necessary if the map has changed, etc).
  sol.timer.stop_all(self)
  -- Destroy sword entity and finish using item.
  if sword then sword:remove(); sword = nil end
  self:set_finished()
  -- Clear list of hit entities.
  list_hit_entities = {}
  -- Reset fixed animations/direction. (Used while loading sword.)
  local hero = self:get_map():get_hero()
  hero:set_fixed_direction(nil)
  hero:set_fixed_animations(nil, nil)
  hero:set_pushing_animation(nil) -- Allow to push walls/blocks again.
  hero:unfreeze()
  hero:refresh_ground_below()
  -- Start new attack if necessary.
  local needs_new_attack = sword_state == "brandish" and sword_command_pressed_times > 0
  sword_state = nil
  sword_command_pressed_times = 0
  if needs_new_attack then self:on_using() end
end

-- Start spin attack.
function item:start_spin_attack(sword)
  sword_state = "spin"
  local hero = self:get_map():get_hero()
  hero:freeze()
  sol.audio.play_sound("sword_spin_attack_release")
  hero:set_animation("spin_attack")
  sword:get_sprite("sword"):set_animation("spin_attack")
  sword:remove_sprite(sword:get_sprite("electricity"))
  local hero_tunic_sprite = hero:get_sprite("tunic")
  local spin_duration = hero_tunic_sprite:get_num_frames()*hero_tunic_sprite:get_frame_delay()
  sol.timer.start(item, spin_duration, function() item:finish_using() end)
end

-- Stop using items when changing maps.
function item:on_map_changed(map)
  if sword_state ~= nil then self:finish_using() end
end

-- Called when a jump has finished.
function item:on_finish_jump(is_good_ground)
  local hero = self:get_game():get_hero()
  local hero_tunic = hero:get_sprite("tunic")
  if not is_good_ground then
  -- Stop using sword if fall on bad ground, or after normal attack on the air.
    self:finish_using()
  elseif sword_state == "brandish" or sword_state == "spin" then
  -- The spin and brandish animations of the hero are interrupted. Fix this.
    hero:freeze()
    local animation = sword:get_sprite("sword"):get_animation()
    local frame = sword:get_sprite("sword"):get_frame()
    hero_tunic:set_animation(animation)
    hero_tunic:set_frame(frame)
  elseif sword_state == "loading" or sword_state == "loaded" then
  -- Keep the loading animation on the hero (it is reseted when the jump finishes).
     hero:set_fixed_animations("sword_loading_stopped", "sword_loading_walking")
  end

  -- Refresh ground below hero (necessary because of a bug after unfreezing).
  hero:refresh_ground_below()

end


enemy_metatable.lua
Code (Lua) Select

local enemy_meta = sol.main.get_metatable("enemy")

-- Redefine how to calculate the damage inflicted by the sword.
function enemy_meta:on_hurt_by_sword(hero, enemy_sprite)
  local force = hero:get_game():get_item("sword"):get_damage()
  local reaction = self:get_attack_consequence_sprite(enemy_sprite, "sword")
  -- Multiply the sword consequence by the force of the hero.
  local life_lost = reaction * force
  if hero:get_state() == "sword spin attack" then
    -- And multiply this by 2 during a spin attack.
    life_lost = life_lost * 2
  end
  self:remove_life(life_lost)
end


-- Helper function to inflict an explicit reaction from a scripted weapon.
-- TODO this should be in the Solarus API one day
function enemy_meta:receive_attack_consequence(attack, reaction)
  if type(reaction) == "number" then
    self:hurt(reaction)
  elseif reaction == "immobilized" then
    self:immobilize()
  elseif reaction == "protected" then
    sol.audio.play_sound("sword_tapping")
  elseif reaction == "custom" then
    if self.on_custom_attack_received ~= nil then
      self:on_custom_attack_received(attack)
    end
  end
end

#682
Game art & music / Re: Original art
July 23, 2016, 11:43:38 PM
Quote from: Zefk on July 23, 2016, 11:25:31 PM
I like how the boss started slow and sped up over time with new attack techniques. The boss is great for catching the player off guard. Also, I did not notice the boss taking damage. Did you mean for that to happen?

It is because I was a bit lazy and did not draw the blinking animation for when he is hurt. Yes, the enemy speeds up when he gets hurt in the 2 first phases, and the damage of the enemy is increased in the second and third phase too. The hammer sprite is invincible, obviously.

I will add this character/enemy to the sample quest (and to the Children of Solarus project) someday soon. :)
#683
This feature involves too much customization, so I think the best would be to make this with scripts and not in the engine. Since many people with few programming knowledge want this kind of features, the faster could be to provide scripts for this, maybe in the "sample quest" of Solarus 1.6 whenever it is released (or in other quest), if Christopho agrees.

My own scripts for this feature are not clean since there is code for many other things mixed with this and I would have to make a new version, which is a ton of work. I do not have much free time for this these days because I am currently working on free art (which is more prioritary), but I guess I could do this before 2018 if you are patient enough.

We may also need to write some kind of documentation explaining how to use of the scripts and which events and functions are defined in them.

It is a very risky feature since it involves modifying many important scripts and functions, and bugs could appear, but since we have both the "sample quest" in Solarus and the "initial quest" in the Editor, we could add this feature in one of them and keep the other clean.
#684
Hi pals! Just by curiosity, I would like to know if you prefer screen-sized overworld maps like in Zelda games of the gameboy, or bigger overworld maps like in A Link To The Past. I mean overworld maps, not for levels/dungeons. I may take into account these opinions when I start mapping someday; but that will be in the far far future (probably Mercuri's Chest will be finished before then, hahah). Anyway, this may be interesting info for new developers too. You can put your opinion and discuss about this.

PS: I personally have preference for small overworld maps that are screen-sized and very dense (i.e., with many things on them: entities, secrets, easter eggs, etc), like in Link's Awakening. However, I prefer bigger maps for dungeons, like the oracle games did. I may change my mind depending on your opinions.

Let the poll and discussion begin! :D
#685
Game art & music / Re: Original art
July 22, 2016, 04:38:32 PM
Quote from: Christopho on July 22, 2016, 01:08:24 PM
When did you sleep Diarandor?! :D
The blacksmith is great and the video is funny :)
Did you make the screen shaking effect using the new camera features?

Thanks for the compliments!
I worked all the night... I could not stop because this was sooo cool! :D Hahah!
Yeah, I used the camera entity with the new features of Solarus 1.5 and it works perfectly.
#686
Game art & music / Re: Original art
July 22, 2016, 10:24:23 AM
New art and new character: the strongest blacksmith in the world!!!!!  ;D ;D ;D

See him in action: https://www.youtube.com/watch?v=Np4BFCWnvzM&index=11&list=PLysNP7i5PKBCgT898-xreWyPcaByEB6Rg
And the pixel art is here: http://diarandor.deviantart.com/art/Blacksmith1-v1-0-623218400
#687
Game art & music / Re: Original art
July 20, 2016, 03:18:10 AM
Greetings! This is the new NPC that I have created: a witch cooking a delicious brew! :p
These graphics may be used to replace the witch from ALTTP in our games made with the Solarus engine.
https://www.youtube.com/watch?v=SSYCzPJG-Pc&index=10&list=PLysNP7i5PKBCgT898-xreWyPcaByEB6Rg
#688
Development / Re: [Test]Reworked items
July 17, 2016, 08:28:32 PM
Hi! No problem, this was an interesting topic to talk about.

I forgot to say it, sorry, but I had already solved this problem with an animation fix (similar to what you have done, but using the script I made for the animation fix with a few changes in the code). The only limitation I found is that, whenever you want to fix an animation, the new one needs to have the same number of frames than the original one, or otherwise it would be stuck at the first frame (each time the animation is changed by the engine the frame would be reseted to the first one, which is too bad). And to avoid pushing blocks while tapping with my custom sword, well... I will just use custom blocks instead of the built-in ones, which will avoid the problem and allow more customization.

I am a bit worried that in the end I will end up only using custom entities for everything, but that is the only way to fully customize everything...  :(
#689
Thanks for the info, Satoh.

I thought the alpha blending had a unique definition, but I was wrong. The definition of the Wikipedia is probably the most standard definition as I have read (and it has very nice properties, like associativity). The definition given in the wiki of the SDL library seems different and non-equivalent (it almost coincides with the formula for pre-multiplied alpha, but there appears one factor that should not be there in the formula, as you can check with the Wikipedia: https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending); maybe their code is fine and it's just that their documentation has a mistake in the formula, who knows. But it is ok anyway, even if the alpha blending is a different ones, since the results are similar in most of the cases. Well, I might be wrong in all of this, so it does not matter at all.

At first I thought all of this had been progammed by Chris, that's why I opened the issues, but I was wrong, this all comes from some SDL library and we cannot change it. So forget about this. I will close both issues. Sorry for the annoyance.
#690
Hi, I could be wrong but I think something is wrong with the definition of alpha blending.
I wrote the explanations here:
https://github.com/christopho/solarus/issues/931

EDIT: I added another issue to request custom blendings. That may be very useful:
https://github.com/christopho/solarus/issues/932