📄 doors.cpp
字号:
//-----------------------------------------------------------------------------
//
// $Logfile:: /Quake 2 Engine/Sin/code/game/doors.cpp $
// $Revision:: 71 $
// $Author:: Markd $
// $Date:: 11/16/98 9:48p $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/doors.cpp $
//
// 71 11/16/98 9:48p Markd
// made door sounds always stop to kill looping sounds
//
// 70 11/13/98 4:35p Jimdose
// doors weren't staying open when wait was -1
//
// 69 10/24/98 3:25a Jimdose
// open was postponing the close event further and further into the future due
// to touchfield activation. Changed it to a cancel and a post of close.
// fixes doors staying open
//
// 68 10/24/98 12:42a Markd
// changed origins to worldorigins where appropriate
//
// 67 10/23/98 11:10p Jimdose
// removed trigger_finished
// Close now cancels pending close events. Hopefully this fixes the spinning
// door bug.
//
// 66 10/23/98 10:12p Jimdose
// fixed bug where doors don't close after actors open them
// fixed code that determines direction door should open
//
// 65 10/21/98 10:58p Jimdose
// fixed (hopefully) most of the door bugs
//
// 64 10/21/98 2:35a Jimdose
// Don't spawn trigger field when DOOR_TOGGLE is set
//
// 63 10/19/98 12:07a Jimdose
// made all code use fast checks for inheritance (no text lookups when
// possible)
// isSubclassOf no longer requires ::_classinfo()
//
// 62 10/16/98 8:24p Jimdose
// Put some extra checks in to make sure master is set
//
// 61 10/07/98 4:11p Markd
// Fixed using of doors
//
// 60 10/06/98 6:07p Markd
// Fixed door message code
//
// 59 10/02/98 7:45p Markd
// put in more door debug info
//
// 58 9/30/98 3:42p Markd
// put in bulletproofing for start thread functions
//
// 57 9/24/98 1:50a Jimdose
// Fixed side of door checks when opening doors
//
// 56 9/23/98 2:19p Markd
// made all doors play sounds not just the masters
//
// 55 9/23/98 1:31p Markd
// changed default door sound documentation
//
// 54 9/22/98 4:23p Markd
// Fixed some targetname stuff for lights, doors and scriptobjects
//
// 53 9/03/98 9:07p Jimdose
// Added CanBeOpenedBy so that the AI can check if a door is useable by an
// actor
// changed owner to master
// Fixed bug with doors that don't stop
// opened doors can be used again to close them
// fixed door blocked
//
// 52 8/28/98 4:14p Markd
// Added sound_locked support
//
// 51 8/26/98 6:43p Jimdose
// doors now only show the item needed when other is a client
//
// 50 8/24/98 6:10p Markd
// Added killable doors, that stop for nothing
//
// 49 8/24/98 5:47p Markd
// Fixed triggerable doors
//
// 48 8/24/98 11:32a Markd
// Added Start method to threads, repladed all ProcessEvent(
// EV_ScriptThread_execute) with thread->Start( -1 )
//
// 47 8/21/98 3:48p Markd
// Added openthread and closethread events
//
// 46 8/21/98 1:43a Markd
// Added full ScriptDoor functionality
//
// 45 8/18/98 11:08p Markd
// Added new Alias System
//
// 44 8/15/98 10:42a Markd
// took out auto-open for actors for non-sin-demo
//
// 43 8/14/98 8:18p Markd
// Fixed silly str thing to get rid of weird messages.
//
// 42 8/13/98 4:57p Jimdose
// Made Open check if there are any event args. If not, it prints a warning so
// that the level designers know.
//
// 41 8/03/98 7:52p Jimdose
// added hack fix doors for matt
//
// 40 7/29/98 2:31p Aldie
// Changed health to a float
//
// 39 7/26/98 3:40p Jimdose
// locked doors don't autoopen for actors
//
// 38 7/26/98 9:51a Markd
// fixed "snd_locked" bug
//
// 37 7/26/98 9:22a Jimdose
// Doors auto-open for actors
//
// 36 7/26/98 1:03a Markd
// Fixed door trigger field
//
// 35 7/26/98 12:48a Jimdose
// Fixed calculating bbox in LinkDoors
//
// 34 7/23/98 6:17p Aldie
// Updated damage system and fixed some damage related bugs. Also put tracers
// back to the way they were, and added gib event to funcscriptmodels
//
// 33 7/21/98 4:22p Aldie
// Make icons work for locks
//
// 32 7/21/98 1:10p Aldie
// Added meansofdeath to obituaries
//
// 31 7/20/98 10:15a Markd
// Fixed funky door problem
//
// 30 7/18/98 4:42p Markd
// Added snd_locked support for locked doors
//
// 29 7/11/98 4:49p Markd
// Fixed minor bug in door code with not setting other
//
// 28 7/11/98 4:46p Markd
// Fixed doors not being lockable
//
// 27 7/10/98 10:34p Markd
// Fixed locked doors
//
// 26 7/10/98 2:09p Markd
// Added locking capability to doors
//
// 25 6/30/98 6:03p Jimdose
// TryOpen now checks if other is NULL
//
// 24 6/28/98 3:15p Markd
// Fixed sliding doors
//
// 23 6/27/98 2:17p Aldie
// Updated centerprint to use new method
//
// 22 6/25/98 8:48p Markd
// Merged RotatingDoors and regular Doors
//
// 21 6/24/98 8:45p Markd
// Rewrote door code
//
// 12 6/17/98 10:14p Jimdose
// Added isOpen for AI
// Made doors stay open while an entity is in its trigger field.
//
// 11 6/10/98 2:10p Aldie
// Updated damage function.
//
// 10 6/04/98 4:35p Markd
// made door sounds not use PHS
//
// 9 5/24/98 8:55p Jimdose
// Removed the char * cast from soundindex call
//
// 8 5/24/98 8:46p Jimdose
// Made a lot of functions more str-friendly.
// Got rid of a lot of char * based strings
// Cleaned up get spawn arg functions and sound functions
// sound functions now use consistant syntax
//
// 7 5/24/98 3:42p Markd
// fixed str bug
//
// 6 5/24/98 2:46p Markd
// Made char *'s into const char *'s
//
// 5 5/24/98 1:04a Jimdose
// Added sound events for ai
//
// 4 5/22/98 9:38p Jimdose
// added DoorBlocked
//
// 3 5/03/98 4:36p Jimdose
// Changed Vector class
//
// 2 4/29/98 9:55p Jimdose
// Created file
//
// DESCRIPTION:
// Doors are environment objects that rotate open when activated by triggers
// or when used by the player.
//
#include "g_local.h"
#include "entity.h"
#include "trigger.h"
#include "mover.h"
#include "doors.h"
#include "sentient.h"
#include "areaportal.h"
#include "scriptmaster.h"
#include "item.h"
#include "actor.h"
#include "player.h"
Event EV_Door_TriggerFieldTouched( "door_triggerfield" );
Event EV_Door_TryOpen( "tryToOpen" );
Event EV_Door_Close( "close" );
Event EV_Door_Open( "open" );
Event EV_Door_DoClose( "doclose" );
Event EV_Door_DoOpen( "doopen" );
Event EV_Door_CloseEnd( "doorclosed" );
Event EV_Door_OpenEnd( "dooropened" );
Event EV_Door_Fire( "toggledoor" );
Event EV_Door_Link( "linkdoor" );
Event EV_Door_SetTime( "time" );
Event EV_Door_Lock( "lock" );
Event EV_Door_Unlock( "unlock" );
CLASS_DECLARATION( ScriptSlave, Door, "NormalDoor" );
#define DOOR_START_OPEN 1
#define DOOR_OPEN_DIRECTION 2
#define DOOR_DONT_LINK 4
#define DOOR_TOGGLE 32
#define DOOR_AUTO_OPEN 64
#define DOOR_TARGETED 128
#define STATE_OPEN 1
#define STATE_OPENING 2
#define STATE_CLOSING 3
#define STATE_CLOSED 4
/*
Doors are similar to buttons, but can spawn a fat trigger field around them
to open without a touch, and they link together to form simultanious
double/quad doors.
Door.master is the master door. If there is only one door, it points to itself.
If multiple doors, all will point to a single one.
Door.enemy chains from the master door through all doors linked in the chain.
*/
ResponseDef Door::Responses[] =
{
{ &EV_Door_TriggerFieldTouched, ( Response )Door::FieldTouched },
{ &EV_Trigger_Effect, ( Response )Door::TryOpen },
{ &EV_Activate, ( Response )Door::TryOpen },
{ &EV_Door_TryOpen, ( Response )Door::TryOpen },
{ &EV_Door_Close, ( Response )Door::Close },
{ &EV_Door_Open, ( Response )Door::Open },
{ &EV_Door_CloseEnd, ( Response )Door::CloseEnd },
{ &EV_Door_OpenEnd, ( Response )Door::OpenEnd },
{ &EV_Door_Fire, ( Response )Door::DoorFire },
{ &EV_Door_Link, ( Response )Door::LinkDoors },
{ &EV_Door_SetTime, ( Response )Door::SetTime },
{ &EV_Use, ( Response )Door::DoorUse },
{ &EV_Killed, ( Response )Door::DoorFire },
{ &EV_Blocked, ( Response )Door::DoorBlocked },
{ &EV_Door_Lock, ( Response )Door::LockDoor },
{ &EV_Door_Unlock, ( Response )Door::UnlockDoor },
{ &EV_Touch, NULL },
{ NULL, NULL }
};
Door::Door()
{
float t;
nextdoor = 0;
trigger = 0;
locked = false;
master = this;
lastblocktime = 0;
diropened = 0;
showModel();
sound_stop = G_GetStringArg( "sound_stop", gi.GlobalAlias_FindRandom( "door_stop" ) );
sound_move = G_GetStringArg( "sound_move", gi.GlobalAlias_FindRandom( "door_moving" ) );
sound_message = G_GetStringArg( "sound_message" );
sound_locked = G_GetStringArg( "sound_locked" );
gi.soundindex( sound_stop.c_str() );
gi.soundindex( sound_move.c_str() );
if ( sound_message.length() > 1 )
gi.soundindex( sound_message.c_str() );
health = G_GetFloatArg( "health" );
max_health = health;
traveltime = G_GetFloatArg( "time", 0.3 );
if ( traveltime < FRAMETIME )
{
traveltime = FRAMETIME;
}
speed = 1.0f / traveltime;
wait = G_GetFloatArg( "wait", 3 );
if ( ( spawnflags & DOOR_TOGGLE ) && ( wait == 3 ) )
wait = 0;
dmg = G_GetIntArg( "dmg", 0 );
setSolidType( SOLID_BSP );
setMoveType( MOVETYPE_PUSH );
setSize( mins, maxs );
dir = G_GetMovedir();
t = dir[ 0 ];
dir[ 0 ] = -dir[ 1 ];
dir[ 1 ] = t;
setOrigin( origin );
doormin = absmin;
doormax = absmax;
// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
// but spawn in the open position
if ( spawnflags & DOOR_START_OPEN )
{
state = STATE_OPEN;
PostEvent( EV_Door_Open, 0.05f );
}
else
{
state = STATE_CLOSED;
}
previous_state = state;
if ( health )
{
takedamage = DAMAGE_YES;
}
// LinkDoors can't be done until all of the doors have been spawned, so
// the sizes can be detected properly.
nextdoor = 0;
PostEvent( EV_Door_Link, 0 );
// Default to work with monsters and players
respondto = TRIGGER_PLAYERS | TRIGGER_MONSTERS;
if ( spawnflags & 8 )
{
respondto &= ~TRIGGER_PLAYERS;
}
if ( spawnflags & 16 )
{
respondto &= ~TRIGGER_MONSTERS;
}
}
qboolean Door::isOpen
(
void
)
{
return ( state == STATE_OPEN );
}
void Door::OpenEnd
(
Event *ev
)
{
// if ( master == this )
{
if ( sound_stop.length() > 1 )
{
ProcessEvent( EV_DoorSound );
sound( sound_stop, 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
}
else
{
RandomGlobalSound( "null_sound", 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
}
}
previous_state = state;
state = STATE_OPEN;
if ( spawnflags & DOOR_TOGGLE )
{
// don't close automatically
return;
}
if ( ( wait > 0 ) && ( master == this ) )
{
PostEvent( EV_Door_Close, wait );
}
}
void Door::CloseEnd
(
Event *ev
)
{
// if ( master == this )
{
if ( sound_stop.length() > 1 )
{
ProcessEvent( EV_DoorSound );
sound( sound_stop, 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
}
else
{
RandomGlobalSound( "null_sound", 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
}
}
SetAreaPortals( Target(), false );
previous_state = state;
state = STATE_CLOSED;
}
void Door::Close
(
Event *ev
)
{
Door *door;
CancelEventsOfType( EV_Door_Close );
previous_state = state;
state = STATE_CLOSING;
ProcessEvent( EV_Door_DoClose );
if ( sound_move.length() > 1 )
{
ProcessEvent( EV_DoorSound );
sound( sound_move, 1, CHAN_VOICE + CHAN_NO_PHS_ADD, ATTN_NORM );
}
if ( master == this )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -