1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include "SWeaponManager.h"
#include "LegacyCpp/WeaponDef.h"
cSWeaponManager::cSWeaponManager(IAICallback* callback, cRAI* global)
{
G=global;
l=global->l;
cb=callback;
}
cSWeaponManager::~cSWeaponManager()
{
}
void cSWeaponManager::UnitFinished(int unit, sRAIUnitDef* udr)
{
if( udr->SWeapon == 0 )
return;
mWeapon.insert(irPair(unit,udr));
}
void cSWeaponManager::UnitDestroyed(int unit)
{
if( mWeapon.find(unit) != mWeapon.end() )
mWeapon.erase(unit);
}
void cSWeaponManager::UnitIdle(int unit, sRAIUnitDef* udr)
{
int stockPile;
int stockQued;
cb->GetProperty(unit,AIVAL_STOCKPILED,&stockPile);
cb->GetProperty(unit,AIVAL_STOCKPILE_QUED,&stockQued);
if( stockPile > 0 && udr->SWeapon->manualfire && G->Enemies.size() >= (G->UMobile.size()/25)+1 )
{
set<int> Targets;
set<int> ImmobileTargets;
for( map<int,EnemyInfo>::iterator iE=G->Enemies.begin(); iE!=G->Enemies.end(); ++iE )
{
if( cb->GetUnitPos(unit).distance(G->CM->GetEnemyPosition(iE->first,&iE->second)) <= udr->SWeapon->range )
{
if( iE->second.ud != 0 && iE->second.ud->speed == 0 )
ImmobileTargets.insert(iE->first);
else if( iE->second.inLOS || iE->second.inRadar )
Targets.insert(iE->first);
}
}
if( int(ImmobileTargets.size()) > 0 || int(Targets.size()) > 0 )
{
set<int>::iterator iE;
if( int(ImmobileTargets.size()) > 0 )
{
iE = ImmobileTargets.begin();
for( int i=0; i < rand()%int(ImmobileTargets.size()); i++ )
++iE;
}
else
{
iE = Targets.begin();
for( int i=0; i < rand()%int(Targets.size()); i++ )
++iE;
}
EnemyInfo *E = &G->Enemies.find(*iE)->second;
Command c;
c.id = CMD_ATTACK;
if( E->inLOS || E->inRadar )
c.params.push_back(*iE);
else
{
float3 Pos = G->CM->GetEnemyPosition(*iE,E);
c.params.push_back(Pos.x);
c.params.push_back(Pos.y);
c.params.push_back(Pos.z);
}
cb->GiveOrder(unit,&c);
return;
}
}
else if( stockPile+stockQued < 5 || (!udr->SWeapon->manualfire && stockPile+stockQued < 10) )
{
if( ((G->UDH->BLMetal->UDefActive == 0 && G->UDH->BLMetalL->UDefActive == 0)
|| 0.66*cb->GetMetalIncome() > udr->SWeapon->metalcost/udr->SWeapon->reload) &&
((G->UDH->BLEnergy->UDefActive == 0 && G->UDH->BLEnergyL->UDefActive == 0)
|| 0.66*cb->GetEnergyIncome() > udr->SWeapon->energycost/udr->SWeapon->reload) )
{
Command c;
c.id = CMD_STOCKPILE;
cb->GiveOrder(unit, &c);
return;
}
}
UnitInfo *UI = &G->Units.find(unit)->second;
if( UI->udrBL->task <= 1 )
{
Command c;
c.id = CMD_WAIT;
cb->GiveOrder(unit, &c);
}
}
void cSWeaponManager::Update()
{
for( map<int,sRAIUnitDef*>::iterator iU = mWeapon.begin(); iU!=mWeapon.end(); ++iU )
if( !G->IsHumanControled(iU->first,&G->Units.find(iU->first)->second) )
UnitIdle(iU->first,iU->second);
}
|