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

[GH-580] Fake Item and Traps #598

Merged
merged 51 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
fb46644
Add logic for item mechanics and item pickup effects
tvillegas98 May 9, 2024
51e3d0b
Add function call to use the item mechanics and pickup effects
tvillegas98 May 9, 2024
7525fe0
Refactor item logic to return the game state
tvillegas98 May 10, 2024
529e06d
Pass the game state to game state
tvillegas98 May 10, 2024
27579af
Commit to debug
tvillegas98 May 10, 2024
89846fc
Refactor process item in game updater
tvillegas98 May 10, 2024
8d8938a
Remove IO.inspect
tvillegas98 May 10, 2024
774c709
Rename variable and add docs
tvillegas98 May 10, 2024
ca9ad9e
Add pickable field for item
tvillegas98 May 13, 2024
dd66b4f
Use all items config when creating an item
tvillegas98 May 13, 2024
5956cd7
Add if to check if an item is pickable
tvillegas98 May 13, 2024
c037b51
Add status to item
tvillegas98 May 13, 2024
7c7a8b0
Merge branch 'main' into gh-580-fake-item
tvillegas98 May 13, 2024
db9f5c7
Merge branch 'main' into gh-580-fake-item
tvillegas98 May 13, 2024
b5216a6
Remove pickup effect from items
tvillegas98 May 14, 2024
a9bc168
Add trap entity
tvillegas98 May 14, 2024
4d59f32
Handle the traps on the game updater
tvillegas98 May 14, 2024
8526fc7
Add feature to activate traps
tvillegas98 May 14, 2024
566ef71
Add logic to activate traps
tvillegas98 May 14, 2024
9ce7607
Add protobuf messages
tvillegas98 May 14, 2024
5536916
Fix activate trap
tvillegas98 May 14, 2024
07e73ed
Add status to traps
tvillegas98 May 14, 2024
d38c9ee
Add trap module
tvillegas98 May 14, 2024
a1ddf5a
Modify config to add mechanics to items
tvillegas98 May 14, 2024
d32c50d
Remove not needed function
tvillegas98 May 14, 2024
e6c42ba
Add status to traps when creating
tvillegas98 May 14, 2024
c3c47f8
Remove traps after a certain time
tvillegas98 May 14, 2024
b0e95f2
Change doc for module doc
tvillegas98 May 14, 2024
75ebecb
Merge branch 'main' into gh-580-fake-item
tvillegas98 May 14, 2024
a00a609
Mix format
tvillegas98 May 14, 2024
d624900
Restore function call
tvillegas98 May 14, 2024
6c82765
Restore item spawn config
tvillegas98 May 14, 2024
1a5c575
Show traps in browser client
agustinesco May 15, 2024
15f17f5
Remove not used function in item.ex
tvillegas98 May 15, 2024
c434d47
Restore golden clock in config.json
tvillegas98 May 15, 2024
eef3ef4
Refactor traps and game updater logic
tvillegas98 May 15, 2024
bd55574
Merge branch 'main' into gh-580-fake-item
tvillegas98 May 15, 2024
aff0d13
restore file
tvillegas98 May 15, 2024
98b4725
Add proximity field
tvillegas98 May 15, 2024
d7bd9fa
Add trap to category enum
tvillegas98 May 15, 2024
fe0e182
Add proximity feature for traps
tvillegas98 May 15, 2024
535f018
Add new status for traps to remove the traps already triggered
tvillegas98 May 15, 2024
a9080e5
Messages proto
tvillegas98 May 15, 2024
a2e256b
Add prepare status for traps
tvillegas98 May 16, 2024
376d8e7
Add new trap status
tvillegas98 May 16, 2024
25d5d52
Remove IO.inspect
tvillegas98 May 16, 2024
bf98807
Merge branch 'main' into gh-580-fake-item
tvillegas98 May 17, 2024
e904f52
Mix format
tvillegas98 May 17, 2024
418faa8
Show traps and crates in the client's browser
tvillegas98 May 20, 2024
8d109d7
Remove fake item config
tvillegas98 May 20, 2024
0191dd8
Remove fake item
tvillegas98 May 20, 2024
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
34 changes: 32 additions & 2 deletions apps/arena/lib/arena/entities.ex
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ defmodule Arena.Entities do
is_moving: false,
aditional_info: %{
name: config.name,
pull_immunity: true,
effects: config.effects
effects: config.effects,
mechanics: config.mechanics,
pull_immunity: true
}
}
end
Expand Down Expand Up @@ -253,6 +254,35 @@ defmodule Arena.Entities do
}
end

