we're so close to working multiplayer

This commit is contained in:
2023-11-16 00:07:41 +11:00
parent 1500c22ccc
commit 2d123bd731
81 changed files with 578 additions and 388 deletions

View File

@ -10,6 +10,10 @@ var lifetime := 10.0
var time_alive := 0.0
func _ready() -> void:
apply_central_impulse(direction * force)
func _process(delta: float) -> void:
time_alive += delta

View File

@ -6,7 +6,7 @@ enum Faction {GENERIC = 0}
@export var title : String
@export var rarity : Data.Rarity
@export var faction : Faction
@export var sprite : AtlasTexture
@export var sprite : Texture
@export var turret_scene : PackedScene
@export var weapon_scene : PackedScene
@export var weapon_stats : CardText

View File

@ -2,5 +2,5 @@ extends Resource
class_name HeroClass
@export var hero_name : String = "Default"
@export var texture : AtlasTexture
@export var texture : Texture
@export var deck : Array[Card]

View File

@ -12,6 +12,10 @@ const SAVE_PATH := "user://preferences.tres"
@export var windowed_mode := 0
@export var hfov := 100.0
@export var fixed_minimap := false
@export var display_tower_damage_indicators := true
@export var display_self_damage_indicators := true
@export var display_party_damage_indicators := true
@export var display_status_effect_damage_indicators := true
func apply_graphical_settings(viewport):

View File

@ -55,6 +55,6 @@ func add_effect(new_effect : StatusEffect):
existing_effect.on_attached(enemy, effects)
icons[existing_effect].set_visible(true)
effects[existing_effect] += 1
existing_effect.time_existed = 0.0
existing_effect.time_existed = 0.0
if existing_effect.stats.max_stacks != 0 and effects[existing_effect] > existing_effect.stats.max_stacks:
effects[existing_effect] = existing_effect.stats.max_stacks

View File

@ -3,7 +3,7 @@ class_name ProjectileTower
@export var projectile_scene : PackedScene
var force := 2.0
var force := 20.0
var projectile_id := 0

View File

@ -0,0 +1,22 @@
extends HitscanTower
class_name StatusApplyingTower
@export var status_stats : StatusStats
func shoot():
super.shoot()
if targeted_enemy and is_instance_valid(targeted_enemy) and targeted_enemy.alive:
targeted_enemy.damage(damage)
targeted_enemy.status_manager.add_effect(build_status_object())
func build_status_object() -> StatusEffect:
var status = StatusEffect.new()
status.stats = status_stats
return status
@rpc("reliable")
func networked_shoot():
super.networked_shoot()

View File

@ -23,6 +23,8 @@ func shoot():
var target_hitbox = target.shape_owner_get_owner(raycast.get_collider_shape())
if target_hitbox is Hitbox:
hit(target, target_hitbox)
if Data.preferences.display_self_damage_indicators:
spawn_damage_indicator(raycast.get_collision_point())
networked_hit.rpc(get_tree().root.get_path_to(target), get_tree().root.get_path_to(target_hitbox))
@ -35,3 +37,5 @@ func networked_hit(target_path : String, target_hitbox_path : String):
var target = get_tree().root.get_node(target_path)
var target_hitbox = get_tree().root.get_node(target_hitbox_path) as Hitbox
hit(target, target_hitbox)
if Data.preferences.display_party_damage_indicators:
spawn_damage_indicator(target.sprite.global_position)

View File

@ -3,23 +3,27 @@ class_name ProjectileWeapon
@export var projectile_scene : PackedScene
var force := 2.0
var force := 20.0
var projectile_id := 0
func shoot():
super.shoot()
var projectile = projectile_scene.instantiate() as Projectile
projectile.position = global_position
projectile.damage = damage
projectile.direction = -global_transform.basis.z
projectile.force = force
projectile.name = str(multiplayer.get_unique_id()) + str(projectile_id)
get_tree().root.add_child(projectile)
projectile_id += 1
networked_spawn_projectile.rpc(multiplayer.get_unique_id(), -global_transform.basis.z)
@rpc("reliable")
func networked_shoot():
super.networked_shoot()
shoot()
@rpc("reliable", "call_local")
func networked_spawn_projectile(peer_id, direction):
var projectile = projectile_scene.instantiate() as Projectile
projectile.position = global_position
projectile.damage = damage
projectile.direction = direction
projectile.force = force
projectile.name = str(peer_id) + str(projectile_id)
get_tree().root.add_child(projectile)
projectile_id += 1

View File

