From ec2dec614ea11fc17dd65269acd4eedf464b257f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Sanchez?= Date: Thu, 23 Jan 2025 12:01:22 -0300 Subject: [PATCH] Add new silence item (#1047) * Add silence_effect from item behavior * Add silence_item in seeds * Add item.mechanic_radius field to send it to the client * Upgrade arena version * Add new status and owner_id for Item proto * Update items status according to user actions * Restore wrongly deleted code in merge * Remove pickup time if item got picked up * Move all items functions to its section * Upgrade arena version --- apps/arena/lib/arena/entities.ex | 21 +- apps/arena/lib/arena/game/effect.ex | 4 + apps/arena/lib/arena/game/item.ex | 5 + apps/arena/lib/arena/game/player.ex | 2 + apps/arena/lib/arena/game/skill.ex | 28 +++ apps/arena/lib/arena/game_updater.ex | 118 +++++++---- .../lib/arena/serialization/messages.pb.ex | 17 ++ apps/arena/mix.exs | 2 +- .../serialization/messages.pb.ex | 18 ++ apps/bot_manager/lib/protobuf/messages.pb.ex | 17 ++ .../lib/game_backend/curse_of_mirra/effect.ex | 3 +- .../assets/js/protobuf/messages_pb.js | 190 +++++++++++++++++- .../lib/game_client/protobuf/messages.pb.ex | 17 ++ apps/serialization/messages.proto | 12 ++ assets/node_modules/.package-lock.json | 7 +- assets/package-lock.json | 9 +- assets/package.json | 2 +- priv/repo/seeds.exs | 40 ++++ 18 files changed, 461 insertions(+), 51 deletions(-) diff --git a/apps/arena/lib/arena/entities.ex b/apps/arena/lib/arena/entities.ex index efbc40a8a..84e51413c 100644 --- a/apps/arena/lib/arena/entities.ex +++ b/apps/arena/lib/arena/entities.ex @@ -91,7 +91,8 @@ defmodule Arena.Entities do bounty_completed: false, current_basic_animation: 0, item_effects_expires_at: now, - position: nil + position: nil, + blocked_actions: false }, collides_with: [] } @@ -244,6 +245,9 @@ defmodule Arena.Entities do is_moving: false, aditional_info: %{ name: config.name, + mechanic_radius: get_range_from_mechanic(config.mechanics), + status: :ITEM_STATUS_UNDEFINED, + owner_id: nil, effect: config.effect, mechanics: config.mechanics, pick_up_time_elapsed: %{}, @@ -254,6 +258,9 @@ defmodule Arena.Entities do } end + defp get_range_from_mechanic([]), do: nil + defp get_range_from_mechanic([mechanic | _]), do: mechanic.range + def new_obstacle(id, %{position: position, radius: radius, shape: shape, vertices: vertices} = params) do %{ id: id, @@ -441,7 +448,8 @@ defmodule Arena.Entities do mana: get_in(entity, [:aditional_info, :mana]), current_basic_animation: get_in(entity, [:aditional_info, :current_basic_animation]), match_position: get_in(entity, [:aditional_info, :match_position]), - team: get_in(entity, [:aditional_info, :team]) + team: get_in(entity, [:aditional_info, :team]), + blocked_actions: get_in(entity, [:aditional_info, :blocked_actions]) }} end @@ -487,6 +495,9 @@ defmodule Arena.Entities do {:item, %Arena.Serialization.Item{ name: get_in(entity, [:aditional_info, :name]), + mechanic_radius: get_in(entity, [:aditional_info, :mechanic_radius]), + status: get_in(entity, [:aditional_info, :status]), + owner_id: get_in(entity, [:aditional_info, :owner_id]), pick_up_time_elapsed: get_in(entity, [:aditional_info, :pick_up_time_elapsed]) }} end @@ -583,6 +594,12 @@ defmodule Arena.Entities do put_in(entity, [:aditional_info, :cooldowns], %{}) end + def block_actions_for_duration(%{category: :player} = entity, duration) do + Process.send(self(), {:block_actions, entity.id, true}, []) + Process.send_after(self(), {:block_actions, entity.id, false}, duration) + put_in(entity, [:aditional_info, :blocked_actions], true) + end + def obstacle_collisionable?(%{type: "dynamic"} = params) do %{base_status: base_status, statuses_cycle: statuses_cycle} = params diff --git a/apps/arena/lib/arena/game/effect.ex b/apps/arena/lib/arena/game/effect.ex index a0825e891..f4212f86b 100644 --- a/apps/arena/lib/arena/game/effect.ex +++ b/apps/arena/lib/arena/game/effect.ex @@ -276,6 +276,10 @@ defmodule Arena.Game.Effect do Entities.refresh_cooldowns(entity) end + defp do_effect_mechanics(_game_state, entity, effect, %{name: "silence"} = _silence_mechanic) do + Entities.block_actions_for_duration(entity, effect.duration_ms) + end + ## Sink for mechanics that don't do anything defp do_effect_mechanics(_game_state, entity, _effect, _mechanic) do entity diff --git a/apps/arena/lib/arena/game/item.ex b/apps/arena/lib/arena/game/item.ex index edd1f9120..bb4164ef2 100644 --- a/apps/arena/lib/arena/game/item.ex +++ b/apps/arena/lib/arena/game/item.ex @@ -5,6 +5,7 @@ defmodule Arena.Game.Item do alias Arena.Entities alias Arena.Game.Player + alias Arena.Game.Skill @doc """ Apply all item mechanics to an entity @@ -38,6 +39,10 @@ defmodule Arena.Game.Item do put_in(game_state, [:players, player.id], player) end + def do_mechanic(game_state, entity, %{type: "circle_hit"} = item_params) do + Skill.do_mechanic(game_state, entity, item_params, %{}) + end + def do_mechanic(game_state, _entity, _mechanic) do game_state end diff --git a/apps/arena/lib/arena/game/player.ex b/apps/arena/lib/arena/game/player.ex index 1dcf017af..7e75ed360 100644 --- a/apps/arena/lib/arena/game/player.ex +++ b/apps/arena/lib/arena/game/player.ex @@ -392,6 +392,8 @@ defmodule Arena.Game.Player do |> maybe_update_player_item_effects_expires_at(player, item.effect) Item.do_mechanics(game_state, player, item.mechanics) + |> put_in([:items, item.id, :aditional_info, :status], :ITEM_USED) + |> put_in([:items, item.id, :aditional_info, :owner_id], player.id) |> put_in( [:players, player.id, :aditional_info, :inventory], Map.delete(player.aditional_info.inventory, item_position) diff --git a/apps/arena/lib/arena/game/skill.ex b/apps/arena/lib/arena/game/skill.ex index 81fed8106..3662038c4 100644 --- a/apps/arena/lib/arena/game/skill.ex +++ b/apps/arena/lib/arena/game/skill.ex @@ -45,6 +45,27 @@ defmodule Arena.Game.Skill do |> maybe_move_player(entity, circle_hit[:move_by]) end + defp execute_mechanic( + game_state, + entity, + %{type: "circle_hit"} = circle_hit, + _skill_params + ) do + circle_center_position = get_position_with_offset(entity.position, nil, circle_hit.offset) + circular_damage_area = Entities.make_circular_area(entity.id, circle_center_position, circle_hit.range) + + entity_player_owner = get_entity_player_owner(game_state, entity) + + apply_damage_and_effects_to_entities( + game_state, + entity_player_owner, + circular_damage_area, + circle_hit.damage, + circle_hit.effect + ) + |> maybe_move_player(entity, circle_hit[:move_by]) + end + defp execute_mechanic( game_state, entity, @@ -403,6 +424,13 @@ defmodule Arena.Game.Skill do Enum.concat([add_side, middle, sub_side]) end + defp get_position_with_offset(position, nil, offset) do + real_position_x = position.x + offset + real_position_y = position.y + offset + + %{x: real_position_x, y: real_position_y} + end + defp get_position_with_offset(position, direction, offset) do real_position_x = position.x + offset * direction.x real_position_y = position.y + offset * direction.y diff --git a/apps/arena/lib/arena/game_updater.ex b/apps/arena/lib/arena/game_updater.ex index 163c8178c..2dd0b2168 100644 --- a/apps/arena/lib/arena/game_updater.ex +++ b/apps/arena/lib/arena/game_updater.ex @@ -248,7 +248,6 @@ defmodule Arena.GameUpdater do |> Effect.apply_effect_mechanic_to_entities() # Players |> move_players() - |> update_pickup_time_for_items() |> reduce_players_cooldowns(delta_time) |> recover_mana() |> resolve_projectiles_effects_on_collisions() @@ -276,6 +275,8 @@ defmodule Arena.GameUpdater do |> add_players_to_respawn_queue(state.game_config) |> respawn_players(state.game_config) # Items + |> update_pickup_time_for_items() + |> update_items_status() |> remove_pickup_time_for_items() {:ok, state_diff} = diff(state.last_broadcasted_game_state, game_state) @@ -679,6 +680,7 @@ defmodule Arena.GameUpdater do end def handle_info({:block_actions, player_id, value}, state) do + state = put_in(state, [:game_state, :players, player_id, :aditional_info, :blocked_actions], value) broadcast_player_block_actions(state.game_state.game_id, player_id, value) {:noreply, state} end @@ -1317,6 +1319,29 @@ defmodule Arena.GameUpdater do end) end + # Mark used items as active + # If items were active already, expire them + defp update_items_status(%{items: items} = game_state) do + updated_items = + Enum.reduce(items, items, fn {item_id, item}, acc -> + case item.aditional_info.status do + :ITEM_EXPIRED -> + Map.delete(acc, item_id) + + :ITEM_USED -> + Map.put(acc, item_id, put_in(item, [:aditional_info, :status], :ITEM_ACTIVE)) + + :ITEM_ACTIVE -> + Map.put(acc, item_id, put_in(item, [:aditional_info, :status], :ITEM_EXPIRED)) + + _ -> + acc + end + end) + + %{game_state | items: updated_items} + end + defp apply_zone_damage_to_players(%{zone: %{enabled: false}} = game_state, _zone_params), do: game_state defp apply_zone_damage_to_players(%{zone: %{enabled: true}} = game_state, zone_params) do @@ -1988,60 +2013,79 @@ defmodule Arena.GameUpdater do defp update_pickup_time_for_items(game_state) do {players, items} = - Enum.reduce(game_state.players, {game_state.players, game_state.items}, fn {player_id, player}, - {players_acc, items_acc} -> - case find_collided_item(player.collides_with, items_acc) do - nil -> - {players_acc, items_acc} + Enum.reduce( + game_state.players, + {game_state.players, + game_state.items |> Map.filter(fn {_item_id, item} -> item.aditional_info.status == :ITEM_STATUS_UNDEFINED end)}, + fn {player_id, player}, {players_acc, items_acc} -> + case find_collided_item(player.collides_with, items_acc) do + nil -> + {players_acc, items_acc} - item -> - now = System.monotonic_time(:millisecond) + item -> + now = System.monotonic_time(:millisecond) - cond do - not Map.has_key?(item.aditional_info.pick_up_time_elapsed, player_id) -> - item = - put_in(item, [:aditional_info, :pick_up_time_elapsed, player_id], 0) - |> put_in([:aditional_info, :pick_up_time_initial_timestamp, player_id], now) + cond do + not Map.has_key?(item.aditional_info.pick_up_time_elapsed, player_id) -> + item = + put_in(item, [:aditional_info, :pick_up_time_elapsed, player_id], 0) + |> put_in([:aditional_info, :pick_up_time_initial_timestamp, player_id], now) - {players_acc, Map.put(items_acc, item.id, item)} + {players_acc, Map.put(items_acc, item.id, item)} - item.aditional_info.pick_up_time_elapsed[player_id] < @standing_time -> - elapsed_time = min(now - item.aditional_info.pick_up_time_initial_timestamp[player_id], @standing_time) + item.aditional_info.pick_up_time_elapsed[player_id] < @standing_time -> + elapsed_time = + min(now - item.aditional_info.pick_up_time_initial_timestamp[player_id], @standing_time) - item = put_in(item, [:aditional_info, :pick_up_time_elapsed, player_id], elapsed_time) + item = put_in(item, [:aditional_info, :pick_up_time_elapsed, player_id], elapsed_time) - {players_acc, Map.put(items_acc, item.id, item)} + {players_acc, Map.put(items_acc, item.id, item)} - not Player.inventory_full?(player) -> - player = Player.store_item(player, item.aditional_info) - {Map.put(players_acc, player.id, player), Map.delete(items_acc, item.id)} + not Player.inventory_full?(player) -> + player = Player.store_item(player, item.aditional_info |> Map.put(:id, item.id)) - true -> - {players_acc, items_acc} - end + {Map.put(players_acc, player.id, player), + Map.put(items_acc, item.id, put_in(item, [:aditional_info, :status], :ITEM_PICKED_UP))} + + true -> + {players_acc, items_acc} + end + end end - end) + ) game_state |> Map.put(:players, players) - |> Map.put(:items, items) + |> Map.put(:items, Map.merge(game_state.items, items)) end defp remove_pickup_time_for_items(game_state) do items = Enum.reduce(game_state.items, %{}, fn {item_id, item}, acc -> - players_colliding = Physics.check_collisions(item, game_state.players) - item = - put_in( - item, - [:aditional_info, :pick_up_time_elapsed], - Map.take(item.aditional_info.pick_up_time_elapsed, players_colliding) - ) - |> put_in( - [:aditional_info, :pick_up_time_initial_timestamp], - Map.take(item.aditional_info.pick_up_time_initial_timestamp, players_colliding) - ) + if item.aditional_info.status != :ITEM_STATUS_UNDEFINED do + put_in( + item, + [:aditional_info, :pick_up_time_elapsed], + %{} + ) + |> put_in( + [:aditional_info, :pick_up_time_initial_timestamp], + nil + ) + else + players_colliding = Physics.check_collisions(item, game_state.players) + + put_in( + item, + [:aditional_info, :pick_up_time_elapsed], + Map.take(item.aditional_info.pick_up_time_elapsed, players_colliding) + ) + |> put_in( + [:aditional_info, :pick_up_time_initial_timestamp], + Map.take(item.aditional_info.pick_up_time_initial_timestamp, players_colliding) + ) + end Map.put(acc, item_id, item) end) diff --git a/apps/arena/lib/arena/serialization/messages.pb.ex b/apps/arena/lib/arena/serialization/messages.pb.ex index f30fb25bc..9f004ff56 100644 --- a/apps/arena/lib/arena/serialization/messages.pb.ex +++ b/apps/arena/lib/arena/serialization/messages.pb.ex @@ -20,6 +20,18 @@ defmodule Arena.Serialization.GameStatus do field(:SELECTING_BOUNTY, 3) end +defmodule Arena.Serialization.ItemStatus do + @moduledoc false + + use Protobuf, enum: true, syntax: :proto3, protoc_gen_elixir_version: "0.13.0" + + field(:ITEM_STATUS_UNDEFINED, 0) + field(:ITEM_PICKED_UP, 1) + field(:ITEM_USED, 2) + field(:ITEM_ACTIVE, 3) + field(:ITEM_EXPIRED, 4) +end + defmodule Arena.Serialization.ProjectileStatus do @moduledoc false @@ -577,6 +589,7 @@ defmodule Arena.Serialization.Player do field(:team, 19, proto3_optional: true, type: :uint32) field(:max_health, 20, proto3_optional: true, type: :uint64, json_name: "maxHealth") field(:inventory, 21, repeated: true, type: Arena.Serialization.Player.InventoryEntry, map: true) + field(:blocked_actions, 22, proto3_optional: true, type: :bool, json_name: "blockedActions") end defmodule Arena.Serialization.Effect do @@ -611,6 +624,10 @@ defmodule Arena.Serialization.Item do json_name: "pickUpTimeElapsed", map: true ) + + field(:mechanic_radius, 4, proto3_optional: true, type: :float, json_name: "mechanicRadius") + field(:status, 5, type: Arena.Serialization.ItemStatus, enum: true) + field(:owner_id, 6, proto3_optional: true, type: :uint64, json_name: "ownerId") end defmodule Arena.Serialization.Projectile do diff --git a/apps/arena/mix.exs b/apps/arena/mix.exs index 74b660e3c..95ff74d43 100644 --- a/apps/arena/mix.exs +++ b/apps/arena/mix.exs @@ -4,7 +4,7 @@ defmodule Arena.MixProject do def project do [ app: :arena, - version: "0.15.1", + version: "0.16.1", build_path: "../../_build", config_path: "../../config/config.exs", deps_path: "../../deps", diff --git a/apps/arena_load_test/lib/arena_load_test/serialization/messages.pb.ex b/apps/arena_load_test/lib/arena_load_test/serialization/messages.pb.ex index b202e8e8c..756fd1cd2 100644 --- a/apps/arena_load_test/lib/arena_load_test/serialization/messages.pb.ex +++ b/apps/arena_load_test/lib/arena_load_test/serialization/messages.pb.ex @@ -20,6 +20,18 @@ defmodule ArenaLoadTest.Serialization.GameStatus do field(:SELECTING_BOUNTY, 3) end +defmodule ArenaLoadTest.Serialization.ItemStatus do + @moduledoc false + + use Protobuf, enum: true, syntax: :proto3, protoc_gen_elixir_version: "0.13.0" + + field(:ITEM_STATUS_UNDEFINED, 0) + field(:ITEM_PICKED_UP, 1) + field(:ITEM_USED, 2) + field(:ITEM_ACTIVE, 3) + field(:ITEM_EXPIRED, 4) +end + defmodule ArenaLoadTest.Serialization.ProjectileStatus do @moduledoc false @@ -635,6 +647,8 @@ defmodule ArenaLoadTest.Serialization.Player do type: ArenaLoadTest.Serialization.Player.InventoryEntry, map: true ) + + field(:blocked_actions, 22, proto3_optional: true, type: :bool, json_name: "blockedActions") end defmodule ArenaLoadTest.Serialization.Effect do @@ -669,6 +683,10 @@ defmodule ArenaLoadTest.Serialization.Item do json_name: "pickUpTimeElapsed", map: true ) + + field(:mechanic_radius, 4, proto3_optional: true, type: :float, json_name: "mechanicRadius") + field(:status, 5, type: ArenaLoadTest.Serialization.ItemStatus, enum: true) + field(:owner_id, 6, proto3_optional: true, type: :uint64, json_name: "ownerId") end defmodule ArenaLoadTest.Serialization.Projectile do diff --git a/apps/bot_manager/lib/protobuf/messages.pb.ex b/apps/bot_manager/lib/protobuf/messages.pb.ex index f04df6193..7f0858657 100644 --- a/apps/bot_manager/lib/protobuf/messages.pb.ex +++ b/apps/bot_manager/lib/protobuf/messages.pb.ex @@ -20,6 +20,18 @@ defmodule BotManager.Protobuf.GameStatus do field(:SELECTING_BOUNTY, 3) end +defmodule BotManager.Protobuf.ItemStatus do + @moduledoc false + + use Protobuf, enum: true, syntax: :proto3, protoc_gen_elixir_version: "0.13.0" + + field(:ITEM_STATUS_UNDEFINED, 0) + field(:ITEM_PICKED_UP, 1) + field(:ITEM_USED, 2) + field(:ITEM_ACTIVE, 3) + field(:ITEM_EXPIRED, 4) +end + defmodule BotManager.Protobuf.ProjectileStatus do @moduledoc false @@ -577,6 +589,7 @@ defmodule BotManager.Protobuf.Player do field(:team, 19, proto3_optional: true, type: :uint32) field(:max_health, 20, proto3_optional: true, type: :uint64, json_name: "maxHealth") field(:inventory, 21, repeated: true, type: BotManager.Protobuf.Player.InventoryEntry, map: true) + field(:blocked_actions, 22, proto3_optional: true, type: :bool, json_name: "blockedActions") end defmodule BotManager.Protobuf.Effect do @@ -611,6 +624,10 @@ defmodule BotManager.Protobuf.Item do json_name: "pickUpTimeElapsed", map: true ) + + field(:mechanic_radius, 4, proto3_optional: true, type: :float, json_name: "mechanicRadius") + field(:status, 5, type: BotManager.Protobuf.ItemStatus, enum: true) + field(:owner_id, 6, proto3_optional: true, type: :uint64, json_name: "ownerId") end defmodule BotManager.Protobuf.Projectile do diff --git a/apps/game_backend/lib/game_backend/curse_of_mirra/effect.ex b/apps/game_backend/lib/game_backend/curse_of_mirra/effect.ex index fb41ad288..990ddbb04 100644 --- a/apps/game_backend/lib/game_backend/curse_of_mirra/effect.ex +++ b/apps/game_backend/lib/game_backend/curse_of_mirra/effect.ex @@ -81,7 +81,8 @@ defmodule GameBackend.CurseOfMirra.Effect do :buff_pool, :refresh_stamina, :refresh_cooldowns, - :invisible + :invisible, + :silence ] ) diff --git a/apps/game_client/assets/js/protobuf/messages_pb.js b/apps/game_client/assets/js/protobuf/messages_pb.js index 9eb2abbfc..31da0b583 100644 --- a/apps/game_client/assets/js/protobuf/messages_pb.js +++ b/apps/game_client/assets/js/protobuf/messages_pb.js @@ -51,6 +51,7 @@ goog.exportSymbol('proto.GameMode', null, global); goog.exportSymbol('proto.GameState', null, global); goog.exportSymbol('proto.GameStatus', null, global); goog.exportSymbol('proto.Item', null, global); +goog.exportSymbol('proto.ItemStatus', null, global); goog.exportSymbol('proto.JoinedLobby', null, global); goog.exportSymbol('proto.KillEntry', null, global); goog.exportSymbol('proto.LeaveLobby', null, global); @@ -6990,7 +6991,8 @@ currentBasicAnimation: (f = jspb.Message.getField(msg, 17)) == null ? undefined matchPosition: (f = jspb.Message.getField(msg, 18)) == null ? undefined : f, team: (f = jspb.Message.getField(msg, 19)) == null ? undefined : f, maxHealth: (f = jspb.Message.getField(msg, 20)) == null ? undefined : f, -inventoryMap: (f = msg.getInventoryMap()) ? f.toObject(includeInstance, proto.Item.toObject) : [] +inventoryMap: (f = msg.getInventoryMap()) ? f.toObject(includeInstance, proto.Item.toObject) : [], +blockedActions: (f = jspb.Message.getBooleanField(msg, 22)) == null ? undefined : f }; if (includeInstance) { @@ -7119,6 +7121,10 @@ proto.Player.deserializeBinaryFromReader = function(msg, reader) { jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readUint32, jspb.BinaryReader.prototype.readMessage, proto.Item.deserializeBinaryFromReader, 0, new proto.Item()); }); break; + case 22: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setBlockedActions(value); + break; default: reader.skipField(); break; @@ -7291,6 +7297,13 @@ proto.Player.serializeBinaryToWriter = function(message, writer) { if (f && f.getLength() > 0) { f.serializeBinary(21, writer, jspb.BinaryWriter.prototype.writeUint32, jspb.BinaryWriter.prototype.writeMessage, proto.Item.serializeBinaryToWriter); } + f = /** @type {boolean} */ (jspb.Message.getField(message, 22)); + if (f != null) { + writer.writeBool( + 22, + f + ); + } }; @@ -8029,6 +8042,42 @@ proto.Player.prototype.clearInventoryMap = function() { }; +/** + * optional bool blocked_actions = 22; + * @return {boolean} + */ +proto.Player.prototype.getBlockedActions = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 22, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.Player} returns this + */ +proto.Player.prototype.setBlockedActions = function(value) { + return jspb.Message.setField(this, 22, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.Player} returns this + */ +proto.Player.prototype.clearBlockedActions = function() { + return jspb.Message.setField(this, 22, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.Player.prototype.hasBlockedActions = function() { + return jspb.Message.getField(this, 22) != null; +}; + + @@ -8252,7 +8301,10 @@ proto.Item.prototype.toObject = function(opt_includeInstance) { proto.Item.toObject = function(includeInstance, msg) { var f, obj = { name: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f, -pickUpTimeElapsedMap: (f = msg.getPickUpTimeElapsedMap()) ? f.toObject(includeInstance, undefined) : [] +pickUpTimeElapsedMap: (f = msg.getPickUpTimeElapsedMap()) ? f.toObject(includeInstance, undefined) : [], +mechanicRadius: (f = jspb.Message.getOptionalFloatingPointField(msg, 4)) == null ? undefined : f, +status: jspb.Message.getFieldWithDefault(msg, 5, 0), +ownerId: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f }; if (includeInstance) { @@ -8299,6 +8351,18 @@ proto.Item.deserializeBinaryFromReader = function(msg, reader) { jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readUint32, jspb.BinaryReader.prototype.readUint32, null, 0, 0); }); break; + case 4: + var value = /** @type {number} */ (reader.readFloat()); + msg.setMechanicRadius(value); + break; + case 5: + var value = /** @type {!proto.ItemStatus} */ (reader.readEnum()); + msg.setStatus(value); + break; + case 6: + var value = /** @type {number} */ (reader.readUint64()); + msg.setOwnerId(value); + break; default: reader.skipField(); break; @@ -8339,6 +8403,27 @@ proto.Item.serializeBinaryToWriter = function(message, writer) { if (f && f.getLength() > 0) { f.serializeBinary(3, writer, jspb.BinaryWriter.prototype.writeUint32, jspb.BinaryWriter.prototype.writeUint32); } + f = /** @type {number} */ (jspb.Message.getField(message, 4)); + if (f != null) { + writer.writeFloat( + 4, + f + ); + } + f = message.getStatus(); + if (f !== 0.0) { + writer.writeEnum( + 5, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 6)); + if (f != null) { + writer.writeUint64( + 6, + f + ); + } }; @@ -8401,6 +8486,96 @@ proto.Item.prototype.clearPickUpTimeElapsedMap = function() { }; +/** + * optional float mechanic_radius = 4; + * @return {number} + */ +proto.Item.prototype.getMechanicRadius = function() { + return /** @type {number} */ (jspb.Message.getFloatingPointFieldWithDefault(this, 4, 0.0)); +}; + + +/** + * @param {number} value + * @return {!proto.Item} returns this + */ +proto.Item.prototype.setMechanicRadius = function(value) { + return jspb.Message.setField(this, 4, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.Item} returns this + */ +proto.Item.prototype.clearMechanicRadius = function() { + return jspb.Message.setField(this, 4, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.Item.prototype.hasMechanicRadius = function() { + return jspb.Message.getField(this, 4) != null; +}; + + +/** + * optional ItemStatus status = 5; + * @return {!proto.ItemStatus} + */ +proto.Item.prototype.getStatus = function() { + return /** @type {!proto.ItemStatus} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** + * @param {!proto.ItemStatus} value + * @return {!proto.Item} returns this + */ +proto.Item.prototype.setStatus = function(value) { + return jspb.Message.setProto3EnumField(this, 5, value); +}; + + +/** + * optional uint64 owner_id = 6; + * @return {number} + */ +proto.Item.prototype.getOwnerId = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.Item} returns this + */ +proto.Item.prototype.setOwnerId = function(value) { + return jspb.Message.setField(this, 6, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.Item} returns this + */ +proto.Item.prototype.clearOwnerId = function() { + return jspb.Message.setField(this, 6, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.Item.prototype.hasOwnerId = function() { + return jspb.Message.getField(this, 6) != null; +}; + + @@ -12550,6 +12725,17 @@ proto.GameStatus = { SELECTING_BOUNTY: 3 }; +/** + * @enum {number} + */ +proto.ItemStatus = { + ITEM_STATUS_UNDEFINED: 0, + ITEM_PICKED_UP: 1, + ITEM_USED: 2, + ITEM_ACTIVE: 3, + ITEM_EXPIRED: 4 +}; + /** * @enum {number} */ diff --git a/apps/game_client/lib/game_client/protobuf/messages.pb.ex b/apps/game_client/lib/game_client/protobuf/messages.pb.ex index 09f4cc2b2..009a49bf5 100644 --- a/apps/game_client/lib/game_client/protobuf/messages.pb.ex +++ b/apps/game_client/lib/game_client/protobuf/messages.pb.ex @@ -20,6 +20,18 @@ defmodule GameClient.Protobuf.GameStatus do field(:SELECTING_BOUNTY, 3) end +defmodule GameClient.Protobuf.ItemStatus do + @moduledoc false + + use Protobuf, enum: true, syntax: :proto3, protoc_gen_elixir_version: "0.13.0" + + field(:ITEM_STATUS_UNDEFINED, 0) + field(:ITEM_PICKED_UP, 1) + field(:ITEM_USED, 2) + field(:ITEM_ACTIVE, 3) + field(:ITEM_EXPIRED, 4) +end + defmodule GameClient.Protobuf.ProjectileStatus do @moduledoc false @@ -577,6 +589,7 @@ defmodule GameClient.Protobuf.Player do field(:team, 19, proto3_optional: true, type: :uint32) field(:max_health, 20, proto3_optional: true, type: :uint64, json_name: "maxHealth") field(:inventory, 21, repeated: true, type: GameClient.Protobuf.Player.InventoryEntry, map: true) + field(:blocked_actions, 22, proto3_optional: true, type: :bool, json_name: "blockedActions") end defmodule GameClient.Protobuf.Effect do @@ -611,6 +624,10 @@ defmodule GameClient.Protobuf.Item do json_name: "pickUpTimeElapsed", map: true ) + + field(:mechanic_radius, 4, proto3_optional: true, type: :float, json_name: "mechanicRadius") + field(:status, 5, type: GameClient.Protobuf.ItemStatus, enum: true) + field(:owner_id, 6, proto3_optional: true, type: :uint64, json_name: "ownerId") end defmodule GameClient.Protobuf.Projectile do diff --git a/apps/serialization/messages.proto b/apps/serialization/messages.proto index 5a8ac3383..437f4724c 100644 --- a/apps/serialization/messages.proto +++ b/apps/serialization/messages.proto @@ -219,6 +219,7 @@ message Player { optional uint32 team = 19; optional uint64 max_health = 20; map inventory = 21; + optional bool blocked_actions = 22; } message Effect { @@ -230,6 +231,17 @@ message Effect { message Item { optional string name = 2; map pick_up_time_elapsed = 3; + optional float mechanic_radius = 4; + ItemStatus status = 5; + optional uint64 owner_id = 6; +} + +enum ItemStatus { + ITEM_STATUS_UNDEFINED = 0; + ITEM_PICKED_UP = 1; + ITEM_USED = 2; + ITEM_ACTIVE = 3; + ITEM_EXPIRED = 4; } message Projectile { diff --git a/assets/node_modules/.package-lock.json b/assets/node_modules/.package-lock.json index 63f7e4b94..246654f07 100644 --- a/assets/node_modules/.package-lock.json +++ b/assets/node_modules/.package-lock.json @@ -4,9 +4,10 @@ "requires": true, "packages": { "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", + "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", + "license": "(BSD-3-Clause AND Apache-2.0)" } } } diff --git a/assets/package-lock.json b/assets/package-lock.json index 4db2df478..c44d2feb2 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -5,13 +5,14 @@ "packages": { "": { "dependencies": { - "google-protobuf": "^3.21.2" + "google-protobuf": "^3.21.4" } }, "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz", + "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==", + "license": "(BSD-3-Clause AND Apache-2.0)" } } } diff --git a/assets/package.json b/assets/package.json index 23e761dc1..5db2f2b2b 100644 --- a/assets/package.json +++ b/assets/package.json @@ -1,5 +1,5 @@ { "dependencies": { - "google-protobuf": "^3.21.2" + "google-protobuf": "^3.21.4" } } diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index e1df46ec1..f60fcb855 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -1560,6 +1560,46 @@ health_item_params = %{ {:ok, _heal_item} = GameBackend.Items.create_consumable_item(health_item_params) +silence_effect = + %{ + name: "silence_effect", + duration_ms: 9000, + remove_on_action: false, + one_time_application: true, + disabled_outside_pool: false, + allow_multiple_effects: true, + effect_mechanics: [ + %{ + name: "silence", + execute_multiple_times: false, + effect_delay_ms: 0 + } + ], + version_id: version.id + } + +silence_item_mechanic = + %{ + name: "silence_item_mechanic", + type: "circle_hit", + damage: 0, + range: 1_000, + offset: 0, + effect: silence_effect, + version_id: version.id + } + +silence_item_params = %{ + active: true, + name: "silence_item", + radius: 200.0, + mechanics: [silence_item_mechanic], + version_id: version.id +} + +{:ok, _silence_item} = + GameBackend.Items.create_consumable_item(silence_item_params) + _slow_field_effect = %{ name: "slow_field_effect", duration_ms: 9000,