btmux-0.6-rc4/doc/
btmux-0.6-rc4/event/
btmux-0.6-rc4/game/
btmux-0.6-rc4/game/maps/
btmux-0.6-rc4/game/mechs/
btmux-0.6-rc4/game/text/help/
btmux-0.6-rc4/game/text/help/cat_faction/
btmux-0.6-rc4/game/text/help/cat_inform/
btmux-0.6-rc4/game/text/help/cat_misc/
btmux-0.6-rc4/game/text/help/cat_mux/
btmux-0.6-rc4/game/text/help/cat_mux/cat_commands/
btmux-0.6-rc4/game/text/help/cat_mux/cat_functions/
btmux-0.6-rc4/game/text/help/cat_templates/
btmux-0.6-rc4/game/text/wizhelp/
btmux-0.6-rc4/include/
btmux-0.6-rc4/misc/
btmux-0.6-rc4/python/
btmux-0.6-rc4/src/hcode/btech/
btmux-0.6-rc4/tree/
/*
 * 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
 */

#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_printf(player, "Tech - BTH: %d(Base:%d, Mod:%d) Roll: %d",
					  s, s - diff, diff, r);
	} else {
		notify_printf(player, "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_printf(player,
					  "Tech-W - BTH: %d(Base:%d, Mod:%d) Roll: %d", s,
					  s - diff, diff, r);
	} else {
		notify_printf(player, "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;
}