@ -4,6 +4,7 @@ class_name Weapon
@export var stats : CardText
@export var animator : AnimationPlayer
var damage_particle_scene = preload("res://Scenes/damage_particle.tscn")
var hero : Hero
var trigger_held := false
var second_trigger_held := false
@ -49,6 +50,14 @@ func release_second_trigger():
second_trigger_held = false
func spawn_damage_indicator(pos):
if damage > 0:
var marker = damage_particle_scene.instantiate()
get_tree().root.add_child(marker)
marker.set_number(damage)
marker.position = pos
func shoot():
animator.play("shoot")

View File

@ -5,10 +5,12 @@ var stats : Card
@export var rarity_sprite : Sprite2D
@export var title_text : Label
@export var description : RichTextLabel
@export var target_label : Label
func set_card(value):
stats = value
title_text.text = stats.title
target_label.text = str(Data.TargetType.keys()[stats.tower_stats.target_type])
rarity_sprite.region_rect = Rect2(64 * stats.rarity, 0, 64, 64)
@ -23,7 +25,9 @@ func process_card_text(card_text : CardText) -> String:
func view_weapon():
description.text = process_card_text(stats.weapon_stats)
target_label.text = "Both"
func view_tower():
description.text = process_card_text(stats.tower_stats)
target_label.text = str(stats.tower_stats.target_type)

View File

@ -33,6 +33,8 @@ func randomize_cards():
card = card_array.pick_random()
card_array.erase(card)
x.set_card(card)
#TODO: in reality this should just show the icon and then hovering over it lets you see either side at the players own discretion
x.view_tower()
$Node3D.set_visible(true)
for x in choice_colliders:
x.disabled = false

View File

@ -38,16 +38,16 @@ func _ready() -> void:
cards.append(preload("res://PCs/Universal/ClassCards/Gatling/card_gatling.tres"))
cards.append(preload("res://PCs/Universal/ClassCards/RocketLauncher/card_rocket_launcher.tres"))
#Uncommon
#cards.append(preload("res://PCs/Universal/ClassCards/Blowdart/card_blowdart.tres"))
cards.append(preload("res://PCs/Universal/ClassCards/Blowdart/card_blowdart.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/Refridgerator/card_refridgerator.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/GlueLauncher/card_glue_launcher.tres"))
cards.append(preload("res://PCs/Universal/ClassCards/GlueLauncher/card_glue_launcher.tres"))
#Rare
#cards.append(preload("res://PCs/Universal/ClassCards/Flamethrower/card_flamethrower.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/DamageEnhancer/card_damage_enhancer.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/SpeedEnhancer/card_speed_enhancer.tres"))
#Epic
#cards.append(preload("res://PCs/Universal/ClassCards/Icicle/card_icicle.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/Fireball/card_fireball.tres"))
cards.append(preload("res://PCs/Universal/ClassCards/Icicle/card_icicle.tres"))
cards.append(preload("res://PCs/Universal/ClassCards/Fireball/card_fireball.tres"))
#cards.append(preload("res://PCs/Universal/ClassCards/GammaLaser/card_gamma_laser.tres"))
#Legendary
cards.append(preload("res://PCs/Universal/ClassCards/Sniper/card_sniper.tres"))

View File

@ -95,6 +95,7 @@ func spawn_tower_preview():
last_card = card
tower_preview = card.turret_scene.instantiate() as Tower
tower_preview.stats = card.tower_stats
tower_preview.position = Vector3.UP
tower_preview.preview_range(true)
ray_collider.add_child(tower_preview)

View File

