Skip to content

Commit 3e9ae19

Browse files
authored
Merge pull request #29 from OctoD/feat/AttributeContainer-virtual-methods
feat: handles manual ticking
2 parents 371cf48 + 85fb34d commit 3e9ae19

11 files changed

Lines changed: 318 additions & 43 deletions

doc_classes/AttributeContainer.xml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@
7474
Gets all attributes.
7575
</description>
7676
</method>
77+
<method name="get_manual_ticking" qualifiers="const">
78+
<return type="bool"/>
79+
<description>
80+
Returns the `manual_ticking` flag
81+
</description>
82+
</method>
7783
<method name="remove_attribute">
7884
<return type="void" />
7985
<param index="0" name="p_attribute" type="AttributeBase" />
@@ -94,15 +100,28 @@
94100
Sets up the container. Call this programmatically in case the [method _ready] method is not called.
95101
</description>
96102
</method>
103+
<method name="set_manual_ticking">
104+
<return type="void" />
105+
<param index="0" name="p_manual_ticking" type="bool" />
106+
<description>
107+
Sets the [manual_ticking] bool.
108+
</description>
109+
</method>
110+
<method name="subtract_attribute_buffs_ticks">
111+
<return type="void" />
112+
<param index="0" name="p_tick" type="float" />
113+
<description>
114+
Subtracts the passed p_tick value to all timed transient [AttributeBuff] instances durations in the container.
115+
Ideal for turn-based games or to handle programmatic resets/updates.
116+
</description>
117+
</method>
97118
</methods>
98119
<members>
99120
<member name="attribute_set" type="AttributeSet" setter="set_attribute_set" getter="get_attribute_set">
100121
The set of attributes.
101122
</member>
102-
<member name="server_authoritative" type="bool" setter="set_server_authoritative" getter="get_server_authoritative" default="false">
103-
If [code]true[/code], the server is authoritative for the attribute values.
104-
It means that only the server can change the attribute values.
105-
[b]Note:[/b] It's still experimental, expect bugs.
123+
<member name="manual_ticking" type="bool" setter="set_manual_ticking" getter="get_manual_ticking">
124+
If set to true, every [AttributeBuff] duration is going to be handled by you.
106125
</member>
107126
</members>
108127
<signals>

docs/classes/AttributeContainer.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ You can place this node wherever you want in your scene tree.
1414
## Members
1515

1616
- `attribute_set`: The attribute set used to store the attributes.
17+
- `manual_ticking`: If set to true, `AttributeBuff` duration is going to be handled by you.
1718

1819
## Signals
1920

@@ -41,5 +42,6 @@ This function accepts a `Callable`, a `String` or an `AttributeBuff` as a parame
4142
- `remove_attribute`: removes an [`Attribute`](Attribute.md) from the attribute container. This also will remove the `RuntimeAttribute` from the container.
4243
- `remove_buff`: removes an [`AttributeBuff`](AttributeBuff.md) from the attribute container.
4344
- `setup`: sets up the attribute container. This will create the `RuntimeAttribute` for each attribute in the attribute set.
45+
- `set_tick`: Sets the tick manually. The value passed is subtracted from transient AttributeBuff durations
4446

4547
[Back to classes](README.md)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Turn based attribute buffs
2+
==========================
3+
4+
> This is straightforward.
5+
6+
To handle turn-based buffs, you need two things:
7+
8+
- You have to mark your `AttributeBuff` as `transient` and give it an integer `duration`.
9+
- You have to activate the `AttributeContainer` `manual_ticking` flag to `true`.
10+
11+
When you apply an `AttributeBuff`, the time left for the buff will not be altered in any way until you will call `AttributeContainer.set_tick()`.
12+
13+
`AttributeContainer.set_tick()` will then decrement the `duration` of all `AttributeBuff`s that have a `duration` greater than `0` by the specified `tick` value.
14+
15+
You can refer to this example to see this in action:
16+
17+
[manual_ticking](../../godot/examples/manual_ticking)

godot/examples/main.tscn

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[gd_scene load_steps=8 format=3 uid="uid://cr6c1qrsan6ay"]
1+
[gd_scene load_steps=9 format=3 uid="uid://cr6c1qrsan6ay"]
22

