Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Area definition + health regen while on base camp #234

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions classes/Map.gd
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ class_name Map
@export var npcs_to_sync: Node2D
@export var player_respawn_locations: Node2D
@export var portals_to_sync: Node2D
@export var areas_to_sync: Node2D

var players: Node2D
var enemies: Node2D
var npcs: Node2D
var items: Node2D
var enemy_respawns: Node2D
var areas: Node2D


# Called when the node enters the scene tree for the first time.
Expand Down Expand Up @@ -45,6 +47,10 @@ func _ready():
items.name = "Items"
items.y_sort_enabled = true
synced_entities.add_child(items)

areas = Node2D.new()
areas.name = "Areas"
synced_entities.add_child(areas)

# Remove map from entities to make sure it takes part of the ysort mechanics
map_to_sync.get_parent().remove_child(map_to_sync)
Expand All @@ -62,6 +68,7 @@ func _ready():

_load_enemies()
_load_npcs()
#load_areas()


func _load_enemies():
Expand All @@ -86,6 +93,17 @@ func _load_npcs():
npcs_to_sync.queue_free()


func load_areas():
for area: MapArea2D in areas_to_sync.get_children():
area.get_parent().remove_child(area)

if multiplayer_connection.is_server():
area.name = str(area.get_instance_id())
areas.add_child(area)

areas_to_sync.queue_free()


func get_entity_by_name(entity_name: String) -> Node:
var entity: Node = enemies.get_node_or_null(entity_name)
if entity != null:
Expand Down
100 changes: 100 additions & 0 deletions classes/MapArea2D.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
extends Area2D
class_name MapArea2D
## A way to define special functionality in certain parts of the map.
## These are intended to be on the client side as well.
## Other objects may use

#TODO: Allow creating and removing areas during runtime

enum Rules {
PVP = 1, # Not implemented. Players cannot damage other players under any circumstances.
SAFE = 2,# The player may regenerate health and perform other "downtime" activities.
NO_ENEMY_PATH = 4,# Not implemented. Enemies may not enter this area under any circumstances.
}

@export_flags(
"Allow PVP:1",
"Safe Zone:2",
"Enemy Cannot Path:4"
) var rules: int = 2

## These may be used as metadata for the area and are safe to be set by other objects.
@export var flags: Dictionary

static var world: World2D

func _init() -> void:
collision_layer = J.PHYSICS_LAYER_MAP_AREA
collision_mask = 0
modulate.a = 0.2


func _ready() -> void:
if not world is World2D:
world = get_world_2d()

print(get_rules_as_text())


func is_rule_active(rule: Rules)->bool:
return rule & rules


func get_rules_as_text() -> String:
var output: String = ""
for rule: String in Rules:
output += rule + " active? " + str(is_rule_active(Rules[rule])) + "\n"

return output


func set_flag(flag: String, state: bool):
flags[flag] = state


func remove_flag(flag: String):
flags.erase(flag)


static func get_default_point_parameters() -> PhysicsPointQueryParameters2D:
var parameters := PhysicsPointQueryParameters2D.new()
parameters.collide_with_bodies = false
parameters.collide_with_areas = true
parameters.collision_mask = J.PHYSICS_LAYER_MAP_AREA

return parameters


static func get_areas_at_point(global_pos: Vector2)->Array[MapArea2D]:
var areas_found: Array[MapArea2D] = []
var direct_space: PhysicsDirectSpaceState2D = world.direct_space_state

var parameters: PhysicsPointQueryParameters2D = get_default_point_parameters()
parameters.position = global_pos

var results: Array[Dictionary] = direct_space.intersect_point(parameters)
for result: Dictionary in results:
if result["collider"] is MapArea2D:
areas_found.append(result["collider"])
else:
GodotLogger.warn("Found non-MapArea2D in MAP_AREA layer with path '{0}'".format([result["collider"].get_path()]))

return areas_found


static func is_rule_active_at(global_pos: Vector2, rule_to_check: Rules) -> bool:
var areas: Array[MapArea2D] = get_areas_at_point(global_pos)
for area: MapArea2D in areas:
if area.is_rule_active(rule_to_check):
return true

return false


static func get_flags_at(global_pos: Vector2) -> Array[String]:
var output: Array[String]
var areas: Array[MapArea2D] = get_areas_at_point(global_pos)
for area: MapArea2D in areas:
output += area.flags.values()

return output
Original file line number Diff line number Diff line change
Expand Up @@ -650,3 +650,6 @@ func _on_energy_regen_timer_timeout():

if energy != energy_max:
energy_recovery(target_node.get_name(), energy_regen)

if hp != hp_max and MapArea2D.is_rule_active_at(target_node.global_position, MapArea2D.Rules.SAFE):
heal(target_node.get_name(), hp_max * 0.05)
1 change: 1 addition & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ locale/translations=PackedStringArray("res://assets/translation/en_US.en.transla
2d_physics/layer_6="Networking"
2d_physics/layer_7="Projectiles"
2d_physics/layer_8="Passable Entity"
2d_physics/layer_9="Map Area"

[rendering]

Expand Down
1 change: 1 addition & 0 deletions scripts/singletons/jdungeon.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const PHYSICS_LAYER_ITEMS = 16
const PHYSICS_LAYER_NETWORKING = 32
const PHYSICS_LAYER_PROJECTILE = 64
const PHYSICS_LAYER_PASSABLE_ENTITIES = 128
const PHYSICS_LAYER_MAP_AREA = 256

const ARRIVAL_DISTANCE = 8
const DROP_RANGE = 64
Expand Down
Loading