Skip to content

Commit

Permalink
Add team attribute to entities (#989)
Browse files Browse the repository at this point in the history
* Add new team attribute to Player proto

* Add new :team and :owner_team params to game entities

* Refactor matchmaking launchers and assign team to players before game starts

* Update GameUpdater to receive players with teams and refactor the game initialization

* Use teams attribute to decide every game decision (damage, autoaim, etc.)

* Refactor dynamic obstacle initialization

* Add proto entry to send list of winners (team) instead of a single winner

* Update winning condition due to new teams concept

* Move repeated code in matchmaking queues to Utils module & add bot name generator

* Update game tracker functions due to changes in code (teams)

* Update arena version due to new and changed messages in Protobuf

* Update arena version once again, due to another merged version upgrade

* Update deathmatch endgame check to fit teams feature
  • Loading branch information
Nico-Sanchez authored Dec 9, 2024
1 parent 2400e56 commit f64096d
Show file tree
Hide file tree
Showing 18 changed files with 651 additions and 404 deletions.
88 changes: 76 additions & 12 deletions apps/arena/lib/arena/entities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,30 @@ defmodule Arena.Entities do
alias Arena.Game.Player
alias Arena.Game.Crate

def new_player(id, character_name, player_name, position, direction, config, now) do
@type new_player_params :: %{
id: integer(),
team: integer(),
player_name: String.t(),
position: %{x: float(), y: float()},
direction: %{x: float(), y: float()},
character_name: String.t(),
config: map(),
now: integer()
}

@spec new_player(new_player_params()) :: map()
def new_player(params) do
%{
id: id,
player_name: player_name,
position: position,
direction: direction,
character_name: character_name,
config: config,
now: now,
team: team
} = params

character = Configuration.get_character_config(character_name, config)

%{
Expand All @@ -21,6 +44,7 @@ defmodule Arena.Entities do
direction: direction,
is_moving: false,
aditional_info: %{
team: team,
health: character.base_health,
base_health: character.base_health,
max_health: character.base_health,
Expand Down Expand Up @@ -72,14 +96,26 @@ defmodule Arena.Entities do
}
end

def new_projectile(
id,
position,
direction,
owner_id,
skill_key,
config_params
) do
@type new_projectile_params :: %{
id: integer(),
owner: map(),
position: %{x: float(), y: float()},
direction: %{x: float(), y: float()},
skill_key: String.t(),
config_params: map()
}

@spec new_projectile(new_projectile_params()) :: map()
def new_projectile(params) do
%{
id: id,
owner: owner,
position: position,
direction: direction,
skill_key: skill_key,
config_params: config_params
} = params

%{
id: id,
category: :projectile,
Expand All @@ -94,7 +130,8 @@ defmodule Arena.Entities do
aditional_info: %{
skill_key: skill_key,
damage: config_params.damage,
owner_id: owner_id,
owner_id: owner.id,
owner_team: owner.aditional_info.team,
status: :ACTIVE,
remove_on_collision: config_params.remove_on_collision,
on_explode_mechanics: Map.get(config_params, :on_explode_mechanics),
Expand Down Expand Up @@ -178,7 +215,8 @@ defmodule Arena.Entities do
is_moving: false,
aditional_info: %{
effect_to_apply: pool_params.effect,
owner_id: pool_params.owner_id,
owner_id: pool_params.owner.id,
owner_team: pool_params.owner.aditional_info.team,
effects: [],
stat_multiplier: 0,
duration_ms: duration_ms,
Expand Down Expand Up @@ -237,6 +275,7 @@ defmodule Arena.Entities do
time_until_transition: nil
}
}
|> Arena.Game.Obstacle.handle_transition_init()
end

def new_bush(id, position, radius, shape, vertices \\ []) do
Expand Down Expand Up @@ -395,7 +434,8 @@ defmodule Arena.Entities do
forced_movement: get_in(entity, [:aditional_info, :forced_movement]),
bounty_completed: get_in(entity, [:aditional_info, :bounty_completed]),
mana: get_in(entity, [:aditional_info, :mana]),
current_basic_animation: get_in(entity, [:aditional_info, :current_basic_animation])
current_basic_animation: get_in(entity, [:aditional_info, :current_basic_animation]),
team: get_in(entity, [:aditional_info, :team])
}}
end

Expand Down Expand Up @@ -492,6 +532,30 @@ defmodule Arena.Entities do
def alive?(%{category: :crate} = entity), do: Crate.alive?(entity)
def alive?(%{category: :pool} = _entity), do: true

def filter_damageable(source, targets) do
Map.filter(targets, fn {_, target} -> can_damage?(source, target) end)
end

def filter_targetable(source, targets) do
Map.filter(targets, fn {_, target} -> can_damage?(source, target) and visible?(source, target) end)
end

defp visible?(%{category: :player} = source, target), do: Player.visible?(source, target)
defp visible?(%{category: _any} = _source, _target), do: true

def can_damage?(source, target) do
alive?(target) and not same_team?(source, target)
end

def same_team?(source, target) do
get_team(source) == get_team(target)
end

defp get_team(%{category: :player} = entity), do: entity.aditional_info.team
defp get_team(%{category: :projectile} = entity), do: entity.aditional_info.owner_team
defp get_team(%{category: :pool} = entity), do: entity.aditional_info.owner_team
defp get_team(%{category: category} = _entity), do: category

def update_entity(%{category: :player} = entity, game_state) do
put_in(game_state, [:players, entity.id], entity)
end
Expand Down
4 changes: 3 additions & 1 deletion apps/arena/lib/arena/game/obstacle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule Arena.Game.Obstacle do
Map.filter(obstacles, fn {_obstacle_id, obstacle} -> obstacle.aditional_info.collide_with_projectiles end)
end

def handle_transition_init(obstacle) do
def handle_transition_init(%{aditional_info: %{type: "dynamic"}} = obstacle) do
now = DateTime.utc_now() |> DateTime.to_unix(:millisecond)

current_status_params =
Expand All @@ -34,6 +34,8 @@ defmodule Arena.Game.Obstacle do
end)
end

