#include #include "structures.h" #include "constantes.h" #include "target.h" #include "character.h" static int compute_damages(const struct chr_t *src, const struct chr_t *dest, enum damages_type_t type, enum element_t element) { int avg; int min; int max; /* we optimize if the target is invulnerable */ if (element != ELEM_NONE && dest->affinities[element] == AFFIN_INVULN) return 0; if (type == DAMAGES_PHYSICAL) { avg = src->strength * 60 - dest->defense * 50; } else if (type == DAMAGES_MAGICAL) { avg = src->magic * 60 - dest->spirit * 50; } if (avg <= 0) return 0; if (element != ELEM_NONE) { switch (dest->affinities[element]) { case AFFIN_SENSITIVE: avg *= 2; break; case AFFIN_RESISTANCE: avg /= 2; break; case AFFIN_ABSORPTION: avg = -avg; break; case AFFIN_NONE: break; default: abort(); } } if (dest->defensive) { avg /= 2; } min = avg - avg / 4; max = avg + avg / 4; return rand() % (max - min + 1) + min; } static int compute_cure(const struct chr_t *src, const struct chr_t *dest) { int avg, max, min; /* TODO maybe we should use the dest to compute the cure ? */ (void) dest; avg = src->magic * 20; min = avg - avg / 4; max = avg + avg / 4; return rand() % (max - min + 1) + min; } static void __attack(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct chr_t *dest) { int damages; damages = compute_damages(src, dest, DAMAGES_PHYSICAL, ELEM_NONE); damage_target_hp(surfaces, positions, dest, damages); } void attack(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { (void) data; __attack(surfaces, positions, src, dest->chr); } void defend(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { (void) data; (void) dest; (void) surfaces; (void) positions; src->defensive = true; } void cast_element(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { int damages; enum element_t elem = *((enum element_t *)data); /* TODO remove the MP */ if (dest->is_chr) { damages = compute_damages(src, dest->chr, DAMAGES_MAGICAL, elem); damage_target_hp(surfaces, positions, dest->chr, damages); } else { for (int i = 0; i < dest->team->chr_cnt; ++i) { struct chr_t *target = &dest->team->chrs[i]; if (!target->alive) continue; damages = compute_damages(src, target, DAMAGES_MAGICAL, elem); damage_target_hp(surfaces, positions, target, damages / 3); } } } void cast_cure(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { int cure; (void) data; if (dest->is_chr) { cure = compute_cure(src, dest->chr); cure_target_hp(surfaces, positions, dest->chr, cure); } else { for (int i = 0; i < dest->team->chr_cnt; ++i) { struct chr_t *target = &dest->team->chrs[i]; if (!target->alive) continue; cure = compute_cure(src, target); cure_target_hp(surfaces, positions, target, cure / 3); } } } static void __use_potion(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct chr_t *dest, int type) { int cure; switch (type) { case POTION: cure = 1000; src->team->objects.potions--; break; case POTIONPLUS: cure = 4000; src->team->objects.potionsplus--; break; default: abort(); } cure_target_hp(surfaces, positions, dest, cure); } void use_potion(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { __use_potion(surfaces, positions, src, dest->chr, *((int *)data)); } static void __use_ether(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct chr_t *dest, int type) { int cure; switch (type) { case ETHER: cure = 10; src->team->objects.ethers--; break; case ETHERPLUS: cure = 40; src->team->objects.ethersplus--; break; default: abort(); } cure_target_mp(surfaces, positions, dest, cure); } void use_ether(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { __use_ether(surfaces, positions, src, dest->chr, *((int *)data)); } void cyanure(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { struct chr_t *target = dest->chr; (void) data; (void) src; damage_target_hp(surfaces, positions, target, target->max_hp / 4); target->poisoned = true; } void esuna(SURFACES *surfaces, POSITIONS *positions, struct chr_t *src, struct target_t *dest, void *data) { (void) surfaces; (void) positions; (void) src; (void) data; /* TODO cure every state and not only poison */ dest->chr->poisoned = false; }