whisper.cat/weboasis/arcade/3dcity/build/city.3d.min.js

253 lines
127 KiB
JavaScript
Raw Normal View History

2023-10-05 23:28:32 +11:00
'use strict';var Micro={speedPowerScan:[2,4,5],speedPollutionTerrainLandValueScan:[2,7,17],speedCrimeScan:[1,8,18],speedPopulationDensityScan:[1,9,19],speedFireAnalysis:[1,10,20],CENSUS_FREQUENCY_10:4};Micro.CENSUS_FREQUENCY_120=10*Micro.CENSUS_FREQUENCY_10;Micro.TAX_FREQUENCY=48;Micro.MAP_WIDTH=128;Micro.MAP_HEIGHT=128;Micro.MAP_DEFAULT_WIDTH=3*Micro.MAP_WIDTH;Micro.MAP_DEFAULT_HEIGHT=3*Micro.MAP_HEIGHT;Micro.MAP_BIG_DEFAULT_WIDTH=16*Micro.MAP_WIDTH;Micro.MAP_BIG_DEFAULT_HEIGHT=16*Micro.MAP_HEIGHT;
Micro.MAP_BIG_DEFAULT_ID="bigMap";Micro.MAP_PARENT_ID="splashContainer";Micro.MAP_DEFAULT_ID="SplashCanvas";Micro.DEFAULT_WIDTH=400;Micro.DEFAULT_HEIGHT=400;Micro.DEFAULT_ID="MicropolisCanvas";Micro.RCI_DEFAULT_ID="RCICanvas";Micro.arrs="res com ind crime money pollution".split(" ");var M_ARRAY_TYPE;M_ARRAY_TYPE||(M_ARRAY_TYPE="undefined"!==typeof Float32Array?Float32Array:Array);Micro.clamp=function(a,b,c){return a<b?b:a>c?c:a};
Micro.makeConstantDescriptor=function(a){return{configurable:!1,enumerable:!1,writeable:!1,value:a}};Micro.rotate10Arrays=function(){for(var a=0;a<Micro.arrs.length;a++){var b=Micro.arrs[a]+"Hist10";this[b].pop();this[b].unshift(0)}};Micro.rotate120Arrays=function(){for(var a=0;a<Micro.arrs.length;a++){var b=Micro.arrs[a]+"Hist120";this[b].pop();this[b].unshift(0)}};Micro.isCallable=function(a){return"function"===typeof a};Micro.LEVEL_EASY=0;Micro.LEVEL_MED=1;Micro.LEVEL_HARD=2;
Micro.SPEED_PAUSED=0;Micro.SPEED_SLOW=1;Micro.SPEED_MED=2;Micro.SPEED_FAST=3;Micro.ROUTE_FOUND=1;Micro.NO_ROUTE_FOUND=0;Micro.NO_ROAD_FOUND=-1;Micro.MAX_TRAFFIC_DISTANCE=30;Micro.perimX=[-1,0,1,2,2,2,1,0,-1,-2,-2,-2];Micro.perimY=[-2,-2,-2,-1,0,1,2,2,2,1,0,-1];Micro.SPRITE_TRAIN=1;Micro.SPRITE_HELICOPTER=2;Micro.SPRITE_AIRPLANE=3;Micro.SPRITE_SHIP=4;Micro.SPRITE_MONSTER=5;Micro.SPRITE_TORNADO=6;Micro.SPRITE_EXPLOSION=7;Micro.CC_VILLAGE="VILLAGE";Micro.CC_TOWN="TOWN";Micro.CC_CITY="CITY";
Micro.CC_CAPITAL="CAPITAL";Micro.CC_METROPOLIS="METROPOLIS";Micro.CC_MEGALOPOLIS="MEGALOPOLIS";Micro.CRIME=0;Micro.POLLUTION=1;Micro.HOUSING=2;Micro.TAXES=3;Micro.TRAFFIC=4;Micro.UNEMPLOYMENT=5;Micro.FIRE=6;Micro.RES_VALVE_RANGE=2E3;Micro.COM_VALVE_RANGE=1500;Micro.IND_VALVE_RANGE=1500;Micro.taxTable=[200,150,120,100,80,50,30,0,-10,-40,-100,-150,-200,-250,-300,-350,-400,-450,-500,-550,-600];Micro.extMarketParamTable=[1.2,1.1,0.98];Micro.RLevels=[0.7,0.9,1.2];Micro.FLevels=[1.4,1.2,0.8];
Micro.MAX_ROAD_EFFECT=32;Micro.MAX_POLICESTATION_EFFECT=1E3;Micro.MAX_FIRESTATION_EFFECT=1E3;Micro.COAL_POWER_STRENGTH=700;Micro.NUCLEAR_POWER_STRENGTH=2E3;Micro.DISASTER_NONE="None";Micro.DISASTER_MONSTER="Monster";Micro.DISASTER_FIRE="Fire";Micro.DISASTER_FLOOD="Flood";Micro.DISASTER_CRASH="Crash";Micro.DISASTER_MELTDOWN="Meltdown";Micro.DISASTER_TORNADO="Tornado";Micro.CURRENT_VERSION=3;Micro.KEY="micropolisJSGame";Micro.lerp=function(a,b,c){return a+(b-a)*c};Micro.rand=function(a,b){return Micro.lerp(a,b,Math.random())};Micro.randInt=function(a,b,c){return 1*Micro.lerp(a,b,Math.random()).toFixed(c||0)};Micro.Random=function(){};
Micro.Random.prototype={constructor:Micro.Random,getChance:function(a){return 0===(this.getRandom16()&a)},getERandom:function(a){var b=this.getRandom(a);a=this.getRandom(a);return Math.min(b,a)},getRandom:function(a){return Math.floor(Math.random()*(a+1))},getRandom16:function(){return this.getRandom(65535)},getRandom16Signed:function(){var a=this.getRandom16();32768<=a&&(a=32768-a);return a}};var Random=new Micro.Random;Micro.Direction=function(){};
Micro.Direction.prototype={constructor:Micro.Direction,INVALID:-1,NORTH:0,NORTHEAST:1,EAST:2,SOUTHEAST:3,SOUTH:4,SOUTHWEST:5,WEST:6,NORTHWEST:7,BEGIN:0,END:8,increment45:function(a,b){if(1>arguments.length)throw new TypeError;if(a==this.INVALID)return a;b||0===b||(b=1);return a+b},increment90:function(a){if(1>arguments.length)throw new TypeError;return this.increment45(a,2)},rotate45:function(a,b){if(1>arguments.length)throw new TypeError;if(a==this.INVALID)return a;b||0===b||(b=1);return(a-this.NORTH+
b&7)+this.NORTH},rotate90:function(a){if(1>arguments.length)throw new TypeError;return this.rotate45(a,2)},rotate180:function(a){if(1>arguments.length)throw new TypeError;return this.rotate45(a,4)}};var Direction=new Micro.Direction;var messageData={AUTOBUDGET_CHANGED:Micro.makeConstantDescriptor("Autobudget changed"),BUDGET_NEEDED:Micro.makeConstantDescriptor("User needs to budget"),BLACKOUTS_REPORTED:Micro.makeConstantDescriptor("Blackouts reported"),DATE_UPDATED:Micro.makeConstantDescriptor("Date changed"),DID_TOOL:Micro.makeConstantDescriptor("Tool applied"),EARTHQUAKE:Micro.makeConstantDescriptor("Earthquake"),EXPLOSION_REPORTED:Micro.makeConstantDescriptor("Explosion Reported"),EVAL_UPDATED:Micro.makeConstantDescriptor("Evaluation Updated"),
FIRE_REPORTED:Micro.makeConstantDescriptor("Fire!"),FIRE_STATION_NEEDS_FUNDING:Micro.makeConstantDescriptor("Fire station needs funding"),FLOODING_REPORTED:Micro.makeConstantDescriptor("Flooding reported"),FUNDS_CHANGED:Micro.makeConstantDescriptor("Total funds has changed"),HEAVY_TRAFFIC:Micro.makeConstantDescriptor("Total funds has changed"),HELICOPTER_CRASHED:Micro.makeConstantDescriptor("Helicopter crashed"),HIGH_CRIME:Micro.makeConstantDescriptor("High crime"),HIGH_POLLUTION:Micro.makeConstantDescriptor("High pollution"),
MONSTER_SIGHTED:Micro.makeConstantDescriptor("Monster sighted"),NEED_ELECTRICITY:Micro.makeConstantDescriptor("More power needed"),NEED_FIRE_STATION:Micro.makeConstantDescriptor("Fire station needed"),NEED_MORE_COMMERCIAL:Micro.makeConstantDescriptor("More commercial zones needed"),NEED_MORE_INDUSTRIAL:Micro.makeConstantDescriptor("More industrial zones needed"),NEED_MORE_RESIDENTIAL:Micro.makeConstantDescriptor("More residential needed"),NEED_MORE_RAILS:Micro.makeConstantDescriptor("More railways needed"),
NEED_MORE_ROADS:Micro.makeConstantDescriptor("More roads needed"),NEED_POLICE_STATION:Micro.makeConstantDescriptor("Police station needed"),NEED_AIRPORT:Micro.makeConstantDescriptor("Airport needed"),NEED_SEAPORT:Micro.makeConstantDescriptor("Seaport needed"),NEED_STADIUM:Micro.makeConstantDescriptor("Stadium needed"),NO_MONEY:Micro.makeConstantDescriptor("No money"),NOT_ENOUGH_POWER:Micro.makeConstantDescriptor("Not enough power"),NUCLEAR_MELTDOWN:Micro.makeConstantDescriptor("Nuclear Meltdown"),
PLANE_CRASHED:Micro.makeConstantDescriptor("Plane crashed"),POLICE_NEEDS_FUNDING:Micro.makeConstantDescriptor("Police need funding"),QUERY_WINDOW_NEEDED:Micro.makeConstantDescriptor("Query window needed"),REACHED_CAPITAL:Micro.makeConstantDescriptor("Now a capital"),REACHED_CITY:Micro.makeConstantDescriptor("Now a city"),REACHED_METROPOLIS:Micro.makeConstantDescriptor("Now a metropolis"),REACHED_MEGALOPOLIS:Micro.makeConstantDescriptor("Now a megalopolis"),REACHED_TOWN:Micro.makeConstantDescriptor("Now a town"),
REACHED_VILLAGE:Micro.makeConstantDescriptor("Now a village"),ROAD_NEEDS_FUNDING:Micro.makeConstantDescriptor("Roads need funding"),SHIP_CRASHED:Micro.makeConstantDescriptor("Shipwrecked"),SOUND_EXPLOSIONHIGH:Micro.makeConstantDescriptor("Explosion! Bang!"),SOUND_EXPLOSIONLOW:Micro.makeConstantDescriptor("Explosion! Bang!"),SOUND_HEAVY_TRAFFIC:Micro.makeConstantDescriptor("Heavy Traffic sound"),SOUND_HONKHONK:Micro.makeConstantDescriptor("HonkHonk sound"),SOUND_MONSTER:Micro.makeConstantDescriptor("Monster sound"),
TAX_TOO_HIGH:Micro.makeConstantDescriptor("Tax too high"),TORNADO_SIGHTED:Micro.makeConstantDescriptor("Tornado sighted"),TRAFFIC_JAMS:Micro.makeConstantDescriptor("Traffic jams reported"),TRAIN_CRASHED:Micro.makeConstantDescriptor("Train crashed"),VALVES_UPDATED:Micro.makeConstantDescriptor("Valves updated"),WELCOME:Micro.makeConstantDescriptor("Welcome to 3D city"),WELCOMEBACK:Micro.makeConstantDescriptor("Welcome back to your 3D city")},Messages=Object.defineProperties({},messageData);Micro.MessageManager=function(){this.data=[]};Micro.MessageManager.prototype={constructor:Micro.MessageManager,sendMessage:function(a,b){this.data.push({message:a,data:b})},clear:function(){this.data=[]},getMessages:function(){return this.data.slice()}};Micro.Text=function(){var a={};a[""+Micro.LEVEL_EASY]="Easy";a[""+Micro.LEVEL_MED]="Medium";a[""+Micro.LEVEL_HARD]="Hard";var b={};b[Micro.CC_VILLAGE]="VILLAGE";b[Micro.CC_TOWN]="TOWN";b[Micro.CC_CITY]="CITY";b[Micro.CC_CAPITAL]="CAPITAL";b[Micro.CC_METROPOLIS]="METROPOLIS";b[Micro.CC_MEGALOPOLIS]="MEGALOPOLIS";var c={};c[Micro.CRIME]="Crime";c[Micro.POLLUTION]="Pollution";c[Micro.HOUSING]="Housing";c[Micro.TAXES]="Taxes";c[Micro.TRAFFIC]="Traffic";c[Micro.UNEMPLOYMENT]="Unemployment";c[Micro.FIRE]=
"Fire";var d={};d[Messages.FIRE_STATION_NEEDS_FUNDING]="Fire departments need funding";d[Messages.NEED_AIRPORT]="Commerce requires an Airport";d[Messages.NEED_FIRE_STATION]="Citizens demand a Fire Department";d[Messages.NEED_ELECTRICITY]="Build a Power Plant";d[Messages.NEED_MORE_INDUSTRIAL]="More industrial zones needed";d[Messages.NEED_MORE_COMMERCIAL]="More commercial zones needed";d[Messages.NEED_MORE_RESIDENTIAL]="More residential zones needed";d[Messages.NEED_MORE_RAILS]="Inadequate rail system";
d[Messages.NEED_MORE_ROADS]="More roads required";d[Messages.NEED_POLICE_STATION]="Citizens demand a Police Department";d[Messages.NEED_SEAPORT]="Industry requires a Sea Port";d[Messages.NEED_STADIUM]="Residents demand a Stadium";d[Messages.ROAD_NEEDS_FUNDING]="Roads deteriorating, due to lack of funds";d[Messages.POLICE_NEEDS_FUNDING]="Police departments need funding";d[Messages.WELCOME]="Welcome to 3D City";d[Messages.WELCOMEBACK]="Welcome to 3D City";var e={};e[Messages.BLACKOUTS_REPORTED]="Brownouts, build another Power Plant";
e[Messages.COPTER_CRASHED]="A helicopter crashed ";e[Messages.EARTHQUAKE]="Major earthquake reported !!";e[Messages.EXPLOSION_REPORTED]="Explosion detected ";e[Messages.FLOODING_REPORTED]="Flooding reported !";e[Messages.FIRE_REPORTED]="Fire reported ";e[Messages.HEAVY_TRAFFIC]="Heavy Traffic reported";e[Messages.HIGH_CRIME]="Crime very high";e[Messages.HIGH_POLLUTION]="Pollution very high";e[Messages.MONSTER_SIGHTED]="A Monster has been sighted !";e[Messages.NO_MONEY]="YOUR CITY HAS GONE BROKE";
e[Messages.NOT_ENOUGH_POWER]="Blackouts reported. insufficient power capacity";e[Messages.NUCLEAR_MELTDOWN]="A Nuclear Meltdown has occurred !!";e[Messages.PLANE_CRASHED]="A plane has crashed ";e[Messages.SHIP_CRASHED]="Shipwreck reported ";e[Messages.TAX_TOO_HIGH]="Citizens upset. The tax rate is too high";e[Messages.TORNADO_SIGHTED]="Tornado reported !";e[Messages.TRAFFIC_JAMS]="Frequent traffic jams reported";e[Messages.TRAIN_CRASHED]="A train crashed ";return{badMessages:e,cityClass:b,crimeStrings:["Safe",
"Light","Moderate","Dangerous"],densityStrings:["Low","Medium","High","Very High"],gameLevel:a,goodMessages:" {}",landValueStrings:["Slum","Lower Class","Middle Class","High"],months:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),neutralMessages:d,problems:c,pollutionStrings:["None","Moderate","Heavy","Very Heavy"],rateStrings:["Declining","Stable","Slow Growth","Fast Growth"],toolMessages:{noMoney:"Insufficient funds to build that",needsDoze:"Area must be bulldozed first"},zoneTypes:"Clear;Water;Trees;Rubble;Flood;Radioactive Waste;Fire;Road;Power;Rail;Residential;Commercial;Industrial;Seaport;Airport;Coal Power;Fire Department;Police Department;Stadium;Nuclear Power;Draw Bridge;Radar Dish;Fountain;Industrial;Steelers 38 Bears 3;Draw Bridge;Ur 238".split(";")}};
var TXT=new Micro.Text;Micro.CensusProps="resPop comPop indPop crimeRamp pollutionRamp landValueAverage pollutionAverage crimeAverage totalPop resHist10 resHist120 comHist10 comHist120 indHist10 indHist120 crimeHist10 crimeHist120 moneyHist10 moneyHist120 pollutionHist10 pollutionHist120".split(" ");
Micro.Census=function(){this.clearCensus();this.changed=!1;for(var a=this.totalPop=this.crimeAverage=this.pollutionAverage=this.landValueAverage=this.pollutionRamp=this.crimeRamp=0;a<Micro.arrs.length;a++){var b=Micro.arrs[a]+"Hist120",c=Micro.arrs[a]+"Hist10";this[c]=[];for(var d=120;d--;)this[c][d]=0;this[b]=[];for(c=120;c--;)this[b][c]=0}};
Micro.Census.prototype={constructor:Micro.Census,save:function(a){for(var b=0,c=Micro.CensusProps.length;b<c;b++)a[Micro.CensusProps[b]]=this[Micro.CensusProps[b]]},load:function(a){for(var b=0,c=Micro.CensusProps.length;b<c;b++)this[Micro.CensusProps[b]]=a[Micro.CensusProps[b]]},clearCensus:function(){this.airportPop=this.seaportPop=this.nuclearPowerPop=this.coalPowerPop=this.stadiumPop=this.fireStationPop=this.policeStationPop=this.churchPop=this.hospitalPop=this.indZonePop=this.comZonePop=this.resZonePop=
this.indPop=this.comPop=this.resPop=this.railTotal=this.roadTotal=this.firePop=this.unpoweredZoneCount=this.poweredZoneCount=0},take10Census:function(a){Micro.rotate10Arrays.call(this);this.resHist10[0]=Math.floor(this.resPop/8);this.comHist10[0]=this.comPop;this.indHist10[0]=this.indPop;this.crimeRamp+=Math.floor((this.crimeAverage-this.crimeRamp)/4);this.crimeHist10[0]=Math.min(this.crimeRamp,255);this.pollutionRamp+=Math.floor((this.pollutionAverage-this.pollutionRamp)/4);this.pollutionHist10[0]=
Math.min(this.pollutionRamp,255);this.moneyHist10[0]=Micro.clamp(Math.floor(a.cashFlow/20)+128,0,255);this.hospitalPop<this.resPopScaled?this.needHospital=1:this.hospitalPop>this.resPopScaled?this.needHospital=-1:this.hospitalPop===this.resPopScaled&&(this.needHospital=0);this.changed=!0},take120Census:function(){Micro.rotate120Arrays.call(this);this.resHist120[0]=Math.floor(this.resPop/8);this.comHist120[0]=this.comPop;this.indHist120[0]=this.indPop;this.crimeHist120[0]=this.crimeHist10[0];this.pollutionHist120[0]=
this.pollutionHist10[0];this.moneyHist120[0]=this.moneyHist10[0];this.changed=!0}};Micro.PROBLEMS="CVP_CRIME CVP_POLLUTION CVP_HOUSING CVP_TAXES CVP_TRAFFIC CVP_UNEMPLOYMENT CVP_FIRE".split(" ");Micro.NUMPROBLEMS=Micro.PROBLEMS.length;Micro.NUM_COMPLAINTS=4;Micro.EvalProps=["cityClass","cityScore"];Micro.getTrafficAverage=function(a){var b=a.trafficDensityMap;a=a.landValueMap;for(var c=0,d=1,e=0;e<a.gameMapWidth;e+=a.blockSize)for(var f=0;f<a.gameMapHeight;f+=a.blockSize)0<a.worldGet(e,f)&&(c+=b.worldGet(e,f),d++);return 2.4*Math.floor(c/d)};
Micro.getUnemployment=function(a){var b=8*(a.comPop+a.indPop);if(0===b)return 0;b=Math.round(255*(a.resPop/b-1));return Math.min(b,255)};Micro.getFireSeverity=function(a){return Math.min(5*a.firePop,255)};Micro.Evaluation=function(a,b){this.sim=b;this.problemVotes=[];this.problemOrder=[];this.evalInit();this.gameLevel=""+a;this.changed=!1};
Micro.Evaluation.prototype={constructor:Micro.Evaluation,save:function(a){for(var b=0,c=Micro.EvalProps.length;b<c;b++)a[Micro.EvalProps[b]]=this[Micro.EvalProps[b]]},load:function(a){for(var b=0,c=Micro.EvalProps.length;b<c;b++)this[Micro.EvalProps[b]]=a[Micro.EvalProps[b]]},cityEvaluation:function(){var a=this.sim.census;if(0<a.totalPop){for(var b=[],c=0;c<Micro.NUMPROBLEMS;c++)b.push(0);this.getAssessedValue(a);this.doPopNum(a);this.doProblems(this.sim.census,this.sim.budget,this.sim.blockMaps,
b);this.getScore(b);this.doVotes()}else this.evalInit(),this.cityYes=50;this.changeEval()},evalInit:function(){this.cityAssessedValue=this.cityPopDelta=this.cityPop=this.cityYes=0;this.cityClass=Micro.CC_VILLAGE;this.cityScore=500;for(var a=this.cityScoreDelta=0;a<Micro.NUMPROBLEMS;a++)this.problemVotes[a]=0;for(a=0;a<Micro.NUM_COMPLAINTS;a++)this.problemOrder[a]=Micro.NUMPROBLEMS},getAssessedValue:function(a){var b;b=5*a.roadTotal;b+=10*a.railTotal;b+=1E3*a.policeStationPop;b+=1E3*a.fireStationPop;
b+=400*a.hospitalPop;b+=3E3*a.stadiumPop;b+=5E3*a.seaportPop;b+=1E4*a.airportPop;b+=3E3*a.coalPowerPop;b+=6E3*a.nuclearPowerPop;this.cityAssessedValue=1E3*b},getPopulation:function(a){return 20*(a.resPop+8*(a.comPop+a.indPop))},doPopNum:function(a){var b=this.cityPop;this.cityPop=this.getPopulation(a);-1==b&&(b=this.cityPop);this.cityPopDelta=this.cityPop-b;this.cityClass=this.getCityClass(this.cityPop)},getCityClass:function(a){this.cityClassification=Micro.CC_VILLAGE;2E3<a&&(this.cityClassification=
Micro.CC_TOWN);1E4<this.cityPopulation&&(this.cityClassification=Micro.CC_CITY);5E4<this.cityPopulation&&(this.cityClassification=Micro.CC_CAPITAL);1E5<this.cityPopulation&&(this.cityClassification=Micro.CC_METROPOLIS);5E5<this.cityPopulation&&(this.cityClassification=Micro.CC_MEGALOPOLIS);return this.cityClassification},voteProblems:function(a){for(var b=0;b<Micro.NUMPROBLEMS;b++)this.problemVotes[b]=0;for(var c=b=0,d=0;100>c&&600>d;)Random.getRandom(300)<a[b]&&(this.problemVotes[b]++,c++),b++,b>
Micro.NUMPROBLEMS&&(b=0),d++},doProblems:function(a,b,c,d){for(var e=[],f=0;f<Micro.NUMPROBLEMS;f++)e[f]=!1,d[f]=0;d[Micro.CRIME]=a.crimeAverage;d[Micro.POLLUTION]=a.pollutionAverage;d[Micro.HOUSING]=7*a.landValueAverage/10;d[Micro.TAXES]=10*b.cityTax;d[Micro.TRAFFIC]=Micro.getTrafficAverage(c);d[Micro.UNEMPLOYMENT]=Micro.getUnemployment(a);d[Micro.FIRE]=Micro.getFireSeverity(a);this.voteProblems(d);for(f=0;f<Micro.NUM_COMPLAINTS;f++){a=0;b=Micro.NUMPROBLEMS;for(c=0;c<Micro.NUMPROBLEMS;c++)this.problemVotes[c]>
a&&!e[c]&&(b=c,a=this.problemVotes[c]);this.problemOrder[f]=b;b<Micro.NUMPROBLEMS&&(e[b]=!0)}},getScore:function(a){var b=this.sim.census,c=this.sim.budget,d=this.sim.valves,e;e=this.cityScore;for(var f=0,g=0;g<Micro.NUMPROBLEMS;g++)f+=a[g];f=Math.floor(f/3);f=Math.min(f,256);f=Micro.clamp(4*(256-f),0,1E3);d.resCap&&(f=Math.round(0.85*f));d.comCap&&(f=Math.round(0.85*f));d.indCap&&(f=Math.round(0.85*f));c.roadEffect<c.MAX_ROAD_EFFECT&&(f-=c.MAX_ROAD_EFFECT-c.roadEffect);c.policeEffect<c.MAX_POLICE_STATION_EFFECT&&
(f=Math.round(f*(0.9+c.policeEffect/(10.0001*c.MAX_POLICE_STATION_EFFECT))));c.fireEffect<c.MAX_FIRE_STATION_EFFECT&&(f=Math.round(f*(0.9+c.fireEffect/(10.0001*c.MAX_FIRE_STATION_EFFECT))));-1E3>d.resValve&&(f=Math.round(0.85*f));-1E3>d.comValve&&(f=Math.round(0.85*f));-1E3>d.indValve&&(f=Math.round(0.85*f));a=1;0===this.cityPop||0===this.cityPopDelta?a=1:this.cityPopDelta==this.cityPop?a=1:0<this.cityPopDelta?a=this.cityPopDelta/this.cityPop+1:0>this.cityPopDelta&&(a=0.95+Math.floor(this.cityPopDelta/
(this.cityPop-this.cityPopDelta)));f=Math.round(f*a);f=f-Micro.getFireSeverity(b)-c.cityTax;a=b.unpoweredZoneCount+b.poweredZoneCount;0<a&&(f=Math.round(b.poweredZoneCount/a*f));f=Micro.clamp(f,0,1E3);this.cityScore=Math.round((this.cityScore+f)/2);this.cityScoreDelta=this.cityScore-e},doVotes:function(){var a;for(a=this.cityYes=0;100>a;a++)Random.getRandom(1E3)<this.cityScore&&this.cityYes++},changeEval:function(){this.changed=!0},countProblems:function(){var a;for(a=0;a<Micro.NUM_COMPLAINTS&&this.problemOrder[a]!==
Micro.NUMPROBLEMS;a++);return a},getProblemNumber:function(a){return 0>a||a>=Micro.NUM_COMPLAINTS||this.problemOrder[a]===Micro.NUMPROBLEMS?-1:this.problemOrder[a]},getProblemVotes:function(a){return 0>a||a>=Micro.NUM_COMPLAINTS||this.problemOrder[a]==Micro.NUMPROBLEMS?-1:this.problemVotes[this.problemOrder[a]]}};Micro.BudgetProps="autoBudget totalFunds policePercent roadPercent firePercent roadSpend policeSpend fireSpend roadMaintenanceBudget policeMaintenanceBudget fireMaintenanceBudget cityTax roadEffect policeEffect fireEffect".split(" ");
Micro.Budget=function(){this.roadEffect=Micro.MAX_ROAD_EFFECT;this.policeEffect=Micro.MAX_POLICESTATION_EFFECT;this.fireEffect=Micro.MAX_FIRESTATION_EFFECT;this.totalFunds=0;this.cityTax=7;this.policeFund=this.fireFund=this.roadFund=this.taxFund=this.cashFlow=0;this.policePercent=this.firePercent=this.roadPercent=1;this.policeSpend=this.fireSpend=this.roadSpend=0;this.autoBudget=!0};
Micro.Budget.prototype={constructor:Micro.Budget,save:function(a){for(var b=0,c=Micro.BudgetProps.length;b<c;b++)a[Micro.BudgetProps[b]]=this[Micro.BudgetProps[b]]},load:function(a,b){for(var c=0,d=Micro.BudgetProps.length;c<d;c++)this[Micro.BudgetProps[c]]=a[Micro.BudgetProps[c]];void 0!==b&&b.sendMessage(Messages.AUTOBUDGET_CHANGED,this.autoBudget);void 0!==b&&b.sendMessage(Messages.FUNDS_CHANGED,this.totalFunds)},doBudget:function(a){return this.doBudgetNow(!1,a)},doBudgetMenu:function(a){return this.doBudgetNow(!1,
a)},doBudgetNow:function(a,b){this.roadSpend=Math.round(this.roadFund*this.roadPercent);this.fireSpend=Math.round(this.fireFund*this.firePercent);this.policeSpend=Math.round(this.policeFund*this.policePercent);var c=this.roadSpend+this.fireSpend+this.policeSpend;0===c&&(this.policePercent=this.firePercent=this.roadPercent=1,this.roadEffect=this.MAX_ROAD_EFFECT,this.policeEffect=this.MAX_POLICESTATION_EFFECT,this.fireEffect=this.MAX_FIRESTATION_EFFECT);var d=this.totalFunds+this.taxFund,e=d,f=0,g=
0,h=0,f=e>=this.roadSpend?this.roadSpend:e,e=e-f,g=e>=this.fireSpend?this.fireSpend:e,e=e-g,h=e>=this.policeSpend?this.policeSpend:e;this.roadPercent=0<this.roadFund?(new Number(f/this.roadFund)).toPrecision(2)-0:1;0<this.fireFund?this.firePercent=(new Number(g/this.fireFund)).toPrecision(2)-0:this.fireFund=1;0<this.policeFund?this.policePercent=(new Number(h/this.policeFund)).toPrecision(2)-0:this.policeFund=1;!this.autoBudget||a?a||this.doBudgetSpend(f,g,h,this.cityTax,b):d>=c?this.doBudgetSpend(f,
g,h,this.cityTax,b):(this.autoBudget=!1,b.sendMessage(Messages.AUTOBUDGET_CHANGED,this.autoBudget),b.sendMessage(Messages.BUDGET_NEEDED),b.sendMessage(Messages.NO_MONEY))},doBudgetSpend:function(a,b,c,d,e){this.roadSpend=a;this.fireSpend=b;this.policeSpend=c;this.setTax(d);this.spend(-(this.taxFund-(this.roadSpend+this.fireSpend+this.policeSpend)),e);this.updateFundEffects()},updateFundEffects:function(){this.roadEffect=Micro.MAX_ROAD_EFFECT;this.policeEffect=Micro.MAX_POLICESTATION_EFFECT;this.fireEffect=
Micro.MAX_FIRESTATION_EFFECT;0<this.roadFund&&(this.roadEffect=Math.floor(this.roadEffect*this.roadSpend/this.roadFund));0<this.fireFund&&(this.fireEffect=Math.floor(this.fireEffect*this.fireSpend/this.fireFund));0<this.policeFund&&(this.policeEffect=Math.floor(this.policeEffect*this.policeSpend/this.policeFund))},collectTax:function(a,b,c){this.cashFlow=0;this.policeFund=100*b.policeStationPop;this.fireFund=100*b.fireStationPop;this.roadFund=Math.floor((b.roadTotal+2*b.railTotal)*Micro.RLevels[a]);
this.taxFund=Math.floor(Math.floor(b.totalPop*b.landValueAverage/120)*this.cityTax*Micro.FLevels[a]);0<b.totalPop?(this.cashFlow=this.taxFund-(this.policeFund+this.fireFund+this.roadFund),this.doBudget(c)):(this.roadEffect=Micro.MAX_ROAD_EFFECT,this.policeEffect=Micro.MAX_POLICESTATION_EFFECT,this.fireEffect=Micro.MAX_FIRESTATION_EFFECT)},setTax:function(a,b){a!==this.cityTax&&(this.cityTax=a,void 0!==b&&b.sendMessage(Messages.TAXRATE_CHANGED,this.cityTax))},setFunds:function(a,b){a!==this.totalFunds&&
(this.totalFunds=Math.max(0,a),void 0!==b&&b.sendMessage(Messages.FUNDS_CHANGED,this.totalFunds))},spend:function(a,b){this.setFunds(this.totalFunds-a,b)},shouldDegradeRoad:function(){return this.roadEffect<Math.floor(15*this.MAX_ROAD_EFFECT/16)}};Micro.Valves=function(){this.changed=!1;this.indValve=this.comValve=this.resValve=0;this.indCap=this.comCap=this.resCap=!1};
Micro.Valves.prototype={constructor:Micro.Valves,save:function(a){a.resValve=this.resValve;a.comValve=this.comValve;a.indValve=this.indValve},load:function(a,b){this.resValve=a.resValve;this.comValve=a.comValve;this.indValve=a.indValve;this.changed=!0;void 0!==b&&b.sendMessage(Messages.VALVES_UPDATED)},setValves:function(a,b,c){var d,e=b.resPop/8;b.totalPop=Math.round(e+b.comPop+b.indPop);var f=e+e*((0<b.resPop?(b.comHist10[1]+b.indHist10[1])/e:1)-1)+0.02*e,g=b.comHist10[1]+b.indHist10[1];d=0<g?b.resHist10[1]/
g:1;d=Micro.clamp(d,0,1.3);g=(e+b.comPop+b.indPop)/3.7*d;d=b.indPop*d*Micro.extMarketParamTable[a];d=Math.max(d,5);g=0<b.comPop?g/b.comPop:g;b=0<b.indPop?d/b.indPop:d;e=Math.min(0<e?f/e:1.3,2);g=Math.min(g,2);b=Math.min(b,2);a=Math.min(c.cityTax+a,20);e=600*(e-1)+Micro.taxTable[a];g=600*(g-1)+Micro.taxTable[a];b=600*(b-1)+Micro.taxTable[a];this.resValve=Micro.clamp(this.resValve+Math.round(e),-Micro.RES_VALVE_RANGE,Micro.RES_VALVE_RANGE);this.comValve=Micro.clamp(this.comValve+Math.round(g),-Micro.COM_VALVE_RANGE,
Micro.COM_VALVE_RANGE);this.indValve=Micro.clamp(this.indValve+Math.round(b),-Micro.IND_VALVE_RANGE,Micro.IND_VALVE_RANGE);this.resCap&&0<this.resValve&&(this.resValve=0);this.comCap&&0<this.comValve&&(this.comValve=0);this.indCap&&0<this.indValve&&(this.indValve=0);this.changed=!0}};Micro.Tile=function(a,b){if(!(this instanceof Micro.Tile))return new Micro.Tile;this._value=a;void 0===this._value&&(this._value=Tile.DIRT);1<arguments.length&&(this._value|=b)};
Micro.Tile.prototype={constructor:Micro.Tile,getValue:function(){return this._value&Tile.BIT_MASK},setValue:function(a){if(0===arguments.length||"number"!==typeof a||0>a)throw Error("Invalid parameter");var b=0;a<Tile.BIT_START&&(b=this._value&Tile.ALLBITS);this._value=a|b},isBulldozable:function(){return 0<(this._value&Tile.BULLBIT)},isAnimated:function(){return 0<(this._value&Tile.ANIMBIT)},isConductive:function(){return 0<(this._value&Tile.CONDBIT)},isCombustible:function(){return 0<(this._value&
Tile.BURNBIT)},isPowered:function(){return 0<(this._value&Tile.POWERBIT)},isZone:function(){return 0<(this._value&Tile.ZONEBIT)},addFlags:function(a){if(!arguments.length||"number"!==typeof a||a<Tile.BIT_START||a>=Tile.BIT_END<<1)throw Error("Invalid parameter");this._value|=a},removeFlags:function(a){if(!arguments.length||"number"!==typeof a||a<Tile.BIT_START||a>=Tile.BIT_END<<1)throw Error("Invalid parameter");this._value&=~a},setFlags:function(a){this._value=this._value&~Tile.ALLBITS|a},getFlags:function(){return this._value&
Tile.ALLBITS},getRawValue:function(){return this._value},set:function(a,b){if(2>arguments.length||"number"!==typeof a||"number"!==typeof b||a>=Tile.TILE_COUNT)throw Error("Invalid parameter");this.setValue(a);this.setFlags(b)},toString:function(){var a="Tile# "+this.getValue(),a=a+(this.isCombustible()?" burning":""),a=a+(this.isPowered()?" powered":""),a=a+(this.isAnimated()?" animated":""),a=a+(this.isConductive()?" conductive":""),a=a+(this.isZone()?" zone":"");return a+=this.isBulldozable()?" bulldozeable":
""}};var Tile={POWERBIT:32768,CONDBIT:16384,BURNBIT:8192,BULLBIT:4096,ANIMBIT:2048,ZONEBIT:1024};Tile.BLBNBIT=Tile.BULLBIT|Tile.BURNBIT;Tile.BLBNCNBIT=Tile.BULLBIT|Tile.BURNBIT|Tile.CONDBIT;Tile.BNCNBIT=Tile.BURNBIT|Tile.CONDBIT;Tile.ASCBIT=Tile.ANIMBIT|Tile.CONDBIT|Tile.BURNBIT;Tile.ALLBITS=Tile.POWERBIT|Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT|Tile.ANIMBIT|Tile.ZONEBIT;Tile.BIT_START=1024;Tile.BIT_END=32768;Tile.BIT_MASK=Tile.BIT_START-1;Tile.DIRT=0;Tile.RIVER=2;Tile.REDGE=3;Tile.CHANNEL=4;
Tile.FIRSTRIVEDGE=5;Tile.LASTRIVEDGE=20;Tile.WATER_LOW=Tile.RIVER;Tile.WATER_HIGH=Tile.LASTRIVEDGE;Tile.TREEBASE=21;Tile.WOODS_LOW=Tile.TREEBASE;Tile.LASTTREE=36;Tile.WOODS=37;Tile.UNUSED_TRASH1=38;Tile.UNUSED_TRASH2=39;Tile.WOODS_HIGH=Tile.UNUSED_TRASH2;Tile.WOODS2=40;Tile.WOODS3=41;Tile.WOODS4=42;Tile.WOODS5=43;Tile.RUBBLE=44;Tile.LASTRUBBLE=47;Tile.FLOOD=48;Tile.LASTFLOOD=51;Tile.RADTILE=52;Tile.UNUSED_TRASH3=53;Tile.UNUSED_TRASH4=54;Tile.UNUSED_TRASH5=55;Tile.FIRE=56;Tile.FIREBASE=Tile.FIRE;
Tile.LASTFIRE=63;Tile.HBRIDGE=64;Tile.ROADBASE=Tile.HBRIDGE;Tile.VBRIDGE=65;Tile.ROADS=66;Tile.ROADS2=67;Tile.ROADS3=68;Tile.ROADS4=69;Tile.ROADS5=70;Tile.ROADS6=71;Tile.ROADS7=72;Tile.ROADS8=73;Tile.ROADS9=74;Tile.ROADS10=75;Tile.INTERSECTION=76;Tile.HROADPOWER=77;Tile.VROADPOWER=78;Tile.BRWH=79;Tile.LTRFBASE=80;Tile.BRWV=95;Tile.BRWXXX1=111;Tile.BRWXXX2=127;Tile.BRWXXX3=143;Tile.HTRFBASE=144;Tile.BRWXXX4=159;Tile.BRWXXX5=175;Tile.BRWXXX6=191;Tile.LASTROAD=206;Tile.BRWXXX7=207;Tile.HPOWER=208;
Tile.VPOWER=209;Tile.LHPOWER=210;Tile.LVPOWER=211;Tile.LVPOWER2=212;Tile.LVPOWER3=213;Tile.LVPOWER4=214;Tile.LVPOWER5=215;Tile.LVPOWER6=216;Tile.LVPOWER7=217;Tile.LVPOWER8=218;Tile.LVPOWER9=219;Tile.LVPOWER10=220;Tile.RAILHPOWERV=221;Tile.RAILVPOWERH=222;Tile.POWERBASE=Tile.HPOWER;Tile.LASTPOWER=Tile.RAILVPOWERH;Tile.UNUSED_TRASH6=223;Tile.HRAIL=224;Tile.VRAIL=225;Tile.LHRAIL=226;Tile.LVRAIL=227;Tile.LVRAIL2=228;Tile.LVRAIL3=229;Tile.LVRAIL4=230;Tile.LVRAIL5=231;Tile.LVRAIL6=232;Tile.LVRAIL7=233;
Tile.LVRAIL8=234;Tile.LVRAIL9=235;Tile.LVRAIL10=236;Tile.HRAILROAD=237;Tile.VRAILROAD=238;Tile.RAILBASE=Tile.HRAIL;Tile.LASTRAIL=238;Tile.ROADVPOWERH=239;Tile.RESBASE=240;Tile.FREEZ=244;Tile.HOUSE=249;Tile.LHTHR=Tile.HOUSE;Tile.HHTHR=260;Tile.RZB=265;Tile.HOSPITALBASE=405;Tile.HOSPITAL=409;Tile.CHURCHBASE=414;Tile.CHURCH0BASE=414;Tile.CHURCH=418;Tile.CHURCH0=418;Tile.COMBASE=423;Tile.COMCLR=427;Tile.CZB=436;Tile.COMLAST=609;Tile.INDBASE=612;Tile.INDCLR=616;Tile.LASTIND=620;Tile.IND1=621;
Tile.IZB=625;Tile.IND2=641;Tile.IND3=644;Tile.IND4=649;Tile.IND5=650;Tile.IND6=676;Tile.IND7=677;Tile.IND8=686;Tile.IND9=689;Tile.PORTBASE=693;Tile.PORT=698;Tile.LASTPORT=708;Tile.AIRPORTBASE=709;Tile.RADAR=711;Tile.AIRPORT=716;Tile.COALBASE=745;Tile.POWERPLANT=750;Tile.LASTPOWERPLANT=760;Tile.FIRESTBASE=761;Tile.FIRESTATION=765;Tile.POLICESTBASE=770;Tile.POLICESTATION=774;Tile.STADIUMBASE=779;Tile.STADIUM=784;Tile.FULLSTADIUM=800;Tile.NUCLEARBASE=811;Tile.NUCLEAR=816;Tile.LASTZONE=826;
Tile.LIGHTNINGBOLT=827;Tile.HBRDG0=828;Tile.HBRDG1=829;Tile.HBRDG2=830;Tile.HBRDG3=831;Tile.HBRDG_END=832;Tile.RADAR0=832;Tile.RADAR1=833;Tile.RADAR2=834;Tile.RADAR3=835;Tile.RADAR4=836;Tile.RADAR5=837;Tile.RADAR6=838;Tile.RADAR7=839;Tile.FOUNTAIN=840;Tile.INDBASE2=844;Tile.TELEBASE=844;Tile.TELELAST=851;Tile.SMOKEBASE=852;Tile.TINYEXP=860;Tile.SOMETINYEXP=864;Tile.LASTTINYEXP=867;Tile.TINYEXPLAST=883;Tile.COALSMOKE1=916;Tile.COALSMOKE2=920;Tile.COALSMOKE3=924;Tile.COALSMOKE4=928;
Tile.FOOTBALLGAME1=932;Tile.FOOTBALLGAME2=940;Tile.VBRDG0=948;Tile.VBRDG1=949;Tile.VBRDG2=950;Tile.VBRDG3=951;Tile.NUKESWIRL1=952;Tile.NUKESWIRL2=953;Tile.NUKESWIRL3=954;Tile.NUKESWIRL4=955;Tile.CHURCH1BASE=956;Tile.CHURCH1=960;Tile.CHURCH2BASE=965;Tile.CHURCH2=969;Tile.CHURCH3BASE=974;Tile.CHURCH3=978;Tile.CHURCH4BASE=983;Tile.CHURCH4=987;Tile.CHURCH5BASE=992;Tile.CHURCH5=996;Tile.CHURCH6BASE=1001;Tile.CHURCH6=1005;Tile.CHURCH7BASE=1010;Tile.CHURCH7=1014;Tile.CHURCH7LAST=1018;Tile.TILE_COUNT=1024;
Tile.TILE_INVALID=-1;Tile.MIN_SIZE=16;Micro.PositionMaker=function(a,b){function c(a){return"number"===typeof a}if(2>arguments.length||"number"!==typeof a||"number"!==typeof b||0>a||0>b)throw Error("Invalid parameter");var d=[Direction.NORTH,Direction.NORTHEAST,Direction.EAST,Direction.SOUTHEAST,Direction.SOUTH,Direction.SOUTHWEST,Direction.WEST,Direction.NORTHWEST,Direction.INVALID],e=function(f,g,h){if(0===arguments.length)return this.y=this.x=0,this;if(!(1!==arguments.length&&3!==arguments.length||f instanceof e))throw Error("Invalid parameter");
if(!(3!==arguments.length||c(g)&&c(h)))throw Error("Invalid parameter");var k;if((k=2===arguments.length)&&!(k=c(f)&&!c(g))&&!(k=f instanceof e&&!c(g))){if(k=f instanceof e)if(k=c(g))k=!(c(g)&&-1!==d.indexOf(g));k=k||!c(f)&&!(f instanceof e)}if(k)throw Error("Invalid parameter");k=!0;c(f)?(this.x=f,this.y=g):(this._assignFrom(f),2===arguments.length?k=this.move(g):3===arguments.length&&(this.x+=g,this.y+=h));if(0>this.x||this.x>=a||0>this.y||this.y>=b||!k)throw Error("Invalid parameter");};e.prototype._assignFrom=
function(a){this.x=a.x;this.y=a.y};e.prototype.toString=function(){return"("+this.x+", "+this.y+")"};e.prototype.toInt=function(){return this.y*a+this.x};e.prototype.move=function(c){switch(c){case Direction.INVALID:return!0;case Direction.NORTH:if(0<this.y)return this.y--,!0;break;case Direction.NORTHEAST:if(0<this.y&&this.x<a-1)return this.y--,this.x++,!0;break;case Direction.EAST:if(this.x<a-1)return this.x++,!0;break;case Direction.SOUTHEAST:if(this.y<b-1&&this.x<a-1)return this.x++,this.y++,
!0;break;case Direction.SOUTH:if(this.y<b-1)return this.y++,!0;break;case Direction.SOUTHWEST:if(this.y<b-1&&0<this.x)return this.y++,this.x--,!0;break;case Direction.WEST:if(0<this.x)return this.x--,!0;break;case Direction.NORTHWEST:if(0<this.y&&0<this.x)return this.y--,this.x--,!0}return!1};return e};Micro.GameMapProps="cityCentreX cityCentreY pollutionMaxX pollutionMaxY width height".split(" ");
Micro.GameMap=function(a,b,c){this.isIsland=!1;this.Direction=new Micro.Direction;this.Position=new Micro.PositionMaker(a,b);this.width=a;this.height=b;this.fsize=this.width*this.height;this.defaultValue=(new Micro.Tile).getValue();this.data=[];this.tilesData=new M_ARRAY_TYPE(this.fsize);this.powerData=new M_ARRAY_TYPE(this.fsize);for(a=this.fsize;a--;)this.data[a]=new Micro.Tile(this.defaultValue),this.tilesData[a]=this.defaultValue;this.cityCentreX=Math.floor(0.5*this.width);this.cityCentreY=Math.floor(0.5*
this.height);this.pollutionMaxX=this.cityCentreX;this.pollutionMaxY=this.cityCentreY};
Micro.GameMap.prototype={constructor:Micro.GameMap,save:function(a){var b=0,c;for(c=Micro.GameMapProps.length;b<c;)a[Micro.GameMapProps[b]]=this[Micro.GameMapProps[b]],b++;a.map=[];b=0;for(c=this.fsize;b<c;)a.map[b]=this.data[b].getRawValue(),b++;a.tileValue=[];b=0;for(c=this.fsize;b<c;)a.tileValue[b]=this.tilesData[b],b++},load:function(a){var b,c,d=0,e=a.map,f=a.tileValue;for(c=Micro.GameMapProps.length;d<c;)this[Micro.GameMapProps[d]]=a[Micro.GameMapProps[d]],d++;var g=void 0!==e[0].value?!0:!1,
d=0;for(c=this.fsize;d<c;)a=d%this.width,b=Math.floor(d/this.width),g?this.setTileValue(a,b,e[d].value):this.setTileValue(a,b,e[d]),d++;d=0;for(c=this.fsize;d<c;)this.tilesData[d]=f[d],d++},_calculateIndex:function(a,b){return a+b*this.width},testBounds:function(a,b){return 0<=a&&0<=b&&a<this.width&&b<this.height},getTile:function(a,b,c){"object"===typeof a&&(b=a.y,a=a.x);var d=this.width,e=this.height;if(0>a||0>b||a>=d||b>=e)return console.warn("getTile called with bad bounds",a,b),new Tile(Tile.TILE_INVALID);
a=this.data[a+b*d];if(!c)return a;c.set(a);return a},getTileValue:function(a,b){var c=Error("Invalid parameter");if(1>arguments.length)throw c;"object"===typeof a&&(b=a.y,a=a.x);if(!this.testBounds(a,b))throw c;c=this._calculateIndex(a,b);c in this.data||(this.data[c]=new Micro.Tile(this.defaultValue));return this.data[c].getValue()},getTileFlags:function(a,b){var c=Error("Invalid parameter");if(1>arguments.length)throw c;"object"===typeof a&&(b=a.y,a=a.x);if(!this.testBounds(a,b))throw c;c=this._calculateIndex(a,
b);c in this.data||(this.data[c]=new Micro.Tile(this.defaultValue));return this.data[c].getFlags()},getTiles:function(a,b,c,d){var e=Error("Invalid parameter");if(3>arguments.length)throw e;3===arguments.length&&(d=c,c=b,b=a.y,a=a.x);if(!this.testBounds(a,b))throw e;for(var e=[],f=b,g=b+d;f<g;f++){e[f-b]=[];for(var h=a,k=a+c;h<k;h++){var l=this._calculateIndex(h,f);e[f-b].push(this.data[l])}}return e},getTileValues:function(a,b,c,d,e){e=e||[];var f=Error("Invalid parameter");if(3>arguments.length)throw f;
3===arguments.length&&(d=c,c=b,b=a.y,a=a.x);for(var f=this.width,g=this.height,h=b,k=b+d;h<k;h++)for(var l=a,m=a+c;l<m;l++)e[(h-b)*c+(l-a)]=0>h||0>l||h>=g||l>=f?Tile.TILE_INVALID:this.data[l+h*f].getRawValue();return e},getTileFromMapOrDefault:function(a,b,c){switch(b){case this.Direction.NORTH:return 0<a.y?this.getTileValue(a.x,a.y-1):c;case this.Direction.EAST:return a.x<this.width-1?this.getTileValue(a.x+1,a.y):c;case this.Direction.SOUTH:return a.y<this.height-1?this.getTileValue(a.x,a.y+1):c;
case this.Direction.WEST:return 0<a.x?this.getTileValue(a.x-1,a.y):c;default:return c}},setTile:function(a,b,c,d){3===arguments.length&&(d=c,c=b,b=a.y,a=a.x);var e=this._calculateIndex(a,b);this.data[e].set(c,d);this.tilesData[e]=c},setTo:function(a,b,c){void 0===c&&(c=b,b=a.y,a=a.x);a=this._calculateIndex(a,b);this.data[a]=c;this.tilesData[a]=c.getValue()},setTileValue:function(a,b,c){2===arguments.length&&(c=b,b=a.y,a=a.x);var d=this._calculateIndex(a,b);this.data[d].setValue(c);this.tilesData[d]=
c},setTileFlags:function(a,b,c){var d=Error("Invalid parameter");if(2>arguments.length)throw d;2===arguments.length&&(c=b,b=a.y,a=a.x);if(!this.testBounds(a,b))throw d;d=this._calculateIndex(a,b);this.data[d].setFlags(c)},addTileFlags:function(a,b,c){var d=Error("Invalid parameter");if(2>arguments.length)throw d;2===arguments.length&&(c=b,b=a.y,a=a.x);if(!this.testBounds(a,b))throw d;d=this._calculateIndex(a,b);this.data[d].addFlags(c)},removeTileFlags:function(a,b,c){var d=Error("Invalid parameter");
if(2>arguments.length)throw d;2===arguments.length&&(c=b,b=a.y,a=a.x);if(!this.testBounds(a,b))throw d;d=this._calculateIndex(a,b);this.data[d].removeFlags(c)},putZone:function(a,b,c,d){var e=Error("Invalid parameter");if(!this.testBounds(a,b)||!this.testBounds(a-1+d,b-1+d))throw e;c=c-1-d;for(var e=a-1,f=b-1,g=f;g<f+d;g++)for(var h=e;h<e+d;h++)h===a&&g===b?this.setTo(h,g,new Micro.Tile(c,Tile.BNCNBIT|Tile.ZONEBIT)):this.setTo(h,g,new Micro.Tile(c,Tile.BNCNBIT)),c+=1}};Micro.TERRAIN_CREATE_ISLAND=0;Micro.TERRAIN_TREE_LEVEL=-1;Micro.TERRAIN_LAKE_LEVEL=-1;Micro.TERRAIN_CURVE_LEVEL=-1;Micro.ISLAND_RADIUS=18;
Micro.generateMap=function(){this.SRMatrix=[[0,0,3,3,0,0],[0,3,2,2,3,0],[3,2,2,2,2,3],[3,2,2,2,2,3],[0,3,2,2,3,0],[0,0,3,3,0,0]];this.BRMatrix=[[0,0,0,3,3,3,0,0,0],[0,0,3,2,2,2,3,0,0],[0,3,2,2,2,2,2,3,0],[3,2,2,2,2,2,2,2,3],[3,2,2,2,4,2,2,2,3],[3,2,2,2,2,2,2,2,3],[0,3,2,2,2,2,2,3,0],[0,0,3,2,2,2,3,0,0],[0,0,0,3,3,3,0,0,0]];this.riverEdge=[13,13,17,15,5,2,19,17,9,11,2,13,7,9,5,2]};
Micro.generateMap.prototype={constructor:Micro.generateMap,construct:function(a,b){Micro.TERRAIN_TREE_LEVEL=-1;Micro.TERRAIN_LAKE_LEVEL=-1;Micro.TERRAIN_CURVE_LEVEL=-1;Micro.ISLAND_RADIUS=18;this.map=new Micro.GameMap(a||Micro.MAP_WIDTH,b||Micro.MAP_HEIGHT);Micro.TERRAIN_CREATE_ISLAND=Random.getRandom(2)-1;if(0>Micro.TERRAIN_CREATE_ISLAND&&10>Random.getRandom(100))return this.makeIsland(),this.map;1===Micro.TERRAIN_CREATE_ISLAND?this.makeNakedIsland():this.clearMap();if(0!==Micro.TERRAIN_CURVE_LEVEL){var c=
40+Random.getRandom(this.map.width-79),d=33+Random.getRandom(this.map.height-66),c=new this.map.Position(c,d);this.doRivers(c)}0!==Micro.TERRAIN_LAKE_LEVEL&&this.makeLakes();this.smoothRiver();0!==Micro.TERRAIN_TREE_LEVEL&&this.doTrees();return this.map},clearMap:function(){var a,b,c=this.map.width,d=this.map.height;for(a=0;a<c;a++)for(b=0;b<d;b++)this.map.setTile(a,b,Tile.DIRT,0)},clearUnnatural:function(){var a,b,c,d=this.map.width,e=this.map.height;for(a=0;a<d;a++)for(b=0;b<e;b++)c=this.map.getTileValue(a,
b),c>Tile.WOODS&&this.map.setTile(a,b,Tile.DIRT,0)},makeNakedIsland:function(){this.map.isIsland=!0;var a=Micro.ISLAND_RADIUS,b,c,d=this.map.width,e=this.map.height;for(c=0;c<e;c++)for(b=0;b<d;b++)this.map.setTile(b,c,Tile.RIVER,0);for(c=5;c<e-5;c++)for(b=5;b<d-5;b++)this.map.setTile(b,c,Tile.DIRT,0);for(b=0;b<d-5;b+=2)c=Random.getERandom(a+1),this.plopBRiver(new this.map.Position(b,c)),c=e-10-Random.getERandom(a+1),this.plopBRiver(new this.map.Position(b,c)),this.plopSRiver(new this.map.Position(b,
0)),this.plopSRiver(new this.map.Position(b,e-6));for(c=0;c<e-5;c+=2)b=Random.getERandom(a+1),this.plopBRiver(new this.map.Position(b,c)),b=d-10-Random.getERandom(a+1),this.plopBRiver(new this.map.Position(b,c)),this.plopSRiver(new this.map.Position(0,c)),this.plopSRiver(new this.map.Position(d-6,c))},makeIsland:function(){this.makeNakedIsland();this.smoothRiver();this.doTrees()},makeLakes:function(){var a,b,c=this.map.width,d=this.map.height,e;for(e=0>Micro.TERRAIN_LAKE_LEVEL?Random.getRandom(11):
0.5*Micro.TERRAIN_LAKE_LEVEL;0<e;)a=Random.getRandom(c-20)+10,b=Random.getRandom(d-19)+10,this.makeSingleLake(new this.map.Position(a,b)),e--},makeSingleLake:function(a){for(var b=Random.getRandom(13)+2;0<b;){var c=new this.map.Position(a,Random.getRandom(13)-6,Random.getRandom(13)-6);Random.getRandom(5)?this.plopSRiver(c):this.plopBRiver(c);b--}},treeSplash:function(a,b){var c;c=0>Micro.TERRAIN_TREE_LEVEL?Random.getRandom(150)+50:Random.getRandom(100+2*Micro.TERRAIN_TREE_LEVEL)+50;for(var d=new this.map.Position(a,
b);0<c;){var e=Direction.NORTH+Random.getRandom(7);d.move(e);if(!this.map.testBounds(d.x,d.y))break;this.map.getTileValue(d)===Tile.DIRT&&this.map.setTile(d,Tile.WOODS,Tile.BLBNBIT);c--}},doTrees:function(){var a,b,c,d,e=this.map.width,f=this.map.height;d=0>Micro.TERRAIN_TREE_LEVEL?Random.getRandom(100)+50:Micro.TERRAIN_TREE_LEVEL+3;for(a=0;a<d;a++)b=Random.getRandom(e-1),c=Random.getRandom(f-1),this.treeSplash(b,c);this.smoothTrees();this.smoothTrees()},smoothRiver:function(){var a,b,c,d=this.map.width,
e=this.map.height,f,g,h,k=[-1,0,1,0],l=[0,1,0,-1];for(a=0;a<d;a++)for(b=0;b<e;b++)if(this.map.getTileValue(a,b)===Tile.REDGE){var m=0;for(c=0;4>c;c++)if(m<<=1,f=a+k[c],g=b+l[c],h=this.map.testBounds(f,g))f=this.map.getTileValue(f,g),f!==Tile.DIRT&&(f<Tile.WOODS_LOW||f>Tile.WOODS_HIGH)&&m++;c=this.riverEdge[m&15];c!==Tile.RIVER&&Random.getRandom(2)&&c++;this.map.setTile(a,b,c,Tile.BULLBIT)}},isTree:function(a){return a>=Tile.WOODS_LOW&&a<=Tile.WOODS_HIGH},smoothTrees:function(){var a,b,c=this.map.width,
d=this.map.height;for(a=0;a<c;a++)for(b=0;b<d;b++)this.isTree(this.map.getTileValue(a,b))&&this.smoothTreesAt(a,b,!1)},smoothTreesAt:function(a,b,c){var d=[-1,0,1,0],e=[0,1,0,-1],f=[0,0,0,34,0,0,36,35,0,32,0,33,30,31,29,37];if(this.isTree(this.map.getTileValue(a,b))){for(var g=0,h=0;4>h;h++){var g=g<<1,k=a+d[h],l=b+e[h];this.map.testBounds(k,l)&&this.isTree(this.map.getTileValue(k,l))&&g++}(d=f[g&15])?(d!==Tile.WOODS&&a+b&1&&(d-=8),this.map.setTile(a,b,d,Tile.BLBNBIT)):c||this.map.setTile(a,b,d,0)}},
doRivers:function(a){var b=Direction.NORTH+2*Random.getRandom(3);this.doBRiver(a,b,b);var b=Direction.rotate180(b),c=this.doBRiver(a,b,b),b=Direction.NORTH+2*Random.getRandom(3);this.doSRiver(a,b,c)},doBRiver:function(a,b,c){var d,e;0>Micro.TERRAIN_CURVE_LEVEL?(d=100,e=200):(d=Micro.TERRAIN_CURVE_LEVEL+10,e=Micro.TERRAIN_CURVE_LEVEL+100);for(a=new this.map.Position(a);this.map.testBounds(a.x+4,a.y+4);)this.plopBRiver(a),10>Random.getRandom(d+1)?c=b:(90<Random.getRandom(e+1)&&(c=Direction.rotate45(c)),
90<Random.getRandom(e+1)&&(c=Direction.rotate45(c,7))),a.move(c);return c},doSRiver:function(a,b,c){var d,e;0>Micro.TERRAIN_CURVE_LEVEL?(d=100,e=200):(d=Micro.TERRAIN_CURVE_LEVEL+10,e=Micro.TERRAIN_CURVE_LEVEL+100);for(a=new this.map.Position(a);this.map.testBounds(a.x+3,a.y+3);)this.plopSRiver(a),10>Random.getRandom(d+1)?c=b:(90<Random.getRandom(e+1)&&(c=Direction.rotate45(c)),90<Random.getRandom(e+1)&&(c=Direction.rotate45(c,7))),a.move(c);return c},putOnMap:function(a,b,c){if(0!==a&&this.map.testBounds(b,
c)){var d=this.map.getTileValue(b,c);d!==Tile.DIRT&&(d===Tile.RIVER&&a!==Tile.CHANNEL||d===Tile.CHANNEL)||this.map.setTile(b,c,a,0)}},plopBRiver:function(a){for(var b=0;9>b;b++)for(var c=0;9>c;c++)this.putOnMap(this.BRMatrix[c][b],a.x+b,a.y+c)},plopSRiver:function(a){for(var b=0;6>b;b++)for(var c=0;6>c;c++)this.putOnMap(this.SRMatrix[c][b],a.x+b,a.y+c)},smoothWater:function(){var a,b,c,d,e,f=this.map.width,g=this.map.height;for(a=0;a<f;a++)for(b=0;b<g;b++)if(c=this.map.getTileValue(a,b),c>=Tile.WATER_LOW&&
c<=Tile.WATER_HIGH)for(d=new this.map.Position(a,b),e=Direction.BEGIN;e<Direction.END;e=Direction.increment90(e))if(c=this.map.getTileFromMapOrDefault(d,e,Tile.WATER_LOW),c<Tile.WATER_LOW||c>Tile.WATER_HIGH){this.map.setTile(a,b,Tile.REDGE,0);break}for(a=0;a<f;a++)for(b=0;b<g;b++)if(c=this.map.getTileValue(a,b),c!==Tile.CHANNEL&&c>=Tile.WATER_LOW&&c<=Tile.WATER_HIGH){var h=!0;d=new this.map.Position(a,b);for(e=Direction.BEGIN;e<Direction.END;e=Direction.increment90(e))if(c=this.map.getTileFromMapOrDefault(d,
e,Tile.WATER_LOW),c<Tile.WATER_LOW||c>Tile.WATER_HIGH){h=!1;break}h&&this.map.setTile(a,b,Tile.RIVER,0)}for(a=0;a<f;a++)for(b=0;b<g;b++)if(c=this.map.getTileValue(a,b),c>=Tile.WOODS_LOW&&c<=Tile.WOODS_HIGH)for(d=new this.map.Position(a,b),e=Direction.BEGIN;e<Direction.END;e=Direction.increment90(e))if(c=this.map.getTileFromMapOrDefault(d,e,Tile.TILE_INVALID),c===Tile.RIVER||c===Tile.CHANNEL){this.map.setTile(a,b,Tile.REDGE,0);break}}};Micro.unwrapTile=function(a){return function(b){b instanceof Micro.Tile&&(b=b.getValue());return a.call(null,b)}};Micro.canBulldoze=Micro.unwrapTile(function(a){return a>=Tile.FIRSTRIVEDGE&&a<=Tile.LASTRUBBLE||a>=Tile.POWERBASE+2&&a<=Tile.POWERBASE+12||a>=Tile.TINYEXP&&a<=Tile.LASTTINYEXP+2});Micro.isCommercial=Micro.unwrapTile(function(a){return a>=Tile.COMBASE&&a<Tile.INDBASE});Micro.isDriveable=Micro.unwrapTile(function(a){return a>=Tile.ROADBASE&&a<=Tile.LASTRAIL||a===Tile.RAILHPOWERV||a===Tile.RAILVPOWERH});
Micro.isFire=Micro.unwrapTile(function(a){return a>=Tile.FIREBASE&&a<Tile.ROADBASE});Micro.isFlood=Micro.unwrapTile(function(a){return a>=Tile.FLOOD&&a<Tile.LASTFLOOD});Micro.isIndustrial=Micro.unwrapTile(function(a){return a>=Tile.INDBASE&&a<Tile.PORTBASE});Micro.isManualExplosion=Micro.unwrapTile(function(a){return a>=Tile.TINYEXP&&a<=Tile.LASTTINYEXP});Micro.isRail=Micro.unwrapTile(function(a){return a>=Tile.RAILBASE&&a<Tile.RESBASE});
Micro.isResidential=Micro.unwrapTile(function(a){return a>=Tile.RESBASE&&a<Tile.HOSPITALBASE});Micro.isRoad=Micro.unwrapTile(function(a){return a>=Tile.ROADBASE&&a<Tile.POWERBASE});Micro.normalizeRoad=Micro.unwrapTile(function(a){return a>=Tile.ROADBASE&&a<=Tile.LASTROAD+1?(a&15)+64:a});Micro.isCommercialZone=function(a){return a.isZone()&&Micro.isCommercial(a)};Micro.isIndustrialZone=function(a){return a.isZone()&&Micro.isIndustrial(a)};Micro.isResidentialZone=function(a){return a.isZone()&&Micro.isResidential(a)};
Micro.randomFire=function(){return new Micro.Tile(Tile.FIRE+(Random.getRandom16()&3),Tile.ANIMBIT)};Micro.randomRubble=function(){return new Micro.Tile(Tile.RUBBLE+(Random.getRandom16()&3),Tile.BULLBIT)};Micro.HOSPITAL=function(){};Micro.checkBigZone=function(a){switch(a){case Tile.POWERPLANT:case Tile.PORT:case Tile.NUCLEAR:case Tile.STADIUM:a={zoneSize:4,deltaX:0,deltaY:0};break;case Tile.POWERPLANT+1:case Tile.COALSMOKE3:case Tile.COALSMOKE3+1:case Tile.COALSMOKE3+2:case Tile.PORT+1:case Tile.NUCLEAR+1:case Tile.STADIUM+1:a={zoneSize:4,deltaX:-1,deltaY:0};break;case Tile.POWERPLANT+4:case Tile.PORT+4:case Tile.NUCLEAR+4:case Tile.STADIUM+4:a={zoneSize:4,deltaX:0,deltaY:-1};break;case Tile.POWERPLANT+5:case Tile.PORT+5:case Tile.NUCLEAR+
5:case Tile.STADIUM+5:a={zoneSize:4,deltaX:-1,deltaY:-1};break;case Tile.AIRPORT:a={zoneSize:6,deltaX:0,deltaY:0};break;case Tile.AIRPORT+1:a={zoneSize:6,deltaX:-1,deltaY:0};break;case Tile.AIRPORT+2:a={zoneSize:6,deltaX:-2,deltaY:0};break;case Tile.AIRPORT+3:a={zoneSize:6,deltaX:-3,deltaY:0};break;case Tile.AIRPORT+6:a={zoneSize:6,deltaX:0,deltaY:-1};break;case Tile.AIRPORT+7:a={zoneSize:6,deltaX:-1,deltaY:-1};break;case Tile.AIRPORT+8:a={zoneSize:6,deltaX:-2,deltaY:-1};break;case Tile.AIRPORT+9:a=
{zoneSize:6,deltaX:-3,deltaY:-1};break;case Tile.AIRPORT+12:a={zoneSize:6,deltaX:0,deltaY:-2};break;case Tile.AIRPORT+13:a={zoneSize:6,deltaX:-1,deltaY:-2};break;case Tile.AIRPORT+14:a={zoneSize:6,deltaX:-2,deltaY:-2};break;case Tile.AIRPORT+15:a={zoneSize:6,deltaX:-3,deltaY:-2};break;case Tile.AIRPORT+18:a={zoneSize:6,deltaX:0,deltaY:-3};break;case Tile.AIRPORT+19:a={zoneSize:6,deltaX:-1,deltaY:-3};break;case Tile.AIRPORT+20:a={zoneSize:6,deltaX:-2,deltaY:-3};break;case Tile.AIRPORT+21:a={zoneSize:6,
deltaX:-3,deltaY:-3};break;default:a={zoneSize:0,deltaX:0,deltaY:0}}return a};Micro.checkZoneSize=function(a){return a>=Tile.RESBASE-1&&a<=Tile.PORTBASE-1||a>=Tile.LASTPOWERPLANT+1&&a<=Tile.POLICESTATION+4||a>=Tile.CHURCH1BASE&&a<=Tile.CHURCH7LAST?3:a>=Tile.PORTBASE&&a<=Tile.LASTPORT||a>=Tile.COALBASE&&a<=Tile.LASTPOWERPLANT||a>=Tile.STADIUMBASE&&a<=Tile.LASTZONE?4:0};
Micro.fireZone=function(a,b,c,d){var e=a.getTileValue(b,c),f=2,g=d.rateOfGrowthMap.worldGet(b,c),g=Micro.clamp(g-20,-200,200);d.rateOfGrowthMap.worldSet(b,c,g);e===Tile.AIRPORT?f=5:e>=Tile.PORTBASE?f=3:e<Tile.PORTBASE&&(f=2);for(d=-1;d<f;d++)for(e=-1;e<f;e++){var g=b+d,h=c+e;a.testBounds(g,h)&&a.getTileValue(g,h>=Tile.ROADBASE)&&a.addTileFlags(g,h,Tile.BULLBIT)}};
Micro.getLandPollutionValue=function(a,b,c){var d=a.landValueMap.worldGet(b,c),d=d-a.pollutionDensityMap.worldGet(b,c);return 30>d?0:80>d?1:150>d?2:3};Micro.incRateOfGrowth=function(a,b,c,d){var e=a.rateOfGrowthMap.worldGet(b,c);d=Micro.clamp(e+4*d,-200,200);a.rateOfGrowthMap.worldSet(b,c,d)};
Micro.putZone=function(a,b,c,d,e){for(var f=0;3>f;f++)for(var g=0;3>g;g++){var h=a.getTileValue(b+g,c+f);if(h>=Tile.FLOOD&&h<Tile.ROADBASE)return}a.putZone(b,c,d,3);a.addTileFlags(b,c,Tile.BULLBIT);e&&a.addTileFlags(b,c,Tile.POWERBIT)};Micro.pixToWorld=function(a){return a>>4};Micro.worldToPix=function(a){return a<<4};Micro.turnTo=function(a,b){if(a===b)return a;a<b?4>b-a?a++:a--:4>a-b?a--:a++;8<a&&(a=1);1>a&&(a=8);return a};Micro.absoluteValue=function(a){return Math.abs(a)};Micro.getTileValue=function(a,b,c){b=Micro.pixToWorld(b);c=Micro.pixToWorld(c);return 0>b||b>=a.width||0>c||c>=a.height?-1:a.getTileValue(b,c)};Micro.directionTable=[0,3,2,1,3,4,5,7,6,5,7,8,1];
Micro.getDir=function(a,b,c,d){a=c-a;b=d-b;d=0>a?0>b?11:8:0>b?2:5;a=Math.abs(a);b=Math.abs(b);2*a<b?d++:2*b<a&&d--;if(0>d||12<d)d=0;return Micro.directionTable[d]};Micro.absoluteDistance=function(a,b,c,d){b=d-b;return Math.abs(c-a)+Math.abs(b)};Micro.checkWet=function(a){return a===Tile.HPOWER||a===Tile.VPOWER||a===Tile.HRAIL||a===Tile.VRAIL||a===Tile.BRWH||a===Tile.BRWV?!0:!1};
Micro.destroyMapTile=function(a,b,c,d,e){var f=Micro.pixToWorld(d),g=Micro.pixToWorld(e);if(b.testBounds(f,g)){var h=b.getTile(f,g),k=h.getValue();k<Tile.TREEBASE||(h.isCombustible()?(h.isZone()&&(Micro.fireZone(b,f,g,c),k>Tile.RZB&&a.makeExplosionAt(d,e)),Micro.checkWet(k)?b.setTo(f,g,new Micro.Tile(Tile.RIVER)):b.setTo(f,g,new Micro.Tile(Tile.TINYEXP,Tile.BULLBIT|Tile.ANIMBIT))):k>=Tile.ROADBASE&&k<=Tile.LASTROAD&&b.setTo(f,g,new Micro.Tile(Tile.RIVER)))}};
Micro.getDistance=function(a,b,c,d){return Math.abs(a-c)+Math.abs(b-d)};Micro.checkSpriteCollision=function(a,b){return 0!==a.frame&&0!==b.frame&&30>Micro.getDistance(a.x,a.y,b.x,b.y)};Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK=0;Micro.SMOOTH_ALL_THEN_CLAMP=1;Micro.smoothMap=function(a,b,c){for(var d=0,e=a.width;d<e;d++)for(var f=0,g=a.height;f<g;f++){var h=0;0<d&&(h+=a.get(d-1,f));d<a.width-1&&(h+=a.get(d+1,f));0<f&&(h+=a.get(d,f-1));f<a.height-1&&(h+=a.get(d,f+1));c===Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK?(h=a.get(d,f)+Math.floor(h/4),b.set(d,f,Math.floor(h/2))):(h=h+a.get(d,f)>>2,255<h&&(h=255),b.set(d,f,h))}};
Micro.decRateOfGrowthMap=function(a){a=a.rateOfGrowthMap;for(var b=0;b<a.width;b++)for(var c=0;c<a.height;c++){var d=a.get(b,c);0!==d&&(0<d?(d--,d=Micro.clamp(d,-200,200),a.set(b,c,d)):0>d&&(d++,d=Micro.clamp(d,-200,200),a.set(b,c,d)))}};Micro.neutraliseRateOfGrowthMap=function(a){a=a.rateOfGrowthMap;for(var b=0,c=a.width;b<c;b++)for(var d=0,e=a.height;d<e;d++){var f=a.get(b,d);0!==f&&(0<f?f--:f++,f=Micro.clamp(f,-200,200),a.set(b,d,f))}};
Micro.decTrafficMap=function(a){a=a.trafficDensityMap;for(var b=0;b<a.gameMapWidth;b+=a.blockSize)for(var c=0;c<a.gameMapHeight;c+=a.blockSize){var d=a.worldGet(b,c);0!==d&&(24>=d?a.worldSet(b,c,0):200<d?a.worldSet(b,c,d-34):a.worldSet(b,c,d-24))}};Micro.neutraliseTrafficMap=function(a){a=a.trafficDensityMap;for(var b=0,c=a.width;b<c;b++)for(var d=0,e=a.height;d<e;d++){var f=a.get(b,d);0!==f&&(f=24>=f?0:200<f?f-34:f-24,a.set(b,d,f))}};
Micro.getPollutionValue=function(a){if(a<Tile.POWERBASE){if(a>=Tile.HTRFBASE)return 75;if(a>=Tile.LTRFBASE)return 50;if(a<Tile.ROADBASE){if(a>Tile.FIREBASE)return 90;if(a>=Tile.RADTILE)return 255}return 0}return a<=Tile.LASTIND?0:a<Tile.PORTBASE?50:a<=Tile.LASTPOWERPLANT?100:0};Micro.getCityCentreDistance=function(a,b,c){return Math.min((b>a.cityCentreX?b-a.cityCentreX:a.cityCentreX-b)+(c>a.cityCentreY?c-a.cityCentreY:a.cityCentreY-c),64)};
Micro.pollutionTerrainLandValueScan=function(a,b,c){var d=c.tempMap1,e=c.tempMap2,f=c.tempMap3;f.clear();var g=c.landValueMap,h=c.terrainDensityMap,k=c.pollutionDensityMap,l=c.crimeRateMap,m,n,p,q=0,x=0;c=0;for(n=g.width;c<n;c++)for(m=0,p=g.height;m<p;m++){for(var r=0,s=!1,u=2*c,t=2*m,w=u;w<=u+1;w++)for(var y=t;y<=t+1;y++){var v=a.getTileValue(w,y);v>Tile.DIRT&&(v<Tile.RUBBLE?(v=f.worldGet(w,y),f.worldSet(w,y,v+15)):(r+=Micro.getPollutionValue(v),v>=Tile.ROADBASE&&(s=!0)))}r=Math.min(r,255);d.set(c,
m,r);s?(r=34-Math.floor(Micro.getCityCentreDistance(a,u,t)/2),r<<=2,r+=h.get(c>>1,m>>1),r-=k.get(c,m),190<l.get(c,m)&&(r-=20),r=Micro.clamp(r,1,250),g.set(c,m,r),q+=r,x++):g.set(c,m,0)}b.landValueAverage=0<x?Math.floor(q/x):0;Micro.smoothMap(d,e,Micro.SMOOTH_ALL_THEN_CLAMP);Micro.smoothMap(e,d,Micro.SMOOTH_ALL_THEN_CLAMP);c=l=g=e=0;for(n=a.width;c<n;c+=k.blockSize)for(m=0,p=a.height;m<p;m+=k.blockSize)if(q=d.worldGet(c,m),k.worldSet(c,m,q),0!==q&&(g++,l+=q,q>e||q===e&&Random.getChance(3)))e=q,a.pollutionMaxX=
c,a.pollutionMaxY=m;b.pollutionAverage=g?Math.floor(l/g):0;Micro.smoothMap(f,h,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK)};
Micro.crimeScan=function(a,b){var c=b.policeStationMap,d=b.policeStationEffectMap,e=b.crimeRateMap,f=b.landValueMap,g=b.populationDensityMap;Micro.smoothMap(c,d,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);Micro.smoothMap(d,c,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);Micro.smoothMap(c,d,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);for(var h=d=0,k=0,l=e.mapWidth,m=e.blockSize;k<l;k+=m)for(var n=0,p=e.mapHeight;n<p;n+=m){var q=f.worldGet(k,n);0<q?(h+=1,q=128-q,q+=g.worldGet(k,n),q=Math.min(q,300),q-=c.worldGet(k,n),q=Micro.clamp(q,
0,250),e.worldSet(k,n,q),d+=q):e.worldSet(k,n,0)}a.crimeAverage=0<h?Math.floor(d/h):0;b.policeStationEffectMap=new Micro.BlockMap(c)};Micro.computeComRateMap=function(a,b){for(var c=b.comRateMap,d=0;d<c.width;d++)for(var e=0;e<c.height;e++){var f=Math.floor(Micro.getCityCentreDistance(a,8*d,8*e)/2),f=4*f,f=64-f;c.set(d,e,f)}};
Micro.fillCityCentreDistScoreMap=function(a,b){for(var c=b.cityCentreDistScoreMap,d=0,e=c.width;d<e;d++)for(var f=0,g=c.height;f<g;f++){var h=Math.floor(Micro.getCityCentreDistance(a,8*d,8*f)/2),h=4*h,h=64-h;c.set(d,f,h)}};Micro.getPopulationDensity=function(a,b,c,d){return d<Tile.COMBASE?Residential.getZonePopulation(a,b,c,d):d<Tile.INDBASE?8*Commercial.getZonePopulation(a,b,c,d):d<Tile.PORTBASE?8*Industrial.getZonePopulation(a,b,c,d):0};
Micro.populationDensityScan=function(a,b){for(var c=b.tempMap1,d=b.tempMap2,e=0,f=0,g=0,h=0,k=a.width;h<k;h++)for(var l=0,m=a.height;l<m;l++){var n=a.getTile(h,l);n.isZone()?(n=n.getValue(),n=8*Micro.getPopulationDensity(a,h,l,n),n=Math.min(n,254),c.worldSet(h,l,n),e+=h,f+=l,g++):c.worldSet(h,l,0)}Micro.smoothMap(c,d,Micro.SMOOTH_ALL_THEN_CLAMP);Micro.smoothMap(d,c,Micro.SMOOTH_ALL_THEN_CLAMP);Micro.smoothMap(c,d,Micro.SMOOTH_ALL_THEN_CLAMP);b.populationDensityMap.copyFrom(d,function(a){return 2*
a});0<g?(a.cityCentreX=Math.floor(e/g),a.cityCentreY=Math.floor(f/g)):(a.cityCentreX=Math.floor(0.5*a.width),a.cityCentreY=Math.floor(0.5*a.height))};Micro.fireAnalysis=function(a){var b=a.fireStationMap,c=a.fireStationEffectMap;Micro.smoothMap(b,c,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);Micro.smoothMap(c,b,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);Micro.smoothMap(b,c,Micro.SMOOTH_NEIGHBOURS_THEN_BLOCK);a.fireStationEffectMap=new Micro.BlockMap(b)};Micro.Residential=function(a){var b=function(a,b,c,d){d instanceof Micro.Tile&&(d=(new Micro.Tile).getValue());if(d===Tile.FREEZ){for(var e=0,f=b-1;f<=b+1;f++)for(var p=c-1;p<=c+1;p++)if(f!==b||p!==c)d=a.getTileValue(f,p),d>=Tile.LHTHR&&d<=Tile.HHTHR&&(e+=1);return e}return 8*(Math.floor((d-Tile.RZB)/9)%4+1)+16},c=[0,3,6,1,4,7,2,5,8],d=function(a,b,d,e,f,n,p){if(0!==f)if(16<f)Micro.putZone(a,b,d,9*(4*n+Math.floor((f-24)/8))+Tile.RZB,p),Micro.incRateOfGrowth(e,b,d,-8);else if(16===f){a.setTo(b,d,new Micro.Tile(Tile.FREEZ,
Tile.BLBNCNBIT|Tile.ZONEBIT));for(p=d-1;p<=d+1;p++)for(f=b-1;f<=b+1;f++)f===b&&p===d||a.setTo(b,d,new Micro.Tile(Tile.LHTHR+n+Random.getRandom(2),Tile.BLBNCNBIT));Micro.incRateOfGrowth(e,b,d,-8)}else for(n=0,Micro.incRateOfGrowth(e,b,d,-1),f=b-1;f<=b+1;f++)for(p=d-1;p<=d+1;p++){e=a.getTileValue(f,p);if(e>=Tile.LHTHR&&e<=Tile.HHTHR){a.setTo(f,p,new Micro.Tile(c[n]+Tile.RESBASE,Tile.BLBNCNBIT));return}n+=1}},e=function(c,e,f,l){var m;a.census.resZonePop+=1;m=c.getTileValue(e,f);var n=b(c,e,f,m);a.census.resPop+=
n;var p=c.getTile(e,f).isPowered();l=Micro.ROUTE_FOUND;if(n>Random.getRandom(35)&&(l=a.traffic.makeTraffic(e,f,a.blockMaps,Micro.isCommercial),l===Micro.NO_ROAD_FOUND)){m=Micro.getLandPollutionValue(a.blockMaps,e,f);d(c,e,f,a.blockMaps,n,m,p);return}if(m===Tile.FREEZ||Random.getChance(7))if(m=a.blockMaps,l===Micro.NO_ROAD_FOUND?l=-3E3:(l=m.landValueMap.worldGet(e,f),l-=m.pollutionDensityMap.worldGet(e,f),l=0>l?0:Math.min(32*l,6E3),l-=3E3),l=a.valves.resValve+l,p||(l=-500),-350<l&&l-26380>Random.getRandom16Signed())if(0===
n&&Random.getChance(3))0<a.census.needHospital&&(Micro.putZone(c,e,f,Tile.HOSPITAL,p),a.census.needHospital=0);else a:{if(m=Micro.getLandPollutionValue(a.blockMaps,e,f),l=a.blockMaps,!(128<l.pollutionDensityMap.worldGet(e,f))){if(c.getTileValue(e,f)===Tile.FREEZ){if(8>n){for(var p=n=0,q=[0,-1,0,1,-1,1,-1,0,1],x=[0,-1,-1,-1,0,0,1,1,1],r=0;9>r;r++){var s;s=c;var u=e+q[r],t=f+x[r],w=[0,1,0,-1],y=[-1,0,1,0],v=s.getTileValue(u,t);if(v<Tile.RESBASE||v>Tile.RESBASE+8)s=-1;else{for(var A=1,z=0;4>z;z++){var v=
u+w[z],B=t+y[z];0>v||v>=s.width||0>B||B>=s.height||(v=s.getTileValue(v,B),v!==Tile.DIRT&&v<=Tile.LASTROAD&&(A+=1))}s=A}s>p?(p=s,n=r):s===p&&Random.getChance(7)&&(n=r)}0<n&&c.testBounds(e+q[n],f+x[n])&&c.setTo(e+q[n],f+x[n],new Micro.Tile(Tile.HOUSE+Random.getRandom(2)+3*m,Tile.BLBNCNBIT));Micro.incRateOfGrowth(l,e,f,1);break a}if(64<l.populationDensityMap.worldGet(e,f)){Micro.putZone(c,e,f,9*(4*m+0)+Tile.RZB,p);Micro.incRateOfGrowth(l,e,f,8);break a}}40>n&&(Micro.putZone(c,e,f,9*(4*m+(Math.floor(n/
8)-1))+Tile.RZB,p),Micro.incRateOfGrowth(l,e,f,8))}}else 350>l&&l+26380<Random.getRandom16Signed()&&(m=Micro.getLandPollutionValue(a.blockMaps,e,f),d(c,e,f,a.blockMaps,n,m,p))},f=function(b,c,d,e){a.census.hospitalPop+=1;-1===a.census.needHospital&&0===Random.getRandom(20)&&Micro.putZone(b,c,d,Tile.FREEZ,b.getTile(c,d).isPowered())};return{registerHandlers:function(a,b){a.addAction(Micro.isResidentialZone,e);a.addAction(Micro.HOSPITAL,f);b.addAction(Tile.HOSPITAL,15,3)},getZonePopulation:b}};Micro.Commercial=function(a){var b=function(a,b,c,d){d instanceof Micro.Tile&&(d=(new Micro.Tile).getValue());return d===Tile.COMCLR?0:Math.floor((d-Tile.CZB)/9)%5+1},c=function(a,b,c,d,k,l,m){1<k?(Micro.putZone(a,b,c,9*(5*l+(k-2))+Tile.CZB,m),Micro.incRateOfGrowth(d,b,c,-8)):1===k&&(Micro.putZone(a,b,c,Tile.COMCLR,m),Micro.incRateOfGrowth(d,b,c,-8))},d=function(d,f,g,h){var k;a.census.comZonePop+=1;h=d.getTileValue(f,g);h=b(d,f,g,h);a.census.comPop+=h;var l=d.getTile(f,g).isPowered(),m=Micro.ROUTE_FOUND;
if(h>Random.getRandom(5)&&(m=a.traffic.makeTraffic(f,g,a.blockMaps,Micro.isIndustrial),m===Micro.NO_ROAD_FOUND)){k=Micro.getLandPollutionValue(a.blockMaps,f,g);c(d,f,g,a.blockMaps,h,k,l);return}if(Random.getChance(7))if(k=m===Micro.NO_ROAD_FOUND?-3E3:a.blockMaps.comRateMap.worldGet(f,g),k=a.valves.comValve+k,l||(k=-500),m&&-350<k&&k-26380>Random.getRandom16Signed()){k=Micro.getLandPollutionValue(a.blockMaps,f,g);var m=a.blockMaps,n=m.landValueMap.worldGet(f,g);!(h>n>>5)&&5>h&&(Micro.putZone(d,f,g,
9*(5*k+h)+Tile.CZB,l),Micro.incRateOfGrowth(m,f,g,8))}else 350>k&&k+26380<Random.getRandom16Signed()&&(k=Micro.getLandPollutionValue(a.blockMaps,f,g),c(d,f,g,a.blockMaps,h,k,l))};return{registerHandlers:function(a,b){a.addAction(Micro.isCommercialZone,d)},getZonePopulation:b}};Micro.Industrial=function(a){var b=function(a,b,c,d){d instanceof Micro.Tile&&(d=(new Micro.Tile).getValue());return d===Tile.INDCLR?0:Math.floor((d-Tile.IZB)/9)%4+1},c=function(a,b,c,d,e,f,g){1<e?(Micro.putZone(a,b,c,9*(4*f+(e-2))+Tile.IZB,g),Micro.incRateOfGrowth(d,b,c,-8)):1===e&&(Micro.putZone(a,b,c,Tile.INDCLR,g),Micro.incRateOfGrowth(d,b,c,-8))},d=[!0,!1,!0,!0,!1,!1,!0,!0],e=[-1,0,1,0,0,0,0,1],f=[-1,0,-1,-1,0,0,-1,-1],g=function(g,k,l,m){a.census.indZonePop+=1;var n=g.getTileValue(k,l);m=b(g,
k,l,n);a.census.indPop+=m;var p=g.getTile(k,l).isPowered();n<Tile.IZB||(n=n-Tile.IZB>>3,d[n]&&p?g.addTileFlags(k+e[n],l+f[n],Tile.ASCBIT):(g.addTileFlags(k+e[n],l+f[n],Tile.BNCNBIT),g.removeTileFlags(k+e[n],l+f[n],Tile.ANIMBIT)));n=Micro.ROUTE_FOUND;if(m>Random.getRandom(5)&&(n=a.traffic.makeTraffic(k,l,a.blockMaps,Micro.isResidential),n===Micro.NO_ROAD_FOUND)){c(g,k,l,a.blockMaps,m,Random.getRandom16()&1,p);return}if(Random.getChance(7)){var q;q=n===Micro.NO_ROAD_FOUND?-1E3:0;q=a.valves.indValve+
q;p||(q=-500);n&&-350<q&&q-26380>Random.getRandom16Signed()?(n=a.blockMaps,q=Random.getRandom16()&1,4>m&&(Micro.putZone(g,k,l,9*(4*q+m)+Tile.IZB,p),Micro.incRateOfGrowth(n,k,l,8))):350>q&&q+26380<Random.getRandom16Signed()&&c(g,k,l,a.blockMaps,m,Random.getRandom16()&1,p)}};return{registerHandlers:function(a,b){a.addAction(Micro.isIndustrialZone,g)},getZonePopulation:b}};Micro.MiscTiles=function(a){var b=[-1,0,1,0],c=[0,-1,0,1],d=function(d,e,f,g){a.census.firePop+=1;if(0===(Random.getRandom16()&3)){for(g=0;4>g;g++)if(Random.getChance(7)&&d.testBounds(e+b[g],f+c[g])){var n=d.getTile(e,f);n.isCombustible()&&(n.isZone()&&(Micro.fireZone(d,e,f,a.blockMaps),n.getValue()>Tile.IZB&&a.spriteManager.makeExplosionAt(e,f)),d.setTo(Micro.randomFire()))}n=10;g=a.blockMaps.fireStationEffectMap.worldGet(e,f);100<g?n=1:20<g?n=2:0<g&&(n=3);0===Random.getRandom(n)&&d.setTo(e,f,Micro.randomRubble())}},
e=function(a,b,c,d){Random.getChance(4095)&&a.setTo(b,c,new Micro.Tile(Tile.DIRT))},f=function(b,c,d,e){a.disasterManager.doFlood(c,d,a.blockMaps)},g=function(a,b,c,d){a.getTileValue(b,c);a.setTo(b,c,Micro.randomRubble())};return{registerHandlers:function(a,b){a.addAction(Micro.isFire,d,!0);a.addAction(Tile.RADTILE,e,!0);a.addAction(Micro.isFlood,f,!0);a.addAction(Micro.isManualExplosion,g,!0)}}};Micro.Road=function(a){var b=function(a,b,c,d,e,f,g){for(var h=0;7>h;h++){var k=b+d[h],l=c+e[h];a.testBounds(k,l)&&a.getTileValue(k,l)===(f[h]&Tile.BIT_MASK)&&a.setTileValue(k,l,g[h])}},c=function(a,b,c,d,e,f,g){for(var h=0;7>h;h++){var k=b+d[h],l=c+e[h];if(a.testBounds(k,l)){var m=a.getTileValue(k,l);m!==Tile.CHANNEL&&(m&15)!==(f[h]&15)||a.setTileValue(k,l,g[h])}}},d=[0,1,0,0,0,0,1],e=[-2,-2,-1,0,1,2,2],f=[Tile.VBRDG0|Tile.BULLBIT,Tile.VBRDG1|Tile.BULLBIT,Tile.RIVER,Tile.BRWV|Tile.BULLBIT,Tile.RIVER,
Tile.VBRDG2|Tile.BULLBIT,Tile.VBRDG3|Tile.BULLBIT],g=[Tile.VBRIDGE|Tile.BULLBIT,Tile.RIVER,Tile.VBRIDGE|Tile.BULLBIT,Tile.VBRIDGE|Tile.BULLBIT,Tile.VBRIDGE|Tile.BULLBIT,Tile.VBRIDGE|Tile.BULLBIT,Tile.RIVER],h=[-2,2,-2,-1,0,1,2],k=[-1,-1,0,0,0,0,0],l=[Tile.HBRDG1|Tile.BULLBIT,Tile.HBRDG3|Tile.BULLBIT,Tile.HBRDG0|Tile.BULLBIT,Tile.RIVER,Tile.BRWH|Tile.BULLBIT,Tile.RIVER,Tile.HBRDG2|Tile.BULLBIT],m=[Tile.RIVER,Tile.RIVER,Tile.HBRIDGE|Tile.BULLBIT,Tile.HBRIDGE|Tile.BULLBIT,Tile.HBRIDGE|Tile.BULLBIT,Tile.HBRIDGE|
Tile.BULLBIT,Tile.HBRIDGE|Tile.BULLBIT],n=[Tile.ROADBASE,Tile.LTRFBASE,Tile.HTRFBASE],p=function(q,p,r,s){a.census.roadTotal+=1;s=q.getTile(p,r);var u=s.getValue();if(a.budget.shouldDegradeRoad()&&Random.getChance(511)&&(s=q.getTile(p,r),!s.isConductive()&&a.budget.roadEffect<(Random.getRandom16()&31))){s.getValue();2>(u&15)||15===(u&15)?q.setTo(p,r,Tile.RIVER):q.setTo(p,r,Micro.randomRubble());return}if(!s.isCombustible()){a.census.roadTotal+=4;var t;a:if(u===Tile.BRWV)Random.getChance(3)&&340<a.spriteManager.getBoatDistance(p,
r)&&c(q,p,r,d,e,f,g),t=!0;else if(u==Tile.BRWH)Random.getChance(3)&&340<a.spriteManager.getBoatDistance(p,r)&&c(q,p,r,h,k,l,m),t=!0;else{if(300>a.spriteManager.getBoatDistance(p,r)||Random.getChance(7))if(u&1){if(p<q.width-1&&q.getTileValue(p+1,r)===Tile.CHANNEL){b(q,p,r,d,e,g,f);t=!0;break a}}else if(0<r&&q.getTileValue(p,r-1)===Tile.CHANNEL){b(q,p,r,h,k,m,l);t=!0;break a}t=!1}if(t)return}var w=0;u<Tile.LTRFBASE?w=0:u<Tile.HTRFBASE?w=1:(a.census.roadTotal+=1,w=2);t=a.blockMaps.trafficDensityMap.worldGet(p,
r)>>6;1<t&&(t-=1);t!==w&&(u=(u-Tile.ROADBASE&15)+n[t],s=s.getFlags()&~Tile.ANIMBIT,0<t&&(s|=Tile.ANIMBIT),q.setTo(p,r,new Micro.Tile(u,s)))};return{registerHandlers:function(a,b){a.addAction(Micro.isRoad,p)}}};Micro.Stadia=function(a){var b=function(b,c,f,g){a.census.stadiumPop+=1;b.getTile(c,f).isPowered()&&0===(a.cityTime+c+f&31)&&(b.putZone(c,f,Tile.FULLSTADIUM,4),b.addTileFlags(c,f,Tile.POWERBIT),b.setTo(c+1,f,new Micro.Tile(Tile.FOOTBALLGAME1,Tile.ANIMBIT)),b.setTo(c+1,f+1,new Micro.Tile(Tile.FOOTBALLGAME2,Tile.ANIMBIT)))},c=function(b,c,f,g){a.census.stadiumPop+=1;g=b.getTile(c,f).isPowered();0===(a.cityTime+c+f&7)&&(b.putZone(c,f,Tile.STADIUM,4),g&&b.addTileFlags(c,f,Tile.POWERBIT))};return{registerHandlers:function(a,
e){a.addAction(Tile.STADIUM,b);a.addAction(Tile.FULLSTADIUM,c);e.addAction(Tile.STADIUM,15,4)}}};Micro.EmergencyServices=function(a){var b=function(b,c,d){return function(h,k,l,m){a.census[b]+=1;m=a.budget[c];h.getTile(k,l).isPowered()||(m=Math.floor(m/2));h=new h.Position(k,l);a.traffic.findPerimeterRoad(h)||(m=Math.floor(m/2));h=a.blockMaps[d].worldGet(k,l);a.blockMaps[d].worldSet(k,l,h+m)}},c=b("policeStationPop","policeEffect","policeStationMap"),d=b("fireStationPop","fireEffect","fireStationMap");return{registerHandlers:function(a,b){a.addAction(Tile.POLICESTATION,c);a.addAction(Tile.FIRESTATION,
d)}}};Micro.Transport=function(a){var b=function(b,c,d,h){a.census.railTotal+=1;a.spriteManager.generateTrain(a.census,c,d);a.budget.shouldDegradeRoad()&&Random.getChance(511)&&(h=b.getTile(c,d),!h.isConductive()&&a.budget.roadEffect<(Random.getRandom16()&31)&&(h.getValue(),b.getTile(c,d)<Tile.RAILBASE+2?b.setTo(c,d,Tile.RIVER):b.setTo(c,d,Micro.randomRubble())))},c=function(b,c,d,h){a.census.airportPop+=1;b.getTile(c,d).isPowered()?(b.getTileValue(c+1,d-1)===Tile.RADAR&&b.setTo(c+1,d-1,new Micro.Tile(Tile.RADAR0,
Tile.CONDBIT|Tile.ANIMBIT|Tile.BURNBIT)),0===Random.getRandom(5)?a.spriteManager.generatePlane(c,d):0===Random.getRandom(12)&&a.spriteManager.generateCopter(c,d)):b.setTo(c+1,d-1,new Micro.Tile(Tile.RADAR,Tile.CONDBIT|Tile.BURNBIT))},d=function(b,c,d,h){a.census.seaportPop+=1;b.getTile(c,d).isPowered()&&null===a.spriteManager.getSprite(Micro.SPRITE_SHIP)&&a.spriteManager.generateShip()};return{registerHandlers:function(a,f){a.addAction(Micro.isRail,b);a.addAction(Tile.PORT,d);a.addAction(Tile.AIRPORT,
c);f.addAction(Tile.PORT,15,4);f.addAction(Tile.AIRPORT,7,6)}}};Micro.toKey=function(a,b){return[a,b].join()};Micro.fromKey=function(a){a=a.split(",");return{x:a[0]-0,y:a[1]-0}};Micro.WorldEffects=function(a){this._map=a;this._data={}};
Micro.WorldEffects.prototype={constructor:Micro.WorldEffects,clear:function(){this._data=[]},getTile:function(a,b){var c=Micro.toKey(a,b),c=this._data[c];void 0===c&&(c=this._map.getTile(a,b));return c},getTileValue:function(a,b){return this.getTile(a,b).getValue()},setTile:function(a,b,c,d){if(void 0!==d&&c instanceof Micro.Tile)throw Error("Flags supplied with already defined tile");void 0!==d||c instanceof Micro.Tile?void 0!==d&&(c=new Micro.Tile(c,d)):c=new Micro.Tile(c);a=Micro.toKey(a,b);this._data[a]=
c},apply:function(){for(var a=Object.keys(this._data),b=0,c=a.length;b<c;b++){var d=Micro.fromKey(a[b]);this._map.setTo(d,this._data[a[b]])}}};Micro.BaseTool=function(){this.TOOLRESULT_OK=0;this.TOOLRESULT_FAILED=1;this.TOOLRESULT_NO_MONEY=2;this.TOOLRESULT_NEEDS_BULLDOZE=3;this.autoBulldoze=!0;this.bulldozerCost=1};
Micro.BaseTool.prototype={constructor:Micro.BaseTool,init:function(a,b,c,d){Object.defineProperty(this,"toolCost",Micro.makeConstantDescriptor(a));this.result=null;this.isDraggable=d||!1;this._shouldAutoBulldoze=c;this._map=b;this._worldEffects=new Micro.WorldEffects(b);this._applicationCost=0},clear:function(){this._applicationCost=0;this._worldEffects.clear()},addCost:function(a){this._applicationCost+=a},doAutoBulldoze:function(a,b){if(this._shouldAutoBulldoze){var c=this._worldEffects.getTile(a,
b);c.isBulldozable()&&(c=Micro.normalizeRoad(c),c>=Tile.TINYEXP&&c<=Tile.LASTTINYEXP||c<Tile.HBRIDGE&&c!==Tile.DIRT)&&(this.addCost(1),this._worldEffects.setTile(a,b,Tile.DIRT))}},apply:function(a){this._worldEffects.apply();a.spend(this._applicationCost);this.clear()},modifyIfEnoughFunding:function(a,b){if(this.result!==this.TOOLRESULT_OK)return this.clear(),!1;if(a.totalFunds<this._applicationCost)return this.result=this.TOOLRESULT_NO_MONEY,this.clear(),!1;this.apply.call(this,a);this.clear();return!0},
setAutoBulldoze:function(a){this.autoBulldoze=a}};Micro.RoadTable=[Tile.ROADS,Tile.ROADS2,Tile.ROADS,Tile.ROADS3,Tile.ROADS2,Tile.ROADS2,Tile.ROADS4,Tile.ROADS8,Tile.ROADS,Tile.ROADS6,Tile.ROADS,Tile.ROADS7,Tile.ROADS5,Tile.ROADS10,Tile.ROADS9,Tile.INTERSECTION];Micro.RailTable=[Tile.LHRAIL,Tile.LVRAIL,Tile.LHRAIL,Tile.LVRAIL2,Tile.LVRAIL,Tile.LVRAIL,Tile.LVRAIL3,Tile.LVRAIL7,Tile.LHRAIL,Tile.LVRAIL5,Tile.LHRAIL,Tile.LVRAIL6,Tile.LVRAIL4,Tile.LVRAIL9,Tile.LVRAIL8,Tile.LVRAIL10];
Micro.WireTable=[Tile.LHPOWER,Tile.LVPOWER,Tile.LHPOWER,Tile.LVPOWER2,Tile.LVPOWER,Tile.LVPOWER,Tile.LVPOWER3,Tile.LVPOWER7,Tile.LHPOWER,Tile.LVPOWER5,Tile.LHPOWER,Tile.LVPOWER6,Tile.LVPOWER4,Tile.LVPOWER9,Tile.LVPOWER8,Tile.LVPOWER10];Micro.BaseToolConnector=function(){Micro.BaseTool.call(this)};Micro.BaseToolConnector.prototype=Object.create(Micro.BaseTool.prototype);
Micro.BaseToolConnector.prototype.fixSingle=function(a,b){var c=0,d=this._worldEffects.getTile(a,b),d=Micro.normalizeRoad(d);d>=Tile.ROADS&&d<=Tile.INTERSECTION?(0<b&&(d=this._worldEffects.getTile(a,b-1),d=Micro.normalizeRoad(d),(d===Tile.HRAILROAD||d>=Tile.ROADBASE&&d<=Tile.VROADPOWER)&&d!==Tile.HROADPOWER&&d!==Tile.VRAILROAD&&d!==Tile.ROADBASE&&(c|=1)),a<this._map.width-1&&(d=this._worldEffects.getTile(a+1,b),d=Micro.normalizeRoad(d),(d===Tile.VRAILROAD||d>=Tile.ROADBASE&&d<=Tile.VROADPOWER)&&d!==
Tile.VROADPOWER&&d!==Tile.HRAILROAD&&d!==Tile.VBRIDGE&&(c|=2)),b<this._map.height-1&&(d=this._worldEffects.getTile(a,b+1),d=Micro.normalizeRoad(d),(d===Tile.HRAILROAD||d>=Tile.ROADBASE&&d<=Tile.VROADPOWER)&&d!==Tile.HROADPOWER&&d!==Tile.VRAILROAD&&d!==Tile.ROADBASE&&(c|=4)),0<a&&(d=this._worldEffects.getTile(a-1,b),d=Micro.normalizeRoad(d),(d===Tile.VRAILROAD||d>=Tile.ROADBASE&&d<=Tile.VROADPOWER)&&d!==Tile.VROADPOWER&&d!==Tile.HRAILROAD&&d!==Tile.VBRIDGE&&(c|=8)),this._worldEffects.setTile(a,b,Micro.RoadTable[c]|
Tile.BULLBIT|Tile.BURNBIT)):d>=Tile.LHRAIL&&d<=Tile.LVRAIL10?(0<b&&(d=this._worldEffects.getTile(a,b-1),d=Micro.normalizeRoad(d),d>=Tile.RAILHPOWERV&&d<=Tile.VRAILROAD&&d!==Tile.RAILHPOWERV&&d!==Tile.HRAILROAD&&d!==Tile.HRAIL&&(c|=1)),a<this._map.width-1&&(d=this._worldEffects.getTile(a+1,b),d=Micro.normalizeRoad(d),d>=Tile.RAILHPOWERV&&d<=Tile.VRAILROAD&&d!==Tile.RAILVPOWERH&&d!==Tile.VRAILROAD&&d!==Tile.VRAIL&&(c|=2)),b<this._map.height-1&&(d=this._worldEffects.getTile(a,b+1),d=Micro.normalizeRoad(d),
d>=Tile.RAILHPOWERV&&d<=Tile.VRAILROAD&&d!==Tile.RAILHPOWERV&&d!==Tile.HRAILROAD&&d!==Tile.HRAIL&&(c|=4)),0<a&&(d=this._worldEffects.getTile(a-1,b),d=Micro.normalizeRoad(d),d>=Tile.RAILHPOWERV&&d<=Tile.VRAILROAD&&d!==Tile.RAILVPOWERH&&d!==Tile.VRAILROAD&&d!==Tile.VRAIL&&(c|=8)),this._worldEffects.setTile(a,b,Micro.RailTable[c]|Tile.BULLBIT|Tile.BURNBIT)):d>=Tile.LHPOWER&&d<=Tile.LVPOWER10&&(0<b&&(d=this._worldEffects.getTile(a,b-1),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!==Tile.VPOWER&&
d!==Tile.VROADPOWER&&d!==Tile.RAILVPOWERH&&(c|=1))),a<this._map.width-1&&(d=this._worldEffects.getTile(a+1,b),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!==Tile.HPOWER&&d!==Tile.HROADPOWER&&d!==Tile.RAILHPOWERV&&(c|=2))),b<this._map.height-1&&(d=this._worldEffects.getTile(a,b+1),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!==Tile.VPOWER&&d!==Tile.VROADPOWER&&d!==Tile.RAILVPOWERH&&(c|=4))),0<a&&(d=this._worldEffects.getTile(a-1,b),d.isConductive()&&(d=d.getValue(),
d=Micro.normalizeRoad(d),d!==Tile.HPOWER&&d!==Tile.HROADPOWER&&d!==Tile.RAILHPOWERV&&(c|=8))),this._worldEffects.setTile(a,b,Micro.WireTable[c]|Tile.BLBNCNBIT))};Micro.BaseToolConnector.prototype.checkZoneConnections=function(a,b){this.fixSingle(a,b);0<b&&this.fixSingle(a,b-1);a<this._map.width-1&&this.fixSingle(a+1,b);b<this._map.height-1&&this.fixSingle(a,b+1);0<a&&this.fixSingle(a-1,b)};
Micro.BaseToolConnector.prototype.checkBorder=function(a,b,c){a-=1;b-=1;var d;for(d=0;d<c;d++)this.fixZone(a+d,b-1);for(d=0;d<c;d++)this.fixZone(a-1,b+d);for(d=0;d<c;d++)this.fixZone(a+d,b+c);for(d=0;d<c;d++)this.fixZone(a+c,b+d)};Micro.ParkTool=function(a){Micro.BaseTool.call(this);this.init(10,a,!0)};Micro.ParkTool.prototype=Object.create(Micro.BaseTool.prototype);Micro.ParkTool.prototype.doTool=function(a,b,c,d){this._worldEffects.getTileValue(a,b)!==Tile.DIRT?this.result=this.TOOLRESULT_NEEDS_BULLDOZE:(d=Random.getRandom(4),c=Tile.BURNBIT|Tile.BULLBIT,4===d?(d=Tile.FOUNTAIN,c|=Tile.ANIMBIT):d+=Tile.WOODS2,this._worldEffects.setTile(a,b,d,c),this.addCost(10),this.result=this.TOOLRESULT_OK)};Micro.BulldozerTool=function(a){Micro.BaseTool.call(this);this.init(10,a,!0)};Micro.BulldozerTool.prototype=Object.create(Micro.BaseTool.prototype);Micro.BulldozerTool.prototype.putRubble=function(a,b,c){for(var d=a;d<a+c;d++)for(var e=b;e<b+c;e++)if(this._map.testBounds(d,e)){var f=this._worldEffects.getTile(d,e);f!=Tile.RADTILE&&f!=Tile.DIRT&&this._worldEffects.setTile(d,e,Tile.TINYEXP+Random.getRandom(2),Tile.ANIMBIT|Tile.BULLBIT)}};
Micro.BulldozerTool.prototype.layDoze=function(a,b){var c=this._worldEffects.getTile(a,b);if(!c.isBulldozable())return this.TOOLRESULT_FAILED;c=c.getValue();c=Micro.normalizeRoad(c);switch(c){case Tile.HBRIDGE:case Tile.VBRIDGE:case Tile.BRWV:case Tile.BRWH:case Tile.HBRDG0:case Tile.HBRDG1:case Tile.HBRDG2:case Tile.HBRDG3:case Tile.VBRDG0:case Tile.VBRDG1:case Tile.VBRDG2:case Tile.VBRDG3:case Tile.HPOWER:case Tile.VPOWER:case Tile.HRAIL:case Tile.VRAIL:this._worldEffects.setTile(a,b,Tile.RIVER);
break;default:this._worldEffects.setTile(a,b,Tile.DIRT)}this.addCost(1);return this.TOOLRESULT_OK};
Micro.BulldozerTool.prototype.doTool=function(a,b,c,d){this._map.testBounds(a,b)||(this.result=this.TOOLRESULT_FAILED);var e=this._worldEffects.getTile(a,b);d=e.getValue();var f=0,g;e.isZone()?(f=Micro.checkZoneSize(d),g=e=0):(g=Micro.checkBigZone(d),f=g.zoneSize,e=g.deltaX,g=g.deltaY);if(0<f){this.addCost(this.bulldozerCost);e=a+e;g=b+g;switch(f){case 3:c.sendMessage(Messages.SOUND_EXPLOSIONHIGH);this.putRubble(e-1,g-1,3);break;case 4:c.sendMessage(Messages.SOUND_EXPLOSIONLOW);this.putRubble(e-1,
g-1,4);break;case 6:c.sendMessage(Messages.SOUND_EXPLOSIONHIGH),c.sendMessage(Messages.SOUND_EXPLOSIONLOW),this.putRubble(e-1,g-1,6)}this.result=this.TOOLRESULT_OK}d===Tile.RIVER||d===Tile.REDGE||d===Tile.CHANNEL?(c=this.layDoze(a,b),d!==this._worldEffects.getTileValue(a,b)&&this.addCost(5)):c=this.layDoze(a,b);this.result=c};Micro.BuildingTool=function(a,b,c,d,e){Micro.BaseToolConnector.call(this);this.init(a,c,!1);this.centreTile=b;this.size=d;this.animated=e};Micro.BuildingTool.prototype=Object.create(Micro.BaseToolConnector.prototype);
Micro.BuildingTool.prototype.putBuilding=function(a,b){for(var c,d,e,f,g=this.centreTile-this.size-1,h=0;h<this.size;h++){d=b+h;for(var k=0;k<this.size;k++)c=a+k,e=g,f=Tile.BNCNBIT,1===k&&(1===h?f|=Tile.ZONEBIT:2===h&&this.animated&&(f|=Tile.ANIMBIT)),this._worldEffects.setTile(c,d,e,f),g++}};
Micro.BuildingTool.prototype.prepareBuildingSite=function(a,b){if(0>a||a+this.size>this._map.width||0>b||b+this.size>this._map.height)return this.TOOLRESULT_FAILED;for(var c,d,e,f=0;f<this.size;f++){d=b+f;for(var g=0;g<this.size;g++)if(c=a+g,e=this._worldEffects.getTileValue(c,d),e!==Tile.DIRT){if(!this.autoBulldoze||!Micro.canBulldoze(e))return this.TOOLRESULT_NEEDS_BULLDOZE;this._worldEffects.setTile(c,d,Tile.DIRT);this.addCost(this.bulldozerCost)}}return this.TOOLRESULT_OK};
Micro.BuildingTool.prototype.buildBuilding=function(a,b){a--;b--;var c=this.prepareBuildingSite(a,b);if(c!==this.TOOLRESULT_OK)return c;this.addCost(this.toolCost);this.putBuilding(a,b);this.checkBorder(a,b);return this.TOOLRESULT_OK};Micro.BuildingTool.prototype.doTool=function(a,b,c,d){this.result=this.buildBuilding(a,b)};Micro.RailTool=function(a){Micro.BaseToolConnector.call(this);this.init(20,a,!0,!0)};Micro.RailTool.prototype=Object.create(Micro.BaseToolConnector.prototype);
Micro.RailTool.prototype.layRail=function(a,b){this.doAutoBulldoze(a,b);var c=20,d=this._worldEffects.getTileValue(a,b),d=Micro.normalizeRoad(d);switch(d){case Tile.DIRT:this._worldEffects.setTile(a,b,Tile.LHRAIL|Tile.BULLBIT|Tile.BURNBIT);break;case Tile.RIVER:case Tile.REDGE:case Tile.CHANNEL:c=100;if(a<this._map.width-1&&(d=this._worldEffects.getTileValue(a+1,b),d=Micro.normalizeRoad(d),d==Tile.RAILHPOWERV||d==Tile.HRAIL||d>=Tile.LHRAIL&&d<=Tile.HRAILROAD)){this._worldEffects.setTile(a,b,Tile.HRAIL,
Tile.BULLBIT);break}if(0<a&&(d=this._worldEffects.getTileValue(a-1,b),d=Micro.normalizeRoad(d),d==Tile.RAILHPOWERV||d==Tile.HRAIL||d>Tile.VRAIL&&d<Tile.VRAILROAD)){this._worldEffects.setTile(a,b,Tile.HRAIL,Tile.BULLBIT);break}if(b<this._map.height-1&&(d=this._worldEffects.getTileValue(a,b+1),d=Micro.normalizeRoad(d),d==Tile.RAILVPOWERH||d==Tile.VRAILROAD||d>Tile.HRAIL&&d<Tile.HRAILROAD)){this._worldEffects.setTile(a,b,Tile.VRAIL,Tile.BULLBIT);break}if(0<b&&(d=this._worldEffects.getTileValue(a,b-1),
d=Micro.normalizeRoad(d),d==Tile.RAILVPOWERH||d==Tile.VRAILROAD||d>Tile.HRAIL&&d<Tile.HRAILROAD)){this._worldEffects.setTile(a,b,Tile.VRAIL,Tile.BULLBIT);break}return this.TOOLRESULT_FAILED;case Tile.LHPOWER:this._worldEffects.setTile(a,b,Tile.RAILVPOWERH,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.LVPOWER:this._worldEffects.setTile(a,b,Tile.RAILHPOWERV,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.ROADS:this._worldEffects.setTile(a,b,Tile.VRAILROAD,Tile.BURNBIT|Tile.BULLBIT);
break;case Tile.ROADS2:this._worldEffects.setTile(a,b,Tile.HRAILROAD,Tile.BURNBIT|Tile.BULLBIT);break;default:return this.TOOLRESULT_FAILED}this.addCost(c);this.checkZoneConnections(a,b);return this.TOOLRESULT_OK};Micro.RailTool.prototype.doTool=function(a,b,c,d){this.result=this.layRail(a,b)};Micro.WireTool=function(a){Micro.BaseToolConnector.call(this);this.init(5,a,!0,!0)};Micro.WireTool.prototype=Object.create(Micro.BaseToolConnector.prototype);
Micro.WireTool.prototype.layWire=function(a,b){this.doAutoBulldoze(a,b);var c=5,d=this._worldEffects.getTileValue(a,b),d=Micro.normalizeRoad(d);switch(d){case Tile.DIRT:this._worldEffects.setTile(a,b,Tile.LHPOWER,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.RIVER:case Tile.REDGE:case Tile.CHANNEL:c=25;if(a<this._map.width-1&&(d=this._worldEffects.getTile(a+1,b),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!=Tile.HROADPOWER&&d!=Tile.RAILHPOWERV&&d!=Tile.HPOWER))){this._worldEffects.setTile(a,
b,Tile.VPOWER,Tile.CONDBIT|Tile.BULLBIT);break}if(0<a&&(d=this._worldEffects.getTile(a-1,b),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!=Tile.HROADPOWER&&d!=Tile.RAILHPOWERV&&d!=Tile.HPOWER))){this._worldEffects.setTile(a,b,Tile.VPOWER,Tile.CONDBIT|Tile.BULLBIT);break}if(b<this._map.height-1&&(d=this._worldEffects.getTile(a,b+1),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!=Tile.VROADPOWER&&d!=Tile.RAILVPOWERH&&d!=Tile.VPOWER))){this._worldEffects.setTile(a,b,Tile.HPOWER,
Tile.CONDBIT|Tile.BULLBIT);break}if(0<b&&(d=this._worldEffects.getTile(a,b-1),d.isConductive()&&(d=d.getValue(),d=Micro.normalizeRoad(d),d!=Tile.VROADPOWER&&d!=Tile.RAILVPOWERH&&d!=Tile.VPOWER))){this._worldEffects.setTile(a,b,Tile.HPOWER,Tile.CONDBIT|Tile.BULLBIT);break}return this.TOOLRESULT_FAILED;case Tile.ROADS:this._worldEffects.setTile(a,b,Tile.HROADPOWER,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.ROADS2:this._worldEffects.setTile(a,b,Tile.VROADPOWER,Tile.CONDBIT|Tile.BURNBIT|
Tile.BULLBIT);break;case Tile.LHRAIL:this._worldEffects.setTile(a,b,Tile.RAILHPOWERV,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.LVRAIL:this._worldEffects.setTile(a,b,Tile.RAILVPOWERH,Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;default:return this.TOOLRESULT_FAILED}this.addCost(c);this.checkZoneConnections(a,b);return this.TOOLRESULT_OK};Micro.WireTool.prototype.doTool=function(a,b,c,d){this.result=this.layWire(a,b)};Micro.RoadTool=function(a){Micro.BaseToolConnector.call(this);this.init(10,a,!0,!0)};Micro.RoadTool.prototype=Object.create(Micro.BaseToolConnector.prototype);
Micro.RoadTool.prototype.layRoad=function(a,b){this.doAutoBulldoze(a,b);var c=this._worldEffects.getTileValue(a,b),d=10;switch(c){case Tile.DIRT:this._worldEffects.setTile(a,b,Tile.ROADS,Tile.BULLBIT|Tile.BURNBIT);break;case Tile.RIVER:case Tile.REDGE:case Tile.CHANNEL:d=50;if(a<this._map.width-1&&(c=this._worldEffects.getTileValue(a+1,b),c=Micro.normalizeRoad(c),c===Tile.VRAILROAD||c===Tile.HBRIDGE||c>=Tile.ROADS&&c<=Tile.HROADPOWER)){this._worldEffects.setTile(a,b,Tile.HBRIDGE,Tile.BULLBIT);break}if(0<
a&&(c=this._worldEffects.getTileValue(a-1,b),c=Micro.normalizeRoad(c),c===Tile.VRAILROAD||c===Tile.HBRIDGE||c>=Tile.ROADS&&c<=Tile.INTERSECTION)){this._worldEffects.setTile(a,b,Tile.HBRIDGE,Tile.BULLBIT);break}if(b<this._map.height-1&&(c=this._worldEffects.getTileValue(a,b+1),c=Micro.normalizeRoad(c),c===Tile.HRAILROAD||c===Tile.VROADPOWER||c>=Tile.VBRIDGE&&c<=Tile.INTERSECTION)){this._worldEffects.setTile(a,b,Tile.VBRIDGE,Tile.BULLBIT);break}if(0<b&&(c=this._worldEffects.getTileValue(a,b-1),c=Micro.normalizeRoad(c),
c===Tile.HRAILROAD||c===Tile.VROADPOWER||c>=Tile.VBRIDGE&&c<=Tile.INTERSECTION)){this._worldEffects.setTile(a,b,Tile.VBRIDGE,Tile.BULLBIT);break}return this.TOOLRESULT_FAILED;case Tile.LHPOWER:this._worldEffects.setTile(a,b,Tile.VROADPOWER|Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.LVPOWER:this._worldEffects.setTile(a,b,Tile.HROADPOWER|Tile.CONDBIT|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.LHRAIL:this._worldEffects.setTile(a,b,Tile.HRAILROAD|Tile.BURNBIT|Tile.BULLBIT);break;case Tile.LVRAIL:this._worldEffects.setTile(a,
b,Tile.VRAILROAD|Tile.BURNBIT|Tile.BULLBIT);break;default:return this.TOOLRESULT_FAILED}this.addCost(d);this.checkZoneConnections(a,b);return this.TOOLRESULT_OK};Micro.RoadTool.prototype.doTool=function(a,b,c,d){this.result=this.layRoad(a,b)};Micro.QueryTool=function(a){Micro.BaseTool.call(this);this.init(0,a,!1,!1);this.txt=""};var debug=!0;Micro.QueryTool.prototype=Object.create(Micro.BaseTool.prototype);Micro.QueryTool.prototype.classifyPopulationDensity=function(a,b,c){a=c.populationDensityMap.worldGet(a,b);a=a>>6&3;this.txt+="Density: "+TXT.densityStrings[a]+"<br>"};
Micro.QueryTool.prototype.classifyLandValue=function(a,b,c){a=c.landValueMap.worldGet(a,b);b=0;150<=a?b=3:80<=a?b=2:30<=a&&(b=1);this.txt+="Value: "+TXT.landValueStrings[b]+"<br>"};Micro.QueryTool.prototype.classifyCrime=function(a,b,c){a=c.crimeRateMap.worldGet(a,b);a=a>>6&3;this.txt+="Crime: "+TXT.crimeStrings[a]+"<br>"};Micro.QueryTool.prototype.classifyPollution=function(a,b,c){a=c.pollutionDensityMap.worldGet(a,b);a=a>>6&3;this.txt+="Pollution: "+TXT.pollutionStrings[a]+"<br>"};
Micro.QueryTool.prototype.classifyRateOfGrowth=function(a,b,c){a=c.rateOfGrowthMap.worldGet(a,b);a=a>>6&3;this.txt+="Growth: "+TXT.rateStrings[a]};Micro.QueryTool.prototype.classifyDebug=function(a,b,c){};
Micro.QueryTool.prototype.classifyZone=function(a,b){var c=[Tile.DIRT,Tile.RIVER,Tile.TREEBASE,Tile.RUBBLE,Tile.FLOOD,Tile.RADTILE,Tile.FIRE,Tile.ROADBASE,Tile.POWERBASE,Tile.RAILBASE,Tile.RESBASE,Tile.COMBASE,Tile.INDBASE,Tile.PORTBASE,Tile.AIRPORTBASE,Tile.COALBASE,Tile.FIRESTBASE,Tile.POLICESTBASE,Tile.STADIUMBASE,Tile.NUCLEARBASE,Tile.HBRDG0,Tile.RADAR0,Tile.FOUNTAIN,Tile.INDBASE2,Tile.FOOTBALLGAME1,Tile.VBRDG0,952],d=this._map.getTileValue(a,b);d>=Tile.COALSMOKE1&&d<Tile.FOOTBALLGAME1&&(d=Tile.COALBASE);
var e=0,f,e=0;for(f=c.length-1;e<f&&!(d<c[e+1]);e++);this.txt="Zone: "+TXT.zoneTypes[e]+"<br>"};Micro.QueryTool.prototype.getInfo=function(){return this.txt};
Micro.QueryTool.prototype.doTool=function(a,b,c,d){this._map.getTileValue(a,b);debug&&this._map.getTile(a,b);this.classifyZone(a,b);this.classifyPopulationDensity(a,b,d);this.classifyLandValue(a,b,d);this.classifyCrime(a,b,d);this.classifyPollution(a,b,d);this.classifyRateOfGrowth(a,b,d);this.classifyDebug(a,b,d);c.sendMessage(Messages.QUERY_WINDOW_NEEDED);this.result=this.TOOLRESULT_OK};Micro.GameTools=function(a){return{airport:new Micro.BuildingTool(1E4,Tile.AIRPORT,a,6,!1),bulldozer:new Micro.BulldozerTool(a),coal:new Micro.BuildingTool(3E3,Tile.POWERPLANT,a,4,!1),commercial:new Micro.BuildingTool(100,Tile.COMCLR,a,3,!1),fire:new Micro.BuildingTool(500,Tile.FIRESTATION,a,3,!1),industrial:new Micro.BuildingTool(100,Tile.INDCLR,a,3,!1),nuclear:new Micro.BuildingTool(5E3,Tile.NUCLEAR,a,4,!0),park:new Micro.ParkTool(a),police:new Micro.BuildingTool(500,Tile.POLICESTATION,a,3,!1),
port:new Micro.BuildingTool(3E3,Tile.PORT,a,4,!1),rail:new Micro.RailTool(a),residential:new Micro.BuildingTool(100,Tile.FREEZ,a,3,!1),road:new Micro.RoadTool(a),query:new Micro.QueryTool(a),stadium:new Micro.BuildingTool(5E3,Tile.STADIUM,a,4,!1),wire:new Micro.WireTool(a)}};Micro.BaseSprite=function(){};
Micro.BaseSprite.prototype={constructor:Micro.BaseSprite,init:function(a,b,c,d,e){this.type=a;this.map=b;this.spriteManager=c;this.x=d;this.y=e;this.accel=this.turn=this.flag=this.step=this.newDir=this.dir=this.soundCount=this.count=this.destY=this.destX=this.origY=this.origX=0;this.speed=100},getFileName:function(){return["obj",this.type,"-",this.frame-1].join("")},spriteNotInBounds:function(){var a=Micro.pixToWorld(this.x),b=Micro.pixToWorld(this.y);return 0>a||0>b||a>=this.map.width||b>=this.map.height}};Micro.TrainSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_TRAIN,a,b,c,d);this.height=this.width=32;this.yOffset=this.xOffset=-16;this.frame=1;this.dir=4;this.tileDeltaX=[0,16,0,-16];this.tileDeltaY=[-16,0,16,0];this.xDelta=[0,4,0,-4,0];this.yDelta=[-4,0,4,0,0];this.TrainPic2=[1,2,1,2,5];this.NORTHSOUTH=1;this.EASTWEST=2;this.NWSE=3;this.NESW=4;this.UNDERWATER=5;this.NORTH=0;this.EAST=1;this.SOUTH=2;this.WEST=3;this.CANTMOVE=4};Micro.TrainSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.TrainSprite.prototype.move=function(a,b,c,d){if(this.frame===this.NWSE||this.frame===this.NESW)this.frame=this.TrainPic2[this.dir];this.x+=this.xDelta[this.dir];this.y+=this.yDelta[this.dir];if(0===(a&3)){for(b=a=Random.getRandom16()&3;b<a+4;b++)if(c=b&3,this.dir===this.CANTMOVE||c!==(this.dir+2&3))if(d=Micro.getTileValue(this.map,this.x+this.tileDeltaX[c],this.y+this.tileDeltaY[c]),d>=Tile.RAILBASE&&d<=Tile.LASTRAIL||d===Tile.RAILVPOWERH||d===Tile.RAILHPOWERV){this.frame=this.dir!==c&&this.dir!==
this.CANTMOVE?this.dir+c===this.WEST?this.NWSE:this.NESW:this.TrainPic2[c];if(d===Tile.HRAIL||d===Tile.VRAIL)this.frame=this.UNDERWATER;this.dir=c;return}this.dir===this.CANTMOVE?this.frame=0:this.dir=this.CANTMOVE}};Micro.TrainSprite.prototype.explodeSprite=function(a){this.frame=0;this.spriteManager.makeExplosionAt(this.x,this.y);a.sendMessage(Messages.TRAIN_CRASHED)};Micro.AirplaneSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_AIRPLANE,a,b,c,d);this.height=this.width=48;this.yOffset=this.xOffset=-24;c>Micro.worldToPix(a.width-20)?(this.destX=this.x-200,this.frame=7):(this.destX=this.x+200,this.frame=11);this.destY=this.y;this.xDelta=[0,0,6,8,6,0,-6,-8,-6,8,8,8];this.yDelta=[0,-8,-6,0,6,8,6,0,-6,0,0,0]};Micro.AirplaneSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.AirplaneSprite.prototype.move=function(a,b,c,d){d=this.frame;0===a%5&&(8<d?(d--,9>d&&(d=3)):(a=Micro.getDir(this.x,this.y,this.destX,this.destY),d=Micro.turnTo(d,a)),this.frame=d);50>Micro.absoluteDistance(this.x,this.y,this.destX,this.destY)&&(this.destX=Random.getRandom(Micro.worldToPix(this.map.width))+8,this.destY=Random.getRandom(Micro.worldToPix(this.map.height))+8);if(c.enableDisasters){c=!1;a=this.spriteManager.getSpriteList();for(var e=0;e<a.length;e++){var f=a[e];0===f.frame||f.type!==
Micro.SPRITE_HELICOPTER&&f.type!==Micro.SPRITE_AIRPLANE||!Micro.checkSpriteCollision(this,f)||(f.explodeSprite(b),c=!0)}c&&this.explodeSprite(b)}this.x+=this.xDelta[d];this.y+=this.yDelta[d];this.spriteNotInBounds()&&(this.frame=0)};Micro.AirplaneSprite.prototype.explodeSprite=function(a){this.frame=0;this.spriteManager.makeExplosionAt(this.x,this.y);a.sendMessage(Messages.PLANE_CRASHED)};Micro.BoatSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_SHIP,a,b,c,d);this.height=this.width=48;this.yOffset=this.xOffset=-24;c<Micro.worldToPix(4)?this.frame=3:c>=Micro.worldToPix(a.width-4)?this.frame=7:d<Micro.worldToPix(4)?this.frame=5:d>=Micro.worldToPix(a.height-4)?this.frame=1:this.frame=3;this.newDir=this.frame;this.dir=10;this.count=1;this.tileDeltaX=[0,0,1,1,1,0,-1,-1,-1];this.tileDeltaY=[0,-1,-1,0,1,1,1,0,-1];this.xDelta=[0,0,2,2,2,0,-2,-2,-2];this.yDelta=
[0,-2,-2,0,2,2,2,0,-2];this.tileWhiteList=[Tile.RIVER,Tile.CHANNEL,Tile.POWERBASE,Tile.POWERBASE+1,Tile.RAILBASE,Tile.RAILBASE+1,Tile.BRWH,Tile.BRWV];this.CANTMOVE=10};Micro.BoatSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.BoatSprite.prototype.move=function(a,b,c,d){a=Tile.RIVER;0<this.soundCount&&this.soundCount--;0===this.soundCount&&(1===(Random.getRandom16()&3)&&b.sendMessage(Messages.SOUND_HONKHONK),this.soundCount=200);0<this.count&&this.count--;if(0===this.count){this.count=9;if(this.frame!==this.newDir){this.frame=Micro.turnTo(this.frame,this.newDir);return}c=Random.getRandom16()&7;for(var e=this.frame,f=c;f<c+8;f++)if(e=(f&7)+1,e!==this.dir){var g=Micro.pixToWorld(this.x)+this.tileDeltaX[e],h=Micro.pixToWorld(this.y)+
this.tileDeltaY[e];if(this.map.testBounds(g,h)&&(g=this.map.getTileValue(g,h),g===Tile.CHANNEL||g===Tile.BRWH||g===Tile.BRWV||this.oppositeAndUnderwater(g,this.dir,e))){this.newDir=e;this.frame=Micro.turnTo(this.frame,this.newDir);this.dir=e+4;8<this.dir&&(this.dir-=8);break}}f===c+8&&(this.dir=this.CANTMOVE,this.newDir=(Random.getRandom16()&7)+1)}else e=this.frame,e===this.newDir&&(this.x+=this.xDelta[e],this.y+=this.yDelta[e]);if(this.spriteNotInBounds())this.frame=0;else for(c=0;8>c&&a!==this.tileWhiteList[c];c++)7===
c&&(this.explodeSprite(b),Micro.destroyMapTile(this.spriteManager,this.map,d,this.x,this.y))};Micro.BoatSprite.prototype.explodeSprite=function(a){this.frame=0;this.spriteManager.makeExplosionAt(this.x,this.y);a.sendMessage(Messages.SHIP_CRASHED)};Micro.BoatSprite.prototype.oppositeAndUnderwater=function(a,b,c){b+=4;8<b&&(b-=8);return c!=b?!1:a==Tile.POWERBASE||a==Tile.POWERBASE+1||a==Tile.RAILBASE||a==Tile.RAILBASE+1?!0:!1};Micro.CopterSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_HELICOPTER,a,b,c,d);this.height=this.width=32;this.yOffset=this.xOffset=-16;this.frame=5;this.count=1500;this.destX=Random.getRandom(Micro.worldToPix(a.width))+8;this.destY=Random.getRandom(Micro.worldToPix(a.height))+8;this.origX=c;this.origY=d;this.xDelta=[0,0,3,5,3,0,-3,-5,-3];this.yDelta=[0,-5,-3,0,3,5,3,0,-3]};Micro.CopterSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.CopterSprite.prototype.move=function(a,b,c,d){0<this.soundCount&&this.soundCount--;0<this.count&&this.count--;if(0===this.count&&(c=this.spriteManager.getSprite(Micro.SPRITE_MONSTER),null!==c?(this.destX=c.x,this.destY=c.y):(c=this.spriteManager.getSprite(Micro.SPRITE_TORNADO),null!==c?(this.destX=c.x,this.destY=c.y):(this.destX=this.origX,this.destY=this.origY)),30>Micro.absoluteDistance(this.x,this.y,this.origX,this.origY))){this.frame=0;return}if(0===this.soundCount){c=Micro.pixToWorld(this.x);
var e=Micro.pixToWorld(this.y);0<=c&&c<this.map.width&&0<=e&&e<this.map.height&&170<d.trafficDensityMap.worldGet(c,e)&&0===(Random.getRandom16()&7)&&(b.sendMessage(Messages.HEAVY_TRAFFIC,{x:c,y:e}),b.sendMessage(Messages.SOUND_HEAVY_TRAFFIC),this.soundCount=200)}b=this.frame;0===(a&3)&&(a=Micro.getDir(this.x,this.y,this.destX,this.destY),this.frame=b=Micro.turnTo(b,a));this.x+=this.xDelta[b];this.y+=this.yDelta[b]};
Micro.CopterSprite.prototype.explodeSprite=function(a){this.frame=0;this.spriteManager.makeExplosionAt(this.x,this.y);a.sendMessage(Messages.HELICOPTER_CRASHED)};Micro.ExplosionSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_EXPLOSION,a,b,c,d);this.height=this.width=48;this.yOffset=this.xOffset=-24;this.frame=1};Micro.ExplosionSprite.prototype=Object.create(Micro.BaseSprite.prototype);Micro.ExplosionSprite.prototype.startFire=function(a,b){a=Micro.pixToWorld(a);b=Micro.pixToWorld(b);if(this.map.testBounds(a,b)){var c=this.map.getTile(a,b),d=c.getValue();if(c.isCombustible()||d===Tile.DIRT)c.isZone()||this.map.setTo(a,b,Micro.randomFire())}};
Micro.ExplosionSprite.prototype.move=function(a,b,c,d){0===(a&1)&&(1===this.frame&&(a=Micro.pixToWorld(this.x),c=Micro.pixToWorld(this.y),b.sendMessage(Messages.SOUND_EXPLOSIONHIGH),b.sendMessage(Messages.EXPLOSION_REPORTED,{x:a,y:c})),this.frame++);6<this.frame&&(this.frame=0,this.startFire(this.x,this.y),this.startFire(this.x-16,this.y-16),this.startFire(this.x+16,this.y+16),this.startFire(this.x-16,this.y+16),this.startFire(this.x+16,this.y+16))};Micro.MonsterSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_MONSTER,a,b,c,d);this.height=this.width=48;this.yOffset=this.xOffset=-24;c>Micro.worldToPix(a.width)/2?d>Micro.worldToPix(a.height)/2?this.frame=10:this.frame=7:d>Micro.worldToPix(a.height)/2?this.frame=1:this.frame=4;this.flag=0;this.count=1E3;this.destX=Micro.worldToPix(a.pollutionMaxX);this.destY=Micro.worldToPix(a.pollutionMaxY);this.origX=this.x;this.origY=this.y;this._seenLand=!1;this.xDelta=[2,2,-2,-2,
0];this.yDelta=[-2,2,2,-2,0];this.cardinals1=[0,1,2,3];this.cardinals2=[1,2,3,0];this.diagonals1=[2,5,8,11];this.diagonals2=[11,2,5,8]};Micro.MonsterSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.MonsterSprite.prototype.move=function(a,b,c,d){0<this.soundCount&&this.soundCount--;a=Math.floor((this.frame-1)/3);var e;if(4>a){c=(this.frame-1)%3;2===c&&(this.step=0);0===c&&(this.step=1);this.step?c++:c--;if(60>Micro.absoluteDistance(this.x,this.y,this.destX,this.destY))if(0===this.flag)this.flag=1,this.destX=this.origX,this.destY=this.origY;else{this.frame=0;return}e=Micro.getDir(this.x,this.y,this.destX,this.destY);e=Math.floor((e-1)/2);e!==a&&Random.getChance(10)&&(c=Random.getRandom16()&
1?this.cardinals1[a]:this.cardinals2[a],a=4,this.soundCount||(b.sendMessage(Messages.SOUND_MONSTER),this.soundCount=50+Random.getRandom(100)))}else a=4,e=this.frame,c=e-13&3,Random.getRandom16()&3||(c=Random.getRandom16()&1?this.diagonals1[c]:this.diagonals2[c],a=Math.floor((c-1)/3),c=(c-1)%3);c=3*a+c+1;16<c&&(c=16);this.frame=c;this.x+=this.xDelta[a];this.y+=this.yDelta[a];0<this.count&&this.count--;a=Micro.getTileValue(this.map,this.x,this.y);if(-1===a||a===Tile.RIVER&&500>this.count)this.frame=
0;if(a===Tile.DIRT||a>Tile.WATER_HIGH)this._seenLand=!0;a=this.spriteManager.getSpriteList();for(c=0;c<a.length;c++)e=a[c],0===e.frame||e.type!==Micro.SPRITE_AIRPLANE&&e.type!==Micro.SPRITE_HELICOPTER&&e.type!==Micro.SPRITE_SHIP&&e.type!==Micro.SPRITE_TRAIN||!Micro.checkSpriteCollision(this,e)||e.explodeSprite(b);Micro.destroyMapTile(this.spriteManager,this.map,d,this.x,this.y)};Micro.TornadoSprite=function(a,b,c,d){Micro.BaseSprite.call(this);this.init(Micro.SPRITE_TORNADO,a,b,c,d);this.height=this.width=48;this.xOffset=-24;this.yOffset=-40;this.frame=1;this.count=200;this.xDelta=[2,3,2,0,-2,-3];this.yDelta=[-2,0,2,3,2,0]};Micro.TornadoSprite.prototype=Object.create(Micro.BaseSprite.prototype);
Micro.TornadoSprite.prototype.move=function(a,b,c,d){a=this.frame;2===a?a=this.flag?3:1:(this.flag=1===a?1:0,a=2);0<this.count&&this.count--;this.frame=a;a=this.spriteManager.getSpriteList();for(c=0;c<a.length;c++){var e=a[c];0===e.frame||e.type!==Micro.SPRITE_AIRPLANE&&e.type!==Micro.SPRITE_HELICOPTER&&e.type!==Micro.SPRITE_SHIP&&e.type!==Micro.SPRITE_TRAIN||!Micro.checkSpriteCollision(this,e)||e.explodeSprite(b)}a=Random.getRandom(5);this.x+=this.xDelta[a];this.y+=this.yDelta[a];this.spriteNotInBounds()&&
(this.frame=0);0!==this.count&&0===Random.getRandom(500)&&(this.frame=0);Micro.destroyMapTile(this.spriteManager,this.map,d,this.x,this.y)};Micro.SpriteManager=function(a,b){this.sim=b;this.spriteList=[];this.map=a;this.spriteCycle=0};
Micro.SpriteManager.prototype={constructor:Micro.SpriteManager,getSprite:function(a){var b=this.spriteList.filter(function(b){return 0!==b.frame&&b.type===a});return 0===b.length?null:b[0]},getSpriteList:function(){return this.spriteList.slice()},getSpritesInView:function(a,b,c,d){a=Micro.worldToPix(a);b=Micro.worldToPix(b);c=Micro.worldToPix(c);d=Micro.worldToPix(d);return this.spriteList.filter(function(e){return e.x+e.xOffset>=a&&e.y+e.yOffset>=b&&!(e.x+e.xOffset>=c&&e.y+e.yOffset>=d)})},moveObjects:function(){var a=
this.sim.messageManager,b=this.sim.disasterManager,c=this.sim.blockMaps;this.spriteCycle+=1;for(var d=this.spriteList.slice(),e=d.length;e--;){var f=d[e];0!==f.frame&&f.move(this.spriteCycle,a,b,c)}this.pruneDeadSprites()},makeSprite:function(a,b,c){this.spriteList.push(new constructors[a](this.map,this,b,c))},makeTornado:function(a){var b=this.getSprite(Micro.SPRITE_TORNADO);if(null!==b)b.count=200;else{var b=Random.getRandom(Micro.worldToPix(this.map.width)-800)+400,c=Random.getRandom(Micro.worldToPix(this.map.height)-
200)+100;this.makeSprite(Micro.SPRITE_TORNADO,b,c);a.sendMessage(Messages.TORNADO_SIGHTED,{x:Micro.pixToWorld(b),y:Micro.pixToWorld(c)})}},makeExplosion:function(a,b){this.map.testBounds(a,b)&&this.makeExplosionAt(Micro.worldToPix(a),Micro.worldToPix(b))},makeExplosionAt:function(a,b){this.makeSprite(Micro.SPRITE_EXPLOSION,a,b)},generatePlane:function(a,b){null===this.getSprite(Micro.SPRITE_AIRPLANE)&&this.makeSprite(Micro.SPRITE_AIRPLANE,Micro.worldToPix(a),Micro.worldToPix(b))},generateTrain:function(a,
b,c){20<a.totalPop&&null===this.getSprite(Micro.SPRITE_TRAIN)&&0===Random.getRandom(25)&&this.makeSprite(Micro.SPRITE_TRAIN,Micro.worldToPix(b)+8,Micro.worldToPix(c)+8)},generateShip:function(){var a;if(Random.getChance(3))for(a=4;a<this.map.width-2;a++)if(this.map.getTileValue(a,0)===Tile.CHANNEL){this.makeShipHere(a,0);return}if(Random.getChance(3))for(a=1;a<this.map.height-2;a++)if(this.map.getTileValue(0,a)===Tile.CHANNEL){this.makeShipHere(0,a);return}if(Random.getChance(3))for(a=4;a<this.map.width-
2;a++)if(this.map.getTileValue(a,this.map.height-1)===Tile.CHANNEL){this.makeShipHere(a,this.map.height-1);return}if(Random.getChance(3))for(a=1;a<this.map.height-2;a++)if(this.map.getTileValue(this.map.width-1,a)===Tile.CHANNEL){this.makeShipHere(this.map.width-1,a);break}},getBoatDistance:function(a,b){for(var c=99999,d=Micro.worldToPix(a)+8,e=Micro.worldToPix(b)+8,f,g=0,h=this.spriteList.length;g<h;g++)f=this.spriteList[g],f.type===Micro.SPRITE_SHIP&&0!==f.frame&&(f=Math.abs(f.x-d)+Math.abs(f.y-
e),c=Math.min(c,f));return c},makeShipHere:function(a,b){this.makeSprite(Micro.SPRITE_SHIP,Micro.worldToPix(a),Micro.worldToPix(b))},generateCopter:function(a,b){null===this.getSprite(Micro.SPRITE_HELICOPTER)&&this.makeSprite(Micro.SPRITE_HELICOPTER,Micro.worldToPix(a),Micro.worldToPix(b))},makeMonsterAt:function(a,b,c){this.makeSprite(Micro.SPRITE_MONSTER,Micro.worldToPix(b),Micro.worldToPix(c));a.sendMessage(Messages.MONSTER_SIGHTED,{x:b,y:c})},makeMonster:function(a){var b=this.getSprite(Micro.SPRITE_MONSTER);
null!==b&&(b.soundCount=1,b.count=1E3,b.destX=Micro.worldToPix(this.map.pollutionMaxX),b.destY=Micro.worldToPix(this.map.pollutionMaxY));for(var c=b=0;300>c;c++){var d=Random.getRandom(this.map.width-20)+10,e=Random.getRandom(this.map.height-10)+5;if(this.map.getTile(d,e).getValue()===Tile.RIVER){this.makeMonsterAt(a,d,e);b=1;break}}0===b&&this.makeMonsterAt(a,60,50)},pruneDeadSprites:function(a){this.spriteList=this.spriteList.filter(function(a){return 0!==a.frame})}};var constructors={};
constructors[Micro.SPRITE_TRAIN]=Micro.TrainSprite;constructors[Micro.SPRITE_SHIP]=Micro.BoatSprite;constructors[Micro.SPRITE_MONSTER]=Micro.MonsterSprite;constructors[Micro.SPRITE_HELICOPTER]=Micro.CopterSprite;constructors[Micro.SPRITE_AIRPLANE]=Micro.AirplaneSprite;constructors[Micro.SPRITE_TORNADO]=Micro.TornadoSprite;constructors[Micro.SPRITE_EXPLOSION]=Micro.ExplosionSprite;Micro.MapScanner=function(a,b){this._map=a;this.mapHeight=this._map.height;this.mapWidth=this._map.width;this._actions=[];this.sim=b};
Micro.MapScanner.prototype={constructor:Micro.MapScanner,addAction:function(a,b){this._actions.push({criterion:a,action:b})},mapScan:function(a,b,c){var d,e,f,g;for(c=this.mapHeight;c--;)for(d=a;d<b;d++)if(e=d+c*this.mapWidth,f=this._map.data[e]||new Micro.Tile,g=f.getValue(),!(g<Tile.FLOOD))for(f.isConductive()&&this.sim.powerManager.setTilePower(d,c),f.isZone()&&(this.sim.repairManager.checkTile(d,c,this.sim._cityTime),f.isPowered()?(this.sim.census.poweredZoneCount+=1,this._map.powerData[e]=1):
(this.sim.census.unpoweredZoneCount+=1,this._map.powerData[e]=2)),e=this._actions.length;e--;){var h=this._actions[e],k=Micro.isCallable(h.criterion);if(k&&h.criterion.call(null,f)){h.action.call(null,this._map,d,c,null);break}else if(!k&&h.criterion===g){h.action.call(null,this._map,d,c,null);break}}}};Micro.PowerManager=function(a,b){this.sim=b;this._map=a;this._powerStack=[];this.powerGridMap=new Micro.BlockMap(this._map.width,this._map.height,1,0)};
Micro.PowerManager.prototype={constructor:Micro.PowerManager,setTilePower:function(a,b){var c=this._map.getTile(a,b),d=c.getValue();d===Tile.NUCLEAR||d===Tile.POWERPLANT||0<this.powerGridMap.worldGet(a,b)?c.addFlags(Tile.POWERBIT):c.removeFlags(Tile.POWERBIT)},clearPowerStack:function(){this._powerStackPointer=0;this._powerStack=[]},testForConductive:function(a,b){var c=new this._map.Position(a);return c.move(b)&&this._map.getTile(c.x,c.y).isConductive()&&0===this.powerGridMap.worldGet(c.x,c.y)?!0:
!1},doPowerScan:function(a,b){this.powerGridMap.clear();for(var c=a.coalPowerPop*Micro.COAL_POWER_STRENGTH+a.nuclearPowerPop*Micro.NUCLEAR_POWER_STRENGTH,d=0;0<this._powerStack.length;){var e=this._powerStack.pop(),f=Direction.INVALID,g;do{d++;if(d>c){b.sendMessage(Messages.NOT_ENOUGH_POWER);return}f!==Direction.INVALID&&e.move(f);this.powerGridMap.worldSet(e.x,e.y,1);g=0;for(var h=Direction.BEGIN;h<Direction.END&&2>g;)this.testForConductive(e,h)&&(g++,f=h),h=Direction.increment90(h);1<g&&this._powerStack.push(new this._map.Position(e))}while(g)}},
coalPowerFound:function(a,b,c,d){this.sim.census.coalPowerPop+=1;this._powerStack.push(new a.Position(b,c));d=[-1,2,1,2];var e=[-1,-1,0,0];if(!this.sim.is3D)for(var f=0;4>f;f++)a.addTileFlags(b+d[f],c+e[f],Tile.ANIMBIT)},nuclearPowerFound:function(a,b,c,d){d=[3E4,2E4,1E4];if(!this.sim.disasterManager.disastersEnabled||0!==Random.getRandom(d[this.sim.gameLevel]))if(this.sim.census.nuclearPowerPop+=1,this._powerStack.push(new a.Position(b,c)),!this.sim.is3D)for(d=0;4>d;d++)a.addTileFlags(b,c,Tile.ANIMBIT|
Tile.CONDBIT|Tile.POWERBIT|Tile.BURNBIT)},registerHandlers:function(a,b){a.addAction(Tile.POWERPLANT,this.coalPowerFound.bind(this));a.addAction(Tile.NUCLEAR,this.nuclearPowerFound.bind(this));b.addAction(Tile.POWERPLANT,7,4);b.addAction(Tile.NUCLEAR,7,4)}};Micro.RepairManager=function(a){this._map=a;this._actions=[]};
Micro.RepairManager.prototype={constructor:Micro.RepairManager,addAction:function(a,b,c){this._actions.push({criterion:a,period:b,zoneSize:c})},repairZone:function(a,b,c){for(var d=this._map.getTileValue(a,b)-c-2,e=-1;e<c-1;e++)for(var f=-1;f<c-1;f++){d++;var g=this._map.getTile(a+f,b+e);g.isZone()||g.isAnimated()||(g=g.getValue(),(g<Tile.RUBBLE||g>=Tile.ROADBASE)&&this._map.setTo(a+f,b+e,new Micro.Tile(d,Tile.CONDBIT|Tile.BURNBIT)))}},checkTile:function(a,b,c){for(var d=0,e=this._actions.length;d<
e;d++){var f=this._actions[d];if(0===(c&f.period)){var g=this._map.getTile(a,b),h=g.getValue(),k=Micro.isCallable(f.criterion);k&&f.criterion.call(null,g)?this.repairZone(a,b,f.zoneSize):k||f.criterion!==h||this.repairZone(a,b,f.zoneSize)}}}};Micro.vulnerable=function(a){var b=a.getValue();return b<Tile.RESBASE||b>Tile.LASTZONE||a.isZone()?!1:!0};Micro.DisasterManager=function(a,b,c){this._map=a;this._spriteManager=b;this._gameLevel=c;this._floodCount=0;this.DisChance=[4800,2400,60];this.Dx=[0,1,0,-1];this.Dy=[-1,0,1,0];Object.defineProperty(this,"disastersEnabled",Micro.makeConstantDescriptor(!1))};
Micro.DisasterManager.prototype={constructor:Micro.DisasterManager,doDisasters:function(a,b){this._floodCount&&this._floodCount--;if(this.disastersEnabled&&Random.getRandom(this.DisChance[this._gameLevel]))switch(Random.getRandom(8)){case 0:case 1:this.setFire(b);break;case 2:case 3:this.makeFlood(b);break;case 5:this._spriteManager.makeTornado(b);break;case 7:case 8:60<a.pollutionAverage&&this._spriteManager.makeMonster(b)}},setDifficulty:function(a){this._gameLevel=a},scenarioDisaster:function(){},
makeMeltdown:function(a){for(var b=0;b<this._map.width-1;b++)for(var c=0;c<this._map.height-1;c++)if(this._map.getTileValue(b,c)===Tile.NUCLEAR){this.doMeltdown(a,b,c);return}},makeEarthquake:function(a){var b=Random.getRandom(700)+300;this.doEarthquake(b);a.sendMessage(Messages.EARTHQUAKE,{x:this._map.cityCenterX,y:this._map.cityCenterY});for(a=0;a<b;a++){var c=Random.getRandom(this._map.width-1),d=Random.getRandom(this._map.height-1);Micro.vulnerable(this._map.getTile(c,d))&&(0!==(a&3)?this._map.setTo(c,
d,Micro.randomRubble()):this._map.setTo(c,d,Micro.randomFire()))}},setFire:function(a,b,c){b=b||1;c=c||!1;for(var d=0;d<b;d++){var e=Random.getRandom(this._map.width-1),f=Random.getRandom(this._map.height-1),g=this._map.getTile(e,f);if(!g.isZone()&&(g=g.getValue(),g>(c?Tile.LHTHR:Tile.TREEBASE)&&g<Tile.LASTZONE)){this._map.setTo(e,f,Micro.randomFire());a.sendMessage(Messages.FIRE_REPORTED,{x:e,y:f});break}}},makeCrash:function(a){var b=this._spriteManager.getSprite(Micro.SPRITE_AIRPLANE);if(null===
b){var b=Random.getRandom(this._map.width-1),c=Random.getRandom(this._map.height-1);this._spriteManager.generatePlane(b,c);b=this._spriteManager.getSprite(Micro.SPRITE_AIRPLANE)}b.explodeSprite(a)},makeFire:function(a){this.setFire(a,40,!1)},makeFlood:function(a){for(var b=0;300>b;b++){var c=Random.getRandom(this._map.width-1),d=Random.getRandom(this._map.height-1),e=this._map.getTileValue(c,d);if(e>Tile.CHANNEL&&e<=Tile.WATER_HIGH)for(e=0;4>e;e++){var f=c+this.Dx[e],g=d+this.Dy[e];if(this._map.testBounds(f,
g)){var h=this._map.getTile(f,g);h.getValue();if(h===Tile.DIRT||h.isBulldozable()&&h.isCombustible){this._map.setTo(f,g,new Tile(Tile.FLOOD));this._floodCount=30;a.sendMessage(Messages.FLOODING_REPORTED,{x:f,y:g});return}}}}},doFlood:function(a,b,c){if(0<this._floodCount)for(var d=0;4>d;d++){if(Random.getChance(7)){var e=a+this.Dx[d],f=b+this.Dy[d];if(this._map.testBounds(e,f)){var g=this._map.getTile(e,f),h=g.getValue();if(g.isCombustible()||h===Tile.DIRT||h>=Tile.WOODS5&&h<Tile.FLOOD)g.isZone()&&
Micro.fireZone(this.map,e,f,c),this._map.setTo(e,f,new Tile(Tile.FLOOD+Random.getRandom(2)))}}}else Random.getChance(15)&&this._map.setTo(a,b,new Tile(Tile.DIRT))},doMeltdown:function(a,b,c){this._spriteManager.makeExplosion(b-1,c-1);this._spriteManager.makeExplosion(b-1,c+2);this._spriteManager.makeExplosion(b+2,c-1);this._spriteManager.makeExplosion(b+2,c+2);var d,e;for(e=b-1;e<b+3;e++)for(d=c-1;d<c+3;d++)this._map.setTo(e,d,Micro.randomFire());for(var f=0;200>f;f++)if(e=b-20+Random.getRandom(40),
d=c-15+Random.getRandom(30),this._map.testBounds(e,d)){var g=this._map.getTile(e,d);g.isZone()||(g.isCombustible()||g.getValue()===Tile.DIRT)&&this._map.setTo(e,d,new Tile(Tile.RADTILE))}a.sendMessage(Messages.NUCLEAR_MELTDOWN,{x:b,y:c})}};Micro.InputStatus=function(a){this.gameTools=new Micro.GameTools(a);this.canvas=document.getElementById(Micro.DEFAULT_ID);this.clickY=this.clickX=-1;this.right=this.left=this.down=this.up=!1;this.mouseY=this.mouseX=-1;this.currentTool=this.toolName=null;this.toolWidth=0;this.toolColour="";this.speedChangeRequested=this.disasterRequested=this.evalRequested=this.budgetRequested=!1;this.requestedSpeed=null;this.bindKeys();var b=this;this.canvas.addEventListener("mouseenter",function(a){b.mouseEnterHandler(a)},
!1);this.canvas.addEventListener("mouseleave",function(a){b.mouseLeaveHandler(a)},!1);a=document.getElementsByClassName("toolButton");for(var c=0;c<a.length;c++)a[c].addEventListener("click",function(a){b.toolButtonHandler(a)},!1),a[c].addEventListener("mouseover",function(a){b.toolButtonOver(a)},!1);document.getElementById("evalRequest").addEventListener("click",function(a){b.evalHandler(a)},!1);document.getElementById("budgetRequest").addEventListener("click",function(a){b.budgetHandler(a)},!1);
document.getElementById("disasterRequest").addEventListener("click",function(a){b.disasterHandler(a)},!1);document.getElementById("pauseRequest").addEventListener("click",function(a){b.speedChangeHandler(a)},!1)};
Micro.InputStatus.prototype={constructor:Micro.InputStatus,bindKeys:function(){var a=this;document.onkeydown=function(b){b=b||window.event;var c=!1;38==b.keyCode?c=a.up=!0:40==b.keyCode?c=a.down=!0:39==b.keyCode?c=a.right=!0:37==b.keyCode&&(c=a.left=!0);c&&b.preventDefault()};document.onkeyup=function(b){b=b||window.event;38==b.keyCode&&(a.up=!1);40==b.keyCode&&(a.down=!1);39==b.keyCode&&(a.right=!1);37==b.keyCode&&(a.left=!1)}},clickHandled:function(){this.clickY=this.clickX=-1;this.currentTool.clear()},
getRelativeCoordinates:function(a){var b=this.canvas.getBoundingClientRect(),c;void 0!==a.x&&void 0!==a.y?(c=a.x-b.left,a=a.y-b.top):(c=a.clientX-b.left,a=a.clientY-b.top);return{x:c,y:a}},speedChangeHandled:function(){this.speedChangeRequested=!1;this.requestedSpeed=null},speedChangeHandler:function(a){this.speedChangeRequested=!0;a="Pause"===document.getElementById("pauseRequest").innerHTML?"Play":"Pause";document.getElementById("pauseRequest").innerHTML=a},mouseEnterHandler:function(a){var b=this;
this.canvas.addEventListener("mousemove",function(a){b.mouseMoveHandler(a)},!1);this.canvas.addEventListener("click",function(a){b.canvasClickHandler(a)},!1)},mouseLeaveHandler:function(a){var b=this;this.canvas.removeEventListener("mousemove",function(a){b.mouseMoveHandler(a)},!1);this.canvas.removeEventListener("click",function(a){b.canvasClickHandler(a)},!1);this.mouseY=this.mouseX=-1},mouseMoveHandler:function(a){a=this.getRelativeCoordinates(a);this.mouseX=a.x;this.mouseY=a.y},canvasClickHandler:function(a){this.clickX=
this.mouseX;this.clickY=this.mouseY;a.preventDefault()},toolButtonOver:function(a){var b=a.target.getAttribute("data-tool");a=a.target.getAttribute("data-price");0==a?(a="",b="info"):a+="$";document.getElementById("buttonsInfos").innerHTML=b+" "+a},toolButtonHandler:function(a){for(var b=document.getElementsByClassName("selected"),c=0;c<b.length;c++)b[c].className=b[c].className.replace("selected","unselected");a.target.className=a.target.className.replace("unselected","selected");this.toolName=a.target.getAttribute("data-tool");
this.toolWidth=a.target.getAttribute("data-size");this.currentTool=this.gameTools[this.toolName];this.toolColour=a.target.getAttribute("data-colour");a.preventDefault()},disasterHandler:function(a){this.disasterRequested=!0},evalHandler:function(a){this.evalRequested=!0},budgetHandler:function(a){this.budgetRequested=!0},evalHandled:function(a){this.evalRequested=!1},disasterHandled:function(a){this.disasterRequested=!1},budgetHandled:function(a){this.budgetRequested=!1}};Micro.Traffic=function(a,b){this._map=a;this._stack=[];this._spriteManager=b};
Micro.Traffic.prototype={constructor:Micro.Traffic,makeTraffic:function(a,b,c,d){this._stack=[];a=new this._map.Position(a,b);return this.findPerimeterRoad(a)?this.tryDrive(a,d)?(this.addToTrafficDensityMap(c),Micro.ROUTE_FOUND):Micro.NO_ROUTE_FOUND:Micro.NO_ROAD_FOUND},addToTrafficDensityMap:function(a){for(a=a.trafficDensityMap;0<this._stack.length;){var b=this._stack.pop();if(this._map.testBounds(b.x,b.y)){var c=this._map.getTileValue(b.x,b.y);c>=Tile.ROADBASE&&c<Tile.POWERBASE&&(c=a.worldGet(b.x,
b.y),c+=50,c=Math.min(c,240),a.worldSet(b.x,b.y,c),240<=c&&0===Random.getRandom(5)&&(c=this._spriteManager.getSprite(Micro.SPRITE_HELICOPTER),null!==c&&(c.destX=Micro.worldToPix(b.x),c.destY=Micro.worldToPix(b.y))))}}},findPerimeterRoad:function(a){for(var b=0;12>b;b++){var c=a.x+Micro.perimX[b],d=a.y+Micro.perimY[b];if(this._map.testBounds(c,d)&&Micro.isDriveable(this._map.getTileValue(c,d)))return a.x=c,a.y=d,!0}return!1},tryDrive:function(a,b){for(var c=Direction.INVALID,d=new this._map.Position(a),
e=0;e<Micro.MAX_TRAFFIC_DISTANCE;e++){var f=this.tryGo(d,c);if(f!=Direction.INVALID){if(d.move(f),c=Direction.rotate180(f),e&1&&this._stack.push(new this._map.Position(d)),this.driveDone(d,b))return!0}else if(0<this._stack.length)this._stack.pop(),e+=3;else break}return!1},tryGo:function(a,b){for(var c=[],d=Direction.NORTH,e=0,f=0;4>f;f++)d!=b&&Micro.isDriveable(this._map.getTileFromMapOrDefault(a,d,Tile.DIRT))?(c[f]=d,e++):c[f]=Direction.INVALID,d=Direction.rotate90(d);if(0===e)return Direction.INVALID;
if(1===e)for(f=0;4>f;f++)if(c[f]!=Direction.INVALID)return c[f];for(f=Random.getRandom16()&3;c[f]===Direction.INVALID;)f=f+1&3;return c[f]},driveDone:function(a,b){return 0<a.y&&b(this._map.getTileValue(a.x,a.y-1))||a.x<this._map.width-1&&b(this._map.getTileValue(a.x+1,a.y))||a.y<this._map.height-1&&b(this._map.getTileValue(a.x,a.y+1))||0<a.x&&b(this._map.getTileValue(a.x-1,a.y))?!0:!1}};Micro.toKey=function(a,b){return[a,b].join()};Micro.TileHistory=function(){this.clear()};Micro.TileHistory.prototype={constructor:Micro.TileHistory,clear:function(){this.data={}},getTile:function(a,b){var c=Micro.toKey(a,b);return this.data[c]},setTile:function(a,b,c){a=Micro.toKey(a,b);this.data[a]=c}};Micro.AnimationManager=function(a,b,c){this._map=a;this.animationPeriod=b||5;this.blinkPeriod=c||30;this.shouldBlink=!1;this.count=1;this._lastPainted=null;this._data=[];this.initArray();this.registerAnimations()};
Micro.AnimationManager.prototype={constructor:Micro.AnimationManager,initArray:function(){for(var a=0;a<Tile.TILE_COUNT;a++)this._data[a]=a},inSequence:function(a,b){for(var c=[a],d=this._data[a];-1===c.indexOf(d);){if(d===b)return!0;c.push(d);d=this._data[d]}return!1},getTiles:function(a,b,c,d,e){e=e||!1;var f=!1;e||(this.count+=1);0===this.count%this.blinkPeriod&&(this.shouldBlink=!this.shouldBlink);0!==this.count%this.animationPeriod||e||(f=!0);e=new Micro.TileHistory;for(var g=[];a<c;a++)for(var h=
b;h<d;h++)if(!(0>a||a>=this._map.width||0>h||h>=this._map.height)){var k=this._map.getTile(a,h);if(k.isZone()&&!k.isPowered()&&this.shouldBlink)g.push({x:a,y:h,tileValue:Tile.LIGHTNINGBOLT});else if(k.isAnimated()){var k=k.getValue(),l=Tile.TILE_INVALID,m;this._lastPainted&&(m=this._lastPainted.getTile(a,h));f?l=m&&this.inSequence(k,m)?this._data[m]:this._data[k]:m&&this.inSequence(k,m)&&(l=m);l!==Tile.TILE_INVALID&&(g.push({x:a,y:h,tileValue:l}),e.setTile(a,h,l))}}this._lastPainted=e;return g},registerSingleAnimation:function(a){for(var b=
1;b<a.length;b++)this._data[a[b-1]]=a[b]},registerAnimations:function(){this.registerSingleAnimation([56,57,58,59,60,61,62,63,56]);this.registerSingleAnimation([80,128,112,96,80]);this.registerSingleAnimation([81,129,113,97,81]);this.registerSingleAnimation([82,130,114,98,82]);this.registerSingleAnimation([83,131,115,99,83]);this.registerSingleAnimation([84,132,116,100,84]);this.registerSingleAnimation([85,133,117,101,85]);this.registerSingleAnimation([86,134,118,102,86]);this.registerSingleAnimation([87,
135,119,103,87]);this.registerSingleAnimation([88,136,120,104,88]);this.registerSingleAnimation([89,137,121,105,89]);this.registerSingleAnimation([90,138,122,106,90]);this.registerSingleAnimation([91,139,123,107,91]);this.registerSingleAnimation([92,140,124,108,92]);this.registerSingleAnimation([93,141,125,109,93]);this.registerSingleAnimation([94,142,126,110,94]);this.registerSingleAnimation([95,143,127,111,95]);this.registerSingleAnimation([144,192,176,160,144]);this.registerSingleAnimation([145,
193,177,161,145]);this.registerSingleAnimation([146,194,178,162,146]);this.registerSingleAnimation([147,195,179,163,147]);this.registerSingleAnimation([148,196,180,164,148]);this.registerSingleAnimation([149,197,181,165,149]);this.registerSingleAnimation([150,198,182,166,150]);this.registerSingleAnimation([151,199,183,167,151]);this.registerSingleAnimation([152,200,184,168,152]);this.registerSingleAnimation([153,201,185,169,153]);this.registerSingleAnimation([154,202,186,170,154]);this.registerSingleAnimation([155,
203,187,171,155]);this.registerSingleAnimation([156,204,188,172,156]);this.registerSingleAnimation([157,205,189,173,157]);this.registerSingleAnimation([158,206,190,174,158]);this.registerSingleAnimation([159,207,191,175,159]);this.registerSingleAnimation([621,852,853,854,855,856,857,858,859,852]);this.registerSingleAnimation([641,884,885,886,887,884]);this.registerSingleAnimation([644,888,889,890,891,888]);this.registerSingleAnimation([649,892,893,894,895,892]);this.registerSingleAnimation([650,896,
897,898,899,896]);this.registerSingleAnimation([676,900,901,902,903,900]);this.registerSingleAnimation([677,904,905,906,907,904]);this.registerSingleAnimation([686,908,909,910,911,908]);this.registerSingleAnimation([689,912,913,914,915,912]);this.registerSingleAnimation([747,916,917,918,919,916]);this.registerSingleAnimation([748,920,921,922,923,920]);this.registerSingleAnimation([751,924,925,926,927,924]);this.registerSingleAnimation([752,928,929,930,931,928]);this.registerSingleAnimation([820,952,
953,954,955,952]);this.registerSingleAnimation([832,833,834,835,836,837,838,839,832]);this.registerSingleAnimation([840,841,842,843,840]);this.registerSingleAnimation([844,845,846,847,848,849,850,851,844]);this.registerSingleAnimation([932,933,934,935,936,937,938,939,932]);this.registerSingleAnimation([940,941,942,943,944,945,946,947,940])}};Micro.copyFrom=function(a,b){for(var c=function(a){return b(a)},d=a.data.length;d--;)this.data[d]=a.data[d].map(c)};Micro.makeArrayOf=function(a,b){for(var c=Array(a),d=a;d--;)c[d]=b;return c};
Micro.BlockMap=function(a,b,c,d){var e,f,g=function(a){return a},h=Error("Invalid parameters");if(3>arguments.length){if(!(a instanceof Micro.BlockMap)||2===arguments.length&&"function"!==typeof b)throw h;e=a;f=void 0===b?g:b}void 0!==e&&(a=e.gameMapWidth,b=e.gameMapHeight,c=e.blockSize,d=e.defaultValue);Object.defineProperties(this,{gameMapWidth:Micro.makeConstantDescriptor(a),gameMapHeight:Micro.makeConstantDescriptor(b),width:Micro.makeConstantDescriptor(Math.floor((a+1)/c)),height:Micro.makeConstantDescriptor(Math.floor((b+
1)/c)),blockSize:Micro.makeConstantDescriptor(c),defaultValue:Micro.makeConstantDescriptor(d)});this.data=[];e?Micro.copyFrom.call(this,e,f):this.clear()};
Micro.BlockMap.prototype={constructor:Micro.BlockMap,clear:function(){for(var a=Math.floor(this.gameMapWidth/this.blockSize)+1,b=Math.floor(this.gameMapHeight/this.blockSize)+1;b--;)this.data[b]=Micro.makeArrayOf(a,this.defaultValue)},copyFrom:function(a,b){a.width===this.width&&a.height===this.height&&a.blockSize===this.blockSize||console.warn("Copying from incompatible blockMap!");for(var c=0,d=a.height;c<d;c++)for(var e=0,f=a.width;e<f;e++)this.data[f*c+e]=b(a.data[f*c+e])},get:function(a,b){return this.data[b][a]},
set:function(a,b,c){this.data[b][a]=c},toBlock:function(a){return Math.floor(a/this.blockSize)},worldGet:function(a,b){return this.get(this.toBlock(a),this.toBlock(b))},worldSet:function(a,b,c){this.set(this.toBlock(a),this.toBlock(b),c)}};var Residential,Commercial,Industrial,Transport,Road,EmergencyServices,MiscTiles,Stadia;Micro.savePropsVar=["cityTime"];
Micro.Simulation=function(a,b,c,d,e){if(b!==Micro.LEVEL_EASY&&b!==Micro.LEVEL_MED&&b!==Micro.LEVEL_HARD)throw Error("Invalid level!");this.map=a;this.gameLevel=b;this.div=this.map.width/8;this.is3D=d||!1;this.speed=c;this.simCycle=this.phaseCycle=this.speedCycle=0;this.doInitialEval=!0;this.cityTime=50;this.cityPopLast=0;this.messageLast=Messages.VILLAGE_REACHED;this.startingYear=1900;this.indValveLast=this.comValveLast=this.resValveLast=0;this._cityMonthLast=this._cityYearLast=-1;this.evaluation=
new Micro.Evaluation(this.gameLevel,this);this.valves=new Micro.Valves;this.budget=new Micro.Budget;this.census=new Micro.Census;this.messageManager=new Micro.MessageManager;this.powerManager=new Micro.PowerManager(this.map,this);this.spriteManager=new Micro.SpriteManager(this.map,this);this.mapScanner=new Micro.MapScanner(this.map,this);this.repairManager=new Micro.RepairManager(this.map);this.traffic=new Micro.Traffic(this.map,this.spriteManager);this.disasterManager=new Micro.DisasterManager(this.map,
this.spriteManager,this.gameLevel);this.blockMaps={comRateMap:new Micro.BlockMap(this.map.width,this.map.height,8,0),crimeRateMap:new Micro.BlockMap(this.map.width,this.map.height,2,0),fireStationMap:new Micro.BlockMap(this.map.width,this.map.height,8,0),fireStationEffectMap:new Micro.BlockMap(this.map.width,this.map.height,8,0),landValueMap:new Micro.BlockMap(this.map.width,this.map.height,2,0),policeStationMap:new Micro.BlockMap(this.map.width,this.map.height,8,0),policeStationEffectMap:new Micro.BlockMap(this.map.width,
this.map.height,8,0),pollutionDensityMap:new Micro.BlockMap(this.map.width,this.map.height,2,0),populationDensityMap:new Micro.BlockMap(this.map.width,this.map.height,2,0),rateOfGrowthMap:new Micro.BlockMap(this.map.width,this.map.height,8,0),terrainDensityMap:new Micro.BlockMap(this.map.width,this.map.height,4,0),trafficDensityMap:new Micro.BlockMap(this.map.width,this.map.height,2,0),tempMap1:new Micro.BlockMap(this.map.width,this.map.height,2,0),tempMap2:new Micro.BlockMap(this.map.width,this.map.height,
2,0),tempMap3:new Micro.BlockMap(this.map.width,this.map.height,4,0)};this.clearCensus();e?this.load(e):(this.budget.setFunds(2E4),this.census.totalPop=1);this.init()};
Micro.Simulation.prototype={constructor:Micro.Simulation,save:function(a){for(var b=0,c=Micro.savePropsVar.length;b<c;b++)a[Micro.savePropsVar[b]]=this[Micro.savePropsVar[b]];this.map.save(a);this.evaluation.save(a);this.valves.save(a);this.budget.save(a);this.census.save(a)},load:function(a){this.messageManager.clear();for(var b=0,c=Micro.savePropsVar.length;b<c;b++)this[Micro.savePropsVar[b]]=a[Micro.savePropsVar[b]];this.evaluation.load(a);this.valves.load(a,this.messageManager);this.budget.load(a,
this.messageManager);this.census.load(a)},setSpeed:function(a){if(a!==Micro.SPEED_PAUSED&&a!==Micro.SPEED_SLOW&&a!==Micro.SPEED_MED&&a!==Micro.SPEED_FAST)throw Error("Invalid speed!");this.speed=a},setDifficulty:function(a){if(a!==Micro.LEVEL_EASY&&a!==Micro.LEVEL_MED&&a!==Micro.LEVEL_HARD)throw Error("Invalid level!");this.gameLevel=a;this.disasterManager.setDifficulty(this.gameLevel)},isPaused:function(){return this.speed===Micro.SPEED_PAUSED},simFrame:function(){this.budget.awaitingValues||0===
this.speed||1===this.speed&&0!==this.speedCycle%5||2===this.speed&&0!==this.speedCycle%3||(this.messageManager.clear(),this.simulate())},clearCensus:function(){this.census.clearCensus();this.powerManager.clearPowerStack();this.blockMaps.fireStationMap.clear();this.blockMaps.policeStationMap.clear()},init:function(){Residential=new Micro.Residential(this);Commercial=new Micro.Commercial(this);Industrial=new Micro.Industrial(this);Road=new Micro.Road(this);Transport=new Micro.Transport(this);EmergencyServices=
new Micro.EmergencyServices(this);MiscTiles=new Micro.MiscTiles(this);Stadia=new Micro.Stadia(this);Commercial.registerHandlers(this.mapScanner,this.repairManager);EmergencyServices.registerHandlers(this.mapScanner,this.repairManager);Industrial.registerHandlers(this.mapScanner,this.repairManager);MiscTiles.registerHandlers(this.mapScanner,this.repairManager);this.powerManager.registerHandlers(this.mapScanner,this.repairManager);Road.registerHandlers(this.mapScanner,this.repairManager);Residential.registerHandlers(this.mapScanner,
this.repairManager);Stadia.registerHandlers(this.mapScanner,this.repairManager);Transport.registerHandlers(this.mapScanner,this.repairManager);this.evaluation.evalInit();this.valves.setValves(this.gameLevel,this.census,this.budget);this.clearCensus();this.mapScanner.mapScan(0,this.map.width,null);this.powerManager.doPowerScan(this.census,this.messageManager);Micro.pollutionTerrainLandValueScan(this.map,this.census,this.blockMaps);Micro.crimeScan(this.census,this.blockMaps);Micro.populationDensityScan(this.map,
this.blockMaps);Micro.fireAnalysis(this.blockMaps)},simulate:function(){this.phaseCycle&=15;var a=this.speed-1;switch(this.phaseCycle){case 0:1023<++this.simCycle&&(this.simCycle=0);this.doInitialEval&&(this.doInitialEval=!1,this.evaluation.cityEvaluation());this.cityTime++;0===(this.simCycle&1)&&this.valves.setValves(this.gameLevel,this.census,this.budget);this.clearCensus();break;case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:this.mapScanner.mapScan((this.phaseCycle-1)*this.div,this.phaseCycle*
this.div,null);break;case 9:0===this.cityTime%Micro.CENSUS_FREQUENCY_10&&this.census.take10Census(this.budget);0===this.cityTime%Micro.CENSUS_FREQUENCY_120&&this.census.take120Census(this.budget);0===this.cityTime%Micro.TAX_FREQUENCY&&(this.budget.collectTax(this.gameLevel,this.census,this.messageManager),this.evaluation.cityEvaluation());break;case 10:0===this.simCycle%5&&Micro.decRateOfGrowthMap(this.blockMaps);Micro.decTrafficMap(this.blockMaps);this.sendMessages();break;case 11:0===this.simCycle%
Micro.speedPowerScan[a]&&this.powerManager.doPowerScan(this.census,this.messageManager);break;case 12:0===this.simCycle%Micro.speedPollutionTerrainLandValueScan[a]&&Micro.pollutionTerrainLandValueScan(this.map,this.census,this.blockMaps);break;case 13:0===this.simCycle%Micro.speedCrimeScan[a]&&Micro.crimeScan(this.census,this.blockMaps);break;case 14:0===this.simCycle%Micro.speedPopulationDensityScan[a]&&Micro.populationDensityScan(this.map,this.blockMaps);break;case 15:0===this.simCycle%Micro.speedFireAnalysis[a]&&
Micro.fireAnalysis(this.blockMaps),this.disasterManager.doDisasters(this.census,this.messageManager)}this.phaseCycle=this.phaseCycle+1&15},sendMessages:function(){this.checkGrowth();var a=this.census.resZonePop+this.census.comZonePop+this.census.indZonePop,b=this.census.nuclearPowerPop+this.census.coalPowerPop;switch(this.cityTime&63){case 1:Math.floor(a/4)>=this.census.resZonePop&&this.messageManager.sendMessage(Messages.NEED_MORE_RESIDENTIAL);break;case 5:Math.floor(a/8)>=this.census.comZonePop&&
this.messageManager.sendMessage(Messages.NEED_MORE_COMMERCIAL);break;case 10:Math.floor(a/8)>=this.census.indZonePop&&this.messageManager.sendMessage(Messages.NEED_MORE_INDUSTRIAL);break;case 14:10<a&&2*a>this.census.roadTotal&&this.messageManager.sendMessage(Messages.NEED_MORE_ROADS);break;case 18:50<a&&a>this.census.railTotal&&this.messageManager.sendMessage(Messages.NEED_MORE_RAILS);break;case 22:10<a&&0==b&&this.messageManager.sendMessage(Messages.NEED_ELECTRICITY);break;case 26:500<this.census.resPop&&
0===this.census.stadiumPop?(this.messageManager.sendMessage(Messages.NEED_STADIUM),this.valves.resCap=!0):this.valves.resCap=!1;break;case 28:70<this.census.indPop&&0===this.census.seaportPop?(this.messageManager.sendMessage(Messages.NEED_SEAPORT),this.valves.indCap=!0):this.valves.indCap=!1;break;case 30:100<this.census.comPop&&0===this.census.airportPop?(this.messageManager.sendMessage(Messages._NEED_AIRPORT),this.valves.comCap=!0):this.valves.comCap=!1;break;case 32:a=this.census.unpoweredZoneCount+
this.census.poweredZoneCount;0<a&&0.7>this.census.poweredZoneCount/a&&this.messageManager.sendMessage(Messages.BLACKOUTS_REPORTED);break;case 35:60<this.census.pollutionAverage&&this.messageManager.sendMessage(Messages.HIGH_POLLUTION);break;case 42:100<this.census.crimeAverage&&this.messageManager.sendMessage(Messages.HIGH_CRIME);break;case 45:60<this.census.totalPop&&0===this.census.fireStationPop&&this.messageManager.sendMessage(Messages.NEED_FIRE_STATION);break;case 48:60<this.census.totalPop&&
0===this.census.policeStationPop&&this.messageManager.sendMessage(Messages.NEED_POLICE_STATION);break;case 51:12<this.budget.cityTax&&this.messageManager.sendMessage(Messages.TAX_TOO_HIGH);break;case 54:this.budget.roadEffect<Math.floor(5*this.budget.MAX_ROAD_EFFECT/8)&&30<this.census.roadTotal&&this.messageManager.sendMessage(Messages.ROAD_NEEDS_FUNDING);break;case 57:this.budget.fireEffect<Math.floor(7*this.budget.MAX_FIRE_STATION_EFFECT/10)&&20<this.census.totalPop&&this.messageManager.sendMessage(Messages.FIRE_STATION_NEEDS_FUNDING);
break;case 60:this.budget.policeEffect<Math.floor(7*this.budget.MAX_POLICE_STATION_EFFECT/10)&&20<this.census.totalPop&&this.messageManager.sendMessage(Messages.POLICE_NEEDS_FUNDING);break;case 63:60<this.census.trafficAverage&&this.messageManager.sendMessage(Messages.TRAFFIC_JAMS,-1,-1,!0)}},checkGrowth:function(){if(0===(this.cityTime&3)){var a="",b=this.evaluation.getPopulation(this.census);if(0<this.cityPopLast){var c=this.evaluation.getCityClass(this.cityPopLast),d=this.evaluation.getCityClass(b);
if(c!==d)switch(d){case Micro.CC_TOWN:a=Messages.REACHED_TOWN;break;case Micro.CC_CITY:a=Messages.REACHED_CITY;break;case Micro.CC_CAPITAL:a=Messages.REACHED_CAPITAL;break;case Micro.CC_METROPOLIS:a=Messages.REACHED_METROPOLIS;break;case Micro.CC_MEGALOPOLIS:a=Messages.REACHED_MEGALOPOLIS}}""!==a&&a!==this.messageLast&&(this.messageManager.sendMessage(a),this.messageLast=a);this.cityPopLast=b}},updateFrontEnd:function(){this.valves.changed&&(this._resLast=this.valves.resValve,this._comLast=this.valves.comValve,
this._indLast=this.valves.indValve,this.messageManager.sendMessage(Messages.VALVES_UPDATED,{residential:this.valves.resValve,commercial:this.valves.comValve,industrial:this.valves.indValve}),this.valves.changed=!1);this.updateTime();this.evaluation.changed&&(this.messageManager.sendMessage(Messages.EVAL_UPDATED,{classification:this.evaluation.cityClass,population:this.evaluation.cityPop,score:this.evaluation.cityScore}),this.evaluation.changed=!1)},setYear:function(a){a<this.startingYear&&(a=this.startingYear);
a=a-this.startingYear-this.cityTime/48;this.cityTime+=48*a;this.updateTime()},updateTime:function(){var a=Math.floor(this.cityTime/48)+this.startingYear,b=Math.floor(this.cityTime%48)>>2;if(1E6<=a)this.setYear(this.startingYear);else if(this._cityYearLast!==a||this._cityMonthLast!==b)this._cityYearLast=a,this._cityMonthLast=b,this.messageManager.sendMessage(Messages.DATE_UPDATED,{month:b,year:a})}};