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-309] add valtimer teleport #305

Merged
merged 29 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5262a02
Handle teleport mechanic
agustinesco Feb 22, 2024
1a329ce
Add character inmunity
agustinesco Feb 22, 2024
f56cf43
Add move to entity on rust
agustinesco Feb 22, 2024
005a62c
Merge branch 'main' into add-valtimer-tp
agustinesco Mar 8, 2024
32c96a5
Fix entity generation
agustinesco Mar 8, 2024
02c53a5
Fix teleport execution
agustinesco Mar 11, 2024
d39b231
Add missing fields to teleport mechanic
agustinesco Mar 11, 2024
a7b45f6
Remove duplicated handler
agustinesco Mar 11, 2024
4127bc4
Move invisibility to skill instead of mechanic
agustinesco Mar 11, 2024
aa31613
Merge branch 'main' into add-valtimer-tp
agustinesco Mar 19, 2024
170bb3a
Fix complete entity
agustinesco Mar 19, 2024
6eb1801
Fix warp
agustinesco Mar 19, 2024
b4aa6f4
Remove duplicated field from config
agustinesco Mar 19, 2024
509ca7c
Merge branch 'main' into add-valtimer-tp
agustinesco Mar 21, 2024
efd3906
Send destination in player action
agustinesco Mar 22, 2024
da321d3
Restore private method
agustinesco Mar 22, 2024
cafc5e9
Restore unnecesary naming
agustinesco Mar 22, 2024
7faf8bb
Merge branch 'main' into add-valtimer-tp
agustinesco Mar 27, 2024
d013f05
restore entities
agustinesco Mar 27, 2024
9a684de
Do not move player if inmune
agustinesco Mar 27, 2024
d7f579c
Fix valtimer basic
agustinesco Mar 27, 2024
3671dba
Restore player
agustinesco Mar 27, 2024
d5f2da8
Merge remote-tracking branch 'origin/main' into add-valtimer-tp
Nico-Sanchez Apr 3, 2024
b338946
Merge branch 'main' into add-valtimer-tp
agustinesco Apr 4, 2024
52fc65c
Fix comment typos
agustinesco Apr 4, 2024
abbacf7
Fix invinsible typo
agustinesco Apr 4, 2024
9c21fce
Merge branch 'main' into add-valtimer-tp
agustinesco Apr 4, 2024
2c3fb72
Merge branch 'main' into add-valtimer-tp
agustinesco Apr 4, 2024
3d476c8
Merge branch 'main' into add-valtimer-tp
BertovDev Apr 5, 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
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),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think action_name would be a better name here? At first sight it looks like action contains an action, as a sort of compound entity, which is not what you're trying to represent here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that makes sense , so we can avoid this abomination action.action

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually i think this is a bigger change than just renaming this, because we need to change the player action everywhere. This change was only something to avoid adding multiple parameters to the add_action function, if you think this make things worse we can revert it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, let's leave it like this then

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_invinsible(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 sinc 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 optmistic 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_invinsible(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why "invisible" instead of "invulnerable"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was the name given by the item implementation, i just s̶t̶o̶l̶e̶ use that in this case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just realized it says "invinsible", not "invisible" as in not visible. There's a typo there though, it should be "invincible"!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right! i didn't noticed it either lol fixed!

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_invinsible(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 @@ -526,7 +526,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 @@ -431,6 +431,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 @@ -65,6 +65,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 @@ -186,6 +201,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 @@ -304,6 +304,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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should include the radius of the ability so we can displayed it in the client. Or maybe we can use the hitbox radius in the client to display it.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm i think the radius and the range are the same in the context of the teleport, we could simply rename this

Copy link
Contributor

@BertovDev BertovDev Mar 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think that is gonna work because we use the range and area to draw different indicators in the client. I mean with the range we draw the outer circle area and with the radius the inner circle area.

Screenshot 2024-03-26 at 16 15 00

What I suggest is that maybe we can use the hitbox of the character to display the inner area since it indicates where the character body is gonna be placed. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooooh right! yeah we should use the body size for the inner circle indicator

}
}
],
"effects_to_apply": []
},
{
"name": "uma_sneak",
"cooldown_mechanism": "time",
Expand Down Expand Up @@ -454,7 +475,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 @@ -5882,7 +5882,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 @@ -5927,6 +5928,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 @@ -5970,6 +5976,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 @@ -6009,6 +6023,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 @@ -431,6 +431,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 @@ -197,6 +197,7 @@ message Pool {
message PlayerAction {
PlayerActionType action = 1;
uint64 duration = 2;
Position destination = 3;
}

enum PlayerActionType {
Expand Down
Loading