@ -59,9 +59,11 @@ func spawn_players(player_array, player_profiles, chatbox_open_signal, chatbox_c
for peer_id in player_array:
var player = player_scene.instantiate() as Hero
player.name = str(peer_id)
player.player_name_tag.text = player_profiles[peer_id].display_name
player.position = level.player_spawns[p_i].global_position
player.profile = player_profiles[peer_id]
player.hero_class = Data.characters[player_profiles[peer_id].preferred_class]
print(player.hero_class.hero_name)
player.ready_state_changed.connect(ready_player)
if peer_id == multiplayer.get_unique_id():
chatbox_open_signal.connect(player.pause)
@ -152,14 +154,15 @@ func end_wave():
func remove_player(peer_id):
connected_players_nodes[peer_id].queue_free()
connected_players_nodes.erase(peer_id)
if connected_players_nodes.has(peer_id):
connected_players_nodes[peer_id].queue_free()
connected_players_nodes.erase(peer_id)
func start_game():
game_active = true
enemies = 0
objective_health = 100
objective_health = 120
wave = 0
level.a_star_graph_3d.make_grid()
level.a_star_graph_3d.find_path()
@ -176,7 +179,7 @@ func restart_game():
connected_players_nodes.clear()
level.queue_free()
enemies = 0
objective_health = 100
objective_health = 120
wave = 0
spawn_level()
game_restarted.emit()

View File

@ -10,11 +10,6 @@ signal health_changed(health)
var current_health
func take_damage(damage):
#var marker = damage_particle_scene.instantiate()
#get_tree().root.add_child(marker)
#marker.set_number(damage)
#marker.position = get_parent().global_position + Vector3.UP
current_health -= damage
health_changed.emit(current_health)
if current_health <= 0:

View File

@ -28,11 +28,11 @@ func _ready():
func _on_player_connected(peer_id):
add_player.rpc_id(peer_id, Data.player_profile.to_dict())
if multiplayer.get_unique_id() == 1:
print("Player connected with id: " + str(peer_id))
func _on_player_disconnected(peer_id):
if chatbox:
chatbox.append_message("SERVER", connected_players_profiles[peer_id].display_name + " has disconnected!")
connected_players_profiles.erase(peer_id)
player_disconnected.emit(peer_id)
@ -115,6 +115,8 @@ func networked_edit_player_profile(peer_id, new_profile_dict):
func add_player(new_player_profile_dict):
var new_player_peer_id = multiplayer.get_remote_sender_id()
var new_player_profile = PlayerProfile.from_dict(new_player_profile_dict)
if chatbox:
chatbox.append_message("SERVER", new_player_profile.display_name + " has connected!")
connected_players_profiles[new_player_peer_id] = new_player_profile
player_connected.emit(new_player_peer_id, new_player_profile)

View File

@ -13,6 +13,10 @@ class_name OptionsMenu
@export var fov_input : SpinBox
@export var fov_slider : HSlider
@export var fixed_minimap : CheckButton
@export var tower_damage : Button
@export var self_damage : Button
@export var party_damage : Button
@export var status_damage : Button
var keybind_boxes = []
var keybind_buttons = {}
var key_event
@ -31,7 +35,10 @@ func _ready():
fov_input.value = Data.preferences.hfov
fov_slider.value = Data.preferences.hfov
fixed_minimap.button_pressed = Data.preferences.fixed_minimap
tower_damage.button_pressed = Data.preferences.display_tower_damage_indicators
self_damage.button_pressed = Data.preferences.display_self_damage_indicators
party_damage.button_pressed = Data.preferences.display_party_damage_indicators
status_damage.button_pressed = Data.preferences.display_status_effect_damage_indicators
for index in Data.keymaps.size():
var map = Data.keymaps[index]
var button = Button.new()
@ -85,6 +92,10 @@ func _on_confirm_pressed() -> void:
Data.preferences.invert_lookY = invert_lookY.button_pressed
Data.preferences.invert_lookX = invert_lookX.button_pressed
Data.preferences.fixed_minimap = fixed_minimap.button_pressed
Data.preferences.display_tower_damage_indicators = tower_damage.button_pressed
Data.preferences.display_self_damage_indicators = self_damage.button_pressed
Data.preferences.display_party_damage_indicators = party_damage.button_pressed
Data.preferences.display_status_effect_damage_indicators = status_damage.button_pressed
Data.preferences.apply_graphical_settings(get_viewport())
Data.preferences.save_profile_to_disk()
Data.player_keymap.save_profile_to_disk()

View File

@ -7,7 +7,7 @@ func calculate_spawn_power(wave_number : int, number_of_players : int) -> int:
func generate_wave(spawn_power : int, spawn_pool : Array[Enemy]) -> Dictionary:
var wave = {}
var sp_used = 0
#var sp_used = 0
var enemy_types = randi_range(1, 5)
var enemy_choices = spawn_pool.duplicate()
var sp_allotment = floori(spawn_power / enemy_types)
@ -16,6 +16,6 @@ func generate_wave(spawn_power : int, spawn_pool : Array[Enemy]) -> Dictionary:
enemy_choices.erase(choice)
if sp_allotment / choice.spawn_power > 0:
wave[Data.enemies.find(choice)] = sp_allotment / choice.spawn_power
sp_used += wave[Data.enemies.find(choice)] * choice.spawn_power
print("tried to generate wave with " + str(spawn_power) + " spawn power, used " + str(sp_used))
#sp_used += wave[Data.enemies.find(choice)] * choice.spawn_power
#print("Generated wave with spawn power: " + str(sp_used) + "/" + str(spawn_power))
return wave