Issue with on_position_changed and set_direction

Started by MetalZelda, November 02, 2015, 08:39:37 PM

Previous topic - Next topic
Ah I understand, again thanks for you help Diarantor and Christopho, but again, I'm not at home at the moment so i'll post feedbacks later about it ^^

November 04, 2015, 12:55:55 PM #16 Last Edit: November 04, 2015, 01:02:52 PM by Username
hmmm, so I put it in quest_manager and initialized it and tested with tunic1, it doesn't fix direction, and I think that's maybe because hero.fixed_direction doesn't have any value to work with

And if I replace self:get_animation_set by sprite_meta;get_animation_set, I got an error

Error: In on_direction_changed: [string "scripts/quest_manager.lua"]:328: calling 'get_animation_set' on bad self (sol.sprite expected, got table)

In my example I assume that you set hero.fixed_direction to an appropriate value whenever you want to fix the direction. It is up to you to do it.

Keep the self variable, not sprite_meta when calling a function. self is the sprite, sprite_meta is the metatable.

November 04, 2015, 01:17:09 PM #18 Last Edit: November 04, 2015, 06:45:22 PM by Username
Quote from: Christopho on November 04, 2015, 01:05:03 PM
In my example I assume that you set hero.fixed_direction to an appropriate value whenever you want to fix the direction. It is up to you to do it.

Keep the self variable, not sprite_meta when calling a function. self is the sprite, sprite_meta is the metatable.

Tried to give a value at hero.fixed_direction when using the bow , same thing happen, it don't work
I might have some idea to fix this, but it looks like that fixed_direction always return nil

November 04, 2015, 08:33:39 PM #19 Last Edit: November 04, 2015, 09:34:19 PM by Username
Okay so now it works ... somehow, it need a tricky way to be triggered by spamming item & sword button, which is ... stange
And it is random

It works better when colliding with a wall, which make this very strange


In your video, it's strange when the hero walks backwards without brandishing the bow... If that is not on purpose there must be something wrong in your code, but 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."

November 04, 2015, 10:42:36 PM #22 Last Edit: November 04, 2015, 11:32:32 PM by Username
Quote from: Diarandor on November 04, 2015, 10:38:03 PM
In your video, it's strange when the hero walks backwards without brandishing the bow... If that is not on purpose there must be something wrong in your code, but I don't know.

You mean when Direction Fix works ?
That was a test using the tunic animation set, i didn't put the direction fix code for the bow, but they do the same issue
I tried to replace the trigger by a temporary savegame variable, same thing occurs

If I test with the bow, the direction fix can be triggered but in a weird way (like the video), but if I press the item input, the direction fix is cancelled, even if the animation set is in the condition

this is the current code, a bit cleaned, but it works the same way too

Code (lua) Select
local function initialize_direction_fix()
local sprite_meta = sol.main.get_metatable("sprite")
function sprite_meta:on_direction_changed()
print("direction changed")
local game = sol.main.game
local hero = game:get_hero()
local tunic = game:get_ability("tunic")
  if  (self:get_animation_set() == "hero/item/bow/bow_arming_arrow_tunic"..tunic)     or
      (self:get_animation_set() == "hero/item/bow/bow_arming_no_arrow_tunic"..tunic)   or
  (self:get_animation_set() == "hero/item/bow/bow_moving_free_tunic"..tunic)       or
  (self:get_animation_set() == "hero/item/bow/bow_moving_no_arrow_tunic"..tunic)   or
      (self:get_animation_set() == "hero/item/bow/bow_moving_with_arrow_tunic"..tunic) or
      (self:get_animation_set() == "hero/item/bow/bow_shoot_tunic1"..tunic)            then
   print("direction is fix !")
       self:set_direction(hero.fixed_direction)
  end
end
end


Tried with Mystery of Solarus, didn't work at all

