Skip to content

Commit

Permalink
[GH-309] add valtimer teleport (#305)
Browse files Browse the repository at this point in the history
* Handle teleport mechanic

* Add character inmunity

* Add move to entity on rust

* Fix entity generation

* Fix teleport execution

* Add missing fields to teleport mechanic

* Remove duplicated handler

* Move invisibility to skill instead of mechanic

* Fix complete entity

* Fix warp

* Remove duplicated field from config

* Send destination in player action

* Restore private method

* Restore unnecesary naming

* restore entities

* Do not move player if inmune

* Fix valtimer basic

* Restore player

* Fix comment typos

* Fix invinsible typo

---------

Co-authored-by: Nicolas Sanchez <[email protected]>
Co-authored-by: BertovDev <[email protected]>
  • Loading branch information
3 people authored Apr 8, 2024
1 parent cf3942c commit 0b2c244
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 18 deletions.
42 changes: 37 additions & 5 deletions apps/arena/lib/arena/game/player.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ defmodule Arena.Game.Player do
alias Arena.Utils
alias Arena.Game.Skill

def add_action(player, action_name, duration_ms) do
Process.send_after(self(), {:remove_skill_action, player.id, action_name}, duration_ms)
def add_action(player, action) do
Process.send_after(self(), {:remove_skill_action, player.id, action.action}, action.duration)

update_in(player, [:aditional_info, :current_actions], fn current_actions ->
current_actions ++ [%{action: action_name, duration: duration_ms}]
current_actions ++ [action]
end)
end

Expand Down Expand Up @@ -189,19 +189,39 @@ defmodule Arena.Game.Player do
skill.activation_delay_ms
)

action_name = skill_key_execution_action(skill_key)
action =
%{
action: skill_key_execution_action(skill_key),
duration: skill.execution_duration_ms
}
|> maybe_add_destination(player, skill_direction, skill)

player =
add_action(player, action_name, skill.execution_duration_ms)
add_action(player, action)
|> apply_skill_cooldown(skill_key, skill)
|> put_in([:direction], skill_direction |> Utils.normalize())
|> put_in([:is_moving], false)
|> put_in([:aditional_info, :last_skill_triggered], System.monotonic_time(:millisecond))
|> maybe_make_invincible(skill)

put_in(game_state, [:players, player.id], player)
end
end

# This is a messy solution to get a mechanic result before actually running the mechanic since the client needed the
# position in wich the player will spawn when the skill start and not when we actually execute the teleport
# this is also optimistic since we asume the destination will be always available
defp maybe_add_destination(action, player, skill_direction, %{mechanics: [{:teleport, teleport}]}) do
target_position = %{
x: player.position.x + skill_direction.x * teleport.range,
y: player.position.y + skill_direction.y * teleport.range
}

Map.put(action, :destination, target_position)
end

defp maybe_add_destination(action, _, _, _), do: action

