-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuturemesh.js
294 lines (294 loc) · 98.9 KB
/
futuremesh.js
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
"use strict";var EventDrivenPlugin;EventDrivenPlugin=function(){var gamePlayInstance;this.handleEvent=function(eventName,eventData){throw new Error('Not implemented yet.');};this.getObservedEvents=function(){throw new Error('Not implemented yet.');};this.sendEvent=function(eventName,eventData){gamePlayInstance.sendEvent(eventName,eventData);};this.setGamePlay=function(gamePlay){gamePlayInstance=gamePlay;};};"use strict";var ScheduledPlugin;ScheduledPlugin=function(){var gamePlayInstance;this.handleTick=function(){throw new Error('Not implemented yet.');};this.ignoresExtraTicks=function(){return false;};this.sendEvent=function(eventName,eventData){gamePlayInstance.sendEvent(eventName,eventData);};this.setGamePlay=function(gamePlay){gamePlayInstance=gamePlay;};};"use strict";var MixedPlugin;MixedPlugin=function(){var gamePlayInstance;this.handleEvent=function(eventName,eventData){throw new Error('Not implemented yet.');};this.getObservedEvents=function(){throw new Error('Not implemented yet.');};this.sendEvent=function(eventName,eventData){gamePlayInstance.sendEvent(eventName,eventData);};this.setGamePlay=function(gamePlay){gamePlayInstance=gamePlay;MixedPlugin.prototype.setGamePlay(gamePlay);};};MixedPlugin.prototype=new ScheduledPlugin();"use strict";var UIPlugin;UIPlugin=function(){var gamePlayInstance;this.renderFrame=function(){throw new Error("Not implemented yet");};this.handleEvent=function(eventName,eventData){throw new Error('Not implemented yet.');};this.getObservedEvents=function(){throw new Error('Not implemented yet.');};this.sendEvent=function(eventName,eventData){gamePlayInstance.sendEvent(eventName,eventData);};this.setGamePlay=function(gamePlay){gamePlayInstance=gamePlay;};};"use strict";var Music;Music=function(){var playlist,playing,current,prepareSong,defaultContainer,volume,instance,loop,observers,notifyObservers;playlist=[];playing=false;current=0;defaultContainer=document.body;volume=1;instance=this;loop=true;observers=[];this.play=function(){if(!playlist.length){throw new Error('Cannot play empty playlist');}
playlist[current].audio.play();playing=true;};this.pause=function(){if(!playlist.length){throw new Error('Cannot play empty playlist');}
playlist[current].audio.pause();playing=false;};this.stop=function(){if(!playlist.length){throw new Error('Cannot play empty playlist');}
playlist[current].audio.stop();playing=false;};this.next=function(){if(!playlist.length){throw new Error('cannot skip to next song of empty playlist');}
this.stop();if(loop||((current+1)<playlist.length)){current=(current+1)%playlist.length;this.play();}};this.previous=function(){if(!playlist.length){throw new Error('Cannot play empty playlist');}
this.stop();if(loop||current){current?--current:(current=playlist.length-1);this.play();}};this.isPlaying=function(){return playing;};this.getCurrentTrack=function(){return current;};this.getCurrentTime=function(){return playlist[current].audio.getCurrentTime();};this.setLoop=function(newLoop){loop=newLoop;};this.getLoop=function(){return loop;};this.fadeToSong=function(next,speed,way){var start,interval;if(!playlist[next]){throw new Error('song of this index is not in playlist');}
if(next===current){throw new Error('cannot fade to the same song');}
if(!(way instanceof Function)){way=function(x){return x;};}
if(!speed){speed=0.5;}
speed*=1000;start=(new Date()).getTime();playlist[next].audio.setVolume(0);playlist[next].audio.play();interval=setInterval(function(){var offset;offset=(new Date()).getTime()-start;offset=offset>speed?speed:offset;offset=way(offset/speed);playlist[current].audio.setVolume(volume*(1-offset));playlist[next].audio.setVolume(volume*offset);if(offset>=1){playlist[current].audio.stop();clearInterval(interval);current=next;}},10);};this.setPlaylist=function(newPlaylist){var i;if(!(newPlaylist instanceof Array)){throw new Error('Playlist has to be an array');}
playlist=newPlaylist;for(i=playlist.length;i--;){prepareSong(playlist[i]);}};this.appendSong=function(song){prepareSong(song);playlist.push(song);};this.setContainer=function(container){defaultContainer=container;};this.setVolume=function(newVolume){var i;volume=newVolume;for(i=playlist.length;i--;){playlist[i].audio.setVolume(volume);}};this.addLoadingObserver=function(observer){if(!(observer instanceof Function)){throw new Error('observer has to be a function');}
observers.push(observer);};notifyObservers=function(){var i,count;count=0;for(i=playlist.length;i--;){count+=playlist[i].loaded?1:0;}
count/=playlist.length;for(i=observers.length;i--;){observers[i](count);}};prepareSong=function(song){song.loaded=false;song.audio=new Audio(song.src,{duration:song.duration,container:defaultContainer,volume:volume,onload:function(){song.loaded=true;notifyObservers();},onended:function(){instance.next();}});};};"use strict";var GameMusic;GameMusic=function(){var playlists,fadeDuration,intensity,song,volume,songDurations,loadedSongs,loaded,loadingObservers,playing,crossFadeTimeout,crossFading,crossFadeQueue;function findIntensity(wantedIntensity){var playlistIntensity,bestIntensity;bestIntensity=0;for(playlistIntensity in playlists){if(!playlists.hasOwnProperty(playlistIntensity)){continue;}
if(Math.abs(wantedIntensity-playlistIntensity)<Math.abs(wantedIntensity-bestIntensity)){bestIntensity=playlistIntensity;}}
return bestIntensity;}
function prepareSongCrossFade(nextIntensity,nextSong,now,continious){var interval,i;if(crossFading){crossFadeQueue.push({intensity:nextIntensity,song:nextSong,now:true,continious:continious});return;}
crossFadeTimeout&&clearTimeout(crossFadeTimeout);crossFadeTimeout=setTimeout(function(){var start,nextFade;crossFading=true;start=(new Date()).getTime();playlists[nextIntensity][nextSong].setVolume(0);playlists[nextIntensity][nextSong].play();interval=setInterval(function(){var current,progress;current=(new Date()).getTime();progress=(current-start)/fadeDuration;if(progress<=1){playlists[intensity][song].setVolume((1-progress)*volume);playlists[nextIntensity][nextSong].setVolume(progress*volume);}else{clearInterval(interval);playlists[intensity][song].stop();intensity=nextIntensity;song=nextSong;crossFading=false;crossFadeQueue.push({intensity:intensity,song:(song+1)%playlists[intensity].length,now:false,continious:true});nextFade=crossFadeQueue.shift();prepareSongCrossFade(nextFade.intensity,nextFade.song,nextFade.now,nextFade.continious);}},10);crossFadeTimeout=null;},now?1:(songDurations[intensity][song]*1000-
(continious?2*fadeDuration:fadeDuration)));}
this.play=function(){var interval,startTime;if(playing){throw new Error('GameMusic: Already playing music');}
song=Math.floor(Math.random()*playlists[intensity].length);playlists[intensity][song].setVolume(0);playlists[intensity][song].play();startTime=(new Date()).getTime();interval=setInterval(function(){var now;now=(new Date()).getTime();if(now-startTime<fadeDuration){playlists[intensity][song].setVolume((now-startTime)/fadeDuration*volume);}else{playlists[intensity][song].setVolume(volume);clearInterval(interval);}},10);playing=true;prepareSongCrossFade(intensity,(song+1)%playlists[intensity].length,false,false);};this.stop=function(){var interval,startTime;if(!playing){throw new Error('GameMusic: The music is not playing');}
crossFadeTimeout&&clearTimeout(crossFadeTimeout);startTime=(new Date()).getTime();interval=setInterval(function(){var now;now=(new Date()).getTime();if(now-startTime<fadeDuration){playlists[intensity][song].setVolume((1-(now-startTime)/fadeDuration)*volume);}else{playlists[intensity][song].stop();clearInterval(interval);playing=false;}},10);};this.setIntensity=function(newIntensity){var i;if((newIntensity<0)||(newIntensity>1)){throw new Error('GameMusic: The intensity must be within range [0, 1]');}
newIntensity=findIntensity(newIntensity);if(newIntensity==intensity){return;}
if(playing){crossFadeQueue=[];prepareSongCrossFade(newIntensity,Math.floor(Math.random()*playlists[newIntensity].length),true,false);}else{intensity=newIntensity;}};this.registerLoadingObserver=function(observer){if(loaded){observer(1);return;}
loadingObservers.push(observer);};playlists=Settings.gameMusic.playlists;fadeDuration=Settings.gameMusic.fadeDuration;volume=Settings.gameMusic.volume;intensity=findIntensity(0);loadedSongs={};songDurations={};loaded=false;loadingObservers=[];playing=false;crossFadeQueue=[];(function(){var playlistIntensity,playlist,i;function loadingCallback(){var songCount,loadedCount,playlistIntensity;songCount=0;loadedCount=0;for(playlistIntensity in playlists){if(!playlists.hasOwnProperty(playlistIntensity)){continue;}
songCount+=playlists[playlistIntensity].length;playlists[playlistIntensity].forEach(function(loaded){loaded&&loadedCount++;});}
loadingObservers.forEach(function(observer){observer(loadedCount/songCount);});loaded=loadedCount==songCount;}
for(playlistIntensity in playlists){if(!playlists.hasOwnProperty(playlistIntensity)){continue;}
playlist=playlists[playlistIntensity];loadedSongs[playlistIntensity]=[];songDurations[playlistIntensity]=[];for(i=playlist.length;i--;){loadedSongs[playlistIntensity][i]=false;songDurations[playlistIntensity][i]=playlist[i].duration;(function(intensityIndex,songIndex){playlist[i]=new Audio(playlist[i].src,{volume:volume,onload:function(){loadedSongs[intensityIndex][songIndex]=true;loadingCallback();}});}(playlistIntensity,i));}}}());};"use strict";(function(){var Audio,defaultContainer,getExtension,createAudio;defaultContainer=false;getExtension=function(path){return path.substring(path.lastIndexOf('.')+1).toLowerCase();};createAudio=function(src,options){var audio,source,i;if(typeof src==='string'){src=[src];}
audio=document.createElement('audio');audio.volume=options.volume!==undefined?options.volume:1;audio.setAttribute('preload','auto');if(options.controls){audio.setAttribute('controls','controls');}
audio.autobuffer=true;if(options.loop){audio.loop=true;}
for(i=src.length;i--;){source=document.createElement('source');source.setAttribute('type','audio/'+
(getExtension(src[i])==='ogg'?'ogg':'mpeg'));source.setAttribute('src',src[i]);audio.appendChild(source);}
audio.load();return audio;};Audio=function(src,options){var audio,i,runOnEnded,container,duration,playOffset,playStart,instance;instance=this;if(!defaultContainer){defaultContainer=document.body;}
container=options.container?options.container:defaultContainer;audio=createAudio(src,options);duration=options.duration||audio.duration;if(options.onload instanceof Function){i=setInterval(function(){if(audio.readyState===4){clearInterval(i);if(!duration){duration=audio.duration;}
options.onload();}},10);}
playOffset=0;runOnEnded=false;if(options.onended instanceof Function){if(!duration){throw new Error('Cannot use onended without duration info');}
setInterval(function(){if(!runOnEnded&&(instance.getCurrentTime()>=duration)){runOnEnded=true;instance.stop();options.onended();}},10);}
this.isLoaded=function(){return audio.readyState===4;};this.play=function(){audio.play();playStart=(new Date()).getTime();runOnEnded=false;};this.pause=function(){audio.pause();playOffset+=((new Date()).getTime()-playStart)/1000;};this.stop=function(){audio.pause();playOffset=0;audio.parentNode.removeChild(audio);audio=createAudio(src,options);container.appendChild(audio);};this.playFromStart=function(){this.stop();this.play();};this.isPaused=function(){return audio.paused;};this.getCurrentTime=function(){if(!duration){throw new Error('cannot determine current time without duration info');}
return playOffset+(this.isPaused()?0:((new Date()).getTime()-playStart)/1000);};this.getVolume=function(){return audio.volume;};this.setVolume=function(volume){audio.volume=volume;};container.appendChild(audio);};Audio.setDefaultContainer=function(container){defaultContainer=container;};window.Audio=Audio;}());"use strict";var Unit;(function(){var id;id=0;Unit=function(x,y,direction,type,player,color){var definition,tileWidth,tileHeight;definition=UnitsDefinition.getType(type);tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=(TilesDefinition.getType(0).imageData.height/2-1)*2;this.id=id++;this.x=x;this.y=y;this.lastX=x;this.lastY=y;this.direction=direction;this.type=type;this.image=definition.image;this.speed=definition.speed;this.turnSpeed=definition.turnSpeed;this.action=0;this.player=player;this.colorify=definition.colorify;this.colorifyDistance=definition.colorifyDistance;this.race=definition.race;this.moveOffset=0;this.moveOffsetX=0;this.moveOffsetY=0;this.turningAzimuth=0;this.turningProgress=0;this.moveTargetX=null;this.moveTargetX=null;this.waypoints=[];this.color=color===undefined?Player.getPlayer(player).color:color;this.move=function(distance){var lastX,lastY;lastX=this.x;lastY=this.y;if(distance>1){this.move(distance-1);}
this.lastX=lastX;this.lastY=lastY;switch(this.direction){case 0:this.y-=2;break;case 1:this.x+=this.y%2;this.y-=1;break;case 2:this.x+=1;break;case 3:this.x+=this.y%2;this.y+=1;break;case 4:this.y+=2;break;case 5:this.x-=1-(this.y%2);this.y+=1;break;case 6:this.x-=1;break;case 7:this.x-=1-(this.y%2);this.y-=1;break;}
this.setMoveOffset(0);this.action=2;};this.getCoordinatesAtDirection=function(azimut){var originalDirection,coordinates;if(azimut<0){azimut%=8;azimut+=8;}
originalDirection=this.direction;this.direction=(this.direction+azimut)%8;coordinates=this.getAheadCoordinates();this.direction=originalDirection;return coordinates;};this.getAheadCoordinates=function(){var coordinates;coordinates={x:this.x,y:this.y};switch(this.direction){case 0:coordinates.y-=2;break;case 1:coordinates.x+=this.y%2;coordinates.y-=1;break;case 2:coordinates.x+=1;break;case 3:coordinates.x+=this.y%2;coordinates.y+=1;break;case 4:coordinates.x+=2;break;case 5:coordinates.x-=1-(this.y%2);coordinates.y+=1;break;case 6:coordinates.x-=1;break;case 7:coordinates.x-=1-(this.y%2);coordinates.y-=1;break;}
return coordinates;};this.setMoveOffset=function(offset){this.moveOffset=offset;offset=(1000-offset)/1000;if((this.direction>=1)&&(this.direction<=3)){this.moveOffsetX=tileWidth*offset*(this.direction===2?1:0.5);}
if(this.direction>=5){this.moveOffsetX=-tileWidth*offset*(this.direction===6?1:0.5);}
if((this.direction===7)||(this.direction<=1)){this.moveOffsetY=-tileHeight*offset*(this.direction===0?1:0.5);}
if((this.direction>=3)&&(this.direction<=5)){this.moveOffsetY=tileHeight*offset*(this.direction===4?1:0.5);}};this.exportData=function(){return{x:this.x,y:this.y,direction:this.direction,type:this.type,player:this.player};};};Unit.importData=function(data){return new Unit(data.x,data.y,data.direction,data.type,data.player);};}());"use strict";var Tile;Tile=function(type){var definition;definition=TilesDefinition.getType(type);this.type=type;this.image=definition.image;this.accessible=definition.accessible;this.minimap=definition.minimap;this.resource=definition.resource;this.lightSfx=0;this.exportData=function(){return{type:this.type,lightSfx:this.lightSfx};};};Tile.importData=function(data){var tile;tile=new Tile(data.type);tile.lightSfx=data.lightSfx;return tile;};"use strict";var Settings;Settings={tileSize:undefined,heightScale:undefined,tileWidth:undefined,tileHeight:undefined,gridIndexGranularity:undefined,tileImagesTransformed:false,buildingImagesTransformed:false,unitImagesTransformed:false,sfx3DLightFactor:undefined,sfx3DLightColor:undefined,sfxBuildLayerColor:undefined,sfxAccessibleTileColor:undefined,sfxInaccessibleTileColor:undefined,mouseWheelSpeed:undefined,loadingMusic:[],loadingMusicVolume:1,loadingMusicLength:undefined,gameMusic:{playlists:{0:[]},fadeDuration:3500,volume:0.7},tickDuration:30,maxTicks:3,gamePlayPlugins:[],pluginConfiguration:{},load:function(settings){this.tileSize=settings.tileSize;this.heightScale=settings.heightScale;this.tileWidth=this.tileSize*Math.cos(Math.PI/4)*2;this.tileHeight=this.tileSize*Math.sin(Math.PI/4)*2*this.heightScale;this.gridIndexGranularity=settings.gridIndexGranularity;if(settings.tileImagesTransformed!==undefined){this.tileImagesTransformed=settings.tileImagesTransformed;}
if(settings.buildingImagesTransformed!==undefined){this.buildingImagesTransformed=settings.buildingImagesTransformed;}
if(settings.unitImagesTransformed!==undefined){this.unitImagesTransformed=settings.unitImagesTransformed;}
this.sfx3DLightFactor=settings.sfx3DLightFactor;this.sfx3DLightColor=settings.sfx3DLightColor;this.sfxBuildLayerColor=settings.sfxBuildLayerColor;this.sfxAccessibleTileColor=settings.sfxAccessibleTileColor;this.sfxInaccessibleTileColor=settings.sfxInaccessibleTileColor;this.mouseWheelSpeed=settings.mouseWheelSpeed;this.loadingMusic=settings.loadingMusic;this.loadingMusicVolume=settings.loadingMusicVolume;this.loadingMusicLength=settings.loadingMusicLength;this.gameMusic=settings.gameMusic;this.gamePlayPlugins=settings.gamePlayPlugins;this.pluginConfiguration=settings.pluginConfiguration;}};"use strict";var Race;Race=function(id,name,signatureColor){this.id=id;this.name=name;this.signatureColor=signatureColor;};"use strict";var Projectile;Projectile=function(type,player,startTileX,startTileY,targetTileX,targetTileY,startOffsetX,startOffsetY,targetOffsetX,targetOffsetY,duration){var tileWidth,tileHeight;tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=TilesDefinition.getType(0).imageData.height/2-1;this.type=type;this.player=player;this.startTileX=startTileX;this.startTileY=startTileY;this.startOffsetX=startOffsetX;this.startOffsetY=startOffsetY;this.targetTileX=targetTileX;this.targetTileY=targetTileY;this.targetOffsetX=targetOffsetX;this.targetOffsetY=targetOffsetY;this.startX=(startTileX+startOffsetX)*tileWidth;this.startY=(startTileY+startOffsetY*2)*tileHeight;this.targetX=(targetTileX+targetOffsetX)*tileWidth;this.targetY=(targetTileY+targetOffsetY)*tileHeight;this.progress=0;this.duration=duration;this.exportData=function(){return{type:this.type,player:this.player.id,start:{x:this.startTileX,y:this.startTileY,xOffset:this.startOffsetX,yOffset:this.startOffsetY},target:{x:this.targetTileX,y:this.targetTileY,xOffset:this.targetOffsetX,yOffset:this.targetOffsetY},progress:this.progress,duration:this.duration};};};Projectile.importData=function(data){var projectile;projectile=new Projectile(data.type,Player.getPlayer(data.player),data.start.x,data.start.y,data.target.x,data.target.y,data.start.xOffset,data.start.yOffset,data.target.xOffset,data.target.yOffset,data.duration);projectile.progress=data.progress;return projectile;};"use strict";var Player;(function(){var id,players;id=0;players=[];Player=function(type,isHuman,name,resources,color,race){type=PlayersDefinition.getType(type);this.id=id++;this.color=color||type.color;this.isHuman=isHuman;this.name=name;this.resources=resources;this.race=race||type.race;players.push(this);};Player.getPlayer=function(id){return players[id];};Player.createGenericPlayers=function(){var i;if(players.length){return;}
for(i=0;PlayersDefinition.getType(i);i++){new Player(i,true,'Player '+(i+1),[]);}};}());"use strict";var Map;Map=function(){var tiles,buildings,buildingsList,units,unitsList,navigationIndex,projectiles;tiles=[];buildings=[];buildingsList=[];units=[];unitsList=[];navigationIndex=[];projectiles=[];this.updateBuilding=function(building){var positions,position,i;buildingsList.push(building);positions=getBuildingPositions(building);for(i=positions.length;i--;){position=positions[i];buildings[position.y][position.x]=building;(!building.passable)&&(navigationIndex[position.y][position.x]=false);}};this.removeBuilding=function(building){var positions,position,i;for(i=buildingsList.length;i--;){if(buildingsList[i].id===building.id){buildingsList.splice(i,1);break;}}
positions=getBuildingPositions(building);for(i=positions.length;i--;){position=positions[i];buildings[position.y][position.x]=null;(!building.passable)&&(navigationIndex[position.y][position.x]=true);}};this.addProjectile=function(projectile){projectiles.push(projectile);};this.getProjectiles=function(){return projectiles;};this.removeProjectile=function(index){projectiles.splice(index,1);};this.updateUnit=function(unit){var i;switch(unit.action){case 0:unitsList.push(unit);units[unit.y][unit.x]=unit;navigationIndex[unit.y][unit.x]=false;break;case 1:for(i=unitsList.length;i--;){if(unitsList[i].id===unit.id){unitsList.splice(i,1);break;}}
if(units[unit.y][unit.x]&&(units[unit.y][unit.x].id===unit.id)){units[unit.y][unit.x]=null;navigationIndex[unit.y][unit.x]=true;}
break;case 2:if(units[unit.lastY][unit.lastX]&&(units[unit.lastY][unit.lastX].id===unit.id)){units[unit.lastY][unit.lastX]=null;navigationIndex[unit.lastY][unit.lastX]=true;}
units[unit.y][unit.x]=unit;navigationIndex[unit.y][unit.x]=false;break;}};this.setMap=function(newMap){tiles=newMap;createIndexes();};this.getMap=function(){return tiles;};this.getObjectAt=function(x,y){if(units[y][x]){return units[y][x];}
return buildings[y][x];};this.setTiles=function(newTiles){tiles=newTiles;createIndex();};this.getTiles=function(){return tiles;};this.getBuildings=function(){return buildingsList;};this.getUnits=function(){return unitsList;};this.getBuildingsIndex=function(){return buildings;};this.getNavigationIndex=function(){return navigationIndex;};this.getView=function(x,y,width,height){var view,i;view=tiles.slice(y,y+height);width+=x;for(i=height;i--;){view[i]=view[i].slice(x,width);}
return view;};this.emptyMap=function(width,height){var i,j,row;tiles=[];for(i=height;i--;){row=[];for(j=width;j--;){row.push(new Tile(0));}
tiles.push(row);}
createIndexes();};this.randomMap=function(width,height){var i,j,row,tile;tiles=[];for(i=height;i--;){row=[];for(j=width;j--;){tile=new Tile(Math.floor(Math.random()*3));tile.lightSfx=!Math.floor(Math.random()*20)?Math.floor(Math.random()*5):0;row.push(tile);}
tiles.push(row);}
createIndexes();};this.exportData=function(){var i,j,data,mapRow,dataRow,buildingData,unitsData,projectileData;data=[];for(i=tiles.length;i--;){mapRow=tiles[i];dataRow=[];for(j=mapRow.length;j--;){dataRow.unshift(mapRow[j].exportData());}
data.unshift(dataRow);}
buildingData=[];for(i=buildingsList.length;i--;){buildingData.unshift(buildingsList[i].exportData());}
unitsData=[];for(i=unitsList.length;i--;){unitsData.unshift(unitsList[i].exportData());}
projectileData=[];for(i=projectiles.length;i--;){projectileData.unshift(projectiles[i].exportData());}
return{tiles:data,buildings:buildingData,units:unitsData,projectiles:projectiles};};this.importData=function(data){var i,j,mapRow,dataRow;tiles=[];for(i=data.tiles.length;i--;){mapRow=[];dataRow=data.tiles[i];for(j=dataRow.length;j--;){mapRow.unshift(Tile.importData(dataRow[j]));}
tiles.unshift(mapRow);}
buildingsList=[];createIndexes();for(i=data.buildings.length;i--;){this.updateBuilding(Building.importData(data.buildings[i]));}
unitsList=[];for(i=data.units.length;i--;){this.updateUnit(Unit.importData(data.units[i]));}
projectiles=[];if(data.projectiles instanceof Array){for(i=data.projectiles.length;i--;){this.addProjectile(Projectile.importData(data.projectiles[i]));}}};this.getTilesOccupiedByBuilding=function(building){return getBuildingPositions(building);};function getBuildingPositions(building){var positions,startX,startY,i,j,x,y;positions=[];startX=building.x+Math.floor((building.height-1)/2);startY=building.y;for(j=0;j<building.height;j++){x=startX-Math.ceil((j-startY%2)/2);y=startY+j;for(i=0;i<building.width;i++){positions.push({x:x,y:y});if(y%2){x++;y++;}else{y++;}}}
return positions;}
function createIndex(){var i,j,row,index;index=[];for(i=tiles.length;i--;){row=[];for(j=tiles[0].length;j--;){row.push(null);}
index.push(row);}
return index;}
function createIndexes(){buildings=createIndex();units=createIndex();navigationIndex=createIndex();initNavigationIndex();}
function initNavigationIndex(){var i,j,row,navigationRow;for(j=tiles.length;j--;){row=tiles[j];navigationRow=navigationIndex[j];for(i=row.length;i--;){navigationRow[i]=row[i].accessible;}}}};"use strict";var GamePlay;GamePlay=function(plugins,settings){var logicThread,renderingThread,scheduledPlugins,lastTick,tickOverflow,eventDeliveryPlugin,eventDrivenPlugins,uiPlugins,eventQueue,singleTickScheduledPlugins,threadsActive,tickDuration,threadInterval;renderingThread=function(){var i;if(threadsActive){requestAnimationFrame(renderingThread);}
for(i=uiPlugins.length;i--;){uiPlugins[i].renderFrame();}};logicThread=function(){var i,j,now,tickCount,tickCountReal;now=(new Date()).getTime();tickCountReal=(now-lastTick)/tickDuration+tickOverflow;tickCount=Math.floor(tickCountReal);tickOverflow=tickCountReal-tickCount;lastTick=now;for(i=Math.min(tickCount,settings.maxTicks);i--;){for(j=scheduledPlugins.length;j--;){scheduledPlugins[j].handleTick();}}
for(i=singleTickScheduledPlugins.length;i--;){singleTickScheduledPlugins[i].handleTick();}};(function(){var PluginConstructor;PluginConstructor=function(){this.handleTick=function(){var currentEvents,i,eventListeningPlugins,j,currentEvent,eventCount;currentEvents=eventQueue;eventQueue=[];eventCount=currentEvents.length;for(i=0;i<eventCount;i++){currentEvent=currentEvents[i];eventListeningPlugins=eventDrivenPlugins[currentEvent.name];if(eventListeningPlugins){for(j=eventListeningPlugins.length;j--;){eventListeningPlugins[j].handleEvent(currentEvent.name,currentEvent.data);}}}};};PluginConstructor.prototype=new ScheduledPlugin();eventDeliveryPlugin=new PluginConstructor();}());this.sendEvent=function(eventName,eventData){eventQueue.push({name:eventName,data:eventData});};this.start=function(){if(threadsActive){throw new Error('GamePlay daemon is already running');}
lastTick=(new Date()).getTime();tickOverflow=0;threadsActive=true;requestAnimationFrame(renderingThread);threadInterval=setInterval(logicThread,settings.tickDuration);this.sendEvent("start",null);eventDeliveryPlugin.handleTick();this.sendEvent("running",null);};this.stop=function(){if(!threadsActive){throw new Error('GamePlay daemon is not running');}
threadsActive=false;clearInterval(threadInterval);this.sendEvent("stop",null);eventDeliveryPlugin.handleTick();};(function(){var i,plugin,registerEventDrivenPlugin;eventQueue=[];scheduledPlugins=[];singleTickScheduledPlugins=[];eventDrivenPlugins={};uiPlugins=[];threadsActive=false;tickDuration=settings.tickDuration;registerEventDrivenPlugin=function(plugin){var observedEvents,i,eventName;observedEvents=plugin.getObservedEvents();for(i=observedEvents.length;i--;){eventName=observedEvents[i];if(!eventDrivenPlugins[eventName]){eventDrivenPlugins[eventName]=[];}
eventDrivenPlugins[eventName].push(plugin);}};for(i=plugins.length;i--;){plugin=plugins[i];plugin.setGamePlay(this);if(plugin instanceof ScheduledPlugin){if(plugin.ignoresExtraTicks()){singleTickScheduledPlugins.push(plugin);}else{scheduledPlugins.push(plugin);}
if(plugin instanceof MixedPlugin){registerEventDrivenPlugin(plugin);}}else if(plugin instanceof EventDrivenPlugin){registerEventDrivenPlugin(plugin);}else if(plugin instanceof UIPlugin){registerEventDrivenPlugin(plugin);uiPlugins.push(plugin);}else{throw new Error('The provided object '+plugin+' is not a valid plugin');}}
scheduledPlugins.push(eventDeliveryPlugin);}.call(this));};"use strict";var GameLoader;GameLoader=function(progressbarAll,progressbarCurrent,progressMessage,loadingScreen,gameplayScreen,mapFileUrl,currentPlayer,playerResources,viewCanvas,minimapContainer){var spriteloader,steps,stepMessages,currentStep,performNextStep,setProgress,backgroundMusic,map,gamePlay,gameMusic,plugins;spriteloader=new SpriteLoader();steps=[function(){spriteloader.addObserver(function(progress){if(progress<0){throw new Error('Cannot load images');}
setProgress(progress);if(progress===1){performNextStep();}});spriteloader.load();},function(){var movedToNextStep;movedToNextStep=false;gameMusic=new GameMusic();gameMusic.registerLoadingObserver(function(progress){if(progress<0){throw new Error('Cannot load music');}
setProgress(progress);if((progress===1)&&!movedToNextStep){performNextStep();movedToNextStep=true;}});},function(){var xhr;xhr=new XMLHttpRequest();xhr.onreadystatechange=function(){var compressor;if(xhr.readyState!==4){return;}
if(xhr.status===200){compressor=new MapCompressor();map=new Map();map.importData(compressor.decompress(xhr.responseText,3));performNextStep();}else{throw new Error('Cannot load map file: '+mapFileUrl);}};xhr.open('GET',mapFileUrl+'?time='+(new Date()).getTime(),true);xhr.send(null);},function(){var i,pluginName;plugins=[];for(i=Settings.gamePlayPlugins.length;i--;){pluginName=Settings.gamePlayPlugins[i];plugins.push(eval('new '+pluginName+'()'));setProgress(i/Settings.gamePlayPlugins.length);}
performNextStep();},function(){gamePlay=new GamePlay(plugins,Settings);gamePlay.sendEvent('gameMusicInitialization',gameMusic);gamePlay.sendEvent('gameMapInitialization',map);gamePlay.sendEvent('playerResourcesInitialization',playerResources);gamePlay.sendEvent('playerInitialization',currentPlayer);gamePlay.sendEvent('viewInitialization',{view:viewCanvas,minimap:minimapContainer});;gamePlay.start();performNextStep();},function(){var i,interval,total;i=0;total=75;interval=setInterval(function(){var volume;i++;volume=(1-i/total)*Settings.loadingMusicVolume;backgroundMusic.setVolume(volume);setProgress(i/total);if(i===total){clearInterval(interval);setTimeout(function(){loadingScreen.style.display='none';gameplayScreen.style.display='block';},15);backgroundMusic.stop();}},20);}];stepMessages=["Loading images...","Loading music...","Loading map...","Initializing the battle interface...","Starting command relays...","Done"];currentStep=-1;this.load=function(){backgroundMusic=new Audio(Settings.loadingMusic,{volume:Settings.loadingMusicVolume,duration:Settings.loadingMusicLength,loop:true,onload:function(){backgroundMusic.play();performNextStep();}});};performNextStep=function(){setTimeout(function(){currentStep++;setProgress(0);progressMessage.innerHTML=stepMessages[currentStep];steps[currentStep]();},15);};setProgress=function(progress){var all;progressbarCurrent.getElementsByTagName('div')[0].style.width=(progress*100)+'%';all=currentStep/steps.length*100+
100/steps.length*progress;progressbarAll.getElementsByTagName('div')[0].style.width=all+'%';};};"use strict";var Building;(function(){var id;id=0;Building=function(x,y,type,player,color){var definition;definition=BuildingsDefinition.getType(type);this.id=id++;this.x=x;this.y=y;this.name=definition.name;this.image=definition.image;this.imageWidth=definition.imageWidth;this.imageHeigth=definition.imageHeigth;this.width=definition.width;this.height=definition.height;this.colorify=definition.colorify;this.colorifyDistance=definition.colorifyDistance;this.type=type;this.passable=definition.passable;this.race=definition.race,this.isCentral=definition.isCentral;this.isSelectedUnitProductionBuilding=false;this.player=player;this.color=color===undefined?Player.getPlayer(player).color:color;this.exportData=function(){return{x:this.x,y:this.y,type:this.type,player:this.player};};};Building.importData=function(data){return new Building(data.x,data.y,data.type,data.player);};}());"use strict";var AdvancedUIPlugin;AdvancedUIPlugin=function(){this.getObservedEvents=function(){var events,i;events=[];for(i in this){if(this[i]instanceof Function){if(/^on[A-Z][a-zA-Z]*$/.test(i)){events.push(i.substring(2,3).toLowerCase()+
i.substring(3));}}}
return events;};this.handleEvent=function(eventName,eventData){var method;method='on'+eventName.substring(0,1).toUpperCase()+
eventName.substring(1);this[method](eventData);};};AdvancedUIPlugin.prototype=new UIPlugin();"use strict";var AdvancedMixedPlugin;AdvancedMixedPlugin=function(){this.getObservedEvents=function(){var events,i;events=[];for(i in this){if(this[i]instanceof Function){if(/^on[A-Z][a-zA-Z]*$/.test(i)){events.push(i.substring(2,3).toLowerCase()+
i.substring(3));}}}
return events;};this.handleEvent=function(eventName,eventData){var method;method='on'+eventName.substring(0,1).toUpperCase()+
eventName.substring(1);this[method](eventData);};};AdvancedMixedPlugin.prototype=new MixedPlugin();"use strict";var AdvancedEventDrivenPlugin;AdvancedEventDrivenPlugin=function(){this.getObservedEvents=function(){var events,i;events=[];for(i in this){if(this[i]instanceof Function){if(/^on[A-Z][a-zA-Z]*$/.test(i)){events.push(i.substring(2,3).toLowerCase()+
i.substring(3));}}}
return events;};this.handleEvent=function(eventName,eventData){var method;method='on'+eventName.substring(0,1).toUpperCase()+
eventName.substring(1);this[method](eventData);};};AdvancedEventDrivenPlugin.prototype=new EventDrivenPlugin();"use strict";var ResourceManagerPlugin;ResourceManagerPlugin=function(){var resources;this.onResourceRequest=function(request){var dispatch,i,playerResources,satisfiable;dispatch={target:request.target,targetType:request.targetType,player:request.player,resources:[]};satisfiable=true;playerResources=resources[request.player];for(i=request.resources.length;i--;){if(playerResources[i]<request.resources[i]){dispatch={target:request.target,targetType:request.targetType,player:request.player,resources:false};break;}
playerResources[i]-=request.resources[i];dispatch.resources[i]=request.resources[i];}
this.sendEvent('resourceDispatch',dispatch);};this.onResourcesGained=function(gainInfo){var playerResources,i;playerResources=resources[gainInfo.player];for(i=gainInfo.resources.length;i--;){playerResources[i]+=gainInfo.resources[i];}};this.onPlayerResourcesInitialization=function(resourceStats){resources=resourceStats;};};ResourceManagerPlugin.prototype=new AdvancedEventDrivenPlugin();"use strict";var UnitAI;UnitAI=function(){var map,navigationIndex,view,productionBuildings;this.handleTick=function(){var i,units,unit;units=map.getUnits();for(i=units.length;i--;){unit=units[i];switch(unit.action){case 0:unit.action=4;break;case 1:break;case 2:startMovingUnitProgress(unit);break;case 3:moveUnit(unit);break;case 4:if(unit.waypoints.length){startMovingUnit(unit);}
break;case 5:break;case 6:turnUnit(unit);break;}}};this.onUnitConstructionProgress=function(data){var player,unitType,direction,unit,productionBuilding,position;if(data.progress<1000){return;}
player=data.player;unitType=data.unit;direction=Math.floor(Math.random()*8);productionBuilding=getProductionBuilding(player);if(!productionBuilding){return;}
position=findNearestFreeTile(productionBuilding);unit=new Unit(position.x,position.y,direction,unitType,player);map.updateUnit(unit);view.onUnitChange(unit);};this.onViewReady=function(newView){view=newView;map.getUnits().forEach(function(unit){if(unit.action===0){unit.action=4;}});};this.onGameMapInitialization=function(gameMap){productionBuildings=[];map=gameMap;navigationIndex=map.getNavigationIndex();};function turnUnit(unit){var progress;if(!unit.turningAzimuth){unit.action=4;return;}
progress=Math.min(1000,unit.turningProgress+unit.turnSpeed);unit.turningProgress=progress;if(progress<1000){return;}
if(unit.turningAzimuth>0){unit.direction=(unit.direction+1)%8;unit.turningAzimuth--;}else{unit.direction--;if(unit.direction===-1){unit.direction=7;}
unit.turningAzimuth++;}
unit.turningProgress=0;}
function findNearestFreeTile(building){var centralX,centralY,radius,circumference,angleStep,angle,x,y,a;centralX=building.x+Math.floor(building.width/2);centralY=building.y+Math.floor(building.height/2);radius=Math.floor((building.width+building.height)/2)-1;while(true){circumference=Math.floor(2*radius*Math.PI);for(angleStep=circumference;angleStep--;){angle=2*Math.PI/circumference*angleStep;x=centralX+Math.floor(Math.cos(angle)*radius);y=centralY+Math.floor(Math.sin(angle)*radius);a=map.getObjectAt(x,y);if(!map.getObjectAt(x,y)&&navigationIndex[y][x]){return{x:x,y:y};}}
radius++;}}
function getProductionBuilding(playerID){var i,building,buildings,centralBuildings;if(productionBuildings[playerID]instanceof Building){return productionBuildings[playerID];}
buildings=map.getBuildings();centralBuildings=[];for(i=buildings.length;i--;){building=buildings[i];if((building.player===playerID)&&building.isCentral){if(building.isSelectedUnitProductionBuilding){productionBuildings[playerID]=building;return building;}
centralBuildings.push(building);}}
if(centralBuildings.length){building=centralBuildings.shift();building.isSelectedUnitProductionBuilding=true;productionBuildings[playerID]=building;return building;}
return null;}
function startMovingUnit(unit){var waypoint;waypoint=unit.waypoints[0];while((waypoint.x===unit.x)&&(waypoint.y===unit.y)){unit.waypoints.shift();waypoint=unit.waypoints[0];if(!waypoint){return;}}
unit.moveTargetX=waypoint.x;unit.moveTargetY=waypoint.y;startMovingUnitToNextTile(unit);}
function startMovingUnitProgress(unit){startMovingUnitToNextTile(unit);}
function moveUnit(unit){var waypoint;unit.setMoveOffset(Math.min(1000,unit.moveOffset+unit.speed));if(unit.moveOffset<1000){return;}
while((unit.x===unit.moveTargetX)&&(unit.y===unit.moveTargetY)){unit.waypoints.shift();if(unit.waypoints.length){waypoint=unit.waypoints[0];unit.moveTargetX=waypoint.x;unit.moveTargetY=waypoint.y;}else{unit.action=4;unit.moveTargetX=null;unit.moveTargetY=null;return;}}
startMovingUnitToNextTile(unit);}
function startMovingUnitToNextTile(unit){var targetDirection,azimuth;targetDirection=getReasonableDirection(unit,unit.moveTargetX,unit.moveTargetY);if(targetDirection!==unit.direction){azimuth=unit.direction-targetDirection;if(azimuth<-4){azimuth=8+azimuth;}
if(azimuth>4){azimuth=-(8-azimuth);}
unit.turningAzimuth=-azimuth;unit.turningProgress=0;unit.action=6;return;}
if(checkAheadMovingUnit(unit)===2){unit.action=5;return;}
unit.move(1);map.updateUnit(unit);view.onUnitChange(unit);unit.action=3;}
function getReasonableDirection(unit,targetX,targetY){var headDirection,oldDirection,reasonableDirectionAzimuth,reasonableDirection;headDirection=getPreferredDirection(unit,targetX,targetY);oldDirection=unit.direction;unit.direction=headDirection;reasonableDirectionAzimuth=findFreeDirection(unit,oldDirection);unit.direction=oldDirection;reasonableDirection=headDirection+reasonableDirectionAzimuth;if(reasonableDirection<0){reasonableDirection+=8;}else if(reasonableDirection>7){reasonableDirection%=8;}
return reasonableDirection;}
function getPreferredDirection(unit,targetX,targetY){var deltaX,deltaY,sourceOffset,destinationOffset;deltaX=targetX-unit.x;deltaY=targetY-unit.y;sourceOffset=unit.y%2;destinationOffset=targetY%2;deltaX+=destinationOffset-sourceOffset;if(deltaX===0){if(deltaY>0){return 4;}
return 0;}
if(deltaY===0){if(deltaX>0){return 2;}
return 6;}
if(deltaY<0){if(deltaX>0){return 1;}
return 7;}
if(deltaX>0){return 3;}
return 5;}
function findFreeDirection(unit,preferedDirection){var direction;if(isFreeDirection(unit,0)){return 0;}
if(preferedDirection> unit.direction){for(direction=1;direction<5;direction++){if(isFreeDirection(unit,direction)){return direction;}}
for(direction=1;direction<4;direction++){if(isFreeDirection(unit,-direction)){return-direction;}}}else{for(direction=1;direction<5;direction++){if(isFreeDirection(unit,-direction)){return-direction;}}
for(direction=1;direction<4;direction++){if(isFreeDirection(unit,direction)){return direction;}}}
return null;}
function isFreeDirection(unit,direction){var coordinates,item;coordinates=unit.getCoordinatesAtDirection(direction);item=map.getObjectAt(coordinates.x,coordinates.y);if(item){if((item instanceof Unit)&&(item.action===3)){if(((unit.direction+8-item.direction)%8)!==4){return true;}}}
return navigationIndex[coordinates.y][coordinates.x];}
function checkAheadMovingUnit(unit){var aheadCoordinates,ahead;aheadCoordinates=unit.getAheadCoordinates();ahead=map.getObjectAt(aheadCoordinates.x,aheadCoordinates.y);if(ahead){if((ahead instanceof Unit)&&(ahead.action===3)){if(((unit.direction+8-ahead.direction)%8)===4){return 1;}
return 2;}
return 1;}
if(navigationIndex[aheadCoordinates.y][aheadCoordinates.x]){return 0;}
return 1;}};UnitAI.prototype=new AdvancedMixedPlugin();"use strict";var BuildingsUnitsConstruction;BuildingsUnitsConstruction=function(){var constructionQueues={},instance,maxQueueLength;(function(){instance=this;maxQueueLength=Settings.pluginConfiguration.BuildingsUnitsConstruction.maxQueueLength;}.call(this));this.handleTick=function(){var playerId,buildingsTasks,buildingType,unitsTasks,unitType;for(playerId in constructionQueues){if(!constructionQueues.hasOwnProperty(playerId)){continue;}
playerId=parseInt(playerId,10);buildingsTasks=constructionQueues[playerId].buildings;for(buildingType in buildingsTasks){if(!buildingsTasks.hasOwnProperty(buildingType)||!buildingsTasks[buildingType]){continue;}
if(buildingsTasks[buildingType].waitingForResources){continue;}
if(buildingsTasks[buildingType].stepTimeout){buildingsTasks[buildingType].stepTimeout--;continue;}
this.sendEvent('resourceRequest',{target:buildingType,targetType:'building',player:playerId,resources:buildingsTasks[buildingType].definition.construction.step});buildingsTasks[buildingType].waitingForResources=true;}
unitsTasks=constructionQueues[playerId].units;for(unitType in unitsTasks){if(!unitsTasks.hasOwnProperty(unitType)||!unitsTasks[unitType]){continue;}
unitType=parseInt(unitType,10);if(unitsTasks[unitType].waitingForResources){continue;}
if(unitsTasks[unitType].stepTimeout){unitsTasks[unitType].stepTimeout--;continue;}
this.sendEvent('resourceRequest',{target:unitType,targetType:'unit',player:playerId,resources:unitsTasks[unitType].definition.construction.step});unitsTasks[unitType].waitingForResources=true;}}};this.onStart=function(data){};this.onStop=function(data){};this.onEnqueueBuildingConstruction=function(eventData){var buildings,definition;if(!constructionQueues[eventData.player]){constructionQueues[eventData.player]={buildings:{},units:{}};}
buildings=constructionQueues[eventData.player].buildings;if(buildings[eventData.building]){return;}
definition=BuildingsDefinition.getType(eventData.building);buildings[eventData.building]={type:eventData.building,progress:0,definition:definition,waitingForResources:false,stepTimeout:0};};this.onCancelBuildingConstruction=function(data){var buildingTasks,resources,i,constructionInfo;if(!constructionQueues[data.player]){return;}
buildingTasks=constructionQueues[data.player].buildings;if(!buildingTasks[data.building]){return;}
resources=[];constructionInfo=buildingTasks[data.building].definition.construction;for(i=constructionInfo.step.length;i--;){resources[i]=constructionInfo.step[i]*buildingTasks[data.building].progress/constructionInfo.stepProgress;}
instance.sendEvent('resourcesGained',{player:data.player,resources:resources});buildingTasks[data.building]=undefined;};this.onRefundBuildingConstruction=function(data){var resources,buildingDefinition,constructionInfo,stepCount,stepProgress,i;buildingDefinition=BuildingsDefinition.getType(data.building);constructionInfo=buildingDefinition.construction;stepCount=1000/constructionInfo.stepProgress;stepProgress=constructionInfo.step;resources=new Array(stepProgress.length);for(i=stepProgress.length;i--;){resources[i]=stepCount*stepProgress[i];}
instance.sendEvent('resourcesGained',{player:data.player,resources:resources});};this.onCancelUnitConstruction=function(data){var unitTasks,resources,i,constructionInfo;if(!constructionQueues[data.player]){return;}
unitTasks=constructionQueues[data.player].units;if(!unitTasks[data.unit]){return;}
if(unitTasks[data.unit].enqueued){unitTasks[data.unit].enqueued--;}else{resources=[];constructionInfo=unitTasks[data.unit].definition.construction;for(i=constructionInfo.step.length;i--;){resources[i]=constructionInfo.step[i]*unitTasks[data.unit].progress/constructionInfo.stepProgress;}
instance.sendEvent('resourcesGained',{player:data.player,resources:resources});unitTasks[data.unit]=undefined;}};this.onEnqueueUnitConstruction=function(data){var units,definition;if(!constructionQueues[data.player]){constructionQueues[data.player]={buildings:{},units:{}};}
units=constructionQueues[data.player].units;if(units[data.unit]){units[data.unit].enqueued=Math.min(units[data.unit].enqueued+1,maxQueueLength);}else{definition=UnitsDefinition.getType(data.unit);units[data.unit]={type:data.unit,progress:0,definition:definition,waitingForResources:false,stepTimeout:0,enqueued:0};}};this.onResourceDispatch=function(data){var playersBuildings,buildingTask,playerUnits,unitTask;if(data.targetType==='unit'){playerUnits=constructionQueues[data.player].units;unitTask=playerUnits[data.target];if(data.resources){if(!unitTask){instance.sendEvent('resourcesGained',{player:data.player,resources:data.resources});return;}
unitTask.progress+=unitTask.definition.construction.stepProgress;unitTask.stepTimeout+=unitTask.definition.construction.stepDuration;instance.sendEvent('unitConstructionProgress',{player:data.player,unit:data.target,progress:unitTask.progress,enqueued:unitTask.enqueued});if(unitTask.progress>=1000){if(unitTask.enqueued){unitTask.enqueued--;unitTask.progress=0;}else{playerUnits[data.target]=undefined;}}}
unitTask.waitingForResources=false;}else if(data.targetType==='building'){playersBuildings=constructionQueues[data.player].buildings;buildingTask=playersBuildings[data.target];if(data.resources){if(!buildingTask){instance.sendEvent('resourcesGained',{player:data.player,resources:data.resources});return;}
buildingTask.progress+=buildingTask.definition.construction.stepProgress;buildingTask.stepTimeout=buildingTask.definition.construction.stepDuration;instance.sendEvent('buildingConstrucionProgress',{player:data.player,building:data.target,progress:buildingTask.progress});if(buildingTask.progress>=1000){playersBuildings[data.target]=undefined;}}
buildingTask.waitingForResources=false;}};};BuildingsUnitsConstruction.prototype=new AdvancedMixedPlugin();"use strict";var Benchmark;Benchmark=function(){var scheduledStart,ticks,benchmarking;(function(){scheduledStart=null;ticks=0;benchmarking=false;}.call(this));this.handleTick=function(){if(benchmarking){ticks++;}
if(scheduledStart){return;}
scheduledStart=setTimeout(function(){benchmarking=true;setTimeout(function(){benchmarking=false;alert(ticks/10);},10000);},10000);ticks++;};this.ignoresExtraTicks=function(){return true;};};Benchmark.prototype=new ScheduledPlugin();"use strict";var ViewRendererPlugin;ViewRendererPlugin=function(){var view,map,x,y,borderOffset,viewWidth,viewHeight,viewLayerSize,minX,minY,maxX,maxY;(function(pluginSettings){borderOffset=pluginSettings.borderOffset;x=borderOffset;y=borderOffset;minX=borderOffset;minY=borderOffset;}(Settings.pluginConfiguration.ViewRendererPlugin));this.renderFrame=function(){view.display(x,y);};this.onScrollMapView=function(vector){x=Math.min(maxX,Math.max(x+vector.x,minX));y=Math.min(maxY,Math.max(y+vector.y,minY));};this.onViewSetByMinimap=function(data){x=Math.floor(viewLayerSize.width*data.x-viewWidth/2);y=Math.floor(viewLayerSize.height*data.y-viewHeight/2);x=Math.min(maxX,Math.max(x,minX));y=Math.min(maxY,Math.max(y,minY));};this.onGameMapInitialization=function(data){map=data;if(view){view.setMap(map);}};this.onViewInitialization=function(data){var minimapSize,viewWidthInTiles,viewHeightInTiles;view=new View();view.setCanvas(data.view);view.setMinimapContainer(data.minimap);minimapSize=Settings.pluginConfiguration.ViewRendererPlugin.minimap;view.setMinimapSize(minimapSize.width,minimapSize.height);if(map){view.setMap(map);}
viewWidth=data.view.width;viewHeight=data.view.height;viewWidthInTiles=Math.round(viewWidth/Settings.tileWidth);viewHeightInTiles=Math.round(viewHeight/Settings.tileHeight);view.setMainViewSize(viewWidthInTiles,viewHeightInTiles);viewLayerSize=view.getMainViewLayersDimensions();maxX=viewLayerSize.width-viewWidth-borderOffset;maxY=viewLayerSize.height-viewHeight-borderOffset;this.sendEvent('viewReady',view);};};ViewRendererPlugin.prototype=new AdvancedUIPlugin();"use strict";var UnitsConstructionUIPlugin;UnitsConstructionUIPlugin=function(){var currentPlayerRace,template,buttonsContainer,instance,playerId,buttons,uiUpdate;(function(){instance=this;buttons={};uiUpdate=[];}.call(this));this.renderFrame=function(){var i;for(i=uiUpdate.length;i--;){uiUpdate[i].node.innerHTML=uiUpdate[i].value;}
uiUpdate=[];};this.onUnitConstructionProgress=function(data){var unitButton,label;if(data.player===playerId){unitButton=buttons[data.unit];label=Math.floor(data.progress/10)+' %';if(data.enqueued){label+=' ('+data.enqueued+')';}else if(data.progress>=1000){label="";}
uiUpdate.push({node:unitButton.progressInfo,value:label});}};this.onPlayerInitialization=function(player){playerId=player.id;currentPlayerRace=player.race;if(template){createButtons();}};this.onStart=function(tmp){var templateNode;templateNode=document.querySelector('#units-buttons .construction-buttons-content *');buttonsContainer=templateNode.parentNode;template={tag:templateNode.nodeName,className:templateNode.className,innerHTML:templateNode.innerHTML,width:70,height:38};buttonsContainer.innerHTML='';if(currentPlayerRace!==undefined){createButtons();}};this.onStop=function(tmp){buttonsContainer.innerHTML='';};function createButton(unit){var node,img,progressInfo;node=document.createElement(template.tag);node.className=template.className;node.innerHTML=template.innerHTML;img=node.getElementsByTagName('img')[0];img.src=unit.imageData[5].src;img.alt=unit.name;img.style.width=Settings.tileWidth+'px';img.style.height=Settings.tileHeight+'px';progressInfo=node.getElementsByTagName('div')[0];node.getElementsByTagName('div')[2].innerHTML=unit.name;node.title='¢ '+(unit.construction.step[0]*(1000/unit.construction.stepProgress));node.addEventListener('click',function(){if(!progressInfo.innerHTML){uiUpdate.push({node:progressInfo,value:"0 %"});}
instance.sendEvent('enqueueUnitConstruction',{player:playerId,unit:unit.type});},false);addEventListener('contextmenu',function(event){var clickedNode;event.preventDefault();clickedNode=getConstructionButton(event.target);if(clickedNode===node){instance.sendEvent('cancelUnitConstruction',{player:playerId,unit:unit.type});}});node.progressInfo=progressInfo;buttons[unit.type]=node;buttonsContainer.appendChild(node);};function createButtons(){var unit,type;for(type=0;unit=UnitsDefinition.getType(type);type++){if((unit.race!==null)&&(unit.race===currentPlayerRace)){createButton(unit);}}};function getConstructionButton(clickedNode){var limit;limit=3;while(clickedNode.className!=='construction-button'){if(!limit--){return null;}
clickedNode=clickedNode.parentNode;if(!clickedNode){return null;}}
return clickedNode;};};UnitsConstructionUIPlugin.prototype=new AdvancedUIPlugin();"use strict";var ResourceManagerUIPlugin;ResourceManagerUIPlugin=function(){var playerId,resources,resourceContainers,shouldUpdateUI;(function(){shouldUpdateUI=false;}.call(this));this.renderFrame=function(){var i;if(shouldUpdateUI){for(i=resources.length;i--;){resourceContainers[i].innerHTML=resources[i];}
shouldUpdateUI=false;}};this.onResourceDispatch=function(dispatch){var dispatchedResources,i;if(dispatch.player!==playerId){return;}
dispatchedResources=dispatch.resources;if(!dispatchedResources){return;}
for(i=dispatchedResources.length;i--;){resources[i]-=dispatchedResources[i];}
shouldUpdateUI=true;};this.onResourcesGained=function(gainInfo){var gainedResources,i;if(gainInfo.player!==playerId){return;}
gainedResources=gainInfo.resources;for(i=gainedResources.length;i--;){resources[i]+=gainedResources[i];}
shouldUpdateUI=true;};this.onPlayerResourcesInitialization=function(resourceStats){resources=resourceStats;if(playerId!==undefined){resources=resources[playerId].slice(0);initContainers();shouldUpdateUI=true;}};this.onPlayerInitialization=function(player){playerId=player.id;if(resources){resources=resources[playerId].slice(0);initContainers();shouldUpdateUI=true;}};function initContainers(){var i;resourceContainers=[];for(i=0;i<resources.length;i++){resourceContainers[i]=document.querySelector('#resource-'+i);}}};ResourceManagerUIPlugin.prototype=new AdvancedUIPlugin();"use strict";var MinimapControlPlugin;MinimapControlPlugin=function(){var mouseDown,width,height,instance;(function(){mouseDown=false;instance=this;}.call(this));this.renderFrame=function(){};this.onRunning=function(data){var minimap;minimap=document.querySelector("#minimap > canvas");minimap.addEventListener("mousedown",function(event){mouseDown=true;handlePositionSelection(event.offsetX,event.offsetY);event.preventDefault();},false);window.addEventListener("mouseup",function(){mouseDown=false;},false);minimap.addEventListener("mousemove",function(event){if(mouseDown){handlePositionSelection(event.offsetX,event.offsetY);}
event.preventDefault();},false);width=minimap.width;height=minimap.height;};function handlePositionSelection(x,y){instance.sendEvent("viewSetByMinimap",{x:x/width,y:y/height});}};MinimapControlPlugin.prototype=new AdvancedUIPlugin();"use strict";var KeyboardMapScroller;KeyboardMapScroller=function(){var vector,speed;(function(){vector={x:0,y:0};speed=Settings.pluginConfiguration.KeyboardMapScroller.scrollSpeed;}.call(this));this.renderFrame=function(){if(vector.x||vector.y){this.sendEvent("scrollMapView",{x:vector.x*speed,y:vector.y*speed});}};this.onStart=function(){addEventListener('keydown',processKeyDown,false);addEventListener('keyup',processKeyUp,false);};this.onStop=function(){removeEventListener('keydown',processKeyDown,false);removeEventListener('keyup',processKeyUp,false);};function processKeyDown(event){switch(event.keyCode){case 38:case 87:vector.y=-1;break;case 40:case 83:vector.y=1;break;case 37:case 65:vector.x=-1;break;case 39:case 68:vector.x=1;break;default:return;}
event.preventDefault();}
function processKeyUp(event){switch(event.keyCode){case 38:case 87:case 40:case 83:vector.y=0;break;case 37:case 65:case 39:case 68:vector.x=0;break;default:return;}
event.preventDefault();}};KeyboardMapScroller.prototype=new AdvancedUIPlugin();"use strict";var GameMusicPlugin;GameMusicPlugin=function(){var gameMusic;this.renderFrame=function(){};this.onGameMusicInitialization=function(gameMusicInstance){gameMusic=gameMusicInstance;gameMusic.play();};this.onGameIntensityChange=function(newIntensity){gameMusic.setIntensity(newIntensity);};this.onStop=function(tmp){gameMusic.stop();};};GameMusicPlugin.prototype=new AdvancedUIPlugin();"use strict";var ConstructionButtonsScroller;ConstructionButtonsScroller=function(){var scrolling1st,scrolling2nd,scrollSpeed,buttonsStrip1,buttonsStrip2,upButton1,downButton1,upButton2,downButton2;(function(){scrollSpeed=5;}.call(this));this.renderFrame=function(){if(scrolling1st){buttonsStrip1.scrollTop+=scrolling1st;}
if(scrolling2nd){buttonsStrip2.scrollTop+=scrolling2nd;}};this.onStart=function(data){upButton1=$('#buildings-buttons .button-scroll-up')[0];downButton1=$('#buildings-buttons .button-scroll-down')[0];buttonsStrip1=$('#buildings-buttons .construction-buttons-content')[0];upButton2=$('#units-buttons .button-scroll-up')[0];downButton2=$('#units-buttons .button-scroll-down')[0];buttonsStrip2=$('#units-buttons .construction-buttons-content')[0];upButton1.addEventListener('mousedown',scrollUp1stHandler,false);upButton1.addEventListener('mouseup',stopScroll1stHandler,false);downButton1.addEventListener('mousedown',scrollDown1stHandler,false);downButton1.addEventListener('mouseup',stopScroll1stHandler,false);upButton2.addEventListener('mousedown',scrollUp2ndHandler,false);upButton2.addEventListener('mouseup',stopScroll2ndHandler,false);downButton2.addEventListener('mousedown',scrollDown2ndHandler,false);downButton2.addEventListener('mouseup',stopScroll2ndHandler,false);};this.onStop=function(data){scrolling1st=0;scrolling2nd=0;upButton1.removeEventListener('mousedown',scrollUp1stHandler,false);upButton1.removeEventListener('mouseup',stopScroll1stHandler,false);downButton1.removeEventListener('mousedown',scrollDown1stHandler,false);downButton1.removeEventListener('mouseup',stopScroll1stHandler,false);upButton2.removeEventListener('mousedown',scrollUp2ndHandler,false);upButton2.removeEventListener('mouseup',stopScroll2ndHandler,false);downButton2.removeEventListener('mousedown',scrollDown2ndHandler,false);downButton2.removeEventListener('mouseup',stopScroll2ndHandler,false);};function $(selector){return document.querySelectorAll(selector);}
function scrollDown1stHandler(){scrolling1st=scrollSpeed;}
function scrollUp1stHandler(){scrolling1st=-scrollSpeed;}
function stopScroll1stHandler(){scrolling1st=0;}
function scrollDown2ndHandler(){scrolling2nd=scrollSpeed;}
function scrollUp2ndHandler(){scrolling2nd=-scrollSpeed;}
function stopScroll2ndHandler(){scrolling2nd=0;}};ConstructionButtonsScroller.prototype=new AdvancedUIPlugin();"use strict";var BuildingsConstructionUIPlugin;BuildingsConstructionUIPlugin=function(){var currentPlayerRace,template,buttonsContainer,instance,playerId,buttons,uiUpdate;(function(){instance=this;buttons={};uiUpdate=[];}.call(this));this.renderFrame=function(){var i;for(i=uiUpdate.length;i--;){uiUpdate[i].node.innerHTML=uiUpdate[i].value;}
uiUpdate=[];};this.onBuildingConstrucionProgress=function(progress){var buildingButton,progressLabel;if(progress.player===playerId){buildingButton=buttons[progress.building];if(!buildingButton.progressInfo.innerHTML){return;}
if(progress.progress>=1000){progressLabel='READY';buildingButton.ready=true;}else{progressLabel=Math.floor(progress.progress/10)+' %';}
uiUpdate.push({node:buildingButton.progressInfo,value:progressLabel});}};this.onPlayerInitialization=function(player){playerId=player.id;currentPlayerRace=player.race;if(template){createButtons();}};this.onStart=function(tmp){var templateNode;templateNode=document.querySelector('#buildings-buttons .construction-buttons-content *');buttonsContainer=templateNode.parentNode;template={tag:templateNode.nodeName,className:templateNode.className,innerHTML:templateNode.innerHTML,width:70,height:38};buttonsContainer.innerHTML='';if(currentPlayerRace!==undefined){createButtons();}};this.onStop=function(tmp){buttonsContainer.innerHTML='';};function scaleButtonIcon(building,img){var horizontalRatio,verticalRatio,shrinkRatio;if((building.imageWidth<=template.width)||(building.imageHeigth<=template.height)){img.style.width=building.imageWidth+'px';img.style.height=building.imageHeigth+'px';}else{horizontalRatio=building.imageWidth/template.width;verticalRatio=building.imageHeigth/template.height;shrinkRatio=Math.max(horizontalRatio,verticalRatio);img.style.width=building.imageWidth/shrinkRatio+'px';img.style.height=building.imageHeigth/shrinkRatio+'px';}}
function createButton(building){var node,img,progressInfo;node=document.createElement(template.tag);node.className=template.className;node.innerHTML=template.innerHTML;img=node.getElementsByTagName('img')[0];img.src=building.imageData.src;img.alt=building.name;progressInfo=node.getElementsByTagName('div')[0];node.getElementsByTagName('div')[2].innerHTML=building.name;node.title='¢ '+(building.construction.step[0]*(1000/building.construction.stepProgress));if(building.imageWidth&&building.imageHeigth){scaleButtonIcon(building,img);}
node.addEventListener('click',function(){if(!progressInfo.innerHTML){uiUpdate.push({node:progressInfo,value:"0 %"});instance.sendEvent('enqueueBuildingConstruction',{player:playerId,building:building.type});}else if(node.ready){alert('placing the building is not implemented yet');}},false);addEventListener('contextmenu',function(event){var clickedNode;event.preventDefault();clickedNode=getConstructionButton(event.target);if(clickedNode===node){if(node.ready){instance.sendEvent('refundBuildingConstruction',{player:playerId,building:building.type});node.ready=false;}else{instance.sendEvent('cancelBuildingConstruction',{player:playerId,building:building.type});}
uiUpdate.push({node:node.progressInfo,value:""});}});node.progressInfo=progressInfo;buttons[building.type]=node;buttonsContainer.appendChild(node);}
function createButtons(){var building,type,playerRace;building=BuildingsDefinition.getType(0);playerRace=currentPlayerRace;for(type=0;building;){if((building.race!==null)&&(building.race===playerRace)){createButton(building);}
building=BuildingsDefinition.getType(++type);}}
function getConstructionButton(clickedNode){var limit;limit=3;while(clickedNode.className!=='construction-button'){if(!limit--){return null;}
clickedNode=clickedNode.parentNode;if(!clickedNode){return null;}}
return clickedNode;}};BuildingsConstructionUIPlugin.prototype=new AdvancedUIPlugin();"use strict";var SpriteLoader;SpriteLoader=function(){var observers,notifyObservers,loadSprite,indexes,getBaseURL,canvas,context,baseUrl,extractTiles,tileWidth,tileHeight,extractImage,extractUnits,extractBuildings,colorifier;observers=[];colorifier=new Colorifier();this.addObserver=function(observer){if(observer instanceof Function){observers.push(observer);}};this.load=function(){var xhr;tileWidth=Math.ceil(Settings.tileWidth);tileHeight=Math.ceil(Settings.tileHeight);baseUrl=baseUrl||getBaseURL();xhr=new XMLHttpRequest();xhr.onreadystatechange=function(){if(xhr.readyState==4){if(xhr.status==200){notifyObservers(0.2);try{indexes=JSON.parse(xhr.responseText);loadSprite();}catch(e){notifyObservers(-1);}}else{notifyObservers(-1);}}};xhr.open('GET',baseUrl+'data/sprite.json',true);xhr.send(null);};loadSprite=function(){var image;image=new Image();image.onload=function(){canvas=document.createElement('canvas');canvas.width=image.width;canvas.height=image.height;context=canvas.getContext('2d');context.drawImage(image,0,0);notifyObservers(0.7);setTimeout(extractTiles,0);};image.onabort=function(){notifyObservers(-1);};image.onerror=function(){notifyObservers(-1);};image.onstalled=function(){notifyObservers(-1);}
image.onsuspend=function(){notifyObservers(-1);}
image.src=baseUrl+'data/images.png?time='+(new Date()).getTime();};extractTiles=function(){var i,tile;for(i=0;tile=TilesDefinition.getType(i);i++){tile.imageData=extractImage(tileWidth*i,0,tileWidth,tileHeight);}
notifyObservers(0.8);setTimeout(extractUnits,0);};extractUnits=function(){var i,j,unit,start;start=indexes.unitsStart;for(i=0;unit=UnitsDefinition.getType(i);i++){unit.imageData=[];unit.playerImages=[]
for(j=0;j<8;j++){unit.imageData.push(extractImage(j*tileWidth,start+i*tileHeight,tileWidth,tileHeight));unit.playerImages.push(colorifier.colorifyForPlayers(unit.imageData[j],unit.colorify,unit.colorifyDistance));}}
notifyObservers(0.9);setTimeout(extractBuildings,0);};extractBuildings=function(){var i,building,starts,heights,startY;starts=indexes.buildings.ends;starts.unshift(0);heights=indexes.buildings.heights;startY=indexes.buildings.start;for(i=0;building=BuildingsDefinition.getType(i);i++){building.imageData=extractImage(starts[i],startY,starts[i+1],heights[i]);building.playerImages=colorifier.colorifyForPlayers(building.imageData,building.colorify,building.colorifyDistance);}
notifyObservers(1);};extractImage=function(x,y,width,height){var imageCanvas,image;imageCanvas=document.createElement('canvas');imageCanvas.width=width;imageCanvas.height=height;imageCanvas.getContext('2d').putImageData(context.getImageData(x,y,width,height),0,0);image=new Image();image.src=imageCanvas.toDataURL();return image;};getBaseURL=function(){var scripts,i,url;scripts=document.getElementsByTagName('script');for(i=scripts.length;i--;){if(scripts[i].src.match(/^.*spriteloader[.]js/)){url=scripts[i].src;url=url.substring(0,url.indexOf('spriteloader.js'));url=url.replace(/js\/$/,'');return url;}}
return'';};notifyObservers=function(progress){var i;for(i=observers.length;i--;){observers[i](progress);}};};"use strict";var ImageLoader;ImageLoader=function(){var loadBuildingImages,notifyObservers,buildingsIndex,observers,unitsIndex,loadUnitImages,tilesIndex,loadTilesImages,transformTileImage,pathPrefix,transformBuildingImage,colorifier;observers=[];pathPrefix='';colorifier=new Colorifier();this.load=function(buildings,units,tiles){loadBuildingImages(buildings);loadUnitImages(units);loadTilesImages(tiles);};this.addObserver=function(observer){observers.push(observer);};this.setPathPrefix=function(prefix){pathPrefix=prefix;};loadTilesImages=function(tiles){var tile,currentType;tilesIndex=[];currentType=0;tile=tiles.getType(currentType);while(tile){tilesIndex.push(false);(function(){var image,type,tileDefinition;tileDefinition=tile;type=currentType;image=new Image();image.onload=function(){tilesIndex[type]=true;tileDefinition.imageData=Settings.tileImagesTransformed?image:transformTileImage(image);notifyObservers();};image.src=pathPrefix+tile.image;}());tile=tiles.getType(++currentType);}};loadUnitImages=function(units){var unit,currentType;unitsIndex=[];currentType=0;unit=units.getType(currentType);while(unit){unitsIndex.push(false);(function(){var images,image,type,i,loadedImages,unitDefinition;unitDefinition=unit;type=currentType;images=[];loadedImages=[];for(i=8;i--;){loadedImages[i]=false;image=new Image();(function(){var index;index=i;image.onload=function(){var i;loadedImages[index]=true;for(i=8;i--;){if(!loadedImages[i]){return;}}
if(!Settings.unitImagesTransformed){for(i=8;i--;){images[i]=transformTileImage(images[i]);}}
unitsIndex[type]=true;unitDefinition.imageData=images;unitDefinition.playerImages=[];for(i=8;i--;){unitDefinition.playerImages[i]=colorifier.colorifyForPlayers(images[i],unitDefinition.colorify,unitDefinition.colorifyDistance);}
notifyObservers();};}());images[i]=image;}
for(i=8;i--;){images[i].src=pathPrefix+unit.image.replace('?',i);}}());unit=units.getType(++currentType);}};loadBuildingImages=function(buildings){var building,currentType;buildingsIndex=[];currentType=0;building=buildings.getType(currentType);while(building){buildingsIndex.push(false);(function(){var image,type,buildingDefinition;buildingDefinition=building;type=currentType;image=new Image();image.onload=function(){buildingsIndex[type]=true;buildingDefinition.imageData=Settings.buildingImagesTransformed?image:transformBuildingImage(image,buildingDefinition.width,buildingDefinition.height);buildingDefinition.playerImages=colorifier.colorifyForPlayers(buildingDefinition.imageData,buildingDefinition.colorify,buildingDefinition.colorifyDistance);notifyObservers();};image.src=pathPrefix+building.image;}());building=buildings.getType(++currentType);}};notifyObservers=function(){var i,done;done=0;for(i=buildingsIndex.length;i--;){if(buildingsIndex[i]){done++;}}
for(i=unitsIndex.length;i--;){if(unitsIndex[i]){done++;}}
for(i=tilesIndex.length;i--;){if(tilesIndex[i]){done++;}}
done/=buildingsIndex.length+unitsIndex.length+tilesIndex.length;for(i=observers.length;i--;){observers[i](done);}};transformBuildingImage=function(source,width,height){var canvas,context,data,offset;canvas=document.createElement('canvas');canvas.width=140+Math.ceil(Settings.tileWidth*width);canvas.height=500+Math.ceil(Settings.tileHeight*height);context=canvas.getContext('2d');context.scale(1,Settings.heightScale);context.rotate(45*Math.PI/180);context.drawImage(source,7*Settings.tileSize,0);offset=(Math.SQRT2/2)*(Math.ceil((width-1)/2)*(Settings.tileWidth+10));data=context.getImageData(84-offset,99*Settings.heightScale,Settings.tileWidth*width,Settings.tileHeight*height);canvas=document.createElement('canvas');canvas.width=data.width;canvas.height=data.height;context=canvas.getContext('2d');context.putImageData(data,0,0);data=new Image();data.src=canvas.toDataURL();return data;};transformTileImage=function(source){var canvas,context,data;canvas=document.createElement('canvas');canvas.width=7+Math.ceil(Settings.tileWidth*2);canvas.height=22+Math.ceil(Settings.tileHeight*2);context=canvas.getContext('2d');context.scale(1,Settings.heightScale);context.rotate(45*Math.PI/180);context.drawImage(source,30,0);data=context.getImageData(7,20*Settings.heightScale,Settings.tileWidth,Settings.tileHeight);canvas=document.createElement('canvas');canvas.width=data.width;canvas.height=data.height;context=canvas.getContext('2d');context.putImageData(data,0,0);data=new Image();data.src=canvas.toDataURL();return data;};};"use strict";var Colorifier;Colorifier=function(){var processData,decodeColor,getDistance,getTargetColor;Player.createGenericPlayers();this.colorifyForPlayers=function(image,source,maxDistance){var images,player,i;images=[];for(i=0;player=Player.getPlayer(i++);){images.push(this.colorify(image,source,player.color,maxDistance));}
return images;};this.colorify=function(image,source,target,maxDistance){var canvas,context,data;canvas=document.createElement('canvas');canvas.width=image.width;canvas.height=image.height;context=canvas.getContext('2d');context.drawImage(image,0,0);data=context.getImageData(0,0,image.width-1,image.height-1);processData(data,decodeColor(source),decodeColor(target),maxDistance);context.putImageData(data,0,0);return canvas;};processData=function(pixelData,source,target,maxDistance){var data,i,r,g,b,length,distance,newColor;data=pixelData.data;length=data.length;for(i=0;i<length;i+=4){r=data[i];g=data[i+1];b=data[i+2];distance=getDistance(r,g,b,source.r,source.g,source.b);if(distance<=maxDistance){newColor=getTargetColor(source,{r:r,g:g,b:b},target);data[i]=newColor.r;data[i+1]=newColor.g;data[i+2]=newColor.b;}}};getTargetColor=function(source,pixel,target){var rd,gd,bd;rd=target.r-source.r;gd=target.g-source.g;bd=target.b-source.b;return{r:Math.max(0,Math.min(255,pixel.r+rd)),g:Math.max(0,Math.min(255,pixel.g+gd)),b:Math.max(0,Math.min(255,pixel.b+bd))};};getDistance=function(r1,g1,b1,r2,g2,b2){return Math.sqrt(Math.pow(r1-r2,2)+Math.pow(g1-g2,2)+
Math.pow(b1-b2,2));};decodeColor=function(color){color=color.length==7?color.substring(1):color;return{r:parseInt(color.substring(0,2),16),g:parseInt(color.substring(2,4),16),b:parseInt(color.substring(4,6),16)};};};"use strict";var View;View=function(){var mainview,minimap;this.setCanvas=function(viewCanvas){mainview=new MainView();mainview.setCanvas(viewCanvas);};this.setMinimapContainer=function(container){minimap=new MiniMap();minimap.setContainer(container);};this.setMinimapSize=function(width,height){minimap.setSize(width,height);};this.setMap=function(map){if(!mainview||!minimap){throw new Error('Cannot set map befor canvases and minimap '+'container');}
mainview.setMap(map);minimap.setMap(map);minimap.setMainViewBufferSize(mainview.getLayersDimensions());};this.onBuildingChange=function(building){if(building.type===false){mainview.onBuildingRemoved(building);}else{mainview.onBuildingAdded(building);}
minimap.onBuildingChange(building);};this.onUnitChange=function(unit){mainview.onUnitChange(unit);minimap.onUnitChange(unit);};this.setMainViewSize=function(width,height){minimap.setMainViewSize(width,height);};this.display=function(x,y){mainview.display(x,y);minimap.render(x,y);};this.getMainViewLayersDimensions=function(){return mainview.getLayersDimensions();};};"use strict";var UnitsLayer;UnitsLayer=function(){var canvas,canvasWidth,canvasHeight,canvasContext,tileWidth,tileHeight,grid,addUnit,removeUnit,gridWidth,gridHeight,horizonzalTilesOnDisplay,verticalTilesOnDisplay,index,horizonzalIndexTilesOnDisplay,verticalIndexTilesOnDisplay,indexGranularity,displayIndexCell;this.setCanvas=function(newCanvas){canvas=newCanvas;canvasWidth=canvas.width;canvasHeight=canvas.height;canvasContext=canvas.getContext('2d');};this.setMap=function(map){var i,j,row,mapData,units;if(!canvas){throw new Error('The canvas has to be set before map');}
mapData=map.getMap();tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=TilesDefinition.getType(0).imageData.height/2-1;horizonzalTilesOnDisplay=Math.ceil(canvasWidth/tileWidth)+2;verticalTilesOnDisplay=Math.ceil(canvasHeight/tileHeight)+2;grid=[];for(i=mapData.length;i--;){row=[];for(j=mapData[0].length;j--;){row.push(false);}
grid.push(row);}
gridWidth=grid[0].length;gridHeight=grid.length;index=[];indexGranularity=Settings.gridIndexGranularity;for(i=Math.ceil(gridHeight/indexGranularity);i--;){row=[];for(j=Math.ceil(gridWidth/indexGranularity);j--;){row.push(0);}
index.push(row);}
horizonzalIndexTilesOnDisplay=Math.ceil(horizonzalTilesOnDisplay/indexGranularity);verticalIndexTilesOnDisplay=Math.ceil(verticalTilesOnDisplay/indexGranularity);units=map.getUnits();for(i=units.length;i--;){this.onUnitChange(units[i]);}};this.getLayerDimensions=function(){return{width:gridWidth*tileWidth+tileWidth/2,height:gridHeight*tileHeight+tileHeight};};this.onUnitChange=function(unit){switch(unit.action){case 2:removeUnit(unit);case 0:addUnit(unit);break;case 1:removeUnit(unit);break;}};this.display=function(x,y){var gridX,gridY,indexX,indexY,i,j;gridX=Math.max(0,Math.floor(x/tileWidth)-1);gridY=Math.max(0,Math.floor(y/tileHeight)-1);indexX=Math.floor(gridX/indexGranularity);indexY=Math.floor(gridY/indexGranularity);for(i=verticalIndexTilesOnDisplay;i--;){if(index[indexY+i]){for(j=horizonzalIndexTilesOnDisplay;j--;){if(index[indexY+i][indexX+j]){displayIndexCell(indexX+j,indexY+i,x,y);}}}}};displayIndexCell=function(x,y,screenX,screenY){var i,j,unit,gridX,gridY,currentX,currentY,offsetX;gridX=x*indexGranularity;gridY=y*indexGranularity;for(i=indexGranularity;i--;){currentY=gridY+i;offsetX=(currentY%2)*tileWidth/2;for(j=indexGranularity;j--;){currentX=gridX+j;if(grid[currentY]&&(unit=grid[currentY][currentX])){canvasContext.drawImage(UnitsDefinition.getType(unit.type).playerImages[unit.direction][unit.player],offsetX+currentX*tileWidth-screenX-
unit.moveOffsetX,currentY*tileHeight-screenY-
unit.moveOffsetY);}}}};addUnit=function(unit){grid[unit.y][unit.x]=unit;index[Math.floor(unit.y/indexGranularity)][Math.floor(unit.x/indexGranularity)]++;};removeUnit=function(unit){if(unit.action==1){grid[unit.y][unit.x]=false;index[Math.floor(unit.y/indexGranularity)][Math.floor(unit.x/indexGranularity)]--;}else{grid[unit.lastY][unit.lastX]=false;index[Math.floor(unit.lastY/indexGranularity)][Math.floor(unit.lastX/indexGranularity)]--;}};};"use strict";var TerrainLayer;TerrainLayer=function(){var buffer,canvas,canvasContext,map,bufferWidth,bufferHeight,bufferCanvas;this.setCanvas=function(newCanvas){canvas=newCanvas;canvasContext=canvas.getContext('2d');};this.getBufferDimensions=function(){return{width:bufferWidth,height:bufferHeight};};this.setMap=function(newMap){if(!(newMap instanceof Array)){throw new TypeError('map has to be an array');}
map=newMap;};this.display=function(x,y){canvasContext.drawImage(bufferCanvas,-x,-y);};this.updateTile=function(x,y){var xOffset,tileWidth,tileHeight;tileWidth=TilesDefinition.getType(0).imageData.width;tileWidth-=1;tileHeight=TilesDefinition.getType(0).imageData.height;tileHeight/=2;tileHeight-=1;xOffset=(y%2)*(tileWidth/2);buffer.drawImage(TilesDefinition.getType(map[y][x].type).imageData,xOffset+x*tileWidth,y*tileHeight-2);};this.init=function(){var tileWidth,tileHeight,i,j,row,xOffset;if(!canvasContext){throw new Error("Missing renderer's target canvas");}
if(!map){throw new Error('Cannot init terrain renderer without map data');}
bufferCanvas=document.createElement('canvas');tileWidth=TilesDefinition.getType(0).imageData.width;tileHeight=TilesDefinition.getType(0).imageData.height;buffer=bufferCanvas.getContext('2d');tileHeight/=2;tileWidth-=1;tileHeight-=1;bufferCanvas.width=map[0].length*tileWidth+tileWidth/2;bufferCanvas.height=map.length*tileHeight+tileHeight;for(i=map.length;i--;){row=map[i];xOffset=(i%2)*(tileWidth/2);for(j=row.length;j--;){buffer.drawImage(TilesDefinition.getType(row[j].type).imageData,xOffset+j*tileWidth,i*tileHeight-2);}}
bufferWidth=bufferCanvas.width;bufferHeight=bufferCanvas.height;};};"use strict";window.TerrainBuildingsLayer=function(){var bufferCanvas,bufferContext,bufferWidth,bufferHeight,renderingView,tiles,map,tileWidth,tileHeight;this.setCanvas=function(canvas){renderingView=canvas.getContext("2d");};this.getBufferDimensions=function(){return{width:bufferWidth,height:bufferHeight};};this.setMap=function(newMap){if(!(newMap instanceof Map)){throw new TypeError("The map has to be a Map instance");}
map=newMap;tiles=newMap.getTiles();};this.display=function(x,y){renderingView.drawImage(bufferCanvas,-x,-y);};this.updateTile=function(x,y){var tileImage;tileImage=TilesDefinition.getType(tiles[y][x].type).imageData;x=((y%2)*(tileWidth/2))+x*tileWidth;bufferContext.drawImage(tileImage,x,y*tileHeight-2);};this.onBuildingAdded=function(building){var type,x,y;type=BuildingsDefinition.getType(building.type);x=(tileWidth/2)*(building.y%2)+tileWidth*building.x;y=tileHeight*building.y;bufferContext.drawImage(type.playerImages[building.player],x,y-2);};this.onBuildingRemoved=function(building){var tileCoordinates,i;tileCoordinates=map.getTilesOccupiedByBuilding(building);for(i=tileCoordinates.length;i--;){this.updateTile(tileCoordinates[i].x,tileCoordinates[i].y);}};this.init=function(){var i,j,row,xOffset,tileImage,buildings;if(!renderingView){throw new Error("The target canvas is not set yet - invoke "+"setCanvas() first");}
if(!tiles){throw new Error("The map is not set set - invoke setMap() first");}
bufferCanvas=document.createElement("canvas");tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=(TilesDefinition.getType(0).imageData.height/2)-1;bufferContext=bufferCanvas.getContext("2d");bufferCanvas.width=tiles[0].length*tileWidth+tileWidth/2;bufferCanvas.height=tiles.length*tileHeight+tileHeight;for(i=tiles.length;i--;){row=tiles[i];xOffset=(i%2)*(tileWidth/2);for(j=row.length;j--;){tileImage=TilesDefinition.getType(row[j].type).imageData;bufferContext.drawImage(tileImage,xOffset+j*tileWidth,i*tileHeight-2);}}
bufferWidth=bufferCanvas.width;bufferHeight=bufferCanvas.height;buildings=map.getBuildings();for(i=buildings.length;i--;){this.onBuildingAdded(buildings[i]);}};};"use strict";var SFX;SFX=function(){var canvas,map,canvasWidth,canvasHeight,tileWidth,tileHeight,context,canvasTileWidth,canvasTileHeight,depthFactor,canvasCenterX,canvasCenterY,buildingsIndex,displayLightSFX,displayBuildableTiles,enableBuildOverlay,navigationIndex,enableNavigationIndex,inaccessibleColor,accessibleColor,projectiles;depthFactor=Settings.sfx3DLightFactor;accessibleColor=Settings.sfxAccessibleTileColor;inaccessibleColor=Settings.sfxInaccessibleTileColor;enableBuildOverlay=false;enableNavigationIndex=false;projectiles=[];this.setCanvas=function(newCanvas){canvas=newCanvas;canvasWidth=canvas.width;canvasHeight=canvas.height;context=canvas.getContext('2d');context.strokeStyle=Settings.sfx3DLightColor;context.lineCap='round';canvasCenterX=canvasWidth/2;canvasCenterY=canvasHeight/2;};this.setMap=function(newMap){if(!canvas){throw new Error("cannot set map for SFX before canvas!");}
map=newMap.getMap();tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=TilesDefinition.getType(0).imageData.height/2-1;canvasTileWidth=Math.ceil(canvasWidth/tileWidth);canvasTileHeight=Math.ceil(canvasHeight/tileHeight);buildingsIndex=newMap.getBuildingsIndex();navigationIndex=newMap.getNavigationIndex();projectiles=newMap.getProjectiles();};this.setDisplayBuildableOverlay=function(displayBuildableOverlay){enableBuildOverlay=displayBuildableOverlay;};this.setDisplayNavigationIndex=function(displayNavigationIndex){enableNavigationIndex=displayNavigationIndex;};this.display=function(x,y){context.globalAlpha=0.6;context.lineWidth=2;displayProjectiles(x,y);context.globalAlpha=0.3;displayLightSFX(x,y);enableBuildOverlay&&displayBuildableTiles(x,y);enableNavigationIndex&&displayNavigableTiles(x,y);context.globalAlpha=1;};function displayProjectiles(x,y){var i,projectile;for(i=projectiles.length;i--;){projectile=projectiles[i];switch(projectile.type){case 0:context.strokeStyle=projectile.player.color;context.beginPath();context.moveTo(projectile.startX-x,projectile.startY-y);context.lineTo(projectile.targetX-x,projectile.targetY-y);context.stroke();break;default:throw new Error("Unsupported projectile type: "+
projectile.type);}}}
function displayLightSFX(x,y){var mapOffsetX,mapOffsetY,i,j,offsetX,offsetY,shiftX,endX,endY,mapRow,mapTile;y-=tileHeight;x-=tileWidth/2;mapOffsetX=Math.floor(x/tileWidth);mapOffsetY=Math.floor(y/tileHeight);context.strokeStyle=Settings.sfx3DLightColor;for(j=canvasTileHeight+2;j--;){mapRow=map[j+mapOffsetY];if(!mapRow){continue;}
offsetY=(j+mapOffsetY)*tileHeight-y;shiftX=((mapOffsetY+j)%2)*tileWidth/2;for(i=canvasTileWidth+2;i--;){mapTile=mapRow[i+mapOffsetX];if(!mapTile||!mapTile.lightSfx){continue;}
offsetX=(i+mapOffsetX)*tileWidth+shiftX-x;endX=offsetX+(offsetX-canvasCenterX)/depthFactor;endY=offsetY+(offsetY-canvasCenterY)/depthFactor;context.lineWidth=mapTile.lightSfx;context.beginPath();context.moveTo(offsetX,offsetY);context.lineTo(endX,endY);context.stroke();}}}
function displayBuildableTiles(x,y){var mapOffsetX,mapOffsetY,i,j,mapRow,offsetY,shiftX,mapTile,offsetX;context.fillStyle=Settings.sfxBuildLayerColor;mapOffsetX=Math.floor(x/tileWidth)-1;mapOffsetY=Math.floor(y/tileHeight)-1;for(j=canvasTileHeight+2;j--;){mapRow=buildingsIndex[j+mapOffsetY];if(!mapRow){continue;}
offsetY=(j+mapOffsetY)*tileHeight-y;shiftX=((mapOffsetY+j)%2)*tileWidth/2;for(i=canvasTileWidth+2;i--;){mapTile=mapRow[i+mapOffsetX];if(!mapTile){continue;}
offsetX=(i+mapOffsetX)*tileWidth+shiftX-x;displayTileOverlay(offsetX,offsetY);}}}
function displayTileOverlay(x,y){context.beginPath();context.moveTo(x+(tileWidth/2),y);context.lineTo(x+tileWidth,y+tileHeight);context.lineTo(x+(tileWidth/2),y+(tileHeight*2));context.lineTo(x,y+tileHeight);context.fill();}
function displayNavigableTiles(x,y){var mapOffsetX,mapOffsetY,i,j,mapRow,offsetY,shiftX,mapTile,offsetX;mapOffsetX=Math.floor(x/tileWidth)-1;mapOffsetY=Math.floor(y/tileHeight)-1;for(j=canvasTileHeight+2;j--;){mapRow=navigationIndex[j+mapOffsetY];if(!mapRow){continue;}
offsetY=(j+mapOffsetY)*tileHeight-y;shiftX=((mapOffsetY+j)%2)*tileWidth/2;for(i=canvasTileWidth+2;i--;){mapTile=mapRow[i+mapOffsetX];context.fillStyle=mapTile?accessibleColor:inaccessibleColor;offsetX=(i+mapOffsetX)*tileWidth+shiftX-x;displayTileOverlay(offsetX,offsetY);}}}};"use strict";var MiniMap;MiniMap=function(){var tiles,container,buildingsLayer,unitsLayer,width,height,mapWidth,mapHeight,buildingsLayerCtx,unitsLayerCtx,xRatio,yRatio,tileWidth,tileHeight,changedTerrain,changedBuildings,changedUnits,drawTileLine,fill,buildingsLayerIndex,createIndex,xRatioC,yRatioC,initRenderer,renderUnitsLayer,renderBuildingsLayer,renderTerrainLayer,terrainLayer,terrainLayerCtx,map,instance,viewBordersLayer,viewBordersCtx,viewBordersWidth,viewBordersHeight,lastX,lastY,mainViewBufferWidth,mainViewBufferHeight;tiles=[];terrainLayer=document.createElement('canvas');terrainLayerCtx=terrainLayer.getContext('2d');buildingsLayer=document.createElement('canvas');buildingsLayerCtx=buildingsLayer.getContext('2d');unitsLayer=document.createElement('canvas');unitsLayerCtx=unitsLayer.getContext('2d');viewBordersLayer=document.createElement('canvas');viewBordersCtx=viewBordersLayer.getContext('2d');viewBordersCtx.lineCap='square';viewBordersCtx.lineJoin='bevel';changedTerrain=false;changedBuildings=false;changedUnits=false;instance=this;this.setMap=function(newMap){if(!(newMap instanceof Map)){throw new TypeError("An instance of the Map class is required");}
map=newMap;tiles=newMap.getTiles();mapHeight=tiles.length;mapWidth=tiles[0].length;if(container&&width){initRenderer();}};this.setMainViewSize=function(width,height){viewBordersWidth=width;viewBordersHeight=height;};this.setContainer=function(newContainer){if(!(newContainer instanceof HTMLElement)){throw new Error("container must be an HTML element");}
container=newContainer;width=container.offsetWidth;height=container.offsetHeight;terrainLayer.width=buildingsLayer.width=unitsLayer.width=viewBordersLayer.width=width;terrainLayer.height=buildingsLayer.height=unitsLayer.height=viewBordersLayer.height=height;newContainer=document.createElement('div');newContainer.style.height='0px';newContainer.appendChild(terrainLayer);container.appendChild(newContainer);newContainer=document.createElement('div');newContainer.style.height='0px';newContainer.appendChild(buildingsLayer);container.appendChild(newContainer);newContainer=document.createElement('div');newContainer.style.height='0px';newContainer.appendChild(unitsLayer);container.appendChild(newContainer);container.appendChild(viewBordersLayer);if(mapWidth&&width){initRenderer();}};this.setSize=function(newWidth,newHeight){width=newWidth;height=newHeight;terrainLayer.width=buildingsLayer.width=unitsLayer.width=viewBordersLayer.width=width;terrainLayer.height=buildingsLayer.height=unitsLayer.height=viewBordersLayer.height=height;if(map&&container){initRenderer();}};this.onBuildingChange=function(building){changedBuildings.push(building);};this.onUnitChange=function(unit){changedUnits.push(unit);};this.render=function(x,y){changedTerrain&&renderTerrainLayer();changedBuildings.length&&renderBuildingsLayer();changedUnits.length&&renderUnitsLayer();if((x!==lastX)||(y!==lastY)){lastX=x;lastY=y;x=Math.round(x/mainViewBufferWidth*width);y=Math.round(y/mainViewBufferHeight*height);viewBordersCtx.strokeStyle='white';viewBordersCtx.lineWidth=Math.round((tileWidth+tileHeight)/2);viewBordersCtx.clearRect(0,0,viewBordersLayer.width,viewBordersLayer.height);viewBordersCtx.strokeRect(x,y,viewBordersWidth*xRatio,viewBordersHeight*yRatio*2);}};this.setMainViewBufferSize=function(dimensions){mainViewBufferWidth=dimensions.width;mainViewBufferHeight=dimensions.height;};renderUnitsLayer=function(){var i,unit;for(i=changedUnits.length;i--;){unit=changedUnits[i];unitsLayerCtx.fillStyle=unit.color;switch(unit.action){case 2:unitsLayerCtx.globalCompositeOperation='destination-out';unitsLayerCtx.fillRect(unit.lastX*xRatio,unit.lastY*yRatio,xRatioC,yRatioC);case 0:unitsLayerCtx.globalCompositeOperation='source-over';unitsLayerCtx.fillRect(unit.x*xRatio,unit.y*yRatio,xRatioC,yRatioC);break;case 1:unitsLayerCtx.globalCompositeOperation='destination-out';unitsLayerCtx.fillRect(unit.x*xRatio,unit.y*yRatio,xRatioC,yRatioC);break;}}
changedUnits=[];};renderBuildingsLayer=function(){var i,building,x1,y1,x2,y2,x3,y3,x4,y4;for(i=changedBuildings.length;i--;){building=changedBuildings[i];buildingsLayerCtx.globalCompositeOperation=building.type===false?'destination-out':'source-over';x1=building.x;y1=building.y;x2=x1+building.width;y2=y1+Math.floor(building.width/2);x3=x1-Math.floor(building.height/2);y3=y1+building.height;x4=x3+building.width;y4=y3+Math.floor(building.width/2);buildingsLayerCtx.fillStyle=building.color;drawTileLine(x1,y1,x2,y2,buildingsLayerCtx);drawTileLine(x1,y1,x3,y3,buildingsLayerCtx);drawTileLine(x2,y2,x4,y4,buildingsLayerCtx);drawTileLine(x3,y3,x4,y4,buildingsLayerCtx);fill(Math.round((x1+x4)/2),Math.round((y1+y4)/2),buildingsLayerCtx);}
changedBuildings=[];};renderTerrainLayer=function(){var i,j,row;for(i=tiles.length;i--;){row=tiles[i];for(j=row.length;j--;){terrainLayerCtx.fillStyle=row[j].minimap;terrainLayerCtx.fillRect(xRatio*j,yRatio*i,tileWidth,tileHeight);}}
changedTerrain=false;};createIndex=function(){var index,i,j;index=new Array(mapWidth);for(i=mapWidth;i--;){index[i]=new Array(mapHeight);for(j=mapHeight;j--;){index[i][j]=false;}}
return index;};fill=function(x,y,ctx,fillColor){var thisColor;if((x>=mapWidth)||(x<0)||(y>=mapHeight)||(y<0)){return;}
thisColor=buildingsLayerIndex[x][y];if(fillColor===undefined){fillColor=thisColor;}
if(thisColor==fillColor){ctx.fillRect(x*xRatio,y*yRatio,xRatioC,yRatioC);buildingsLayerIndex[x][y]=!buildingsLayerIndex[x][y];fill(x-1,y,ctx,fillColor);fill(x+1,y,ctx,fillColor);fill(x,y-1,ctx,fillColor);fill(x,y+1,ctx,fillColor);}};drawTileLine=function(x1,y1,x2,y2,ctx){var len,vx,vy,rx,ry;vx=x2-x1;vy=y2-y1;len=Math.sqrt(vx*vx+vy*vy);vx/=len;vy/=len;ctx.fillRect(xRatio*Math.round(x1),yRatio*Math.round(y1),xRatioC,yRatioC);do{x1+=vx;y1+=vy;rx=Math.round(x1);ry=Math.round(y1);if(buildingsLayerIndex[rx]&&(buildingsLayerIndex[rx][ry]!==undefined)){buildingsLayerIndex[rx][ry]=true;ctx.fillRect(xRatio*rx,yRatio*ry,xRatioC,yRatioC);}}while((Math.round(x1)!=x2)&&(Math.round(y1)!=y2))};initRenderer=function(){var i;xRatio=width/mapWidth;yRatio=height/mapHeight;xRatioC=Math.ceil(xRatio);yRatioC=Math.ceil(yRatio);tileWidth=Math.ceil(xRatio);tileHeight=Math.ceil(yRatio);changedTerrain=true;changedBuildings=[];changedUnits=[];buildingsLayerIndex=createIndex();for(i=map.getBuildings().length;i--;){instance.onBuildingChange(map.getBuildings()[i]);}
for(i=map.getUnits().length;i--;){instance.onUnitChange(map.getUnits()[i]);}};};"use strict";var MainView;MainView=function(){var terrainBuildingsLayer,unitsLayer,sfxLayer;this.setCanvas=function(viewCanvas){terrainBuildingsLayer=new TerrainBuildingsLayer();terrainBuildingsLayer.setCanvas(viewCanvas);unitsLayer=new UnitsLayer();unitsLayer.setCanvas(viewCanvas);sfxLayer=new SFX();sfxLayer.setCanvas(viewCanvas);};this.setMap=function(map){if(!terrainBuildingsLayer){throw new Error('Cannot set map before canvas');}
terrainBuildingsLayer.setMap(map);unitsLayer.setMap(map);sfxLayer.setMap(map);terrainBuildingsLayer.init();};this.display=function(x,y){terrainBuildingsLayer.display(x,y);unitsLayer.display(x,y);sfxLayer.display(x,y);};this.onBuildingAdded=function(building){terrainBuildingsLayer.onBuildingAdded(building);};this.onBuildingRemoved=function(building){terrainBuildingsLayer.onBuildingRemoved(building);};this.onUnitChange=function(unit){unitsLayer.onUnitChange(unit);};this.getLayersDimensions=function(){if(!terrainBuildingsLayer){throw new Error("Layer renderers have not been initialized yet");}
return terrainBuildingsLayer.getBufferDimensions();};};"use strict";var BuildingsLayer;BuildingsLayer=function(){var buffer,canvas,canvasWidth,canvasHeight,canvasContext,bufferWidth,bufferHeight,tileWidth,tileHeight,bufferCanvas;this.setCanvas=function(newCanvas){canvas=newCanvas;canvasWidth=canvas.width;canvasHeight=canvas.height;canvasContext=canvas.getContext('2d');};this.getBufferDimensions=function(){return{width:bufferWidth,height:bufferHeight};};this.setMap=function(map){var buildings,i;tileWidth=TilesDefinition.getType(0).imageData.width;tileHeight=TilesDefinition.getType(0).imageData.height;tileHeight/=2;tileWidth-=1;tileHeight-=1;bufferWidth=map.getMap()[0].length*tileWidth+tileWidth/2;bufferHeight=map.getMap().length*tileHeight+tileHeight;bufferCanvas=document.createElement('canvas');bufferCanvas.width=bufferWidth;bufferCanvas.height=bufferHeight;buffer=bufferCanvas.getContext('2d');buildings=map.getBuildings();for(i=buildings.length;i--;){this.onBuildingAdded(buildings[i]);}};this.onBuildingAdded=function(building){var type,x,y;type=BuildingsDefinition.getType(building.type);x=(tileWidth/2)*(building.y%2)+tileWidth*building.x;y=tileHeight*building.y;buffer.globalCompositeOperation='source-over';buffer.drawImage(type.playerImages[building.player],x,y-2);};this.onBuildingRemoved=function(building){var type,x,y;type=BuildingsDefinition.getType(building.type);x=(tileWidth/2)*(building.y%2)+tileWidth*building.x;y=tileHeight*building.y;buffer.globalCompositeOperation='destination-out';buffer.drawImage(type.imageData,x,y-2);};this.display=function(x,y){canvasContext.drawImage(bufferCanvas,-x,-y);};};"use strict";var MouseGestures;MouseGestures=function(directionGranularity,ignoreDuplicates,minDistance,mouseButton){var previousX,previousY,active,computeDirection,lastDirection,gesture,listeners,executeListeners,gestures;active=false;listeners=[];gestures={};this.addListener=function(listener){listeners.push(listener);};this.addGestureListener=function(gesture,listener){if(!gestures[gesture]){gestures[gesture]=[];}
gestures[gesture].push(listener);};this.addListener(function(gesture){var i,listeners;listeners=gestures[gesture.join('')];if(listeners){for(i=listeners.length;i--;){listeners[i]();}}});computeDirection=function(x,y){var max,absX,absY;absX=Math.abs(x);absY=Math.abs(y);max=Math.max(absX,absY);x/=max;y/=max;if(directionGranularity==4){if(absX>absY){return x>0?1:3;}
return y>0?2:0;}
if(absX/2>absY){return x>0?2:6;}
if(absX>absY/2){return x>0?(y>0?3:1):(y>0?5:7);}
return y>0?4:0;};executeListeners=function(gesture){var i;for(i=listeners.length;i--;){listeners[i](gesture);}};addEventListener('mousedown',function(e){if(mouseButton==e.button){e.preventDefault();e.stopPropagation();active=true;previousX=undefined;lastDirection=undefined;gesture=[];}},false);if(mouseButton==2){addEventListener('contextmenu',function(e){e.preventDefault();});}
addEventListener('mouseup',function(){if(active){active=false;executeListeners(gesture);}});addEventListener('mousemove',function(e){var direction,distance,distanceX,distanceY;if(previousX&&active){distanceX=e.pageX-previousX;distanceY=e.pageY-previousY;distance=Math.sqrt(Math.pow(distanceX,2)+
Math.pow(distanceY,2));if(distance<minDistance){return;}
direction=computeDirection(distanceX,distanceY);if(ignoreDuplicates&&(lastDirection==direction)){return;}
lastDirection=direction;gesture.push(direction);previousX=undefined;return;}
previousX=e.pageX;previousY=e.pageY;},false);};"use strict";var Mouse;Mouse=function(){var x,y,mapX,mapY,canvasLeftOffset,canvasTopOffset,tileWidth,tileHeight,tileWidthHalf,mapXOffset,mapYOffset;tileWidth=TilesDefinition.getType(0).imageData.width-1;tileHeight=TilesDefinition.getType(0).imageData.height/2-1;tileWidthHalf=tileWidth/2;mapXOffset=0;mapYOffset=0;this.getX=function(){return x;};this.getY=function(){return y;};this.getMapX=function(){return mapX;};this.getMapY=function(){return mapY;};this.setCanvasOffset=function(left,top){canvasLeftOffset=left;canvasTopOffset=top;};this.setMapOffset=function(x,y){mapXOffset=x;mapYOffset=y;};addEventListener('mousemove',function(e){var xShift,yShift;x=e.pageX-canvasLeftOffset+mapXOffset;y=e.pageY-canvasTopOffset+mapYOffset;mapX=Math.floor(x/tileWidth);mapY=Math.floor(y/tileHeight);xShift=x-mapX*tileWidth;yShift=y-mapY*tileHeight;if(mapY%2){if(xShift>=tileWidthHalf){xShift-=tileWidthHalf;mapY-=(xShift+yShift<tileWidthHalf)?1:0;}else{if(tileWidthHalf-xShift+yShift<tileWidthHalf){mapY--;}else{mapX--;}}}else{if(xShift>=tileWidthHalf){xShift-=tileWidthHalf;mapY-=(tileWidthHalf-xShift+yShift<tileWidthHalf)?1:0;}else{if(xShift+yShift<tileWidthHalf){mapX--;mapY--;}}}},false);};"use strict";var Storage={persist:function(name,data){localStorage.setItem(name,JSON.stringify(data));window[name]=data;},get:function(name){return JSON.parse(localStorage.getItem(name));},getKeys:function(){var keys,i;keys=[];for(i=localStorage.length;i--;){keys.push(localStorage.key(i));}
return keys;},remove:function(name){localStorage.removeItem(name);},clear:function(){localStorage.clear();}};(function(){var keys,i;keys=Storage.getKeys();for(i=keys.length;i--;){window[keys[i]]=Storage.get(keys[i]);}
addEventListener('beforeunload',function(){keys=Storage.getKeys();for(i=keys.length;i--;){if(window[keys[i]]===undefined){Storage.remove(keys[i])}else{Storage.persist(keys[i],window[keys[i]]);}}},false);}());"use strict";var MapCompressor;MapCompressor=function(){var compressLevel1,compressLevel2,compressLevel1Buildings,compressLevel3,decompressLevel1,decompressLevel2,decompressLevel3,spliceTiles,decompressLevel1Tiles;this.compress=function(map,level){(level>0)&&(map=compressLevel1(map));(level>1)&&(map=compressLevel2(map));(level>2)&&(map=compressLevel3(map));return map;};this.decompress=function(map,level){(level>2)&&(map=decompressLevel3(map));(level>1)&&(map=decompressLevel2(map));(level>0)&&(map=decompressLevel1(map));return map;};decompressLevel1=function(map){var tiles,i,buildings,units;tiles=decompressLevel1Tiles(map);buildings=map.buildings;buildings.reverse();for(i=buildings.length;i--;){buildings[i]={x:buildings[i].x,y:buildings[i].y,type:buildings[i].t,player:buildings[i].p};}
units=map.units;units.reverse();for(i=units.length;i--;){units[i]={x:units[i].x,y:units[i].y,direction:units[i].d,type:units[i].t,player:units[i].p};}
return{tiles:tiles,buildings:buildings,units:units,projectiles:[]};};decompressLevel1Tiles=function(map){var tiles,row,i,j;tiles=spliceTiles(map.tiles,map.width);for(i=tiles.length;i--;){row=tiles[i];row.reverse();for(j=row.length;j--;){row[j]={type:row[j].t,lightSfx:row[j].l};}}
return tiles;};spliceTiles=function(tiles,cols){var rows;rows=[];while(tiles.length){rows.push(tiles.splice(0,cols));}
rows.reverse();return rows;};decompressLevel2=function(map){var i,tiles,mapTiles,buildings,mapBuildings,units,mapUnits;tiles=map.tiles;mapTiles=[];for(i=tiles.length;i--;){mapTiles.push({t:parseInt(tiles[i][0],10),l:parseInt(tiles[i][1],10)});}
buildings=map.buildings;mapBuildings=[];for(i=buildings.length;i--;){mapBuildings.push({x:parseInt(buildings[i][0],10),y:parseInt(buildings[i][1],10),t:parseInt(buildings[i][2],10),p:parseInt(buildings[i][3],10)});}
units=map.units;mapUnits=[];for(i=units.length;i--;){mapUnits.push({x:parseInt(units[i][0],10),y:parseInt(units[i][1],10),d:parseInt(units[i][2],10),t:parseInt(units[i][3],10),p:parseInt(units[i][4],10)});}
return{width:map.width,height:map.height,tiles:mapTiles,buildings:mapBuildings,units:mapUnits};};decompressLevel3=function(map){var tiles,buildings,units,i;map=map.split('|');tiles=map[2].split('-');buildings=map[3]?map[3].split('-'):[];units=map[4]?map[4].split('-'):[];for(i=tiles.length;i--;){tiles[i]=tiles[i].split(',');}
for(i=buildings.length;i--;){buildings[i]=buildings[i].split(',');}
for(i=units.length;i--;){units[i]=units[i].split(',');}
return{width:parseInt(map[0],10),height:parseInt(map[1],10),tiles:tiles,buildings:buildings,units:units};};compressLevel3=function(map){var tiles,buildings,units,i;tiles=map.tiles;for(i=tiles.length;i--;){tiles[i]=tiles[i].join(',');}
buildings=map.buildings;for(i=buildings.length;i--;){buildings[i]=buildings[i].join(',');}
units=map.units;for(i=units.length;i--;){units[i]=units[i].join(',');}
return[map.width,map.height,tiles.join('-'),buildings.join('-'),units.join('-')].join('|');};compressLevel2=function(map){var tiles,mapTiles,buildings,mapBuildings,units,mapUnits,i;tiles=[];mapTiles=map.tiles;for(i=mapTiles.length;i--;){tiles.push([mapTiles[i].t,mapTiles[i].l]);}
buildings=[];mapBuildings=map.buildings;for(i=mapBuildings.length;i--;){buildings.push([mapBuildings[i].x,mapBuildings[i].y,mapBuildings[i].t,mapBuildings[i].p]);}
units=[];mapUnits=map.units;for(i=mapUnits.length;i--;){units.push([mapUnits[i].x,mapUnits[i].y,mapUnits[i].d,mapUnits[i].t,mapUnits[i].p]);}
return{width:map.width,height:map.height,tiles:tiles,buildings:buildings,units:units};};compressLevel1=function(map){var rowCount,colCount,mapTiles,mapTilesRow,tiles,i,j,buildings,units,mapUnits;mapTiles=map.tiles;rowCount=mapTiles.length;colCount=mapTiles[0].length;tiles=[];for(j=rowCount;j--;){mapTilesRow=mapTiles[j];for(i=colCount;i--;){tiles.push({t:mapTilesRow[i].type,l:mapTilesRow[i].lightSfx});}}
buildings=compressLevel1Buildings(map.buildings);mapUnits=map.units;units=[];for(i=mapUnits.length;i--;){units.push({x:mapUnits[i].x,y:mapUnits[i].y,d:mapUnits[i].direction,t:mapUnits[i].type,p:mapUnits[i].player});}
return{width:colCount,height:rowCount,tiles:tiles,buildings:buildings,units:units};};compressLevel1Buildings=function(mapBuildings){var buildings,i;buildings=[];for(i=mapBuildings.length;i--;){buildings.push({x:mapBuildings[i].x,y:mapBuildings[i].y,t:mapBuildings[i].type,p:mapBuildings[i].player});}
return buildings;};};"use strict";var LZW;LZW=function(){this.encode=function(string){var dictionary,data,output,character,phrase,code,i,length;dictionary={};data=string.split('');output=[];phrase=data[0];code=256;length=data.length;for(i=1;i<length;i++){character=data[i];if(dictionary[phrase+character]){phrase+=character;}else{output.push(phrase.length>1?dictionary[phrase]:phrase.charCodeAt(0));dictionary[phrase+character]=code++;phrase=character;}}
output.push(phrase.length>1?dictionary[phrase]:phrase.charCodeAt(0));for(i=length;i--;){output[i]=String.fromCharCode(output[i]);}
return output.join('');};this.decode=function(string){var dictionary,data,character,oldPhrase,output,code,phrase,i,length,charCode;dictionary={};data=string.split('');character=data[0];oldPhrase=character;output=[character];code=256;length=data.length;for(i=1;i<length;i++){charCode=data[i].charCodeAt(0);if(charCode<256){phrase=data[i];}else{phrase=dictionary[charCode]||(oldPhrase+character);}
output.push(phrase);character=phrase.charAt(0);dictionary[code++]=oldPhrase+character;oldPhrase=phrase;}
return output.join('');};};"use strict";var Base64;Base64=function(){var keyString;keyString='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'+'0123456789+/=';this.encode=function(input){var output,chr1,chr2,chr3,enc1,enc2,enc3,enc4,i;input=escape(input);output='';i=0;do{chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;isNaN(chr2)&&(enc3=enc4=64);isNaN(chr3)&&(enc4=64);output+=keyString.charAt(enc1)+keyString.charAt(enc2)+
keyString.charAt(enc3)+keyString.charAt(enc4);}while(i<input.length);return output;};this.decode=function(input){var output,chr1,chr2,chr3,enc1,enc2,enc3,enc4,i;i=0;output='';do{enc1=keyString.indexOf(input.charAt(i++));enc2=keyString.indexOf(input.charAt(i++));enc3=keyString.indexOf(input.charAt(i++));enc4=keyString.indexOf(input.charAt(i++));chr1=(enc1<<2)|(enc2>>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output+=String.fromCharCode(chr1);(enc3!=64)&&(output+=String.fromCharCode(chr2));(enc4!=64)&&(output+=String.fromCharCode(chr3));}while(i<input.length);return unescape(output);};};