gzdoom-last-svn/src/g_game.cpp

2638 lines
58 KiB
C++
Raw Normal View History

// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log:$
//
// DESCRIPTION: none
//
//-----------------------------------------------------------------------------
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <time.h>
#include "templates.h"
#include "version.h"
#include "m_alloc.h"
#include "doomdef.h"
#include "doomstat.h"
#include "d_protocol.h"
#include "d_netinf.h"
#include "f_finale.h"
#include "m_argv.h"
#include "m_misc.h"
#include "m_menu.h"
#include "m_random.h"
#include "m_crc32.h"
#include "i_system.h"
#include "p_setup.h"
#include "p_saveg.h"
#include "p_effect.h"
#include "p_tick.h"
#include "d_main.h"
#include "wi_stuff.h"
#include "hu_stuff.h"
#include "st_stuff.h"
#include "am_map.h"
#include "c_console.h"
#include "c_cvars.h"
#include "c_bind.h"
#include "c_dispatch.h"
#include "v_video.h"
#include "w_wad.h"
#include "p_local.h"
#include "s_sound.h"
#include "gstrings.h"
#include "r_data.h"
#include "r_sky.h"
#include "r_draw.h"
#include "g_game.h"
#include "g_level.h"
#include "b_bot.h" //Added by MC:
#include "sbar.h"
#include "m_swap.h"
#include "m_png.h"
#include "gi.h"
#include "a_keys.h"
#include "a_artifacts.h"
#include "r_translate.h"
#include <zlib.h>
#include "g_hub.h"
static FRandom pr_dmspawn ("DMSpawn");
const int SAVEPICWIDTH = 216;
const int SAVEPICHEIGHT = 162;
bool G_CheckDemoStatus (void);
void G_ReadDemoTiccmd (ticcmd_t *cmd, int player);
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf);
void G_PlayerReborn (int player);
void G_DoNewGame (void);
void G_DoLoadGame (void);
void G_DoPlayDemo (void);
void G_DoCompleted (void);
void G_DoVictory (void);
void G_DoWorldDone (void);
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description);
void G_DoAutoSave ();
FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Bool, chasedemo, false, 0);
CVAR (Bool, storesavepic, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, longsavemessages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
gameaction_t gameaction;
gamestate_t gamestate = GS_STARTUP;
int paused;
bool sendpause; // send a pause event next tic
bool sendsave; // send a save event next tic
bool sendturn180; // [RH] send a 180 degree turn next tic
bool usergame; // ok to save / end game
bool insave; // Game is saving - used to block exit commands
bool timingdemo; // if true, exit with report on completion
bool nodrawers; // for comparative timing purposes
bool noblit; // for comparative timing purposes
bool viewactive;
bool netgame; // only true if packets are broadcast
bool multiplayer;
player_t players[MAXPLAYERS];
bool playeringame[MAXPLAYERS];
DWORD playerswiping;
int consoleplayer; // player taking events
int gametic;
CVAR(Bool, demo_compress, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
char demoname[256];
bool demorecording;
bool demoplayback;
bool netdemo;
bool demonew; // [RH] Only used around G_InitNew for demos
int demover;
BYTE* demobuffer;
BYTE* demo_p;
BYTE* democompspot;
BYTE* demobodyspot;
size_t maxdemosize;
BYTE* zdemformend; // end of FORM ZDEM chunk
BYTE* zdembodyend; // end of ZDEM BODY chunk
bool singledemo; // quit after playing a demo from cmdline
bool precache = true; // if true, load all graphics at start
wbstartstruct_t wminfo; // parms for world map / intermission
short consistancy[MAXPLAYERS][BACKUPTICS];
BYTE* savebuffer;
#define MAXPLMOVE (forwardmove[1])
#define TURBOTHRESHOLD 12800
float normforwardmove[2] = {0x19, 0x32}; // [RH] For setting turbo from console
float normsidemove[2] = {0x18, 0x28}; // [RH] Ditto
fixed_t forwardmove[2], sidemove[2];
fixed_t angleturn[4] = {640, 1280, 320, 320}; // + slow turn
fixed_t flyspeed[2] = {1*256, 3*256};
int lookspeed[2] = {450, 512};
#define SLOWTURNTICS 6
CVAR (Bool, cl_run, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Always run?
CVAR (Bool, invertmouse, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Invert mouse look down/up?
CVAR (Bool, freelook, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Always mlook?
CVAR (Bool, lookstrafe, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Always strafe with mouse?
CVAR (Float, m_pitch, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // Mouse speeds
CVAR (Float, m_yaw, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
CVAR (Float, m_forward, 1.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
CVAR (Float, m_side, 2.f, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
int turnheld; // for accelerative turning
// mouse values are used once
int mousex;
int mousey;
FString savegamefile;
char savedescription[SAVESTRINGSIZE];
// [RH] Name of screenshot file to generate (usually NULL)
FString shotfile;
AActor* bodyque[BODYQUESIZE];
int bodyqueslot;
void R_ExecuteSetViewSize (void);
FString savename;
FString BackupSaveName;
bool SendLand;
const AInventory *SendItemUse, *SendItemDrop;
EXTERN_CVAR (Int, team)
CVAR (Bool, teamplay, false, CVAR_SERVERINFO)
// [RH] Allow turbo setting anytime during game
CUSTOM_CVAR (Float, turbo, 100.f, 0)
{
if (self < 10.f)
{
self = 10.f;
}
else if (self > 256.f)
{
self = 256.f;
}
else
{
Update to ZDoom r1062: - Rewrote myvsnprintf to use the StringFormat routines directly so that no additional memory needs to be allocated from the heap. - Polyobject sounds now play from their lines, similar to the way sector sounds are handled. - Why do polyobjects have a 3D start spot? Flattened it to 2D. - Moved the sector sound origin calculation out of fmodsound.cpp and into s_sound.cpp so that the near sound limiting will use the correct sound location for deciding on neighbors. - Removed the S_Sound() variant that allows for pointing the origin at an arbitrary point. It has been replaced with a variant that takes a polyobject as a source, since that was the only use that couldn't be rewritten with the other variants. This also fixes the bug that polyobject sounds were not successfully saved and caused a crash when reloading the game. Note that this is a significant change to how equality of sound sources is determined, so some things may not behave quite the same as before. (Which would be a bug, but hopefully everything still sounds the same.) - Adjusted the noise debug table so that fractional volume levels do not run into the adjacent columns. - Added a NullSoundRenderer so that most of the checks against a NULL GSnd can be removed. - Fixed: Looping sounds must always successfully allocate a channel, even if it's only a pre-evicted channel. - Added A_ClearReFire code pointer for weapons. Preferably A_WeaponReady should reset this counter but that can't be done due to unwanted side effects with existing weapons. - Changed the 'scale' variable in CVAR(turbo) to double because the calculations depended on the current floating point precision setting and only worked properly when set to 'precise' in VC++. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@130 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-04 16:54:29 +00:00
double scale = self * 0.01;
forwardmove[0] = (int)(normforwardmove[0]*scale);
forwardmove[1] = (int)(normforwardmove[1]*scale);
sidemove[0] = (int)(normsidemove[0]*scale);
sidemove[1] = (int)(normsidemove[1]*scale);
}
}
CCMD (turnspeeds)
{
if (argv.argc() == 1)
{
Printf ("Current turn speeds: %d %d %d %d\n", angleturn[0],
angleturn[1], angleturn[2], angleturn[3]);
}
else
{
int i;
for (i = 1; i <= 4 && i < argv.argc(); ++i)
{
angleturn[i-1] = atoi (argv[i]);
}
if (i <= 2)
{
angleturn[1] = angleturn[0] * 2;
}
if (i <= 3)
{
angleturn[2] = angleturn[0] / 2;
}
if (i <= 4)
{
angleturn[3] = angleturn[2];
}
}
}
CCMD (slot)
{
if (argv.argc() > 1)
{
int slot = atoi (argv[1]);
if (slot < NUM_WEAPON_SLOTS)
{
SendItemUse = LocalWeapons.Slots[slot].PickWeapon (&players[consoleplayer]);
}
}
}
CCMD (centerview)
{
Net_WriteByte (DEM_CENTERVIEW);
}
CCMD(crouch)
{
Net_WriteByte(DEM_CROUCH);
}
CCMD (land)
{
SendLand = true;
}
CCMD (pause)
{
sendpause = true;
}
CCMD (turn180)
{
sendturn180 = true;
}
CCMD (weapnext)
{
SendItemUse = PickNextWeapon (&players[consoleplayer]);
}
CCMD (weapprev)
{
SendItemUse = PickPrevWeapon (&players[consoleplayer]);
}
CCMD (invnext)
{
AInventory *next;
if (who == NULL)
return;
if (who->InvSel != NULL)
{
if ((next = who->InvSel->NextInv()) != NULL)
{
who->InvSel = next;
}
else
{
// Select the first item in the inventory
if (!(who->Inventory->ItemFlags & IF_INVBAR))
{
who->InvSel = who->Inventory->NextInv();
}
else
{
who->InvSel = who->Inventory;
}
}
}
who->player->inventorytics = 5*TICRATE;
}
CCMD (invprev)
{
AInventory *item, *newitem;
if (who == NULL)
return;
if (who->InvSel != NULL)
{
if ((item = who->InvSel->PrevInv()) != NULL)
{
who->InvSel = item;
}
else
{
// Select the last item in the inventory
item = who->InvSel;
while ((newitem = item->NextInv()) != NULL)
{
item = newitem;
}
who->InvSel = item;
}
}
who->player->inventorytics = 5*TICRATE;
}
CCMD (invuseall)
{
SendItemUse = (const AInventory *)1;
}
CCMD (invuse)
{
if (players[consoleplayer].inventorytics == 0 || gameinfo.gametype == GAME_Strife)
{
if (players[consoleplayer].mo) SendItemUse = players[consoleplayer].mo->InvSel;
}
players[consoleplayer].inventorytics = 0;
}
CCMD (use)
{
if (argv.argc() > 1 && who != NULL)
{
SendItemUse = who->FindInventory (PClass::FindClass (argv[1]));
}
}
CCMD (invdrop)
{
if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel;
}
CCMD (drop)
{
if (argv.argc() > 1 && who != NULL)
{
SendItemDrop = who->FindInventory (PClass::FindClass (argv[1]));
}
}
CCMD (useflechette)
{ // Select from one of arti_poisonbag1-3, whichever the player has
static const ENamedName bagnames[3] =
{
NAME_ArtiPoisonBag1,
NAME_ArtiPoisonBag2,
NAME_ArtiPoisonBag3
};
int i, j;
if (who == NULL)
return;
if (who->IsKindOf (PClass::FindClass (NAME_ClericPlayer)))
i = 0;
else if (who->IsKindOf (PClass::FindClass (NAME_MagePlayer)))
i = 1;
else
i = 2;
for (j = 0; j < 3; ++j)
{
AInventory *item;
if ( (item = who->FindInventory (bagnames[(i+j)%3])) )
{
SendItemUse = item;
break;
}
}
}
CCMD (select)
{
if (argv.argc() > 1)
{
AInventory *item = who->FindInventory (PClass::FindClass (argv[1]));
if (item != NULL)
{
who->InvSel = item;
}
}
who->player->inventorytics = 5*TICRATE;
}
//
// G_BuildTiccmd
// Builds a ticcmd from all of the available inputs
// or reads it from the demo buffer.
// If recording a demo, write it out
//
void G_BuildTiccmd (ticcmd_t *cmd)
{
int strafe;
int speed;
int forward;
int side;
int fly;
ticcmd_t *base;
base = I_BaseTiccmd (); // empty, or external driver
*cmd = *base;
cmd->consistancy = consistancy[consoleplayer][(maketic/ticdup)%BACKUPTICS];
strafe = Button_Strafe.bDown;
speed = Button_Speed.bDown ^ (int)cl_run;
forward = side = fly = 0;
// [RH] only use two stage accelerative turning on the keyboard
// and not the joystick, since we treat the joystick as
// the analog device it is.
if (Button_Left.bDown || Button_Right.bDown)
turnheld += ticdup;
else
turnheld = 0;
// let movement keys cancel each other out
if (strafe)
{
if (Button_Right.bDown)
side += sidemove[speed];
if (Button_Left.bDown)
side -= sidemove[speed];
}
else
{
int tspeed = speed;
if (turnheld < SLOWTURNTICS)
tspeed *= 2; // slow turn
if (Button_Right.bDown)
{
G_AddViewAngle (angleturn[tspeed]);
LocalKeyboardTurner = true;
}
if (Button_Left.bDown)
{
G_AddViewAngle (-angleturn[tspeed]);
LocalKeyboardTurner = true;
}
}
if (Button_LookUp.bDown)
G_AddViewPitch (lookspeed[speed]);
if (Button_LookDown.bDown)
G_AddViewPitch (-lookspeed[speed]);
if (Button_MoveUp.bDown)
fly += flyspeed[speed];
if (Button_MoveDown.bDown)
fly -= flyspeed[speed];
if (Button_Klook.bDown)
{
if (Button_Forward.bDown)
G_AddViewPitch (lookspeed[speed]);
if (Button_Back.bDown)
G_AddViewPitch (-lookspeed[speed]);
}
else
{
if (Button_Forward.bDown)
forward += forwardmove[speed];
if (Button_Back.bDown)
forward -= forwardmove[speed];
}
if (Button_MoveRight.bDown)
side += sidemove[speed];
if (Button_MoveLeft.bDown)
side -= sidemove[speed];
// buttons
if (Button_Attack.bDown)
cmd->ucmd.buttons |= BT_ATTACK;
if (Button_AltAttack.bDown)
cmd->ucmd.buttons |= BT_ALTATTACK;
if (Button_Use.bDown)
cmd->ucmd.buttons |= BT_USE;
if (Button_Jump.bDown)
cmd->ucmd.buttons |= BT_JUMP;
if (Button_Crouch.bDown)
cmd->ucmd.buttons |= BT_DUCK;
// [RH] Scale joystick moves to full range of allowed speeds
if (JoyAxes[JOYAXIS_PITCH] != 0)
{
G_AddViewPitch (int((JoyAxes[JOYAXIS_PITCH] * 2048) / 256));
LocalKeyboardTurner = true;
}
if (JoyAxes[JOYAXIS_YAW] != 0)
{
G_AddViewAngle (int((-1280 * JoyAxes[JOYAXIS_YAW]) / 256));
LocalKeyboardTurner = true;
}
side += int((MAXPLMOVE * JoyAxes[JOYAXIS_SIDE]) / 256);
forward += int((JoyAxes[JOYAXIS_FORWARD] * MAXPLMOVE) / 256);
fly += int(JoyAxes[JOYAXIS_UP] * 8);
if (!Button_Mlook.bDown && !freelook)
{
forward += (int)((float)mousey * m_forward);
}
cmd->ucmd.pitch = LocalViewPitch >> 16;
if (SendLand)
{
SendLand = false;
fly = -32768;
}
if (strafe || lookstrafe)
side += (int)((float)mousex * m_side);
mousex = mousey = 0;
if (forward > MAXPLMOVE)
forward = MAXPLMOVE;
else if (forward < -MAXPLMOVE)
forward = -MAXPLMOVE;
if (side > MAXPLMOVE)
side = MAXPLMOVE;
else if (side < -MAXPLMOVE)
side = -MAXPLMOVE;
cmd->ucmd.forwardmove += forward;
cmd->ucmd.sidemove += side;
cmd->ucmd.yaw = LocalViewAngle >> 16;
cmd->ucmd.upmove = fly;
LocalViewAngle = 0;
LocalViewPitch = 0;
// special buttons
if (sendturn180)
{
sendturn180 = false;
cmd->ucmd.buttons |= BT_TURN180;
}
if (sendpause)
{
sendpause = false;
Net_WriteByte (DEM_PAUSE);
}
if (sendsave)
{
sendsave = false;
Net_WriteByte (DEM_SAVEGAME);
Net_WriteString (savegamefile);
Net_WriteString (savedescription);
savegamefile = "";
}
if (SendItemUse == (const AInventory *)1)
{
Net_WriteByte (DEM_INVUSEALL);
SendItemUse = NULL;
}
else if (SendItemUse != NULL)
{
Net_WriteByte (DEM_INVUSE);
Net_WriteLong (SendItemUse->InventoryID);
SendItemUse = NULL;
}
if (SendItemDrop != NULL)
{
Net_WriteByte (DEM_INVDROP);
Net_WriteLong (SendItemDrop->InventoryID);
SendItemDrop = NULL;
}
cmd->ucmd.forwardmove <<= 8;
cmd->ucmd.sidemove <<= 8;
}
//[Graf Zahl] This really helps if the mouse update rate can't be increased!
CVAR (Bool, smooth_mouse, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
void G_AddViewPitch (int look)
{
if (gamestate == GS_TITLELEVEL)
{
return;
}
look <<= 16;
if (!level.IsFreelookAllowed())
{
LocalViewPitch = 0;
}
else if (look > 0)
{
// Avoid overflowing
if (LocalViewPitch + look <= LocalViewPitch)
{
LocalViewPitch = 0x78000000;
}
else
{
LocalViewPitch = MIN(LocalViewPitch + look, 0x78000000);
}
}
else if (look < 0)
{
// Avoid overflowing
if (LocalViewPitch + look >= LocalViewPitch)
{
LocalViewPitch = -0x78000000;
}
else
{
LocalViewPitch = MAX(LocalViewPitch + look, -0x78000000);
}
}
if (look != 0)
{
LocalKeyboardTurner = smooth_mouse;
}
}
void G_AddViewAngle (int yaw)
{
if (gamestate == GS_TITLELEVEL)
{
return;
}
LocalViewAngle -= yaw << 16;
if (yaw != 0)
{
LocalKeyboardTurner = smooth_mouse;
}
}
CVAR (Bool, bot_allowspy, false, 0)
// [RH] Spy mode has been separated into two console commands.
// One goes forward; the other goes backward.
static void ChangeSpy (bool forward)
{
// If you're not in a level, then you can't spy.
if (gamestate != GS_LEVEL)
{
return;
}
// If not viewing through a player, return your eyes to your own head.
if (players[consoleplayer].camera->player == NULL)
{
players[consoleplayer].camera = players[consoleplayer].mo;
return;
}
// Otherwise, cycle to the next player.
bool checkTeam = !demoplayback && deathmatch;
int pnum = players[consoleplayer].camera->player - players;
int step = forward ? 1 : -1;
do
{
pnum += step;
pnum &= MAXPLAYERS-1;
if (playeringame[pnum] &&
(!checkTeam || players[pnum].mo->IsTeammate (players[consoleplayer].mo) ||
(bot_allowspy && players[pnum].isbot)))
{
break;
}
} while (pnum != consoleplayer);
players[consoleplayer].camera = players[pnum].mo;
S_UpdateSounds(players[consoleplayer].camera);
StatusBar->AttachToPlayer (&players[pnum]);
if (demoplayback || multiplayer)
{
StatusBar->ShowPlayerName ();
}
}
CCMD (spynext)
{
// allow spy mode changes even during the demo
ChangeSpy (true);
}
CCMD (spyprev)
{
// allow spy mode changes even during the demo
ChangeSpy (false);
}
//
// G_Responder
// Get info needed to make ticcmd_ts for the players.
//
bool G_Responder (event_t *ev)
{
// any other key pops up menu if in demos
// [RH] But only if the key isn't bound to a "special" command
if (gameaction == ga_nothing &&
(demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL))
{
const char *cmd = C_GetBinding (ev->data1);
if (ev->type == EV_KeyDown)
{
if (!cmd || (
strnicmp (cmd, "menu_", 5) &&
stricmp (cmd, "toggleconsole") &&
stricmp (cmd, "sizeup") &&
stricmp (cmd, "sizedown") &&
stricmp (cmd, "togglemap") &&
stricmp (cmd, "spynext") &&
stricmp (cmd, "spyprev") &&
stricmp (cmd, "chase") &&
stricmp (cmd, "+showscores") &&
stricmp (cmd, "bumpgamma") &&
stricmp (cmd, "screenshot")))
{
M_StartControlPanel (true);
return true;
}
else
{
return C_DoKey (ev);
}
}
if (cmd && cmd[0] == '+')
return C_DoKey (ev);
return false;
}
if (CT_Responder (ev))
return true; // chat ate the event
if (gamestate == GS_LEVEL)
{
if (ST_Responder (ev))
return true; // status window ate it
if (!viewactive && AM_Responder (ev))
return true; // automap ate it
}
else if (gamestate == GS_FINALE)
{
if (F_Responder (ev))
return true; // finale ate the event
}
switch (ev->type)
{
case EV_KeyDown:
if (C_DoKey (ev))
return true;
break;
case EV_KeyUp:
C_DoKey (ev);
break;
// [RH] mouse buttons are sent as key up/down events
case EV_Mouse:
mousex = (int)(ev->x * mouse_sensitivity);
mousey = (int)(ev->y * mouse_sensitivity);
break;
}
// [RH] If the view is active, give the automap a chance at
// the events *last* so that any bound keys get precedence.
if (gamestate == GS_LEVEL && viewactive)
return AM_Responder (ev);
return (ev->type == EV_KeyDown ||
ev->type == EV_Mouse);
}
//
// G_Ticker
// Make ticcmd_ts for the players.
//
extern FTexture *Page;
void G_Ticker ()
{
int i;
gamestate_t oldgamestate;
// do player reborns if needed
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] &&
(players[i].playerstate == PST_REBORN || players[i].playerstate == PST_ENTER))
{
G_DoReborn (i, false);
}
}
if (ToggleFullscreen)
{
static char toggle_fullscreen[] = "toggle fullscreen";
ToggleFullscreen = false;
AddCommandString (toggle_fullscreen);
}
// do things to change the game state
oldgamestate = gamestate;
while (gameaction != ga_nothing)
{
if (gameaction == ga_newgame2)
{
gameaction = ga_newgame;
break;
}
switch (gameaction)
{
case ga_loadlevel:
G_DoLoadLevel (-1, false);
break;
case ga_newgame2: // Silence GCC (see above)
case ga_newgame:
G_DoNewGame ();
break;
case ga_loadgame:
G_DoLoadGame ();
break;
case ga_savegame:
G_DoSaveGame (true, savegamefile, savedescription);
gameaction = ga_nothing;
savegamefile = "";
savedescription[0] = '\0';
break;
case ga_autosave:
G_DoAutoSave ();
gameaction = ga_nothing;
break;
case ga_playdemo:
G_DoPlayDemo ();
break;
case ga_completed:
G_DoCompleted ();
break;
case ga_slideshow:
F_StartSlideshow ();
break;
case ga_worlddone:
G_DoWorldDone ();
break;
case ga_screenshot:
M_ScreenShot (shotfile);
shotfile = "";
gameaction = ga_nothing;
break;
case ga_fullconsole:
C_FullConsole ();
gameaction = ga_nothing;
break;
case ga_togglemap:
AM_ToggleMap ();
gameaction = ga_nothing;
break;
case ga_nothing:
break;
}
C_AdjustBottom ();
}
if (oldgamestate != gamestate)
{
if (oldgamestate == GS_DEMOSCREEN && Page != NULL)
{
Page->Unload();
Page = NULL;
}
else if (oldgamestate == GS_FINALE)
{
F_EndFinale ();
}
}
// get commands, check consistancy, and build new consistancy check
int buf = (gametic/ticdup)%BACKUPTICS;
// [RH] Include some random seeds and player stuff in the consistancy
// check, not just the player's x position like BOOM.
DWORD rngsum = FRandom::StaticSumSeeds ();
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
{
ticcmd_t *cmd = &players[i].cmd;
ticcmd_t *newcmd = &netcmds[i][buf];
if ((gametic % ticdup) == 0)
{
RunNetSpecs (i, buf);
}
if (demorecording)
{
G_WriteDemoTiccmd (newcmd, i, buf);
}
// If the user alt-tabbed away, paused gets set to -1. In this case,
// we do not want to read more demo commands until paused is no
// longer negative.
if (demoplayback && paused >= 0)
{
G_ReadDemoTiccmd (cmd, i);
}
else
{
memcpy (cmd, newcmd, sizeof(ticcmd_t));
}
// check for turbo cheats
if (cmd->ucmd.forwardmove > TURBOTHRESHOLD &&
!(gametic&31) && ((gametic>>5)&(MAXPLAYERS-1)) == i )
{
Printf ("%s is turbo!\n", players[i].userinfo.netname);
}
if (netgame && !players[i].isbot && !netdemo && (gametic%ticdup) == 0)
{
//players[i].inconsistant = 0;
if (gametic > BACKUPTICS*ticdup && consistancy[i][buf] != cmd->consistancy)
{
players[i].inconsistant = gametic - BACKUPTICS*ticdup;
}
if (players[i].mo)
{
DWORD sum = rngsum + players[i].mo->x + players[i].mo->y + players[i].mo->z
+ players[i].mo->angle + players[i].mo->pitch;
sum ^= players[i].health;
consistancy[i][buf] = sum;
}
else
{
consistancy[i][buf] = rngsum;
}
}
}
}
// do main actions
switch (gamestate)
{
case GS_LEVEL:
P_Ticker ();
AM_Ticker ();
break;
case GS_TITLELEVEL:
P_Ticker ();
break;
case GS_INTERMISSION:
WI_Ticker ();
break;
case GS_FINALE:
F_Ticker ();
break;
case GS_DEMOSCREEN:
D_PageTicker ();
break;
case GS_STARTUP:
if (gameaction == ga_nothing)
{
gamestate = GS_FULLCONSOLE;
gameaction = ga_fullconsole;
}
break;
default:
break;
}
}
//
// PLAYER STRUCTURE FUNCTIONS
// also see P_SpawnPlayer in P_Mobj
//
//
// G_PlayerFinishLevel
// Called when a player completes a level.
//
void G_PlayerFinishLevel (int player, EFinishLevelType mode, bool resetinventory)
{
AInventory *item, *next;
player_t *p;
p = &players[player];
// Strip all current powers, unless moving in a hub and the power is okay to keep.
item = p->mo->Inventory;
while (item != NULL)
{
next = item->Inventory;
if (item->IsKindOf (RUNTIME_CLASS(APowerup)))
{
if (deathmatch || mode != FINISH_SameHub || !(item->ItemFlags & IF_HUBPOWER))
{
item->Destroy ();
}
}
item = next;
}
if (p->ReadyWeapon != NULL &&
p->ReadyWeapon->WeaponFlags&WIF_POWERED_UP &&
p->PendingWeapon == p->ReadyWeapon->SisterWeapon)
{
// Unselect powered up weapons if the unpowered counterpart is pending
p->ReadyWeapon=p->PendingWeapon;
}
p->mo->flags &= ~MF_SHADOW; // cancel invisibility
p->mo->RenderStyle = STYLE_Normal;
p->mo->alpha = FRACUNIT;
p->extralight = 0; // cancel gun flashes
p->fixedcolormap = 0; // cancel ir goggles
p->damagecount = 0; // no palette changes
p->bonuscount = 0;
p->poisoncount = 0;
p->inventorytics = 0;
if (mode != FINISH_SameHub)
{
// Take away flight and keys (and anything else with IF_INTERHUBSTRIP set)
item = p->mo->Inventory;
while (item != NULL)
{
next = item->Inventory;
if (item->ItemFlags & IF_INTERHUBSTRIP)
{
item->Destroy ();
}
item = next;
}
}
if (mode == FINISH_NoHub && !(level.flags & LEVEL_KEEPFULLINVENTORY))
{ // Reduce all owned (visible) inventory to 1 item each
for (item = p->mo->Inventory; item != NULL; item = item->Inventory)
{
// There may be depletable items with an amount of 0.
// Those need to stay at 0; the rest get dropped to 1.
if (item->ItemFlags & IF_INVBAR && item->Amount > 1)
{
item->Amount = 1;
}
}
}
if (p->morphTics)
{ // Undo morph
- Fixed: When walking on sloped 3D-floors, P_TryMove got the floor position from the sector's actual floor instead from the 3D-floor. - Fixed: Brightmaps were not disabled when fog was defined with a fadetable command in MAPINFO. Update to ZDoom r994: - Fixed: The compatibility searches for teleport destinations did not work properly when the teleporter had both a tid and a tag. Now, if a teleporter has a tag these are skipped because they are only present for Hexen compatibility. - Fixed: The first texture in a TEXTURE1 lump, although invalid when used elsewhere, must be usable as sky (see Requiem.wad's SKY3.) - Fixed: side_t::GetLightLevel relied on the global 'linedef' variable for automatic fake contrast. - Changed: Fake contrast now uses the WALLF_AUTOCONTRAST globally instead of manipulating the sides' light values individually. This allows changing the fake contrast at run time and also allows adding individual relative lighting on top of it which is a planned UDMF feature. - Fixed: ActorStencilColor() did not set the palette part of the actor's fill color, so it would always produce black for STYLE_Shaded. - Added volume reduction for stereo sounds played in 3D to obtain levels closer to FMOD 3, which downmixed all stereo sounds to mono before playing them in 3D. Also added experimental 3D spread for stereo sounds so that you can actually hear them in stereo. - Reworked a few options that previously depended on LEVEL_HEXENFORMAT (actors being forced to the ground by instantly moving sectors, strife railing handling and shooting lines with a non-zero but unassigned tag.) With UDMF such semantics have to be handled diffently. - finalized UDMF 1.0 implementation. - Added Martin Howe's latest morph update. - Fixed: When R_DrawTiltedPlane() calculates the p vector, it can overflow if the view is near the bounds of the fixed point coordinate system. This happens because it rotates the view position around (0,0) according to the current viewangle, so the resultant coordinate may be outside the bounds of fixed point. All important math in this function is now done entirely in floating point. - Fixed: Slopes didn't draw right on 64-bit platforms. - Fixed: With hardware 2D, the console and menu need not reimplement palette flashes to ensure their visibility. - Fixed: DFlashFader::Destroy() did not call its super method. - Fixed: If a player was morphed into a class with a taller view height, their perceived view height would not change until they walked up a step. - Since KDIZD is the only mapset I know of that used reverb, and it didn't define any new ones of its own, I'm pre-emptively renaming the SNDEAX lump to REVERBS to remove any possible misunderstanding that this is something that requires EAX hardware support. (Ideally, it would have been REVERBDEF, but that's 10 characters long.) The eaxedit console command has also been renamed to reverbedit for the same reason. - Fixed: The Palette part of FRemapTable was not initialized with alpha values other than 0. I'm not sure if it would be better to fix this in the game palette that it copies from or not, but right now, they get set unconditionally to 255. - Fixed: M_DrawSave() and M_DrawLoad() need to use GetScaledWidth(), in case the texture is high-res. - Replaced all instances of "flags +=" in sbarinfo_parser.cpp with "flags |=" so that using the same flag multiple times will not have unexpected results. (sbarinfo update #21) - Added: sigil image type to correctly draw the sigil's icon. - Added: Strife inventory bar style. This is the only style that is radically different from the others. First of all it changes the SELECTBO to be INVCURS and draws it before the icons. Each box is changed to have a width of 35 pixels instead of 31 pixels. And the INVCURS graphic is drawn at (x-6, y-2). - Added: whennnotzero flag to drawnumber which will cause it to draw nothing if the value is 0. - Fixed: New mugshot code would not leave the god state when it was supposed to enter the rampage state. - Fixed: The ouch state was mostly broken. (SBarInfo Update #20) - Added: hasweaponpiece command to check for custom weapon pieces. - Added: usessecondaryammo command to check if the current weapon has a second ammo type. - Most of SBarInfo's mugshot scripting can be used with the default Doom status bar. - Fixed: By default drawmugshot would never come out of normal god mode state. In addition the state change to and from god mode was not quite as responsive as the original code. - Fixed: When FTextureManager::CheckForTexture finds a matching NULL texture it should always return 0, not the actual texture's index. - Fixed coordinate checks for objects on 3DMidtex lines. - Fixed: All translucent blending operations for CopyColors must treat an alpha of 0 so that the pixel is not modified or texture composition as intended will not work. - Fixed: 3D hardware texture filling did not copy pixels with 0 alpha, preserving whatever was underneath in the texture box previously. - Fixed: s_sound.cpp had its own idea of whether or not sounds were paused and did not entirely keep it in sync with the sound system's. This meant that when starting a new game from the menu, all sounds were played as menu sounds until you did something to pause the game, because s_sound.cpp thought sounds were unpaused, while the FMOD system thought they were. - I finally managed to test the translucency options for composite texture definitions in HIRESTEX. The feature should be complete now. - Fixed: A_CheckTargetInLOS used BAM angles instead of degrees which is the DECORATE convention. - Added Snowkate709's A_CheckTargetInLOS addition. - Added listmaps CCMD. - Revised underwater effect now uses a lowpass filter in combination with an optional freeverb unit. - Removed ResetEnvironment hack, since with software reverb, losing the existing reverb when focus is lost isn't a problem. - Commented out the TiMidity FIXME messages. - Fixed: FBarShader::GetColumn() passed incorrect information to the software renderer for horizontal bars. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@107 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-23 17:58:17 +00:00
P_UndoPlayerMorph (p, p, true);
}
// Clears the entire inventory and gives back the defaults for starting a game
if (resetinventory)
{
AInventory *inv = p->mo->Inventory;
while (inv != NULL)
{
AInventory *next = inv->Inventory;
if (!(inv->ItemFlags & IF_UNDROPPABLE))
{
inv->Destroy ();
}
else if (inv->GetClass() == RUNTIME_CLASS(AHexenArmor))
{
AHexenArmor *harmor = static_cast<AHexenArmor *> (inv);
harmor->Slots[3] = harmor->Slots[2] = harmor->Slots[1] = harmor->Slots[0] = 0;
}
inv = next;
}
p->ReadyWeapon = NULL;
p->PendingWeapon = WP_NOCHANGE;
p->psprites[ps_weapon].state = NULL;
p->psprites[ps_flash].state = NULL;
p->mo->GiveDefaultInventory();
}
}
//
// G_PlayerReborn
// Called after a player dies
// almost everything is cleared and initialized
//
void G_PlayerReborn (int player)
{
player_t* p;
int frags[MAXPLAYERS];
int fragcount; // [RH] Cumulative frags
int killcount;
int itemcount;
int secretcount;
int chasecam;
BYTE currclass;
userinfo_t userinfo; // [RH] Save userinfo
botskill_t b_skill;//Added by MC:
APlayerPawn *actor;
const PClass *cls;
FString log;
p = &players[player];
memcpy (frags, p->frags, sizeof(frags));
fragcount = p->fragcount;
killcount = p->killcount;
itemcount = p->itemcount;
secretcount = p->secretcount;
currclass = p->CurrentPlayerClass;
b_skill = p->skill; //Added by MC:
memcpy (&userinfo, &p->userinfo, sizeof(userinfo));
actor = p->mo;
cls = p->cls;
log = p->LogText;
chasecam = p->cheats & CF_CHASECAM;
// Reset player structure to its defaults
p->~player_t();
::new(p) player_t;
memcpy (p->frags, frags, sizeof(p->frags));
p->fragcount = fragcount;
p->killcount = killcount;
p->itemcount = itemcount;
p->secretcount = secretcount;
p->CurrentPlayerClass = currclass;
memcpy (&p->userinfo, &userinfo, sizeof(userinfo));
p->mo = actor;
p->cls = cls;
p->LogText = log;
p->cheats |= chasecam;
p->skill = b_skill; //Added by MC:
p->oldbuttons = 255, p->attackdown = true; // don't do anything immediately
p->playerstate = PST_LIVE;
if (gamestate != GS_TITLELEVEL)
{
actor->GiveDefaultInventory ();
p->ReadyWeapon = p->PendingWeapon;
}
//Added by MC: Init bot structure.
if (bglobal.botingame[player])
bglobal.CleanBotstuff (p);
else
p->isbot = false;
}
//
// G_CheckSpot
// Returns false if the player cannot be respawned
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
// at the given mapthing spot
// because something is occupying it
//
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
bool G_CheckSpot (int playernum, FMapThing *mthing)
{
fixed_t x;
fixed_t y;
fixed_t z, oldz;
int i;
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
x = mthing->x;
y = mthing->y;
z = mthing->z;
z += P_PointInSector (x, y)->floorplane.ZatPoint (x, y);
if (!players[playernum].mo)
{ // first spawn of level, before corpses
for (i = 0; i < playernum; i++)
if (players[i].mo && players[i].mo->x == x && players[i].mo->y == y)
return false;
return true;
}
oldz = players[playernum].mo->z; // [RH] Need to save corpse's z-height
players[playernum].mo->z = z; // [RH] Checks are now full 3-D
// killough 4/2/98: fix bug where P_CheckPosition() uses a non-solid
// corpse to detect collisions with other players in DM starts
//
// Old code:
// if (!P_CheckPosition (players[playernum].mo, x, y))
// return false;
players[playernum].mo->flags |= MF_SOLID;
i = P_CheckPosition(players[playernum].mo, x, y);
players[playernum].mo->flags &= ~MF_SOLID;
players[playernum].mo->z = oldz; // [RH] Restore corpse's height
if (!i)
return false;
return true;
}
//
// G_DeathMatchSpawnPlayer
// Spawns a player at one of the random death match spots
// called at level load and each death
//
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
// [RH] Returns the distance of the closest player to the given mapthing
static fixed_t PlayersRangeFromSpot (FMapThing *spot)
{
fixed_t closest = INT_MAX;
fixed_t distance;
int i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || !players[i].mo || players[i].health <= 0)
continue;
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
distance = P_AproxDistance (players[i].mo->x - spot->x,
players[i].mo->y - spot->y);
if (distance < closest)
closest = distance;
}
return closest;
}
// [RH] Select the deathmatch spawn spot farthest from everyone.
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
static FMapThing *SelectFarthestDeathmatchSpot (size_t selections)
{
fixed_t bestdistance = 0;
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
FMapThing *bestspot = NULL;
unsigned int i;
for (i = 0; i < selections; i++)
{
fixed_t distance = PlayersRangeFromSpot (&deathmatchstarts[i]);
if (distance > bestdistance)
{
bestdistance = distance;
bestspot = &deathmatchstarts[i];
}
}
return bestspot;
}
// [RH] Select a deathmatch spawn spot at random (original mechanism)
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
static FMapThing *SelectRandomDeathmatchSpot (int playernum, unsigned int selections)
{
unsigned int i, j;
for (j = 0; j < 20; j++)
{
i = pr_dmspawn() % selections;
if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
{
return &deathmatchstarts[i];
}
}
// [RH] return a spot anyway, since we allow telefragging when a player spawns
return &deathmatchstarts[i];
}
void G_DeathMatchSpawnPlayer (int playernum)
{
unsigned int selections;
- Fixed: The hitscan tracer had the current sector point to a temporary variable when 3D floors were involved. Update to ZDoom r965: - Fixed: SPAC_AnyCross didn't work. - Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Changed: HIRESTEX 'define' textures now replace existing textures of type MiscPatch with the same name. - Added UDMF line trigger types MonsterUse and MonsterPush. - Separated skill and class filter bits from FMapThing::flags so that UDMF can define up to 16 of each. Also separated easy/baby and hard/nightmare and changed default MAPINFO definitions. - Fixed: FWadCollection::MergeLumps() did not initialize the flags for any marker lumps it inserted. - Fixed: Need write barriers when modifying SequenceListHead. - Added a new cvar: midi_timiditylike. This re-enables TiMidity handling of GUS patch flags, envelopes, and volume levels, while trying to be closer to TiMidity++ than original TiMidity. - Renamed timidity_config and timidity_voices to midi_config and midi_voices respectively. - Changed: Crosshair drawing uses the current player class's default health instead of 100 to calculate the color for the crosshair. - Added SECF_NOFALLINGDAMAGE flag plus Sector_ChangeFlags to set it. Also separated all user settable flags from MoreFlags into their own Flags variable. - Reduced volume, expression, and panning controllers back to 7 bits. - Added very basic Soundfont support to the internal TiMidity. Things missing: filter, LFOs, modulation envelope, chorus, reverb, and modulators. May or may not be compatible with TiMidity++'s soundfont extensions. - Changed all thing coordinates that were stored as shorts into fixed_t. - Separated mapthing2_t into mapthinghexen_t and the internal FMapThing so that it is easier to add new features in the UDMF map format. - Added some initial code to read UDMF maps. - Added support for quoted strings to the TiMidity config parser. - Split off the slope creation code from p_Setup.cpp into its own file. - Separated the linedef activation types into a bit mask that allows combination of all types on the same linedef. Also added a 'first side only' flag. This is not usable from Hexen or Doom format maps though but in preparation of the UDMF format discussed here: http://www.doomworld.com/vb/source-ports/43145-udmf-v0-99-specification-draft-aka-textmap/ - Changed linedef's alpha property from a byte to fixed point after seeing that 255 wasn't handled to be fully opaque. - fixed a GCC warning in fmodsound.cpp - Fixed: Warped textures didn't work anymore because the default speed was 0. - Fixed: I had instrument vibrato setting the tremolo_sweep_increment value in the instrument loader, effectively disabling vibrato. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@103 b0f79afe-0144-0410-b225-9a4edf0717df
2008-05-12 09:58:47 +00:00
FMapThing *spot;
selections = deathmatchstarts.Size ();
// [RH] We can get by with just 1 deathmatch start
if (selections < 1)
I_Error ("No deathmatch starts");
// At level start, none of the players have mobjs attached to them,
// so we always use the random deathmatch spawn. During the game,
// though, we use whatever dmflags specifies.
if ((dmflags & DF_SPAWN_FARTHEST) && players[playernum].mo)
spot = SelectFarthestDeathmatchSpot (selections);
else
spot = SelectRandomDeathmatchSpot (playernum, selections);
if (!spot)
{ // no good spot, so the player will probably get stuck
spot = &playerstarts[playernum];
}
else
{
if (playernum < 4)
spot->type = playernum+1;
else if (gameinfo.gametype != GAME_Hexen)
spot->type = playernum+4001-4; // [RH] > 4 players
else
spot->type = playernum+9100-4;
}
Update to ZDoom r1052: - Fixed: Dead players didn't get the MF_CORPSE flag set. - Fixed: The internal definition of Floor_LowerToNearest had incorrect parameter settings. - Fixed: Heretic's ActivatedTimeBomb had the same spawn ID as the inventory item. - fixed: Heretic's mace did not have its spawn ID set. - For controls that are not bound, the customize controls menu now displays a black --- instead of ???. - Applied Gez's BossBrainPatch3. - Fixed: P_BulletSlope() did not return the linetarget. This effected the Sigil, A_JumpIfCloser, and A_JumpIfTargetInLOS. - Fixed all the new warnings tossed out by GCC 4.3. - Fixed: PickNext/PrevWeapon() did not check for NULL player actors. - Fixed compilation issues with GCC. - Removed special case for nobotnodes in MAPINFO. - Added support for ST's QUARTERGRAVITY flag. - Added a generalized version of Skulltag's A_CheckRailReload function. - Fixed: DrawImage didn't take 0 as a valid image index. - Added Gez's RandomSpawner submission with significant changes. - Added optional blocks for MAPINFO map definitions. ZDoom doesn't use this feature itself but it allows other ports based on ZDoom to implement their own sets of options without making such a MAPINFO unreadable by ZDoom. - Fixed: The mugshot would not reset on re-spawn. - Fixed: Picking up a weapon would sometimes not activate the grin. - Changed: Line_SetIdentification will ignore extended parameters when used in maps defined Hexen style in MAPINFO. - Fixed: Ambient sounds didn't pass their point of origin to S_StartSound. - Fixed: UseType was not properly set for textures defined in TEXTURES. - Fixed: You couldn't set an offset for sprites defined in TEXTURES. - Added read barriers to all actor pointers within player_t except for mo, ReadyWeapon and PendingWeapon. - Added a read barrier to player_t::PrewmorphWeapon. - Fixed: After spawning a deathmatch player P_PlayerStartStomp must be called. - Fixed: SpawnThings must check if the players were spawned before calling P_PlayerStartStomp. - Fixed typo in flat scroll interpolation. - Changed FImageCollection to return translated texture indices so that animated icons can be done with it. - Changed FImageCollection to use a TArray to hold its data. - Fixed: SetChanHeadSettings did an assignment instead of comparing the channel ID witg CHAN_CEILING. - Changed sound sequence names for animated doors to FNames. - Automatically fixed: DCeiling didn't properly serialize its texture id. - Replaced integers as texture ID representation with a specific new type to track down all potentially incorrect uses and remaining WORDs used for texture IDs so that more than 32767 or 65535 textures can be defined. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@124 b0f79afe-0144-0410-b225-9a4edf0717df
2008-06-28 13:29:59 +00:00
AActor *mo = P_SpawnPlayer (spot);
if (mo != NULL) P_PlayerStartStomp(mo);
}
//
// G_QueueBody
//
static void G_QueueBody (AActor *body)
{
// flush an old corpse if needed
int modslot = bodyqueslot%BODYQUESIZE;
if (bodyqueslot >= BODYQUESIZE && bodyque[modslot] != NULL)
{
bodyque[modslot]->Destroy ();
}
bodyque[modslot] = body;
// Copy the player's translation, so that if they change their color later, only
// their current body will change and not all their old corpses.
if (GetTranslationType(body->Translation) == TRANSLATION_Players ||
GetTranslationType(body->Translation) == TRANSLATION_PlayersExtra)
{
*translationtables[TRANSLATION_PlayerCorpses][modslot] = *TranslationToTable(body->Translation);
body->Translation = TRANSLATION(TRANSLATION_PlayerCorpses,modslot);
}
bodyqueslot++;
}
//
// G_DoReborn
//
void G_DoReborn (int playernum, bool freshbot)
{
if (!multiplayer && !(level.flags & LEVEL_ALLOWRESPAWN))
{
if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars()))
{ // Load game from the last point it was saved
savename = BackupSaveName;
gameaction = ga_loadgame;
}
else
{ // Reload the level from scratch
bool indemo = demoplayback;
BackupSaveName = "";
G_InitNew (level.mapname, false);
demoplayback = indemo;
// gameaction = ga_loadlevel;
}
}
else
{
// respawn at the start
int i;
// first disassociate the corpse
if (players[playernum].mo)
{
G_QueueBody (players[playernum].mo);
players[playernum].mo->player = NULL;
}
// spawn at random spot if in death match
if (deathmatch)
{
G_DeathMatchSpawnPlayer (playernum);
return;
}
if (G_CheckSpot (playernum, &playerstarts[playernum]) )
{
Update to ZDoom r1052: - Fixed: Dead players didn't get the MF_CORPSE flag set. - Fixed: The internal definition of Floor_LowerToNearest had incorrect parameter settings. - Fixed: Heretic's ActivatedTimeBomb had the same spawn ID as the inventory item. - fixed: Heretic's mace did not have its spawn ID set. - For controls that are not bound, the customize controls menu now displays a black --- instead of ???. - Applied Gez's BossBrainPatch3. - Fixed: P_BulletSlope() did not return the linetarget. This effected the Sigil, A_JumpIfCloser, and A_JumpIfTargetInLOS. - Fixed all the new warnings tossed out by GCC 4.3. - Fixed: PickNext/PrevWeapon() did not check for NULL player actors. - Fixed compilation issues with GCC. - Removed special case for nobotnodes in MAPINFO. - Added support for ST's QUARTERGRAVITY flag. - Added a generalized version of Skulltag's A_CheckRailReload function. - Fixed: DrawImage didn't take 0 as a valid image index. - Added Gez's RandomSpawner submission with significant changes. - Added optional blocks for MAPINFO map definitions. ZDoom doesn't use this feature itself but it allows other ports based on ZDoom to implement their own sets of options without making such a MAPINFO unreadable by ZDoom. - Fixed: The mugshot would not reset on re-spawn. - Fixed: Picking up a weapon would sometimes not activate the grin. - Changed: Line_SetIdentification will ignore extended parameters when used in maps defined Hexen style in MAPINFO. - Fixed: Ambient sounds didn't pass their point of origin to S_StartSound. - Fixed: UseType was not properly set for textures defined in TEXTURES. - Fixed: You couldn't set an offset for sprites defined in TEXTURES. - Added read barriers to all actor pointers within player_t except for mo, ReadyWeapon and PendingWeapon. - Added a read barrier to player_t::PrewmorphWeapon. - Fixed: After spawning a deathmatch player P_PlayerStartStomp must be called. - Fixed: SpawnThings must check if the players were spawned before calling P_PlayerStartStomp. - Fixed typo in flat scroll interpolation. - Changed FImageCollection to return translated texture indices so that animated icons can be done with it. - Changed FImageCollection to use a TArray to hold its data. - Fixed: SetChanHeadSettings did an assignment instead of comparing the channel ID witg CHAN_CEILING. - Changed sound sequence names for animated doors to FNames. - Automatically fixed: DCeiling didn't properly serialize its texture id. - Replaced integers as texture ID representation with a specific new type to track down all potentially incorrect uses and remaining WORDs used for texture IDs so that more than 32767 or 65535 textures can be defined. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@124 b0f79afe-0144-0410-b225-9a4edf0717df
2008-06-28 13:29:59 +00:00
AActor *mo = P_SpawnPlayer (&playerstarts[playernum]);
if (mo != NULL) P_PlayerStartStomp(mo);
}
else
{
// try to spawn at one of the other players' spots
for (i = 0; i < MAXPLAYERS; i++)
{
if (G_CheckSpot (playernum, &playerstarts[i]) )
{
int oldtype = playerstarts[i].type;
// fake as other player
// [RH] These numbers should be common across all games. Or better yet, not
// used at all outside P_SpawnMapThing().
if (playernum < 4 || gameinfo.gametype == GAME_Strife)
{
playerstarts[i].type = playernum + 1;
}
else if (gameinfo.gametype == GAME_Hexen)
{
playerstarts[i].type = playernum + 9100 - 4;
}
else
{
playerstarts[i].type = playernum + 4001 - 4;
}
Update to ZDoom r1052: - Fixed: Dead players didn't get the MF_CORPSE flag set. - Fixed: The internal definition of Floor_LowerToNearest had incorrect parameter settings. - Fixed: Heretic's ActivatedTimeBomb had the same spawn ID as the inventory item. - fixed: Heretic's mace did not have its spawn ID set. - For controls that are not bound, the customize controls menu now displays a black --- instead of ???. - Applied Gez's BossBrainPatch3. - Fixed: P_BulletSlope() did not return the linetarget. This effected the Sigil, A_JumpIfCloser, and A_JumpIfTargetInLOS. - Fixed all the new warnings tossed out by GCC 4.3. - Fixed: PickNext/PrevWeapon() did not check for NULL player actors. - Fixed compilation issues with GCC. - Removed special case for nobotnodes in MAPINFO. - Added support for ST's QUARTERGRAVITY flag. - Added a generalized version of Skulltag's A_CheckRailReload function. - Fixed: DrawImage didn't take 0 as a valid image index. - Added Gez's RandomSpawner submission with significant changes. - Added optional blocks for MAPINFO map definitions. ZDoom doesn't use this feature itself but it allows other ports based on ZDoom to implement their own sets of options without making such a MAPINFO unreadable by ZDoom. - Fixed: The mugshot would not reset on re-spawn. - Fixed: Picking up a weapon would sometimes not activate the grin. - Changed: Line_SetIdentification will ignore extended parameters when used in maps defined Hexen style in MAPINFO. - Fixed: Ambient sounds didn't pass their point of origin to S_StartSound. - Fixed: UseType was not properly set for textures defined in TEXTURES. - Fixed: You couldn't set an offset for sprites defined in TEXTURES. - Added read barriers to all actor pointers within player_t except for mo, ReadyWeapon and PendingWeapon. - Added a read barrier to player_t::PrewmorphWeapon. - Fixed: After spawning a deathmatch player P_PlayerStartStomp must be called. - Fixed: SpawnThings must check if the players were spawned before calling P_PlayerStartStomp. - Fixed typo in flat scroll interpolation. - Changed FImageCollection to return translated texture indices so that animated icons can be done with it. - Changed FImageCollection to use a TArray to hold its data. - Fixed: SetChanHeadSettings did an assignment instead of comparing the channel ID witg CHAN_CEILING. - Changed sound sequence names for animated doors to FNames. - Automatically fixed: DCeiling didn't properly serialize its texture id. - Replaced integers as texture ID representation with a specific new type to track down all potentially incorrect uses and remaining WORDs used for texture IDs so that more than 32767 or 65535 textures can be defined. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@124 b0f79afe-0144-0410-b225-9a4edf0717df
2008-06-28 13:29:59 +00:00
AActor *mo = P_SpawnPlayer (&playerstarts[i]);
if (mo != NULL) P_PlayerStartStomp(mo);
playerstarts[i].type = oldtype; // restore
return;
}
// he's going to be inside something. Too bad.
}
Update to ZDoom r1052: - Fixed: Dead players didn't get the MF_CORPSE flag set. - Fixed: The internal definition of Floor_LowerToNearest had incorrect parameter settings. - Fixed: Heretic's ActivatedTimeBomb had the same spawn ID as the inventory item. - fixed: Heretic's mace did not have its spawn ID set. - For controls that are not bound, the customize controls menu now displays a black --- instead of ???. - Applied Gez's BossBrainPatch3. - Fixed: P_BulletSlope() did not return the linetarget. This effected the Sigil, A_JumpIfCloser, and A_JumpIfTargetInLOS. - Fixed all the new warnings tossed out by GCC 4.3. - Fixed: PickNext/PrevWeapon() did not check for NULL player actors. - Fixed compilation issues with GCC. - Removed special case for nobotnodes in MAPINFO. - Added support for ST's QUARTERGRAVITY flag. - Added a generalized version of Skulltag's A_CheckRailReload function. - Fixed: DrawImage didn't take 0 as a valid image index. - Added Gez's RandomSpawner submission with significant changes. - Added optional blocks for MAPINFO map definitions. ZDoom doesn't use this feature itself but it allows other ports based on ZDoom to implement their own sets of options without making such a MAPINFO unreadable by ZDoom. - Fixed: The mugshot would not reset on re-spawn. - Fixed: Picking up a weapon would sometimes not activate the grin. - Changed: Line_SetIdentification will ignore extended parameters when used in maps defined Hexen style in MAPINFO. - Fixed: Ambient sounds didn't pass their point of origin to S_StartSound. - Fixed: UseType was not properly set for textures defined in TEXTURES. - Fixed: You couldn't set an offset for sprites defined in TEXTURES. - Added read barriers to all actor pointers within player_t except for mo, ReadyWeapon and PendingWeapon. - Added a read barrier to player_t::PrewmorphWeapon. - Fixed: After spawning a deathmatch player P_PlayerStartStomp must be called. - Fixed: SpawnThings must check if the players were spawned before calling P_PlayerStartStomp. - Fixed typo in flat scroll interpolation. - Changed FImageCollection to return translated texture indices so that animated icons can be done with it. - Changed FImageCollection to use a TArray to hold its data. - Fixed: SetChanHeadSettings did an assignment instead of comparing the channel ID witg CHAN_CEILING. - Changed sound sequence names for animated doors to FNames. - Automatically fixed: DCeiling didn't properly serialize its texture id. - Replaced integers as texture ID representation with a specific new type to track down all potentially incorrect uses and remaining WORDs used for texture IDs so that more than 32767 or 65535 textures can be defined. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@124 b0f79afe-0144-0410-b225-9a4edf0717df
2008-06-28 13:29:59 +00:00
AActor *mo = P_SpawnPlayer (&playerstarts[playernum]);
if (mo != NULL) P_PlayerStartStomp(mo);
}
}
}
void G_ScreenShot (char *filename)
{
shotfile = filename;
gameaction = ga_screenshot;
}
//
// G_InitFromSavegame
// Can be called by the startup code or the menu task.
//
void G_LoadGame (const char* name)
{
if (name != NULL)
{
savename = name;
gameaction = ga_loadgame;
}
}
static bool CheckSingleWad (char *name, bool &printRequires, bool printwarn)
{
if (name == NULL)
{
return true;
}
if (Wads.CheckIfWadLoaded (name) < 0)
{
if (printwarn)
{
if (!printRequires)
{
Printf ("This savegame needs these wads:\n%s", name);
}
else
{
Printf (", %s", name);
}
}
printRequires = true;
delete[] name;
return false;
}
delete[] name;
return true;
}
// Return false if not all the needed wads have been loaded.
bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
{
char *text;
bool printRequires = false;
text = M_GetPNGText (png, "Game WAD");
CheckSingleWad (text, printRequires, printwarn);
text = M_GetPNGText (png, "Map WAD");
CheckSingleWad (text, printRequires, printwarn);
if (printRequires)
{
if (printwarn)
{
Printf ("\n");
}
return false;
}
return true;
}
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
void G_DoLoadGame ()
{
char sigcheck[20];
char *text = NULL;
char *map;
gameaction = ga_nothing;
demoplayback = false;
FILE *stdfile = fopen (savename.GetChars(), "rb");
if (stdfile == NULL)
{
Printf ("Could not read savegame '%s'\n", savename.GetChars());
return;
}
PNGHandle *png = M_VerifyPNG (stdfile);
if (png == NULL)
{
fclose (stdfile);
Printf ("'%s' is not a valid (PNG) savegame\n", savename.GetChars());
return;
}
SaveVersion = 0;
// Check whether this savegame actually has been created by a compatible engine.
// Since there are ZDoom derivates using the exact same savegame format but
// with mutual incompatibilities this check simplifies things significantly.
char *engine = M_GetPNGText (png, "Engine");
if (engine == NULL || 0 != strcmp (engine, GAMESIG))
{
// Make a special case for the message printed for old savegames that don't
// have this information.
if (engine == NULL)
{
Printf ("Savegame is from an incompatible version\n");
}
else
{
Printf ("Savegame is from another ZDoom-based engine: %s\n", engine);
delete[] engine;
}
delete png;
fclose (stdfile);
return;
}
if (engine != NULL)
{
delete[] engine;
}
if (!M_GetPNGText (png, "ZDoom Save Version", sigcheck, 20) ||
0 != strncmp (sigcheck, SAVESIG, 9) || // ZDOOMSAVE is the first 9 chars
(SaveVersion = atoi (sigcheck+9)) < MINSAVEVER)
{
Printf ("Savegame is from an incompatible version\n");
delete png;
fclose (stdfile);
return;
}
if (!G_CheckSaveGameWads (png, true))
{
fclose (stdfile);
return;
}
map = M_GetPNGText (png, "Current Map");
if (map == NULL)
{
Printf ("Savegame is missing the current map\n");
fclose (stdfile);
return;
}
// Read intermission data for hubs
G_ReadHubInfo(png);
bglobal.RemoveAllBots (true);
text = M_GetPNGText (png, "Important CVARs");
if (text != NULL)
{
BYTE *vars_p = (BYTE *)text;
C_ReadCVars (&vars_p);
delete[] text;
}
// dearchive all the modifications
if (M_FindPNGChunk (png, MAKE_ID('p','t','I','c')) == 8)
{
DWORD time[2];
fread (&time, 8, 1, stdfile);
time[0] = BigLong((unsigned int)time[0]);
time[1] = BigLong((unsigned int)time[1]);
level.time = Scale (time[1], TICRATE, time[0]);
}
else
{ // No ptIc chunk so we don't know how long the user was playing
level.time = 0;
}
G_ReadSnapshots (png);
FRandom::StaticReadRNGState (png);
P_ReadACSDefereds (png);
// load a base level
savegamerestore = true; // Use the player actors in the savegame
bool demoplaybacksave = demoplayback;
G_InitNew (map, false);
demoplayback = demoplaybacksave;
delete[] map;
savegamerestore = false;
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
NextSkill = -1;
if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1)
{
BYTE next;
fread (&next, 1, 1, stdfile);
NextSkill = next;
}
if (level.info->snapshot != NULL)
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
BackupSaveName = savename;
delete png;
fclose (stdfile);
// At this point, the GC threshold is likely a lot higher than the
// amount of memory in use, so bring it down now by starting a
// collection.
GC::StartCollection();
}
//
// G_SaveGame
// Called by the menu task.
// Description is a 24 byte text string
//
void G_SaveGame (const char *filename, const char *description)
{
if (sendsave || gameaction == ga_savegame)
{
Printf ("A game save is still pending.\n");
return;
}
savegamefile = filename;
strncpy (savedescription, description, sizeof(savedescription)-1);
savedescription[sizeof(savedescription)-1] = '\0';
sendsave = true;
}
FString G_BuildSaveName (const char *prefix, int slot)
{
FString name;
const char *leader;
const char *slash = "";
if (NULL != (leader = Args->CheckValue ("-savedir")))
{
size_t len = strlen (leader);
if (leader[len-1] != '\\' && leader[len-1] != '/')
{
slash = "/";
}
}
#ifndef unix
else if (Args->CheckParm ("-cdrom"))
{
leader = CDROM_DIR "/";
}
else
{
leader = progdir;
}
#else
else
{
leader = "";
}
#endif
if (slot < 0)
{
name.Format ("%s%s%s", leader, slash, prefix);
}
else
{
name.Format ("%s%s%s%d.zds", leader, slash, prefix, slot);
}
#ifdef unix
if (leader[0] == 0)
{
name = GetUserFile (name);
}
#endif
return name;
}
CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Int, disableautosave, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Int, autosavecount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
if (self < 0)
self = 0;
if (self > 20)
self = 20;
}
extern void P_CalcHeight (player_t *);
void G_DoAutoSave ()
{
char description[SAVESTRINGSIZE];
FString file;
// Keep up to four autosaves at a time
UCVarValue num;
const char *readableTime;
int count = autosavecount != 0 ? autosavecount : 1;
num.Int = (autosavenum + 1) % count;
autosavenum.ForceSet (num, CVAR_Int);
file = G_BuildSaveName ("auto", num.Int);
readableTime = myasctime ();
strcpy (description, "Autosave ");
strncpy (description+9, readableTime+4, 12);
description[9+12] = 0;
G_DoSaveGame (false, file, description);
}
static void PutSaveWads (FILE *file)
{
const char *name;
// Name of IWAD
name = Wads.GetWadName (FWadCollection::IWAD_FILENUM);
M_AppendPNGText (file, "Game WAD", name);
// Name of wad the map resides in
if (Wads.GetLumpFile (level.lumpnum) > 1)
{
name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum));
M_AppendPNGText (file, "Map WAD", name);
}
}
static void PutSaveComment (FILE *file)
{
char comment[256];
const char *readableTime;
WORD len;
int levelTime;
// Get the current date and time
readableTime = myasctime ();
strncpy (comment, readableTime, 10);
strncpy (comment+10, readableTime+19, 5);
strncpy (comment+15, readableTime+10, 9);
comment[24] = 0;
M_AppendPNGText (file, "Creation Time", comment);
// Get level name
//strcpy (comment, level.level_name);
sprintf(comment, "%s - %s", level.mapname, level.level_name);
len = (WORD)strlen (comment);
comment[len] = '\n';
// Append elapsed time
levelTime = level.time / TICRATE;
sprintf (comment+len+1, "time: %02d:%02d:%02d",
levelTime/3600, (levelTime%3600)/60, levelTime%60);
comment[len+16] = 0;
// Write out the comment
M_AppendPNGText (file, "Comment", comment);
}
static void PutSavePic (FILE *file, int width, int height)
{
if (width <= 0 || height <= 0 || !storesavepic)
{
M_CreateDummyPNG (file);
}
else
{
P_CheckPlayerSprites();
screen->WriteSavePic(&players[consoleplayer], file, width, height);
}
}
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description)
{
Update to ZDoom r1069: - Added a check to G_DoSaveGame() to prevent saving when you're not actually in a level. - Fixed: Serialized player data must always be loaded, even if it's simply to be discarded, so that anything serialized after the players will load from the correct position in the file when revisiting a hub map. - Changed: AInventory::Tick now only calls the super method if the item is not owned. Having owned inventory items interact with the world is not supposed to happen. - Fixed: case PCD_SECTORDAMAGE in p_acs.cpp was missing a terminating 'break'. - Fixed: When a weapon is destroyed, its sister weapon must also be destroyed. - Added a check for PUFFGETSOWNER to A_BFGSpray. - Moved the PUFFGETSOWNER check into P_SpawnPuff and removed the limitation to players only. - Fixed: P_SpawnMapThing still checked FMapThing::flags for the class bits instead of FMapThing::ClassFilter. - Fixed: A_CustomMissile must not let P_SpawnMissile call P_CheckMissileSpawn. It must do this itself after setting the proper owner. - Fixed: CCMD(give) increased the total item count. - Fixed: A_Stop didn't set the player specific variables to 0. - Fixed: Screenwipes now pause sounds, since there can be sounds playing during them. - UI sounds are now omitted from savegames. - Fixed: Menu sounds had been restricted to one at a time again. - Moved the P_SerializeSounds() call to the end of G_SerializeLevel() so that it will occur after the players are loaded. - Added fixes from FreeBSD for 0-length and very large string buffers passed to myvsnprintf. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@131 b0f79afe-0144-0410-b225-9a4edf0717df
2008-07-06 17:32:31 +00:00
// Do not even try, if we're not in a level. (Can happen after
// a demo finishes playback.)
if (lines == NULL || sectors == NULL)
{
return;
}
if (demoplayback)
{
filename = G_BuildSaveName ("demosave.zds", -1);
}
insave = true;
G_SnapshotLevel ();
FILE *stdfile = fopen (filename.GetChars(), "wb");
if (stdfile == NULL)
{
Printf ("Could not create savegame '%s'\n", filename.GetChars());
insave = false;
return;
}
SaveVersion = SAVEVER;
PutSavePic (stdfile, SAVEPICWIDTH, SAVEPICHEIGHT);
M_AppendPNGText (stdfile, "Software", "ZDoom " DOTVERSIONSTR);
M_AppendPNGText (stdfile, "Engine", GAMESIG);
M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG);
M_AppendPNGText (stdfile, "Title", description);
M_AppendPNGText (stdfile, "Current Map", level.mapname);
PutSaveWads (stdfile);
PutSaveComment (stdfile);
// Intermission stats for hubs
G_WriteHubInfo(stdfile);
{
BYTE vars[4096], *vars_p;
vars_p = vars;
C_WriteCVars (&vars_p, CVAR_SERVERINFO);
*vars_p = 0;
M_AppendPNGText (stdfile, "Important CVARs", (char *)vars);
}
if (level.time != 0 || level.maptime != 0)
{
DWORD time[2] = { BigLong(TICRATE), BigLong(level.time) };
M_AppendPNGChunk (stdfile, MAKE_ID('p','t','I','c'), (BYTE *)&time, 8);
}
G_WriteSnapshots (stdfile);
FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile);
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
if (NextSkill != -1)
{
BYTE next = NextSkill;
M_AppendPNGChunk (stdfile, MAKE_ID('s','n','X','t'), &next, 1);
}
M_NotifyNewSave (filename.GetChars(), description, okForQuicksave);
M_FinishPNG (stdfile);
fclose (stdfile);
// Check whether the file is ok.
bool success = false;
stdfile = fopen (filename.GetChars(), "rb");
if (stdfile != NULL)
{
PNGHandle *pngh = M_VerifyPNG(stdfile);
if (pngh != NULL)
{
success = true;
delete pngh;
}
fclose(stdfile);
}
if (success)
{
if (longsavemessages) Printf ("%s (%s)\n", GStrings("GGSAVED"), filename.GetChars());
else Printf ("%s\n", GStrings("GGSAVED"));
}
else Printf(PRINT_HIGH, "Save failed\n");
BackupSaveName = filename;
// We don't need the snapshot any longer.
if (level.info->snapshot != NULL)
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
insave = false;
}
//
// DEMO RECORDING
//
void G_ReadDemoTiccmd (ticcmd_t *cmd, int player)
{
int id = DEM_BAD;
while (id != DEM_USERCMD && id != DEM_EMPTYUSERCMD)
{
if (!demorecording && demo_p >= zdembodyend)
{
// nothing left in the BODY chunk, so end playback.
G_CheckDemoStatus ();
break;
}
id = ReadByte (&demo_p);
switch (id)
{
case DEM_STOP:
// end of demo stream
G_CheckDemoStatus ();
break;
case DEM_USERCMD:
UnpackUserCmd (&cmd->ucmd, &cmd->ucmd, &demo_p);
break;
case DEM_EMPTYUSERCMD:
// leave cmd->ucmd unchanged
break;
case DEM_DROPPLAYER:
{
BYTE i = ReadByte (&demo_p);
if (i < MAXPLAYERS)
{
playeringame[i] = false;
playerswiping &= ~(1 << i);
}
}
break;
default:
Net_DoCommand (id, &demo_p, player);
break;
}
}
}
bool stoprecording;
CCMD (stop)
{
stoprecording = true;
}
extern BYTE *lenspot;
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf)
{
BYTE *specdata;
int speclen;
if (stoprecording)
{ // use "stop" console command to end demo recording
G_CheckDemoStatus ();
if (!netgame)
{
gameaction = ga_fullconsole;
}
return;
}
// [RH] Write any special "ticcmds" for this player to the demo
if ((specdata = NetSpecs[player][buf].GetData (&speclen)) && gametic % ticdup == 0)
{
memcpy (demo_p, specdata, speclen);
demo_p += speclen;
NetSpecs[player][buf].SetData (NULL, 0);
}
// [RH] Now write out a "normal" ticcmd.
WriteUserCmdMessage (&cmd->ucmd, &players[player].cmd.ucmd, &demo_p);
// [RH] Bigger safety margin
if (demo_p > demobuffer + maxdemosize - 64)
{
ptrdiff_t pos = demo_p - demobuffer;
ptrdiff_t spot = lenspot - demobuffer;
ptrdiff_t comp = democompspot - demobuffer;
ptrdiff_t body = demobodyspot - demobuffer;
// [RH] Allocate more space for the demo
maxdemosize += 0x20000;
demobuffer = (BYTE *)M_Realloc (demobuffer, maxdemosize);
demo_p = demobuffer + pos;
lenspot = demobuffer + spot;
democompspot = demobuffer + comp;
demobodyspot = demobuffer + body;
}
}
//
// G_RecordDemo
//
void G_RecordDemo (char* name)
{
char *v;
usergame = false;
strcpy (demoname, name);
FixPathSeperator (demoname);
DefaultExtension (demoname, ".lmp");
v = Args->CheckValue ("-maxdemo");
maxdemosize = 0x20000;
demobuffer = (BYTE *)M_Malloc (maxdemosize);
demorecording = true;
}
// [RH] Demos are now saved as IFF FORMs. I've also removed support
// for earlier ZDEMs since I didn't want to bother supporting
// something that probably wasn't used much (if at all).
void G_BeginRecording (const char *startmap)
{
int i;
if (startmap == NULL)
{
startmap = level.mapname;
}
demo_p = demobuffer;
WriteLong (FORM_ID, &demo_p); // Write FORM ID
demo_p += 4; // Leave space for len
WriteLong (ZDEM_ID, &demo_p); // Write ZDEM ID
// Write header chunk
StartChunk (ZDHD_ID, &demo_p);
WriteWord (DEMOGAMEVERSION, &demo_p); // Write ZDoom version
*demo_p++ = 2; // Write minimum version needed to use this demo.
*demo_p++ = 3; // (Useful?)
for (i = 0; i < 8; i++) // Write name of map demo was recorded on.
{
*demo_p++ = startmap[i];
}
WriteLong (rngseed, &demo_p); // Write RNG seed
*demo_p++ = consoleplayer;
FinishChunk (&demo_p);
// Write player info chunks
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
{
StartChunk (UINF_ID, &demo_p);
WriteByte ((BYTE)i, &demo_p);
D_WriteUserInfoStrings (i, &demo_p);
FinishChunk (&demo_p);
}
}
// It is possible to start a "multiplayer" game with only one player,
// so checking the number of players when playing back the demo is not
// enough.
if (multiplayer)
{
StartChunk (NETD_ID, &demo_p);
FinishChunk (&demo_p);
}
// Write cvars chunk
StartChunk (VARS_ID, &demo_p);
C_WriteCVars (&demo_p, CVAR_SERVERINFO|CVAR_DEMOSAVE);
FinishChunk (&demo_p);
// Indicate body is compressed
StartChunk (COMP_ID, &demo_p);
democompspot = demo_p;
WriteLong (0, &demo_p);
FinishChunk (&demo_p);
// Begin BODY chunk
StartChunk (BODY_ID, &demo_p);
demobodyspot = demo_p;
}
//
// G_PlayDemo
//
- Fixed: The players were not added to FS's list of spawned things. - Update to ZDoom r882 - Added the option to use $ as a prefix to a string table name everywhere in MAPINFO where 'lookup' could be specified so that there is one consistent way to do it. - Externalized all default episode definitions. Added an 'optional' keyword to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData function and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SBarInfo Update #16 - Added: fillzeros flag for drawnumber. When set the string will always have a length of the specified size and zeros will fill in for the missing places. If the number is negative the negative sign will take the place of the last digit. - Added: globalarray type to drawnumber which will display the value in a global array with the index set to the player's number. Untested. - Added: isselected command to SBarInfo. - Fixed: Bi and Tri colored numbers didn't work. - Fixed: Crash when using nullimage as the last image in drawswitchableimage. - Applied Graf suggestion to include the y coord when calulating heights to fix most of the gaps caused by round off errors. At least for now anyways and it is only applied for drawimage. - SBarInfo inventory bars have been converted to use screen->DrawTexture() - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided line. - Fixed: P_SpawnPuff assumed that all melee attacks have the same range (MELEERANGE) and didn't set the puff to its melee state if the range was different. Even worse, it checked a global variable for this so the behavior was undefined when P_SpawnPuff was called from anywhere else but P_LineAttack. To reduce the amount of parameters I combined this information with the hitthing and temporary parameters into one flags parameter. Also changed P_LineAttack so that it gets passed an additional parameter that specifies whether the attack is a melee attack or not and set this to true in all calls that are to be considered melee attacks. I couldn't use the damage type because A_CustomPunch and A_CustomMeleeAttack allow passing any damage type they want. - Added a sprite option as an alternative of particles for FX_ROCKET and FX_GRENADE. - Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for DECORATE was wrong (2 instead of 1.) - Changed: Hexen set every cluster to be a hub if it hadn't been defined before a level using this cluster. Now it will only do that if HexenHack is true, i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format MAPINFOs it will now be the same as for the other games which means that 'hub' has to be declared explicitly. - Added an Idle state that is entered in place of the spawn state if a monster has to return to its inactive state if it can't find any more targets. - Added MF5_NOINTERACTION flag which completely disables all physics related code for any actor with this flag. Mostly useful for particle effects where the actors just move a certain distance and then disappear. - Removed the last remains of the antialias precalculation code from am_map.cpp because it was no longer used. - Fixed: Two-sided lines bordering a secret sector were not drawn in the proper color - Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color. - Switched sounds local to the listener from head-relative 3D sounds to 2D sounds so stereo sounds have full separation. I tried using set3DSpread, but that still caused some blending of the channels. - Changed FScanner so that opening a lump gives the complete wad+lump name rather than a generic one, so identifying errors among files that all have the same lump name no longer involves any degree of guesswork in determining exactly which file the error occurred in. - Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final sequences. - Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL pointer checks, in case an improper sequence was encountered during parsing but not early enough to avoid creating a slot for it in the array. - Added support for dumping from RAW/DRO/IMF files, so now anything that can be played as OPL can also be dumped. - Removed the opl_enable cvar, since OPL playback is now selectable as just another MIDI device. - Added support for DRO playback and dual-chip RAW playback. - Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with MUSSong2 works just as well. There are still lots of leftover bits in the class that should probably be removed at some point, too. - Added dual-chip dumping support for the RAW format. - Added DosBox Raw OPL (.DRO) dumping support. For whatever reason, in_adlib calculates the song length for this format wrong, even though the exact length is stored right in the header. (But in_adlib seems buggy in general; too bad it's the only Windows version of Adplug that seems to exist.) - Rewrote the OPL dumper to work with MIDI as well as MUS. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
FString defdemoname;
void G_DeferedPlayDemo (char *name)
{
- Fixed: The players were not added to FS's list of spawned things. - Update to ZDoom r882 - Added the option to use $ as a prefix to a string table name everywhere in MAPINFO where 'lookup' could be specified so that there is one consistent way to do it. - Externalized all default episode definitions. Added an 'optional' keyword to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData function and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SBarInfo Update #16 - Added: fillzeros flag for drawnumber. When set the string will always have a length of the specified size and zeros will fill in for the missing places. If the number is negative the negative sign will take the place of the last digit. - Added: globalarray type to drawnumber which will display the value in a global array with the index set to the player's number. Untested. - Added: isselected command to SBarInfo. - Fixed: Bi and Tri colored numbers didn't work. - Fixed: Crash when using nullimage as the last image in drawswitchableimage. - Applied Graf suggestion to include the y coord when calulating heights to fix most of the gaps caused by round off errors. At least for now anyways and it is only applied for drawimage. - SBarInfo inventory bars have been converted to use screen->DrawTexture() - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided line. - Fixed: P_SpawnPuff assumed that all melee attacks have the same range (MELEERANGE) and didn't set the puff to its melee state if the range was different. Even worse, it checked a global variable for this so the behavior was undefined when P_SpawnPuff was called from anywhere else but P_LineAttack. To reduce the amount of parameters I combined this information with the hitthing and temporary parameters into one flags parameter. Also changed P_LineAttack so that it gets passed an additional parameter that specifies whether the attack is a melee attack or not and set this to true in all calls that are to be considered melee attacks. I couldn't use the damage type because A_CustomPunch and A_CustomMeleeAttack allow passing any damage type they want. - Added a sprite option as an alternative of particles for FX_ROCKET and FX_GRENADE. - Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for DECORATE was wrong (2 instead of 1.) - Changed: Hexen set every cluster to be a hub if it hadn't been defined before a level using this cluster. Now it will only do that if HexenHack is true, i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format MAPINFOs it will now be the same as for the other games which means that 'hub' has to be declared explicitly. - Added an Idle state that is entered in place of the spawn state if a monster has to return to its inactive state if it can't find any more targets. - Added MF5_NOINTERACTION flag which completely disables all physics related code for any actor with this flag. Mostly useful for particle effects where the actors just move a certain distance and then disappear. - Removed the last remains of the antialias precalculation code from am_map.cpp because it was no longer used. - Fixed: Two-sided lines bordering a secret sector were not drawn in the proper color - Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color. - Switched sounds local to the listener from head-relative 3D sounds to 2D sounds so stereo sounds have full separation. I tried using set3DSpread, but that still caused some blending of the channels. - Changed FScanner so that opening a lump gives the complete wad+lump name rather than a generic one, so identifying errors among files that all have the same lump name no longer involves any degree of guesswork in determining exactly which file the error occurred in. - Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final sequences. - Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL pointer checks, in case an improper sequence was encountered during parsing but not early enough to avoid creating a slot for it in the array. - Added support for dumping from RAW/DRO/IMF files, so now anything that can be played as OPL can also be dumped. - Removed the opl_enable cvar, since OPL playback is now selectable as just another MIDI device. - Added support for DRO playback and dual-chip RAW playback. - Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with MUSSong2 works just as well. There are still lots of leftover bits in the class that should probably be removed at some point, too. - Added dual-chip dumping support for the RAW format. - Added DosBox Raw OPL (.DRO) dumping support. For whatever reason, in_adlib calculates the song length for this format wrong, even though the exact length is stored right in the header. (But in_adlib seems buggy in general; too bad it's the only Windows version of Adplug that seems to exist.) - Rewrote the OPL dumper to work with MIDI as well as MUS. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
defdemoname = name;
gameaction = ga_playdemo;
}
CCMD (playdemo)
{
if (argv.argc() > 1)
{
G_DeferedPlayDemo (argv[1]);
singledemo = true;
}
}
CCMD (timedemo)
{
if (argv.argc() > 1)
{
G_TimeDemo (argv[1]);
singledemo = true;
}
}
// [RH] Process all the information in a FORM ZDEM
// until a BODY chunk is entered.
bool G_ProcessIFFDemo (char *mapname)
{
bool headerHit = false;
bool bodyHit = false;
int numPlayers = 0;
int id, len, i;
uLong uncompSize = 0;
BYTE *nextchunk;
demoplayback = true;
for (i = 0; i < MAXPLAYERS; i++)
playeringame[i] = 0;
len = ReadLong (&demo_p);
zdemformend = demo_p + len + (len & 1);
// Check to make sure this is a ZDEM chunk file.
// TODO: Support multiple FORM ZDEMs in a CAT. Might be useful.
id = ReadLong (&demo_p);
if (id != ZDEM_ID)
{
Printf ("Not a ZDoom demo file!\n");
return true;
}
// Process all chunks until a BODY chunk is encountered.
while (demo_p < zdemformend && !bodyHit)
{
id = ReadLong (&demo_p);
len = ReadLong (&demo_p);
nextchunk = demo_p + len + (len & 1);
if (nextchunk > zdemformend)
{
Printf ("Demo is mangled!\n");
return true;
}
switch (id)
{
case ZDHD_ID:
headerHit = true;
demover = ReadWord (&demo_p); // ZDoom version demo was created with
if (demover < MINDEMOVERSION)
{
Printf ("Demo requires an older version of ZDoom!\n");
//return true;
}
if (ReadWord (&demo_p) > DEMOGAMEVERSION) // Minimum ZDoom version
{
Printf ("Demo requires a newer version of ZDoom!\n");
return true;
}
memcpy (mapname, demo_p, 8); // Read map name
mapname[8] = 0;
demo_p += 8;
rngseed = ReadLong (&demo_p);
FRandom::StaticClearRandom ();
consoleplayer = *demo_p++;
break;
case VARS_ID:
C_ReadCVars (&demo_p);
break;
case UINF_ID:
i = ReadByte (&demo_p);
if (!playeringame[i])
{
playeringame[i] = 1;
numPlayers++;
}
D_ReadUserInfoStrings (i, &demo_p, false);
break;
case NETD_ID:
multiplayer = true;
break;
case BODY_ID:
bodyHit = true;
zdembodyend = demo_p + len;
break;
case COMP_ID:
uncompSize = ReadLong (&demo_p);
break;
}
if (!bodyHit)
demo_p = nextchunk;
}
if (!numPlayers)
{
Printf ("Demo has no players!\n");
return true;
}
if (!bodyHit)
{
zdembodyend = NULL;
Printf ("Demo has no BODY chunk!\n");
return true;
}
if (numPlayers > 1)
multiplayer = netgame = netdemo = true;
if (uncompSize > 0)
{
BYTE *uncompressed = new BYTE[uncompSize];
int r = uncompress (uncompressed, &uncompSize, demo_p, zdembodyend - demo_p);
if (r != Z_OK)
{
Printf ("Could not decompress demo!\n");
delete[] uncompressed;
return true;
}
M_Free (demobuffer);
zdembodyend = uncompressed + uncompSize;
demobuffer = demo_p = uncompressed;
}
return false;
}
void G_DoPlayDemo (void)
{
char mapname[9];
int demolump;
gameaction = ga_nothing;
// [RH] Allow for demos not loaded as lumps
- Fixed: The players were not added to FS's list of spawned things. - Update to ZDoom r882 - Added the option to use $ as a prefix to a string table name everywhere in MAPINFO where 'lookup' could be specified so that there is one consistent way to do it. - Externalized all default episode definitions. Added an 'optional' keyword to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData function and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SBarInfo Update #16 - Added: fillzeros flag for drawnumber. When set the string will always have a length of the specified size and zeros will fill in for the missing places. If the number is negative the negative sign will take the place of the last digit. - Added: globalarray type to drawnumber which will display the value in a global array with the index set to the player's number. Untested. - Added: isselected command to SBarInfo. - Fixed: Bi and Tri colored numbers didn't work. - Fixed: Crash when using nullimage as the last image in drawswitchableimage. - Applied Graf suggestion to include the y coord when calulating heights to fix most of the gaps caused by round off errors. At least for now anyways and it is only applied for drawimage. - SBarInfo inventory bars have been converted to use screen->DrawTexture() - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided line. - Fixed: P_SpawnPuff assumed that all melee attacks have the same range (MELEERANGE) and didn't set the puff to its melee state if the range was different. Even worse, it checked a global variable for this so the behavior was undefined when P_SpawnPuff was called from anywhere else but P_LineAttack. To reduce the amount of parameters I combined this information with the hitthing and temporary parameters into one flags parameter. Also changed P_LineAttack so that it gets passed an additional parameter that specifies whether the attack is a melee attack or not and set this to true in all calls that are to be considered melee attacks. I couldn't use the damage type because A_CustomPunch and A_CustomMeleeAttack allow passing any damage type they want. - Added a sprite option as an alternative of particles for FX_ROCKET and FX_GRENADE. - Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for DECORATE was wrong (2 instead of 1.) - Changed: Hexen set every cluster to be a hub if it hadn't been defined before a level using this cluster. Now it will only do that if HexenHack is true, i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format MAPINFOs it will now be the same as for the other games which means that 'hub' has to be declared explicitly. - Added an Idle state that is entered in place of the spawn state if a monster has to return to its inactive state if it can't find any more targets. - Added MF5_NOINTERACTION flag which completely disables all physics related code for any actor with this flag. Mostly useful for particle effects where the actors just move a certain distance and then disappear. - Removed the last remains of the antialias precalculation code from am_map.cpp because it was no longer used. - Fixed: Two-sided lines bordering a secret sector were not drawn in the proper color - Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color. - Switched sounds local to the listener from head-relative 3D sounds to 2D sounds so stereo sounds have full separation. I tried using set3DSpread, but that still caused some blending of the channels. - Changed FScanner so that opening a lump gives the complete wad+lump name rather than a generic one, so identifying errors among files that all have the same lump name no longer involves any degree of guesswork in determining exactly which file the error occurred in. - Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final sequences. - Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL pointer checks, in case an improper sequence was encountered during parsing but not early enough to avoid creating a slot for it in the array. - Added support for dumping from RAW/DRO/IMF files, so now anything that can be played as OPL can also be dumped. - Removed the opl_enable cvar, since OPL playback is now selectable as just another MIDI device. - Added support for DRO playback and dual-chip RAW playback. - Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with MUSSong2 works just as well. There are still lots of leftover bits in the class that should probably be removed at some point, too. - Added dual-chip dumping support for the RAW format. - Added DosBox Raw OPL (.DRO) dumping support. For whatever reason, in_adlib calculates the song length for this format wrong, even though the exact length is stored right in the header. (But in_adlib seems buggy in general; too bad it's the only Windows version of Adplug that seems to exist.) - Rewrote the OPL dumper to work with MIDI as well as MUS. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
demolump = Wads.CheckNumForFullName (defdemoname, true);
if (demolump >= 0)
{
int demolen = Wads.LumpLength (demolump);
demobuffer = (BYTE *)M_Malloc(demolen);
Wads.ReadLump (demolump, demobuffer);
}
else
{
FixPathSeperator (defdemoname);
DefaultExtension (defdemoname, ".lmp");
M_ReadFile (defdemoname, &demobuffer);
}
demo_p = demobuffer;
- Fixed: The players were not added to FS's list of spawned things. - Update to ZDoom r882 - Added the option to use $ as a prefix to a string table name everywhere in MAPINFO where 'lookup' could be specified so that there is one consistent way to do it. - Externalized all default episode definitions. Added an 'optional' keyword to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData function and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SBarInfo Update #16 - Added: fillzeros flag for drawnumber. When set the string will always have a length of the specified size and zeros will fill in for the missing places. If the number is negative the negative sign will take the place of the last digit. - Added: globalarray type to drawnumber which will display the value in a global array with the index set to the player's number. Untested. - Added: isselected command to SBarInfo. - Fixed: Bi and Tri colored numbers didn't work. - Fixed: Crash when using nullimage as the last image in drawswitchableimage. - Applied Graf suggestion to include the y coord when calulating heights to fix most of the gaps caused by round off errors. At least for now anyways and it is only applied for drawimage. - SBarInfo inventory bars have been converted to use screen->DrawTexture() - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided line. - Fixed: P_SpawnPuff assumed that all melee attacks have the same range (MELEERANGE) and didn't set the puff to its melee state if the range was different. Even worse, it checked a global variable for this so the behavior was undefined when P_SpawnPuff was called from anywhere else but P_LineAttack. To reduce the amount of parameters I combined this information with the hitthing and temporary parameters into one flags parameter. Also changed P_LineAttack so that it gets passed an additional parameter that specifies whether the attack is a melee attack or not and set this to true in all calls that are to be considered melee attacks. I couldn't use the damage type because A_CustomPunch and A_CustomMeleeAttack allow passing any damage type they want. - Added a sprite option as an alternative of particles for FX_ROCKET and FX_GRENADE. - Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for DECORATE was wrong (2 instead of 1.) - Changed: Hexen set every cluster to be a hub if it hadn't been defined before a level using this cluster. Now it will only do that if HexenHack is true, i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format MAPINFOs it will now be the same as for the other games which means that 'hub' has to be declared explicitly. - Added an Idle state that is entered in place of the spawn state if a monster has to return to its inactive state if it can't find any more targets. - Added MF5_NOINTERACTION flag which completely disables all physics related code for any actor with this flag. Mostly useful for particle effects where the actors just move a certain distance and then disappear. - Removed the last remains of the antialias precalculation code from am_map.cpp because it was no longer used. - Fixed: Two-sided lines bordering a secret sector were not drawn in the proper color - Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color. - Switched sounds local to the listener from head-relative 3D sounds to 2D sounds so stereo sounds have full separation. I tried using set3DSpread, but that still caused some blending of the channels. - Changed FScanner so that opening a lump gives the complete wad+lump name rather than a generic one, so identifying errors among files that all have the same lump name no longer involves any degree of guesswork in determining exactly which file the error occurred in. - Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final sequences. - Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL pointer checks, in case an improper sequence was encountered during parsing but not early enough to avoid creating a slot for it in the array. - Added support for dumping from RAW/DRO/IMF files, so now anything that can be played as OPL can also be dumped. - Removed the opl_enable cvar, since OPL playback is now selectable as just another MIDI device. - Added support for DRO playback and dual-chip RAW playback. - Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with MUSSong2 works just as well. There are still lots of leftover bits in the class that should probably be removed at some point, too. - Added dual-chip dumping support for the RAW format. - Added DosBox Raw OPL (.DRO) dumping support. For whatever reason, in_adlib calculates the song length for this format wrong, even though the exact length is stored right in the header. (But in_adlib seems buggy in general; too bad it's the only Windows version of Adplug that seems to exist.) - Rewrote the OPL dumper to work with MIDI as well as MUS. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
Printf ("Playing demo %s\n", defdemoname.GetChars());
C_BackupCVars (); // [RH] Save cvars that might be affected by demo
if (ReadLong (&demo_p) != FORM_ID)
{
const char *eek = "Cannot play non-ZDoom demos.\n(They would go out of sync badly.)\n";
if (singledemo)
{
I_Error (eek);
}
else
{
Printf (PRINT_BOLD, eek);
gameaction = ga_nothing;
}
}
else if (G_ProcessIFFDemo (mapname))
{
gameaction = ga_nothing;
demoplayback = false;
}
else
{
// don't spend a lot of time in loadlevel
precache = false;
demonew = true;
G_InitNew (mapname, false);
C_HideConsole ();
demonew = false;
precache = true;
usergame = false;
demoplayback = true;
}
}
//
// G_TimeDemo
//
void G_TimeDemo (char* name)
{
nodrawers = !!Args->CheckParm ("-nodraw");
noblit = !!Args->CheckParm ("-noblit");
timingdemo = true;
singletics = true;
- Fixed: The players were not added to FS's list of spawned things. - Update to ZDoom r882 - Added the option to use $ as a prefix to a string table name everywhere in MAPINFO where 'lookup' could be specified so that there is one consistent way to do it. - Externalized all default episode definitions. Added an 'optional' keyword to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData function and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SBarInfo Update #16 - Added: fillzeros flag for drawnumber. When set the string will always have a length of the specified size and zeros will fill in for the missing places. If the number is negative the negative sign will take the place of the last digit. - Added: globalarray type to drawnumber which will display the value in a global array with the index set to the player's number. Untested. - Added: isselected command to SBarInfo. - Fixed: Bi and Tri colored numbers didn't work. - Fixed: Crash when using nullimage as the last image in drawswitchableimage. - Applied Graf suggestion to include the y coord when calulating heights to fix most of the gaps caused by round off errors. At least for now anyways and it is only applied for drawimage. - SBarInfo inventory bars have been converted to use screen->DrawTexture() - Increased limit for demon/melee to 4. - Fixed: P_CheckSwitchRange accessed invalid memory when testing a one-sided line. - Fixed: P_SpawnPuff assumed that all melee attacks have the same range (MELEERANGE) and didn't set the puff to its melee state if the range was different. Even worse, it checked a global variable for this so the behavior was undefined when P_SpawnPuff was called from anywhere else but P_LineAttack. To reduce the amount of parameters I combined this information with the hitthing and temporary parameters into one flags parameter. Also changed P_LineAttack so that it gets passed an additional parameter that specifies whether the attack is a melee attack or not and set this to true in all calls that are to be considered melee attacks. I couldn't use the damage type because A_CustomPunch and A_CustomMeleeAttack allow passing any damage type they want. - Added a sprite option as an alternative of particles for FX_ROCKET and FX_GRENADE. - Fixed: The minimum parameter count for ACS_Execute and ACS_ExecuteAlways for DECORATE was wrong (2 instead of 1.) - Changed: Hexen set every cluster to be a hub if it hadn't been defined before a level using this cluster. Now it will only do that if HexenHack is true, i.e. when original Hexen format MAPINFOs are parsed. For ZDoom format MAPINFOs it will now be the same as for the other games which means that 'hub' has to be declared explicitly. - Added an Idle state that is entered in place of the spawn state if a monster has to return to its inactive state if it can't find any more targets. - Added MF5_NOINTERACTION flag which completely disables all physics related code for any actor with this flag. Mostly useful for particle effects where the actors just move a certain distance and then disappear. - Removed the last remains of the antialias precalculation code from am_map.cpp because it was no longer used. - Fixed: Two-sided lines bordering a secret sector were not drawn in the proper color - Fixed: The automap didn't check ACS_LockedExecuteDoor for its lock color. - Switched sounds local to the listener from head-relative 3D sounds to 2D sounds so stereo sounds have full separation. I tried using set3DSpread, but that still caused some blending of the channels. - Changed FScanner so that opening a lump gives the complete wad+lump name rather than a generic one, so identifying errors among files that all have the same lump name no longer involves any degree of guesswork in determining exactly which file the error occurred in. - Added a check to S_ParseSndSeq() for SNDSEQ lumps with unterminated final sequences. - Fixed: Parts of s_sndseq.cpp that scan the Sequences array need NULL pointer checks, in case an improper sequence was encountered during parsing but not early enough to avoid creating a slot for it in the array. - Added support for dumping from RAW/DRO/IMF files, so now anything that can be played as OPL can also be dumped. - Removed the opl_enable cvar, since OPL playback is now selectable as just another MIDI device. - Added support for DRO playback and dual-chip RAW playback. - Removed MUS support from OPLMUSSong, since using the OPLMIDIDevice with MUSSong2 works just as well. There are still lots of leftover bits in the class that should probably be removed at some point, too. - Added dual-chip dumping support for the RAW format. - Added DosBox Raw OPL (.DRO) dumping support. For whatever reason, in_adlib calculates the song length for this format wrong, even though the exact length is stored right in the header. (But in_adlib seems buggy in general; too bad it's the only Windows version of Adplug that seems to exist.) - Rewrote the OPL dumper to work with MIDI as well as MUS. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@86 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-05 13:28:48 +00:00
defdemoname = name;
gameaction = ga_playdemo;
}
/*
===================
=
= G_CheckDemoStatus
=
= Called after a death or level completion to allow demos to be cleaned up
= Returns true if a new demo loop action will take place
===================
*/
bool G_CheckDemoStatus (void)
{
if (!demorecording)
{ // [RH] Restore the player's userinfo settings.
D_SetupUserInfo();
}
if (demoplayback)
{
extern int starttime;
int endtime = 0;
if (timingdemo)
endtime = I_GetTime (false) - starttime;
C_RestoreCVars (); // [RH] Restore cvars demo might have changed
M_Free (demobuffer);
demoplayback = false;
netdemo = false;
netgame = false;
multiplayer = false;
singletics = false;
{
int i;
for (i = 1; i < MAXPLAYERS; i++)
playeringame[i] = 0;
}
consoleplayer = 0;
players[0].camera = NULL;
StatusBar->AttachToPlayer (&players[0]);
if (singledemo || timingdemo)
{
if (timingdemo)
{
// Trying to get back to a stable state after timing a demo
// seems to cause problems. I don't feel like fixing that
// right now.
I_FatalError ("timed %i gametics in %i realtics (%.1f fps)\n"
"(This is not really an error.)", gametic,
endtime, (float)gametic/(float)endtime*(float)TICRATE);
}
else
{
Printf ("Demo ended.\n");
}
gameaction = ga_fullconsole;
timingdemo = false;
return false;
}
else
{
D_AdvanceDemo ();
}
return true;
}
if (demorecording)
{
BYTE *formlen;
WriteByte (DEM_STOP, &demo_p);
if (demo_compress)
{
// Now that the entire BODY chunk has been created, replace it with
// a compressed version. If the BODY successfully compresses, the
// contents of the COMP chunk will be changed to indicate the
// uncompressed size of the BODY.
uLong len = demo_p - demobodyspot;
uLong outlen = (len + len/100 + 12);
Byte *compressed = new Byte[outlen];
int r = compress2 (compressed, &outlen, demobodyspot, len, 9);
if (r == Z_OK && outlen < len)
{
formlen = democompspot;
WriteLong (len, &democompspot);
memcpy (demobodyspot, compressed, outlen);
demo_p = demobodyspot + outlen;
}
delete[] compressed;
}
FinishChunk (&demo_p);
formlen = demobuffer + 4;
WriteLong (demo_p - demobuffer - 8, &formlen);
M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
M_Free (demobuffer);
demorecording = false;
stoprecording = false;
Printf ("Demo %s recorded\n", demoname);
}
return false;
}