Basic boss patterns

This commit is contained in:
Marco 2025-04-29 16:10:17 +02:00
commit d5eda3c7b4
15 changed files with 387 additions and 64 deletions

BIN
ExternalMaterial/RoboBoss/RoboBoss.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://p6cs703f5m3n"
path="res://.godot/imported/RoboBoss.png-f0fe8d2e5e22384032fb6bb9a9368471.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://ExternalMaterial/RoboBoss/RoboBoss.png"
dest_files=["res://.godot/imported/RoboBoss.png-f0fe8d2e5e22384032fb6bb9a9368471.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,145 @@
[gd_resource type="Resource" script_class="BossPhase" load_steps=14 format=3 uid="uid://go6rfnglefe8"]
[ext_resource type="Resource" uid="uid://bpc2kyft8q2qq" path="res://Resources/Bullets/simple_enemy_bullet_big.tres" id="1_favpk"]
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_36ba4"]
[ext_resource type="Script" uid="uid://c0ndqalsc4jve" path="res://Scripts/AttackPatterns/SpiralPattern.cs" id="3_agmbo"]
[ext_resource type="PackedScene" uid="uid://dohakkayqj4w2" path="res://Scenes/Weapons/Bullets/enemyBullet_green.tscn" id="4_agmbo"]
[ext_resource type="Script" uid="uid://cdd6q2h0t1hhq" path="res://Scripts/Resources/BossPhase.cs" id="4_tppsm"]
[ext_resource type="Script" uid="uid://dslyrfcej3g2n" path="res://Scripts/Resources/BulletResource.cs" id="5_tppsm"]
[ext_resource type="PackedScene" uid="uid://ck6f08w1fy5fa" path="res://Scenes/Weapons/Bullets/enemyBullet_rice_yellow.tscn" id="6_tppsm"]
[sub_resource type="Resource" id="Resource_n7vdy"]
script = ExtResource("3_agmbo")
BulletResource = ExtResource("1_favpk")
bulletCount = 16
rotationSpeed = 15.0
_rotationOffset = 0.0
duration = 0.5
spread = 360.0
burstInterval = 0.1
ShotsPerBurst = 4
BurstRate = 2.0
_targetPlayer = false
OverrideOwner = false
Owner = 0
OverrideDamageType = false
DamageType = 0
OverrideControllable = false
Controllable = false
OverrideCreationModifier = false
TimeModifiers = Array[ExtResource("2_36ba4")]([])
WaitForCompletion = true
metadata/_custom_type_script = "uid://c0ndqalsc4jve"
[sub_resource type="Resource" id="Resource_du806"]
script = ExtResource("5_tppsm")
BulletScene = ExtResource("4_agmbo")
BulletSpeed = 60.0
Direction = Vector2(1, 0)
BulletDamage = 12.0
LifeTime = 10.0
DestroyOnCollision = true
Owner = 2
DamageType = 0
RotateSprite = false
Controllable = false
Freezable = true
Grazeable = true
GrazeValue = 1.0
TimeModifiers = []
metadata/_custom_type_script = "uid://dslyrfcej3g2n"
[sub_resource type="Resource" id="Resource_hmrwn"]
script = ExtResource("3_agmbo")
BulletResource = SubResource("Resource_du806")
bulletCount = 8
rotationSpeed = 0.0
_rotationOffset = -90.0
duration = 2.0
spread = 128.0
burstInterval = 0.2
ShotsPerBurst = 4
BurstRate = 0.0
_targetPlayer = true
OverrideOwner = false
Owner = 0
OverrideDamageType = false
DamageType = 0
OverrideControllable = false
Controllable = false
OverrideCreationModifier = false
TimeModifiers = Array[ExtResource("2_36ba4")]([])
WaitForCompletion = true
metadata/_custom_type_script = "uid://c0ndqalsc4jve"
[sub_resource type="Resource" id="Resource_tppsm"]
script = ExtResource("3_agmbo")
BulletResource = ExtResource("1_favpk")
bulletCount = 16
rotationSpeed = -15.0
_rotationOffset = 0.0
duration = 0.5
spread = 360.0
burstInterval = 0.1
ShotsPerBurst = 4
BurstRate = 2.0
_targetPlayer = false
OverrideOwner = false
Owner = 0
OverrideDamageType = false
DamageType = 0
OverrideControllable = false
Controllable = false
OverrideCreationModifier = false
TimeModifiers = Array[ExtResource("2_36ba4")]([])
WaitForCompletion = true
metadata/_custom_type_script = "uid://c0ndqalsc4jve"
[sub_resource type="Resource" id="Resource_qhi1m"]
script = ExtResource("5_tppsm")
BulletScene = ExtResource("6_tppsm")
BulletSpeed = 80.0
Direction = Vector2(1, 0)
BulletDamage = 12.0
LifeTime = 10.0
DestroyOnCollision = true
Owner = 2
DamageType = 0
RotateSprite = true
Controllable = false
Freezable = true
Grazeable = true
GrazeValue = 1.0
TimeModifiers = null
metadata/_custom_type_script = "uid://dslyrfcej3g2n"
[sub_resource type="Resource" id="Resource_we0cr"]
script = ExtResource("3_agmbo")
BulletResource = SubResource("Resource_qhi1m")
bulletCount = 1
rotationSpeed = 0.0
_rotationOffset = 0.0
duration = 2.0
spread = 360.0
burstInterval = 0.2
ShotsPerBurst = 8
BurstRate = 1.0
_targetPlayer = true
OverrideOwner = false
Owner = 0
OverrideDamageType = false
DamageType = 0
OverrideControllable = false
Controllable = false
OverrideCreationModifier = false
TimeModifiers = Array[ExtResource("2_36ba4")]([])
WaitForCompletion = true
metadata/_custom_type_script = "uid://c0ndqalsc4jve"
[resource]
script = ExtResource("4_tppsm")
PhaseName = "Asdf"
Threshold = 0
PlayAnimation = false
Patterns = Array[Object]([SubResource("Resource_n7vdy"), SubResource("Resource_hmrwn"), SubResource("Resource_tppsm"), SubResource("Resource_we0cr")])
metadata/_custom_type_script = "uid://cdd6q2h0t1hhq"

View file

@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="BossScript" load_steps=4 format=3 uid="uid://umimlgb0hs7k"]
[ext_resource type="Script" uid="uid://cdd6q2h0t1hhq" path="res://Scripts/Resources/BossPhase.cs" id="1_2i700"]
[ext_resource type="Resource" uid="uid://go6rfnglefe8" path="res://Resources/BossPhases/Roguelite/Roguelite_Boss_1.tres" id="2_bv4fb"]
[ext_resource type="Script" uid="uid://inasa76li3ym" path="res://Scripts/Resources/ScriptableBullets/BossScript.cs" id="3_hj6ge"]
[resource]
script = ExtResource("3_hj6ge")
BossName = &"Test"
Phases = Array[ExtResource("1_2i700")]([ExtResource("2_bv4fb")])
metadata/_custom_type_script = "uid://inasa76li3ym"

