diff --git a/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd b/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd
index 58f71e6e..a825b1cf 100644
--- a/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd
+++ b/addons/escoria-core/game/core-scripts/esc/commands/change_scene.gd
@@ -71,8 +71,6 @@ func run(command_params: Array) -> int:
escoria.inputs_manager.clear_stack()
- escoria.main_menu_instance.hide()
-
var res_room = escoria.resource_cache.get_resource(command_params[0])
# Load game scene
diff --git a/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd b/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd
index 1a697af5..054729d5 100644
--- a/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd
+++ b/addons/escoria-core/game/core-scripts/esc/commands/spawn.gd
@@ -1,4 +1,4 @@
-# `spawn path [object2]`
+# `spawn identifier path [is_active=true] [object2] `
#
# Instances a scene determined by "path", and places in the position of
# object2 (object2 is optional)
@@ -11,50 +11,71 @@ class_name SpawnCommand
# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
return ESCCommandArgumentDescriptor.new(
- 1,
- [TYPE_STRING, TYPE_STRING],
- [null, null]
+ 2,
+ [TYPE_STRING, TYPE_STRING, TYPE_BOOL, TYPE_STRING],
+ [null, null, true, null]
)
# Validate wether the given arguments match the command descriptor
func validate(arguments: Array):
- if not ResourceLoader.exists(arguments[0]):
+ if arguments[0].empty() \
+ or arguments[0] in escoria.object_manager.RESERVED_OBJECTS:
+ escoria.logger.report_errors(
+ "spawn: invalid global_id",
+ [
+ "global_id %s is invalid" % arguments[0]
+ ]
+ )
+ return false
+ if not ResourceLoader.exists(arguments[1]):
escoria.logger.report_errors(
"spawn: invalid scene path",
[
- "Scene with path %s not found" % arguments[0]
+ "Scene with path %s not found" % arguments[1]
]
)
- return false
- if arguments[1] and not escoria.object_manager.objects.has(arguments[1]):
+ return false
+ if arguments[3] and not escoria.object_manager.objects.has(arguments[2]):
escoria.logger.report_errors(
"spawn: invalid object",
[
- "Object with global id %s not found" % arguments[1]
+ "Object with global id %s not found" % arguments[2]
]
)
- return false
+ return false
return .validate(arguments)
# Run the command
func run(command_params: Array) -> int:
- var res_scene = escoria.resource_cache.get_resource(command_params[0])
+ var res_scene = escoria.resource_cache.get_resource(command_params[1])
# Load room scene
var scene = res_scene.instance()
if scene:
escoria.main.get_node("/root").add_child(scene)
- if command_params[1]:
- var obj = escoria.object_manager.get_object(command_params[1])
+ if command_params[3]:
+ var obj = escoria.object_manager.get_object(command_params[3])
scene.set_position(obj.get_global_position())
escoria.inputs_manager.hotspot_focused = ""
+
+ escoria.object_manager.register_object(
+ ESCObject.new(
+ command_params[0],
+ scene
+ ),
+ true
+ )
+
+ escoria.object_manager.get_object(command_params[0]).active = \
+ command_params[2]
+
else:
escoria.logger.report_errors(
"spawn: Invalid scene",
[
- "Failed loading scene %s" % command_params[0]
+ "Failed loading scene %s" % command_params[1]
]
)
diff --git a/addons/escoria-core/game/escoria.gd b/addons/escoria-core/game/escoria.gd
index d872881f..7ab936b7 100644
--- a/addons/escoria-core/game/escoria.gd
+++ b/addons/escoria-core/game/escoria.gd
@@ -49,9 +49,6 @@ var command_registry: ESCCommandRegistry
# Resource cache handler
var resource_cache: ESCResourceCache
-# Instance of the main menu
-var main_menu_instance
-
# Terrain of the current room
var room_terrain
@@ -64,7 +61,6 @@ var inventory
# These are settings that the player can affect and save/load later
var settings: ESCSaveSettings
-
# The current state of the game
onready var current_state = GAME_STATE.DEFAULT
@@ -87,6 +83,11 @@ var controller: ESCController
# The game scene loaded
var game_scene: ESCGame
+# The compiled start script loaded from ProjectSettings
+# escoria/main/game_start_script
+var start_script : ESCScript
+
+
# Initialize various objects
func _init():
@@ -119,38 +120,25 @@ func _init():
ProjectSettings.get_setting("escoria/ui/game_scene")
).instance()
- if ProjectSettings.get_setting("escoria/ui/main_menu_scene") == "":
- logger.report_errors("escoria.gd",
- ["Parameter escoria/ui/main_menu_scene is not set!"]
- )
- else:
- self.main_menu_instance = resource_cache.get_resource(
- ProjectSettings.get_setting("escoria/ui/main_menu_scene")
- ).instance()
-
# Load settings
func _ready():
inputs_manager.register_core()
-
-
+ start_script = self.esc_compiler.load_esc_file(
+ ProjectSettings.get_setting("escoria/main/game_start_script")
+ )
+
+
+# Called by Escoria's main_scene as very very first event EVER.
+# Usually you'll want to show some logos animations before spawning the main
+# menu in the escoria/main/game_start_script 's :init event
+func init():
+ run_event_from_script(start_script, "init")
+
# Called by Main menu "start new game"
func new_game():
- var script = self.esc_compiler.load_esc_file(
- ProjectSettings.get_setting("escoria/main/game_start_script")
- )
- event_manager.queue_event(script.events["start"])
- var rc = yield(event_manager, "event_finished")
- while rc[1] != "start":
- rc = yield(event_manager, "event_finished")
-
- if rc[0] != ESCExecution.RC_OK:
- self.logger.report_errors(
- "Start event of the start script returned unsuccessful: %d" % rc[0],
- []
- )
- return
+ run_event_from_script(start_script, "newgame")
# Run a generic action
@@ -319,3 +307,29 @@ func _input(event):
# - p_paused: if true, pauses the game. If false, unpauses the game.
func set_game_paused(p_paused: bool):
get_tree().paused = p_paused
+
+
+# Runs the event "event_name" from the "script" ESC script.
+#
+# #### Parameters
+# - script: ESC script containing the event to run. The script must have been
+# loaded.
+# - event_name: Name of the event to run
+func run_event_from_script(script: ESCScript, event_name: String):
+ if script == null:
+ logger.report_errors(
+ "escoria.gd:run_event_from_script()",
+ ["Requested action %s on unloaded script %s" % [event_name, script],
+ "Please load the ESC script using esc_compiler.load_esc_file()."]
+ )
+ event_manager.queue_event(script.events[event_name])
+ var rc = yield(event_manager, "event_finished")
+ while rc[1] != event_name:
+ rc = yield(event_manager, "event_finished")
+
+ if rc[0] != ESCExecution.RC_OK:
+ self.logger.report_errors(
+ "Start event of the start script returned unsuccessful: %d" % rc[0],
+ []
+ )
+ return
diff --git a/addons/escoria-core/game/main_scene.gd b/addons/escoria-core/game/main_scene.gd
index 2752b53e..59bcaeb6 100644
--- a/addons/escoria-core/game/main_scene.gd
+++ b/addons/escoria-core/game/main_scene.gd
@@ -5,15 +5,5 @@ extends Node
# Start the main menu
func _ready():
- if escoria.main_menu_instance == null:
- if ProjectSettings.get_setting("escoria/ui/main_menu_scene") == "":
- escoria.logger.report_errors("escoria.gd",
- ["Parameter escoria/ui/main_menu_scene is not set!"]
- )
- else:
- escoria.main_menu_instance = escoria.resource_cache.get_resource(
- ProjectSettings.get_setting("escoria/ui/main_menu_scene")
- ).instance()
- escoria.call_deferred("add_child", escoria.main_menu_instance)
-
+ escoria.init()
diff --git a/addons/escoria-core/plugin.gd b/addons/escoria-core/plugin.gd
index 6a7de0b7..66313665 100644
--- a/addons/escoria-core/plugin.gd
+++ b/addons/escoria-core/plugin.gd
@@ -50,26 +50,6 @@ func set_escoria_ui_settings():
}
ProjectSettings.add_property_info(default_dialog_scene_property_info)
- if !ProjectSettings.has_setting("escoria/ui/main_menu_scene"):
- ProjectSettings.set_setting("escoria/ui/main_menu_scene", "")
- var main_menu_scene_property_info = {
- "name": "escoria/ui/main_menu_scene",
- "type": TYPE_STRING,
- "hint": PROPERTY_HINT_FILE,
- "hint_string": "*.tscn, *.scn"
- }
- ProjectSettings.add_property_info(main_menu_scene_property_info)
-
- if !ProjectSettings.has_setting("escoria/ui/pause_menu_scene"):
- ProjectSettings.set_setting("escoria/ui/pause_menu_scene", "")
- var pause_menu_scene_property_info = {
- "name": "escoria/ui/pause_menu_scene",
- "type": TYPE_STRING,
- "hint": PROPERTY_HINT_FILE,
- "hint_string": "*.tscn, *.scn"
- }
- ProjectSettings.add_property_info(pause_menu_scene_property_info)
-
if !ProjectSettings.has_setting("escoria/ui/game_scene"):
ProjectSettings.set_setting("escoria/ui/game_scene", "")
var game_scene_property_info = {
diff --git a/docs/api/SpawnCommand.md b/docs/api/SpawnCommand.md
index d11d8cbc..a94558ba 100644
--- a/docs/api/SpawnCommand.md
+++ b/docs/api/SpawnCommand.md
@@ -6,7 +6,7 @@
## Description
-`spawn path [object2]`
+`spawn identifier path [is_active=true] [object2] `
Instances a scene determined by "path", and places in the position of
object2 (object2 is optional)
diff --git a/docs/api/escoria.gd.md b/docs/api/escoria.gd.md
index 10974871..69656560 100644
--- a/docs/api/escoria.gd.md
+++ b/docs/api/escoria.gd.md
@@ -113,14 +113,6 @@ var resource_cache: ESCResourceCache
Resource cache handler
-### main\_menu\_instance
-
-```gdscript
-var main_menu_instance
-```
-
-Instance of the main menu
-
### room\_terrain
```gdscript
@@ -210,8 +202,27 @@ var game_scene: ESCGame
The game scene loaded
+### start\_script
+
+```gdscript
+var start_script: ESCScript
+```
+
+The compiled start script loaded from ProjectSettings
+escoria/main/game_start_script
+
## Method Descriptions
+### init
+
+```gdscript
+func init()
+```
+
+Called by Escoria's main_scene as very very first event EVER.
+Usually you'll want to show some logos animations before spawning the main
+menu in the escoria/main/game_start_script 's :init event
+
### new\_game
```gdscript
@@ -246,6 +257,19 @@ Pauses or unpause the game
#### Parameters
- p_paused: if true, pauses the game. If false, unpauses the game.
+### run\_event\_from\_script
+
+```gdscript
+func run_event_from_script(script: ESCScript, event_name: String)
+```
+
+Runs the event "event_name" from the "script" ESC script.
+
+#### Parameters
+- script: ESC script containing the event to run. The script must have been
+loaded.
+- event_name: Name of the event to run
+
## Signals
- signal request_pause_menu(): Signal sent when pause menu has to be displayed
diff --git a/docs/esc.md b/docs/esc.md
index 84426e25..799da835 100644
--- a/docs/esc.md
+++ b/docs/esc.md
@@ -338,7 +338,7 @@ Moves object1 towards the position of object2, at the speed determined by
object1's "speed" property, unless overridden. This command is non-blocking.
It does not respect the room's navigation polygons, so you can move items
where the player can't walk.
-#### `spawn path [object2]` [API-Doc](api/SpawnCommand.md)
+#### `spawn identifier path [is_active=true] [object2] ` [API-Doc](api/SpawnCommand.md)
Instances a scene determined by "path", and places in the position of
object2 (object2 is optional)
diff --git a/game/rooms/room08/esc/button_puzzle.esc b/game/rooms/room08/esc/button_puzzle.esc
index 0f184123..df79b37b 100755
--- a/game/rooms/room08/esc/button_puzzle.esc
+++ b/game/rooms/room08/esc/button_puzzle.esc
@@ -4,7 +4,7 @@ say player "That must be the command to open the door."
:use
> [!r8_m_door_open]
#superpose_scene "res://game/rooms/room08/puzzle/10_buttons_puzzle.tscn"
- spawn "res://game/rooms/room08/puzzle/10_buttons_puzzle.tscn"
+ spawn puzzle "res://game/rooms/room08/puzzle/10_buttons_puzzle.tscn"
> [r8_m_door_open]
say player "The door is already open."
diff --git a/game/start_game.esc b/game/start_game.esc
old mode 100755
new mode 100644
index a2dec9e8..b5c0c3eb
--- a/game/start_game.esc
+++ b/game/start_game.esc
@@ -1,4 +1,13 @@
-:start
+:init
+
+spawn _main_menu res://game/ui/commons/main_menu/main_menu.tscn false
+set_active _main_menu true
+
+
+:newgame
+
+# Hide main menu
+set_active _main_menu false
# 1/ Simple scene
change_scene res://game/rooms/room01/room01.tscn
@@ -36,3 +45,5 @@ change_scene res://game/rooms/room01/room01.tscn
# 12/ Event flags tests 2
#change_scene res://game/rooms/room12/room12.tscn
+
+
diff --git a/project.godot b/project.godot
index 3fa2032e..1cdaa405 100644
--- a/project.godot
+++ b/project.godot
@@ -648,8 +648,6 @@ debug/terminate_on_errors=true
debug/development_lang="en"
ui/tooltip_follows_mouse=true
ui/default_dialog_scene="res://game/ui/commons/dialogs/dialog_label.tscn"
-ui/main_menu_scene="res://game/ui/commons/main_menu/main_menu.tscn"
-ui/pause_menu_scene="res://game/ui/commons/pause_menu/pause_menu.tscn"
main/text_lang="fr_FR"
main/voice_lang="fr_FR"
sound/music_volume=1
@@ -672,6 +670,8 @@ sound/speech_folder="res://game/speech"
sound/speech_extension="ogg"
ui/default_transition="curtain"
ui/transition_paths=[ "res://addons/escoria-core/game/scenes/transitions/shaders/" ]
+ui/main_menu_scene="res://game/ui/commons/main_menu/main_menu.tscn"
+ui/pause_menu_scene="res://game/ui/commons/pause_menu/pause_menu.tscn"
internals/save_data=""
[input]