#include #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; } }