33
[ext_resource type="Script" uid="uid://ceg6sbsaa5b6f" path="res://examples/main.gd" id="1_26gv5"]
44
[ext_resource type="PackedScene" uid="uid://cp2wvvpx0rprl" path="res://examples/attributes_initialization/attributes_initialization.tscn" id="2_oe2cu"]
@@ -7,6 +7,7 @@
77
[ext_resource type="PackedScene" uid="uid://b3bcwisw4ppdi" path="res://examples/attribute_buff_stacking_example/attribute_buff_stacking_example.tscn" id="5_w7hkg"]
88
[ext_resource type="PackedScene" uid="uid://curqgkv32cxfw" path="res://examples/attribute_buff_queue_execution/attribute_buff_queue_execution.tscn" id="6_xyviw"]
99
[ext_resource type="PackedScene" uid="uid://c0gv10tax7leh" path="res://examples/transient_buff_execution_order/transient_buff_execution_order.tscn" id="7_plcr4"]
10+
[ext_resource type="PackedScene" uid="uid://d0gy5xejuwvvm" path="res://examples/manual_ticking/manual_ticking.tscn" id="8_avhjo"]
1011

1112
[node name="Main" type="VBoxContainer"]
1213
anchors_preset = 15
@@ -15,7 +16,7 @@ anchor_bottom = 1.0
1516
grow_horizontal = 2
1617
grow_vertical = 2
1718
script = ExtResource("1_26gv5")
18-
examples = Array[PackedScene]([ExtResource("2_oe2cu"), ExtResource("3_pw243"), ExtResource("4_pw243"), ExtResource("5_w7hkg"), ExtResource("6_xyviw"), ExtResource("7_plcr4")])
19+
examples = Array[PackedScene]([ExtResource("2_oe2cu"), ExtResource("3_pw243"), ExtResource("4_pw243"), ExtResource("5_w7hkg"), ExtResource("6_xyviw"), ExtResource("7_plcr4"), ExtResource("8_avhjo")])
1920