def new_trap(
id,
owner_id,
position,
config
) do
%{
id: id,
category: :trap,
shape: :circle,
name: "Trap" <> Integer.to_string(id),
position: position,
radius: config.radius,
vertices: config.vertices,
speed: 0.0,
direction: %{x: 0.0, y: 0.0},
is_moving: false,
aditional_info: %{
name: config.name,
mechanics: config.mechanics,
preparation_delay_ms: config.preparation_delay_ms,
activation_delay_ms: config.activation_delay_ms,
owner_id: owner_id,
activate_on_proximity: config.activate_on_proximity,
status: :PENDING
}
}
end

def make_circular_area(id, position, range) do
%{
id: id,
Expand Down
33 changes: 33 additions & 0 deletions apps/arena/lib/arena/game/item.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule Arena.Game.Item do
@moduledoc """
Module to handle items logic
"""

alias Arena.Entities

@doc """
Apply all item mechanics to an entity
"""
def do_mechanics(game_state, entity, mechanics) do
Enum.reduce(mechanics, game_state, fn mechanic, game_state_acc ->
do_mechanic(game_state_acc, entity, mechanic)
end)
end

@doc """
Apply an item mechanic to an entity, depending on the mechanic type.
"""
def do_mechanic(game_state, entity, {:spawn_bomb, bomb_params}) do
last_id = game_state.last_id + 1

now = System.monotonic_time(:millisecond)

new_trap =
Entities.new_trap(last_id, entity.id, entity.position, bomb_params)
|> Map.put(:prepare_at, now + bomb_params.preparation_delay_ms)

game_state
|> put_in([:last_id], last_id)
|> put_in([:traps, new_trap.id], new_trap)
end
end
14 changes: 9 additions & 5 deletions apps/arena/lib/arena/game/player.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Arena.Game.Player do
alias Arena.Utils
alias Arena.Game.Effect
alias Arena.Game.Skill
alias Arena.Game.Item

def add_action(player, action) do
Process.send_after(self(), {:remove_skill_action, player.id, action.action}, action.duration)
Expand Down Expand Up @@ -277,11 +278,14 @@ defmodule Arena.Game.Player do
game_state

item ->
Enum.reduce(item.effects, game_state, fn effect_name, game_state_acc ->
effect = Enum.find(game_config.effects, fn %{name: name} -> name == effect_name end)
Effect.put_effect_to_entity(game_state_acc, player, player.id, effect)
end)
|> put_in([:players, player.id, :aditional_info, :inventory], nil)
game_state =
Enum.reduce(item.effects, game_state, fn effect_name, game_state_acc ->
effect = Enum.find(game_config.effects, fn %{name: name} -> name == effect_name end)
Effect.put_effect_to_entity(game_state_acc, player, player.id, effect)
end)
|> put_in([:players, player.id, :aditional_info, :inventory], nil)

Item.do_mechanics(game_state, player, item.mechanics)
end
end

Expand Down
6 changes: 6 additions & 0 deletions apps/arena/lib/arena/game/skill.ex
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ defmodule Arena.Game.Skill do
}),
do: get_in(game_state, [:players, owner_id])

defp get_entity_player_owner(game_state, %{
category: :trap,
aditional_info: %{owner_id: owner_id}
}),
do: get_in(game_state, [:players, owner_id])

defp maybe_move_player(game_state, %{category: :player} = player, move_by)
when not is_nil(move_by) do
player_for_moving = %{player | is_moving: true, speed: move_by}
Expand Down
23 changes: 23 additions & 0 deletions apps/arena/lib/arena/game/trap.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Arena.Game.Trap do
@moduledoc """
Module to handle traps logic
"""
alias Arena.Game.Skill

@doc """
Apply all trap mechanics to an entity
"""
def do_mechanics(game_state, entity, mechanics) do
Enum.reduce(mechanics, game_state, fn mechanic, game_state_acc ->
do_mechanic(game_state_acc, entity, mechanic)
end)
end

