Compare commits
6 Commits
801742dd4c
...
22460c5aa0
Author | SHA1 | Date |
---|---|---|
Marco Cawthorne | 22460c5aa0 | |
Marco Cawthorne | 8566a9a5a7 | |
Marco Cawthorne | 32f9d974bb | |
Marco Cawthorne | bf705a9e31 | |
Marco Cawthorne | 4790e9d230 | |
Marco Cawthorne | 038265dd64 |
|
@ -1,2 +1,3 @@
|
|||
#pragma sourcefile client/progs.src
|
||||
#pragma sourcefile server/progs.src
|
||||
#pragma sourcefile menu/progs.src
|
||||
|
|
|
@ -92,7 +92,7 @@ bot::UseButton(void)
|
|||
}
|
||||
|
||||
bestButton.Trigger(this, TRIG_TOGGLE);
|
||||
sound(this, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE);
|
||||
StartSoundDef("Player.WeaponSelected", CHAN_ITEM, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -7,5 +7,6 @@ bot_chat.qc
|
|||
bot_combat.qc
|
||||
route.qc
|
||||
way.qc
|
||||
way_convert.qc
|
||||
cmd.qc
|
||||
#endlist
|
||||
|
|
|
@ -27,14 +27,14 @@ typedef struct waypoint_s
|
|||
int m_numNeighbours;
|
||||
} waypoint_t;
|
||||
|
||||
static waypoint_t *g_pWaypoints;
|
||||
static int g_iWaypoints;
|
||||
waypoint_t *g_pWaypoints;
|
||||
int g_iWaypoints;
|
||||
|
||||
static int g_waylink_status;
|
||||
var int g_way1 = -1;
|
||||
var int g_way2 = -1;
|
||||
|
||||
static void
|
||||
void
|
||||
Way_WipeWaypoints(void)
|
||||
{
|
||||
for (int i = 0; i < g_iWaypoints; i++) {
|
||||
|
@ -45,7 +45,7 @@ Way_WipeWaypoints(void)
|
|||
g_iWaypoints = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
Way_LinkNodes(waypoint_t *wp, waypoint_t *w2)
|
||||
{
|
||||
int w2n = w2 - g_pWaypoints;
|
||||
|
@ -103,7 +103,7 @@ Way_UnlinkNodes(waypoint_t *wp, waypoint_t *w2)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
Way_AutoLink(int wpidx)
|
||||
{
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
|
@ -518,21 +518,34 @@ Way_SaveFile(string filename)
|
|||
}
|
||||
|
||||
void
|
||||
Way_ReadFile(string strFile)
|
||||
Way_ReadFile(string strFile, bool flush)
|
||||
{
|
||||
float file = fopen(strFile, FILE_READ);
|
||||
int startId = 0i;
|
||||
int offSet = 0i;
|
||||
|
||||
filestream file = fopen(strFile, FILE_READ);
|
||||
if (file < 0) {
|
||||
print("Way_ReadFile: unable to open ", strFile, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Way_WipeWaypoints();
|
||||
|
||||
/* read the number of waypoints */
|
||||
tokenize(fgets(file));
|
||||
g_iWaypoints = stoi(argv(0));
|
||||
g_pWaypoints = memalloc(sizeof(*g_pWaypoints) * g_iWaypoints);
|
||||
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
if (flush) {
|
||||
Way_WipeWaypoints();
|
||||
g_iWaypoints = stoi(argv(0));
|
||||
g_pWaypoints = memalloc(sizeof(*g_pWaypoints) * g_iWaypoints);
|
||||
} else {
|
||||
int oldSize = g_iWaypoints;
|
||||
int newSize = g_iWaypoints + stoi(argv(0));
|
||||
g_pWaypoints = (waypoint_t *)memrealloc(g_pWaypoints, sizeof(waypoint_t), oldSize, newSize);
|
||||
g_iWaypoints = newSize;
|
||||
startId = oldSize;
|
||||
offSet = oldSize;
|
||||
}
|
||||
|
||||
for (int i = startId; i < g_iWaypoints; i++) {
|
||||
tokenize(fgets(file));
|
||||
g_pWaypoints[i].m_vecOrigin[0] = stof(argv(0));
|
||||
g_pWaypoints[i].m_vecOrigin[1] = stof(argv(1));
|
||||
|
@ -543,7 +556,7 @@ Way_ReadFile(string strFile)
|
|||
|
||||
for (int j = 0i; j < g_pWaypoints[i].m_numNeighbours; j++) {
|
||||
tokenize(fgets(file));
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iNode = stoi(argv(0));
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iNode = offSet + stoi(argv(0));
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_flCost = stof(argv(1));
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iFlags = stoi(argv(2));
|
||||
}
|
||||
|
@ -551,7 +564,6 @@ Way_ReadFile(string strFile)
|
|||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Way_ConnectOne(void)
|
||||
{
|
||||
|
@ -725,6 +737,9 @@ Way_DrawDebugInfo(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Way_ReadFBFile(string, bool);
|
||||
void Way_ReadPBFile(string, bool);
|
||||
void Way_ReadJumbotFile(string, bool);
|
||||
void
|
||||
Way_Cmd(void)
|
||||
{
|
||||
|
@ -780,6 +795,25 @@ Way_Cmd(void)
|
|||
g_pWaypoints[i].m_flRadius = autocvar_nav_radius;
|
||||
}
|
||||
break;
|
||||
case "offset":
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
g_pWaypoints[i].m_vecOrigin += stov(argv(2));
|
||||
}
|
||||
break;
|
||||
case "flipx":
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
g_pWaypoints[i].m_vecOrigin[0] *= -1;
|
||||
}
|
||||
case "flipy":
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
g_pWaypoints[i].m_vecOrigin[1] *= -1;
|
||||
}
|
||||
break;
|
||||
case "flipz":
|
||||
for (int i = 0i; i < g_iWaypoints; i++) {
|
||||
g_pWaypoints[i].m_vecOrigin[2] *= -1;
|
||||
}
|
||||
break;
|
||||
case "linkjump":
|
||||
Way_FlagJump();
|
||||
break;
|
||||
|
@ -821,7 +855,19 @@ Way_Cmd(void)
|
|||
Way_SaveFile(argv(2));
|
||||
break;
|
||||
case "load":
|
||||
Way_ReadFile(argv(2));
|
||||
Way_ReadFile(argv(2), true);
|
||||
break;
|
||||
case "merge":
|
||||
Way_ReadFile(argv(2), false);
|
||||
break;
|
||||
case "loadpb":
|
||||
Way_ReadPBFile(argv(2), true);
|
||||
break;
|
||||
case "loadrich":
|
||||
Way_ReadJumbotFile(argv(2), true);
|
||||
break;
|
||||
case "loadfb":
|
||||
Way_ReadFBFile(argv(2), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* 8 bytes */
|
||||
int type1;
|
||||
int type2;
|
||||
|
||||
int versionNumber;
|
||||
int extraFlags;
|
||||
int numNodes;
|
||||
|
||||
/* 32 bytes */
|
||||
int mapname1;
|
||||
int mapname2;
|
||||
int mapname3;
|
||||
int mapname4;
|
||||
int mapname5;
|
||||
int mapname6;
|
||||
int mapname7;
|
||||
int mapname8;
|
||||
} fb_header;
|
||||
|
||||
#define FBFL_TEAM1 0x00000001
|
||||
#define FBFL_TEAM2 0x00000002
|
||||
#define FBFL_TEAMSPECIFIC 0x00000004
|
||||
#define FBFL_CROUCH 0x00000008
|
||||
#define FBFL_LADDER 0x00000010
|
||||
#define FBFL_LIFT 0x00000020
|
||||
#define FBFL_WALK 0x00000040
|
||||
#define FBFL_HEALTH 0x00000080
|
||||
#define FBFL_ARMOR 0x00000100
|
||||
#define FBFL_AMMO 0x00000200
|
||||
#define FBFL_SNIPER 0x00000400
|
||||
#define FBFL_GOALITEM 0x00000800
|
||||
#define FBFL_GOAL 0x00001000
|
||||
#define FBFL_SENTRY 0x00002000
|
||||
#define FBFL_AIMING 0x00004000
|
||||
#define FBFL_JUMP 0x00008000
|
||||
#define FBFL_DETPACKSEAL 0x00010000
|
||||
#define FBFL_PATHCHECK 0x00020000
|
||||
#define FBFL_UNUSED1 0x00040000
|
||||
#define FBFL_UNUSED2 0x00080000
|
||||
#define FBFL_UNUSED3 0x00100000
|
||||
#define FBFL_UNUSED4 0x00200000
|
||||
#define FBFL_UNUSED5 0x00400000
|
||||
#define ITEM_UNUSED6 0x00800000
|
||||
#define FBFL_PIPETRAP 0x01000000
|
||||
#define FBFL_DETPACKCLEAR 0x02000000
|
||||
#define FBFL_TELEENTER 0x04000000
|
||||
#define FBFL_CONCJUMP 0x08000000
|
||||
#define FBFL_SENTRY_180 0x10000000
|
||||
#define FBFL_DEFEND 0x20000000
|
||||
#define FBFL_TELEEXIT 0x40000000
|
||||
#define FBFL_DELETED 0x80000000
|
||||
|
||||
int
|
||||
Way_FBFlagsToNC(int inputFlags)
|
||||
{
|
||||
int outFlags = 0i;
|
||||
|
||||
if (inputFlags & FBFL_JUMP)
|
||||
outFlags |= LF_JUMP;
|
||||
|
||||
if (inputFlags & FBFL_WALK)
|
||||
outFlags |= LF_WALK;
|
||||
|
||||
if (inputFlags & FBFL_CROUCH)
|
||||
outFlags |= LF_CROUCH;
|
||||
|
||||
if (inputFlags & FBFL_AIMING)
|
||||
outFlags |= LF_AIM;
|
||||
|
||||
if (inputFlags & FBFL_LADDER)
|
||||
outFlags |= LF_AIM;
|
||||
|
||||
return outFlags;
|
||||
}
|
||||
|
||||
/* Reads a FB waypoint file.
|
||||
|
||||
These are binary files and contain a lot of type sizes that we don't
|
||||
have access to in QC. So we cannot just fread() into a struct.
|
||||
|
||||
The only flag between nodes is seemingly JUMP (1), however the
|
||||
individual nodes themselves have defining info flags too including
|
||||
ones for using buttons and ladders. Ideally we'd want to re-interpret
|
||||
those into linkflags.
|
||||
*/
|
||||
void
|
||||
Way_ReadFBFile(string strFile, bool flush)
|
||||
{
|
||||
int startId = 0i;
|
||||
int offSet = 0i;
|
||||
fb_header fbHeader;
|
||||
int *nodeFlags;
|
||||
|
||||
filestream file = fopen(strFile, FILE_READ);
|
||||
if (file < 0) {
|
||||
print("Way_ReadFile: unable to open ", strFile, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fread(file, (void*)&fbHeader, sizeof(fb_header));
|
||||
|
||||
if (flush) {
|
||||
Way_WipeWaypoints();
|
||||
g_iWaypoints = fbHeader.numNodes;
|
||||
g_pWaypoints = memalloc(sizeof(*g_pWaypoints) * g_iWaypoints);
|
||||
} else {
|
||||
int oldSize = g_iWaypoints;
|
||||
int newSize = g_iWaypoints + fbHeader.numNodes;
|
||||
g_pWaypoints = (waypoint_t *)memrealloc(g_pWaypoints, sizeof(waypoint_t), oldSize, newSize);
|
||||
g_iWaypoints = newSize;
|
||||
startId = oldSize;
|
||||
offSet = oldSize;
|
||||
}
|
||||
|
||||
print(sprintf("FB Waypoints Version %i, %i nodes\n", fbHeader.versionNumber, fbHeader.numNodes));
|
||||
|
||||
nodeFlags = (int *)memalloc(sizeof(int) * fbHeader.numNodes);
|
||||
|
||||
/* create the nodes */
|
||||
for (int i = startId; i < g_iWaypoints; i++) {
|
||||
int iData = 0i;
|
||||
float flData = 0.0f;
|
||||
|
||||
fread(file, (void*)&nodeFlags[i], 4); /* flags */
|
||||
fread(file, (void*)&iData, 4); /* script flags, should be 1 byte but it's padded. */
|
||||
|
||||
fread(file, (void*)&flData, 4); /* origin x */
|
||||
g_pWaypoints[i].m_vecOrigin[0] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin y */
|
||||
g_pWaypoints[i].m_vecOrigin[1] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin z */
|
||||
g_pWaypoints[i].m_vecOrigin[2] = flData;
|
||||
}
|
||||
|
||||
/* create the links */
|
||||
for (int i = startId; i < g_iWaypoints; i++) {
|
||||
int iData = 0i;
|
||||
fread(file, (void*)&iData, 2); /* neighbour count */
|
||||
//print(sprintf("%i neighbours\n", iData));
|
||||
|
||||
g_pWaypoints[i].m_numNeighbours = iData;
|
||||
g_pWaypoints[i].m_pNeighbour = memalloc(sizeof(*g_pWaypoints[i].m_pNeighbour) * g_pWaypoints[i].m_numNeighbours);
|
||||
|
||||
for (int j = 0i; j < g_pWaypoints[i].m_numNeighbours; j++) {
|
||||
fread(file, (void*)&iData, 2); /* neighbour index */
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iNode = offSet + iData;
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_flCost = -1;
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iFlags = Way_FBFlagsToNC(nodeFlags[offSet + iData]);
|
||||
}
|
||||
}
|
||||
|
||||
memfree(nodeFlags);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* 8 bytes */
|
||||
int type1;
|
||||
int type2;
|
||||
int versionNumber;
|
||||
int numNodes;
|
||||
/* 32 bytes */
|
||||
int mapname1;
|
||||
int mapname2;
|
||||
int mapname3;
|
||||
int mapname4;
|
||||
int mapname5;
|
||||
int mapname6;
|
||||
int mapname7;
|
||||
int mapname8;
|
||||
/* 32 bytes */
|
||||
int author1;
|
||||
int author2;
|
||||
int author3;
|
||||
int author4;
|
||||
int author5;
|
||||
int author6;
|
||||
int author7;
|
||||
int author8;
|
||||
} pb_header;
|
||||
|
||||
#define PBFL_USEBUTTON 0x00000001i
|
||||
#define PBFL_ELEVATOR 0x00000002i
|
||||
#define PBFL_CROUCH 0x00000004i
|
||||
#define PBFL_CROSSING 0x00000008i
|
||||
#define PBFL_GOAL 0x00000010i
|
||||
#define PBFL_LADDER 0x00000020i
|
||||
#define PBFL_RESCUE 0x00000040i
|
||||
#define PBFL_CAMP 0x00000080i
|
||||
|
||||
int
|
||||
Way_PBFlagsToNC(int inputFlags)
|
||||
{
|
||||
int outFlags = 0i;
|
||||
|
||||
if (inputFlags & 1)
|
||||
outFlags |= LF_JUMP;
|
||||
|
||||
return outFlags;
|
||||
}
|
||||
|
||||
/* Reads a PB version 5, 6, 7 file.
|
||||
|
||||
These are binary files and contain a lot of type sizes that we don't
|
||||
have access to in QC. So we cannot just fread() into a struct.
|
||||
|
||||
The only flag between nodes is seemingly JUMP (1), however the
|
||||
individual nodes themselves have defining info flags too including
|
||||
ones for using buttons and ladders. Ideally we'd want to re-interpret
|
||||
those into linkflags.
|
||||
*/
|
||||
void
|
||||
Way_ReadPBFile(string strFile, bool flush)
|
||||
{
|
||||
int startId = 0i;
|
||||
int offSet = 0i;
|
||||
pb_header pbHeader;
|
||||
|
||||
filestream file = fopen(strFile, FILE_READ);
|
||||
if (file < 0) {
|
||||
print("Way_ReadFile: unable to open ", strFile, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fread(file, (void*)&pbHeader, sizeof(pb_header));
|
||||
|
||||
if (flush) {
|
||||
Way_WipeWaypoints();
|
||||
g_iWaypoints = pbHeader.numNodes;
|
||||
g_pWaypoints = memalloc(sizeof(*g_pWaypoints) * g_iWaypoints);
|
||||
} else {
|
||||
int oldSize = g_iWaypoints;
|
||||
int newSize = g_iWaypoints + pbHeader.numNodes;
|
||||
g_pWaypoints = (waypoint_t *)memrealloc(g_pWaypoints, sizeof(waypoint_t), oldSize, newSize);
|
||||
g_iWaypoints = newSize;
|
||||
startId = oldSize;
|
||||
offSet = oldSize;
|
||||
}
|
||||
|
||||
print(sprintf("PB Waypoints Version %i, %i nodes\n", pbHeader.versionNumber, pbHeader.numNodes));
|
||||
|
||||
for (int i = startId; i < g_iWaypoints; i++) {
|
||||
int neighbours = 0i;
|
||||
int index[8];
|
||||
float cost[8];
|
||||
int nFlags[8];
|
||||
int iData = 0i;
|
||||
float flData = 0.0f;
|
||||
|
||||
/* make them all invalid */
|
||||
for (int n = 0i; n < 8i; n++) {
|
||||
index[n] = 65535;
|
||||
}
|
||||
|
||||
if (pbHeader.versionNumber == 7) {
|
||||
fread(file, (void*)&iData, 4); /* number */
|
||||
fread(file, (void*)&iData, 4); /* flags */
|
||||
fread(file, (void*)&flData, 4); /* origin x */
|
||||
g_pWaypoints[i].m_vecOrigin[0] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin y */
|
||||
g_pWaypoints[i].m_vecOrigin[1] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin z */
|
||||
g_pWaypoints[i].m_vecOrigin[2] = flData;
|
||||
fread(file, (void*)&flData, 4); /* radius */
|
||||
g_pWaypoints[i].m_flRadius = flData;
|
||||
fread(file, (void*)&flData, 4); /* camp start x */
|
||||
fread(file, (void*)&flData, 4); /* camp start y */
|
||||
fread(file, (void*)&flData, 4); /* camp end x */
|
||||
fread(file, (void*)&flData, 4); /* camp end y */
|
||||
fread(file, (void*)&index[0], 2); /* index 1 */
|
||||
fread(file, (void*)&index[1], 2); /* index 2 */
|
||||
fread(file, (void*)&index[2], 2); /* index 3 */
|
||||
fread(file, (void*)&index[3], 2); /* index 4 */
|
||||
fread(file, (void*)&index[4], 2); /* index 5 */
|
||||
fread(file, (void*)&index[5], 2); /* index 6 */
|
||||
fread(file, (void*)&index[6], 2); /* index 7 */
|
||||
fread(file, (void*)&index[7], 2); /* index 8 */
|
||||
fread(file, (void*)&nFlags[0], 2); /* nFlags 1 */
|
||||
fread(file, (void*)&nFlags[1], 2); /* nFlags 2 */
|
||||
fread(file, (void*)&nFlags[2], 2); /* nFlags 3 */
|
||||
fread(file, (void*)&nFlags[3], 2); /* nFlags 4 */
|
||||
fread(file, (void*)&nFlags[4], 2); /* nFlags 5 */
|
||||
fread(file, (void*)&nFlags[5], 2); /* nFlags 6 */
|
||||
fread(file, (void*)&nFlags[6], 2); /* nFlags 7 */
|
||||
fread(file, (void*)&nFlags[7], 2); /* nFlags 8 */
|
||||
fread(file, (void*)&flData, 4); /* velocity 1 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 1 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 1 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 2 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 2 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 2 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 3 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 3 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 3 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 4 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 4 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 4 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 5 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 5 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 5 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 6 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 6 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 6 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 7 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 7 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 7 z */
|
||||
fread(file, (void*)&flData, 4); /* velocity 8 x */
|
||||
fread(file, (void*)&flData, 4); /* velocity 8 y */
|
||||
fread(file, (void*)&flData, 4); /* velocity 8 z */
|
||||
fread(file, (void*)&iData, 4); /* distance 1 */
|
||||
cost[0] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 2 */
|
||||
cost[1] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 3 */
|
||||
cost[2] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 4 */
|
||||
cost[3] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 5 */
|
||||
cost[4] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 6 */
|
||||
cost[5] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 7 */
|
||||
cost[6] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 8 */
|
||||
cost[7] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* pointer */
|
||||
} else if (pbHeader.versionNumber == 6) {
|
||||
fread(file, (void*)&iData, 4); /* number */
|
||||
fread(file, (void*)&iData, 4); /* flags */
|
||||
fread(file, (void*)&flData, 4); /* origin x */
|
||||
g_pWaypoints[i].m_vecOrigin[0] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin y */
|
||||
g_pWaypoints[i].m_vecOrigin[1] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin z */
|
||||
g_pWaypoints[i].m_vecOrigin[2] = flData;
|
||||
fread(file, (void*)&flData, 4); /* radius */
|
||||
g_pWaypoints[i].m_flRadius = flData;
|
||||
fread(file, (void*)&flData, 4); /* camp start x */
|
||||
fread(file, (void*)&flData, 4); /* camp start y */
|
||||
fread(file, (void*)&flData, 4); /* camp end x */
|
||||
fread(file, (void*)&flData, 4); /* camp end y */
|
||||
fread(file, (void*)&index[0], 2); /* index 1 */
|
||||
fread(file, (void*)&index[1], 2); /* index 2 */
|
||||
fread(file, (void*)&index[2], 2); /* index 3 */
|
||||
fread(file, (void*)&index[3], 2); /* index 4 */
|
||||
fread(file, (void*)&index[4], 2); /* index 5 */
|
||||
fread(file, (void*)&index[5], 2); /* index 6 */
|
||||
fread(file, (void*)&index[6], 2); /* index 7 */
|
||||
fread(file, (void*)&index[7], 2); /* index 8 */
|
||||
fread(file, (void*)&iData, 4); /* distance 1 */
|
||||
cost[0] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 2 */
|
||||
cost[1] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 3 */
|
||||
cost[2] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 4 */
|
||||
cost[3] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 5 */
|
||||
cost[4] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 6 */
|
||||
cost[5] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 7 */
|
||||
cost[6] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 8 */
|
||||
cost[7] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* pointer */
|
||||
} else if (pbHeader.versionNumber == 5) {
|
||||
fread(file, (void*)&iData, 4); /* number */
|
||||
fread(file, (void*)&iData, 4); /* flags */
|
||||
fread(file, (void*)&flData, 4); /* origin x */
|
||||
g_pWaypoints[i].m_vecOrigin[0] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin y */
|
||||
g_pWaypoints[i].m_vecOrigin[1] = flData;
|
||||
fread(file, (void*)&flData, 4); /* origin z */
|
||||
g_pWaypoints[i].m_vecOrigin[2] = flData;
|
||||
fread(file, (void*)&flData, 4); /* radius */
|
||||
g_pWaypoints[i].m_flRadius = flData;
|
||||
fread(file, (void*)&flData, 4); /* camp start x */
|
||||
fread(file, (void*)&flData, 4); /* camp start y */
|
||||
fread(file, (void*)&flData, 4); /* camp end x */
|
||||
fread(file, (void*)&flData, 4); /* camp end y */
|
||||
fread(file, (void*)&index[0], 2); /* index 1 */
|
||||
fread(file, (void*)&index[1], 2); /* index 2 */
|
||||
fread(file, (void*)&index[2], 2); /* index 3 */
|
||||
fread(file, (void*)&index[3], 2); /* index 4 */
|
||||
fread(file, (void*)&iData, 4); /* distance 1 */
|
||||
cost[0] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 2 */
|
||||
cost[1] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 3 */
|
||||
cost[2] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* distance 4 */
|
||||
cost[3] = (float)iData;
|
||||
fread(file, (void*)&iData, 4); /* pointer */
|
||||
}
|
||||
|
||||
/* check for valid neighbours */
|
||||
for (int n = 0i; n < 8i; n++) {
|
||||
if (index[n] != 65535) /* -1 */
|
||||
neighbours++;
|
||||
}
|
||||
|
||||
g_pWaypoints[i].m_numNeighbours = neighbours;
|
||||
g_pWaypoints[i].m_pNeighbour = memalloc(sizeof(*g_pWaypoints[i].m_pNeighbour) * g_pWaypoints[i].m_numNeighbours);
|
||||
|
||||
for (int j = 0i; j < g_pWaypoints[i].m_numNeighbours; j++) {
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iNode = offSet + index[j];
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_flCost = cost[j];
|
||||
g_pWaypoints[i].m_pNeighbour[j].m_iFlags = Way_PBFlagsToNC(nFlags[j]);
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Reads a Jumbot file.
|
||||
|
||||
Plaintext that's simple to parse, however does not store any node
|
||||
connections. That's because Jumbot was specific to Half-Life and
|
||||
the AI was smart enough to know how to navigate using only those
|
||||
helper points.
|
||||
|
||||
We count all lines until we hit the end character '$' and then parse
|
||||
each line - which contains the info: [id] [flag] ([position])
|
||||
|
||||
We then link those in linear order. There's probably better ways of
|
||||
doing that so that'll be an area of research.
|
||||
*/
|
||||
void
|
||||
Way_ReadJumbotFile(string strFile, bool flush)
|
||||
{
|
||||
int startId = 0i;
|
||||
int offSet = 0i;
|
||||
int nodeCount = 0i;
|
||||
string line;
|
||||
|
||||
filestream file = fopen(strFile, FILE_READ);
|
||||
if (file < 0) {
|
||||
print("Way_ReadFile: unable to open ", strFile, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* read the number of waypoints */
|
||||
while ((line = fgets(file))) {
|
||||
if (line != "$") {
|
||||
nodeCount++;
|
||||
}
|
||||
}
|
||||
fseek(file, 0);
|
||||
|
||||
print(sprintf("Jumpbot Waypoints Version %i, %i nodes\n", 1i, nodeCount));
|
||||
|
||||
if (flush) {
|
||||
Way_WipeWaypoints();
|
||||
g_iWaypoints = nodeCount;
|
||||
g_pWaypoints = memalloc(sizeof(*g_pWaypoints) * g_iWaypoints);
|
||||
} else {
|
||||
int oldSize = g_iWaypoints;
|
||||
int newSize = g_iWaypoints + nodeCount;
|
||||
g_pWaypoints = (waypoint_t *)memrealloc(g_pWaypoints, sizeof(waypoint_t), oldSize, newSize);
|
||||
g_iWaypoints = newSize;
|
||||
startId = oldSize;
|
||||
offSet = oldSize;
|
||||
}
|
||||
|
||||
for (int i = startId; i < g_iWaypoints; i++) {
|
||||
float length = strlen(argv(5));
|
||||
line = fgets(file);
|
||||
tokenize(line);
|
||||
g_pWaypoints[i].m_vecOrigin[0] = stof(argv(3));
|
||||
g_pWaypoints[i].m_vecOrigin[1] = stof(argv(4));
|
||||
g_pWaypoints[i].m_vecOrigin[2] = stof(argv(5));
|
||||
g_pWaypoints[i].m_flRadius = 32.0f;
|
||||
|
||||
if (i > startId) {
|
||||
Way_LinkNodes(&g_pWaypoints[i], &g_pWaypoints[i-1]);
|
||||
Way_LinkNodes(&g_pWaypoints[i-1], &g_pWaypoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
|
@ -265,6 +265,12 @@ Cmd_Parse(string sCMD)
|
|||
case "listParticles":
|
||||
CMD_ListParticles();
|
||||
break;
|
||||
case "listClientSoundDef":
|
||||
Sound_DebugList();
|
||||
break;
|
||||
case "listServerSoundDef":
|
||||
localcmd("sv listSoundDef\n");
|
||||
break;
|
||||
case "cleardecals":
|
||||
CMD_Cleardecals();
|
||||
break;
|
||||
|
@ -446,6 +452,8 @@ Cmd_Init(void)
|
|||
registercommand("listSounds");
|
||||
registercommand("listParticles");
|
||||
registercommand("listTitles");
|
||||
registercommand("listClientSoundDef");
|
||||
registercommand("listServerSoundDef");
|
||||
|
||||
registercommand("cleardecals");
|
||||
registercommand("testLight");
|
||||
|
|
|
@ -51,6 +51,10 @@ Entity_EntityUpdate(float type, float new)
|
|||
NSENTITY_READENTITY(NSTalkMonster, new)
|
||||
self.customphysics = Empty;
|
||||
break;
|
||||
case ENT_SPEAKER:
|
||||
NSENTITY_READENTITY(speaker, new)
|
||||
self.customphysics = Empty;
|
||||
break;
|
||||
case ENT_VEHICLE:
|
||||
NSENTITY_READENTITY(NSVehicle, new)
|
||||
break;
|
||||
|
@ -122,6 +126,9 @@ Entity_EntityUpdate(float type, float new)
|
|||
case ENT_FOGCONTROLLER:
|
||||
NSENTITY_READENTITY(env_fog_controller, new)
|
||||
break;
|
||||
case ENT_CASCADELIGHT:
|
||||
NSENTITY_READENTITY(env_cascade_light, new)
|
||||
break;
|
||||
case ENT_PARTSYSTEM:
|
||||
NSENTITY_READENTITY(info_particle_system, new)
|
||||
break;
|
||||
|
@ -140,6 +147,9 @@ Entity_EntityUpdate(float type, float new)
|
|||
case ENT_WAYPOINT:
|
||||
NSENTITY_READENTITY(info_waypoint, new)
|
||||
break;
|
||||
case ENT_INSTRUCTOR:
|
||||
NSENTITY_READENTITY(env_instructor_hint, new)
|
||||
break;
|
||||
case ENT_PUSH:
|
||||
NSENTITY_READENTITY(trigger_push, new)
|
||||
break;
|
||||
|
|
|
@ -58,13 +58,6 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
PropData_Init();
|
||||
DecalGroups_Init();
|
||||
|
||||
precache_sound("common/wpn_hudon.wav");
|
||||
precache_sound("common/wpn_hudoff.wav");
|
||||
precache_sound("common/wpn_moveselect.wav");
|
||||
precache_sound("common/wpn_select.wav");
|
||||
|
||||
precache_sound("common/null.wav");
|
||||
|
||||
/* VGUI */
|
||||
VGUI_Init();
|
||||
|
||||
|
@ -88,6 +81,12 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
|
||||
WorldSpawn_Init();
|
||||
|
||||
Sound_Precache("Player.DenyWeaponSelection");
|
||||
Sound_Precache("Player.WeaponSelected");
|
||||
Sound_Precache("Player.WeaponSelectionMoveSlot");
|
||||
Sound_Precache("Player.WeaponSelectionOpen");
|
||||
Sound_Precache("Player.WeaponSelectionClose");
|
||||
|
||||
/* end msg */
|
||||
print("Client game initialized.\n");
|
||||
|
||||
|
|
|
@ -165,6 +165,13 @@ EV_TraceDebug(void)
|
|||
traceRep.angles = endOrg;
|
||||
}
|
||||
|
||||
void
|
||||
EV_Achievement(void)
|
||||
{
|
||||
string eventName = readstring();
|
||||
NSLog("EV_Achievement: %S", eventName);
|
||||
}
|
||||
|
||||
void
|
||||
Event_Parse(float type)
|
||||
{
|
||||
|
@ -240,6 +247,9 @@ Event_Parse(float type)
|
|||
case EV_TRACEDEBUG:
|
||||
EV_TraceDebug();
|
||||
break;
|
||||
case EV_ACHIEVEMENT:
|
||||
EV_Achievement();
|
||||
break;
|
||||
default:
|
||||
error(sprintf("event id %d not recognized. abort immediately.\n", type));
|
||||
}
|
||||
|
|
|
@ -103,12 +103,12 @@ server/trigger_once.qc
|
|||
server/trigger_multiple.qc
|
||||
server/trigger_teleport.qc
|
||||
server/trigger_playerfreeze.qc
|
||||
server/trigger_monsterjump.qc
|
||||
server/trigger_relay.qc
|
||||
server/env_shooter.qc
|
||||
server/gibshooter.qc
|
||||
server/env_beverage.qc
|
||||
server/item_food.qc
|
||||
server/speaker.qc
|
||||
server/multi_manager.qc
|
||||
server/momentarybase.qc
|
||||
server/momentary_rot_button.qc
|
||||
|
|
|
@ -30,3 +30,14 @@ If you don't want this entity to have collision, consider using func_detail_illu
|
|||
# TRIVIA
|
||||
This entity was introduced in Quake II (1997).
|
||||
*/
|
||||
class
|
||||
func_detail:info_null
|
||||
{
|
||||
public:
|
||||
void func_detail(void);
|
||||
};
|
||||
|
||||
void
|
||||
func_detail::func_detail(void)
|
||||
{
|
||||
}
|
|
@ -29,5 +29,16 @@ except that it does not use an entity slot or require custom materials.
|
|||
If you want this entity to have collision, consider using func_detail.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake II (1997).
|
||||
This entity was introduced in ericw-tools (2017).
|
||||
*/
|
||||
class
|
||||
func_detail_illusionary:info_null
|
||||
{
|
||||
public:
|
||||
void func_detail_illusionary(void);
|
||||
};
|
||||
|
||||
void
|
||||
func_detail_illusionary::func_detail_illusionary(void)
|
||||
{
|
||||
}
|
|
@ -27,3 +27,14 @@ worldspawn upon compile.
|
|||
# TRIVIA
|
||||
This entity was introduced in Quake II (1997).
|
||||
*/
|
||||
class
|
||||
func_group:info_null
|
||||
{
|
||||
public:
|
||||
void func_group(void);
|
||||
};
|
||||
|
||||
void
|
||||
func_group::func_group(void)
|
||||
{
|
||||
}
|
|
@ -152,7 +152,6 @@ private:
|
|||
hinttype_t m_hintType;
|
||||
string m_strHintActivity;
|
||||
float m_flNodeFOV;
|
||||
bool m_bStartDisabled;
|
||||
string m_strHintGroup;
|
||||
ignorefacing_t m_ignoreFacing;
|
||||
aistate_t m_minState;
|
||||
|
@ -165,7 +164,6 @@ info_hint::info_hint(void)
|
|||
m_hintType = HINT_NONE;
|
||||
m_strHintActivity = __NULL__;
|
||||
m_flNodeFOV = 360;
|
||||
m_bStartDisabled = false;
|
||||
m_strHintGroup = __NULL__;
|
||||
m_ignoreFacing = IGNORE_DEFAULT;
|
||||
m_minState = AISTATE_IDLE;
|
||||
|
@ -179,7 +177,6 @@ info_hint::Save(float handle)
|
|||
SaveFloat(handle, "m_hintType", m_hintType);
|
||||
SaveString(handle, "m_strHintActivity", m_strHintActivity);
|
||||
SaveFloat(handle, "m_flNodeFOV", m_flNodeFOV);
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveString(handle, "m_strHintGroup", m_strHintGroup);
|
||||
SaveFloat(handle, "m_ignoreFacing", m_ignoreFacing);
|
||||
SaveFloat(handle, "m_minState", m_minState);
|
||||
|
@ -199,9 +196,6 @@ info_hint::Restore(string strKey, string strValue)
|
|||
case "m_flNodeFOV":
|
||||
m_flNodeFOV = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_strHintGroup":
|
||||
m_strHintGroup = ReadString(strValue);
|
||||
break;
|
||||
|
|
|
@ -168,9 +168,15 @@ light::SpawnKey(string strKey, string strValue)
|
|||
case "_cone":
|
||||
case "_cone2":
|
||||
case "_sky":
|
||||
case "pitch":
|
||||
case "_light":
|
||||
break;
|
||||
/* mostly for light_environment */
|
||||
case "pitch":
|
||||
angles[0] = ReadFloat(strValue);
|
||||
break;
|
||||
case "sunangle":
|
||||
angles[1] = ReadFloat(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
}
|
||||
|
@ -236,9 +242,22 @@ light::Trigger(entity act, triggermode_t state)
|
|||
}
|
||||
|
||||
CLASSEXPORT(light_spot, light)
|
||||
CLASSEXPORT(light_environment, light)
|
||||
|
||||
class
|
||||
light_environment:light
|
||||
{
|
||||
public:
|
||||
void light_environment(void);
|
||||
};
|
||||
|
||||
void
|
||||
light_environment::light_environment(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!QUAKED light_surface (0 1 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Material property modifier related to lighting.
|
||||
|
||||
# KEYS
|
||||
|
|
|
@ -59,73 +59,32 @@ public:
|
|||
virtual void Respawn(void);
|
||||
virtual void SpawnKey(string, string);
|
||||
virtual void Input(entity, string, string);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string, string);
|
||||
|
||||
private:
|
||||
bool m_bStartDisabled;
|
||||
bool m_bEnabled;
|
||||
};
|
||||
|
||||
void
|
||||
logic_relay::logic_relay(void)
|
||||
{
|
||||
m_bStartDisabled = false;
|
||||
}
|
||||
|
||||
void
|
||||
logic_relay::Respawn(void)
|
||||
{
|
||||
InitPointTrigger();
|
||||
m_bEnabled = (m_bStartDisabled) ? false : true;
|
||||
}
|
||||
|
||||
void
|
||||
logic_relay::SpawnKey(string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadBool(setValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logic_relay::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
logic_relay::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logic_relay::Input(entity activatorEntity, string inputName, string dataField)
|
||||
{
|
||||
switch (inputName) {
|
||||
case "Enable":
|
||||
m_bEnabled = true;
|
||||
break;
|
||||
case "Disable":
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case "Trigger":
|
||||
if (m_bEnabled == true) {
|
||||
/* if we don't allow fast retrigger... */
|
||||
|
@ -143,9 +102,6 @@ logic_relay::Input(entity activatorEntity, string inputName, string dataField)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bEnabled = (m_bEnabled) ? false : true;
|
||||
break;
|
||||
/* TODO: complete this mess */
|
||||
case "CancelPending":
|
||||
break;
|
||||
|
|
|
@ -74,13 +74,11 @@ private:
|
|||
float m_flRandMins;
|
||||
float m_flRandMaxs;
|
||||
float m_flRefireTime;
|
||||
bool m_bStartDisabled;
|
||||
bool m_bOscillator;
|
||||
|
||||
string m_strOnTimer;
|
||||
string m_strOnTimerHigh;
|
||||
string m_strOnTimerLow;
|
||||
bool m_bEnabled;
|
||||
entity m_eActivator;
|
||||
};
|
||||
|
||||
|
@ -91,9 +89,7 @@ logic_timer::logic_timer(void)
|
|||
m_flRandMins = 0.0f;
|
||||
m_flRandMaxs = 1.0f;
|
||||
m_flRefireTime = 0.0;
|
||||
m_bStartDisabled = false;
|
||||
m_bOscillator = false;
|
||||
m_bEnabled = true;
|
||||
m_eActivator = this;
|
||||
m_strOnTimer = m_strOnTimerHigh = m_strOnTimerLow = __NULL__;
|
||||
}
|
||||
|
@ -114,9 +110,6 @@ logic_timer::SpawnKey(string keyName, string setValue)
|
|||
case "RefireTime":
|
||||
m_flRefireTime = ReadFloat(setValue);
|
||||
break;
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadBool(setValue);
|
||||
break;
|
||||
/* I/O related */
|
||||
case "OnTimer":
|
||||
m_strOnTimer = PrepareOutput(m_strOnTimer, setValue);
|
||||
|
@ -167,12 +160,10 @@ logic_timer::Save(float handle)
|
|||
SaveFloat(handle, "m_flRandMins", m_flRandMins);
|
||||
SaveFloat(handle, "m_flRandMaxs", m_flRandMaxs);
|
||||
SaveFloat(handle, "m_flRefireTime", m_flRefireTime);
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveString(handle, "m_strOnTimer", m_strOnTimer);
|
||||
SaveString(handle, "m_strOnTimerHigh", m_strOnTimerHigh);
|
||||
SaveString(handle, "m_strOnTimerLow", m_strOnTimerLow);
|
||||
SaveBool(handle, "m_bOscillator", m_bOscillator);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
SaveEntity(handle, "m_eActivator", m_eActivator);
|
||||
}
|
||||
|
||||
|
@ -192,9 +183,6 @@ logic_timer::Restore(string strKey, string strValue)
|
|||
case "m_flRefireTime":
|
||||
m_flRefireTime = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_strOnTimer":
|
||||
m_strOnTimer = ReadString(strValue);
|
||||
break;
|
||||
|
@ -207,9 +195,6 @@ logic_timer::Restore(string strKey, string strValue)
|
|||
case "m_bOscillator":
|
||||
m_bOscillator = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_eActivator":
|
||||
m_eActivator = ReadEntity(strValue);
|
||||
break;
|
||||
|
@ -242,9 +227,6 @@ logic_timer::Input(entity activatorEntity, string inputName, string dataField)
|
|||
m_bEnabled = true;
|
||||
TimerSetup(); /* reset timer */
|
||||
break;
|
||||
case "Disable":
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bEnabled = (m_bEnabled) ? false : true;
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ prop_physics::Respawn(void)
|
|||
if (HasSpawnFlags(PHYSPROPSFL_PHYSDEVICE))
|
||||
Sleep();
|
||||
|
||||
//Sleep();
|
||||
Sleep();
|
||||
}
|
||||
#else
|
||||
class
|
||||
|
|
|
@ -87,11 +87,3 @@ CLASSEXPORT(func_dustmotes, info_null)
|
|||
CLASSEXPORT(env_soundscape, info_null)
|
||||
CLASSEXPORT(env_cubemap, info_null)
|
||||
CLASSEXPORT(sky_camera, info_null)
|
||||
|
||||
void
|
||||
env_glow(void)
|
||||
{
|
||||
if (self.model) {
|
||||
precache_model(self.model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*!QUAKED trigger_monsterjump (.5 .5 .5) ?
|
||||
# OVERVIEW
|
||||
When monsters touch this volume, they will be forced to jump.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "target" : Target when triggered.
|
||||
- "speed" : Speed of the jump.
|
||||
- "height" : Height of the jump.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
*/
|
||||
class
|
||||
trigger_monsterjump:NSBrushTrigger
|
||||
{
|
||||
public:
|
||||
void trigger_monsterjump(void);
|
||||
|
||||
virtual void Respawn(void);
|
||||
virtual void Touch(entity);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
|
||||
private:
|
||||
float m_flSpeed;
|
||||
float m_flHeight;
|
||||
};
|
||||
|
||||
void
|
||||
trigger_monsterjump::trigger_monsterjump(void)
|
||||
{
|
||||
m_flSpeed = 0.0f;
|
||||
m_flHeight = 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
trigger_monsterjump::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "speed":
|
||||
m_flSpeed = ReadFloat(strValue);
|
||||
break;
|
||||
case "height":
|
||||
m_flHeight = ReadFloat(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
trigger_monsterjump::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
SaveFloat(handle, "m_flSpeed", m_flSpeed);
|
||||
SaveFloat(handle, "m_flHeight", m_flHeight);
|
||||
}
|
||||
|
||||
void
|
||||
trigger_monsterjump::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_flSpeed":
|
||||
m_flSpeed = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flHeight":
|
||||
m_flHeight = ReadFloat(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
trigger_monsterjump::Respawn(void)
|
||||
{
|
||||
InitBrushTrigger();
|
||||
}
|
||||
|
||||
void
|
||||
trigger_monsterjump::Touch(entity touchingEntity)
|
||||
{
|
||||
vector targetVelocity = g_vec_null;
|
||||
|
||||
if (!touchingEntity.flags & FL_MONSTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetMaster(touchingEntity) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMonster theMonster = (NSMonster)touchingEntity;
|
||||
targetVelocity = theMonster.GetForward() * m_flSpeed;
|
||||
targetVelocity[2] += m_flHeight;
|
||||
theMonster.SetVelocity(targetVelocity);
|
||||
}
|
|
@ -21,7 +21,7 @@ enumflags
|
|||
TM_PUSHABLES
|
||||
};
|
||||
|
||||
/*!QUAKED trigger_multiple (.5 .5 .5) ? TM_MONSTERS TM_NOCLIENTS TM_PUSHABLES
|
||||
/*!QUAKED trigger_multiple (.5 .5 .5) ? CLIENTS NPCS PUSHABLES PHYSICS FRIENDLIES CLIENTSINVEHICLES EVERYTHING x x CLIENTSNOTINVEHICLES DEBRIS NPCSINVEHICLES NOBOTS
|
||||
# OVERVIEW
|
||||
A trigger volume which works more than once.
|
||||
|
||||
|
@ -31,16 +31,40 @@ A trigger volume which works more than once.
|
|||
- "killtarget" : Target to kill when triggered.
|
||||
- "delay" : Delay until target is triggered.
|
||||
- "wait" : Time until this entity can trigger again
|
||||
- "StartDisabled" : Entity will have to be enabled in order to work when set to 1.
|
||||
|
||||
# INPUTS
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# OUTPUTS
|
||||
- "OnStartTouch": Triggered when something starts touching this volume
|
||||
- "OnEndTouchAll": Triggered when nothing touched the entity no more
|
||||
|
||||
# SPAWNFLAGS
|
||||
- TF_CLIENTS (1) : Clients can touch it.
|
||||
- TF_NPCS (2) : NPCs can touch it.
|
||||
- TF_PUSHABLE (4) : Pushables can touch it.
|
||||
- TF_PHYSICS (8) : NSPhysicsEntity based classes can touch it.
|
||||
- TF_FRIENDLIES (16) : Friendly NPCs can touch it.
|
||||
- TF_CLIENTSINVEHICLES (32) : Clients within vehicles can touch it.
|
||||
- TF_EVERYTHING (64) : Everything can touch it.
|
||||
- TF_CLIENTSNOTINVEHICLES (512) : Clients outside vehicles can touch it.
|
||||
- TF_DEBRIS (1024) : Debris can touch it.
|
||||
- TF_NPCSINVEHICLES (2048) : NPCs in vehicles can touch it.
|
||||
- TF_NOBOTS (4096) : Bots are never allowed to touch it.
|
||||
|
||||
# SPAWNFLAGS (LEGACY)
|
||||
These work when 'StartDisabled' is not set in the entity definition.
|
||||
|
||||
- TM_MONSTERS (1) : Allow NPCs to activate this entity.
|
||||
- TM_NOCLIENTS (2) : Don't allow players to activate this entity.
|
||||
- TM_PUSHABLES (4) : Allow func_pushables to trigger this entity.
|
||||
|
||||
# NOTES
|
||||
If you want an entity like this that can only be used once, see trigger_once.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
*/
|
||||
|
@ -61,9 +85,6 @@ public:
|
|||
|
||||
private:
|
||||
float m_flWait;
|
||||
bool m_bStartDisabled;
|
||||
bool m_bIsModern;
|
||||
bool m_bEnabled;
|
||||
|
||||
/* Input/Output */
|
||||
string m_strOnStartTouch;
|
||||
|
@ -80,8 +101,6 @@ trigger_multiple::trigger_multiple(void)
|
|||
m_strOnStartTouch =
|
||||
m_strOnEndTouchAll =
|
||||
m_strOnTrigger = __NULL__;
|
||||
m_bIsModern = false;
|
||||
m_bEnabled = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -89,9 +108,6 @@ trigger_multiple::Save(float handle)
|
|||
{
|
||||
super::Save(handle);
|
||||
SaveFloat(handle, "m_flWait", m_flWait);
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveBool(handle, "m_bIsModern", m_bIsModern);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
SaveString(handle, "m_strOnStartTouch", m_strOnStartTouch);
|
||||
SaveString(handle, "m_strOnEndTouchAll", m_strOnEndTouchAll);
|
||||
SaveString(handle, "m_strOnTrigger", m_strOnTrigger);
|
||||
|
@ -104,15 +120,6 @@ trigger_multiple::Restore(string strKey, string strValue)
|
|||
case "m_flWait":
|
||||
m_flWait = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bIsModern":
|
||||
m_bIsModern = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_strOnStartTouch":
|
||||
m_strOnStartTouch = ReadString(strValue);
|
||||
break;
|
||||
|
@ -170,22 +177,12 @@ void
|
|||
trigger_multiple::Respawn(void)
|
||||
{
|
||||
InitBrushTrigger();
|
||||
m_bEnabled = (m_bStartDisabled) ? false : true;
|
||||
}
|
||||
|
||||
void
|
||||
trigger_multiple::Input(entity entityActivator, string inputName, string dataField)
|
||||
{
|
||||
switch (inputName) {
|
||||
case "Enable":
|
||||
m_bEnabled = true;
|
||||
break;
|
||||
case "Disable":
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bEnabled = (m_bEnabled) ? false : true;
|
||||
break;
|
||||
case "TouchTest":
|
||||
Touch(entityActivator);
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,7 @@ enumflags
|
|||
TO_PUSHABLES
|
||||
};
|
||||
|
||||
/*!QUAKED trigger_once (.5 .5 .5) ? TO_MONSTERS TO_NOCLIENTS TO_PUSHABLES
|
||||
/*!QUAKED trigger_once (.5 .5 .5) ? CLIENTS NPCS PUSHABLES PHYSICS FRIENDLIES CLIENTSINVEHICLES EVERYTHING x x CLIENTSNOTINVEHICLES DEBRIS NPCSINVEHICLES NOBOTS
|
||||
# OVERVIEW
|
||||
A trigger volume which works only once.
|
||||
|
||||
|
@ -30,11 +30,35 @@ A trigger volume which works only once.
|
|||
- "target" : Target when triggered.
|
||||
- "killtarget" : Target to kill when triggered.
|
||||
- "delay" : Delay until target is triggered.
|
||||
- "StartDisabled" : Entity will have to be enabled in order to work when set to 1.
|
||||
|
||||
# INPUTS
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# SPAWNFLAGS
|
||||
- TO_MONSTERS (1) : Allow NPCs to activate this entity.
|
||||
- TO_NOCLIENTS (2) : Don't allow players to activate this entity.
|
||||
- TO_PUSHABLES (4) : Allow func_pushables to trigger this entity.
|
||||
- TF_CLIENTS (1) : Clients can touch it.
|
||||
- TF_NPCS (2) : NPCs can touch it.
|
||||
- TF_PUSHABLE (4) : Pushables can touch it.
|
||||
- TF_PHYSICS (8) : NSPhysicsEntity based classes can touch it.
|
||||
- TF_FRIENDLIES (16) : Friendly NPCs can touch it.
|
||||
- TF_CLIENTSINVEHICLES (32) : Clients within vehicles can touch it.
|
||||
- TF_EVERYTHING (64) : Everything can touch it.
|
||||
- TF_CLIENTSNOTINVEHICLES (512) : Clients outside vehicles can touch it.
|
||||
- TF_DEBRIS (1024) : Debris can touch it.
|
||||
- TF_NPCSINVEHICLES (2048) : NPCs in vehicles can touch it.
|
||||
- TF_NOBOTS (4096) : Bots are never allowed to touch it.
|
||||
|
||||
# SPAWNFLAGS (LEGACY)
|
||||
These work when 'StartDisabled' is not set in the entity definition.
|
||||
|
||||
- TM_MONSTERS (1) : Allow NPCs to activate this entity.
|
||||
- TM_NOCLIENTS (2) : Don't allow players to activate this entity.
|
||||
- TM_PUSHABLES (4) : Allow func_pushables to trigger this entity.
|
||||
|
||||
# NOTES
|
||||
If you want an entity like this that can be used more than once, see trigger_multiple.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
|
@ -55,11 +79,8 @@ public:
|
|||
virtual void Input(entity, string, string);
|
||||
|
||||
private:
|
||||
bool m_bStartDisabled;
|
||||
bool m_bEnabled;
|
||||
string m_strOnStartTouch;
|
||||
string m_strOnTrigger;
|
||||
bool m_bIsModern;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -67,9 +88,6 @@ trigger_once::trigger_once(void)
|
|||
{
|
||||
m_strOnStartTouch =
|
||||
m_strOnTrigger = __NULL__;
|
||||
m_bIsModern = false;
|
||||
m_bStartDisabled = false;
|
||||
m_bEnabled = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -88,39 +106,26 @@ trigger_once::Respawn(void)
|
|||
{
|
||||
InitBrushTrigger();
|
||||
m_iValue = 0;
|
||||
m_bEnabled = (m_bStartDisabled) ? false : true;
|
||||
}
|
||||
|
||||
void
|
||||
trigger_once::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
SaveString(handle, "m_strOnStartTouch", m_strOnStartTouch);
|
||||
SaveString(handle, "m_strOnTrigger", m_strOnTrigger);
|
||||
SaveBool(handle, "m_bIsModern", m_bIsModern);
|
||||
}
|
||||
|
||||
void
|
||||
trigger_once::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_strOnStartTouch":
|
||||
m_strOnStartTouch = ReadString(strValue);
|
||||
break;
|
||||
case "m_strOnTrigger":
|
||||
m_strOnTrigger = ReadString(strValue);
|
||||
break;
|
||||
case "m_bIsModern":
|
||||
m_bIsModern = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
|
@ -130,10 +135,6 @@ void
|
|||
trigger_once::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
m_bIsModern = true;
|
||||
break;
|
||||
case "OnStartTouch":
|
||||
m_strOnStartTouch = PrepareOutput(m_strOnStartTouch, strValue);
|
||||
break;
|
||||
|
@ -150,15 +151,6 @@ void
|
|||
trigger_once::Input(entity entityActivator, string inputName, string dataField)
|
||||
{
|
||||
switch (inputName) {
|
||||
case "Enable":
|
||||
m_bEnabled = true;
|
||||
break;
|
||||
case "Disable":
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bEnabled = (m_bEnabled) ? false : true;
|
||||
break;
|
||||
case "StartTouch":
|
||||
StartTouch(entityActivator);
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,7 @@ Freezing a player means they're unable to move, they can still look around.
|
|||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "killtarget" : Target to kill when triggered.
|
||||
- "killtarget" : Target to remove when triggered.
|
||||
|
||||
# NOTES
|
||||
Ideas: Add ability to supress looking around, firing weapons, using items
|
||||
|
|
|
@ -21,18 +21,26 @@ enumflags
|
|||
|
||||
/*!QUAKED trigger_relay (.5 .5 .5) ? TRLY_ONCE
|
||||
# OVERVIEW
|
||||
This is an inbetween trigger that forces a desired output state
|
||||
This is an in-between trigger that forces a desired output state
|
||||
instead of toggling e.g. a door open.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "target" : Target when triggered.
|
||||
- "killtarget" : Target to kill when triggered.
|
||||
- "delay" : Delay til the target is triggered.
|
||||
- "target" : Target to trigger.
|
||||
- "triggerstate" : Desired state of the triggered entity.
|
||||
- "delay" : Delay til the target is triggered, in seconds.
|
||||
- "killtarget" : Target to remove when triggered.
|
||||
|
||||
# SPAWNFLAGS
|
||||
- TRLY_ONCE (1) : Will be removed upon triggering its targets.
|
||||
- TRLY_ONCE (1) : When set, this entity will be removed upon triggering its targets.
|
||||
|
||||
# NOTES
|
||||
The `triggerstate` key can be one of three things:
|
||||
- 0: Off
|
||||
- 1: On
|
||||
- 2: Toggle
|
||||
|
||||
Where 'off' will close entities like func_door, and 'on' will open them.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
|
|
|
@ -20,18 +20,46 @@ enumflags
|
|||
TRIGTELE_NOCLIENTS
|
||||
};
|
||||
|
||||
/*!QUAKED trigger_teleport (.5 .5 .5) ? MONSTERS NOCLIENTS
|
||||
/*!QUAKED trigger_teleport (.5 .5 .5) ? CLIENTS NPCS PUSHABLES PHYSICS FRIENDLIES CLIENTSINVEHICLES EVERYTHING x x CLIENTSNOTINVEHICLES DEBRIS NPCSINVEHICLES NOBOTS
|
||||
# OVERVIEW
|
||||
Teleportation volume. Teleports anything it touches to the position of
|
||||
any entity set as the "target". Works best with info_teleport_destination.
|
||||
any entity set as the "target".
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "target" : Which target to teleport to.
|
||||
- "snd_teleport" : SoundDef to play on the entity teleporting.
|
||||
- "snd_teleport_enter" : SoundDef to play on the teleporter entrance.
|
||||
- "snd_teleport_exit" : SoundDef to play on the teleporter exit.
|
||||
- "StartDisabled" : Entity will have to be enabled in order to work when set to 1.
|
||||
|
||||
# INPUTS
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# SPAWNFLAGS
|
||||
- MONSTERS (1) : Allow monsters to use this teleporter.
|
||||
- NOCLIENTS (2) : Disallow clients from using this teleporter.
|
||||
- TF_CLIENTS (1) : Clients can touch it.
|
||||
- TF_NPCS (2) : NPCs can touch it.
|
||||
- TF_PUSHABLE (4) : Pushables can touch it.
|
||||
- TF_PHYSICS (8) : NSPhysicsEntity based classes can touch it.
|
||||
- TF_FRIENDLIES (16) : Friendly NPCs can touch it.
|
||||
- TF_CLIENTSINVEHICLES (32) : Clients within vehicles can touch it.
|
||||
- TF_EVERYTHING (64) : Everything can touch it.
|
||||
- TF_CLIENTSNOTINVEHICLES (512) : Clients outside vehicles can touch it.
|
||||
- TF_DEBRIS (1024) : Debris can touch it.
|
||||
- TF_NPCSINVEHICLES (2048) : NPCs in vehicles can touch it.
|
||||
- TF_NOBOTS (4096) : Bots are never allowed to touch it.
|
||||
|
||||
# SPAWNFLAGS (LEGACY)
|
||||
These work when 'StartDisabled' is not set in the entity definition.
|
||||
|
||||
- TM_MONSTERS (1) : Allow NPCs to activate this entity.
|
||||
- TM_NOCLIENTS (2) : Don't allow players to activate this entity.
|
||||
- TM_PUSHABLES (4) : Allow func_pushables to trigger this entity.
|
||||
|
||||
# NOTES
|
||||
Works best with info_teleport_destination, but you can in theory use any other point entity as well.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
|
@ -180,16 +208,24 @@ trigger_teleport::Touch(entity eToucher)
|
|||
entity eTarget = find(world, ::targetname, target);
|
||||
|
||||
if (eTarget) {
|
||||
vector endpos = eTarget.origin + [0,0,16];
|
||||
vector endpos = eTarget.origin;
|
||||
float flSpeed = vlen(eToucher.velocity);
|
||||
makevectors(eTarget.angles);
|
||||
eToucher.velocity = (v_forward * flSpeed);
|
||||
eToucher.angles = eTarget.angles;
|
||||
setorigin_safe(eToucher, endpos);
|
||||
|
||||
if (eToucher.flags & FL_CLIENT)
|
||||
if (eToucher.flags & FL_CLIENT) {
|
||||
Client_FixAngle(eToucher, eToucher.angles);
|
||||
|
||||
/* level designers place destinations where the feet
|
||||
are going to be, because monsters are mainly set up
|
||||
to be that way (0 0 0 being ground). players however
|
||||
have their it at the center of mass, so nudge it a little. */
|
||||
endpos[2] -= eToucher.mins[2];
|
||||
}
|
||||
|
||||
setorigin_safe(eToucher, endpos);
|
||||
|
||||
if (m_sndTeleport) {
|
||||
Sound_Play(eToucher, CHAN_VOICE, m_sndTeleport);
|
||||
}
|
||||
|
@ -212,8 +248,13 @@ trigger_teleport::Touch(entity eToucher)
|
|||
}
|
||||
|
||||
/*!QUAKED info_teleport_destination (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Entity designed to designate a destination for a trigger_teleport.
|
||||
|
||||
# KEYS
|
||||
"targetname" Name
|
||||
|
||||
Entity designed to designate a destination for a trigger_teleport.
|
||||
# TRIVIA
|
||||
This entity was introduced in Quake (1996).
|
||||
*/
|
||||
CLASSEXPORT(info_teleport_destination, info_notnull)
|
||||
|
|
|
@ -16,21 +16,30 @@
|
|||
|
||||
/*!QUAKED trigger_transition (.5 .5 .5) ?
|
||||
# OVERVIEW
|
||||
Currently unused. This is meant for defining level transition regions.
|
||||
Defines level transition regions.
|
||||
All entities touching this volume would carry across to the next level.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
|
||||
# NOTES
|
||||
In order for this entity to work, you have to assign a working info_landmark entity to your trigger_changelevel, and give this entity the same targetname as said landmark.
|
||||
|
||||
If you don't assign a transition, no entities will carry over currently. This is not accurate to vanilla behaviour in Half-Life but should mirror what Source does.
|
||||
In Half-Life, everything as part of the current PVS seems to carry over. This is probably not what you want to ever do, especially in large outdoor maps.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Half-Life (1998).
|
||||
*/
|
||||
class
|
||||
trigger_transition:NSBrushTrigger
|
||||
{
|
||||
public:
|
||||
void trigger_transition(void);
|
||||
|
||||
|
||||
/* overrides */
|
||||
virtual void Respawn(void);
|
||||
|
||||
nonvirtual void SaveTransition(void);
|
||||
nonvirtual NSEntity FindCarrierEntity(string);
|
||||
nonvirtual void LoadTransition(void);
|
||||
|
|
|
@ -15,12 +15,14 @@ shared/env_glow.qc
|
|||
shared/env_projectedtexture.qc
|
||||
shared/env_fog.qc
|
||||
shared/env_fog_controller.qc
|
||||
shared/env_cascade_light.qc
|
||||
shared/env_smoker.qc
|
||||
shared/env_muzzleflash.qc
|
||||
//shared/env_fire.qc
|
||||
shared/env_steam.qc
|
||||
shared/env_shockwave.qc
|
||||
shared/light_dynamic.qc
|
||||
shared/logic_achievement.qc
|
||||
shared/func_monitor.qc
|
||||
shared/func_illusionary.qc
|
||||
shared/func_ladder.qc
|
||||
|
@ -31,6 +33,7 @@ shared/trigger_camera.qc
|
|||
shared/trigger_gravity.qc
|
||||
shared/info_particle_system.qc
|
||||
shared/info_waypoint.qc
|
||||
shared/env_instructor_hint.qc
|
||||
shared/prop_physics_multiplayer.qc
|
||||
shared/prop_vehicle_driveable.qc
|
||||
shared/point_spotlight.qc
|
||||
|
@ -39,4 +42,5 @@ shared/func_conveyor.qc
|
|||
shared/prop_rope.qc
|
||||
shared/phys_rope.qc
|
||||
shared/worldspawn.qc
|
||||
shared/speaker.qc
|
||||
#endlist
|
||||
|
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enumflags
|
||||
{
|
||||
ENVCASLIGHT_CHANGED_ACTIVE,
|
||||
ENVCASLIGHT_CHANGED_ANGLE_X,
|
||||
ENVCASLIGHT_CHANGED_ANGLE_Y,
|
||||
ENVCASLIGHT_CHANGED_ANGLE_Z,
|
||||
ENVCASLIGHT_CHANGED_COLOR_X,
|
||||
ENVCASLIGHT_CHANGED_COLOR_Y,
|
||||
ENVCASLIGHT_CHANGED_COLOR_Z,
|
||||
ENVCASLIGHT_CHANGED_DISTANCE,
|
||||
};
|
||||
|
||||
/*!QUAKED env_cascade_light (1 .5 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Shadowmapped outdoor lighting entity.
|
||||
|
||||
![Shadows cast by an env_cascade_light](@ref Documentation/Entities/env_cascade_light.png)
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "color" : Color of the sun light. Three space separated 0-255 based values.
|
||||
- "maxshadowdistance" : Maximum shadow distance from the camera.
|
||||
- "uselightenvangles" : When set to 1, the angles are taken from the light_environment in the map.
|
||||
- "StartDisabled" : Entity will have to be enabled in order to work when set to 1.
|
||||
|
||||
# INPUTS
|
||||
- "SetAngles" : Sets the light angle.
|
||||
- "LightColor" : Sets the light color. Three space separated 0-255 based values.
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Counter-Strike: Global Offensive (2012).
|
||||
*/
|
||||
class
|
||||
env_cascade_light:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void env_cascade_light(void);
|
||||
|
||||
#ifdef SERVER
|
||||
virtual float SendEntity(entity,float);
|
||||
virtual void EvaluateEntity(void);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
virtual void Respawn(void);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Input(entity, string, string);
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
virtual void OnRemoveEntity(void);
|
||||
virtual void ReceiveEntity(float,float);
|
||||
virtual void RendererRestarted(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
NETWORKED_BOOL(m_bLightActive)
|
||||
NETWORKED_VECTOR(m_vecLightColor)
|
||||
NETWORKED_FLOAT(m_flShadowDistance)
|
||||
|
||||
#ifdef CLIENT
|
||||
float m_lightHandle;
|
||||
#else
|
||||
bool m_bUseEnvAngles;
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
env_cascade_light::env_cascade_light(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
m_vecLightColor = [1.0, 1.0, 1.0];
|
||||
m_bLightActive = true;
|
||||
m_flShadowDistance = 512.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
env_cascade_light::SpawnKey(string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "color":
|
||||
m_vecLightColor = ReadVector(setValue) / 255;
|
||||
break;
|
||||
case "maxshadowdistance":
|
||||
m_flShadowDistance = ReadFloat(setValue);
|
||||
break;
|
||||
case "uselightenvangles":
|
||||
m_bUseEnvAngles = ReadBool(setValue);
|
||||
break;
|
||||
case "StartDisabled":
|
||||
m_bLightActive = ReadBool(setValue) == true ? false : true;
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::Respawn(void)
|
||||
{
|
||||
InitPointTrigger();
|
||||
pvsflags = PVSF_IGNOREPVS;
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
SaveBool(handle, "m_bLightActive", m_bLightActive);
|
||||
SaveVector(handle, "m_vecLightColor", m_vecLightColor);
|
||||
SaveFloat(handle, "m_flShadowDistance", m_flShadowDistance);
|
||||
SaveBool(handle, "m_bUseEnvAngles", m_bUseEnvAngles);
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::Restore(string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "m_bLightActive":
|
||||
m_bLightActive = ReadBool(setValue);
|
||||
break;
|
||||
case "m_vecLightColor":
|
||||
m_vecLightColor = ReadVector(setValue);
|
||||
break;
|
||||
case "m_flShadowDistance":
|
||||
m_flShadowDistance = ReadFloat(setValue);
|
||||
break;
|
||||
case "m_bUseEnvAngles":
|
||||
m_bUseEnvAngles = ReadBool(setValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::Input(entity activatingEntity, string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "Enable":
|
||||
m_bLightActive = false;
|
||||
break;
|
||||
case "Disable":
|
||||
m_bLightActive = true;
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bLightActive = !m_bLightActive;
|
||||
break;
|
||||
case "SetAngles":
|
||||
angles = stov(setValue);
|
||||
break;
|
||||
case "LightColor":
|
||||
m_vecLightColor = stov(setValue) / 255;
|
||||
break;
|
||||
default:
|
||||
super::Input(activatingEntity, keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::Trigger(entity activatingEntity, triggermode_t triggerState)
|
||||
{
|
||||
switch (triggerState) {
|
||||
case TRIG_OFF:
|
||||
m_bLightActive = (false);
|
||||
break;
|
||||
case TRIG_ON:
|
||||
m_bLightActive = (true);
|
||||
break;
|
||||
default:
|
||||
m_bLightActive = (true - m_bLightActive);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::EvaluateEntity(void)
|
||||
{
|
||||
if (m_bUseEnvAngles == true) {
|
||||
light envLight = (light)find(world, ::classname, "light_environment");
|
||||
|
||||
if (!envLight) {
|
||||
error("env_cascade_light unable to find light_environment.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
makevectors(envLight.GetAngles());
|
||||
angles = vectoangles(v_forward * -1);
|
||||
}
|
||||
|
||||
//angles[0] = sin(time) * 180.0f;
|
||||
//angles[1] = sin(time*2) * 180.0f;
|
||||
|
||||
EVALUATE_FIELD(m_bLightActive, ENVCASLIGHT_CHANGED_ACTIVE)
|
||||
EVALUATE_VECTOR(angles, 0, ENVCASLIGHT_CHANGED_ANGLE_X)
|
||||
EVALUATE_VECTOR(angles, 1, ENVCASLIGHT_CHANGED_ANGLE_Y)
|
||||
EVALUATE_VECTOR(angles, 2, ENVCASLIGHT_CHANGED_ANGLE_Z)
|
||||
EVALUATE_VECTOR(m_vecLightColor, 0, ENVCASLIGHT_CHANGED_COLOR_X)
|
||||
EVALUATE_VECTOR(m_vecLightColor, 1, ENVCASLIGHT_CHANGED_COLOR_Y)
|
||||
EVALUATE_VECTOR(m_vecLightColor, 2, ENVCASLIGHT_CHANGED_COLOR_Z)
|
||||
EVALUATE_FIELD(m_flShadowDistance, ENVCASLIGHT_CHANGED_DISTANCE)
|
||||
}
|
||||
|
||||
float
|
||||
env_cascade_light::SendEntity(entity ePVEnt, float flChanged)
|
||||
{
|
||||
if (m_bLightActive == false)
|
||||
return (0);
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_CASCADELIGHT);
|
||||
WriteFloat(MSG_ENTITY, flChanged);
|
||||
|
||||
SENDENTITY_BYTE(m_bLightActive, ENVCASLIGHT_CHANGED_ACTIVE)
|
||||
SENDENTITY_COORD(angles[0], ENVCASLIGHT_CHANGED_ANGLE_X)
|
||||
SENDENTITY_COORD(angles[1], ENVCASLIGHT_CHANGED_ANGLE_Y)
|
||||
SENDENTITY_COORD(angles[2], ENVCASLIGHT_CHANGED_ANGLE_Z)
|
||||
SENDENTITY_COLOR(m_vecLightColor[0], ENVCASLIGHT_CHANGED_COLOR_X)
|
||||
SENDENTITY_COLOR(m_vecLightColor[1], ENVCASLIGHT_CHANGED_COLOR_Y)
|
||||
SENDENTITY_COLOR(m_vecLightColor[2], ENVCASLIGHT_CHANGED_COLOR_Z)
|
||||
SENDENTITY_FLOAT(m_flShadowDistance, ENVCASLIGHT_CHANGED_DISTANCE)
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
env_cascade_light::OnRemoveEntity(void)
|
||||
{
|
||||
/* this tells the engine to re-use this for a later light */
|
||||
dynamiclight_set(m_lightHandle, LFIELD_RADIUS, 0);
|
||||
m_lightHandle = 0;
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::LightChanged(float flFlags)
|
||||
{
|
||||
bool updateAngle = false;
|
||||
bool updateColor = false;
|
||||
|
||||
updateAngle |= (flFlags & ENVCASLIGHT_CHANGED_ANGLE_X) ? true : false;
|
||||
updateAngle |= (flFlags & ENVCASLIGHT_CHANGED_ANGLE_Y) ? true : false;
|
||||
updateAngle |= (flFlags & ENVCASLIGHT_CHANGED_ANGLE_Z) ? true : false;
|
||||
|
||||
updateColor |= (flFlags & ENVCASLIGHT_CHANGED_COLOR_X) ? true : false;
|
||||
updateColor |= (flFlags & ENVCASLIGHT_CHANGED_COLOR_Y) ? true : false;
|
||||
updateColor |= (flFlags & ENVCASLIGHT_CHANGED_COLOR_Z) ? true : false;
|
||||
|
||||
if (updateAngle) {
|
||||
dynamiclight_set(m_lightHandle, LFIELD_ANGLES, angles);
|
||||
}
|
||||
if (updateColor) {
|
||||
dynamiclight_set(m_lightHandle, LFIELD_COLOUR, m_vecLightColor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::ReceiveEntity(float flNew, float flChanged)
|
||||
{
|
||||
READENTITY_BYTE(m_bLightActive, ENVCASLIGHT_CHANGED_ACTIVE)
|
||||
READENTITY_COORD(angles[0], ENVCASLIGHT_CHANGED_ANGLE_X)
|
||||
READENTITY_COORD(angles[1], ENVCASLIGHT_CHANGED_ANGLE_Y)
|
||||
READENTITY_COORD(angles[2], ENVCASLIGHT_CHANGED_ANGLE_Z)
|
||||
READENTITY_COLOR(m_vecLightColor[0], ENVCASLIGHT_CHANGED_COLOR_X)
|
||||
READENTITY_COLOR(m_vecLightColor[1], ENVCASLIGHT_CHANGED_COLOR_Y)
|
||||
READENTITY_COLOR(m_vecLightColor[2], ENVCASLIGHT_CHANGED_COLOR_Z)
|
||||
READENTITY_FLOAT(m_flShadowDistance, ENVCASLIGHT_CHANGED_DISTANCE)
|
||||
|
||||
if (flNew) {
|
||||
RendererRestarted();
|
||||
} else {
|
||||
LightChanged(flChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_cascade_light::RendererRestarted(void)
|
||||
{
|
||||
OnRemoveEntity();
|
||||
m_lightHandle = dynamiclight_spawnstatic(origin, m_flShadowDistance, m_vecLightColor);
|
||||
dynamiclight_set(m_lightHandle, LFIELD_FLAGS, LFLAG_ORTHOSUN | LFLAG_SHADOWMAP | LFLAG_REALTIMEMODE);
|
||||
LightChanged(0xFFFFFF);
|
||||
}
|
||||
#endif
|
|
@ -33,11 +33,13 @@ enumflags
|
|||
enumflags
|
||||
{
|
||||
FUNNEL_REVERSE,
|
||||
FUNNEL_REPEATABLE
|
||||
};
|
||||
|
||||
/*!QUAKED env_funnel (1 .5 0) (-8 -8 -8) (8 8 8) REVERSE
|
||||
/*!QUAKED env_funnel (1 .5 0) (-8 -8 -8) (8 8 8) REVERSE REPEATABLE
|
||||
# OVERVIEW
|
||||
Controllable beam effect, akin to lightning. Also known as env_lightning.
|
||||
An effect that when triggered, will create lots of glowing orbs that funnel into
|
||||
the position of this entity.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enumflags
|
||||
{
|
||||
ENVINSTRUCTOR_CHANGED_ORIGIN,
|
||||
ENVINSTRUCTOR_CHANGED_IMAGE,
|
||||
ENVINSTRUCTOR_CHANGED_IMAGE_OFF,
|
||||
ENVINSTRUCTOR_CHANGED_TEXT,
|
||||
ENVINSTRUCTOR_CHANGED_TEXT_COLOR,
|
||||
ENVINSTRUCTOR_CHANGED_TIMEOUT,
|
||||
ENVINSTRUCTOR_CHANGED_OFFSET,
|
||||
ENVINSTRUCTOR_CHANGED_STATE
|
||||
};
|
||||
|
||||
/*!QUAKED env_instructor_hint (0 1 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Used to display hints throughout the environment.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "hint_caption" : Text of your hint.
|
||||
- "hint_color" : Color tint of your text.
|
||||
- "hint_icon_onscreen" : Icon to use when the hint is visible.
|
||||
- "hint_icon_offscreen" : Icon to use when the hint is out of view.
|
||||
- "hint_binding" : Name of the command that we'll display a key/button for.
|
||||
- "hint_nooffscreen" : When 1, will not show an off-screen hint at all.
|
||||
- "hint_target" : Hint will be displayed at the named entity.
|
||||
- "hint_static" : When 0, follows the entity specified in `hint_target`. Will be displayed on the heads-up-display otherwise.
|
||||
- "hint_allow_nodraw_target" : When 0, will stop rendering if the `hint_target` becomes invisible.
|
||||
- "hint_forcecaption" : When 1, will show the hint even if it's obscured by a wall.
|
||||
- "hint_icon_offset" : Height offset at which the hint will be displayed in-world.
|
||||
- "hint_pulseoption" : Speed at which the icon pulses in size. 0 is none, 3 is very fast.
|
||||
- "hint_alphaoption" : Speed at which the icon pulses in transparency. 0 is none, 3 is very fast.
|
||||
- "hint_shakeoption" : Strength at which the icon shakes. 0 is none, 2 is wide.
|
||||
- "hint_timeout" : Time until the hint stops showing. When 0, needs to be triggered to be disabled.
|
||||
- "hint_range" : Visible range of the hint in world units.
|
||||
- "hint_auto_start" : When set to 0, the entity no longer has to be triggered to show, line-of-sight will be enough.
|
||||
- "hint_display_limit" : Number of times this hint can be shown.
|
||||
|
||||
# INPUTS
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Left 4 Dead 2 (2009).
|
||||
*/
|
||||
class
|
||||
env_instructor_hint:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void env_instructor_hint(void);
|
||||
|
||||
#ifdef SERVER
|
||||
virtual void Respawn(void);
|
||||
virtual void SpawnKey(string,string);
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
virtual void Input(entity,string,string);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
|
||||
virtual void EvaluateEntity(void);
|
||||
virtual float SendEntity(entity,float);
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
virtual void ReceiveEntity(float, float);
|
||||
virtual void postdraw(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
PREDICTED_STRING(m_strIcon)
|
||||
PREDICTED_STRING(m_strIconOff)
|
||||
PREDICTED_STRING(m_strText)
|
||||
PREDICTED_VECTOR(m_vecTextColor)
|
||||
PREDICTED_BOOL(m_bEnabled)
|
||||
NETWORKED_FLOAT(m_flTimeOut)
|
||||
NETWORKED_FLOAT(m_flOffset)
|
||||
|
||||
#ifdef CLIENT
|
||||
bool m_bOldHintState;
|
||||
float m_flHintTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
env_instructor_hint::env_instructor_hint(void)
|
||||
{
|
||||
m_strIcon =
|
||||
m_strIconOff =
|
||||
m_strText = __NULL__;
|
||||
m_vecTextColor = [1,1,1];
|
||||
m_flTimeOut = 0.0f;
|
||||
m_flOffset = 0.0f;
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
env_instructor_hint::Respawn(void)
|
||||
{
|
||||
InitPointTrigger();
|
||||
m_bEnabled = false;
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::SpawnKey(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "hint_icon_onscreen":
|
||||
m_strIcon = strValue;
|
||||
break;
|
||||
case "hint_icon_offscreen":
|
||||
m_strIconOff = strValue;
|
||||
break;
|
||||
case "hint_caption":
|
||||
m_strText = strValue;
|
||||
break;
|
||||
case "hint_color":
|
||||
m_vecTextColor = ReadVector(strValue) / 255;
|
||||
break;
|
||||
case "hint_timeout":
|
||||
m_flTimeOut = ReadFloat(strValue);
|
||||
break;
|
||||
case "hint_icon_offset":
|
||||
m_flOffset = ReadFloat(strValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::Save(float handle)
|
||||
{
|
||||
super::Save(handle);
|
||||
SaveString(handle, "m_strIcon", m_strIcon);
|
||||
SaveString(handle, "m_strIconOff", m_strIconOff);
|
||||
SaveString(handle, "m_strText", m_strText);
|
||||
SaveVector(handle, "m_vecTextColor", m_vecTextColor);
|
||||
SaveFloat(handle, "m_flTimeOut", m_flTimeOut);
|
||||
SaveFloat(handle, "m_flOffset", m_flOffset);
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::Restore(string strKey, string strValue)
|
||||
{
|
||||
switch (strKey) {
|
||||
case "m_strIcon":
|
||||
m_strIcon = ReadString(strValue);
|
||||
break;
|
||||
case "m_strIconOff":
|
||||
m_strIconOff = ReadString(strValue);
|
||||
break;
|
||||
case "m_strText":
|
||||
m_strText = ReadString(strValue);
|
||||
break;
|
||||
case "m_vecTextColor":
|
||||
m_vecTextColor = ReadVector(strValue);
|
||||
break;
|
||||
case "m_flTimeOut":
|
||||
m_flTimeOut = ReadFloat(strValue);
|
||||
break;
|
||||
case "m_flOffset":
|
||||
m_flOffset = ReadFloat(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::Trigger(entity act, triggermode_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case TRIG_OFF:
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case TRIG_ON:
|
||||
m_bEnabled = true;
|
||||
break;
|
||||
default:
|
||||
m_bEnabled = m_bEnabled ? false : true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::Input(entity eAct, string strInput, string strData)
|
||||
{
|
||||
switch (strInput) {
|
||||
case "Enable":
|
||||
Trigger(eAct, TRIG_ON);
|
||||
break;
|
||||
case "Disable":
|
||||
Trigger(eAct, TRIG_OFF);
|
||||
break;
|
||||
case "Toggle":
|
||||
Trigger(eAct, TRIG_TOGGLE);
|
||||
break;
|
||||
default:
|
||||
super::Input(eAct, strInput, strData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::EvaluateEntity(void)
|
||||
{
|
||||
EVALUATE_VECTOR(origin, 0, ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
EVALUATE_VECTOR(origin, 1, ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
EVALUATE_VECTOR(origin, 2, ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
EVALUATE_FIELD(m_strIcon, ENVINSTRUCTOR_CHANGED_IMAGE)
|
||||
EVALUATE_FIELD(m_strIconOff, ENVINSTRUCTOR_CHANGED_IMAGE_OFF)
|
||||
EVALUATE_FIELD(m_strText, ENVINSTRUCTOR_CHANGED_TEXT)
|
||||
EVALUATE_VECTOR(m_vecTextColor, 0, ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
EVALUATE_VECTOR(m_vecTextColor, 1, ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
EVALUATE_VECTOR(m_vecTextColor, 2, ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
EVALUATE_FIELD(m_flTimeOut, ENVINSTRUCTOR_CHANGED_TIMEOUT)
|
||||
EVALUATE_FIELD(m_flOffset, ENVINSTRUCTOR_CHANGED_OFFSET)
|
||||
EVALUATE_FIELD(m_bEnabled, ENVINSTRUCTOR_CHANGED_STATE)
|
||||
pvsflags = PVSF_IGNOREPVS;
|
||||
}
|
||||
|
||||
float
|
||||
env_instructor_hint::SendEntity(entity ePEnt, float flChanged)
|
||||
{
|
||||
WriteByte(MSG_ENTITY, ENT_INSTRUCTOR);
|
||||
WriteFloat(MSG_ENTITY, flChanged);
|
||||
SENDENTITY_COORD(origin[0], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
SENDENTITY_COORD(origin[1], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
SENDENTITY_COORD(origin[2], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
SENDENTITY_STRING(m_strIcon, ENVINSTRUCTOR_CHANGED_IMAGE)
|
||||
SENDENTITY_STRING(m_strIconOff, ENVINSTRUCTOR_CHANGED_IMAGE_OFF)
|
||||
SENDENTITY_STRING(m_strText, ENVINSTRUCTOR_CHANGED_TEXT)
|
||||
SENDENTITY_COORD(m_vecTextColor[0], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
SENDENTITY_COORD(m_vecTextColor[1], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
SENDENTITY_COORD(m_vecTextColor[2], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
SENDENTITY_FLOAT(m_flTimeOut, ENVINSTRUCTOR_CHANGED_TIMEOUT)
|
||||
SENDENTITY_FLOAT(m_flOffset, ENVINSTRUCTOR_CHANGED_OFFSET)
|
||||
SENDENTITY_BYTE(m_bEnabled, ENVINSTRUCTOR_CHANGED_STATE)
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
env_instructor_hint::ReceiveEntity(float flNew, float flChanged)
|
||||
{
|
||||
READENTITY_COORD(origin[0], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
READENTITY_COORD(origin[1], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
READENTITY_COORD(origin[2], ENVINSTRUCTOR_CHANGED_ORIGIN)
|
||||
READENTITY_STRING(m_strIcon, ENVINSTRUCTOR_CHANGED_IMAGE)
|
||||
READENTITY_STRING(m_strIconOff, ENVINSTRUCTOR_CHANGED_IMAGE_OFF)
|
||||
READENTITY_STRING(m_strText, ENVINSTRUCTOR_CHANGED_TEXT)
|
||||
READENTITY_COORD(m_vecTextColor[0], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
READENTITY_COORD(m_vecTextColor[1], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
READENTITY_COORD(m_vecTextColor[2], ENVINSTRUCTOR_CHANGED_TEXT_COLOR)
|
||||
READENTITY_FLOAT(m_flTimeOut, ENVINSTRUCTOR_CHANGED_TIMEOUT)
|
||||
READENTITY_FLOAT(m_flOffset, ENVINSTRUCTOR_CHANGED_OFFSET)
|
||||
READENTITY_BYTE(m_bEnabled, ENVINSTRUCTOR_CHANGED_STATE)
|
||||
setorigin(this, origin);
|
||||
|
||||
if (m_bEnabled != m_bOldHintState) {
|
||||
m_flHintTime = m_flTimeOut;
|
||||
}
|
||||
m_bOldHintState = m_bEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
env_instructor_hint::postdraw(void)
|
||||
{
|
||||
bool visible = false;
|
||||
bool inView = false;
|
||||
vector positionValues;
|
||||
|
||||
if (!m_bEnabled)
|
||||
return;
|
||||
|
||||
if (m_flHintTime <= 0.0f)
|
||||
return;
|
||||
|
||||
/* calculation for the edge positions */
|
||||
{
|
||||
vector delta;
|
||||
vector p2 = g_view.GetCameraOrigin();
|
||||
vector ang = g_view.GetCameraAngle();
|
||||
vector outputValue;
|
||||
float leftValue;
|
||||
float upValue;
|
||||
|
||||
makevectors(ang);
|
||||
delta = normalize (origin - p2);
|
||||
|
||||
leftValue = delta * v_right;
|
||||
upValue = delta * -v_up;
|
||||
|
||||
positionValues[0] = (delta * v_forward);
|
||||
positionValues[1] = (leftValue + 1.0f) * 0.5f;
|
||||
positionValues[2] = (upValue + 1.0f) * 0.5f;
|
||||
|
||||
if (fabs(leftValue) > fabs(upValue)) {
|
||||
/* clamp leftvalue */
|
||||
if (positionValues[1] > 0.5)
|
||||
positionValues[1] = 1.0f;
|
||||
else
|
||||
positionValues[1] = 0.0f;
|
||||
} else {
|
||||
/* clamp upvalue */
|
||||
if (positionValues[2] > 0.5)
|
||||
positionValues[2] = 1.0f;
|
||||
else
|
||||
positionValues[2] = 0.0f;
|
||||
}
|
||||
|
||||
/* within field of view... */
|
||||
if (positionValues[0] > (g_view.GetAFOV()/180)) {
|
||||
traceline(p2, origin, MOVE_WORLDONLY, self);
|
||||
|
||||
/* totally visible */
|
||||
if (trace_fraction == 1.0) {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
inView = true;
|
||||
}
|
||||
}
|
||||
|
||||
vector iconPos;
|
||||
vector textPos;
|
||||
vector hintPos;
|
||||
float textLength = Font_StringWidth(m_strText, true, FONT_CON);
|
||||
float sideOffset = textLength + 64.0f;
|
||||
float a = (visible == false) ? 0.25 : 1.0f;
|
||||
a = 1.0f;
|
||||
|
||||
/* in-world position of the center */
|
||||
hintPos = project(origin + [0, m_flOffset]) - [(textLength * 0.5f), 0];
|
||||
|
||||
if (inView == false) {
|
||||
hintPos[0] = Math_Lerp(32.0f, video_res[0] - sideOffset, positionValues[1]);
|
||||
hintPos[1] = Math_Lerp(32.0f, video_res[1] - 32.0f, positionValues[2]);
|
||||
}
|
||||
|
||||
/* draw the thing */
|
||||
iconPos = hintPos - [32, 32];
|
||||
textPos = hintPos + [48.0f, 0];
|
||||
drawpic(iconPos, m_strIcon, [64, 64], [1,1,1], a);
|
||||
Font_DrawText_RGBA(textPos + [1,1], m_strText, [0,0,0], a, FONT_CON);
|
||||
Font_DrawText_RGBA(textPos, m_strText, m_vecTextColor, a, FONT_CON);
|
||||
|
||||
m_flHintTime -= clframetime;
|
||||
}
|
||||
#endif
|
|
@ -35,8 +35,9 @@ by players.
|
|||
- "Text" : A localised string to display next to it.
|
||||
|
||||
# INPUTS
|
||||
- "Enable" : Enables the entity.
|
||||
- "Disable" : Disables the entity.
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in Obsidian Conflict (2006).
|
||||
|
@ -74,7 +75,6 @@ info_waypoint::info_waypoint(void)
|
|||
{
|
||||
m_strIcon =
|
||||
m_strText = __NULL__;
|
||||
m_bEnabled = false;
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
|
@ -99,7 +99,6 @@ info_waypoint::Save(float handle)
|
|||
super::Save(handle);
|
||||
SaveString(handle, "m_strIcon", m_strIcon);
|
||||
SaveString(handle, "m_strText", m_strText);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -112,9 +111,6 @@ info_waypoint::Restore(string strKey, string strValue)
|
|||
case "m_strText":
|
||||
m_strText = ReadString(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
/*!QUAKED logic_achievement (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
Unlocks achievements or aids in the progression of them.
|
||||
|
||||
# KEYS
|
||||
- "targetname" : Name
|
||||
- "AchievementEvent" : Identifier of the achievement.
|
||||
- "StartDisabled" : Entity will have to be enabled in order to work when set to 1.
|
||||
|
||||
# INPUTS
|
||||
- "FireEvent" : Triggers the achievement.
|
||||
- "Enable" : Enable the entity.
|
||||
- "Disable" : Disable the entity.
|
||||
- "Toggle" : Toggles between enabled/disabled states.
|
||||
|
||||
# OUTPUTS
|
||||
- "OnFired" : Triggered when the 'FireEvent' is received.
|
||||
|
||||
# NOTES
|
||||
Ensure to prefix the value of the `AchievementEvent` key with `ACHIEVEMENT_EVENT_`. For example, if you are using SteamWorks and have your achievement on there named `FOOBAR` then you want the value to be `ACHIEVEMENT_EVENT_FOOBAR`.
|
||||
|
||||
# TRIVIA
|
||||
This entity was introduced in The Orange Box (2007) for Xbox 360.
|
||||
*/
|
||||
class
|
||||
logic_achievement:NSPointTrigger
|
||||
{
|
||||
public:
|
||||
void logic_achievement(void);
|
||||
|
||||
/** overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string, string);
|
||||
virtual void SpawnKey(string, string);
|
||||
virtual void Spawned(void);
|
||||
virtual void Respawn(void);
|
||||
virtual void Input(entity, string, string);
|
||||
virtual void Trigger(entity, triggermode_t);
|
||||
|
||||
nonvirtual void CallEvent(entity);
|
||||
|
||||
private:
|
||||
string m_strAchievementEvent;
|
||||
string m_strOnFired;
|
||||
};
|
||||
|
||||
void
|
||||
logic_achievement::logic_achievement(void)
|
||||
{
|
||||
m_strAchievementEvent = __NULL__;
|
||||
m_strOnFired = __NULL__;
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Save(float handle)
|
||||
{
|
||||
SaveString(handle, "m_strAchievementEvent", m_strAchievementEvent);
|
||||
SaveString(handle, "m_strOnFired", m_strOnFired);
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Restore(string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "m_strAchievementEvent":
|
||||
m_strAchievementEvent = ReadString(setValue);
|
||||
break;
|
||||
case "m_strOnFired":
|
||||
m_strOnFired = ReadString(setValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::SpawnKey(string keyName, string setValue)
|
||||
{
|
||||
switch (keyName) {
|
||||
case "AchievementEvent":
|
||||
m_strAchievementEvent = ReadString(setValue);
|
||||
break;
|
||||
case "OnFired":
|
||||
m_strOnFired = PrepareOutput(m_strOnFired, setValue);
|
||||
break;
|
||||
default:
|
||||
super::SpawnKey(keyName, setValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Spawned(void)
|
||||
{
|
||||
super::Spawned();
|
||||
|
||||
if (m_strOnFired)
|
||||
m_strOnFired = CreateOutput(m_strOnFired);
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Respawn(void)
|
||||
{
|
||||
InitPointTrigger();
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Input(entity activatorEntity, string inputName, string dataField)
|
||||
{
|
||||
switch (inputName) {
|
||||
case "FireEvent":
|
||||
CallEvent(activatorEntity);
|
||||
break;
|
||||
default:
|
||||
super::Input(activatorEntity, inputName, dataField);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::Trigger(entity activatorEntity, triggermode_t state)
|
||||
{
|
||||
CallEvent(activatorEntity);
|
||||
}
|
||||
|
||||
void
|
||||
logic_achievement::CallEvent(entity targetPlayer)
|
||||
{
|
||||
if (m_bEnabled == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
UseOutput(targetPlayer, m_strOnFired);
|
||||
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_ACHIEVEMENT);
|
||||
WriteString(MSG_MULTICAST, m_strAchievementEvent);
|
||||
msg_entity = targetPlayer;
|
||||
multicast([0,0,0], MULTICAST_ONE_R);
|
||||
}
|
||||
#endif
|
|
@ -14,6 +14,7 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
enumflags
|
||||
{
|
||||
SPEAKFL_SILENT
|
||||
|
@ -33,6 +34,7 @@ string g_speaker_hlpresets[] = {
|
|||
"!C3A1_",
|
||||
"!C3A2_"
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!QUAKED speaker (1 0 0) (-8 -8 -8) (8 8 8)
|
||||
# OVERVIEW
|
||||
|
@ -69,7 +71,8 @@ speaker:NSTalkMonster
|
|||
{
|
||||
public:
|
||||
void speaker(void);
|
||||
|
||||
|
||||
#ifdef SERVER
|
||||
/* overrides */
|
||||
virtual void Save(float);
|
||||
virtual void Restore(string,string);
|
||||
|
@ -79,18 +82,32 @@ public:
|
|||
|
||||
nonvirtual void Announce(void);
|
||||
|
||||
virtual void EvaluateEntity(void);
|
||||
virtual float SendEntity(entity,float);
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
virtual void ReceiveEntity(float, float);
|
||||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
private:
|
||||
|
||||
string m_strSentence;
|
||||
float m_flVolume;
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
speaker::speaker(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
m_strSentence = __NULL__;
|
||||
m_flVolume = 1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
speaker::Save(float handle)
|
||||
{
|
||||
|
@ -139,10 +156,7 @@ speaker::SpawnKey(string strKey, string strValue)
|
|||
void
|
||||
speaker::Respawn(void)
|
||||
{
|
||||
/* force this thing to be networked */
|
||||
SetModel("models/player.mdl");
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
Hide();
|
||||
|
||||
if (HasSpawnFlags(SPEAKFL_SILENT) == false)
|
||||
ScheduleThink(Announce, 10.0f);
|
||||
|
@ -173,3 +187,42 @@ speaker::Trigger(entity eAct, triggermode_t foo)
|
|||
{
|
||||
ScheduleThink(Announce, 0.0f);
|
||||
}
|
||||
|
||||
void
|
||||
speaker::EvaluateEntity(void)
|
||||
{
|
||||
EVALUATE_VECTOR(origin, 0, MONFL_CHANGED_ORIGIN_X)
|
||||
EVALUATE_VECTOR(origin, 1, MONFL_CHANGED_ORIGIN_Y)
|
||||
EVALUATE_VECTOR(origin, 2, MONFL_CHANGED_ORIGIN_Z)
|
||||
}
|
||||
|
||||
/* Make sure StartFrame calls this */
|
||||
float
|
||||
speaker::SendEntity(entity ePEnt, float flChanged)
|
||||
{
|
||||
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
|
||||
return (0);
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_SPEAKER);
|
||||
|
||||
/* broadcast how much data is expected to be read */
|
||||
WriteFloat(MSG_ENTITY, flChanged);
|
||||
|
||||
SENDENTITY_COORD(origin[0], MONFL_CHANGED_ORIGIN_X)
|
||||
SENDENTITY_COORD(origin[1], MONFL_CHANGED_ORIGIN_Y)
|
||||
SENDENTITY_COORD(origin[2], MONFL_CHANGED_ORIGIN_Z)
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
speaker::ReceiveEntity(float flNew, float flChanged)
|
||||
{
|
||||
READENTITY_COORD(origin[0], MONFL_CHANGED_ORIGIN_X)
|
||||
READENTITY_COORD(origin[1], MONFL_CHANGED_ORIGIN_Y)
|
||||
READENTITY_COORD(origin[2], MONFL_CHANGED_ORIGIN_Z)
|
||||
SetOrigin(origin);
|
||||
}
|
||||
#endif
|
|
@ -394,11 +394,9 @@ initents(void)
|
|||
PMove_Init();
|
||||
|
||||
/** compat... */
|
||||
precache_sound("misc/null.wav");
|
||||
precache_sound("common/null.wav");
|
||||
|
||||
Sound_Precache("player.GaspLight");
|
||||
Sound_Precache("player.GaspHeavy");
|
||||
Sound_Precache("Player.GaspLight");
|
||||
Sound_Precache("Player.GaspHeavy");
|
||||
Sound_Precache("player.WaterEnter");
|
||||
Sound_Precache("player.WaterExit");
|
||||
Sound_Precache("Player.Death");
|
||||
|
@ -407,9 +405,12 @@ initents(void)
|
|||
Sound_Precache("Player.Swim");
|
||||
Sound_Precache("Player.DenyWeaonSelection");
|
||||
Sound_Precache("Player.WeaponSelected");
|
||||
Sound_Precache("Player.FallDamage");
|
||||
Sound_Precache("Player.LightFall");
|
||||
Sound_Precache("Player.FallGib");
|
||||
|
||||
Sound_Precache("damage_bullet.hit");
|
||||
Sound_Precache("player.spraylogo");
|
||||
Sound_Precache("SprayCan.Paint");
|
||||
Sound_Precache("step_ladder.left");
|
||||
Sound_Precache("step_ladder.right");
|
||||
|
||||
|
@ -558,6 +559,9 @@ ConsoleCmd(string cmd)
|
|||
Way_Cmd();
|
||||
break;
|
||||
#endif
|
||||
case "listSoundDef":
|
||||
Sound_DebugList();
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -35,4 +35,8 @@ NSBrushTrigger::InitBrushTrigger(void)
|
|||
SetModel(GetSpawnModel());
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
SetSolid(SOLID_BSPTRIGGER);
|
||||
|
||||
#ifdef SERVER
|
||||
m_bEnabled = (m_bStartDisabled) ? false : true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -303,20 +303,13 @@ NSClientPlayer::predraw(void)
|
|||
if (entnum == player_localentnum)
|
||||
g_view.SetDrawLocalPlayer(true);
|
||||
|
||||
/* sucks we can't draw a shadow on this thing, maybe in the future when FTEQW allows it */
|
||||
if (p_model) {
|
||||
if (p_model.GetRenderMode() != RM_DONTRENDER)
|
||||
addentity(p_model);
|
||||
}
|
||||
} else { /* we're doing first person stuff */
|
||||
/* flags that the model appear in mirrors only */
|
||||
renderflags |= RF_EXTERNALMODEL;
|
||||
|
||||
/* ditto */
|
||||
p_model.renderflags |= RF_EXTERNALMODEL;
|
||||
|
||||
/* give mods a chance to de-render attachments */
|
||||
UpdatePlayerAttachments(false);
|
||||
UpdatePlayerAttachments(true);
|
||||
Weapons_PreDraw((player)this, false);
|
||||
|
||||
/* this is here just to make sure our view hides us if it's the local player */
|
||||
|
@ -324,6 +317,16 @@ NSClientPlayer::predraw(void)
|
|||
g_view.SetDrawLocalPlayer(false);
|
||||
}
|
||||
|
||||
if (p_model) {
|
||||
p_model.entnum = entnum;
|
||||
p_model.drawmask = 0;
|
||||
|
||||
if (p_model.GetRenderMode() != RM_DONTRENDER)
|
||||
addentity(p_model);
|
||||
|
||||
p_model.entnum = 0;
|
||||
}
|
||||
|
||||
/* this needs to be called absolutely last */
|
||||
/* we're calling this so that the shadow can still be drawn */
|
||||
if (GetRenderMode() != RM_DONTRENDER)
|
||||
|
@ -1162,10 +1165,10 @@ NSClientPlayer::InputUse_Down(void)
|
|||
|
||||
/* Some entities want to support Use spamming */
|
||||
if (HasFlags(FL_USE_RELEASED) == false) {
|
||||
sound(this, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE);
|
||||
StartSoundDef("Player.WeaponSelected", CHAN_ITEM, false);
|
||||
}
|
||||
} else {
|
||||
sound(this, CHAN_ITEM, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE);
|
||||
StartSoundDef("Player.DenyWeaponSelection", CHAN_ITEM, false);
|
||||
flags &= ~FL_USE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
@ -1208,27 +1211,15 @@ NSClientPlayer::Footsteps_Update(void)
|
|||
return;
|
||||
|
||||
if (waterlevel == 1) {
|
||||
if (step)
|
||||
StartSoundDef("step_slosh.left", CHAN_BODY, true);
|
||||
else
|
||||
StartSoundDef("step_slosh.right", CHAN_BODY, true);
|
||||
|
||||
step_time = time + 0.35f;
|
||||
StartSoundDef("Player.Wade", CHAN_BODY, true);
|
||||
step_time = time + 2.0f;
|
||||
return;
|
||||
} else if (waterlevel == 2) {
|
||||
if (step)
|
||||
StartSoundDef("step_wade.left", CHAN_BODY, true);
|
||||
else
|
||||
StartSoundDef("step_wade.right", CHAN_BODY, true);
|
||||
|
||||
step_time = time + 1.0f;
|
||||
StartSoundDef("Player.Wade", CHAN_BODY, true);
|
||||
step_time = time + 2.0f;
|
||||
return;
|
||||
} else if (waterlevel == 3) {
|
||||
if (step)
|
||||
StartSoundDef("step_swim.left", CHAN_BODY, true);
|
||||
else
|
||||
StartSoundDef("step_swim.right", CHAN_BODY, true);
|
||||
|
||||
StartSoundDef("Player.Swim", CHAN_BODY, true);
|
||||
step_time = time + 2.0f;
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,19 @@ NSItem::Spawned(void)
|
|||
void
|
||||
NSItem::Respawn(void)
|
||||
{
|
||||
/* we need to delay the DropToFloor() by at least a frame.
|
||||
otherwise they may just fall through an entity (func_wall, func_train etc.)
|
||||
that came after this entity in the lump. */
|
||||
static void AdjustSpawnPos(void) {
|
||||
RestoreAngles();
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
|
||||
if (!m_bFloating) {
|
||||
DropToFloor();
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
}
|
||||
}
|
||||
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
SetOrigin(GetSpawnOrigin());
|
||||
botinfo = BOTINFO_WEAPON;
|
||||
|
@ -54,12 +67,7 @@ NSItem::Respawn(void)
|
|||
}
|
||||
|
||||
SetSize([-16,-16,0], [16,16,16]);
|
||||
ReleaseThink();
|
||||
|
||||
if (!m_bFloating) {
|
||||
DropToFloor();
|
||||
SetMovetype(MOVETYPE_TOSS);
|
||||
}
|
||||
ScheduleThink(AdjustSpawnPos, 0.0f);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -148,7 +148,7 @@ typedef enumflags
|
|||
MSF_RESERVED2,
|
||||
MSF_IGNOREPLAYER,
|
||||
MSF_WAITFORSCRIPT,
|
||||
MSF_PREDISASTER,
|
||||
MSF_RESERVED3,
|
||||
MSF_FADECORPSE,
|
||||
MSF_MULTIPLAYER,
|
||||
MSF_FALLING,
|
||||
|
@ -381,6 +381,8 @@ public:
|
|||
|
||||
/** Returns TRUE if 'enemy' should be considered a valid target for killing */
|
||||
nonvirtual bool IsValidEnemy(entity);
|
||||
/** Returns TRUE if the monster is currently on route to a position. */
|
||||
virtual bool IsOnRoute(void);
|
||||
|
||||
/* sequences */
|
||||
/** Internal use only. Called when a sequence is done. */
|
||||
|
|
|
@ -646,6 +646,12 @@ NSMonster::IsValidEnemy(entity enny)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NSMonster::IsOnRoute(void)
|
||||
{
|
||||
return (m_iNodes || m_pathTarget) && (GetState() == MONSTER_IDLE || GetState() == MONSTER_ALERT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
NSMonster_TraceAgainsTarget(NSMonster monster, NSEntity target)
|
||||
{
|
||||
|
@ -1258,12 +1264,11 @@ NSMonster::RouteEnded(void)
|
|||
void
|
||||
NSMonster::WalkRoute(void)
|
||||
{
|
||||
|
||||
/* we're busy shooting at something, don't walk */
|
||||
if (GetState() == MONSTER_AIMING && m_eEnemy) {
|
||||
input_angles = vectoangles(m_eEnemy.origin - origin);
|
||||
input_angles[0] = input_angles[2] = 0;
|
||||
} else if ((m_iNodes || m_pathTarget) && (GetState() == MONSTER_IDLE || GetState() == MONSTER_ALERT)) {
|
||||
} else if (IsOnRoute()) {
|
||||
input_angles = GetRouteDirection();
|
||||
input_angles[0] = input_angles[2] = 0;
|
||||
input_movevalues = GetRouteMovevalues() * m_flSequenceSpeed;
|
||||
|
@ -1548,8 +1553,30 @@ NSMonster::Touch(entity eToucher)
|
|||
|
||||
if (autocvar(pm_pushMonsters, 0))
|
||||
if (eToucher.movetype == MOVETYPE_WALK) {
|
||||
if (eToucher.absmin[2] < origin[2])
|
||||
velocity = normalize(eToucher.origin - origin) * -128;
|
||||
if (eToucher.absmin[2] < origin[2]) {
|
||||
float bestYaw = 0.0f;
|
||||
float best_fraction = 0.0f;
|
||||
vector bestPos = g_vec_null;
|
||||
|
||||
for (float yaw = angles[1]; yaw < (angles[1] + 360.0f); yaw += 1.0f) {
|
||||
makevectors([0, yaw, 0]);
|
||||
tracebox(origin, mins, maxs, origin + (v_forward * 128.0f), FALSE, this);
|
||||
|
||||
if (trace_startsolid) {
|
||||
bestYaw = random(0, 360);
|
||||
break;
|
||||
}
|
||||
|
||||
if (trace_fraction > best_fraction) {
|
||||
best_fraction = trace_fraction;
|
||||
bestYaw = yaw;
|
||||
bestPos = trace_endpos;
|
||||
}
|
||||
}
|
||||
|
||||
RouteToPosition(bestPos);
|
||||
m_flSequenceSpeed = GetWalkSpeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ NSPointTrigger::InitPointTrigger(void)
|
|||
{
|
||||
SetSize(VEC_HULL_MIN, VEC_HULL_MAX);
|
||||
SetSolid(SOLID_TRIGGER);
|
||||
|
||||
#ifdef SERVER
|
||||
m_bEnabled = (m_bStartDisabled) ? false : true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -170,6 +170,6 @@ CSEv_Spraylogo(void)
|
|||
spray.SendEntity = Spray_SendEntity;
|
||||
spray.SendFlags = 1;
|
||||
|
||||
Sound_Play(self, CHAN_VOICE, "player.spraylogo");
|
||||
Sound_Play(self, CHAN_VOICE, "SprayCan.Paint");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -308,6 +308,9 @@ NSTalkMonster::Speak(string sentence)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerGreet(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
|
||||
|
@ -336,10 +339,12 @@ NSTalkMonster::TalkPlayerGreet(void)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerIdle(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
if (HasSpawnFlags(MSF_PREDISASTER))
|
||||
return;
|
||||
|
||||
if (m_flNextSentence > time)
|
||||
return;
|
||||
|
||||
|
@ -366,10 +371,12 @@ NSTalkMonster::TalkPlayerIdle(void)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerAsk(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
if (HasSpawnFlags(MSF_PREDISASTER))
|
||||
return;
|
||||
|
||||
if (m_flNextSentence > time)
|
||||
return;
|
||||
|
||||
|
@ -391,6 +398,9 @@ NSTalkMonster::TalkPlayerAsk(void)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerWounded1(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
|
||||
|
@ -417,6 +427,9 @@ NSTalkMonster::TalkPlayerWounded1(void)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerWounded2(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
|
||||
|
@ -444,6 +457,9 @@ NSTalkMonster::TalkPlayerWounded2(void)
|
|||
void
|
||||
NSTalkMonster::TalkPlayerWounded3(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
|
||||
|
@ -468,6 +484,9 @@ NSTalkMonster::TalkPlayerWounded3(void)
|
|||
void
|
||||
NSTalkMonster::TalkPanic(void)
|
||||
{
|
||||
if (HasSpawnFlags(MSF_GAG))
|
||||
return;
|
||||
|
||||
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
||||
return;
|
||||
|
||||
|
@ -519,6 +538,9 @@ NSTalkMonster::TalkDenyFollow(void)
|
|||
void
|
||||
NSTalkMonster::Touch(entity eToucher)
|
||||
{
|
||||
if (eToucher == world)
|
||||
return;
|
||||
|
||||
if (eToucher == m_eFollowing) {
|
||||
makevectors(eToucher.angles);
|
||||
velocity = v_forward * 250.0f;
|
||||
|
@ -634,23 +656,35 @@ NSTalkMonster::FollowPlayer(void)
|
|||
void
|
||||
NSTalkMonster::PanicFrame(void)
|
||||
{
|
||||
float bestYaw = 0.0f;
|
||||
float best_fraction = 0.0f;
|
||||
float secondBest = 0.0f;
|
||||
|
||||
m_iFlags |= MONSTER_METPLAYER;
|
||||
input_movevalues = [240, 0, 0];
|
||||
|
||||
if (m_flTraceTime < time) {
|
||||
traceline(origin, origin + (v_forward * 64), FALSE, this);
|
||||
|
||||
if (trace_fraction < 1.0f) {
|
||||
m_flChangePath = 0.0f;
|
||||
for (float yaw = -180.0f; yaw < 180.0f; yaw += 1.0f) {
|
||||
makevectors([0, yaw, 0]);
|
||||
tracebox(origin, mins, maxs, origin + (v_forward * 1024), FALSE, this);
|
||||
|
||||
if (trace_startsolid) {
|
||||
bestYaw = random(0, 360);
|
||||
break;
|
||||
}
|
||||
|
||||
if (trace_fraction > best_fraction) {
|
||||
best_fraction = trace_fraction;
|
||||
bestYaw = yaw;
|
||||
}
|
||||
}
|
||||
m_flTraceTime = time + 0.5f;
|
||||
|
||||
angles[1] = Math_FixDelta(bestYaw + random(-25, 25));
|
||||
input_angles[1] = angles[1];
|
||||
v_angle[1] = angles[1];
|
||||
m_flTraceTime = time + 0.5f + random();
|
||||
}
|
||||
|
||||
if (m_flChangePath < time) {
|
||||
input_angles[1] -= 180 + ((random() - 0.5) * 90);
|
||||
input_angles[1] = Math_FixDelta(input_angles[1]);
|
||||
m_flChangePath = time + floor(random(2,10));
|
||||
}
|
||||
|
||||
if (m_flNextSentence > time)
|
||||
return;
|
||||
|
@ -1112,7 +1146,7 @@ NSTalkMonster_ParseSentence(void)
|
|||
ent = findfloat(world, entnum, e);
|
||||
|
||||
if (ent) {
|
||||
if (ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic")
|
||||
if (ent.classname != "speaker" && ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic")
|
||||
NSMonster_Log("^3 NSTalkMonster_ParseSentence ^7: Entity %d not a NSTalkMonster!", e);
|
||||
else {
|
||||
targ = (NSTalkMonster)ent;
|
||||
|
|
|
@ -55,6 +55,8 @@ enumflags
|
|||
TOUCHFILTER_FRIENDLIES,
|
||||
TOUCHFILTER_CLIENTSINVEHICLES,
|
||||
TOUCHFILTER_EVERYTHING,
|
||||
TOUCHFILTER_PADDING1,
|
||||
TOUCHFILTER_PADDING2,
|
||||
TOUCHFILTER_CLIENTSNOTINVEHICLES,
|
||||
TOUCHFILTER_DEBRIS,
|
||||
TOUCHFILTER_NPCSINVEHICLES,
|
||||
|
@ -154,6 +156,10 @@ private:
|
|||
int m_iUseType;
|
||||
int m_iValue;
|
||||
|
||||
bool m_bEnabled;
|
||||
bool m_bStartDisabled;
|
||||
bool m_bIsModern;
|
||||
|
||||
float team_no;
|
||||
|
||||
/* legacy trigger architecture */
|
||||
|
|
|
@ -30,6 +30,9 @@ NSTrigger::NSTrigger(void)
|
|||
team = 0;
|
||||
m_iValue = 0i;
|
||||
m_flDelay = 0.0f;
|
||||
m_bStartDisabled = false;
|
||||
m_bEnabled = true;
|
||||
m_bIsModern = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -236,6 +239,9 @@ NSTrigger::Save(float handle)
|
|||
SaveInt(handle, "m_iValue", m_iValue);
|
||||
SaveFloat(handle, "m_flDelay", m_flDelay);
|
||||
SaveString(handle, "m_strGlobalName", m_strGlobalName);
|
||||
SaveBool(handle, "m_bStartDisabled", m_bStartDisabled);
|
||||
SaveBool(handle, "m_bEnabled", m_bEnabled);
|
||||
SaveBool(handle, "m_bIsModern", m_bIsModern);
|
||||
}
|
||||
void
|
||||
NSTrigger::Restore(string strKey, string strValue)
|
||||
|
@ -271,6 +277,15 @@ NSTrigger::Restore(string strKey, string strValue)
|
|||
case "m_strGlobalName":
|
||||
m_strGlobalName = ReadString(strValue);
|
||||
break;
|
||||
case "m_bStartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bEnabled":
|
||||
m_bEnabled = ReadBool(strValue);
|
||||
break;
|
||||
case "m_bIsModern":
|
||||
m_bIsModern = ReadBool(strValue);
|
||||
break;
|
||||
default:
|
||||
super::Restore(strKey, strValue);
|
||||
}
|
||||
|
@ -283,6 +298,15 @@ NSTrigger::Input(entity eAct, string strInput, string strData)
|
|||
case "Trigger":
|
||||
Trigger(eAct, TRIG_TOGGLE);
|
||||
break;
|
||||
case "Enable":
|
||||
m_bEnabled = true;
|
||||
break;
|
||||
case "Disable":
|
||||
m_bEnabled = false;
|
||||
break;
|
||||
case "Toggle":
|
||||
m_bEnabled = (m_bEnabled) ? false : true;
|
||||
break;
|
||||
default:
|
||||
super:: Input(eAct, strInput, strData);
|
||||
}
|
||||
|
@ -333,6 +357,10 @@ NSTrigger::SpawnKey(string strKey, string strValue)
|
|||
case "globalname":
|
||||
m_strGlobalName = ReadString(strValue);
|
||||
break;
|
||||
case "StartDisabled":
|
||||
m_bStartDisabled = ReadBool(strValue);
|
||||
m_bIsModern = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
super::SpawnKey(strKey, strValue);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2022 Vera Visions LLC.
|
||||
* Copyright (c) 2016-2023 Vera Visions LLC.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -25,6 +25,7 @@ typedef enum
|
|||
ENT_PHYSICS, /**< of type NSPhysicsEntity */
|
||||
ENT_MONSTER, /**< of type NSMonster */
|
||||
ENT_TALKMONSTER, /**< of type NSTalkMonster */
|
||||
ENT_SPEAKER, /**< of type speaker */
|
||||
ENT_PLAYER, /**< of type NSClientPlayer */
|
||||
ENT_WEAPON, /**< of type NSWeapon */
|
||||
ENT_SPECTATOR, /**< of type NSClientSpectator */
|
||||
|
@ -37,8 +38,9 @@ typedef enum
|
|||
ENT_PROJECTEDTEXTURE, /**< of type env_projectedtexture */
|
||||
ENT_SPOTLIGHT, /**< of type point_spotlight */
|
||||
ENT_FOG, /*<< of type env_fog */
|
||||
ENT_STEAM,
|
||||
ENT_STEAM, /*<< of type env_steam */
|
||||
ENT_FOGCONTROLLER, /**< of type env_fog_controller */
|
||||
ENT_CASCADELIGHT, /*<< of type env_cascade_light */
|
||||
ENT_LASER, /**< of type env_laser */
|
||||
ENT_PARTSYSTEM, /**< of type info_particle_system */
|
||||
ENT_SPRITE, /**< of type env_sprite */
|
||||
|
@ -56,6 +58,7 @@ typedef enum
|
|||
ENT_BUBBLES, /**< of type env_bubbles */
|
||||
ENT_CONVEYOR, /**< of type func_conveyor */
|
||||
ENT_WAYPOINT, /**< of type info_waypoint */
|
||||
ENT_INSTRUCTOR, /**< of type env_instructor_hint */
|
||||
ENT_PUSH, /**< of type trigger_push */
|
||||
ENT_SEPARATOR, /**< This is a separator. This separator is used by you to add game-specific networked entities. When declaring your own entity-update types, you want the first value to equal ENT_SEPARATOR at all times to ensure you'll not be overriding existing slots. */
|
||||
} entupdate_t;
|
||||
|
|
|
@ -59,5 +59,6 @@ enum
|
|||
EV_BEAMCYLINDER,
|
||||
EV_MUZZLEFLASH,
|
||||
EV_TRACEDEBUG,
|
||||
EV_ACHIEVEMENT,
|
||||
EV_SEPARATOR
|
||||
};
|
||||
|
|
|
@ -81,9 +81,9 @@ NSClientPlayer::Physics_Fall(float flDownforce)
|
|||
}
|
||||
|
||||
Damage_Apply(this, world, fFallDamage, 0, DMG_FALL | DMG_SKIP_ARMOR);
|
||||
Sound_Play(this, CHAN_VOICE, "player.fall");
|
||||
StartSoundDef("Player.FallDamage", CHAN_VOICE, true);
|
||||
} else if (flDownforce >= PHY_FALL_DISTANCE) {
|
||||
Sound_Play(this, CHAN_VOICE, "player.lightfall");
|
||||
StartSoundDef("Player.LightFall", CHAN_VOICE, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -135,6 +135,9 @@ NSClientPlayer::Physics_Crouch(void)
|
|||
void
|
||||
NSClientPlayer::Physics_Jump(void)
|
||||
{
|
||||
if (GetMovetype() != MOVETYPE_WALK)
|
||||
return;
|
||||
|
||||
/* we're underwater... */
|
||||
if (WaterLevel() >= 2) {
|
||||
/* different water contents allow for different speeds */
|
||||
|
@ -241,7 +244,6 @@ NSClientPlayer::Physics_WaterMove(void)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
if (WaterLevel() > 0) {
|
||||
if (watertype == CONTENT_LAVA) {
|
||||
if (m_flPainTime < time) {
|
||||
|
@ -255,14 +257,13 @@ NSClientPlayer::Physics_WaterMove(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we've just exited water */
|
||||
if (WaterLevel() != 3) {
|
||||
if (m_flUnderwaterTime < time) {
|
||||
Sound_Play(this, CHAN_BODY, "player.gaspheavy");
|
||||
StartSoundDef("Player.GaspHeavy", CHAN_BODY, true);
|
||||
} else if (m_flUnderwaterTime < time + 9) {
|
||||
Sound_Play(this, CHAN_BODY, "player.gasplight");
|
||||
StartSoundDef("Player.GaspLight", CHAN_BODY, true);
|
||||
}
|
||||
m_flUnderwaterTime = time + 12;
|
||||
} else if (m_flUnderwaterTime < time) {
|
||||
|
@ -279,7 +280,7 @@ NSClientPlayer::Physics_WaterMove(void)
|
|||
if (!WaterLevel()){
|
||||
if (GetFlags() & FL_INWATER) {
|
||||
#ifdef SERVER
|
||||
Sound_Play(this, CHAN_BODY, "player.waterexit");
|
||||
StartSoundDef("Player.WaterExit", CHAN_BODY, true);
|
||||
#endif
|
||||
RemoveFlags(FL_INWATER);
|
||||
}
|
||||
|
@ -288,7 +289,7 @@ NSClientPlayer::Physics_WaterMove(void)
|
|||
|
||||
if (!(GetFlags() & FL_INWATER)) {
|
||||
#ifdef SERVER
|
||||
Sound_Play(this, CHAN_BODY, "player.waterenter");
|
||||
StartSoundDef("Player.WaterEnter", CHAN_BODY, true);
|
||||
m_flPainTime = 0;
|
||||
#endif
|
||||
AddFlags(FL_INWATER);
|
||||
|
@ -303,53 +304,54 @@ NSClientPlayer::Physics_WaterMove(void)
|
|||
float
|
||||
NSClientPlayer::Physics_MaxSpeed(void)
|
||||
{
|
||||
float maxspeed = serverkeyfloat("phy_maxspeed");
|
||||
float desiredspeed = (GetFlags() & FL_CROUCHING) ? PMOVE_STEP_WALKSPEED : maxspeed;
|
||||
return min(desiredspeed, maxspeed);
|
||||
float maxValue = serverkeyfloat("phy_maxspeed");
|
||||
float wishSpeed = (GetFlags() & FL_CROUCHING) ? PMOVE_STEP_WALKSPEED : maxValue;
|
||||
return min(wishSpeed, maxValue);
|
||||
}
|
||||
|
||||
void
|
||||
NSClientPlayer::Physics_InputPreMove(void)
|
||||
{
|
||||
NSVehicle veh = (NSVehicle)vehicle;
|
||||
bool canmove = true;
|
||||
NSVehicle currentVehicle = (NSVehicle)vehicle;
|
||||
bool canMove = true;
|
||||
|
||||
/* when pressing the 'use' button, we also walk slower for precision */
|
||||
if (input_buttons & INPUT_BUTTON5) {
|
||||
input_movevalues *= 0.25;
|
||||
}
|
||||
|
||||
bool flying = ((GetMovetype() == MOVETYPE_NOCLIP) || (GetMovetype() == MOVETYPE_FLY));
|
||||
|
||||
if (flying == true) {
|
||||
/* move camera up (noclip, fly) when holding jump */
|
||||
if (input_buttons & INPUT_BUTTON2) {
|
||||
input_movevalues[2] = 240;
|
||||
}
|
||||
/* move camera down (noclip, fly) when holding crouching */
|
||||
if (input_buttons & INPUT_BUTTON8) {
|
||||
input_movevalues[2] = -240;
|
||||
}
|
||||
/* find all the valid ways to freeze a player... */
|
||||
if (currentVehicle) {
|
||||
if (currentVehicle.PreventPlayerMovement() == true)
|
||||
canMove = false;
|
||||
}
|
||||
|
||||
/* find all the valid ways to freeze a player... */
|
||||
if (veh)
|
||||
if (veh.PreventPlayerMovement() == true)
|
||||
canmove = false;
|
||||
|
||||
if (flags & FL_FROZEN || movetype == MOVETYPE_NONE)
|
||||
canmove = false;
|
||||
if (flags & FL_FROZEN || movetype == MOVETYPE_NONE) {
|
||||
canMove = false;
|
||||
}
|
||||
|
||||
/* freeze in place */
|
||||
if (canmove == false) {
|
||||
if (canMove == false) {
|
||||
input_movevalues = [0,0,0];
|
||||
input_buttons &= ~INPUT_BUTTON2;
|
||||
}
|
||||
|
||||
/* clamp movement values to max speed */
|
||||
{
|
||||
float wishSpeed = vlen(input_movevalues);
|
||||
|
||||
if (wishSpeed > maxspeed) {
|
||||
wishSpeed = maxspeed;
|
||||
}
|
||||
|
||||
input_movevalues = normalize(input_movevalues) * wishSpeed;
|
||||
}
|
||||
|
||||
/* suppress crouching in vehicles */
|
||||
if (veh)
|
||||
if (veh.CanDriverCrouch() == false)
|
||||
if (currentVehicle) {
|
||||
if (currentVehicle.CanDriverCrouch() == false)
|
||||
input_buttons &= ~INPUT_BUTTON8;
|
||||
}
|
||||
}
|
||||
|
||||
/* timers get processed here after physics are run */
|
||||
|
@ -379,7 +381,7 @@ NSClientPlayer::Physics_Run(void)
|
|||
{
|
||||
float flFallVel = (flags & FL_ONGROUND) ? 0 : -velocity[2];
|
||||
float flBaseVel = basevelocity[2];
|
||||
bool onGround = (flags & FL_ONGROUND) ? true : false;
|
||||
bool wasOnGround = (flags & FL_ONGROUND) ? true : false;
|
||||
|
||||
saved_input_movevalues = input_movevalues;
|
||||
saved_input_buttons = input_buttons;
|
||||
|
@ -417,7 +419,7 @@ NSClientPlayer::Physics_Run(void)
|
|||
|
||||
Physics_CheckJump(FALSE);
|
||||
|
||||
if (onGround == false && (flags & FL_ONGROUND)) {
|
||||
if (wasOnGround == false && (flags & FL_ONGROUND)) {
|
||||
if (waterlevel != 0) {
|
||||
flFallVel = 0;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ PMoveCustom_StartFrame(void)
|
|||
PMoveCustom_UpdateVar("phy_maxspeed", "pm_maxspeed");
|
||||
PMoveCustom_UpdateVar("phy_noclipspeed", "pm_noclipspeed");
|
||||
PMoveCustom_UpdateVar("phy_noclipaccelerate", "pm_noclipaccelerate");
|
||||
PMoveCustom_UpdateVar("phy_nospeedcap", "pm_nospeedcap");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -82,6 +83,9 @@ PMoveCustom_Categorize(void)
|
|||
bool inladder = false;
|
||||
vector testPos;
|
||||
|
||||
if (self.movetype == MOVETYPE_NOCLIP)
|
||||
return;
|
||||
|
||||
tracebox(self.origin, self.mins, self.maxs, self.origin - [0,0,1], MOVE_NORMAL, self);
|
||||
|
||||
if (!trace_startsolid) {
|
||||
|
@ -97,6 +101,7 @@ PMoveCustom_Categorize(void)
|
|||
}
|
||||
} else {
|
||||
self.groundentity = __NULL__;
|
||||
self.flags |= FL_ONGROUND;
|
||||
}
|
||||
|
||||
self.flags &= ~FL_WATERJUMP;
|
||||
|
@ -198,7 +203,7 @@ PMoveCustom_AccelWater(float move_time, float premove)
|
|||
|
||||
wish_speed = vlen(vecWishVel);
|
||||
|
||||
if (wish_speed > self.maxspeed) {
|
||||
if (serverkeyfloat("phy_nospeedcap") == 0 && wish_speed > self.maxspeed) {
|
||||
wish_speed = self.maxspeed;
|
||||
}
|
||||
|
||||
|
@ -258,11 +263,17 @@ PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float
|
|||
float flFriction;
|
||||
vector vecTemp;
|
||||
|
||||
#ifdef SERVER
|
||||
/* too finicky with monsters between the various game settings */
|
||||
if (self.flags & FL_MONSTER) {
|
||||
self.velocity = wish_dir * wish_speed;
|
||||
return;
|
||||
NSMonster checkMe = (NSMonster)self;
|
||||
|
||||
if (checkMe.IsOnRoute() == true && checkMe.HasFlags(FL_ONGROUND) == true) {
|
||||
self.velocity = wish_dir * wish_speed;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
flApplyFriction = serverkeyfloat("phy_friction");
|
||||
|
||||
|
@ -305,7 +316,12 @@ PMoveCustom_AccelFriction(float move_time, float premove, vector wish_dir, float
|
|||
if (flFriction < 0) {
|
||||
self.velocity = [0,0,0];
|
||||
} else {
|
||||
self.velocity = self.velocity * flFriction;
|
||||
self.velocity[0] = self.velocity[0] * flFriction;
|
||||
self.velocity[1] = self.velocity[1] * flFriction;
|
||||
|
||||
/* don't apply friction to horizontal movement... or else jumps get clamped */
|
||||
if (self.flags & FL_JUMPRELEASED)
|
||||
self.velocity[2] = self.velocity[2] * flFriction;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,33 +348,14 @@ PMoveCustom_AccelNoclip(float move_time, float premove, vector wish_dir, float w
|
|||
}
|
||||
|
||||
/* apply friction */
|
||||
if (self.velocity[0] || self.velocity[1]) {
|
||||
if (vlen(self.velocity)) {
|
||||
vecTemp = self.velocity;
|
||||
vecTemp[2] = 0;
|
||||
flFriction = vlen(vecTemp);
|
||||
|
||||
/* Next few lines of code assumes self is using player's hull, however it could be a monster
|
||||
who use differen hull size, therefore it is invalid, so we probably better of using mins/maxs,
|
||||
on the other hand edge friction is probably not that important. */
|
||||
|
||||
// if the leading edge is over a dropoff, increase friction
|
||||
vecTemp = self.origin + normalize(vecTemp) * 16 + [0,0,1] * self.mins[2];
|
||||
traceline(vecTemp, vecTemp + [0,0,-34], TRUE, self);
|
||||
|
||||
// apply friction
|
||||
if (trace_fraction == 1.0) {
|
||||
if (flFriction < serverkeyfloat("phy_stopspeed")) {
|
||||
flFriction = 1 - move_time * (serverkeyfloat("phy_stopspeed") / flFriction) * flApplyFriction * serverkeyfloat("phy_edgefriction");
|
||||
} else {
|
||||
flFriction = 1 - move_time * flApplyFriction * serverkeyfloat("phy_edgefriction");
|
||||
}
|
||||
if (flFriction < serverkeyfloat("phy_stopspeed")) {
|
||||
flFriction = 1 - move_time * (serverkeyfloat("phy_stopspeed") / flFriction) * flApplyFriction;
|
||||
} else {
|
||||
if (flFriction < serverkeyfloat("phy_stopspeed")) {
|
||||
flFriction = 1 - move_time * (serverkeyfloat("phy_stopspeed") / flFriction) * flApplyFriction;
|
||||
} else {
|
||||
|
||||
flFriction = 1 - move_time * flApplyFriction;
|
||||
}
|
||||
flFriction = 1 - move_time * flApplyFriction;
|
||||
}
|
||||
|
||||
if (flFriction < 0) {
|
||||
|
@ -424,7 +421,9 @@ PMoveCustom_Acceleration(float move_time, float premove)
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
vecWishVel = v_forward * input_movevalues[0] + v_right * input_movevalues[1];
|
||||
vecWishVel = v_forward * input_movevalues[0];
|
||||
vecWishVel += v_right * input_movevalues[1];
|
||||
vecWishVel += v_up * input_movevalues[2];
|
||||
wish_dir = normalize(vecWishVel);
|
||||
wish_speed = serverkeyfloat("phy_noclipspeed");
|
||||
PMoveCustom_AccelNoclip(move_time, premove, wish_dir, wish_speed);
|
||||
|
@ -450,21 +449,16 @@ PMoveCustom_Acceleration(float move_time, float premove)
|
|||
wish_dir = normalize(vecWishVel);
|
||||
wish_speed = vlen(vecWishVel);
|
||||
|
||||
if (wish_speed > self.maxspeed) {
|
||||
if (serverkeyfloat("phy_nospeedcap") == 0 && wish_speed > self.maxspeed) {
|
||||
wish_speed = self.maxspeed;
|
||||
}
|
||||
|
||||
if (self.movetype == MOVETYPE_NOCLIP) {
|
||||
self.flags &= ~FL_ONGROUND;
|
||||
self.velocity = wish_dir * wish_speed;
|
||||
if (self.flags & FL_ONLADDER) {
|
||||
PMoveCustom_AccelLadder(move_time, premove, wish_dir, wish_speed);
|
||||
} else if (self.flags & FL_ONGROUND) {
|
||||
PMoveCustom_AccelFriction(move_time, premove, wish_dir, wish_speed);
|
||||
} else {
|
||||
if (self.flags & FL_ONLADDER) {
|
||||
PMoveCustom_AccelLadder(move_time, premove, wish_dir, wish_speed);
|
||||
} else if (self.flags & FL_ONGROUND) {
|
||||
PMoveCustom_AccelFriction(move_time, premove, wish_dir, wish_speed);
|
||||
} else {
|
||||
PMoveCustom_AccelGravity(move_time, premove, wish_dir, wish_speed);
|
||||
}
|
||||
PMoveCustom_AccelGravity(move_time, premove, wish_dir, wish_speed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,10 +594,11 @@ PMoveCustom_Move(void)
|
|||
break;
|
||||
}
|
||||
|
||||
/* there's something in the way, so let's try to bounce off of it, or step up */
|
||||
saved_plane = trace_plane_normal;
|
||||
move_time -= move_time * trace_fraction;
|
||||
|
||||
if (move_time) {
|
||||
if (move_time > 0.0) {
|
||||
/* step up if we can */
|
||||
trace_endpos = self.origin;
|
||||
|
||||
|
@ -622,7 +617,7 @@ PMoveCustom_Move(void)
|
|||
dest = trace_endpos + (self.velocity * move_time);
|
||||
dest += (self.basevelocity * move_time);
|
||||
dest[2] = trace_endpos[2]; /*only horizontally*/
|
||||
|
||||
|
||||
/* clear base-velocity */
|
||||
self.basevelocity = [0,0,0];
|
||||
|
||||
|
@ -630,7 +625,7 @@ PMoveCustom_Move(void)
|
|||
tracebox(trace_endpos, self.mins, self.maxs, dest, MOVE_NORMAL, self);
|
||||
|
||||
/* if we got anywhere, make this raised-step move count */
|
||||
if (trace_fraction == 1.0f) {
|
||||
if (trace_fraction >= 1.0f) {
|
||||
float fwfrac = trace_fraction;
|
||||
vector fwplane = trace_plane_normal;
|
||||
|
||||
|
@ -641,10 +636,12 @@ PMoveCustom_Move(void)
|
|||
|
||||
if (trace_fraction < 1.0 && trace_plane_normal[2] > 0.7f) {
|
||||
move_time -= move_time * fwfrac;
|
||||
|
||||
/* bounce off the ceiling */
|
||||
if (roof_fraction < 1) {
|
||||
PMoveCustom_Rebound(roof_plane_normal);
|
||||
}
|
||||
|
||||
if (trace_fraction < 1) {
|
||||
PMoveCustom_Rebound(trace_plane_normal);
|
||||
} else if (fwfrac < 1) {
|
||||
|
@ -710,6 +707,20 @@ PMoveCustom_RunPlayerPhysics(entity target)
|
|||
if (self.maxspeed <= 0)
|
||||
self.maxspeed = 240;
|
||||
|
||||
|
||||
bool flying = ((target.movetype == MOVETYPE_NOCLIP) || (target.movetype == MOVETYPE_FLY));
|
||||
|
||||
if (flying == true) {
|
||||
/* move camera up (noclip, fly) when holding jump */
|
||||
if (input_buttons & INPUT_BUTTON2) {
|
||||
input_movevalues[2] = 240;
|
||||
}
|
||||
/* move camera down (noclip, fly) when holding crouching */
|
||||
if (input_buttons & INPUT_BUTTON8) {
|
||||
input_movevalues[2] = -240;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CUSTOMPLAYERPHYSICS
|
||||
/* call accelerate before and after the actual move,
|
||||
* with half the move each time. this reduces framerate dependence.
|
||||
|
@ -726,8 +737,9 @@ PMoveCustom_RunPlayerPhysics(entity target)
|
|||
self.angles[0] *= -0.333;
|
||||
|
||||
#ifdef CUSTOMPLAYERPHYSICS
|
||||
/* activate any SOLID_TRIGGER entities */
|
||||
touchtriggers();
|
||||
/* activate any SOLID_TRIGGER entities, when not in noclip anyway */
|
||||
if (self.movetype != MOVETYPE_NOCLIP)
|
||||
touchtriggers();
|
||||
#endif
|
||||
|
||||
setorigin(self, self.origin);
|
||||
|
@ -747,7 +759,7 @@ PMoveCustom_RunCrouchPhysics(entity target)
|
|||
} else {
|
||||
// If we aren't holding down duck anymore and 'attempt' to stand up, prevent it
|
||||
if (target.flags & FL_CROUCHING) {
|
||||
if (PMove_IsStuck(target, [0,0,36], PHY_HULL_MIN, PHY_HULL_MAX) == FALSE) {
|
||||
if (PMove_IsStuck(target, [0,0,36], PHY_HULL_MIN, PHY_HULL_MAX) == false) {
|
||||
target.flags &= ~FL_CROUCHING;
|
||||
iFixCrouch = TRUE;
|
||||
}
|
||||
|
@ -764,7 +776,7 @@ PMoveCustom_RunCrouchPhysics(entity target)
|
|||
if (iFixCrouch && PMove_IsStuck(target, [0,0,0], PHY_HULL_MIN, PHY_HULL_MAX)) {
|
||||
for (int i = 0; i < 36; i++) {
|
||||
target.origin[2] += 1;
|
||||
if (PMove_IsStuck(target, [0,0,0], target.mins, target.maxs) == FALSE) {
|
||||
if (PMove_IsStuck(target, [0,0,0], target.mins, target.maxs) == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,3 +99,5 @@ int Sound_GetID(string sndDef);
|
|||
/** Server-side only: Play a sentences.txt entry on a given entity. */
|
||||
void Sound_Speak(entity targetEntity, string sentencesEntry);
|
||||
#endif
|
||||
|
||||
void Sound_DebugList();
|
|
@ -67,6 +67,8 @@ Sound_Init(void)
|
|||
SoundSource_Init();
|
||||
|
||||
precache_sound("misc/missing.wav");
|
||||
precache_sound("misc/null.wav");
|
||||
precache_sound("common/null.wav");
|
||||
|
||||
print("SoundDef initialized.\n");
|
||||
}
|
||||
|
@ -459,6 +461,7 @@ Sound_Precache(string shader)
|
|||
print("^1no soundDef found for ");
|
||||
print(shader);
|
||||
print("\n");
|
||||
g_sounds_count--;
|
||||
|
||||
search_end(sh);
|
||||
return -1;
|
||||
|
@ -943,3 +946,15 @@ SoundSource_Init(void)
|
|||
}
|
||||
fclose(manifestFile);
|
||||
}
|
||||
|
||||
|
||||
/** Called by listSoundDef */
|
||||
void
|
||||
Sound_DebugList(void)
|
||||
{
|
||||
for (int i = 0; i < g_sounds_count; i++) {
|
||||
print(sprintf("%i: %s (%i samples)\n", i, g_sounds[i].name, g_sounds[i].sample_count));
|
||||
}
|
||||
|
||||
print(sprintf("\t%i total soundDef loaded\n", g_sounds_count));
|
||||
}
|
Loading…
Reference in New Issue