View file

@ -58,7 +58,7 @@ metadata/_custom_type_script = "uid://rgx0g5iqksnn"
[sub_resource type="Resource" id="Resource_tsgja"]
script = ExtResource("11_eegnh")
Items = Array[Object]([ExtResource("1_ae3bb"), ExtResource("2_p3lfl"), ExtResource("3_tsgja"), ExtResource("4_qo6vk"), ExtResource("5_ga54h"), ExtResource("6_cxv74"), ExtResource("7_f7mru"), ExtResource("8_3kwn2"), ExtResource("9_to7mi"), ExtResource("10_w335g")])
Items = Array[Object]([ExtResource("1_ae3bb"), ExtResource("6_cxv74"), ExtResource("7_f7mru"), ExtResource("8_3kwn2"), ExtResource("9_to7mi"), ExtResource("10_w335g")])
metadata/_custom_type_script = "uid://rgx0g5iqksnn"
[sub_resource type="Resource" id="Resource_11cll"]

View file

@ -0,0 +1,98 @@
[gd_resource type="SpriteFrames" load_steps=9 format=3 uid="uid://crpuifbo5c7fd"]
[ext_resource type="Texture2D" uid="uid://xhwfgbv0fjbr" path="res://Sprites/Actors/FairyGuard.png" id="1_eijki"]
[ext_resource type="Texture2D" uid="uid://p6cs703f5m3n" path="res://ExternalMaterial/RoboBoss/RoboBoss.png" id="2_c65c5"]
[sub_resource type="AtlasTexture" id="AtlasTexture_em6qg"]
atlas = ExtResource("1_eijki")
region = Rect2(0, 64, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_klwxr"]
atlas = ExtResource("1_eijki")
region = Rect2(16, 64, 16, 16)
[sub_resource type="AtlasTexture" id="AtlasTexture_hakkv"]
atlas = ExtResource("2_c65c5")
region = Rect2(0, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_c65c5"]
atlas = ExtResource("2_c65c5")
region = Rect2(128, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_xmlxq"]
atlas = ExtResource("2_c65c5")
region = Rect2(384, 0, 64, 64)
[sub_resource type="AtlasTexture" id="AtlasTexture_68q7p"]
atlas = ExtResource("2_c65c5")
region = Rect2(256, 0, 64, 64)
[resource]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_klwxr")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_em6qg")
}],
"loop": true,
"name": &"dead",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_hakkv")
}],
"loop": true,
"name": &"down",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_c65c5")
}],
"loop": true,
"name": &"left",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_xmlxq")
}],
"loop": true,
"name": &"right",
"speed": 5.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_68q7p")
}],
"loop": true,
"name": &"up",
"speed": 5.0
}]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=46 format=3 uid="uid://dt7i3x3g5ktbl"]
[gd_scene load_steps=39 format=3 uid="uid://dt7i3x3g5ktbl"]
[ext_resource type="Script" uid="uid://bi2edpdosngll" path="res://Scripts/Components/FSM/Enemy/EnemyFSMProxy.cs" id="1_krhq1"]
[ext_resource type="Resource" uid="uid://ng3lpe8ifbsn" path="res://Resources/Enemies/Boss_1.tres" id="2_u32k8"]
@ -8,21 +8,17 @@
[ext_resource type="Script" uid="uid://dbmc3klko5x18" path="res://Scripts/Components/FSM/Enemy/Alert.cs" id="6_u32k8"]
[ext_resource type="Script" uid="uid://difn6d5np1pui" path="res://Scripts/Components/FSM/Boss/Shooting.cs" id="7_u32k8"]
[ext_resource type="Script" uid="uid://4hwtlc1ftjsc" path="res://Scripts/Components/FSM/Enemy/Dead.cs" id="8_3n0dy"]
[ext_resource type="Resource" uid="uid://bpc2kyft8q2qq" path="res://Resources/Bullets/simple_enemy_bullet_big.tres" id="8_xcri6"]
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="9_3n0dy"]
[ext_resource type="Resource" uid="uid://umimlgb0hs7k" path="res://Resources/BossPhases/Roguelite/Roguelite_Boss_1_Script.tres" id="8_q8sxg"]
[ext_resource type="Script" uid="uid://dj37rup1ibnn6" path="res://Scripts/Components/FSM/Enemy/Controlled.cs" id="9_d5ed4"]
[ext_resource type="Script" uid="uid://c0ndqalsc4jve" path="res://Scripts/AttackPatterns/SpiralPattern.cs" id="10_d5ed4"]
[ext_resource type="SpriteFrames" uid="uid://ch2ll1on8im2p" path="res://Resources/Sprites/FairyGuard.tres" id="10_v2gvi"]
[ext_resource type="Script" uid="uid://mb4ugq74a17c" path="res://Scripts/Components/FSM/Enemy/PlayerDetectionModule.cs" id="11_qrag5"]
[ext_resource type="Script" uid="uid://cdd6q2h0t1hhq" path="res://Scripts/Resources/BossPhase.cs" id="11_v2gvi"]
[ext_resource type="Script" uid="uid://bflvr26h52c55" path="res://Scripts/Components/FSM/Enemy/EnemyStorageModule.cs" id="12_n7vdy"]
[ext_resource type="Script" uid="uid://inasa76li3ym" path="res://Scripts/Resources/ScriptableBullets/BossScript.cs" id="12_qrag5"]
[ext_resource type="Script" uid="uid://c6467d6yx50qh" path="res://Scripts/Components/BulletSpawner.cs" id="13_3n0dy"]
[ext_resource type="Script" uid="uid://cq3hkweplldbr" path="res://Scripts/Components/Actors/GenericDamageReceiver.cs" id="13_uiuc5"]
[ext_resource type="PackedScene" uid="uid://cuixq5ex0j40h" path="res://Scenes/enemyBullet.tscn" id="14_d5ed4"]
[ext_resource type="PackedScene" uid="uid://cm564ue740cpx" path="res://Scenes/Actors/DeadFairyGuard.tscn" id="14_k00rh"]
[ext_resource type="Script" uid="uid://cqwvssstkrdmw" path="res://Scripts/Components/Actors/ActorResourceProvider.cs" id="15_fumcm"]
[ext_resource type="Script" uid="uid://ik7s65de723k" path="res://Scripts/Components/FSM/Enemy/NavigationMovementModule.cs" id="16_v7pqc"]
[ext_resource type="SpriteFrames" uid="uid://crpuifbo5c7fd" path="res://Resources/Sprites/RoboBoss.tres" id="17_3n0dy"]
[ext_resource type="PackedScene" uid="uid://cj63k0dmk7tl1" path="res://Scenes/Weapons/enemy_weapon_base.tscn" id="17_o816w"]
[ext_resource type="Resource" uid="uid://csdlihliv4cr8" path="res://Resources/Weapons/EnemyWeapon_simple.tres" id="18_jdgrw"]
[ext_resource type="Script" uid="uid://dhsqsajq537qn" path="res://Scripts/Components/FSM/Enemy/EnemyAlarmModule.cs" id="19_ka71q"]
@ -36,49 +32,13 @@
[ext_resource type="Texture2D" uid="uid://cf2855sd3hqty" path="res://Sprites/Actors/Aiming_Reticule_Small.png" id="27_8kytv"]
[sub_resource type="CircleShape2D" id="CircleShape2D_pnkma"]
[sub_resource type="Resource" id="Resource_n7vdy"]
script = ExtResource("10_d5ed4")
BulletResource = ExtResource("8_xcri6")
bulletCount = 16
rotationSpeed = 0.0
_rotationOffset = 0.0
duration = 5.0
spread = 360.0
burstInterval = 0.5
ShotsPerBurst = 100
BurstRate = 0.0
_targetPlayer = false
OverrideOwner = false
Owner = 0
OverrideDamageType = false
DamageType = 0
OverrideControllable = false
Controllable = false
OverrideCreationModifier = false
TimeModifiers = Array[ExtResource("9_3n0dy")]([])
WaitForCompletion = true
metadata/_custom_type_script = "uid://c0ndqalsc4jve"
[sub_resource type="Resource" id="Resource_uiuc5"]
script = ExtResource("11_v2gvi")
PhaseName = "Asdf"
Threshold = 0
PlayAnimation = false
Patterns = Array[Object]([SubResource("Resource_n7vdy")])
metadata/_custom_type_script = "uid://cdd6q2h0t1hhq"
[sub_resource type="Resource" id="Resource_k00rh"]
script = ExtResource("12_qrag5")
BossName = &"Test"
Phases = Array[ExtResource("11_v2gvi")]([SubResource("Resource_uiuc5")])
metadata/_custom_type_script = "uid://inasa76li3ym"
radius = 23.0217
[sub_resource type="CircleShape2D" id="CircleShape2D_5wstg"]
radius = 29.0
radius = 92.0054
[sub_resource type="CircleShape2D" id="CircleShape2D_6x22m"]
radius = 5.0
radius = 24.0156
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_poxpj"]
particle_flag_disable_z = true
@ -156,7 +116,7 @@ script = ExtResource("7_u32k8")
DamageReceiver = NodePath("../../DamageReceiver")
EquippedWeapon = NodePath("../../EnemyWeapon")
StorageModule = NodePath("../../Storage")
BossScript = SubResource("Resource_k00rh")
BossScript = ExtResource("8_q8sxg")
_moduleNodes = [NodePath("../../AnimationModule")]
[node name="BulletSpawner" type="Node2D" parent="StateMachine/Shooting"]
@ -178,10 +138,11 @@ EquippedWeapon = NodePath("../../EnemyWeapon")
_moduleNodes = [NodePath("../../AnimationModule")]
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
sprite_frames = ExtResource("10_v2gvi")
animation = &"right"
sprite_frames = ExtResource("17_3n0dy")
animation = &"down"
[node name="PlayerDetection" type="Area2D" parent="."]
visible = false
collision_layer = 0
collision_mask = 2
script = ExtResource("11_qrag5")
@ -263,6 +224,7 @@ sprite_frames = SubResource("SpriteFrames_wafqr")
script = ExtResource("25_8rqch")
[node name="CrosshairProvider" type="Node2D" parent="." node_paths=PackedStringArray("AnimatedSprite")]
visible = false
script = ExtResource("26_q2yik")
AnimatedSprite = NodePath("Crosshair")
CrosshairDistance = 35.0

