Appearance sets
This commit is contained in:
BIN
assets/sprites/CP002AB.BMP
Normal file
BIN
assets/sprites/CP002AB.BMP
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
40
assets/sprites/CP002AB.BMP.import
Normal file
40
assets/sprites/CP002AB.BMP.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b6smsdyydtiv4"
|
||||
path="res://.godot/imported/CP002AB.BMP-83c77e61ea705a94bd90d268ad08d826.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/sprites/CP002AB.BMP"
|
||||
dest_files=["res://.godot/imported/CP002AB.BMP-83c77e61ea705a94bd90d268ad08d826.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
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/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
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
|
||||
71
export_presets.cfg
Normal file
71
export_presets.cfg
Normal file
@@ -0,0 +1,71 @@
|
||||
[preset.0]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
patches=PackedStringArray()
|
||||
patch_delta_encoding=false
|
||||
patch_delta_compression_level_zstd=19
|
||||
patch_delta_min_reduction=0.1
|
||||
patch_delta_include_filters="*"
|
||||
patch_delta_exclude_filters=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
seed=0
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
debug/export_console_wrapper=1
|
||||
binary_format/embed_pck=false
|
||||
texture_format/s3tc_bptc=true
|
||||
texture_format/etc2_astc=false
|
||||
shader_baker/enabled=false
|
||||
binary_format/architecture="x86_64"
|
||||
codesign/enable=false
|
||||
codesign/timestamp=true
|
||||
codesign/timestamp_server_url=""
|
||||
codesign/digest_algorithm=1
|
||||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon=""
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=4
|
||||
application/file_version=""
|
||||
application/product_version=""
|
||||
application/company_name=""
|
||||
application/product_name=""
|
||||
application/file_description=""
|
||||
application/copyright=""
|
||||
application/trademarks=""
|
||||
application/export_angle=0
|
||||
application/export_d3d12=0
|
||||
application/d3d12_agility_sdk_multiarch=true
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
ssh_remote_deploy/port="22"
|
||||
ssh_remote_deploy/extra_args_ssh=""
|
||||
ssh_remote_deploy/extra_args_scp=""
|
||||
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
|
||||
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
|
||||
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
|
||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
|
||||
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
|
||||
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
|
||||
Start-ScheduledTask -TaskName godot_remote_debug
|
||||
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
|
||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||
@@ -3,8 +3,6 @@
|
||||
[ext_resource type="Script" uid="uid://cmh4lphvboggy" path="res://scripts/battle/deployed_units/deployed_unit.gd" id="1_cq4v0"]
|
||||
[ext_resource type="Texture2D" uid="uid://cw5su6lignryo" path="res://assets/sprites/flag.png" id="2_fhs1y"]
|
||||
[ext_resource type="Shader" uid="uid://bd8ki8xwym5nc" path="res://shaders/chroma_key.gdshader" id="3_fhs1y"]
|
||||
[ext_resource type="Texture2D" uid="uid://dyutp4m5d53gd" path="res://assets/sprites/CP002AA.BMP" id="3_on614"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_on614"]
|
||||
resource_name = "UnitSelectorHandler"
|
||||
script/source = "extends ColorRect
|
||||
@@ -27,42 +25,6 @@ shader = ExtResource("3_fhs1y")
|
||||
shader_parameter/key_color = Color(0, 1, 0, 1)
|
||||
shader_parameter/threshold = 0.01
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fhs1y"]
|
||||
atlas = ExtResource("3_on614")
|
||||
region = Rect2(0, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_4j20j"]
|
||||
atlas = ExtResource("3_on614")
|
||||
region = Rect2(40, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_v0xod"]
|
||||
atlas = ExtResource("3_on614")
|
||||
region = Rect2(0, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_50p1h"]
|
||||
atlas = ExtResource("3_on614")
|
||||
region = Rect2(40, 50, 40, 50)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_7jqdg"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fhs1y")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_4j20j")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_v0xod")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_50p1h")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"idle",
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="DeployedUnit" type="Node2D" unique_id=1893234933 groups=["deployed_units"]]
|
||||
script = ExtResource("1_cq4v0")
|
||||
metadata/_custom_type_script = "uid://cmh4lphvboggy"
|
||||
@@ -83,9 +45,6 @@ script = SubResource("GDScript_fhs1y")
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1796991032]
|
||||
material = SubResource("ShaderMaterial_fhs1y")
|
||||
position = Vector2(50, 50)
|
||||
sprite_frames = SubResource("SpriteFrames_7jqdg")
|
||||
animation = &"idle"
|
||||
autoplay = "idle"
|
||||
|
||||
[connection signal="unit_allegiance_changed" from="." to="AllegianceIndicator" method="_on_unit_unit_allegiance_changed"]
|
||||
[connection signal="unit_selected_changed" from="." to="SelectionIndicator" method="_unit_selected_changed"]
|
||||
|
||||
178
resources/units/appearance_sets/lily_child_deployed.tres
Normal file
178
resources/units/appearance_sets/lily_child_deployed.tres
Normal file
@@ -0,0 +1,178 @@
|
||||
[gd_resource type="Resource" script_class="UnitAppearanceSet" format=3 uid="uid://c18djmm6orf5y"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://divxkbo321ql" path="res://scripts/units/unit_appearance_set.gd" id="1_am7go"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6smsdyydtiv4" path="res://assets/sprites/CP002AB.BMP" id="1_cdqv0"]
|
||||
[ext_resource type="Texture2D" uid="uid://dyutp4m5d53gd" path="res://assets/sprites/CP002AA.BMP" id="2_3pgcd"]
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_4hgk0"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(0, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_scnul"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(40, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ec51f"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(80, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ix7mx"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(120, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_su6vo"]
|
||||
atlas = ExtResource("2_3pgcd")
|
||||
region = Rect2(0, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_6idlb"]
|
||||
atlas = ExtResource("2_3pgcd")
|
||||
region = Rect2(40, 0, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ui8f1"]
|
||||
atlas = ExtResource("2_3pgcd")
|
||||
region = Rect2(0, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_wk1hp"]
|
||||
atlas = ExtResource("2_3pgcd")
|
||||
region = Rect2(40, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_p4e4i"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(0, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_knbtp"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(40, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ni45v"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(80, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_a51r0"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(120, 50, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_pvxdl"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(0, 150, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_qle0x"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(40, 150, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_iork5"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(80, 150, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hbqxy"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(120, 150, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_e4j68"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(0, 100, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_n1qde"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(40, 100, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_de2lv"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(80, 100, 40, 50)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1nls0"]
|
||||
atlas = ExtResource("1_cdqv0")
|
||||
region = Rect2(120, 100, 40, 50)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_psufo"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_4hgk0")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_scnul")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ec51f")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ix7mx")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"down",
|
||||
"speed": 8.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_su6vo")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_6idlb")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ui8f1")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_wk1hp")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"idle",
|
||||
"speed": 8.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_p4e4i")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_knbtp")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ni45v")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_a51r0")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"left",
|
||||
"speed": 8.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_pvxdl")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_qle0x")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_iork5")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_hbqxy")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"right",
|
||||
"speed": 8.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_e4j68")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_n1qde")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_de2lv")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_1nls0")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"up",
|
||||
"speed": 8.0
|
||||
}]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_am7go")
|
||||
deployed_sprite_sheet = SubResource("SpriteFrames_psufo")
|
||||
metadata/_custom_type_script = "uid://divxkbo321ql"
|
||||
33
resources/units/lily_child.tres
Normal file
33
resources/units/lily_child.tres
Normal file
@@ -0,0 +1,33 @@
|
||||
[gd_resource type="Resource" script_class="Unit" format=3 uid="uid://sqrlba15ncyr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c016mxgatcpse" path="res://scripts/units/unit.gd" id="1_bqd3m"]
|
||||
[ext_resource type="Script" uid="uid://divxkbo321ql" path="res://scripts/units/unit_appearance_set.gd" id="1_lko56"]
|
||||
[ext_resource type="Script" uid="uid://b67rtbb5gixus" path="res://scripts/battle/combat_tactics/combat_tactic.gd" id="2_0tmvt"]
|
||||
[ext_resource type="Resource" uid="uid://c18djmm6orf5y" path="res://resources/units/appearance_sets/lily_child_deployed.tres" id="2_f8ij3"]
|
||||
[ext_resource type="Script" uid="uid://b402hsmbaj536" path="res://scripts/units/unit_appearance.gd" id="2_nxnrh"]
|
||||
[ext_resource type="Script" uid="uid://d37ulss2k0bq5" path="res://scripts/units/unit_info.gd" id="3_f8ij3"]
|
||||
[ext_resource type="Script" uid="uid://cydoey8a8nmb8" path="res://scripts/units/unit_stats.gd" id="5_rqhbp"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ki4ax"]
|
||||
script = ExtResource("2_nxnrh")
|
||||
appearance_sets = Dictionary[String, ExtResource("1_lko56")]({
|
||||
"default": ExtResource("2_f8ij3")
|
||||
})
|
||||
metadata/_custom_type_script = "uid://b402hsmbaj536"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_q2jxx"]
|
||||
script = ExtResource("3_f8ij3")
|
||||
name = "Lily"
|
||||
metadata/_custom_type_script = "uid://d37ulss2k0bq5"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_nc6h6"]
|
||||
script = ExtResource("5_rqhbp")
|
||||
max_hp = 20
|
||||
metadata/_custom_type_script = "uid://cydoey8a8nmb8"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_bqd3m")
|
||||
stats = SubResource("Resource_nc6h6")
|
||||
info = SubResource("Resource_q2jxx")
|
||||
appearance = SubResource("Resource_ki4ax")
|
||||
metadata/_custom_type_script = "uid://c016mxgatcpse"
|
||||
@@ -78,23 +78,18 @@ script/source = "extends TextureButton
|
||||
const COMBAT_SCENE = preload(\"res://scenes/views/battle_view.tscn\")
|
||||
const PLAYER_ALLEGIANCE = preload(\"res://resources/allegiance_types/player_allegiance.tres\")
|
||||
const ENEMY_ALLEGIANCE = preload(\"res://resources/allegiance_types/enemy_allegiance.tres\")
|
||||
const LILY_CHILD = preload(\"res://resources/units/lily_child.tres\")
|
||||
|
||||
func _pressed() -> void:
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
var combat_instance := COMBAT_SCENE.instantiate()
|
||||
var combat_map: CombatMap = combat_instance.find_child(\"CombatMap\")
|
||||
|
||||
var player_unit := Unit.new()
|
||||
player_unit.stats = UnitStats.new()
|
||||
player_unit.info = UnitInfo.new()
|
||||
player_unit.info.name = \"Putit\"
|
||||
var player_unit: Unit = LILY_CHILD.duplicate(true)
|
||||
player_unit.allegiance = PLAYER_ALLEGIANCE
|
||||
combat_map.deploy_unit(player_unit, Vector2i(3, 3))
|
||||
|
||||
var enemy_unit := Unit.new()
|
||||
enemy_unit.stats = UnitStats.new()
|
||||
enemy_unit.info = UnitInfo.new()
|
||||
enemy_unit.info.name = \"Putit\"
|
||||
var enemy_unit: Unit = LILY_CHILD.duplicate(true)
|
||||
enemy_unit.allegiance = ENEMY_ALLEGIANCE
|
||||
combat_map.deploy_unit(enemy_unit, Vector2i(6, 3))
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func create_proposal(attacker: DeployedUnit, defender: DeployedUnit, distance: i
|
||||
func _filter_tactics(deployed: DeployedUnit, distance: int) -> Array[CombatTactic]:
|
||||
var valid: Array[CombatTactic] = []
|
||||
for tactic in deployed.tactics:
|
||||
if tactic.tactic_range and tactic.tactic_range.is_valid_range(distance, deployed.unit):
|
||||
if tactic.tactic_range and tactic.tactic_range.is_valid_range(distance, deployed.current_stats):
|
||||
valid.append(tactic)
|
||||
return valid
|
||||
|
||||
@@ -35,27 +35,29 @@ func _find_default_attack(tactics: Array[CombatTactic]) -> CombatTactic:
|
||||
|
||||
|
||||
func _snapshot(deployed: DeployedUnit, opponent: DeployedUnit, available: Array[CombatTactic], selected: CombatTactic, opponent_selected: CombatTactic) -> CombatProposal.CombatantStats:
|
||||
var current := deployed.current_stats
|
||||
var opp_current := opponent.current_stats
|
||||
var stats := CombatProposal.CombatantStats.new()
|
||||
stats.deployed = deployed
|
||||
stats.max_hp = deployed.unit.stats.max_hp
|
||||
stats.hp = deployed.current_stats.current_hp
|
||||
stats.sp = deployed.current_stats.current_sp
|
||||
stats.spd = deployed.unit.stats.spd
|
||||
stats.max_hp = current.max_hp
|
||||
stats.hp = current.current_hp
|
||||
stats.sp = current.current_sp
|
||||
stats.spd = current.spd
|
||||
stats.available_tactics = available
|
||||
stats.selected_tactic = selected
|
||||
|
||||
if selected and selected.deals_damage():
|
||||
var offensive: Dictionary = selected.get_offensive_stats(deployed.unit)
|
||||
var offensive: Dictionary = selected.get_offensive_stats(current)
|
||||
stats.atk = offensive["atk"]
|
||||
stats.hit = offensive["hit"] - opponent.unit.stats.eva
|
||||
stats.hit = offensive["hit"] - opp_current.eva
|
||||
else:
|
||||
stats.atk = 0
|
||||
stats.hit = 0
|
||||
|
||||
if opponent_selected and opponent_selected.deals_damage():
|
||||
stats.def = opponent_selected.get_relevant_defense(deployed.unit)
|
||||
stats.def = opponent_selected.get_relevant_defense(current)
|
||||
else:
|
||||
stats.def = deployed.unit.stats.phys_def
|
||||
stats.def = current.phys_def
|
||||
|
||||
return stats
|
||||
|
||||
@@ -74,18 +76,18 @@ func update_tactic(proposal: CombatProposal, is_attacker: bool, tactic: CombatTa
|
||||
|
||||
# Recalculate this side's offensive stats
|
||||
if tactic and tactic.deals_damage():
|
||||
var offensive: Dictionary = tactic.get_offensive_stats(self_stats.deployed.unit)
|
||||
var offensive: Dictionary = tactic.get_offensive_stats(self_stats.deployed.current_stats)
|
||||
self_stats.atk = offensive["atk"]
|
||||
self_stats.hit = offensive["hit"] - opp_stats.deployed.unit.stats.eva
|
||||
self_stats.hit = offensive["hit"] - opp_stats.deployed.current_stats.eva
|
||||
else:
|
||||
self_stats.atk = 0
|
||||
self_stats.hit = 0
|
||||
|
||||
# Recalculate opponent's def based on this side's new tactic
|
||||
if tactic and tactic.deals_damage():
|
||||
opp_stats.def = tactic.get_relevant_defense(opp_stats.deployed.unit)
|
||||
opp_stats.def = tactic.get_relevant_defense(opp_stats.deployed.current_stats)
|
||||
else:
|
||||
opp_stats.def = opp_stats.deployed.unit.stats.phys_def
|
||||
opp_stats.def = opp_stats.deployed.current_stats.phys_def
|
||||
|
||||
|
||||
func select_ai_tactic(deployed: DeployedUnit, opponent: DeployedUnit, available_tactics: Array[CombatTactic]) -> CombatTactic:
|
||||
@@ -95,8 +97,8 @@ func select_ai_tactic(deployed: DeployedUnit, opponent: DeployedUnit, available_
|
||||
for tactic in available_tactics:
|
||||
if not tactic.deals_damage():
|
||||
continue
|
||||
var offensive: Dictionary = tactic.get_offensive_stats(deployed.unit)
|
||||
var defense: int = tactic.get_relevant_defense(opponent.unit)
|
||||
var offensive: Dictionary = tactic.get_offensive_stats(deployed.current_stats)
|
||||
var defense: int = tactic.get_relevant_defense(opponent.current_stats)
|
||||
var damage := maxi(offensive["atk"] - defense, 0)
|
||||
if damage > best_damage:
|
||||
best_damage = damage
|
||||
|
||||
@@ -3,11 +3,11 @@ class_name CombatTactic extends Resource
|
||||
@export var tactic_name: String = ""
|
||||
@export var tactic_range: CombatTacticRange
|
||||
|
||||
func get_offensive_stats(_unit: Unit) -> Variant:
|
||||
func get_offensive_stats(_stats: DeployedUnitStats) -> Variant:
|
||||
return null
|
||||
|
||||
func get_relevant_defense(unit: Unit) -> int:
|
||||
return unit.stats.phys_def
|
||||
func get_relevant_defense(stats: DeployedUnitStats) -> int:
|
||||
return stats.phys_def
|
||||
|
||||
func deals_damage() -> bool:
|
||||
return false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# resources/resource_definitions/any_combat_tactic_range.gd
|
||||
class_name AnyCombatTacticRange extends CombatTacticRange
|
||||
|
||||
func is_valid_range(_distance: int, _unit: Unit) -> bool:
|
||||
func is_valid_range(_distance: int, _stats: DeployedUnitStats) -> bool:
|
||||
return true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# resources/resource_definitions/combat_tactic_range.gd
|
||||
class_name CombatTacticRange extends Resource
|
||||
|
||||
func is_valid_range(_distance: int, _unit: Unit) -> bool:
|
||||
func is_valid_range(_distance: int, _stats: DeployedUnitStats) -> bool:
|
||||
return false
|
||||
|
||||
@@ -3,5 +3,5 @@ class_name FixedCombatTacticRange extends CombatTacticRange
|
||||
|
||||
@export var tactic_range: int = 1
|
||||
|
||||
func is_valid_range(distance: int, unit: Unit) -> bool:
|
||||
func is_valid_range(distance: int, _stats: DeployedUnitStats) -> bool:
|
||||
return distance <= tactic_range
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# resources/resource_definitions/unit_matching_combat_tactic_range.gd
|
||||
class_name UnitMatchingCombatTacticRange extends CombatTacticRange
|
||||
|
||||
func is_valid_range(distance: int, unit: Unit) -> bool:
|
||||
return distance <= unit.stats.atk_range
|
||||
func is_valid_range(distance: int, stats: DeployedUnitStats) -> bool:
|
||||
return distance <= stats.atk_range
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
class_name AttackCombatTactic extends CombatTactic
|
||||
|
||||
func get_offensive_stats(unit: Unit) -> Variant:
|
||||
return {"atk": unit.stats.phys_atk, "hit": unit.stats.hit}
|
||||
func get_offensive_stats(stats: DeployedUnitStats) -> Variant:
|
||||
return {"atk": stats.phys_atk, "hit": stats.hit}
|
||||
|
||||
func get_relevant_defense(unit: Unit) -> int:
|
||||
return unit.stats.phys_def
|
||||
func get_relevant_defense(stats: DeployedUnitStats) -> int:
|
||||
return stats.phys_def
|
||||
|
||||
func deals_damage() -> bool:
|
||||
return true
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
class_name DefendCombatTactic extends CombatTactic
|
||||
|
||||
func get_offensive_stats(_unit: Unit) -> Variant:
|
||||
func get_offensive_stats(_stats: DeployedUnitStats) -> Variant:
|
||||
return null
|
||||
|
||||
func get_relevant_defense(unit: Unit) -> int:
|
||||
return unit.stats.phys_def
|
||||
func get_relevant_defense(stats: DeployedUnitStats) -> int:
|
||||
return stats.phys_def
|
||||
|
||||
func deals_damage() -> bool:
|
||||
return false
|
||||
|
||||
@@ -59,7 +59,7 @@ func _on_unit_died(deployed: DeployedUnit) -> void:
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _selected_unit and is_instance_valid(_selected_unit):
|
||||
hp_bar.max_value = _selected_unit.unit.stats.max_hp
|
||||
hp_bar.max_value = _selected_unit.current_stats.max_hp
|
||||
hp_bar.value = _selected_unit.current_stats.current_hp
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
@@ -72,7 +72,7 @@ func _on_unit_selected_changed(deployed: DeployedUnit, selected: bool) -> void:
|
||||
if selected:
|
||||
_selected_unit = deployed
|
||||
name_label.text = deployed.unit.info.name
|
||||
hp_bar.max_value = deployed.unit.stats.max_hp
|
||||
hp_bar.max_value = deployed.current_stats.max_hp
|
||||
hp_bar.value = deployed.current_stats.current_hp
|
||||
unit_panel.visible = true
|
||||
else:
|
||||
|
||||
@@ -8,6 +8,9 @@ var current_stats: DeployedUnitStats
|
||||
var tactics: Array[CombatTactic] = []
|
||||
var state: UnitState = UnitState.ALIVE
|
||||
|
||||
var _sprite: AnimatedSprite2D
|
||||
var _previous_position: Vector2
|
||||
|
||||
signal unit_selected_changed(deployed: DeployedUnit, selected: bool)
|
||||
signal unit_allegiance_changed(deployed: DeployedUnit, allegiance: UnitAllegiance)
|
||||
signal unit_died(deployed: DeployedUnit)
|
||||
@@ -17,6 +20,35 @@ func _ready() -> void:
|
||||
tactics = unit.tactics.duplicate()
|
||||
_append_builtin_tactics()
|
||||
unit_allegiance_changed.emit(self, unit.allegiance)
|
||||
_previous_position = position
|
||||
_setup_appearance()
|
||||
|
||||
func _setup_appearance() -> void:
|
||||
_sprite = get_node_or_null("AnimatedSprite2D") as AnimatedSprite2D
|
||||
if not _sprite:
|
||||
return
|
||||
var sprite_frames: SpriteFrames = unit.appearance.deployed_sprite_sheet if unit.appearance else null
|
||||
if not sprite_frames:
|
||||
return
|
||||
_sprite.sprite_frames = sprite_frames
|
||||
_sprite.play("idle")
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if not _sprite or not _sprite.sprite_frames:
|
||||
return
|
||||
var delta_pos := position - _previous_position
|
||||
_previous_position = position
|
||||
if delta_pos.length_squared() < 0.01:
|
||||
if _sprite.animation != &"idle":
|
||||
_sprite.play("idle")
|
||||
return
|
||||
var anim: StringName
|
||||
if absf(delta_pos.x) >= absf(delta_pos.y):
|
||||
anim = &"right" if delta_pos.x > 0 else &"left"
|
||||
else:
|
||||
anim = &"down" if delta_pos.y > 0 else &"up"
|
||||
if _sprite.animation != anim:
|
||||
_sprite.play(anim)
|
||||
|
||||
func _append_builtin_tactics() -> void:
|
||||
var attack := AttackCombatTactic.new()
|
||||
|
||||
@@ -5,6 +5,35 @@ class_name DeployedUnitStats extends Resource
|
||||
@export var current_sp: int
|
||||
@export var current_fs: int
|
||||
|
||||
# Passthrough accessors. Future buff/debuff layers can override these
|
||||
# without mutating the underlying UnitStats template.
|
||||
var max_hp: int:
|
||||
get: return unit_stats.max_hp
|
||||
var max_sp: int:
|
||||
get: return unit_stats.max_sp
|
||||
var max_fs: int:
|
||||
get: return unit_stats.max_fs
|
||||
var phys_atk: int:
|
||||
get: return unit_stats.phys_atk
|
||||
var phys_def: int:
|
||||
get: return unit_stats.phys_def
|
||||
var magic_atk: int:
|
||||
get: return unit_stats.magic_atk
|
||||
var magic_def: int:
|
||||
get: return unit_stats.magic_def
|
||||
var hit: int:
|
||||
get: return unit_stats.hit
|
||||
var atk_range: int:
|
||||
get: return unit_stats.atk_range
|
||||
var spd: int:
|
||||
get: return unit_stats.spd
|
||||
var eva: int:
|
||||
get: return unit_stats.eva
|
||||
var lck: int:
|
||||
get: return unit_stats.lck
|
||||
var mov: int:
|
||||
get: return unit_stats.mov
|
||||
|
||||
static func from_unit_stats(source: UnitStats) -> DeployedUnitStats:
|
||||
var stats := DeployedUnitStats.new()
|
||||
stats.unit_stats = source
|
||||
|
||||
@@ -4,3 +4,4 @@ class_name Unit extends Resource
|
||||
@export var info: UnitInfo
|
||||
@export var allegiance: UnitAllegiance
|
||||
@export var tactics: Array[CombatTactic] = []
|
||||
@export var appearance: UnitAppearance
|
||||
|
||||
19
scripts/units/unit_appearance.gd
Normal file
19
scripts/units/unit_appearance.gd
Normal file
@@ -0,0 +1,19 @@
|
||||
class_name UnitAppearance extends Resource
|
||||
|
||||
@export var default_appearance_key: String = "default"
|
||||
@export var current_appearance_key: String
|
||||
@export var appearance_sets: Dictionary[String, UnitAppearanceSet]
|
||||
|
||||
var deployed_sprite_sheet: SpriteFrames:
|
||||
get:
|
||||
var key: String = current_appearance_key
|
||||
if(key == null or key == ""):
|
||||
key = default_appearance_key
|
||||
if(!appearance_sets.has(key)):
|
||||
return null
|
||||
var appearance_set: UnitAppearanceSet = appearance_sets[key]
|
||||
var sprite_value = appearance_set.deployed_sprite_sheet
|
||||
if(sprite_value == null):
|
||||
sprite_value = appearance_sets[default_appearance_key].deployed_sprite_sheet
|
||||
|
||||
return sprite_value
|
||||
1
scripts/units/unit_appearance.gd.uid
Normal file
1
scripts/units/unit_appearance.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b402hsmbaj536
|
||||
3
scripts/units/unit_appearance_set.gd
Normal file
3
scripts/units/unit_appearance_set.gd
Normal file
@@ -0,0 +1,3 @@
|
||||
class_name UnitAppearanceSet extends Resource
|
||||
|
||||
@export var deployed_sprite_sheet: SpriteFrames
|
||||
1
scripts/units/unit_appearance_set.gd.uid
Normal file
1
scripts/units/unit_appearance_set.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://divxkbo321ql
|
||||
Reference in New Issue
Block a user