Refactor cutscene queue
This commit is contained in:
@@ -2,9 +2,6 @@ class_name BattleSingleton extends Node
|
|||||||
|
|
||||||
var battleScene:BattleScene = null
|
var battleScene:BattleScene = null
|
||||||
|
|
||||||
func startBattle(
|
func startBattle(params) -> void:
|
||||||
fighters:Dictionary[BattleScene.BattlePosition, BattleFighter]
|
|
||||||
) -> void:
|
|
||||||
assert(battleScene != null)
|
assert(battleScene != null)
|
||||||
battleScene.startBatle(fighters
|
battleScene.startBattle(params)
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
class_name BattleScene extends BattleFighterScene
|
class_name BattleScene extends BattleFighterScene
|
||||||
|
const CutsceneBattleAction = preload("res://cutscene/battle/CutsceneBattleAction.gd")
|
||||||
|
|
||||||
enum BattlePosition {
|
enum BattlePosition {
|
||||||
LEFT_TOP_BACK,
|
LEFT_TOP_BACK,
|
||||||
@@ -16,8 +17,11 @@ enum BattlePosition {
|
|||||||
RIGHT_BOTTOM_FRONT
|
RIGHT_BOTTOM_FRONT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var active:bool = false
|
||||||
var fighterMap:Dictionary[BattlePosition, BattleFighterScene] = {}
|
var fighterMap:Dictionary[BattlePosition, BattleFighterScene] = {}
|
||||||
|
|
||||||
|
@export var actionBox:ActionBox = null
|
||||||
|
|
||||||
@export var fighterTopLeftBack:BattleFighterScene = null:
|
@export var fighterTopLeftBack:BattleFighterScene = null:
|
||||||
get:
|
get:
|
||||||
return fighterMap.get(BattlePosition.LEFT_TOP_BACK, null)
|
return fighterMap.get(BattlePosition.LEFT_TOP_BACK, null)
|
||||||
@@ -94,8 +98,48 @@ func _init() ->void:
|
|||||||
BATTLE.battleScene = self
|
BATTLE.battleScene = self
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func startBatle(fighters:Dictionary[BattlePosition, BattleFighter]) -> void:
|
func getFigheterAtPosition(battlePos:BattlePosition) -> BattleFighterScene:
|
||||||
for position in fighters.keys():
|
return fighterMap.get(battlePos, null)
|
||||||
var fighterScene:BattleFighterScene = fighterMap.get(position, null)
|
|
||||||
|
func getPositionForFighterScene(fighterScene:BattleFighterScene) -> BattlePosition:
|
||||||
|
for battlePos in fighterMap.keys():
|
||||||
|
var scene:BattleFighterScene = fighterMap[battlePos]
|
||||||
|
if scene == fighterScene:
|
||||||
|
return battlePos
|
||||||
|
assert(false)
|
||||||
|
return BattlePosition.LEFT_TOP_BACK
|
||||||
|
|
||||||
|
func getPositionForFighter(fighter:BattleFighter) -> BattlePosition:
|
||||||
|
for battlePos in fighterMap.keys():
|
||||||
|
var fighterScene:BattleFighterScene = fighterMap[battlePos]
|
||||||
|
if fighterScene.fighter == fighter:
|
||||||
|
return battlePos
|
||||||
|
assert(false)
|
||||||
|
return BattlePosition.LEFT_TOP_BACK
|
||||||
|
|
||||||
|
func getFighterSceneForFighter(fighter:BattleFighter) -> BattleFighterScene:
|
||||||
|
for battlePos in fighterMap.keys():
|
||||||
|
var fighterScene:BattleFighterScene = fighterMap[battlePos]
|
||||||
|
if fighterScene.fighter == fighter:
|
||||||
|
return fighterScene
|
||||||
|
return null
|
||||||
|
|
||||||
|
func startBattle(params:Dictionary) -> void:
|
||||||
|
assert(params.has('fighters'))
|
||||||
|
assert(!active)
|
||||||
|
|
||||||
|
var cutscene:Cutscene = params.get('cutscene', Cutscene.new())
|
||||||
|
|
||||||
|
for battlePos in params['fighters'].keys():
|
||||||
|
var fighterScene:BattleFighterScene = fighterMap.get(battlePos, null)
|
||||||
assert(fighterScene != null)
|
assert(fighterScene != null)
|
||||||
fighterScene.setFighter(fighters[position])
|
fighterScene.setFighter(params['fighters'][battlePos])
|
||||||
|
|
||||||
|
# Initial cutscene elements. In future I may need to make this editable
|
||||||
|
# somehow?
|
||||||
|
cutscene.addCallable({ "function": CutsceneBattleAction.playerDecision })
|
||||||
|
|
||||||
|
if !cutscene.running:
|
||||||
|
cutscene.start()
|
||||||
|
|
||||||
|
active = true
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
[gd_scene load_steps=3 format=3 uid="uid://dy54m7dvjgqta"]
|
[gd_scene load_steps=4 format=3 uid="uid://dy54m7dvjgqta"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://d1xyb0hdf1yeh" path="res://battle/fighter/BattleFighterScene.tscn" id="1_abr1f"]
|
[ext_resource type="PackedScene" uid="uid://d1xyb0hdf1yeh" path="res://battle/fighter/BattleFighterScene.tscn" id="1_abr1f"]
|
||||||
[ext_resource type="Script" uid="uid://dihfp05x6pktn" path="res://battle/BattleScene.gd" id="1_acaen"]
|
[ext_resource type="Script" uid="uid://dihfp05x6pktn" path="res://battle/BattleScene.gd" id="1_acaen"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ktmvnapibv2q" path="res://battle/ui/ActionBox.tscn" id="2_c3ndu"]
|
||||||
|
|
||||||
[node name="BattleScene" type="Node3D" node_paths=PackedStringArray("fighterTopLeftBack", "fighterTopLeftFront", "fighterMiddleLeftBack", "fighterMiddleLeftFront", "fighterBottomLeftBack", "fighterBottomLeftFront", "fighterTopRightBack", "fighterTopRightFront", "fighterMiddleRightBack", "fighterMiddleRightFront", "fighterBottomRightBack", "fighterBottomRightFront")]
|
[node name="BattleScene" type="Node3D" node_paths=PackedStringArray("actionBox", "fighterTopLeftBack", "fighterTopLeftFront", "fighterMiddleLeftBack", "fighterMiddleLeftFront", "fighterBottomLeftBack", "fighterBottomLeftFront", "fighterTopRightBack", "fighterTopRightFront", "fighterMiddleRightBack", "fighterMiddleRightFront", "fighterBottomRightBack", "fighterBottomRightFront")]
|
||||||
script = ExtResource("1_acaen")
|
script = ExtResource("1_acaen")
|
||||||
|
actionBox = NodePath("UI/ActionBox")
|
||||||
fighterTopLeftBack = NodePath("Fighters/LeftTopBack")
|
fighterTopLeftBack = NodePath("Fighters/LeftTopBack")
|
||||||
fighterTopLeftFront = NodePath("Fighters/LeftTopFront")
|
fighterTopLeftFront = NodePath("Fighters/LeftTopFront")
|
||||||
fighterMiddleLeftBack = NodePath("Fighters/LeftMiddleBack")
|
fighterMiddleLeftBack = NodePath("Fighters/LeftMiddleBack")
|
||||||
@@ -19,13 +21,18 @@ fighterBottomRightBack = NodePath("Fighters/RightBottomBack")
|
|||||||
fighterBottomRightFront = NodePath("Fighters/RightBottomFront")
|
fighterBottomRightFront = NodePath("Fighters/RightBottomFront")
|
||||||
metadata/_custom_type_script = "uid://dihfp05x6pktn"
|
metadata/_custom_type_script = "uid://dihfp05x6pktn"
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="."]
|
[node name="UI" type="Control" parent="."]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 0
|
anchors_preset = 15
|
||||||
offset_right = 40.0
|
anchor_right = 1.0
|
||||||
offset_bottom = 40.0
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="Control"]
|
[node name="ActionBox" parent="UI" instance=ExtResource("2_c3ndu")]
|
||||||
|
layout_mode = 1
|
||||||
|
|
||||||
|
[node name="Battle" type="Label" parent="UI"]
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
offset_right = 40.0
|
offset_right = 40.0
|
||||||
offset_bottom = 12.0
|
offset_bottom = 12.0
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ func _init(params:Dictionary) -> void:
|
|||||||
self.moveType = params.get("moveType", MoveType.PHYSICAL)
|
self.moveType = params.get("moveType", MoveType.PHYSICAL)
|
||||||
self.fieldUse = params.get("fieldUse", false)
|
self.fieldUse = params.get("fieldUse", false)
|
||||||
|
|
||||||
|
func start(_params:Dictionary) -> void:
|
||||||
|
# Implement move execution logic here
|
||||||
|
await UI.TEXTBOX.setTextAndWait("Action")
|
||||||
|
|
||||||
# Moves
|
# Moves
|
||||||
static var MOVE_PUNCH = BattleMove.new({
|
static var MOVE_PUNCH = BattleMove.new({
|
||||||
"name": "Punch",
|
"name": "Punch",
|
||||||
|
|||||||
1
battle/fighter/BattleMove.gd.uid
Normal file
1
battle/fighter/BattleMove.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://gb08hhwk0paw
|
||||||
26
battle/ui/ActionBox.gd
Normal file
26
battle/ui/ActionBox.gd
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class_name ActionBox extends GridContainer
|
||||||
|
const BattleMove = preload("res://battle/fighter/BattleMove.gd")
|
||||||
|
|
||||||
|
@export var btnAttack:Button
|
||||||
|
@export var btnMagic:Button
|
||||||
|
@export var btnItem:Button
|
||||||
|
|
||||||
|
signal decisionMade(move:BattleMove)
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
btnAttack.pressed.connect(onAttackPressed)
|
||||||
|
btnMagic.pressed.connect(onMagicPressed)
|
||||||
|
btnItem.pressed.connect(onItemPressed)
|
||||||
|
self.visible = false
|
||||||
|
|
||||||
|
func onAttackPressed() -> void:
|
||||||
|
print("Attack button pressed")
|
||||||
|
decisionMade.emit(null)
|
||||||
|
|
||||||
|
func onMagicPressed() -> void:
|
||||||
|
print("Magic button pressed")
|
||||||
|
decisionMade.emit(null)
|
||||||
|
|
||||||
|
func onItemPressed() -> void:
|
||||||
|
print("Item button pressed")
|
||||||
|
decisionMade.emit(null)
|
||||||
1
battle/ui/ActionBox.gd.uid
Normal file
1
battle/ui/ActionBox.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://27274005hbgh
|
||||||
36
battle/ui/ActionBox.tscn
Normal file
36
battle/ui/ActionBox.tscn
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://ktmvnapibv2q"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://27274005hbgh" path="res://battle/ui/ActionBox.gd" id="1_w5s71"]
|
||||||
|
|
||||||
|
[node name="ActionBox" type="GridContainer" node_paths=PackedStringArray("btnAttack", "btnMagic", "btnItem")]
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -86.0
|
||||||
|
offset_top = -44.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
columns = 2
|
||||||
|
script = ExtResource("1_w5s71")
|
||||||
|
btnAttack = NodePath("Attack")
|
||||||
|
btnMagic = NodePath("Magic")
|
||||||
|
btnItem = NodePath("Items")
|
||||||
|
metadata/_custom_type_script = "uid://27274005hbgh"
|
||||||
|
|
||||||
|
[node name="Attack" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Attack"
|
||||||
|
|
||||||
|
[node name="Magic" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Magic"
|
||||||
|
|
||||||
|
[node name="Items" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Items"
|
||||||
|
|
||||||
|
[node name="idk" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "idk"
|
||||||
@@ -1,25 +1,55 @@
|
|||||||
class_name CutsceneSingleton extends Node
|
class_name Cutscene
|
||||||
|
|
||||||
const CUTSCENE_CONTINUE = -1
|
const CUTSCENE_CONTINUE = -1
|
||||||
const CUTSCENE_END = -2
|
const CUTSCENE_END = -2
|
||||||
|
|
||||||
|
const CUTSCENE_ADD_END = -1
|
||||||
|
const CUTSCENE_ADD_NEXT = -2
|
||||||
|
|
||||||
var running:bool = false
|
var running:bool = false
|
||||||
|
var index:int = 0
|
||||||
|
var queue:Array[Dictionary] = []
|
||||||
|
|
||||||
func setConversation(conversation:Array[ConversationElement]) -> void:
|
# Accepts;
|
||||||
var functions:Array[Callable] = []
|
# function:Callable - The function to add
|
||||||
|
# position:int - Where to add the function (default: end)
|
||||||
|
# data:Dictionary - Data to pass to the function when called
|
||||||
|
func addCallable(params:Dictionary) -> int:
|
||||||
|
assert(params.has("function"))
|
||||||
|
|
||||||
|
if !params.has("position"):
|
||||||
|
params["position"] = CUTSCENE_ADD_END
|
||||||
|
|
||||||
|
params['cutscene'] = self
|
||||||
|
|
||||||
|
if params["position"] == CUTSCENE_ADD_END || params["position"] >= queue.size():
|
||||||
|
queue.append(params)
|
||||||
|
return queue.size() - 1
|
||||||
|
|
||||||
|
elif params["position"] == CUTSCENE_ADD_NEXT:
|
||||||
|
queue.insert(index + 1, params)
|
||||||
|
return index + 1
|
||||||
|
|
||||||
|
queue.insert(params["position"], params)
|
||||||
|
return params["position"]
|
||||||
|
|
||||||
|
|
||||||
|
func addConversation(conversation:Array[ConversationElement]) -> Array[int]:
|
||||||
|
var indexes:Array[int] = []
|
||||||
for element in conversation:
|
for element in conversation:
|
||||||
functions.append(element.sceneItem)
|
indexes.append(addCallable({ 'function': element.start }))
|
||||||
setScene(functions)
|
return indexes
|
||||||
|
|
||||||
func setScene(functions:Array[Callable]) -> void:
|
func start() -> void:
|
||||||
if functions.size() == 0:
|
if queue.size() == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
assert(!running)
|
||||||
running = true
|
running = true
|
||||||
|
index = 0
|
||||||
var index = 0
|
|
||||||
while true:
|
while true:
|
||||||
var result = await functions[index].call()
|
var queueItem = queue[index]
|
||||||
|
var result = await queueItem['function'].call(queueItem)
|
||||||
|
|
||||||
match result:
|
match result:
|
||||||
CUTSCENE_CONTINUE:
|
CUTSCENE_CONTINUE:
|
||||||
@@ -31,7 +61,7 @@ func setScene(functions:Array[Callable]) -> void:
|
|||||||
_:
|
_:
|
||||||
index = result
|
index = result
|
||||||
|
|
||||||
if index >= functions.size() || index < 0:
|
if index >= queue.size() || index < 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
running = false
|
running = false
|
||||||
|
|||||||
1
cutscene/CutsceneSingleton.gd
Normal file
1
cutscene/CutsceneSingleton.gd
Normal file
@@ -0,0 +1 @@
|
|||||||
|
class_name CutsceneSingleton extends Node
|
||||||
1
cutscene/CutsceneSingleton.gd.uid
Normal file
1
cutscene/CutsceneSingleton.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://dtq6p6mop3xfo
|
||||||
7
cutscene/battle/CutsceneBattleAction.gd
Normal file
7
cutscene/battle/CutsceneBattleAction.gd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class_name CutsceneBattleAction
|
||||||
|
|
||||||
|
static func playerDecision(_params:Dictionary) -> int:
|
||||||
|
BATTLE.battleScene.actionBox.visible = true
|
||||||
|
var move = await BATTLE.battleScene.actionBox.decisionMade
|
||||||
|
BATTLE.battleScene.actionBox.visible = false
|
||||||
|
return Cutscene.CUTSCENE_CONTINUE
|
||||||
1
cutscene/battle/CutsceneBattleAction.gd.uid
Normal file
1
cutscene/battle/CutsceneBattleAction.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://cj38yci04aylm
|
||||||
@@ -4,6 +4,6 @@ class_name ConversationElement
|
|||||||
@export_node_path("Entity") var entity:NodePath
|
@export_node_path("Entity") var entity:NodePath
|
||||||
@export_multiline var label: String
|
@export_multiline var label: String
|
||||||
|
|
||||||
func sceneItem() -> int:
|
func start(_params:Dictionary) -> int:
|
||||||
await UI.TEXTBOX.setTextAndWait(label)
|
await UI.TEXTBOX.setTextAndWait(label)
|
||||||
return CutsceneSingleton.CUTSCENE_CONTINUE
|
return Cutscene.CUTSCENE_CONTINUE
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ TRANSITION="*res://singleton/Transition.tscn"
|
|||||||
QUEST="*res://quest/Quest.tscn"
|
QUEST="*res://quest/Quest.tscn"
|
||||||
OVERWORLD="*res://overworld/Overworld.gd"
|
OVERWORLD="*res://overworld/Overworld.gd"
|
||||||
SCENE="*res://scene/Scene.gd"
|
SCENE="*res://scene/Scene.gd"
|
||||||
CUTSCENE="*res://cutscene/Cutscene.gd"
|
|
||||||
BATTLE="*res://battle/Battle.gd"
|
BATTLE="*res://battle/Battle.gd"
|
||||||
PARTY="*res://party/Party.gd"
|
PARTY="*res://party/Party.gd"
|
||||||
COOKING="*res://cooking/Cooking.gd"
|
COOKING="*res://cooking/Cooking.gd"
|
||||||
SAVE="*res://save/Save.gd"
|
SAVE="*res://save/Save.gd"
|
||||||
ControllerIcons="*res://addons/controller_icons/ControllerIcons.gd"
|
CUTSCENE="*res://cutscene/CutsceneSingleton.gd"
|
||||||
UI="*res://ui/UISingleton.gd"
|
UI="*res://ui/UISingleton.gd"
|
||||||
|
ControllerIcons="*res://addons/controller_icons/ControllerIcons.gd"
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ func onNewGamePressed() -> void:
|
|||||||
#OVERWORLD.mapChange(newGameScene, "PlayerSpawnPoint")
|
#OVERWORLD.mapChange(newGameScene, "PlayerSpawnPoint")
|
||||||
SCENE.setScene(SceneSingleton.SceneType.BATTLE)
|
SCENE.setScene(SceneSingleton.SceneType.BATTLE)
|
||||||
BATTLE.startBattle({
|
BATTLE.startBattle({
|
||||||
BattleScene.BattlePosition.LEFT_TOP_BACK: PartySingleton.PARTY_JOHN,
|
'fighters': {
|
||||||
|
BattleScene.BattlePosition.RIGHT_TOP_FRONT: PartySingleton.PARTY_JOHN,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
func onSettingsPressed() -> void:
|
func onSettingsPressed() -> void:
|
||||||
|
|||||||
Reference in New Issue
Block a user