Add modified source code in game directory (part 4)

This commit is contained in:
LegendGuard 2023-07-26 17:42:52 +02:00 committed by GitHub
parent b6b8a04ab2
commit 0e0bdc0ac8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 2438 additions and 66 deletions

View file

@ -384,6 +384,9 @@ idAI::idAI() {
eyeFocusRate = 0.0f;
headFocusRate = 0.0f;
focusAlignTime = 0;
// HEXEN : Zeroth
ignoreObstacles = false;
}
/*
@ -531,6 +534,9 @@ void idAI::Save( idSaveGame *savefile ) const {
savefile->WriteJoint( flyTiltJoint );
savefile->WriteBool( GetPhysics() == static_cast<const idPhysics *>(&physicsObj) );
// HEXEN : Zeroth
savefile->WriteBool( ignoreObstacles );
}
/*
@ -698,6 +704,19 @@ void idAI::Restore( idRestoreGame *savefile ) {
if ( restorePhysics ) {
RestorePhysics( &physicsObj );
}
savefile->ReadBool( ignoreObstacles );
}
/*
=====================
Zeroth
idAI::Kill
=====================
*/
void idAI::Kill( void ) {
health = 0;
DirectDamage( "damage_generic", this );
}
/*
@ -1049,6 +1068,11 @@ idAI::Think
=====================
*/
void idAI::Think( void ) {
// HEXEN : Zeroth
if ( !AI_DEAD && gameLocal.time < onFire || onFire == -1 ) {
EmitFlames();
}
// if we are completely closed off from the player, don't do anything at all
if ( CheckDormant() ) {
return;
@ -1687,6 +1711,10 @@ bool idAI::MoveToEnemy( void ) {
move.startTime = gameLocal.time;
}
if ( spawnArgs.GetBool( "wall_walker" ) ) {
move.moveDest.z = lastVisibleEnemyPos.z;
}
move.moveDest = pos;
move.goalEntity = enemyEnt;
move.speed = fly_speed;
@ -1926,6 +1954,95 @@ bool idAI::MoveToPosition( const idVec3 &pos ) {
return true;
}
/*
=====================
Zeroth
idAI::MoveForward
=====================
*/
void idAI::MoveForward( void ) {
idVec3 pos;
//idVec3 org;
//int areaNum;
//aasPath_t path;
idVec3 dir;
//ideal_yaw = current_yaw;
//idVec3 dir=angles.ToForward() * physicsObj.GetGravityAxis();
idAngles ang;
ang.yaw = ideal_yaw;
ang.ToVectors( &dir );
dir.Normalize();
pos = physicsObj.GetOrigin() + (dir * 64);
//idVec3 dir;
//idVec3 local_dir;
//float lengthSqr;
// dir = pos - physicsObj.GetOrigin();
// physicsObj.GetGravityAxis().ProjectVector( dir, local_dir );
// local_dir.z = 0.0f;
// lengthSqr = local_dir.LengthSqr();
// if ( lengthSqr > Square( 2.0f ) || ( lengthSqr > Square( 0.1f ) && enemy.GetEntity() == NULL ) ) {
// ideal_yaw = idMath::AngleNormalize180( local_dir.ToYaw() );
// }
DirectMoveToPosition(pos);
TurnToward( pos );
}
/*
=====================
HEXEN
idAI::Event_GetJumpVelocity
=====================
*/
idVec3 idAI::GetJumpVelocity( const idVec3 &pos, float speed, float max_height ) {
idVec3 start;
idVec3 end;
idVec3 dir;
float dist;
bool result;
idEntity *enemyEnt = enemy.GetEntity();
if ( !enemyEnt ) {
return vec3_zero;
}
if ( speed <= 0.0f ) {
gameLocal.Error( "Invalid speed. speed must be > 0." );
}
start = physicsObj.GetOrigin();
end = pos;
dir = end - start;
dist = dir.Normalize();
if ( dist > 16.0f ) {
dist -= 16.0f;
end -= dir * 16.0f;
}
result = PredictTrajectory( start, end, speed, physicsObj.GetGravity(), physicsObj.GetClipModel(), MASK_MONSTERSOLID, max_height, this, enemyEnt, ai_debugMove.GetBool() ? 4000 : 0, dir );
if ( result ) {
return dir * speed ;
} else {
return vec3_zero ;
}
}
/*
=====================
Zeroth
idAI::FacingNormal
=====================
*/
idVec3 idAI::FacingNormal( void ) {
idVec3 dir = viewAxis[ 0 ] * physicsObj.GetGravityAxis();
dir.Normalize();
return dir;
}
/*
=====================
idAI::MoveToCover
@ -2147,6 +2264,11 @@ bool idAI::NewWanderDir( const idVec3 &dest ) {
}
}
// HEXEN : Zeroth - always move direcly toward the player when ignoring obstacles.
if ( ignoreObstacles ) {
return true;
}
// try other directions
if ( ( gameLocal.random.RandomInt() & 1 ) || idMath::Fabs( deltay ) > idMath::Fabs( deltax ) ) {
tdir = d[ 1 ];
@ -2682,10 +2804,16 @@ void idAI::AnimMove( void ) {
if ( gameLocal.time < move.startTime + move.duration ) {
goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time );
delta = goalPos - oldorigin;
delta.z = 0.0f;
if ( !spawnArgs.GetBool( "wall_walker" ) ) {
gameLocal.Printf("lolz\n");
delta.z = 0.0f;
}
} else {
delta = move.moveDest - oldorigin;
delta.z = 0.0f;
if ( !spawnArgs.GetBool( "wall_walker" ) ) {
gameLocal.Printf("lolz mang\n");
delta.z = 0.0f;
}
StopMove( MOVE_STATUS_DONE );
}
} else if ( allowMove ) {
@ -2711,7 +2839,7 @@ void idAI::AnimMove( void ) {
gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 );
}
if ( !af_push_moveables && attack.Length() && TestMelee() ) {
if ( !af_push_moveables && attack.Length() && TestMelee( idVec3() ) ) {
DirectDamage( attack, enemy.GetEntity() );
} else {
idEntity *blockEnt = physicsObj.GetSlideMoveEntity();
@ -3085,7 +3213,7 @@ void idAI::FlyMove( void ) {
RunPhysics();
monsterMoveResult_t moveResult = physicsObj.GetMoveResult();
if ( !af_push_moveables && attack.Length() && TestMelee() ) {
if ( !af_push_moveables && attack.Length() && TestMelee( idVec3() ) ) {
DirectDamage( attack, enemy.GetEntity() );
} else {
idEntity *blockEnt = physicsObj.GetSlideMoveEntity();
@ -3139,7 +3267,7 @@ void idAI::StaticMove( void ) {
AI_ONGROUND = false;
if ( !af_push_moveables && attack.Length() && TestMelee() ) {
if ( !af_push_moveables && attack.Length() && TestMelee( idVec3() ) ) {
DirectDamage( attack, enemyEnt );
}
@ -3398,6 +3526,7 @@ void idAI::Killed( idEntity *inflictor, idEntity *attacker, int damage, const id
if ( ( attacker && attacker->IsType( idPlayer::Type ) ) && ( inflictor && !inflictor->IsType( idSoulCubeMissile::Type ) ) ) {
static_cast< idPlayer* >( attacker )->AddAIKill();
}
gameLocal.SetPersistentRemove( name.c_str() );
}
/***********************************************************************
@ -4256,7 +4385,7 @@ void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) {
idVec3 globalKickDir;
globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir;
ent->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT );
ent->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT, idVec3( 0, 0, 0 ) );
// end the attack if we're a multiframe attack
EndAttack();
@ -4267,7 +4396,7 @@ void idAI::DirectDamage( const char *meleeDefName, idEntity *ent ) {
idAI::TestMelee
=====================
*/
bool idAI::TestMelee( void ) const {
bool idAI::TestMelee( const idVec3 &iPoint ) const {
trace_t trace;
idActor *enemyEnt = enemy.GetEntity();
@ -4306,6 +4435,7 @@ bool idAI::TestMelee( void ) const {
gameLocal.clip.TracePoint( trace, start, end, MASK_SHOT_BOUNDINGBOX, this );
if ( ( trace.fraction == 1.0f ) || ( gameLocal.GetTraceEntity( trace ) == enemyEnt ) ) {
// iPoint = trace.c.point;
return true;
}
@ -4366,7 +4496,8 @@ bool idAI::AttackMelee( const char *meleeDefName ) {
}
// make sure the trace can actually hit the enemy
if ( forceMiss || !TestMelee() ) {
idVec3 iPoint;
if ( forceMiss || !TestMelee( iPoint ) ) {
// missed
p = meleeDef->GetString( "snd_miss" );
if ( p && *p ) {
@ -4391,7 +4522,7 @@ bool idAI::AttackMelee( const char *meleeDefName ) {
idVec3 globalKickDir;
globalKickDir = ( viewAxis * physicsObj.GetGravityAxis() ) * kickDir;
enemyEnt->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT );
enemyEnt->Damage( this, this, globalKickDir, meleeDefName, 1.0f, INVALID_JOINT, iPoint );
lastAttackTime = gameLocal.time;
@ -4432,7 +4563,7 @@ void idAI::PushWithAF( void ) {
vel = ent->GetPhysics()->GetAbsBounds().GetCenter() - touchList[ i ].touchedByBody->GetWorldOrigin();
vel.Normalize();
if ( attack.Length() && ent->IsType( idActor::Type ) ) {
ent->Damage( this, this, vel, attack, 1.0f, INVALID_JOINT );
ent->Damage( this, this, vel, attack, 1.0f, INVALID_JOINT, idVec3( 0, 0, 0 ) );
} else {
ent->GetPhysics()->SetLinearVelocity( 100.0f * vel, touchList[ i ].touchedClipModel->GetId() );
}

View file

@ -252,6 +252,7 @@ public:
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
void Kill( void );
void Spawn( void );
void HeardSound( idEntity *ent, const char *action );
@ -514,7 +515,7 @@ protected:
idProjectile *LaunchProjectile( const char *jointname, idEntity *target, bool clampToAttackCone );
virtual void DamageFeedback( idEntity *victim, idEntity *inflictor, int &damage );
void DirectDamage( const char *meleeDefName, idEntity *ent );
bool TestMelee( void ) const;
bool TestMelee( const idVec3 &iPoint ) const;
bool AttackMelee( const char *meleeDefName );
void BeginAttack( const char *name );
void EndAttack( void );
@ -664,6 +665,38 @@ protected:
void Event_CanReachEntity( idEntity *ent );
void Event_CanReachEnemy( void );
void Event_GetReachableEntityPosition( idEntity *ent );
// HEXEN : Zeroth
protected:
void Event_IsEnemy( const idEntity *test );
void Event_NumGroundContacts( void );
void Event_VecForward( void );
void Event_VecFacing( void );
void Event_SetFacingDir( idVec3 dir);
void Event_IgnoreObstacles( void );
void Event_GetRealEnemyPos( void );
void Event_DirectMoveToPosition( const idVec3 &pos );
void Event_MoveForward( void );
// HEXEN : Zeroth
public:
bool ignoreObstacles;
// HEXEN : Zeroth
public:
idVec3 FacingNormal( void );
idVec3 PredictEnemyPos( float time );
bool CanHitEnemy( void );
void BecomeNonSolid( void );
bool CanBecomeSolid( void );
void BecomeSolid( void );
// HEXEN : Zeroth
protected:
// bool AI_DirectMoveToPosition( const idVec3 &pos );
// bool AI_MoveForward( void );
void MoveForward( void );
idVec3 GetJumpVelocity( const idVec3 &pos, float speed, float max_height );
};
class idCombatNode : public idEntity {

304
game/ai/AI_Golem.cpp Normal file
View file

@ -0,0 +1,304 @@
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
const idVec3 GOLEM_ROCKS_NO_GRAVITY = idVec3(0,0,0);
const int GOLEM_ROCKS_MAX = 13;
const int GOLEM_ROCKS_MIN = 8;
const int GOLEM_ROCKS_MIN_CHECK_DELAY = 2000;
const int GOLEM_ROCKS_MAX_DIST = 300;
const int GOLEM_ROCKS_ATTRACT_SPEED = 240;
const int GOLEM_RICKS_MAX_MOVE_TIME_BEFORE_BIND = 5000;
const int GOLEM_ROCKS_BIND_DISTANCE = 16;
const idEventDef AI_Golem_SawEnemy( "SawEnemy" );
CLASS_DECLARATION( idAI, idAI_Golem )
EVENT( AI_Golem_SawEnemy, idAI_Golem::Event_SawEnemy )
END_CLASS
void idAI_Golem::Spawn() {
alive = false;
nextFindRocks = 0;
totRocks = 0;
nextBoneI = 0;
nextBone(); // start er off
golemType = spawnArgs.GetString("golemType");
onEnt = 0;
onFire = -1;
}
void idAI_Golem::Save( idSaveGame *savefile ) const {
savefile->WriteFloat( totRocks );
savefile->WriteFloat( nextFindRocks );
savefile->WriteInt( nextBoneI );
savefile->WriteString( curBone );
savefile->WriteString( golemType );
savefile->WriteBool( alive );
savefile->WriteInt( rocks.Num() );
for ( int i=0; i<rocks.Num(); i++ ) {
savefile->WriteObject( rocks[i] );
}
}
void idAI_Golem::Restore( idRestoreGame *savefile ) {
savefile->ReadFloat( totRocks );
savefile->ReadFloat( nextFindRocks );
savefile->ReadInt( nextBoneI );
savefile->ReadString( curBone );
savefile->ReadString( golemType );
savefile->ReadBool( alive );
int i;
savefile->ReadInt( i );
idClass *obj;
for ( ; i>0; i-- ) {
savefile->ReadObject( obj );
rocks.Append( static_cast< idMoveable* >( obj ) );
}
}
void idAI_Golem::findNewRocks() {
idMoveable *rock = FindGolemRock();
if ( rock ) {
addRock( rock );
}
}
void idAI_Golem::addRock( idMoveable *newRock ) {
newRock->BecomeNonSolid();
newRock->spawnArgs.SetBool("golem_owned", 1);
newRock->spawnArgs.SetFloat("golem_bindTime", gameLocal.time + GOLEM_RICKS_MAX_MOVE_TIME_BEFORE_BIND );
newRock->spawnArgs.SetBool("golem_bound", 0);
newRock->spawnArgs.Set("old_bounce", newRock->spawnArgs.GetString("snd_bounce") );
newRock->spawnArgs.Set("snd_bounce", ""); // no bounce sounds while on the golem, gets REAL annoying.
newRock->spawnArgs.Set("bone", curBone);
newRock->health = 1000;
newRock->GetPhysics()->DisableClip();
rocks.Append(newRock);
totRocks++;
nextBone();
}
void idAI_Golem::Think() {
idAI::Think();
if ( alive ) {
evalRocks();
}
}
void idAI_Golem::evalRocks() {
int i;
float length;
idVec3 dist;
idStr bone;
if ( gameLocal.time > nextFindRocks ) {
nextFindRocks = gameLocal.time + 2000; // find new rocks every 2 seconds
findNewRocks();
}
for (i=0; i < rocks.Num(); i++) {
if ( !rocks[i] ) {
continue;
}
bone = rocks[i]->spawnArgs.GetString("bone");
if ( !rocks[i]->spawnArgs.GetBool("golem_bound") ) {
dist = GetJointPos(animator.GetJointHandle(bone)) - rocks[i]->GetPhysics()->GetOrigin();
length = dist.Length();
// if rocks are close enough or max time movement has passed, bind them.
if ( length < GOLEM_ROCKS_BIND_DISTANCE || gameLocal.time > rocks[i]->spawnArgs.GetFloat("golem_bindTime") ) {
rocks[i]->GetPhysics()->SetGravity( GOLEM_ROCKS_NO_GRAVITY );
//rocks[i]->SetOrigin( GetLocalCoordinates( GetJointPos(animator.GetJointHandle(bone)) ) );
rocks[i]->SetOrigin( GetJointPos(animator.GetJointHandle(bone)) );
rocks[i]->spawnArgs.Set("golem_bound", "1");
rocks[i]->SetAngles( idAngles(gameLocal.random.RandomInt() % 200 - 100, gameLocal.random.RandomInt() % 200 - 100, gameLocal.random.RandomInt() % 200 - 100 ) );
rocks[i]->BindToJoint(this, bone, 1);
rocks[i]->GetPhysics()->EnableClip();
// else just move them
} else {
dist.Normalize();
//looks shitty: rocks[i]->GetPhysics()->SetAngularVelocity( idVec3(gameLocal.random.RandomInt() % 200 - 100, gameLocal.random.RandomInt() % 200 - 100, gameLocal.random.RandomInt() % 200 - 100 ) );
rocks[i]->GetPhysics()->SetLinearVelocity( dist * GOLEM_ROCKS_ATTRACT_SPEED );
}
continue;
}
// if a rock takes damage, the golem takes damage
if ( rocks[i]->health < 1000 ) {
Damage( NULL, NULL, idVec3(0,0,0), "damage_golem1", 1000 - rocks[i]->health, 0 ); // Z.TODO: this needs to be the damage def of the weapon used...somehow...
rocks[i]->health = 1000;
}
}
}
void idAI_Golem::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, idVec3 &iPoint ) {
if ( !fl.takedamage ) {
return;
}
if ( !inflictor ) {
inflictor = gameLocal.world;
}
if ( !attacker ) {
attacker = gameLocal.world;
}
const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
if ( !damageDef ) {
gameLocal.Error( "Unknown damageDef '%s'", damageDefName );
}
int damage = damageDef->GetInt( "damage" ) * damageScale;
damage = GetDamageForLocation( damage, location );
// inform the attacker that they hit someone
attacker->DamageFeedback( this, inflictor, damage );
if ( damage > 0 ) {
health -= damage;
if ( health <= 0 ) {
if ( health < -999 ) {
health = -999;
}
gameLocal.Printf("BLOWUP!\n");
BlowUp();
Killed( inflictor, attacker, damage, dir, location );
} else {
Pain( inflictor, attacker, damage, dir, location );
}
} else {
// don't accumulate knockback
if ( af.IsLoaded() ) {
// clear impacts
af.Rest();
// physics is turned off by calling af.Rest()
BecomeActive( TH_PHYSICS );
}
}
}
void idAI_Golem::BlowUp( void ) {
//spawnArgs.SetVector( "origin", GetPhysics()->GetOrigin() );
//spawnArgs.Set( "classname", "proj_golemsoul" );
//gameLocal.SpawnEntityDef( spawnArgs );
//soul->GetPhysics()->SetOrigin( GetPhysics()->GetOrigin() );
// rocks get removed from head to toe.
for (int i=rocks.Num(); i >= 0; i--) {
if ( !rocks[i] ) {
rocks[i]->GetPhysics()->SetGravity(gameLocal.GetGravity());
rocks[i]->spawnArgs.Set("golem_owned", 0);
rocks[i]->spawnArgs.Set("golem_bound", 0);
rocks[i]->spawnArgs.Set("golem_bindTime", 0);
rocks[i]->spawnArgs.Set("snd_bounce", rocks[i]->spawnArgs.GetString("old_bounce") ); //Z.TODO
rocks[i]->Unbind();
rocks[i]->BecomeSolid();
idVec3 dx;
dx.x = gameLocal.random.RandomInt() % 200 - 100;
dx.y = gameLocal.random.RandomInt() % 200 - 100;
dx.z = ( gameLocal.random.RandomInt() % 100 ) * 3;
dx.Normalize();
rocks[i]->GetPhysics()->SetLinearVelocity( dx * 600 );
dx.x = gameLocal.random.RandomInt() % 200 - 100;
dx.y = gameLocal.random.RandomInt() % 200 - 100;
dx.z = gameLocal.random.RandomInt() % 200 - 100;
dx.Normalize();
rocks[i]->GetPhysics()->EnableClip();
rocks[i]->GetPhysics()->SetAngularVelocity( dx * 100 );
rocks.RemoveIndex(i);
}
}
}
void idAI_Golem::nextBone() {
// one rock per joint, from toe to head.
switch ( nextBoneI ) {
case 0: curBone = "lfoot"; break;
case 1: curBone = "rfoot"; break;
case 2: curBone = "lknee"; break;
case 3: curBone = "rknee"; break;
case 4: curBone = "pelvis"; break;
case 5: curBone = "spineup"; break;
case 6: curBone = "lhand"; break;
case 7: curBone = "rhand"; break;
case 8: curBone = "lloarm"; break;
case 9: curBone = "rloarm"; break;
case 10: curBone = "luparm"; break;
case 11: curBone = "ruparm"; break;
case 12: curBone = "head"; break;
default: curBone = ""; break;
}
nextBoneI++;
}
void idAI_Golem::Event_SawEnemy() {
alive=true;
}
const char * idAI_Golem::GetGolemType( void ) const {
return golemType.c_str();
}
// HEXEN : Zeroth
idMoveable *idAI_Golem::FindGolemRock( void ) {
int hash, i;
idMoveable *target=NULL;
hash = gameLocal.entypeHash.GenerateKey( idMoveable::Type.classname, true );
for ( i = gameLocal.entypeHash.First( hash ); i != -1; i = gameLocal.entypeHash.Next( i ) ) {
if ( gameLocal.entities[i] && gameLocal.entities[i]->IsType( idMoveable::Type ) ) {
target = static_cast< idMoveable* >( gameLocal.entities[i] );
if ( target->IsHidden() ) {
continue;
}
if ( target->spawnArgs.GetInt("golem_owned") == 1 ) {
continue;
}
/* smaller golemd haven't been implemented yet
if ( !target->spawnArgs.GetInt("forLargeGolem") ) {
continue;
}
*/
if ( GetGolemType() != target->spawnArgs.GetString("rockType") ) {
continue;
}
// trace from golem to rock
trace_t trace;
idEntity *traceEnt = NULL;
gameLocal.clip.TraceBounds( trace,
GetJointPos( animator.GetJointHandle( curBone ) ),
target->GetPhysics()->GetOrigin(),
idBounds( GOLEM_TRACE_MINS, GOLEM_TRACE_MAXS ),
MASK_MONSTERSOLID,
this );
if ( trace.fraction < 1.0f ) {
traceEnt = gameLocal.entities[ trace.c.entityNum ];
}
// make sure rock isn't through a wall or something.
if ( !traceEnt || traceEnt != target ) {
continue;
}
return target;
}
}
return NULL;
}

46
game/ai/AI_Golem.h Normal file
View file

@ -0,0 +1,46 @@
#ifndef __AI_GOLEM_
#define __AI_GOLEM_
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
const idVec3 GOLEM_TRACE_MINS = idVec3(-1,-1,-1);
const idVec3 GOLEM_TRACE_MAXS = idVec3(-1,-1,-1);
class idAI_Golem : public idAI {
public:
CLASS_PROTOTYPE( idAI_Golem );
void Spawn();
void Think();
void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location, idVec3 &iPoint );
void Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location ) { idVec3 zero; Damage(inflictor, attacker, dir, damageDefName, damageScale, location, zero); }
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
public:
const char * GetGolemType( void ) const;
private:
float totRocks; // this IS the total number of rocks.
float nextFindRocks; // time delay for finding new rocks
int nextBoneI;
idStr curBone;
idStr golemType;
idList<idMoveable *> rocks;
bool alive;
int onEnt;
private:
void findNewRocks( void ); // look for new rocks
void addRock( idMoveable *newRock );
void evalRocks( void ); // call this every frame to do all rock related junk
void nextBone( void );
void BlowUp( void );
void Event_SawEnemy( void );
idMoveable *idAI_Golem::FindGolemRock( void );
};
#endif // __AI_GOLEM_

118
game/ai/AI_Shadowspawn.cpp Normal file
View file

@ -0,0 +1,118 @@
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
const int SHADOWSPAWN_RANGE_ATTACK_RATE = 3;
const int SHADOWSPAWN_DRAIN_RATE = 10;
#if 0
CLASS_DECLARATION( idAI, idAI_Shadowspawn )
END_CLASS
void idAI_Shadowspawn::regenerate() {
float drainTime=0;
idVec3 dir;
float giveUp=DelayTime(5);
// // regenerate 2 health every second
// if ( regenTime > ( gameLocal.time / 1000 ) && getHealth() < getFloat("health") ) {
// setHealth(getHealth() + 1);
// regenTime = delaytime(1);
// }
//vec.Length(GetOrigin() - enemy.GetEyePos()) < 80
if ( !enemy ) {
return;
}
SetAnimState( ANIMCHANNEL_TORSO, "Torso_TelePull", 4 );
stayPut=getWorldOrigin(); // shadowspawn should not be moved by projectiles, etc, might put player outside of level
while ( 1 ) {
setWorldOrigin(stayPut);
if ( vec.Length(stayPut - enemy->GetPhysics()->GetOrigin()()) < 90 ) {
break;
} else if (( gameLocal.time / 1000 ) > giveUp) {
SetAnimState( ANIMCHANNEL_TORSO, "Torso_Idle", 4 );
return;
}
enemy->GetPhysics()->SetLinearVelocity( sys.vecNormalize(stayPut - enemy->GetPhysics()->GetOrigin()()) * 80);
waitFrame();
}
enemy.bind(me);
//enemyStayPut = enemy.getWorldOrigin();
float tim=DelayTime(2);
//vector turny = getAngles();
SetAnimState( ANIMCHANNEL_TORSO, "Torso_AttackDrain", 4 );
while ( 1 ) {
setWorldOrigin(stayPut); // shadowspawn should not be moved by projectiles, etc, might put player outside of level
//enemy.setWorldOrigin(enemyStayPut);
//turnTo(turny.y + 180);
if (drainTime < ( gameLocal.time / 1000 )) {
drainTime = DelayTime(1);
directDamage(enemy, "damage_shadowspawn_drain");
setHealth(getHealth()+100);
}
if ( tim < ( gameLocal.time / 1000 ) ) {
SetAnimState( ANIMCHANNEL_TORSO, "Torso_Repulse", 4 );
waitAction( "repulse" );
enemy.unbind();
dir = sys.vecNormalize(enemy->GetPhysics()->GetOrigin()() - stayPut) * 1180;
dir.z = 0;
enemy->GetPhysics()->SetLinearVelocity( dir );
break;
}
waitFrame();
}
}
void idAI_Shadowspawn::telleport() {
float tDelay;
idVec3 pV;
float dist;
float ang;
idVec3 enemyOrigin = enemy->GetPhysics()->GetOrigin()();
nextTelleport = ( gameLocal.time / 1000 ) + sys.random(4)+7;
// lunge at player and disappear
pV = sys.vecNormalize(enemy.GetEyePos() - GetOrigin());
turnToEntity(enemy);
tDelay = 1 + ( gameLocal.time / 1000 );
GetPhysics()->SetLinearVelocity(pV * 1066);
while (( gameLocal.time / 1000 ) < tDelay && vec.Length(GetOrigin() - enemy.GetEyePos()) > 20) {
waitFrame();
}
hide();
// delay
tDelay = sys.random(3) + ( gameLocal.time / 1000 );
while (( gameLocal.time / 1000 ) < tDelay) {
waitFrame();
}
// reappear
ang = sys.random(360);
dist = sys.random(350)+150;
pV = enemy.GetEyePos();
pV.x = pV.x + dist * sys.sin(ang);
pV.y = pV.y + dist * sys.cos(ang);
//pV.z = enemyOrigin.z;
SetOrigin(pV);
show();
doTelleport = false;
}
#endif

15
game/ai/AI_Shadowspawn.h Normal file
View file

@ -0,0 +1,15 @@
#if 0
class idAI_Shadowspawn : public idAI {
public:
CLASS_PROTOTYPE( idAI_Shadowspawn );
void telleport();
void Spawn();
void regenerate();
private:
idEntity enemy;
idVec3 stayPut;
//vector enemyStayPut;
};
#endif

621
game/ai/AI_Veloxite.cpp Normal file
View file

@ -0,0 +1,621 @@
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
const float VELOX_MAX_WALL_DIST = 75.0f; // get on walls this far away
const float VELOX_SURFACECHECK_RATE = 0.25f; // four times per second should be enough
const float VELOX_WALLCHECK_RATE = 1.0f;
const float VELOX_LEAP_RANGE_MIN = 64.0f;
const float VELOX_LEAP_RANGE_MAX = 275.0f; // this only pertains to AI_LEAPING from walls.
const float VELOX_LEAP_SPEED = 650.0f;
const float VELOX_LEAP_MAXHEIGHT = 48.0f;
// for all angles defined below, the angle is between floor and wall/slop angles. in other words, the angle is the opposite of what you'd think (180 - value).
const float VELOX_MAX_WALL_ANGLE = 100.0f; // more than 100 is probably asking for clipping problems
const float VELOX_MIN_WALL_ANGLE = 46.0f; // 46 degrees is the very nearly the max slope walkable for aas48 entites
const float VELOX_MIN_SLOPE_ANGLE = 0.0f; // change gravity only on slopes with this angle or greater
const float VELOX_MIN_TRANS_FRAMES = 10;
const float VELOX_MAX_TRANS_FRAMES = 25;
const float VELOX_WALLLEAP_TRANSITIONS = 4;
// ***********************************************************
// Script Stuff Continued
// ***********************************************************
const idEventDef AI_Veloxite_doSurfaceChecks( "velox_doSurfaceChecks", NULL, 'f' );
const idEventDef AI_Veloxite_getJumpVelocity( "velox_getJumpVelocity", "fffs", 'v' );
const idEventDef AI_Veloxite_startLeaping( "velox_startLeaping" );
const idEventDef AI_Veloxite_doneLeaping( "velox_doneLeaping" );
const idEventDef AI_Veloxite_getOffWall( "velox_getOffWall", "f" );
CLASS_DECLARATION( idAI, idAI_Veloxite )
EVENT( AI_Veloxite_doSurfaceChecks, idAI_Veloxite::Event_doSurfaceChecks )
EVENT( AI_Veloxite_getJumpVelocity, idAI_Veloxite::Event_getVeloxJumpVelocity )
EVENT( AI_Veloxite_doneLeaping, idAI_Veloxite::Event_doneLeaping )
EVENT( AI_Veloxite_startLeaping, idAI_Veloxite::Event_startLeaping )
EVENT( AI_Veloxite_getOffWall, idAI_Veloxite::Event_getOffWall )
END_CLASS
void idAI_Veloxite::LinkScriptVariables( void ) {
AI_ALIGNING.LinkTo( scriptObject, "AI_ALIGNING" );
AI_WALLING.LinkTo( scriptObject, "AI_WALLING" );
AI_LEDGING.LinkTo( scriptObject, "AI_LEDGING" );
AI_SLOPING.LinkTo( scriptObject, "AI_SLOPING" );
AI_LEAPING.LinkTo( scriptObject, "AI_LEAPING" );
AI_FALLING.LinkTo( scriptObject, "AI_FALLING" );
AI_DROPATTACK.LinkTo( scriptObject, "AI_DROPATTACK" );
AI_ONWALL.LinkTo( scriptObject, "AI_ONWALL" );
idAI::LinkScriptVariables();
}
void idAI_Veloxite::Save( idSaveGame *savefile ) const {
idAI::Save( savefile );
savefile->WriteBool( doPostTrans );
savefile->WriteBool( doTrans );
savefile->WriteInt( curTrans );
savefile->WriteInt( numTrans );
savefile->WriteVec3( transGrav );
savefile->WriteVec3( destGrav );
savefile->WriteVec3( upVec );
savefile->WriteTrace( trace );
savefile->WriteFloat( nextWallCheck );
savefile->WriteFloat( maxGraceTime );
savefile->WriteFloat( debuglevel );
savefile->WriteVec3( veloxMins );
savefile->WriteVec3( veloxMaxs );
savefile->WriteVec3( traceMins );
savefile->WriteVec3( traceMaxs );
savefile->WriteBool( AI_ALIGNING ? true : false );
savefile->WriteBool( AI_WALLING ? true : false );
savefile->WriteBool( AI_LEDGING ? true : false );
savefile->WriteBool( AI_SLOPING ? true : false );
savefile->WriteBool( AI_LEAPING ? true : false );
savefile->WriteBool( AI_FALLING ? true : false );
savefile->WriteBool( AI_DROPATTACK ? true : false );
savefile->WriteBool( AI_ONWALL ? true : false );
}
void idAI_Veloxite::Restore( idRestoreGame *savefile ) {
idAI::Restore( savefile );
savefile->ReadBool( doPostTrans );
savefile->ReadBool( doTrans );
savefile->ReadInt( curTrans );
savefile->ReadInt( numTrans );
savefile->ReadVec3( transGrav );
savefile->ReadVec3( destGrav );
savefile->ReadVec3( upVec );
savefile->ReadTrace( trace );
savefile->ReadFloat( nextWallCheck );
savefile->ReadFloat( maxGraceTime );
savefile->ReadFloat( debuglevel );
savefile->ReadVec3( veloxMins );
savefile->ReadVec3( veloxMaxs );
savefile->ReadVec3( traceMins );
savefile->ReadVec3( traceMaxs );
bool b;
savefile->ReadBool( b ); b ? AI_ALIGNING = true : AI_ALIGNING = false;
savefile->ReadBool( b ); b ? AI_WALLING = true : AI_WALLING = false;
savefile->ReadBool( b ); b ? AI_LEDGING = true : AI_LEDGING = false;
savefile->ReadBool( b ); b ? AI_SLOPING = true : AI_SLOPING = false;
savefile->ReadBool( b ); b ? AI_LEAPING = true : AI_LEAPING = false;
savefile->ReadBool( b ); b ? AI_FALLING = true : AI_FALLING = false;
savefile->ReadBool( b ); b ? AI_DROPATTACK = true : AI_DROPATTACK = false;
savefile->ReadBool( b ); b ? AI_ONWALL = true : AI_ONWALL = false;
// Link the script variables back to the scriptobject
LinkScriptVariables();
}
// ***********************************************************
// Class Method Definitions
// ***********************************************************
void idAI_Veloxite::Spawn( void ) {
idVec3 veloxSize = spawnArgs.GetVector( "size", "15 15 15" );
veloxMins = -veloxSize / 2;
veloxMaxs = veloxSize / 2;
traceMins = veloxMins;
traceMaxs = traceMaxs;
transGrav.Zero();
doTrans = false;
doPostTrans = false;
curTrans = 0;
debuglevel = 1;
AI_ONWALL = onWall();
LinkScriptVariables();next=0;
// just to make sure 'trace' is safe
idVec3 addHeight = physicsObj.GetGravity();
addHeight.Normalize();
addHeight *= 24;
idVec3 A = physicsObj.GetOrigin() + addHeight;
idVec3 B = A - addHeight * 2;
gameLocal.clip.TraceBounds( trace, idVec3(), B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this);
}
void idAI_Veloxite::Think( void ) {
next=0;
if ( ( (float) gameLocal.time / 1000 ) > next ) {
next = ( (float) gameLocal.time / 1000 ) + 1;
}
if ( AI_FALLING && !AI_ALIGNING && AI_ONGROUND ) {
AI_FALLING = false;
}
if ( AI_DROPATTACK && !AI_ALIGNING && AI_ONGROUND ) {
AI_DROPATTACK = false;
}
if ( AI_PAIN && onWall() ) {
getOffSurface( true );
}
if ( doTrans ) {
doSurfaceTransition();
}
if ( doPostTrans ) {
postSurfaceTransition();
}
idAI::Think();
}
float idAI_Veloxite::checkSurfaces() {
if ( checkFallingSideways() ) {
return VELOX_SURFACECHECK_RATE ; // we're in the air, so we might as well issue a delay
}
if (!AI_ONGROUND && disableGravity == true && physicsObj.GetLinearVelocity() == idVec3(0,0,0) ) {
disableGravity = false;
getOffSurface(true);
}
if (AI_ONGROUND && !AI_FALLING && !AI_ALIGNING && !AI_LEAPING && !AI_DROPATTACK )
{
// checkStuckInWall();
if ( checkSlope() ) { return VELOX_SURFACECHECK_RATE ; }
if ( checkLedge() ) { return VELOX_SURFACECHECK_RATE ; }
if ( checkWall() ) { return VELOX_SURFACECHECK_RATE ; }
if ( AI_ONWALL && checkDropAttack() ) { return VELOX_SURFACECHECK_RATE ; }
}
if ( !AI_ALIGNING ) checkHovering(); // todo: maybe check hovering when all bools are false?
return VELOX_SURFACECHECK_RATE;
}
bool idAI_Veloxite::checkWall() {
int asd=0;
if (( (float) gameLocal.time / 1000 ) < nextWallCheck) {
return false;
}
idVec3 addHeight = physicsObj.GetGravity();
addHeight.Normalize();
addHeight = -addHeight*24;
idVec3 A = physicsObj.GetOrigin() + addHeight;
idVec3 B = A + ( FacingNormal() * VELOX_MAX_WALL_DIST );
idVec3 normal = gameLocal.clip.TraceSurfaceNormal(trace, A, B, MASK_MONSTERSOLID, this);
if ( surfaceType( normal ) == v_wall ) {
gameLocal.clip.TraceBounds( trace, A, B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this); // trace point just wouldn't do the trick. dunno why (didn't return an idEntity)
idEntity *wall = gameLocal.entities[ trace.c.entityNum ];
if ( wall && wallIsWalkable(wall) ) {
nextWallCheck = ( (float) gameLocal.time / 1000 ) + VELOX_WALLCHECK_RATE; // to prevent rapid new surface AI_ALIGNING, wait 5 seconds for old surface.
AI_WALLING=true;
AI_ALIGNING = true;
getOnSurface( -normal );
return true;
}
}
return false;
}
bool idAI_Veloxite::checkDropAttack() {
idVec3 A = physicsObj.GetOrigin();
idVec3 B = A + DEFAULT_GRAVITY_NORMAL * 1024;
gameLocal.clip.TraceBounds( trace, A, B, idBounds(veloxMins, veloxMaxs), MASK_MONSTERSOLID, this);
idEntity *nmy = gameLocal.entities[ trace.c.entityNum ];
if ( nmy && nmy->GetName() == enemy.GetEntity()->GetName() ) {
AI_DROPATTACK = true;
BeginAttack( "melee_veloxite_fall" );
SetAnimState( ANIMCHANNEL_TORSO, "Torso_LeapAttack", 4 );
getOffSurface(true);
}
return false;
}
bool idAI_Veloxite::checkLedge() {
if (AI_FORWARD) {
idVec3 addHeight = physicsObj.GetGravity();
addHeight.Normalize();
addHeight = -addHeight*24; //24 seems to be just enough to penetrate max slopes for ground - at least for velox
idVec3 myOrigin=physicsObj.GetOrigin();
idVec3 addForward = FacingNormal() * 24;
idVec3 A = myOrigin + addHeight;
idVec3 B = A + addForward;
idEntity *wall;
//make sure there isn't a wall right in our way
idVec3 normal = gameLocal.clip.TraceSurfaceNormal(trace, A, B, MASK_MONSTERSOLID, this);
if ( normal != idVec3(0,0,0) ) {
return false;
}
// do a trace straight through the floor, a bit of infront of the velox
A = myOrigin + addHeight + addForward;
B = myOrigin - addHeight + addForward;
gameLocal.clip.TraceBounds( trace, A, B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this);
wall = gameLocal.entities[ trace.c.entityNum ];
// if the trace found nothing, then we have a ledge, look for a surface to get on
if ( !wall ) {
A = myOrigin - addHeight + addForward;
B = myOrigin - addHeight - addForward;
normal = gameLocal.clip.TraceSurfaceNormal(trace, A, B, MASK_MONSTERSOLID, this);
gameLocal.clip.TraceBounds( trace, A, B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this);
wall = gameLocal.entities[ trace.c.entityNum ];
if ( !wall ) return false;
if ( wallIsWalkable(wall) ) {
AI_LEDGING = true;
AI_ALIGNING = true;
getOnSurface( -normal );
return true;
}
return false;
}
}
return false;
}
bool idAI_Veloxite::checkFallingSideways( void ) {
idVec3 vec = physicsObj.GetLinearVelocity();
float mySpeed = vec.Length();
if ( !AI_ONGROUND && !AI_ALIGNING && !AI_WALLING && !AI_FALLING && AI_ONWALL && !AI_DROPATTACK && !AI_SLOPING && !AI_LEDGING && !AI_LEAPING && mySpeed > 125.0f) {
getOffSurface(true);
return true;
}
return false;
}
bool idAI_Veloxite::checkSlope( void ) {
idVec3 addHeight = physicsObj.GetGravity();
addHeight.Normalize();
addHeight = -addHeight* 24; //24 seems to be just enough to penetrate max slopes for ground - at least for velox
// do a trace straight through the floor
idVec3 A = physicsObj.GetOrigin() + addHeight;
idVec3 B = A - addHeight * 2;
idVec3 normal=gameLocal.clip.TraceSurfaceNormal(trace, A, B, MASK_MONSTERSOLID, this);
if ( normal != -curNorm() && surfaceType(normal) == v_slope ) { // gravity normal is the opposite of the normal of the plane velox is on
gameLocal.clip.TraceBounds( trace, A, B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this); // trace point just wouldn't do the trick. dunno why (didn't return an idEntity)
idEntity *wall = gameLocal.entities[ trace.c.entityNum ];
if ( wall && wallIsWalkable( wall ) ) { // make sure they don't climb on stupid things
AI_SLOPING = true;
AI_ALIGNING = true;
getOnSurface( -normal );
return true;
}
}
return false;
}
bool idAI_Veloxite::checkHovering( void ) {
if ( AI_ONGROUND ) {
idVec3 addHeight = physicsObj.GetGravity();
addHeight.Normalize();
addHeight *= 24; //24 seems to be just enough to penetrate max slopes for ground - at least for velox
// do a trace straight through the floor
idVec3 A = physicsObj.GetOrigin() + addHeight;
idVec3 B = A - addHeight * 2;
gameLocal.clip.TraceBounds( trace, A, B, idBounds(traceMins, traceMaxs), MASK_MONSTERSOLID, this); // trace point just wouldn't do the trick. dunno why (didn't return an idEntity)
idEntity *wall = gameLocal.entities[ trace.c.entityNum ];
if ( wall && !wallIsWalkable( wall ) ) {
idVec3 vecUp = physicsObj.GetGravity(); vecUp.Normalize();
idVec3 dir = FacingNormal() + vecUp * 0.5; dir.Normalize();
physicsObj.SetLinearVelocity( dir * 150);
return true;
}
}
return false;
}
void idAI_Veloxite::getOffSurface( bool fall ) {
if ( AI_ONWALL || AI_LEAPING ) {
// sometimes we might want to keep pre-existing velocity, such as for leapattacks. in such cases, fall is false.
if (fall) {
AI_FALLING = true; // prevent checkSurfaces while AI_FALLING. clipping issues otherwise.
idVec3 thisNorm = physicsObj.GetGravity();
thisNorm.Normalize();
thisNorm = -thisNorm;
// set origin a bit away from the wall to prevent velox from getting on the other side during a drop attack, or getting stuck when falling off a wall.
physicsObj.SetOrigin( physicsObj.GetOrigin() + thisNorm * 10 );
physicsObj.SetGravity(thisNorm*100); // reduce gravity to reduse "wall friction"
physicsObj.SetLinearVelocity(DEFAULT_GRAVITY * DEFAULT_GRAVITY_NORMAL); // pull to floor
}
getOnSurface(DEFAULT_GRAVITY_NORMAL);
}
}
void idAI_Veloxite::getOnSurface( const idVec3 &newNorm, int numt ) {
AI_ALIGNING = true;
float upMax; // max height we will lift the veloxite to in the transition (avoid clipping probs)
destGrav = newNorm * DEFAULT_GRAVITY;
// PREPARING TO TRANSITION
// we need to move the velox up, so it doesn't get stuck in a wall when the gravity changes.
if (!AI_LEAPING) { // if we're AI_LEAPING, don't screw with the origin
// if AI_LEDGING, we need to go away from the new surface instead
// if not AI_LEDGING, upVec will point mostly straight up (relative to the velox)
if (AI_LEDGING) {
upVec = destGrav; upVec.Normalize(); upVec = -upVec;
} else {
upVec = -curNorm();
}
// the more perpendicular the wall is to the ground, the more height. from 0 to 90 degrees, increase height. after 90 degrees, decrease height from max. this works for AI_LEDGING, AI_WALLING, and AI_SLOPING
float ang = curNorm().toAngle(newNorm);
if (ang > 90) {
ang = ang - 90;
ang = 90 - ang;
}
float proportion;
if (AI_SLOPING) {
proportion = ang / 180;
}else{
proportion = ang / 90;
}
// now define the maximum height we will lift the velox
if (AI_LEDGING) { upMax = 2.0f; }
else if (AI_SLOPING) { upMax = 0.66f; }
else { upMax = 1.66f; } // AI_FALLING, AI_WALLING
upMax = upMax;
// now proportion is a decimal value from 0 to 1. do some magic to get the right height:
upVec = upVec * (((upMax-1) * proportion) + 1); // multiplying by less than 1 causes upVec to get shorter (bad)
if ( numt < 1 ) {
// we transition the gravity change because when you change gravity, the veolx's model aligns instantly. if done gradually, it looks like a natural rotation.
// the more perpendicular the wall is to the ground, the longer the transition. from 0 to 90 degrees, increase ti after 90 degrees, decrease time from max.
numTrans = ( ( VELOX_MAX_TRANS_FRAMES - VELOX_MIN_TRANS_FRAMES ) * proportion ) + VELOX_MIN_TRANS_FRAMES;
} else {
numTrans = numt;
}
}
if (AI_LEDGING || AI_WALLING) { disableGravity = true; }
doTrans = true;
curTrans = 0;
transGrav = physicsObj.GetGravity();
doSurfaceTransition();
}
void idAI_Veloxite::doSurfaceTransition( void ) {
idVec3 midGrav;
if ( curTrans >= numTrans || AI_LEAPING ) { // no transition for AI_LEAPING, causes too many problems.
doTrans = false;
curTrans = 0;
physicsObj.SetGravity(destGrav); // set the final gravity just incase we missed some in the rounding
disableGravity = false;
RunPhysics(); //physicsObj.Evaluate(); // particularly for velocity
maxGraceTime=( (float) gameLocal.time / 1000 )+0.5;
doPostTrans = true;
return;
}
// TRANSITION
curTrans++;
// move the Veloxite up:
physicsObj.SetOrigin(physicsObj.GetOrigin() + upVec); // Z.TODO: clip test with velox model
// change velox gravity to the new normal:
midGrav = transGrav * ( 1.0f / curTrans) +
destGrav * ( 1.0f / (numTrans+1-curTrans));
physicsObj.SetGravity(midGrav);
return;
}
void idAI_Veloxite::postSurfaceTransition( void ) {
if (!physicsObj.OnGround()
&& !AI_PAIN
&& !AI_LEAPING
&& !(( (float) gameLocal.time / 1000 ) > maxGraceTime)
&& physicsObj.GetLinearVelocity() != idVec3(0,0,0) ) {
return;
}
doPostTrans = false;
AI_ALIGNING = false;
AI_WALLING = false;
AI_LEDGING = false;
AI_SLOPING = false;
AI_DROPATTACK = false;
idVec3 worldNorm = gameLocal.GetGravity();
worldNorm.Normalize();
AI_ONWALL = onWall();
}
/******************************************************************
Script Events
******************************************************************/
void idAI_Veloxite::Event_getOffWall( float fall ) {
getOffSurface( !(!fall) );
}
void idAI_Veloxite::Event_doSurfaceChecks( void ) {
idThread::ReturnFloat( checkSurfaces() );
}
void idAI_Veloxite::Event_doneLeaping( void ) {
AI_LEAPING = false;
}
void idAI_Veloxite::Event_startLeaping( void ) {
// leaping from wall handled here
// if ( AI_ONWALL ) {
// StopMove( MOVE_STATUS_DONE );
// getOffSurface(false);
// //get jumpVelocity
// idVec3 jumpTo = lastVisibleEnemyPos + lastVisibleEnemyEyeOffset;
// idVec3 jumpVel = jumpTo - physicsObj.GetOrigin();
// jumpVel *= ;
// TurnToward( jumpTo );
// SetAnimState( ANIMCHANNEL_TORSO, "Torso_LeapAttackFromWall", 4 );
// }
// leaping from ground handled in script
AI_LEAPING = true;
}
void idAI_Veloxite::Event_getVeloxJumpVelocity( float speed, float max_height, float channel, const char *animname ) {
float range;
idVec3 jumpVelocity;
if ( AI_ENEMY_IN_FOV ) { //todo: no?
if ( AI_LEAPING ) {
goto returnZero;
}
if ( AI_ONWALL ) {
if ( !enemy.GetEntity() ) {
goto returnZero;
}
// don't leap if player is much higher than veloxc because he cant be reached
idVec3 veloxO = physicsObj.GetOrigin();
idVec3 enemyO = enemy.GetEntity()->GetPhysics()->GetOrigin();
float zDist = enemyO.z - veloxO.z;
if ( zDist > VELOX_LEAP_MAXHEIGHT / 2 ) {
goto returnZero;
}
// now check horizontal range (no height considered)
range = ( idVec3(veloxO.x,veloxO.y,0) - idVec3(enemyO.x,enemyO.y,0) ).Length();
if ( VELOX_LEAP_RANGE_MIN > range && range > VELOX_LEAP_RANGE_MAX) {
goto returnZero;
}
// trace to the player
gameLocal.clip.TraceBounds( trace, veloxO, enemyO, idBounds(veloxMins, veloxMaxs), MASK_MONSTERSOLID, this);
idEntity *traceEnt = gameLocal.entities[ trace.c.entityNum ];
if ( !traceEnt) {
goto returnZero;
}
if ( traceEnt->spawnArgs.GetString("name") != enemy.GetEntity()->spawnArgs.GetString("name") ) {
goto returnZero;
}
jumpVelocity = enemyO - veloxO;
// if player is higher, add height to make sure velox will reach him
if ( zDist > 0 ) { jumpVelocity.z += zDist * 2; }
jumpVelocity.Normalize();
jumpVelocity *= VELOX_LEAP_SPEED;
idThread::ReturnVector( jumpVelocity ); return;
} else {
if ( !idAI::CanHitEnemy() ) {
goto returnZero;
}
range = ( enemy.GetEntity()->GetPhysics()->GetOrigin() - physicsObj.GetOrigin() ).Length();
if ( range < VELOX_LEAP_RANGE_MIN ) {
goto returnZero;
}
// dont check range max, not necessary
idThread::ReturnVector( GetJumpVelocity( PredictEnemyPos( GetAnimLength( (int)channel, animname ) ), VELOX_LEAP_SPEED, VELOX_LEAP_MAXHEIGHT ) ); return;
}
}
returnZero:
idThread::ReturnVector( idVec3(0,0,0) ); return;
}
/******************************************************************
Helper Functions
******************************************************************/
ID_INLINE bool idAI_Veloxite::wallIsWalkable( idEntity *wall ) {
if ( !wall ) { return false; }
if (wall->name == "world" || wall->name.Mid(0, 11) == "func_static" || wall->spawnArgs.GetInt("veloxite_walkable") == 1) {
if (wall->name.Right(4) != "_sky") { // not a skybox
return true;
}
}
return false;
}
ID_INLINE bool idAI_Veloxite::onWall() {
float ang = curNorm().toAngle(DEFAULT_GRAVITY_NORMAL);
if ( ang > VELOX_MIN_WALL_ANGLE ) {
return true;
} else {
return false;
}
}
ID_INLINE v_stype idAI_Veloxite::surfaceType( idVec3 normal ) {
v_stype t = v_none;
if ( normal == idVec3(0,0,0) ) {
return t;
}
float ang = normal.toAngle(-curNorm());
if ( VELOX_MIN_SLOPE_ANGLE <= ang && ang < VELOX_MIN_WALL_ANGLE ) {
t = v_slope;
}
if ( VELOX_MIN_WALL_ANGLE <= ang && ang < VELOX_MAX_WALL_ANGLE ) {
t = v_wall;
}
return t;
}

108
game/ai/AI_Veloxite.h Normal file
View file

@ -0,0 +1,108 @@
#ifndef __AI_VELOXITE_H__
#define __AI_VELOXITE_H__
typedef enum v_stype {
v_none = 0,
v_slope = 1,
v_wall = 2
};
class idAI_Veloxite : public idAI {
public:
CLASS_PROTOTYPE( idAI_Veloxite );
void Spawn( void );
void Think( void );
void LinkScriptVariables( void );
void Save( idSaveGame *savefile ) const;
void Restore( idRestoreGame *savefile );
// ***********************************************************
// Helper Functions
// ***********************************************************
private:
ID_INLINE bool onWall( void );
ID_INLINE bool wallIsWalkable( idEntity *wall );
ID_INLINE v_stype surfaceType( idVec3 normal );
// ***********************************************************
// Class Method Declarations
// ***********************************************************
private:
// surface checks etc
float checkSurfaces( void );
bool checkSlope( void );
bool checkLedge( void );
bool checkWall( void );
void getOnSurface( const idVec3 &norm, int numt = 0 );
void getOffSurface( bool fall );
void doSurfaceTransition( void );
void postSurfaceTransition( void );
// player chasing / attacks
bool checkDropAttack( void );
// bool checkParallel( void ); // if enemy is above velox (relative to velox's gravity) and there there is floor to drop on, do it.
// fix oops's
bool checkFallingSideways( void ); // if we're going faster than 300, we must be falling, make sure it's truly straight down!
bool checkHovering( void ); // if we're AI_ONGROUND but origin is not above a surface, we're hovering over a ledge. do something...
// ***********************************************************
// Variables
// ***********************************************************
private:
// transitions
bool doPostTrans;
bool doTrans;
int curTrans;
int numTrans; // in frames
idVec3 transGrav;
idVec3 destGrav;
idVec3 upVec;
// other stuff
trace_t trace;
float nextWallCheck;
float maxGraceTime;
float debuglevel;
idVec3 veloxMins;
idVec3 veloxMaxs;
idVec3 traceMins;float next;
idVec3 traceMaxs;
/* Debug Level:
1 - useful functions that dont happen every frame
5 - useful functions that happen every frame
10 - unuseful functions that happen every frame
15 - unuseful functions that may happen more than every frame
20 - things you'll functions never want to see
*/
// ***********************************************************
// Script Stuff
// ***********************************************************
protected:
idScriptBool AI_ALIGNING;
idScriptBool AI_WALLING;
idScriptBool AI_LEDGING;
idScriptBool AI_SLOPING;
idScriptBool AI_LEAPING;
idScriptBool AI_FALLING;
idScriptBool AI_DROPATTACK;
idScriptBool AI_ONWALL;
private:
void Event_doSurfaceChecks( void );
void Event_doneLeaping( void );
void Event_startLeaping( void );
void Event_getVeloxJumpVelocity( float speed, float max_height, float channel, const char *animname );
void Event_getOffWall( float fall );
};
#endif // __AI_VELOXITE_H__

View file

@ -60,6 +60,7 @@ const idEventDef AI_MeleeAttackToJoint( "meleeAttackToJoint", "ss", 'd' );
const idEventDef AI_RandomPath( "randomPath", NULL, 'e' );
const idEventDef AI_CanBecomeSolid( "canBecomeSolid", NULL, 'f' );
const idEventDef AI_BecomeSolid( "becomeSolid" );
const idEventDef AI_BecomeNonSolid( "becomeNonSolid" );
const idEventDef AI_BecomeRagdoll( "becomeRagdoll", NULL, 'd' );
const idEventDef AI_StopRagdoll( "stopRagdoll" );
const idEventDef AI_SetHealth( "setHealth", "f" );
@ -162,6 +163,16 @@ const idEventDef AI_CanReachPosition( "canReachPosition", "v", 'd' );
const idEventDef AI_CanReachEntity( "canReachEntity", "E", 'd' );
const idEventDef AI_CanReachEnemy( "canReachEnemy", NULL, 'd' );
const idEventDef AI_GetReachableEntityPosition( "getReachableEntityPosition", "e", 'v' );
// HEXEN : Zeroth
const idEventDef AI_IsEnemy( "IsEnemy", "e", 'f' );
const idEventDef AI_NumGroundContacts( "NumGroundContacts", NULL, 'f' );
const idEventDef AI_VecForward( "VecForward", NULL, 'v' );
const idEventDef AI_VecFacing( "VecFacing", NULL, 'v' );
//const idEventDef AI_SetFacingDir( "SetFacingDir", "v" );
const idEventDef AI_IgnoreObstacles( "IgnoreObstacles" );
const idEventDef AI_DirectMoveToPosition( "DirectMoveToPosition", "v" );
const idEventDef AI_MoveForward( "MoveForward" );
const idEventDef AI_GetRealEnemyPos( "getRealEnemyPos", NULL, 'v' );
CLASS_DECLARATION( idActor, idAI )
EVENT( EV_Activate, idAI::Event_Activate )
@ -292,6 +303,17 @@ CLASS_DECLARATION( idActor, idAI )
EVENT( AI_CanReachEntity, idAI::Event_CanReachEntity )
EVENT( AI_CanReachEnemy, idAI::Event_CanReachEnemy )
EVENT( AI_GetReachableEntityPosition, idAI::Event_GetReachableEntityPosition )
// HEXEN : Zeroth
EVENT( AI_IsEnemy, idAI::Event_IsEnemy )
EVENT( AI_NumGroundContacts, idAI::Event_NumGroundContacts )
EVENT( AI_VecForward, idAI::Event_VecForward )
EVENT( AI_VecFacing, idAI::Event_VecFacing )
//EVENT( AI_SetFacingDir, idAI::Event_SetFacingDir )
EVENT( AI_IgnoreObstacles, idAI::Event_IgnoreObstacles )
EVENT( AI_IgnoreObstacles, idAI::Event_IgnoreObstacles )
EVENT( AI_MoveForward, idAI::MoveForward )
EVENT( AI_DirectMoveToPosition, idAI::DirectMoveToPosition )
EVENT( AI_GetRealEnemyPos, idAI::Event_GetRealEnemyPos )
END_CLASS
/*
@ -772,6 +794,16 @@ idAI::Event_CanBecomeSolid
=====================
*/
void idAI::Event_CanBecomeSolid( void ) {
idThread::ReturnFloat( CanBecomeSolid() );
}
/*
=====================
HEXEN
idAI::CanBecomeSolid
=====================
*/
bool idAI::CanBecomeSolid( void ) {
int i;
int num;
idEntity * hit;
@ -794,11 +826,11 @@ void idAI::Event_CanBecomeSolid( void ) {
if ( physicsObj.ClipContents( cm ) ) {
idThread::ReturnFloat( false );
return;
return false;
}
}
idThread::ReturnFloat( true );
return true;
}
/*
@ -807,6 +839,16 @@ idAI::Event_BecomeSolid
=====================
*/
void idAI::Event_BecomeSolid( void ) {
BecomeSolid();
}
/*
=====================
HEXEN
idAI::BecomeSolid
=====================
*/
void idAI::BecomeSolid( void ) {
physicsObj.EnableClip();
if ( spawnArgs.GetBool( "big_monster" ) ) {
physicsObj.SetContents( 0 );
@ -825,6 +867,16 @@ idAI::Event_BecomeNonSolid
=====================
*/
void idAI::Event_BecomeNonSolid( void ) {
BecomeNonSolid();
}
/*
=====================
HEXEN
idAI::BecomeNonSolid
=====================
*/
void idAI::BecomeNonSolid( void ) {
fl.takedamage = false;
physicsObj.SetContents( 0 );
physicsObj.GetClipModel()->Unlink();
@ -1207,37 +1259,7 @@ idAI::Event_GetJumpVelocity
=====================
*/
void idAI::Event_GetJumpVelocity( const idVec3 &pos, float speed, float max_height ) {
idVec3 start;
idVec3 end;
idVec3 dir;
float dist;
bool result;
idEntity *enemyEnt = enemy.GetEntity();
if ( !enemyEnt ) {
idThread::ReturnVector( vec3_zero );
return;
}
if ( speed <= 0.0f ) {
gameLocal.Error( "Invalid speed. speed must be > 0." );
}
start = physicsObj.GetOrigin();
end = pos;
dir = end - start;
dist = dir.Normalize();
if ( dist > 16.0f ) {
dist -= 16.0f;
end -= dir * 16.0f;
}
result = PredictTrajectory( start, end, speed, physicsObj.GetGravity(), physicsObj.GetClipModel(), MASK_MONSTERSOLID, max_height, this, enemyEnt, ai_debugMove.GetBool() ? 4000 : 0, dir );
if ( result ) {
idThread::ReturnVector( dir * speed );
} else {
idThread::ReturnVector( vec3_zero );
}
idThread::ReturnVector( GetJumpVelocity( pos, speed, max_height ) ) ;
}
/*
@ -1377,6 +1399,16 @@ void idAI::Event_GetEnemy( void ) {
idThread::ReturnEntity( enemy.GetEntity() );
}
/*
=====================
HEXEN
idAI::Event_GetRealEnemyPos
=====================
*/
void idAI::Event_GetRealEnemyPos( void ) {
idThread::ReturnVector( enemy.GetEntity()->GetPhysics()->GetOrigin() );
}
/*
=====================
idAI::Event_GetEnemyPos
@ -1401,19 +1433,29 @@ idAI::Event_PredictEnemyPos
=====================
*/
void idAI::Event_PredictEnemyPos( float time ) {
idThread::ReturnVector( PredictEnemyPos( time ) );
}
/*
=====================
HEXEN
idAI::PredictEnemyPos
=====================
*/
idVec3 idAI::PredictEnemyPos( float time ) {
predictedPath_t path;
idActor *enemyEnt = enemy.GetEntity();
// if no enemy set
if ( !enemyEnt ) {
idThread::ReturnVector( physicsObj.GetOrigin() );
return;
return physicsObj.GetOrigin();
}
// predict the enemy movement
idAI::PredictPath( enemyEnt, aas, lastVisibleEnemyPos, enemyEnt->GetPhysics()->GetLinearVelocity(), SEC2MS( time ), SEC2MS( time ), ( move.moveType == MOVETYPE_FLY ) ? SE_BLOCKED : ( SE_BLOCKED | SE_ENTER_LEDGE_AREA ), path );
idThread::ReturnVector( path.endPos );
return path.endPos;
}
/*
@ -1422,19 +1464,29 @@ idAI::Event_CanHitEnemy
=====================
*/
void idAI::Event_CanHitEnemy( void ) {
idThread::ReturnInt( CanHitEnemy() );
}
/*
=====================
HEXEN
idAI::CanHitEnemy
=====================
*/
bool idAI::CanHitEnemy( void ) {
trace_t tr;
idEntity *hit;
idActor *enemyEnt = enemy.GetEntity();
if ( !AI_ENEMY_VISIBLE || !enemyEnt ) {
idThread::ReturnInt( false );
return;
return false;
}
// don't check twice per frame
if ( gameLocal.time == lastHitCheckTime ) {
idThread::ReturnInt( lastHitCheckResult );
return;
return lastHitCheckResult;
}
lastHitCheckTime = gameLocal.time;
@ -1458,7 +1510,7 @@ void idAI::Event_CanHitEnemy( void ) {
lastHitCheckResult = false;
}
idThread::ReturnInt( lastHitCheckResult );
return lastHitCheckResult;
}
/*
@ -1773,7 +1825,7 @@ idAI::Event_TestMeleeAttack
=====================
*/
void idAI::Event_TestMeleeAttack( void ) {
bool result = TestMelee();
bool result = TestMelee( idVec3() );
idThread::ReturnInt( result );
}
@ -2706,3 +2758,74 @@ void idAI::Event_GetReachableEntityPosition( idEntity *ent ) {
idThread::ReturnVector( pos );
}
/*
================
Zeroth
idAI::Event_GetReachableEntityPosition
================
*/
void idAI::Event_IsEnemy( const idEntity *test ) {
idThread::ReturnFloat(IsEnemy( (idEntity *) test));
}
/*
================
Zeroth
idAI::Event_NumGroundContacts
================
*/
void idAI::Event_NumGroundContacts( void ) {
idThread::ReturnFloat( physicsObj.NumGroundContacts() );
}
/*
================
Zeroth
idAI::Event_VecFacing
================
*/
void idAI::Event_VecFacing( void ) {
// return proper facing direction (yaw only)
idVec3 dir=viewAxis[ 0 ] * physicsObj.GetGravityAxis();
dir.Normalize();
idThread::ReturnVector(dir);
}
// HEXEN : Zeroth - no workie
#if 0
/*
================
Zeroth
idAI::Event_SetFacingDir
================
*/
void idAI::Event_SetFacingDir( idVec3 dir ) {
// return proper facing direction (yaw only)
dir.Normalize();
viewAxis[ 0 ] = dir;// * physicsObj.GetGravityAxis();
}
#endif
/*
================
Zeroth
idAI::Event_VecForward
================
*/
void idAI::Event_VecForward( void ) {
// return proper forward vector for whatever way the AI is looking
idVec3 dir=deltaViewAngles.ToForward() * physicsObj.GetGravityAxis();
dir.Normalize();
idThread::ReturnVector(dir);
}
/*
================
Zeroth
idAI::Event_IgnoreObstacles
================
*/
void idAI::Event_IgnoreObstacles( void ) {
ignoreObstacles = true;
}

View file

@ -592,6 +592,15 @@ private:
idList<idJointQuat> AFPoseJointFrame;
idBounds AFPoseBounds;
int AFPoseTime;
// HEXEN : Zeroth
private:
idList< idDict > jointTransitions;
void transitionJoints( void );
// HEXEN : Zeroth
public:
void eoc_TransitionJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, idAngles &to, idAngles &from, float seconds, float transitions );
};
/*

View file

@ -3032,6 +3032,9 @@ idAnimator::idAnimator() {
channels[ i ][ j ].Reset( NULL );
}
}
// HEXEN : Zeroth
jointTransitions.Clear();
}
/*
@ -3607,6 +3610,51 @@ void idAnimator::SetJointPos( jointHandle_t jointnum, jointModTransform_t transf
ForceUpdate();
}
/*
=====================
HEXEN
idAnimator::eoc_TransitionJointAngle
=====================
*/
void idAnimator::eoc_TransitionJointAngle( jointHandle_t jointnum, jointModTransform_t transform_type, idAngles &to, idAngles &from, float seconds, float transitions ) {
int i, c;
// find the joint if it's already got a transition going on
for ( i = 0; i < jointTransitions.Num(); i++ ) {
if ( jointTransitions[i].GetInt( "jointnum" ) == jointnum ) {
break;
}
}
// add the joint to our transition list if its not already there
if ( i == jointTransitions.Num() ) {
jointTransitions.Append( idDict() );
jointTransitions[i].SetInt( "jointnum", (int) jointnum );
}
jointTransitions[i].SetInt( "transform_type", (int) transform_type );
jointTransitions[i].SetInt( "transitions", (int) transitions );
// do position and calculations beforehand.
float curTime = gameLocal.time;
float tranLen = seconds / transitions ;
idAngles inc = ( to - from ) / transitions ;
// a different method, trying to get the wind_dir relative to world, instead of facing angle of tree.
// idVec3 a = TJPfrom.ToForward();
// idVec3 b = TJPto.ToForward();
// a.Normalize();
// b.Normalize();
// idVec3 newVec = a * TJPcurTransition +
// b * (TJPtransitions-TJPcurTransition);
// idAngles inc = newVec.ToAngles();
for ( c = 0; c < transitions; c++ ) {
jointTransitions[ i ].SetFloat(va( "time_%i", c ), curTime + ( tranLen * c ) );
jointTransitions[ i ].SetAngles( va( "angle_%i", c ), inc * c + from );
}
}
/*
=====================
idAnimator::SetJointAxis
@ -4188,6 +4236,8 @@ bool idAnimator::CreateFrame( int currentTime, bool force ) {
const jointMod_t * jointMod;
const idJointQuat * defaultPose;
transitionJoints(); // HEXEN : Zeroth
static idCVar r_showSkel( "r_showSkel", "0", CVAR_RENDERER | CVAR_INTEGER, "", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
if ( gameLocal.inCinematic && gameLocal.skipCinematic ) {
@ -5031,3 +5081,53 @@ idRenderModel *idGameEdit::ANIM_CreateMeshForAnim( idRenderModel *model, const c
return newmodel;
}
/*
=====================
Zeroth
idAnimator::transitionJoints
=====================
*/
void idAnimator::transitionJoints( void ) {
for ( int i = 0; i < jointTransitions.Num(); i++ ) {
int t;
int transitions = jointTransitions[i].GetInt( "transitions" );
int nextTran = jointTransitions[i].GetInt( "next_transition", "0" );
float curTime = gameLocal.time;
float time = jointTransitions[i].GetFloat( va( "time_%i", nextTran ) );
// make sure we aren't lagging behind the time.
for ( t = nextTran; t < transitions; t++ ) {
if ( curTime < time ) {
// t is the transition we're on for the current time.
break;
} else {
// get the next time and up the transition counter
time = jointTransitions[i].GetFloat( va( "time_%i", t ) );
}
}
// if we've cycled all the transitions and all of them are in the past, just set this to the last transition
if ( t == transitions ) {
t = transitions - 1;
}
// get the angle we need to set to
idAngles ang = jointTransitions[i].GetAngles( va( "angle_%i", t ) );
SetJointAxis( (jointHandle_t) jointTransitions[i].GetInt( "jointnum" ),
(jointModTransform_t) jointTransitions[i].GetInt( "transform_type" ),
ang.ToMat3() );
// only up the transition if the current time is greater than the time to apply the current transition
if ( t < transitions && curTime > jointTransitions[i].GetFloat( va( "time_%i", t - 1 ) ) ) {
t++;
}
if ( t == transitions ) {
jointTransitions.RemoveIndex( i );
} else {
jointTransitions[i].SetInt( "next_transition", t );
}
}
}

View file

@ -837,6 +837,8 @@ void idRestoreGame::RestoreObjects( void ) {
// restore all the objects
for( i = 1; i < objects.Num(); i++ ) {
// MessageBox( NULL, objects[ i ]->GetClassname(), objects[ i ]->GetClassname(), 1 );
// MessageBox( NULL, static_cast<idEntity *>(objects[ i ])->GetName(), "ah", MB_OK );
CallRestore_r( objects[ i ]->GetType(), objects[ i ] );
}

View file

@ -233,6 +233,546 @@ void KillEntities( const idCmdArgs &args, const idTypeInfo &superClass ) {
}
}
/*
==================
Zeroth
Cmd_MapRestart_f
==================
*/
void Cmd_MapRestart_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
idStr map = gameLocal.GetMapName();
idStr cmd;
map = map.Right(map.Length() - 4); // get right of the leading "/map" because the 'map' session command tacks it on.
gameLocal.sessionCommand = "map ";
//gameLocal.sessionCommand += map.c_str();
//gameLocal.sessionCommand += gameLocal.eoc_MapPath.c_str();
gameLocal.sessionCommand += gameLocal.mapNameForCheat;
}
/*
==================
Zeroth
Cmd_guiUpdateSettings_f
Determine which parts of the settings GUI should be visible and display the proper settings on it.
==================
*/
void Cmd_guiUpdateSettings_f( const idCmdArgs &args ) {
int i;
int ratio = cvarSystem->GetCVarInteger( "r_aspectRatio" );
idUserInterface *mainMenuGui = uiManager->FindGui( "guis/mainmenu.gui", true, false, true );
// HEXEN : Zeroth. determine what mode we're in
for ( i = 0; i < EOC_NUM_VMODES; i++ ) {
if ( gameLocal.r_vmodes[i].width == cvarSystem->GetCVarInteger( "r_customWidth" ) &&
gameLocal.r_vmodes[i].height == cvarSystem->GetCVarInteger( "r_customHeight" ) &&
gameLocal.r_vmodes[i].ratio == cvarSystem->GetCVarInteger( "r_aspectRatio" ) )
{
r_vmode.SetInteger( i );
break;
}
}
if ( i == EOC_NUM_VMODES ) {
r_vmode.SetInteger( -1 );
mainMenuGui->SetStateBool( "modeCustom", true );
mainMenuGui->SetStateBool( "modeSetCustom", true );
} else {
mainMenuGui->SetStateBool( "modeCustom", false );
mainMenuGui->SetStateBool( "modeSetCustom", false );
if ( ratio == 0 ) {
mainMenuGui->SetStateBool( "modeSet0", true );
mainMenuGui->SetStateBool( "modeChoices0", true );
} else {
mainMenuGui->SetStateBool( "modeSet0", false );
mainMenuGui->SetStateBool( "modeChoices0", false );
}
if ( ratio == 1 ) {
mainMenuGui->SetStateBool( "modeSet1", true );
mainMenuGui->SetStateBool( "modeChoices1", true );
} else {
mainMenuGui->SetStateBool( "modeSet1", false );
mainMenuGui->SetStateBool( "modeChoices1", false );
}
if ( ratio == 2 ) {
mainMenuGui->SetStateBool( "modeSet2", true );
mainMenuGui->SetStateBool( "modeChoices2", true );
} else {
mainMenuGui->SetStateBool( "modeSet2", false );
mainMenuGui->SetStateBool( "modeChoices2", false );
}
}
mainMenuGui->SetStateInt( "r_aspectRatio", ratio );
mainMenuGui->SetStateInt( "r_customWidth", cvarSystem->GetCVarInteger( "r_customWidth" ) );
mainMenuGui->SetStateInt( "r_customHeight", cvarSystem->GetCVarInteger( "r_customHeight" ) );
switch ( ratio ) {
case 0: mainMenuGui->SetStateString( "r_aspectRatioString", "3:4" ); break;
case 1: mainMenuGui->SetStateString( "r_aspectRatioString", "16:9" ); break;
case 2: mainMenuGui->SetStateString( "r_aspectRatioString", "16:10" ); break;
}
// set up font color for video graphics options on settings menu (so much easier than doing it in gui)
idStr str;
char key[ 50 ];
for ( int n = 0; n < 4; n++ ) {
if ( cvarSystem->GetCVarInteger( "com_machineSpec" ) == n ) {
str = "1,.66,.15,1";
} else {
str = "1, 0.8, 0.5, 1";
}
sprintf( key, "video_%i_fcolor", n );
mainMenuGui->SetStateString( key, str );
}
}
/*
==================
Zeroth
Cmd_UpdateFog_f
==================
*/
void Cmd_UpdateFog_f( const idCmdArgs &args ) {
gameLocal.UpdateFog();
}
/*
==================
Zeroth
Cmd_SetClass_f
==================
*/
void Cmd_SetClass_f( const idCmdArgs &args ) {
idStr clas = args.Argv( 1 );
gameLocal.GetLocalPlayer()->SetClass( atoi(clas.c_str()) );
}
/*
==================
Zeroth
Cmd_ClearPLI_f
==================
*/
void Cmd_ClearPLI_f( const idCmdArgs &args ) {
gameLocal.persistentLevelInfo.Clear();
idEntity* ent;
idStr name;
for (int i = 0; i < MAX_GENTITIES; i++ ) {
ent = gameLocal.entities[i];
if (ent) {
name = ent->GetEntityDefName();
// find moveables locations
if ( name.Left(9) == "moveable_" ) {
// z.todo: crash on moveables which inherit from "moveable_item_default" via def.
// (SVN 2889, check moveable_book_1 in moveable.def)
static_cast<idMoveable *>( ent )->savePersistentInfo = false;
}
}
}
}
/*
==================
Zeroth
Cmd_VidRestart_f
Set up video mode.
==================
*/
void Cmd_VidRestart_f( const idCmdArgs &args ) {
bool doit = false;
int ratio;
int width;
int height;
int eoc_cvarmode = r_vmode.GetInteger();
idPlayer *localplayer = gameLocal.GetLocalPlayer();
/// if you click too fast, doom3 doesnt register that you've unclicked when it resets video. let's try to find the best way to go about this...
//float wait=gameLocal.time+500;
//while ( gameLocal.time < wait ) {
// sys.wait(
//}
//if ( localplayer != NULL ) {
// localplayer->usercmd.buttons = 1;
// localplayer->weapon.GetEntity()->eoc_UnstickAllButtons();
//}
// figure out what resolution to use
if ( eoc_cvarmode >= 0 && eoc_cvarmode < EOC_NUM_VMODES ) { // preset resolution/ratio
height = gameLocal.r_vmodes[eoc_cvarmode].height;
width = gameLocal.r_vmodes[eoc_cvarmode].width;
ratio = gameLocal.r_vmodes[eoc_cvarmode].ratio;
} else if ( eoc_cvarmode == -1 ) { // custom resoultion/ratio
height = cvarSystem->GetCVarInteger( "r_customHeight" );
width = cvarSystem->GetCVarInteger( "r_customWidth" );
ratio = cvarSystem->GetCVarInteger( "r_aspectRatio" );
}
cvarSystem->SetCVarInteger( "r_aspectRatio", ratio );
cvarSystem->SetCVarInteger( "r_mode", -1 );
cvarSystem->SetCVarInteger( "r_customHeight", height );
cvarSystem->SetCVarInteger( "r_customWidth", width );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart" );
const idCmdArgs nil;
Cmd_guiUpdateSettings_f( nil );
gameLocal.UpdateFog();
}
/*
==================
Zeroth
Cmd_NewGame_f
Clear persistent info and start newgame.
==================
*/
void Cmd_NewGame_f( const idCmdArgs &args ) {
const idCmdArgs nil;
if ( args.Argc() == 0 ) {
gameLocal.Printf( "no map specified" );
return;
}
Cmd_ClearPLI_f( nil );
idStr cmd;
cmd = "map ";
cmd += args.Argv( 1 );
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, cmd.c_str() );
}
/*
==================
Zeroth
Cmd_SpawnAt_f
==================
*/
void Cmd_SpawnAt_f( const idCmdArgs &args ) {
idStr point = "info_player_start_";
point.Append( args.Args() );
gameLocal.SetLocalPlayerSpawnPoint( point );
gameLocal.Printf( "Spawn point set to %s", point.c_str() );
}
/*
==================
Zeroth
Cmd_Visit_f
==================
*/
void Cmd_Visit_f( const idCmdArgs &args ) {
idStr cmd = args.Args();
if ( cmd.Length() != 6 ) {
gameLocal.Printf( "Usage: visit e#h#m#" );
return;
}
idStr episode;
idStr map;
idStr path = "map hexen/ep";
cmd.Mid( 1, 1, episode );
path.Append( episode );
path.Append( "/" );
cmd.Right( 4, map );
path.Append( map );
gameLocal.Printf( "Changing map to: %s", path.c_str() );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, path.c_str() );
}
/*
==================
Zeroth
Cmd_Where_f
==================
*/
void Cmd_Where_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
idVec3 origin = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin();
gameLocal.Printf( "You are here -> %f, %f, %f", origin.x, origin.y, origin.z );
}
/*
==================
Zeroth
Cmd_Ticker_f
==================
*/
void Cmd_Ticker_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
if (cvarSystem->GetCVarBool( "com_showFPS" ) ) {
cvarSystem->SetCVarBool( "com_showFPS", false );
} else {
cvarSystem->SetCVarBool( "com_showFPS", true );
}
}
/*
==================
Zeroth
Cmd_iddqd_f
==================
*/
void Cmd_iddqd_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
idPlayer *player;
if ( gameLocal.isMultiplayer ) {
if ( gameLocal.isClient ) {
idBitMsg outMsg;
byte msgBuf[ MAX_GAME_MESSAGE_SIZE ];
outMsg.Init( msgBuf, sizeof( msgBuf ) );
outMsg.WriteByte( GAME_RELIABLE_MESSAGE_KILL );
networkSystem->ClientSendReliableMessage( outMsg );
} else {
player = gameLocal.GetClientByCmdArgs( args );
if ( !player ) {
common->Printf( "kill <client nickname> or kill <client index>\n" );
return;
}
player->Kill( false, false );
cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
}
} else {
player = gameLocal.GetLocalPlayer();
if ( !player ) {
return;
}
gameLocal.Printf( "Trying to cheat, eh? Now you die!" );
player->hud->SetStateString( "eoc_message", "Trying to cheat, eh? Now you die!" );
player->hud->HandleNamedEvent( "eoc_MessageShow" );
player->Kill( false, false );
}
}
/*
==================
Zeroth
Cmd_Conan_f
==================
*/
void Cmd_Conan_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
idPlayer *player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
player->inventory.weapons = 1;
player->PerformImpulse( 0 );
gameLocal.Printf( "Conan-Mode!" );
}
/*
==================
Zeroth
Cmd_FullHealth_f
==================
*/
void Cmd_FullHealth_f( const idCmdArgs &args ) {
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
player->health = player->inventory.maxHealth;
gameLocal.Printf( "Health Restored\n" );
}
/*
==================
Zeroth
Cmd_idkfa_f
==================
*/
void Cmd_idkfa_f( const idCmdArgs &args ) {
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
idPlayer *player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
gameLocal.Printf( "Trying to cheat, eh? You don't deserve items!" );
player->hud->SetStateString( "eoc_message", "Trying to cheat, eh? You don't deserve items!" );
player->hud->HandleNamedEvent( "eoc_MessageShow" );
int i;
for ( i = NUM_UNIQUE_ARTIFACTS - 1; i >= 0; i-- ) {
player->ArtifactRemove( i );
}
player->UpdateHudArtifacts();
player->UpdateArtifactHudDescription();
player->ShowArtifactHud();
player->inventory.weapons = 1;
player->PerformImpulse( 0 );
player->inventory.powerups = 0;
player->inventory.armor = 0;
player->inventory.items.Clear();
for ( i = 0; i < AMMO_NUMTYPES; i++ )
player->inventory.ammo[ i ] = 0;
for ( i = 0; i < MAX_WEAPONS; i++ )
player->inventory.clip[ i ] = 0;
}
/*
==================
Zeroth
Cmd_WallWalk_f
==================
*/
void Cmd_WallWalk_f( const idCmdArgs &args ) {
char *msg;
idPlayer *player;
idPhysics *phys;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
if ( player->gravityMod ) {
player->gravityMod = false;
//player->GetPhysics()->SetGravity( idVec3( 0, 0, -1066 ) );
//phys = static_cast<idPhysics_Player *>( player->GetPlayerPhysics() );
phys = player->GetPhysics();
phys->TransitionToGravity = idVec3( 0, 0, -1 );
phys->TransitionFromGravity = phys->GetGravityNormal();
phys->curTransition = 0;
msg = "OFF";
} else {
player->gravityMod = true;
msg = "ON - try walking up a slope somewhere";
}
gameLocal.Printf( "wall walking %s", msg );
}
/*
==================
Zeroth
Cmd_Beaten_f
==================
*/
void Cmd_Beaten_f( const idCmdArgs &args ) {
idPlayer *player=gameLocal.GetLocalPlayer();
if ( player ) {
if ( player->beaten ) {
player->beaten = false;
gameLocal.Printf( "set: beaten." );
} else {
player->beaten = true;
gameLocal.Printf( "set: not beaten." );
}
}
}
/*
==================
Zeroth
Cmd_Hexinfo_f
==================
*/
void Cmd_Hexinfo_f( const idCmdArgs &args ) {
int i;
char str[ 1024 ];
FILE *fsvn = NULL;
fsvn = fopen( "eoc/.svn/entries", "r" );
if ( !fsvn ) {
fsvn = fopen( "trunk/.svn/entries", "r" );
}
if ( !fsvn ) {
fsvn = fopen( "hexen/.svn/entries", "r" );
}
// print time
time_t rawtime;
time( &rawtime );
gameLocal.Printf( "Date: %s", ctime( &rawtime ) );
idPlayer *player = gameLocal.GetLocalPlayer();
gameLocal.Printf( "one: %s", player->spawnArgs.GetString( "one" ) );
gameLocal.Printf( "two: %s", player->spawnArgs.GetString( "two" ) );
gameLocal.Printf( "beaten: %s", player->spawnArgs.GetString( "beaten" ) );
// print svn revision
if ( fsvn ) {
// skip 3 lines (lines in this svn file are pretty short)
for ( i = 0; i < 3; i++ ) {
fgets( str, sizeof( str ), fsvn );
}
fgets( str, sizeof( str ), fsvn );
gameLocal.Printf( "SVN: %s", str );
fclose( fsvn );
}
gameLocal.Printf( "Release: %i", EOC_RELEASE );
}
/*
==================
Zeroth
Cmd_ToggleFog_f
==================
*/
void Cmd_ToggleFog_f( const idCmdArgs &args ) {
if ( r_fog.GetBool() ) {
r_fog.SetBool( false );
} else {
r_fog.SetBool( true );
}
gameLocal.UpdateFog();
}
/*
==================
Cmd_KillMonsters_f
@ -241,10 +781,22 @@ Kills all the monsters in a level.
==================
*/
void Cmd_KillMonsters_f( const idCmdArgs &args ) {
KillEntities( args, idAI::Type );
idEntity *ent;
if ( !gameLocal.GetLocalPlayer() || !gameLocal.CheatsOk( false ) ) {
return;
}
for ( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) {
if ( ent->IsType( idAI::Type ) ) {
static_cast< idAI* >( ent )->Kill();
}
}
// kill any projectiles as well since they have pointers to the monster that created them
KillEntities( args, idProjectile::Type );
gameLocal.Printf( "Butchered All Monsters\n" );
}
/*
@ -276,6 +828,52 @@ void Cmd_KillRagdolls_f( const idCmdArgs &args ) {
KillEntities( args, idAFEntity_WithAttachedHead::Type );
}
/*
==================
Zeroth
Cmd_Indiana_f
==================
*/
void Cmd_Indiana_f( const idCmdArgs &args ) {
idStr art[ 15 ];
int i = 0;
idDict iargs;
idPlayer * player = gameLocal.GetLocalPlayer();
if ( !player ) {
return;
}
art[ i++ ] = "artifact_banish" ;
art[ i++ ] = "artifact_boots" ;
art[ i++ ] = "artifact_bracers" ;
art[ i++ ] = "artifact_chaos" ;
art[ i++ ] = "artifact_defender" ;
art[ i++ ] = "artifact_disc" ;
art[ i++ ] = "artifact_flask" ;
art[ i++ ] = "artifact_flechette" ;
art[ i++ ] = "artifact_krater" ;
//notineocalpha art[ i++ ] = "artifact_pork" ;
//notineocalpha art[ i++ ] = "artifact_servant" ;
art[ i++ ] = "artifact_tome" ;
art[ i++ ] = "artifact_torch" ;
art[ i++ ] = "artifact_urn" ;
for ( int a = 0; a < 15; a++ ) {
idDict artifact( *gameLocal.FindEntityDefDict( art[a] ) );
int max = gameLocal.FindEntityDefDict( art[a] )->GetInt( "max_inventory" );
max -= gameLocal.GetLocalPlayer()->InventoryItemQty( artifact.GetString( "inv_name" ) );
for ( i = 0; i < max; i++ ) {
iargs.Set( "classname", art[a] );
iargs.Set( "owner", gameLocal.GetLocalPlayer()->GetName() );
iargs.Set( "snd_acquire", "" );
iargs.Set( "dontNotifyOnPickup", "1" );
gameLocal.SpawnEntityDef( iargs );
}
}
}
/*
==================
Cmd_Give_f
@ -313,11 +911,18 @@ void Cmd_Give_f( const idCmdArgs &args ) {
}
}
if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) {
// HEXEN : Zeroth
if ( ( idStr::Cmpn( name, "weapon_", 7 ) == 0 ) || idStr::Cmpn( name, "artifact_", 9 ) == 0 || ( idStr::Cmpn( name, "item_", 5 ) == 0 ) || ( idStr::Cmpn( name, "ammo_", 5 ) == 0 ) ) {
player->GiveItem( name );
return;
}
// HEXEN : Zeroth
if ( give_all ) {
const idCmdArgs blah;
Cmd_Indiana_f( blah );
}
if ( give_all || idStr::Icmp( name, "health" ) == 0 ) {
player->health = player->inventory.maxHealth;
if ( !give_all ) {
@ -375,6 +980,66 @@ void Cmd_Give_f( const idCmdArgs &args ) {
}
}
/*
==================
Zeroth
Cmd_Shazam_f
==================
*/
void Cmd_Shazam_f( const idCmdArgs &args ) {
if ( gameLocal.GetLocalPlayer()->PowerTome ) {
gameLocal.GetLocalPlayer()->PowerTome = false;
} else {
gameLocal.GetLocalPlayer()->PowerTome = true;
}
}
/*
==================
Zeroth
Cmd_Rambo_f
==================
*/
void Cmd_Rambo_f( const idCmdArgs &args ) {
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
player->inventory.weapons = BIT( MAX_WEAPONS ) - 1;
player->CacheWeapons();
for ( int i = 0 ; i < AMMO_NUMTYPES; i++ ) {
player->inventory.ammo[ i ] = player->inventory.MaxAmmoForAmmoClass( player, idWeapon::GetAmmoNameForNum( ( ammo_t )i ) );
}
}
/*
==================
Zeroth
Cmd_NRA_f
==================
*/
void Cmd_NRA_f( const idCmdArgs &args ) {
idPlayer *player;
player = gameLocal.GetLocalPlayer();
if ( !player || !gameLocal.CheatsOk() ) {
return;
}
player->inventory.weapons = BIT( MAX_WEAPONS ) - 1;
player->CacheWeapons();
for ( int i = 0 ; i < AMMO_NUMTYPES; i++ ) {
player->inventory.ammo[ i ] = player->inventory.MaxAmmoForAmmoClass( player, idWeapon::GetAmmoNameForNum( ( ammo_t )i ) );
}
player->inventory.armor = player->inventory.maxarmor;
}
/*
==================
Cmd_CenterView_f
@ -416,13 +1081,13 @@ void Cmd_God_f( const idCmdArgs &args ) {
if ( player->godmode ) {
player->godmode = false;
msg = "godmode OFF\n";
msg = "OFF\n";
} else {
player->godmode = true;
msg = "godmode ON\n";
msg = "ON\n";
}
gameLocal.Printf( "%s", msg );
gameLocal.Printf( "Satan-Mode %s", msg );
}
/*
@ -487,6 +1152,7 @@ Cmd_Kill_f
*/
void Cmd_Kill_f( const idCmdArgs &args ) {
idPlayer *player;
static int times = 0;
if ( gameLocal.isMultiplayer ) {
if ( gameLocal.isClient ) {
@ -505,11 +1171,16 @@ void Cmd_Kill_f( const idCmdArgs &args ) {
cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "say killed client %d '%s^0'\n", player->entityNumber, gameLocal.userInfo[ player->entityNumber ].GetString( "ui_name" ) ) );
}
} else {
times++;
if ( times != 3 ) {
return;
}
player = gameLocal.GetLocalPlayer();
if ( !player ) {
return;
}
player->Kill( false, false );
gameLocal.Printf( "Butchered Self." );
}
}
@ -841,7 +1512,7 @@ void Cmd_Damage_f( const idCmdArgs &args ) {
return;
}
ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT );
ent->Damage( gameLocal.world, gameLocal.world, idVec3( 0, 0, 1 ), "damage_moverCrush", atoi( args.Argv( 2 ) ), INVALID_JOINT, idVec3( 0, 0, 0 ) );
}
@ -1509,7 +2180,7 @@ static void Cmd_TestDamage_f( const idCmdArgs &args ) {
// give the player full health before and after
// running the damage
player->health = player->inventory.maxHealth;
player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT );
player->Damage( NULL, NULL, dir, damageDefName, 1.0f, INVALID_JOINT, idVec3( 0, 0, 0 ) );
player->health = player->inventory.maxHealth;
}
@ -1556,7 +2227,7 @@ static void Cmd_TestDeath_f( const idCmdArgs &args ) {
dir[2] = 0;
g_testDeath.SetBool( 1 );
player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT );
player->Damage( NULL, NULL, dir, "damage_triggerhurt_1000", 1.0f, INVALID_JOINT, idVec3( 0, 0, 0 ) );
if ( args.Argc() >= 2) {
player->SpawnGibs( dir, "damage_triggerhurt_1000" );
}
@ -2304,6 +2975,66 @@ so it can perform tab completion
=================
*/
void idGameLocal::InitConsoleCommands( void ) {
// HEXEN : Zeroth - hexen / heretic / modified cheats
cmdSystem->AddCommand( "satan", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" );
cmdSystem->AddCommand( "quicken", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" );
cmdSystem->AddCommand( "indiana", Cmd_Indiana_f, CMD_FL_GAME|CMD_FL_CHEAT, "give max of each artifact" );
cmdSystem->AddCommand( "gimme", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" );
cmdSystem->AddCommand( "rambo", Cmd_Rambo_f, CMD_FL_GAME|CMD_FL_CHEAT, "give all weapons, full mana" );
cmdSystem->AddCommand( "nra", Cmd_NRA_f, CMD_FL_GAME|CMD_FL_CHEAT, "give all weapons, full mana, full armor" );
cmdSystem->AddCommand( "clubmed", Cmd_FullHealth_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives full health" );
cmdSystem->AddCommand( "ponce", Cmd_FullHealth_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives full health" );
cmdSystem->AddCommand( "conan", Cmd_Conan_f, CMD_FL_GAME|CMD_FL_CHEAT, "remove all but main weapon" );
cmdSystem->AddCommand( "casper", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" );
cmdSystem->AddCommand( "kitty", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" );
cmdSystem->AddCommand( "butcher", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "kills all monsters" );
cmdSystem->AddCommand( "massacre", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "kills all monsters" );
//notineocalpha cmdSystem->AddCommand( "init", Cmd_MapRestart_f, CMD_FL_GAME|CMD_FL_CHEAT, "restart local map (MIGHT CRASH!)" );
cmdSystem->AddCommand( "visit", Cmd_Visit_f, CMD_FL_GAME|CMD_FL_CHEAT, "change map e#h#m#" );
cmdSystem->AddCommand( "engage", Cmd_Visit_f, CMD_FL_GAME|CMD_FL_CHEAT, "change map e#h#m#" );
cmdSystem->AddCommand( "shazam", Cmd_Shazam_f, CMD_FL_GAME|CMD_FL_CHEAT, "toggle power mode" );
cmdSystem->AddCommand( "spawnat", Cmd_SpawnAt_f, CMD_FL_GAME|CMD_FL_CHEAT, "set spawn point" );
cmdSystem->AddCommand( "where", Cmd_Where_f, CMD_FL_GAME, "Display coordinates" );
//notineocalpha cmdSystem->AddCommand( "ticker", Cmd_Ticker_f, CMD_FL_GAME, "Display frame rate" );
// naughty things
cmdSystem->AddCommand( "martek", Cmd_Kill_f, CMD_FL_GAME|CMD_FL_CHEAT, "kills you" );
cmdSystem->AddCommand( "iddqd", Cmd_iddqd_f, CMD_FL_GAME|CMD_FL_CHEAT, "kills you" );
cmdSystem->AddCommand( "god", Cmd_iddqd_f, CMD_FL_GAME|CMD_FL_CHEAT, "kills you" );
cmdSystem->AddCommand( "idkfa", Cmd_idkfa_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all weapons and items" );
cmdSystem->AddCommand( "give", Cmd_idkfa_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all weapons and items" );
// what?
//cmdSystem->AddCommand( "albouy", Cmd_Albouy_f, CMD_FL_GAME, "Answer" );
//cmdSystem->AddCommand( "arnold", Cmd_Arnold_f, CMD_FL_GAME, "Proposal" );
// do later
//cmdSystem->AddCommand( "shadowcaster", Cmd_Class_f, CMD_FL_GAME|CMD_FL_CHEAT, "Change character: shadowcaster #" );
//cmdSystem->AddCommand( "deliverance", Cmd_Deliverance_f, CMD_FL_GAME|CMD_FL_CHEAT, "pig mode" );
//cmdSystem->AddCommand( "locksmith", Cmd_Locksmith_f, CMD_FL_GAME|CMD_FL_CHEAT, "All keys" );
//cmdSystem->AddCommand( "mapsco", Cmd_Mapsco_f, CMD_FL_GAME|CMD_FL_CHEAT, "full map" );
//cmdSystem->AddCommand( "ravskel", Cmd_RavSkel_f, CMD_FL_GAME|CMD_FL_CHEAT, "obtain all skeleton keys" );
//cmdSystem->AddCommand( "cockadoodledoo", Cmd_Chicken_f, CMD_FL_GAME|CMD_FL_CHEAT, "chicken mode" );
//cmdSystem->AddCommand( "engage41", Cmd_Engage41_f, CMD_FL_GAME|CMD_FL_CHEAT, "deathmatch level" );
//cmdSystem->AddCommand( "idmus", Cmd_idMus_f, CMD_FL_GAME, "Select music track: idmus<01-31>" );
//cmdSystem->AddCommand( "sherlock", Cmd_Sherlock_f, CMD_FL_GAME|CMD_FL_CHEAT, "All puzzle pieces" );
// ORBIT : Zeroth
cmdSystem->AddCommand( "tommy", Cmd_WallWalk_f, CMD_FL_GAME|CMD_FL_CHEAT, "is it easter?" );
// HEXEN : Zeroth: EoC Settings Menu
cmdSystem->AddCommand( "eoc_vid_restart", Cmd_VidRestart_f, CMD_FL_RENDERER, "" );
cmdSystem->AddCommand( "eoc_guiUpdateSettings", Cmd_guiUpdateSettings_f, CMD_FL_SYSTEM, "used by the mainmenu GUI. determine which parts of the settings GUI should be visible and display the proper settings on it." );
// HEXEN : Zeroth
cmdSystem->AddCommand( "eoc_beaten", Cmd_Beaten_f, CMD_FL_GAME|CMD_FL_CHEAT, "used by the game to signify that you have completed this game release." );
cmdSystem->AddCommand( "hexinfo", Cmd_Hexinfo_f, CMD_FL_SYSTEM, "print information about this release." );
cmdSystem->AddCommand( "toggleFog", Cmd_ToggleFog_f, CMD_FL_GAME, "toggles fog." );
cmdSystem->AddCommand( "updateFog", Cmd_UpdateFog_f, CMD_FL_GAME, "toggles fog." );
//notineocalpha cmdSystem->AddCommand( "setClass", Cmd_SetClass_f, CMD_FL_GAME|CMD_FL_CHEAT, "set class, 0=cleric, 1=mage, 2=fighter." );
cmdSystem->AddCommand( "clearPersistentLevelInfo", Cmd_ClearPLI_f, CMD_FL_GAME|CMD_FL_CHEAT, "clear info about levels already visited." );
cmdSystem->AddCommand( "newGame", Cmd_NewGame_f, CMD_FL_GAME, "clear info about levels already visited." );
cmdSystem->AddCommand( "listTypeInfo", ListTypeInfo_f, CMD_FL_GAME, "list type info" );
cmdSystem->AddCommand( "writeGameState", WriteGameState_f, CMD_FL_GAME, "write game state" );
cmdSystem->AddCommand( "testSaveGame", TestSaveGame_f, CMD_FL_GAME|CMD_FL_CHEAT, "test a save game for a level" );
@ -2318,12 +3049,8 @@ void idGameLocal::InitConsoleCommands( void ) {
cmdSystem->AddCommand( "sayTeam", Cmd_SayTeam_f, CMD_FL_GAME, "team text chat" );
cmdSystem->AddCommand( "addChatLine", Cmd_AddChatLine_f, CMD_FL_GAME, "internal use - core to game chat lines" );
cmdSystem->AddCommand( "gameKick", Cmd_Kick_f, CMD_FL_GAME, "same as kick, but recognizes player names" );
cmdSystem->AddCommand( "give", Cmd_Give_f, CMD_FL_GAME|CMD_FL_CHEAT, "gives one or more items" );
cmdSystem->AddCommand( "centerview", Cmd_CenterView_f, CMD_FL_GAME, "centers the view" );
cmdSystem->AddCommand( "god", Cmd_God_f, CMD_FL_GAME|CMD_FL_CHEAT, "enables god mode" );
cmdSystem->AddCommand( "notarget", Cmd_Notarget_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables the player as a target" );
cmdSystem->AddCommand( "noclip", Cmd_Noclip_f, CMD_FL_GAME|CMD_FL_CHEAT, "disables collision detection for the player" );
cmdSystem->AddCommand( "kill", Cmd_Kill_f, CMD_FL_GAME, "kills the player" );
cmdSystem->AddCommand( "where", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
cmdSystem->AddCommand( "getviewpos", Cmd_GetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "prints the current view position" );
cmdSystem->AddCommand( "setviewpos", Cmd_SetViewpos_f, CMD_FL_GAME|CMD_FL_CHEAT, "sets the current view position" );
@ -2332,7 +3059,6 @@ void idGameLocal::InitConsoleCommands( void ) {
cmdSystem->AddCommand( "spawn", Cmd_Spawn_f, CMD_FL_GAME|CMD_FL_CHEAT, "spawns a game entity", idCmdSystem::ArgCompletion_Decl<DECL_ENTITYDEF> );
cmdSystem->AddCommand( "damage", Cmd_Damage_f, CMD_FL_GAME|CMD_FL_CHEAT, "apply damage to an entity", idGameLocal::ArgCompletion_EntityName );
cmdSystem->AddCommand( "remove", Cmd_Remove_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes an entity", idGameLocal::ArgCompletion_EntityName );
cmdSystem->AddCommand( "killMonsters", Cmd_KillMonsters_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all monsters" );
cmdSystem->AddCommand( "killMoveables", Cmd_KillMovables_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all moveables" );
cmdSystem->AddCommand( "killRagdolls", Cmd_KillRagdolls_f, CMD_FL_GAME|CMD_FL_CHEAT, "removes all ragdolls" );
cmdSystem->AddCommand( "addline", Cmd_AddDebugLine_f, CMD_FL_GAME|CMD_FL_CHEAT, "adds a debug line" );

View file

@ -123,8 +123,8 @@ idCVar g_debugTriggers( "g_debugTriggers", "0", CVAR_GAME | CVAR_BOOL, ""
idCVar g_debugCinematic( "g_debugCinematic", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_stopTime( "g_stopTime", "0", CVAR_GAME | CVAR_BOOL, "" );
idCVar g_damageScale( "g_damageScale", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "scale final damage on player by this factor" );
idCVar g_armorProtection( "g_armorProtection", "0.3", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" );
idCVar g_armorProtectionMP( "g_armorProtectionMP", "0.6", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" );
idCVar g_armorProtection( "g_armorProtection", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage" ); // HEXEN : Zeroth - 0.3 to 1
idCVar g_armorProtectionMP( "g_armorProtectionMP", "1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE, "armor takes this percentage of damage in mp" ); // HEXEN : Zeroth - 0.6 to 1
idCVar g_useDynamicProtection( "g_useDynamicProtection", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "scale damage and armor dynamically to keep the player alive more often" );
idCVar g_healthTakeTime( "g_healthTakeTime", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how often to take health in nightmare mode" );
idCVar g_healthTakeAmt( "g_healthTakeAmt", "5", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "how much health to take in nightmare mode" );
@ -149,6 +149,7 @@ idCVar g_showEnemies( "g_showEnemies", "0", CVAR_GAME | CVAR_BOOL, "draws
idCVar g_frametime( "g_frametime", "0", CVAR_GAME | CVAR_BOOL, "displays timing information for each game frame" );
idCVar g_timeentities( "g_timeEntities", "0", CVAR_GAME | CVAR_FLOAT, "when non-zero, shows entities whose think functions exceeded the # of milliseconds specified" );
idCVar g_enablePortalSky( "g_enablePortalSky", "1", CVAR_GAME | CVAR_BOOL, "enables the portal sky" ); // HEXEN : Zeroth
idCVar ai_debugScript( "ai_debugScript", "-1", CVAR_GAME | CVAR_INTEGER, "displays script calls for the specified monster entity number" );
idCVar ai_debugMove( "ai_debugMove", "0", CVAR_GAME | CVAR_BOOL, "draws movement information for monsters" );
idCVar ai_debugTrajectory( "ai_debugTrajectory", "0", CVAR_GAME | CVAR_BOOL, "draws trajectory tests for monsters" );
@ -279,7 +280,7 @@ idCVar g_gun_y( "g_gunY", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_gun_z( "g_gunZ", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_viewNodalX( "g_viewNodalX", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_viewNodalZ( "g_viewNodalZ", "0", CVAR_GAME | CVAR_FLOAT, "" );
idCVar g_fov( "g_fov", "90", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "" );
idCVar g_fov( "g_fov", "90", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_NOCHEAT, "" );
idCVar g_skipViewEffects( "g_skipViewEffects", "0", CVAR_GAME | CVAR_BOOL, "skip damage and other view effects" );
idCVar g_mpWeaponAngleScale( "g_mpWeaponAngleScale", "0", CVAR_GAME | CVAR_FLOAT, "Control the weapon sway in MP" );
@ -335,3 +336,21 @@ idCVar mod_validSkins( "mod_validSkins", "skins/characters/player/marine_mp
idCVar net_serverDownload( "net_serverDownload", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "enable server download redirects. 0: off 1: redirect to si_serverURL 2: use builtin download. see net_serverDl cvars for configuration" );
idCVar net_serverDlBaseURL( "net_serverDlBaseURL", "", CVAR_GAME | CVAR_ARCHIVE, "base URL for the download redirection" );
idCVar net_serverDlTable( "net_serverDlTable", "", CVAR_GAME | CVAR_ARCHIVE, "pak names for which download is provided, separated by ;" );
// HEXEN : Zeroth
// ****** thanks SnoopJeDi ( http://www.doom3world.org/phpbb2/viewtopic.php?f=56&t=12469&p=214427#p214427 )
idCVar s_music_vol( "s_music_vol", "0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE , "the volume in dB of all speakers with the s_music key set" );
// ******
// HEXEN : Zeroth
idCVar pm_flybob( "pm_flybob", "0.1", CVAR_GAME | CVAR_NETWORKSYNC | CVAR_FLOAT| CVAR_NOCHEAT, "bob much slower when flying" );
idCVar g_noHudAutoHide( "g_noHudAutohide", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE| CVAR_NOCHEAT, "don't auto-hide hud" );
idCVar g_noArtifactDescriptions( "g_noArtifactDescriptions", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE| CVAR_NOCHEAT, "when set, shows breif descriptions on hud of artifact when selected." );
idCVar r_vmode( "r_vmode", "0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE| CVAR_NOCHEAT, "resolution and fov presets" );
idCVar r_dofDelay( "r_dofDelay", "0.1", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE| CVAR_NOCHEAT, "How long it takes before stuff comes into focus. The higher the number, the quicker dof responds, 0 = instantaneous, 5 = very slow." );
idCVar r_dofRange( "r_dofRange", "10000", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE| CVAR_NOCHEAT, "How far the scan range is for dof." );
idCVar r_dof( "r_dof", "0", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE| CVAR_NOCHEAT, "whether Depth of Field is on or not." );
idCVar r_fog( "r_fog", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE| CVAR_NOCHEAT, "whether Fog is on or not." );
idCVar g_hellions( "g_hellions", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "whether hellions spawn if player camps." );
idCVar g_crosshairVis( "g_crosshairVis", "1", CVAR_ARCHIVE | CVAR_GAME | CVAR_BOOL | CVAR_NOCHEAT, "whether crosshair is visible." );
idCVar g_noPickupNotification( "g_noPickupNotification", "0", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Set to 1 to disable artifact pickup messages and sounds." );

View file

@ -118,6 +118,7 @@ extern idCVar g_vehicleSuspensionDown;
extern idCVar g_vehicleSuspensionKCompress;
extern idCVar g_vehicleSuspensionDamping;
extern idCVar g_vehicleTireFriction;
extern idCVar g_enablePortalSky; //Zeroth404
extern idCVar ik_enable;
extern idCVar ik_debug;
@ -250,8 +251,24 @@ extern idCVar si_spectators;
extern idCVar net_clientSelfSmoothing;
extern idCVar net_clientLagOMeter;
// HEXEN : Zeroth
extern idCVar g_noHudAutoHide;
extern idCVar g_noArtifactDescriptions;
extern idCVar pm_flybob;
extern idCVar g_noPickupNotification;
extern idCVar r_vmode;
extern idCVar r_dofDelay;
extern idCVar r_dofRange;
extern idCVar r_dof;
extern idCVar r_fog;
extern const char *si_gameTypeArgs[];
extern const char *ui_skinArgs[];
// HEXEN : Zeroth
// ****** thanks SnoopJeDi ( http://www.doom3world.org/phpbb2/viewtopic.php?f=56&t=12469&p=214427#p214427 )
extern idCVar s_music_vol;
// ******
#endif /* !__SYS_CVAR_H__ */