diff --git a/apps/champions/lib/champions/battle/simulator.ex b/apps/champions/lib/champions/battle/simulator.ex index 7368444a5..a32849444 100644 --- a/apps/champions/lib/champions/battle/simulator.ex +++ b/apps/champions/lib/champions/battle/simulator.ex @@ -195,6 +195,16 @@ defmodule Champions.Battle.Simulator do }, :skill_action ) + |> add_to_history( + %{ + target_id: unit.id, + stat_affected: %{ + stat: :ENERGY, + amount: 0 + } + }, + :stat_override + ) {new_state, new_history} @@ -892,13 +902,32 @@ defmodule Champions.Battle.Simulator do # Called at the end of step processing. Sets unit health to max_health if it's above it. defp cap_units_health({state, history}) do - {Map.put( - state, - :units, - Enum.map(state.units, fn {unit_id, unit} -> - {unit_id, Map.put(unit, :health, min(unit.max_health, unit.health))} - end) - ), history} + {new_history, units_state} = + Enum.reduce(state.units, {history, %{}}, fn {unit_id, unit}, {history_acc, state_acc} -> + units_state = + Map.put(state_acc, unit_id, Map.put(unit, :health, min(unit.max_health, unit.health))) + + if unit.health > unit.max_health do + new_history = + add_to_history( + history_acc, + %{ + target_id: unit.id, + stat_affected: %{ + stat: :HEALTH, + amount: unit.max_health + } + }, + :stat_override + ) + + {new_history, units_state} + else + {history_acc, units_state} + end + end) + + {Map.put(state, :units, units_state), new_history} end # Used to create the initial unit maps to be used during simulation. diff --git a/apps/gateway/lib/gateway/champions_socket_handler.ex b/apps/gateway/lib/gateway/champions_socket_handler.ex index b11c894cc..fc228dcbf 100644 --- a/apps/gateway/lib/gateway/champions_socket_handler.ex +++ b/apps/gateway/lib/gateway/champions_socket_handler.ex @@ -17,7 +17,8 @@ defmodule Gateway.ChampionsSocketHandler do SkillAction, WebSocketResponse, ExecutionReceived, - EnergyRegen + EnergyRegen, + StatOverride } alias Champions.{Battle, Campaigns, Gacha, Items, Users, Units} @@ -235,50 +236,102 @@ defmodule Gateway.ChampionsSocketHandler do end) end - defp prepare_action(%{action_type: {type, action}}) do + defp prepare_action(%{action_type: {:skill_action, action}}) do %{ action_type: - case type do - :skill_action -> - {type, - Kernel.struct( - SkillAction, - action - )} - - :modifier_received -> - {type, - Kernel.struct( - ModifierReceived, - update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) - )} - - :tag_received -> - {type, Kernel.struct(TagReceived, action)} - - :tag_expired -> - {type, Kernel.struct(TagExpired, action)} - - :modifier_expired -> - {type, - Kernel.struct( - ModifierExpired, - update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) - )} - - :death -> - {type, Kernel.struct(Death, action)} - - :execution_received -> - {type, - Kernel.struct( - ExecutionReceived, - update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) - )} - - :energy_regen -> - {type, Kernel.struct(EnergyRegen, action)} - end + {:skill_action, + Kernel.struct( + SkillAction, + action + )} + } + end + + defp prepare_action(%{action_type: {:modifier_received, action}}) do + %{ + action_type: + {:modifier_received, + Kernel.struct( + ModifierReceived, + update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) + )} + } + end + + defp prepare_action(%{action_type: {:tag_received, action}}) do + %{ + action_type: + {:tag_received, + Kernel.struct( + TagReceived, + action + )} + } + end + + defp prepare_action(%{action_type: {:tag_expired, action}}) do + %{ + action_type: + {:tag_expired, + Kernel.struct( + TagExpired, + action + )} + } + end + + defp prepare_action(%{action_type: {:modifier_expired, action}}) do + %{ + action_type: + {:modifier_expired, + Kernel.struct( + ModifierExpired, + update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) + )} + } + end + + defp prepare_action(%{action_type: {:death, action}}) do + %{ + action_type: + {:death, + Kernel.struct( + Death, + action + )} + } + end + + defp prepare_action(%{action_type: {:execution_received, action}}) do + %{ + action_type: + {:execution_received, + Kernel.struct( + ExecutionReceived, + update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) + )} + } + end + + defp prepare_action(%{action_type: {:energy_regen, action}}) do + %{ + action_type: + {:energy_regen, + Kernel.struct( + EnergyRegen, + action + )} + } + end + + defp prepare_action(%{action_type: {:stat_override, action}}) do + %{ + action_type: + {:stat_override, + Kernel.struct( + StatOverride, + update_in(action, [:stat_affected], &Kernel.struct(StatAffected, &1)) + )} } end diff --git a/apps/gateway/lib/gateway/serialization/gateway.pb.ex b/apps/gateway/lib/gateway/serialization/gateway.pb.ex index ec801634c..85bb4f7b3 100644 --- a/apps/gateway/lib/gateway/serialization/gateway.pb.ex +++ b/apps/gateway/lib/gateway/serialization/gateway.pb.ex @@ -758,6 +758,12 @@ defmodule Gateway.Serialization.Action do json_name: "energyRegen", oneof: 0 ) + + field(:stat_override, 9, + type: Gateway.Serialization.StatOverride, + json_name: "statOverride", + oneof: 0 + ) end defmodule Gateway.Serialization.StatAffected do @@ -853,3 +859,12 @@ defmodule Gateway.Serialization.EnergyRegen do field(:skill_id, 2, type: :string, json_name: "skillId") field(:amount, 3, type: :float) end + +defmodule Gateway.Serialization.StatOverride do + @moduledoc false + + use Protobuf, syntax: :proto3, protoc_gen_elixir_version: "0.12.0" + + field(:target_id, 1, type: :string, json_name: "targetId") + field(:stat_affected, 2, type: Gateway.Serialization.StatAffected, json_name: "statAffected") +end diff --git a/apps/serialization/gateway.proto b/apps/serialization/gateway.proto index 59a197e9a..4be76860e 100644 --- a/apps/serialization/gateway.proto +++ b/apps/serialization/gateway.proto @@ -376,6 +376,7 @@ syntax = "proto3"; Death death = 6; ExecutionReceived execution_received = 7; EnergyRegen energy_regen = 8; + StatOverride stat_override = 9; } } @@ -431,3 +432,8 @@ syntax = "proto3"; string skill_id = 2; float amount = 3; } + + message StatOverride { + string target_id = 1; + StatAffected stat_affected = 2; + }