The following source code changes are required in the cgame project to support AI scripting. There is one new file that must be added to the cgame project. This file is cg_sound.c and it is avalible on the Downloads page as part of the AI Scripting Source Files package. It is placed in the code/cgame folder. In Visual C++ you use the Project->Add to Project->Add Files dialog to achieve this. After this is complete you can make the changes to the rest of the cgame project.
In cg_consolecmds.c in function CG_StartCamera about line 457 add :
trap_startCamera(CAM_PRIMARY, cg.time); // camera on in client
trap_Cvar_Set ("cl_inCameraMode","1"); // ai script
// end multi camera
} else {
In cg_consolecmds.c in function CG_CameraStop_f about line 472 add :
static void CG_CameraStop_f( void ) {
cg.cameraMode = qfalse;
// ai script
trap_Cvar_Set ("cl_inCameraMode","0");
CG_Fade(255, 0, 0); // go black
CG_Fade(0, cg.time + 200, 1500); // then fadeup
black_bars=0; // blackbar addon
// end ai script
}
In cg_ents.c in function CG_EntityEffects about line 131 add :
if (cent->currentState.eType != ET_SPEAKER) {
// ai script sounds
if (cent->currentState.eType == SOLID_BMODEL)
{
vec3_t origin;
float *v;
v = cgs.inlineModelMidpoints[ cent->currentState.modelindex ];
VectorAdd( cent->lerpOrigin, v, origin );
if(cgs.gameSoundTypes[ cent->currentState.loopSound ] == 1)
trap_S_AddLoopingSound( cent->currentState.number, origin,
vec3_origin, cgs.gameSounds[ cent->currentState.loopSound ] );
else {
int soundIndex;
soundIndex = soundScripts[cgs.gameSounds[ cent->currentState.loopSound ]
- 1 ].soundList->sfxHandle;
trap_S_AddLoopingSound( cent->currentState.number, origin,
vec3_origin, soundIndex );
}
} else
{
trap_S_AddLoopingSound( cent->currentState.number,
cent->lerpOrigin, vec3_origin,
cgs.gameSounds[ cent->currentState.loopSound ] );
}
// end ai script
} else {
In cg_event.c in function CG_EntityEvent about line 863 add :
case EV_PLAYERSTOP:
player_stop=cg.time+(es->eventParm&0x7F)*2000;
if (es->eventParm&0x80) black_bars=1;
break;
// ai script
case EV_PLAYERLOCK:
player_lock=es->eventParm;
break;
// end ai script
#endif
In cg_event.c in function CG_EntityEvent about line 1005 add :
DEBUGNAME("EV_GENERAL_SOUND");
// ai script sounds
s = CG_ConfigString( CS_SOUNDS + es->eventParm );
if ( !strstr( s, ".wav" ) ) {
CG_SoundPlaySoundScript( s, NULL, es->number );
break;
}
// end ai script
if ( cgs.gameSounds[ es->eventParm ] ) {
In cg_event.c in function CG_EntityEvent about line 1022 add :
DEBUGNAME("EV_GLOBAL_SOUND");
// ai script sounds
s = CG_ConfigString( CS_SOUNDS + es->eventParm );
if ( !strstr( s, ".wav" ) ) {
CG_SoundPlaySoundScript( s, NULL, es->number );
break;
}
// end ai script
if ( cgs.gameSounds[ es->eventParm ] ) {
In cg_local.h in definition of centity_s about line 208 add :
playerEntity_t pe;
#ifdef SINGLEPLAYER // npc
npcEntity_t ne;
#endif
#ifdef SINGLEPLAYER // entity
md3Entity_t md3;
// ai script
int skin;
// end ai script
#endif
int errorTime;
In cg_local.h after the definition of cgMedia_t about line 1067 add :
// ai script sounds
//
// SOUND SCRIPTING
//
typedef struct soundScriptSound_s
{
char filename[MAX_QPATH];
sfxHandle_t sfxHandle;
int lastPlayed;
struct soundScriptSound_s *next;
} soundScriptSound_t;
#define MAX_SOUND_SCRIPT_SOUNDS 8192
#define MAX_SOUND_SCRIPTS 4096
#define FILE_HASH_SIZE 1024
extern soundScriptSound_t soundScriptSounds[MAX_SOUND_SCRIPT_SOUNDS];
typedef struct soundScript_s
{
int index;
char name[MAX_QPATH];
int channel;
int attenuation;
qboolean streaming;
qboolean looping;
int shakeScale;
float shakeRadius;
int shakeDuration;
qboolean random; // TODO
int numSounds;
soundScriptSound_t *soundList;
struct soundScript_s *nextHash;
} soundScript_t;
extern soundScript_t* hashTable[FILE_HASH_SIZE];
extern soundScript_t soundScripts[MAX_SOUND_SCRIPTS];
extern soundScript_t soundScripts[MAX_SOUND_SCRIPTS];
// end ai script
In cg_local.h in the definition of cgs_t about line 1162 add :
qhandle_t gameModels[MAX_MODELS];
sfxHandle_t gameSounds[MAX_SOUNDS];
// ai script sounds
int gameSoundTypes[MAX_SOUNDS];
// end ai script
int numInlineModels;
qhandle_t inlineDrawModel[MAX_MODELS];
In cg_local.h after the definition of cgs_t about line 1210 add :
#ifdef SINGLEPLAYER // entity
extern player_stop;
extern black_bars;
extern player_lock; // ai script
#endif
In cg_local.h at end of file add :
// ai script sounds
//
// cg_sounds.c
//
int CG_SoundScriptPrecache( const char *name );
qboolean CG_SoundPlaySoundScript( const char *name, vec3_t org, int entnum );
void CG_SoundPlayIndexedScript( int index, vec3_t org, int entnum );
void CG_SoundInit( void );
// end ai script
In cg_main.c in function CG_RegisterSounds about line 635 add :
// voice commands
#ifdef MISSIONPACK
CG_LoadVoiceChats();
#endif
// ai script sounds
CG_SoundInit();
// end ai script
cgs.media.oneMinuteSound = trap_S_RegisterSound( "sound/feedback/1_minute.wav", qtrue );
In cg_main.c in function CG_RegisterSounds about line 837 add :
if ( soundName[0] == '*' ) {
continue; // custom sound
}
// ai script sounds
if (!strstr(soundName, ".wav")) {
cgs.gameSounds[i] = CG_SoundScriptPrecache( soundName );
cgs.gameSoundTypes[i] = 2;
} else {
cgs.gameSounds[i] = trap_S_RegisterSound( soundName, qfalse );
cgs.gameSoundTypes[i] = 1;
}
// end ai script
}
In cg_npcs.c in function CG_ParseAnimationNPCFile about line 81 add :
animations[i].frameLerp = 1000 / fps;
animations[i].initialLerp = 1000 / fps;
}
// ai script
//if ( i != MAX_ANIMATIONS_NPC ) {
//CG_Printf( "Error parsing animation file: %s", filename );
//return qfalse;
//}
// end ai script
return qtrue;
In cg_npcs.c in function CG_NPC about line 293 add :
CG_NPCAnimation(cent,&body.oldframe,&body.frame,&body.backlerp);
body.hModel = cg_npcs[es->modelindex].model;
// ai script
body.customSkin = cent->skin;
// end ai script
AnglesToAxis( cent->lerpAngles, body.axis );
In cg_predict.c about line 32 add :
#ifdef SINGLEPLAYER // entity
int player_stop=0;
int black_bars=0;
int player_lock=0; // ai script
#endif
In cg_predict.c in function CG_PredictPlayerState about line 522 add :
else
{
player_stop=0;
black_bars=0;
}
}
// ai script
if (player_lock)
{
cg_pmove.cmd.forwardmove=0;
cg_pmove.cmd.rightmove=0;
cg_pmove.cmd.upmove=0;
}
// end ai script
#endif
if ( cg_pmove.pmove_fixed ) {
In cg_servercmds.c in function CG_ConfigStringModified about line 322 add :
} else if ( num == CS_INTERMISSION ) {
cg.intermissionStarted = atoi( str );
// ai script
} else if ( num == CS_NPCSKIN ) {
char *v;
int num;
v = Info_ValueForKey(str, "n");
num = atoi(v);
v = Info_ValueForKey( str, "t" );
cg_entities[num].skin = trap_R_RegisterSkin(v);
// end ai script
} else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
cgs.gameModels[ num-CS_MODELS ] = trap_R_RegisterModel( str );
} else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_MODELS ) {
if ( str[0] != '*' ) { // player specific sounds don't register here
if (!strstr(str, ".wav")) {
// ai script sounds
CG_SoundScriptPrecache( str );
} else {
cgs.gameSounds[ num-CS_SOUNDS] = trap_S_RegisterSound( str, qfalse );
}
// end ai script
}
} else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
In cg_servercmds.c in function CG_MapRestart about line 468 add :
cgs.voteTime = 0;
// ai script sounds
CG_SoundInit ();
// end ai script
cg.mapRestart = qtrue;
In cg_servercmds.c in function CG_ServerCommand about line 1015 add :
if ( !strcmp( cmd, "stopCam" ) ) {
cg.cameraMode = qfalse;
trap_Cvar_Set ("cl_inCameraMode","0"); // ai script
CG_Fade(255, 0, 0); // go black
CG_Fade(0, cg.time + 200, 1500); // then fadeup
black_bars=0; // blackbar addon
return;
}
// end camera script
// ai script
if ( !strcmp( cmd, "fadeBlack" ) ) {
CG_Fade(255, 0, 0);
CG_Fade(0, cg.time + 200, atoi(CG_Argv(1))); // then fadeup
return;
}
if ( !strcmp( cmd, "setBlack" ) ) {
CG_Fade(255, 0, 0); // go black
return;
}
if ( !strcmp( cmd, "fadeWhite" ) ) {
CG_Fade(0, 0, 0);
CG_Fade(255, cg.time + 200, atoi(CG_Argv(1)));
return;
}
// end ai script
if ( !strcmp( cmd, "mu_start" ) ) {
In cg_view.c in function CG_CalcViewValues about line 642 add :
} else {
trap_Cvar_Set ("cl_inCameraMode","0"); // ai script
cg.cameraMode = qfalse;
CG_Fade(255, 0, 0); // go black
CG_Fade(0, cg.time + 200, 1500); // then fadeup
black_bars=0; // blackbar addon
}