cs16-client-legacy/dlls/doors.cpp

958 lines
22 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#include "stdafx.h"
#include "cbase.h"
#include "doors.h"
extern void SetMovedir(entvars_t *ev);
#define noiseMoving noise1
#define noiseArrived noise2
class CBaseDoor : public CBaseToggle
{
public:
void Spawn(void);
void Restart(void);
void Precache(void);
void KeyValue(KeyValueData *pkvd);
void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Blocked(CBaseEntity *pOther);
int ObjectCaps(void)
{
if (pev->spawnflags & SF_ITEM_USE_ONLY)
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE;
else
return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION);
};
int Save(CSave &save);
int Restore(CRestore &restore);
void SetToggleState(int state);
public:
static TYPEDESCRIPTION m_SaveData[];
public:
void EXPORT DoorTouch(CBaseEntity *pOther);
int DoorActivate(void);
void EXPORT DoorGoUp(void);
void EXPORT DoorGoDown(void);
void EXPORT DoorHitTop(void);
void EXPORT DoorHitBottom(void);
public:
BYTE m_bHealthValue;
BYTE m_bMoveSnd;
BYTE m_bStopSnd;
locksound_t m_ls;
BYTE m_bLockedSound;
BYTE m_bLockedSentence;
BYTE m_bUnlockedSound;
BYTE m_bUnlockedSentence;
float m_lastBlockedTimestamp;
};
TYPEDESCRIPTION CBaseDoor::m_SaveData[] =
{
DEFINE_FIELD(CBaseDoor, m_bHealthValue, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bMoveSnd, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bStopSnd, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bLockedSound, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bLockedSentence, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bUnlockedSound, FIELD_CHARACTER),
DEFINE_FIELD(CBaseDoor, m_bUnlockedSentence, FIELD_CHARACTER),
};
IMPLEMENT_SAVERESTORE(CBaseDoor, CBaseToggle);
#define DOOR_SENTENCEWAIT 6
#define DOOR_SOUNDWAIT 3
#define BUTTON_SOUNDWAIT 0.5
void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton)
{
float flsoundwait = fbutton ? BUTTON_SOUNDWAIT : DOOR_SOUNDWAIT;
if (flocked)
{
int fplaysound = (pls->sLockedSound && gpGlobals->time > pls->flwaitSound);
int fplaysentence = (pls->sLockedSentence && !pls->bEOFLocked && gpGlobals->time > pls->flwaitSentence);
float fvol = (fplaysound && fplaysentence) ? 0.25 : 1;
if (fplaysound)
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, (char *)STRING(pls->sLockedSound), fvol, ATTN_NORM);
pls->flwaitSound = gpGlobals->time + flsoundwait;
}
if (fplaysentence)
{
int iprev = pls->iLockedSentence;
pls->iLockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sLockedSentence), 0.85, ATTN_NORM, 0, 100, pls->iLockedSentence, FALSE);
pls->iUnlockedSentence = 0;
pls->bEOFLocked = (iprev == pls->iLockedSentence);
pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT;
}
}
else
{
int fplaysound = (pls->sUnlockedSound && gpGlobals->time > pls->flwaitSound);
int fplaysentence = (pls->sUnlockedSentence && !pls->bEOFUnlocked && gpGlobals->time > pls->flwaitSentence);
float fvol = (fplaysound && fplaysentence) ? 0.25 : 1;
if (fplaysound)
{
EMIT_SOUND(ENT(pev), CHAN_ITEM, (char *)STRING(pls->sUnlockedSound), fvol, ATTN_NORM);
pls->flwaitSound = gpGlobals->time + flsoundwait;
}
if (fplaysentence)
{
int iprev = pls->iUnlockedSentence;
pls->iUnlockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sUnlockedSentence), 0.85, ATTN_NORM, 0, 100, pls->iUnlockedSentence, FALSE);
pls->iLockedSentence = 0;
pls->bEOFUnlocked = (iprev == pls->iUnlockedSentence);
pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT;
}
}
}
void CBaseDoor::KeyValue(KeyValueData *pkvd)
{
if (FStrEq(pkvd->szKeyName, "skin"))
{
pev->skin = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "movesnd"))
{
m_bMoveSnd = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "stopsnd"))
{
m_bStopSnd = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "healthvalue"))
{
m_bHealthValue = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "locked_sound"))
{
m_bLockedSound = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "locked_sentence"))
{
m_bLockedSentence = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "unlocked_sound"))
{
m_bUnlockedSound = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "unlocked_sentence"))
{
m_bUnlockedSentence = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "WaveHeight"))
{
pev->scale = atof(pkvd->szValue) * (1.0 / 8);
pkvd->fHandled = TRUE;
}
else
CBaseToggle::KeyValue(pkvd);
}
LINK_ENTITY_TO_CLASS(func_door, CBaseDoor);
LINK_ENTITY_TO_CLASS(func_water, CBaseDoor);
void CBaseDoor::Spawn(void)
{
Precache();
SetMovedir(pev);
if (pev->skin == 0)
{
if (FBitSet(pev->spawnflags, SF_DOOR_PASSABLE))
pev->solid = SOLID_NOT;
else
pev->solid = SOLID_BSP;
}
else
{
pev->solid = SOLID_NOT;
SetBits(pev->spawnflags, SF_DOOR_SILENT);
}
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model));
if (pev->speed == 0)
pev->speed = 100;
m_vecPosition1 = pev->origin;
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs(pev->movedir.x * (pev->size.x - 2)) + fabs(pev->movedir.y * (pev->size.y - 2)) + fabs(pev->movedir.z * (pev->size.z - 2)) - m_flLip));
if (FBitSet(pev->spawnflags, SF_DOOR_START_OPEN))
{
UTIL_SetOrigin(pev, m_vecPosition2);
m_vecPosition2 = m_vecPosition1;
m_vecPosition1 = pev->origin;
}
m_toggle_state = TS_AT_BOTTOM;
if (FBitSet(pev->spawnflags, SF_DOOR_USE_ONLY))
SetTouch(NULL);
else
SetTouch(&CBaseDoor::DoorTouch);
m_lastBlockedTimestamp = 0;
}
void CBaseDoor::Restart(void)
{
SetMovedir(pev);
m_toggle_state = TS_AT_BOTTOM;
DoorGoDown();
if (FBitSet(pev->spawnflags, SF_DOOR_USE_ONLY))
SetTouch(NULL);
else
SetTouch(&CBaseDoor::DoorTouch);
}
void CBaseDoor::SetToggleState(int state)
{
if (state == TS_AT_TOP)
UTIL_SetOrigin(pev, m_vecPosition2);
else
UTIL_SetOrigin(pev, m_vecPosition1);
}
void CBaseDoor::Precache(void)
{
switch (m_bMoveSnd)
{
case 0: pev->noiseMoving = ALLOC_STRING("common/null.wav"); break;
case 1:
{
PRECACHE_SOUND("doors/doormove1.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav");
break;
}
case 2:
{
PRECACHE_SOUND("doors/doormove2.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav");
break;
}
case 3:
{
PRECACHE_SOUND("doors/doormove3.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav");
break;
}
case 4:
{
PRECACHE_SOUND("doors/doormove4.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav");
break;
}
case 5:
{
PRECACHE_SOUND("doors/doormove5.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav");
break;
}
case 6:
{
PRECACHE_SOUND("doors/doormove6.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav");
break;
}
case 7:
{
PRECACHE_SOUND("doors/doormove7.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav");
break;
}
case 8:
{
PRECACHE_SOUND("doors/doormove8.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav");
break;
}
case 9:
{
PRECACHE_SOUND("doors/doormove9.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove9.wav");
break;
}
case 10:
{
PRECACHE_SOUND("doors/doormove10.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove10.wav");
break;
}
default: pev->noiseMoving = ALLOC_STRING("common/null.wav"); break;
}
switch (m_bStopSnd)
{
case 0: pev->noiseArrived = ALLOC_STRING("common/null.wav"); break;
case 1:
{
PRECACHE_SOUND("doors/doorstop1.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop1.wav");
break;
}
case 2:
{
PRECACHE_SOUND("doors/doorstop2.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop2.wav");
break;
}
case 3:
{
PRECACHE_SOUND("doors/doorstop3.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav");
break;
}
case 4:
{
PRECACHE_SOUND("doors/doorstop4.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop4.wav");
break;
}
case 5:
{
PRECACHE_SOUND("doors/doorstop5.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop5.wav");
break;
}
case 6:
{
PRECACHE_SOUND("doors/doorstop6.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop6.wav");
break;
}
case 7:
{
PRECACHE_SOUND("doors/doorstop7.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop7.wav");
break;
}
case 8:
{
PRECACHE_SOUND("doors/doorstop8.wav");
pev->noiseArrived = ALLOC_STRING("doors/doorstop8.wav");
break;
}
default: pev->noiseArrived = ALLOC_STRING("common/null.wav"); break;
}
if (m_bLockedSound)
{
char *pszSound = ButtonSound((int)m_bLockedSound);
PRECACHE_SOUND(pszSound);
m_ls.sLockedSound = ALLOC_STRING(pszSound);
}
if (m_bUnlockedSound)
{
char *pszSound = ButtonSound((int)m_bUnlockedSound);
PRECACHE_SOUND(pszSound);
m_ls.sUnlockedSound = ALLOC_STRING(pszSound);
}
switch (m_bLockedSentence)
{
case 1: m_ls.sLockedSentence = ALLOC_STRING("NA"); break;
case 2: m_ls.sLockedSentence = ALLOC_STRING("ND"); break;
case 3: m_ls.sLockedSentence = ALLOC_STRING("NF"); break;
case 4: m_ls.sLockedSentence = ALLOC_STRING("NFIRE"); break;
case 5: m_ls.sLockedSentence = ALLOC_STRING("NCHEM"); break;
case 6: m_ls.sLockedSentence = ALLOC_STRING("NRAD"); break;
case 7: m_ls.sLockedSentence = ALLOC_STRING("NCON"); break;
case 8: m_ls.sLockedSentence = ALLOC_STRING("NH"); break;
case 9: m_ls.sLockedSentence = ALLOC_STRING("NG"); break;
default: m_ls.sLockedSentence = 0; break;
}
switch (m_bUnlockedSentence)
{
case 1: m_ls.sUnlockedSentence = ALLOC_STRING("EA"); break;
case 2: m_ls.sUnlockedSentence = ALLOC_STRING("ED"); break;
case 3: m_ls.sUnlockedSentence = ALLOC_STRING("EF"); break;
case 4: m_ls.sUnlockedSentence = ALLOC_STRING("EFIRE"); break;
case 5: m_ls.sUnlockedSentence = ALLOC_STRING("ECHEM"); break;
case 6: m_ls.sUnlockedSentence = ALLOC_STRING("ERAD"); break;
case 7: m_ls.sUnlockedSentence = ALLOC_STRING("ECON"); break;
case 8: m_ls.sUnlockedSentence = ALLOC_STRING("EH"); break;
default: m_ls.sUnlockedSentence = 0; break;
}
}
void CBaseDoor::DoorTouch(CBaseEntity *pOther)
{
entvars_t *pevToucher = pOther->pev;
if (pevToucher->deadflag != DEAD_NO)
return;
if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, pOther))
PlayLockSounds(pev, &m_ls, TRUE, FALSE);
if (!FStringNull(pev->targetname))
{
PlayLockSounds(pev, &m_ls, TRUE, FALSE);
return;
}
m_hActivator = pOther;
if (DoorActivate())
SetTouch(NULL);
}
void CBaseDoor::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
m_hActivator = pActivator;
if (m_toggle_state == TS_AT_BOTTOM || FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP)
DoorActivate();
}
int CBaseDoor::DoorActivate(void)
{
if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator))
return 0;
if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP)
{
DoorGoDown();
return 1;
}
if (m_hActivator != 0 && m_hActivator->IsPlayer())
m_hActivator->TakeHealth(m_bHealthValue, DMG_GENERIC);
PlayLockSounds(pev, &m_ls, FALSE, FALSE);
DoorGoUp();
return 1;
}
extern Vector VecBModelOrigin(entvars_t *pevBModel);
void CBaseDoor::DoorGoUp(void)
{
entvars_t *pevActivator;
bool isReversing = m_toggle_state == TS_GOING_DOWN;
ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN);
if (m_toggle_state != TS_GOING_DOWN)
{
if (!FBitSet(pev->spawnflags, SF_DOOR_SILENT))
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), 1, ATTN_NORM);
}
m_toggle_state = TS_GOING_UP;
SetMoveDone(&CBaseDoor::DoorHitTop);
if (FClassnameIs(pev, "func_door_rotating"))
{
float sign = 1;
if (m_hActivator != 0)
{
pevActivator = m_hActivator->pev;
if (!FBitSet(pev->spawnflags, SF_DOOR_ONEWAY) && pev->movedir.y)
{
float loX = pev->mins.x + pev->origin.x;
float loY = pev->mins.y + pev->origin.y;
float hiX = pev->maxs.x + pev->origin.x;
float hiY = pev->maxs.y + pev->origin.y;
float momentArmX = pevActivator->origin.x - pev->origin.x;
float momentArmY = pevActivator->origin.y - pev->origin.y;
if (loX > pevActivator->origin.x)
{
if (pevActivator->origin.y < loY)
{
if (fabs(momentArmY) > fabs(momentArmX))
sign = (momentArmY < 0) ? 1 : -1;
else
sign = (momentArmX > 0) ? 1 : -1;
}
else if (pevActivator->origin.y > hiY)
{
if (fabs(momentArmY) > fabs(momentArmX))
sign = (momentArmY < 0) ? 1 : -1;
else
sign = (momentArmX < 0) ? 1 : -1;
}
else
sign = (momentArmY < 0) ? 1 : -1;
}
else
{
if (pevActivator->origin.x <= hiX)
{
if (pevActivator->origin.y > loY)
sign = (momentArmX > 0) ? 1 : -1;
else if (pevActivator->origin.y > hiY)
sign = (momentArmX < 0) ? 1 : -1;
}
else if (pevActivator->origin.y < loY)
{
if (fabs(momentArmY) > fabs(momentArmX))
sign = (momentArmY > 0) ? 1 : -1;
else
sign = (momentArmX > 0) ? 1 : -1;
}
else if (pevActivator->origin.y > hiY)
{
if (fabs(momentArmY) > fabs(momentArmX))
sign = (momentArmY > 0) ? 1 : -1;
else
sign = (momentArmX < 0) ? 1 : -1;
}
else
sign = (momentArmY > 0) ? 1 : -1;
}
if (isReversing)
sign = -sign;
}
}
AngularMove(m_vecAngle2 * sign, pev->speed);
}
else
LinearMove(m_vecPosition2, pev->speed);
}
void CBaseDoor::DoorHitTop(void)
{
if (!FBitSet(pev->spawnflags, SF_DOOR_SILENT))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), 1, ATTN_NORM);
}
ASSERT(m_toggle_state == TS_GOING_UP);
m_toggle_state = TS_AT_TOP;
if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN))
{
if (!FBitSet(pev->spawnflags, SF_DOOR_USE_ONLY))
SetTouch(&CBaseDoor::DoorTouch);
}
else
{
pev->nextthink = pev->ltime + m_flWait;
SetThink(&CBaseDoor::DoorGoDown);
if (m_flWait == -1)
pev->nextthink = -1;
}
if (pev->netname && (pev->spawnflags & SF_DOOR_START_OPEN))
FireTargets(STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0);
SUB_UseTargets(m_hActivator, USE_TOGGLE, 0);
}
void CBaseDoor::DoorGoDown(void)
{
if (m_toggle_state != TS_GOING_UP)
{
if (!FBitSet(pev->spawnflags, SF_DOOR_SILENT))
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), VOL_NORM, ATTN_NORM);
}
#ifdef DOOR_ASSERT
ASSERT(m_toggle_state == TS_AT_TOP);
#endif
m_toggle_state = TS_GOING_DOWN;
SetMoveDone(&CBaseDoor::DoorHitBottom);
if (FClassnameIs(pev, "func_door_rotating"))
AngularMove(m_vecAngle1, pev->speed);
else
LinearMove(m_vecPosition1, pev->speed);
}
void CBaseDoor::DoorHitBottom(void)
{
if (!FBitSet(pev->spawnflags, SF_DOOR_SILENT))
{
STOP_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving));
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseArrived), VOL_NORM, ATTN_NORM);
}
ASSERT(m_toggle_state == TS_GOING_DOWN);
m_toggle_state = TS_AT_BOTTOM;
if (FBitSet(pev->spawnflags, SF_DOOR_USE_ONLY))
SetTouch(NULL);
else
SetTouch(&CBaseDoor::DoorTouch);
SUB_UseTargets(m_hActivator, USE_TOGGLE, 0);
if (pev->netname && !(pev->spawnflags & SF_DOOR_START_OPEN))
FireTargets(STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0);
}
void CBaseDoor::Blocked(CBaseEntity *pOther)
{
edict_t *pentTarget = NULL;
if (pev->dmg)
pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH);
if (gpGlobals->time - m_lastBlockedTimestamp >= 0.25)
{
m_lastBlockedTimestamp = gpGlobals->time;
if (m_flWait >= 0)
{
if (m_toggle_state == TS_GOING_DOWN)
DoorGoUp();
else
DoorGoDown();
}
if (!FStringNull(pev->targetname))
{
edict_t *pentTarget = NULL;
while (1)
{
pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->targetname));
if (VARS(pentTarget) != pev)
{
if (FNullEnt(pentTarget))
break;
if (FClassnameIs(pentTarget, "func_door") || FClassnameIs(pentTarget, "func_door_rotating"))
{
CBaseDoor *pDoor = GetClassPtr((CBaseDoor *)VARS(pentTarget));
if (pDoor->m_flWait >= 0)
{
if (pDoor->pev->velocity == pev->velocity && pDoor->pev->avelocity == pev->velocity)
{
if (FClassnameIs(pentTarget, "func_door"))
{
pDoor->pev->origin = pev->origin;
pDoor->pev->velocity = g_vecZero;
}
else
{
pDoor->pev->angles = pev->angles;
pDoor->pev->avelocity = g_vecZero;
}
}
if (pDoor->m_toggle_state == TS_GOING_DOWN)
pDoor->DoorGoUp();
else
pDoor->DoorGoDown();
}
}
}
}
}
}
}
class CRotDoor : public CBaseDoor
{
public:
void Restart(void);
void Spawn(void);
void SetToggleState(int state);
};
LINK_ENTITY_TO_CLASS(func_door_rotating, CRotDoor);
void CRotDoor::Restart(void)
{
CBaseToggle::AxisDir(pev);
if (FBitSet(pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS))
pev->movedir = pev->movedir * -1;
if (pev->speed == 0)
pev->speed = 100;
if (FBitSet(pev->spawnflags, SF_DOOR_START_OPEN))
{
pev->angles = m_vecAngle2;
Vector vecSav = m_vecAngle1;
m_vecAngle2 = m_vecAngle1;
m_vecAngle1 = vecSav;
pev->movedir = pev->movedir * -1;
}
m_toggle_state = TS_AT_BOTTOM;
DoorGoDown();
}
void CRotDoor::Spawn(void)
{
Precache();
CBaseToggle::AxisDir(pev);
if (FBitSet(pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS))
pev->movedir = pev->movedir * -1;
m_vecAngle1 = pev->angles;
m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance;
if (FBitSet(pev->spawnflags, SF_DOOR_PASSABLE))
pev->solid = SOLID_NOT;
else
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model));
if (pev->speed == 0)
pev->speed = 100;
if (FBitSet(pev->spawnflags, SF_DOOR_START_OPEN))
{
pev->angles = m_vecAngle2;
Vector vecSav = m_vecAngle1;
m_vecAngle2 = m_vecAngle1;
m_vecAngle1 = vecSav;
pev->movedir = pev->movedir * -1;
}
m_toggle_state = TS_AT_BOTTOM;
if (FBitSet(pev->spawnflags, SF_DOOR_USE_ONLY))
SetTouch(NULL);
else
SetTouch(&CBaseDoor::DoorTouch);
}
void CRotDoor::SetToggleState(int state)
{
if (state == TS_AT_TOP)
pev->angles = m_vecAngle2;
else
pev->angles = m_vecAngle1;
UTIL_SetOrigin(pev, pev->origin);
}
class CMomentaryDoor : public CBaseToggle
{
public:
void Spawn(void);
void Precache(void);
void KeyValue(KeyValueData *pkvd);
void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
int ObjectCaps(void) { return CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
int Save(CSave &save);
int Restore(CRestore &restore);
public:
static TYPEDESCRIPTION m_SaveData[];
public:
BYTE m_bMoveSnd;
};
LINK_ENTITY_TO_CLASS(momentary_door, CMomentaryDoor);
TYPEDESCRIPTION CMomentaryDoor::m_SaveData[] =
{
DEFINE_FIELD(CMomentaryDoor, m_bMoveSnd, FIELD_CHARACTER),
};
IMPLEMENT_SAVERESTORE(CMomentaryDoor, CBaseToggle);
void CMomentaryDoor::Spawn(void)
{
SetMovedir(pev);
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
UTIL_SetOrigin(pev, pev->origin);
SET_MODEL(ENT(pev), STRING(pev->model));
if (pev->speed == 0)
pev->speed = 100;
if (pev->dmg == 0)
pev->dmg = 2;
m_vecPosition1 = pev->origin;
m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs(pev->movedir.x * (pev->size.x - 2)) + fabs(pev->movedir.y * (pev->size.y - 2)) + fabs(pev->movedir.z * (pev->size.z - 2)) - m_flLip));
if (FBitSet(pev->spawnflags, SF_DOOR_START_OPEN))
{
UTIL_SetOrigin(pev, m_vecPosition2);
m_vecPosition2 = m_vecPosition1;
m_vecPosition1 = pev->origin;
}
SetTouch(NULL);
Precache();
}
void CMomentaryDoor::Precache(void)
{
switch (m_bMoveSnd)
{
case 0: pev->noiseMoving = ALLOC_STRING("common/null.wav"); break;
case 1:
{
PRECACHE_SOUND("doors/doormove1.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav");
break;
}
case 2:
{
PRECACHE_SOUND("doors/doormove2.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav");
break;
}
case 3:
{
PRECACHE_SOUND("doors/doormove3.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav");
break;
}
case 4:
{
PRECACHE_SOUND("doors/doormove4.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav");
break;
}
case 5:
{
PRECACHE_SOUND("doors/doormove5.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav");
break;
}
case 6:
{
PRECACHE_SOUND("doors/doormove6.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav");
break;
}
case 7:
{
PRECACHE_SOUND("doors/doormove7.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav");
break;
}
case 8:
{
PRECACHE_SOUND("doors/doormove8.wav");
pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav");
break;
}
default: pev->noiseMoving = ALLOC_STRING("common/null.wav"); break;
}
}
void CMomentaryDoor::KeyValue(KeyValueData *pkvd)
{
if (FStrEq(pkvd->szKeyName, "movesnd"))
{
m_bMoveSnd = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "stopsnd"))
{
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "healthvalue"))
{
pkvd->fHandled = TRUE;
}
else
CBaseToggle::KeyValue(pkvd);
}
void CMomentaryDoor::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
if (useType != USE_SET)
return;
if (value > 1)
value = 1;
Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1));
Vector delta = move - pev->origin;
float speed = delta.Length() * 10;
if (speed)
{
if (pev->nextthink < pev->ltime || !pev->nextthink)
EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), VOL_NORM, ATTN_NORM);
LinearMove(move, speed);
}
}