From 0b14efee60765701f439b5174e56c0cf0639d20c Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Sun, 29 Sep 2024 14:28:57 +0100 Subject: player,bsp_level_generator: Add lockers and interaction --- prefabs/locker.tscn | 31 ++++++++++++++++++++++++ prefabs/test_arena.tscn | 16 ++++++++++++- project.godot | 6 +++++ scripts/bsp_level_generator.gd | 54 +++++++++++++++++++++++++++++++++++------- scripts/locker.gd | 11 +++++++++ scripts/player.gd | 23 +++++++++++++++++- scripts/tile.gd | 2 +- 7 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 prefabs/locker.tscn create mode 100644 scripts/locker.gd diff --git a/prefabs/locker.tscn b/prefabs/locker.tscn new file mode 100644 index 0000000..ce4f5ff --- /dev/null +++ b/prefabs/locker.tscn @@ -0,0 +1,31 @@ +[gd_scene load_steps=5 format=3 uid="uid://gq2idl5jgymn"] + +[ext_resource type="Script" path="res://scripts/locker.gd" id="1_t5tjw"] + +[sub_resource type="BoxMesh" id="BoxMesh_uasm5"] +size = Vector3(1, 1.5, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_a2nrx"] +size = Vector3(2, 1.5, 2) + +[sub_resource type="BoxShape3D" id="BoxShape3D_lc36s"] +size = Vector3(1, 1.5, 1) + +[node name="Locker" type="Area3D"] +collision_layer = 8 +collision_mask = 8 +script = ExtResource("1_t5tjw") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.75, 0.5) +mesh = SubResource("BoxMesh_uasm5") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.75, 0.5) +shape = SubResource("BoxShape3D_a2nrx") + +[node name="StaticBody3D" type="StaticBody3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.75, 0.5) +shape = SubResource("BoxShape3D_lc36s") diff --git a/prefabs/test_arena.tscn b/prefabs/test_arena.tscn index 87d6463..c84ae4b 100644 --- a/prefabs/test_arena.tscn +++ b/prefabs/test_arena.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=9 format=3 uid="uid://dlevowk0jrhlg"] +[gd_scene load_steps=10 format=3 uid="uid://dlevowk0jrhlg"] [ext_resource type="Script" path="res://scripts/dungeon_manager.gd" id="1_dbsm0"] [ext_resource type="PackedScene" uid="uid://cc1m2a1obsyn4" path="res://addons/fpc/character.tscn" id="1_vc6b5"] @@ -71,6 +71,9 @@ _data = { "walk": SubResource("Animation_nw35k") } +[sub_resource type="BoxShape3D" id="BoxShape3D_r46wa"] +size = Vector3(1.5, 2, 1.5) + [node name="Node3D" type="Node3D"] script = ExtResource("1_dbsm0") @@ -107,4 +110,15 @@ libraries = { "": SubResource("AnimationLibrary_7dyvd") } +[node name="Area3D" type="Area3D" parent="Player/PlayerCam"] +collision_layer = 8 +collision_mask = 8 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Player/PlayerCam/Area3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, -1) +shape = SubResource("BoxShape3D_r46wa") + [node name="LevelContainer" type="Node3D" parent="."] + +[connection signal="area_entered" from="Player/PlayerCam/Area3D" to="Player/PlayerCam" method="_on_interactable_enter"] +[connection signal="area_exited" from="Player/PlayerCam/Area3D" to="Player/PlayerCam" method="_on_interactable_exit"] diff --git a/project.godot b/project.godot index 34a0654..be734f2 100644 --- a/project.godot +++ b/project.godot @@ -64,11 +64,17 @@ attack={ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(184, 6),"global_position":Vector2(193, 52),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) ] } +interact={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +] +} [layer_names] 3d_physics/layer_2="grapple" 3d_physics/layer_3="player" +3d_physics/layer_4="interact" [rendering] diff --git a/scripts/bsp_level_generator.gd b/scripts/bsp_level_generator.gd index f8b850d..0f38b96 100644 --- a/scripts/bsp_level_generator.gd +++ b/scripts/bsp_level_generator.gd @@ -10,6 +10,7 @@ extends Node3D @export var wall_thickness: float = 1 var wall_inst = preload("res://models/wall.blend") +var locker_inst = preload("res://prefabs/locker.tscn") var level_geo: Node3D enum Direction {LEFT, RIGHT} @@ -21,6 +22,8 @@ var min_room_size: int = min_dim * min_dim var grid_width = width + 1 var grid_height = height + 1 +var rooms: Array[Rect2i] = [] + class BSPNode: var axis: int var min_dims: Vector2i @@ -91,6 +94,10 @@ func generate_grid(map: BSPNode, grid: Array[Tile.Tile]) -> void: for y in range(map.min_dims.y, map.max_dims.y - 1): for x in range(map.min_dims.x, map.max_dims.x - 1): grid[(y+1) * grid_width + (x+1)] = Tile.Tile.FLOOR + + # TODO double check room dimensions are correct here + var room = Rect2i(map.min_dims + Vector2i.ONE, map.max_dims - map.min_dims) + rooms.append(room) else: generate_grid(map.left, grid) generate_grid(map.right, grid) @@ -124,6 +131,29 @@ func generate_grid(map: BSPNode, grid: Array[Tile.Tile]) -> void: get_tree().quit() return +func get_tile(grid: Array[Tile.Tile], pos: Vector2i) -> Tile.Tile: + return grid[pos.y * grid_width + pos.x] + +func populate_grid(grid: Array[Tile.Tile]) -> void: + for room in rooms: + var num_lockers = randi_range(0, 2) + print("Generating ", num_lockers, "Lockers") + for i in range(num_lockers): + var found = false + while not found: + var pos = Vector2i(randi_range(room.position.x, room.end.x - 1), randi_range(room.position.y, room.end.y - 1)) + if grid[pos.y * grid_width + pos.x] == Tile.Tile.FLOOR \ + and (get_tile(grid, pos + Vector2i(1, 0)) == Tile.Tile.WALL \ + or get_tile(grid, pos + Vector2i(-1, 0)) == Tile.Tile.WALL \ + or get_tile(grid, pos + Vector2i(0, 1)) == Tile.Tile.WALL \ + or get_tile(grid, pos + Vector2i(0, -1)) == Tile.Tile.WALL) \ + and get_tile(grid, pos + Vector2i(1, 0)) != Tile.Tile.DOOR \ + and get_tile(grid, pos + Vector2i(-1, 0)) != Tile.Tile.DOOR \ + and get_tile(grid, pos + Vector2i(0, 1)) != Tile.Tile.DOOR \ + and get_tile(grid, pos + Vector2i(0, -1)) != Tile.Tile.DOOR: + grid[pos.y * grid_width + pos.x] = Tile.Tile.LOCKER + found = true + func generate_plane(array: Array, pos: Vector3, dim: Array[Vector3], normal: Vector3) -> void: var index = len(array[Mesh.ARRAY_VERTEX]) array[Mesh.ARRAY_VERTEX].append(wall_thickness*pos) @@ -148,7 +178,15 @@ func generate_geo(grid: Array[Tile.Tile], array: Array) -> void: for x in range(grid_width): var tile = grid[y * grid_width + x] - if tile == Tile.Tile.FLOOR or tile == Tile.Tile.DOOR: + if tile == Tile.Tile.WALL: + generate_plane(array, Vector3(x, 2, y), [Vector3(0, 0, 1), Vector3(0, -2, 0)], Vector3.LEFT) + generate_plane(array, Vector3(x, 2, y+1), [Vector3(1, 0, 0), Vector3(0, -2, 0)], Vector3.BACK) + generate_plane(array, Vector3(x+1, 2, y+1), [Vector3(0, 0, -1), Vector3(0, -2, 0)], Vector3.RIGHT) + generate_plane(array, Vector3(x+1, 2, y), [Vector3(-1, 0, 0), Vector3(0, -2, 0)], Vector3.FORWARD) + var wall: Node3D = level_geo.get_node("./Wall").duplicate() + wall.position = Vector3(x, 0, y) + add_child(wall) + else: generate_plane(array, Vector3(x, 0, y), [Vector3(1, 0, 0), Vector3(0, 0, 1)], Vector3.UP) var floor_tile: Node3D = level_geo.get_node("./Floor").duplicate() floor_tile.position = Vector3(x, 0, y) @@ -158,14 +196,11 @@ func generate_geo(grid: Array[Tile.Tile], array: Array) -> void: ciel_tile.rotate_z(deg_to_rad(180)) ciel_tile.position = Vector3(x+1, 2, y) add_child(ciel_tile) - elif tile == Tile.Tile.WALL: - generate_plane(array, Vector3(x, 2, y), [Vector3(0, 0, 1), Vector3(0, -2, 0)], Vector3.LEFT) - generate_plane(array, Vector3(x, 2, y+1), [Vector3(1, 0, 0), Vector3(0, -2, 0)], Vector3.BACK) - generate_plane(array, Vector3(x+1, 2, y+1), [Vector3(0, 0, -1), Vector3(0, -2, 0)], Vector3.RIGHT) - generate_plane(array, Vector3(x+1, 2, y), [Vector3(-1, 0, 0), Vector3(0, -2, 0)], Vector3.FORWARD) - var wall: Node3D = level_geo.get_node("./Wall").duplicate() - wall.position = Vector3(x, 0, y) - add_child(wall) + + if tile == Tile.Tile.LOCKER: + var locker: Node3D = locker_inst.instantiate() + locker.position = Vector3(x, 0, y) + add_child(locker) func _ready() -> void: var starting_axis = randi_range(0, 1) @@ -184,6 +219,7 @@ func _ready() -> void: surface_array[Mesh.ARRAY_NORMAL] = PackedVector3Array() generate_grid(map, grid) + populate_grid(grid) grid_generated.emit(grid, grid_width, grid_height) level_geo = wall_inst.instantiate() generate_geo(grid, surface_array) diff --git a/scripts/locker.gd b/scripts/locker.gd new file mode 100644 index 0000000..b19d23a --- /dev/null +++ b/scripts/locker.gd @@ -0,0 +1,11 @@ +extends Area3D + +var contents: int = 0 +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + contents = randi_range(0, 20) + +func get_contents() -> int: + var con = contents + contents = 0 + return con diff --git a/scripts/player.gd b/scripts/player.gd index 275100a..3b1fb6a 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -20,6 +20,8 @@ var bullet_inst = preload("res://prefabs/bullet.tscn") var ammo: int = 100 var fire_timer: float = fire_rate +var interactable: Node3D = null + # Called when the node enters the scene tree for the first time. func _ready() -> void: pass # Replace with function body. @@ -80,12 +82,31 @@ func fire_weapon(delta: float) -> void: fire_timer = 0 else: fire_timer += delta - + +func do_interact() -> void: + if Input.is_action_just_pressed("interact") and interactable != null: + if interactable.has_method("get_contents"): + var contents = interactable.get_contents() + if contents > 0: + ammo += contents + print("Got ", contents, " ammo!") + else: + print("Empty container") func _physics_process(delta: float) -> void: do_grapple() + do_interact() fire_weapon(delta) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta: float) -> void: pass + + +func _on_interactable_enter(body: Node3D) -> void: + interactable = body + print("Got interactable") + +func _on_interactable_exit(body: Node3D) -> void: + if interactable == body: + interactable = null diff --git a/scripts/tile.gd b/scripts/tile.gd index 87bc2a3..38bc445 100644 --- a/scripts/tile.gd +++ b/scripts/tile.gd @@ -1,3 +1,3 @@ extends Node -enum Tile {FLOOR, WALL, DOOR} +enum Tile {FLOOR, WALL, DOOR, LOCKER} -- cgit