feat: refactor numerous areas and tokenize string literals where possible; also fixes some small bugs (#487)

Co-authored-by: Duncan Brown <duncan@bhs-consultants.com>
This commit is contained in:
Duncan Brown
2022-02-04 11:10:40 -05:00
committed by GitHub
parent 7913aadb6d
commit 99dc1e0110
50 changed files with 1103 additions and 593 deletions

View File

@@ -312,7 +312,7 @@ func update_terrain(on_event_finished_name = null) -> void:
if !parent.terrain or parent.terrain == null \
or !is_instance_valid(parent.terrain):
return
if on_event_finished_name != null and on_event_finished_name != "setup":
if on_event_finished_name != null and on_event_finished_name != escoria.event_manager.EVENT_SETUP:
return
if parent.get("is_exit"):
return

View File

@@ -47,7 +47,7 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.push(
escoria.object_manager.get_object(command_params[0]).node,
command_params[1],

View File

@@ -26,7 +26,7 @@ func configure() -> ESCCommandArgumentDescriptor:
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.set_target(
Vector2(command_params[1], command_params[2]),
command_params[0]

View File

@@ -39,7 +39,7 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.set_target(
escoria.object_manager.get_object(command_params[1]).node,
command_params[0]

View File

@@ -28,7 +28,7 @@ func configure() -> ESCCommandArgumentDescriptor:
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.set_camera_zoom(
command_params[0],
command_params[1]

View File

@@ -40,7 +40,7 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.set_camera_zoom(
command_params[0] / escoria.game_size.y,
command_params[1]

View File

@@ -38,7 +38,7 @@ func configure() -> ESCCommandArgumentDescriptor:
# Run the command
func run(command_params: Array) -> int:
(escoria.object_manager.get_object("_camera").node as ESCCamera)\
(escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera)\
.shift(
Vector2(
command_params[0],

View File

@@ -32,13 +32,15 @@ func validate(arguments: Array) -> bool:
)
return false
if not ResourceLoader.exists(
ProjectSettings.get_setting("escoria/ui/game_scene")
escoria.project_settings_manager.get_setting(escoria.project_settings_manager.GAME_SCENE)
):
escoria.logger.report_errors(
"change_scene: Game scene not found",
[
"The path set in 'ui/game_scene' was not found: %s" % \
ProjectSettings.get_setting("escoria/ui/game_scene")
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_SCENE
)
]
)
return false

View File

@@ -72,28 +72,10 @@ func run(arguments: Array) -> int:
arguments[0]
).node
var esc_script = escoria.esc_compiler.load_esc_file(node.esc_script)
if arguments[2] == "_front":
escoria.event_manager.queue_event(esc_script.events[arguments[1]])
else:
escoria.event_manager.queue_background_event(
arguments[2],
esc_script.events[arguments[1]]
)
if arguments[3]:
if arguments[2] == "_front":
var rc = yield(escoria.event_manager, "event_finished")
while rc[1] != arguments[1]:
rc = yield(escoria.event_manager, "event_finished")
return rc
else:
var rc = yield(
escoria.event_manager,
"background_event_finished"
)
while rc[1] != arguments[1] and rc[2] != arguments[2]:
rc = yield(
escoria.event_manager,
"background_event_finished"
)
return rc
return ESCExecution.RC_OK
return escoria.event_manager.queue_event_from_esc(
esc_script,
arguments[1], # event name
arguments[2], # channel name
arguments[3] # whether to block
)

View File

@@ -46,5 +46,8 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
escoria.do("walk", command_params)
escoria.action_manager.do(
escoria.action_manager.ACTION.BACKGROUND_CLICK,
command_params
)
return ESCExecution.RC_OK

View File

@@ -37,7 +37,7 @@ func validate(arguments: Array):
escoria.logger.report_errors(
"walk_block: invalid second object",
[
"Object with global id %s not found" % arguments[0]
"Object with global id %s not found" % arguments[1]
]
)
return false
@@ -46,7 +46,10 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
escoria.do("walk", command_params)
escoria.action_manager.do(
escoria.action_manager.ACTION.BACKGROUND_CLICK,
command_params
)
yield(
(escoria.object_manager.objects[command_params[0]].node as ESCItem),
"arrived"

View File

@@ -39,7 +39,7 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
escoria.do("walk", [
escoria.action_manager.do(escoria.action_manager.ACTION.BACKGROUND_CLICK, [
command_params[0],
Vector2(command_params[1], command_params[2])
])

View File

@@ -39,7 +39,7 @@ func validate(arguments: Array):
# Run the command
func run(command_params: Array) -> int:
escoria.do("walk", [
escoria.action_manager.do(escoria.action_manager.ACTION.BACKGROUND_CLICK, [
command_params[0],
Vector2(command_params[1], command_params[2])
])

View File

@@ -34,6 +34,26 @@ enum ACTION_INPUT_STATE {
COMPLETED
}
# Actions understood by the do(...) method
# * BACKGROUND_CLICK: Object is to move from its current position
# * ITEM_LEFT_CLICK: Item has been clicked on with LMB.
# * ITEM_RIGHT_CLICK: Item has been clicked on with RMB.
# * TRIGGER_IN: Character has moved into a trigger area.
# * TRIGGER_OUT: Character has moved out of a trigger area.
enum ACTION {
BACKGROUND_CLICK,
ITEM_LEFT_CLICK,
ITEM_RIGHT_CLICK,
TRIGGER_IN,
TRIGGER_OUT
}
# Basic required internal actions
const ACTION_ARRIVED = "arrived"
const ACTION_EXIT_SCENE = "exit_scene"
const ACTION_WALK = "walk"
# Current verb used
var current_action: String = "" setget set_current_action
@@ -49,6 +69,119 @@ var action_state = ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM \
setget set_action_input_state
# Run a generic action
#
# #### Parameters
#
# - action: type of the action to run
# - params: Parameters for the action
# - can_interrupt: if true, this command will interrupt any ongoing event
# before it is finished
func do(action: int, params: Array = [], can_interrupt: bool = false) -> void:
if escoria.current_state == escoria.GAME_STATE.DEFAULT:
match action:
ACTION.BACKGROUND_CLICK:
if can_interrupt:
escoria.event_manager.interrupt_running_event()
self.clear_current_action()
var walk_fast = false
if params.size() > 2:
walk_fast = true if params[2] else false
# Check moving object.
if not escoria.object_manager.has(params[0]):
escoria.logger.report_errors(
"esc_action_manager.gd:do()",
[
"Walk action requested on nonexisting " + \
"object: %s " % params[0]
]
)
return
var moving_obj = escoria.object_manager.get_object(params[0])
var target
if params[1] is String:
if not escoria.object_manager.has(params[1]):
escoria.logger.report_errors(
"esc_action_manager.gd:do()",
[
"Walk action requested to nonexisting " + \
"object: %s " % params[1]
]
)
return
target = escoria.object_manager.get_object(params[1])
elif params[1] is Vector2:
target = params[1]
self.perform_walk(moving_obj, target, walk_fast)
ACTION.ITEM_LEFT_CLICK:
if params[0] is String:
escoria.logger.info(
"esc_action_manager.do(): item_left_click on item ",
[params[0]]
)
if can_interrupt:
escoria.event_manager.interrupt_running_event()
var item = escoria.object_manager.get_object(params[0])
self.perform_inputevent_on_object(item, params[1])
ACTION.ITEM_RIGHT_CLICK:
if params[0] is String:
escoria.logger.info(
"esc_action_manager.do(): item_right_click on item ",
[params[0]]
)
if can_interrupt:
escoria.event_manager.interrupt_running_event()
var item = escoria.object_manager.get_object(params[0])
self.perform_inputevent_on_object(item, params[1], true)
ACTION.TRIGGER_IN:
var trigger_id = params[0]
var object_id = params[1]
var trigger_in_verb = params[2]
escoria.logger.info("esc_action_manager.do(): trigger_in %s by %s" % [
trigger_id,
object_id
])
escoria.event_manager.queue_event(
escoria.object_manager.get_object(trigger_id).events[
trigger_in_verb
]
)
ACTION.TRIGGER_OUT:
var trigger_id = params[0]
var object_id = params[1]
var trigger_out_verb = params[2]
escoria.logger.info("esc_action_manager.do(): trigger_out %s by %s" % [
trigger_id,
object_id
])
escoria.event_manager.queue_event(
escoria.object_manager.get_object(trigger_id).events[
trigger_out_verb
]
)
_:
escoria.logger.report_warnings("esc_action_manager.gd:do()",
["Action received:", action, "with params ", params])
elif escoria.current_state == escoria.GAME_STATE.WAIT:
pass
# Sets the current state of action input.
#
# ## Parameters
@@ -410,15 +543,15 @@ func perform_inputevent_on_object(
return
# Manage exits
if obj.node.is_exit and current_action in ["", "walk"]:
_activate("exit_scene", obj)
if obj.node.is_exit and current_action in ["", ACTION_WALK]:
_activate(ACTION_EXIT_SCENE, obj)
else:
# Manage movements towards object before activating it
if current_action in ["", "walk"] and \
if current_action in ["", ACTION_WALK] and \
not escoria.inventory_manager.inventory_has(obj.global_id):
_activate("arrived", obj)
_activate(ACTION_ARRIVED, obj)
# Manage action on object
elif not current_action in ["", "walk"]:
elif not current_action in ["", ACTION_WALK]:
if need_combine and current_target:
_activate(
current_action,

View File

@@ -14,8 +14,8 @@ var registry: Dictionary = {}
# - command_name: Name of command to load
# **Returns** The command object
func load_command(command_name: String) -> ESCBaseCommand:
for command_directory in ProjectSettings.get(
"escoria/main/command_directories"
for command_directory in escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.COMMAND_DIRECTORIES
):
if ResourceLoader.exists("%s/%s.gd" % [command_directory, command_name]):
registry[command_name] = load(

View File

@@ -10,9 +10,21 @@ const COMMENT_REGEX = '^\\s*#.*$'
const EMPTY_REGEX = '^\\s*$'
# A RegEx for finding out the indent of a line
const INDENT_REGEX = '^(?<indent>\\s*)'
const INDENT_REGEX_GROUP = "indent"
const INDENT_REGEX = '^(?<%s>\\s*)' % INDENT_REGEX_GROUP
# RegEx objects for use by the ESC compiler
var _comment_regex
var _empty_regex
var _indent_regex
var _event_regex
var _command_regex
var _dialog_regex
var _dialog_end_regex
var _dialog_option_regex
var _group_regex
# The currently compiled event
var _current_event = null
@@ -35,6 +47,8 @@ var _current_indent = 0
func _init():
# Assure command list preference
# (we use ProjectSettings instead of escoria.project_settings_manager
# here because this is called from escoria._init())
if not ProjectSettings.has_setting("escoria/esc/command_paths"):
ProjectSettings.set_setting("escoria/esc/command_paths", [
"res://addons/escoria-core/game/core-scripts/esc/commands"
@@ -44,8 +58,29 @@ func _init():
"type": TYPE_STRING_ARRAY
}
ProjectSettings.add_property_info(property_info)
# Compile all regex objects just once
_comment_regex = RegEx.new()
_comment_regex.compile(COMMENT_REGEX)
_empty_regex = RegEx.new()
_empty_regex.compile(EMPTY_REGEX)
_indent_regex = RegEx.new()
_indent_regex.compile(INDENT_REGEX)
_event_regex = RegEx.new()
_event_regex.compile(ESCEvent.REGEX)
_command_regex = RegEx.new()
_command_regex.compile(ESCCommand.REGEX)
_dialog_regex = RegEx.new()
_dialog_regex.compile(ESCDialog.REGEX)
_dialog_end_regex = RegEx.new()
_dialog_end_regex.compile(ESCDialog.END_REGEX)
_dialog_option_regex = RegEx.new()
_dialog_option_regex.compile(ESCDialogOption.REGEX)
_group_regex = RegEx.new()
_group_regex.compile(ESCGroup.REGEX)
# Load an ESC file from a file resource
func load_esc_file(path: String) -> ESCScript:
escoria.logger.debug("Parsing file %s" % path)
@@ -79,49 +114,28 @@ func compile(lines: Array) -> ESCScript:
# Compile an array of ESC script lines into an array of ESC objects
func _compile(lines: Array) -> Array:
var comment_regex = RegEx.new()
comment_regex.compile(COMMENT_REGEX)
var empty_regex = RegEx.new()
empty_regex.compile(EMPTY_REGEX)
var indent_regex = RegEx.new()
indent_regex.compile(INDENT_REGEX)
var event_regex = RegEx.new()
event_regex.compile(ESCEvent.REGEX)
var command_regex = RegEx.new()
command_regex.compile(ESCCommand.REGEX)
var dialog_regex = RegEx.new()
dialog_regex.compile(ESCDialog.REGEX)
var dialog_end_regex = RegEx.new()
dialog_end_regex.compile(ESCDialog.END_REGEX)
var dialog_option_regex = RegEx.new()
dialog_option_regex.compile(ESCDialogOption.REGEX)
var group_regex = RegEx.new()
group_regex.compile(ESCGroup.REGEX)
var returned = []
while lines.size() > 0:
var line = lines.pop_front()
escoria.logger.trace("Parsing line %s" % line)
if comment_regex.search(line) or empty_regex.search(line):
if _comment_regex.search(line) or _empty_regex.search(line):
# Ignore comments and empty lines
escoria.logger.trace("Line is empty or a comment. Skipping.")
continue
var indent = \
escoria.utils.get_re_group(
indent_regex.search(line),
"indent"
_indent_regex.search(line),
INDENT_REGEX_GROUP
).length()
if event_regex.search(line):
if _event_regex.search(line):
var event = ESCEvent.new(line)
escoria.logger.trace("Line is the event %s" % event.name)
var event_lines = []
while lines.size() > 0:
var next_line = lines.pop_front()
if not event_regex.search(next_line):
if not _event_regex.search(next_line):
event_lines.append(next_line)
else:
lines.push_front(next_line)
@@ -133,19 +147,19 @@ func _compile(lines: Array) -> Array:
)
event.statements = self._compile(event_lines)
returned.append(event)
elif group_regex.search(line):
elif _group_regex.search(line):
var group = ESCGroup.new(line)
escoria.logger.trace("Line is a group")
var group_lines = []
while lines.size() > 0:
var next_line = lines.pop_front()
if comment_regex.search(next_line) or \
empty_regex.search(next_line):
if _comment_regex.search(next_line) or \
_empty_regex.search(next_line):
continue
var next_line_indent = \
escoria.utils.get_re_group(
indent_regex.search(next_line),
"indent"
_indent_regex.search(next_line),
INDENT_REGEX_GROUP
).length()
if next_line_indent > indent:
group_lines.append(next_line)
@@ -159,21 +173,21 @@ func _compile(lines: Array) -> Array:
)
group.statements = self._compile(group_lines)
returned.append(group)
elif dialog_regex.search(line):
elif _dialog_regex.search(line):
var dialog = ESCDialog.new()
dialog.load_string(line)
escoria.logger.trace("Line is a dialog")
var dialog_lines = []
while lines.size() > 0:
var next_line = lines.pop_front()
if comment_regex.search(next_line) or \
empty_regex.search(next_line):
if _comment_regex.search(next_line) or \
_empty_regex.search(next_line):
continue
var end_line = dialog_end_regex.search(next_line)
var end_line = _dialog_end_regex.search(next_line)
if end_line and \
escoria.utils.get_re_group(
end_line,
"indent"
INDENT_REGEX_GROUP
).length() == indent:
break
else:
@@ -187,7 +201,7 @@ func _compile(lines: Array) -> Array:
# Remove the end line from the stack
lines.pop_front()
returned.append(dialog)
elif dialog_option_regex.search(line):
elif _dialog_option_regex.search(line):
var dialog_option = ESCDialogOption.new()
dialog_option.load_string(line)
escoria.logger.trace(
@@ -197,13 +211,13 @@ func _compile(lines: Array) -> Array:
var dialog_option_lines = []
while lines.size() > 0:
var next_line = lines.pop_front()
if comment_regex.search(next_line) or \
empty_regex.search(next_line):
if _comment_regex.search(next_line) or \
_empty_regex.search(next_line):
continue
var next_line_indent = \
escoria.utils.get_re_group(
indent_regex.search(next_line),
"indent"
_indent_regex.search(next_line),
INDENT_REGEX_GROUP
).length()
if next_line_indent > indent:
dialog_option_lines.append(next_line)
@@ -217,7 +231,7 @@ func _compile(lines: Array) -> Array:
)
dialog_option.statements = self._compile(dialog_option_lines)
returned.append(dialog_option)
elif command_regex.search(line):
elif _command_regex.search(line):
var command = ESCCommand.new(line)
if command.command_exists():
returned.append(command)

View File

@@ -20,12 +20,29 @@ signal event_finished(return_code, event_name)
signal background_event_finished(return_code, event_name, channel_name)
# Pre-defined ESC events
const EVENT_DEBUG = "debug"
const EVENT_EXIT_SCENE = "exit_scene"
const EVENT_INIT = "init"
const EVENT_LOAD = "load"
const EVENT_NEW_GAME = "newgame"
const EVENT_READY = "ready"
const EVENT_ROOM_SELECTOR = "room_selector"
const EVENT_SETUP = "setup"
const EVENT_TRANSITION_IN = "transition_in"
const EVENT_TRANSITION_OUT = "transition_out"
# Event channel names
const CHANNEL_FRONT = "_front"
# A list of currently scheduled events
var scheduled_events: Array = []
# A list of constantly running events in multiple background channels
var events_queue: Dictionary = {
"_front": []
CHANNEL_FRONT: []
}
# Currently running event in background channels
@@ -82,7 +99,7 @@ func _process(delta: float) -> void:
CONNECT_ONESHOT
)
if channel_name == "_front":
if channel_name == CHANNEL_FRONT:
emit_signal(
"event_started",
_running_events[channel_name].name
@@ -109,7 +126,49 @@ func _process(delta: float) -> void:
(event as ESCScheduledEvent).timeout -= delta
if (event as ESCScheduledEvent).timeout <= 0:
self.scheduled_events.erase(event)
self.events_queue['_front'].append(event.event)
self.events_queue[CHANNEL_FRONT].append(event.event)
# Queue a new event based on input from an ESC command, most likely "queue_event"
#
# #### Parameters
# - script_object: Compiled script object, i.e. the one with the event to queue
# - event: Name of the event to queue
# - channel: Channel to run the event on (default: `_front`)
# - block: Whether to wait for the queue to finish. This is only possible, if
# the queued event is not to be run on the same event as this command
# (default: `false`)
#
# **Returns** indicator of success/status
func queue_event_from_esc(script_object: ESCScript, event: String,
channel: String, block: bool) -> int:
if channel == CHANNEL_FRONT:
escoria.event_manager.queue_event(script_object.events[event])
else:
escoria.event_manager.queue_background_event(
channel,
script_object.events[event]
)
if block:
if channel == CHANNEL_FRONT:
var rc = yield(escoria.event_manager, "event_finished")
while rc[1] != event:
rc = yield(escoria.event_manager, "event_finished")
return rc
else:
var rc = yield(
escoria.event_manager,
"background_event_finished"
)
while rc[1] != event and rc[2] != channel:
rc = yield(
escoria.event_manager,
"background_event_finished"
)
return rc
return ESCExecution.RC_OK
# Queue a new event to run in the foreground
@@ -117,7 +176,7 @@ func _process(delta: float) -> void:
# #### Parameters
# - event: Event to run
func queue_event(event: ESCEvent) -> void:
self.events_queue['_front'].append(event)
self.events_queue[CHANNEL_FRONT].append(event)
# Schedule an event to run after a timeout
@@ -212,7 +271,7 @@ func _on_event_finished(finished_statement: ESCStatement, return_code: int, chan
_running_events[channel_name] = null
_channels_state[channel_name] = true
if channel_name == "_front":
if channel_name == CHANNEL_FRONT:
emit_signal(
"event_finished",
return_code,

View File

@@ -31,7 +31,7 @@ func items_in_inventory() -> Array:
# - item: Inventory item id
func remove_item(item: String):
if not inventory_has(item):
self.logger.report_errors(
escoria.logger.report_errors(
"ESCInventoryManager.remove_item: Error removing inventory item",
[
"Trying to remove non-existent item %s" % item

View File

@@ -3,11 +3,16 @@ extends Node
class_name ESCObjectManager
const CAMERA = "_camera"
const MUSIC = "_music"
const SOUND = "_sound"
const SPEECH = "_speech"
const RESERVED_OBJECTS = [
"_music",
"_sound",
"_speech",
"_camera"
MUSIC,
SOUND,
SPEECH,
CAMERA
]

View File

@@ -24,6 +24,16 @@ const RESERVED_GLOBALS = {
}
# ESC commands kept around for references to their command names.
var _transition: TransitionCommand
var _wait: WaitCommand
func _init() -> void:
_transition = TransitionCommand.new()
_wait = WaitCommand.new()
# Registers all reserved global flags for use.
func register_reserved_globals() -> void:
for key in RESERVED_GLOBALS:
@@ -55,9 +65,13 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void
not escoria.globals_manager.get_global( \
GLOBAL_LAST_SCENE).empty()
or (
escoria.event_manager.get_running_event("_front") != null \
and escoria.event_manager.get_running_event("_front").name \
in ["newgame", "exit_scene", "room_selector"]
escoria.event_manager.get_running_event(escoria.event_manager.CHANNEL_FRONT) != null \
and escoria.event_manager.get_running_event(escoria.event_manager.CHANNEL_FRONT).name \
in [
escoria.event_manager.EVENT_NEW_GAME,
escoria.event_manager.EVENT_EXIT_SCENE,
escoria.event_manager.EVENT_ROOM_SELECTOR
]
and escoria.globals_manager.get_global(
GLOBAL_LAST_SCENE
).empty()
@@ -109,7 +123,9 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void
"ESCRoomManager.change_scene: Failed loading game scene",
[
"Failed loading scene %s" % \
ProjectSettings.get_setting("escoria/ui/game_scene")
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_SCENE
)
]
)
@@ -123,9 +139,9 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void
var room_scene = res_room.instance()
if room_scene:
if enable_automatic_transitions \
and escoria.event_manager.get_running_event("_front") != null \
and escoria.event_manager.get_running_event("_front").name \
== "room_selector":
and escoria.event_manager.get_running_event(escoria.event_manager.CHANNEL_FRONT) != null \
and escoria.event_manager.get_running_event(escoria.event_manager.CHANNEL_FRONT).name \
== escoria.event_manager.EVENT_ROOM_SELECTOR:
room_scene.enabled_automatic_transitions = true
else:
room_scene.enabled_automatic_transitions = enable_automatic_transitions
@@ -231,7 +247,7 @@ func init_room(room: ESCRoom) -> void:
animations[room.player.global_id]
)
room.player.update_idle()
escoria.object_manager.get_object("_camera").node.set_target(room.player)
escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player)
if room.global_id.empty():
room.global_id = room.name
@@ -251,12 +267,12 @@ func init_room(room: ESCRoom) -> void:
#
# - room: The ESCRoom to be initialized for use.
func _perform_script_events(room: ESCRoom):
if escoria.event_manager.is_channel_free("_front") \
if room.esc_script and escoria.event_manager.is_channel_free(escoria.event_manager.CHANNEL_FRONT) \
or (
not escoria.event_manager.is_channel_free("_front") and \
not escoria.event_manager.is_channel_free(escoria.event_manager.CHANNEL_FRONT) and \
not escoria.event_manager.get_running_event(
"_front"
).name == "load"
escoria.event_manager.CHANNEL_FRONT
).name == escoria.event_manager.EVENT_LOAD
):
# If the room was loaded from change_scene and automatic transitions
@@ -265,14 +281,18 @@ func _perform_script_events(room: ESCRoom):
and not room.is_run_directly \
and not room.exited_previous_room:
var script_transition_out = escoria.esc_compiler.compile([
":transition_out",
"transition %s out" % ProjectSettings.get_setting(
"escoria/ui/default_transition"
),
"wait 0.1"
"%s%s" % [ESCEvent.PREFIX, escoria.event_manager.EVENT_TRANSITION_OUT],
"%s %s out" %
[
_transition.get_command_name(),
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.DEFAULT_TRANISITION
)
],
"%s 0.1" % _wait.get_command_name()
])
escoria.event_manager.queue_event(
script_transition_out.events['transition_out']
script_transition_out.events[escoria.event_manager.EVENT_TRANSITION_OUT]
)
# Unpause the game if it was
@@ -280,7 +300,7 @@ func _perform_script_events(room: ESCRoom):
# Wait for transition_out event to be done
var rc = yield(escoria.event_manager, "event_finished")
while rc[1] != "transition_out":
while rc[1] != escoria.event_manager.EVENT_TRANSITION_OUT:
rc = yield(escoria.event_manager, "event_finished")
if rc[0] != ESCExecution.RC_OK:
return rc[0]
@@ -290,8 +310,7 @@ func _perform_script_events(room: ESCRoom):
escoria.game_scene.unpause_game()
# Run the setup event
if room.esc_script:
_run_script_event("setup", room)
_run_script_event(escoria.event_manager.EVENT_SETUP, room)
if room.enabled_automatic_transitions \
or (
@@ -300,28 +319,31 @@ func _perform_script_events(room: ESCRoom):
escoria.room_manager.GLOBAL_FORCE_LAST_SCENE_NULL)
):
var script_transition_in = escoria.esc_compiler.compile([
":transition_in",
"transition %s in" % ProjectSettings.get_setting(
"escoria/ui/default_transition"
),
"wait 0.1"
"%s%s" % [ESCEvent.PREFIX, escoria.event_manager.EVENT_TRANSITION_IN],
"%s %s in" %
[
_transition.get_command_name(),
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.DEFAULT_TRANISITION
)
],
"%s 0.1" % _wait.get_command_name()
])
escoria.event_manager.queue_event(
script_transition_in.events['transition_in']
script_transition_in.events[escoria.event_manager.EVENT_TRANSITION_IN]
)
if room.esc_script:
var ready_event_added: bool = false
# Run the ready event, if there is one.
ready_event_added = _run_script_event("ready", room)
if ready_event_added:
# Wait for ready event to be done
var rc = yield(escoria.event_manager, "event_finished")
while rc[1] != "ready":
rc = yield(escoria.event_manager, "event_finished")
if rc[0] != ESCExecution.RC_OK:
return rc[0]
var ready_event_added: bool = false
# Run the ready event, if there is one.
ready_event_added = _run_script_event(escoria.event_manager.EVENT_READY, room)
if ready_event_added:
# Wait for ready event to be done
var rc = yield(escoria.event_manager, "event_finished")
while rc[1] != escoria.event_manager.EVENT_READY:
rc = yield(escoria.event_manager, "event_finished")
if rc[0] != ESCExecution.RC_OK:
return rc[0]
# Now that :ready is finished, if FORCE_LAST_SCENE_NULL was true, reset it
# to false

View File

@@ -4,6 +4,22 @@ extends Node
class_name ESCBaseCommand
# Regex for creating command name based on the script's filename, including
# named groups
const PATH_REGEX_GROUP = "path"
const FILE_REGEX_GROUP = "file"
const EXTENSION_REGEX_GROUP = "extension"
const COMMAND_NAME_REGEX = "(?<%s>.+)\/(?<%s>[^.]+)(?<%s>\\.[^.]*$|$)" % \
[PATH_REGEX_GROUP, FILE_REGEX_GROUP, EXTENSION_REGEX_GROUP]
# Regex matcher for command names
var command_name_regex: RegEx = RegEx.new()
func _init() -> void:
command_name_regex.compile(COMMAND_NAME_REGEX)
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
escoria.logger.error("Command %s did not override configure." % get_class())
@@ -19,3 +35,8 @@ func validate(arguments: Array) -> bool:
func run(command_params: Array) -> int:
escoria.logger.error("Command %s did not override run." % get_class())
return 0
# Return the name of the command based on the script's filename
func get_command_name() -> String:
return command_name_regex.search(get_script().get_path()).get_string(FILE_REGEX_GROUP)

View File

@@ -99,7 +99,9 @@ func is_valid() -> bool:
# *Returns* True if the command exists, else false.
func command_exists() -> bool:
var command_found = false
for base_path in ProjectSettings.get("escoria/main/command_directories"):
for base_path in escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.COMMAND_DIRECTORIES
):
var command_path = "%s/%s.gd" % [
base_path.trim_suffix("/"),
self.name

View File

@@ -16,6 +16,9 @@ const REGEX = \
'(TK|NO_TT|NO_UI|NO_SAVE)' + \
')+))?$'
# Prefix to identify this as an ESC event.
const PREFIX = ":"
# Valid event flags
# * TK: stands for "telekinetic". It means the player won't walk over to
@@ -80,3 +83,4 @@ func run() -> int:
reset_interrupt()
escoria.logger.debug("Event %s started" % name)
return .run()

View File

@@ -85,8 +85,8 @@ func _ready():
func _unhandled_input(event) -> void:
if not escoria.current_state == escoria.GAME_STATE.DEFAULT:
return
if InputMap.has_action("switch_action_verb") \
and event.is_action_pressed("switch_action_verb"):
if InputMap.has_action(escoria.inputs_manager.SWITCH_ACTION_VERB) \
and event.is_action_pressed(escoria.inputs_manager.SWITCH_ACTION_VERB):
if event.button_index == BUTTON_WHEEL_UP:
emit_signal("mouse_wheel_up")
elif event.button_index == BUTTON_WHEEL_DOWN:

View File

@@ -9,36 +9,44 @@ export(String, FILE, "*.tscn") var target_scene = ""
# Sound effect to play when changing the scene
export(String, FILE, "*.ogg,*.mp3,*.wav") var switch_sound = ""
# ESC commands kept around for references to their command names.
var _play_snd: PlaySndCommand
var _change_scene: ChangeSceneCommand
func _enter_tree():
is_exit = true
player_orients_on_arrival = false
default_action = "walk"
func _ready():
_play_snd = PlaySndCommand.new()
_change_scene = ChangeSceneCommand.new()
call_deferred("_register_event")
# Registers the exit_scene event based on the properties
func _register_event():
if escoria.object_manager.has(self.global_id) and\
not "exit_scene" in escoria.object_manager.get_object(
not escoria.event_manager.EVENT_EXIT_SCENE in escoria.object_manager.get_object(
self.global_id
).events:
var exit_scene_event_script = [
":exit_scene",
"%s%s" % [ESCEvent.PREFIX, escoria.event_manager.EVENT_EXIT_SCENE]
]
if switch_sound != "":
exit_scene_event_script.append(
"play_snd %s" % switch_sound
"%s %s" % [_play_snd.get_command_name(), switch_sound]
)
exit_scene_event_script.append("change_scene %s" % target_scene)
exit_scene_event_script.append(
"%s %s" % [_change_scene.get_command_name(), target_scene]
)
var exit_scene_event = escoria.esc_compiler.compile(
exit_scene_event_script
).events["exit_scene"]
).events[escoria.event_manager.EVENT_EXIT_SCENE]
escoria.object_manager.get_object(self.global_id)\
.events["exit_scene"] = exit_scene_event
.events[escoria.event_manager.EVENT_EXIT_SCENE] = exit_scene_event

View File

@@ -67,7 +67,7 @@ func _exit_tree():
# Ready function
func _ready():
escoria.apply_settings(escoria.settings)
connect("crash_popup_confirmed", escoria, "quit",
connect("crash_popup_confirmed", escoria, "quit",
[], CONNECT_ONESHOT)
@@ -88,6 +88,56 @@ func _draw():
draw_rect(mouse_limits, ColorN("red"), false, 10.0)
# Sets up and performs default walking action
#
# #### Parameters
#
# - destination: Destination to walk to
# - params: Parameters for the action
# - can_interrupt: if true, this command will interrupt any ongoing event
func do_walk(destination, params: Array = [], can_interrupt: bool = false) -> void:
if can_interrupt:
escoria.event_manager.interrupt_running_event()
escoria.action_manager.clear_current_action()
var walk_fast = false
if params.size() > 1:
walk_fast = true if params[1] else false
# Check moving object.
if not escoria.object_manager.has(params[0]):
escoria.logger.report_errors(
"esc_game.gd:do_walk()",
[
"Walk action requested on nonexisting " + \
"object: %s " % params[0]
]
)
return
var moving_obj = escoria.object_manager.get_object(params[0])
var target
if destination is String:
if not escoria.object_manager.has(destination):
escoria.logger.report_errors(
"esc_game.gd:do_walk()",
[
"Walk action requested to nonexisting " + \
"object: %s " % destination
]
)
return
target = escoria.object_manager.get_object(destination)
elif destination is Vector2:
target = destination
escoria.action_manager.perform_walk(moving_obj, target, walk_fast)
# Called when the player left clicks on the background
# (Needs to be overridden, if supported)
#
@@ -95,9 +145,9 @@ func _draw():
#
# - position: Position clicked
func left_click_on_bg(position: Vector2) -> void:
escoria.do(
"walk",
[escoria.main.current_scene.player.global_id, position],
do_walk(
position,
[escoria.main.current_scene.player.global_id],
true
)
@@ -109,9 +159,9 @@ func left_click_on_bg(position: Vector2) -> void:
#
# - position: Position clicked
func right_click_on_bg(position: Vector2) -> void:
escoria.do(
"walk",
[escoria.main.current_scene.player.global_id, position],
do_walk(
position,
[escoria.main.current_scene.player.global_id],
true
)
@@ -123,9 +173,9 @@ func right_click_on_bg(position: Vector2) -> void:
#
# - position: Position clicked
func left_double_click_on_bg(position: Vector2) -> void:
escoria.do(
"walk",
[escoria.main.current_scene.player.global_id, position, true],
do_walk(
position,
[escoria.main.current_scene.player.global_id, true],
true
)
@@ -153,8 +203,8 @@ func element_unfocused() -> void:
# - item_global_id: Global id of the item that was clicked
# - event: The received input event
func left_click_on_item(item_global_id: String, event: InputEvent) -> void:
escoria.do(
"item_left_click",
escoria.action_manager.do(
escoria.action_manager.ACTION.ITEM_LEFT_CLICK,
[item_global_id, event],
true
)
@@ -168,8 +218,8 @@ func left_click_on_item(item_global_id: String, event: InputEvent) -> void:
# - item_global_id: Global id of the item that was clicked
# - event: The received input event
func right_click_on_item(item_global_id: String, event: InputEvent) -> void:
escoria.do(
"item_right_click",
escoria.action_manager.do(
escoria.action_manager.ACTION.ITEM_RIGHT_CLICK,
[item_global_id, event],
true
)
@@ -186,8 +236,8 @@ func left_double_click_on_item(
item_global_id: String,
event: InputEvent
) -> void:
escoria.do(
"item_left_click",
escoria.action_manager.do(
escoria.action_manager.ACTION.ITEM_LEFT_CLICK,
[item_global_id, event],
true
)
@@ -363,8 +413,8 @@ func show_crash_popup(files: Array = []) -> void:
var files_to_send: String = ""
for file in files:
files_to_send += "- %s\n" % file
crash_popup.dialog_text = tr(ProjectSettings.get_setting(
"escoria/debug/crash_message")
crash_popup.dialog_text = tr(escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.CRASH_MESSAGE)
) % files_to_send
crash_popup.popup_centered()
escoria.set_game_paused(true)

View File

@@ -356,7 +356,10 @@ func _on_mouse_exited():
func element_entered(body):
if body is ESCBackground or body.get_parent() is ESCBackground:
return
escoria.do("trigger_in", [global_id, body.global_id, trigger_in_verb])
escoria.action_manager.do(
escoria.action_manager.ACTION.TRIGGER_IN,
[global_id, body.global_id, trigger_in_verb]
)
# Another item (e.g. the player) has exited this element
@@ -366,7 +369,10 @@ func element_entered(body):
func element_exited(body):
if body is ESCBackground or body.get_parent() is ESCBackground:
return
escoria.do("trigger_out", [global_id, body.global_id, trigger_out_verb])
escoria.action_manager.do(
escoria.action_manager.ACTION.TRIGGER_OUT,
[global_id, body.global_id, trigger_out_verb]
)
# Use the movable node to teleport this item to the target item

View File

@@ -39,7 +39,7 @@ func queue_resource(path: String, p_in_front: bool = false, p_permanent: bool =
elif ResourceLoader.has(path):
var res = ResourceLoader.load(path)
pending[path] = { "res": res, "permanent": p_permanent }
pending[path] = ESCResourceDescriptor.new(res, p_permanent)
_unlock("queue_resource")
return
else:
@@ -49,7 +49,7 @@ func queue_resource(path: String, p_in_front: bool = false, p_permanent: bool =
queue.insert(0, res)
else:
queue.push_back(res)
pending[path] = { "res": res, "permanent": p_permanent }
pending[path] = ESCResourceDescriptor.new(res, p_permanent)
_post("queue_resource")
_unlock("queue_resource")
return
@@ -138,12 +138,11 @@ func get_resource(path):
return res
else:
_unlock("return")
# We can't use escoria.project_settings_manager here since this method
# can be called from escoria._init()
if not ProjectSettings.get_setting("escoria/platform/skip_cache"):
var res = ResourceLoader.load(path)
pending[path] = {
"res": res,
"permanent": true
}
pending[path] = ESCResourceDescriptor.new(res, true)
return res
return ResourceLoader.load(path)

View File

@@ -38,6 +38,9 @@ var _level_map: Dictionary = {
func _init():
# Open logfile in write mode
log_file = File.new()
# this is left alone as this constructor is called from escoria.gd's own
# constructor
var log_file_path = ProjectSettings.get_setting(
"escoria/debug/log_file_path"
)
@@ -105,14 +108,16 @@ func warning(string: String, args = []):
if _get_log_level() >= LOG_WARNING and !crashed:
var argsstr = str(args) if !args.empty() else ""
_log("(W)\t" + string + " \t" + argsstr, true)
if ProjectSettings.get_setting("escoria/debug/terminate_on_warnings"):
if escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.TERMINATE_ON_WARNINGS
):
_perform_stack_trace_log()
crashed = true
var files = "- %s" % log_file.get_path_absolute()
var message = ProjectSettings.get_setting(
"escoria/debug/crash_message"
var message = escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.CRASH_MESSAGE
) % files
_log(message, true)
@@ -134,7 +139,9 @@ func error(string: String, args = [], do_savegame: bool = true):
var argsstr = str(args) if !args.empty() else ""
_log("(E)\t" + string + " \t" + argsstr, true)
if ProjectSettings.get_setting("escoria/debug/terminate_on_errors"):
if escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.TERMINATE_ON_ERRORS
):
_perform_stack_trace_log()
crashed = true
if do_savegame:
@@ -148,8 +155,8 @@ func error(string: String, args = [], do_savegame: bool = true):
]
var files = "- %s\n- %s" % files_to_send
var message = ProjectSettings.get_setting(
"escoria/debug/crash_message"
var message = escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.CRASH_MESSAGE
) % files
_log(message, true)
@@ -222,7 +229,9 @@ func _log(message:String, err: bool = false):
# Returns the currently set log level
# **Returns** Log level as set in the configuration
func _get_log_level() -> int:
return _level_map[ProjectSettings.get_setting("escoria/debug/log_level")]
return _level_map[escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.LOG_LEVEL
)]
# Creates a savegame file and save it in output log location
@@ -232,8 +241,8 @@ func _perform_save_game_log():
if error == OK:
_log(
"Emergency savegame created successfully in folder: %s" %
ProjectSettings.get_setting(
"escoria/debug/log_file_path"
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.LOG_FILE_PATH
)
)
else:

View File

@@ -0,0 +1,15 @@
# Describes a resource for use in the resource cache
extends Object
class_name ESCResourceDescriptor
# The resource being described
var res: Resource
# Whether the resource is permanent
var permanent: bool
func _init(res_in: Resource, permanent_in: bool) -> void:
res = res_in
permanent = permanent_in

View File

@@ -1,6 +1,17 @@
# Saves and loads savegame and settings files
class_name ESCSaveManager
# Template for settings filename
const SETTINGS_TEMPLATE: String = "settings.tres"
# Template for savegames filenames
const SAVE_NAME_TEMPLATE: String = "save_%03d.tres"
# Template for crash savegames filenames
const CRASH_SAVE_NAME_TEMPLATE: String = "crash_autosave_%s_%s.tres"
# If true, saving a game is enabled. Else, saving is disabled
var save_enabled: bool = true
@@ -10,28 +21,46 @@ var save_folder: String
# Filename of the latest crash savegame file
var crash_savegame_filename: String
# Template for savegames filenames
const SAVE_NAME_TEMPLATE: String = "save_%03d.tres"
# Template for crash savegames filenames
const CRASH_SAVE_NAME_TEMPLATE: String = "crash_autosave_%s_%s.tres"
# Variable containing the settings folder obtained from Project Settings
var settings_folder: String
# Template for settings filename
const SETTINGS_TEMPLATE: String = "settings.tres"
# ESC commands kept around for references to their command names.
var _transition: TransitionCommand
var _hide_menu: HideMenuCommand
var _change_scene: ChangeSceneCommand
var _set_active: SetActiveCommand
var _set_interactive: SetInteractiveCommand
var _teleport_pos: TeleportPosCommand
var _set_angle: SetAngleCommand
var _set_state: SetStateCommand
var _stop_snd: StopSndCommand
var _play_snd: PlaySndCommand
# Constructor of ESCSaveManager object.
func _init():
# We leave the calls to ProjectSettings as-is since this constructor can be
# called from escoria.gd's own.
save_folder = ProjectSettings.get_setting("escoria/main/savegames_path")
settings_folder = ProjectSettings.get_setting("escoria/main/settings_path")
_transition = TransitionCommand.new()
_hide_menu = HideMenuCommand.new()
_change_scene = ChangeSceneCommand.new()
_set_active = SetActiveCommand.new()
_set_interactive = SetInteractiveCommand.new()
_teleport_pos = TeleportPosCommand.new()
_set_angle = SetAngleCommand.new()
_set_state = SetStateCommand.new()
_stop_snd = StopSndCommand.new()
_play_snd = PlaySndCommand.new()
# Return a list of savegames metadata (id, date, name and game version)
func get_saves_list() -> Dictionary:
var regex = RegEx.new()
regex.compile("save_([0-9]{3})\\.tres")
var saves = {}
var dirsave = Directory.new()
if dirsave.open(save_folder) == OK:
@@ -46,7 +75,7 @@ func get_saves_list() -> Dictionary:
"name": save_game_res["name"],
"game_version": save_game_res["game_version"],
}
var id: int
var matches = regex.search(nextfile)
if matches.strings.size() > 1:
@@ -76,10 +105,10 @@ func save_game_exists(id: int) -> bool:
func save_game(id: int, p_savename: String):
if not save_enabled:
escoria.logger.debug(
"esc_save_data_resources.gd",
"esc_save_manager.gd",
["Save requested while saving is not possible. Save canceled."])
return
var save_game := _do_save_game(p_savename)
var directory: Directory = Directory.new()
@@ -90,7 +119,7 @@ func save_game(id: int, p_savename: String):
var error: int = ResourceSaver.save(save_path, save_game)
if error != OK:
escoria.logger.report_errors(
"esc_save_data_resources.gd",
"esc_save_manager.gd",
["There was an issue writing the save %s to %s" % [id, save_path]]
)
@@ -105,11 +134,11 @@ func save_game_crash():
datetime["hour"],
datetime["minute"],
]
var save_game := _do_save_game("Crash %s" % datetime_string)
var save_file_path: String = ProjectSettings.get_setting(
"escoria/debug/log_file_path"
var save_file_path: String = escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.LOG_FILE_PATH
)
crash_savegame_filename = save_file_path.plus_file(
CRASH_SAVE_NAME_TEMPLATE % [
@@ -119,11 +148,11 @@ func save_game_crash():
+ str(datetime["second"])
]
)
var error: int = ResourceSaver.save(crash_savegame_filename, save_game)
if error != OK:
escoria.logger.report_errors(
"esc_save_data_resources.gd",
"esc_save_manager.gd",
["There was an issue writing the crash save to %s"
% crash_savegame_filename])
return error
@@ -135,12 +164,12 @@ func save_game_crash():
# - p_savename: name of the savegame
func _do_save_game(p_savename: String) -> ESCSaveGame:
var save_game = ESCSaveGame.new()
save_game.escoria_version = escoria.ESCORIA_VERSION
save_game.game_version = ProjectSettings.get_setting(
"escoria/main/game_version"
save_game.escoria_version = escoria.ESCORIA_VERSION
save_game.game_version = escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_VERSION
)
save_game.name = p_savename
var datetime = OS.get_datetime()
var datetime_string = "%02d/%02d/%02d %02d:%02d" % [
datetime["day"],
@@ -150,7 +179,7 @@ func _do_save_game(p_savename: String) -> ESCSaveGame:
datetime["minute"],
]
save_game.date = datetime_string
escoria.globals_manager.save_game(save_game)
escoria.object_manager.save_game(save_game)
escoria.main.save_game(save_game)
@@ -175,15 +204,15 @@ func load_game(id: int):
escoria.logger.info(
"esc_save_manager.gd:load_game()",
["Loading savegame %s" % str(id)])
var save_game: ESCSaveGame = ResourceLoader.load(save_file_path)
var plugin_config = ConfigFile.new()
plugin_config.load("res://addons/escoria-core/plugin.cfg")
var escoria_version = plugin_config.get_value("plugin", "version")
# Migrate savegame through escoria versions
if escoria_version != save_game.escoria_version:
var migration_manager: ESCMigrationManager = ESCMigrationManager.new()
save_game = migration_manager.migrate(
@@ -193,41 +222,48 @@ func load_game(id: int):
"res://addons/escoria-core/game/core-scripts/migrations/versions"
)
# Migrate savegame through game versions
if ProjectSettings.get_setting("escoria/main/game_version") != \
save_game.game_version and \
ProjectSettings.get_setting(
"escoria/main/game_migration_path"
) != "":
# Migrate savegame through game versions
if escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_VERSION
) != save_game.game_version \
and escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_MIGRATION_PATH
) != "":
var migration_manager: ESCMigrationManager = ESCMigrationManager.new()
save_game = migration_manager.migrate(
save_game,
save_game.game_version,
ProjectSettings.get_setting("escoria/main/game_version"),
ProjectSettings.get_setting(
"escoria/main/game_migration_path"
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_VERSION
),
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.GAME_MIGRATION_PATH
)
)
escoria.event_manager.interrupt_running_event()
var load_event = ESCEvent.new(":load")
var load_event = ESCEvent.new("%s%s" % [ESCEvent.PREFIX, escoria.event_manager.EVENT_LOAD])
var load_statements = []
load_statements.append(
ESCCommand.new(
"transition %s out" %
[ProjectSettings.get_setting("escoria/ui/default_transition")]
"%s %s out" %
[
_transition.get_command_name(),
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.DEFAULT_TRANISITION
)]
)
)
load_statements.append(
ESCCommand.new("hide_menu main")
ESCCommand.new("%s main" % _hide_menu.get_command_name())
)
load_statements.append(
ESCCommand.new("hide_menu pause")
ESCCommand.new("%s pause" % _hide_menu.get_command_name())
)
## GLOBALS
for k in save_game.globals.keys():
escoria.globals_manager.set_global(
@@ -235,83 +271,115 @@ func load_game(id: int):
save_game.globals[k],
true
)
## ROOM
load_statements.append(
ESCCommand.new("change_scene %s false" \
% save_game.main["current_scene_filename"])
ESCCommand.new("%s %s false" %
[
_change_scene.get_command_name(),
save_game.main["current_scene_filename"]
]
)
)
## OBJECTS
for object_global_id in save_game.objects.keys():
if escoria.object_manager.has(object_global_id) and \
save_game.objects[object_global_id].has("active"):
load_statements.append(ESCCommand.new("set_active %s %s" \
% [object_global_id,
save_game.objects[object_global_id]["active"]])
)
if save_game.objects[object_global_id].has("interactive"):
load_statements.append(ESCCommand.new("set_interactive %s %s" \
% [object_global_id,
save_game.objects[object_global_id]["interactive"]])
)
if save_game.objects[object_global_id].has("state"):
load_statements.append(ESCCommand.new("set_state %s %s true" \
% [object_global_id,
save_game.objects[object_global_id]["state"]])
)
if save_game.objects[object_global_id].has("global_transform"):
load_statements.append(ESCCommand.new("teleport_pos %s %s %s" \
% [object_global_id,
int(save_game.objects[object_global_id] \
["global_transform"].origin.x),
int(save_game.objects[object_global_id] \
["global_transform"].origin.y)]
load_statements.append(ESCCommand.new("%s %s %s" \
% [
_set_active.get_command_name(),
object_global_id,
save_game.objects[object_global_id]["active"]
]
)
)
load_statements.append(ESCCommand.new("set_angle %s %s" \
% [object_global_id,
save_game.objects[object_global_id]["last_deg"]])
if save_game.objects[object_global_id].has("interactive"):
load_statements.append(ESCCommand.new("%s %s %s" \
% [
_set_interactive.get_command_name(),
object_global_id,
save_game.objects[object_global_id]["interactive"]
]
)
)
if object_global_id in ["_music", "_sound", "_speech"]:
if save_game.objects[object_global_id].has("state"):
load_statements.append(ESCCommand.new("%s %s %s true" \
% [
_set_state.get_command_name(),
object_global_id,
save_game.objects[object_global_id]["state"]
]
)
)
if save_game.objects[object_global_id].has("global_transform"):
load_statements.append(ESCCommand.new("%s %s %s %s" \
% [
_teleport_pos.get_command_name(),
object_global_id,
int(save_game.objects[object_global_id] \
["global_transform"].origin.x),
int(save_game.objects[object_global_id] \
["global_transform"].origin.y)
]
)
)
load_statements.append(ESCCommand.new("%s %s %s" \
% [
_set_angle.get_command_name(),
object_global_id,
save_game.objects[object_global_id]["last_deg"]
]
)
)
if object_global_id in [
escoria.object_manager.MUSIC,
escoria.object_manager.SOUND, escoria.object_manager.SPEECH
]:
if save_game.objects[object_global_id]["state"] in [
"default",
"off"
]:
load_statements.append(
ESCCommand.new("stop_snd %s" % [
ESCCommand.new("%s %s" % [
_stop_snd.get_command_name(),
object_global_id,
])
)
else:
load_statements.append(
ESCCommand.new("play_snd %s %s" % [
ESCCommand.new("%s %s %s" % [
_play_snd.get_command_name(),
save_game.objects[object_global_id]["state"],
object_global_id,
])
)
load_statements.append(
ESCCommand.new(
"transition %s in" %
[ProjectSettings.get_setting("escoria/ui/default_transition")]
"%s %s in" %
[
_transition.get_command_name(),
escoria.project_settings_manager.get_setting(
escoria.project_settings_manager.DEFAULT_TRANISITION
)]
)
)
load_event.statements = load_statements
escoria.set_game_paused(false)
escoria.event_manager.queue_event(load_event)
escoria.logger.debug(
"esc_save_manager.gd:load_game()",
["Load event queued."])
# Save the game settings in the settings file.
func save_settings():
var settings_res := ESCSaveSettings.new()
@@ -335,9 +403,10 @@ func save_settings():
var error: int = ResourceSaver.save(save_path, settings_res)
if error != OK:
escoria.logger.report_errors(
"esc_save_data_resources.gd:save_settings()",
"esc_save_manager.gd:save_settings()",
["There was an issue writing settings %s" % save_path])
# Load the game settings from the settings file
# **Returns** The Resource structure loaded from settings file
func load_settings() -> Resource:
@@ -346,7 +415,7 @@ func load_settings() -> Resource:
var file: File = File.new()
if not file.file_exists(save_settings_path):
escoria.logger.report_warnings(
"esc_save_data_resources.gd:load_settings()",
"esc_save_manager.gd:load_settings()",
["Settings file %s doesn't exist" % save_settings_path,
"Setting default settings."])
save_settings()

View File

@@ -1,4 +1,6 @@
# Resource holding game settings.
# Resource holding game settings. Note that we call directly to ProjectSettings
# for instance variable initialization since this class is instantiated from
# escoria.gd.
extends Resource
class_name ESCSaveSettings