2021
[node name="Toolbar" type="HBoxContainer" parent="."]
2122
unique_name_in_owner = true
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
extends Control
2+
3+
const ManualTickingBuffLabel = preload("uid://c1g42dnwl5xxp")
4+
const TEST_ATTRIBUTE_NAME := LevelAttribute.ATTRIBUTE_NAME
5+
6+
7+
@onready var apply_buff_button: Button = %ApplyBuffButton
8+
@onready var attribute_container: AttributeContainer = $AttributeContainer
9+
@onready var attribute_value_label: Label = %AttributeValueLabel
10+
@onready var buffs_v_box_container: VBoxContainer = %BuffsVBoxContainer
11+
@onready var end_turn_button: Button = %EndTurnButton
12+
@onready var turn_duration_spin_box: SpinBox = %TurnDurationSpinBox
13+
14+
15+
func _ready() -> void:
16+
attribute_container.apply_buff(InitializeAttributes.new())
17+
18+
attribute_container.buff_applied.connect(func (runtime_buff: RuntimeBuff):
19+
var buff_label := ManualTickingBuffLabel.new()
20+
21+
buff_label.runtime_buff = runtime_buff
22+
23+
buffs_v_box_container.add_child(buff_label)
24+
25+
update_attribute_value_label()
26+
)
27+
28+
attribute_container.buff_time_elapsed.connect(func (_runtime_buff):
29+
for child in buffs_v_box_container.get_children():
30+
child.draw()
31+
)
32+
33+
attribute_container.buff_removed.connect(func (runtime_buff: RuntimeBuff):
34+
for child in buffs_v_box_container.get_children():
35+
if child.runtime_buff == runtime_buff:
36+
child.queue_free()
37+
)
38+
39+
apply_buff_button.pressed.connect(func ():
40+
var buff := TheBuff.new()
41+
buff.duration = turn_duration_spin_box.value
42+
attribute_container.apply_buff(buff)
43+
)
44+
45+
end_turn_button.pressed.connect(end_turn)
46+
47+
update_attribute_value_label()
48+
49+
50+
func end_turn() -> void:
51+
attribute_container.set_tick(1.0)
52+
53+
54+
func update_attribute_value_label() -> void:
55+
attribute_value_label.text = TEST_ATTRIBUTE_NAME + " " + String.num(attribute_container.get_attribute_buffed_value_by_name(TEST_ATTRIBUTE_NAME), 0)
56+
57+
58+
class TheBuff extends AttributeBuff:
59+
func _init() -> void:
60+
attribute_name = TEST_ATTRIBUTE_NAME # that's just for the sake of the example
61+
buff_name = "Turn based buff"
62+
duration = 3.0 # the default number of turns
63+
operation = AttributeOperation.add(1.0)
64+
transient = true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://4ufnt4uh87di
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
[gd_scene load_steps=3 format=3 uid="uid://d0gy5xejuwvvm"]
2+
3+
[ext_resource type="Script" uid="uid://4ufnt4uh87di" path="res://examples/manual_ticking/manual_ticking.gd" id="1_trv3u"]
4+
[ext_resource type="AttributeSet" uid="uid://bwhjuw1lmci26" path="res://examples/diablo_like_stats_panel/diablo_like_stats_panel_attribute_set.tres" id="2_6xsa1"]
5+
6+
[node name="ManualTicking" type="Control"]
7+
layout_mode = 3
8+
anchors_preset = 15
9+
anchor_right = 1.0
10+
anchor_bottom = 1.0
11+
grow_horizontal = 2
12+
grow_vertical = 2
13+
script = ExtResource("1_trv3u")
14+
15+
[node name="VBoxContainer" type="VBoxContainer" parent="."]
16+
layout_mode = 1
17+
anchors_preset = 8
18+
anchor_left = 0.5
19+
anchor_top = 0.5
20+
anchor_right = 0.5
21+
anchor_bottom = 0.5
22+
offset_left = -20.0
23+
offset_top = -20.0
24+
offset_right = 20.0
25+
offset_bottom = 20.0
26+
grow_horizontal = 2
27+
grow_vertical = 2
28+
29+
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
30+
custom_minimum_size = Vector2(480, 0)
31+
layout_mode = 2
32+
33+
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer"]
34+
layout_mode = 2
35+
size_flags_horizontal = 3
36+
37+
[node name="AttributeValueLabel" type="Label" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
38+
unique_name_in_owner = true
39+
layout_mode = 2
40+
text = "Attribute value {0}"
41+
42+
[node name="BuffsAppliedLabel" type="Label" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
43+
layout_mode = 2
44+
text = "Buffs applied"
45+
46+
[node name="BuffsVBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
47+
unique_name_in_owner = true
48+
custom_minimum_size = Vector2(0, 300)
49+
layout_mode = 2
50+
51+
[node name="TurnControlVBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer"]
52+
layout_mode = 2
53+
size_flags_horizontal = 3
54+
theme_override_constants/separation = 32
55+
56+
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer/TurnControlVBoxContainer"]
57+
layout_mode = 2
58+
59+
[node name="TurnDurationSpinBox" type="SpinBox" parent="VBoxContainer/HBoxContainer/TurnControlVBoxContainer/HBoxContainer"]
60+
unique_name_in_owner = true
61+
layout_mode = 2
62+
size_flags_horizontal = 3
63+
alignment = 2
64+
suffix = "turns"
65+
66+
[node name="ApplyBuffButton" type="Button" parent="VBoxContainer/HBoxContainer/TurnControlVBoxContainer/HBoxContainer"]
67+
unique_name_in_owner = true
68+
layout_mode = 2
69+
size_flags_horizontal = 3
70+
text = "Apply buff"
71+
72+
[node name="EndTurnButton" type="Button" parent="VBoxContainer/HBoxContainer/TurnControlVBoxContainer"]
73+
unique_name_in_owner = true
74+
layout_mode = 2
75+
text = "End turn"
76+
77+
[node name="AttributeContainer" type="AttributeContainer" parent="."]
78+
attribute_set = ExtResource("2_6xsa1")
79+
manual_ticking = true
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
extends Label
2+
3+
4+
var runtime_buff: RuntimeBuff = null
5+
6+
7+
func _ready() -> void:
8+
draw()
9+
10+
11+
func draw() -> void:
12+
if runtime_buff:
13+
text = runtime_buff.buff.buff_name + " (will expire in " + String.num(runtime_buff.get_time_left(), 0) + " turns)"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://c1g42dnwl5xxp

0 commit comments

Comments
 (0)