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