1
2 #include "spring_api.h"
3
4 #include <iterator>
5 #include <stdlib.h>
6
7 #include "SpringUnitType.h"
8 #include "SpringMap.h"
9
10 #include "ExternalAI/Interface/AISCommands.h" // for UNIT_COMMAND_BUILD_NO_FACING
11
CSpringMap(springai::OOAICallback * callback,CSpringGame * game)12 CSpringMap::CSpringMap(springai::OOAICallback* callback, CSpringGame* game)
13 : callback(callback),
14 game(game),
15 metal(NULL), map(callback->GetMap()), lastMapFeaturesUpdate(-1) {
16
17 std::vector<springai::Resource*> resources = callback->GetResources();
18 if ( !resources.empty() ) {
19
20 std::vector<springai::Resource*>::iterator i = resources.begin();
21 for(;i != resources.end();++i){
22 springai::Resource* r = *i;
23 std::string name = r->GetName();
24 if(name == "Metal"){
25 this->metal = r;
26 break;
27 } else {
28 delete r;
29 }
30 }
31 }
32
33 if(metal){
34 this->GetMetalSpots();
35 }
36 }
37
~CSpringMap()38 CSpringMap::~CSpringMap(){
39 this->metalspots.clear();
40 game = NULL;
41 callback = NULL;
42 delete map;
43 map = NULL;
44 delete metal;
45 for (std::vector<IMapFeature*>::iterator i = mapFeatures.begin(); i != mapFeatures.end(); ++i) {
46 delete (*i);
47 }
48 mapFeatures.clear();
49 }
50
FindClosestBuildSite(IUnitType * t,Position builderPos,double searchRadius,double minimumDistance)51 Position CSpringMap::FindClosestBuildSite(IUnitType* t, Position builderPos, double searchRadius, double minimumDistance){
52 return this->FindClosestBuildSiteFacing(t,builderPos,searchRadius,minimumDistance,UNIT_COMMAND_BUILD_NO_FACING);
53 }
54
FindClosestBuildSiteFacing(IUnitType * t,Position builderPos,double searchRadius,double minimumDistance,int facing)55 Position CSpringMap::FindClosestBuildSiteFacing(IUnitType* t, Position builderPos, double searchRadius, double minimumDistance,int facing){
56 if ((t == NULL) || (callback==NULL)){
57 return Position(0.0f, 1.0f, 0.0f);
58 }
59 CSpringUnitType* ut = static_cast<CSpringUnitType*>(t);
60 const springai::AIFloat3 bPos(builderPos.x, builderPos.y, builderPos.z);
61 const springai::AIFloat3 pos = map->FindClosestBuildSite(ut->GetUnitDef(), bPos, searchRadius, minimumDistance, facing);
62 Position p;
63 p.x = pos.x;
64 p.y = pos.y;
65 p.z = pos.z;
66 return p;
67 }
68
CanBuildHere(IUnitType * t,Position p)69 bool CSpringMap::CanBuildHere(IUnitType* t, Position p){
70 return this->CanBuildHereFacing(t,p,UNIT_COMMAND_BUILD_NO_FACING);
71 }
72
CanBuildHereFacing(IUnitType * t,Position p,int facing)73 bool CSpringMap::CanBuildHereFacing(IUnitType* t, Position p, int facing){
74 CSpringUnitType* ut = static_cast<CSpringUnitType*>(t);
75 const springai::AIFloat3 pos(p.x, p.y, p.z);
76 return map->IsPossibleToBuildAt( ut->GetUnitDef(), pos, facing );
77 }
78
SpotCount()79 int CSpringMap::SpotCount(){
80 return metalspots.size();
81 }
82
GetSpot(int idx)83 Position CSpringMap::GetSpot(int idx){
84 return metalspots[idx];
85 }
86
GetMetalSpots()87 std::vector<Position>& CSpringMap::GetMetalSpots(){
88 metal = this->GetMetalResource();
89 metalspots.clear();
90 std::vector<springai::AIFloat3> positions = map->GetResourceMapSpotsPositions( metal );
91 if ( !positions.empty() ) {
92 std::vector<springai::AIFloat3>::iterator j = positions.begin();
93 for(;j != positions.end();++j){
94 Position p;
95 p.x = j->x;
96 p.y = j->y;
97 p.z = j->z;
98 metalspots.push_back(p);
99 }
100 }
101 return metalspots;
102 }
103
MapDimensions()104 Position CSpringMap::MapDimensions(){
105 Position p;
106 p.x = map->GetWidth();
107 p.z = map->GetHeight();
108
109 return p;
110 }
111
MapName()112 std::string CSpringMap::MapName(){
113 return map->GetName();
114 }
115
MaximumHeight()116 float CSpringMap::MaximumHeight(){
117 return map->GetMaxHeight();
118 }
119
MinimumHeight()120 float CSpringMap::MinimumHeight(){
121 return map->GetMinHeight();
122 }
123
AverageWind()124 double CSpringMap::AverageWind(){
125 float minwind = map->GetMinWind();
126 float maxwind = map->GetMaxWind();
127 return (minwind+maxwind)/2;
128 }
129
MinimumWindSpeed()130 double CSpringMap::MinimumWindSpeed(){
131 return map->GetMinWind();
132 }
133
MaximumWindSpeed()134 double CSpringMap::MaximumWindSpeed(){
135 return map->GetMaxWind();
136 }
137
TidalStrength()138 double CSpringMap::TidalStrength(){
139 return map->GetTidalStrength();
140 }
141
GetMapFeatureIteratorById(int id)142 std::vector<IMapFeature*>::iterator CSpringMap::GetMapFeatureIteratorById(int id) {
143 for (std::vector<IMapFeature*>::iterator i = mapFeatures.begin(); i != mapFeatures.end(); ++i) {
144 if ((*i)->ID() == id) {
145 return i;
146 }
147 }
148 return mapFeatures.end();
149 }
150
UpdateMapFeatures()151 void CSpringMap::UpdateMapFeatures() {
152 std::vector<IMapFeature*> newMapFeatures;
153 if(lastMapFeaturesUpdate != game->Frame()) {
154 std::vector<springai::Feature*> features = callback->GetFeatures();
155 std::vector<springai::Feature*>::iterator i = features.begin();
156
157 for(;i != features.end(); ++i){
158 std::vector<IMapFeature*>::iterator obj = GetMapFeatureIteratorById((*i)->GetFeatureId());
159 if(obj != mapFeatures.end()) { //feature was already present, keep old object.
160 newMapFeatures.push_back(*obj);
161 mapFeatures.erase(obj); //remove from old map.
162 } else { //feature was not yet presend, add new one.
163 CSpringMapFeature* f = new CSpringMapFeature(callback,*i,game);
164 newMapFeatures.push_back(f);
165 }
166 }
167
168 //clear up old features that spring api did not deliver => they got deleted.
169 for(std::vector<IMapFeature*>::iterator i = mapFeatures.begin(); i != mapFeatures.end(); ++i) {
170 delete (*i);
171 }
172
173 mapFeatures = newMapFeatures;
174 lastMapFeaturesUpdate = game->Frame();
175 }
176 }
177
GetMapFeatures()178 std::vector<IMapFeature*> CSpringMap::GetMapFeatures(){
179 UpdateMapFeatures();
180 return mapFeatures;
181 }
182
GetMapFeaturesAt(Position p,double radius)183 std::vector<IMapFeature*> CSpringMap::GetMapFeaturesAt(Position p, double radius){
184 const springai::AIFloat3 pos(p.x, p.y, p.z);
185 UpdateMapFeatures();
186 std::vector<IMapFeature*> results;
187
188 std::vector<springai::Feature*> features = callback->GetFeaturesIn(pos,radius);
189 std::vector<springai::Feature*>::iterator i = features.begin();
190 for(;i != features.end(); ++i){
191 std::vector<IMapFeature*>::iterator obj = GetMapFeatureIteratorById((*i)->GetFeatureId());
192 if(obj != mapFeatures.end()) {
193 results.push_back(*obj);
194 } else { //can this ever happen?
195 CSpringMapFeature* f = new CSpringMapFeature(callback,*i,game);
196 mapFeatures.push_back(f);
197 results.push_back(f);
198 }
199 }
200 return results;
201 }
202
GetMetalResource()203 springai::Resource* CSpringMap::GetMetalResource(){
204 return metal;
205 }
206