static tick_type to_tick_count(hour_type hours, min_type minutes, sec_type seconds, fractional_seconds_type fs) { return (((hours*3600) + (minutes*60) + seconds)*res_adjust()) + fs; }
//! Any negative argument results in a negative tick_count static tick_type to_tick_count(hour_type hours, min_type minutes, sec_type seconds, fractional_seconds_type fs) { if (hours < 0 || minutes < 0 || seconds < 0 || fs < 0) { hours = absolute_value(hours); minutes = absolute_value(minutes); seconds = absolute_value(seconds); fs = absolute_value(fs); return (((((fractional_seconds_type(hours)*3600) + (fractional_seconds_type(minutes)*60) + seconds)*res_adjust()) + fs) * -1); } return (((fractional_seconds_type(hours)*3600) + (fractional_seconds_type(minutes)*60) + seconds)*res_adjust()) + fs; }
/*! \brief Attack all enemies at once * \author Josh Bolduc * \date Created ???????? * \date Updated * * This does the actual attack calculation. The damage done to * the target is kept in the ta[] array. * * \param ar Attacker * \param dr Defender * \returns 0 if attack was a miss, 1 if attack was successful, * or 2 if attack was a critical hit. */ static int attack_result (int ar, int dr) { int c; int check_for_critical_hit; int attacker_critical_status = 0; int crit_hit = 0; int base; int to_hit; int mult; int dmg; /* extra */ int attacker_attack; int attacker_hit; int attacker_weapon_element; int defender_defense; int defender_evade; attacker_attack = tempa.stats[A_ATT]; attacker_hit = tempa.stats[A_HIT]; attacker_weapon_element = tempa.welem; defender_defense = tempd.stats[A_DEF]; defender_evade = tempd.stats[A_EVD]; /* JB: check to see if the attacker is in critical status... */ /* increases chance for a critical hit */ if (tempa.mhp > 250) { if (tempa.hp <= 50) attacker_critical_status = 1; } else { if (tempa.hp <= (tempa.mhp / 5)) attacker_critical_status = 1; } /* JB: check to see if the defender is 'defending' */ if (tempd.defend == 1) defender_defense = (defender_defense * 15) / 10; /* JB: if the attacker is empowered by trueshot */ if (tempa.sts[S_TRUESHOT] > 0) { fighter[ar].sts[S_TRUESHOT] = 0; defender_evade = 0; } attacker_attack += (tempa.stats[tempa.bstat] * tempa.bonus / 100); if (attacker_attack < DMG_RND_MIN * 5) base = (rand () % DMG_RND_MIN) + attacker_attack; else base = (rand () % (attacker_attack / 5)) + attacker_attack; base -= defender_defense; if (base < 1) base = 1; mult = 0; to_hit = attacker_hit + defender_evade; if (to_hit < 1) to_hit = 1; if (rand () % to_hit < attacker_hit) mult++; /* JB: If the defender is etherealized, set mult to 0 */ if (tempd.sts[S_ETHER] > 0) mult = 0; if (mult > 0) { if (tempd.crit == 1) { check_for_critical_hit = 1; if (attacker_critical_status == 1) check_for_critical_hit = 2; /* PH I _think_ this makes Sensar 2* as likely to make a critical hit */ if (pidx[ar] == SENSAR) check_for_critical_hit = check_for_critical_hit * 2; check_for_critical_hit = (20 - check_for_critical_hit); if (rand () % 20 >= check_for_critical_hit) { crit_hit = 1; /* TT: Changed following line from: * base = base * 15 / 10; */ base = ((int) base * 3) / 2; } } /* JB: if affected by a NAUSEA/MALISON spell, the defender */ /* takes more damage than normal */ if (tempd.sts[S_MALISON] > 0) base *= (int) 5 / 4; /* JB: check for elemental/status weapons */ if (base < 1) base = 1; c = attacker_weapon_element - 1; if ((c >= R_EARTH) && (c <= R_ICE)) base = res_adjust (dr, c, base); if ((c >= R_POISON) && (c <= R_SLEEP)) { if ((res_throw (dr, c) == 0) && (fighter[dr].sts[c - 8] == 0)) { if (non_dmg_save (dr, 50) == 0) { if ((c == R_POISON) || (c == R_PETRIFY) || (c == R_SILENCE)) tempd.sts[c - 8] = 1; else tempd.sts[c - 8] = rand () % 3 + 2; } } } } /* JB: Apply the damage multiplier */ /* RB FIXME: check if the changes I made here didn't break something */ /* TT TODO: * If magic, attacks, etc. are zero, they should return as a miss. * For some reason, this isn't properly being reported. */ #ifdef KQ_CHEATS if (cheat && every_hit_999) { ta[dr] = -999; return 1; } #endif dmg = mult * base; if (dmg == 0) { dmg = MISS; ta[dr] = dmg; return 0; } else { ta[dr] = 0 - dmg; return ((crit_hit == 1) ? 2 : 1); } }
/*! \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; }