21 Jan 2008

This commit is contained in:
g-cont 2008-01-21 00:00:00 +03:00 committed by Alibek Omarov
parent b83219a1ac
commit adae34a7a1
137 changed files with 4583 additions and 8283 deletions

View File

@ -25,9 +25,6 @@ engine\
engine\client\
engine\server\
engine\uimenu\
pr_client\
pr_server\
pr_uimenu\
launch\
launch\xash\
launch\bsplib\

View File

@ -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. Другие типы не поддерживаются

View File

@ -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];

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 )

View File

@ -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" );

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 );
//

View File

@ -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");

View File

@ -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)));
}
/*

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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 );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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:

View File

@ -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[];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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

BIN
launch/mipdec/mipdec.RES Normal file

Binary file not shown.

28
launch/mipdec/mipdec.rc Normal file
View File

@ -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"

BIN
launch/mipdec/tool.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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

BIN
launch/roqlib/roqlib.RES Normal file

Binary file not shown.

28
launch/roqlib/roqlib.rc Normal file
View File

@ -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"

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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

BIN
launch/sprite/spritegen.RES Normal file

Binary file not shown.

View File

@ -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"

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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

BIN
launch/studio/studiomdl.RES Normal file

Binary file not shown.

View File

@ -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"

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
launch/wadlib/wadlib.RES Normal file

Binary file not shown.

28
launch/wadlib/wadlib.rc Normal file
View File

@ -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"

View File

@ -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

View File

@ -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];
}
/*

View File

@ -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 )

View File

@ -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 );

View File

@ -1,6 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// client.src - project file for client progs
//=======================================================================
../temp/client.dat

View File

@ -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);
};

View File

@ -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 ();
}
};

View File

@ -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");
}
}

View File

@ -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);
}
};

View File

@ -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;

View File

@ -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 );
}

View File

@ -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;
}

View File

@ -1,13 +0,0 @@
/*
FUNC_BUTTON();
Description;
Points func_button to the unified func_mover(); code.
*/
void() func_button =
{
func_mover();
pev->classname = "button";
};

View File

@ -1,12 +0,0 @@
/*
FUNC_DOOR();
Description;
Points func_door to the unified func_mover(); code.
*/
void() func_door =
{
func_mover();
pev->classname = "door";
};

View File

@ -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;
};

View File

@ -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');
};

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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.
};

View File

@ -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);
}
}
};

View File

@ -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
};

View File

@ -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");
};

View File

@ -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");
};

View File

@ -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();
};

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -1 +0,0 @@
qcclib -progdefs

View File

@ -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;
};

View File

@ -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";
};

View File

@ -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;
};

View File

@ -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";
};

View File

@ -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";
};

View File

@ -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);
};

Some files were not shown because too many files have changed in this diff Show More