first draft of the new card gameplay

This commit is contained in:
2025-06-26 02:32:45 +10:00
parent 0cd8715468
commit a6c503b8ff
32 changed files with 388 additions and 179 deletions

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_yqa4b")
duration = 5
rarity = 0
faction = 1
turret_scene = ExtResource("4_5nu32")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_qtxcq")
duration = 6
rarity = 0
faction = 1
turret_scene = ExtResource("3_v4x2k")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_xmwih")
duration = 3
rarity = 2
faction = 1
turret_scene = ExtResource("4_rgkdc")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_5html")
duration = 4
rarity = 0
faction = 1
turret_scene = ExtResource("4_thk7u")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_tdu8a")
duration = 4
rarity = 0
faction = 1
turret_scene = ExtResource("4_xcrut")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_t3tfw")
duration = 8
rarity = 1
faction = 1
turret_scene = ExtResource("3_d6lco")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_0ciid")
duration = 4
rarity = 4
faction = 1
turret_scene = ExtResource("3_l4xwa")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_ly0o5")
duration = 5
rarity = 0
faction = 1
turret_scene = ExtResource("3_73c50")

View File

@@ -8,6 +8,7 @@
[resource]
script = ExtResource("1_5vmtk")
duration = 6
rarity = 1
faction = 1
turret_scene = ExtResource("4_k5nhs")

View File

@@ -16,7 +16,7 @@ script = ExtResource("7_ftkad")
hero_name = "Engineer"
texture = ExtResource("8_0o0bw")
hand_texture = ExtResource("6_a8dvt")
deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("3_eml7q"), ExtResource("4_ovvb2"), ExtResource("5_vqkxt")])
deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("4_ovvb2"), ExtResource("4_ovvb2"), ExtResource("4_ovvb2"), ExtResource("5_vqkxt"), ExtResource("5_vqkxt"), ExtResource("3_eml7q")])
faction = 1
podium = ExtResource("7_nyup7")
card_item = ExtResource("1_2m5d7")

View File

@@ -25,13 +25,13 @@ health = 180
penalty = 10
movement_speed = 1.2
spawn_cooldown = 1.2
common_group = 8
common_group = 6
common_cost = 1
uncommon_group = 12
uncommon_group = 10
uncommon_cost = 2
rare_group = 18
rare_group = 16
rare_cost = 3
epic_group = 26
epic_group = 22
epic_cost = 5
legendary_group = 34
legendary_group = 28
legendary_cost = 6

View File

@@ -2,7 +2,6 @@ class_name PathEditTool
extends Node3D
@export var hero: Hero
@export var inventory: Inventory
@export var ray: RayCast3D
@export var wall_preview: TowerBase
@export var progress_bar: TextureProgressBar
@@ -13,6 +12,7 @@ var point: FlowNode
var obstacle_last_point: int = -1
var valid_point: bool = false # a point is valid if the path would still be traversable overall if this point was made untraversable
var tower_preview: Tower
var tower_preview_card: Card
var ray_collider: Object
var ray_point: Vector3
var last_point: FlowNode
@@ -38,7 +38,7 @@ func _process(delta: float) -> void:
if interact_key_held:
if !interacted_once:
if valid_point and hero.currency >= Data.wall_cost and ray_collider and point.buildable:
if valid_point and hero.energy >= Data.wall_cost and ray_collider and point.buildable:
interact_held_time += delta
set_progress_percent(interact_held_time / interact_hold_time)
wall_preview.set_float(interact_held_time / interact_hold_time)
@@ -98,7 +98,7 @@ func process_looking_at_level() -> void:
if tower_preview:
delete_tower_preview()
point = level.flow_field.get_closest_buildable_point(ray_point)
if level.walls.has(point) or !point.buildable or hero.currency < Data.wall_cost:
if level.walls.has(point) or !point.buildable or hero.energy < Data.wall_cost:
wall_preview.set_visible(false)
valid_point = false
clear_previous_point()
@@ -131,15 +131,16 @@ func process_looking_at_tower() -> void:
wall_preview.set_visible(false)
ray_collider.set_color(Color.RED)
ray_collider.set_float(0.0)
if inventory.contents.size() > 0 and !ray_collider.has_card:
if ray_collider != last_tower_base or inventory.selected_item != inventory.contents.keys()[hero.inventory_selected_index]:
if hero.hand.size > 0 and !ray_collider.has_card:
if ray_collider != last_tower_base or hero.hand.item_at(hero.hand_selected_index) != tower_preview_card:
spawn_tower_preview()
func spawn_tower_preview() -> void:
delete_tower_preview()
last_tower_base = ray_collider
var card: Card = inventory.contents.keys()[hero.inventory_selected_index]
var card: Card = hero.hand.item_at(hero.hand_selected_index)
tower_preview_card = card
tower_preview = card.turret_scene.instantiate() as Tower
tower_preview.stats = card.tower_stats
tower_preview.position = Vector3.UP
@@ -152,6 +153,7 @@ func delete_tower_preview() -> void:
if is_instance_valid(tower_preview):
tower_preview.queue_free()
tower_preview = null
tower_preview_card = null
func interact() -> void:
@@ -161,8 +163,8 @@ func interact() -> void:
func build_wall() -> void:
if point and valid_point and hero.currency >= Data.wall_cost:
hero.currency -= Data.wall_cost
if point and valid_point and hero.energy >= Data.wall_cost:
hero.energy -= Data.wall_cost
level.set_wall(point, multiplayer.get_unique_id())
wall_preview.visible = false
@@ -176,14 +178,21 @@ func refund_wall(wall: TowerBase) -> void:
func put_card_in_tower_base(tower_base: TowerBase) -> void:
if tower_base.has_card:
tower_base.remove_card()
elif inventory.size > 0:
var card: Card = inventory.remove_at(hero.inventory_selected_index)
if !inventory.contents.has(card):
hero.decrement_selected()
var energy_cost: int = int(hero.hand.item_at(hero.hand_selected_index).rarity) + 1
if hero.energy < energy_cost:
return
if hero.hand.size > 0:
if tower_base.has_card:
tower_base.remove_card()
var card: Card = hero.hand.remove_at(hero.hand_selected_index)
hero.card_sprites[hero.hand_selected_index].queue_free()
hero.card_sprites.remove_at(hero.hand_selected_index)
#if !hero.hand.contents.has(card):
hero.decrement_selected()
tower_base.add_card(card, multiplayer.get_unique_id())
hero.discard_pile.add(card)
hero.place_card_audio.play()
hero.energy -= energy_cost
func set_progress_percent(value: float) -> void:

