Add set_angle 'immediate' parameter. (#357)
* Add set_angle 'immediate' parameter. Modified fade_in transition to happen between :setup and :ready so that :ready don't start before fade_in is finished. * docs: Automatic update of API docs * Same fixes in style and removed a useless test. Co-authored-by: StraToN <StraToN@users.noreply.github.com>
This commit is contained in:
@@ -59,7 +59,7 @@ onready var task = MovableTask.NONE
|
||||
# the destination position was reached
|
||||
func _ready() -> void:
|
||||
parent.add_user_signal("arrived")
|
||||
|
||||
|
||||
|
||||
# Main processing loop
|
||||
#
|
||||
@@ -70,8 +70,7 @@ func _process(delta: float) -> void:
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
if task == MovableTask.WALK or \
|
||||
task == MovableTask.SLIDE:
|
||||
if task == MovableTask.WALK or task == MovableTask.SLIDE:
|
||||
var pos = parent.get_position()
|
||||
var old_pos = pos
|
||||
var next
|
||||
@@ -247,7 +246,9 @@ func walk_stop(pos: Vector2) -> void:
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[orientation].mirrored else 1
|
||||
else:
|
||||
parent.animation_sprite.play(parent.animations.idles[last_dir].animation)
|
||||
parent.animation_sprite.play(
|
||||
parent.animations.idles[last_dir].animation
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[last_dir].mirrored else 1
|
||||
|
||||
update_terrain()
|
||||
@@ -351,7 +352,10 @@ func _get_dir_deg(deg: int, animations: ESCAnimationResource) -> int:
|
||||
# - direction_angle: ESCDirectionAngle resource, containing the starting angle,
|
||||
# and the size of interval
|
||||
# eg: angle_start=90, angle_size=40 corresponds to angle between 90° and 130°
|
||||
func is_angle_in_interval(angle: float, direction_angle: ESCDirectionAngle) -> bool:
|
||||
func is_angle_in_interval(
|
||||
angle: float,
|
||||
direction_angle: ESCDirectionAngle
|
||||
) -> bool:
|
||||
angle = wrapi(angle, 0, 360)
|
||||
if angle == 0:
|
||||
angle = 360
|
||||
@@ -379,8 +383,8 @@ func is_angle_in_interval(angle: float, direction_angle: ESCDirectionAngle) -> b
|
||||
#
|
||||
# - deg int angle to set the character
|
||||
# - immediate
|
||||
# If true, direction is switched immediately. Else, successive animations are
|
||||
# used so that the character turns to target angle.
|
||||
# If true, direction is switched immediately. Else, successive
|
||||
# animations are used so that the character turns to target angle.
|
||||
func set_angle(deg: int, immediate = true) -> void:
|
||||
if deg < 0 or deg > 360:
|
||||
escoria.logger.report_errors(
|
||||
@@ -388,18 +392,87 @@ func set_angle(deg: int, immediate = true) -> void:
|
||||
["Invalid degree to turn to " + str(deg)]
|
||||
)
|
||||
moved = true
|
||||
last_deg = deg
|
||||
last_dir = _get_dir_deg(deg, parent.animations)
|
||||
|
||||
if immediate:
|
||||
last_deg = deg
|
||||
last_dir = _get_dir_deg(deg, parent.animations)
|
||||
|
||||
# The character may have a state animation from before, which would be
|
||||
# resumed, so we immediately force the correct idle animation
|
||||
if parent.animation_sprite.animation != \
|
||||
parent.animations.idles[last_dir].animation:
|
||||
parent.animation_sprite.play(parent.animations.idles[last_dir].animation)
|
||||
pose_scale = -1 if parent.animations.idles[last_dir].mirrored else 1
|
||||
# The character may have a state animation from before, which would be
|
||||
# resumed, so we immediately force the correct idle animation
|
||||
if parent.animation_sprite.animation != \
|
||||
parent.animations.idles[last_dir].animation:
|
||||
parent.animation_sprite.play(
|
||||
parent.animations.idles[last_dir].animation
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[last_dir].mirrored else 1
|
||||
else:
|
||||
var current_dir = last_dir
|
||||
last_deg = deg
|
||||
var target_dir = _get_dir_deg(deg, parent.animations)
|
||||
|
||||
var way_to_turn = get_shortest_way_to_dir(current_dir, target_dir)
|
||||
|
||||
var dir = current_dir
|
||||
while dir != target_dir:
|
||||
dir += way_to_turn
|
||||
if dir >= parent.animations.dir_angles.size():
|
||||
dir = 0
|
||||
if dir < 0:
|
||||
dir = parent.animations.dir_angles.size() - 1
|
||||
|
||||
parent.animation_sprite.play(
|
||||
parent.animations.idles[dir].animation
|
||||
)
|
||||
yield(parent.animation_sprite, "animation_finished")
|
||||
pose_scale = -1 if parent.animations.idles[dir].mirrored else 1
|
||||
|
||||
update_terrain()
|
||||
|
||||
|
||||
# Returns the angle that corresponds to the current direction of the object.
|
||||
func _get_angle() -> int:
|
||||
return parent.animations.dir_angles[last_dir].animation
|
||||
|
||||
|
||||
# Return the shortest way to turn from a direction to another. Returned way is
|
||||
# either:
|
||||
# -1 (shortest way is to turn anti-clockwise)
|
||||
# 0 (already at the right direction)
|
||||
# 1 (clockwise).
|
||||
#
|
||||
# ####Parameters
|
||||
# - current_dir: integer corresponding to the starting direction as defined in
|
||||
# the attached ESCAnimationResource.directions.
|
||||
# - target_dir: integer corresponding to the target direction as defined in
|
||||
# the attached ESCAnimationResource.directions.
|
||||
#
|
||||
# *Returns*
|
||||
# Integer: -1 (anti-clockwise), 1 (clockwise) or 0 (no movement needed).
|
||||
func get_shortest_way_to_dir(current_dir: int, target_dir: int) -> int:
|
||||
if current_dir < 0 or current_dir > parent.animations.dir_angles.size() - 1:
|
||||
escoria.logger.report_errors(
|
||||
"esc_movable.gd:get_shortest_way_to_dir()",
|
||||
["Invalid direction (current_dir) %s" % str(current_dir)]
|
||||
)
|
||||
|
||||
if target_dir < 0 or target_dir > parent.animations.dir_angles.size() - 1:
|
||||
escoria.logger.report_errors(
|
||||
"esc_movable.gd:get_shortest_way_to_dir()",
|
||||
["Invalid direction (target_dir) %s " % str(target_dir)]
|
||||
)
|
||||
|
||||
if current_dir == target_dir:
|
||||
return 0
|
||||
|
||||
var internal = false
|
||||
if max(current_dir, target_dir) - min(current_dir, target_dir) \
|
||||
< parent.animations.dir_angles.size() / 2:
|
||||
internal = true
|
||||
else:
|
||||
internal = false
|
||||
|
||||
if internal and current_dir < target_dir or \
|
||||
(not internal and current_dir > target_dir):
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
@@ -92,7 +92,7 @@ func run(command_params: Array) -> int:
|
||||
var script = escoria.esc_compiler.load_esc_file(
|
||||
room_scene.esc_script
|
||||
)
|
||||
|
||||
|
||||
if script.events.has("setup"):
|
||||
escoria.event_manager.queue_event(script.events["setup"])
|
||||
var rc = yield(escoria.event_manager, "event_finished")
|
||||
@@ -100,7 +100,10 @@ func run(command_params: Array) -> int:
|
||||
rc = yield(escoria.event_manager, "event_finished")
|
||||
if rc[0] != ESCExecution.RC_OK:
|
||||
return rc[0]
|
||||
|
||||
|
||||
escoria.main.scene_transition.fade_in()
|
||||
yield(escoria.main.scene_transition, "transition_done")
|
||||
|
||||
# If scene was never visited, add "ready" event to the events stack
|
||||
if not command_params[0] in self.readied_scenes \
|
||||
and script.events.has("ready"):
|
||||
@@ -111,9 +114,6 @@ func run(command_params: Array) -> int:
|
||||
if rc[0] != ESCExecution.RC_OK:
|
||||
return rc[0]
|
||||
|
||||
escoria.main.scene_transition.fade_in()
|
||||
yield(escoria.main.scene_transition, "transition_done")
|
||||
|
||||
self.readied_scenes.append(command_params[0])
|
||||
|
||||
# Clear queued resources
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# `set_angle object degrees`
|
||||
# `set_angle object degrees [immediate]`
|
||||
#
|
||||
# Turns object to a degrees angle without animations. 0 sets object facing
|
||||
# forward, 90 sets it 90 degrees clockwise ("east") etc. When turning to the
|
||||
@@ -16,8 +16,8 @@ class_name SetAngleCommand
|
||||
func configure() -> ESCCommandArgumentDescriptor:
|
||||
return ESCCommandArgumentDescriptor.new(
|
||||
2,
|
||||
[TYPE_STRING, TYPE_INT],
|
||||
[null, null]
|
||||
[TYPE_STRING, TYPE_INT, TYPE_BOOL],
|
||||
[null, null, true]
|
||||
)
|
||||
|
||||
|
||||
@@ -36,10 +36,12 @@ func validate(arguments: Array):
|
||||
|
||||
# Run the command
|
||||
func run(command_params: Array) -> int:
|
||||
var immediate = command_params[2]
|
||||
|
||||
# HACK Countering the fact that angle_to_point() function gives
|
||||
# angle against X axis not Y, we need to check direction using (angle-90°).
|
||||
# Since the ESC command already gives the right angle, we add 90.
|
||||
escoria.object_manager.get_object(command_params[0]).node\
|
||||
.set_angle(wrapi(int(command_params[1]) + 90, 0, 360))
|
||||
.set_angle(wrapi(int(command_params[1]) + 90, 0, 360), immediate)
|
||||
return ESCExecution.RC_OK
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
extends ColorRect
|
||||
|
||||
|
||||
# Emitted when the transition was player
|
||||
# Emitted when the transition was played
|
||||
signal transition_done
|
||||
|
||||
|
||||
|
||||
@@ -181,20 +181,10 @@ Update the sprite scale and lighting
|
||||
func is_angle_in_interval(angle: float, direction_angle: ESCDirectionAngle) -> bool
|
||||
```
|
||||
|
||||
Returns true if given angle is inside the interval given by a starting_angle
|
||||
and the size.
|
||||
|
||||
#### Parameters
|
||||
|
||||
- angle: Angle to test
|
||||
- direction_angle: ESCDirectionAngle resource, containing the starting angle,
|
||||
and the size of interval
|
||||
eg: angle_start=90, angle_size=40 corresponds to angle between 90° and 130°
|
||||
|
||||
### set\_angle
|
||||
|
||||
```gdscript
|
||||
func set_angle(deg: int, immediate = true) -> void
|
||||
func set_angle(deg: int, immediate = true) -> var
|
||||
```
|
||||
|
||||
Sets character's angle and plays according animation.
|
||||
@@ -203,5 +193,26 @@ Sets character's angle and plays according animation.
|
||||
|
||||
- deg int angle to set the character
|
||||
- immediate
|
||||
If true, direction is switched immediately. Else, successive animations are
|
||||
used so that the character turns to target angle.
|
||||
If true, direction is switched immediately. Else, successive
|
||||
animations are used so that the character turns to target angle.
|
||||
|
||||
### get\_shortest\_way\_to\_dir
|
||||
|
||||
```gdscript
|
||||
func get_shortest_way_to_dir(current_dir: int, target_dir: int) -> int
|
||||
```
|
||||
|
||||
Return the shortest way to turn from a direction to another. Returned way is
|
||||
either:
|
||||
-1 (shortest way is to turn anti-clockwise)
|
||||
0 (already at the right direction)
|
||||
1 (clockwise).
|
||||
|
||||
####Parameters
|
||||
- current_dir: integer corresponding to the starting direction as defined in
|
||||
the attached ESCAnimationResource.directions.
|
||||
- target_dir: integer corresponding to the target direction as defined in
|
||||
the attached ESCAnimationResource.directions.
|
||||
|
||||
*Returns*
|
||||
Integer: -1 (anti-clockwise), 1 (clockwise) or 0 (no movement needed).
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Description
|
||||
|
||||
`set_angle object degrees`
|
||||
`set_angle object degrees [immediate]`
|
||||
|
||||
Turns object to a degrees angle without animations. 0 sets object facing
|
||||
forward, 90 sets it 90 degrees clockwise ("east") etc. When turning to the
|
||||
|
||||
@@ -36,4 +36,4 @@ Fade in the transition
|
||||
|
||||
## Signals
|
||||
|
||||
- signal transition_done(): Emitted when the transition was player
|
||||
- signal transition_done(): Emitted when the transition was played
|
||||
|
||||
@@ -266,7 +266,7 @@ event ends.
|
||||
|
||||
Changes the "active" state of the object, value can be true or false.
|
||||
Inactive objects are hidden in the scene.
|
||||
#### <a name="SetAngleCommand.md"></a>`set_angle object degrees` [API-Doc](api/SetAngleCommand.md)
|
||||
#### <a name="SetAngleCommand.md"></a>`set_angle object degrees [immediate]` [API-Doc](api/SetAngleCommand.md)
|
||||
|
||||
Turns object to a degrees angle without animations. 0 sets object facing
|
||||
forward, 90 sets it 90 degrees clockwise ("east") etc. When turning to the
|
||||
|
||||
@@ -12,4 +12,9 @@
|
||||
|
||||
:ready
|
||||
set_sound_state bg_music res://game/sfx/contemplation.ogg true
|
||||
|
||||
walk player r1_destination_point
|
||||
wait 2
|
||||
walk player r1_destination_point2
|
||||
wait 2
|
||||
set_angle player 225 false
|
||||
|
||||
@@ -58,6 +58,7 @@ is_exit = true
|
||||
tooltip_name = "Exit"
|
||||
default_action = "walk"
|
||||
dialog_color = Color( 1, 1, 1, 1 )
|
||||
animations = null
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/r_door"]
|
||||
polygon = PoolVector2Array( 1177.94, 348.61, 1175.95, 45.3759, 1276.06, 92.0953, 1277.95, 399.407 )
|
||||
@@ -74,6 +75,7 @@ esc_script = "res://game/rooms/room01/esc/wall_item.esc"
|
||||
tooltip_name = "Item on the wall"
|
||||
default_action = "look"
|
||||
dialog_color = Color( 1, 1, 1, 1 )
|
||||
animations = null
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/item"]
|
||||
polygon = PoolVector2Array( 635.586, 253.345, 568.928, 60.1716, 709.047, 120.028, 699.524, 247.903 )
|
||||
@@ -109,6 +111,7 @@ esc_script = "res://game/rooms/room01/esc/wall_item_popupdialog.esc"
|
||||
tooltip_name = "Item on the wall"
|
||||
default_action = "look"
|
||||
dialog_color = Color( 1, 1, 1, 1 )
|
||||
animations = null
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hotspots/item2"]
|
||||
polygon = PoolVector2Array( 635.586, 253.345, 568.928, 60.1716, 709.047, 120.028, 699.524, 247.903 )
|
||||
@@ -137,7 +140,7 @@ __meta__ = {
|
||||
}
|
||||
|
||||
[node name="player_start" type="Position2D" parent="."]
|
||||
position = Vector2( 76.7617, 437.649 )
|
||||
position = Vector2( 653.761, 443.306 )
|
||||
script = ExtResource( 7 )
|
||||
global_id = "r1_start"
|
||||
|
||||
@@ -146,3 +149,9 @@ position = Vector2( 476.984, 487.146 )
|
||||
script = ExtResource( 7 )
|
||||
global_id = "r1_destination_point"
|
||||
interaction_direction = 4
|
||||
|
||||
[node name="destination_point2" type="Position2D" parent="."]
|
||||
position = Vector2( 994.586, 458.862 )
|
||||
script = ExtResource( 7 )
|
||||
global_id = "r1_destination_point2"
|
||||
player_orients_on_arrival = false
|
||||
|
||||
Reference in New Issue
Block a user