Work on pickups and multiplayer
This commit is contained in:
@@ -65,8 +65,8 @@ func is_multiplayer() -> bool:
|
||||
return multiplayer_game
|
||||
|
||||
|
||||
func start_level(pawns : Dictionary[int, StringName]) -> void:
|
||||
pawns_selected = pawns
|
||||
func start_level(pawn_dict : Dictionary[int, StringName]) -> void:
|
||||
pawns_selected = pawn_dict
|
||||
if !Multiplayer.is_host():
|
||||
return
|
||||
|
||||
@@ -135,11 +135,11 @@ func level_spawned(peer_id : int) -> void:
|
||||
check_level_ready()
|
||||
|
||||
func check_level_ready() -> void:
|
||||
var ready : bool = true
|
||||
var level_ready : bool = true
|
||||
for id in level_synced:
|
||||
if level_synced[id] == false:
|
||||
ready = false
|
||||
if ready:
|
||||
level_ready = false
|
||||
if level_ready:
|
||||
level.setup()
|
||||
|
||||
func oneshot(stream : AudioStream) -> void:
|
||||
|
||||
@@ -81,26 +81,26 @@ func is_server() -> bool:
|
||||
func is_host() -> bool:
|
||||
return id == 1
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
if waiting:
|
||||
var ready : bool = true
|
||||
var group_ready : bool = true
|
||||
for pr in player_readiness.values():
|
||||
if !pr:
|
||||
ready = false
|
||||
group_ready = false
|
||||
break
|
||||
if ready:
|
||||
if group_ready:
|
||||
all_ready.emit()
|
||||
waiting = false
|
||||
for pr in player_readiness.keys():
|
||||
player_readiness[pr] = false
|
||||
|
||||
func _add_player_to_game(id : int) -> void:
|
||||
print("Player %s joined the game!" % id)
|
||||
func _add_player_to_game(pid : int) -> void:
|
||||
print("Player %s joined the game!" % pid)
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
get_handle_from_peer(id)
|
||||
get_handle_from_peer(pid)
|
||||
|
||||
func _remove_player_from_game(id : int) -> void:
|
||||
print("Player %s left the game!" % id)
|
||||
func _remove_player_from_game(pid : int) -> void:
|
||||
print("Player %s left the game!" % pid)
|
||||
|
||||
func get_handle_from_peer(peer_id) -> void:
|
||||
rpc_id(peer_id, "report_handle_to_peer", id)
|
||||
|
||||
17
scripts/collectable.gd
Normal file
17
scripts/collectable.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
class_name Pickup extends Area3D
|
||||
|
||||
|
||||
enum Type{
|
||||
DATABLOCK,
|
||||
INTEGRITY,
|
||||
SCAN,
|
||||
BASIC_HACK,
|
||||
ADVANCED_HACK
|
||||
}
|
||||
|
||||
@export var type : Type
|
||||
|
||||
func _on_body_entered(body: Node3D) -> void:
|
||||
if body is PawnController:
|
||||
body.pickup(type)
|
||||
queue_free()
|
||||
1
scripts/collectable.gd.uid
Normal file
1
scripts/collectable.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://du3s0b1kotb6l
|
||||
@@ -10,7 +10,7 @@ func _on_melee_range_changed(melee : bool) -> void:
|
||||
range_attack_button.visible = !melee
|
||||
melee_attack_button.visible = melee
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
hack_button.set_pressed_no_signal(Input.is_action_pressed("install"))
|
||||
detect_button.set_pressed_no_signal(Input.is_action_pressed("detect"))
|
||||
switch_button.set_pressed_no_signal(Input.is_action_pressed("detonate"))
|
||||
|
||||
@@ -47,7 +47,7 @@ var decompiling : bool
|
||||
var failed : bool
|
||||
var difficulty : int = 1
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
timer_label.text = "%02f.3" % timer.time_left
|
||||
|
||||
func start_decompiling() -> void:
|
||||
@@ -109,5 +109,5 @@ func succeed() -> void:
|
||||
func _on_hack_failed() -> void:
|
||||
fail()
|
||||
|
||||
func _on_hack_removed(type : Hack.Type) -> void:
|
||||
func _on_hack_removed(_type : Hack.Type) -> void:
|
||||
Game.player.close_modal()
|
||||
|
||||
@@ -22,25 +22,25 @@ func _on_timeout() -> void:
|
||||
|
||||
func spread() -> void:
|
||||
var new_squares : Dictionary[Vector3i, bool] = {}
|
||||
for square in last_spread:
|
||||
for sq in last_spread:
|
||||
for i in range(-1, 2):
|
||||
for j in range(-1, 2):
|
||||
for k in range(-1, 2):
|
||||
var ts = square + Vector3i(i, j, k)
|
||||
new_squares[square + Vector3i(i, j, k)] = true
|
||||
#var ts = sq + Vector3i(i, j, k)
|
||||
new_squares[sq + Vector3i(i, j, k)] = true
|
||||
last_spread = []
|
||||
for square in new_squares.keys():
|
||||
if squares.has(square):
|
||||
for sq in new_squares.keys():
|
||||
if squares.has(sq):
|
||||
continue
|
||||
var floor_square = square + Vector3i(0,-1,0)
|
||||
var floor_square = sq + Vector3i(0,-1,0)
|
||||
if(Game.level.floor_layer.get_cell_item(floor_square) == GridMap.INVALID_CELL_ITEM
|
||||
and Game.level.ramp_layer.get_cell_item(floor_square) == GridMap.INVALID_CELL_ITEM):
|
||||
continue
|
||||
last_spread.append(square)
|
||||
squares[square] = true
|
||||
emit_gas(square)
|
||||
last_spread.append(sq)
|
||||
squares[sq] = true
|
||||
emit_gas(sq)
|
||||
|
||||
func emit_gas(square) -> void:
|
||||
func emit_gas(sq) -> void:
|
||||
var gas = gas_square_template.instantiate()
|
||||
gas.setup(hack_owner, damage)
|
||||
Game.level.add_vfx(gas, square)
|
||||
Game.level.add_vfx(gas, sq)
|
||||
|
||||
@@ -16,9 +16,9 @@ func _physics_process(delta: float) -> void:
|
||||
if time_remaining <= 0:
|
||||
queue_free()
|
||||
|
||||
func setup(owner, damage) -> void:
|
||||
self.hack_owner = hack_owner
|
||||
self.damage = damage
|
||||
func setup(h_owner, dam) -> void:
|
||||
hack_owner = h_owner
|
||||
damage = dam
|
||||
time_remaining = 2.0
|
||||
|
||||
func _on_body_entered(body: Node3D) -> void:
|
||||
|
||||
@@ -26,10 +26,10 @@ const hack_icons : Dictionary = {
|
||||
Hack.Type.PURGE : preload("res://external/purge-icon.png"),
|
||||
}
|
||||
|
||||
const destroy_explosion_template = preload("res://templates/explosion.tscn")
|
||||
const purge_explosion_template = preload("res://templates/explosion.tscn")
|
||||
const destroy_explosion_template = preload("res://experimental/BinbunVFX/impact_explosions/effects/explosion/vfx_explosion_01.tscn")
|
||||
const purge_explosion_template = preload("res://experimental/BinbunVFX/impact_explosions/effects/explosion/vfx_explosion_03.tscn")
|
||||
const contain_template = preload("res://templates/pitfall.tscn")
|
||||
const trigger_explosion_template = preload("res://templates/explosion.tscn")
|
||||
const trigger_explosion_template = preload("res://experimental/BinbunVFX/impact_explosions/effects/explosion/vfx_explosion_04.tscn")
|
||||
const infect_emitter_template = preload("res://templates/gas_emitter.tscn")
|
||||
const force_activate_sound = preload("res://audio/sounds/TomWinandySFX_UI_ScifiTech_Start_06.wav")
|
||||
|
||||
@@ -69,13 +69,13 @@ func _enter_tree() -> void:
|
||||
func _exit_tree() -> void:
|
||||
Game.level.remove_map_marker(self)
|
||||
|
||||
func setup(type : Type, direction : Vector3, hack_owner : int) -> void:
|
||||
self.type = type
|
||||
self.hack_owner = hack_owner
|
||||
func setup(new_type : Type, dir : Vector3, h_owner : int) -> void:
|
||||
type = new_type
|
||||
hack_owner = h_owner
|
||||
if type == Type.REDIRECT:
|
||||
var r : float = atan2(direction.z, direction.x)
|
||||
var r : float = atan2(dir.z, dir.x)
|
||||
var cardinal : float = roundi(r * 2 / PI) * PI / 2
|
||||
self.direction = Vector3(cos(cardinal), 0, sin(cardinal))
|
||||
direction = Vector3(cos(cardinal), 0, sin(cardinal))
|
||||
|
||||
func remove() -> void:
|
||||
removed.emit(type)
|
||||
@@ -127,7 +127,7 @@ func _ready() -> void:
|
||||
force_strip.rotate_y(r)
|
||||
force_strip.visible = owns_hack
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
just_revealed = false
|
||||
|
||||
func blast(body : PawnController) -> void:
|
||||
@@ -149,16 +149,16 @@ func activate() -> void:
|
||||
for body in get_overlapping_bodies():
|
||||
body.fling(direction, 5.0)
|
||||
Type.PURGE:
|
||||
var exp = purge_explosion_template.instantiate()
|
||||
Game.level.add_vfx(exp, square)
|
||||
var expl = purge_explosion_template.instantiate()
|
||||
Game.level.add_vfx(expl, square)
|
||||
explode = true
|
||||
Type.TRIGGER:
|
||||
var exp = trigger_explosion_template.instantiate()
|
||||
Game.level.add_vfx(exp, square)
|
||||
var expl = trigger_explosion_template.instantiate()
|
||||
Game.level.add_vfx(expl, square)
|
||||
explode = true
|
||||
Type.DESTROY:
|
||||
var exp = destroy_explosion_template.instantiate()
|
||||
Game.level.add_vfx(exp, square)
|
||||
var expl = destroy_explosion_template.instantiate()
|
||||
Game.level.add_vfx(expl, square)
|
||||
explode = true
|
||||
Type.INFECT:
|
||||
var emitter = infect_emitter_template.instantiate()
|
||||
@@ -181,10 +181,10 @@ func trigger_adjacent_bombs() -> void:
|
||||
if hack.type == Type.DESTROY and hack != self:
|
||||
hack.delay_trigger()
|
||||
|
||||
func generate_contain(square : Vector3i) -> void:
|
||||
func generate_contain(sq : Vector3i) -> void:
|
||||
var contain = contain_template.instantiate()
|
||||
contain.duration = 6.0
|
||||
Game.level.add_vfx(contain, square)
|
||||
Game.level.add_vfx(contain, sq)
|
||||
|
||||
func blast_players() -> void:
|
||||
for body in range_area.get_overlapping_bodies():
|
||||
@@ -206,7 +206,7 @@ func _on_body_entered(body: Node3D) -> void:
|
||||
return
|
||||
|
||||
if !decompiling or body.id != decompile_id:
|
||||
if !body.detecting:
|
||||
if !body.is_detecting():
|
||||
activate()
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ func proximal_shake(distance : float) -> void:
|
||||
var d = global_position.distance_squared_to(Game.player.global_position)
|
||||
var d_sq = distance * distance
|
||||
if d <= d_sq:
|
||||
var str : float = (d_sq - d) / d_sq
|
||||
var l_val : float = lerp(0.0, 1.0, str)
|
||||
Input.start_joy_vibration(0, l_val,l_val,lerp(0.5, 1.0, str))
|
||||
var strength : float = (d_sq - d) / d_sq
|
||||
var l_val : float = lerp(0.0, 1.0, strength)
|
||||
Input.start_joy_vibration(0, l_val,l_val,lerp(0.5, 1.0, strength))
|
||||
Game.player.camera.add_trauma(l_val)
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ func _ready() -> void:
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
pass
|
||||
|
||||
func _on_health_changed(current : int, max : int) -> void:
|
||||
max_value = max
|
||||
func _on_health_changed(current : int, max_amt : int) -> void:
|
||||
max_value = max_amt
|
||||
value = current
|
||||
|
||||
func _on_poison_status_changed(poisoned : bool) -> void:
|
||||
|
||||
@@ -25,6 +25,6 @@ func set_ammo(ammo : int) -> void:
|
||||
ammo_label.text = str(ammo)
|
||||
ammo_label.modulate = Color.DIM_GRAY if ammo == 0 else Color.WHITE
|
||||
|
||||
func _on_ammo_changed(current : int, max : int) -> void:
|
||||
func _on_ammo_changed(current : int, _max_amt : int) -> void:
|
||||
set_ammo(current)
|
||||
|
||||
|
||||
@@ -56,13 +56,13 @@ func spawn_players_singleplayer() -> void:
|
||||
var pc : PawnController = pawn_controller.instantiate()
|
||||
pawns[1] = pc
|
||||
pawns_node.add_child(pc,true)
|
||||
var position : Vector3
|
||||
var pos : Vector3
|
||||
if(spawn_points == null
|
||||
or len(spawn_points) <= 1):
|
||||
position = Vector3(0,0,0)
|
||||
pos = Vector3(0,0,0)
|
||||
else:
|
||||
position = spawn_points[0].global_position
|
||||
pc.global_position = position
|
||||
pos = spawn_points[0].global_position
|
||||
pc.global_position = pos
|
||||
pc.setup(1, Game.pawns_selected[1])
|
||||
add_pawn_camera(pc)
|
||||
cameras[1].register_pawn(1)
|
||||
@@ -83,17 +83,17 @@ func spawn_players_multiplayer() -> void:
|
||||
|
||||
for key in pawns:
|
||||
var pc = pawns[key]
|
||||
var position : Vector3
|
||||
var pos : Vector3
|
||||
if(spawn_points == null
|
||||
or len(spawn_points) <= count):
|
||||
if key == Multiplayer.id:
|
||||
position = Vector3(0,0,0)
|
||||
pos = Vector3(0,0,0)
|
||||
else:
|
||||
position = Vector3(3,0,0)
|
||||
pos = Vector3(3,0,0)
|
||||
else:
|
||||
position = spawn_points[count].global_position
|
||||
pos = spawn_points[count].global_position
|
||||
count += 1
|
||||
pc.global_position = position
|
||||
pc.global_position = pos
|
||||
pc.setup.rpc(key, Game.pawns_selected[key])
|
||||
|
||||
multiplayer_level_setup.set_players_unready(Multiplayer.players.values())
|
||||
@@ -198,7 +198,7 @@ func remove_map_marker(target) -> void:
|
||||
|
||||
func add_map_marker(target) -> void:
|
||||
var marker : MapMarker
|
||||
var height : float
|
||||
var height : float = 0
|
||||
if target is PawnController:
|
||||
marker = map_marker_templates.pawn.instantiate()
|
||||
height += 40
|
||||
|
||||
@@ -2,17 +2,17 @@ class_name MapMarker extends Node3D
|
||||
|
||||
var target : Node3D
|
||||
|
||||
func register_target(target : Node3D) -> void:
|
||||
self.target = target
|
||||
func register_target(new_target : Node3D) -> void:
|
||||
target = new_target
|
||||
reposition()
|
||||
|
||||
func reposition() -> void:
|
||||
var loc = target.position
|
||||
position = Vector3(loc.x, position.y, loc.z)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
if target:
|
||||
reposition()
|
||||
|
||||
func _on_hack_revealed(is_visible : bool) -> void:
|
||||
visible = is_visible
|
||||
func _on_hack_revealed(reveal : bool) -> void:
|
||||
visible = reveal
|
||||
|
||||
@@ -56,7 +56,7 @@ func _on_pawn_spawner_spawned(node: Node) -> void:
|
||||
|
||||
|
||||
|
||||
func _on_camera_spawner_spawned(node: Node) -> void:
|
||||
func _on_camera_spawner_spawned(_node: Node) -> void:
|
||||
cameras_expected -= 1
|
||||
if cameras_expected == 0:
|
||||
all_cameras_spawned.emit()
|
||||
|
||||
@@ -70,7 +70,7 @@ func _on_joining_back_button_pressed() -> void:
|
||||
%Joining.visible = false
|
||||
%Menu.visible = true
|
||||
|
||||
func _on_client_added(peer_handle : String, peer_id : int) -> void:
|
||||
func _on_client_added(peer_handle : String, _peer_id : int) -> void:
|
||||
%ParticipantsText.text = "[color=FFFF00][b]*%s[/b][/color]\n[color=FFFFFF]*%s[/color]" % [handle, peer_handle]
|
||||
%StartButton.disabled = false
|
||||
|
||||
|
||||
@@ -48,6 +48,21 @@ func _on_struggle_changed(value : float) -> void:
|
||||
else:
|
||||
struggle_bar.value = value
|
||||
|
||||
func set_animation_length(node_name : String, length : float) -> void:
|
||||
if length == 0:
|
||||
length = 0.01
|
||||
var blendtree : AnimationNodeBlendTree = anim_tree.tree_root.get_node(node_name)
|
||||
if !blendtree:
|
||||
return
|
||||
var anim_node : AnimationNodeAnimation = blendtree.get_node("Animation")
|
||||
if !anim_node:
|
||||
return
|
||||
var animation : Animation = anim_player.get_animation(anim_node.animation)
|
||||
if !animation:
|
||||
return
|
||||
var a_scale : float = animation.length / length
|
||||
anim_tree["parameters/%s/TimeScale/scale" % node_name] = a_scale
|
||||
|
||||
|
||||
func _on_footstep_timer_timeout() -> void:
|
||||
walk_sound.play()
|
||||
|
||||
@@ -45,7 +45,7 @@ func _process(delta: float) -> void:
|
||||
func shake():
|
||||
noise_y += .1
|
||||
var amount = pow(trauma, trauma_power)
|
||||
var n_val = noise.get_noise_2d(noise.seed*2, noise_y)
|
||||
#var n_val = noise.get_noise_2d(noise.seed*2, noise_y)
|
||||
h_offset = max_offset.x * amount * randf_range(-1, 1)
|
||||
v_offset = max_offset.y * amount * randf_range(-1, 1)
|
||||
print("%f %f" % [h_offset, v_offset])
|
||||
|
||||
@@ -2,6 +2,11 @@ class_name PawnController extends CharacterBody3D
|
||||
|
||||
enum State {
|
||||
NORMAL,
|
||||
DETECTING,
|
||||
INSTALLING,
|
||||
UNINSTALLING,
|
||||
MELEE_ATTACKING,
|
||||
RANGED_ATTACKING,
|
||||
KNOCKDOWN,
|
||||
KNOCKUP,
|
||||
FLUNG,
|
||||
@@ -26,7 +31,7 @@ const range_sphere_template = preload("res://templates/range_sphere.tscn")
|
||||
@onready var detect_sound : AudioStreamPlayer3D = $DetectSound
|
||||
@onready var fling_sound : AudioStreamPlayer3D = $FlingSound
|
||||
@onready var crash_sound : AudioStreamPlayer3D = $CrashSound
|
||||
@onready var reload_sound : AudioStreamPlayer3D = $PawnBody/ReloadSound
|
||||
@onready var reload_sound : AudioStreamPlayer3D
|
||||
@onready var detect_icon : Sprite3D = $DetectIcon
|
||||
|
||||
@export var id : int = 1
|
||||
@@ -35,9 +40,6 @@ const range_sphere_template = preload("res://templates/range_sphere.tscn")
|
||||
var button_actions : Dictionary[int, String]
|
||||
var current_square : Vector3i
|
||||
var facing : Vector3
|
||||
@export var detecting : bool = false
|
||||
var installing : bool = false
|
||||
var uninstalling : bool = false
|
||||
var range_sphere : RangeSphere
|
||||
var detect_squares : Dictionary[Vector3i, bool] = {}
|
||||
var detect_tween : Tween = null
|
||||
@@ -51,18 +53,17 @@ var poison_time_remaining : float = 0
|
||||
var poison_pulse_timer : float
|
||||
|
||||
var melee_range : float = 3.0
|
||||
var can_melee : bool = false
|
||||
var ranged_range : float = 6
|
||||
var attack_timer : float = 0
|
||||
var melee_recovery_time : float = .75
|
||||
var ranged_recovery_time : float = .2
|
||||
var ranged_recovery_time : float = 0.25
|
||||
var ranged_reload_time : float = 1
|
||||
var projectile_speed : float = 10.0
|
||||
var projectile_damage : int = 4
|
||||
var ammo = 5
|
||||
var max_ammo = 5
|
||||
var combat_target
|
||||
var meleeing : bool = false
|
||||
var shooting : bool = false
|
||||
var reloading : bool = false
|
||||
var take_shot : bool = false
|
||||
var flinch : float = 0
|
||||
@@ -98,7 +99,22 @@ func _exit_tree() -> void:
|
||||
#Game.level.evaluate_outcome()
|
||||
#Game.evaluate
|
||||
|
||||
func calculate_pawn_velocity(dir : Vector3) -> Vector3:
|
||||
var y = velocity.y
|
||||
var result = speed * dir
|
||||
if is_poisoned():
|
||||
result *= 0.5
|
||||
if is_crouching():
|
||||
result *= .33
|
||||
result.y = y
|
||||
return result
|
||||
|
||||
func play_footsteps(spd : float, loud : bool) -> void:
|
||||
if loud:
|
||||
body.play_footsteps(spd)
|
||||
|
||||
func stop_footsteps() -> void:
|
||||
body.stop_footsteps()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if attack_timer > 0:
|
||||
@@ -142,26 +158,16 @@ func _physics_process(delta: float) -> void:
|
||||
knockdown(-fling_direction)
|
||||
hurt(10)
|
||||
moving = false
|
||||
State.NORMAL:
|
||||
State.NORMAL, State.DETECTING, State.INSTALLING:
|
||||
can_fall = true
|
||||
|
||||
if dir.length_squared() > 0:
|
||||
moving = true
|
||||
velocity = calculate_pawn_velocity(dir)
|
||||
facing = dir.normalized()
|
||||
body.look_at(body.global_position - dir)
|
||||
var y = velocity.y
|
||||
velocity = speed * dir
|
||||
if is_poisoned():
|
||||
velocity *= 0.5
|
||||
if is_crouching():
|
||||
velocity *= .33
|
||||
velocity.y = y
|
||||
if !detecting:
|
||||
body.play_footsteps(lerp(.78, .33, dir.length()))
|
||||
else:
|
||||
body.stop_footsteps()
|
||||
elif body != null:
|
||||
body.stop_footsteps()
|
||||
play_footsteps(lerp(.78, .33, dir.length()), true)
|
||||
else:
|
||||
stop_footsteps()
|
||||
if body != null:
|
||||
body.set_animation_parameter("parameters/Motion/blend_position", dir.length())
|
||||
body.set_animation_parameter("parameters/Crouch/blend_position", dir.length())
|
||||
@@ -171,12 +177,9 @@ func _physics_process(delta: float) -> void:
|
||||
else:
|
||||
moving = true
|
||||
can_fall = true
|
||||
State.KNOCKDOWN,State.BOUND,State.DEAD:
|
||||
return
|
||||
|
||||
|
||||
if can_fall:
|
||||
var down = 0
|
||||
if !is_on_floor():
|
||||
velocity.y = velocity.y + get_gravity().y * delta
|
||||
moving = true
|
||||
@@ -184,8 +187,9 @@ func _physics_process(delta: float) -> void:
|
||||
if moving:
|
||||
move_and_slide()
|
||||
|
||||
if detecting:
|
||||
if is_detecting():
|
||||
update_detect_region.rpc(true)
|
||||
|
||||
if range_sphere:
|
||||
update_range_sphere()
|
||||
#Deal with the rest of the buttons
|
||||
@@ -200,7 +204,7 @@ func _physics_process(delta: float) -> void:
|
||||
for button in buttons:
|
||||
if input.is_action_just_pressed(button):
|
||||
modal.button_pressed(button)
|
||||
elif state == State.NORMAL:
|
||||
else:
|
||||
update_actions()
|
||||
|
||||
@rpc("call_local", "reliable")
|
||||
@@ -213,15 +217,17 @@ func set_pawn_body(pb : PawnBody) -> void:
|
||||
body = pb
|
||||
pb.reloading.connect(reload_ranged)
|
||||
pb.shooting.connect(fire_ranged)
|
||||
reload_sound = body.find_child("ReloadSound")
|
||||
add_child(body)
|
||||
body.set_animation_length("Ranged Fire", ranged_recovery_time)
|
||||
struggling.connect(body._on_struggle_changed)
|
||||
|
||||
|
||||
func attack() -> void:
|
||||
if attack_timer > 0:
|
||||
return
|
||||
if meleeing:
|
||||
body.play_animation.rpc("melee")
|
||||
if can_melee:
|
||||
state = State.MELEE_ATTACKING
|
||||
attack_timer = melee_recovery_time
|
||||
else:
|
||||
if ammo <= 0:
|
||||
@@ -229,14 +235,14 @@ func attack() -> void:
|
||||
return
|
||||
|
||||
attack_timer = ranged_recovery_time
|
||||
shooting = true
|
||||
state = State.RANGED_ATTACKING
|
||||
take_shot = true
|
||||
if combat_target != null:
|
||||
var v = body.global_position.direction_to(combat_target.global_position)
|
||||
v.y = 0
|
||||
body.look_at(body.global_position - v)
|
||||
|
||||
|
||||
|
||||
func reload_ranged() -> void:
|
||||
reloading = false
|
||||
reload_sound.play()
|
||||
@@ -245,41 +251,44 @@ func reload_ranged() -> void:
|
||||
ammo_changed.emit(ammo, max_ammo)
|
||||
|
||||
func update_actions() -> void:
|
||||
if attack_timer <= 0 and shooting and !input.is_action_pressed("attack"):
|
||||
shooting = false
|
||||
|
||||
if state == State.DEAD:
|
||||
return
|
||||
|
||||
if attack_timer <= 0 and is_attacking():
|
||||
if !input.is_action_pressed("attack"):
|
||||
state = State.NORMAL
|
||||
elif is_shooting():
|
||||
if ammo <= 0:
|
||||
reloading = true
|
||||
else:
|
||||
take_shot = true
|
||||
|
||||
if input.is_action_just_pressed("left cycle hack"):
|
||||
cycle_active_hack(-1)
|
||||
if input.is_action_just_pressed("right cycle hack"):
|
||||
cycle_active_hack(1)
|
||||
if input.is_action_just_pressed("detonate"):
|
||||
detonate()
|
||||
elif !installing:
|
||||
if input.is_action_just_pressed("detect"):
|
||||
start_detecting()
|
||||
elif input.is_action_just_released("detect"):
|
||||
stop_detecting()
|
||||
if!detecting:
|
||||
if input.is_action_just_pressed("install"):
|
||||
installing = true
|
||||
if range_sphere != null:
|
||||
range_sphere.queue_free()
|
||||
range_sphere = range_sphere_template.instantiate()
|
||||
Game.level.add_child(range_sphere)
|
||||
#Set the range sphere size based upon the current hack
|
||||
update_range_sphere()
|
||||
if input.is_action_just_released("install"):
|
||||
installing = false
|
||||
range_sphere.queue_free()
|
||||
range_sphere = null
|
||||
try_install_hack()
|
||||
match(state):
|
||||
State.NORMAL:
|
||||
if input.is_action_just_pressed("detonate"):
|
||||
detonate()
|
||||
if(input.is_action_just_pressed("detect")
|
||||
and input.is_action_pressed("detect")):
|
||||
start_detecting()
|
||||
return
|
||||
if(input.is_action_just_pressed("install")
|
||||
and input.is_action_pressed("install")):
|
||||
start_installing()
|
||||
return
|
||||
elif input.is_action_pressed("attack"):
|
||||
attack()
|
||||
elif input.is_action_just_released("install"):
|
||||
installing = false
|
||||
range_sphere.queue_free()
|
||||
range_sphere = null
|
||||
try_install_hack()
|
||||
State.DETECTING:
|
||||
if !input.is_action_pressed("detect"):
|
||||
stop_detecting()
|
||||
State.INSTALLING:
|
||||
if !input.is_action_pressed("install"):
|
||||
stop_installing()
|
||||
try_install_hack()
|
||||
|
||||
func update_range_sphere() -> void:
|
||||
var new_pos = (global_position - Vector3.ONE * .5).round() + Vector3(0.5, 0, 0.5)
|
||||
@@ -324,6 +333,7 @@ func fire_ranged() -> void:
|
||||
ammo-=1
|
||||
ammo_changed.emit(ammo, max_ammo)
|
||||
shot.speed = projectile_speed
|
||||
shot.id = id
|
||||
tdir = body.ranged_point.global_position.direction_to(combat_target.global_position) if combat_target else facing
|
||||
shot.direction = tdir
|
||||
shot.damage = projectile_damage
|
||||
@@ -368,10 +378,10 @@ func check_attack_target() -> void:
|
||||
ranged_closest = target
|
||||
ranged_d_sq = d_sq
|
||||
if melee_closest != null:
|
||||
meleeing = true
|
||||
can_melee = true
|
||||
combat_target = melee_closest
|
||||
else:
|
||||
meleeing = false
|
||||
can_melee = false
|
||||
if ranged_closest != null:
|
||||
combat_target = ranged_closest
|
||||
combat_target_changed.emit(melee_closest != null)
|
||||
@@ -423,21 +433,21 @@ func detect_alert() -> void:
|
||||
detect_tween.tween_callback(func(): detect_tween = null)
|
||||
|
||||
func close_modal() -> void:
|
||||
uninstalling = false
|
||||
state = State.NORMAL
|
||||
if modal != null:
|
||||
modal.queue_free()
|
||||
modal = null
|
||||
|
||||
func show_uninstall_hack_modal() -> void:
|
||||
stop_detecting()
|
||||
uninstalling = true
|
||||
state = State.UNINSTALLING
|
||||
modal = uninstall_hack_modal.instantiate()
|
||||
modal.square = current_square
|
||||
Game.level.add_child(modal)
|
||||
|
||||
func show_decompile_hack_modal() -> void:
|
||||
stop_detecting()
|
||||
uninstalling = true
|
||||
state = State.UNINSTALLING
|
||||
modal = decompile_hack_modal.instantiate()
|
||||
modal.difficulty = Game.level.difficulty
|
||||
modal.square = current_square
|
||||
@@ -451,8 +461,23 @@ func show_decompile_hack_modal() -> void:
|
||||
Game.level.add_child(modal)
|
||||
|
||||
func start_detecting() -> void:
|
||||
detecting = true
|
||||
update_detect_region.rpc(false)
|
||||
state = State.DETECTING
|
||||
update_detect_region(false)
|
||||
|
||||
func start_installing() -> void:
|
||||
state = State.INSTALLING
|
||||
if id == Multiplayer.id:
|
||||
if range_sphere != null:
|
||||
range_sphere.queue_free()
|
||||
range_sphere = range_sphere_template.instantiate()
|
||||
Game.level.add_child(range_sphere)
|
||||
#Set the range sphere size based upon the current hack
|
||||
update_range_sphere()
|
||||
|
||||
func stop_installing() -> void:
|
||||
state = State.NORMAL
|
||||
range_sphere.queue_free()
|
||||
range_sphere = null
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
func update_detect_region(update : bool) -> void:
|
||||
@@ -477,13 +502,14 @@ func update_detect_region(update : bool) -> void:
|
||||
|
||||
var remove_list = []
|
||||
var hack_detected : bool = false
|
||||
var hack : Hack
|
||||
for sq in new_squares.keys():
|
||||
if update and detect_squares.has(sq):
|
||||
continue
|
||||
if !Game.level.detect_square(sq, true):
|
||||
remove_list.append(sq)
|
||||
else:
|
||||
var hack = Game.level.get_square_hack(sq + Vector3i(0,1,0))
|
||||
hack = Game.level.get_square_hack(sq + Vector3i(0,1,0))
|
||||
if hack and hack.is_just_revealed():
|
||||
hack_detected = true
|
||||
|
||||
@@ -495,7 +521,7 @@ func update_detect_region(update : bool) -> void:
|
||||
for key in remove_list:
|
||||
detect_squares.erase(key)
|
||||
|
||||
var hack : Hack = Game.level.get_square_hack(current_square)
|
||||
hack = Game.level.get_square_hack(current_square)
|
||||
if hack != null:
|
||||
if hack.hack_owner == Multiplayer.id:
|
||||
show_uninstall_hack_modal()
|
||||
@@ -504,7 +530,7 @@ func update_detect_region(update : bool) -> void:
|
||||
show_decompile_hack_modal()
|
||||
|
||||
func stop_detecting() -> void:
|
||||
detecting = false
|
||||
state = State.NORMAL
|
||||
clear_detect_region.rpc()
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
@@ -516,8 +542,8 @@ func clear_detect_region() -> void:
|
||||
detect_squares = {}
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func setup(id : int, pawn : StringName) -> void:
|
||||
self.id = id
|
||||
func setup(p_id : int, pawn : StringName) -> void:
|
||||
id = p_id
|
||||
var base_data : PawnBaseData = Game.pawns[pawn]
|
||||
var hacklist : Array[PawnLevelData.HackData] = []
|
||||
for hack in base_data.starting_hacks:
|
||||
@@ -564,9 +590,11 @@ func hurt(damage : int) -> void:
|
||||
health_changed.emit(data.life, data.max_life)
|
||||
if data.life == 0:
|
||||
die.rpc()
|
||||
@rpc("any_peer", "call_local")
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
func die() -> void:
|
||||
state = State.DEAD
|
||||
body.travel_animation("Death")
|
||||
input_locked = true
|
||||
if id == Multiplayer.id:
|
||||
var death_tween = create_tween()
|
||||
@@ -578,21 +606,15 @@ func _on_hack_decompiled(type : Hack.Type) -> void:
|
||||
for i in range(len(data.hacks)):
|
||||
var d = data.hacks[i]
|
||||
if d.type == type:
|
||||
d.max -= 1
|
||||
d.max_quantity -= 1
|
||||
hack_quantity_changed.emit(i, d.quantity)
|
||||
break
|
||||
#hurt
|
||||
#blast
|
||||
#blast_players
|
||||
#activate
|
||||
#activate_hack
|
||||
#fail
|
||||
#on_hack_failed
|
||||
|
||||
func _on_hack_activated(type : Hack.Type) -> void:
|
||||
for i in range(len(data.hacks)):
|
||||
var d = data.hacks[i]
|
||||
if d.type == type:
|
||||
d.quantity = min(d.max, d.quantity+ 1)
|
||||
d.quantity = min(d.max_quantity, d.quantity+ 1)
|
||||
hack_quantity_changed.emit(i, d.quantity)
|
||||
break
|
||||
|
||||
@@ -623,10 +645,10 @@ func poison(damage : int, length : float) -> void:
|
||||
pshader.set_shader_parameter("strength", 0.5)
|
||||
poison_status_changed.emit(true)
|
||||
|
||||
func fling(direction : Vector3, speed : float) -> void:
|
||||
func fling(direction : Vector3, spd : float) -> void:
|
||||
state = State.FLUNG
|
||||
fling_direction = direction
|
||||
fling_speed = speed
|
||||
fling_speed = spd
|
||||
fling_sound.play()
|
||||
|
||||
func knockdown(direction : Vector3) -> void:
|
||||
@@ -641,14 +663,14 @@ func knockdown(direction : Vector3) -> void:
|
||||
knockdown_tween.tween_property(self, "input_locked", false, 0)
|
||||
knockdown_tween.tween_callback(Callable(body.look_at).bind(facing, Vector3(0,1,0)))
|
||||
|
||||
func knockup(velocity : Vector3) -> void:
|
||||
func knockup(vel : Vector3) -> void:
|
||||
if state != State.KNOCKUP:
|
||||
state = State.KNOCKUP
|
||||
input_locked = true
|
||||
if is_on_floor():
|
||||
self.velocity = Vector3.UP * .1
|
||||
velocity = Vector3.UP * .1
|
||||
move_and_slide()
|
||||
self.velocity = velocity
|
||||
velocity = vel
|
||||
|
||||
func knockback(direction : Vector3, impact : float) -> void:
|
||||
if state != State.NORMAL:
|
||||
@@ -672,14 +694,46 @@ func start_pitfall(square : Vector3, duration : float) -> void:
|
||||
tween.tween_property(self, "input_locked", false, 0)
|
||||
tween.tween_callback(pitfall.bind(duration))
|
||||
|
||||
func _on_melee_hit(body : Node3D) -> void:
|
||||
func _on_melee_hit(_body : Node3D) -> void:
|
||||
#TODO: WRITE THE MELEE DAMAGE CODE
|
||||
pass
|
||||
|
||||
|
||||
func is_attacking() -> bool:
|
||||
return state == State.RANGED_ATTACKING or state == State.MELEE_ATTACKING
|
||||
|
||||
func is_meleeing() -> bool:
|
||||
return state == State.MELEE_ATTACKING
|
||||
func is_shooting() -> bool:
|
||||
return state == State.RANGED_ATTACKING
|
||||
|
||||
func is_dead() -> bool:
|
||||
return state == State.DEAD
|
||||
|
||||
func is_detecting() -> bool:
|
||||
return detecting
|
||||
return state == State.DETECTING
|
||||
|
||||
func is_installing() -> bool:
|
||||
return state == State.INSTALLING
|
||||
|
||||
func is_uninstalling() -> bool:
|
||||
return state == State.UNINSTALLING
|
||||
|
||||
func is_crouching() -> bool:
|
||||
return detecting or installing or uninstalling
|
||||
var result : bool = false
|
||||
match(state):
|
||||
State.DETECTING: result = true
|
||||
State.INSTALLING: result = true
|
||||
State.UNINSTALLING: result = true
|
||||
return result
|
||||
|
||||
func add_random_hack(advanced : bool) -> void:
|
||||
#TODO: Add random hack spawning using RPCs
|
||||
pass
|
||||
|
||||
func pickup(type : Pickup.Type) -> void:
|
||||
if id != Multiplayer.id:
|
||||
return
|
||||
match(type):
|
||||
Pickup.Type.DATABLOCK: print("Datablock picked up!")
|
||||
Pickup.Type.BASIC_HACK: add_random_hack(false)
|
||||
|
||||
@@ -35,5 +35,5 @@ func tv_blur(amount : float) -> void:
|
||||
var blinder_mat : ShaderMaterial = portrait_blinder.material
|
||||
blinder_mat.set_shader_parameter("opacity_limit", amount)
|
||||
|
||||
func set_pawn_name(name : String) -> void:
|
||||
pawn_name.text = name
|
||||
func set_pawn_name(p_name : String) -> void:
|
||||
pawn_name.text = p_name
|
||||
|
||||
@@ -32,7 +32,7 @@ func _ready() -> void:
|
||||
"attack":false
|
||||
}
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if get_multiplayer_authority() != Multiplayer.id:
|
||||
return
|
||||
var d = Input.get_vector("west", "east", "north", "south")
|
||||
|
||||
@@ -3,12 +3,12 @@ class_name PawnLevelData extends Node
|
||||
class HackData:
|
||||
var type : Hack.Type
|
||||
var quantity : int
|
||||
var max : int
|
||||
var max_quantity : int
|
||||
|
||||
func _init(type : Hack.Type, quantity : int, max : int) -> void:
|
||||
self.type = type
|
||||
self.quantity = quantity
|
||||
self.max = max
|
||||
func _init(new_type : Hack.Type, amt : int, max_amt : int) -> void:
|
||||
type = new_type
|
||||
quantity = amt
|
||||
max_quantity = max_amt
|
||||
|
||||
var hacks : Array[HackData] = []
|
||||
var active_hack : int = 0
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
class_name Projectile extends RigidBody3D
|
||||
class_name Projectile extends Area3D
|
||||
|
||||
var id : int = 0
|
||||
var direction : Vector3
|
||||
var speed : float
|
||||
var friend_safe : bool = true
|
||||
var damage
|
||||
var time_remaining : float
|
||||
func _ready() -> void:
|
||||
linear_velocity = speed * direction
|
||||
time_remaining = 2
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
global_position += speed * direction * delta
|
||||
time_remaining -= delta
|
||||
if time_remaining <= 0:
|
||||
queue_free()
|
||||
|
||||
func _on_body_entered(body: Node) -> void:
|
||||
queue_free()
|
||||
|
||||
|
||||
|
||||
func _on_hit_area_entered(body: Node3D) -> void:
|
||||
if body is PawnController:
|
||||
body.hurt(damage)
|
||||
if !friend_safe or id != body.id:
|
||||
body.hurt(damage)
|
||||
queue_free()
|
||||
else:
|
||||
queue_free()
|
||||
|
||||
@@ -15,8 +15,7 @@ var type : Hack.Type = -1
|
||||
rim_sphere.radius = _radius
|
||||
if intersect_sphere != null:
|
||||
intersect_sphere.radius = _radius
|
||||
|
||||
|
||||
|
||||
func set_range(range : float) -> void:
|
||||
radius = range
|
||||
func set_range(new_radius : float) -> void:
|
||||
radius = new_radius
|
||||
|
||||
@@ -56,7 +56,7 @@ func _ready() -> void:
|
||||
glow_tween.tween_property(target, "modulate:a", .8, .5)
|
||||
glow_tween.tween_property(target, "modulate:a", 1, .5)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
func _process(_delta: float) -> void:
|
||||
if Input.is_action_just_pressed("ui_menu"):
|
||||
opened = !opened
|
||||
start.visible = !opened
|
||||
|
||||
Reference in New Issue
Block a user