View File

@@ -7,7 +7,6 @@ signal ready_state_changed(state: bool)
@export var camera: Camera3D
@export var gun_camera: Camera3D
@export var left_hand_sprite: Sprite3D
@export var card_sprites: Array[CardInHand]
@export var left_hand: Node3D
@export var right_hand: Node3D
@export var right_hand_animator: AnimationPlayer
@@ -16,7 +15,9 @@ signal ready_state_changed(state: bool)
@export var sprite: EightDirectionSprite3D
@export var hand_sprite: Sprite2D
@export var interaction_raycast: RayCast3D
@export var inventory: Inventory
@export var draw_pile: Inventory
@export var hand: Inventory
@export var discard_pile: Inventory
@export var gauntlet_cards: Array[CardInHand]
@export var pause_menu_scene: PackedScene
@export var hud: HUD
@@ -36,10 +37,12 @@ signal ready_state_changed(state: bool)
@export var swap_off_audio: AudioStreamPlayer
@export var swap_on_audio: AudioStreamPlayer
var hand_card_scene: PackedScene = preload("res://Scenes/UI/card_hand.tscn")
var card_sprites: Array[CardInHand]
var game_manager: GameManager
var hovering_item: InteractButton = null
var weapons_spawn_count: int = 0 #Used to prevent node name collisions for multiplayer
var inventory_selected_index: int = 0
var hand_selected_index: int = 0
var equipped_weapon: int = 0
var weapons: Array[Weapon] = [null, null]
var cards: Array[Card] = [null, null]
@@ -57,6 +60,12 @@ var currency: int = 0 :
hud.set_currency_count(value)
get:
return currency
var energy: int = 0 :
set(value):
energy = value
hud.set_energy_amount(value)
get:
return energy
func set_zoom_factor(value: float) -> void:
@@ -70,10 +79,11 @@ func _ready() -> void:
ears.make_current()
camera.make_current()
sprite.queue_free()
hand.max_size = 5
hand_sprite.texture = hero_class.hand_texture
player_name_tag.queue_free()
for card: Card in hero_class.deck:
inventory.add(card)
draw_pile.add(card)
else:
camera.set_visible(false)
gun_camera.set_visible(false)
@@ -118,38 +128,21 @@ func _process(delta: float) -> void:
hovering_item.disable_hover_effect()
hovering_item = null
if is_instance_valid(edit_tool.ray_collider) and edit_tool.ray_collider is TowerBase:
card_sprites[0].view_tower()
else:
card_sprites[0].view_weapon()
if Input.is_action_just_pressed("Interact"):
edit_tool.interact()
if interaction_raycast.get_collider() is InteractButton:
var button: InteractButton = interaction_raycast.get_collider() as InteractButton
if currency >= button.press_cost:
button.press(self)
currency -= button.press_cost
button.press(self)
if interaction_raycast.get_collider() is ItemCard:
add_card(interaction_raycast.get_collider().pick_up())
#if Input.is_action_just_pressed("Equip In Gauntlet"):
# equip_weapon()
#if Input.is_action_just_pressed("Secondary Fire"):
# if equipped_card or offhand_card:
# swap_weapons()
if Input.is_action_just_pressed("Equip Primary Weapon"):
if weapons[0]:
unequip_weapon(0)
else:
equip_weapon(0)
equip_weapon(0)
if Input.is_action_just_pressed("Equip Secondary Weapon"):
if weapons[1]:
unequip_weapon(1)
else:
equip_weapon(1)
if Input.is_action_just_pressed("Select Next Card") and inventory.contents.size() > 1:
equip_weapon(1)
if Input.is_action_just_pressed("Select Next Card") and hand.size > 1:
increment_selected()
swap_card_audio.play()
if Input.is_action_just_pressed("Select Previous Card") and inventory.contents.size() > 1:
if Input.is_action_just_pressed("Select Previous Card") and hand.size > 1:
decrement_selected()
swap_card_audio.play()
if Input.is_action_just_pressed("Primary Fire"):
@@ -180,7 +173,8 @@ func _process(delta: float) -> void:
if equipped_weapon == 0 and weapons[1]:
swap_weapons()
if Input.is_action_just_pressed("Swap Weapons"):
swap_weapons()
if weapons[0] and weapons[1]:
swap_weapons()
if movement.sprinting:
movement.zoom_factor -= sprint_zoom_speed * delta
@@ -198,15 +192,18 @@ func _process(delta: float) -> void:
func increment_selected() -> void:
inventory_selected_index += 1
if inventory_selected_index >= inventory.contents.keys().size():
inventory_selected_index = 0
hand_selected_index += 1
if hand_selected_index >= hand.size:
hand_selected_index = 0
func decrement_selected() -> void:
inventory_selected_index -= 1
if inventory_selected_index < 0:
inventory_selected_index = max(inventory.contents.keys().size() - 1, 0)
if hand.size == 0:
hand_selected_index = 0
return
hand_selected_index -= 1
if hand_selected_index < 0:
hand_selected_index = hand.size - 1
func _unhandled_input(event: InputEvent) -> void:
@@ -241,17 +238,13 @@ func ready_self() -> void:
func unready_self() -> void:
if ready_state:
ready_state = false
#if !equipped_card:
# hud.place_icon.set_visible(true)
#if !offhand_card:
# hud.swap_icon.set_visible(true)
hud.grow_wave_start_label()
unready_audio.play()
networked_set_ready_state(ready_state)
func add_card(new_card: Card) -> void:
inventory.add(new_card)
hand.append(new_card)
hud.pickup(new_card)
place_card_audio.play()
@@ -286,17 +279,13 @@ func exit_editing_mode(value: int) -> void:
gauntlet_sprite.visible = false
weapons_active = false
hud.set_wave_count(value)
#if !weapon and offhand_weapon:
# swap_weapons()
var offhand_weapon: Weapon = weapons[0] if equipped_weapon == 1 else weapons[1]
if offhand_weapon:
offhand_weapon.current_energy = offhand_weapon.max_energy
#offhand_weapon.energy_changed.emit(offhand_weapon.current_energy)
if (!weapons[equipped_weapon] and offhand_weapon) or (weapons[0] and equipped_weapon == 1):
swap_weapons()
if weapons[equipped_weapon]:
hud.set_energy_visible(true)
#weapon.set_visible(false)
weapons[equipped_weapon].current_energy = weapons[equipped_weapon].max_energy
#this had to be commented out coz the new energy bar thinks "energy changed" is "energy used"
#weapons[equipped_weapon].energy_changed.emit(weapons[equipped_weapon].current_energy)
@@ -311,38 +300,93 @@ func exit_editing_mode(value: int) -> void:
func check_left_hand_valid() -> void:
if !editing_mode:
return
if inventory.size == 0:
if hand.size == 0:
left_hand_sprite.visible = false
#gauntlet.texture.region = Rect2(64, 0, 64, 64)
else:
left_hand_sprite.visible = true
#gauntlet.texture.region = Rect2(0, 0, 64, 64)
var selected_card: Card = inventory.contents.keys()[inventory_selected_index]
var selected_card: Card = hand.item_at(hand_selected_index)
for index: int in card_sprites.size():
if index < inventory.contents[selected_card]:
card_sprites[index].visible = true
card_sprites[index].set_card(selected_card)
#card_sprites[index].view_weapon()
if hand_selected_index == index:
var tween: Tween = create_tween()
tween.set_ease(Tween.EASE_OUT)
tween.set_trans(Tween.TRANS_CUBIC)
tween.tween_property(card_sprites[index], "position", Vector2(200.0 * index, -20.0), 0.5)
else:
card_sprites[index].visible = false
var tween: Tween = create_tween()
tween.set_ease(Tween.EASE_OUT)
tween.set_trans(Tween.TRANS_CUBIC)
tween.tween_property(card_sprites[index], "position", Vector2(200.0 * index, 80.0), 0.5)
#if index < inventory.contents[selected_card]:
#card_sprites[index].visible = true
#card_sprites[index].set_card(selected_card)
##card_sprites[index].view_weapon()
#else:
#card_sprites[index].visible = false
func iterate_duration() -> void:
for slot: int in weapons.size():
if weapons[slot] == null:
continue
weapons[slot].duration -= 1
if slot == 0:
hud.primary_duration.text = "primary weapon rounds left = " + str(weapons[slot].duration)
elif slot == 1:
hud.secondary_duration.text = "secondary weapon rounds left = " + str(weapons[slot].duration)
if weapons[slot].duration <= 0:
unequip_weapon(slot)
func draw_to_hand_size() -> void:
while hand.size < hand.max_size:
if draw_pile.size == 0 and discard_pile.size == 0:
return
if draw_pile.size > 0:
var card: Card = draw_pile.remove_at(0)
hand.add(card)
var display: CardInHand = hand_card_scene.instantiate()
display.set_card(card)
$FirstPersonViewport/Head2/LeftHand/SubViewport.add_child(display)
card_sprites.append(display)
var tween: Tween = create_tween()
tween.set_ease(Tween.EASE_OUT)
tween.set_trans(Tween.TRANS_CUBIC)
tween.tween_property(display, "position", Vector2(200.0 * hand.size, 80.0), 0.5)
else:
for x: int in discard_pile.size:
draw_pile.add(discard_pile.remove_at(0))
draw_pile.shuffle()
func equip_weapon(slot: int = 0) -> void:
if weapons[slot] != null:
unequip_weapon()
var energy_cost: int = int(hand.item_at(hand_selected_index).rarity) + 1
if energy < energy_cost:
return
if inventory.size > 0:
if weapons[slot] != null:
unequip_weapon(slot)
if hand.size > 0:
energy -= energy_cost
place_card_audio.play()
cards[slot] = inventory.remove_at(inventory_selected_index)
if !inventory.contents.has(cards[slot]):
decrement_selected()
cards[slot] = hand.remove_at(hand_selected_index)
card_sprites[hand_selected_index].queue_free()
card_sprites.remove_at(hand_selected_index)
discard_pile.add(cards[slot])
#TODO: Alternate thing to do with the hand i guess
#if !inventory.contents.has(cards[slot]):
decrement_selected()
weapons[slot] = cards[slot].weapon_scene.instantiate()
weapons[slot].name = str(weapons_spawn_count)
weapons[slot].duration = cards[slot].duration
networked_equip_weapon.rpc(Data.cards.find(cards[slot]), 0, weapons_spawn_count)
weapons_spawn_count += 1
#weapons[slot].energy_changed.connect(hud.set_weapon_energy.bind(weapons[slot].stats.energy_type))
weapons[slot].set_multiplayer_authority(multiplayer.get_unique_id())
gauntlet_cards[slot].set_card(cards[slot])
if slot == 0:
hud.primary_duration.text = "primary weapon rounds left = " + str(weapons[slot].duration)
elif slot == 1:
hud.secondary_duration.text = "secondary weapon rounds left = " + str(weapons[slot].duration)
if slot == 0:
hud.place_icon.visible = false
else:
@@ -425,10 +469,8 @@ func unequip_weapon(slot: int = 0) -> void:
else:
hud.swap_icon.visible = true
hud.new_energy_bar.disable_secondary_energy()
#gauntlet_sprite.set_visible(true)
weapons[slot].queue_free()
weapons[slot] = null
inventory.add(cards[slot])
cards[slot] = null
place_card_audio.play()
check_left_hand_valid()