November 05, 2015, 03:02:45 AM #23 Last Edit: November 05, 2015, 03:04:48 AM by Diarandor
Hi!
@Username: I have read all your code and understand better now the input part you use. I realized you use savegame variables to save or get the state of the bow; but using savegame variables for this is probably not necessary; it would be better to use a normal variable instead, I think. I also noticed that you use lots of tunics instead of changing animation, for the bow. I would use only one sprite, used also for the stopped and walking animations, but changing the animation when necessary in the on_animation_changed event of the sprite metatable, in a similar way as we do with the direction (that should work if the frame number is not reseted when the animation changes, which I think is true). This part of the sprite animation is not trivial at all, and will be easier when we can access to the sprite of the hero in v1.5. I will try to make my own script for this direction fix feature of the bow or shield, maybe this weekend if I get enough time.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

November 05, 2015, 03:42:23 AM #24 Last Edit: November 05, 2015, 03:47:50 AM by Diarandor
@Username:
I realized that there are several errors appearing in the black window during the gameplay in your last video. One of them is produced because you do not have a pushing animation in some of your bow sprites.

The important point is that this made me think that, even if we use only 1 sprite for all these animations, we could still have some problem: the hero could be able, maybe, of pushing or pulling blocks while walking while brandishing the bow (if the hero is facing the block, of course), which is not a nice behavior. (We would have the same problem with a scripted shield.)

I do not know how we can avoid this problem, because we cannot disable these features (that is from the engine part). Maybe the only workaround at present would be to use custom entities to make the blocks, which would be fully scripted. But still, if the hero grabs a wall while carrying a bow or shield, he would not move until the action command is released, which is bad.

Another solution would be to allow the functions game:get/set_ability(...) of the engine to have "pushing" and "pulling" as parameters. Do you agree Christopho? I will open an issue for this in github, since this could be a useful feature.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

November 05, 2015, 12:09:19 PM #25 Last Edit: November 05, 2015, 12:12:24 PM by Username
Quote from: Diarandor on November 05, 2015, 03:02:45 AM
Hi!
@Username: I have read all your code and understand better now the input part you use. I realized you use savegame variables to save or get the state of the bow; but using savegame variables for this is probably not necessary; it would be better to use a normal variable instead

Hi

The fact that I use savegame variable for geting the state is because the item script is divided in 2 scripts : the item itself, and item_manager (the one that control the inputs), I did tried local and global variables, but they result in issues and freezes, so to counter this I did have take the savegame variable solutions, disabled the pause menu access during the item control sequence and reset every item savegame variable each time the game resets / is stopped. So they act as temporary in-game variable, and can be used in various other items scripts (to check if the item state is 0, otherwise start the put-away sequence and start the new item)

Quote from: Diarandor on November 05, 2015, 03:02:45 AM
I also noticed that you use lots of tunics instead of changing animation, for the bow. I would use only one sprite, used also for the stopped and walking animations, but changing the animation when necessary in the on_animation_changed event of the sprite metatable, in a similar way as we do with the direction (that should work if the frame number is not reseted when the animation changes, which I think is true).

I already thought about it, but since we can't change the default hero animation in 1.4.4, the solution was to make different tunic for each actions (shoot, moving without aiming, moving while aiming with or without arrows), and since hero's default animations must be "stopped" or "walking", this was the only solution available. I did tried with "hero/tunic1", but it instantly reset to stopped / walking animation when the animation finish, so a set_tunic_sprite_id was the only solution..

This is the sprite used, and as you might see, it take a lot of parameters (including moving, aiming, arming, shooting without any arrow, and same thing, but with arrows)



Quote from: Diarandor on November 05, 2015, 03:02:45 AM
This part of the sprite animation is not trivial at all, and will be easier when we can access to the sprite of the hero in v1.5. I will try to make my own script for this direction fix feature of the bow or shield, maybe this weekend if I get enough time.

I might give a look at the C++ side of on_direction_changed, that might be easier
But it looks like that what Christopho did with the LUA-sided script is that it is a mix with on_position_changed and on_obstacle_reached

