update
This commit is contained in:
82
systems/aggro/aggro_tracker.gd
Normal file
82
systems/aggro/aggro_tracker.gd
Normal file
@@ -0,0 +1,82 @@
|
||||
extends Node
|
||||
|
||||
var aggro_tables: Dictionary = {}
|
||||
var players_in_range: Dictionary = {}
|
||||
|
||||
func add_aggro(enemy: Node, player: Node, amount: float) -> void:
|
||||
if enemy not in aggro_tables:
|
||||
aggro_tables[enemy] = {}
|
||||
if player in aggro_tables[enemy]:
|
||||
aggro_tables[enemy][player] += amount
|
||||
else:
|
||||
aggro_tables[enemy][player] = amount
|
||||
|
||||
func remove_aggro(enemy: Node, player: Node, amount: float) -> void:
|
||||
if enemy in aggro_tables and player in aggro_tables[enemy]:
|
||||
aggro_tables[enemy][player] -= amount
|
||||
if aggro_tables[enemy][player] <= 0:
|
||||
aggro_tables[enemy].erase(player)
|
||||
|
||||
func add_player_in_range(enemy: Node, player: Node) -> void:
|
||||
if enemy not in players_in_range:
|
||||
players_in_range[enemy] = []
|
||||
if player not in players_in_range[enemy]:
|
||||
players_in_range[enemy].append(player)
|
||||
|
||||
func remove_player_in_range(enemy: Node, player: Node) -> void:
|
||||
if enemy in players_in_range:
|
||||
players_in_range[enemy].erase(player)
|
||||
|
||||
func is_player_in_any_range(player: Node) -> bool:
|
||||
for enemy in players_in_range:
|
||||
if is_instance_valid(enemy) and player in players_in_range[enemy]:
|
||||
return true
|
||||
return false
|
||||
|
||||
func get_top_target(table: Dictionary) -> Node:
|
||||
var top: Node = null
|
||||
var top_val := 0.0
|
||||
for player in table:
|
||||
if is_instance_valid(player) and table[player] > top_val:
|
||||
top_val = table[player]
|
||||
top = player
|
||||
return top
|
||||
|
||||
func update_target(enemy: Node) -> void:
|
||||
if not "state" in enemy:
|
||||
return
|
||||
var table: Dictionary = aggro_tables[enemy]
|
||||
var top: Node = get_top_target(table)
|
||||
if top and top != enemy.target:
|
||||
enemy.target = top
|
||||
if enemy.state == enemy.State.IDLE or enemy.state == enemy.State.RETURN:
|
||||
enemy.state = enemy.State.CHASE
|
||||
elif not top and enemy.state != enemy.State.IDLE and enemy.state != enemy.State.RETURN:
|
||||
enemy.target = null
|
||||
enemy.state = enemy.State.RETURN
|
||||
|
||||
func get_enemies_in_radius(source: Node, radius: float) -> Array:
|
||||
var result: Array = []
|
||||
for enemy in get_tree().get_nodes_in_group("enemies"):
|
||||
if enemy != source and is_instance_valid(enemy):
|
||||
var dist: float = source.global_position.distance_to(enemy.global_position)
|
||||
if dist <= radius:
|
||||
result.append(enemy)
|
||||
return result
|
||||
|
||||
func get_alert_radius(entity: Node) -> float:
|
||||
var base: BaseStats = Stats.get_base(entity)
|
||||
return base.alert_radius if base is EnemyStats else 10.0
|
||||
|
||||
func erase_entity(entity: Node) -> void:
|
||||
aggro_tables.erase(entity)
|
||||
players_in_range.erase(entity)
|
||||
for enemy in aggro_tables:
|
||||
if is_instance_valid(enemy):
|
||||
aggro_tables[enemy].erase(entity)
|
||||
if "target" in enemy and entity == enemy.target:
|
||||
enemy.target = null
|
||||
enemy.state = enemy.State.RETURN
|
||||
for enemy in players_in_range:
|
||||
if is_instance_valid(enemy):
|
||||
players_in_range[enemy].erase(entity)
|
||||
Reference in New Issue
Block a user