View File

@@ -129,7 +129,7 @@ stream_0/stream = ExtResource("36_lsvj8")
streams_count = 1
stream_0/stream = ExtResource("37_kv1mg")
[node name="Hero" type="CharacterBody3D" node_paths=PackedStringArray("camera", "gun_camera", "left_hand_sprite", "card_sprites", "left_hand", "right_hand", "right_hand_animator", "edit_tool", "gauntlet_sprite", "sprite", "hand_sprite", "interaction_raycast", "inventory", "gauntlet_cards", "hud", "movement", "player_name_tag", "weapon_swap_timer", "ears", "place_card_audio", "swap_card_audio", "ready_audio", "unready_audio", "fullpower_audio", "zeropower_audio", "swap_off_audio", "swap_on_audio")]
[node name="Hero" type="CharacterBody3D" node_paths=PackedStringArray("camera", "gun_camera", "left_hand_sprite", "left_hand", "right_hand", "right_hand_animator", "edit_tool", "gauntlet_sprite", "sprite", "hand_sprite", "interaction_raycast", "draw_pile", "hand", "discard_pile", "gauntlet_cards", "hud", "movement", "player_name_tag", "weapon_swap_timer", "ears", "place_card_audio", "swap_card_audio", "ready_audio", "unready_audio", "fullpower_audio", "zeropower_audio", "swap_off_audio", "swap_on_audio")]
collision_layer = 2
collision_mask = 37
script = ExtResource("1_pihpe")
@@ -137,7 +137,6 @@ hero_class = ExtResource("2_dbyo0")
camera = NodePath("ViewMovement/Head")
gun_camera = NodePath("FirstPersonViewport/Head2")
left_hand_sprite = NodePath("FirstPersonViewport/Head2/LeftHand/Sprite3D")
card_sprites = [NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card1"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card2"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card3"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card4"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card5"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card6"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card7"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card8"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card9"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Card10")]
left_hand = NodePath("FirstPersonViewport/Head2/LeftHand")
right_hand = NodePath("FirstPersonViewport/Head2/RightHand")
right_hand_animator = NodePath("FirstPersonViewport/Head2/RightHand/AnimationPlayer")
@@ -146,7 +145,9 @@ gauntlet_sprite = NodePath("FirstPersonViewport/Head2/RightHand/Gauntlet")
sprite = NodePath("EightDirectionSprite")
hand_sprite = NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport/Sprite2D")
interaction_raycast = NodePath("ViewMovement/Head/RayCast3D")
inventory = NodePath("Inventory")
draw_pile = NodePath("DrawPile")
hand = NodePath("Hand")
discard_pile = NodePath("DiscardPile")
gauntlet_cards = [NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport2/Node2D"), NodePath("FirstPersonViewport/Head2/LeftHand/SubViewport3/Node2D")]
pause_menu_scene = ExtResource("3_avnsx")
hud = NodePath("HUD")
@@ -182,9 +183,8 @@ keep_aspect = 0
cull_mask = 1048569
fov = 100.0
[node name="EditTool" parent="ViewMovement/Head" node_paths=PackedStringArray("hero", "inventory") instance=ExtResource("5_jlxb3")]
[node name="EditTool" parent="ViewMovement/Head" node_paths=PackedStringArray("hero") instance=ExtResource("5_jlxb3")]
hero = NodePath("../../..")
inventory = NodePath("../../../Inventory")
[node name="RayCast3D" type="RayCast3D" parent="ViewMovement/Head"]
target_position = Vector3(0, 0, -2)
@@ -225,49 +225,9 @@ transform = Transform3D(0.235, 0, 0, 0, 0.235, 0, 0, 0, 0.235, -0.665, -0.275, -
[node name="SubViewport" type="SubViewport" parent="FirstPersonViewport/Head2/LeftHand"]
transparent_bg = true
size = Vector2i(1024, 512)
size = Vector2i(1400, 800)
render_target_update_mode = 4
[node name="Card10" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(544, 0)
[node name="Card9" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(512, 0)
[node name="Card8" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(480, 0)
[node name="Card7" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(448, 0)
[node name="Card6" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(416, 0)
[node name="Card5" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(384, 0)
[node name="Card4" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(352, 0)
[node name="Card3" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(320, 0)
[node name="Card2" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(288, 0)
[node name="Card1" parent="FirstPersonViewport/Head2/LeftHand/SubViewport" instance=ExtResource("4_mwtvp")]
visible = false
position = Vector2(256, 0)
[node name="Sprite2D" type="Sprite2D" parent="FirstPersonViewport/Head2/LeftHand/SubViewport"]
texture_filter = 1
position = Vector2(512, 256)
@@ -289,7 +249,7 @@ render_target_update_mode = 4
visible = false
[node name="Sprite3D" type="Sprite3D" parent="FirstPersonViewport/Head2/LeftHand"]
transform = Transform3D(0.45, 0, 0, 0, 0.45, 0, 0, 0, 0.45, 0.2, 0.19, 0)
transform = Transform3D(0.3, 0, 0, 0, 0.3, 0, 0, 0, 0.3, 1.56, -0.245, 0)
layers = 2
texture_filter = 0
texture = SubResource("ViewportTexture_8f12g")
@@ -356,7 +316,13 @@ no_depth_test = true
fixed_size = true
texture = SubResource("ViewportTexture_m3ots")
[node name="Inventory" type="Node" parent="."]
[node name="DrawPile" type="Node" parent="."]
script = ExtResource("6_cf5ap")
[node name="Hand" type="Node" parent="."]
script = ExtResource("6_cf5ap")
[node name="DiscardPile" type="Node" parent="."]
script = ExtResource("6_cf5ap")
[node name="PlayerMovement" type="Node" parent="." node_paths=PackedStringArray("player", "head")]
@@ -368,7 +334,7 @@ max_look_down_angle = 80.0
max_look_up_angle = 80.0
enable_jumping = true
[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar")]
[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar", "energy_label", "primary_duration", "secondary_duration")]
script = ExtResource("8_yl6ka")
player = NodePath("..")
wave_count = NodePath("EnemyTracker/WaveCount")
@@ -390,6 +356,9 @@ place_text = NodePath("PlaceIcon/RichTextLabel")
swap_text = NodePath("SwapIcon/RichTextLabel")
enemy_card_scene = ExtResource("18_dfkac")
new_energy_bar = NodePath("EnergyBar")
energy_label = NodePath("EnergyLabel")
primary_duration = NodePath("weapon_duration")
secondary_duration = NodePath("weapon_duration2")
[node name="FirstPersonCam" type="TextureRect" parent="HUD"]
anchors_preset = 15
@@ -773,6 +742,45 @@ texture = ExtResource("26_dfkac")
expand_mode = 3
stretch_mode = 5
[node name="EnergyLabel" type="Label" parent="HUD"]
anchors_preset = -1
anchor_left = 0.978
anchor_top = 0.341
anchor_right = 0.978
anchor_bottom = 0.341
offset_left = -103.0
offset_bottom = 40.0
grow_horizontal = 0
text = "energy = 0"
horizontal_alignment = 1
vertical_alignment = 1
[node name="weapon_duration" type="Label" parent="HUD"]
anchors_preset = -1
anchor_left = 0.978
anchor_top = 0.376
anchor_right = 0.978
anchor_bottom = 0.376
offset_left = -103.0
offset_bottom = 40.0
grow_horizontal = 0
text = "primary weapon rounds left = 0"
horizontal_alignment = 1
vertical_alignment = 1
[node name="weapon_duration2" type="Label" parent="HUD"]
anchors_preset = -1
anchor_left = 0.978
anchor_top = 0.411
anchor_right = 0.978
anchor_bottom = 0.411
offset_left = -103.0
offset_bottom = 40.0
grow_horizontal = 0
text = "secondary weapon rounds left = 0"
horizontal_alignment = 1
vertical_alignment = 1
[node name="WeaponSwapTimer" type="Timer" parent="."]
wait_time = 0.4
one_shot = true

View File

@@ -22,6 +22,9 @@ extends CanvasLayer
@export var swap_text: RichTextLabel
@export var enemy_card_scene: PackedScene
@export var new_energy_bar: EnergyBar
@export var energy_label: Label
@export var primary_duration: Label
@export var secondary_duration: Label
var last_lives_count: int = 120
var enemy_names: Array[String]
@@ -152,6 +155,10 @@ func set_currency_count(value: int) -> void:
currency_count.text = str(value)
func set_energy_amount(value: int) -> void:
energy_label.text = "energy = " + str(value)
func set_crosshair_visible(value: bool) -> void:
crosshair.set_visible(value)

View File

@@ -79,6 +79,10 @@ func card_picked_up(card_item: CardItem) -> void:
func _on_static_body_3d_button_interacted(_value: int, reply: Hero) -> void:
reply_player = reply
if reply.energy >= 3:
reply.energy -= 3
else:
return
button_collider.disabled = true
$StaticBody3D/AudioStreamPlayer3D.play()
randomize_cards(reply.hero_class.faction)

View File

@@ -29,8 +29,8 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.847404, 0.610684)
collision_layer = 16
collision_mask = 0
script = ExtResource("4_eavi1")
press_cost = 15
hover_text = "[center]#Interact# draft a card for $15"
press_cost = 3
hover_text = "[center]#Interact# draft a card for 3 Energy"
[node name="CollisionShape3D2" type="CollisionShape3D" parent="StaticBody3D"]
transform = Transform3D(1, 0, 0, 0, 0.866025, -0.5, 0, 0.5, 0.866025, -6.55949e-05, 0.349496, -0.579584)

View File

@@ -4,6 +4,8 @@ class_name TowerBase extends StaticBody3D
@export var block: Node3D
@export var collider: CollisionShape3D
@export var minimap_icon: Sprite3D
@export var duration_label: Label
@export var duration_sprites: Array[Sprite3D] = []
var game_manager: GameManager
var owner_id: int
@@ -14,6 +16,12 @@ var has_card: bool :
return
get:
return inventory.size != 0
var duration: int = 0 :
set(value):
duration = value
duration_label.text = str(value)
get():
return duration
func set_color(color: Color) -> void:
@@ -36,24 +44,44 @@ func toggle_collision() -> void:
collider.disabled = !collider.disabled
func iterate_duration() -> void:
duration -= 1
if duration <= 0:
networked_remove_tower.rpc()
func enable_duration_sprites() -> void:
for sprite: Sprite3D in duration_sprites:
sprite.visible = true
func disable_duration_sprites() -> void:
for sprite: Sprite3D in duration_sprites:
sprite.visible = false
@rpc("reliable", "call_local", "any_peer")
func networked_spawn_tower(card_index: int, caller_id: int) -> void:
var card: Card = Data.cards[card_index]
inventory.add(card)
tower = inventory.contents.keys()[0].turret_scene.instantiate() as Tower
tower.stats = inventory.contents.keys()[0].tower_stats
tower = inventory.item_at(0).turret_scene.instantiate() as Tower
tower.stats = inventory.item_at(0).tower_stats
tower.name = "tower"
tower.base_name = name
tower.owner_id = caller_id
tower.position = Vector3(0, 1.2, 0)
minimap_icon.modulate = Color.RED
duration = card.duration
enable_duration_sprites()
add_child(tower)
@rpc("reliable", "call_local", "any_peer")
func networked_remove_tower() -> void:
game_manager.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0))
game_manager.connected_players_nodes[tower.owner_id].unready_self()
inventory.remove_at(0)
#game_manager.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0))
#game_manager.connected_players_nodes[tower.owner_id].unready_self()
tower.queue_free()
disable_duration_sprites()
tower = null
minimap_icon.modulate = Color.GREEN

View File

@@ -1,21 +1,26 @@
[gd_scene load_steps=7 format=3 uid="uid://ddbbwx0yy16lh"]
[gd_scene load_steps=8 format=3 uid="uid://ddbbwx0yy16lh"]
[ext_resource type="Script" uid="uid://si58bm4r7r2i" path="res://Scenes/TowerBase/tower_base.gd" id="1_kalmg"]
[ext_resource type="Script" uid="uid://do24iuot0j7d7" path="res://Scripts/inventory.gd" id="2_m0oxx"]
[ext_resource type="Material" uid="uid://bi0grduhgdma4" path="res://Scenes/TowerBase/new_shader_material.tres" id="3_ueedj"]
[ext_resource type="ArrayMesh" uid="uid://cr83c74ys8rll" path="res://Scenes/TowerBase/textmesh.res" id="4_8j8ue"]
[ext_resource type="ArrayMesh" uid="uid://cm5xjp442ew0y" path="res://Scenes/TowerBase/textmesh.res" id="4_8j8ue"]
[ext_resource type="Texture2D" uid="uid://ba85u6i558x4w" path="res://Assets/Textures/minimap_node.png" id="4_lbvtm"]
[sub_resource type="BoxShape3D" id="BoxShape3D_lc72v"]
size = Vector3(1.381, 1.377, 1.381)
[node name="TowerBase" type="StaticBody3D" node_paths=PackedStringArray("inventory", "block", "collider", "minimap_icon") groups=["TowerBases"]]
[sub_resource type="ViewportTexture" id="ViewportTexture_ueedj"]
viewport_path = NodePath("SubViewport")
[node name="TowerBase" type="StaticBody3D" node_paths=PackedStringArray("inventory", "block", "collider", "minimap_icon", "duration_label", "duration_sprites") groups=["TowerBases"]]
collision_layer = 17
script = ExtResource("1_kalmg")
inventory = NodePath("Inventory")
block = NodePath("MeshInstance3D")
collider = NodePath("CollisionShape3D")
minimap_icon = NodePath("MinimapIcon")
duration_label = NodePath("SubViewport/Label")
duration_sprites = [NodePath("Sprite3D"), NodePath("Sprite3D2"), NodePath("Sprite3D3"), NodePath("Sprite3D4")]
[node name="Inventory" type="Node" parent="."]
script = ExtResource("2_m0oxx")
@@ -35,3 +40,42 @@ layers = 4
modulate = Color(0, 1, 0, 1)
texture_filter = 0
texture = ExtResource("4_lbvtm")
[node name="SubViewport" type="SubViewport" parent="."]
transparent_bg = true
size = Vector2i(128, 128)
[node name="Label" type="Label" parent="SubViewport"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 128
text = "4"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Sprite3D" type="Sprite3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0.6)
visible = false
double_sided = false
texture = SubResource("ViewportTexture_ueedj")
[node name="Sprite3D2" type="Sprite3D" parent="."]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0, 2, -0.6)
visible = false
double_sided = false
texture = SubResource("ViewportTexture_ueedj")
[node name="Sprite3D3" type="Sprite3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.6, 2, 0)
visible = false
double_sided = false
texture = SubResource("ViewportTexture_ueedj")
[node name="Sprite3D4" type="Sprite3D" parent="."]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.6, 2, 0)
visible = false
double_sided = false
texture = SubResource("ViewportTexture_ueedj")

View File

@@ -4,12 +4,14 @@
[ext_resource type="Texture2D" uid="uid://dlqnhs8or4ik2" path="res://Assets/Textures/cardhand.png" id="1_d5oo3"]
[ext_resource type="Texture2D" uid="uid://buf8t5gc7iw3a" path="res://Assets/TextureAtlases/rarityborders.tres" id="3_pclfx"]
[node name="Node2D" type="Node2D" node_paths=PackedStringArray("rarity_sprite", "title_text", "description", "target_label")]
[node name="Node2D" type="Node2D" node_paths=PackedStringArray("rarity_sprite", "title_text", "description", "target_label", "energy_cost", "duration")]
script = ExtResource("1_2cfmh")
rarity_sprite = NodePath("Sprite2D2")
title_text = NodePath("Title")
description = NodePath("Description")
target_label = NodePath("Title2")
energy_cost = NodePath("EnergyCost")
duration = NodePath("Duration")
[node name="Sprite2D" type="Sprite2D" parent="."]
texture_filter = 1
@@ -60,3 +62,23 @@ text = "In here goes some card text that really be quite long sometimes if you'r
In fact, sometimes its really really really rediculously long, when it needs to be and im too dumb to shorten it"
fit_content = true
[node name="EnergyCost" type="Label" parent="."]
offset_left = 340.0
offset_top = 55.0
offset_right = 40.0
offset_bottom = 40.0
theme_override_colors/font_color = Color(0.228497, 0.570097, 0.884935, 1)
text = "3"
horizontal_alignment = 1
vertical_alignment = 1
[node name="Duration" type="Label" parent="."]
offset_left = 125.0
offset_top = 55.0
offset_right = 42.0
offset_bottom = 95.0
theme_override_colors/font_color = Color(0.228497, 0.570097, 0.884935, 1)
text = "4"
horizontal_alignment = 1
vertical_alignment = 1

View File

@@ -7,6 +7,7 @@ enum Faction {
MAGE = 2,
}
@export var duration: int
@export var rarity: Data.Rarity
@export var faction: Faction
@export var turret_scene: PackedScene

View File

@@ -22,6 +22,7 @@ var recharging: bool = false
var recharge_speed: float = 0.0
var recharge_acceleration: float = 2.0
var recharge_max_speed: float = 25.0
var duration: int = 0
#var time_since_trigger: float = 0.0

View File

@@ -6,6 +6,8 @@ var stats: Card
@export var title_text: Label
@export var description: RichTextLabel
@export var target_label: Label
@export var energy_cost: Label
@export var duration: Label
func set_card(value: Card) -> void:
@@ -13,6 +15,17 @@ func set_card(value: Card) -> void:
title_text.text = stats.display_name
target_label.text = str(Data.TargetType.keys()[stats.tower_stats.target_type])
rarity_sprite.region_rect = Rect2(64 * stats.rarity, 0, 64, 64)
if stats.rarity == Data.Rarity.COMMON:
energy_cost.text = "1"
if stats.rarity == Data.Rarity.UNCOMMON:
energy_cost.text = "2"
if stats.rarity == Data.Rarity.RARE:
energy_cost.text = "3"
if stats.rarity == Data.Rarity.EPIC:
energy_cost.text = "4"
if stats.rarity == Data.Rarity.LEGENDARY:
energy_cost.text = "5"
duration.text = str(value.duration)
func process_card_text(card_text: CardText) -> String:

View File

@@ -18,6 +18,7 @@ enum TargetType {UNDEFINED = 0, LAND = 1, AIR = 2, BOTH = 3}
enum EnemyType {UNDEFINED = 0, LAND = 1, AIR = 2}
enum Rarity {COMMON = 0, UNCOMMON = 1, RARE = 2, EPIC = 3, LEGENDARY = 4}
static var starting_cash: int = 10
static var wall_cost: int = 1
static var printer_cost: int = 15
static var rarity_weights: Dictionary = {

View File

@@ -27,7 +27,6 @@ var pot: float
var UILayer: CanvasLayer
var chatbox: Chatbox
var wave_limit: int = 20
var starting_cash: int = 25
var shop_chance: float = 0.0
var stats: RoundStats
@@ -175,6 +174,8 @@ func spawn_enemy_wave() -> void:
#spawn.path.disable_visualization()
spawn.visible = false
spawn.spawn_wave()
for tower_base: TowerBase in level.walls.values():
tower_base.disable_duration_sprites()
wave_started.emit(wave)
@@ -245,10 +246,18 @@ func damage_goal(enemy: Enemy, penalty: int) -> void:
func end_wave() -> void:
for peer_id: int in connected_players_nodes:
connected_players_nodes[peer_id].currency += ceili(pot / connected_players_nodes.size())
connected_players_nodes[peer_id].unready_self()
var player: Hero = connected_players_nodes[peer_id] as Hero
player.currency += ceili(pot / connected_players_nodes.size())
player.energy = 8
player.iterate_duration()
player.draw_to_hand_size()
player.unready_self()
for spawn: EnemySpawner in level.enemy_spawns:
spawn.visible = true
for tower_base: TowerBase in level.walls.values():
if tower_base.has_card:
tower_base.enable_duration_sprites()
tower_base.iterate_duration()
#level.a_star_graph_3d.enable_non_path_tower_frames()
level.enable_non_path_tower_frames()
if is_multiplayer_authority():
@@ -308,7 +317,10 @@ func start() -> void:
#Relies on player list having been decided
spawn_players()
for peer_id: int in connected_players_nodes:
connected_players_nodes[peer_id].currency = ceili(float(starting_cash) / float(connected_players_nodes.size()))
connected_players_nodes[peer_id].currency = ceili(float(Data.starting_cash) / float(connected_players_nodes.size()))
connected_players_nodes[peer_id].energy = 8
connected_players_nodes[peer_id].draw_pile.shuffle()
connected_players_nodes[peer_id].draw_to_hand_size()
#Relies on rng having been seeded
set_upcoming_wave()
@@ -318,7 +330,7 @@ func start() -> void:
level.generate_obstacles()
level.enable_non_path_tower_frames()
#level.a_star_graph_3d.disable_all_tower_frames()
#level.a_star_graph_3d.enable_non_path_tower_frames()z
#level.a_star_graph_3d.enable_non_path_tower_frames()
#level.a_star_graph_3d.find_path()
#Start game

View File

@@ -5,53 +5,58 @@ signal item_added(item: Item)
signal item_removed(item: Item)
@export var max_size: int = 0
var contents: Dictionary = {}
var shuffle_count: int = 0
var contents: Array[Item] = []
var size: int :
get:
var x: int = 0
for key: Item in contents:
x += contents[key]
return x
set(_value):
return
get:
return contents.size()
func add(item: Item) -> bool:
if item != null and max_size == 0 or size < max_size:
if contents.has(item):
contents[item] += 1
else:
contents[item] = 1
contents.append(item)
item_added.emit(item)
#networked_add.rpc(Data.cards.find(item))
return true
return false
func remove_at(index: int) -> Item:
var item: Item = contents.keys()[index]
contents[item] -= 1
if contents[item] == 0:
contents.erase(item)
item_removed.emit(item)
#networked_remove_at.rpc(index)
func item_at(index: int) -> Item:
#if size == 0:
#return null
var item: Item = contents[index]
return item
@rpc("reliable", "any_peer")
func networked_add(value: int) -> void:
var item: Item = Data.cards[value]
if contents.has(item):
contents[item] += 1
else:
contents[item] = 1
item_added.emit(item)
@rpc("reliable", "any_peer")
func networked_remove_at(value: int) -> void:
var item: Item = contents.keys()[value]
contents[item] -= 1
if contents[item] == 0:
contents.erase(item)
func remove_at(index: int) -> Item:
var item: Item = contents.pop_at(index)
item_removed.emit(item)
return item
func shuffle() -> void:
var new_contents: Array[Item] = []
for x: int in contents.size():
new_contents.append(contents.pop_at(NoiseRandom.randi_in_range(shuffle_count * 9, 0, contents.size() - 1)))
contents = new_contents
#@rpc("reliable", "any_peer")
#func networked_add(value: int) -> void:
#var item: Item = Data.cards[value]
#if contents.has(item):
#contents[item] += 1
#else:
#contents[item] = 1
#item_added.emit(item)
#
#
#@rpc("reliable", "any_peer")
#func networked_remove_at(value: int) -> void:
#var item: Item = contents.keys()[value]
#contents[item] -= 1
#if contents[item] == 0:
#contents.erase(item)
#item_removed.emit(item)

View File

@@ -58,7 +58,7 @@ func set_wall(point: FlowNode, caller_id: int) -> void:
func remove_wall(point: FlowNode) -> void:
var wall: TowerBase = walls[point]
game_manager.connected_players_nodes[wall.owner_id].currency += Data.wall_cost
#game_manager.connected_players_nodes[wall.owner_id].currency += Data.wall_cost
game_manager.connected_players_nodes[wall.owner_id].unready_self()
walls.erase(point)
wall.queue_free()

View File

@@ -13,7 +13,7 @@ extends Object
## Takes in wave number and number of players and returns a spawn power value
## intended for passing into the generate_wave method
static func calculate_spawn_power(wave_number: int, number_of_players: int) -> int:
return (30 * number_of_players) + (6 * wave_number)
return (20 * number_of_players) + (5 * wave_number)
## Takes in wave number and number of players and returns the amount of coins

View File

@@ -21,5 +21,6 @@ value = 8.0
[resource]
script = ExtResource("2_1vuma")
target_type = 1
energy_type = 0
attributes = Array[ExtResource("1_eglp5")]([SubResource("Resource_yb48y"), SubResource("Resource_ewwvw"), SubResource("Resource_qu5dv")])
text = "Launch a bomb that deals /Damage\\ damage every /Fire Delay\\ seconds"

View File

@@ -21,5 +21,6 @@ value = 2.0
[resource]
script = ExtResource("2_226sm")
target_type = 1
energy_type = 0
attributes = Array[ExtResource("1_ytycf")]([SubResource("Resource_gbocu"), SubResource("Resource_6a2im"), SubResource("Resource_7npe0")])
text = "Fires every /Fire Delay\\s, making the target Sticky at a range of /Range\\m"

View File

@@ -26,5 +26,6 @@ value = 20.0
[resource]
script = ExtResource("2_lag26")
target_type = 2
energy_type = 0
attributes = Array[ExtResource("1_jajj0")]([SubResource("Resource_4fjm2"), SubResource("Resource_uwj4j"), SubResource("Resource_6qv5v"), SubResource("Resource_y1rtq")])
text = "Every /Fire Delay\\s, fires a homing rocket at up to /Target Limit\\ flying enemies up to /Range\\m away that deal /Damage\\ damage"

View File

@@ -6,7 +6,7 @@
[sub_resource type="Resource" id="Resource_fi7tc"]
script = ExtResource("1_7oh83")
key = "Fire Delay"
value = 0.4
value = 0.3
[sub_resource type="Resource" id="Resource_r6h5d"]
script = ExtResource("1_7oh83")
@@ -31,7 +31,7 @@ value = 4.0
[sub_resource type="Resource" id="Resource_d1lvi"]
script = ExtResource("1_7oh83")
key = "Energy"
value = 20.0
value = 30.0
[resource]
script = ExtResource("2_y36gr")