/* * $Id: mech.tech.c,v 1.2 2005/01/15 16:57:14 kstevens Exp $ * * Author: Markus Stenberg <fingon@iki.fi> * * Copyright (c) 1996 Markus Stenberg * Copyright (c) 1998-2002 Thomas Wouters * Copyright (c) 2000-2002 Cord Awtry * All rights reserved * * Created: Fri Aug 30 15:27:33 1996 fingon * Last modified: Sat Jun 6 19:33:13 1998 fingon * */ #include "mech.h" #include "muxevent.h" #include "mech.events.h" #include "mech.tech.h" #include "p.mech.utils.h" #include "p.btechstats.h" #include "p.mech.build.h" #include "p.mech.partnames.h" int game_lag(void) { if (!muxevent_tick) return 0; return 100 * (mudstate.now - mudstate.restart_time) / muxevent_tick - 100; } int game_lag_time(int i) { return (100 + game_lag()) * i / 100; } int tech_roll(dbref player, MECH * mech, int diff) { int s; int succ; int r = (HasBoolAdvantage(player, "tech_aptitude") ? char_rollsaving() : Roll()); s = FindTechSkill(player, mech); s += diff; succ = r >= s; if (Wizard(player)) { notify(player, tprintf("Tech - BTH: %d(Base:%d, Mod:%d) Roll: %d", s, s - diff, diff, r)); } else { notify(player, tprintf("BTH: %d Roll: %d", s, r)); } if (succ && In_Character(mech->mynum)) AccumulateTechXP(player, mech, BOUNDED(1, s - 7, MAX(2, 1 + diff))); return (r - s); } int tech_weapon_roll(dbref player, MECH * mech, int diff) { int s; int succ; int r = (HasBoolAdvantage(player, "tech_aptitude") ? char_rollsaving() : Roll()); s = char_getskilltarget(player, "technician-weapons", 0); s += diff; succ = r >= s; if (Wizard(player)) { notify(player, tprintf("Tech-W - BTH: %d(Base:%d, Mod:%d) Roll: %d", s, s - diff, diff, r)); } else { notify(player, tprintf("BTH: %d Roll: %d", s, r)); } if (succ && In_Character(mech->mynum)) AccumulateTechWeaponsXP(player, mech, BOUNDED(1, s - 7, MAX(2, 1 + diff))); return (r - s); } /* Basic idea: Check for attribute, if not set, set it, and do interesting stuff */ void tech_status(dbref player, time_t dat) { char buf[MBUF_SIZE]; char *olds; int un; if (dat <= 0) { olds = silly_atr_get(player, A_TECHTIME); if (olds) { dat = (time_t) atoi(olds); if (dat < mudstate.now) dat = mudstate.now; } else dat = mudstate.now; } if (dat <= mudstate.now) notify(player, "You have no jobs pending!"); else { un = (dat - mudstate.now) / TECH_TICK; sprintf(buf, "You have %d %s%s of repairs pending", un, TECH_UNIT, un != 1 ? "s" : ""); if (un >= MAX_TECHTIME) sprintf(buf + strlen(buf), " and you're too tired to do more efficiently."); else { un = MAX_TECHTIME - un; sprintf(buf + strlen(buf), " and you're ready to do at least %d more %s%s of work.", un, TECH_UNIT, un == 1 ? "" : "s"); } notify(player, buf); } } int tech_addtechtime(dbref player, int time) { time_t old; char *olds = silly_atr_get(player, A_TECHTIME); if (olds) { old = (time_t) atoi(olds); if (old < mudstate.now) old = mudstate.now; } else old = mudstate.now; old += time * TECH_TICK; silly_atr_set(player, A_TECHTIME, tprintf("%u", old)); tech_status(player, old); return (old - mudstate.now); } int tech_parsepart_advanced(MECH * mech, char *buffer, int *loc, int *pos, int *extra, int allowrear) { char *args[5]; int l, argc, isrear = 0; if (!(argc = mech_parseattributes(buffer, args, 4))) return -1; if (argc > (2 + (extra != NULL))) return -1; if (!allowrear) { if ((!extra && argc != (1 + (pos != NULL))) || (extra && (argc < (1 + (pos != NULL)) || argc > (2 + (pos != NULL))))) return -1; } else { if (argc == 2) { if (toupper(args[1][0]) != 'R') return -1; isrear = 8; } } if ((*loc = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0])) < 0) return -1; if (allowrear) *loc += isrear; if (pos) { l = atoi(args[1]) - 1; if (l < 0 || l >= CritsInLoc(mech, *loc)) return -2; *pos = l; } if (extra) { if (argc > 2) *extra = args[2][0]; else *extra = 0; } return 0; } int tech_parsepart(MECH * mech, char *buffer, int *loc, int *pos, int *extra) { return tech_parsepart_advanced(mech, buffer, loc, pos, extra, 0); } int tech_parsegun(MECH * mech, char *buffer, int *loc, int *pos, int *brand) { char *args[3]; int l, argc, t, c = 0, pi, pb; argc = mech_parseattributes(buffer, args, 3); if (argc < 1 || argc > (2 + (brand != NULL))) return -1; if (argc == (2 + (brand != NULL)) || (brand && argc == 2 && atoi(args[1]))) { if ((*loc = ArmorSectionFromString(MechType(mech), MechMove(mech), args[0])) < 0) return -1; l = atoi(args[1]); if (l <= 0 || l > CritsInLoc(mech, *loc)) return -4; *pos = l - 1; } else { /* Check if it's a number */ if (args[0][0] < '0' || args[0][0] > '9') return -1; l = atoi(args[0]); if (l < 0) return -1; if ((t = FindWeaponNumberOnMech(mech, l, loc, pos)) == -1) return -1; } t = GetPartType(mech, *loc, *pos); if (brand != NULL && argc > 1 && !atoi(args[argc - 1])) { if (!find_matching_long_part(args[argc - 1], &c, &pi, &pb)) return -2; if (pi != t) return -3; *brand = pb; } else if (brand != NULL) *brand = GetPartBrand(mech, *loc, *pos); return 0; } int cheated_last = 0; static void cheat_find_last(MUXEVENT * e) { int ofs = e->tick - muxevent_tick; int amount = (((int) e->data2) % PLAYERPOS) / 16 - 1; switch (e->type) { case EVENT_REPAIR_FIXI: ofs += amount * FIXINTERNAL_TIME * TECH_TICK; break; case EVENT_REPAIR_FIX: ofs += amount * FIXARMOR_TIME * TECH_TICK; break; } if (ofs > cheated_last) cheated_last = ofs; } int figure_latest_tech_event(MECH * mech) { int i; cheated_last = 0; for (i = FIRST_TECH_EVENT; i <= LAST_TECH_EVENT; i++) muxevent_gothru_type_data(i, (void *) mech, cheat_find_last); return cheated_last; }