avp/src/avp/ai_sight.c
2019-08-20 02:09:04 +02:00

198 lines
5.3 KiB
C

/*KJL*****************************************
* AI_Sight.c handles the NPC's visual senses *
*****************************************KJL*/
#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "gamedef.h"
#include "dynblock.h"
#include "dynamics.h"
#include "los.h"
#include "ShowCmds.h"
#include "equipmnt.h"
#include "bh_marin.h"
#include "bh_xeno.h"
#include "targeting.h"
#include "bh_weap.h"
#include "AI_Sight.h"
#define UseLocalAssert Yes
#include "ourasert.h"
extern int MarineSight_FrustrumReject(STRATEGYBLOCK *sbPtr,VECTORCH *localOffset,STRATEGYBLOCK *target);
extern int FrisbeeSight_FrustrumReject(STRATEGYBLOCK *sbPtr,VECTORCH *localOffset,STRATEGYBLOCK *target);
int NPCCanSeeTarget(STRATEGYBLOCK *sbPtr, STRATEGYBLOCK *target, int viewRange)
{
int frustrum_test;
/* connect eyeposition to head */
VECTORCH eyePosition = {0,-1500,0};
LOCALASSERT(target);
LOCALASSERT(sbPtr);
if (target->containingModule==NULL) {
return(0);
}
if (sbPtr->containingModule==NULL) {
return(0);
}
if ((target->SBdptr==NULL)||(sbPtr->SBdptr==NULL)) {
if ((IsModuleVisibleFromModule(target->containingModule,sbPtr->containingModule))) {
return(1);
} else {
return(0);
}
} else {
switch (sbPtr->I_SBtype) {
case I_BehaviourFrisbee:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
FRISBEE_BEHAV_BLOCK *frisbeeStatusPointer;
SECTION_DATA *disc_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
frisbeeStatusPointer = (FRISBEE_BEHAV_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(frisbeeStatusPointer);
/* Arc reject. */
disc_sec=GetThisSectionData(frisbeeStatusPointer->HModelController.section_data,"Mdisk");
if (disc_sec) {
WtoL=disc_sec->SecMat;
sourcepos=disc_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=FrisbeeSight_FrustrumReject(sbPtr,&offset,target);
}
break;
case I_BehaviourMarine:
case I_BehaviourSeal:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
MARINE_STATUS_BLOCK *marineStatusPointer;
SECTION_DATA *head_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(marineStatusPointer);
/* Arc reject. */
head_sec=GetThisSectionData(marineStatusPointer->HModelController.section_data,"head");
if (head_sec) {
WtoL=head_sec->SecMat;
sourcepos=head_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=MarineSight_FrustrumReject(sbPtr,&offset,target);
}
break;
case I_BehaviourXenoborg:
{
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
XENO_STATUS_BLOCK *xenoStatusPointer;
SECTION_DATA *head_sec;
LOCALASSERT(sbPtr);
LOCALASSERT(sbPtr->containingModule);
xenoStatusPointer = (XENO_STATUS_BLOCK *)(sbPtr->SBdataptr);
LOCALASSERT(xenoStatusPointer);
/* Arc reject. */
head_sec=GetThisSectionData(xenoStatusPointer->HModelController.section_data,"head");
if (head_sec) {
WtoL=head_sec->SecMat;
sourcepos=head_sec->World_Offset;
} else {
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
}
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=XenoSight_FrustrumReject(sbPtr,&offset);
}
break;
case I_BehaviourAutoGun:
{
/* Less pretentious, based on the SB. */
MATRIXCH WtoL;
VECTORCH offset, sourcepos, targetpos;
/* Arc reject. */
WtoL=sbPtr->DynPtr->OrientMat;
GetTargetingPointOfObject_Far(sbPtr,&sourcepos);
GetTargetingPointOfObject_Far(target,&targetpos);
offset.vx=sourcepos.vx-targetpos.vx;
offset.vy=sourcepos.vy-targetpos.vy;
offset.vz=sourcepos.vz-targetpos.vz;
TransposeMatrixCH(&WtoL);
RotateVector(&offset,&WtoL);
frustrum_test=AGunSight_FrustrumReject(&offset);
}
break;
default:
frustrum_test=1;
break;
}
if (frustrum_test) {
RotateVector(&eyePosition,&(sbPtr->DynPtr->OrientMat));
eyePosition.vx += sbPtr->DynPtr->Position.vx;
eyePosition.vy += sbPtr->DynPtr->Position.vy;
eyePosition.vz += sbPtr->DynPtr->Position.vz;
return IsThisObjectVisibleFromThisPosition_WithIgnore(target->SBdptr,sbPtr->SBdptr,&eyePosition,NPC_MAX_VIEWRANGE);
}
}
return(0);
}