@doc """
Apply a trap mechanic to an entity, depending on the mechanic type.
"""
def do_mechanic(game_state, entity, {:circle_hit, circle_hit}) do
# We will be using the skill mechanic here until we abstract the attacks
Skill.do_mechanic(game_state, entity, {:circle_hit, circle_hit}, %{})
end
end
83 changes: 81 additions & 2 deletions apps/arena/lib/arena/game_updater.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule Arena.GameUpdater do
alias Arena.Serialization.{GameEvent, GameState, GameFinished}
alias Phoenix.PubSub
alias Arena.Utils
alias Arena.Game.Trap

##########################
# API
Expand Down Expand Up @@ -151,6 +152,11 @@ defmodule Arena.GameUpdater do
# Crates
|> handle_destroyed_crates(state.game_config)
|> Map.put(:server_timestamp, now)
# Traps
|> remove_activated_traps()
|> prepare_traps()
|> handle_trap_collisions()
|> activate_trap_mechanics()

broadcast_game_update(game_state)
game_state = %{game_state | killfeed: [], damage_taken: %{}, damage_done: %{}}
Expand Down Expand Up @@ -490,7 +496,8 @@ defmodule Arena.GameUpdater do
status: state.status,
start_game_timestamp: state.start_game_timestamp,
obstacles: complete_entities(state.obstacles),
crates: complete_entities(state.crates)
crates: complete_entities(state.crates),
traps: complete_entities(state.traps)
}}
})

Expand Down Expand Up @@ -562,6 +569,7 @@ defmodule Arena.GameUpdater do
|> Map.put(:status, :PREPARING)
|> Map.put(:start_game_timestamp, initial_timestamp + config.game.start_game_time_ms)
|> Map.put(:positions, %{})
|> Map.put(:traps, %{})

