void Monster_SetTargets(edict_t *eMonster) { int iRelationship; if(!eMonster->monster.eTarget) { eMonster->monster.eTarget = Monster_GetTarget(eMonster); if(eMonster->monster.eTarget) { if((eMonster->monster.eTarget == eMonster->monster.eFriend) || (eMonster->monster.eTarget == eMonster->monster.eEnemy)) return; iRelationship = Monster_GetRelationship(eMonster,eMonster->monster.eTarget); if(iRelationship == RELATIONSHIP_LIKE) { eMonster->monster.eFriend = eMonster->monster.eTarget; eMonster->monster.eTarget = NULL; } else if(iRelationship == RELATIONSHIP_HATE) { eMonster->monster.eEnemy = eMonster->monster.eTarget; eMonster->monster.eTarget = NULL; } } } }
bool Waypoint_IsSafe(ServerEntity_t *eMonster,Waypoint_t *wPoint) { #if 0 ServerEntity_t *eMonsters; eMonsters = Engine.Server_FindRadius(wPoint->position,MONSTER_RANGE_NEAR); while(eMonsters) { // Check this by relationship rather than type. if(Monster_GetRelationship(eMonster,eMonsters) == MONSTER_RELATIONSHIP_HATE) return false; eMonsters = eMonsters->v.chain; } #endif return true; }
/* Sets the current targetted entity and checks if it's a valid enemy then updates eEnemy and eOldTarget. eTarget needs to be set first! Assumes that the target is visible... ~hogsy */ bool Monster_SetEnemy(edict_t *eMonster) { if(eMonster->monster.eTarget == eMonster) return false; if(eMonster->monster.eTarget != eMonster->monster.eOldTarget) { if(!eMonster->monster.eTarget->v.iHealth) return false; if(Monster_GetRelationship(eMonster,eMonster->monster.eTarget) == RELATIONSHIP_HATE) { eMonster->monster.eEnemy = eMonster->monster.eOldTarget = eMonster->monster.eTarget; eMonster->monster.eTarget = NULL; return true; } } return false; }
void Bot_Think(edict_t *eBot) { // If the bot isn't dead, then add animations. if(eBot->monster.iState != STATE_DEAD) { if(eBot->v.flags & FL_ONGROUND) { if(( (eBot->v.velocity[0] < -4.0f || eBot->v.velocity[0] > 4.0f) || (eBot->v.velocity[1] < -4.0f || eBot->v.velocity[1] > 4.0f)) && (!eBot->local.dAnimationTime || eBot->local.iAnimationEnd == 9)) Entity_Animate(eBot,PlayerAnimation_Walk); else if((eBot->v.velocity[0] == 0 || eBot->v.velocity[1] == 0) && (!eBot->local.dAnimationTime || eBot->local.iAnimationEnd > 9)) { #ifdef GAME_OPENKATANA if(eBot->v.iActiveWeapon == WEAPON_DAIKATANA) Entity_Animate(eBot,PlayerAnimation_KatanaIdle); else #endif Entity_Animate(eBot,PlayerAnimation_Idle); } } } switch(eBot->monster.iThink) { case THINK_IDLE: #if 1 // Add some random movement. ~hogsy if(rand()%120 == 0) { int iResult = rand()%3; if(iResult == 0) eBot->v.velocity[0] += BOT_MIN_SPEED; else if(iResult == 1) eBot->v.velocity[0] -= BOT_MIN_SPEED; iResult = rand()%3; if(iResult == 0) eBot->v.velocity[1] += BOT_MIN_SPEED; else if(iResult == 1) eBot->v.velocity[1] -= BOT_MIN_SPEED; eBot->v.angles[1] = Math_VectorToYaw(eBot->v.velocity); } else if(rand()%150 == 0) { Monster_Jump(eBot,200.0f); Entity_Animate(eBot,PlayerAnimation_Jump); } #endif break; case THINK_WANDERING: { edict_t *eTarget; Waypoint_t *wPoint; // Weapon_t *wMyWeapon; // vec3_t vAngle; eTarget = Monster_GetTarget(eBot); if(eTarget) { if(Monster_GetRelationship(eBot,eTarget) == RELATIONSHIP_HATE) { // [22/3/2013] Begin attacking next frame ~hogsy Monster_SetThink(eBot,THINK_ATTACKING); return; } } if(!eBot->monster.vTarget) { // [28/7/2012] TODO: Find specific waypoint such as an item ~hogsy wPoint = Waypoint_GetByVisibility(eBot->v.origin); if(wPoint) { if(wPoint->bOpen) { // [22/3/2013] TODO: Tell that current entity it's time to move... ~hogsy } Math_VectorCopy(wPoint->position,eBot->monster.vTarget); } } #if 0 wMyWeapon = Weapon_GetCurrentWeapon(eBot); if(MONSTER_GetRange(eBot,eBot->v.enemy->v.origin) > 4000) return; else if(wMyWeapon->iPrimaryType == AM_MELEE && MONSTER_GetRange(eBot,eBot->v.enemy->v.origin) > MONSTER_RANGE_MELEE) return; else if(Monster_IsVisible(eBot,eBot->v.enemy)) { // [5/8/2012] No ammo and it's not a melee weapon? ~hogsy if(!Weapon_CheckPrimaryAmmo(eBot) && wMyWeapon->iPrimaryType != AM_MELEE) { // [5/8/2012] Should probably flee ~hogsy Monster_SetThink(eBot,THINK_FLEEING); return; } Math_VectorSubtract(eBot->v.enemy->v.origin,eBot->v.origin,vAngle); // ent->v.ideal_yaw = VectorToAngles(vAngle); ChangeYaw(eBot); } #endif } break; } }