def handle_transition_init(obstacle), do: obstacle

def update_obstacle_transition_status(game_state, %{aditional_info: %{type: "dynamic"}} = obstacle) do
now = DateTime.utc_now() |> DateTime.to_unix(:millisecond)

Expand Down
13 changes: 6 additions & 7 deletions apps/arena/lib/arena/game/player.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ defmodule Arena.Game.Player do
Module for interacting with Player entity
"""

alias Arena.Game.Crate
alias Arena.GameUpdater
alias Arena.GameTracker
alias Arena.Utils
Expand Down Expand Up @@ -90,8 +89,8 @@ defmodule Arena.Game.Player do
Map.filter(players, fn {_, player} -> alive?(player) end)
end

def targetable_players(current_player, players) do
Map.filter(players, fn {_, player} -> alive?(player) and visible?(current_player, player) end)
def same_team?(source, target) do
target.aditional_info.team != source.aditional_info.team
end

def stamina_full?(player) do
Expand Down Expand Up @@ -225,10 +224,10 @@ defmodule Arena.Game.Player do

{auto_aim?, skill_direction} =
skill_params.target
|> Skill.maybe_auto_aim(skill, player, targetable_players(player, game_state.players))
|> Skill.maybe_auto_aim(skill, player, game_state.players)
|> case do
{false, _} ->
Skill.maybe_auto_aim(skill_params.target, skill, player, Crate.alive_crates(game_state.crates))
Skill.maybe_auto_aim(skill_params.target, skill, player, game_state.crates)

auto_aim ->
auto_aim
Expand Down Expand Up @@ -382,8 +381,8 @@ defmodule Arena.Game.Player do
end
end

def visible?(current_player, candidate_player) do
candidate_player.id in current_player.aditional_info.visible_players
def visible?(source_player, target_player) do
target_player.id in source_player.aditional_info.visible_players
end

def remove_expired_effects(player) do
Expand Down
Loading

0 comments on commit f64096d

Please sign in to comment.