{game, _} =
Enum.reduce(clients, {new_game, config.map.initial_positions}, fn {client_id, character_name, player_name,
Expand Down Expand Up @@ -670,6 +678,74 @@ defmodule Arena.GameUpdater do
%{game_state | players: players}
end

defp activate_trap_mechanics(game_state) do
now = System.monotonic_time(:millisecond)

activated_traps =
Enum.filter(game_state.traps, fn {_trap_id, trap} ->
trap_activated?(trap, now)
end)

Enum.reduce(activated_traps, game_state, fn {_trap_id, trap}, game_state_acc ->
game_state = Trap.do_mechanics(game_state_acc, trap, trap.aditional_info.mechanics)
trap = put_in(trap, [:aditional_info, :status], :USED)
update_entity_in_game_state(game_state, trap)
end)
end

defp remove_activated_traps(game_state) do
remaining_traps =
Enum.filter(game_state.traps, fn {_trap_id, trap} ->
trap.aditional_info.status != :USED
end)
|> Map.new()

put_in(game_state, [:traps], remaining_traps)
end

def handle_trap_collisions(game_state) do
players = game_state.players
traps = game_state.traps |> Enum.filter(fn {_trap_id, trap} -> trap.aditional_info.status == :PREPARED end)

Enum.reduce(players, game_state, fn {_player_id, player}, game_state_acc ->
Enum.reduce(traps, game_state_acc, fn {trap_id, trap}, game_state_acc ->
if trap_id in player.collides_with && trap.aditional_info.activate_on_proximity do
now = System.monotonic_time(:millisecond)

trap =
trap
|> put_in([:aditional_info, :status], :TRIGGERED)
|> Map.put(:activate_at, now + trap.aditional_info.activation_delay_ms)

update_entity_in_game_state(game_state_acc, trap)
else
game_state_acc
end
end)
end)
end

def prepare_traps(game_state) do
now = System.monotonic_time(:millisecond)

Enum.reduce(game_state.traps, game_state, fn {_trap_id, trap}, game_state_acc ->
if trap_ready?(trap, now) do
trap = put_in(trap, [:aditional_info, :status], :PREPARED)
update_entity_in_game_state(game_state_acc, trap)
else
game_state_acc
end
end)
end

defp trap_activated?(trap, now) do
Map.has_key?(trap, :activate_at) && trap.activate_at < now && trap.aditional_info.status == :TRIGGERED
end

defp trap_ready?(trap, now) do
trap.aditional_info.status == :PENDING && trap.prepare_at < now
end

defp remove_effects_on_action(game_state) do
players =
Map.new(game_state.players, fn {player_id, player} ->
Expand Down Expand Up @@ -716,10 +792,12 @@ defmodule Arena.GameUpdater do
power_ups: power_ups,
pools: pools,
items: items,
traps: traps,
crates: crates
} = game_state
) do
entities_to_collide = Map.merge(power_ups, pools) |> Map.merge(items) |> Map.merge(bushes) |> Map.merge(crates)
entities_to_collide =
Map.merge(power_ups, pools) |> Map.merge(items) |> Map.merge(bushes) |> Map.merge(crates) |> Map.merge(traps)

moved_players =
players
Expand Down Expand Up @@ -1408,6 +1486,7 @@ defmodule Arena.GameUpdater do
defp get_entity_path(%{category: :power_up}), do: :power_ups
defp get_entity_path(%{category: :projectile}), do: :projectiles
defp get_entity_path(%{category: :obstacle}), do: :obstacles
defp get_entity_path(%{category: :trap}), do: :traps
defp get_entity_path(%{category: :crate}), do: :crates

def get_effects_from_config([], _game_config), do: []
Expand Down
32 changes: 32 additions & 0 deletions apps/arena/lib/arena/serialization/messages.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ defmodule Arena.Serialization.PlayerActionType do
field(:EXECUTING_SKILL_3, 5)
end

defmodule Arena.Serialization.TrapStatus do
@moduledoc false

use Protobuf, enum: true, syntax: :proto3, protoc_gen_elixir_version: "0.12.0"

field(:PENDING, 0)
field(:PREPARED, 1)
field(:TRIGGERED, 2)
field(:USED, 3)
end

defmodule Arena.Serialization.Direction do
@moduledoc false

Expand Down Expand Up @@ -318,6 +329,15 @@ defmodule Arena.Serialization.GameState.BushesEntry do
field(:value, 2, type: Arena.Serialization.Entity)
end

defmodule Arena.Serialization.GameState.TrapsEntry do
@moduledoc false

use Protobuf, map: true, syntax: :proto3, protoc_gen_elixir_version: "0.12.0"

field(:key, 1, type: :uint64)
field(:value, 2, type: Arena.Serialization.Entity)
end

defmodule Arena.Serialization.GameState do
@moduledoc false

Expand Down Expand Up @@ -377,6 +397,7 @@ defmodule Arena.Serialization.GameState do
field(:pools, 15, repeated: true, type: Arena.Serialization.GameState.PoolsEntry, map: true)
field(:crates, 16, repeated: true, type: Arena.Serialization.GameState.CratesEntry, map: true)
field(:bushes, 17, repeated: true, type: Arena.Serialization.GameState.BushesEntry, map: true)
field(:traps, 18, repeated: true, type: Arena.Serialization.GameState.TrapsEntry, map: true)
end

defmodule Arena.Serialization.Entity do
Expand Down Expand Up @@ -405,6 +426,7 @@ defmodule Arena.Serialization.Entity do
field(:pool, 17, type: Arena.Serialization.Pool, oneof: 0)
field(:crate, 18, type: Arena.Serialization.Crate, oneof: 0)
field(:bush, 19, type: Arena.Serialization.Bush, oneof: 0)
field(:trap, 20, type: Arena.Serialization.Trap, oneof: 0)
end

defmodule Arena.Serialization.Player.CooldownsEntry do
Expand Down Expand Up @@ -512,6 +534,16 @@ defmodule Arena.Serialization.Bush do
use Protobuf, syntax: :proto3, protoc_gen_elixir_version: "0.12.0"
end

defmodule Arena.Serialization.Trap do
@moduledoc false

use Protobuf, syntax: :proto3, protoc_gen_elixir_version: "0.12.0"

field(:owner_id, 1, type: :uint64, json_name: "ownerId")
field(:name, 2, type: :string)
field(:status, 3, type: Arena.Serialization.TrapStatus, enum: true)
end

defmodule Arena.Serialization.PlayerAction do
@moduledoc false

Expand Down
1 change: 1 addition & 0 deletions apps/arena/native/physics/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub enum Category {
Item,
Bush,
Crate,
Trap,
}

impl Position {
Expand Down
Loading
Loading