RogueLife/src/skills.c

173 lines
4.7 KiB
C

#include <gint/defs/util.h>
#include "skills.h"
#include "comp/fighter.h"
#include "comp/physical.h"
#include "comp/visible.h"
#include "enemies.h"
#include "aoe.h"
fixed_t skill_cooldown(int skill)
{
if(skill == SKILL_DASH)
return fix(1.0);
else if(skill == SKILL_SPEED)
return fix(5.0);
else if(skill == AOE_PROJECTILE)
return fix(2.0);
else if(skill == AOE_PROJECTILE_FAST)
return fix(0.2);
else if(skill == AOE_SHOCK)
return fix(6.0);
else if(skill == AOE_JUDGEMENT)
return fix(3.0);
else if(skill == AOE_BULLET)
return fix(4.0);
else if(skill == AOE_FIRE_CHARGE
|| skill == AOE_WATER_CHARGE
|| skill == AOE_CHEMICAL_CHARGE)
return fix(3.0);
return fix(0.0);
}
bool skill_use(game_t *game, entity_t *e, int slot, vec2 dir)
{
fighter_t *f = getcomp(e, fighter);
int skill = f->skills[slot];
if(skill < 0 || f->actions_cooldown[slot] > 0)
return false;
f->actions_cooldown[slot] = skill_cooldown(skill);
if(skill == SKILL_DASH) {
mechanical_dash(e, frdir(dir));
}
else if(skill == SKILL_SPEED) {
fighter_effect_speed(e, fix(2.0));
}
else if(skill == AOE_PROJECTILE) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(AOE_PROJECTILE, e, dir);
game_add_entity(game, aoe);
if(!f->enemy)
visible_set_anim(e, &anims_player_Attack, 2);
else
visible_set_anim(e, f->enemy->id->anim_attack, 2);
}
else if(skill == AOE_PROJECTILE_FAST) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(AOE_PROJECTILE_FAST, e, dir);
getcomp(aoe, visible)->z = fix(0.25);
game_add_entity(game, aoe);
if(!f->enemy)
visible_set_anim(e, &anims_player_Attack, 2);
else
visible_set_anim(e, f->enemy->id->anim_attack, 2);
}
else if(skill == AOE_SHOCK) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(AOE_SHOCK, e, dir);
game_add_entity(game, aoe);
if(!f->enemy)
visible_set_anim(e, &anims_player_Attack, 2);
else
visible_set_anim(e, f->enemy->id->anim_attack, 2);
f->current_attack = aoe;
f->attack_follows_movement = true;
fighter_effect_stun(e, fix(0.5));
game_shake(game, 5, fix(0.7));
}
else if(skill == AOE_JUDGEMENT) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(AOE_JUDGEMENT, e, dir);
game_add_entity(game, aoe);
if(!f->enemy)
visible_set_anim(e, &anims_player_Attack, 2);
else
visible_set_anim(e, f->enemy->id->anim_attack, 2);
game_shake(game, 3, fix(1.3));
}
else if(skill == AOE_BULLET) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(AOE_BULLET, e, dir);
game_add_entity(game, aoe);
if(!f->enemy)
visible_set_anim(e, &anims_player_Attack, 2);
else
visible_set_anim(e, f->enemy->id->anim_attack, 2);
}
else if(skill == AOE_FIRE_CHARGE
|| skill == AOE_WATER_CHARGE
|| skill == AOE_CHEMICAL_CHARGE) {
if(f->current_attack)
return false;
entity_t *aoe = aoe_make_attack(skill, e, dir);
game_add_entity(game, aoe);
f->current_attack = aoe;
f->attack_follows_movement = true;
/* This skill is used by enemies, the AI will set the animation
themselves on a per-enemy basis */
}
return true;
}
bool skill_render_get(int skill, image_t **img, int *left, int *top)
{
extern bopti_image_t img_skillicons;
*img = &img_skillicons;
*top = 0;
int base = 3;
if(skill == SKILL_DASH)
*left = 23 * (base + 0);
else if(skill == AOE_SHOCK)
*left = 23 * (base + 1);
else if(skill == AOE_JUDGEMENT)
*left = 23 * (base + 2);
else if(skill == AOE_BULLET)
*left = 23 * (base + 3);
else
return false;
return true;
}
void skill_render(int x, int y, int skill, int bg, int color)
{
image_t *img;
int left, top;
bool exists = skill_render_get(skill, &img, &left, &top);
if(bg > 0)
dsubimage(x, y, img, 23*(bg-1), 0, 23, 23, DIMAGE_NONE);
if(!exists)
return;
dsubimage(x, y, img, left, top, 23, 23, DIMAGE_NONE);
/* Hacky color change */
for(int dy = 0; dy < 23; dy++)
for(int dx = 0; dx < 23; dx++) {
int i = (y+dy) * DWIDTH + (x+dx);
if(gint_vram[i] == 0xffff)
gint_vram[i] = color;
}
}