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