/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../g_local.h" #include "ai_local.h" void AI_SetUpAnimMoveFlags( edict_t *ent, usercmd_t *ucmd ) { int xyspeedcheck; vec3_t velocity; pmanim_t *pmAnim; pmAnim = &ent->pmAnim; //Update anim movement flags for monsters with ppms. if(ent->r.svflags & SVF_FAKECLIENT) return; //---------------------------------------- //splitmodels jal[start] //VectorSubtract( ent->s.origin, ent->s.old_origin, velocity ); VectorCopy( ent->velocity, velocity ); xyspeedcheck = sqrt(velocity[0]*velocity[0] + velocity[1]*velocity[1]); Com_Printf("XYspeed:%i\n", xyspeedcheck ); pmAnim->anim_moveflags = 0;//start from 0 if (ucmd->forwardmove < -1) pmAnim->anim_moveflags |= ANIMMOVE_BACK; else if (ucmd->forwardmove > 1) pmAnim->anim_moveflags |= ANIMMOVE_FRONT; if (ucmd->sidemove < -1) pmAnim->anim_moveflags |= ANIMMOVE_LEFT; else if (ucmd->sidemove > 1) pmAnim->anim_moveflags |= ANIMMOVE_RIGHT; if (xyspeedcheck > 20) pmAnim->anim_moveflags |= ANIMMOVE_RUN; else if (xyspeedcheck) pmAnim->anim_moveflags |= ANIMMOVE_WALK; //if (client->ps.pmove.pm_flags & PMF_DUCKED) // client->pmAnim.anim_moveflags |= ANIMMOVE_DUCK; } //AI_HELPERS // // Taken and modified (or not) from g_ai.c // //============= //visible //returns 1 if the entity is visible to self, even if not infront () //============= qboolean AI_visible (edict_t *self, edict_t *other) { vec3_t spot1; vec3_t spot2; trace_t trace; VectorCopy (self->s.origin, spot1); spot1[2] += self->viewheight; VectorCopy (other->s.origin, spot2); spot2[2] += other->viewheight; trap_Trace (&trace, spot1, vec3_origin, vec3_origin, spot2, self, MASK_OPAQUE); //trace = gi.trace( spot1, vec3_origin, vec3_origin, spot2, self, MASK_OPAQUE ); if (trace.fraction == 1.0) return qtrue; return qfalse; } //============= //infront //returns 1 if the entity is in front (in sight) of self //============= qboolean AI_infront (edict_t *self, edict_t *other) { vec3_t vec; float dot; vec3_t forward; AngleVectors( self->s.angles, forward, NULL, NULL ); VectorSubtract( other->s.origin, self->s.origin, vec ); VectorNormalizeFast( vec ); dot = DotProduct( vec, forward ); if(dot > 0.3) return qtrue; return qfalse; } //============= //inView //returns 1 if the entity is in view field to self (in front and not blocked) //============= qboolean AI_inView (edict_t *self, edict_t *other) { vec3_t vec; float dot; vec3_t forward; float MONSTER_VIEWDISTANCE = 1000.0f;//jalfixme: make a class based field float MONSTER_VIEWSIZE = 0.3f;//jalfixme: make a class based field //too far away for our view capabilities if( DistanceFast(self->s.old_origin, other->s.origin) > MONSTER_VIEWDISTANCE ) return qfalse; //check if in front AngleVectors (self->s.angles, forward, NULL, NULL); VectorSubtract (other->s.origin, self->s.origin, vec); VectorNormalizeFast (vec); dot = DotProduct (vec, forward); if( dot < MONSTER_VIEWSIZE ) return qfalse; if( !AI_visible (self, other) ) //bloqued return qfalse; return qtrue; } //============= //AI_Sounds // //============= //========================================== // // COMMANDS // //========================================== void Cmd_ShowPLinks_f( edict_t *ent ) { if( !sv_cheats->integer ) { G_PrintMsg( ent, "Cheats are not enabled in this server\n" ); AIDevel.showPLinks = qfalse; AIDevel.plinkguy = NULL; return; } if (AIDevel.showPLinks == qfalse) { AIDevel.showPLinks = qtrue; AIDevel.plinkguy = ent; } else { AIDevel.showPLinks = qfalse; AIDevel.plinkguy = NULL; } } void AITools_SaveNodes( void ); void AITools_InitEditnodes( void ); void AITools_InitMakenodes( void ); void AITools_AddBotRoamNode(void); void M_default_Spawn( void ); /* //========================================== // BOT_Commands // Special command processor //========================================== qboolean BOT_Commands(edict_t *ent) { char *cmd; cmd = trap_Cmd_Argv(0); // show plinks at current node if(Q_stricmp (cmd, "showplinks") == 0) { if (AIDevel.showPLinks == qfalse) { AIDevel.showPLinks = qtrue; AIDevel.plinkguy = ent; } else { AIDevel.showPLinks = qfalse; AIDevel.plinkguy = NULL; } return qtrue; } return qfalse; } */ //========================================== // BOT_ServerCommand // Special server command processor //========================================== qboolean BOT_ServerCommand (void) { char *cmd; cmd = trap_Cmd_Argv (1); // debug if(Q_stricmp (cmd, "botdebug") == 0) AIDebug_ToogleBotDebug(); // addbot else if( !Q_stricmp (cmd, "addbot") ) { BOT_SpawnBot( trap_Cmd_Argv(2) ); //team "red", "blue", etc } // removebot else if( !Q_stricmp (cmd, "removebot")) BOT_RemoveBot(trap_Cmd_Argv(2)); else if( !Q_stricmp (cmd, "editnodes") ) AITools_InitEditnodes(); else if( !Q_stricmp (cmd, "makenodes") ) AITools_InitMakenodes(); else if( !Q_stricmp (cmd, "savenodes") ) AITools_SaveNodes(); else if( !Q_stricmp (cmd, "addnode") || !Q_stricmp (cmd, "dropnode") ) AITools_AddNode_Cmd(); else if( !Q_stricmp (cmd, "addbotroam") ) AITools_AddBotRoamNode_Cmd(); else if( !Q_stricmp (cmd, "addmonster") ) M_default_Spawn(); else return qfalse; return qtrue; }