21 Jan 2008
|
@ -25,9 +25,6 @@ engine\
|
|||
engine\client\
|
||||
engine\server\
|
||||
engine\uimenu\
|
||||
pr_client\
|
||||
pr_server\
|
||||
pr_uimenu\
|
||||
launch\
|
||||
launch\xash\
|
||||
launch\bsplib\
|
||||
|
|
|
@ -14,44 +14,35 @@ fopen
|
|||
1. viewer ничего не пишет в лог (сцуко)
|
||||
|
||||
// из неоконченного
|
||||
0. Приделать бы всем утилитам разные иконки
|
||||
1. snd encoder для roqlib
|
||||
2. doom snd decoder для snddec
|
||||
0. snd encoder для roqlib
|
||||
1. doom snd decoder для snddec
|
||||
|
||||
physic.dll
|
||||
Шаги до выпуска альфы:
|
||||
1. Сделать проверку столкновений со сферой OK
|
||||
2. Обновить bsp-формат до ver. 39 rev. 1 OK
|
||||
3. Добавить загрузку hl-текстур из wad OK
|
||||
4. Исправить чтение g_TX command OK
|
||||
5. Иконки всем экзешникам OK
|
||||
6. Поменять нужные пути для graphics OK
|
||||
7. Доделать меню OK
|
||||
8. перенести qc код в sdk_main OK
|
||||
|
||||
engine.dll
|
||||
{
|
||||
1. Вернуть квантизацию пространства в 0.125 юнита OK
|
||||
2. поля в вирт машине для сохранения матрицы OK
|
||||
3. сохранить velocity и avelocity OK
|
||||
4. дописать лоадер кастомных мешей OK
|
||||
5. Отладить менеджер загрузки моделей на сервере OK
|
||||
6. Перенести создание mesh-buffer в cmodel OK
|
||||
7. разобраться куда пропали модели из dm_qstyle OK
|
||||
8. Придумать как развернуть меш на 90 грд OK
|
||||
9. Пофиксить утечку памяти в cmodel OK
|
||||
10.Найти все кластеры для карт без виза (рендер\сервер) OK
|
||||
11.Перенести cmodel в physic.dll OK
|
||||
12.Подключить его к серверу и клиенту OK
|
||||
13.Билдер коллижн мешей для бсп-моделей OK
|
||||
14.Переписать трасинг OK
|
||||
15.Доделать трасинг OK
|
||||
16.Переписать pmove OK
|
||||
17.Переписать player_state_t (избавиться от pmove_state_t) OK
|
||||
18.Добавить проверку столкновений со сферой
|
||||
написать код для некоторых энтить
|
||||
}
|
||||
|
||||
Создание sdk_main
|
||||
{
|
||||
0. переименовать папку в !sdk_main OK
|
||||
1. подключить пользовательскую дллку к движку
|
||||
2. иконки для всех экзешников
|
||||
3. перенести qc код в sdk_main
|
||||
}
|
||||
|
||||
|
||||
//==================================================
|
||||
// то, что уже готово
|
||||
//==================================================
|
||||
+добавлена динамическая смена шрифта
|
||||
+новый трасинг (проверка на капсулы)
|
||||
+текущая версия bsp обновлена до rev. 1
|
||||
+сохранение физики на сервере
|
||||
+дописан лоадер кастомных мешей
|
||||
+переписан менеджер моделей
|
||||
+пофикшен парсинг map-карт для bsplib
|
||||
+переписана физика игрока
|
||||
+скриншоты теперь учитывают текущую гамму
|
||||
+освещение влияет на спрайты (кроме additive и glow)
|
||||
+базовые форматы текстур - tga и dds. Другие типы не поддерживаются
|
||||
|
|
|
@ -40,10 +40,10 @@ int numedges;
|
|||
dedge_t dedges[MAX_MAP_EDGES];
|
||||
|
||||
int numleaffaces;
|
||||
word dleaffaces[MAX_MAP_LEAFFACES];
|
||||
dword dleaffaces[MAX_MAP_LEAFFACES];
|
||||
|
||||
int numleafbrushes;
|
||||
word dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
dword dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
int numsurfedges;
|
||||
int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
|
|
|
@ -336,9 +336,9 @@ extern dface_t dfaces[MAX_MAP_FACES];
|
|||
extern int numedges;
|
||||
extern dedge_t dedges[MAX_MAP_EDGES];
|
||||
extern int numleaffaces;
|
||||
extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
|
||||
extern dword dleaffaces[MAX_MAP_LEAFFACES];
|
||||
extern int numleafbrushes;
|
||||
extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
extern dword dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
extern int numsurfedges;
|
||||
extern int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
extern int numareas;
|
||||
|
|
|
@ -509,7 +509,7 @@ bool MakeBrushWindings (mapbrush_t *ob)
|
|||
ParseBrush
|
||||
=================
|
||||
*/
|
||||
void ParseBrush (bsp_entity_t *mapent)
|
||||
void ParseBrush( bsp_entity_t *mapent )
|
||||
{
|
||||
mapbrush_t *b;
|
||||
int i,j, k;
|
||||
|
@ -554,14 +554,14 @@ void ParseBrush (bsp_entity_t *mapent)
|
|||
}
|
||||
|
||||
// read the texturedef
|
||||
Com_GetToken (false);
|
||||
strcpy (td.name, com_token);
|
||||
Com_GetToken( false );
|
||||
strcpy( td.name, com_token );
|
||||
|
||||
if(g_mapversion == VALVE_FORMAT) // Worldcraft 2.2+
|
||||
{
|
||||
// texture U axis
|
||||
Com_GetToken(false);
|
||||
if (strcmp(com_token, "[")) Sys_Error("missing '[' in texturedef (U)");
|
||||
Com_GetToken( false );
|
||||
if(!Com_MatchToken("[")) Sys_Error("missing '[' in texturedef (U)");
|
||||
Com_GetToken(false);
|
||||
td.vects.valve.UAxis[0] = atof(com_token);
|
||||
Com_GetToken(false);
|
||||
|
|
15
debug.bat
|
@ -29,15 +29,6 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% viewer/viewer.dsp %CONFIG%"viewer - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
qcclib.exe -dir pr_server /V7 /Od
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
qcclib.exe -dir pr_client /V7 /Od
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
qcclib.exe -dir pr_uimenu /V7 /Od
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
if "%BUILD_ERROR%"=="" goto build_ok
|
||||
|
||||
echo *********************
|
||||
|
@ -64,13 +55,9 @@ if exist ripper\ripper.plg del /f /q ripper\ripper.plg
|
|||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist viewer\viewer.plg del /f /q viewer\viewer.plg
|
||||
if exist temp\server.dat move temp\server.dat D:\Xash3D\xash\vprogs\server.dat
|
||||
if exist temp\client.dat move temp\client.dat D:\Xash3D\xash\vprogs\client.dat
|
||||
if exist temp\uimenu.dat move temp\uimenu.dat D:\Xash3D\xash\vprogs\uimenu.dat
|
||||
if exist compile.log del /f /q compile.log
|
||||
|
||||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
xash.exe +map qctest -log -debug -dev 3
|
||||
xash.exe +map dm_qstyle -log -debug -dev 3
|
||||
:done
|
|
@ -15,6 +15,16 @@ void SCR_Loading_f (void)
|
|||
S_StopAllSounds();
|
||||
}
|
||||
|
||||
void CL_SetFont_f( void )
|
||||
{
|
||||
if(Cmd_Argc() < 2)
|
||||
{
|
||||
Msg("Usage: setfont <fontname>\n");
|
||||
return;
|
||||
}
|
||||
Cvar_Set("cl_font", Cmd_Argv(1));
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ScreenshotGetName
|
||||
|
|
|
@ -284,7 +284,8 @@ void CL_UpdateMouse( void )
|
|||
return;
|
||||
}
|
||||
|
||||
if( !cl.refresh_prepped || cls.key_dest == key_console )
|
||||
// uimenu.dat using mouse
|
||||
if((!cl.refresh_prepped && cls.key_dest != key_menu) || cls.key_dest == key_console )
|
||||
{
|
||||
// temporarily deactivate if in fullscreen
|
||||
if(!Cvar_VariableValue ("fullscreen"))
|
||||
|
@ -630,7 +631,7 @@ void CL_FinishMove (usercmd_t *cmd)
|
|||
cmd->impulse = in_impulse;
|
||||
in_impulse = 0;
|
||||
|
||||
// send the ambient light level at the player's current position
|
||||
// send the ambient light level at the player's current position
|
||||
cmd->lightlevel = (byte)cl_lightlevel->value;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,19 +239,23 @@ void Field_CompleteCommand( field_t *field )
|
|||
// autocomplete second arg
|
||||
if(!stricmp(Cmd_Argv(0), "map" ) || !stricmp(Cmd_Argv(0), "\\map" ))
|
||||
{
|
||||
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_QPATH );
|
||||
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING );
|
||||
}
|
||||
else if(!stricmp(Cmd_Argv(0), "demo" ) || !stricmp(Cmd_Argv(0), "\\demo" ))
|
||||
{
|
||||
result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_QPATH );
|
||||
result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_STRING );
|
||||
}
|
||||
else if(!stricmp(Cmd_Argv(0), "movie" ) || !stricmp(Cmd_Argv(0), "\\movie" ))
|
||||
{
|
||||
result = Cmd_GetMovieList(Cmd_Argv(1), filename, MAX_QPATH );
|
||||
result = Cmd_GetMovieList(Cmd_Argv(1), filename, MAX_STRING );
|
||||
}
|
||||
else if(!stricmp(Cmd_Argv(0), "changelevel" ) || !stricmp(Cmd_Argv(0), "\\changelevel" ))
|
||||
{
|
||||
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_QPATH );
|
||||
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING );
|
||||
}
|
||||
else if(!stricmp(Cmd_Argv(0), "setfont" ) || !stricmp(Cmd_Argv(0), "\\setfont" ))
|
||||
{
|
||||
result = Cmd_GetFontList(Cmd_Argv(1), filename, MAX_STRING );
|
||||
}
|
||||
|
||||
if( result )
|
||||
|
|
|
@ -42,7 +42,7 @@ cvar_t *cl_autoskins;
|
|||
cvar_t *cl_footsteps;
|
||||
cvar_t *cl_timeout;
|
||||
cvar_t *cl_predict;
|
||||
//cvar_t *cl_minfps;
|
||||
cvar_t *cl_showfps;
|
||||
cvar_t *cl_maxfps;
|
||||
cvar_t *cl_gun;
|
||||
|
||||
|
@ -1358,6 +1358,7 @@ void CL_InitLocal (void)
|
|||
gender_auto = Cvar_Get ("gender_auto", "1", CVAR_ARCHIVE);
|
||||
gender->modified = false; // clear this so we know when user sets it manually
|
||||
cl_vwep = Cvar_Get ("cl_vwep", "1", CVAR_ARCHIVE);
|
||||
cl_showfps = Cvar_Get ("cl_showfps", "1", CVAR_ARCHIVE );
|
||||
|
||||
// register our commands
|
||||
Cmd_AddCommand ("cmd", CL_ForwardToServer_f, "send a console commandline to the server" );
|
||||
|
|
|
@ -105,7 +105,7 @@ void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
|||
}
|
||||
if( tr->allsolid ) return;
|
||||
|
||||
trace = pe->TransformedBoxTrace( start, end, mins, maxs, cmodel, MASK_PLAYERSOLID, ent->origin, angles );
|
||||
trace = pe->TransformedBoxTrace( start, end, mins, maxs, cmodel, MASK_PLAYERSOLID, ent->origin, angles, false );
|
||||
|
||||
if( trace.allsolid || trace.startsolid || trace.fraction < tr->fraction )
|
||||
{
|
||||
|
@ -132,7 +132,7 @@ trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
|
|||
trace_t t;
|
||||
|
||||
// check against world
|
||||
t = pe->BoxTrace( start, end, mins, maxs, NULL, MASK_PLAYERSOLID );
|
||||
t = pe->BoxTrace( start, end, mins, maxs, NULL, MASK_PLAYERSOLID, true );
|
||||
if (t.fraction < 1.0) t.ent = (edict_t *)1;
|
||||
|
||||
// check all other solid models
|
||||
|
|
|
@ -16,6 +16,7 @@ cvar_t *scr_loading;
|
|||
cvar_t *scr_width;
|
||||
cvar_t *scr_height;
|
||||
cvar_t *cl_levelshot_name;
|
||||
cvar_t *cl_font;
|
||||
|
||||
void SCR_TimeRefresh_f( void );
|
||||
void SCR_Loading_f( void );
|
||||
|
@ -107,7 +108,7 @@ void SCR_DrawChar( int x, int y, float w, float h, int ch )
|
|||
fcol = (ch & 15)*0.0625f + (0.5f / 256.0f);
|
||||
size = 0.0625f - (1.0f / 256.0f);
|
||||
|
||||
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, "fonts/conchars" );
|
||||
re->DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + size, frow + size, va( "fonts/%s", cl_font->string ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -131,7 +132,7 @@ void SCR_DrawSmallChar( int x, int y, int ch )
|
|||
fcol = (ch & 15)*0.0625f + (0.5f / 256.0f);
|
||||
size = 0.0625f - (1.0f / 256.0f);
|
||||
|
||||
re->DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, fcol, frow, fcol + size, frow + size, "fonts/conchars" );
|
||||
re->DrawStretchPic( x, y, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, fcol, frow, fcol + size, frow + size, va( "fonts/%s", cl_font->string ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -271,6 +272,7 @@ void SCR_DrawFPS( void )
|
|||
float *color;
|
||||
|
||||
if(cls.state != ca_active) return;
|
||||
if(!cl_showfps->integer) return;
|
||||
|
||||
newtime = Sys_DoubleTime();
|
||||
if (newtime >= nexttime)
|
||||
|
@ -345,12 +347,14 @@ void SCR_Init (void)
|
|||
scr_centertime = Cvar_Get("scr_centertime", "2.5", 0);
|
||||
scr_printspeed = Cvar_Get("scr_printspeed", "8", 0);
|
||||
cl_levelshot_name = Cvar_Get("cl_levelshot_name", "common/black", 0 );
|
||||
cl_font = Cvar_Get("cl_font", "conchars", CVAR_ARCHIVE );
|
||||
|
||||
// register our commands
|
||||
Cmd_AddCommand ("timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" );
|
||||
Cmd_AddCommand ("loading", SCR_Loading_f, "prepare client to a loading new map" );
|
||||
Cmd_AddCommand ("skyname", CL_SetSky_f, "set new skybox by basename" );
|
||||
|
||||
Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" );
|
||||
Cmd_AddCommand( "loading", SCR_Loading_f, "prepare client to a loading new map" );
|
||||
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );
|
||||
Cmd_AddCommand( "setfont", CL_SetFont_f, "set new system font" );
|
||||
|
||||
scr_initialized = true;
|
||||
|
||||
}
|
|
@ -1978,7 +1978,6 @@ void S_FreeOldestSound( void )
|
|||
sfx->soundData = NULL;
|
||||
}
|
||||
|
||||
#define DEF_COMSOUNDMEGS "8"
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -2026,16 +2025,16 @@ void SND_setup( void )
|
|||
cvar_t *cv;
|
||||
int scs;
|
||||
|
||||
cv = Cvar_Get( "com_soundMegs", DEF_COMSOUNDMEGS, CVAR_LATCH | CVAR_ARCHIVE );
|
||||
cv = Cvar_Get( "s_memory", "4", CVAR_LATCH|CVAR_ARCHIVE );
|
||||
|
||||
scs = (cv->value * 1536);
|
||||
scs = (cv->integer * 1536);
|
||||
|
||||
if(!buffer) buffer = Z_Malloc(scs * sizeof(sndBuffer));
|
||||
// allocate the stack based hunk allocator
|
||||
if(sfxScratchBuffer) sfxScratchBuffer = Z_Malloc(SND_CHUNK_SIZE * sizeof(short) * 4);
|
||||
sfxScratchPointer = NULL;
|
||||
|
||||
inUse = scs*sizeof(sndBuffer);
|
||||
inUse = scs * sizeof(sndBuffer);
|
||||
p = buffer;
|
||||
q = p + scs;
|
||||
while (--q > p) *(sndBuffer **)q = q-1;
|
||||
|
|
|
@ -313,7 +313,7 @@ extern cvar_t *cl_predict;
|
|||
extern cvar_t *cl_footsteps;
|
||||
extern cvar_t *cl_noskins;
|
||||
extern cvar_t *cl_autoskins;
|
||||
|
||||
extern cvar_t *cl_showfps;
|
||||
extern cvar_t *cl_upspeed;
|
||||
extern cvar_t *cl_forwardspeed;
|
||||
extern cvar_t *cl_sidespeed;
|
||||
|
@ -476,6 +476,7 @@ void CL_Quit_f (void);
|
|||
void CL_ScreenShot_f( void );
|
||||
void CL_LevelShot_f( void );
|
||||
void CL_SetSky_f( void );
|
||||
void CL_SetFont_f( void );
|
||||
void CL_ParseLayout (void);
|
||||
|
||||
|
||||
|
|
|
@ -258,8 +258,8 @@ bool Cmd_GetMapList (const char *s, char *completedname, int length )
|
|||
{
|
||||
search_t *t;
|
||||
file_t *f;
|
||||
char message[MAX_QPATH];
|
||||
char matchbuf[MAX_QPATH];
|
||||
string message;
|
||||
string matchbuf;
|
||||
byte buf[MAX_SYSPATH]; // 1 kb
|
||||
int i, nummaps;
|
||||
|
||||
|
@ -294,7 +294,8 @@ bool Cmd_GetMapList (const char *s, char *completedname, int length )
|
|||
|
||||
switch(ver)
|
||||
{
|
||||
case 38: // quake2 (xash)
|
||||
case 38: // quake2
|
||||
case 39: // xash3d
|
||||
case 46: // quake3
|
||||
case 47: // return to castle wolfenstein
|
||||
lumpofs = LittleLong(header->lumps[LUMP_ENTITIES].fileofs);
|
||||
|
@ -350,13 +351,6 @@ bool Cmd_GetMapList (const char *s, char *completedname, int length )
|
|||
Com_ParseToken(&data);
|
||||
strncpy(message, com_token, sizeof(message));
|
||||
}
|
||||
else if(!strcmp(com_token, "mapversion" ))
|
||||
{
|
||||
// get map version
|
||||
Com_ParseToken(&data);
|
||||
// old xash maps are Half-Life, so don't overwrite version
|
||||
if(ver > 30) ver = atoi(com_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,9 +364,9 @@ bool Cmd_GetMapList (const char *s, char *completedname, int length )
|
|||
case 29: strncpy((char *)buf, "Quake1", sizeof(buf)); break;
|
||||
case 30: strncpy((char *)buf, "Half-Life", sizeof(buf)); break;
|
||||
case 38: strncpy((char *)buf, "Quake 2", sizeof(buf)); break;
|
||||
case 39: strncpy((char *)buf, "Xash 3D", sizeof(buf)); break;
|
||||
case 46: strncpy((char *)buf, "Quake 3", sizeof(buf)); break;
|
||||
case 47: strncpy((char *)buf, "RTCW", sizeof(buf)); break;
|
||||
case 220: strncpy((char *)buf, "Xash 3D", sizeof(buf)); break;
|
||||
default: strncpy((char *)buf, "??", sizeof(buf)); break;
|
||||
}
|
||||
Msg("%16s (%s) ^3%s^7\n", matchbuf, buf, message);
|
||||
|
@ -390,6 +384,51 @@ bool Cmd_GetMapList (const char *s, char *completedname, int length )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetFontList
|
||||
|
||||
Prints or complete font filename
|
||||
=====================================
|
||||
*/
|
||||
bool Cmd_GetFontList (const char *s, char *completedname, int length )
|
||||
{
|
||||
search_t *t;
|
||||
string matchbuf;
|
||||
int i, numfonts;
|
||||
|
||||
t = FS_Search(va("graphics/fonts/%s*.dds", s ), true);
|
||||
if(!t) return false;
|
||||
|
||||
FS_FileBase(t->filenames[0], matchbuf );
|
||||
if(completedname && length) com.strncpy( completedname, matchbuf, length );
|
||||
if(t->numfilenames == 1) return true;
|
||||
|
||||
for(i = 0, numfonts = 0; i < t->numfilenames; i++)
|
||||
{
|
||||
const char *ext = FS_FileExtension( t->filenames[i] );
|
||||
|
||||
if( com.stricmp(ext, "dds" )) continue;
|
||||
FS_FileBase(t->filenames[i], matchbuf );
|
||||
Msg("%16s\n", matchbuf );
|
||||
numfonts++;
|
||||
}
|
||||
Msg("\n^3 %i fonts found.\n", numfonts );
|
||||
Z_Free(t);
|
||||
|
||||
// cut shortestMatch to the amount common with s
|
||||
if(completedname && length)
|
||||
{
|
||||
for( i = 0; matchbuf[i]; i++ )
|
||||
{
|
||||
if(tolower(completedname[i]) != tolower(matchbuf[i]))
|
||||
completedname[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetDemoList
|
||||
|
@ -400,7 +439,7 @@ Prints or complete demo filename
|
|||
bool Cmd_GetDemoList (const char *s, char *completedname, int length )
|
||||
{
|
||||
search_t *t;
|
||||
char matchbuf[MAX_QPATH];
|
||||
string matchbuf;
|
||||
int i, numdems;
|
||||
|
||||
t = FS_Search(va("demos/%s*.dem", s ), true);
|
||||
|
@ -419,7 +458,7 @@ bool Cmd_GetDemoList (const char *s, char *completedname, int length )
|
|||
Msg("%16s\n", matchbuf );
|
||||
numdems++;
|
||||
}
|
||||
Msg("\n^3 %i demos found.\n", numdems );
|
||||
Msg("\n^3 %i fonts found.\n", numdems );
|
||||
Z_Free(t);
|
||||
|
||||
// cut shortestMatch to the amount common with s
|
||||
|
@ -445,7 +484,7 @@ Prints or complete movie filename
|
|||
bool Cmd_GetMovieList (const char *s, char *completedname, int length )
|
||||
{
|
||||
search_t *t;
|
||||
char matchbuf[MAX_QPATH];
|
||||
string matchbuf;
|
||||
int i, nummovies;
|
||||
|
||||
t = FS_Search(va("video/%s*.roq", s ), true);
|
||||
|
|
|
@ -165,6 +165,7 @@ char *Cvar_Userinfo( void );
|
|||
char *Cvar_Serverinfo( void );
|
||||
void Cmd_WriteVariables( file_t *f );
|
||||
bool Cmd_GetMapList (const char *s, char *completedname, int length );
|
||||
bool Cmd_GetFontList (const char *s, char *completedname, int length );
|
||||
bool Cmd_GetDemoList(const char *s, char *completedname, int length );
|
||||
bool Cmd_GetMovieList(const char *s, char *completedname, int length);
|
||||
|
||||
|
|
|
@ -299,6 +299,7 @@ void SV_ExecuteClientMessage (client_state_t *cl);
|
|||
// sv_ccmds.c
|
||||
//
|
||||
void SV_Status_f( void );
|
||||
void SV_Newgame_f( void );
|
||||
void SV_SectorList_f( void );
|
||||
|
||||
//
|
||||
|
|
|
@ -200,6 +200,12 @@ void SV_Movie_f( void )
|
|||
SV_BroadcastCommand( "reconnect\n" );
|
||||
}
|
||||
|
||||
void SV_Newgame_f( void )
|
||||
{
|
||||
// FIXME: do some clear operations
|
||||
Cbuf_ExecuteText(EXEC_APPEND, va("map %s\n", GI->startmap ));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SV_Load_f
|
||||
|
@ -512,6 +518,7 @@ void SV_InitOperatorCommands( void )
|
|||
|
||||
Cmd_AddCommand("map", SV_Map_f, "start new level" );
|
||||
Cmd_AddCommand("demo", SV_Demo_f, "playing a demo file" );
|
||||
Cmd_AddCommand("newgame", SV_Newgame_f, "begin new game" );
|
||||
Cmd_AddCommand("movie", SV_Movie_f, "playing video file" );
|
||||
Cmd_AddCommand("changelevel", SV_ChangeLevel_f, "changing level" );
|
||||
Cmd_AddCommand("restart", SV_Restart_f, "restarting current level" );
|
||||
|
@ -539,6 +546,7 @@ void SV_KillOperatorCommands( void )
|
|||
Cmd_RemoveCommand("map");
|
||||
Cmd_RemoveCommand("demo");
|
||||
Cmd_RemoveCommand("movie");
|
||||
Cmd_RemoveCommand("newgame");
|
||||
Cmd_RemoveCommand("changelevel");
|
||||
Cmd_RemoveCommand("restart");
|
||||
Cmd_RemoveCommand("sectorlist");
|
||||
|
|
|
@ -664,7 +664,7 @@ void PF_modelframes (void)
|
|||
|
||||
void PF_changelevel (void)
|
||||
{
|
||||
Msg("changelevel\n");
|
||||
Cbuf_ExecuteText(EXEC_APPEND, va("changelevel %s\n", PRVM_G_STRING(OFS_PARM0)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -428,7 +428,7 @@ void SV_ClipMoveToEntities( moveclip_t *clip )
|
|||
angles = touch->progs.sv->angles;
|
||||
|
||||
if( !touch->progs.sv->solid == SOLID_BSP ) angles = vec3_origin; // boxes don't rotate
|
||||
trace = pe->TransformedBoxTrace((float *)clip->start, (float *)clip->end, (float *)clip->mins, (float *)clip->maxs, cmodel, clip->contentmask, origin, angles );
|
||||
trace = pe->TransformedBoxTrace((float *)clip->start, (float *)clip->end, (float *)clip->mins, (float *)clip->maxs, cmodel, clip->contentmask, origin, angles, false );
|
||||
|
||||
if( trace.allsolid )
|
||||
{
|
||||
|
@ -471,7 +471,7 @@ trace_t SV_Trace( const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end
|
|||
memset( &clip, 0, sizeof( moveclip_t ));
|
||||
|
||||
// clip to world
|
||||
clip.trace = pe->BoxTrace( start, end, mins, maxs, NULL, contentmask );
|
||||
clip.trace = pe->BoxTrace( start, end, mins, maxs, NULL, contentmask, true );
|
||||
clip.trace.ent = clip.trace.fraction != 1.0 ? prog->edicts : NULL;
|
||||
if( clip.trace.fraction == 0 ) return clip.trace; // blocked immediately by the world
|
||||
|
||||
|
@ -567,7 +567,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs
|
|||
angles = touch->progs.sv->angles;
|
||||
if( !touch->progs.sv->solid == SOLID_BSP ) angles = vec3_origin; // boxes don't rotate
|
||||
|
||||
trace = pe->TransformedBoxTrace( start, end, mins, maxs, cmodel, contentsmask, origin, angles );
|
||||
trace = pe->TransformedBoxTrace( start, end, mins, maxs, cmodel, contentsmask, origin, angles, true );
|
||||
if( trace.fraction < 1.0f ) trace.ent = touch;
|
||||
|
||||
return trace;
|
||||
|
|
|
@ -29,6 +29,8 @@ static char *menu_in_sound = "misc/menu1.wav";
|
|||
static char *menu_move_sound = "misc/menu2.wav";
|
||||
static char *menu_out_sound = "misc/menu3.wav";
|
||||
|
||||
cvar_t *menu_progs;
|
||||
|
||||
void M_Menu_Main_f (void);
|
||||
void M_Menu_Game_f (void);
|
||||
void M_Menu_LoadGame_f (void);
|
||||
|
@ -119,7 +121,8 @@ void M_ForceMenuOff (void)
|
|||
cls.key_dest = key_game;
|
||||
m_menudepth = 0;
|
||||
Key_ClearStates();
|
||||
Cvar_Set ("paused", "0");
|
||||
Cvar_Set( "paused", "0" );
|
||||
UI_HideMenu();
|
||||
}
|
||||
|
||||
void M_PopMenu (void)
|
||||
|
@ -439,7 +442,9 @@ const char *M_Main_Key(int key)
|
|||
|
||||
void M_Menu_Main_f (void)
|
||||
{
|
||||
M_PushMenu (M_Main_Draw, M_Main_Key);
|
||||
if( menu_progs->integer ) UI_ShowMenu();
|
||||
else M_PushMenu (M_Main_Draw, M_Main_Key);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1322,6 +1327,7 @@ static const char *xash_credits[] =
|
|||
"^3THANKS TO"
|
||||
"ID Software at all",
|
||||
"Lord Havoc (Darkplaces Team)",
|
||||
"Georg Destroy for icon graphics",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -1331,8 +1337,7 @@ static const char *xash_credits[] =
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Copyright XashXT Group 2007 (C)",
|
||||
"Copyright XashXT Group 2008 (C)",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -3397,8 +3402,9 @@ void M_Menu_Quit_f (void)
|
|||
M_Init
|
||||
=================
|
||||
*/
|
||||
void M_Init (void)
|
||||
void M_Init( void )
|
||||
{
|
||||
menu_progs = Cvar_Get( "m_progs", "1", CVAR_ARCHIVE );
|
||||
Cmd_AddCommand ("menu_main", M_Menu_Main_f, "opens main menu" );
|
||||
Cmd_AddCommand ("menu_game", M_Menu_Game_f, "opens game menu" );
|
||||
Cmd_AddCommand ("menu_loadgame", M_Menu_LoadGame_f, "opens menu loadgame" );
|
||||
|
@ -3415,7 +3421,6 @@ void M_Init (void)
|
|||
Cmd_AddCommand ("menu_options", M_Menu_Options_f, "opens main options menu");
|
||||
Cmd_AddCommand ("menu_keys", M_Menu_Keys_f, "opens redefinition keys menu" );
|
||||
Cmd_AddCommand ("menu_quit", M_Menu_Quit_f, "show quit dialog" );
|
||||
Cmd_AddCommand ("menu_toggle", UI_ToggleMenu_f, "enable progs menu(test)" );
|
||||
|
||||
UI_Init();
|
||||
}
|
||||
|
@ -3430,8 +3435,14 @@ void M_Draw (void)
|
|||
{
|
||||
if (cls.key_dest != key_menu) return;
|
||||
|
||||
if(m_drawfunc) m_drawfunc();
|
||||
if(ui_active) UI_Draw();
|
||||
if( menu_progs->integer && ui_active )
|
||||
{
|
||||
UI_Draw();
|
||||
}
|
||||
else if( m_drawfunc )
|
||||
{
|
||||
m_drawfunc();
|
||||
}
|
||||
|
||||
// delay playing the enter sound until after the
|
||||
// menu has been drawn, to avoid delay while
|
||||
|
@ -3453,7 +3464,7 @@ void M_Keydown (int key)
|
|||
{
|
||||
const char *s;
|
||||
|
||||
if (m_keyfunc)
|
||||
if( m_keyfunc )
|
||||
{
|
||||
if(( s = m_keyfunc( key )) != 0 )
|
||||
S_StartLocalSound(( char * )s);
|
||||
|
|
|
@ -13,7 +13,8 @@ typedef struct ui_globalvars_s
|
|||
func_t m_shutdown;
|
||||
func_t m_keydown;
|
||||
func_t m_draw;
|
||||
func_t m_toggle;
|
||||
func_t m_show;
|
||||
func_t m_hide;
|
||||
} ui_globalvars_t;
|
||||
|
||||
typedef struct ui_entvars_s
|
||||
|
@ -105,6 +106,6 @@ static fields_t ui_reqfields[] =
|
|||
{93, 2, "find2"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_UIMENU 31295
|
||||
#define PROG_CRC_UIMENU 36416
|
||||
|
||||
#endif//UI_EDICT_H
|
|
@ -50,10 +50,10 @@ void UI_KeyEvent( int key )
|
|||
|
||||
PRVM_End;
|
||||
|
||||
switch (key)
|
||||
switch( key )
|
||||
{
|
||||
case K_ESCAPE:
|
||||
UI_ToggleMenu_f();
|
||||
UI_HideMenu();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -70,16 +70,27 @@ void UI_Draw( void )
|
|||
PRVM_End;
|
||||
}
|
||||
|
||||
void UI_ToggleMenu_f( void )
|
||||
void UI_ShowMenu( void )
|
||||
{
|
||||
PRVM_Begin;
|
||||
PRVM_SetProg(PRVM_MENUPROG);
|
||||
|
||||
// set time
|
||||
*prog->time = cls.realtime;
|
||||
ui_active = !ui_active;
|
||||
ui_active = true;
|
||||
PRVM_ExecuteProgram (prog->globals.ui->m_show, "QC function m_toggle is missing");
|
||||
PRVM_End;
|
||||
}
|
||||
|
||||
PRVM_ExecuteProgram (prog->globals.ui->m_toggle, "QC function m_toggle is missing");
|
||||
void UI_HideMenu( void )
|
||||
{
|
||||
PRVM_Begin;
|
||||
PRVM_SetProg(PRVM_MENUPROG);
|
||||
|
||||
// set time
|
||||
*prog->time = cls.realtime;
|
||||
ui_active = false;
|
||||
PRVM_ExecuteProgram (prog->globals.ui->m_hide, "QC function m_toggle is missing");
|
||||
PRVM_End;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,8 @@ extern prvm_builtin_t vm_ui_builtins[];
|
|||
|
||||
void UI_Init( void );
|
||||
void UI_KeyEvent( int key );
|
||||
void UI_ToggleMenu_f( void );
|
||||
void UI_ShowMenu( void );
|
||||
void UI_HideMenu( void );
|
||||
void UI_Shutdown( void );
|
||||
void UI_Draw( void );
|
||||
|
||||
|
|
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 9.4 KiB |
|
@ -1072,7 +1072,7 @@ static bool FS_AddWad3File( const char *filename )
|
|||
w->name[0] = 0;
|
||||
return false;
|
||||
}
|
||||
// turn doom1 format into quake lump
|
||||
// convert doom1 format into quake lump
|
||||
for (i = 0; i < numlumps; i++)
|
||||
{
|
||||
// will swap later
|
||||
|
@ -1361,6 +1361,7 @@ void FS_CreateGameInfo( const char *filename )
|
|||
com_strncat(buffer, va("gamedir\t\t\"%s\"\n", gs_basedir ), MAX_SYSPATH);
|
||||
com_strncat(buffer, va("title\t\t\"New Game\"\rversion\t\t\"%g\"\rviewmode\t\"firstperson\"\r", XASH_VERSION), MAX_SYSPATH );
|
||||
com_strncat(buffer, va("gamemode\t\t\"singleplayer\"\rgamekey\t\t\"%s\"", GI.key), MAX_SYSPATH );
|
||||
com_strncat(buffer, "\nstartmap\t\t\"newmap\"", MAX_SYSPATH );
|
||||
|
||||
FS_WriteFile( filename, buffer, com_strlen(buffer));
|
||||
Mem_Free( buffer );
|
||||
|
@ -1410,6 +1411,10 @@ void FS_LoadGameInfo( const char *filename )
|
|||
{
|
||||
com_strcpy(GI.title, SC_GetToken( false ));
|
||||
}
|
||||
else if(SC_MatchToken( "startmap"))
|
||||
{
|
||||
com_strcpy(GI.startmap, SC_GetToken( false ));
|
||||
}
|
||||
else if(SC_MatchToken( "version"))
|
||||
{
|
||||
GI.version = com_atof(SC_GetToken( false ));
|
||||
|
@ -1459,9 +1464,11 @@ void FS_Init( void )
|
|||
|
||||
if(!FS_GetParmFromCmdLine("-game", gs_basedir ))
|
||||
{
|
||||
if(GetModuleFileName( NULL, szTemp, MAX_SYSPATH ))
|
||||
if( Sys.app_name == COMP_BSPLIB )
|
||||
com_strcpy( gs_basedir, "xash" );
|
||||
else if(GetModuleFileName( NULL, szTemp, MAX_SYSPATH ))
|
||||
FS_FileBase( szTemp, gs_basedir );
|
||||
else com_strcpy(gs_basedir, "xash" ); // default dir
|
||||
else com_strcpy( gs_basedir, "xash" ); // default dir
|
||||
}
|
||||
// checked nasty path: "bin" it's a reserved word
|
||||
if(FS_CheckNastyPath( gs_basedir, true ) || !com_stricmp("bin", gs_basedir ))
|
||||
|
@ -1847,7 +1854,7 @@ static byte *FS_OpenWadFile( const char *name, fs_offset_t *filesizeptr, int mat
|
|||
{
|
||||
uint i, k;
|
||||
wadfile_t *w;
|
||||
char basename[MAX_QPATH];
|
||||
string basename;
|
||||
char texname[17];
|
||||
|
||||
// no wads loaded
|
||||
|
@ -1858,7 +1865,7 @@ static byte *FS_OpenWadFile( const char *name, fs_offset_t *filesizeptr, int mat
|
|||
FS_FileBase( name, basename );
|
||||
if(filesizeptr) *filesizeptr = 0;
|
||||
|
||||
if(strlen(basename) >= WAD3_NAMELEN )
|
||||
if(com.strlen(basename) > WAD3_NAMELEN )
|
||||
{
|
||||
Msg("FS_OpenWad3File: %s too long name\n", basename );
|
||||
return NULL;
|
||||
|
|
|
@ -18,7 +18,9 @@ extern byte *image_rgba; // image pointer (see image_type for details)
|
|||
extern uint image_ptr; // common moveable pointer
|
||||
|
||||
// image lib utilites
|
||||
bool Image_Copy8bitRGBA(const byte *in, byte *out, int pixels);
|
||||
void Image_RoundDimensions(int *scaled_width, int *scaled_height);
|
||||
bool FS_AddMipmapToPack( const byte *in, int width, int height );
|
||||
byte *Image_Resample(const void *in, int inwidth, int inheight, int outwidth, int outheight, int in_type);
|
||||
|
||||
#endif//IMAGE_H
|
|
@ -27,6 +27,15 @@ uint cubemap_image_type; // shared image type
|
|||
char *suf[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
|
||||
#define LERPBYTE(i) r = resamplerow1[i];out[i] = (byte) ((((resamplerow2[i] - r) * lerp) >> 16) + r)
|
||||
|
||||
// palette stuff
|
||||
#define LUMP_NORMAL 0
|
||||
#define LUMP_TRANSPARENT 1
|
||||
#define LUMP_DECAL 2
|
||||
#define LUMP_QFONT 3
|
||||
|
||||
uint d_currentpal[256];
|
||||
int d_rendermode = LUMP_NORMAL;
|
||||
|
||||
//=======================================================================
|
||||
// IMGLIB COMMON TOOLS
|
||||
//=======================================================================
|
||||
|
@ -50,6 +59,129 @@ bool Image_ValidSize( char *name )
|
|||
return true;
|
||||
}
|
||||
|
||||
void Image_SetPalette( byte *pal, uint *d_table )
|
||||
{
|
||||
int i;
|
||||
byte rgba[4];
|
||||
|
||||
// setup palette
|
||||
switch( d_rendermode )
|
||||
{
|
||||
case LUMP_DECAL:
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
rgba[3] = pal[765];
|
||||
rgba[2] = pal[766];
|
||||
rgba[1] = pal[767];
|
||||
rgba[0] = i;
|
||||
d_table[i] = BuffBigLong( rgba );
|
||||
}
|
||||
break;
|
||||
case LUMP_TRANSPARENT:
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
rgba[3] = pal[i*3+0];
|
||||
rgba[2] = pal[i*3+1];
|
||||
rgba[1] = pal[i*3+2];
|
||||
rgba[0] = pal[i] == 255 ? pal[i] : 0xFF;
|
||||
d_table[i] = BuffBigLong( rgba );
|
||||
}
|
||||
break;
|
||||
case LUMP_QFONT:
|
||||
for (i = 1; i < 256; i++)
|
||||
{
|
||||
rgba[3] = pal[i*3+0];
|
||||
rgba[2] = pal[i*3+1];
|
||||
rgba[1] = pal[i*3+2];
|
||||
rgba[0] = 0xFF;
|
||||
d_table[i] = BuffBigLong( rgba );
|
||||
}
|
||||
break;
|
||||
case LUMP_NORMAL:
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
rgba[3] = pal[i*3+0];
|
||||
rgba[2] = pal[i*3+1];
|
||||
rgba[1] = pal[i*3+2];
|
||||
rgba[0] = 0xFF;
|
||||
d_table[i] = BuffBigLong( rgba );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Image_GetPalette( byte *pal, int rendermode )
|
||||
{
|
||||
d_rendermode = rendermode;
|
||||
|
||||
if( !pal )
|
||||
{
|
||||
MsgDev(D_ERROR, "Image_GetPalette: palette not found\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Image_SetPalette( pal, d_currentpal );
|
||||
d_currentpal[255] &= LittleLong(0xffffff);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Image_Copy8bitRGBA
|
||||
|
||||
NOTE: must call Image_GetPaletteXXX before used
|
||||
============
|
||||
*/
|
||||
bool Image_Copy8bitRGBA(const byte *in, byte *out, int pixels)
|
||||
{
|
||||
int *iout = (int *)out;
|
||||
|
||||
if(!d_currentpal)
|
||||
{
|
||||
MsgDev(D_ERROR,"Image_Copy8bitRGBA: no palette set\n");
|
||||
return false;
|
||||
}
|
||||
if(!in)
|
||||
{
|
||||
MsgDev(D_ERROR,"Image_Copy8bitRGBA: no input image\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (pixels >= 8)
|
||||
{
|
||||
iout[0] = d_currentpal[in[0]];
|
||||
iout[1] = d_currentpal[in[1]];
|
||||
iout[2] = d_currentpal[in[2]];
|
||||
iout[3] = d_currentpal[in[3]];
|
||||
iout[4] = d_currentpal[in[4]];
|
||||
iout[5] = d_currentpal[in[5]];
|
||||
iout[6] = d_currentpal[in[6]];
|
||||
iout[7] = d_currentpal[in[7]];
|
||||
in += 8;
|
||||
iout += 8;
|
||||
pixels -= 8;
|
||||
}
|
||||
if (pixels & 4)
|
||||
{
|
||||
iout[0] = d_currentpal[in[0]];
|
||||
iout[1] = d_currentpal[in[1]];
|
||||
iout[2] = d_currentpal[in[2]];
|
||||
iout[3] = d_currentpal[in[3]];
|
||||
in += 4;
|
||||
iout += 4;
|
||||
}
|
||||
if (pixels & 2)
|
||||
{
|
||||
iout[0] = d_currentpal[in[0]];
|
||||
iout[1] = d_currentpal[in[1]];
|
||||
in += 2;
|
||||
iout += 2;
|
||||
}
|
||||
if (pixels & 1) // last byte
|
||||
iout[0] = d_currentpal[in[0]];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Image_RoundDimensions(int *scaled_width, int *scaled_height)
|
||||
{
|
||||
int width, height;
|
||||
|
@ -390,7 +522,7 @@ void Image_Resample24Nolerp(const void *indata, int inwidth, int inheight, void
|
|||
Image_Resample
|
||||
================
|
||||
*/
|
||||
byte *Image_Resample (const void *indata, int inwidth, int inheight, int outwidth, int outheight, int in_type )
|
||||
byte *Image_Resample( const void *indata, int inwidth, int inheight, int outwidth, int outheight, int in_type )
|
||||
{
|
||||
bool quality = false; //FIXME
|
||||
byte *outdata;
|
||||
|
@ -447,8 +579,9 @@ bool Image_Processing( const char *name, rgbdata_t **pix, int width, int height
|
|||
else if(image->type == PF_RGB_24) pixel = 3;
|
||||
else if(image->type == PF_RGB_24_FLIP) pixel = 3;
|
||||
else return false; // unknown format
|
||||
MsgDev(D_INFO,"Resampling %s from[%d x %d] to [%d x %d]\n",name, image->width, image->height,w,h );
|
||||
Mem_Move( Sys.imagepool, &image->buffer, out, w * h * pixel ); // update image->buffer
|
||||
MsgDev(D_INFO, "Resampling %s from[%d x %d] to [%d x %d]\n", name, image->width, image->height, w, h );
|
||||
image->buffer = out;
|
||||
// Mem_Move( Sys.imagepool, &image->buffer, out, w * h * pixel ); // update image->buffer
|
||||
image->width = w, image->height = h;
|
||||
image->size = w * h * pixel;
|
||||
*pix = image;
|
||||
|
@ -817,6 +950,69 @@ bool LoadTGA( char *name, char *buffer, int filesize )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
LoadMIP
|
||||
============
|
||||
*/
|
||||
bool LoadMIP( char *name, char *buffer, int filesize )
|
||||
{
|
||||
mip_t mip;
|
||||
byte *fin, *pal;
|
||||
int ofs[4], rendermode;
|
||||
int i, pixels, numcolors;
|
||||
|
||||
if(filesize < (int)sizeof(mip))
|
||||
{
|
||||
MsgWarn("LoadMIP: file (%s) have invalid size\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
Mem_Copy(&mip, buffer, sizeof(mip));
|
||||
image_width = LittleLong(mip.width);
|
||||
image_height = LittleLong(mip.height);
|
||||
for(i = 0; i < 4; i++) ofs[i] = LittleLong(mip.offsets[i]);
|
||||
pixels = image_width * image_height;
|
||||
image_num_layers = 1;
|
||||
image_type = PF_RGBA_32;
|
||||
|
||||
if(filesize >= (int)sizeof(mip) + ((pixels * 85)>>6) + sizeof(short) + 768)
|
||||
{
|
||||
// half-life 1.0.0.1 mip version with palette
|
||||
fin = buffer + mip.offsets[0];
|
||||
pal = buffer + mip.offsets[0] + (((image_width * image_height) * 85)>>6);
|
||||
numcolors = BuffLittleShort( pal );
|
||||
if(numcolors != 256) pal = NULL; // corrupted mip ?
|
||||
else pal += sizeof(short); // skip colorsize
|
||||
// detect rendermode
|
||||
if( name[0] == '{' )
|
||||
{
|
||||
// note: i trying determine transparent miptex by last color in palette
|
||||
// e.g. valve used in their textures blue color (0,0,255)
|
||||
// other cases for red (255,0,0) ang green (0,255,0) colors,
|
||||
// otherwise - it will use decal palette with ugly results. ughgrrr..
|
||||
if(pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 && pal[255*3+3] == 0)
|
||||
rendermode = LUMP_TRANSPARENT;
|
||||
else if(pal[255*3+0] == 0 && pal[255*3+1] == 255 && pal[255*3+2] == 0 && pal[255*3+3] == 0)
|
||||
rendermode = LUMP_TRANSPARENT;
|
||||
else if(pal[255*3+0] == 255 && pal[255*3+1] == 0 && pal[255*3+2] == 0 && pal[255*3+3] == 0)
|
||||
rendermode = LUMP_TRANSPARENT;
|
||||
else rendermode = LUMP_DECAL;
|
||||
image_flags |= IMAGE_HAS_ALPHA;
|
||||
}
|
||||
else rendermode = LUMP_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgWarn("LoadMIP: lump (%s) is corrupted\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Image_ValidSize( name )) return false;
|
||||
Image_GetPalette( pal, rendermode );
|
||||
return FS_AddMipmapToPack( fin, image_width, image_height );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadDDS
|
||||
|
@ -1087,8 +1283,10 @@ loadformat_t load_formats[] =
|
|||
{
|
||||
{"textures/%s%s.%s", "dds", LoadDDS},
|
||||
{"textures/%s%s.%s", "tga", LoadTGA},
|
||||
{"textures/%s%s.%s", "mip", LoadMIP},
|
||||
{"%s%s.%s", "dds", LoadDDS},
|
||||
{"%s%s.%s", "tga", LoadTGA},
|
||||
{"%s%s.%s", "mip", LoadMIP},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -1166,6 +1364,21 @@ bool FS_AddImageToPack( const char *name )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FS_AddMipmapToPack( const byte *in, int width, int height )
|
||||
{
|
||||
int mipsize = width * height;
|
||||
int outsize = width * height * 4;
|
||||
|
||||
// reallocate image buffer
|
||||
image_rgba = Mem_Realloc( Sys.imagepool, image_rgba, image_size + outsize );
|
||||
if(!Image_Copy8bitRGBA( in, image_rgba + image_size, mipsize ))
|
||||
return false; // pallette not installed
|
||||
image_size += outsize;
|
||||
image_num_mips++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_LoadImage
|
||||
|
|
|
@ -97,7 +97,7 @@ void SC_ResetScript( void )
|
|||
SC_ReadToken
|
||||
==============
|
||||
*/
|
||||
bool SC_ReadToken(bool newline)
|
||||
bool SC_ReadToken( bool newline )
|
||||
{
|
||||
char *token_p;
|
||||
int c;
|
||||
|
@ -130,17 +130,12 @@ skip_whitespace: // skip whitespace
|
|||
return SC_EndOfScript (newline);
|
||||
|
||||
// ; // comments
|
||||
if (*script->script_p == ';' || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
|
||||
if(*script->script_p == ';' || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
|
||||
{
|
||||
if (!newline) goto line_incomplete;
|
||||
|
||||
// ets++
|
||||
if (*script->script_p == '/') script->script_p++;
|
||||
if(*script->script_p == '#' && script->script_p[1] == 'T' && script->script_p[2] == 'X')
|
||||
{
|
||||
GI.TXcommand = script->script_p[3]; // TX#"-style comment
|
||||
Msg("Quark TX command %s\n", GI.TXcommand );
|
||||
}
|
||||
while (*script->script_p++ != '\n')
|
||||
{
|
||||
if (script->script_p >= script->end_p)
|
||||
|
@ -193,7 +188,7 @@ skip_whitespace: // skip whitespace
|
|||
}
|
||||
script->script_p++;
|
||||
}
|
||||
else if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' || c == ',')
|
||||
else if (c == '{' || c == '}' || c == ')' || c == '(' || c == '\'' || c == ':' || c == ',' || c == '[' || c == ']')
|
||||
{
|
||||
// parse single characters
|
||||
*token_p++ = *script->script_p++;
|
||||
|
@ -214,7 +209,7 @@ skip_whitespace: // skip whitespace
|
|||
|
||||
if (script->script_p == script->end_p)
|
||||
break;
|
||||
if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ':' || c == ',' || c == ';')
|
||||
if (c == '{' || c == '}'|| c == ')'|| c == '(' || c == '\'' || c == ':' || c == ',' || c == ';' || c == '[' || c == ']')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +228,134 @@ line_incomplete:
|
|||
//invoke error
|
||||
return SC_EndOfScript( newline );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SC_ReadTokenSimple
|
||||
==============
|
||||
*/
|
||||
bool SC_ReadTokenSimple( bool newline )
|
||||
{
|
||||
char *token_p;
|
||||
|
||||
if (tokenready) // is a token allready waiting?
|
||||
{
|
||||
tokenready = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (script->script_p >= script->end_p)
|
||||
return SC_EndOfScript( newline );
|
||||
|
||||
|
||||
skip_whitespace: // skip whitespace
|
||||
while (*script->script_p <= 32)
|
||||
{
|
||||
if (script->script_p >= script->end_p)
|
||||
return SC_EndOfScript (newline);
|
||||
|
||||
if (*script->script_p++ == '\n')
|
||||
{
|
||||
if (!newline) goto line_incomplete;
|
||||
scriptline = script->line++;
|
||||
}
|
||||
}
|
||||
|
||||
if (script->script_p >= script->end_p)
|
||||
return SC_EndOfScript (newline);
|
||||
|
||||
// ; # // comments
|
||||
if (*script->script_p == ';' || *script->script_p == '#' || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
|
||||
{
|
||||
if (!newline) goto line_incomplete;
|
||||
|
||||
// ets+++
|
||||
if(*script->script_p == '/') script->script_p++;
|
||||
if(script->script_p[1] == 'T' && script->script_p[2] == 'X')
|
||||
{
|
||||
GI.TXcommand = script->script_p[3];//TX#"-style comment
|
||||
Msg("Quark TX command %s\n", GI.TXcommand );
|
||||
}
|
||||
while (*script->script_p++ != '\n')
|
||||
{
|
||||
if (script->script_p >= script->end_p)
|
||||
return SC_EndOfScript (newline);
|
||||
}
|
||||
goto skip_whitespace;
|
||||
}
|
||||
|
||||
// /* */ comments
|
||||
if (script->script_p[0] == '/' && script->script_p[1] == '*')
|
||||
{
|
||||
if (!newline) goto line_incomplete;
|
||||
|
||||
script->script_p += 2;
|
||||
while (script->script_p[0] != '*' && script->script_p[1] != '/')
|
||||
{
|
||||
if (script->script_p >= script->end_p)
|
||||
return SC_EndOfScript (newline);
|
||||
if (*script->script_p++ == '\n')
|
||||
{
|
||||
if (!newline) goto line_incomplete;
|
||||
scriptline = script->line++;
|
||||
}
|
||||
}
|
||||
script->script_p += 2;
|
||||
goto skip_whitespace;
|
||||
}
|
||||
|
||||
// copy token
|
||||
token_p = token;
|
||||
|
||||
if (*script->script_p == '"')
|
||||
{
|
||||
// quoted token
|
||||
script->script_p++;
|
||||
while (*script->script_p != '"')
|
||||
{
|
||||
if (token_p == &token[MAX_SYSPATH - 1])
|
||||
{
|
||||
MsgDev(D_WARN, "GetToken: Token too large on line %i\n", scriptline);
|
||||
break;
|
||||
}
|
||||
|
||||
*token_p++ = *script->script_p++;
|
||||
if (script->script_p == script->end_p)
|
||||
break;
|
||||
}
|
||||
script->script_p++;
|
||||
}
|
||||
else // regular token
|
||||
{
|
||||
while ( *script->script_p > 32 && *script->script_p != ';')
|
||||
{
|
||||
if (token_p == &token[MAX_SYSPATH - 1])
|
||||
{
|
||||
MsgWarn("GetToken: Token too large on line %i\n",scriptline);
|
||||
break;
|
||||
}
|
||||
|
||||
*token_p++ = *script->script_p++;
|
||||
if (script->script_p == script->end_p)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*token_p = 0;
|
||||
|
||||
//quake style include & default MSVC style
|
||||
if (!strcmp(token, "$include"))
|
||||
{
|
||||
SC_ReadTokenSimple(false);
|
||||
SC_AddScript(token, NULL, 0 );
|
||||
return SC_ReadTokenSimple(newline);
|
||||
}
|
||||
return true;
|
||||
|
||||
line_incomplete:
|
||||
//invoke error
|
||||
return SC_EndOfScript( newline );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
|
@ -666,8 +789,17 @@ get token on current or newline
|
|||
*/
|
||||
char *SC_GetToken( bool newline )
|
||||
{
|
||||
if(SC_ReadToken( newline ))
|
||||
return token;
|
||||
if( Sys.app_name == COMP_BSPLIB )
|
||||
{
|
||||
// don't handle single characters
|
||||
if(SC_ReadTokenSimple( newline ))
|
||||
return token;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(SC_ReadToken( newline ))
|
||||
return token;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ dll_info_t common_dll = { "common.dll", NULL, "CreateAPI", NULL, NULL, true, siz
|
|||
dll_info_t engine_dll = { "engine.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t viewer_dll = { "viewer.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t ripper_dll = { "ripper.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
dll_info_t custom_dll = { "custom.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(launch_exp_t) };
|
||||
|
||||
static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group 2007 ©\n\t\
|
||||
All Rights Reserved\n\n\t Visit www.xash.ru\n";
|
||||
|
@ -366,19 +365,6 @@ void Sys_LookupInstance( void )
|
|||
com_sprintf(Sys.log_path, "%s/source.log", sys_rootdir ); // default
|
||||
com_strcpy(Sys.caption, va("QuakeC Decompiler ver.%g", XASH_VERSION ));
|
||||
}
|
||||
else if(!com_strcmp(Sys.progname, "sdklib"))
|
||||
{
|
||||
string szTemp;
|
||||
|
||||
// extract caption from exe-name
|
||||
if(GetModuleFileName( NULL, szTemp, MAX_STRING ))
|
||||
FS_FileBase( szTemp, Sys.caption );
|
||||
else com_strcpy( Sys.caption, "Xash Generic Compiler" );
|
||||
Sys.app_name = COMP_SDKLIB;
|
||||
Sys.con_readonly = true;
|
||||
Sys.linked_dll = &custom_dll; // pointer to custom.dll info
|
||||
com_sprintf(Sys.log_path, "%s/result.log", sys_rootdir ); // default
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -405,7 +391,6 @@ void Sys_CreateInstance( void )
|
|||
case COMP_SPRITE:
|
||||
case COMP_STUDIO:
|
||||
case COMP_WADLIB:
|
||||
case COMP_SDKLIB:
|
||||
case RIPP_MIPDEC:
|
||||
case RIPP_SPRDEC:
|
||||
case RIPP_MDLDEC:
|
||||
|
@ -456,7 +441,6 @@ void Sys_CreateInstance( void )
|
|||
case COMP_SPRITE:
|
||||
case COMP_STUDIO:
|
||||
case COMP_WADLIB:
|
||||
case COMP_SDKLIB:
|
||||
case RIPP_MIPDEC:
|
||||
case RIPP_SPRDEC:
|
||||
case RIPP_MDLDEC:
|
||||
|
|
|
@ -357,6 +357,7 @@ void SC_SkipToken( void );
|
|||
void SC_FreeToken( void );
|
||||
bool SC_TryToken( void );
|
||||
char *SC_GetToken( bool newline );
|
||||
char *SC_GetTokenSimple( bool newline );
|
||||
char *SC_Token( void );
|
||||
extern char token[];
|
||||
|
||||
|
|
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -9,11 +9,12 @@
|
|||
|
||||
MAINTARGET = mipdec
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"mipdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj mipdec.res
|
||||
$(link) $(OBJS) mipdec.res /out:"mipdec.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
|
@ -22,3 +23,6 @@ clean:
|
|||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
mipdec.res : mipdec.rc
|
||||
$(RC) $(RCFLAGS) /r mipdec.rc
|
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,39
|
||||
#define VER_FILEVERSION_STR "0.39"
|
||||
#define VER_PRODUCTVERSION 0,39
|
||||
#define VER_PRODUCTVERSION_STR "0.39"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "mipdec"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "Miptex Decompiler"
|
||||
#define VER_ORIGINALFILENAME_STR "mipdec.exe"
|
||||
#define VER_INTERNALNAME_STR "mipdec"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 9.4 KiB |
|
@ -9,11 +9,12 @@
|
|||
|
||||
MAINTARGET = roqlib
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"roqlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj roqlib.res
|
||||
$(link) $(OBJS) roqlib.res /out:"roqlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
|
@ -22,3 +23,6 @@ clean:
|
|||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
roqlib.res : roqlib.rc
|
||||
$(RC) $(RCFLAGS) /r roqlib.rc
|
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,29
|
||||
#define VER_FILEVERSION_STR "0.29"
|
||||
#define VER_PRODUCTVERSION 0,29
|
||||
#define VER_PRODUCTVERSION_STR "0.29"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "RoqLib Launcher"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "R.O.Q. video convertor"
|
||||
#define VER_ORIGINALFILENAME_STR "roqlib.exe"
|
||||
#define VER_INTERNALNAME_STR "roqlib"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -9,11 +9,12 @@
|
|||
|
||||
MAINTARGET = spritegen
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"spritegen.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj spritegen.res
|
||||
$(link) $(OBJS) spritegen.res /out:"spritegen.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
|
@ -22,3 +23,6 @@ clean:
|
|||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
spritegen.res : spritegen.rc
|
||||
$(RC) $(RCFLAGS) /r spritegen.rc
|
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,29
|
||||
#define VER_FILEVERSION_STR "0.29"
|
||||
#define VER_PRODUCTVERSION 0,29
|
||||
#define VER_PRODUCTVERSION_STR "0.29"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "Spritegen"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "Sprite Generator"
|
||||
#define VER_ORIGINALFILENAME_STR "sprite.exe"
|
||||
#define VER_INTERNALNAME_STR "sprite"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -9,11 +9,12 @@
|
|||
|
||||
MAINTARGET = studiomdl
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"studiomdl.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj studiomdl.res
|
||||
$(link) $(OBJS) studiomdl.res /out:"studiomdl.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
|
@ -22,3 +23,6 @@ clean:
|
|||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
studiomdl.res : studiomdl.rc
|
||||
$(RC) $(RCFLAGS) /r studiomdl.rc
|
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,48
|
||||
#define VER_FILEVERSION_STR "0.48"
|
||||
#define VER_PRODUCTVERSION 0,48
|
||||
#define VER_PRODUCTVERSION_STR "0.48"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "studiomdl"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "Studio Model Compiler"
|
||||
#define VER_ORIGINALFILENAME_STR "studio.exe"
|
||||
#define VER_INTERNALNAME_STR "studio"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 9.4 KiB |
|
@ -9,11 +9,12 @@
|
|||
|
||||
MAINTARGET = wadlib
|
||||
OBJS = $(MAINTARGET).obj
|
||||
RES = $(MAINTARGET).rc
|
||||
|
||||
default: $(MAINTARGET).exe
|
||||
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj
|
||||
$(link) $(OBJS) /out:"wadlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
$(MAINTARGET).exe: $(MAINTARGET).obj wadlib.res
|
||||
$(link) $(OBJS) wadlib.res /out:"wadlib.exe" /subsystem:console /opt:nowin98 /nodefaultlib:"libc.lib"
|
||||
@del $(MAINTARGET).obj $(MAINTARGET).lib $(MAINTARGET).exp > nul
|
||||
@copy $(MAINTARGET).exe D:\Xash3D\sdk_main\tools\$(MAINTARGET).exe
|
||||
@del $(MAINTARGET).exe
|
||||
|
@ -22,3 +23,6 @@ clean:
|
|||
|
||||
.cpp.obj:
|
||||
$(CC) $(CFLAGS) /c $<
|
||||
|
||||
wadlib.res : wadlib.rc
|
||||
$(RC) $(RCFLAGS) /r wadlib.rc
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
@ -0,0 +1,28 @@
|
|||
#include <winver.h>
|
||||
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define VER_FILEVERSION 0,1
|
||||
#define VER_FILEVERSION_STR "0.1"
|
||||
#define VER_PRODUCTVERSION 0,1
|
||||
#define VER_PRODUCTVERSION_STR "0.1"
|
||||
|
||||
#define VER_FILEFLAGSMASK VS_FF_PRERELEASE | VS_FF_PATCHED
|
||||
#define VER_FILEFLAGS VS_FF_PRERELEASE
|
||||
#define VER_FILEOS VOS__WINDOWS32
|
||||
#define VER_FILETYPE VFT_DLL
|
||||
#define VER_FILESUBTYPE VFT2_UNKNOWN
|
||||
|
||||
#define VER_COMPANYNAME_STR "XashXT Group"
|
||||
#define VER_LEGALCOPYRIGHT_STR "XashXT 2007"
|
||||
#define VER_PRODUCTNAME_STR "WadLib Launcher"
|
||||
|
||||
#define VER_ANSICP
|
||||
|
||||
#define VER_FILEDESCRIPTION_STR "wad packer"
|
||||
#define VER_ORIGINALFILENAME_STR "wadlib.exe"
|
||||
#define VER_INTERNALNAME_STR "wadlib"
|
||||
|
||||
#include <common.ver>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "tool.ico"
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "physic.h"
|
||||
|
||||
#define CAPSULE_MODEL_HANDLE MAX_MODELS - 2
|
||||
#define BOX_MODEL_HANDLE MAX_MODELS - 1
|
||||
|
||||
typedef struct
|
||||
|
@ -58,7 +59,7 @@ typedef struct clipmap_s
|
|||
char *entitystring;
|
||||
cplane_t *planes; // 12 extra planes for box hull
|
||||
cleaf_t *leafs; // 1 extra leaf for box hull
|
||||
word *leafbrushes;
|
||||
dword *leafbrushes;
|
||||
cnode_t *nodes; // 6 extra planes for box hull
|
||||
dvertex_t *vertices;
|
||||
dedge_t *edges;
|
||||
|
@ -131,7 +132,7 @@ typedef struct box_s
|
|||
{
|
||||
cplane_t *planes;
|
||||
cbrush_t *brush;
|
||||
cmodel_t model;
|
||||
cmodel_t *model;
|
||||
} box_t;
|
||||
|
||||
typedef struct mapleaf_s
|
||||
|
@ -155,6 +156,14 @@ typedef struct leaflist_s
|
|||
void (*storeleafs)( struct leaflist_s *ll, int nodenum );
|
||||
} leaflist_t;
|
||||
|
||||
typedef struct sphere_s
|
||||
{
|
||||
bool use;
|
||||
float radius;
|
||||
float halfheight;
|
||||
vec3_t offset;
|
||||
} sphere_t;
|
||||
|
||||
typedef struct tracework_s
|
||||
{
|
||||
vec3_t start;
|
||||
|
@ -165,10 +174,11 @@ typedef struct tracework_s
|
|||
float maxOffset; // longest corner length from origin
|
||||
vec3_t bounds[2]; // enclosing box of start and end surrounding by size
|
||||
vec3_t extents; // greatest of abs(size[0]) and abs(size[1])
|
||||
vec3_t origin;
|
||||
int contents;
|
||||
vec3_t origin; // origin of the model tracing through
|
||||
int contents; // trace contents
|
||||
bool ispoint; // optimized case
|
||||
trace_t result; // returned from trace call
|
||||
sphere_t sphere; // sphere for oriendted capsule collision
|
||||
} tracework_t;
|
||||
|
||||
extern clipmap_t cm;
|
||||
|
@ -191,5 +201,7 @@ void CM_StoreBrushes( leaflist_t *ll, int nodenum );
|
|||
void CM_BoxLeafnums_r( leaflist_t *ll, int nodenum );
|
||||
int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *lastleaf );
|
||||
int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize );
|
||||
cmodel_t *CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, bool capsule );
|
||||
|
||||
|
||||
#endif//CM_LOCAL_H
|
|
@ -79,6 +79,19 @@ void CM_BoundBrush( cbrush_t *b )
|
|||
b->bounds[1][2] = sides[5].plane->dist;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_FreeModel
|
||||
================
|
||||
*/
|
||||
void CM_FreeModel( cmodel_t *mod )
|
||||
{
|
||||
Mem_FreePool( &mod->mempool );
|
||||
memset(mod->physmesh, 0, MAXSTUDIOMODELS * sizeof(cmesh_t));
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
mod = NULL;
|
||||
}
|
||||
|
||||
int CM_NumTexinfo( void ) { return cm.numtexinfo; }
|
||||
int CM_NumClusters( void ) { return cm.numclusters; }
|
||||
int CM_NumInlineModels( void ) { return cm.numbmodels; }
|
||||
|
@ -144,8 +157,8 @@ void BSP_LoadModels( lump_t *l )
|
|||
{
|
||||
dmodel_t *in;
|
||||
cmodel_t *out;
|
||||
int *indexes;
|
||||
int i, j, count;
|
||||
short *indexes;
|
||||
|
||||
in = (void *)(cm.mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in)) Host_Error("CMod_LoadModels: funny lump size\n");
|
||||
|
@ -174,7 +187,7 @@ void BSP_LoadModels( lump_t *l )
|
|||
|
||||
// make a "leaf" just to hold the model's brushes and surfaces
|
||||
out->leaf.numleafbrushes = LittleLong( in->numbrushes );
|
||||
indexes = Mem_Alloc( out->mempool, out->leaf.numleafbrushes * sizeof(short));
|
||||
indexes = Mem_Alloc( out->mempool, out->leaf.numleafbrushes * sizeof(dword));
|
||||
out->leaf.firstleafbrush = indexes - cm.leafbrushes;
|
||||
for( j = 0; j < out->leaf.numleafbrushes; j++ )
|
||||
indexes[j] = LittleLong( in->firstbrush ) + j;
|
||||
|
@ -350,7 +363,7 @@ BSP_LoadLeafBrushes
|
|||
*/
|
||||
void BSP_LoadLeafBrushes( lump_t *l )
|
||||
{
|
||||
word *in, *out;
|
||||
dword *in, *out;
|
||||
int i, count;
|
||||
|
||||
in = (void *)(cm.mod_base + l->fileofs);
|
||||
|
@ -358,7 +371,7 @@ void BSP_LoadLeafBrushes( lump_t *l )
|
|||
count = l->filelen / sizeof(*in);
|
||||
|
||||
if( count < 1 ) Host_Error("Map %s with no leaf brushes\n", cm.name );
|
||||
out = cm.leafbrushes = (word *)Mem_Alloc( cmappool, (count + 1) * sizeof(*out));
|
||||
out = cm.leafbrushes = (dword *)Mem_Alloc( cmappool, (count + 1) * sizeof(*out));
|
||||
cm.numleafbrushes = count;
|
||||
for ( i = 0; i < count; i++, in++, out++) *out = LittleShort(*in);
|
||||
}
|
||||
|
@ -775,12 +788,23 @@ void CM_LoadWorld( const void *buffer )
|
|||
|
||||
void CM_FreeWorld( void )
|
||||
{
|
||||
int i;
|
||||
cmodel_t *mod;
|
||||
|
||||
// free old stuff
|
||||
if( cm.loaded ) Mem_EmptyPool( cmappool );
|
||||
cm.numplanes = cm.numnodes = cm.numleafs = 0;
|
||||
cm.num_models = cm.numfaces = cm.numbmodels = 0;
|
||||
cm.name[0] = 0;
|
||||
|
||||
// free bmodels too
|
||||
for (i = 0, mod = &cm.bmodels[0]; i < cm.numbmodels; i++, mod++)
|
||||
{
|
||||
if(!mod->name[0]) continue;
|
||||
if(mod->registration_sequence != registration_sequence)
|
||||
CM_FreeModel( mod );
|
||||
}
|
||||
|
||||
if( cm.body )
|
||||
{
|
||||
// and physical body release too
|
||||
|
@ -866,20 +890,6 @@ cmodel_t *CM_BeginRegistration( const char *name, bool clientload, uint *checksu
|
|||
return &cm.bmodels[0];
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_FreeModel
|
||||
================
|
||||
*/
|
||||
void CM_FreeModel( cmodel_t *mod )
|
||||
{
|
||||
Mem_FreePool( &mod->mempool );
|
||||
memset(mod->physmesh, 0, MAXSTUDIOMODELS * sizeof(cmesh_t));
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
mod = NULL;
|
||||
}
|
||||
|
||||
|
||||
void CM_EndRegistration( void )
|
||||
{
|
||||
cmodel_t *mod;
|
||||
|
@ -891,12 +901,6 @@ void CM_EndRegistration( void )
|
|||
if(mod->registration_sequence != registration_sequence)
|
||||
CM_FreeModel( mod );
|
||||
}
|
||||
for (i = 0, mod = &cm.bmodels[0]; i < cm.numbmodels; i++, mod++)
|
||||
{
|
||||
if(!mod->name[0]) continue;
|
||||
if(mod->registration_sequence != registration_sequence)
|
||||
CM_FreeModel( mod );
|
||||
}
|
||||
}
|
||||
|
||||
int CM_LeafContents( int leafnum )
|
||||
|
@ -946,8 +950,10 @@ void CM_InitBoxHull( void )
|
|||
box.brush->numsides = 6;
|
||||
box.brush->firstbrushside = cm.numbrushsides;
|
||||
box.brush->contents = CONTENTS_MONSTER;//FIXME
|
||||
box.model.leaf.numleafbrushes = 1;
|
||||
box.model.leaf.firstleafbrush = cm.numleafbrushes;
|
||||
box.model = &cm.bmodels[BOX_MODEL_HANDLE];
|
||||
com.strcpy( box.model->name, "*4095" );
|
||||
box.model->leaf.numleafbrushes = 1;
|
||||
box.model->leaf.firstleafbrush = cm.numleafbrushes;
|
||||
cm.leafbrushes[cm.numleafbrushes] = cm.numbrushes;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
|
@ -973,6 +979,9 @@ void CM_InitBoxHull( void )
|
|||
p->normal[i>>1] = -1;
|
||||
PlaneClassify( p );
|
||||
}
|
||||
|
||||
// capsule name
|
||||
com.strcpy( cm.bmodels[CAPSULE_MODEL_HANDLE].name, "*4094" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -984,10 +993,15 @@ BSP trees instead of being compared directly.
|
|||
Capsules are handled differently though.
|
||||
===================
|
||||
*/
|
||||
int CM_TempBoxModel( const vec3_t mins, const vec3_t maxs )
|
||||
cmodel_t *CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, bool capsule )
|
||||
{
|
||||
VectorCopy( mins, box.model.mins );
|
||||
VectorCopy( maxs, box.model.maxs );
|
||||
VectorCopy( mins, box.model->mins );
|
||||
VectorCopy( maxs, box.model->maxs );
|
||||
|
||||
if( capsule )
|
||||
{
|
||||
return &cm.bmodels[CAPSULE_MODEL_HANDLE];
|
||||
}
|
||||
|
||||
box.planes[0].dist = maxs[0];
|
||||
box.planes[1].dist = -maxs[0];
|
||||
|
@ -1005,7 +1019,7 @@ int CM_TempBoxModel( const vec3_t mins, const vec3_t maxs )
|
|||
VectorCopy( mins, box.brush->bounds[0] );
|
||||
VectorCopy( maxs, box.brush->bounds[1] );
|
||||
|
||||
return BOX_MODEL_HANDLE;
|
||||
return &cm.bmodels[BOX_MODEL_HANDLE];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
// keep 1/8 unit away to keep the position valid before network snapping
|
||||
// and to avoid various numeric issues
|
||||
#define DIST_EPSILON (0.125) // 1/8 epsilon to keep floating point happy
|
||||
#define RADIUS_EPSILON 1.0f
|
||||
#define MAX_POSITION_LEAFS 1024
|
||||
#define Square(x) ((x)*(x))
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
@ -58,10 +61,91 @@ void CreateRotationMatrix(const vec3_t angles, vec3_t matrix[3])
|
|||
VectorNegate( matrix[1], matrix[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_ProjectPointOntoVector
|
||||
================
|
||||
*/
|
||||
void CM_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vDir, vec3_t vProj )
|
||||
{
|
||||
vec3_t pVec;
|
||||
|
||||
VectorSubtract( point, vStart, pVec );
|
||||
// project onto the directional vector for this segment
|
||||
VectorMA( vStart, DotProduct( pVec, vDir ), vDir, vProj );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_DistanceFromLineSquared
|
||||
================
|
||||
*/
|
||||
float CM_DistanceFromLineSquared(vec3_t p, vec3_t lp1, vec3_t lp2, vec3_t dir)
|
||||
{
|
||||
vec3_t proj, t;
|
||||
int j;
|
||||
|
||||
CM_ProjectPointOntoVector( p, lp1, dir, proj );
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
if ((proj[j] > lp1[j] && proj[j] > lp2[j]) || (proj[j] < lp1[j] && proj[j] < lp2[j]))
|
||||
break;
|
||||
}
|
||||
if( j < 3 )
|
||||
{
|
||||
if(fabs(proj[j] - lp1[j]) < fabs(proj[j] - lp2[j]))
|
||||
{
|
||||
VectorSubtract(p, lp1, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract(p, lp2, t);
|
||||
}
|
||||
return VectorLength2(t);
|
||||
}
|
||||
VectorSubtract(p, proj, t);
|
||||
return VectorLength2(t);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_VectorDistanceSquared
|
||||
================
|
||||
*/
|
||||
float CM_VectorDistanceSquared( vec3_t p1, vec3_t p2 )
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
VectorSubtract(p2, p1, dir);
|
||||
return VectorLength2(dir);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SquareRootFloat
|
||||
================
|
||||
*/
|
||||
float SquareRootFloat( float number )
|
||||
{
|
||||
long i;
|
||||
float x, y;
|
||||
const float f = 1.5F;
|
||||
|
||||
x = number * 0.5F;
|
||||
y = number;
|
||||
i = *(long*)&y;
|
||||
i = 0x5f3759df - (i>>1);
|
||||
y = *(float *)&i;
|
||||
y = y*(f-(x*y*y));
|
||||
y = y*(f-(x*y*y));
|
||||
|
||||
return number*y;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
BOX TRACING
|
||||
POSITION TESTING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
@ -73,8 +157,9 @@ CM_TestBoxInBrush
|
|||
void CM_TestBoxInBrush( tracework_t *tw, cbrush_t *brush )
|
||||
{
|
||||
cplane_t *plane;
|
||||
float dist, d1;
|
||||
float t, dist, d1;
|
||||
cbrushside_t *side;
|
||||
vec3_t startp;
|
||||
int i;
|
||||
|
||||
if(!brush->numsides) return;
|
||||
|
@ -87,19 +172,48 @@ void CM_TestBoxInBrush( tracework_t *tw, cbrush_t *brush )
|
|||
return;
|
||||
}
|
||||
|
||||
// the first six planes are the axial planes, so we only
|
||||
// need to test the remainder
|
||||
for( i = 6; i < brush->numsides; i++ )
|
||||
if( tw->sphere.use )
|
||||
{
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
// the first six planes are the axial planes, so we only
|
||||
// need to test the remainder
|
||||
for( i = 6; i < brush->numsides; i++ )
|
||||
{
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
|
||||
// adjust the plane distance apropriately for mins/maxs
|
||||
dist = plane->dist - DotProduct( tw->offsets[plane->signbits], plane->normal );
|
||||
d1 = DotProduct( tw->start, plane->normal ) - dist;
|
||||
// adjust the plane distance apropriately for radius
|
||||
dist = plane->dist + tw->sphere.radius;
|
||||
// find the closest point on the capsule to the plane
|
||||
t = DotProduct( plane->normal, tw->sphere.offset );
|
||||
if( t > 0 )
|
||||
{
|
||||
VectorSubtract( tw->start, tw->sphere.offset, startp );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAdd( tw->start, tw->sphere.offset, startp );
|
||||
}
|
||||
d1 = DotProduct( startp, plane->normal ) - dist;
|
||||
// if completely in front of face, no intersection
|
||||
if( d1 > 0 ) return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the first six planes are the axial planes, so we only
|
||||
// need to test the remainder
|
||||
for( i = 6; i < brush->numsides; i++ )
|
||||
{
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
|
||||
// if completely in front of face, no intersection
|
||||
if ( d1 > 0 ) return;
|
||||
// adjust the plane distance apropriately for mins/maxs
|
||||
dist = plane->dist - DotProduct( tw->offsets[plane->signbits], plane->normal );
|
||||
d1 = DotProduct( tw->start, plane->normal ) - dist;
|
||||
|
||||
// if completely in front of face, no intersection
|
||||
if ( d1 > 0 ) return;
|
||||
}
|
||||
}
|
||||
|
||||
// inside this brush
|
||||
|
@ -135,6 +249,166 @@ void CM_TestInLeaf( tracework_t *tw, cleaf_t *leaf )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_TestCapsuleInCapsule
|
||||
|
||||
capsule inside capsule check
|
||||
==================
|
||||
*/
|
||||
void CM_TestCapsuleInCapsule( tracework_t *tw, cmodel_t *model )
|
||||
{
|
||||
int i;
|
||||
vec3_t mins, maxs;
|
||||
vec3_t top, bottom;
|
||||
vec3_t p1, p2, tmp;
|
||||
vec3_t offset, symetricSize[2];
|
||||
float radius, halfwidth, halfheight, offs, r;
|
||||
|
||||
CM_ModelBounds( model, mins, maxs );
|
||||
|
||||
VectorAdd( tw->start, tw->sphere.offset, top );
|
||||
VectorSubtract( tw->start, tw->sphere.offset, bottom );
|
||||
for( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
offset[i] = ( mins[i] + maxs[i] ) * 0.5;
|
||||
symetricSize[0][i] = mins[i] - offset[i];
|
||||
symetricSize[1][i] = maxs[i] - offset[i];
|
||||
}
|
||||
halfwidth = symetricSize[1][0];
|
||||
halfheight = symetricSize[1][2];
|
||||
radius = ( halfwidth > halfheight ) ? halfheight : halfwidth;
|
||||
offs = halfheight - radius;
|
||||
|
||||
r = Square(tw->sphere.radius + radius);
|
||||
// check if any of the spheres overlap
|
||||
VectorCopy(offset, p1);
|
||||
p1[2] += offs;
|
||||
VectorSubtract(p1, top, tmp);
|
||||
if ( VectorLength2(tmp) < r )
|
||||
{
|
||||
tw->result.startsolid = tw->result.allsolid = true;
|
||||
tw->result.fraction = 0;
|
||||
}
|
||||
VectorSubtract(p1, bottom, tmp);
|
||||
if ( VectorLength2(tmp) < r )
|
||||
{
|
||||
tw->result.startsolid = tw->result.allsolid = true;
|
||||
tw->result.fraction = 0;
|
||||
}
|
||||
VectorCopy(offset, p2);
|
||||
p2[2] -= offs;
|
||||
VectorSubtract(p2, top, tmp);
|
||||
if ( VectorLength2(tmp) < r )
|
||||
{
|
||||
tw->result.startsolid = tw->result.allsolid = true;
|
||||
tw->result.fraction = 0;
|
||||
}
|
||||
VectorSubtract(p2, bottom, tmp);
|
||||
if ( VectorLength2(tmp) < r )
|
||||
{
|
||||
tw->result.startsolid = tw->result.allsolid = true;
|
||||
tw->result.fraction = 0;
|
||||
}
|
||||
// if between cylinder up and lower bounds
|
||||
if((top[2] >= p1[2] && top[2] <= p2[2]) || (bottom[2] >= p1[2] && bottom[2] <= p2[2]))
|
||||
{
|
||||
top[2] = p1[2] = 0; // 2d coordinates
|
||||
VectorSubtract(top, p1, tmp); // if the cylinders overlap
|
||||
if( VectorLength2(tmp) < r )
|
||||
{
|
||||
tw->result.startsolid = tw->result.allsolid = true;
|
||||
tw->result.fraction = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_TestBoundingBoxInCapsule
|
||||
|
||||
bounding box inside capsule check
|
||||
==================
|
||||
*/
|
||||
void CM_TestBoundingBoxInCapsule( tracework_t *tw, cmodel_t *model )
|
||||
{
|
||||
vec3_t mins, maxs, offset, size[2];
|
||||
cmodel_t *cmod;
|
||||
int i;
|
||||
|
||||
// mins maxs of the capsule
|
||||
CM_ModelBounds(model, mins, maxs);
|
||||
|
||||
// offset for capsule center
|
||||
for( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
offset[i] = ( mins[i] + maxs[i] ) * 0.5;
|
||||
size[0][i] = mins[i] - offset[i];
|
||||
size[1][i] = maxs[i] - offset[i];
|
||||
tw->start[i] -= offset[i];
|
||||
tw->end[i] -= offset[i];
|
||||
}
|
||||
|
||||
// replace the bounding box with the capsule
|
||||
tw->sphere.use = true;
|
||||
tw->sphere.radius = ( maxs[0] > maxs[2] ) ? maxs[2]: maxs[0];
|
||||
tw->sphere.halfheight = maxs[2];
|
||||
VectorSet( tw->sphere.offset, 0, 0, maxs[2] - tw->sphere.radius );
|
||||
|
||||
// replace the capsule with the bounding box
|
||||
cmod = CM_TempBoxModel( tw->mins, tw->maxs, false );
|
||||
// calculate collision
|
||||
CM_TestInLeaf( tw, &cmod->leaf );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_PositionTest
|
||||
==================
|
||||
*/
|
||||
void CM_PositionTest( tracework_t *tw )
|
||||
{
|
||||
int leafs[MAX_POSITION_LEAFS];
|
||||
int i;
|
||||
leaflist_t ll;
|
||||
|
||||
// identify the leafs we are touching
|
||||
VectorAdd( tw->start, tw->mins, ll.bounds[0] );
|
||||
VectorAdd( tw->start, tw->maxs, ll.bounds[1] );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ll.bounds[0][i] -= 1;
|
||||
ll.bounds[1][i] += 1;
|
||||
}
|
||||
|
||||
ll.count = 0;
|
||||
ll.maxcount = MAX_POSITION_LEAFS;
|
||||
ll.list = leafs;
|
||||
ll.storeleafs = CM_StoreLeafs;
|
||||
ll.lastleaf = 0;
|
||||
ll.overflowed = false;
|
||||
cm.checkcount++;
|
||||
|
||||
CM_BoxLeafnums_r( &ll, 0 );
|
||||
cm.checkcount++;
|
||||
|
||||
// test the contents of the leafs
|
||||
for( i = 0; i < ll.count; i++)
|
||||
{
|
||||
CM_TestInLeaf( tw, &cm.leafs[leafs[i]] );
|
||||
if( tw->result.allsolid )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
TRACING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
/*
|
||||
================
|
||||
CM_TraceThroughBrush
|
||||
|
@ -146,9 +420,10 @@ void CM_TraceThroughBrush( tracework_t *tw, cbrush_t *brush )
|
|||
cplane_t *plane, *clipplane;
|
||||
float dist;
|
||||
float enterFrac, leaveFrac;
|
||||
float f, d1, d2;
|
||||
float t, f, d1, d2;
|
||||
bool getout, startout;
|
||||
cbrushside_t *side, *leadside;
|
||||
vec3_t startp, endp;
|
||||
|
||||
enterFrac = -1.0;
|
||||
leaveFrac = 1.0;
|
||||
|
@ -160,54 +435,116 @@ void CM_TraceThroughBrush( tracework_t *tw, cbrush_t *brush )
|
|||
startout = false;
|
||||
leadside = NULL;
|
||||
|
||||
// compare the trace against all planes of the brush
|
||||
// find the latest time the trace crosses a plane towards the interior
|
||||
// and the earliest time the trace crosses a plane towards the exterior
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
if ( tw->sphere.use )
|
||||
{
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
|
||||
// adjust the plane distance apropriately for mins/maxs
|
||||
dist = plane->dist - DotProduct( tw->offsets[ plane->signbits ], plane->normal );
|
||||
|
||||
d1 = DotProduct( tw->start, plane->normal ) - dist;
|
||||
d2 = DotProduct( tw->end, plane->normal ) - dist;
|
||||
|
||||
if( d2 > 0 ) getout = true; // endpoint is not in solid
|
||||
if( d1 > 0 ) startout = true;
|
||||
|
||||
// if completely in front of face, no intersection with the entire brush
|
||||
if(d1 > 0 && ( d2 >= DIST_EPSILON || d2 >= d1 ) )
|
||||
return;
|
||||
|
||||
// if it doesn't cross the plane, the plane isn't relevent
|
||||
if( d1 <= 0 && d2 <= 0 ) continue;
|
||||
|
||||
// crosses face
|
||||
if( d1 > d2 )
|
||||
// compare the trace against all planes of the brush
|
||||
// find the latest time the trace crosses a plane towards the interior
|
||||
// and the earliest time the trace crosses a plane towards the exterior
|
||||
for( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
// enter
|
||||
f = (d1 - DIST_EPSILON) / (d1-d2);
|
||||
if( f < 0 ) f = 0;
|
||||
if( f > enterFrac )
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
|
||||
// adjust the plane distance apropriately for radius
|
||||
dist = plane->dist + tw->sphere.radius;
|
||||
|
||||
// find the closest point on the capsule to the plane
|
||||
t = DotProduct( plane->normal, tw->sphere.offset );
|
||||
if ( t > 0 )
|
||||
{
|
||||
enterFrac = f;
|
||||
clipplane = plane;
|
||||
leadside = side;
|
||||
VectorSubtract( tw->start, tw->sphere.offset, startp );
|
||||
VectorSubtract( tw->end, tw->sphere.offset, endp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// leave
|
||||
f = (d1 + DIST_EPSILON) / (d1-d2);
|
||||
if( f > 1 ) f = 1;
|
||||
if( f < leaveFrac )
|
||||
else
|
||||
{
|
||||
leaveFrac = f;
|
||||
VectorAdd( tw->start, tw->sphere.offset, startp );
|
||||
VectorAdd( tw->end, tw->sphere.offset, endp );
|
||||
}
|
||||
|
||||
d1 = DotProduct( startp, plane->normal ) - dist;
|
||||
d2 = DotProduct( endp, plane->normal ) - dist;
|
||||
|
||||
if( d2 > 0 ) getout = true; // endpoint is not in solid
|
||||
if( d1 > 0 ) startout = true;
|
||||
|
||||
// if completely in front of face, no intersection with the entire brush
|
||||
if( d1 > 0 && ( d2 >= DIST_EPSILON || d2 >= d1 ))
|
||||
return;
|
||||
|
||||
// if it doesn't cross the plane, the plane isn't relevent
|
||||
if( d1 <= 0 && d2 <= 0 ) continue;
|
||||
|
||||
// crosses face
|
||||
if( d1 > d2 )
|
||||
{ // enter
|
||||
f = (d1 - DIST_EPSILON) / (d1-d2);
|
||||
if( f < 0 ) f = 0;
|
||||
if( f > enterFrac )
|
||||
{
|
||||
enterFrac = f;
|
||||
clipplane = plane;
|
||||
leadside = side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // leave
|
||||
f = (d1 + DIST_EPSILON) / (d1-d2);
|
||||
if( f > 1 ) f = 1;
|
||||
if( f < leaveFrac ) leaveFrac = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// compare the trace against all planes of the brush
|
||||
// find the latest time the trace crosses a plane towards the interior
|
||||
// and the earliest time the trace crosses a plane towards the exterior
|
||||
for (i = 0; i < brush->numsides; i++)
|
||||
{
|
||||
side = &cm.brushsides[brush->firstbrushside + i];
|
||||
plane = side->plane;
|
||||
|
||||
// adjust the plane distance apropriately for mins/maxs
|
||||
dist = plane->dist - DotProduct( tw->offsets[ plane->signbits ], plane->normal );
|
||||
|
||||
d1 = DotProduct( tw->start, plane->normal ) - dist;
|
||||
d2 = DotProduct( tw->end, plane->normal ) - dist;
|
||||
|
||||
if( d2 > 0 ) getout = true; // endpoint is not in solid
|
||||
if( d1 > 0 ) startout = true;
|
||||
|
||||
// if completely in front of face, no intersection with the entire brush
|
||||
if(d1 > 0 && ( d2 >= DIST_EPSILON || d2 >= d1 ) )
|
||||
return;
|
||||
|
||||
// if it doesn't cross the plane, the plane isn't relevent
|
||||
if( d1 <= 0 && d2 <= 0 ) continue;
|
||||
|
||||
// crosses face
|
||||
if( d1 > d2 )
|
||||
{
|
||||
// enter
|
||||
f = (d1 - DIST_EPSILON) / (d1-d2);
|
||||
if( f < 0 ) f = 0;
|
||||
if( f > enterFrac )
|
||||
{
|
||||
enterFrac = f;
|
||||
clipplane = plane;
|
||||
leadside = side;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// leave
|
||||
f = (d1 + DIST_EPSILON) / (d1-d2);
|
||||
if( f > 1 ) f = 1;
|
||||
if( f < leaveFrac )
|
||||
{
|
||||
leaveFrac = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all planes have been checked, and the trace was not
|
||||
// completely outside the brush
|
||||
|
@ -266,44 +603,286 @@ void CM_TraceThroughLeaf( tracework_t *tw, cleaf_t *leaf )
|
|||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_PositionTest
|
||||
==================
|
||||
================
|
||||
CM_TraceThroughSphere
|
||||
|
||||
get the first intersection of the ray with the sphere
|
||||
================
|
||||
*/
|
||||
void CM_PositionTest( tracework_t *tw )
|
||||
void CM_TraceThroughSphere( tracework_t *tw, vec3_t origin, float radius, vec3_t start, vec3_t end )
|
||||
{
|
||||
int leafs[MAX_POSITION_LEAFS];
|
||||
float l1, l2, length, scale, fraction;
|
||||
float a, b, c, d, sqrtd;
|
||||
vec3_t v1, dir, intersection;
|
||||
|
||||
// if inside the sphere
|
||||
VectorSubtract( start, origin, dir );
|
||||
l1 = VectorLength2(dir);
|
||||
if (l1 < Square(radius))
|
||||
{
|
||||
tw->result.fraction = 0;
|
||||
tw->result.startsolid = true;
|
||||
// test for allsolid
|
||||
VectorSubtract(end, origin, dir);
|
||||
l1 = VectorLength2(dir);
|
||||
if(l1 < Square(radius))
|
||||
{
|
||||
tw->result.allsolid = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSubtract(end, start, dir);
|
||||
length = VectorNormalize(dir);
|
||||
|
||||
l1 = CM_DistanceFromLineSquared(origin, start, end, dir);
|
||||
VectorSubtract(end, origin, v1);
|
||||
l2 = VectorLength2(v1);
|
||||
|
||||
// if no intersection with the sphere and the end point is at least an epsilon away
|
||||
if(l1 >= Square(radius) && l2 > Square(radius + DIST_EPSILON))
|
||||
return;
|
||||
|
||||
// | origin - (start + t * dir) | = radius
|
||||
// a = dir[0]^2 + dir[1]^2 + dir[2]^2;
|
||||
// b = 2 * (dir[0] * (start[0] - origin[0]) + dir[1] * (start[1] - origin[1]) + dir[2] * (start[2] - origin[2]));
|
||||
// c = (start[0] - origin[0])^2 + (start[1] - origin[1])^2 + (start[2] - origin[2])^2 - radius^2;
|
||||
|
||||
VectorSubtract( start, origin, v1 );
|
||||
a = 1.0f; // dir is normalized so a = 1
|
||||
b = 2.0f * (dir[0] * v1[0] + dir[1] * v1[1] + dir[2] * v1[2]);
|
||||
c = v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2] - (radius + RADIUS_EPSILON) * (radius + RADIUS_EPSILON);
|
||||
|
||||
d = b * b - 4.0f * c;
|
||||
if( d > 0 )
|
||||
{
|
||||
sqrtd = SquareRootFloat( d );
|
||||
fraction = (- b - sqrtd) * 0.5f;
|
||||
if( fraction < 0 ) fraction = 0;
|
||||
else fraction /= length;
|
||||
|
||||
if( fraction < tw->result.fraction )
|
||||
{
|
||||
tw->result.fraction = fraction;
|
||||
VectorSubtract(end, start, dir);
|
||||
VectorMA(start, fraction, dir, intersection);
|
||||
VectorSubtract( intersection, origin, dir );
|
||||
scale = 1 / (radius + RADIUS_EPSILON);
|
||||
VectorScale( dir, scale, dir );
|
||||
VectorCopy(dir, tw->result.plane.normal);
|
||||
VectorAdd( tw->origin, intersection, intersection);
|
||||
tw->result.plane.dist = DotProduct(tw->result.plane.normal, intersection);
|
||||
tw->result.contents = CONTENTS_MONSTER;
|
||||
}
|
||||
}
|
||||
else if (d == 0)
|
||||
{
|
||||
// slide along the sphere
|
||||
}
|
||||
// no intersection at all
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_TraceThroughVerticalCylinder
|
||||
|
||||
get the first intersection of the ray with the cylinder
|
||||
the cylinder extends halfheight above and below the origin
|
||||
================
|
||||
*/
|
||||
void CM_TraceThroughVerticalCylinder( tracework_t *tw, vec3_t origin, float radius, float halfheight, vec3_t start, vec3_t end )
|
||||
{
|
||||
float length, scale, fraction, l1, l2;
|
||||
float a, b, c, d, sqrtd;
|
||||
vec3_t v1, dir, start2d, end2d, org2d, intersection;
|
||||
|
||||
// 2d coordinates
|
||||
VectorSet(start2d, start[0], start[1], 0);
|
||||
VectorSet(end2d, end[0], end[1], 0);
|
||||
VectorSet(org2d, origin[0], origin[1], 0);
|
||||
// if between lower and upper cylinder bounds
|
||||
if( start[2] <= origin[2] + halfheight && start[2] >= origin[2] - halfheight )
|
||||
{
|
||||
// if inside the cylinder
|
||||
VectorSubtract(start2d, org2d, dir);
|
||||
l1 = VectorLength2(dir);
|
||||
if( l1 < Square(radius))
|
||||
{
|
||||
tw->result.fraction = 0;
|
||||
tw->result.startsolid = true;
|
||||
VectorSubtract(end2d, org2d, dir);
|
||||
l1 = VectorLength2(dir);
|
||||
if(l1 < Square(radius))
|
||||
{
|
||||
tw->result.allsolid = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VectorSubtract( end2d, start2d, dir );
|
||||
length = VectorNormalize( dir );
|
||||
|
||||
l1 = CM_DistanceFromLineSquared( org2d, start2d, end2d, dir );
|
||||
VectorSubtract(end2d, org2d, v1);
|
||||
l2 = VectorLength2(v1);
|
||||
|
||||
// if no intersection with the cylinder and the end point is at least an epsilon away
|
||||
if( l1 >= Square(radius) && l2 > Square(radius + DIST_EPSILON))
|
||||
return;
|
||||
|
||||
// (start[0] - origin[0] - t * dir[0]) ^ 2 + (start[1] - origin[1] - t * dir[1]) ^ 2 = radius ^ 2
|
||||
// (v1[0] + t * dir[0]) ^ 2 + (v1[1] + t * dir[1]) ^ 2 = radius ^ 2;
|
||||
// v1[0] ^ 2 + 2 * v1[0] * t * dir[0] + (t * dir[0]) ^ 2 + v1[1] ^ 2 + 2 * v1[1] * t * dir[1] + (t * dir[1]) ^ 2 = radius ^ 2
|
||||
// t ^ 2 * (dir[0] ^ 2 + dir[1] ^ 2) + t * (2 * v1[0] * dir[0] + 2 * v1[1] * dir[1]) + v1[0] ^ 2 + v1[1] ^ 2 - radius ^ 2 = 0
|
||||
|
||||
VectorSubtract( start, origin, v1 );
|
||||
a = 1.0f; // dir is normalized so we can use a = 1
|
||||
b = 2.0f * (v1[0] * dir[0] + v1[1] * dir[1]);
|
||||
c = v1[0] * v1[0] + v1[1] * v1[1] - (radius + RADIUS_EPSILON) * (radius + RADIUS_EPSILON);
|
||||
|
||||
d = b * b - 4.0f * c;
|
||||
if( d > 0 )
|
||||
{
|
||||
sqrtd = SquareRootFloat(d);
|
||||
fraction = (- b - sqrtd) * 0.5f;// / (2.0f * a);
|
||||
if( fraction < 0 ) fraction = 0;
|
||||
else fraction /= length;
|
||||
|
||||
if( fraction < tw->result.fraction )
|
||||
{
|
||||
VectorSubtract( end, start, dir );
|
||||
VectorMA( start, fraction, dir, intersection );
|
||||
|
||||
// if the intersection is between the cylinder lower and upper bound
|
||||
if( intersection[2] <= origin[2] + halfheight && intersection[2] >= origin[2] - halfheight )
|
||||
{
|
||||
tw->result.fraction = fraction;
|
||||
VectorSubtract(intersection, origin, dir);
|
||||
dir[2] = 0;
|
||||
scale = 1 / (radius + RADIUS_EPSILON);
|
||||
VectorScale( dir, scale, dir );
|
||||
VectorCopy(dir, tw->result.plane.normal);
|
||||
VectorAdd( tw->origin, intersection, intersection );
|
||||
tw->result.plane.dist = DotProduct( tw->result.plane.normal, intersection );
|
||||
tw->result.contents = CONTENTS_MONSTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( d == 0 )
|
||||
{
|
||||
// slide along the cylinder
|
||||
}
|
||||
// no intersection at all
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_TraceCapsuleThroughCapsule
|
||||
|
||||
capsule vs. capsule collision (not rotated)
|
||||
================
|
||||
*/
|
||||
void CM_TraceCapsuleThroughCapsule( tracework_t *tw, cmodel_t *model )
|
||||
{
|
||||
int i;
|
||||
vec3_t mins, maxs;
|
||||
vec3_t top, bottom, starttop, startbottom, endtop, endbottom;
|
||||
vec3_t offset, symetricSize[2];
|
||||
float radius, halfwidth, halfheight, offs, h;
|
||||
|
||||
CM_ModelBounds( model, mins, maxs );
|
||||
|
||||
// test trace bounds vs. capsule bounds
|
||||
if ( tw->bounds[0][0] > maxs[0] + RADIUS_EPSILON || tw->bounds[0][1] > maxs[1] + RADIUS_EPSILON
|
||||
|| tw->bounds[0][2] > maxs[2] + RADIUS_EPSILON || tw->bounds[1][0] < mins[0] - RADIUS_EPSILON
|
||||
|| tw->bounds[1][1] < mins[1] - RADIUS_EPSILON || tw->bounds[1][2] < mins[2] - RADIUS_EPSILON )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// top origin and bottom origin of each sphere at start and end of trace
|
||||
VectorAdd( tw->start, tw->sphere.offset, starttop );
|
||||
VectorSubtract( tw->start, tw->sphere.offset, startbottom );
|
||||
VectorAdd( tw->end, tw->sphere.offset, endtop );
|
||||
VectorSubtract( tw->end, tw->sphere.offset, endbottom );
|
||||
|
||||
// calculate top and bottom of the capsule spheres to collide with
|
||||
for( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
offset[i] = ( mins[i] + maxs[i] ) * 0.5f;
|
||||
symetricSize[0][i] = mins[i] - offset[i];
|
||||
symetricSize[1][i] = maxs[i] - offset[i];
|
||||
}
|
||||
|
||||
halfwidth = symetricSize[1][0];
|
||||
halfheight = symetricSize[1][2];
|
||||
radius = ( halfwidth > halfheight ) ? halfheight : halfwidth;
|
||||
offs = halfheight - radius;
|
||||
VectorCopy( offset, top );
|
||||
|
||||
top[2] += offs;
|
||||
VectorCopy(offset, bottom);
|
||||
bottom[2] -= offs;
|
||||
|
||||
// expand radius of spheres
|
||||
radius += tw->sphere.radius;
|
||||
// if there is horizontal movement
|
||||
if( tw->start[0] != tw->end[0] || tw->start[1] != tw->end[1] )
|
||||
{
|
||||
// height of the expanded cylinder is the height of both cylinders minus the radius of both spheres
|
||||
h = halfheight + tw->sphere.halfheight - radius;
|
||||
|
||||
// if the cylinder has a height
|
||||
if( h > 0 )
|
||||
{
|
||||
// test for collisions between the cylinders
|
||||
CM_TraceThroughVerticalCylinder(tw, offset, radius, h, tw->start, tw->end);
|
||||
}
|
||||
}
|
||||
|
||||
// test for collision between the spheres
|
||||
CM_TraceThroughSphere( tw, top, radius, startbottom, endbottom );
|
||||
CM_TraceThroughSphere( tw, bottom, radius, starttop, endtop );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CM_TraceBoundingBoxThroughCapsule
|
||||
|
||||
bounding box vs. capsule collision
|
||||
================
|
||||
*/
|
||||
void CM_TraceBoundingBoxThroughCapsule( tracework_t *tw, cmodel_t *model )
|
||||
{
|
||||
vec3_t mins, maxs, offset, size[2];
|
||||
cmodel_t *cmod;
|
||||
int i;
|
||||
leaflist_t ll;
|
||||
|
||||
// identify the leafs we are touching
|
||||
VectorAdd( tw->start, tw->mins, ll.bounds[0] );
|
||||
VectorAdd( tw->start, tw->maxs, ll.bounds[1] );
|
||||
// mins maxs of the capsule
|
||||
CM_ModelBounds( model, mins, maxs );
|
||||
|
||||
// offset for capsule center
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ll.bounds[0][i] -= 1;
|
||||
ll.bounds[1][i] += 1;
|
||||
offset[i] = ( mins[i] + maxs[i] ) * 0.5f;
|
||||
size[0][i] = mins[i] - offset[i];
|
||||
size[1][i] = maxs[i] - offset[i];
|
||||
tw->start[i] -= offset[i];
|
||||
tw->end[i] -= offset[i];
|
||||
}
|
||||
|
||||
ll.count = 0;
|
||||
ll.maxcount = MAX_POSITION_LEAFS;
|
||||
ll.list = leafs;
|
||||
ll.storeleafs = CM_StoreLeafs;
|
||||
ll.lastleaf = 0;
|
||||
ll.overflowed = false;
|
||||
cm.checkcount++;
|
||||
// replace the bounding box with the capsule
|
||||
tw->sphere.use = true;
|
||||
tw->sphere.radius = ( size[1][0] > size[1][2] ) ? size[1][2]: size[1][0];
|
||||
tw->sphere.halfheight = size[1][2];
|
||||
VectorSet( tw->sphere.offset, 0, 0, size[1][2] - tw->sphere.radius );
|
||||
|
||||
CM_BoxLeafnums_r( &ll, 0 );
|
||||
cm.checkcount++;
|
||||
// replace the capsule with the bounding box
|
||||
cmod = CM_TempBoxModel(tw->mins, tw->maxs, false);
|
||||
|
||||
// test the contents of the leafs
|
||||
for( i = 0; i < ll.count; i++)
|
||||
{
|
||||
CM_TestInLeaf( tw, &cm.leafs[leafs[i]] );
|
||||
if( tw->result.allsolid )
|
||||
break;
|
||||
}
|
||||
// calculate collision
|
||||
CM_TraceThroughLeaf( tw, &cmod->leaf );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -420,7 +999,7 @@ void CM_TraceThroughTree( tracework_t *tw, int num, float p1f, float p2f, vec3_t
|
|||
CM_Trace
|
||||
==================
|
||||
*/
|
||||
void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *mod, const vec3_t origin, int brushmask )
|
||||
void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *mod, const vec3_t origin, int brushmask, bool capsule, sphere_t *sphere )
|
||||
{
|
||||
int i;
|
||||
tracework_t tw;
|
||||
|
@ -459,6 +1038,19 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
|
|||
tw.end[i] = end[i] + offset[i];
|
||||
}
|
||||
|
||||
// if a sphere is already specified
|
||||
if( sphere )
|
||||
{
|
||||
tw.sphere = *sphere;
|
||||
}
|
||||
else
|
||||
{
|
||||
tw.sphere.use = capsule;
|
||||
tw.sphere.radius = ( tw.maxs[0] > tw.maxs[2] ) ? tw.maxs[2]: tw.maxs[0];
|
||||
tw.sphere.halfheight = tw.maxs[2];
|
||||
VectorSet( tw.sphere.offset, 0, 0, tw.maxs[2] - tw.sphere.radius );
|
||||
}
|
||||
|
||||
tw.maxOffset = tw.maxs[0] + tw.maxs[1] + tw.maxs[2];
|
||||
|
||||
// tw.offsets[signbits] = vector to apropriate corner from origin
|
||||
|
@ -495,30 +1087,57 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
|
|||
tw.offsets[7][2] = tw.maxs[2];
|
||||
|
||||
// calculate bounds
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
if( tw.sphere.use )
|
||||
{
|
||||
if ( tw.start[i] < tw.end[i] )
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
tw.bounds[0][i] = tw.start[i] + tw.mins[i];
|
||||
tw.bounds[1][i] = tw.end[i] + tw.maxs[i];
|
||||
if( tw.start[i] < tw.end[i] )
|
||||
{
|
||||
tw.bounds[0][i] = tw.start[i] - fabs(tw.sphere.offset[i]) - tw.sphere.radius;
|
||||
tw.bounds[1][i] = tw.end[i] + fabs(tw.sphere.offset[i]) + tw.sphere.radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
tw.bounds[0][i] = tw.end[i] - fabs(tw.sphere.offset[i]) - tw.sphere.radius;
|
||||
tw.bounds[1][i] = tw.start[i] + fabs(tw.sphere.offset[i]) + tw.sphere.radius;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
tw.bounds[0][i] = tw.end[i] + tw.mins[i];
|
||||
tw.bounds[1][i] = tw.start[i] + tw.maxs[i];
|
||||
if ( tw.start[i] < tw.end[i] )
|
||||
{
|
||||
tw.bounds[0][i] = tw.start[i] + tw.mins[i];
|
||||
tw.bounds[1][i] = tw.end[i] + tw.maxs[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
tw.bounds[0][i] = tw.end[i] + tw.mins[i];
|
||||
tw.bounds[1][i] = tw.start[i] + tw.maxs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for position test special case
|
||||
if( VectorCompare( start, end ))
|
||||
{
|
||||
if( mod && mod->type == mod_brush ) CM_TestInLeaf( &tw, &mod->leaf );
|
||||
if( mod )
|
||||
{
|
||||
if( !com.strcmp( mod->name, "*4094" )) // capsule
|
||||
{
|
||||
if( tw.sphere.use ) CM_TestCapsuleInCapsule( &tw, mod );
|
||||
else CM_TestBoundingBoxInCapsule( &tw, mod );
|
||||
}
|
||||
else CM_TestInLeaf( &tw, &mod->leaf );
|
||||
}
|
||||
else CM_PositionTest( &tw );
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for point special case
|
||||
if ( tw.mins[0] == 0 && tw.mins[1] == 0 && tw.mins[2] == 0 )
|
||||
if( VectorIsNull( tw.mins ))
|
||||
{
|
||||
tw.ispoint = true;
|
||||
VectorClear( tw.extents );
|
||||
|
@ -532,7 +1151,15 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
|
|||
}
|
||||
|
||||
// general sweeping through world
|
||||
if ( mod && mod->type == mod_brush ) CM_TraceThroughLeaf( &tw, &mod->leaf );
|
||||
if( mod )
|
||||
{
|
||||
if( !com.strcmp( mod->name, "*4094" )) // capsule
|
||||
{
|
||||
if( tw.sphere.use ) CM_TraceCapsuleThroughCapsule( &tw, mod );
|
||||
else CM_TraceBoundingBoxThroughCapsule( &tw, mod );
|
||||
}
|
||||
else CM_TraceThroughLeaf( &tw, &mod->leaf );
|
||||
}
|
||||
else CM_TraceThroughTree( &tw, 0, 0, 1, tw.start, tw.end );
|
||||
}
|
||||
|
||||
|
@ -567,9 +1194,9 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
|
|||
CM_BoxTrace
|
||||
==================
|
||||
*/
|
||||
trace_t CM_BoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask )
|
||||
trace_t CM_BoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, bool capsule )
|
||||
{
|
||||
CM_Trace( &cm.trace, start, end, mins, maxs, model, vec3_origin, brushmask );
|
||||
CM_Trace( &cm.trace, start, end, mins, maxs, model, vec3_origin, brushmask, capsule, NULL );
|
||||
return cm.trace;
|
||||
}
|
||||
|
||||
|
@ -581,13 +1208,14 @@ Handles offseting and rotation of the end points for moving and
|
|||
rotating entities
|
||||
==================
|
||||
*/
|
||||
trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, vec3_t origin, vec3_t angles )
|
||||
trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, vec3_t origin, vec3_t angles, int capsule )
|
||||
{
|
||||
vec3_t start_l, end_l;
|
||||
vec3_t offset;
|
||||
vec3_t symetricSize[2];
|
||||
vec3_t matrix[3];
|
||||
vec3_t transpose[3];
|
||||
vec3_t matrix[3], transpose[3];
|
||||
float t, halfwidth, halfheight;
|
||||
sphere_t sphere;
|
||||
bool rotated;
|
||||
int i;
|
||||
|
||||
|
@ -611,9 +1239,17 @@ trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t min
|
|||
VectorSubtract( end_l, origin, end_l );
|
||||
|
||||
// rotate start and end into the models frame of reference
|
||||
if(!VectorIsNull( angles )) rotated = true;
|
||||
if(com.strcmp( model->name, "*4095" ) && !VectorIsNull( angles )) rotated = true;
|
||||
else rotated = false;
|
||||
|
||||
halfwidth = symetricSize[1][0];
|
||||
halfheight = symetricSize[1][2];
|
||||
|
||||
sphere.use = capsule;
|
||||
sphere.radius = ( halfwidth > halfheight ) ? halfheight : halfwidth;
|
||||
sphere.halfheight = halfheight;
|
||||
t = halfheight - sphere.radius;
|
||||
|
||||
if( rotated )
|
||||
{
|
||||
// rotation on trace line (start-end) instead of rotating the bmodel
|
||||
|
@ -625,10 +1261,19 @@ trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t min
|
|||
CreateRotationMatrix( angles, matrix );
|
||||
RotatePoint( start_l, matrix );
|
||||
RotatePoint( end_l, matrix );
|
||||
|
||||
// rotated sphere offset for capsule
|
||||
sphere.offset[0] = matrix[0][2] * t;
|
||||
sphere.offset[1] = -matrix[1][2] * t;
|
||||
sphere.offset[2] = matrix[2][2] * t;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet( sphere.offset, 0, 0, t );
|
||||
}
|
||||
|
||||
// sweep the box through the model
|
||||
CM_Trace( &cm.trace, start_l, end_l, symetricSize[0], symetricSize[1], model, origin, brushmask );
|
||||
CM_Trace( &cm.trace, start_l, end_l, symetricSize[0], symetricSize[1], model, origin, brushmask, capsule, &sphere );
|
||||
|
||||
// if the bmodel was rotated and there was a collision
|
||||
if( rotated && cm.trace.fraction != 1.0 )
|
||||
|
|
|
@ -46,8 +46,8 @@ const char *CM_EntityString( void );
|
|||
const char *CM_TexName( int index );
|
||||
int CM_PointContents( const vec3_t p, cmodel_t *model );
|
||||
int CM_TransformedPointContents( const vec3_t p, cmodel_t *model, const vec3_t origin, const vec3_t angles );
|
||||
trace_t CM_BoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask );
|
||||
trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, vec3_t origin, vec3_t angles );
|
||||
trace_t CM_BoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, bool capsule );
|
||||
trace_t CM_TransformedBoxTrace( const vec3_t start, const vec3_t end, vec3_t mins, vec3_t maxs, cmodel_t *model, int brushmask, vec3_t origin, vec3_t angles, bool capsule );
|
||||
byte *CM_ClusterPVS( int cluster );
|
||||
byte *CM_ClusterPHS( int cluster );
|
||||
int CM_PointLeafnum( const vec3_t p );
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// client.src - project file for client progs
|
||||
//=======================================================================
|
||||
|
||||
../temp/client.dat
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
+-------+
|
||||
|Ambient|
|
||||
+-------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Spawns and handles the 'Ambient' (background) sound effects for Quake. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
|
||||
void(string soundfile, float volume) doambient; // Definition from Ambient.qc
|
||||
|
||||
void() ambient_suck_wind = {doambient("ambience/suck1.wav", 1);};
|
||||
void() ambient_flouro_buzz = {doambient("ambience/buzz1.wav", 1);};
|
||||
void() ambient_drip = {doambient("ambience/drip1.wav", 1);};
|
||||
void() ambient_comp_hum = {doambient("ambience/comp1.wav", 1);};
|
||||
void() ambient_drone = {doambient("ambience/drone6.wav", 0.5);};
|
||||
void() ambient_thunder = {doambient("ambience/thunder1.wav", 0.5);};
|
||||
void() ambient_light_buzz = {doambient("ambience/fl_hum1.wav", 0.5);};
|
||||
void() ambient_swamp1 = {doambient("ambience/swamp1.wav", 0.5);};
|
||||
void() ambient_swamp2 = {doambient("ambience/swamp2.wav", 0.5);};
|
||||
|
||||
void(string soundfile, float volume) doambient =
|
||||
{
|
||||
precache_sound (soundfile);
|
||||
ambientsound (pev, soundfile);
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
====================================================
|
||||
= New Ccam - www.inside3d.com/qctut/lesson-39.shtml=
|
||||
====================================================
|
||||
*/
|
||||
|
||||
void () CCam;
|
||||
|
||||
void () CCamChasePlayer =
|
||||
{
|
||||
makevectors (pev->v_angle);
|
||||
traceline ((pev->origin + pev->view_ofs),((((pev->origin + pev->view_ofs) + (v_forward * pev->camview_z)) + (v_up * pev->camview_x)) + (v_right * pev->camview_y)),FALSE,pev);
|
||||
setorigin (pev->trigger_field,trace_endpos);
|
||||
MsgBegin( 5 );
|
||||
WriteEntity (pev->trigger_field);
|
||||
MsgEnd( MSG_ONE, '0 0 0', pev );
|
||||
pev->weaponmodel = "";
|
||||
};
|
||||
|
||||
void () CCam =
|
||||
{
|
||||
local entity camera;
|
||||
|
||||
if (pev->aflag == FALSE)
|
||||
{
|
||||
pev->aflag = TRUE;
|
||||
camera = create("camera", "models/supp1.mdl", trace_endpos );
|
||||
pev->trigger_field = camera;
|
||||
camera.classname = "camera";
|
||||
camera.movetype = MOVETYPE_FLY;
|
||||
camera.solid = SOLID_NOT;
|
||||
setmodel (camera,"models/supp1.mdl");
|
||||
setsize (camera,'0 0 0','0 0 0');
|
||||
makevectors (pev->v_angle);
|
||||
traceline ((pev->origin + pev->view_ofs),(((pev->origin + pev->view_ofs) + (v_forward * -64.000))), FALSE, pev);
|
||||
pev->camview = '0 0 -64'; // added
|
||||
setorigin (camera,trace_endpos);
|
||||
camera.angles = pev->angles;
|
||||
pev->weaponmodel = "";
|
||||
|
||||
MsgBegin( 5 );
|
||||
WriteEntity (camera);
|
||||
WriteByte (10.000);
|
||||
WriteAngle (camera.angles_x);
|
||||
WriteAngle (camera.angles_y);
|
||||
WriteAngle (camera.angles_z);
|
||||
MsgEnd( MSG_ONE, '0 0 0', pev );
|
||||
sprint (pev,"Chase Cam On\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
pev->aflag = FALSE;
|
||||
MsgBegin( 5 );
|
||||
WriteEntity (pev);
|
||||
WriteByte (10);
|
||||
WriteAngle (camera.angles_x);
|
||||
WriteAngle (camera.angles_y);
|
||||
WriteAngle (camera.angles_z);
|
||||
MsgEnd( MSG_ONE, '0 0 0', pev );
|
||||
remove (pev->trigger_field);
|
||||
sprint (pev,"Chase Cam Off\n");
|
||||
//W_SetCurrentAmmo ();
|
||||
}
|
||||
};
|
|
@ -1,358 +0,0 @@
|
|||
/*
|
||||
+------+
|
||||
|Client|
|
||||
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Handle's "clients" (eg, Players) connecting, disconnecting, etc. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
|
||||
//DEFS;
|
||||
|
||||
void() CCamChasePlayer; // From Ccam.qc
|
||||
void() CheckImpulses; // From Impulses.QC
|
||||
void() PutClientInServer; //From Client.QC
|
||||
|
||||
//END DEFS;
|
||||
.float showhelp;
|
||||
.float showinventory;
|
||||
|
||||
/*
|
||||
+=========+
|
||||
|PPRINT():|
|
||||
+=========+==============================================================================+
|
||||
|Description: |
|
||||
|This function prints a server wide(bprint) 'entity' 'did' 'what" message... v useful for all those|
|
||||
|client joining, leaving msgs etc.. saves a fair amount of code i hope.. [8 lines i think..] |
|
||||
+========================================================================================+
|
||||
*/
|
||||
|
||||
void(entity dude, string did, string what)pprint =
|
||||
{
|
||||
bprint("\n");
|
||||
bprint(dude.netname);
|
||||
bprint(did);
|
||||
bprint(what);
|
||||
bprint("\n");
|
||||
};
|
||||
|
||||
/*
|
||||
CLIENTRESPAWN();
|
||||
*/
|
||||
|
||||
void() ClientRespawn =
|
||||
{
|
||||
if (coop)
|
||||
{
|
||||
// get the spawn parms as they were at level start
|
||||
GetLevelParms();
|
||||
// respawn
|
||||
PutClientInServer();
|
||||
}
|
||||
else if (deathmatch)
|
||||
{
|
||||
// set default spawn parms
|
||||
SetNewParms();
|
||||
// respawn
|
||||
PutClientInServer();
|
||||
}
|
||||
else
|
||||
{ // restart the entire server
|
||||
server_command ("restart\n");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
CLIENTOBITURARY()
|
||||
|
||||
Description;
|
||||
Describes the entity 'who_died' in relation to enitity 'who_killed'.
|
||||
Called when a player gets 'killed' by KILLED(); [DAMAGE.QC]
|
||||
*/
|
||||
|
||||
void(entity who_died, entity who_killed) ClientObiturary =
|
||||
{
|
||||
local string deathstring;
|
||||
local float rnum, msgdt;
|
||||
|
||||
rnum = random_float(0, 1);
|
||||
|
||||
if(who_died.flags & FL_CLIENT)
|
||||
{
|
||||
if(who_killed == world)
|
||||
{
|
||||
deathstring = "was killed";
|
||||
|
||||
if(who_died.watertype == CONTENT_WATER)
|
||||
deathstring = " drowned";
|
||||
else if(who_died.watertype == CONTENT_SLIME)
|
||||
deathstring = " melted";
|
||||
else if(who_died.watertype == CONTENT_LAVA)
|
||||
deathstring = " got incinerated";
|
||||
|
||||
msgdt = TRUE;
|
||||
}
|
||||
|
||||
if(who_killed.classname == "door")
|
||||
{
|
||||
if(rnum < 0.25)
|
||||
{
|
||||
deathstring = " got crushed";
|
||||
}
|
||||
else
|
||||
deathstring = " angered the ";
|
||||
}
|
||||
|
||||
if(who_killed.classname == "button")
|
||||
{
|
||||
if(rnum < 0.25)
|
||||
{
|
||||
deathstring = " pushed it the wrong way";
|
||||
msgdt = TRUE;
|
||||
}
|
||||
else
|
||||
deathstring = " angered the ";
|
||||
}
|
||||
|
||||
if(who_killed.classname == "train")
|
||||
{
|
||||
deathstring = " jumped infront the ";
|
||||
}
|
||||
|
||||
if(who_killed.classname == "teledeath")
|
||||
{
|
||||
deathstring = " was telefragged by ";
|
||||
}
|
||||
|
||||
if(who_killed.classname == "t_hurt")
|
||||
{
|
||||
deathstring = " got hurt too much...";
|
||||
}
|
||||
|
||||
if(who_killed.classname == "t_push")
|
||||
{
|
||||
deathstring = " got pushed too far...";
|
||||
}
|
||||
|
||||
if(who_killed == who_died)
|
||||
{
|
||||
deathstring = " killed themselves...";
|
||||
msgdt = TRUE;
|
||||
}
|
||||
|
||||
bprint(who_died.netname);
|
||||
bprint(deathstring);
|
||||
|
||||
if(msgdt != TRUE)
|
||||
{
|
||||
if(who_killed.flags & FL_CLIENT)
|
||||
bprint(who_killed.netname);
|
||||
else
|
||||
bprint(who_killed.classname);
|
||||
}
|
||||
|
||||
bprint("\n");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
===============
|
||||
|CLIENTKILL():|
|
||||
=================================================================================
|
||||
Description:
|
||||
This function is called when the player enters the 'kill' command in the console.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() ClientKill =
|
||||
{
|
||||
//pprint(pev, " has", " killed themselves.");
|
||||
T_Damage(pev, pev, pev, pev->health);
|
||||
ClientRespawn();
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
|CLIENTCONNECT():|
|
||||
=================================================================================
|
||||
Description:
|
||||
This function is called when the player connects to the server.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() ClientConnect =
|
||||
{
|
||||
pprint(pev, " has", " joined the game.");
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
|CLIENTDISCONNECT():|
|
||||
=================================================================================
|
||||
Description:
|
||||
This function is called when the player disconnects from the server.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() ClientDisconnect =
|
||||
{
|
||||
pprint(pev, " has", " left the game.");
|
||||
};
|
||||
|
||||
/*
|
||||
====================
|
||||
|PLAYERPRETHINK():|
|
||||
===========================================================
|
||||
Description:
|
||||
This function is called every frame *BEFORE* world physics.
|
||||
===========================================================
|
||||
*/
|
||||
|
||||
|
||||
void() PlayerPreThink =
|
||||
{
|
||||
WaterMove ();
|
||||
SetClientFrame ();
|
||||
CheckImpulses();
|
||||
};
|
||||
|
||||
/*
|
||||
====================
|
||||
|PLAYERPOSTTHINK():|
|
||||
===========================================================
|
||||
Description:
|
||||
This function is called every frame *AFTER* world physics.
|
||||
===========================================================
|
||||
*/
|
||||
|
||||
void() PlayerPostThink = {};
|
||||
|
||||
/*
|
||||
======================
|
||||
|PUTCLIENTINSERVER():|
|
||||
===========================================================
|
||||
Description:
|
||||
This function is called whenever a client enters the world.
|
||||
It sets up the player entity.
|
||||
===========================================================
|
||||
*/
|
||||
|
||||
entity() find_spawnspot =
|
||||
{
|
||||
local entity spot;
|
||||
local string a;
|
||||
|
||||
if(deathmatch == 1)
|
||||
a = "info_player_deathmatch";
|
||||
else if(coop == 1)
|
||||
a = "info_player_coop";
|
||||
|
||||
else if(!deathmatch || !coop)
|
||||
a = "info_player_start";
|
||||
|
||||
spot = find (world, classname, a);
|
||||
|
||||
return spot;
|
||||
};
|
||||
|
||||
void() PutClientInServer =
|
||||
{
|
||||
local entity spawn_spot; // This holds where we want to spawn
|
||||
spawn_spot = find_spawnspot(); //find (world, classname, "info_player_start"); // Find it :)
|
||||
|
||||
pev->classname = "player"; // I'm a player!
|
||||
pev->health = pev->max_health = 100; // My health (and my max) is 100
|
||||
pev->takedamage = DAMAGE_AIM; // I can be fired at
|
||||
pev->solid = SOLID_BBOX; // Things sort of 'slide' past me
|
||||
pev->movetype = MOVETYPE_WALK; // Yep, I want to walk.
|
||||
pev->flags = FL_CLIENT; // Yes, I'm a client.
|
||||
|
||||
pev->origin = spawn_spot.origin + '0 0 1'; // Move to the spawnspot location
|
||||
pev->angles = spawn_spot.angles; // Face the angle the spawnspot indicates
|
||||
pev->fixangle = TRUE; // Turn this way immediately
|
||||
pev->weaponmodel = "models/weapons/v_eagle.mdl"; // FIXME: rename to viewmodel
|
||||
|
||||
MsgWarn("PutClientInServer()\n");
|
||||
|
||||
setmodel (pev, "models/player.mdl"); // Set my player to the player model
|
||||
setsize (pev, VEC_HULL_MIN, VEC_HULL_MAX); // Set my size
|
||||
|
||||
pev->view_ofs = '0 0 22'; // Center my view
|
||||
|
||||
setsize(pev, '-16 -16 -32', '16 16 32' );
|
||||
|
||||
if(pev->aflag) CCamChasePlayer ();
|
||||
|
||||
pev->velocity = '0 0 0'; // Stop any old movement
|
||||
|
||||
pev->mass = 90;
|
||||
pev->th_pain = PlayerPain;
|
||||
pev->th_die = PlayerDie;
|
||||
pev->touch = PlayerTouch;
|
||||
|
||||
setstats( pev, STAT_HEALTH_ICON, "hud/i_health");
|
||||
setstats( pev, STAT_HEALTH, ftoa(pev->health));
|
||||
setstats( pev, STAT_HELPICON, "hud/i_help");
|
||||
|
||||
image_index( "hud/help" );
|
||||
GetLevelParms();
|
||||
};
|
||||
|
||||
void ShowInventory( void )
|
||||
{
|
||||
float layout;
|
||||
|
||||
if(pev->showinventory == TRUE) pev->showinventory = FALSE;
|
||||
else pev->showinventory = TRUE;
|
||||
|
||||
if(pev->showinventory == TRUE) layout |= 2;
|
||||
else layout = 0;
|
||||
|
||||
setstats( pev, STAT_LAYOUTS, ftoa(layout));
|
||||
|
||||
MsgBegin( SVC_LAYOUT );
|
||||
WriteString( "" ); // build-in inventory
|
||||
MsgEnd(MSG_ONE, '0 0 0', pev );
|
||||
}
|
||||
|
||||
void HelpComputer( void )
|
||||
{
|
||||
float layout;
|
||||
|
||||
if(pev->showhelp == TRUE) pev->showhelp = FALSE;
|
||||
else pev->showhelp = TRUE;
|
||||
|
||||
if(pev->showhelp == TRUE) layout |= 1;
|
||||
else layout = 0;
|
||||
|
||||
setstats( pev, STAT_LAYOUTS, ftoa(layout));
|
||||
|
||||
MsgBegin( SVC_LAYOUT );
|
||||
WriteString( "Hud_HelpComputer" );
|
||||
MsgEnd(MSG_ONE, '0 0 0', pev );
|
||||
}
|
||||
|
||||
void ClientCommand( void )
|
||||
{
|
||||
string cmd;
|
||||
|
||||
cmd = argv(0);
|
||||
|
||||
if(cmd == "help")
|
||||
{
|
||||
HelpComputer();
|
||||
}
|
||||
if(cmd == "inven")
|
||||
{
|
||||
ShowInventory();
|
||||
}
|
||||
if(cmd == "say")
|
||||
{
|
||||
Msg("say me now ", argv(1), "\n");
|
||||
}
|
||||
if(cmd == "say_team")
|
||||
{
|
||||
Msg("say me now ", argv(1), "\n");
|
||||
}
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
+------+
|
||||
|Damage|
|
||||
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch http://www.inside3d.com/qctut/scratch.shtml |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| T_Damage and other like functions |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
//DEFS
|
||||
void(entity who_died, entity who_killed) ClientObiturary;
|
||||
//END DEFS
|
||||
/*
|
||||
=-=-=-=-=
|
||||
Killed
|
||||
=-=-=-=-=
|
||||
*/
|
||||
|
||||
void(entity target, entity attacker) Killed =
|
||||
{
|
||||
local entity oldpev;
|
||||
|
||||
if (target.health < -99)
|
||||
target.health = -99; // don't let sbar look bad if a player
|
||||
|
||||
target.takedamage = DAMAGE_NO;
|
||||
target.touch = SUB_Null;
|
||||
|
||||
oldpev = pev;
|
||||
pev = target; // pev must be targ for th_die
|
||||
pev->th_die ();
|
||||
pev = oldpev;
|
||||
|
||||
ClientObiturary(target, attacker);
|
||||
};
|
||||
|
||||
/*
|
||||
+=======+
|
||||
|T_Heal|
|
||||
+=======+
|
||||
|Heal entity e for healamount possibly ignoring max health.|
|
||||
+======================================================+
|
||||
*/
|
||||
|
||||
void(entity e, float healamount, float ignore) T_Heal =
|
||||
{
|
||||
if (e.health <= 0)
|
||||
return;
|
||||
|
||||
if ((!ignore) && (e.health >= other.max_health))
|
||||
return;
|
||||
|
||||
healamount = ceil(healamount);
|
||||
|
||||
e.health = e.health + healamount;
|
||||
|
||||
if ((!ignore) && (e.health >= other.max_health))
|
||||
e.health = other.max_health;
|
||||
};
|
||||
|
||||
/*
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
T_Damage
|
||||
|
||||
The damage is coming from inflictor, but get mad at attacker
|
||||
This should be the only function that ever reduces health.
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
*/
|
||||
void(entity target, entity inflictor, entity attacker, float damage) T_Damage=
|
||||
{
|
||||
local vector dir;
|
||||
local entity oldpev;
|
||||
|
||||
if (!target.takedamage)
|
||||
return;
|
||||
|
||||
// used by buttons and triggers to set activator for targetet firing
|
||||
damage_attacker = attacker;
|
||||
|
||||
// figure momentum add
|
||||
if ( (inflictor != world) && (target.movetype == MOVETYPE_WALK) )
|
||||
{
|
||||
dir = target.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
|
||||
dir = normalize(dir);
|
||||
target.velocity = target.velocity + dir*damage*8;
|
||||
}
|
||||
|
||||
// check for godmode
|
||||
if (target.aiflags & AI_GODMODE)
|
||||
return;
|
||||
|
||||
// add to the damage total for clients, which will be sent as a single
|
||||
// message at the end of the frame
|
||||
if (target.flags & FL_CLIENT)
|
||||
{
|
||||
target.dmg_take = target.dmg_take + damage;
|
||||
target.dmg_save = target.dmg_save + damage;
|
||||
target.dmg_inflictor = inflictor;
|
||||
}
|
||||
|
||||
// team play damage avoidance
|
||||
if ( (teamplay == 1) && (target.team > 0)&&(target.team == attacker.team) )
|
||||
return;
|
||||
|
||||
// do the damage
|
||||
target.health = target.health - damage;
|
||||
|
||||
if (target.health <= 0)
|
||||
{
|
||||
Killed (target, attacker);
|
||||
return;
|
||||
}
|
||||
|
||||
// react to the damage
|
||||
oldpev = pev;
|
||||
pev = target;
|
||||
|
||||
if (pev->th_pain)
|
||||
pev->th_pain (attacker, damage);
|
||||
|
||||
pev = oldpev;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
WaterMove
|
||||
|
||||
Can be used for clients or monsters
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
*/
|
||||
void() WaterMove =
|
||||
{
|
||||
if (pev->movetype == MOVETYPE_NOCLIP)
|
||||
return;
|
||||
if (pev->health < 0)
|
||||
return;
|
||||
|
||||
if (pev->waterlevel != 3)
|
||||
{
|
||||
pev->air_finished = time + 12;
|
||||
pev->dmg = 2;
|
||||
}
|
||||
else if (pev->air_finished < time && pev->pain_finished < time)
|
||||
{ // drown!
|
||||
pev->dmg = pev->dmg + 2;
|
||||
if (pev->dmg > 15)
|
||||
pev->dmg = 10;
|
||||
T_Damage (pev, world, world, pev->dmg);
|
||||
pev->pain_finished = time + 1;
|
||||
}
|
||||
|
||||
if (pev->watertype == CONTENT_LAVA && pev->dmgtime < time)
|
||||
{ // do damage
|
||||
pev->dmgtime = time + 0.2;
|
||||
T_Damage (pev, world, world, 6*pev->waterlevel);
|
||||
}
|
||||
else if (pev->watertype == CONTENT_SLIME && pev->dmgtime < time)
|
||||
{ // do damage
|
||||
pev->dmgtime = time + 1;
|
||||
T_Damage (pev, world, world, 4*pev->waterlevel);
|
||||
}
|
||||
};
|
428
pr_server/defs.c
|
@ -1,428 +0,0 @@
|
|||
/*
|
||||
+----+
|
||||
|Defs|
|
||||
+----+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| This contains necessary definitions from the original V1.06 defs.qc file. |
|
||||
| This includes some basic constants, the built in function definitions, and |
|
||||
| some variable's used by the Quake Engine internally. |
|
||||
| Certain lines in this file are hardcoded into Quake engine, and -must- be |
|
||||
| present and unchanged, in the order they are shown. Otherwise Quake will |
|
||||
| refuse to run. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
#pragma version 7 // set right version
|
||||
|
||||
// These lines CANNOT be altered/moved
|
||||
// pointers to ents
|
||||
entity pev; // Pointer EntVars (same as pev)
|
||||
entity other;
|
||||
entity world;
|
||||
|
||||
// timer
|
||||
float time;
|
||||
float frametime;
|
||||
|
||||
// map global info
|
||||
string mapname;
|
||||
string startspot;
|
||||
vector spotoffset;
|
||||
|
||||
// gameplay modes
|
||||
float deathmatch;
|
||||
float coop;
|
||||
float teamplay;
|
||||
|
||||
float serverflags; // propagated from level to level, used to
|
||||
|
||||
// game info
|
||||
float total_secrets;
|
||||
float total_monsters;
|
||||
float found_secrets; // number of secrets found
|
||||
float killed_monsters; // number of monsters killed
|
||||
|
||||
// MakeVectors result
|
||||
vector v_forward;
|
||||
vector v_right;
|
||||
vector v_up;
|
||||
|
||||
// SV_trace result
|
||||
float trace_allsolid;
|
||||
float trace_startsolid;
|
||||
float trace_fraction;
|
||||
vector trace_endpos;
|
||||
vector trace_plane_normal;
|
||||
float trace_plane_dist;
|
||||
float trace_hitgroup;
|
||||
float trace_contents;
|
||||
entity trace_ent;
|
||||
float trace_flags;
|
||||
|
||||
void() main; // only for testing
|
||||
void() StartFrame;
|
||||
void() EndFrame;
|
||||
void() PlayerPreThink;
|
||||
void() PlayerPostThink;
|
||||
void() ClientKill;
|
||||
void() ClientConnect;
|
||||
void() PutClientInServer; // call after setting the parm1... parms
|
||||
void() ClientDisconnect;
|
||||
void() ClientCommand; // process client commands
|
||||
|
||||
void end_sys_globals; // flag for structure dumping
|
||||
|
||||
// base entity info
|
||||
.string classname;
|
||||
.string globalname;
|
||||
.float modelindex;
|
||||
|
||||
// physics description
|
||||
.vector origin;
|
||||
.vector angles;
|
||||
.vector old_origin; // interpolated values
|
||||
.vector old_angles;
|
||||
.vector velocity;
|
||||
.vector avelocity;
|
||||
.vector m_pmatrix[4];
|
||||
.vector m_pcentre[3]; // current centre of mass
|
||||
.vector torque;
|
||||
.vector force;
|
||||
.vector post_origin;
|
||||
.vector post_angles;
|
||||
.vector origin_offset;
|
||||
.float ltime;
|
||||
|
||||
.float bouncetype;
|
||||
.float movetype;
|
||||
.float solid;
|
||||
.vector absmin, absmax;
|
||||
.vector mins, maxs;
|
||||
.vector size;
|
||||
|
||||
// entity base description
|
||||
.entity chain; // dynamic list of all ents
|
||||
.string model;
|
||||
.float frame;
|
||||
.float sequence;
|
||||
.float renderfx;
|
||||
.float effects;
|
||||
.float skin;
|
||||
.float body;
|
||||
.string weaponmodel;
|
||||
.float weaponframe;
|
||||
|
||||
// base generic funcs
|
||||
.void() use;
|
||||
.void() touch;
|
||||
.void() think;
|
||||
.void() blocked;
|
||||
.void() activate;
|
||||
|
||||
// npc generic funcs
|
||||
.void() walk;
|
||||
.void() jump;
|
||||
.void() duck;
|
||||
|
||||
// flags
|
||||
.float flags;
|
||||
.float aiflags;
|
||||
.float spawnflags;
|
||||
|
||||
// other variables
|
||||
.entity groundentity;
|
||||
.float nextthink;
|
||||
.float takedamage;
|
||||
.float health;
|
||||
|
||||
.float frags;
|
||||
.float weapon;
|
||||
.float items;
|
||||
.string target;
|
||||
.string parent;
|
||||
.string targetname;
|
||||
.entity aiment; // attachment edict
|
||||
.entity goalentity;
|
||||
.vector punchangle;
|
||||
.float deadflag;
|
||||
.vector view_ofs; //.entity viewheight;
|
||||
.float button0;
|
||||
.float button1;
|
||||
.float button2;
|
||||
.float impulse;
|
||||
.float fixangle;
|
||||
.vector v_angle;
|
||||
.float idealpitch;
|
||||
.string netname;
|
||||
.entity enemy;
|
||||
.float alpha;
|
||||
.float team;
|
||||
.float max_health;
|
||||
.float teleport_time;
|
||||
.float armortype;
|
||||
.float armorvalue;
|
||||
.float waterlevel;
|
||||
.float watertype;
|
||||
.float ideal_yaw;
|
||||
.float yaw_speed;
|
||||
.float dmg_take;
|
||||
.float dmg_save;
|
||||
.entity dmg_inflictor;
|
||||
.entity owner;
|
||||
.vector movedir;
|
||||
.string message;
|
||||
.float sounds;
|
||||
.string noise;
|
||||
.string noise1;
|
||||
.string noise2;
|
||||
.string noise3; //a looped sound case
|
||||
.float jumpup;
|
||||
.float jumpdn;
|
||||
.entity movetarget;
|
||||
.float mass;
|
||||
.float density;
|
||||
.float gravity;
|
||||
.float dmg;
|
||||
.float dmgtime;
|
||||
.float speed;
|
||||
void end_sys_fields; // flag for structure dumping
|
||||
// End. Lines below this MAY be altered, to some extent
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
//
|
||||
// constants
|
||||
//
|
||||
|
||||
float FALSE = 0;
|
||||
float TRUE = 1;
|
||||
|
||||
// newdefines
|
||||
#define CS_NAME 0
|
||||
#define CS_SKY 1
|
||||
#define CS_SKYAXIS 2 // %f %f %f format
|
||||
#define CS_SKYROTATE 3
|
||||
#define CS_STATUSBAR 4 // hud_program section name
|
||||
//NOTE: other CS_* will be set by engine
|
||||
|
||||
#define STAT_HEALTH_ICON 0
|
||||
#define STAT_HEALTH 1
|
||||
#define STAT_AMMO_ICON 2
|
||||
#define STAT_AMMO 3
|
||||
#define STAT_ARMOR_ICON 4
|
||||
#define STAT_ARMOR 5
|
||||
#define STAT_SELECTED_ICON 6
|
||||
#define STAT_PICKUP_ICON 7
|
||||
#define STAT_PICKUP_STRING 8
|
||||
#define STAT_TIMER_ICON 9
|
||||
#define STAT_TIMER 10
|
||||
#define STAT_HELPICON 11
|
||||
#define STAT_SELECTED_ITEM 12
|
||||
#define STAT_LAYOUTS 13
|
||||
#define STAT_FRAGS 14
|
||||
#define STAT_FLASHES 15 // cleared each frame, 1 = health, 2 = armor
|
||||
#define STAT_CHASE 16
|
||||
#define STAT_SPECTATOR 17
|
||||
#define STAT_SPEED 22
|
||||
#define STAT_ZOOM 23
|
||||
#define MAX_STATS 32
|
||||
|
||||
// edict.aiflags
|
||||
#define AI_FLY 1 // monster is flying
|
||||
#define AI_SWIM 2 // swimming monster
|
||||
#define AI_ONGROUND 4 // monster is onground
|
||||
#define AI_PARTIALONGROUND 8 // monster is partially onground
|
||||
#define AI_GODMODE 16 // monster don't give damage at all
|
||||
#define AI_NOTARGET 32 // monster will no searching enemy's
|
||||
#define AI_NOSTEP 64 // Lazarus stuff
|
||||
#define AI_DUCKED 128 // monster (or player) is ducked
|
||||
#define AI_JUMPING 256 // monster (or player) is jumping
|
||||
#define AI_FROZEN 512 // stop moving, but continue thinking
|
||||
#define AI_ACTOR 1024 // disable ai for actor
|
||||
#define AI_DRIVER 2048 // npc or player driving vehcicle or train
|
||||
#define AI_SPECTATOR 4096 // spectator mode for clients
|
||||
|
||||
// edict.flags
|
||||
#define FL_CLIENT 1 // this is client
|
||||
#define FL_MONSTER 2 // this is npc
|
||||
#define FL_DEADMONSTER 4
|
||||
#define FL_WORLDBRUSH 8 // Not moveable/removeable brush entity
|
||||
#define FL_DORMANT 16 // Entity is dormant, no updates to client
|
||||
#define FL_FRAMETHINK 32 // entity will be thinking every frame
|
||||
#define FL_GRAPHED 64 // ainode list member
|
||||
#define FL_FLOAT 128 // this entity can be floating. FIXME: remove this ?
|
||||
#define FL_TRACKTRAIN 256 // this is tracktrain entity
|
||||
|
||||
// edict.movetype values
|
||||
enum
|
||||
{
|
||||
MOVETYPE_NONE, // never moves
|
||||
MOVETYPE_NOCLIP, // origin and angles change with no interaction
|
||||
MOVETYPE_PUSH, // no clip to world, push on box contact
|
||||
MOVETYPE_WALK, // gravity
|
||||
MOVETYPE_STEP, // gravity, special edge handling
|
||||
MOVETYPE_FLY,
|
||||
MOVETYPE_TOSS, // gravity
|
||||
MOVETYPE_BOUNCE,
|
||||
MOVETYPE_FOLLOW, // attached models
|
||||
MOVETYPE_CONVEYOR,
|
||||
MOVETYPE_PUSHABLE,
|
||||
MOVETYPE_PHYSIC // phys simulation
|
||||
};
|
||||
|
||||
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
|
||||
#define RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors
|
||||
#define RF_WEAPONMODEL 4 // only draw through eyes
|
||||
#define RF_FULLBRIGHT 8 // allways draw full intensity
|
||||
#define RF_DEPTHHACK 16 // for view weapon Z crunching
|
||||
#define RF_TRANSLUCENT 32
|
||||
#define RF_FRAMELERP 64
|
||||
#define RF_BEAM 128
|
||||
#define RF_CUSTOMSKIN 256 // skin is an index in image_precache
|
||||
#define RF_GLOW 512 // pulse lighting for bonus items
|
||||
|
||||
// edict.solid values
|
||||
enum
|
||||
{
|
||||
SOLID_NOT = 0, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP, // bsp clip, touch on edge
|
||||
SOLID_BOX, // physbox
|
||||
SOLID_SPHERE, // sphere
|
||||
SOLID_CYLINDER, // cylinder e.g. barrel
|
||||
SOLID_MESH // custom convex hull
|
||||
};
|
||||
|
||||
// range values
|
||||
float RANGE_MELEE = 0;
|
||||
float RANGE_NEAR = 1;
|
||||
float RANGE_MID = 2;
|
||||
float RANGE_FAR = 3;
|
||||
|
||||
// deadflag values
|
||||
|
||||
float DEAD_NO = 0;
|
||||
float DEAD_DYING = 1;
|
||||
float DEAD_DEAD = 2;
|
||||
float DEAD_RESPAWNABLE = 3;
|
||||
|
||||
// takedamage values
|
||||
|
||||
float DAMAGE_NO = 0;
|
||||
float DAMAGE_YES = 1;
|
||||
float DAMAGE_AIM = 2;
|
||||
|
||||
.void() th_stand;
|
||||
.void() th_walk;
|
||||
.void() th_run;
|
||||
.void(entity attacker, float damage) th_pain;
|
||||
.void() th_die;
|
||||
.void() th_missile;
|
||||
.void() th_melee;
|
||||
|
||||
// point content values
|
||||
|
||||
float CONTENT_EMPTY = -1;
|
||||
float CONTENT_SOLID = -2;
|
||||
float CONTENT_WATER = -3;
|
||||
float CONTENT_SLIME = -4;
|
||||
float CONTENT_LAVA = -5;
|
||||
float CONTENT_SKY = -6;
|
||||
|
||||
float STATE_RAISED = 0;
|
||||
float STATE_LOWERED = 1;
|
||||
float STATE_UP = 2;
|
||||
float STATE_DOWN = 3;
|
||||
|
||||
vector VEC_ORIGIN = '0 0 0';
|
||||
vector VEC_HULL_MIN = '-16 -16 -24';
|
||||
vector VEC_HULL_MAX = '16 16 32';
|
||||
|
||||
vector VEC_HULL2_MIN = '-32 -32 -24';
|
||||
vector VEC_HULL2_MAX = '32 32 64';
|
||||
|
||||
// protocol bytes
|
||||
#define SVC_TEMP_ENTITY 1
|
||||
#define SVC_LAYOUT 2
|
||||
#define SVC_INVENTORY 3
|
||||
|
||||
enum
|
||||
{
|
||||
EV_NONE,
|
||||
EV_ITEM_RESPAWN,
|
||||
EV_FOOTSTEP,
|
||||
EV_FALLSHORT,
|
||||
EV_FALL,
|
||||
EV_FALLFAR,
|
||||
EV_PLAYER_TELEPORT,
|
||||
EV_OTHER_TELEPORT
|
||||
};
|
||||
|
||||
float TE_SPIKE = 0;
|
||||
float TE_SUPERSPIKE = 1;
|
||||
float TE_GUNSHOT = 2;
|
||||
float TE_EXPLOSION = 3;
|
||||
float TE_TAREXPLOSION = 4;
|
||||
float TE_LIGHTNING1 = 5;
|
||||
float TE_LIGHTNING2 = 6;
|
||||
float TE_WIZSPIKE = 7;
|
||||
float TE_KNIGHTSPIKE = 8;
|
||||
float TE_LIGHTNING3 = 9;
|
||||
float TE_LAVASPLASH = 10;
|
||||
float TE_TELEPORT = 11;
|
||||
|
||||
// sound channels
|
||||
// channel 0 never willingly overrides
|
||||
// other channels (1-7) allways override a playing sound on that channel
|
||||
float CHAN_AUTO = 0;
|
||||
float CHAN_WEAPON = 1;
|
||||
float CHAN_VOICE = 2;
|
||||
float CHAN_ITEM = 3;
|
||||
float CHAN_BODY = 4;
|
||||
|
||||
float ATTN_NONE = 0;
|
||||
float ATTN_NORM = 1;
|
||||
float ATTN_IDLE = 2;
|
||||
float ATTN_STATIC = 3;
|
||||
|
||||
// update types
|
||||
|
||||
float UPDATE_GENERAL = 0;
|
||||
float UPDATE_STATIC = 1;
|
||||
float UPDATE_BINARY = 2;
|
||||
float UPDATE_TEMP = 3;
|
||||
|
||||
// entity effects
|
||||
|
||||
float EF_TELEPORT = 1;
|
||||
float EF_ROTATE = 2;
|
||||
|
||||
float AS_STRAIGHT = 1;
|
||||
float AS_SLIDING = 2;
|
||||
float AS_MELEE = 3;
|
||||
float AS_MISSILE = 4;
|
||||
|
||||
void() SUB_Null = {};
|
||||
void() SUB_Null2 = {};
|
||||
|
||||
// Quake assumes these are defined.
|
||||
entity activator;
|
||||
string string_null; // null string, nothing should be held here
|
||||
|
||||
.string wad, map, landmark;
|
||||
.float worldtype, delay, wait, lip, light_lev, speed, style, skill;
|
||||
.string killtarget;
|
||||
.vector pos1, pos2, mangle;
|
||||
|
||||
void() SUB_Remove = {remove(pev);};
|
||||
// End
|
||||
|
||||
// Damage.qc
|
||||
entity damage_attacker;
|
||||
.float pain_finished, air_finished, dmg, dmgtime;
|
||||
|
||||
//ChaseCAm
|
||||
.vector camview;
|
||||
.float aflag;
|
||||
.entity trigger_field;
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
+------+
|
||||
|Dummys|
|
||||
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| This file contains remove(pev); statements for entities not yet coded. |
|
||||
| This avoids Quake spewing out pages and pages of error messages when |
|
||||
| loading maps. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
// General Junk
|
||||
|
||||
void() event_lightning = {remove(pev);};
|
||||
void() misc_fireball = {remove(pev);};
|
||||
void() misc_explobox2 = {remove(pev);};
|
||||
void() trap_spikeshooter = {remove(pev);};
|
||||
void() trap_shooter = {remove(pev);};
|
||||
void() func_bossgate = {remove(pev);};
|
||||
void() func_episodegate = {remove(pev);};
|
||||
//void() func_illusionary = {remove(pev);};
|
||||
//void() func_train = {remove(pev);};
|
||||
//void() func_button = {remove(pev);};
|
||||
//void() func_door = {remove(pev);};
|
||||
void() func_door_secret = {remove(pev);};
|
||||
void() func_plat = {remove(pev);};
|
||||
void() info_intermission = {remove(pev);};
|
||||
void() info_null = {remove(pev);};
|
||||
//void() info_teleport_destination= {remove(pev);};
|
||||
//void() path_corner = {remove(pev);};
|
||||
|
||||
// Triggers
|
||||
//void() trigger_relay = {remove(pev);};
|
||||
//void() trigger_multiple = {remove(pev);};
|
||||
//void() trigger_once = {remove(pev);};
|
||||
//void() trigger_changelevel = {remove(pev);};
|
||||
//void() trigger_counter = {remove(pev);};
|
||||
//void() trigger_teleport = {remove(pev);};
|
||||
//void() trigger_secret = {remove(pev);};
|
||||
//void() trigger_setskill = {remove(pev);};
|
||||
void() trigger_monsterjump = {remove(pev);};
|
||||
void() trigger_onlyregistered = {remove(pev);};
|
||||
//void() trigger_push = {remove(pev);};
|
||||
//void() trigger_hurt = {remove(pev);};
|
||||
|
||||
// Player Starts
|
||||
void() info_player_start = {};
|
||||
//void() info_player_start2 = {};
|
||||
void() info_player_deathmatch = {};
|
||||
void() info_player_coop = {};
|
||||
void() info_target = {};
|
||||
|
||||
// Weapons
|
||||
void() weapon_supershotgun = {remove(pev);};
|
||||
void() weapon_nailgun = {remove(pev);};
|
||||
void() weapon_supernailgun = {remove(pev);};
|
||||
void() weapon_grenadelauncher = {remove(pev);};
|
||||
void() weapon_rocketlauncher = {remove(pev);};
|
||||
void() weapon_lightning = {remove(pev);};
|
||||
|
||||
// Monsters
|
||||
void() monster_enforcer = {remove(pev);};
|
||||
void() monster_ogre = {remove(pev);};
|
||||
void() monster_demon1 = {remove(pev);};
|
||||
void() monster_shambler = {remove(pev);};
|
||||
void() monster_knight = {remove(pev);};
|
||||
void() monster_army = {remove(pev);};
|
||||
void() monster_wizard = {remove(pev);};
|
||||
void() monster_dog = {remove(pev);};
|
||||
void() monster_zombie = {remove(pev);};
|
||||
void() monster_tarbaby = {remove(pev);};
|
||||
void() monster_hell_knight = {remove(pev);};
|
||||
void() monster_fish = {remove(pev);};
|
||||
void() monster_shalrath = {remove(pev);};
|
||||
void() monster_oldone = {remove(pev);};
|
||||
|
||||
void() item_health = {remove(pev);};
|
||||
void() item_megahealth_rot = {remove(pev);};
|
||||
void() item_armor1 = {remove(pev);};
|
||||
void() item_armor2 = {remove(pev);};
|
||||
void() item_armorInv = {remove(pev);};
|
||||
void() item_shells = {remove(pev);};
|
||||
void() item_spikes = {remove(pev);};
|
||||
void() item_rockets = {remove(pev);};
|
||||
void() item_cells = {remove(pev);};
|
||||
void() item_key1 = {remove(pev);};
|
||||
void() item_key2 = {remove(pev);};
|
||||
void() item_artifact_invulnerability = {remove(pev);};
|
||||
void() item_artifact_envirosuit = {remove(pev);};
|
||||
void() item_artifact_invisibility = {remove(pev);};
|
||||
void() item_artifact_super_damage = {remove(pev);};
|
||||
|
||||
void barrel_touch( void )
|
||||
{
|
||||
float ratio;
|
||||
vector v;
|
||||
|
||||
// only players can move barrel
|
||||
if (!(other->flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
ratio = (float)other->mass / (float)pev->mass;
|
||||
v = pev->origin - other->origin;
|
||||
walkmove(vectoyaw(v), 20 * ratio * frametime);
|
||||
}
|
||||
|
||||
void barrel_spawn(string netname1, string model1, string deathmessage, float damage)
|
||||
{
|
||||
local float oldz;
|
||||
|
||||
precache_model (model1);
|
||||
precache_sound ("weapons/r_exp3.wav");
|
||||
|
||||
if (!pev->dmg) pev->dmg = damage;
|
||||
pev->netname = netname1;
|
||||
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
setmodel (pev, model1);
|
||||
pev->health = 20;
|
||||
pev->th_die = SUB_Null;
|
||||
pev->takedamage = DAMAGE_AIM;
|
||||
pev->think = SUB_Null;
|
||||
pev->nextthink = -1;
|
||||
pev->touch = barrel_touch;
|
||||
pev->flags = 0;
|
||||
if(!pev->mass) pev->mass = 25;
|
||||
|
||||
pev->origin_z = pev->origin_z + 2;
|
||||
oldz = pev->origin_z;
|
||||
|
||||
droptofloor();
|
||||
|
||||
if (oldz - pev->origin_z > 250)
|
||||
{
|
||||
MsgWarn ("explosive box fell out of level at", vtoa(pev->origin), "\n" );
|
||||
remove(pev);
|
||||
}
|
||||
}
|
||||
|
||||
void() misc_explobox =
|
||||
{
|
||||
barrel_spawn("Large exploding box", "models/barrel2.mdl", " was blown up by an explosive box", 750);
|
||||
};
|
||||
|
||||
void misc_physbox ( void )
|
||||
{
|
||||
precache_model ("models/box2.mdl");
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_BOX;
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, "models/box2.mdl");
|
||||
}
|
||||
|
||||
void misc_barrel( void )
|
||||
{
|
||||
string name = "models/barrel2.mdl";
|
||||
|
||||
precache_model( name );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_CYLINDER; //test
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, name );
|
||||
}
|
||||
|
||||
void misc_sphere( void )
|
||||
{
|
||||
string name = "models/nexplode.mdl";
|
||||
|
||||
precache_model( name );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_SPHERE; //test
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, name );
|
||||
}
|
||||
|
||||
void item_healthkit( void )
|
||||
{
|
||||
pev->model = "models/w_medkit.mdl";
|
||||
|
||||
precache_model( pev->model );
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_MESH;
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, pev->model );
|
||||
}
|
||||
|
||||
void env_sprite( void )
|
||||
{
|
||||
precache_model ("sprites/explode01.spr");
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
setmodel (pev, "sprites/explode01.spr");
|
||||
pev->frame = 0;
|
||||
}
|
||||
|
||||
void walk_sprite( void )
|
||||
{
|
||||
pev->frame++;
|
||||
if(pev->frame > 3) pev->frame = 0;
|
||||
pev->nextthink = time + 0.1;
|
||||
makevectors( pev->angles );
|
||||
pev->velocity = v_forward * 60;
|
||||
}
|
||||
|
||||
void env_monster( void )
|
||||
{
|
||||
precache_model ("sprites/boss.spr");
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
setmodel (pev, "sprites/boss.spr");
|
||||
|
||||
pev->nextthink = time;
|
||||
pev->think = walk_sprite;
|
||||
pev->frame = 0;
|
||||
}
|
||||
|
||||
void func_physbox( void )
|
||||
{
|
||||
pev->owner = pev;
|
||||
pev->solid = SOLID_MESH;
|
||||
pev->movetype = MOVETYPE_PHYSIC;
|
||||
setmodel (pev, pev->model );
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
.float count;
|
||||
.float style;
|
||||
|
||||
void use_areaportal( void )
|
||||
{
|
||||
pev->count = 1; // toggle state
|
||||
areaportal_state( pev->style, pev->count);
|
||||
}
|
||||
|
||||
/*QUAKED func_areaportal (0 0 0) ?
|
||||
|
||||
This is a non-visible object that divides the world into
|
||||
areas that are seperated when this portal is not activated.
|
||||
Usually enclosed in the middle of a door.
|
||||
*/
|
||||
void func_areaportal( void )
|
||||
{
|
||||
pev->use = use_areaportal;
|
||||
pev->count = 0; // always start closed;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
FUNC_BUTTON();
|
||||
|
||||
Description;
|
||||
Points func_button to the unified func_mover(); code.
|
||||
*/
|
||||
|
||||
void() func_button =
|
||||
{
|
||||
func_mover();
|
||||
pev->classname = "button";
|
||||
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
FUNC_DOOR();
|
||||
|
||||
Description;
|
||||
Points func_door to the unified func_mover(); code.
|
||||
*/
|
||||
|
||||
void() func_door =
|
||||
{
|
||||
func_mover();
|
||||
pev->classname = "door";
|
||||
};
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
+====================
|
||||
|MOVERS.QC
|
||||
+--------
|
||||
|Description;
|
||||
+------------
|
||||
|This file handles movers in BaseQC.
|
||||
+----------------------------------
|
||||
|What each void() does;
|
||||
+----------------------
|
||||
|
||||
This is a unified door_button function...
|
||||
|
||||
FUNC_MOVER(); This is the spawning function for movers;
|
||||
|
||||
FUNC_MOVER_TOUCH(); Called when our mover is touched by something;
|
||||
Works out whether a player is touching it.
|
||||
Then sets up next think function to happen in 0.1 secs;
|
||||
Makes mover un touchable;
|
||||
FUNC_MOVER_THINK(); Decides whether mover is open or closed;
|
||||
Then moves mover appropiately;
|
||||
|
||||
FUNC_MOVER_MOVE(); Called upon our mover wishing to move;
|
||||
Works out maths of moving mover to destination;
|
||||
Sets a think for when journey is completed;
|
||||
|
||||
FUNC_MOVER_STOP(); Called when our mover wishes to stop;
|
||||
Especially if i want to return;
|
||||
|
||||
FUNC_MOVER_STOP_DEAD(): " "
|
||||
This one just stops it dead with no return;
|
||||
|
||||
|
||||
FUNC_MOVER_USE(); Called when our mover is targeted by IEM_usetargets;
|
||||
Basically does the same as touch function but fakes it;
|
||||
|
||||
FUNC_MOVER_BLOCKED(): Called when our mover is blocked by an entity;
|
||||
Hurts whatever is blocking it and goes back to where it was coming from;
|
||||
|
||||
FUNC_MOVER_DIE(); Called upon our movers death(when health is zero);
|
||||
Toggles mover upon death;
|
||||
|
||||
FUNC_MOVER_FIRE(); allows me to have a target that is triggered after movers delay..
|
||||
|
||||
=====================
|
||||
*/
|
||||
|
||||
//DEFINITIONS FOR FILE;
|
||||
|
||||
void() func_mover_think; //from movers.QC
|
||||
|
||||
.vector dest;
|
||||
.string target_dest;
|
||||
|
||||
//Floats below this line are used in the mapping .fgd file and inputted by the mapper. (FLAGS)
|
||||
|
||||
float MOVER_START_OPEN = 1;
|
||||
float MOVER_DONT_LINK = 4;
|
||||
float MOVER_GOLD_KEY = 8;
|
||||
float MOVER_SILVER_KEY = 16;
|
||||
float MOVER_TOGGLE = 32;
|
||||
|
||||
//END DEFS;
|
||||
|
||||
void() func_mover_stop_general =
|
||||
{
|
||||
pev->velocity = '0 0 0'; //Stop me!
|
||||
pev->touched = FALSE; //Touch me!
|
||||
sound (pev, CHAN_VOICE, pev->noise1, 1, ATTN_NORM); //make a sound!
|
||||
setorigin(pev, pev->dest); //set my origin exactly to dest.
|
||||
};
|
||||
|
||||
void() func_mover_stop =
|
||||
{
|
||||
func_mover_stop_general();
|
||||
|
||||
if(pev->wait >= 0) //Return upon wait over!
|
||||
{
|
||||
pev->think = func_mover_think;
|
||||
pev->nextthink = pev->ltime + pev->wait;
|
||||
}
|
||||
};
|
||||
|
||||
void() func_mover_stop_dead =
|
||||
{
|
||||
entity t;
|
||||
|
||||
// lookup all areaportals
|
||||
t = find(world, targetname, pev->target);
|
||||
while(t)
|
||||
{
|
||||
if(t->classname == "func_areaportal")
|
||||
areaportal_state( t->style, FALSE );
|
||||
t = find(t, targetname, pev->target);
|
||||
}
|
||||
|
||||
func_mover_stop_general();
|
||||
};
|
||||
|
||||
void() func_mover_blocked =
|
||||
{
|
||||
T_Damage (other, pev, pev, pev->dmg); //Do my damage;
|
||||
|
||||
func_mover_think(); //Return;
|
||||
};
|
||||
|
||||
void(vector destination, float movespeed, void() dest_func) func_mover_move =
|
||||
{
|
||||
local vector path;
|
||||
local float pathlength, traveltime;
|
||||
|
||||
//Calculate movement vector
|
||||
path = destination - pev->origin;
|
||||
|
||||
//Calculate length of movement vector;
|
||||
pathlength = veclength(path);
|
||||
|
||||
//Divide length of movement vector by desired movespeed to get travel time.
|
||||
traveltime = (pathlength) / (movespeed);
|
||||
|
||||
// scale the destdelta vector by the time spent traveling to get velocity
|
||||
pev->velocity = path * (1/traveltime);
|
||||
|
||||
if(traveltime < 0.1 || pev->origin == destination)
|
||||
{
|
||||
pev->think = dest_func;
|
||||
pev->nextthink = pev->ltime + 0.1;
|
||||
pev->dest = destination;
|
||||
return;
|
||||
}
|
||||
|
||||
pev->think = dest_func;
|
||||
pev->nextthink = pev->ltime + traveltime;
|
||||
|
||||
pev->dest = destination;
|
||||
};
|
||||
|
||||
void() func_mover_think =
|
||||
{
|
||||
local vector a;
|
||||
local void() b;
|
||||
|
||||
if(pev->state == STATE_OPEN) //Am i open?
|
||||
{
|
||||
pev->state = STATE_CLOSED; //Now im closing!
|
||||
a = pev->pos1; //My first position!
|
||||
b = func_mover_stop_dead; //Stopping func to use!
|
||||
}
|
||||
else if (pev->state == STATE_CLOSED)
|
||||
{
|
||||
pev->state = STATE_OPEN;
|
||||
a = pev->pos2;
|
||||
|
||||
if(pev->spawnflags & MOVER_TOGGLE) //Am i toggable?
|
||||
b = func_mover_stop_dead; //if yes.. stop me dead.
|
||||
else
|
||||
b = func_mover_stop; //if no.. return me;
|
||||
}
|
||||
|
||||
func_mover_move(a, pev->speed, b); //Loaded move function;
|
||||
|
||||
sound (pev, CHAN_VOICE, pev->noise2, 1, ATTN_NORM);
|
||||
};
|
||||
|
||||
void() func_mover_fire =
|
||||
{
|
||||
IEM_usetarget(); //Use my targets;
|
||||
|
||||
func_mover_think(); //Run think function straight away!
|
||||
};
|
||||
|
||||
void() func_mover_touch =
|
||||
{
|
||||
if(other.classname != "player") //Are you a player?
|
||||
return;
|
||||
if(other == world) //Are you the world?
|
||||
return;
|
||||
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
pev->triggerer = other;
|
||||
|
||||
pev->touched = TRUE; //stop touching me!
|
||||
pev->think = func_mover_fire; //set me next think
|
||||
pev->nextthink = pev->ltime + pev->delay; //set it so it happens in 0.1 secs from now.
|
||||
}
|
||||
};
|
||||
|
||||
void func_mover_null ( void )
|
||||
{
|
||||
// null touching function
|
||||
}
|
||||
|
||||
void() func_mover_use =
|
||||
{
|
||||
if(pev->message)
|
||||
centerprint(pev->triggerer, pev->message);
|
||||
|
||||
pev->touched = TRUE; //Fake touch!
|
||||
|
||||
pev->think = func_mover_fire; //set me next think!
|
||||
pev->nextthink = pev->ltime + pev->delay; //in delay
|
||||
};
|
||||
|
||||
void() func_mover_die =
|
||||
{
|
||||
pev->health = pev->max_health; //reset health on death;
|
||||
|
||||
pev->takedamage = DAMAGE_YES; //These two are set to no and null in killed function;
|
||||
pev->touch = func_mover_touch; //[Damage.QC]
|
||||
};
|
||||
|
||||
void() func_mover =
|
||||
{
|
||||
func_setup(); //Sets up some basic func properties;[funcs.qc]
|
||||
pev->classname = "mover";
|
||||
|
||||
if(pev->health)
|
||||
{
|
||||
pev->max_health = pev->health;
|
||||
pev->takedamage = DAMAGE_YES;
|
||||
}
|
||||
|
||||
pev->blocked = func_mover_blocked;
|
||||
pev->use = func_mover_use;
|
||||
pev->th_die = func_mover_die;
|
||||
|
||||
if(!pev->targetname) pev->touch = func_mover_touch;
|
||||
else pev->touch = func_mover_null;
|
||||
|
||||
//func_mover; DEFAULTS;
|
||||
if (!pev->speed)
|
||||
pev->speed = 100;
|
||||
if (!pev->wait)
|
||||
pev->wait = 3;
|
||||
if (!pev->lip)
|
||||
pev->lip = 8;
|
||||
if (!pev->dmg)
|
||||
pev->dmg = 2;
|
||||
|
||||
if(!pev->delay)
|
||||
pev->delay = 0.1; //stuff with 0 delay dont move! (or work ;) )
|
||||
|
||||
|
||||
//func_mover; positions; .pos1 == closed; .pos2 == open;
|
||||
|
||||
pev->pos1 = pev->origin;
|
||||
pev->pos2 = pev->pos1 + pev->movedir*(fabs(pev->movedir*pev->size) - pev->lip);
|
||||
|
||||
if(pev->spawnflags & MOVER_START_OPEN)
|
||||
{
|
||||
pev->state = STATE_OPEN;
|
||||
setorigin(pev, pev->pos2);
|
||||
}
|
||||
else
|
||||
pev->state = STATE_CLOSED;
|
||||
};
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
FUNC_PATH_CORNER();
|
||||
|
||||
Description;
|
||||
This is the spawning function to the map entity 'func_path_corner'
|
||||
Currently only trains use this to tell their next stop position;
|
||||
*/
|
||||
|
||||
void() path_corner =
|
||||
{
|
||||
if (!pev->targetname)
|
||||
Error ("monster_movetarget: no targetname\n");
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
setsize (pev, '-8 -8 -8', '8 8 8');
|
||||
};
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
+==================+
|
||||
|FUNC_TRAIN.QC |
|
||||
+==================+=====================================================================+
|
||||
|Description;
|
||||
|This file handles the func_train map entity;
|
||||
+========================================================================================+
|
||||
*/
|
||||
|
||||
//DEFINITIONS FOR FILE;
|
||||
void() func_train_next; //[func_train.qc]
|
||||
//END DEFS;
|
||||
|
||||
/*
|
||||
FUNC_TRAIN_WAIT();
|
||||
|
||||
Desciption;
|
||||
Called after the train has reached its target.
|
||||
If the train has the 'wait' field set on its spawn it waits the alloted time then finds its next target.
|
||||
*/
|
||||
|
||||
void() func_train_wait =
|
||||
{
|
||||
if (pev->wait)
|
||||
{
|
||||
pev->nextthink = pev->ltime + pev->wait;
|
||||
//sound (pev, CHAN_VOICE, pev->noise, 1, ATTN_NORM);
|
||||
}
|
||||
else
|
||||
pev->nextthink = pev->ltime + 0.1;
|
||||
|
||||
pev->think = func_train_next;
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_TRAIN_NEXT();
|
||||
|
||||
Desciption;
|
||||
Finds the trains next target;
|
||||
Then sets it moving in its direction;
|
||||
*/
|
||||
|
||||
void() func_train_next =
|
||||
{
|
||||
local entity next_targ;
|
||||
|
||||
next_targ = find (world, targetname, pev->target);
|
||||
|
||||
pev->target = next_targ->target;
|
||||
|
||||
if (!pev->target)
|
||||
Error ("train_next: no next target\n");
|
||||
|
||||
if (next_targ.wait)
|
||||
pev->wait = next_targ.wait;
|
||||
else
|
||||
pev->wait = 0;
|
||||
|
||||
//sound (pev, CHAN_VOICE, pev->noise1, 1, ATTN_NORM);
|
||||
|
||||
func_mover_move (next_targ.origin - pev->mins, pev->speed, func_train_wait);
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_TRAIN_FIND();
|
||||
|
||||
Desciption;
|
||||
Called on spawning, this function finds the trains first target and sets the trains origin and hence starting position to it. Then calls FUNC_TRAIN_NEXT();
|
||||
*/
|
||||
|
||||
void() func_train_find =
|
||||
{
|
||||
local entity next_targ;
|
||||
|
||||
next_targ = find (world, targetname, pev->target);
|
||||
|
||||
pev->target = next_targ.target;
|
||||
|
||||
setorigin (pev, next_targ.origin - pev->mins);
|
||||
|
||||
if (!pev->targetname) // not triggered, so start immediately
|
||||
{
|
||||
pev->nextthink = pev->ltime + 0.1;
|
||||
pev->think = func_train_next;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_TRAIN_USE();
|
||||
|
||||
Desciption;
|
||||
The use function for trains;
|
||||
If targeted the train starts moving then cannot be used/targetted again;
|
||||
*/
|
||||
|
||||
void() func_train_use =
|
||||
{
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
pev->touched = TRUE;
|
||||
pev->nextthink = pev->ltime + 0.1;
|
||||
pev->think = func_train_next;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_TRAIN();
|
||||
|
||||
Desciption;
|
||||
The spawning function for the map entity func_train;
|
||||
*/
|
||||
|
||||
void() func_train =
|
||||
{
|
||||
func_setup();
|
||||
|
||||
setsize (pev, pev->mins , pev->maxs);
|
||||
|
||||
pev->classname = "train";
|
||||
|
||||
//func_train defaults;
|
||||
if (!pev->speed)
|
||||
pev->speed = 100;
|
||||
if (!pev->target)
|
||||
Error ("func_train without a target\n");
|
||||
if (!pev->dmg)
|
||||
pev->dmg = 2;
|
||||
|
||||
pev->nextthink = pev->ltime + 0.1;
|
||||
pev->think = func_train_find;
|
||||
};
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
+==========+
|
||||
|FUNCS.QC|
|
||||
+==========+=============================================================================+
|
||||
|Description;
|
||||
|Handles our basic func_setup stuff, aswell as containing base defintions for the 'func_' class;
|
||||
+========================================================================================+
|
||||
*/
|
||||
|
||||
//DEFINITIONS FOR FILE;
|
||||
.float state;
|
||||
.float used;
|
||||
|
||||
float STATE_OPEN = 1;
|
||||
float STATE_CLOSED = 0;
|
||||
//END DEFS;
|
||||
|
||||
/*
|
||||
FUNC_SETUP();
|
||||
|
||||
Description;
|
||||
This function is used by ALL our map func_'s. It sets up the func_'s basic and most common properties;
|
||||
With the only exception being 'pev->movetype = MOVETYPE_PUSH;' which usually gets set to something else
|
||||
in the func_'s spawning function after this has been called. It's included because out of the func_'s we have so far
|
||||
more require this field to be set to that than any other.
|
||||
*/
|
||||
void() func_setup =
|
||||
{
|
||||
SetMovedir ();
|
||||
|
||||
pev->solid = SOLID_BSP;
|
||||
pev->movetype = MOVETYPE_PUSH;
|
||||
|
||||
setorigin (pev, pev->origin);
|
||||
setmodel (pev, pev->model);
|
||||
setsize (pev, pev->mins , pev->maxs);
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_ILLUSIONARY();
|
||||
|
||||
Description;
|
||||
This is the spawning func for the map placeable 'func_illusionary'.
|
||||
It is to allow our mapper to place what looks like a wall in the map, but which the player can walk through.
|
||||
*/
|
||||
|
||||
void() func_illusionary =
|
||||
{
|
||||
func_setup();
|
||||
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
};
|
||||
|
||||
void func_wall_touch ( void )
|
||||
{
|
||||
// null touching function
|
||||
}
|
||||
|
||||
void animate_wall( void )
|
||||
{
|
||||
pev->frame++;
|
||||
if(pev->frame > 7) pev->frame = 0;
|
||||
pev->nextthink = time + 0.1;
|
||||
}
|
||||
|
||||
void() func_wall =
|
||||
{
|
||||
func_setup();
|
||||
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
|
||||
pev->nextthink = time + 1.0;
|
||||
pev->think = animate_wall;
|
||||
pev->touch = func_wall_touch;
|
||||
};
|
||||
|
||||
/*
|
||||
FUNC_PLACE_MODEL();
|
||||
|
||||
Description;
|
||||
This is the spawning func for the map placeable 'func_place_model'.
|
||||
Quite simply it allows our mapper to place custom models within the map.
|
||||
|
||||
Credits;
|
||||
Jon Eriksson - For the idea and base code!
|
||||
*/
|
||||
|
||||
void() func_place_model =
|
||||
{
|
||||
precache_model (pev->model);
|
||||
|
||||
func_setup();
|
||||
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
+--------+
|
||||
|Impulses|
|
||||
+--------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Handle and execute "Impulse" commands - as entered from console. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
|
||||
void() CheckImpulses =
|
||||
{
|
||||
if (pev->impulse == 15)
|
||||
CCam ();
|
||||
|
||||
if(pev->impulse == 10)
|
||||
{
|
||||
local string a;
|
||||
a = ftoa(pev->items);
|
||||
sprint(pev, a);
|
||||
sprint(pev, "Items Printed\n");
|
||||
}
|
||||
if(pev->impulse == 11)
|
||||
{
|
||||
pev->items = pev->items + 8;
|
||||
sprint(pev, "Items added to\{136}\n");
|
||||
}
|
||||
|
||||
if(pev->impulse == 150)
|
||||
{
|
||||
set_effect( pev, EV_PLAYER_TELEPORT );
|
||||
}
|
||||
|
||||
pev->impulse = 0; // Clear impulse list.
|
||||
};
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
+--------+
|
||||
|Internal|
|
||||
+--------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Internal Entity Management stuff for Quake. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
.float touched; //used to tell if an entity has been touched or not.
|
||||
.string name; //
|
||||
.entity triggerer;
|
||||
|
||||
void(string modelname) Precache_Set = // Precache model, and set mypev to it
|
||||
{
|
||||
precache_model(modelname);
|
||||
setmodel(pev, modelname);
|
||||
};
|
||||
|
||||
/*
|
||||
QuakeEd only writes a single float for angles (bad idea), so up and down are
|
||||
just constant angles.
|
||||
*/
|
||||
void() SetMovedir =
|
||||
{
|
||||
if (pev->angles == '0 -1 0')
|
||||
pev->movedir = '0 0 1';
|
||||
else if (pev->angles == '0 -2 0')
|
||||
pev->movedir = '0 0 -1';
|
||||
else
|
||||
{
|
||||
makevectors (pev->angles);
|
||||
pev->movedir = v_forward;
|
||||
}
|
||||
|
||||
pev->angles = '0 0 0';
|
||||
};
|
||||
|
||||
void() IEM_usetarget =
|
||||
{
|
||||
local entity t, oldpev, oldother;
|
||||
|
||||
if(pev->target)
|
||||
{
|
||||
t = find(world, targetname, pev->target);
|
||||
|
||||
while(t)
|
||||
{
|
||||
if(pev->triggerer)
|
||||
t.triggerer = pev->triggerer;
|
||||
|
||||
oldpev = pev;
|
||||
oldother = other;
|
||||
pev = t;
|
||||
|
||||
if(t.use)
|
||||
t.use();
|
||||
|
||||
pev = oldpev;
|
||||
other = oldother;
|
||||
|
||||
|
||||
t = find(t, targetname, pev->target);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
+==========+
|
||||
|ITEMS.QC|
|
||||
+==========+=============================================================================+
|
||||
|Description;
|
||||
|Handles our basic item_setup stuff, aswell as containing base defintions for the 'item_' class;
|
||||
|Also contains item respawning and pickup routines;
|
||||
+========================================================================================+
|
||||
*/
|
||||
|
||||
//DEFINITIONS FOR FILE;
|
||||
.string oldmodel;
|
||||
float ITEM_PICKUP_ONCE = 1;
|
||||
//END DEFS
|
||||
|
||||
/*
|
||||
ITEM_SETUP();
|
||||
|
||||
Description;
|
||||
All our items will call this bit of code first in their spawning functions.
|
||||
It sets up all the required and most basic item parimeters.
|
||||
*/
|
||||
|
||||
void() item_setup =
|
||||
{
|
||||
if(!pev->think) //Items should start after other solids....
|
||||
{
|
||||
pev->think = item_setup;
|
||||
pev->nextthink = time + 0.2;
|
||||
return;
|
||||
}
|
||||
|
||||
pev->oldmodel = pev->model; // so it can be restored on respawn
|
||||
|
||||
pev->solid = SOLID_TRIGGER; //Im a TRIGGER!
|
||||
pev->movetype = MOVETYPE_TOSS; //Toss me baby!... erm..
|
||||
pev->velocity = '0 0 0'; //Stop me moving!
|
||||
pev->origin_z = pev->origin_z + 6; //Raise me a bit off the floor
|
||||
};
|
||||
|
||||
/*
|
||||
IPRINT()
|
||||
|
||||
Description;
|
||||
Prints the item pickup stuff to the player
|
||||
*/
|
||||
|
||||
void(entity picker, string pickupmessage, string pickupoptional) iprint =
|
||||
{
|
||||
sprint(picker, pickupmessage);
|
||||
sprint(picker, pickupoptional);
|
||||
sprint(picker, "\n");
|
||||
};
|
||||
|
||||
/*
|
||||
ITEM_RESPAWN();
|
||||
|
||||
Description;
|
||||
Simply resets the item fields that get set in item_pickup() code.
|
||||
Makes the item pickupable again.
|
||||
*/
|
||||
|
||||
void() item_respawn =
|
||||
{
|
||||
setorigin(pev, pev->origin);
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
pev->model = pev->oldmodel;
|
||||
};
|
||||
|
||||
/*
|
||||
ITEM_PICKUP();
|
||||
|
||||
Description;
|
||||
Should get called when an item is touched by a player.
|
||||
|
||||
It makes the item FIRE/USE its target.
|
||||
Stops the item getting picked up for a while, nextthink at bottom of code.
|
||||
*/
|
||||
|
||||
void() item_pickup =
|
||||
{
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->model = string_null;
|
||||
|
||||
IEM_usetarget();
|
||||
|
||||
if(pev->spawnflags & ITEM_PICKUP_ONCE)
|
||||
return;
|
||||
|
||||
pev->think = item_respawn;
|
||||
|
||||
if(deathmatch)
|
||||
pev->nextthink = time + 20; //This ideally would be a CVAR
|
||||
};
|
||||
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
+------+
|
||||
|Lights|
|
||||
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Spawns and handles Quake's lights and torches |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
|
||||
float START_OFF = 1; // Light on/off spawnflag
|
||||
void() Light_setup; // Definition from Lights.qc
|
||||
void(string soundfile, float volume) doambient; // Definition from Ambient.qc
|
||||
|
||||
void() light = // Basic Light
|
||||
{
|
||||
Light_setup(); // Setup Light
|
||||
};
|
||||
|
||||
void() light_fluoro = // Light with hum ambient
|
||||
{
|
||||
Light_setup(); // Setup Light
|
||||
doambient("ambience/fl_hum1.wav", 0.5); // Spawn Ambient hum sound
|
||||
};
|
||||
|
||||
void() light_fluorospark = // Light with buzz ambient
|
||||
{
|
||||
Light_setup(); // Setup Light
|
||||
doambient("ambience/buzz1.wav", 0.5); // Spawn ambient buzz sound
|
||||
};
|
||||
|
||||
void() light_globe = // Light with visible globe
|
||||
{
|
||||
Precache_Set("progs/s_light.spr"); // Set model
|
||||
makestatic(pev); // Static entity. Never changes.
|
||||
};
|
||||
|
||||
void() light_torch_small_walltorch = // Light with visible wall torch
|
||||
{
|
||||
Precache_Set("progs/flame.mdl"); // Set model
|
||||
makestatic(pev); // Static entity. Never changes.
|
||||
doambient("ambience/fire1.wav", 0.5); // Spawn fire ambient sound
|
||||
};
|
||||
|
||||
void() light_flame_small_yellow = // Light with small flame & fire sound
|
||||
{
|
||||
Precache_Set("progs/flame2.mdl"); // Set model
|
||||
makestatic(pev); // Static entity. Never changes.
|
||||
doambient("ambience/fire1.wav", 0.5); // Spawn fire ambient sound
|
||||
};
|
||||
|
||||
void() light_flame_large_yellow = // Light with larger flame & fire sound
|
||||
{
|
||||
Precache_Set("progs/flame2.mdl"); // Set model
|
||||
pev->frame = 1; // Switch to second frame (large)
|
||||
makestatic(pev); // Static entity. Never changes.
|
||||
doambient("ambience/fire1.wav", 0.5); // Spawn fire ambient sound
|
||||
};
|
||||
|
||||
void() light_flame_small_white = // Light with small flame & fire sound
|
||||
{
|
||||
Precache_Set("progs/flame2.mdl"); // Set model
|
||||
makestatic(pev); // Static entity. Never changes.
|
||||
doambient("ambience/fire1.wav", 0.5); // Spawn fire ambient sound
|
||||
};
|
||||
|
||||
void() Light_setup = // Set light on or off, as per spawnflags
|
||||
{
|
||||
if (pev->style < 32) {return;} // Dont switch other styles.
|
||||
|
||||
if (pev->spawnflags & START_OFF)
|
||||
lightstyle(pev->style, "a"); // If light starts off, set it off.
|
||||
else
|
||||
lightstyle(pev->style, "m"); // If light starts ON, turn in ON. Simple :)
|
||||
};
|
||||
|
||||
void() LightStyles_setup =
|
||||
{
|
||||
// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
|
||||
|
||||
lightstyle(0,"m"); // Style 0: Normal
|
||||
lightstyle(1,"mmnmmommommnonmmonqnmmo"); // Style 1: Flicker
|
||||
// Style 2: Slow Strong
|
||||
// Pulse
|
||||
lightstyle(2,"abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
|
||||
lightstyle(3,"mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); // Style 3: Candle
|
||||
lightstyle(4,"mamamamamama"); // Style 4: Fast Strobe
|
||||
lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); // Style 5: Gentle Pulse
|
||||
lightstyle(6,"nmonqnmomnmomomno"); // Style 6: Flicker 2
|
||||
lightstyle(7,"mmmaaaabcdefgmmmmaaaammmaamm"); // Style 7: Candle 2
|
||||
// Style 8: Candle 3
|
||||
lightstyle(8,"mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
|
||||
lightstyle(9,"aaaaaaaazzzzzzzz"); // Style 9: Slow Strobe
|
||||
lightstyle(10,"mmamammmmammamamaaamammma"); // Style 10: Fluro
|
||||
// Style 11: Slow Pulse
|
||||
// (no black)
|
||||
lightstyle(11,"abcdefghijklmnopqrrqponmlkjihgfedcba");
|
||||
};
|
||||
|
147
pr_server/main.c
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
+----+
|
||||
|Main|
|
||||
+----+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch Http://www.admdev.com/scratch |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Contains some 'base' subroutines. As a general rule nothing in this file |
|
||||
| does much, except to setup basic variables and entities. |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
|
||||
//INCLUDES;
|
||||
|
||||
void() LightStyles_setup; // Entities/Lights.QC
|
||||
void() precaches;
|
||||
|
||||
//END INCLUDES;
|
||||
|
||||
void() main = {};
|
||||
|
||||
/*
|
||||
================
|
||||
|SETNEWPARMS():|
|
||||
=================================================================================
|
||||
Description:
|
||||
This function is called to set up new player info.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() SetNewParms = //Sets up start game parms
|
||||
{
|
||||
pev->items = 10;
|
||||
pev->health = 100;
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
|SETCHANGEPARMS():|
|
||||
=================================================================================
|
||||
Description:
|
||||
|
||||
This function is called when the player hits a change level. Stores player info for
|
||||
loading upon next level.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() SetChangeParms = //called on changelevel; command
|
||||
{
|
||||
if (pev->health <= 0)
|
||||
{
|
||||
SetNewParms();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
==================
|
||||
|GETLEVELPARMS():|
|
||||
=================================================================================
|
||||
Description:
|
||||
|
||||
This function is called by 'PUTCLIENTINSERVER(); in (CLIENT.QC)' and carries over
|
||||
information in between level loads, or sets new parms at start map.
|
||||
|
||||
Information stored in .parms which are the ONLY floats to be stored in memory in
|
||||
between level loads.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() GetLevelParms =
|
||||
{
|
||||
if (world.model == "maps/start.bsp")
|
||||
SetNewParms (); // take away all stuff on starting new episode
|
||||
};
|
||||
|
||||
|
||||
void() StartFrame = {};
|
||||
void() EndFrame = {};
|
||||
|
||||
// hud program string
|
||||
string single_statusbar =
|
||||
"yb -24 xv 0 hnum xv 50 x 0 y 0 pic STAT_HEALTH_ICON \
|
||||
if 2 { xv 100 anum xv 150 pic STAT_AMMO_ICON } \
|
||||
if 4 { xv 200 rnum xv 250 pic 4 } \
|
||||
if 6 { xv 296 pic 6 } yb -50 \
|
||||
if 7 { xv 0 pic 7 xv 26 yb -42 stat_string 8 yb -50 } \
|
||||
if 9 { xv 230 num 4 10 xv 296 pic 9 } \
|
||||
if 11 { xv 148 pic 11 } \
|
||||
if 22 { yb -90 xv 128 pic 22 } \
|
||||
if 23 { yv 0 xv 0 pic 23 }";
|
||||
|
||||
/*
|
||||
===============
|
||||
|WORLDSPAWN():|
|
||||
=================================================================================
|
||||
Description:
|
||||
This function is called when the world spawns.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void worldspawn( void )
|
||||
{
|
||||
MsgWarn("world spawned\n");
|
||||
precaches();
|
||||
LightStyles_setup();
|
||||
|
||||
// CS_MAXCLIENTS already sended by engine
|
||||
configstring (CS_STATUSBAR, "Hud_Single" );
|
||||
configstring (CS_SKY, "sky" );
|
||||
configstring (CS_SKYROTATE, ftoa( pev->speed )); // rotate speed
|
||||
configstring (CS_SKYAXIS, vtoa( pev->angles )); // rotate axis
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
|PRECACHES():|
|
||||
=================================================================================
|
||||
Description:
|
||||
Precaches for the game.
|
||||
=================================================================================
|
||||
*/
|
||||
|
||||
void() precaches =
|
||||
{
|
||||
precache_model ("models/player.mdl");
|
||||
precache_model("models/supp1.mdl");
|
||||
|
||||
// pain sounds
|
||||
precache_sound ("player/drown1.wav"); // drowning pain
|
||||
precache_sound ("player/drown2.wav"); // drowning pain
|
||||
precache_sound ("player/lburn1.wav"); // slime/lava burn
|
||||
precache_sound ("player/lburn2.wav"); // slime/lava burn
|
||||
precache_sound ("player/pain1.wav");
|
||||
precache_sound ("player/pain2.wav");
|
||||
precache_sound ("player/pain3.wav");
|
||||
precache_sound ("player/pain4.wav");
|
||||
precache_sound ("player/pain5.wav");
|
||||
precache_sound ("player/pain6.wav");
|
||||
|
||||
// death sounds
|
||||
precache_sound ("player/h2odeath.wav"); // drowning death
|
||||
precache_sound ("player/death1.wav");
|
||||
precache_sound ("player/death2.wav");
|
||||
precache_sound ("player/death3.wav");
|
||||
precache_sound ("player/death4.wav");
|
||||
precache_sound ("player/death5.wav");
|
||||
};
|
|
@ -1,252 +0,0 @@
|
|||
/*
|
||||
+------+
|
||||
|Player|
|
||||
+------+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Scratch http://www.inside3d.com/qctut/scratch.shtml |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
| Handle player animations and other misc player functions |
|
||||
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
|
||||
*/
|
||||
.float anim_time; // used for animation timing
|
||||
.float anim_end; // end frame for current scene
|
||||
.float anim_priority; // prioritize animations
|
||||
.float anim_run; // running or not
|
||||
|
||||
// client_t->anim_priority
|
||||
float ANIM_BASIC = 0; // stand / run
|
||||
float ANIM_PAIN = 1;
|
||||
float ANIM_ATTACK = 2;
|
||||
float ANIM_DEATH = 3;
|
||||
|
||||
|
||||
// running
|
||||
|
||||
$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
|
||||
$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
|
||||
|
||||
// standing
|
||||
$frame stand1 stand2 stand3 stand4 stand5
|
||||
$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
|
||||
$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
|
||||
|
||||
// pain
|
||||
$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
|
||||
$frame pain1 pain2 pain3 pain4 pain5 pain6
|
||||
|
||||
// death
|
||||
$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
|
||||
$frame axdeth7 axdeth8 axdeth9
|
||||
$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
|
||||
$frame deatha9 deatha10 deatha11
|
||||
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
|
||||
$frame deathb9
|
||||
$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
|
||||
$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
|
||||
$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
|
||||
$frame deathd8 deathd9
|
||||
$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
|
||||
$frame deathe8 deathe9
|
||||
|
||||
// attacks
|
||||
$frame nailatt1 nailatt2
|
||||
$frame light1 light2
|
||||
$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
|
||||
$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
|
||||
$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
|
||||
$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
|
||||
$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
|
||||
$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
|
||||
|
||||
|
||||
void () SetClientFrame =
|
||||
{
|
||||
// note: call whenever weapon frames are called!
|
||||
if (pev->anim_time > time)
|
||||
return; //don't call every frame, if it is the animations will play too fast
|
||||
pev->anim_time = time + 0.1;
|
||||
|
||||
local float anim_change, run;
|
||||
|
||||
if (pev->velocity_x || pev->velocity_y)
|
||||
run = TRUE;
|
||||
else
|
||||
run = FALSE;
|
||||
|
||||
anim_change = FALSE;
|
||||
|
||||
// check for stop/go and animation transitions
|
||||
if (run != pev->anim_run && pev->anim_priority == ANIM_BASIC)
|
||||
anim_change = TRUE;
|
||||
|
||||
if (anim_change != TRUE)
|
||||
{
|
||||
if (pev->frame < pev->anim_end)
|
||||
{ // continue an animation
|
||||
pev->frame = pev->frame + 1;
|
||||
return;
|
||||
}
|
||||
if (pev->anim_priority == ANIM_DEATH)
|
||||
{
|
||||
if (pev->deadflag == DEAD_DYING)
|
||||
{
|
||||
pev->nextthink = -1;
|
||||
pev->deadflag = DEAD_DEAD;
|
||||
}
|
||||
return; // stay there
|
||||
}
|
||||
}
|
||||
|
||||
// return to either a running or standing frame
|
||||
pev->anim_priority = ANIM_BASIC;
|
||||
pev->anim_run = run;
|
||||
|
||||
if (pev->velocity_x || pev->velocity_y)
|
||||
{ // running
|
||||
pev->frame = $rockrun1;
|
||||
pev->anim_end = $rockrun6;
|
||||
}
|
||||
else
|
||||
{ // standing
|
||||
pev->frame = $stand1;
|
||||
pev->anim_end = $stand5;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
Pain sound, and Pain animation function
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
*/
|
||||
void() PainSound =
|
||||
{
|
||||
if (pev->health < 0)
|
||||
return;
|
||||
pev->noise = "";
|
||||
|
||||
if (pev->watertype == CONTENT_WATER && pev->waterlevel == 3)
|
||||
{ // water pain sounds
|
||||
if (random_float(0,1) <= 0.5)
|
||||
pev->noise = "player/drown1.wav";
|
||||
else
|
||||
pev->noise = "player/drown2.wav";
|
||||
}
|
||||
else if (pev->watertype == CONTENT_SLIME || pev->watertype == CONTENT_LAVA)
|
||||
{ // slime/lava pain sounds
|
||||
if (random_float(0,1) <= 0.5)
|
||||
pev->noise = "player/lburn1.wav";
|
||||
else
|
||||
pev->noise = "player/lburn2.wav";
|
||||
}
|
||||
|
||||
if (pev->noise)
|
||||
{
|
||||
sound (pev, CHAN_VOICE, pev->noise, 1, ATTN_NORM);
|
||||
return;
|
||||
}
|
||||
//don't make multiple pain sounds right after each other
|
||||
if (pev->pain_finished > time)
|
||||
return;
|
||||
pev->pain_finished = time + 0.5;
|
||||
|
||||
local float rs;
|
||||
rs = random_long(0, 5);
|
||||
|
||||
if (rs == 1)
|
||||
pev->noise = "player/pain1.wav";
|
||||
else if (rs == 2)
|
||||
pev->noise = "player/pain2.wav";
|
||||
else if (rs == 3)
|
||||
pev->noise = "player/pain3.wav";
|
||||
else if (rs == 4)
|
||||
pev->noise = "player/pain4.wav";
|
||||
else if (rs == 5)
|
||||
pev->noise = "player/pain5.wav";
|
||||
else
|
||||
pev->noise = "player/pain6.wav";
|
||||
|
||||
sound (pev, CHAN_VOICE, pev->noise, 1, ATTN_NORM);
|
||||
};
|
||||
|
||||
void () PlayerPain =
|
||||
{
|
||||
if (pev->anim_priority < ANIM_PAIN) // call only if not attacking and not already in pain
|
||||
{
|
||||
pev->anim_priority = ANIM_PAIN;
|
||||
pev->frame = $pain1;
|
||||
pev->anim_end = $pain6;
|
||||
}
|
||||
PainSound ();
|
||||
};
|
||||
|
||||
/*
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
Death sound, and Death function
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
*/
|
||||
void() DeathSound =
|
||||
{
|
||||
local float rs;
|
||||
rs = random_long(0, 5);
|
||||
|
||||
if (pev->waterlevel == 3) // water death sound
|
||||
pev->noise = "player/h2odeath.wav";
|
||||
else if (rs == 1)
|
||||
pev->noise = "player/death1.wav";
|
||||
else if (rs == 2)
|
||||
pev->noise = "player/death2.wav";
|
||||
else if (rs == 3)
|
||||
pev->noise = "player/death3.wav";
|
||||
else if (rs == 4)
|
||||
pev->noise = "player/death4.wav";
|
||||
else if (rs == 5)
|
||||
pev->noise = "player/death5.wav";
|
||||
|
||||
sound (pev, CHAN_VOICE, pev->noise, 1, ATTN_NONE);
|
||||
};
|
||||
|
||||
void PlayerTouch( void )
|
||||
{
|
||||
}
|
||||
|
||||
void () PlayerDie =
|
||||
{
|
||||
pev->view_ofs = '0 0 -8';
|
||||
pev->angles_x = pev->angles_z = 0;
|
||||
pev->deadflag = DEAD_DYING;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_TOSS;
|
||||
pev->aiflags = pev->aiflags - (pev->aiflags & AI_ONGROUND);
|
||||
if (pev->velocity_z < 10)
|
||||
pev->velocity_z = pev->velocity_z + random_long(30, 300);
|
||||
|
||||
local float rand;
|
||||
rand = random_long(0, 5);
|
||||
|
||||
pev->anim_priority = ANIM_DEATH;
|
||||
if (rand == 1)
|
||||
{
|
||||
pev->frame = $deatha1;
|
||||
pev->anim_end = $deatha11;
|
||||
}
|
||||
else if (rand == 2)
|
||||
{
|
||||
pev->frame = $deathb1;
|
||||
pev->anim_end = $deathb9;
|
||||
}
|
||||
else if (rand == 3)
|
||||
{
|
||||
pev->frame = $deathc1;
|
||||
pev->anim_end = $deathc15;
|
||||
}
|
||||
else if (rand == 4)
|
||||
{
|
||||
pev->frame = $deathd1;
|
||||
pev->anim_end = $deathd9;
|
||||
}
|
||||
else
|
||||
{
|
||||
pev->frame = $deathe1;
|
||||
pev->anim_end = $deathe9;
|
||||
}
|
||||
DeathSound();
|
||||
};
|
|
@ -1,238 +0,0 @@
|
|||
|
||||
// progdefs.h
|
||||
// generated by Xash3D QuakeC compiler
|
||||
|
||||
#ifndef PROGDEFS_H
|
||||
#define PROGDEFS_H
|
||||
|
||||
typedef struct globalvars_s
|
||||
{
|
||||
int pad[28];
|
||||
int pev;
|
||||
int other;
|
||||
int world;
|
||||
float time;
|
||||
float frametime;
|
||||
string_t mapname;
|
||||
string_t startspot;
|
||||
vec3_t spotoffset;
|
||||
float deathmatch;
|
||||
float coop;
|
||||
float teamplay;
|
||||
float serverflags;
|
||||
float total_secrets;
|
||||
float total_monsters;
|
||||
float found_secrets;
|
||||
float killed_monsters;
|
||||
vec3_t v_forward;
|
||||
vec3_t v_right;
|
||||
vec3_t v_up;
|
||||
float trace_allsolid;
|
||||
float trace_startsolid;
|
||||
float trace_fraction;
|
||||
vec3_t trace_endpos;
|
||||
vec3_t trace_plane_normal;
|
||||
float trace_plane_dist;
|
||||
float trace_hitgroup;
|
||||
float trace_contents;
|
||||
int trace_ent;
|
||||
float trace_flags;
|
||||
func_t main;
|
||||
func_t StartFrame;
|
||||
func_t EndFrame;
|
||||
func_t PlayerPreThink;
|
||||
func_t PlayerPostThink;
|
||||
func_t ClientKill;
|
||||
func_t ClientConnect;
|
||||
func_t PutClientInServer;
|
||||
func_t ClientDisconnect;
|
||||
func_t ClientCommand;
|
||||
} globalvars_t;
|
||||
|
||||
typedef struct entvars_s
|
||||
{
|
||||
string_t classname;
|
||||
string_t globalname;
|
||||
float modelindex;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t old_origin;
|
||||
vec3_t old_angles;
|
||||
vec3_t velocity;
|
||||
vec3_t avelocity;
|
||||
vec3_t m_pmatrix;
|
||||
vec3_t m_pmatrix[1];
|
||||
vec3_t m_pmatrix[2];
|
||||
vec3_t m_pmatrix[3];
|
||||
vec3_t m_pcentre;
|
||||
vec3_t m_pcentre[1];
|
||||
vec3_t m_pcentre[2];
|
||||
vec3_t torque;
|
||||
vec3_t force;
|
||||
vec3_t post_origin;
|
||||
vec3_t post_angles;
|
||||
vec3_t origin_offset;
|
||||
float ltime;
|
||||
float bouncetype;
|
||||
float movetype;
|
||||
float solid;
|
||||
vec3_t absmin;
|
||||
vec3_t absmax;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t size;
|
||||
int chain;
|
||||
string_t model;
|
||||
float frame;
|
||||
float sequence;
|
||||
float renderfx;
|
||||
float effects;
|
||||
float skin;
|
||||
float body;
|
||||
string_t weaponmodel;
|
||||
float weaponframe;
|
||||
func_t use;
|
||||
func_t touch;
|
||||
func_t think;
|
||||
func_t blocked;
|
||||
func_t activate;
|
||||
func_t walk;
|
||||
func_t jump;
|
||||
func_t duck;
|
||||
float flags;
|
||||
float aiflags;
|
||||
float spawnflags;
|
||||
int groundentity;
|
||||
float nextthink;
|
||||
float takedamage;
|
||||
float health;
|
||||
float frags;
|
||||
float weapon;
|
||||
float items;
|
||||
string_t target;
|
||||
string_t parent;
|
||||
string_t targetname;
|
||||
int aiment;
|
||||
int goalentity;
|
||||
vec3_t punchangle;
|
||||
float deadflag;
|
||||
vec3_t view_ofs;
|
||||
float button0;
|
||||
float button1;
|
||||
float button2;
|
||||
float impulse;
|
||||
float fixangle;
|
||||
vec3_t v_angle;
|
||||
float idealpitch;
|
||||
string_t netname;
|
||||
int enemy;
|
||||
float alpha;
|
||||
float team;
|
||||
float max_health;
|
||||
float teleport_time;
|
||||
float armortype;
|
||||
float armorvalue;
|
||||
float waterlevel;
|
||||
float watertype;
|
||||
float ideal_yaw;
|
||||
float yaw_speed;
|
||||
float dmg_take;
|
||||
float dmg_save;
|
||||
int dmg_inflictor;
|
||||
int owner;
|
||||
vec3_t movedir;
|
||||
string_t message;
|
||||
float sounds;
|
||||
string_t noise;
|
||||
string_t noise1;
|
||||
string_t noise2;
|
||||
string_t noise3;
|
||||
float jumpup;
|
||||
float jumpdn;
|
||||
int movetarget;
|
||||
float mass;
|
||||
float density;
|
||||
float gravity;
|
||||
float dmg;
|
||||
float dmgtime;
|
||||
float speed;
|
||||
} entvars_t;
|
||||
|
||||
|
||||
#define REQFIELDS (sizeof(reqfields) / sizeof(fields_t))
|
||||
|
||||
static fields_t reqfields[] =
|
||||
{
|
||||
{159, 6, "th_stand"},
|
||||
{160, 6, "th_walk"},
|
||||
{161, 6, "th_run"},
|
||||
{162, 6, "th_pain"},
|
||||
{163, 6, "th_die"},
|
||||
{164, 6, "th_missile"},
|
||||
{165, 6, "th_melee"},
|
||||
{166, 1, "wad"},
|
||||
{167, 1, "map"},
|
||||
{168, 1, "landmark"},
|
||||
{169, 2, "worldtype"},
|
||||
{170, 2, "delay"},
|
||||
{171, 2, "wait"},
|
||||
{172, 2, "lip"},
|
||||
{173, 2, "light_lev"},
|
||||
{174, 2, "style"},
|
||||
{175, 2, "skill"},
|
||||
{176, 1, "killtarget"},
|
||||
{177, 3, "pos1"},
|
||||
{180, 3, "pos2"},
|
||||
{183, 3, "mangle"},
|
||||
{186, 2, "pain_finished"},
|
||||
{187, 2, "air_finished"},
|
||||
{188, 3, "camview"},
|
||||
{191, 2, "aflag"},
|
||||
{192, 4, "trigger_field"},
|
||||
{193, 2, "anim_time"},
|
||||
{194, 2, "anim_end"},
|
||||
{195, 2, "anim_priority"},
|
||||
{196, 2, "anim_run"},
|
||||
{197, 2, "showhelp"},
|
||||
{198, 2, "showinventory"},
|
||||
{199, 2, "touched"},
|
||||
{200, 1, "name"},
|
||||
{201, 4, "triggerer"},
|
||||
{202, 1, "targ"},
|
||||
{203, 1, "targ[1]"},
|
||||
{204, 1, "targ[2]"},
|
||||
{205, 1, "targ[3]"},
|
||||
{206, 1, "targ[4]"},
|
||||
{207, 1, "targ[5]"},
|
||||
{208, 1, "targ[6]"},
|
||||
{209, 1, "targ[7]"},
|
||||
{210, 1, "oldtarg"},
|
||||
{211, 1, "oldtarg[1]"},
|
||||
{212, 1, "oldtarg[2]"},
|
||||
{213, 1, "oldtarg[3]"},
|
||||
{214, 1, "oldtarg[4]"},
|
||||
{215, 1, "oldtarg[5]"},
|
||||
{216, 1, "oldtarg[6]"},
|
||||
{217, 1, "oldtarg[7]"},
|
||||
{218, 2, "twait"},
|
||||
{219, 2, "twait[1]"},
|
||||
{220, 2, "twait[2]"},
|
||||
{221, 2, "twait[3]"},
|
||||
{222, 2, "twait[4]"},
|
||||
{223, 2, "twait[5]"},
|
||||
{224, 2, "twait[6]"},
|
||||
{225, 2, "twait[7]"},
|
||||
{226, 2, "olddelay"},
|
||||
{227, 1, "message1"},
|
||||
{228, 1, "message2"},
|
||||
{229, 2, "count"},
|
||||
{230, 2, "state"},
|
||||
{231, 2, "used"},
|
||||
{232, 3, "dest"},
|
||||
{235, 1, "target_dest"},
|
||||
{236, 1, "oldmodel"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_SERVER 6477
|
||||
|
||||
#endif//PROGDEFS_H
|
|
@ -1,38 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// server.src - project file for server progs
|
||||
//=======================================================================
|
||||
|
||||
../temp/server.dat
|
||||
|
||||
defs.c
|
||||
main.c
|
||||
damage.c
|
||||
player.c
|
||||
client.c
|
||||
dummys.c
|
||||
internal.c
|
||||
lights.c
|
||||
ambient.c
|
||||
ccam.c
|
||||
triggers.c
|
||||
trigger_generic.c
|
||||
trigger_once.c
|
||||
trigger_sequence.c
|
||||
trigger_message.c
|
||||
trigger_counter.c
|
||||
trigger_teleport.c
|
||||
trigger_hurt.c
|
||||
trigger_push.c
|
||||
trigger_changelevel.c
|
||||
trigger_setskill.c
|
||||
trigger_secret.c
|
||||
funcs.c
|
||||
func_mover.c
|
||||
func_door.c
|
||||
func_button.c
|
||||
func_path_corner.c
|
||||
func_train.c
|
||||
func_areaportal.c
|
||||
items.c
|
||||
impulses.c // should be last
|
|
@ -1 +0,0 @@
|
|||
qcclib -progdefs
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
====================
|
||||
|TRIGGER_CHANGLEVEL|
|
||||
========================
|
||||
|Changes level on touch|
|
||||
========================
|
||||
*/
|
||||
void() trigger_changelevel_touch =
|
||||
{
|
||||
changelevel(pev->map, pev->landmark);
|
||||
};
|
||||
|
||||
void() trigger_changelevel =
|
||||
{
|
||||
entity lmark;
|
||||
|
||||
if(!pev->map) Error("chagnelevel trigger doesn't have map\n");
|
||||
|
||||
trigger_setup();
|
||||
|
||||
lmark = find(world, classname, "info_landmark");
|
||||
if( lmark ) pev->landmark = lmark->targetname;
|
||||
|
||||
pev->touch = trigger_changelevel_touch;
|
||||
};
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
TRIGGER_COUNTER();
|
||||
|
||||
Description;
|
||||
Counts the number of times it gets fired.. then fires its targets..
|
||||
*/
|
||||
|
||||
//DEFS;
|
||||
.float count;
|
||||
//END DEFS;
|
||||
|
||||
void() trigger_counter_use =
|
||||
{
|
||||
pev->count = pev->count - 1; // subtract my count by one; 'ive been triggered'
|
||||
|
||||
if(pev->count != 0)
|
||||
{
|
||||
if (pev->count >= 4) centerprint (pev->triggerer, pev->targ[0]);
|
||||
else if (pev->count == 3) centerprint (pev->triggerer, pev->targ[1]);
|
||||
else if (pev->count == 2) centerprint (pev->triggerer, pev->targ[2]);
|
||||
else centerprint (pev->triggerer, pev->targ[3]);
|
||||
}
|
||||
|
||||
if(pev->count <= 0)
|
||||
{
|
||||
IEM_usetarget();
|
||||
|
||||
if(pev->spawnflags & TRIGGER_ONCE) // if im a trigger_once, remove me;
|
||||
remove(pev);
|
||||
else pev->count = pev->twait[0]; // restore old count
|
||||
}
|
||||
};
|
||||
|
||||
void() trigger_counter =
|
||||
{
|
||||
if(!pev->count) //If my count not set in map default it to 1;
|
||||
pev->count = 1;
|
||||
|
||||
pev->twait[0] = pev->count; //store count levels;
|
||||
|
||||
pev->use = trigger_counter_use; //my use function;
|
||||
|
||||
if(!pev->targ[0]) //if a custom message is not set use the standard ones instead;
|
||||
pev->targ[0] = "There are more to go...";
|
||||
if(!pev->targ[1])
|
||||
pev->targ[1] = "Only 3 more to go...";
|
||||
if(!pev->targ[2])
|
||||
pev->targ[2] = "Only 2 more to go...";
|
||||
if(!pev->targ[3])
|
||||
pev->targ[3] = "Only 1 more to go...";
|
||||
|
||||
pev->classname = "t_counter";
|
||||
};
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
+===================+
|
||||
|TRIGGER_GENERIC|
|
||||
+===================+
|
||||
*/
|
||||
|
||||
void() trigger_generic_think =
|
||||
{
|
||||
pev->touched = FALSE;
|
||||
|
||||
if(pev->message)
|
||||
centerprint(pev->triggerer , pev->message);
|
||||
|
||||
if(pev->target)
|
||||
IEM_usetarget();
|
||||
|
||||
if(pev->spawnflags & TRIGGER_ONCE)
|
||||
remove(pev);
|
||||
};
|
||||
|
||||
void() trigger_generic_touch =
|
||||
{
|
||||
if(!(other.flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
pev->triggerer = other;
|
||||
|
||||
pev->touched = TRUE;
|
||||
pev->think = trigger_generic_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
}
|
||||
};
|
||||
|
||||
void() trigger_generic_use =
|
||||
{
|
||||
if(pev->touched == TRUE)
|
||||
return;
|
||||
|
||||
pev->touched = TRUE;
|
||||
|
||||
if(pev->message)
|
||||
centerprint(pev->triggerer, pev->message);
|
||||
|
||||
pev->think = trigger_generic_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
};
|
||||
|
||||
void() trigger_generic =
|
||||
{
|
||||
trigger_setup();
|
||||
|
||||
pev->touch = trigger_generic_touch;
|
||||
pev->use = trigger_generic_use;
|
||||
|
||||
pev->classname = "generic";
|
||||
|
||||
if(!pev->delay)
|
||||
pev->delay = 2;
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
+============+
|
||||
|TRIGGER_HURT|
|
||||
+============+==============+
|
||||
|Description; |
|
||||
|Hurt player for pev->dmg. |
|
||||
+===========================+
|
||||
*/
|
||||
|
||||
void() trigger_hurt_think =
|
||||
{
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
pev->touched = FALSE;
|
||||
};
|
||||
|
||||
void() trigger_hurt_touch =
|
||||
{
|
||||
if(other.takedamage)
|
||||
{
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
T_Damage (other, pev, pev, pev->dmg);
|
||||
|
||||
pev->touched = TRUE;
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->think = trigger_hurt_think;
|
||||
pev->nextthink = time + 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void() trigger_hurt =
|
||||
{
|
||||
trigger_setup();
|
||||
|
||||
pev->touch = trigger_hurt_touch;
|
||||
|
||||
if(!pev->dmg)
|
||||
pev->dmg = 5;
|
||||
|
||||
pev->classname = "t_hurt";
|
||||
};
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
+===============+
|
||||
|TRIGGER_MESSAGE|
|
||||
+===============+
|
||||
*/
|
||||
|
||||
.string message1;
|
||||
.string message2;
|
||||
.entity triggerer;
|
||||
|
||||
void() trigger_message_think =
|
||||
{
|
||||
pev->touched = FALSE;
|
||||
|
||||
if(pev->message)
|
||||
centerprint(pev->triggerer, pev->message);
|
||||
if(pev->message1)
|
||||
{
|
||||
sprint(pev->triggerer, pev->message1);
|
||||
sprint(pev->triggerer, "\n");
|
||||
}
|
||||
if(pev->message2)
|
||||
{
|
||||
MsgWarn("%s\n", pev->message2);
|
||||
}
|
||||
|
||||
if(pev->target)
|
||||
IEM_usetarget();
|
||||
|
||||
if(pev->spawnflags & TRIGGER_ONCE)
|
||||
remove(pev);
|
||||
};
|
||||
|
||||
void() trigger_message_touch =
|
||||
{
|
||||
if(!(other.flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
pev->touched = TRUE;
|
||||
|
||||
pev->triggerer = other;
|
||||
|
||||
pev->think = trigger_message_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
}
|
||||
};
|
||||
|
||||
void() trigger_message_use =
|
||||
{
|
||||
if(pev->touched == TRUE)
|
||||
return;
|
||||
|
||||
pev->touched = TRUE;
|
||||
|
||||
if(pev->message)
|
||||
centerprint(pev->triggerer, pev->message);
|
||||
if(pev->message1)
|
||||
{
|
||||
sprint(pev->triggerer, pev->message1);
|
||||
sprint(pev->triggerer, "\n");
|
||||
}
|
||||
if(pev->message2)
|
||||
{
|
||||
MsgWarn("%s\n", pev->message2);
|
||||
}
|
||||
|
||||
pev->think = trigger_message_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
};
|
||||
|
||||
void() trigger_message =
|
||||
{
|
||||
trigger_setup();
|
||||
|
||||
if(!pev->delay)
|
||||
pev->delay = 1;
|
||||
|
||||
pev->touch = trigger_message_touch;
|
||||
pev->use = trigger_message_use;
|
||||
|
||||
pev->classname = "t_message";
|
||||
};
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
+================+
|
||||
|TRIGGER_ONCE|
|
||||
+================+
|
||||
*/
|
||||
|
||||
void() trigger_once_think =
|
||||
{
|
||||
if(pev->target)
|
||||
IEM_usetarget();
|
||||
|
||||
remove(pev);
|
||||
};
|
||||
|
||||
void() trigger_once_touch =
|
||||
{
|
||||
if(!(other.flags & FL_CLIENT))
|
||||
return;
|
||||
|
||||
if(pev->touched == FALSE)
|
||||
{
|
||||
if(pev->message)
|
||||
centerprint(other, pev->message);
|
||||
|
||||
pev->think = trigger_once_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
}
|
||||
};
|
||||
|
||||
void() trigger_once_use =
|
||||
{
|
||||
if(pev->touched == TRUE)
|
||||
return;
|
||||
|
||||
pev->touched = TRUE;
|
||||
|
||||
if(pev->message)
|
||||
{
|
||||
bprint("%s\n", pev->message);
|
||||
}
|
||||
|
||||
pev->think = trigger_once_think;
|
||||
pev->nextthink = time + pev->delay;
|
||||
}
|
||||
|
||||
void() trigger_once =
|
||||
{
|
||||
trigger_setup();
|
||||
|
||||
pev->touch = trigger_once_touch;
|
||||
pev->use = trigger_once_use;
|
||||
|
||||
pev->classname = "once";
|
||||
|
||||
if(!pev->delay)
|
||||
pev->delay = 0.1;
|
||||
|
||||
if(!pev->target)
|
||||
remove(pev);
|
||||
};
|