View file

@ -15,10 +15,11 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u3c1h"]
size = Vector2(272, 85)
[node name="Tilemaps" type="Node2D"]
[node name="Tilemaps" type="Node2D" node_paths=PackedStringArray("RoomClearActivation")]
process_mode = 1
script = ExtResource("1_vhsym")
RoomResource = ExtResource("2_vhsym")
RoomClearActivation = []
metadata/test_scene = "res://Scenes/Maps/Roguelike.tscn"
[node name="Floor" type="TileMapLayer" parent="." node_paths=PackedStringArray("_solidLayers") groups=["Solid"]]

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=15 format=4 uid="uid://b7oa5icmcetwj"]
[gd_scene load_steps=16 format=4 uid="uid://b7oa5icmcetwj"]
[ext_resource type="Script" uid="uid://b2j00riayxkit" path="res://Scripts/Controllers/RogueliteRoom.cs" id="1_84eqy"]
[ext_resource type="Resource" uid="uid://b8lpo4im87rx7" path="res://Resources/RogueliteMaps/Long_Factory.tres" id="2_k6121"]
@ -8,6 +8,7 @@
[ext_resource type="PackedScene" uid="uid://dcbcyp1qogcl0" path="res://Scenes/Props/BigTankHorizontal.tscn" id="6_rse1i"]
[ext_resource type="Script" uid="uid://8umfjejbkcsm" path="res://Scripts/Actors/RogueliteEnemySpawner.cs" id="6_x05mq"]
[ext_resource type="Resource" uid="uid://qbo6avc7x64b" path="res://Resources/Enemies/Fairy_Guard.tres" id="7_agp2x"]
[ext_resource type="PackedScene" uid="uid://dux8pv1y8wkt0" path="res://Scenes/Props/Capacitor.tscn" id="7_jw5yi"]
[ext_resource type="Resource" uid="uid://cqfyuurvqb8m6" path="res://Resources/Enemies/Base_Fairy_Special.tres" id="8_agp2x"]
[ext_resource type="Script" uid="uid://umyqgyxjiaig" path="res://Scripts/Actors/ChestMarker.cs" id="10_3vkr4"]
[ext_resource type="Texture2D" uid="uid://qeh4ai8h6sw5" path="res://Sprites/Chest.png" id="11_oc0wb"]
@ -66,6 +67,12 @@ position = Vector2(31, 49)
[node name="BigTankHorizontal2" parent="Tilemaps/Actors" instance=ExtResource("6_rse1i")]
position = Vector2(65, 48)
[node name="Capacitor" parent="Tilemaps/Actors" node_paths=PackedStringArray("Target") instance=ExtResource("7_jw5yi")]
position = Vector2(296, 55)
Health = 6.0
ActivationType = 2
Target = NodePath("../HorizontalForceField")
[node name="EnemySpawners" type="Node2D" parent="."]
[node name="RogueliteEnemySpawner4" type="Marker2D" parent="EnemySpawners"]

