|
|
|
@ -30,7 +30,7 @@ void aoe_destroy(entity_t *e)
|
|
|
|
|
free(aoe->hits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing) |
|
|
|
|
entity_t *aoe_make_attack(uint16_t type, entity_t *origin, vec2 dir) |
|
|
|
|
{ |
|
|
|
|
entity_t *e = aoe_make(type, physical_pos(origin), fix(0)); |
|
|
|
|
if(e == NULL) |
|
|
|
@ -44,7 +44,6 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing)
|
|
|
|
|
|
|
|
|
|
rect hitbox = { 0 }; |
|
|
|
|
fixed_t distance = fix(0.625); |
|
|
|
|
vec2 dir = fdir(facing); |
|
|
|
|
anim_t const *anim = NULL; |
|
|
|
|
bool rotate = true; |
|
|
|
|
fixed_t lifetime = fix(0); |
|
|
|
@ -54,6 +53,12 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing)
|
|
|
|
|
anim = &anims_skill_hit; |
|
|
|
|
hitbox = (rect){ -fix(4)/16, fix(3)/16, -fix(4)/16, fix(3)/16 }; |
|
|
|
|
} |
|
|
|
|
else if(type == AOE_PROJECTILE) { |
|
|
|
|
anim = &anims_skill_projectile; |
|
|
|
|
hitbox = (rect){ -fix(1)/16, fix(1)/16, -fix(1)/16, fix(1)/16 }; |
|
|
|
|
distance = fix(0.5); |
|
|
|
|
lifetime = fix(999.0); |
|
|
|
|
} |
|
|
|
|
else if(type == AOE_SLASH) { |
|
|
|
|
anim = &anims_skill_swing; |
|
|
|
|
hitbox = (rect){ -fix(10)/16, fix(10)/16, -fix(8)/16, 0 }; |
|
|
|
@ -84,8 +89,8 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing)
|
|
|
|
|
|
|
|
|
|
p->x += fmul(distance, dir.x); |
|
|
|
|
p->y += fmul(distance, dir.y); |
|
|
|
|
p->facing = facing; |
|
|
|
|
p->hitbox = rotate ? rect_rotate(hitbox, UP, facing) : hitbox; |
|
|
|
|
p->facing = frdir(dir); |
|
|
|
|
p->hitbox = rotate ? rect_rotate(hitbox, UP, p->facing) : hitbox; |
|
|
|
|
|
|
|
|
|
v->sprite_plane = plane; |
|
|
|
|
|
|
|
|
@ -98,7 +103,15 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing)
|
|
|
|
|
|| type == AOE_IMPALE |
|
|
|
|
|| type == AOE_JUDGEMENT) { |
|
|
|
|
aoe->data.generic.strength = f->ATK; |
|
|
|
|
aoe->data.generic.dir = facing; |
|
|
|
|
aoe->data.generic.dir = p->facing; |
|
|
|
|
} |
|
|
|
|
else if(type == AOE_PROJECTILE) { |
|
|
|
|
aoe->data.projectile.strength = f->ATK; |
|
|
|
|
aoe->data.projectile.direction = dir; |
|
|
|
|
aoe->data.projectile.speed = fix(3.0); |
|
|
|
|
p->facing = (dir.x >= 0 ? RIGHT : LEFT); |
|
|
|
|
v->z = fix(0.5); |
|
|
|
|
v->shadow_size = 3; |
|
|
|
|
} |
|
|
|
|
else if(type == AOE_SHOCK) { |
|
|
|
|
aoe->data.shock.strength = f->ATK; |
|
|
|
@ -107,16 +120,24 @@ entity_t *aoe_make_attack(uint16_t type, entity_t *origin, int facing)
|
|
|
|
|
} |
|
|
|
|
else if(type == AOE_BULLET) { |
|
|
|
|
aoe->data.bullet.strength = f->ATK; |
|
|
|
|
aoe->data.bullet.dir = facing; |
|
|
|
|
aoe->data.bullet.dir = p->facing; |
|
|
|
|
aoe->data.bullet.v = fix(10.0); |
|
|
|
|
aoe->data.bullet.final_v = fix(4.5); |
|
|
|
|
aoe->repeat_delay = fix(0.05); |
|
|
|
|
v->z = fix(0.5); |
|
|
|
|
v->shadow_size = 4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
visible_set_anim(e, anim, 1); |
|
|
|
|
return e; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
entity_t *aoe_make_attack_4(uint16_t type, entity_t *origin, int facing) |
|
|
|
|
{ |
|
|
|
|
return aoe_make_attack(type, origin, fdir(facing)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Existing record of the area hitting this entity */ |
|
|
|
|
static aoe_record_t *aoe_record(aoe_t *aoe, entity_t *target) |
|
|
|
|
{ |
|
|
|
@ -161,6 +182,13 @@ static bool attack_apply(game_t *game, aoe_t *aoe, entity_t *target)
|
|
|
|
|
dir = fdir(aoe->data.generic.dir); |
|
|
|
|
damage = aoe->data.generic.strength; |
|
|
|
|
} |
|
|
|
|
else if(aoe->type == AOE_PROJECTILE) { |
|
|
|
|
dir = aoe->data.projectile.direction; |
|
|
|
|
damage = aoe->data.projectile.strength; |
|
|
|
|
r /= 2; |
|
|
|
|
/* Projectile disappears after hitting a single target */ |
|
|
|
|
aoe->lifetime = fix(0); |
|
|
|
|
} |
|
|
|
|
else if(aoe->type == AOE_SHOCK) { |
|
|
|
|
dir.x = target_p->x - aoe->data.shock.origin.x; |
|
|
|
|
dir.y = target_p->y - aoe->data.shock.origin.y; |
|
|
|
@ -209,6 +237,7 @@ void aoe_apply(game_t *game, entity_t *entity, entity_t *e)
|
|
|
|
|
if(rec && aoe->lifetime > rec->lifetime - aoe->repeat_delay) return; |
|
|
|
|
|
|
|
|
|
if(aoe->type == AOE_HIT |
|
|
|
|
|| aoe->type == AOE_PROJECTILE |
|
|
|
|
|| aoe->type == AOE_SLASH |
|
|
|
|
|| aoe->type == AOE_IMPALE |
|
|
|
|
|| aoe->type == AOE_SHOCK |
|
|
|
@ -238,7 +267,18 @@ void aoe_update(game_t *game, entity_t *entity, fixed_t dt)
|
|
|
|
|
physical_t *p = getcomp(entity, physical); |
|
|
|
|
aoe_t *aoe = getcomp(entity, aoe); |
|
|
|
|
|
|
|
|
|
if(aoe->type == AOE_BULLET) { |
|
|
|
|
if(aoe->type == AOE_PROJECTILE) { |
|
|
|
|
fixed_t v = aoe->data.projectile.speed; |
|
|
|
|
p->x += fmul(fmul(aoe->data.projectile.direction.x, v), dt); |
|
|
|
|
p->y += fmul(fmul(aoe->data.projectile.direction.y, v), dt); |
|
|
|
|
|
|
|
|
|
rect small_box = { 0, 0, 0, 0 }; |
|
|
|
|
small_box = rect_translate(small_box, physical_pos(entity)); |
|
|
|
|
|
|
|
|
|
if(map_collides(game->map, small_box)) |
|
|
|
|
aoe->lifetime = 0; |
|
|
|
|
} |
|
|
|
|
else if(aoe->type == AOE_BULLET) { |
|
|
|
|
vec2 dir = fdir(aoe->data.bullet.dir); |
|
|
|
|
p->x += fmul(fmul(aoe->data.bullet.v, dir.x), dt); |
|
|
|
|
p->y += fmul(fmul(aoe->data.bullet.v, dir.y), dt); |
|
|
|
|