Merge branch 'master' of github.com:unfa/jam-01 into master

remotes/1705382094874458415/tmp_refs/heads/godot4-port
unfa 2020-10-02 19:24:33 +02:00
commit 90d6c3c79e
9 changed files with 250 additions and 109 deletions

View File

@ -1,24 +1,13 @@
extends Control
func update_ammo(var weapon, var amount):
$Weapon/VBoxContainer/RoundsClips.text = str(amount)
func updateHealth(health: int):
$Health/HealthBar.value = health
$Health/HealthBar/HealthText.text = String(health)
func updateCrosshair(visible: bool, hit: bool):
func update_crosshair(visible: bool, hit: bool):
$Crosshair.visible = visible
if hit:
$Crosshair/HitConfirmation.activate(0.2)
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass

View File

@ -144,7 +144,7 @@ alignment = 1
margin_top = 16.0
margin_right = 116.0
margin_bottom = 30.0
text = "12 / 6"
text = "10"
align = 1
valign = 1
__meta__ = {

View File

@ -1,5 +1,8 @@
extends Spatial
signal damage_dealt
signal ammo_changed(type, amount)
export(bool) var Hitscan = false
export(int) var Damage = 100
export(float) var Delay = 0.1
@ -9,35 +12,90 @@ export(int) var MaxRoundsInClip = 10
export(int) var Clips = 1
export(int) var MaxClips = 4
onready var camera = get_parent().get_parent()
onready var player = get_parent().get_parent().get_parent()
onready var ejector = find_node("Ejector")
onready var muzzle = find_node("Muzzle")
onready var current_rounds = Rounds
var currently_fireing = false
var cached_fire = false
#onready var sound_shoot = $SoundShoot
var casing = preload("res://Assets/Weapons/Handgun/Casing.tscn")
var tracer = preload("res://Assets/Effects/BulletTracer.tscn")
func shoot():
rpc("show_muzzle_flash")
rpc("show_tracer")
rpc("spawn_casing")
rpc("compute_bullet_flyby")
func shoot(camera):
if cached_fire == true:
return
if currently_fireing == true:
cached_fire = true
yield($Handgun/AnimationPlayer, "animation_finished")
# TODO: mutexes
currently_fireing = true
cached_fire = false
if current_rounds > 0:
rpc("fire_weapon", current_rounds)
rpc("compute_bullet_flyby")
current_rounds -= 1
emit_signal("ammo_changed", "handgun", current_rounds)
var space_state = get_world().direct_space_state
var crosshair_pos = get_viewport().size / 2
var from = camera.project_ray_origin(crosshair_pos)
var to = from + camera.project_ray_normal(crosshair_pos) * 1000
var result = space_state.intersect_ray(from, to)
if "collider" in result:
var hit = result.collider
if hit.has_method("on_hit"):
hit.rpc("on_hit", 30, result.position)
if hit is preload("res://Player.gd"):
emit_signal("damage_dealt")
else:
rpc("dry_fire")
return current_rounds
sync func fire_weapon(var rounds_left):
show_muzzle_flash(rounds_left)
show_tracer()
spawn_casing()
yield($Handgun/AnimationPlayer, "animation_finished")
if !cached_fire:
currently_fireing = false
sync func show_muzzle_flash():
sync func dry_fire():
pass
func show_muzzle_flash(var rounds_left):
$Handgun/AnimationPlayer.stop()
$Handgun/AnimationPlayer.play("Shoot", -1, 2)
if rounds_left == 1:
$Handgun/AnimationPlayer.play("Empty", -1, 2)
else:
$Handgun/AnimationPlayer.play("Shoot", -1, 2)
$SoundShoot.play()
$MuzzleFlash.emitting = true
yield(get_tree().create_timer(0.07),"timeout")
$MuzzleFlash.emitting = false
sync func show_tracer():
func show_tracer():
var tracer_instance = tracer.instance()
tracer_instance.hide()
tracer_instance.global_transform = muzzle.global_transform
@ -45,7 +103,7 @@ sync func show_tracer():
get_tree().root.call_deferred("add_child", tracer_instance)
tracer_instance.call_deferred("show")
sync func spawn_casing():
func spawn_casing():
var casing_instance = casing.instance()
casing_instance.global_transform = ejector.global_transform
@ -64,3 +122,21 @@ remote func compute_bullet_flyby():
var to = global_transform.xform(Vector3(-1000, 0, 0))
local_player.on_bullet_flyby(from, to)
func reload():
rpc("play_reload_animation")
currently_fireing = true
cached_fire = false
yield($Handgun/AnimationPlayer, "animation_finished")
if not cached_fire:
currently_fireing = false
current_rounds = Rounds
emit_signal("ammo_changed", "handgun", current_rounds)
sync func play_reload_animation():
$Handgun/AnimationPlayer.play("Reload", 0.5, 1)

35
Game.gd
View File

@ -15,12 +15,13 @@ var settingmap = {
"mouse_sensitivity": "set_mouse_sensitivity"
}
onready var peer = NetworkedMultiplayerENet.new()
var local_player = null
# Called when the node enters the scene tree for the first time.
func _ready():
$MenuContainer/MainMenu/Destination/IPAdress.set_text(SERVER_IP)
$MenuContainer/MainMenu/Destination/Port.set_text(str(SERVER_PORT))
$MenuContainer/ConnectMenu/Destination/IPAdress.set_text(SERVER_IP)
$MenuContainer/ConnectMenu/Destination/Port.set_text(str(SERVER_PORT))
load_settings()
@ -96,6 +97,10 @@ func open_menu(type):
else:
menu.hide()
func join_test_server():
SERVER_IP = "unfa.xyz"
initialize_client()
func join_home():
SERVER_IP = "127.0.0.1"
initialize_client()
@ -144,23 +149,40 @@ func get_port():
return SERVER_PORT
func initialize_server(join=true):
var peer = NetworkedMultiplayerENet.new()
peer.create_server(SERVER_PORT, MAX_PLAYERS)
get_tree().connect("network_peer_connected", self, "on_peer_connected")
get_tree().connect("network_peer_disconnected", self, "on_peer_disconnected")
get_tree().network_peer = peer
$MenuContainer/MainMenu/Connect.hide()
$MenuContainer/MainMenu/Disconnect.show()
close_menus()
if join:
add_player(1, false)
func initialize_client():
var peer = NetworkedMultiplayerENet.new()
peer.create_client(SERVER_IP, SERVER_PORT)
get_tree().connect("connected_to_server", self, "on_connection_established")
get_tree().connect("connection_failed", self, "on_connection_failed")
get_tree().network_peer = peer
return_to_menu("MainMenu")
$MenuContainer/MainMenu/Connect.hide()
$MenuContainer/MainMenu/Disconnect.show()
close_menus()
func free_client():
$MenuContainer/MainMenu/Connect.show()
$MenuContainer/MainMenu/Disconnect.hide()
for player in $Players.get_children():
player.queue_free()
peer.close_connection()
func quit():
get_tree().quit()
@ -183,10 +205,7 @@ sync func check_players(player_names):
player.translation += Vector3(0.0, 3.0, 0.0)
if player_name == str(get_tree().get_network_unique_id()):
player.camera.current = true
player.set_network_master(get_tree().get_network_unique_id())
local_player = player
player.set_local_player()
func add_player(id, check=true):
var player = player_scene.instance()

128
Game.tscn
View File

@ -56,22 +56,61 @@ __meta__ = {
[node name="MainMenu" type="VBoxContainer" parent="MenuContainer"]
margin_left = 312.0
margin_top = 240.0
margin_top = 244.0
margin_right = 712.0
margin_bottom = 360.0
margin_bottom = 356.0
rect_min_size = Vector2( 400, 0 )
[node name="QuickJoin" type="Button" parent="MenuContainer/MainMenu"]
[node name="QuickConnect" type="Button" parent="MenuContainer/MainMenu"]
margin_right = 400.0
margin_bottom = 40.0
rect_min_size = Vector2( 0, 40 )
text = "Quick Connect!"
[node name="Connect" type="Button" parent="MenuContainer/MainMenu"]
margin_top = 44.0
margin_right = 400.0
margin_bottom = 64.0
text = "Connect"
[node name="Disconnect" type="Button" parent="MenuContainer/MainMenu"]
visible = false
margin_top = 24.0
margin_right = 400.0
margin_bottom = 44.0
text = "Disconnect"
[node name="Options" type="Button" parent="MenuContainer/MainMenu"]
margin_top = 68.0
margin_right = 400.0
margin_bottom = 88.0
text = "Options"
[node name="Quit" type="Button" parent="MenuContainer/MainMenu"]
margin_top = 92.0
margin_right = 400.0
margin_bottom = 112.0
text = "Quit"
[node name="ConnectMenu" type="VBoxContainer" parent="MenuContainer"]
visible = false
margin_left = 312.0
margin_top = 212.0
margin_right = 712.0
margin_bottom = 388.0
rect_min_size = Vector2( 400, 0 )
[node name="Back" type="Button" parent="MenuContainer/ConnectMenu"]
margin_right = 400.0
margin_bottom = 20.0
text = "Quick Join"
text = "Back"
[node name="Destination" type="HBoxContainer" parent="MenuContainer/MainMenu"]
[node name="Destination" type="HBoxContainer" parent="MenuContainer/ConnectMenu"]
margin_top = 24.0
margin_right = 400.0
margin_bottom = 48.0
[node name="IPAdress" type="LineEdit" parent="MenuContainer/MainMenu/Destination"]
[node name="IPAdress" type="LineEdit" parent="MenuContainer/ConnectMenu/Destination"]
margin_right = 278.0
margin_bottom = 24.0
size_flags_horizontal = 3
@ -80,7 +119,7 @@ placeholder_text = "IP address"
caret_blink = true
caret_blink_speed = 0.5
[node name="Port" type="LineEdit" parent="MenuContainer/MainMenu/Destination"]
[node name="Port" type="LineEdit" parent="MenuContainer/ConnectMenu/Destination"]
margin_left = 282.0
margin_right = 400.0
margin_bottom = 24.0
@ -89,72 +128,57 @@ placeholder_text = "port"
caret_blink = true
caret_blink_speed = 0.5
[node name="NetworkType" type="HBoxContainer" parent="MenuContainer/MainMenu"]
[node name="NetworkType" type="HBoxContainer" parent="MenuContainer/ConnectMenu"]
margin_top = 52.0
margin_right = 400.0
margin_bottom = 72.0
[node name="Host" type="Button" parent="MenuContainer/MainMenu/NetworkType"]
[node name="Host" type="Button" parent="MenuContainer/ConnectMenu/NetworkType"]
margin_right = 130.0
margin_bottom = 20.0
size_flags_horizontal = 3
text = "Host"
[node name="HostAsSpectator" type="Button" parent="MenuContainer/MainMenu/NetworkType"]
[node name="HostAsSpectator" type="Button" parent="MenuContainer/ConnectMenu/NetworkType"]
margin_left = 134.0
margin_right = 265.0
margin_bottom = 20.0
size_flags_horizontal = 3
text = "Host As Spectator"
[node name="Join" type="Button" parent="MenuContainer/MainMenu/NetworkType"]
[node name="Join" type="Button" parent="MenuContainer/ConnectMenu/NetworkType"]
margin_left = 269.0
margin_right = 400.0
margin_bottom = 20.0
size_flags_horizontal = 3
text = "Join"
[node name="Options" type="Button" parent="MenuContainer/MainMenu"]
[node name="HSeparator" type="HSeparator" parent="MenuContainer/ConnectMenu"]
margin_right = 40.0
margin_bottom = 4.0
[node name="Test Server" type="Button" parent="MenuContainer/ConnectMenu"]
margin_top = 76.0
margin_right = 400.0
margin_bottom = 96.0
text = "Options"
text = "Test Server"
[node name="Quit" type="Button" parent="MenuContainer/MainMenu"]
[node name="Home" type="Button" parent="MenuContainer/ConnectMenu"]
margin_top = 100.0
margin_right = 400.0
margin_bottom = 120.0
text = "Quit"
[node name="QuickJoinMenu" type="VBoxContainer" parent="MenuContainer"]
visible = false
margin_left = 312.0
margin_top = 254.0
margin_right = 712.0
margin_bottom = 346.0
rect_min_size = Vector2( 400, 0 )
[node name="Back" type="Button" parent="MenuContainer/QuickJoinMenu"]
margin_right = 300.0
margin_bottom = 20.0
text = "Back"
[node name="Home" type="Button" parent="MenuContainer/QuickJoinMenu"]
margin_top = 24.0
margin_right = 300.0
margin_bottom = 44.0
text = "Home"
[node name="Unfa" type="Button" parent="MenuContainer/QuickJoinMenu"]
margin_top = 48.0
margin_right = 300.0
margin_bottom = 68.0
[node name="Unfa" type="Button" parent="MenuContainer/ConnectMenu"]
margin_top = 124.0
margin_right = 400.0
margin_bottom = 144.0
text = "Unfa"
[node name="Jan" type="Button" parent="MenuContainer/QuickJoinMenu"]
margin_top = 72.0
margin_right = 300.0
margin_bottom = 92.0
[node name="Jan" type="Button" parent="MenuContainer/ConnectMenu"]
margin_top = 148.0
margin_right = 400.0
margin_bottom = 168.0
text = "Jan"
[node name="OptionsMenu" type="VBoxContainer" parent="MenuContainer"]
@ -238,17 +262,21 @@ margin_top = 24.0
margin_right = 300.0
margin_bottom = 64.0
text = "Fullscreen"
[connection signal="pressed" from="MenuContainer/MainMenu/QuickJoin" to="." method="open_menu" binds= [ "QuickJoinMenu" ]]
[connection signal="text_changed" from="MenuContainer/MainMenu/Destination/IPAdress" to="." method="set_ip"]
[connection signal="pressed" from="MenuContainer/MainMenu/NetworkType/Host" to="." method="initialize_server"]
[connection signal="pressed" from="MenuContainer/MainMenu/NetworkType/HostAsSpectator" to="." method="initialize_server" binds= [ false ]]
[connection signal="pressed" from="MenuContainer/MainMenu/NetworkType/Join" to="." method="initialize_client"]
[connection signal="pressed" from="MenuContainer/MainMenu/QuickConnect" to="." method="join_test_server"]
[connection signal="pressed" from="MenuContainer/MainMenu/QuickConnect" to="." method="_on_QuickConnect_pressed"]
[connection signal="pressed" from="MenuContainer/MainMenu/Connect" to="." method="open_menu" binds= [ "ConnectMenu" ]]
[connection signal="pressed" from="MenuContainer/MainMenu/Disconnect" to="." method="free_client"]
[connection signal="pressed" from="MenuContainer/MainMenu/Options" to="." method="open_menu" binds= [ "OptionsMenu" ]]
[connection signal="pressed" from="MenuContainer/MainMenu/Quit" to="." method="quit"]
[connection signal="pressed" from="MenuContainer/QuickJoinMenu/Back" to="." method="return_to_menu" binds= [ "MainMenu" ]]
[connection signal="pressed" from="MenuContainer/QuickJoinMenu/Home" to="." method="join_home"]
[connection signal="pressed" from="MenuContainer/QuickJoinMenu/Unfa" to="." method="join_unfa"]
[connection signal="pressed" from="MenuContainer/QuickJoinMenu/Jan" to="." method="join_jan"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/Back" to="." method="return_to_menu" binds= [ "MainMenu" ]]
[connection signal="text_changed" from="MenuContainer/ConnectMenu/Destination/IPAdress" to="." method="set_ip"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/NetworkType/Host" to="." method="initialize_server"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/NetworkType/HostAsSpectator" to="." method="initialize_server" binds= [ false ]]
[connection signal="pressed" from="MenuContainer/ConnectMenu/NetworkType/Join" to="." method="initialize_client"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/Test Server" to="." method="join_test_server"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/Home" to="." method="join_home"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/Unfa" to="." method="join_unfa"]
[connection signal="pressed" from="MenuContainer/ConnectMenu/Jan" to="." method="join_jan"]
[connection signal="pressed" from="MenuContainer/OptionsMenu/Back" to="." method="return_to_menu" binds= [ "MainMenu" ]]
[connection signal="pressed" from="MenuContainer/OptionsMenu/Controls" to="." method="open_menu" binds= [ "ControlsMenu" ]]
[connection signal="pressed" from="MenuContainer/OptionsMenu/Graphics" to="." method="open_menu" binds= [ "GraphicsMenu" ]]

View File

@ -220,8 +220,7 @@ master func kill():
#print ("set as dead")
$MeshInstance.hide()
$Camera/Hand.hide()
$HUD.updateCrosshair(false, false)
#$HUD.update_crosshair(false, false)
yield(get_tree().create_timer(3), "timeout")
@ -249,8 +248,6 @@ func spawn():
$MeshInstance.show()
$Camera/Hand.show()
$HUD.updateCrosshair(true, false)
$CollisionShapeBody.disabled = false
$CollisionShapeFeet.disabled = false
@ -258,28 +255,14 @@ func spawn():
rotation = Vector3.ZERO
func shoot():
var gun = find_node("Weapon")
var weapon = find_node("Weapon")
gun.shoot()
var remaining_ammo = weapon.shoot($Camera)
func reload():
var weapon = find_node("Weapon")
var space_state = get_world().direct_space_state
var crosshair_pos = get_viewport().size / 2
var from = $Camera.project_ray_origin(crosshair_pos)
var to = from + $Camera.project_ray_normal(crosshair_pos) * 1000
var result = space_state.intersect_ray(from, to)
if "collider" in result:
var hit = result.collider
if hit.has_method("on_hit"):
hit.rpc("on_hit", 30, result.position)
if hit is get_script():
print("Is a live player")
$HUD.updateCrosshair(true, true)
weapon.reload()
func _input(event):
@ -324,6 +307,15 @@ func _input(event):
if event.is_action_pressed("WeaponPrimary"):
shoot()
if event.is_action_pressed("WeaponReload"):
reload()
func set_local_player():
set_network_master(get_tree().get_network_unique_id())
game.local_player = self
camera.current = true
$HUD.show()
# Called when the node enters the scene tree for the first time.
func _ready():

View File

@ -70,3 +70,6 @@ SoundClip = "res://Assets/SFX/Player-Pain-01.wav"
MinDelay = 0.2
[node name="HUD" parent="." instance=ExtResource( 3 )]
visible = false
[connection signal="ammo_changed" from="Camera/Hand/Weapon" to="HUD" method="update_ammo"]
[connection signal="damage_dealt" from="Camera/Hand/Weapon" to="HUD" method="update_crosshair" binds= [ true, true ]]

View File

@ -1,2 +1,31 @@
# Liblast
Libre Multiplayer FPS Game build with Godot game Engine
Libre Multiplayer FPS Game build with Godot 3 game engine.
## Controls
Standard FPS stuff:
- W,A,S,D to move
- Mouse to look around
- Left mouse button to shoot
- Space to jump
- R to reload
## Features in 0.1 pre-alpha release
The game currently has:
- a public online server at unfa.xyz (accessible via Connect > Test Server menu)
- simple but exciting gameplay
- one weapon (a handgun)
- a very basic HUD with health and ammo indication
- a single test level (watch you step!)
- particle effects
- mouth-made sound effects fro various things
- bullet fly-by sound effects!
- gun animation, bouncing shell casings and smoke effects
- a random rigidbody cube that's not working correctly
Video of a version of the game not long before 0.1 release:
https://youtu.be/g3KvNeu4X54

View File

@ -65,6 +65,11 @@ WeaponSecondary={
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":2,"pressed":false,"doubleclick":false,"script":null)
]
}
WeaponReload={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
]
}
ToggleMenu={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)