View file

@ -62,6 +62,7 @@ public partial class RogueliteEnemySpawner : Marker2D
Item = mapTheme.EnemiesLootTable.Items.ToList().Shuffle().First(),
Chance = mapTheme.EnemyDropChance
});
_spawnedEnemy.ExtraLoot.Add(new LootDrop()
{
Item = mapTheme.PointItemResource,

View file

@ -0,0 +1,58 @@
using Cirno.Scripts.Actors;
using Cirno.Scripts.AttackPatterns;
using Godot;
namespace Cirno.Scripts.Resources;
[GlobalClass]
public partial class FSMMovementPattern : AttackPattern
{
[Export] private Vector2 relativeTargetPosition;
[Export] private float moveDuration = 2f;
[Export] private Tween.TransitionType transitionType = Tween.TransitionType.Linear;
[Export] private Tween.EaseType easeType = Tween.EaseType.InOut;
public override IPatternMachine MakeMachine(Node2D parent)
{
return new FSMMovementPatternMachine(this, parent);
}
public class FSMMovementPatternMachine(FSMMovementPattern pattern, Node2D parent) : IPatternMachine
{
public Node2D Parent => parent;
private Tween tween;
private bool isComplete = false;
protected IScriptHost Boss;
public void Start()
{
if (parent is not IScriptHost boss)
return;
Boss = boss;
tween = Parent.CreateTween();
isComplete = false;
Vector2 targetPosition = (Boss?.HomePosition ?? Parent.GlobalPosition) + pattern.relativeTargetPosition;
boss.ChangeSpriteDirection(-(Parent.GlobalPosition - targetPosition));
tween.TweenProperty(Parent, "global_position", targetPosition, pattern.moveDuration)
.SetTrans(pattern.transitionType)
.SetEase(pattern.easeType)
.Finished += () =>
{
isComplete = true;
boss.ChangeSpriteDirection(Vector2.Zero);
};
}
public void UpdatePattern(double delta) { }
public bool IsComplete()
{
return isComplete;
}
}
}

View file

@ -0,0 +1 @@
uid://bj3v4rlov86gw