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

Paladin Taunt Skill - Avengers Shield #134

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ee9daac
initial avengers shield paladin taunt
thmsndk Apr 16, 2024
f6d628a
avengers shield use the instance of target, not a clone
thmsndk Apr 17, 2024
216346a
avengers shield now bounces between targets
thmsndk Apr 17, 2024
5c06712
fixed some logic errors in forwarding chained projectiles
thmsndk Apr 18, 2024
aafcc2e
chain to nearest target
thmsndk Apr 18, 2024
be916ca
some notes
thmsndk Apr 20, 2024
56afc22
complete_attack now returns true if the projectile should be deleted
thmsndk Apr 20, 2024
db8f727
avengers shield should now taunt on each chained target
thmsndk Apr 20, 2024
3dc7fa0
extract G.skills[atype] to variable in commence_attack and complete_a…
thmsndk Apr 20, 2024
5673c25
Avengers Shield does 10% of attack as damage
thmsndk Apr 20, 2024
41afeed
moved redirect to complete_attack / on_hit
thmsndk Apr 20, 2024
3f357f2
moved chained out of splash/combo targets
thmsndk Apr 20, 2024
0e4a525
chained needs to modify def before hit event is sent to client for pr…
thmsndk Apr 20, 2024
ada6163
initial throw shield animation
thmsndk Apr 20, 2024
d0517a0
move asprite to a variable
thmsndk Apr 21, 2024
f59b58f
fixed an issue that would cause chained projectiles to despawn / be d…
thmsndk Apr 21, 2024
7084b52
use a crusader shield as projectile
thmsndk Apr 21, 2024
4d8952f
use correct tigershield
thmsndk Apr 21, 2024
af29c44
choose projectile based on equipped shield
thmsndk Apr 21, 2024
07722e3
performance optimization finding targets
thmsndk Apr 22, 2024
095c75d
removed performance recording
thmsndk Apr 23, 2024
7f83079
added missing shield projectiles
thmsndk Apr 23, 2024
f06fbac
removed taunt / redirect from commence_attack
thmsndk Apr 23, 2024
59306a9
handle a case reported by @olDrippy where `sprite.target` was undefined
thmsndk Oct 13, 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
63 changes: 63 additions & 0 deletions design/animations.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,69 @@
"speed":160,
"front":True,
},
"throw_wshield":{
"file":"/images/sprites/animations/throw_wshield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_sshield":{
"file":"/images/sprites/animations/throw_sshield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_mshield":{
"file":"/images/sprites/animations/throw_mshield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_xshield":{
"file":"/images/sprites/animations/throw_xshield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_tigershield":{
"file":"/images/sprites/animations/throw_tigershield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_shield":{
"file":"/images/sprites/animations/throw_shield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"throw_crusader_shield":{
"file":"/images/sprites/animations/throw_crusader_shield.png",
"frames":4,
"continuous":True,
"directional":True,
"speed":500,
"size":0.75,
"front":True,
},
"arrow_hit":{
"file":"/images/sprites/animations/Slash0Arrow.png", # nice animation, damage-like
"frames":7,
Expand Down
35 changes: 35 additions & 0 deletions design/projectiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,41 @@
"speed":320,
"hit_animation":"explode_b",
},
"wshield":{
"animation":"throw_wshield",
"speed":220,
"hit_animation":"explode_c",
},
"sshield":{
"animation":"throw_sshield",
"speed":220,
"hit_animation":"explode_c",
},
"shield":{
"animation":"throw_shield",
"speed":220,
"hit_animation":"explode_c",
},
"mshield":{
"animation":"throw_mshield",
"speed":220,
"hit_animation":"explode_c",
},
"xshield":{
"animation":"throw_xshield",
"speed":220,
"hit_animation":"explode_c",
},
"tigershield":{
"animation":"throw_tigershield",
"speed":220,
"hit_animation":"explode_c",
},
"crusader_shield":{
"animation":"throw_crusader_shield",
"speed":220,
"hit_animation":"explode_c",
},
"fireball":{
"animation":"fireball",
"speed":320,
Expand Down
17 changes: 17 additions & 0 deletions design/skills.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,23 @@
"procs":True,
"pierces_immunity":True,
},
"avengers_shield":{
"type":"skill",
"skin":"shield",
"class":["paladin"],
"slot": [["offhand","shield"]],
"name":"Avengers Shield",
"explanation":"Hurls your shield at an enemy target, dealing (10% of Attack power) Holy damage, interrupting and silencing the non-Player target for 3 sec, and then jumping to 2 additional nearby enemie",
"attack_multiplier": 0.10, # 10% of Attack power
"range":200, # range multiplier of character range?
"mp":40,
"cooldown":3000,
"target":True,
"hostile":True,
"projectile":"crusader_shield", # would be cool if this could adapt to the equipped shield
"pierces_immunity":True,
"chained": { "targets": 2 }
},
"alchemy":{
"type":"skill",
"skin":"skill_alchemy",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_gold_shield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_mshield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_shield.aseprite
Binary file not shown.
Binary file added images/sprites/animations/throw_shield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_sshield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_tigershield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_wshield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/sprites/animations/throw_xshield.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
112 changes: 84 additions & 28 deletions js/game.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2956,7 +2956,27 @@ function init_socket(args)
var owner=get_entity(data.hid);
var color="red";

if(map_animations[data.pid]) map_animations[data.pid].to_delete=true;
const asprite = map_animations[data.pid];

const shouldDeleteAnimation = !data.chained
if(shouldDeleteAnimation && asprite) asprite.to_delete=true;


console.log('hit',data.id, data.chained, asprite?.to_delete, data.next_chain_id, asprite?.going_x,asprite?.going_y, asprite?.speed)
if (data.chained) {
if (asprite) {
asprite.chained = data.chained;
if(data.next_chain_id)
{
const chain_target=get_entity(data.next_chain_id)
asprite.target=chain_target;
asprite.going_x=get_x(chain_target);
asprite.going_y=get_y(chain_target)-get_height(chain_target)/2;
if(point_distance(asprite.x,asprite.y,asprite.going_x,asprite.going_y)<100) asprite.speed*=0.75;
console.log('next chain',data.next_chain_id,asprite.going_x,asprite.going_y, asprite.speed)
}
}
}

var attack_data=clone(data); delete attack_data.id; delete attack_data.hid;
attack_data.actor=data.hid; attack_data.target=data.id;
Expand Down Expand Up @@ -3734,39 +3754,75 @@ function update_sprite(sprite)

}

if((sprite.stype=="animation" || sprite.stype=="item") && sprite.atype=="map")
{
var target_x=get_x(sprite.target),target_y=get_y(sprite.target)-get_height(sprite.target)/2;
if(sprite.m!=sprite.target.m) target_x=sprite.going_x,target_y=sprite.going_y;
var ms=mssince(sprite.last_update);
sprite.crotation=Math.atan2(target_y-sprite.y,target_x-sprite.x)+Math.PI/2;
if(sprite.first_rotation===undefined)
{
sprite.first_rotation=sprite.crotation;
if(sprite.directional) sprite.rotation=sprite.crotation;
if ((sprite.stype == "animation" || sprite.stype == "item") && sprite.atype == "map") {
if (!sprite.target) {
console.error(`sprite has no target`, sprite);
}
if(sprite.directional && point_distance(target_x,target_y,sprite.x,sprite.y)>50)
{
sprite.rotation=sprite.crotation;

// sprite.target can be undefined causing get_x to throw an error, so we default to going_ because the code does that with .m
let target_x = sprite.target ? get_x(sprite.target) : sprite.going_x;
let target_y = sprite.target ? get_y(sprite.target) - get_height(sprite.target) / 2 : sprite.going_y;

// TODO: what is .m? and why do we use going_ instead?
if (sprite.target && sprite.m != sprite.target.m) {
target_x = sprite.going_x;
target_y = sprite.going_y;
}

var ms = mssince(sprite.last_update);

// calculate current rotation
sprite.crotation = Math.atan2(target_y - sprite.y, target_x - sprite.x) + Math.PI / 2;

// update rotation if sprite is directional and it has not been updated yet
if (sprite.first_rotation === undefined) {
sprite.first_rotation = sprite.crotation;
if (sprite.directional) sprite.rotation = sprite.crotation;
}
sprite.from_x=sprite.x; sprite.from_y=sprite.y;
sprite.going_x=target_x; sprite.going_y=target_y;

// Update rotation to match current rotation if we are more than 50px away
if (sprite.directional && point_distance(target_x, target_y, sprite.x, sprite.y) > 50) {
sprite.rotation = sprite.crotation;
}

// move sprite based on velocity
sprite.from_x = sprite.x;
sprite.from_y = sprite.y;
sprite.going_x = target_x;
sprite.going_y = target_y;

calculate_vxy(sprite);
sprite.x=sprite.x+sprite.vx*ms/1000.0;
sprite.y=sprite.y+sprite.vy*ms/1000.0;
if(mssince(sprite.last_frame)>=sprite.framefps) sprite.frame+=1,sprite.last_frame=new Date();
if(sprite.to_fade) sprite.alpha-=((sprite.to_fade!==true&&sprite.to_fade)||0.025)*ms/16.6;
if(sprite.frame>=sprite.frames) sprite.frame=0;
set_texture(sprite,sprite.frame);
sprite.crotation=Math.atan2(target_y-sprite.y,target_x-sprite.x)+Math.PI/2;
if(sprite.to_delete || point_distance(target_x,target_y,sprite.x,sprite.y)<(sprite.limit||16) || abs(sprite.first_rotation-sprite.crotation)>Math.PI/2)
{
destroy_sprite(sprite,"children");
sprite.x = sprite.x + (sprite.vx * ms) / 1000.0;
sprite.y = sprite.y + (sprite.vy * ms) / 1000.0;

// set next sprite animation frame depending on sprite framefps
if (mssince(sprite.last_frame) >= sprite.framefps) (sprite.frame += 1), (sprite.last_frame = new Date());

// fade sprite to invisible over time
if (sprite.to_fade) sprite.alpha -= (((sprite.to_fade !== true && sprite.to_fade) || 0.025) * ms) / 16.6;

// reset sprite animation frame to first frame
if (sprite.frame >= sprite.frames) sprite.frame = 0;
set_texture(sprite, sprite.frame);

// TODO: calculate current rotation again? not sure why
sprite.crotation = Math.atan2(target_y - sprite.y, target_x - sprite.x) + Math.PI / 2;

// delete unchained sprites that are close enough or if it has rotated more than half compared to the first rotation
if (
sprite.to_delete ||
(!sprite.chained &&
(point_distance(target_x, target_y, sprite.x, sprite.y) < (sprite.limit || 16) ||
abs(sprite.first_rotation - sprite.crotation) > Math.PI / 2))
) {
destroy_sprite(sprite, "children");
delete map_animations[sprite.id];
return;
}
sprite.last_update=new Date();
}

sprite.last_update = new Date();

}
else if(sprite.stype=="animation" && sprite.atype=="cmap")
{
var ms=mssince(sprite.last_update);
Expand Down
7 changes: 6 additions & 1 deletion js/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -4219,14 +4219,18 @@ function render_skills()
var s=[],slast=0,a=[],alast=0;
object_sort(G.skills).forEach(function(io){
var name=io[0],skill=io[1];
if(skill.slot)

// We still want to show class specific skills, like avenger's shield
if(skill.slot && !skill.class)
{
var found=false;
skill.slot.forEach(function(p){
if(character.slots[p[0]] && character.slots[p[0]].name==p[1]) found=true;
});

if(!found) return;
}

if(skill.inventory)
{
var found=false;
Expand All @@ -4239,6 +4243,7 @@ function render_skills()
});
if(!found) return;
}

if(skill.type=="skill" && (!skill['class'] || in_arr(character.ctype,skill['class']) || character.role=="gm"))
s.push({name:name});
if(skill.type=="passive" && (!skill['class'] || in_arr(character.ctype,skill['class']) || character.role=="gm"))
Expand Down
Loading