Add rover game and such
This commit is contained in:
1 parent
e80cd37534
commit
373838d3e7
37 files changed
+1558
-35
No files matched your search
@@ -0,0 +1,9 @@
|
||||
extends Spatial
|
||||
|
||||
onready var playback = $AnimationTree["parameters/playback"]
|
||||
|
||||
func idle():
|
||||
playback.travel("idle")
|
||||
|
||||
func drive():
|
||||
playback.travel("driving")
|
||||
@@ -0,0 +1,40 @@
|
||||
extends Resource
|
||||
class_name Interface
|
||||
|
||||
export(Array, String) var method_names
|
||||
|
||||
func assert_implemented_by(script):
|
||||
if !(script is Script):
|
||||
script = script.get_script()
|
||||
var methods = {}
|
||||
for method in script.get_script_method_list():
|
||||
methods[method.name] = method
|
||||
|
||||
for method_name in method_names:
|
||||
assert(methods.has(method_name), "`%s` does not implement `%s` from interface `%s`" % [script.resource_path, method_name, resource_path])
|
||||
|
||||
static func check_script(path: String):
|
||||
var script: Script = load(path)
|
||||
var interfaces = script.get("INTERFACES")
|
||||
if interfaces == null:
|
||||
return
|
||||
for interface in interfaces:
|
||||
interface.assert_implemented_by(script)
|
||||
|
||||
static func check_all_scripts(path: String):
|
||||
if not OS.is_debug_build():
|
||||
return
|
||||
var dir = Directory.new()
|
||||
if dir.open(path) == OK:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if dir.current_is_dir():
|
||||
if not file_name.begins_with("."):
|
||||
check_all_scripts(path + "/" + file_name)
|
||||
else:
|
||||
if file_name.ends_with(".gd"):
|
||||
check_script(path + "/" + file_name)
|
||||
file_name = dir.get_next()
|
||||
else:
|
||||
print("An error occurred when trying to access the path.")
|
||||
@@ -0,0 +1,11 @@
|
||||
extends Spatial
|
||||
|
||||
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
func start_drill():
|
||||
$AnimationPlayer.play("Excavator Running-loop")
|
||||
|
||||
func stop_drill():
|
||||
$AnimationPlayer.play("Excavator Reset")
|
||||
@@ -0,0 +1,4 @@
|
||||
extends Node
|
||||
|
||||
func _init():
|
||||
Interface.check_all_scripts("res://scripts")
|
||||
@@ -5,6 +5,7 @@ signal starved_to_death
|
||||
const StateDefault = preload("res://scripts/player/state/default.gd")
|
||||
const StateInteracting = preload("res://scripts/player/state/interacting.gd")
|
||||
const StateSleeping = preload("res://scripts/player/state/sleeping.gd")
|
||||
const StatePlayingRoverGame = preload("res://scripts/player/state/playing_rover_game.gd")
|
||||
|
||||
const SPEED = 10.0
|
||||
const MAX_HEALTH = 4
|
||||
@@ -133,3 +134,8 @@ func _on_blink_timer_timeout():
|
||||
func sleep(made_it_to_bed: bool, hop_position: Spatial):
|
||||
state.on_sleep(made_it_to_bed, hop_position)
|
||||
|
||||
func start_playing_rover_game():
|
||||
state.on_start_playing_rover_game()
|
||||
|
||||
func stop_playing_rover_game():
|
||||
state.on_stop_playing_rover_game()
|
||||
@@ -1,5 +1,6 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/player/state/state_interface.tres")]
|
||||
const NAME = "default"
|
||||
const EPSILON = 0.0001
|
||||
|
||||
@@ -7,9 +8,6 @@ var ctx = null
|
||||
var anim_tree: AnimationTree
|
||||
var move_playback
|
||||
|
||||
func _init():
|
||||
pass
|
||||
|
||||
func enter_from(state):
|
||||
anim_tree = ctx.get_node("model_transform/DungMan/AnimationTree")
|
||||
move_playback = anim_tree["parameters/Move/playback"]
|
||||
@@ -34,3 +32,10 @@ func unhandled_input(event):
|
||||
|
||||
func on_sleep(made_it_to_bed: bool, hop_position: Spatial):
|
||||
ctx.change_state(ctx.StateSleeping.new(made_it_to_bed, hop_position))
|
||||
|
||||
func on_start_playing_rover_game():
|
||||
ctx.change_state(ctx.StatePlayingRoverGame.new())
|
||||
|
||||
func on_stop_playing_rover_game():
|
||||
assert(false, "invalid state")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/player/state/state_interface.tres")]
|
||||
const NAME = "interacting"
|
||||
|
||||
var ctx: KinematicBody = null
|
||||
@@ -17,7 +18,8 @@ func enter_from(state):
|
||||
timer.connect("timeout", self, "_on_timeout", [], CONNECT_ONESHOT)
|
||||
|
||||
func exit_to(state):
|
||||
pass
|
||||
if timer.is_connected("timeout", self, "_on_timeout"):
|
||||
timer.disconnect("timeout", self, "_on_timeout")
|
||||
|
||||
func physics_process(delta):
|
||||
pass
|
||||
@@ -50,5 +52,10 @@ func try_trigger_interact(area) -> bool:
|
||||
return true
|
||||
|
||||
func on_sleep(made_it_to_bed: bool, hop_position: Spatial):
|
||||
timer.disconnect("timeout", self, "_on_timeout")
|
||||
ctx.change_state(ctx.StateSleeping.new(made_it_to_bed, hop_position))
|
||||
|
||||
func on_start_playing_rover_game():
|
||||
ctx.change_state(ctx.StatePlayingRoverGame.new())
|
||||
|
||||
func on_stop_playing_rover_game():
|
||||
assert(false, "invalid state")
|
||||
@@ -0,0 +1,29 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/player/state/state_interface.tres")]
|
||||
const NAME = "playing_rover_game"
|
||||
|
||||
var ctx: KinematicBody = null
|
||||
|
||||
func enter_from(state):
|
||||
var anim_tree: AnimationTree = ctx.get_node("model_transform/DungMan/AnimationTree")
|
||||
var move_playback: AnimationNodeStateMachinePlayback = anim_tree["parameters/Move/playback"]
|
||||
move_playback.travel("idle")
|
||||
|
||||
func exit_to(state):
|
||||
pass
|
||||
|
||||
func physics_process(delta):
|
||||
pass
|
||||
|
||||
func unhandled_input(event: InputEvent):
|
||||
pass
|
||||
|
||||
func on_sleep(made_it_to_bed: bool, hop_position: Spatial):
|
||||
ctx.change_state(ctx.StateSleeping.new(made_it_to_bed, hop_position))
|
||||
|
||||
func on_start_playing_rover_game():
|
||||
assert(false, "invalid state")
|
||||
|
||||
func on_stop_playing_rover_game():
|
||||
ctx.change_state(ctx.StateDefault.new())
|
||||
@@ -1,5 +1,6 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/player/state/state_interface.tres")]
|
||||
const NAME = "sleeping"
|
||||
|
||||
var ctx: KinematicBody = null
|
||||
@@ -16,6 +17,7 @@ func _init(p_made_it_to_bed: bool, p_hop_position: Spatial = null):
|
||||
made_it_to_bed = p_made_it_to_bed
|
||||
|
||||
func enter_from(state):
|
||||
ctx.get_tree().call_group("on_player_sleep_listener", "on_player_sleep")
|
||||
hop_position = hop_position if hop_position else ctx.get_tree().get_nodes_in_group("bed_hop_position")[0]
|
||||
model_transform = ctx.get_node("model_transform")
|
||||
anim_player = ctx.get_node("model_transform/node_animations")
|
||||
@@ -97,3 +99,9 @@ func unhandled_input(event: InputEvent):
|
||||
|
||||
func on_sleep(made_it_to_bed: bool, hop_position: Spatial):
|
||||
assert(false, "shouldn't be able to sleep while sleeping")
|
||||
|
||||
func on_start_playing_rover_game():
|
||||
assert(false, "invalid state")
|
||||
|
||||
func on_stop_playing_rover_game():
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="Resource" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/Interface.gd" type="Script" id=1]
|
||||
|
||||
[resource]
|
||||
script = ExtResource( 1 )
|
||||
method_names = [ "enter_from", "exit_to", "physics_process", "unhandled_input", "on_sleep", "on_start_playing_rover_game", "on_stop_playing_rover_game" ]
|
||||
@@ -1,5 +1,6 @@
|
||||
extends RigidBody
|
||||
|
||||
export var treasure: Resource
|
||||
|
||||
func _ready():
|
||||
$hit_box.set_meta("owner", self)
|
||||
|
||||
+8
-2
@@ -1,11 +1,17 @@
|
||||
extends RigidBody
|
||||
|
||||
const EPSILON = 0.0001
|
||||
const SPEED = 300.0
|
||||
const TURN = 2.5
|
||||
var heading := Vector3.FORWARD
|
||||
var heading := Vector3.BACK
|
||||
|
||||
func _physics_process(delta):
|
||||
heading = heading.rotated(Vector3.UP, Input.get_axis("right", "left") * TURN * delta).normalized()
|
||||
var input = Vector3(Input.get_axis("right", "left"), 0.0, Input.get_axis("down", "up"))
|
||||
if input.length_squared() > EPSILON:
|
||||
$visual/BeetleIX.drive()
|
||||
else:
|
||||
$visual/BeetleIX.idle()
|
||||
heading = heading.rotated(Vector3.UP, input.x * TURN * delta).normalized()
|
||||
$visual.global_transform = $visual.global_transform.looking_at($visual.global_transform.origin + heading, Vector3.UP)
|
||||
|
||||
func _integrate_forces(state):
|
||||
|
||||
+19
-1
@@ -1,6 +1,19 @@
|
||||
extends Spatial
|
||||
|
||||
signal game_over
|
||||
signal got_treasure(item_type)
|
||||
|
||||
export var play_time: float = 20.0
|
||||
|
||||
const loot_table = {
|
||||
#preload("res://")
|
||||
}
|
||||
|
||||
var main: Node
|
||||
var treasure := [] # is array of item_types
|
||||
|
||||
func _ready():
|
||||
$Timer.start(play_time)
|
||||
spawn_rocks(10)
|
||||
|
||||
func spawn_rocks(count: int):
|
||||
@@ -10,12 +23,17 @@ func spawn_rocks(count: int):
|
||||
var location = locations[i]
|
||||
var rock = preload("res://scenes/rock.tscn").instance()
|
||||
location.add_child(rock)
|
||||
|
||||
|
||||
func _on_collection_area_area_entered(area):
|
||||
if area.has_meta("owner"):
|
||||
area = area.get_meta("owner")
|
||||
area.queue_free()
|
||||
emit_signal("got_treasure", preload("res://item_types/ore.tres"))
|
||||
|
||||
func _process(delta):
|
||||
$"%progress_bar".value = $Timer.time_left * 100.0 / $Timer.wait_time
|
||||
|
||||
func _on_Timer_timeout():
|
||||
emit_signal("game_over")
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
extends Damageable
|
||||
|
||||
const StateIdle = preload("res://scripts/rover_station/state/idle.gd")
|
||||
const StateBroken = preload("res://scripts/rover_station/state/broken.gd")
|
||||
const StatePlaying = preload("res://scripts/rover_station/state/playing.gd")
|
||||
|
||||
var state = null
|
||||
var treasure := [] # array of ItemTypes
|
||||
|
||||
func _ready():
|
||||
state = StateBroken.new() if start_broken else StateIdle.new()
|
||||
state.ctx = self
|
||||
state.enter_from(null)
|
||||
print("rover_station: NULL -> ", state.NAME)
|
||||
|
||||
func change_state(new_state):
|
||||
print("rover_station: ", state.NAME, " -> ", new_state.NAME)
|
||||
new_state.ctx = self
|
||||
state.exit_to(new_state)
|
||||
new_state.enter_from(state)
|
||||
state = new_state
|
||||
|
||||
func _on_coin_machine_coin_requirement_met(player):
|
||||
state.on_coin_machine_coin_requirement_met(player)
|
||||
|
||||
func _on_item_dump_completed():
|
||||
state.on_item_dump_completed()
|
||||
|
||||
func on_player_sleep():
|
||||
state.on_player_sleep()
|
||||
|
||||
func add_treasure(item_type: Resource):
|
||||
if $item_holder.item_in_hold == null:
|
||||
$item_holder.add_item(item_type.spawn_node())
|
||||
else:
|
||||
treasure.push_back(item_type)
|
||||
|
||||
func _on_item_holder_item_changed(item):
|
||||
if item == null and not treasure.empty():
|
||||
$item_holder.add_item(treasure.pop_front().spawn_node())
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/rover_station/state/state_interface.tres")]
|
||||
const NAME = "broken"
|
||||
|
||||
var ctx = null
|
||||
|
||||
func _init():
|
||||
pass
|
||||
|
||||
func enter_from(state):
|
||||
ctx.get_node("item_dump").enabled = true
|
||||
ctx.get_node("item_dump").reset()
|
||||
ctx.get_node("coin_machine").enabled = false
|
||||
ctx.get_node("item_holder").add_enabled = true
|
||||
ctx.get_node("item_holder").remove_enabled = true
|
||||
ctx.get_node("status_light").fail()
|
||||
|
||||
func exit_to(state):
|
||||
assert(state.NAME != "broken")
|
||||
|
||||
func on_coin_machine_coin_requirement_met(player):
|
||||
assert(false, "should be impossible while broken")
|
||||
|
||||
func on_item_dump_completed():
|
||||
ctx.full_heal()
|
||||
ctx.change_state(ctx.StateIdle.new())
|
||||
|
||||
func on_damage_taken():
|
||||
assert(false, "should be impossible while broken")
|
||||
|
||||
func on_player_sleep():
|
||||
ctx.treasure.clear()
|
||||
@@ -0,0 +1,32 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/rover_station/state/state_interface.tres")]
|
||||
const NAME = "idle"
|
||||
|
||||
var ctx = null
|
||||
|
||||
func _init():
|
||||
pass
|
||||
|
||||
func enter_from(state):
|
||||
ctx.get_node("item_dump").enabled = false
|
||||
ctx.get_node("coin_machine").enabled = true
|
||||
ctx.get_node("item_holder").add_enabled = true
|
||||
ctx.get_node("item_holder").remove_enabled = true
|
||||
ctx.get_node("status_light").idle()
|
||||
|
||||
func exit_to(state):
|
||||
pass
|
||||
|
||||
func on_coin_machine_coin_requirement_met(player):
|
||||
ctx.change_state(ctx.StatePlaying.new(player))
|
||||
|
||||
func on_item_dump_completed():
|
||||
assert(false, "item dump should be disabled")
|
||||
|
||||
func on_damage_taken():
|
||||
if ctx.hp <= 0:
|
||||
ctx.change_state(ctx.StateBroken.new())
|
||||
|
||||
func on_player_sleep():
|
||||
ctx.treasure.clear()
|
||||
@@ -0,0 +1,52 @@
|
||||
extends Reference
|
||||
|
||||
const INTERFACES = [preload("res://scripts/rover_station/state/state_interface.tres")]
|
||||
const NAME = "playing"
|
||||
|
||||
var ctx: Spatial = null
|
||||
var game: Node
|
||||
var player: Node
|
||||
|
||||
func _init(p_player: Node):
|
||||
player = p_player
|
||||
|
||||
func enter_from(state):
|
||||
ctx.get_node("item_dump").enabled = false
|
||||
ctx.get_node("coin_machine").enabled = false
|
||||
ctx.get_node("item_holder").add_enabled = false
|
||||
ctx.get_node("item_holder").remove_enabled = false
|
||||
ctx.get_node("status_light").activate()
|
||||
# START THE GAME
|
||||
game = ctx.get_node("%rover_game").create_instance()
|
||||
game.connect("got_treasure", self, "on_got_treasure")
|
||||
game.connect("game_over", self, "on_game_over")
|
||||
ctx.get_node("game_canvas").visible = true
|
||||
player.start_playing_rover_game()
|
||||
|
||||
func exit_to(state):
|
||||
# END THE GAME
|
||||
player.stop_playing_rover_game()
|
||||
ctx.get_node("game_canvas").visible = false
|
||||
if game:
|
||||
game.queue_free()
|
||||
game = null
|
||||
|
||||
func on_coin_machine_coin_requirement_met(player):
|
||||
assert(false, "coin machine should be disabled while playing")
|
||||
|
||||
func on_item_dump_completed():
|
||||
assert(false, "item dump should be disabled while playing")
|
||||
|
||||
func on_damage_taken():
|
||||
if ctx.hp <= 0:
|
||||
ctx.change_state(ctx.StateBroken.new())
|
||||
|
||||
func on_got_treasure(treasure: Resource):
|
||||
ctx.add_treasure(treasure)
|
||||
|
||||
func on_game_over():
|
||||
ctx.change_state(ctx.StateIdle.new())
|
||||
|
||||
func on_player_sleep():
|
||||
ctx.treasure.clear()
|
||||
ctx.change_state(ctx.StateIdle.new())
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="Resource" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/Interface.gd" type="Script" id=1]
|
||||
|
||||
[resource]
|
||||
script = ExtResource( 1 )
|
||||
method_names = [ "enter_from", "exit_to", "on_coin_machine_coin_requirement_met", "on_item_dump_completed", "on_player_sleep" ]
|
||||
Reference in new issue
Block a user