@doc """
Receives a player that owns the damage and the damage number
Expand Down Expand Up @@ -362,4 +382,16 @@ defmodule Arena.Game.Player do
player
end
end

defp maybe_make_invincible(
player,
%{inmune_while_executing: true, execution_duration_ms: execution_duration_ms} = _skill
) do
Process.send_after(self(), {:remove_damage_immunity, player.id}, execution_duration_ms)
put_in(player, [:aditional_info, :damage_immunity], true)
end

defp maybe_make_invincible(player, _) do
player
end
end
36 changes: 27 additions & 9 deletions apps/arena/lib/arena/game/skill.ex
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ defmodule Arena.Game.Skill do
) do
Process.send_after(self(), {:stop_dash, entity.id, entity.speed}, duration)

player =
entity =
entity
|> Map.put(:is_moving, true)
|> Map.put(:speed, speed)
|> put_in([:aditional_info, :forced_movement], true)

players = Map.put(game_state.players, entity.id, player)
players = Map.put(game_state.players, entity.id, entity)

%{game_state | players: players}
end
Expand Down Expand Up @@ -202,7 +202,7 @@ defmodule Arena.Game.Skill do
last_id,
get_position_with_offset(
entity_player_owner.position,
entity_player_owner.directio,
entity_player_owner.direction,
simple_shoot.projectile_offset
),
entity.direction,
Expand Down Expand Up @@ -240,7 +240,21 @@ defmodule Arena.Game.Skill do
|> Map.put(:speed, speed)
|> put_in([:aditional_info, :forced_movement], true)

put_in(game_state, [:players, entity.id], player)
put_in(game_state, [:players, player.id], player)
end

def do_mechanic(game_state, entity, {:teleport, teleport}, %{skill_direction: skill_target}) do
target_position = %{
x: entity.position.x + skill_target.x * teleport.range,
y: entity.position.y + skill_target.y * teleport.range
}

entity =
entity
|> Physics.move_entity_to_position(target_position, game_state.external_wall)
|> Map.put(:aditional_info, entity.aditional_info)

put_in(game_state, [:players, entity.id], entity)
end

def do_mechanic(game_state, player, {:spawn_pool, pool_params}, %{
Expand Down Expand Up @@ -347,11 +361,15 @@ defmodule Arena.Game.Skill do
player

pool ->
direction = Physics.get_direction_from_positions(player.position, pool.position)

Physics.move_entity_to_direction(player, direction, pull_params.force)
|> Map.put(:aditional_info, player.aditional_info)
|> Map.put(:collides_with, player.collides_with)
if player.aditional_info.damage_immunity do
player
else
direction = Physics.get_direction_from_positions(player.position, pool.position)

Physics.move_entity_to_direction(player, direction, pull_params.force)
|> Map.put(:aditional_info, player.aditional_info)
|> Map.put(:collides_with, player.collides_with)
end
end
end

Expand Down
1 change: 0 additions & 1 deletion apps/arena/lib/arena/game_updater.ex
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,6 @@ defmodule Arena.GameUpdater do
defp complete_entity(entity) do
Map.put(entity, :category, to_string(entity.category))
|> Map.put(:shape, to_string(entity.shape))
|> Map.put(:name, entity.name)
|> Map.put(:aditional_info, entity |> Entities.maybe_add_custom_info())
end

Expand Down
1 change: 1 addition & 0 deletions apps/arena/lib/arena/serialization/messages.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ defmodule Arena.Serialization.PlayerAction do

field(:action, 1, type: Arena.Serialization.PlayerActionType, enum: true)
field(:duration, 2, type: :uint64)
field(:destination, 3, type: Arena.Serialization.Position)
end

defmodule Arena.Serialization.Move do
Expand Down
4 changes: 4 additions & 0 deletions apps/arena/lib/physics.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ defmodule Physics do
def move_entity(_entity, _ticks_to_move, _external_wall, _obstacles),
do: :erlang.nif_error(:nif_not_loaded)

def move_entity(_entity, _ticks_to_move, _external_wall), do: :erlang.nif_error(:nif_not_loaded)

def move_entity_to_position(_entity, _new_position, _external_wall), do: :erlang.nif_error(:nif_not_loaded)

def move_entity_to_direction(_entity, _direction, _amount),
do: :erlang.nif_error(:nif_not_loaded)

Expand Down
18 changes: 17 additions & 1 deletion apps/arena/native/physics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ fn move_entity(
entity
}

#[rustler::nif()]
fn move_entity_to_position(
entity: Entity,
new_position: Position,
external_wall: Entity,
) -> Entity {
let mut entity: Entity = entity;
entity.position = new_position;

if entity.category == Category::Player && !entity.is_inside_map(&external_wall) {
entity.move_to_next_valid_position_inside(&external_wall);
}
entity
}

#[rustler::nif()]
fn move_entity_to_direction(entity: Entity, direction: Position, amount: f32) -> Entity {
let mut entity: Entity = entity;
Expand Down Expand Up @@ -193,6 +208,7 @@ rustler::init!(
calculate_triangle_vertices,
get_direction_from_positions,
calculate_speed,
nearest_entity_direction
nearest_entity_direction,
move_entity_to_position
]
);
23 changes: 22 additions & 1 deletion apps/arena/priv/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,27 @@
],
"effects_to_apply": []
},
{
"name": "valt_warp",
"cooldown_mechanism": "time",
"cooldown_ms": 2000,
"execution_duration_ms": 800,
"inmune_while_executing": true,
"activation_delay_ms": 600,
"is_passive": false,
"autoaim": false,
"can_pick_destination": true,
"stamina_cost": 1,
"mechanics": [
{
"teleport": {
"range": 1000,
"duration_ms": 300
}
}
],
"effects_to_apply": []
},
{
"name": "uma_sneak",
"cooldown_mechanism": "time",
Expand Down Expand Up @@ -460,7 +481,7 @@
"skills": {
"1": "valt_antimatter",
"2": "valt_singularity",
"3": "valt_sneak"
"3": "valt_warp"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ defmodule ArenaLoadTest.Serialization.PlayerAction do

field(:action, 1, type: ArenaLoadTest.Serialization.PlayerActionType, enum: true)
field(:duration, 2, type: :uint64)
field(:destination, 3, type: ArenaLoadTest.Serialization.Position)
end

defmodule ArenaLoadTest.Serialization.Move do
Expand Down
53 changes: 52 additions & 1 deletion apps/game_client/assets/js/protobuf/messages_pb.js
Original file line number Diff line number Diff line change
Expand Up @@ -5916,7 +5916,8 @@ proto.PlayerAction.prototype.toObject = function(opt_includeInstance) {
proto.PlayerAction.toObject = function(includeInstance, msg) {
var f, obj = {
action: jspb.Message.getFieldWithDefault(msg, 1, 0),
duration: jspb.Message.getFieldWithDefault(msg, 2, 0)
duration: jspb.Message.getFieldWithDefault(msg, 2, 0),
destination: (f = msg.getDestination()) && proto.Position.toObject(includeInstance, f)
};

if (includeInstance) {
Expand Down Expand Up @@ -5961,6 +5962,11 @@ proto.PlayerAction.deserializeBinaryFromReader = function(msg, reader) {
var value = /** @type {number} */ (reader.readUint64());
msg.setDuration(value);
break;
case 3:
var value = new proto.Position;
reader.readMessage(value,proto.Position.deserializeBinaryFromReader);
msg.setDestination(value);
break;
default:
reader.skipField();
break;
Expand Down Expand Up @@ -6004,6 +6010,14 @@ proto.PlayerAction.serializeBinaryToWriter = function(message, writer) {
f
);
}
f = message.getDestination();
if (f != null) {
writer.writeMessage(
3,
f,
proto.Position.serializeBinaryToWriter
);
}
};


Expand Down Expand Up @@ -6043,6 +6057,43 @@ proto.PlayerAction.prototype.setDuration = function(value) {
};


/**
* optional Position destination = 3;
* @return {?proto.Position}
*/
proto.PlayerAction.prototype.getDestination = function() {
return /** @type{?proto.Position} */ (
jspb.Message.getWrapperField(this, proto.Position, 3));
};


/**
* @param {?proto.Position|undefined} value
* @return {!proto.PlayerAction} returns this
*/
proto.PlayerAction.prototype.setDestination = function(value) {
return jspb.Message.setWrapperField(this, 3, value);
};


/**
* Clears the message field making it undefined.
* @return {!proto.PlayerAction} returns this
*/
proto.PlayerAction.prototype.clearDestination = function() {
return this.setDestination(undefined);
};


/**
* Returns whether this field is set.
* @return {boolean}
*/
proto.PlayerAction.prototype.hasDestination = function() {
return jspb.Message.getField(this, 3) != null;
};





Expand Down
1 change: 1 addition & 0 deletions apps/game_client/lib/game_client/protobuf/messages.pb.ex
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ defmodule GameClient.Protobuf.PlayerAction do

field(:action, 1, type: GameClient.Protobuf.PlayerActionType, enum: true)
field(:duration, 2, type: :uint64)
field(:destination, 3, type: GameClient.Protobuf.Position)
end

defmodule GameClient.Protobuf.Move do
Expand Down
1 change: 1 addition & 0 deletions apps/serialization/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ message Pool {
message PlayerAction {
PlayerActionType action = 1;
uint64 duration = 2;
Position destination = 3;
}

enum PlayerActionType {
Expand Down

0 comments on commit 0b2c244

Please sign in to comment.