Quote from: Diarandor on November 05, 2015, 03:42:23 AM
@Username:
I realized that there are several errors appearing in the black window during the gameplay in your last video. One of them is produced because you do not have a pushing animation in some of your bow sprites.
The important point is that this made me think that, even if we use only 1 sprite for all these animations, we could still have some problem: the hero could be able, maybe, of pushing or pulling blocks while walking while brandishing the bow (if the hero is facing the block, of course), which is not a nice behavior. (We would have the same problem with a scripted shield.)

I do not know how we can avoid this problem, because we cannot disable these features (that is from the engine part). Maybe the only workaround at present would be to use custom entities to make the blocks, which would be fully scripted. But still, if the hero grabs a wall while carrying a bow or shield, he would not move until the action command is released, which is bad.

Another solution would be to allow the functions game:get/set_ability(...) of the engine to have "pushing" and "pulling" as parameters. Do you agree Christopho? I will open an issue for this in github, since this could be a useful feature.

There is a error with the hammer which is easily fix-able and the error appearing while pausing is because I didn't appaired any world to the map, so there is nothing to draw.
Yes, this might be avoidable if there would be any game:set_ability(ability, true/false/nil/value), I think that this is useful, for custom abilities.

To save states or other info, you can use any entity of the engine, or even the game, because almost everything are Lua lists. In the same manner as you did with
Code (Lua) Select

hero.fixed_direction = direction

you can put a list like
Code (Lua) Select

hero.bow_info={}

or
Code (Lua) Select

game.bow_info={}

and store the bow variables inside.

(On the other hand, for the changes of animation to avoid changing tunic, I think I will wait for v1.5 to avoid workarounds with the sprite metatable,...).
"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 November 05, 2015, 02:20:58 PM
To save states or other info, you can use any entity of the engine, or even the game, because almost everything are Lua lists. In the same manner as you did with
Code (Lua) Select

hero.fixed_direction = direction

you can put a list like
Code (Lua) Select

hero.bow_info={}

or
Code (Lua) Select

game.bow_info={}

and store the bow variables inside.

(On the other hand, for the changes of animation to avoid changing tunic, I think I will wait for v1.5 to avoid workarounds with the sprite metatable,...).

Hmmm i'm gonna try your method, thanks.
For the bow having a lot of tunic sprites that shouldn't be a problem, since the old method (see OP) try to keep direction fixed even if the sprite id has changed, i'm gonna wait for 1.5 to be released then for the direction fix, in hope that it'll arrive before next year  :)

Quote from: Diarandor on November 05, 2015, 03:42:23 AM
Another solution would be to allow the functions game:get/set_ability(...) of the engine to have "pushing" and "pulling" as parameters. Do you agree Christopho? I will open an issue for this in github, since this could be a useful feature.
This is the link of the issue on github, just to have it here too:
https://github.com/christopho/solarus/issues/788

I have thought that, when we fix the direction of the hero, maybe we should not forget to reset the variable hero.fixed_direction to nil when the hero changes map (to stop fixing the direction), just to avoid some possible problems. I just wanted to point out this small detail. (One must be always careful with these small details...  :()
"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 November 05, 2015, 08:58:28 PM
Quote from: Diarandor on November 05, 2015, 03:42:23 AM
Another solution would be to allow the functions game:get/set_ability(...) of the engine to have "pushing" and "pulling" as parameters. Do you agree Christopho? I will open an issue for this in github, since this could be a useful feature.
This is the link of the issue on github, just to have it here too:
https://github.com/christopho/solarus/issues/788

I have thought that, when we fix the direction of the hero, maybe we should not forget to reset the variable hero.fixed_direction to nil when the hero changes map (to stop fixing the direction), just to avoid some possible problems. I just wanted to point out this small detail. (One must be always careful with these small details...  :()

Oh I did have check the github issue, thanks ^^
for the direction fix thing, the best solution is, when 1.5 would be here, to do a item:on_map_changed function, and disable the item right after being teleported, the value should reset itself since the sprite id would have been changed if I do like christopho did (with quest manager script) but with the "official" on_direction_changed.