Godot Version
v4.4.1.stable.official
Question
`I am making a battle scene (somewhat similar to a pokemon battle), and I have made the action category buttons (options/actions) just fine. I made a class containing the sub action information, and I tried looping through a dictionary to instance the buttons. In that loop it shows the error:
Invalid access to property or key ‘Counterpoint’ on a base object of type ‘Dictionary’
This error shows up on line 40 of battle_options.gd (for sub_option in sub_options[action])
I’ll provide the code below (sorry if it’s confusing, I really should’ve commented while making this project)
I appreciate any help!`
sub_action_data.gd
extends Resource
class_name SubActionData
@export_category("SubActionInfo")
@export var name : String
@export var target : String
@export var amount : int
func _init(sub_name:String, sub_target:String, sub_amount:int):
name = sub_name
target = sub_target
amount = sub_amount
action_data.gd
extends Resource
class_name ActionData
@export_category("Actions")
@export var actions : Array = [
"Logic",
"Entertain",
"Appeal",
"Pursuade"
]
#logic attacks the opponents argument
#entertain "attacks" the opponents audience
#appeal boosts entertain actions
#pursuade boosts logic actions
@export var sub_actions : Dictionary = {
"Logic" = {
"Counterpoint" = SubActionData.new("Counterpoint", "Argument", 10)
},
"Entertain" = {
"Ad Hominem" = SubActionData.new("Ad Hominem", "Audience", 10)
},
"Appeal" = {
"Straight Face" = SubActionData.new("Straight Face", "Entertain", 2)
},
"Pursuade" = {
"Analyze" = SubActionData.new("Analyze", "Logic", 2)
}
}
battle_options.gd
extends Control
@export_category('Options')
@export var options : Array
@export var sub_options : Dictionary
@onready var option_nodes : Dictionary
@onready var sub_option_nodes : Dictionary
var option_button_scene = preload("res://battle_screen/battle_option_button.tscn")
@onready var option_container = $OptionContainer/VBoxContainer
@onready var sub_option_container = $SubOptionContainer/VBoxContainer
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func set_options():
for option in options:
option_container.add_child(option_button_scene.instantiate())
var new_option = $OptionContainer/VBoxContainer/BattleOptionButton
new_option.name = str(option)
option_nodes[option] = new_option
new_option.text = option
new_option.pressed.connect(_on_option_pressed(option))
func set_sub_options(action:String):
for child in sub_option_container.get_children():
sub_option_container.remove_child(child)
child.queue_free()
sub_option_nodes.clear()
for sub_option in sub_options[action]:
var sub_option_name = sub_options[action][sub_option].name
sub_option_container.add_child(option_button_scene.instantiate())
var new_sub_option = $SubOptionContainer/VBoxContainer/BattleOptionButton
new_sub_option.name = sub_option_name
sub_option_nodes[sub_option] = new_sub_option
new_sub_option.text = sub_option_name
new_sub_option.pressed.connect(_on_option_pressed(sub_option_name))
func _on_option_pressed(option_name:String):
set_sub_options(option_name)
func _on_sub_option_pressed(sub_option_name:String):
pass
battle_screen.gd
extends Control
@onready var battle_options = get_node("BattleOptions")
var enemy_state : Dictionary = {
'talking' = load('res://art_work/enemy/enemy-talking.png')
}
var enemy : Dictionary = {
'enemy' = enemy_state
}
@export_category('BattleInfo')
@export var current_enemy : String = 'enemy'
@export var current_state : String = 'talking'
@export_category("ActionInfo")
@export var action_info = preload("res://resources/action_resources/action_data.gd").new()
# Called when the node enters the scene tree for the first time.
func _ready():
change_enemy_state()
set_battle_options()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
pass
func change_enemy_state():
$EnemySprite.texture = enemy[current_enemy][current_state]
func set_battle_options():
battle_options.options = action_info.actions
battle_options.sub_options = action_info.sub_actions
battle_options.set_options()
func set_sub_options():
pass