/*! \brief Process each enemy skill * * Just a function to process each enemy skill by index number. * * \param who Index of attacker */ void combat_skill (int who) { int sk = fighter[who].ai[fighter[who].csmem] - 100; int tgt = fighter[who].ctmem; int a; int b; tempa = status_adjust (who); battle_render (0, 0, 0); blit2screen (0, 0); if (sk == 1) { strcpy (ctext, _("Venomous Bite")); dct = 1; tempa.welem = R_POISON + 1; fight (who, tgt, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 2) { strcpy (ctext, _("Double Slash")); dct = 1; tempa.stats[A_ATT] = tempa.stats[A_ATT] * 15 / 10; fight (who, tgt, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 3) { strcpy (ctext, _("Chill Touch")); dct = 1; draw_spellsprite (tgt, 0, 10, 1); special_damage_oneall_enemies (who, 60, R_ICE, tgt, 0); dct = 0; fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 4) { strcpy (ctext, _("Flash Flood")); dct = 1; draw_hugesprite (0, 80, 108, 21, 1); /* dudaskank suggest replacing 999 with SEL_ALL_ENEMIES */ special_damage_oneall_enemies (who, 40, R_ICE, SEL_ALL_ENEMIES, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 5) { b = 0; for (a = 0; a < numchrs; a++) if (fighter[a].sts[S_DEAD] == 0) b++; if (b > 1) fighter[who].ctmem = 1000; strcpy (ctext, _("Sweep")); dct = 1; tempa.stats[A_ATT] = tempa.stats[A_ATT] * 75 / 100; multi_fight (who); dct = 0; fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 6) { strcpy (ctext, _("ParaClaw")); dct = 1; tempa.welem = R_PARALYZE + 1; fight (who, tgt, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 7) { strcpy (ctext, _("Dragon Bite")); dct = 1; tempa.stats[A_ATT] = tempa.stats[A_ATT] * 15 / 10; tempa.stats[A_HIT] = tempa.stats[A_HIT] * 9 / 10; tempa.welem = 0; fight (who, tgt, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 8) { b = 0; strcpy (ctext, _("Stone Gas")); draw_spellsprite (0, 1, 46, 1); for (a = 0; a < numchrs; a++) { if (fighter[a].sts[S_DEAD] == 0) { if (res_throw (a, R_PETRIFY) == 0 && non_dmg_save (a, 75) == 0) { fighter[a].sts[S_STONE] = rand () % 3 + 2; ta[a] = NODISPLAY; } else { ta[a] = MISS; b++; } } } if (b > 0) display_amount (0, FNORMAL, 1); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 9) { b = 0; strcpy (ctext, _("Zemmel Rod")); if (rand () % 4 < 2) { draw_spellsprite (0, 1, 11, 1); /* dudaskank suggest replacing 999 with SEL_ALL_ENEMIES */ special_damage_oneall_enemies (who, 25, R_THUNDER, SEL_ALL_ENEMIES, 1); fighter[who].atrack[fighter[who].csmem] = 2; return; } draw_spellsprite (0, 1, 40, 0); for (a = 0; a < numchrs; a++) { if (res_throw (a, R_TIME) == 0) { if (non_dmg_save (a, 75) == 0 && fighter[a].sts[S_STONE] == 0) { if (fighter[a].sts[S_TIME] == 2) fighter[a].sts[S_TIME] = 0; else { if (fighter[a].sts[S_TIME] == 0) { fighter[a].sts[S_TIME] = 1; ta[a] = NODISPLAY; } else { ta[a] = MISS; b++; } } } else { ta[a] = MISS; b++; } } else { ta[a] = MISS; b++; } } if (b > 0) display_amount (0, FNORMAL, 1); fighter[who].atrack[fighter[who].csmem] = 2; } if (sk == 10) { strcpy (ctext, _("Poison Gas")); draw_spellsprite (0, 1, 47, 1); /* dudaskank suggest replacing 999 with SEL_ALL_ENEMIES */ special_damage_oneall_enemies (who, 40, R_POISON, SEL_ALL_ENEMIES, 1); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 11) { b = 0; strcpy (ctext, _("Tangle Root")); draw_spellsprite (0, 1, 24, 0); for (a = 0; a < numchrs; a++) { if (res_throw (a, S_STOP) == 0 && non_dmg_save (a, 65) == 0 && fighter[a].sts[S_STONE] == 0) { fighter[a].sts[S_STOP] = 2 + rand () % 2; ta[a] = NODISPLAY; } else { ta[a] = MISS; b++; } } if (b > 0) display_amount (0, FNORMAL, 1); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 12) { strcpy (ctext, _("Petrifying Bite")); dct = 1; tempa.stats[A_ATT] = tempa.stats[A_ATT]; tempa.stats[A_HIT] = tempa.stats[A_HIT] * 8 / 10; tempa.welem = 13; fight (who, tgt, 1); dct = 0; fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 13) { strcpy (ctext, _("Maul of the Titans")); draw_hugesprite (0, 80, 110, 29, 1); /* dudaskank suggest replacing 999 with SEL_ALL_ENEMIES */ special_damage_oneall_enemies (who, 60, R_EARTH, SEL_ALL_ENEMIES, 1); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 14) { strcpy (ctext, _("Stunning Strike")); dct = 1; tempa.stats[A_ATT] = tempa.stats[A_ATT] * 8 / 10; fight (who, tgt, 1); dct = 0; if (non_dmg_save (tgt, 80) == 0 && ta[tgt] != MISS) fighter[tgt].sts[S_STOP] = 2; fighter[who].atrack[fighter[who].csmem] = 4; } if (sk == 15) { strcpy (ctext, _("Howl")); draw_spellsprite (0, 1, 14, 0); b = 0; for (a = 0; a < numchrs; a++) { if (fighter[who].sts[S_MUTE] == 0) { if (res_throw (a, S_CHARM) == 0 && non_dmg_save (a, 65) == 0 && fighter[a].sts[S_STONE] == 0) { fighter[a].sts[S_CHARM] = 2 + rand () % 2; ta[a] = NODISPLAY; } else { ta[a] = MISS; b++; } } else { ta[a] = MISS; b++; } } if (b > 0) display_amount (0, FNORMAL, 1); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 16) { strcpy (ctext, _("Rasp")); draw_spellsprite (0, 1, 48, 0); for (a = 0; a < numchrs; a++) { b = fighter[a].hp / 3; ta[a] = 0 - b; } display_amount (0, FNORMAL, 1); for (a = 0; a < numchrs; a++) adjust_hp (a, ta[a]); for (a = 0; a < numchrs; a++) { b = fighter[a].mp / 3; ta[a] = 0 - b; } display_amount (0, FRED, 1); for (a = 0; a < numchrs; a++) adjust_mp (a, ta[a]); fighter[who].atrack[fighter[who].csmem] = 3; } if (sk == 17) { strcpy (ctext, _("Shadow Blast")); draw_spellsprite (0, 1, 49, 1); special_damage_oneall_enemies (who, 75, R_BLACK, SEL_ALL_ENEMIES, 1); fighter[who].atrack[fighter[who].csmem] = 3; } }
/*! \brief Battle gauge, action controls * \author Josh Bolduc * \date Created ???????? * \date Updated 20020914 - 16:16 (RB) * * This function controls the battle gauges and calls for action * when necessary. This is also where things like poison, sleep, * and what-not are checked. */ static void do_round (void) { int a; int index; timer_count = 0; while (!combatend) { if (timer_count >= 10) { rcount += BATTLE_INC; if (rcount >= ROUND_MAX) rcount = 0; for (index = 0; index < PSIZE + numens; index++) { if ((index < numchrs) || (index >= PSIZE)) { if (((fighter[index].sts[S_POISON] - 1) == rcount) && (fighter[index].hp > 1)) { a = rand () % ((fighter[index].mhp / 20) + 1); if (a < 2) a = 2; if ((fighter[index].hp - a) < 1) a = fighter[index].hp - 1; ta[index] = a; display_amount (index, FNORMAL, 0); fighter[index].hp -= a; } /* RB: the character is regenerating? when needed, get a */ /* random value (never lower than 5), and increase */ /* the character's health by that amount. */ if ((fighter[index].sts[S_REGEN] - 1) == rcount) { a = rand () % 5 + (fighter[index].mhp / 10); if (a < 5) a = 5; ta[index] = a; display_amount (index, FYELLOW, 0); adjust_hp (index, a); } /* RB: the character has ether actived? */ cact[index] = 1; if ((fighter[index].sts[S_ETHER] > 0) && (rcount == 0)) fighter[index].sts[S_ETHER]--; /* RB: the character is stopped? */ if (fighter[index].sts[S_STOP] > 0) { if (pidx[index] == TEMMIN) fighter[index].aux = 0; if (rcount == 0) fighter[index].sts[S_STOP]--; cact[index] = 0; } /* RB: the character is sleeping? */ if (fighter[index].sts[S_SLEEP] > 0) { if (pidx[index] == TEMMIN) fighter[index].aux = 0; if (rcount == 0) fighter[index].sts[S_SLEEP]--; cact[index] = 0; } /* RB: the character is petrified? */ if (fighter[index].sts[S_STONE] > 0) { if (pidx[index] == TEMMIN) fighter[index].aux = 0; if (rcount == 0) fighter[index].sts[S_STONE]--; cact[index] = 0; } if ((fighter[index].sts[S_DEAD] != 0) || (fighter[index].mhp <= 0)) { if (pidx[index] == TEMMIN) fighter[index].aux = 0; bspeed[index] = 0; cact[index] = 0; } if (cact[index] > 0) { if (fighter[index].sts[S_TIME] == 0) bspeed[index] += nspeed[index]; else { if (fighter[index].sts[S_TIME] == 1) bspeed[index] += (nspeed[index] / 2 + 1); else bspeed[index] += (nspeed[index] * 2); } } } else cact[index] = 0; } readcontrols (); battle_render (0, 0, 0); blit2screen (0, 0); for (index = 0; index < (PSIZE + numens); index++) { if ((bspeed[index] >= ROUND_MAX) && (cact[index] > 0)) { do_action (index); fighter[index].ctmem = 0; fighter[index].csmem = 0; cact[index] = 1; bspeed[index] = 0; } if (combatend) return; } timer_count = 0; } kq_yield (); } }
/*! \brief Perform item effects * * Perform item effects. This is kind of clunky, but it works. * * \param sa Index of attacker * \param t Index of item to use * \param ti Index of target(s) * \returns 0 if ineffective (cannot use item) * \returns 1 if success (1 target) * \returns 2 if success (multiple targets) */ int item_effects(int sa, int t, int ti) { int tmp = 0, i, a, b, z, san = 0, se = 0, sen = 0; if (sa == 0) { san = numchrs; se = PSIZE; sen = num_enemies; } else { san = num_enemies; se = 0; sen = numchrs; } switch (ti) { case I_MHERB: case I_SALVE: case I_PCURING: if (fighter[t].sts[S_DEAD] != 0) { return 0; } if (fighter[t].hp == fighter[t].mhp) { return 0; } tmp = rand() % (items[ti].stats[A_ATT] / 2) + items[ti].stats[A_ATT]; if (in_combat == 0) { adjust_hp(t, tmp); } else { ta[t] = tmp; draw_spellsprite(t, 0, items[ti].eff, 0); display_amount(t, FYELLOW, 0); adjust_hp(t, ta[t]); } break; case I_OSEED: case I_EDROPS: if (fighter[t].sts[S_DEAD] != 0) { return 0; } if (fighter[t].mp == fighter[t].mmp) { return 0; } tmp = rand() % (items[ti].stats[A_ATT] / 2) + items[ti].stats[A_ATT]; if (in_combat == 0) { adjust_mp(t, tmp); } else { ta[t] = tmp; draw_spellsprite(t, 0, items[ti].eff, 0); display_amount(t, FGREEN, 0); adjust_mp(t, ta[t]); } break; case I_NLEAF: case I_NPOULTICE: case I_KBREW: if (fighter[t].sts[S_DEAD] != 0 || fighter[t].sts[S_STONE] != 0) { return 0; } if (fighter[t].sts[items[ti].elem] != 0) { fighter[t].sts[items[ti].elem] = 0; } else { return 0; } if (in_combat == 1) { draw_spellsprite(t, 0, items[ti].eff, 0); } break; case I_WENSAI: if (fighter[t].sts[S_DEAD] != 0) { return 0; } if (fighter[t].sts[S_STONE] != 0) { fighter[t].sts[S_STONE] = 0; } else { return 0; } if (in_combat == 1) { draw_spellsprite(t, 0, items[ti].eff, 0); } break; case I_EDAENRA: tmp = 0; for (i = 0; i < 7; i++) if (fighter[t].sts[i] != 0) { tmp++; } if (tmp == 0 || fighter[t].sts[S_DEAD] != 0) { return 0; } if (fighter[t].sts[S_DEAD] != 0) { return 0; } for (i = 0; i < 12; i++) { fighter[t].sts[i] = 0; } if (in_combat == 1) { draw_spellsprite(t, 0, items[ti].eff, 0); } break; case I_LTONIC: if (fighter[t].sts[S_DEAD] == 0) { return 0; } for (a = 0; a < 24; a++) { fighter[t].sts[a] = 0; } fighter[t].hp = 1; fighter[t].aframe = 0; if (in_combat == 1) { draw_spellsprite(t, 0, items[ti].eff, 0); } break; case I_RRUNE: tmp = 0; for (i = sa; i < sa + san; i++) if (fighter[i].hp == fighter[i].mhp) { tmp++; } if (tmp == san) { return 0; } for (i = sa; i < sa + san; i++) { if (fighter[i].sts[S_DEAD] == 0 && fighter[i].sts[S_STONE] == 0) { b = fighter[i].lvl * items[ti].stats[A_ATT]; tmp = rand() % b + b + 1; if (in_combat == 0) { adjust_hp(i, tmp); } else { ta[i] = do_shell_check(i, tmp); } } } if (in_combat == 1) { draw_spellsprite(sa, 1, items[ti].eff, 1); display_amount(sa, FYELLOW, 1); for (i = sa; i < sa + san; i++) { adjust_hp(i, ta[i]); } } break; case I_ERUNE: case I_FRUNE: case I_WRUNE: case I_IRUNE: if (in_combat == 0) { return 0; } tmp = items[ti].elem; for (i = se; i < se + sen; i++) { if (fighter[i].sts[S_DEAD] == 0 && fighter[i].mhp > 0) { b = fighter[i].lvl * items[ti].stats[A_ATT]; a = rand() % b + b + 20; if (a > 250) { a = 250; } b = res_adjust(i, tmp, a); a = do_shell_check(i, b); ta[i] = 0 - a; } else { ta[i] = 0; } } draw_spellsprite(se, 1, items[ti].eff, 1); return 2; case I_TP100S: if (in_combat == 0) { return 0; } if (fighter[t].sts[S_DEAD] == 0 && fighter[t].sts[S_STONE] == 0) { ta[t] = items[ti].stats[A_ATT]; } draw_spellsprite(t, 0, items[ti].eff, 0); return 2; } if (sa == PSIZE || in_combat == 1) { return 1; } if (ti >= I_STRSEED && ti <= I_WISSEED) { if (fighter[t].sts[S_DEAD] != 0 || in_combat == 1 || t >= PSIZE) { return 0; } z = items[ti].bst; party[pidx[t]].stats[z] += (rand() % 3 + 1) * 100; play_effect(SND_TWINKLE, 128); switch (z) { case 0: message(_("Strength up!"), 255, 0, xofs, yofs); break; case 1: message(_("Agility up!"), 255, 0, xofs, yofs); break; case 2: message(_("Vitality up!"), 255, 0, xofs, yofs); break; case 3: message(_("Intellect up!"), 255, 0, xofs, yofs); break; case 4: message(_("Wisdom up!"), 255, 0, xofs, yofs); break; } return 2; } if ((items[ti].icon == W_SBOOK || items[ti].icon == W_ABOOK)) { tmp = 0; for (i = 0; i < 60; i++) if (party[pidx[t]].spells[i] > 0) { tmp++; } if (tmp == 60) { return 0; } tmp = 0; for (i = 0; i < 60; i++) if (party[pidx[t]].spells[i] == items[ti].hnds || party[pidx[t]].lvl < items[ti].ilvl) { tmp = 1; } if (tmp == 1) { return 0; } tmp = items[ti].hnds; for (i = 0; i < 60; i++) { if (party[pidx[t]].spells[i] == 0) { party[pidx[t]].spells[i] = tmp; i = 60; } } sprintf(strbuf, _("%s learned!"), magic[tmp].name); play_effect(SND_TWINKLE, 128); message(strbuf, magic[tmp].icon, 0, xofs, yofs); return 2; } if (ti == I_HPUP) { if (fighter[t].sts[S_DEAD] != 0) { return 0; } i = rand() % 11 + 10; party[pidx[t]].mhp += i; fighter[t].hp += i; } if (ti == I_MPUP) { if (fighter[t].sts[S_DEAD] != 0) { return 0; } i = rand() % 11 + 10; party[pidx[t]].mmp += i; fighter[t].mp += i; } if (ti == I_SSTONE) { if (use_sstone == 0) { return 0; } for (i = sa; i < sa + san; i++) { fighter[i].hp = fighter[i].mhp; fighter[i].mp = fighter[i].mmp; for (b = 0; b < 8; b++) { fighter[i].sts[b] = 0; } } } return 1; }