crude TS dead thirdperson and respawn delay, obituary drawn at all times
This commit is contained in:
parent
497393eea6
commit
b5e7cf4bbf
14 changed files with 239 additions and 162 deletions
|
@ -182,6 +182,9 @@ ClientGame_EventParse(float fHeader)
|
|||
case EVENT_TS::PLAYER_DEATH:{
|
||||
EV_PlayerDeath();
|
||||
}break;
|
||||
case EVENT_TS::PLAYER_NOCLIP:{
|
||||
EV_PlayerNoclip();
|
||||
}break;
|
||||
case EVENT_TS::EQUIP_CALLBACK:{
|
||||
EV_EquipCallback();
|
||||
}break;
|
||||
|
|
|
@ -71,6 +71,10 @@ HUD_Draw(void)
|
|||
player pl = (player)pSeat->m_ePlayer;
|
||||
|
||||
|
||||
//TAGGG - outside the rest for now
|
||||
Obituary_Draw();
|
||||
Textmenu_Draw();
|
||||
|
||||
if(pl.iState == PLAYER_STATE::SPAWNED){
|
||||
// A player
|
||||
|
||||
|
@ -109,8 +113,6 @@ HUD_Draw(void)
|
|||
// Nuclide methods in its weapons struct
|
||||
Weapons_DrawCrosshair();
|
||||
TS_HUD_DrawWeaponSelect();
|
||||
Obituary_Draw();
|
||||
Textmenu_Draw();
|
||||
|
||||
|
||||
//TAGGG - new
|
||||
|
|
|
@ -144,6 +144,7 @@ Obituary_Add(string attacker, string victim, float weapon, float flags)
|
|||
void
|
||||
Obituary_Draw(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
vector pos;
|
||||
vector item;
|
||||
|
|
|
@ -34,6 +34,12 @@ var float autocvar_mp_timelimit = 60;
|
|||
var string autocvar_motdfile = "motd.txt";
|
||||
var int autocvar_mp_friendlyfire = FALSE;
|
||||
|
||||
var float autocvar_weaponstay = 60; //default originally 15
|
||||
|
||||
// orignal TS name. Minimum allowed time before respawns for self-respawnable gamemodes,
|
||||
// deathmatch and team-deathmatch, I forget if there's anything else. Not round-based ones.
|
||||
var float autocvar_respawntime = 5.0;
|
||||
|
||||
|
||||
var int autocvar_debug_spawnpointforced = 0;
|
||||
|
||||
|
|
|
@ -113,7 +113,9 @@ class TSMultiplayerRules:TSGameRules
|
|||
|
||||
virtual void(player pl) MakePlayerInvisible;
|
||||
virtual void(base_player) PlayerMakePlayable;
|
||||
virtual void(base_player pp) PlayerMakePlayableWithDefaultMoney;
|
||||
virtual void(base_player) PlayerMakeSpectator;
|
||||
virtual void(base_player) PlayerMakeSpectatorAndNotify;
|
||||
virtual void(base_player pp) PlayerMakeSpectatorDelayed;
|
||||
virtual void(base_player, int) PlayerRespawn;
|
||||
virtual entity(float) PlayerFindSpawn;
|
||||
|
|
|
@ -360,11 +360,17 @@ TSMultiplayerRules::PlayerDeath(base_player pp)
|
|||
// Redundant for gibbing but doesn't hurt
|
||||
MakePlayerInvisible(pl);
|
||||
|
||||
PlayerMakeSpectatorDelayed(pl);
|
||||
// Now doing this instead
|
||||
//PlayerMakeSpectatorDelayed(pl);
|
||||
|
||||
pl.iState = PLAYER_STATE::DEAD_RECENT;
|
||||
pl.deathCameraChangeTime = 2.5;
|
||||
pl.minimumRespawnTime = autocvar_respawntime;
|
||||
|
||||
// Not done just for this player, still a check on all alive players
|
||||
// that happens to involve this deceased player. Strange.
|
||||
DeathCheck(pl);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -580,45 +586,19 @@ TSMultiplayerRules::RestartRound(int iWipe)
|
|||
|
||||
// TAGGG - CRITICAL.
|
||||
// If gamemodes where the starting cash isn't reset to a static amount at every spawn
|
||||
// are ever intended, this is bad!
|
||||
// Skipping a clean reset for all currently in spectator (classname="spectator") is bad!
|
||||
// are ever intended, this has to be adjusted.
|
||||
for (entity eFind = world; (eFind = find(eFind, ::classname, "player"));) {
|
||||
//self = eFind;
|
||||
player pl = (player)eFind;
|
||||
|
||||
// only affect players ingame!
|
||||
if(pl.iState != PLAYER_STATE::SPAWNED){
|
||||
continue;
|
||||
if(pl.iState == PLAYER_STATE::SPAWNED){
|
||||
PlayerMakePlayableWithDefaultMoney(pl);
|
||||
}
|
||||
|
||||
//printfline("PLAYER MONEY 1: %i", pl.money);
|
||||
|
||||
// only respawn players that were ingame. Those that weren't may want to stay in spectator.
|
||||
if(pl.health > 0){
|
||||
//pl.reset(TRUE);
|
||||
|
||||
// Something about this resets the player money..? Is it changing to Spectator
|
||||
// right before Player that did it here?
|
||||
//PlayerMakeSpectator(pl);
|
||||
// just let PlayerMakePlayable work.
|
||||
pl.iState = PLAYER_STATE::NOCLIP;
|
||||
PlayerMakePlayable(pl);
|
||||
}
|
||||
|
||||
// do the money set here and it works out fine, doesn't leave the player on
|
||||
// initial-round-respawn with 0 money.
|
||||
setPlayerMoneyDefault(pl);
|
||||
//printfline("PLAYER MONEY 3: %i", pl.money);
|
||||
|
||||
}
|
||||
|
||||
// anything to do with spectators.
|
||||
//TAGGG - CRITICAL! As spectators, changing "pl.money" would not make sense. Not a player now.
|
||||
/*
|
||||
for (entity eFind = world; (eFind = find(eFind, ::classname, "spectator"));) {
|
||||
|
||||
}
|
||||
*/
|
||||
// anything to do with spectators?
|
||||
// Remember, any classname="spectator" is an authentic spectator, not players that can open the
|
||||
// buymenu and click to spawn after.
|
||||
|
||||
}//END OF !startingGame check
|
||||
|
||||
|
@ -679,6 +659,8 @@ TSMultiplayerRules::RestartRound(int iWipe)
|
|||
|
||||
|
||||
|
||||
// From FreeCS, to check if all players on a team are dead for doing something
|
||||
// gamerules-wise like ending in the other side's favor.
|
||||
void
|
||||
TSMultiplayerRules::DeathCheck(base_player pl)
|
||||
{
|
||||
|
@ -806,7 +788,6 @@ TSMultiplayerRules::PlayerRespawn(base_player pp, int fTeam)
|
|||
//pl.classname = "player";
|
||||
|
||||
// fresh inventory for you
|
||||
//TAGGG - QUESTION: Why reset the player on death or going to spectator instead?
|
||||
TS_resetPlayer(pl, TRUE);
|
||||
|
||||
// Also, FreeHL did these, but it looks like a simple way of 0'ing everything out.
|
||||
|
@ -1006,12 +987,6 @@ void
|
|||
TSMultiplayerRules::PlayerMakePlayable(base_player pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
if(pl.iState == PLAYER_STATE::SPAWNED){
|
||||
// no need to do this again.
|
||||
// Set pl.iState to something else first if this was an intentional re-spawn
|
||||
// for an ingame player
|
||||
return;
|
||||
}
|
||||
|
||||
pl.iState = PLAYER_STATE::SPAWNED;
|
||||
// Nope!
|
||||
|
@ -1021,32 +996,40 @@ TSMultiplayerRules::PlayerMakePlayable(base_player pp)
|
|||
PlayerRespawn(pl, pl.team);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
PlayerMakeSpectator
|
||||
|
||||
Force the player to become an observer.
|
||||
=================
|
||||
*/
|
||||
void
|
||||
TSMultiplayerRules::PlayerMakePlayableWithDefaultMoney(base_player pp){
|
||||
player pl = (player)pp;
|
||||
PlayerMakePlayable(pp);
|
||||
setPlayerMoneyDefault(pl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
TSMultiplayerRules::PlayerMakeSpectatorAndNotify(base_player pp){
|
||||
|
||||
PlayerMakeSpectator(pp);
|
||||
|
||||
// let the client know of the chane to revert any 'cl_thirdperson' change
|
||||
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
|
||||
WriteByte( MSG_MULTICAST, EVENT_TS::PLAYER_NOCLIP );
|
||||
msg_entity = pp;
|
||||
multicast( [0,0,0], MULTICAST_ONE_R );
|
||||
}
|
||||
|
||||
// Turns the player into a fake spectator (open buymenu and fire to spawn
|
||||
// when its closed)
|
||||
void
|
||||
TSMultiplayerRules::PlayerMakeSpectator(base_player pp)
|
||||
{
|
||||
player pl = (player)pp;
|
||||
|
||||
if(pl.iState == PLAYER_STATE::NOCLIP){
|
||||
// Already in fake spectator! Stop.
|
||||
return;
|
||||
}
|
||||
|
||||
if(pl.modelindex != 0){
|
||||
// assume this is necessary
|
||||
MakePlayerInvisible(pl);
|
||||
}
|
||||
|
||||
// is that necessary still?
|
||||
//TS_resetPlayer(pl, TRUE);
|
||||
// And don't do this! Just change iState
|
||||
//MakeSpectator(pl);
|
||||
pl.iState = PLAYER_STATE::NOCLIP;
|
||||
|
||||
// And do the rest of the lines to finish that
|
||||
|
@ -1056,12 +1039,8 @@ TSMultiplayerRules::PlayerMakeSpectator(base_player pp)
|
|||
pl.think = NULL;
|
||||
pl.nextthink = 0.0f;
|
||||
pl.maxspeed = 250;
|
||||
//pl.spec_ent = 0;
|
||||
//pl.spec_mode = 0;
|
||||
|
||||
//#ifdef SERVER
|
||||
forceinfokey(pl, "*spec", "1");
|
||||
//#endif
|
||||
forceinfokey(pl, "*spec", "1");
|
||||
|
||||
pl.armor = pl.activeweapon = pl.g_items = 0;
|
||||
pl.health = 0;
|
||||
|
@ -1080,27 +1059,6 @@ TSMultiplayerRules::PlayerMakeSpectatorDelayed(base_player pp)
|
|||
player pl = (player)pp;
|
||||
PlayerMakeSpectator(pp);
|
||||
|
||||
/*
|
||||
player pl = (player)pp;
|
||||
if(pl.classname != "spectator" && pl.modelindex != 0){
|
||||
// assume this is necessary
|
||||
MakePlayerInvisible(pl);
|
||||
}
|
||||
|
||||
//TS_resetPlayer(pl, TRUE);
|
||||
static void GoSpec(void) {
|
||||
spawnfunc_spectator();
|
||||
}
|
||||
pl.think = GoSpec;
|
||||
pl.nextthink = time;
|
||||
// ? Is this for the specator-spawn to sense that the classname
|
||||
// wasn't already "spectator" in case this happens twice in the
|
||||
// same frame?
|
||||
pl.classname = "player";
|
||||
// "dead" should already be set.
|
||||
//forceinfokey(pl, "*dead", "1");
|
||||
//forceinfokey(pl, "*team", ftos(pl.team));
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1136,16 +1094,12 @@ TSMultiplayerRules::PlayerSpawn(base_player pp)
|
|||
//pl.team = TEAM_SPECTATOR;
|
||||
|
||||
|
||||
// immediately put us into spectating mode
|
||||
// (iState forced to a wrong value to stop MakeSpectator from being skipped)
|
||||
pl.iState = PLAYER_STATE::SPAWNED;
|
||||
// immediately put us into fake spectating mode (MoTD followed by buy-menu)
|
||||
PlayerMakeSpectator(pl);
|
||||
// Use our game's custom ObserverCam instead.
|
||||
Game_Spawn_ObserverCam(pl);
|
||||
|
||||
// give the initial server-joining money
|
||||
//TAGGG - WARNING! This sets 'pl.money', should that be some infokey stat instead
|
||||
// for player/spectator entity-change reasons?
|
||||
setPlayerMoneyDefault(pl);
|
||||
|
||||
// I guess this state counts as "dead"?
|
||||
|
@ -1156,10 +1110,13 @@ TSMultiplayerRules::PlayerSpawn(base_player pp)
|
|||
forceinfokey(pl, "*deaths", "0"); //ftos(pl.deaths));
|
||||
|
||||
forceinfokey(pl, "done_connecting", "1");
|
||||
|
||||
// ALSO - start the minimum spawn delay.
|
||||
pl.minimumRespawnTime = autocvar_respawntime;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
TSMultiplayerRules::setPlayerMoneyDefault(player pl)
|
||||
{
|
||||
|
@ -1169,30 +1126,51 @@ TSMultiplayerRules::setPlayerMoneyDefault(player pl)
|
|||
|
||||
|
||||
|
||||
void
|
||||
CSEv_GameEarlyNoclip(void)
|
||||
{
|
||||
TSMultiplayerRules rules;
|
||||
player pl = (player)self;
|
||||
|
||||
if(pl.iState != PLAYER_STATE::DEAD_RECENT){
|
||||
// This is for looking at a recently dead player only.
|
||||
return;
|
||||
}
|
||||
|
||||
if(pl.deathCameraChangeTime > 1.5){
|
||||
if(pl.deathCameraChangeTime < 1.5 + 0.5){
|
||||
pl.waitingForEarlyNoclip = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rules = (TSMultiplayerRules)g_grMode;
|
||||
rules.PlayerMakeSpectatorAndNotify(pl);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// An order from the client (while in spectator) that they want to spawn.
|
||||
void
|
||||
CSEv_GamePlayerSpawn(void)
|
||||
{
|
||||
TSMultiplayerRules rules = (TSMultiplayerRules)g_grMode;
|
||||
TSMultiplayerRules rules;
|
||||
player pl = (player)self;
|
||||
|
||||
if(pl.iState == PLAYER_STATE::SPAWNED){
|
||||
// what.
|
||||
// already spawned?
|
||||
return;
|
||||
}
|
||||
|
||||
//self.dmg_take = 0;
|
||||
//self.dmg_inflictor = NULL; //good idea?
|
||||
|
||||
// For now stop deathspammin'
|
||||
if (pl.health > 0) {
|
||||
if(pl.minimumRespawnTime > 0){
|
||||
// the spawn-delay hasn't expired yet, then no.
|
||||
// Although, if close enough, mark this as 'waitingToSpawn' to happen as it finishes
|
||||
if(pl.minimumRespawnTime < 0.5){
|
||||
pl.waitingForSpawn = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rules.PlayerMakeSpectator(pl);
|
||||
rules.PlayerMakePlayable(pl);
|
||||
|
||||
// reset the money
|
||||
rules.setPlayerMoneyDefault(pl);
|
||||
rules = (TSMultiplayerRules)g_grMode;
|
||||
rules.PlayerMakePlayableWithDefaultMoney(pl);
|
||||
}
|
||||
|
||||
|
|
|
@ -289,8 +289,9 @@ Game_Worldspawn(void)
|
|||
// see what calls that if uncertain from nuclide.
|
||||
initSpawnMem();
|
||||
|
||||
|
||||
clientstat(STAT_MONEY, EV_INTEGER, player::money);
|
||||
clientstat(STAT_DEATHCAMERACHANGETIME, EV_FLOAT, player::deathCameraChangeTime);
|
||||
clientstat(STAT_MINIMUMRESPAWNTIME, EV_FLOAT, player::minimumRespawnTime);
|
||||
pointerstat(STAT_GAMETIME, EV_FLOAT, &g_ts_gametime);
|
||||
pointerstat(STAT_GAMESTATE, EV_INTEGER, &g_ts_gamestate);
|
||||
|
||||
|
|
|
@ -20,12 +20,6 @@ enum TS_Team{
|
|||
//#define INPUT_BUTTON9 0x00000100
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
//server CVar
|
||||
var float autocvar_weaponstay = 60; //default originally 15
|
||||
#endif
|
||||
|
||||
|
||||
// for convenience and clarity, see fteextensions.qc for the rest of the SOUNDFLAG choices
|
||||
#define SOUNDFLAG_NONE 0
|
||||
|
||||
|
@ -66,10 +60,14 @@ enum TS_Team{
|
|||
|
||||
//TAGGG - Still need to remove some irrelevant ones like BUYZONE,, ESCAPEZONE, WON_T, etc.
|
||||
// Also starting at stat 34? Feel some constant would be more comfortable for that, might not be an option though.
|
||||
// ALSO - don't exceed 127, going by fteextensions.qc
|
||||
enum {
|
||||
STAT_MONEY = STAT_BUILTIN_SEPARATOR,
|
||||
|
||||
//STAT_TEAM, // will we ever need that?
|
||||
STAT_DEATHCAMERACHANGETIME,
|
||||
STAT_MINIMUMRESPAWNTIME,
|
||||
|
||||
//STAT_TEAM, // later
|
||||
STAT_GAMETIME,
|
||||
STAT_GAMESTATE,
|
||||
STAT_RULE_MONEYALLOWED,
|
||||
|
|
|
@ -37,6 +37,7 @@ void EV_TS_resetPlayer(player pl, BOOL resetInventory)
|
|||
|
||||
#ifdef CLIENT
|
||||
void EV_PlayerDeath(void)
|
||||
void EV_PlayerNoclip(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -390,8 +390,6 @@ EV_TS_resetPlayer(player pl, BOOL resetInventory){
|
|||
// keeping the event in case it has some use later.
|
||||
void
|
||||
EV_PlayerDeath(void){
|
||||
printfline("EV_PlayerDeath");
|
||||
|
||||
// Require a tiny amount of time and a mouse release before a respawn, so that
|
||||
// dying with the mouse held down isn't enough to trigger a respawn request.
|
||||
//pSeatLocal->m_bNeedPrimaryRelease = TRUE;
|
||||
|
@ -406,11 +404,27 @@ EV_PlayerDeath(void){
|
|||
|
||||
player pl = (player)self;
|
||||
pl.resetZoom();
|
||||
|
||||
// also this, anticipating that it will be shown after the DEAD_RECENT state is over
|
||||
pl.displayMinimumRespawnTimeCountdown = TRUE;
|
||||
|
||||
// force third-person while the player is in RECENT_DEAD at least
|
||||
pl.old_cl_thirdperson = cvar("cl_thirdperson");
|
||||
//autocvar_cl_thirdperson = 1i;
|
||||
cvar_set("cl_thirdperson", itos(1i));
|
||||
}
|
||||
|
||||
void
|
||||
EV_PlayerNoclip(void){
|
||||
player pl = (player)self;
|
||||
//autocvar_cl_thirdperson = pl.old_cl_thirdperson;
|
||||
cvar_set("cl_thirdperson", itos(pl.old_cl_thirdperson));
|
||||
//cvar_set("cl_thirdperson", ftos(0));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
//NOTICE - clientside components removed, except for clientside being able
|
||||
// to signal that the server should remove a weapon.
|
||||
|
|
|
@ -7,6 +7,7 @@ enum EVENT_TS{
|
|||
RESET_VIEW_MODEL,
|
||||
RESET_PLAYER,
|
||||
PLAYER_DEATH,
|
||||
PLAYER_NOCLIP,
|
||||
EV_IMPACT_MELEE,
|
||||
//DROP_WEAPON,
|
||||
FX_TS_EXPLOSION_GRENADE,
|
||||
|
|
|
@ -64,6 +64,12 @@ Game_Input(void)
|
|||
// not ingame (fake spectator)? Do another check instead: spawning.
|
||||
#ifdef CLIENT
|
||||
PreSpawn_Input();
|
||||
// since PreSpawn_Input may end early, guarantee this runs
|
||||
if(input_buttons & INPUT_BUTTON0){
|
||||
pl.gflags |= GF_SEMI_TOGGLED;
|
||||
}else{
|
||||
pl.gflags &= ~GF_SEMI_TOGGLED;
|
||||
}
|
||||
#endif
|
||||
// client or server, don't pay attention to the rest of this file if not spawned
|
||||
return;
|
||||
|
@ -411,9 +417,49 @@ void PreSpawn_Input(void){
|
|||
!(pl.gflags & GF_SEMI_TOGGLED) &&
|
||||
pSeatLocal->m_flBlockSpawnInputTime <= time
|
||||
){
|
||||
sendevent( "GamePlayerSpawn", "");
|
||||
|
||||
if(pl.iState == PLAYER_STATE::DEAD_RECENT){
|
||||
|
||||
if(getstatf(STAT_DEATHCAMERACHANGETIME) <= 1.5 + 0.35){
|
||||
// change, and fall-through to do the minimum respawn timer too.
|
||||
sendevent("GameEarlyNoclip", "");
|
||||
}else{
|
||||
// don't do anything
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(getstatf(STAT_MINIMUMRESPAWNTIME) < 0.35){
|
||||
// allow a little time before the countdown finishes to send the message anyway in case of lag,
|
||||
// should reach the server soon, no need for the countdown notice
|
||||
sendevent("GamePlayerSpawn", "");
|
||||
}else{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// show a printout of how long until the player can click to spawn.
|
||||
// TODO - use our own system instead to use a larger font, and the same one
|
||||
// used for the buymenu buttons, most things seem to do that.
|
||||
// Also, any 'Using New Config' centerprint will be overwritten by this instantly,
|
||||
// so there should probably be a check to let that one appear independently of this
|
||||
// countdown and below if both need to be shown.
|
||||
if(pl.iState == PLAYER_STATE::NOCLIP && pl.displayMinimumRespawnTimeCountdown){
|
||||
int roundedMinimumRespawnTime = (int)ceil(getstatf(STAT_MINIMUMRESPAWNTIME));
|
||||
if(roundedMinimumRespawnTime != 0){
|
||||
CSQC_Parse_CenterPrint(sprintf("%i", roundedMinimumRespawnTime));
|
||||
}else{
|
||||
// last one.
|
||||
pl.displayMinimumRespawnTimeCountdown = FALSE;
|
||||
CSQC_Parse_CenterPrint("Press fire to play!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if(
|
||||
((input_buttons & INPUT_BUTTON0) && pSeatLocal->m_flBlockSpawnInputTime > time) ||
|
||||
|
@ -426,12 +472,6 @@ void PreSpawn_Input(void){
|
|||
}
|
||||
*/
|
||||
|
||||
// since the rest of this method is about to be skipped.
|
||||
if(input_buttons & INPUT_BUTTON0){
|
||||
pl.gflags |= GF_SEMI_TOGGLED;
|
||||
}else{
|
||||
pl.gflags &= ~GF_SEMI_TOGGLED;
|
||||
}
|
||||
}//PreSpawn_Input
|
||||
|
||||
|
||||
|
|
|
@ -15,9 +15,11 @@ enum PLAYER_STATE{
|
|||
// Nothing special. Collision, gravity, equips things.
|
||||
SPAWNED = 0,
|
||||
// Like a third-person view of the player's most recent position, unsure
|
||||
// if it follows the corpse, try dying while moving in TS to see.
|
||||
// Slowly zooms out to a point.
|
||||
// Changes to DEAD_NOCLIP (aka "Fake Spectator") on clicking between 1
|
||||
// if it follows the corpse, try dying while moving in TS to see, my guess
|
||||
// is yes because it appears to behave like third-person.
|
||||
// Slowly zooms out to a point. I doubt wonkiness in dying in third-person
|
||||
// (already) was intentional.
|
||||
// Changes to NOCLIP (aka "Fake Spectator") on clicking between 1
|
||||
// and 2.5 seconds, or waiting out the 2.5 seconds (happens anyway)
|
||||
DEAD_RECENT,
|
||||
// Starts at the exact point where the dead player was.
|
||||
|
@ -51,9 +53,21 @@ class player:base_player
|
|||
|
||||
// On death, the player cannot change the camera to fake-specator until at least 1 second
|
||||
// has passed.
|
||||
// On death, set this to 2.5. If it is less than 1.5,
|
||||
// On death, set this to 2.5. If it is less than 1.5, allow clicking to reach
|
||||
#ifdef CLIENT
|
||||
BOOL displayMinimumRespawnTimeCountdown;
|
||||
int old_cl_thirdperson;
|
||||
#else
|
||||
// SERVER
|
||||
float deathCameraChangeTime;
|
||||
float minimumRespawnTime;
|
||||
BOOL waitingForSpawn;
|
||||
BOOL waitingForEarlyNoclip;
|
||||
|
||||
#endif
|
||||
|
||||
// Send everything in the inventory to the client this frame?
|
||||
// If not, only the one of the currently equipped weapon gets updated.
|
||||
BOOL completeInventorySend;
|
||||
|
||||
|
||||
|
@ -142,8 +156,6 @@ class player:base_player
|
|||
int equippedWeaponWaitingForCallback_ID;
|
||||
float equippedWeaponWaitingForCallback_maxWaitTime;
|
||||
|
||||
|
||||
|
||||
// For telling how long it's been since I've been on the ground.
|
||||
// Don't oscillate the view model bob on going down short steps.
|
||||
float flRecentGroundTime;
|
||||
|
@ -211,58 +223,32 @@ class player:base_player
|
|||
// ...also, this variable will be shared. Serverside since it must be presistent
|
||||
// (not just something to step away from after it happens the first frame), and
|
||||
// clientside to keep track of how to behave in case the connection is broken since.
|
||||
//vector vViewAngleOffsetTarget;
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// should be better networked when it's better understood what the block feature
|
||||
// (reload with karate out, I assume?) is supposed to do.
|
||||
float flKarateBlockCooldown;
|
||||
|
||||
PREDICTED_INT(iMeleeCycler);
|
||||
|
||||
|
||||
// SHARED
|
||||
// PREDICTED_whatever(...);
|
||||
//vector vViewAngleOffsetTarget;
|
||||
|
||||
/*
|
||||
vector vViewAngleOffsetEnd;
|
||||
vector vViewAngleOffsetStart;
|
||||
float flViewAngleOffsetLerp;
|
||||
vector vViewAngleOffsetCurrent;
|
||||
vector vViewAngleOffsetTarget;
|
||||
vector vViewAngleMemory;
|
||||
*/
|
||||
//vector vViewAngleOffsetEnd;
|
||||
//vector vViewAngleOffsetStart;
|
||||
//float flViewAngleOffsetLerp;
|
||||
//vector vViewAngleOffsetCurrent;
|
||||
PREDICTED_FLOAT(flViewAngleOffsetTarget);
|
||||
PREDICTED_VECTOR(vViewAngleOffsetTargetDir);
|
||||
//vector vViewAngleMemory;
|
||||
|
||||
//vector vViewAngleOffsetTotalChange;
|
||||
PREDICTED_VECTOR(vViewAngleOffsetTotalChange);
|
||||
#ifdef SERVER
|
||||
vector vViewAngleOffsetTotalChangeAlt;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
PREDICTED_FLOAT(fAccuracyKickback);
|
||||
PREDICTED_FLOAT(fAccuracyKickbackStartCooldown);
|
||||
|
||||
// The client can keep its own in mind as prediction between frames if needed. Server
|
||||
// time and client time aren't really compatible to send like this.
|
||||
|
||||
|
||||
|
||||
PREDICTED_FLOAT(fMoveBlockDelay);
|
||||
PREDICTED_FLOAT(fUncrouchBlockDelay);
|
||||
// not networked, set by the player individually client and serverside on picking
|
||||
|
@ -271,8 +257,8 @@ class player:base_player
|
|||
PREDICTED_FLOAT(fKarateStamina);
|
||||
|
||||
|
||||
//These will be shared and help with slowdown logic.
|
||||
//They are all 0 to 1.0 (normal) unless there are further restrictions.
|
||||
// These will be shared and help with slowdown logic.
|
||||
// They are all 0 to 1.0 (normal) unless there are further restrictions.
|
||||
float flBaseSpeedMulti; //How should miscelaneous things be affected (client animation)?
|
||||
float flMoveSpeedMulti; //how is move speed affected?
|
||||
float flSoundSpeedMulti; //can range from 0.5 to 1.
|
||||
|
@ -283,8 +269,6 @@ class player:base_player
|
|||
float flProjectileSpeedMulti; //how are non-projectiles (grenades, knives, etc.) affected?
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO - see how to handle saving / loadig these on the client's end.
|
||||
//Server probably dosen't need to store config stuff at all.
|
||||
#ifdef CLIENT
|
||||
|
@ -323,8 +307,6 @@ class player:base_player
|
|||
float flViewShake;
|
||||
|
||||
#else
|
||||
//serverside
|
||||
float nextUseCooldown;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -296,7 +296,7 @@ player::ReceiveEntity(float new, float fl)
|
|||
this.completeInventorySend = readbyte();
|
||||
|
||||
#ifdef FORCE_NETWORK_ALL_INVENTORY
|
||||
completeInventorySend = TRUE;
|
||||
this.completeInventorySend = TRUE;
|
||||
#endif
|
||||
|
||||
if(this.completeInventorySend){
|
||||
|
@ -1004,6 +1004,11 @@ player::reset(BOOL resetInventory){
|
|||
// should this even make any assumptions about this?
|
||||
//iState = ?;
|
||||
|
||||
// seem like good ideas?
|
||||
#ifdef SERVER
|
||||
dmg_take = 0;
|
||||
dmg_inflictor = NULL;
|
||||
#endif
|
||||
|
||||
resetZoom();
|
||||
|
||||
|
@ -1037,12 +1042,19 @@ player::reset(BOOL resetInventory){
|
|||
|
||||
forceViewModelUpdate = FALSE;
|
||||
prev_iForceBodygroup1Submodel = 0;
|
||||
|
||||
|
||||
// assuming the player is in spectator and wanting to spawn soon.
|
||||
displayMinimumRespawnTimeCountdown = TRUE;
|
||||
old_cl_thirdperson = 0;
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
switchToRecentlyAddedWeapon = FALSE;
|
||||
nextUseCooldown = 0;
|
||||
|
||||
deathCameraChangeTime = 0;
|
||||
minimumRespawnTime = 0;
|
||||
waitingForSpawn = FALSE;
|
||||
waitingForEarlyNoclip = FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1683,11 +1695,47 @@ player::callWeaponThink(void){
|
|||
|
||||
void
|
||||
player::frameThink_fromServer(void){
|
||||
TSMultiplayerRules rules;
|
||||
|
||||
// no, leave that to shared/input.qc
|
||||
//updateTimers();
|
||||
|
||||
//preThinkShared();
|
||||
|
||||
// only in DEAD_RECENT. This is the temporary third-person for looking at the recently
|
||||
// dead player (self). After the countdown is over, goto the NOCLIP one.
|
||||
if(iState == PLAYER_STATE::DEAD_RECENT){
|
||||
|
||||
if(deathCameraChangeTime > 0){
|
||||
deathCameraChangeTime -= frametime;
|
||||
}
|
||||
if(deathCameraChangeTime <= 0 || (waitingForEarlyNoclip && deathCameraChangeTime <= 1.5) ){
|
||||
// time's up? Go ahead and change
|
||||
deathCameraChangeTime = 0;
|
||||
rules = (TSMultiplayerRules)g_grMode;
|
||||
rules.PlayerMakeSpectatorAndNotify(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(iState != PLAYER_STATE::SPAWNED){
|
||||
// Once this delay has passed, spawning is allowed.
|
||||
// If the click was very close to the end (waitingForSpawn), count it and spawn
|
||||
// as soon as possible anyway, helps with some lag perhaps.
|
||||
if(minimumRespawnTime > 0){
|
||||
minimumRespawnTime -= frametime;
|
||||
if(minimumRespawnTime <= 0){
|
||||
minimumRespawnTime = 0;
|
||||
if(waitingForSpawn){
|
||||
// do it!
|
||||
rules = (TSMultiplayerRules)g_grMode;
|
||||
rules.PlayerMakePlayableWithDefaultMoney(this);
|
||||
}else{
|
||||
// Nothing special happens, user must click to spawn.
|
||||
}
|
||||
}
|
||||
}
|
||||
}// not-SPAWNED check
|
||||
|
||||
|
||||
}// frameThink_fromServer
|
||||
|
|
Loading…
Reference in a new issue