305 lines
7.7 KiB
C
305 lines
7.7 KiB
C
|
/* Emacs style mode select -*- C++ -*-
|
||
|
*-----------------------------------------------------------------------------
|
||
|
*
|
||
|
*
|
||
|
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
|
||
|
* based on BOOM, a modified and improved DOOM engine
|
||
|
* Copyright (C) 1999 by
|
||
|
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
||
|
* Copyright (C) 1999-2000 by
|
||
|
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
||
|
* Copyright 2005, 2006 by
|
||
|
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||
|
* 02111-1307, USA.
|
||
|
*
|
||
|
* DESCRIPTION: tracers stuff
|
||
|
*
|
||
|
*-----------------------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif
|
||
|
|
||
|
#include "doomdef.h"
|
||
|
#include "doomstat.h"
|
||
|
#include "m_argv.h"
|
||
|
#include "m_misc.h"
|
||
|
#include "lprintf.h"
|
||
|
|
||
|
#include "hu_tracers.h"
|
||
|
|
||
|
dboolean traces_present;
|
||
|
|
||
|
hu_textline_t w_traces[NUMTRACES];
|
||
|
|
||
|
void TracerApply(tracertype_t index);
|
||
|
void GivenDamageReset(tracertype_t index);
|
||
|
void GivenDamageApply(tracertype_t index);
|
||
|
|
||
|
traceslist_t traces[NUMTRACES];
|
||
|
|
||
|
void InitTracers(void)
|
||
|
{
|
||
|
int i, p;
|
||
|
int value, count;
|
||
|
|
||
|
traceslistinit_t traces_init[NUMTRACES] = {
|
||
|
{"-trace_thingshealth", "health ", TracerApply, NULL},
|
||
|
{"-trace_thingspickup", "pickup ", TracerApply, NULL},
|
||
|
{"-trace_linescross" , "lcross ", TracerApply, NULL},
|
||
|
{"-trace_givendamage" , "damage ", GivenDamageApply, GivenDamageReset},
|
||
|
};
|
||
|
|
||
|
traces_present = false;
|
||
|
|
||
|
for (i = 0; i < NUMTRACES; i++)
|
||
|
{
|
||
|
strcpy(traces[i].cmd, traces_init[i].cmd);
|
||
|
strcpy(traces[i].prefix, traces_init[i].prefix);
|
||
|
traces[i].ApplyFunc = traces_init[i].ApplyFunc;
|
||
|
traces[i].ResetFunc = traces_init[i].ResetFunc;
|
||
|
|
||
|
count = 0;
|
||
|
traces[i].count = 0;
|
||
|
if ((p = M_CheckParm(traces[i].cmd)) && (p < myargc - 1))
|
||
|
{
|
||
|
while (count < 3 && p + count < myargc - 1 && M_StrToInt(myargv[p + 1 + count], &value))
|
||
|
{
|
||
|
sprintf(traces[i].items[count].value, "\x1b\x36%d\x1b\x33 0", value);
|
||
|
traces[i].items[count].index = value;
|
||
|
|
||
|
if (traces[i].ApplyFunc)
|
||
|
traces[i].ApplyFunc(i);
|
||
|
|
||
|
traces_present = true;
|
||
|
count++;
|
||
|
}
|
||
|
traces[i].count = count;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TracerApply(tracertype_t index)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
strcpy(traces[index].hudstr, traces[index].prefix);
|
||
|
for (i = 0; i < traces[index].count; i++)
|
||
|
{
|
||
|
sprintf(traces[index].hudstr + strlen(traces[index].hudstr),
|
||
|
"\x1b\x33%s ", traces[index].items[i].value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CheckThingsPickupTracer(mobj_t *mobj)
|
||
|
{
|
||
|
if (traces[TRACE_PICKUP].count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[TRACE_PICKUP].count; i++)
|
||
|
{
|
||
|
if (mobj->index == traces[TRACE_PICKUP].items[i].index)
|
||
|
{
|
||
|
sprintf(traces[TRACE_PICKUP].items[i].value,
|
||
|
"\x1b\x36%d \x1b\x33%05.2f",
|
||
|
traces[TRACE_PICKUP].items[i].index, (float)(leveltime)/35);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CheckThingsHealthTracer(mobj_t *mobj)
|
||
|
{
|
||
|
if (traces[TRACE_HEALTH].count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[TRACE_HEALTH].count; i++)
|
||
|
{
|
||
|
if (mobj->index == traces[TRACE_HEALTH].items[i].index)
|
||
|
{
|
||
|
sprintf(traces[TRACE_HEALTH].items[i].value,
|
||
|
"\x1b\x36%d \x1b\x33%d",
|
||
|
mobj->index, mobj->health);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int crossed_lines_count = 0;
|
||
|
void CheckLinesCrossTracer(line_t *line)
|
||
|
{
|
||
|
if (traces[TRACE_CROSS].count)
|
||
|
{
|
||
|
int i;
|
||
|
crossed_lines_count++;
|
||
|
for (i = 0;i < traces[TRACE_CROSS].count; i++)
|
||
|
{
|
||
|
if (line->iLineID == traces[TRACE_CROSS].items[i].index)
|
||
|
{
|
||
|
if (!traces[TRACE_CROSS].items[i].data1)
|
||
|
{
|
||
|
sprintf(traces[TRACE_CROSS].items[i].value,
|
||
|
"\x1b\x36%d \x1b\x33%05.2f",
|
||
|
traces[TRACE_CROSS].items[i].index, (float)(leveltime)/35);
|
||
|
traces[TRACE_CROSS].items[i].data1 = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ClearLinesCrossTracer(void)
|
||
|
{
|
||
|
if (traces[TRACE_CROSS].count)
|
||
|
{
|
||
|
if (!crossed_lines_count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[TRACE_CROSS].count; i++)
|
||
|
{
|
||
|
traces[TRACE_CROSS].items[i].data1 = 0;
|
||
|
}
|
||
|
}
|
||
|
crossed_lines_count = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int given_damage_pertic[MAXTRACEITEMS];
|
||
|
static int given_damage_pertic_saved[MAXTRACEITEMS];
|
||
|
static int given_damage_total[MAXTRACEITEMS];
|
||
|
static int given_damage_processed[MAXTRACEITEMS];
|
||
|
|
||
|
void CheckGivenDamageTracer(mobj_t *mobj, int damage)
|
||
|
{
|
||
|
if (traces[TRACE_DAMAGE].count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[TRACE_DAMAGE].count; i++)
|
||
|
{
|
||
|
if (mobj->index == traces[TRACE_DAMAGE].items[i].index)
|
||
|
{
|
||
|
given_damage_processed[i] = false;
|
||
|
given_damage_pertic[i] += damage;
|
||
|
given_damage_total[i] += damage;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void GivenDamageApply(tracertype_t index)
|
||
|
{
|
||
|
if (traces[index].count)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[index].count; i++)
|
||
|
{
|
||
|
if (!given_damage_processed[i])
|
||
|
{
|
||
|
given_damage_processed[i] = true;
|
||
|
given_damage_pertic_saved[i] = given_damage_pertic[i];
|
||
|
}
|
||
|
|
||
|
sprintf(traces[index].items[i].value,
|
||
|
"\x1b\x36%d \x1b\x33%d/\x1b\x33%d",
|
||
|
traces[index].items[i].index, given_damage_pertic_saved[i], given_damage_total[i]);
|
||
|
TracerApply(index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void GivenDamageReset(tracertype_t index)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < traces[index].count; i++)
|
||
|
{
|
||
|
given_damage_pertic[i] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
typedef struct {
|
||
|
int init_index;
|
||
|
int index;
|
||
|
} PACKEDATTR tracer_mapthing_t;
|
||
|
|
||
|
static tracer_mapthing_t *deathmatchstarts_indexes = NULL;
|
||
|
static tracer_mapthing_t playerstarts_indexes[MAXPLAYERS];
|
||
|
int num_deathmatchstarts_indexes = 0;
|
||
|
|
||
|
void TracerAddDeathmatchStart(int num, int index)
|
||
|
{
|
||
|
if (num >= num_deathmatchstarts_indexes)
|
||
|
{
|
||
|
num_deathmatchstarts_indexes = num + 1;
|
||
|
|
||
|
deathmatchstarts_indexes = realloc(
|
||
|
deathmatchstarts_indexes,
|
||
|
num_deathmatchstarts_indexes * sizeof(deathmatchstarts_indexes[0]));
|
||
|
}
|
||
|
|
||
|
deathmatchstarts_indexes[num].index = index;
|
||
|
}
|
||
|
|
||
|
void TracerAddPlayerStart(int num, int index)
|
||
|
{
|
||
|
if (traces_present)
|
||
|
{
|
||
|
//init
|
||
|
if (gametic == 0)
|
||
|
{
|
||
|
playerstarts_indexes[num].init_index = index;
|
||
|
playerstarts_indexes[num].index = index;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
playerstarts_indexes[num].index = playerstarts_indexes[num].init_index;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int TracerGetDeathmatchStart(int index)
|
||
|
{
|
||
|
if (index >= num_deathmatchstarts_indexes)
|
||
|
I_Error("TracerGetDeathmatchStart: index out of bounds");
|
||
|
|
||
|
return deathmatchstarts_indexes[index].index;
|
||
|
}
|
||
|
|
||
|
int TracerGetPlayerStart(int index)
|
||
|
{
|
||
|
if (index >= MAXPLAYERS)
|
||
|
I_Error("TracerGetDeathmatchStart: index out of bounds");
|
||
|
|
||
|
return playerstarts_indexes[index].index;
|
||
|
}
|
||
|
|
||
|
void TracerClearStarts(void)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||
|
{
|
||
|
playerstarts_indexes[i].index = 0;
|
||
|
}
|
||
|
|
||
|
num_deathmatchstarts_indexes = 0;
|
||
|
if (deathmatchstarts_indexes)
|
||
|
{
|
||
|
free(deathmatchstarts_indexes);
|
||
|
deathmatchstarts_indexes = NULL;
|
||
|
}
|
||
|
}
|