#include "attack.h" #include "bullet.h" #include "conf.h" #include "level.h" #include "lzy.h" #include "particle.h" #include "player.h" #include "tools.h" #include #include static struct Attack_table attack_table; static void attack_table_free(void); static void attack_update(struct Attack *attack); static void attack_draw(struct Attack *attack, int timer); static int attack_collide(struct Attack *attack, int x, int y, int w, int h, int hitbox); void attack_table_init(void) { attack_table_free(); attack_table.attacks = malloc(MAX_ATTACKS * sizeof(struct Attack)); attack_table.n = 0; for (int i = 0; i < MAX_ATTACKS; ++i) { attack_table.attacks[i].active = 0; } } void attack_table_free(void) { if (attack_table.attacks != NULL) { attack_table.attacks = NULL; } }; int attack(int x, int y, int dir_x, int dir_y, int type) { int cooldown = 5; for (int i = 0; i < MAX_ATTACKS; ++i) { if (!attack_table.attacks[i].active) { struct Attack *att = &attack_table.attacks[i]; *att = (struct Attack){ .pos = (struct Vec2){.x = x, .y = y}, .type = type, .active = 1, .ice = 0, .dam = 0, }; switch (type) { case 1: att->w = 5; att->h = 5; att->life = 2; att->dir = (struct FVec2){.x = dir_x * 2, .y = dir_y * 0.5}; att->dam = 2; cooldown = 10; particle_new(att->pos.x, att->pos.y, dir_x > 0 ? 7 : 8, att->life); break; case 2: att->w = 10; att->h = 10; att->life = 2; att->dam = 4; att->dir = (struct FVec2){.x = 0, .y = -2}; cooldown = 15; particle_new(att->pos.x, att->pos.y, 9, att->life); break; case 3: att->w = 10; att->h = 5; att->life = 2; att->dam = 3; att->dir = (struct FVec2){.x = 0, .y = 1.5}; cooldown = 10; particle_new(att->pos.x, att->pos.y, 4, att->life); break; case 4: att->w = 16; att->h = 16; att->life = 3; att->dam = 1; att->dir = (struct FVec2){.x = dir_x * 0.5, .y = 0.5}; cooldown = 60; att->ice = 1; break; case 5: att->pos.x -= dir_x * 2; att->pos.y += 3; att->w = 5; att->h = 8; att->life = 2; att->dam = 2; att->dir = (struct FVec2){.x = dir_x * 1.5, .y = dir_y * 0.5}; cooldown = 10; particle_new(att->pos.x, att->pos.y + 4, dir_x > 0 ? 7 : 8, att->life); break; case 6: att->w = 6; att->pos.x -= att->w / 2; att->h = 2; att->life = 80; att->dam = 5; att->dir = (struct FVec2){.x = 0, .y = -0.5}; cooldown = 20; bullet_fire(att->pos.x, att->pos.y, 0, 1, 8); particle_new(att->pos.x, att->pos.y, 9, 2); break; case 7: att->w = 13; att->h = 4; att->life = 2; att->dam = 4; att->dir = (struct FVec2){.x = 0, .y = 1.5}; cooldown = 10; particle_new(att->pos.x, att->pos.y, 3, att->life); break; case 8: att->w = 8; att->h = 8; att->life = 2; att->dam = 2; att->dir = (struct FVec2){.x = dir_x * 0.25, .y = 1}; cooldown = 10; break; case 9: att->pos.x += dir_x * 4; att->w = 8; att->h = 12; att->life = 2; att->dam = 3; att->dir = (struct FVec2){.x = dir_x * 2.5, .y = dir_y * 1}; cooldown = 10; particle_new(att->pos.x - dir_x * 4, att->pos.y, dir_x > 0 ? 7 : 8, att->life); break; case 10: att->pos.y += 2; att->w = 12; att->h = 6; att->life = 2; att->dam = 5; att->dir = (struct FVec2){.x = 0, .y = -4}; cooldown = 15; particle_new(att->pos.x, att->pos.y, 9, att->life); break; case 11: att->w = 10; att->h = 5; att->life = 2; att->dam = 5; att->dir = (struct FVec2){.x = 0, .y = 1.5}; cooldown = 10; particle_new(att->pos.x, att->pos.y, 4, att->life); break; case 12: att->w = 18; att->h = 18; att->life = 1; att->dam = 6; att->dir = (struct FVec2){.x = dir_x * 2, .y = 1.5}; particle_new(att->pos.x, att->pos.y, 0, 2); particle_new(att->pos.x + dir_x * 8, att->pos.y - 8, 0, 4); particle_new(att->pos.x + dir_x * 16, att->pos.y - 16, 0, 8); cooldown = 30; break; case 13: att->w = 5; att->h = 5; att->life = 2; att->dam = 2; att->dir = (struct FVec2){.x = dir_x * 2, .y = dir_y * 0.5}; cooldown = 10; particle_new(att->pos.x, att->pos.y, dir_x > 0 ? 7 : 8, att->life); break; case 14: att->w = 10; att->h = 10; att->life = 2; att->dir = (struct FVec2){.x = 0, .y = -2}; cooldown = 15; att->dam = 3; particle_new(att->pos.x, att->pos.y, 9, att->life); break; case 15: att->w = 10; att->h = 5; att->life = 2; att->dir = (struct FVec2){.x = 0, .y = 1.5}; cooldown = 10; att->dam = 3; particle_new(att->pos.x, att->pos.y, 4, att->life); break; case 16: att->w = 16; att->h = 16; att->life = 60; att->dir = (struct FVec2){.x = 0, .y = 0}; cooldown = 120; att->dam = 1; particle_new(att->pos.x, att->pos.y, 6, att->life); break; default: att->w = 0; att->h = 0; att->life = 0; att->dir = (struct FVec2){.x = dir_x, .y = 0}; cooldown = 0; break; } attack_table.attacks[i].pos.x -= attack_table.attacks[i].w / 2; attack_table.attacks[i].pos.y -= attack_table.attacks[i].h / 2; break; } } ++attack_table.n; return cooldown; } void attack_table_update(void) { for (int i = 0; i < MAX_ATTACKS; ++i) { if (attack_table.attacks[i].active) { attack_update(&attack_table.attacks[i]); } } } void attack_update(struct Attack *attack) { if (attack->type == 6) { attack->pos.y += 8; } --attack->life; if (attack->life < 0) { player_reset_attack(); attack_destroy(attack); } } void attack_table_draw(int timer) { for (int i = 0; i < MAX_ATTACKS; ++i) { if (attack_table.attacks[i].active) { attack_draw(&attack_table.attacks[i], timer); } } } void attack_draw(struct Attack *attack, int timer) {} void attack_destroy(struct Attack *attack) { attack->active = 0; --attack_table.n; } int attack_nb(void) { return attack_table.n; } struct Attack *attack_table_collide(int x, int y, int w, int h, int hitbox) { for (int i = 0; i < MAX_ATTACKS; ++i) { if (attack_table.attacks[i].active) { if (attack_collide(&attack_table.attacks[i], x, y, w, h, hitbox)) { return &attack_table.attacks[i]; } } } return NULL; } int attack_collide(struct Attack *attack, int x, int y, int w, int h, int hitbox) { if ((attack->pos.x + hitbox < x + w && attack->pos.x + attack->w - hitbox > x && attack->pos.y + hitbox < y + h && attack->pos.y + attack->h - hitbox > y) || (attack->pos.x + hitbox > x && attack->pos.x + attack->w - hitbox < x + w && attack->pos.y + hitbox > y && attack->pos.y + attack->h - hitbox < y + h)) { return 1; } return 0; }