Hi
My title might be unclear but it is quite easy to understand.
I modified a script that set the hero direction to the entity direction, it worls great the first time, but then the script runs a movement on the entity and alters direction by angle, and so the second time I wanna re-use that event, I get a error "invalid direction for "set_animation_direction" while it was working the first time.
self:get_angle doesn't work eigher
the script :
-- A minecart to be used by the hero on railroads.
-- Source : Mercuri's Chest, customized to fit Minish Cap style (insane speed, sound effects, re-usable in opposite direction, destroy-able).
--[[
ToDo :
- Cane of Pacci system (if planned)
- entity (minecart_turn) dependant of entity state (use prefices and set_enabled) 0 = in default place 1 = opposite direction
Done :
- Speed
- Sprites
- Disable action, pause
- player ejection, keeping the minecart entity usable
- looping sound effects
--]]
local minecart = ...
local map = minecart:get_map()
local game = minecart:get_game()
local hero = map:get_hero()
-- Whether the hero is facing the minecart stopped.
local hero_facing_minecart = false
local action_command_minecart = false
minecart:set_drawn_in_y_order(true)
-- Don't let the hero traverse the minecart.
minecart:set_traversable_by("hero", false)
-- Hurt enemies hit by the minecart.
minecart:add_collision_test("sprite", function(minecart, other)
if other:get_type() == "enemy" then
other:hurt(4)
end
end)
-- Detect minecart turns.
minecart:add_collision_test("containing", function(minecart, other)
if other:get_type() == "custom_entity" then
if other:get_model() == "object/minecart_turn" then
local movement = hero:get_movement()
if movement ~= nil then
-- Simply change the hero's movement direction.
local direction4 = other:get_direction()
movement:set_angle(direction4 * math.pi / 2)
hero:set_direction(other:get_direction())
end
end
if other:get_model() == "object/minecart_turn_diagonal" then
local movement = hero:get_movement()
if movement ~= nil then
-- Simply change the hero's movement direction.
local direction8 = other:get_direction() * 2 + 1
movement:set_angle(direction8 * math.pi / 4)
local direction4 = (direction8 == 1 or direction == 7) and 0 or 2
hero:set_direction(direction4)
end
end
if other:get_model() == "object/minecart_end" then
if other:get_direction() == minecart:get_direction() then
game:set_value("is_on_minecart", false)
minecart_se:stop()
link_se:stop()
end
local movement = hero:get_movement()
local direction4 = hero:get_direction()
if movement ~= nil then
game:set_ability("tunic", game:get_value("item_saved_tunic"))
hero:set_tunic_sprite_id("hero/tunic"..game:get_value("item_saved_tunic"))
game:set_ability("sword", game:get_value("item_saved_sword"))
game:set_ability("shield", game:get_value("item_saved_shield"))
game:set_command_keyboard_binding("action", game:get_value("item_saved_action"))
game:set_pause_allowed(true)
movement:stop()
minecart:get_sprite():set_animation("stopped")
sol.audio.play_sound("objects/minecart/landing")
sol.audio.play_sound("objects/minecart/preparing")
sol.audio.play_sound("objects/minecart/common")
if math.random(1) == 0 then
sol.audio.play_sound("characters/link/voice/fall_damage0")
else
sol.audio.play_sound("characters/link/voice/fall_damage1")
end
hero:start_jumping(direction4 * 2, 32, false)
sol.timer.start(200,function()
minecart:set_traversable_by("hero", false)
minecart:set_drawn_in_y_order(true)
-- oppose the direction
minecart:set_direction(minecart:get_direction() - 2)
end)
end
end
if other:get_model() == "object/minecart_dead_end" then
minecart:get_sprite():set_animation("turning_over")
game:set_ability("tunic", game:get_value("item_saved_tunic"))
hero:set_tunic_sprite_id("hero/tunic"..game:get_value("item_saved_tunic"))
game:set_ability("sword", game:get_value("item_saved_sword"))
game:set_ability("shield", game:get_value("item_saved_shield"))
game:set_command_keyboard_binding("action", game:get_value("item_saved_action"))
game:set_pause_allowed(true)
movement:stop()
sol.audio.play_sound("objects/minecart/landing")
sol.audio.play_sound("objects/minecart/preparing")
sol.audio.play_sound("objects/minecart/common")
if math.random(1) == 0 then
sol.audio.play_sound("characters/link/voice/fall_damage0")
else
sol.audio.play_sound("characters/link/voice/fall_damage1")
end
local explode_movement = sol.movement.create("straight")
explode_movement:set_max_distance(128)
explode_movement:set_speed(150)
explode_movement:set_angle(minecart:get_direction() * math.pi / 2 )
explode_movement:start(minecart)
--todo project link away, if he strikes a wall, damage him.###
sol.timer.start(200,function()
minecart:set_traversable_by("hero", false)
minecart:set_drawn_in_y_order(true)
end)
sol.timer.start(800, function()
--restart the same movement but oppose the direction
minecart:set_direction(0)
minecart:get_sprite():set_animation("destroy")
minecart:remove()
end)
end
end
end)
-- Show an action icon when the player faces the minecart.
minecart:add_collision_test("facing", function(minecart, other)
if other:get_type() == "hero" then
hero_facing_minecart = true
if minecart:get_movement() == nil
and game:get_command_effect("action") == nil
and game:get_custom_command_effect("action") == nil then
action_command_minecart = true
game:set_custom_command_effect("action", "action")
end
end
end)
-- Remove the action icon when stopping facing the minecart.
function minecart:on_update()
if action_command_minecart and not hero_facing_minecart then
game:set_custom_command_effect("action", nil)
action_command_minecart = false
end
hero_facing_minecart = false
end
local function store_equipment()
local tunic = game:get_ability("tunic")
local sword = game:get_ability("sword")
game:set_ability("sword", 0)
local shield = game:get_ability("shield")
game:set_ability("shield", 0)
local kb_action_key = game:get_command_keyboard_binding("action")
game:set_command_keyboard_binding("action", nil)
game:set_value("item_saved_tunic", tunic)
game:set_value("item_saved_sword", sword)
game:set_value("item_saved_shield", shield)
game:set_value("item_saved_action", kb_action_key)
end
-- Called when the hero presses the action command near the minecart.
function minecart:on_interaction()
if self:get_sprite():get_animation() == "stopped" then
local x,y = minecart:get_position()
local tunic = game:get_ability("tunic")
local direction4 = hero:get_direction()
if hero:get_direction() == 0 then --right
minecart:set_drawn_in_y_order(false)
hero:set_position(x-16, y)
elseif hero:get_direction() == 1 then --up
minecart:set_drawn_in_y_order(false)
hero:set_position(x, y+16)
elseif hero:get_direction() == 2 then --left
minecart:set_drawn_in_y_order(false)
hero:set_position(x+16, y)
elseif hero:get_direction() == 3 then --down
hero:set_position(x, y-16)
end
hero:freeze()
minecart:set_traversable_by("hero", true)
minecart:set_drawn_in_y_order(false)
store_equipment()
game:set_pause_allowed(false)
if math.random(1) == 0 then
sol.audio.play_sound("characters/link/voice/jump0")
else
sol.audio.play_sound("characters/link/voice/jump1")
end
sol.audio.play_sound("characters/link/voice/jump")
local jump_movement = sol.movement.create("jump")
jump_movement:set_distance(16)
jump_movement:set_direction8(direction4 * 2)
jump_movement:start(hero)
sol.timer.start(200, function()
sol.audio.play_sound("objects/minecart/preparing")
sol.audio.play_sound("objects/minecart/landing")
hero:set_tunic_sprite_id("hero/action/minecart/minecarting.tunic_"..tunic)
hero:set_animation("stopped")
hero:set_direction(minecart:get_direction())
end)
sol.timer.start(700, function()
minecart:go()
-- play the sound once, the rest is handled bellow
sol.audio.play_sound("characters/link/voice/fall1")
sol.audio.play_sound("objects/minecart/moving")
end)
end
end
-- Starts driving the minecart.
function minecart:go()
if hero:get_movement() ~= nil then
game:set_value("is_on_minecart", true)
end
if game:get_value("is_on_minecart") == true and hero:get_movement() ~= nil then
link_se = sol.timer.start(1000, function()
sol.audio.play_sound("characters/link/voice/fall1")
return true
end)
minecart_se = sol.timer.start(300, function()
sol.audio.play_sound("objects/minecart/moving")
return true
end)
end
hero:set_position(minecart:get_position())
hero:set_animation("walking")
minecart:get_sprite():set_animation("start")
game:set_custom_command_effect("action", nil)
action_command_minecart = false
hero_facing_minecart = false
-- Create a movement on the hero.
local direction4 = minecart:get_direction()
local movement = sol.movement.create("straight")
movement:set_angle(direction4 * math.pi / 2)
movement:set_speed(500)
movement:set_smooth(false)
function movement:on_position_changed()
-- Put the minecart at the same position as the hero.
minecart:set_position(hero:get_position())
minecart:set_direction(hero:get_direction())
end
-- Destroy the minecart when reaching an obstacle.
function movement:on_obstacle_reached()
minecart:stop()
end
-- The hero must be allowed to traverse the minecart during the movement.
minecart:set_traversable_by("hero", true)
movement:start(hero)
end
-- Stops driving the minecart and destroys it.
function minecart:stop()
local minecart_sprite = minecart:get_sprite()
-- restore values
game:set_ability("tunic", game:get_value("item_saved_tunic"))
hero:set_tunic_sprite_id("hero/tunic"..game:get_value("item_saved_tunic"))
game:set_ability("sword", game:get_value("item_saved_sword"))
game:set_ability("shield", game:get_value("item_saved_shield"))
game:set_command_keyboard_binding("action", game:get_value("item_saved_action"))
game:set_pause_allowed(true)
game:set_value("is_on_minecart", false)
minecart_se:stop()
link_se:stop()
-- Break the minecart.
local direction4 = hero:get_direction()
minecart_sprite:set_direction(0)
minecart_sprite:set_animation("destroy")
function minecart_sprite:on_animation_finished()
-- Remove it from the map when the animation is finished.
minecart:remove()
end
-- Restore control to the player.
-- map.on_command_pressed = nil
hero:unfreeze()
end
The direction issue is on on_interaction()
hero:set_direction(minecart:get_direction())
Hi! Maybe you can use the event on_direction_changed of the custom entity or its sprite to change the direction of the hero.
Quote from: Diarandor on November 21, 2015, 08:43:18 PM
Hi! Maybe you can use the event on_direction_changed of the custom entity or its sprite to change the direction of the hero.
Hi
As you may see, the whole script works, if the minecart encounter the turning entity, it turns well and it change the direction of both the entity and the hero.
The main issue is when I wanna go again in the minecart when it finished, the hero:set_direction(minecart:get_direction()) don't work, while it was working the first time.
The strangest thing is this
function movement:on_position_changed()
-- Put the minecart at the same position as the hero.
minecart:set_position(hero:get_position())
minecart:set_direction(hero:get_direction())
end
This works, but not the opposite (hero:set_direction(minecart ...))
Is there some error in error.txt? If so, in which line?
Also, I think that the line
minecart:set_direction(minecart:get_direction() - 2)
should be
minecart:set_direction((minecart:get_direction() - 2)%4)
Quote from: Diarandor on November 22, 2015, 12:16:45 AM
Is there some error in error.txt? If so, in which line?
Also, I think that the line
minecart:set_direction(minecart:get_direction() - 2)
should be
minecart:set_direction((minecart:get_direction() - 2)%4)
Oh that was that, I didn't though about the %4 in the algorythm, thanks, it now works properly.
hero:set_direction(((minecart:get_direction() + 4)%4))
Thanks Diarandor :)