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