Files
gymkhana-actions/addons/escoria-core/game/escoria.gd
Julian Murgia 5d1df7aaa9 Add sound volume management and language selection
Not all translated yet though
2021-06-01 07:35:50 +02:00

322 lines
11 KiB
GDScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends Node
# Scripts
onready var esc_compiler = $esc_compiler
onready var logger = load("res://addons/escoria-core/game/core-scripts/log/logging.gd").new()
onready var main = $main
onready var esc_runner = $esc_runner
onready var esc_level_runner = $esc_runner/esc_level_runner
onready var inputs_manager = $inputs_manager
onready var utils = load("res://addons/escoria-core/game/core-scripts/utils/utils.gd").new()
# INSTANCES
var main_menu_instance
## Dialog player instantiator. This instance is called directly for dialogs.
var dialog_player
## Inventory scene
var inventory
# Game variables
var room_terrain
enum GAME_STATE {
DEFAULT,
DIALOG,
WAIT
}
onready var current_state = GAME_STATE.DEFAULT
onready var game_size = get_viewport().size
# These are settings that the player can affect and save/load later
var settings : Dictionary
# These are default settings
var settings_default : Dictionary = {
# Text language
"text_lang": ProjectSettings.get_setting("escoria/main/text_lang"),
# Voice language
"voice_lang": ProjectSettings.get_setting("escoria/main/voice_lang"),
# Speech enabled
"speech_enabled": ProjectSettings.get_setting("escoria/sound/speech_enabled"),
# Master volume (max is 1.0)
"master_volume": ProjectSettings.get_setting("escoria/sound/master_volume"),
# Music volume (max is 1.0)
"music_volume": ProjectSettings.get_setting("escoria/sound/music_volume"),
# Sound effects volume (max is 1.0)
"sfx_volume": ProjectSettings.get_setting("escoria/sound/sfx_volume"),
# Voice volume (for speech only, max is 1.0)
"voice_volume": ProjectSettings.get_setting("escoria/sound/speech_volume"),
# Set fullscreen
"fullscreen": false,
# Allow dialog skipping
"skip_dialog": true,
# XXX: What is this? `achievements.gd` looks like iOS-only
"rate_shown": false,
}
func _init():
logger = load("res://addons/escoria-core/game/core-scripts/log/logging.gd").new()
##################################################################################
# Called by Main menu "start new game"
func new_game():
var actions = esc_compiler.load_esc_file(ProjectSettings.get_setting("escoria/main/game_start_script"))
$esc_runner.run_game(actions)
escoria.main.scene_transition.fade_in()
yield(escoria.main.scene_transition, "transition_done")
"""
Add object to the environement.
"""
func register_object(object : Object):
var object_id
if object.get("global_id"):
object_id = object.global_id
else:
object_id = object.name
if object is ESCDialogsPlayer:
dialog_player = object
if object is ESCPlayer:
$esc_runner.register_object(object_id, object, true)
if object is Position2D:
$esc_runner.register_object(object_id, object, true)
if object is ESCItem:
$esc_runner.register_object(object_id, object, true)
if object is ESCTerrain:
room_terrain = object
# if object is ESCBackground:
# $esc_runner.register_object(object_id, object, true)
if object is ESCCamera:
$esc_runner.register_object(object_id, object, true)
if object is ESCInventory:
inventory = object
if object is ESCTooltip:
if main.current_scene:
main.current_scene.game.tooltip_node = object
if object is ESCBackgroundMusic:
$esc_runner.register_object(object_id, object, true)
if object is ESCBackgroundSound:
$esc_runner.register_object(object_id, object, true)
"""
Generic action function that runs an action on an element of the room (eg player walk)
action: type of the action ()
"""
func do(action : String, params : Array = []) -> void:
if current_state == GAME_STATE.DEFAULT:
match action:
"walk":
# Reset current action.
esc_runner.clear_current_action()
# Check moving object.
if !escoria.esc_runner.check_obj(params[0], "escoria.do(walk)"):
escoria.logger.report_errors("escoria.gd:do()",
["Walk action requested on inexisting object: " + params[0]])
return
var moving_obj = escoria.esc_runner.get_object(params[0])
# Walk to Position2D.
if params[1] is Vector2:
var target_position = params[1]
var is_fast : bool = false
if params.size() > 2 and params[2] == true:
is_fast = true
var walk_context = {"fast": is_fast, "target": target_position}
moving_obj.walk_to(target_position, walk_context)
# Walk to object from its id
elif params[1] is String:
if !escoria.esc_runner.check_obj(params[1], "escoria.do(walk)"):
escoria.logger.report_errors("escoria.gd:do()",
["Walk action requested TOWARDS inexisting object: " + params[1]])
return
var object = escoria.esc_runner.get_object(params[1])
if object:
var target_position : Vector2 = object.interact_position
var is_fast : bool = false
if params.size() > 2 and params[2] == true:
is_fast = true
var walk_context = {"fast": is_fast, "target_object" : object}
moving_obj.walk_to(target_position, walk_context)
"item_left_click":
if params[0] is String:
escoria.logger.info("escoria.do() : item_left_click on item ", [params[0]])
var item = $esc_runner.get_object(params[0])
ev_left_click_on_item(item, params[1])
"item_right_click":
if params[0] is String:
escoria.logger.info("escoria.do() : item_right_click on item ", [params[0]])
ev_left_click_on_item($esc_runner.get_object(params[0]), params[1], true)
"trigger_in":
var trigger_id = params[0]
var object_id = params[1]
var trigger_in_verb = params[2]
escoria.logger.info("escoria.do() : trigger_in " + trigger_id + " by " + object_id)
esc_runner.run_event(esc_runner.objects_events_table[trigger_id][trigger_in_verb])
"trigger_out":
var trigger_id = params[0]
var object_id = params[1]
var trigger_out_verb = params[2]
escoria.logger.info("escoria.do() : trigger_out " + trigger_id + " by " + object_id)
esc_runner.run_event(esc_runner.objects_events_table[trigger_id][trigger_out_verb])
_:
escoria.logger.report_warnings("escoria.gd:do()",
["Action received:", action, "with params ", params])
elif current_state == GAME_STATE.WAIT:
pass
# PRIVATE
func ev_left_click_on_item(obj, event, default_action = false):
"""
Event occurring when an object/item is left clicked
obj : object that was left clicked
event :
"""
if obj is String:
obj = esc_runner.objects[obj]
escoria.logger.info(obj.global_id + " left-clicked with event ", [event])
var need_combine = false
# Check if current_action and current_tool are already set
if esc_runner.current_action:
if esc_runner.current_tool:
if esc_runner.current_action in esc_runner.current_tool.combine_if_action_used_among:
need_combine = true
else:
esc_runner.current_tool = obj
else:
if default_action:
if esc_runner.inventory_has(obj.global_id):
esc_runner.current_action = obj.default_action_inventory
else:
esc_runner.current_action = obj.default_action
elif esc_runner.current_action in obj.combine_if_action_used_among:
esc_runner.current_tool = obj
# Don't interact after player movement towards object (because object is inactive for example)
var dont_interact = false
var destination_position : Vector2 = main.current_scene.player.global_position
# Create walk context
var walk_context = {"fast": event.doubleclick, "target_object" : obj}
# If object not in inventory, player walks towards it
if !esc_runner.inventory_has(obj.global_id):
var clicked_object_has_interact_position = false
if esc_runner.get_interactive(obj.global_id):
# if obj.interact_positions.default != null:
# destination_position = obj.interact_positions.default#.global_position
# clicked_object_has_interact_position = true
# else:
# destination_position = obj.position
if obj.get_interact_position() != null:
destination_position = obj.get_interact_position()
clicked_object_has_interact_position = true
else:
destination_position = obj.position
else:
destination_position = event.position
dont_interact = true
# Use esc_runner for this?
var is_already_walking = main.current_scene.player.walk_to(destination_position, walk_context)
# Wait for the player to arrive before continuing with action.
var context = yield(main.current_scene.player, "arrived")
escoria.logger.info("Context arrived: ", [context])
if context.has("target_object") and walk_context.has("target_object"):
if (context.target_object.global_id != walk_context.target_object.global_id) \
or (context.target_object.global_id == walk_context.target_object.global_id and is_already_walking):
dont_interact = true
elif context.has("target") and walk_context.has("target"):
if (context.target.global_id != walk_context.target.global_id) \
or (context.target.global_id == walk_context.target.global_id and is_already_walking):
dont_interact = true
# If no interaction should happen after player has arrived, leave immediately.
if dont_interact:
return
var player_global_pos = main.current_scene.player.global_position
var clicked_position = event.position
# If player has arrived at the position he was supposed to reach so he can interact
if player_global_pos == destination_position:
# Manage exits
if obj.is_exit and $esc_runner.current_action == "" or $esc_runner.current_action == "walk":
var params = [obj]
$esc_runner.activate("exit_scene", params)
else:
# Manage movements towards object before activating it
if $esc_runner.current_action == "" or $esc_runner.current_action == "walk":
if destination_position != clicked_position \
and !esc_runner.inventory_has(obj.global_id):
esc_runner.activate("arrived", [obj])
# Manage action on object
elif $esc_runner.current_action != "" and $esc_runner.current_action != "walk":
# If apply_interact, perform combine between items
if need_combine:
esc_runner.activate(esc_runner.current_action, [esc_runner.current_tool, obj])
else:
esc_runner.activate(esc_runner.current_action, [obj])
# else:
## escoria.fallback("")
# pass
func _on_settings_loaded(p_settings : Dictionary):
escoria.logger.info("******* settings loaded", p_settings)
if p_settings != null:
settings = p_settings
else:
settings = {}
for k in settings_default:
if !(k in settings):
settings[k] = settings_default[k]
# TODO Apply globally
# AudioServer.set_fx_global_volume_scale(settings.sfx_volume)
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db(settings.master_volume))
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("SFX"), linear2db(settings.sfx_volume))
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear2db(settings.music_volume))
TranslationServer.set_locale(settings.text_lang)
# music_volume_changed()