mirror of
https://github.com/Cola-Echo/memory-manager-concurrent.git
synced 2026-06-06 15:55:52 +00:00
7 lines
117 KiB
JavaScript
7 lines
117 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2010-2022 3d.City.js Authors
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).city={})}(this,(function(t){"use strict";const e={haveMapAnimation:!0,localStorage:null,GameMapProps:["cityCentreX","cityCentreY","pollutionMaxX","pollutionMaxY","width","height"],savePropsVar:["cityTime"],CensusProps:["resPop","comPop","indPop","crimeRamp","pollutionRamp","landValueAverage","pollutionAverage","crimeAverage","totalPop","resHist10","resHist120","comHist10","comHist120","indHist10","indHist120","crimeHist10","crimeHist120","moneyHist10","moneyHist120","pollutionHist10","pollutionHist120"],BudgetProps:["autoBudget","totalFunds","policePercent","roadPercent","firePercent","roadSpend","policeSpend","fireSpend","roadMaintenanceBudget","policeMaintenanceBudget","fireMaintenanceBudget","cityTax","roadEffect","policeEffect","fireEffect"],PROBLEMS:["CVP_CRIME","CVP_POLLUTION","CVP_HOUSING","CVP_TAXES","CVP_TRAFFIC","CVP_UNEMPLOYMENT","CVP_FIRE"],NUMPROBLEMS:7,NUM_COMPLAINTS:4,problemData:[],EvalProps:["cityClass","cityScore"],speedPowerScan:[2,4,5,6],speedPollutionTerrainLandValueScan:[2,7,17,30],speedCrimeScan:[1,8,18,32],speedPopulationDensityScan:[1,9,19,38],speedFireAnalysis:[1,10,20,40],CENSUS_FREQUENCY_10:4,CENSUS_FREQUENCY_120:40,TAX_FREQUENCY:48,MAP_WIDTH:128,MAP_HEIGHT:128,MAP_DEFAULT_WIDTH:384,MAP_DEFAULT_HEIGHT:384,MAP_BIG_DEFAULT_WIDTH:2048,MAP_BIG_DEFAULT_HEIGHT:2048,MAP_BIG_DEFAULT_ID:"bigMap",MAP_PARENT_ID:"splashContainer",MAP_DEFAULT_ID:"SplashCanvas",DEFAULT_WIDTH:400,DEFAULT_HEIGHT:400,DEFAULT_ID:"MicropolisCanvas",RCI_DEFAULT_ID:"RCICanvas",LEVEL_EASY:0,LEVEL_MED:1,LEVEL_HARD:2,SPEED_PAUSED:0,SPEED_SLOW:1,SPEED_MED:2,SPEED_FAST:3,SPEED_ULTRA:4,ROUTE_FOUND:1,NO_ROUTE_FOUND:0,NO_ROAD_FOUND:-1,MAX_TRAFFIC_DISTANCE:30,perimX:[-1,0,1,2,2,2,1,0,-1,-2,-2,-2],perimY:[-2,-2,-2,-1,0,1,2,2,2,1,0,-1],SPRITE_TRAIN:1,SPRITE_HELICOPTER:2,SPRITE_AIRPLANE:3,SPRITE_SHIP:4,SPRITE_MONSTER:5,SPRITE_TORNADO:6,SPRITE_EXPLOSION:7,CC_VILLAGE:"VILLAGE",CC_TOWN:"TOWN",CC_CITY:"CITY",CC_CAPITAL:"CAPITAL",CC_METROPOLIS:"METROPOLIS",CC_MEGALOPOLIS:"MEGALOPOLIS",CRIME:0,POLLUTION:1,HOUSING:2,TAXES:3,TRAFFIC:4,UNEMPLOYMENT:5,FIRE:6,RES_VALVE_RANGE:2e3,COM_VALVE_RANGE:1500,IND_VALVE_RANGE:1500,taxTable:[200,150,120,100,80,50,30,0,-10,-40,-100,-150,-200,-250,-300,-350,-400,-450,-500,-550,-600],extMarketParamTable:[1.2,1.1,.98],RLevels:[.7,.9,1.2],FLevels:[1.4,1.2,.8],MAX_ROAD_EFFECT:32,MAX_POLICESTATION_EFFECT:1e3,MAX_FIRESTATION_EFFECT:1e3,policeMaintenanceCost:100,fireMaintenanceCost:100,roadMaintenanceCost:1,railMaintenanceCost:2,COAL_POWER_STRENGTH:700,NUCLEAR_POWER_STRENGTH:2e3,DISASTER_NONE:"None",DISASTER_MONSTER:"Monster",DISASTER_FIRE:"Fire",DISASTER_FLOOD:"Flood",DISASTER_CRASH:"Crash",DISASTER_MELTDOWN:"Meltdown",DISASTER_TORNADO:"Tornado",CURRENT_VERSION:3,KEY:"micropolisJSGame",DisChance:[479,239,59],TERRAIN_CREATE_ISLAND:0,TERRAIN_TREE_LEVEL:-1,TERRAIN_LAKE_LEVEL:-1,TERRAIN_CURVE_LEVEL:-1,ISLAND_RADIUS:18,M_ARRAY_TYPE:"undefined"!=typeof Float32Array?Float32Array:Array,arrs:["res","com","ind","crime","money","pollution"],directionTable:[0,3,2,1,3,4,5,7,6,5,7,8,1],SMOOTH_NEIGHBOURS_THEN_BLOCK:0,SMOOTH_ALL_THEN_CLAMP:1,simData:null,messageManager:null};class i{static emitEvent(t,i){e.messageManager.sendMessage(t,i)}}class s{static mcd(t){return{configurable:!1,enumerable:!1,writeable:!1,value:t}}static rotate10Arrays(){for(var t=0;t<e.arrs.length;t++){var i=e.arrs[t]+"Hist10";this[i].pop(),this[i].unshift(0)}}static rotate120Arrays(){for(var t=0;t<e.arrs.length;t++){var i=e.arrs[t]+"Hist120";this[i].pop(),this[i].unshift(0)}}static isCallable(t){return"function"==typeof t}static copyFrom(t,e,i){for(var s=function(t){return i(t)},a=e.data.length;a--;)t[a]=e.data[a].map(s)}static makeArrayOf(t,e){for(var i=new Array(t),s=t;s--;)i[s]=e;return i}}class a{static lerp(t,e,i){return(1-i)*t+i*e}static rand(t,e){return t+Math.random()*(e-t)}static randInt(t,e){return t+Math.floor(Math.random()*(e-t+1))}static clamp(t,e,i){return t<e?e:t>i?i:t}static getChance(t){return 0==(a.getRandom16()&t)}static getERandom(t){var e=a.getRandom(t),i=a.getRandom(t);return Math.min(e,i)}static getRandom(t){return Math.floor(Math.random()*(t+1))}static getRandom16(){return a.getRandom(65535)}static getRandom16Signed(){var t=a.getRandom16();return t<32768?t:-65536+t}}class o{static pixToWorld(t){return t>>4}static worldToPix(t){return t<<4}static unwrapTile(t){return t.isTile?t.getValue():t}static canBulldoze(t){return(t=o.unwrapTile(t))>=n.FIRSTRIVEDGE&&t<=n.LASTRUBBLE||t>=n.POWERBASE+2&&t<=n.POWERBASE+12||t>=n.TINYEXP&&t<=n.LASTTINYEXP+2}static isCommercial(t){return(t=o.unwrapTile(t))>=n.COMBASE&&t<n.INDBASE}static isIndustrial(t){return(t=o.unwrapTile(t))>=n.INDBASE&&t<n.PORTBASE}static isResidential(t){return(t=o.unwrapTile(t))>=n.RESBASE&&t<n.HOSPITALBASE}static isDriveable(t){return(t=o.unwrapTile(t))>=n.ROADBASE&&t<=n.LASTRAIL||t===n.RAILHPOWERV||t===n.RAILVPOWERH}static isFire(t){return(t=o.unwrapTile(t))>=n.FIREBASE&&t<n.ROADBASE}static isFlood(t){return(t=o.unwrapTile(t))>=n.FLOOD&&t<n.LASTFLOOD}static isManualExplosion(t){return(t=o.unwrapTile(t))>=n.TINYEXP&&t<=n.LASTTINYEXP}static isRail(t){return(t=o.unwrapTile(t))>=n.RAILBASE&&t<n.RESBASE}static isRoad(t){return(t=o.unwrapTile(t))>=n.ROADBASE&&t<n.POWERBASE}static normalizeRoad(t){return(t=o.unwrapTile(t))>=n.ROADBASE&&t<=n.LASTROAD+1?64+(15&t):t}static isCommercialZone(t){return t.isZone()&&o.isCommercial(t)}static isIndustrialZone(t){return t.isZone()&&o.isIndustrial(t)}static isResidentialZone(t){return t.isZone()&&o.isResidential(t)}static randomFire(t){return new r(n.FIRE+(3&a.getRandom16()),n.ANIMBIT)}static randomRubble(t){return new r(n.RUBBLE+(3&a.getRandom16()),n.BULLBIT)}static HOSPITAL(t){}static checkZoneSize(t){return t>=n.RESBASE-1&&t<=n.PORTBASE-1||t>=n.LASTPOWERPLANT+1&&t<=n.POLICESTATION+4||t>=n.CHURCH1BASE&&t<=n.CHURCH7LAST?3:t>=n.PORTBASE&&t<=n.LASTPORT||t>=n.COALBASE&&t<=n.LASTPOWERPLANT||t>=n.STADIUMBASE&&t<=n.LASTZONE?4:0}static fireZone(t,e,i,s){let o,r,h,l,d=t.getTileValue(e,i),E=2,c=s.rateOfGrowthMap.worldGet(e,i);for(c=a.clamp(c-20,-200,200),s.rateOfGrowthMap.worldSet(e,i,c),d===n.AIRPORT?E=5:d>=n.PORTBASE?E=3:d<n.PORTBASE&&(E=2),o=-1;o<E;o++)for(r=-1;r<E;r++)h=e+o,l=i+r,t.testBounds(h,l)&&t.getTileValue(h,l>=n.ROADBASE)&&t.addTileFlags(h,l,n.BULLBIT)}static getLandPollutionValue(t,e,i){let s=t.landValueMap.worldGet(e,i);return s-=t.pollutionDensityMap.worldGet(e,i),s<30?0:s<80?1:s<150?2:3}static incRateOfGrowth(t,e,i,s){let o=t.rateOfGrowthMap.worldGet(e,i),r=a.clamp(o+4*s,-200,200);t.rateOfGrowthMap.worldSet(e,i,r)}static putZone(t,e,i,s,a){let o,r,h;for(o=-1;o<2;o++)for(r=-1;r<2;r++)if(h=t.getTileValue(e+r,i+o),h>=n.FLOOD&&h<n.ROADBASE)return;t.putZone(e,i,s,3),t.addTileFlags(e,i,n.BULLBIT),a&&t.addTileFlags(e,i,n.POWERBIT)}}o.checkBigZone=function(t){let e;switch(t){case n.POWERPLANT:case n.PORT:case n.NUCLEAR:case n.STADIUM:e={zoneSize:4,deltaX:0,deltaY:0};break;case n.POWERPLANT+1:case n.COALSMOKE3:case n.COALSMOKE3+1:case n.COALSMOKE3+2:case n.PORT+1:case n.NUCLEAR+1:case n.STADIUM+1:e={zoneSize:4,deltaX:-1,deltaY:0};break;case n.POWERPLANT+4:case n.PORT+4:case n.NUCLEAR+4:case n.STADIUM+4:e={zoneSize:4,deltaX:0,deltaY:-1};break;case n.POWERPLANT+5:case n.PORT+5:case n.NUCLEAR+5:case n.STADIUM+5:e={zoneSize:4,deltaX:-1,deltaY:-1};break;case n.AIRPORT:e={zoneSize:6,deltaX:0,deltaY:0};break;case n.AIRPORT+1:e={zoneSize:6,deltaX:-1,deltaY:0};break;case n.AIRPORT+2:e={zoneSize:6,deltaX:-2,deltaY:0};break;case n.AIRPORT+3:e={zoneSize:6,deltaX:-3,deltaY:0};break;case n.AIRPORT+6:e={zoneSize:6,deltaX:0,deltaY:-1};break;case n.AIRPORT+7:e={zoneSize:6,deltaX:-1,deltaY:-1};break;case n.AIRPORT+8:e={zoneSize:6,deltaX:-2,deltaY:-1};break;case n.AIRPORT+9:e={zoneSize:6,deltaX:-3,deltaY:-1};break;case n.AIRPORT+12:e={zoneSize:6,deltaX:0,deltaY:-2};break;case n.AIRPORT+13:e={zoneSize:6,deltaX:-1,deltaY:-2};break;case n.AIRPORT+14:e={zoneSize:6,deltaX:-2,deltaY:-2};break;case n.AIRPORT+15:e={zoneSize:6,deltaX:-3,deltaY:-2};break;case n.AIRPORT+18:e={zoneSize:6,deltaX:0,deltaY:-3};break;case n.AIRPORT+19:e={zoneSize:6,deltaX:-1,deltaY:-3};break;case n.AIRPORT+20:e={zoneSize:6,deltaX:-2,deltaY:-3};break;case n.AIRPORT+21:e={zoneSize:6,deltaX:-3,deltaY:-3};break;default:e={zoneSize:0,deltaX:0,deltaY:0}}return e};class r{constructor(t=n.DIRT,e){this.isTile=!0,this._value=t,arguments.length>1&&(this._value|=e)}getValue(){return this._value&n.BIT_MASK}setValue(t){if(0===arguments.length||"number"!=typeof t||t<0)throw new Error("Invalid parameter");let e=0;t<n.BIT_START&&(e=this._value&n.ALLBITS),this._value=t|e}isBulldozable(){return(this._value&n.BULLBIT)>0}isAnimated(){return(this._value&n.ANIMBIT)>0}isConductive(){return(this._value&n.CONDBIT)>0}isCombustible(){return(this._value&n.BURNBIT)>0}isPowered(){return(this._value&n.POWERBIT)>0}isZone(){return(this._value&n.ZONEBIT)>0}addFlags(t){if(!arguments.length||"number"!=typeof t||t<n.BIT_START||t>=n.BIT_END<<1)throw new Error("Invalid parameter");this._value|=t}removeFlags(t){if(!arguments.length||"number"!=typeof t||t<n.BIT_START||t>=n.BIT_END<<1)throw new Error("Invalid parameter");this._value&=~t}setFlags(t){let e=this._value&~n.ALLBITS;this._value=e|t}getFlags(){return this._value&n.ALLBITS}getRawValue(){return this._value}set(t,e){if(arguments.length<2||"number"!=typeof t||"number"!=typeof e||t>=n.TILE_COUNT)throw new Error("Invalid parameter");this.setValue(t),this.setFlags(e)}toString(){let t="Tile# "+this.getValue();return t+=this.isCombustible()?" burning":"",t+=this.isPowered()?" powered":"",t+=this.isAnimated()?" animated":"",t+=this.isConductive()?" conductive":"",t+=this.isZone()?" zone":"",t+=this.isBulldozable()?" bulldozeable":"",t}}const n={POWERBIT:32768,CONDBIT:16384,BURNBIT:8192,BULLBIT:4096,ANIMBIT:2048,ZONEBIT:1024,BLBNBIT:12288,BLBNCNBIT:28672,BNCNBIT:24576,ASCBIT:26624,ALLBITS:64512,BIT_START:1024,BIT_END:32768,BIT_MASK:1023,DIRT:0,RIVER:2,REDGE:3,CHANNEL:4,FIRSTRIVEDGE:5,LASTRIVEDGE:20,WATER_LOW:2,WATER_HIGH:20,TREEBASE:21,WOODS_LOW:21,LASTTREE:36,WOODS:37,UNUSED_TRASH1:38,UNUSED_TRASH2:39,WOODS_HIGH:39,WOODS2:40,WOODS3:41,WOODS4:42,WOODS5:43,RUBBLE:44,LASTRUBBLE:47,FLOOD:48,LASTFLOOD:51,RADTILE:52,UNUSED_TRASH3:53,UNUSED_TRASH4:54,UNUSED_TRASH5:55,FIRE:48,FIREBASE:48,LASTFIRE:55,HBRIDGE:64,ROADBASE:64,VBRIDGE:65,ROADS:66,ROADS2:67,ROADS3:68,ROADS4:69,ROADS5:70,ROADS6:71,ROADS7:72,ROADS8:73,ROADS9:74,ROADS10:75,INTERSECTION:76,HROADPOWER:77,VROADPOWER:78,BRWH:79,LTRFBASE:80,BRWV:95,BRWXXX1:111,BRWXXX2:127,BRWXXX3:143,HTRFBASE:144,BRWXXX4:159,BRWXXX5:175,BRWXXX6:191,LASTROAD:206,BRWXXX7:207,HPOWER:208,VPOWER:209,LHPOWER:210,LVPOWER:211,LVPOWER2:212,LVPOWER3:213,LVPOWER4:214,LVPOWER5:215,LVPOWER6:216,LVPOWER7:217,LVPOWER8:218,LVPOWER9:219,LVPOWER10:220,RAILHPOWERV:221,RAILVPOWERH:222,POWERBASE:208,LASTPOWER:222,UNUSED_TRASH6:223,HRAIL:224,VRAIL:225,LHRAIL:226,LVRAIL:227,LVRAIL2:228,LVRAIL3:229,LVRAIL4:230,LVRAIL5:231,LVRAIL6:232,LVRAIL7:233,LVRAIL8:234,LVRAIL9:235,LVRAIL10:236,HRAILROAD:237,VRAILROAD:238,RAILBASE:224,LASTRAIL:238,ROADVPOWERH:239,RESBASE:240,FREEZ:244,HOUSE:249,LHTHR:249,HHTHR:260,RZB:265,HOSPITALBASE:405,HOSPITAL:409,CHURCHBASE:414,CHURCH0BASE:414,CHURCH:418,CHURCH0:418,COMBASE:423,COMCLR:427,CZB:436,COMLAST:609,INDBASE:612,INDCLR:616,LASTIND:620,IND1:621,IZB:625,IND2:641,IND3:644,IND4:649,IND5:650,IND6:676,IND7:677,IND8:686,IND9:689,PORTBASE:693,PORT:698,LASTPORT:708,AIRPORTBASE:709,RADAR:711,AIRPORT:716,COALBASE:745,POWERPLANT:750,LASTPOWERPLANT:760,FIRESTBASE:761,FIRESTATION:765,POLICESTBASE:770,POLICESTATION:774,STADIUMBASE:779,STADIUM:784,FULLSTADIUM:800,NUCLEARBASE:811,NUCLEAR:816,LASTZONE:826,LIGHTNINGBOLT:827,HBRDG0:828,HBRDG1:829,HBRDG2:830,HBRDG3:831,RADAR0:832,RADAR1:833,RADAR2:834,RADAR3:835,RADAR4:836,RADAR5:837,RADAR6:838,RADAR7:839,FOUNTAIN:840,INDBASE2:844,TELEBASE:844,TELELAST:851,SMOKEBASE:852,TINYEXP:860,SOMETINYEXP:864,LASTTINYEXP:867,TINYEXPLAST:883,COALSMOKE1:916,COALSMOKE2:920,COALSMOKE3:924,COALSMOKE4:928,FOOTBALLGAME1:932,FOOTBALLGAME2:940,VBRDG0:948,VBRDG1:949,VBRDG2:950,VBRDG3:951,NUKESWIRL1:952,NUKESWIRL2:953,NUKESWIRL3:954,NUKESWIRL4:955,CHURCH1BASE:956,CHURCH1:960,CHURCH2BASE:965,CHURCH2:969,CHURCH3BASE:974,CHURCH3:978,CHURCH4BASE:983,CHURCH4:987,CHURCH5BASE:992,CHURCH5:996,CHURCH6BASE:1001,CHURCH6:1005,CHURCH7BASE:1010,CHURCH7:1014,CHURCH7LAST:1018,TILE_COUNT:1024,TILE_INVALID:-1,MIN_SIZE:16},h=[n.ROADS,n.ROADS2,n.ROADS,n.ROADS3,n.ROADS2,n.ROADS2,n.ROADS4,n.ROADS8,n.ROADS,n.ROADS6,n.ROADS,n.ROADS7,n.ROADS5,n.ROADS10,n.ROADS9,n.INTERSECTION],l=[n.LHRAIL,n.LVRAIL,n.LHRAIL,n.LVRAIL2,n.LVRAIL,n.LVRAIL,n.LVRAIL3,n.LVRAIL7,n.LHRAIL,n.LVRAIL5,n.LHRAIL,n.LVRAIL6,n.LVRAIL4,n.LVRAIL9,n.LVRAIL8,n.LVRAIL10],d=[n.LHPOWER,n.LVPOWER,n.LHPOWER,n.LVPOWER2,n.LVPOWER,n.LVPOWER,n.LVPOWER3,n.LVPOWER7,n.LHPOWER,n.LVPOWER5,n.LHPOWER,n.LVPOWER6,n.LVPOWER4,n.LVPOWER9,n.LVPOWER8,n.LVPOWER10];class E{constructor(){this.data=[]}sendMessage(t,e){this.data.push({message:t,data:e})}clear(){this.data=[]}getMessages(){return this.data.slice()}}var c={AUTOBUDGET_CHANGED:s.mcd("Autobudget changed"),BUDGET_NEEDED:s.mcd("User needs to budget"),BUDGET_REQUESTED:s.mcd("Budget window requested"),BUDGET_WINDOW_CLOSED:s.mcd("Budget window closed"),BLACKOUTS_REPORTED:s.mcd("Blackouts reported"),CLASSIFICATION_UPDATED:s.mcd("Classification updated"),CONGRATS_SHOWING:s.mcd("Congratulations showing"),CONGRATS_WINDOW_CLOSED:s.mcd("Congratulations window closed"),DATE_UPDATED:s.mcd("Date changed"),DEBUG_WINDOW_REQUESTED:s.mcd("Debug Window Requested"),DEBUG_WINDOW_CLOSED:s.mcd("Debug Window Closed"),DISASTER_REQUESTED:s.mcd("Disaster Requested"),DISASTER_WINDOW_CLOSED:s.mcd("Disaster window closed"),EARTHQUAKE:s.mcd("Earthquake"),EVAL_REQUESTED:s.mcd("Evaluation Requested"),EVAL_UPDATED:s.mcd("Evaluation Updated"),EVAL_WINDOW_CLOSED:s.mcd("Eval window closed"),EXPLOSION_REPORTED:s.mcd("Explosion Reported"),FIRE_REPORTED:s.mcd("Fire!"),FIRE_STATION_NEEDS_FUNDING:s.mcd("Fire station needs funding"),FLOODING_REPORTED:s.mcd("Flooding reported"),FRONT_END_MESSAGE:s.mcd("Front-end Message"),FUNDS_CHANGED:s.mcd("Total funds has changed"),HEAVY_TRAFFIC:s.mcd("Heavy traffic in city"),HELICOPTER_CRASHED:s.mcd("Helicopter crashed"),HIGH_CRIME:s.mcd("High crime"),HIGH_POLLUTION:s.mcd("High pollution"),MONSTER_SIGHTED:s.mcd("Monster sighted"),NAG_WINDOW_CLOSED:s.mcd("Nag window closed"),NEED_AIRPORT:s.mcd("Airport needed"),NEED_ELECTRICITY:s.mcd("More power needed"),NEED_FIRE_STATION:s.mcd("Fire station needed"),NEED_MORE_COMMERCIAL:s.mcd("More commercial zones needed"),NEED_MORE_INDUSTRIAL:s.mcd("More industrial zones needed"),NEED_MORE_RAILS:s.mcd("More railways needed"),NEED_MORE_RESIDENTIAL:s.mcd("More residential needed"),NEED_MORE_ROADS:s.mcd("More roads needed"),NEED_POLICE_STATION:s.mcd("Police station needed"),NEED_SEAPORT:s.mcd("Seaport needed"),NEED_STADIUM:s.mcd("Stadium needed"),NO_MONEY:s.mcd("No money"),NOT_ENOUGH_POWER:s.mcd("Not enough power"),NUCLEAR_MELTDOWN:s.mcd("Nuclear Meltdown"),PLANE_CRASHED:s.mcd("Plane crashed"),POLICE_NEEDS_FUNDING:s.mcd("Police need funding"),POPULATION_UPDATED:s.mcd("Population updated"),QUERY_WINDOW_CLOSED:s.mcd("Query window closed"),QUERY_WINDOW_NEEDED:s.mcd("Query window needed"),REACHED_CAPITAL:s.mcd("Now a capital"),REACHED_CITY:s.mcd("Now a city"),REACHED_METROPOLIS:s.mcd("Now a metropolis"),REACHED_MEGALOPOLIS:s.mcd("Now a megalopolis"),REACHED_TOWN:s.mcd("Now a town"),REACHED_VILLAGE:s.mcd("Now a village"),ROAD_NEEDS_FUNDING:s.mcd("Roads need funding"),SAVE_REQUESTED:s.mcd("Save requested"),SAVE_WINDOW_CLOSED:s.mcd("Save window closed"),SCORE_UPDATED:s.mcd("Score updated"),SCREENSHOT_LINK_CLOSED:s.mcd("Screenshot link closed"),SCREENSHOT_WINDOW_CLOSED:s.mcd("Screenshot window closed"),SCREENSHOT_WINDOW_REQUESTED:s.mcd("Screenshot window requested"),SETTINGS_WINDOW_CLOSED:s.mcd("Settings window closed"),SETTINGS_WINDOW_REQUESTED:s.mcd("Settings window requested"),SHIP_CRASHED:s.mcd("Shipwrecked"),SOUND_EXPLOSIONHIGH:s.mcd("Explosion! Bang!"),SOUND_EXPLOSIONLOW:s.mcd("Explosion! Bang!"),SOUND_HEAVY_TRAFFIC:s.mcd("Heavy Traffic sound"),SOUND_HONKHONK:s.mcd("HonkHonk sound"),SOUND_MONSTER:s.mcd("Monster sound"),SPEED_CHANGE:s.mcd("Speed change"),SPRITE_DYING:s.mcd("Sprite dying"),SPRITE_MOVED:s.mcd("Sprite move"),TAX_TOO_HIGH:s.mcd("Tax too high"),TOOL_CLICKED:s.mcd("Tool clicked"),TORNADO_SIGHTED:s.mcd("Tornado sighted"),TOUCH_WINDOW_CLOSED:s.mcd("Touch Window closed"),TRAFFIC_JAMS:s.mcd("Traffic jams reported"),TRAIN_CRASHED:s.mcd("Train crashed"),VALVES_UPDATED:s.mcd("Valves updated"),WELCOME:s.mcd("Welcome to micropolisJS"),WELCOMEBACK:s.mcd("Welcome back to your 3D city")};const R=Object.defineProperties({},c);var u=[R.EARTHQUAKE,R.EXPLOSION_REPORTED,R.FIRE_REPORTED,R.FLOODING_REPORTED,R.MONSTER_SIGHTED,R.NUCLEAR_MELTDOWN,R.TORNADO_SIGHTED];Object.defineProperty(R,"disasterMessages",s.mcd(u));var T=[R.HELICOPTER_CRASHED,R.PLANE_CRASHED,R.SHIP_CRASHED,R.TRAIN_CRASHED];Object.defineProperty(R,"crashes",s.mcd(T));const p=new function(){var t={};t[""+e.LEVEL_EASY]="Easy",t[""+e.LEVEL_MED]="Medium",t[""+e.LEVEL_HARD]="Hard";var i={};i[e.CC_VILLAGE]="VILLAGE",i[e.CC_TOWN]="TOWN",i[e.CC_CITY]="CITY",i[e.CC_CAPITAL]="CAPITAL",i[e.CC_METROPOLIS]="METROPOLIS",i[e.CC_MEGALOPOLIS]="MEGALOPOLIS";var s={};s[e.CRIME]="Crime",s[e.POLLUTION]="Pollution",s[e.HOUSING]="Housing",s[e.TAXES]="Taxes",s[e.TRAFFIC]="Traffic",s[e.UNEMPLOYMENT]="Unemployment",s[e.FIRE]="Fire";var a={};a[R.FIRE_STATION_NEEDS_FUNDING]="Fire departments need funding",a[R.NEED_AIRPORT]="Commerce requires an Airport",a[R.NEED_FIRE_STATION]="Citizens demand a Fire Department",a[R.NEED_ELECTRICITY]="Build a Power Plant",a[R.NEED_MORE_INDUSTRIAL]="More industrial zones needed",a[R.NEED_MORE_COMMERCIAL]="More commercial zones needed",a[R.NEED_MORE_RESIDENTIAL]="More residential zones needed",a[R.NEED_MORE_RAILS]="Inadequate rail system",a[R.NEED_MORE_ROADS]="More roads required",a[R.NEED_POLICE_STATION]="Citizens demand a Police Department",a[R.NEED_SEAPORT]="Industry requires a Sea Port",a[R.NEED_STADIUM]="Residents demand a Stadium",a[R.ROAD_NEEDS_FUNDING]="Roads deteriorating, due to lack of funds",a[R.POLICE_NEEDS_FUNDING]="Police departments need funding",a[R.WELCOME]="Welcome to 3D City",a[R.WELCOMEBACK]="Welcome to 3D City";var o={};o[R.BLACKOUTS_REPORTED]="Brownouts, build another Power Plant",o[R.COPTER_CRASHED]="A helicopter crashed ",o[R.EARTHQUAKE]="Major earthquake reported !!",o[R.EXPLOSION_REPORTED]="Explosion detected ",o[R.FLOODING_REPORTED]="Flooding reported !",o[R.FIRE_REPORTED]="Fire reported ",o[R.HEAVY_TRAFFIC]="Heavy Traffic reported",o[R.HIGH_CRIME]="Crime very high",o[R.HIGH_POLLUTION]="Pollution very high",o[R.MONSTER_SIGHTED]="A Monster has been sighted !",o[R.NO_MONEY]="YOUR CITY HAS GONE BROKE",o[R.NOT_ENOUGH_POWER]="Blackouts reported. insufficient power capacity",o[R.NUCLEAR_MELTDOWN]="A Nuclear Meltdown has occurred !!",o[R.PLANE_CRASHED]="A plane has crashed ",o[R.SHIP_CRASHED]="Shipwreck reported ",o[R.TAX_TOO_HIGH]="Citizens upset. The tax rate is too high",o[R.TORNADO_SIGHTED]="Tornado reported !",o[R.TRAFFIC_JAMS]="Frequent traffic jams reported",o[R.TRAIN_CRASHED]="A train crashed ";var r={};return r[R.REACHED_CAPITAL]="Population has reached 50,000",r[R.REACHED_CITY]="Population has reached 10,000",r[R.REACHED_MEGALOPOLIS]="Population has reached 500,000",r[R.REACHED_METROPOLIS]="Population has reached 100,000",r[R.REACHED_TOWN]="Population has reached 2,000",{badMessages:o,cityClass:i,crimeStrings:["Safe","Light","Moderate","Dangerous"],densityStrings:["Low","Medium","High","Very High"],gameLevel:t,goodMessages:r,landValueStrings:["Slum","Lower Class","Middle Class","High"],months:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],neutralMessages:a,problems:s,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\tBears 3","Draw Bridge","Ur 238"]}};class m{static pixToWorld(t){return o.pixToWorld(t)}static worldToPix(t){return o.worldToPix(t)}static turnTo(t,e){return t===e||(t<e?e-t<4?t++:t--:t-e<4?t--:t++,t>8&&(t=1),t<1&&(t=8)),t}static absoluteValue(t){return Math.abs(t)}static getTileValue(t,e,i){let s=o.pixToWorld(e),a=o.pixToWorld(i);return s<0||s>=t.width||a<0||a>=t.height?-1:t.getTileValue(s,a)}static getDir(t,i,s,a){let o,r=s-t,n=a-i;return o=r<0?n<0?11:8:n<0?2:5,r=Math.abs(r),n=Math.abs(n),2*r<n?o++:2*n<r&&o--,(o<0||o>12)&&(o=0),e.directionTable[o]}static absoluteDistance(t,e,i,s){let a=i-t,o=s-e;return Math.abs(a)+Math.abs(o)}static checkWet(t){return t===n.HPOWER||t===n.VPOWER||t===n.HRAIL||t===n.VRAIL||t===n.BRWH||t===n.BRWV}static destroyMapTile(t,e,i,s,a){let r=o.pixToWorld(s),h=o.pixToWorld(a);if(!e.testBounds(r,h))return;let l=e.getTile(r,h),d=l.getValue();d<n.TREEBASE||(l.isCombustible()?(l.isZone()&&(o.fireZone(e,r,h,i),d>n.RZB&&t.makeExplosionAt(s,a)),m.checkWet(d)?e.setTile(r,h,n.RIVER,0):e.setTile(r,h,n.TINYEXP,n.BULLBIT|n.ANIMBIT)):d>=n.ROADBASE&&d<=n.LASTROAD&&e.setTile(r,h,n.RIVER,0))}static getDistance(t,e,i,s){return Math.abs(t-i)+Math.abs(e-s)}static checkSpriteCollision(t,e){return 0!==t.frame&&0!==e.frame&&m.getDistance(t.x,t.y,e.x,e.y)<30}}class A{constructor(){}init(t,e,i,s,a){this.type=t,this.map=e,this.spriteManager=i,this.x=s,this.y=a,this.origX=0,this.origY=0,this.destX=0,this.destY=0,this.count=0,this.soundCount=0,this.dir=0,this.newDir=0,this.step=0,this.flag=0,this.turn=0,this.accel=0,this.speed=100}getFileName(){return["obj",this.type,"-",this.frame-1].join("")}spriteNotInBounds(){let t=m.pixToWorld(this.x),e=m.pixToWorld(this.y);return t<0||e<0||t>=this.map.width||e>=this.map.height}}const g={};g[e.SPRITE_TRAIN]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_TRAIN,t,i,s,a),this.width=32,this.height=32,this.xOffset=-16,this.yOffset=-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}move(t,e,i,s){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],0==(3&t)){let t=3&a.getRandom16();for(let e=t;e<t+4;e++){let t=3&e;if(this.dir!==this.CANTMOVE&&t===(this.dir+2&3))continue;let i=m.getTileValue(this.map,this.x+this.tileDeltaX[t],this.y+this.tileDeltaY[t]);if(i>=n.RAILBASE&&i<=n.LASTRAIL||i===n.RAILVPOWERH||i===n.RAILHPOWERV)return this.dir!==t&&this.dir!==this.CANTMOVE?this.dir+t===this.WEST?this.frame=this.NWSE:this.frame=this.NESW:this.frame=this.TrainPic2[t],i!==n.HRAIL&&i!==n.VRAIL||(this.frame=this.UNDERWATER),void(this.dir=t)}if(this.dir===this.CANTMOVE)return void(this.frame=0);this.dir=this.CANTMOVE}}explodeSprite(t){this.frame=0,this.spriteManager.makeExplosionAt(this.x,this.y),t.sendMessage(R.TRAIN_CRASHED)}},g[e.SPRITE_SHIP]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_SHIP,t,i,s,a),this.width=48,this.height=48,this.xOffset=-24,this.yOffset=-24,s<m.worldToPix(4)?this.frame=3:s>=m.worldToPix(t.width-4)?this.frame=7:a<m.worldToPix(4)?this.frame=5:a>=m.worldToPix(t.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=[n.RIVER,n.CHANNEL,n.POWERBASE,n.POWERBASE+1,n.RAILBASE,n.RAILBASE+1,n.BRWH,n.BRWV],this.CANTMOVE=10}move(t,e,i,s){let o,r,h,l,d,E,c=n.RIVER;if(this.soundCount>0&&this.soundCount--,0===this.soundCount&&(1==(3&a.getRandom16())&&e.sendMessage(R.SOUND_HONKHONK),this.soundCount=200),this.count>0&&this.count--,0===this.count){if(this.count=9,this.frame!==this.newDir)return void(this.frame=m.turnTo(this.frame,this.newDir));for(o=7&a.getRandom16(),r=this.frame,h=o;h<o+8;h++)if(r=1+(7&h),r!==this.dir&&(l=m.pixToWorld(this.x)+this.tileDeltaX[r],d=m.pixToWorld(this.y)+this.tileDeltaY[r],this.map.testBounds(l,d)&&(E=this.map.getTileValue(l,d),E===n.CHANNEL||E===n.BRWH||E===n.BRWV||this.oppositeAndUnderwater(E,this.dir,r)))){this.newDir=r,this.frame=m.turnTo(this.frame,this.newDir),this.dir=r+4,this.dir>8&&(this.dir-=8);break}h===o+8&&(this.dir=this.CANTMOVE,this.newDir=1+(7&a.getRandom16()))}else r=this.frame,r===this.newDir&&(this.x+=this.xDelta[r],this.y+=this.yDelta[r]);if(this.spriteNotInBounds())this.frame=0;else for(let t=0;t<8&&c!==this.tileWhiteList[t];t++)7===t&&(this.explodeSprite(e),m.destroyMapTile(this.spriteManager,this.map,s,this.x,this.y))}explodeSprite(t){this.frame=0,this.spriteManager.makeExplosionAt(this.x,this.y),t.sendMessage(R.SHIP_CRASHED)}oppositeAndUnderwater(t,e,i){let s=e+4;return s>8&&(s-=8),i==s&&(t==n.POWERBASE||t==n.POWERBASE+1||t==n.RAILBASE||t==n.RAILBASE+1)}},g[e.SPRITE_MONSTER]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_MONSTER,t,i,s,a),this.width=48,this.height=48,this.xOffset=-24,this.yOffset=-24,s>m.worldToPix(t.width)/2?a>m.worldToPix(t.height)/2?this.frame=10:this.frame=7:a>m.worldToPix(t.height)/2?this.frame=1:this.frame=4,this.flag=0,this.count=1e3,this.destX=m.worldToPix(t.pollutionMaxX),this.destY=m.worldToPix(t.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]}move(t,i,s,o){this.soundCount>0&&this.soundCount--;let r,h,l=Math.floor((this.frame-1)/3);if(l<4){if(r=(this.frame-1)%3,2===r&&(this.step=0),0===r&&(this.step=1),this.step?r++:r--,m.absoluteDistance(this.x,this.y,this.destX,this.destY)<60){if(0!==this.flag)return void(this.frame=0);this.flag=1,this.destX=this.origX,this.destY=this.origY}h=m.getDir(this.x,this.y,this.destX,this.destY),h=Math.floor((h-1)/2),h!==l&&a.getChance(10)&&(r=1&a.getRandom16()?this.cardinals1[l]:this.cardinals2[l],l=4,this.soundCount||(i.sendMessage(R.SOUND_MONSTER),this.soundCount=50+a.getRandom(100)))}else l=4,h=this.frame,r=h-13&3,3&a.getRandom16()||(r=1&a.getRandom16()?this.diagonals1[r]:this.diagonals2[r],l=Math.floor((r-1)/3),r=(r-1)%3);r=3*l+r+1,r>16&&(r=16),this.frame=r,this.x+=this.xDelta[l],this.y+=this.yDelta[l],this.count>0&&this.count--;let d=m.getTileValue(this.map,this.x,this.y);(-1===d||d===n.RIVER&&this.count<500)&&(this.frame=0),(d===n.DIRT||d>n.WATER_HIGH)&&(this._seenLand=!0);let E=this.spriteManager.getSpriteList();for(let t=0;t<E.length;t++){let s=E[t];0===s.frame||s.type!==e.SPRITE_AIRPLANE&&s.type!==e.SPRITE_HELICOPTER&&s.type!==e.SPRITE_SHIP&&s.type!==e.SPRITE_TRAIN||!m.checkSpriteCollision(this,s)||s.explodeSprite(i)}m.destroyMapTile(this.spriteManager,this.map,o,this.x,this.y)}},g[e.SPRITE_HELICOPTER]=class extends A{constructor(t,i,s,o){super(),this.init(e.SPRITE_HELICOPTER,t,i,s,o),this.width=32,this.height=32,this.xOffset=-16,this.yOffset=-16,this.frame=5,this.count=1500,this.destX=a.getRandom(m.worldToPix(t.width))+8,this.destY=a.getRandom(m.worldToPix(t.height))+8,this.origX=s,this.origY=o,this.xDelta=[0,0,3,5,3,0,-3,-5,-3],this.yDelta=[0,-5,-3,0,3,5,3,0,-3]}move(t,i,s,o){if(this.soundCount>0&&this.soundCount--,this.count>0&&this.count--,0===this.count){let t=this.spriteManager.getSprite(e.SPRITE_MONSTER);if(null!==t?(this.destX=t.x,this.destY=t.y):(t=this.spriteManager.getSprite(e.SPRITE_TORNADO),null!==t?(this.destX=t.x,this.destY=t.y):(this.destX=this.origX,this.destY=this.origY)),m.absoluteDistance(this.x,this.y,this.origX,this.origY)<30)return void(this.frame=0)}if(0===this.soundCount){let t=m.pixToWorld(this.x),e=m.pixToWorld(this.y);t>=0&&t<this.map.width&&e>=0&&e<this.map.height&&o.trafficDensityMap.worldGet(t,e)>170&&0==(7&a.getRandom16())&&(i.sendMessage(R.HEAVY_TRAFFIC,{x:t,y:e}),i.sendMessage(R.SOUND_HEAVY_TRAFFIC),this.soundCount=200)}let r=this.frame;if(0==(3&t)){let t=m.getDir(this.x,this.y,this.destX,this.destY);r=m.turnTo(r,t),this.frame=r}this.x+=this.xDelta[r],this.y+=this.yDelta[r]}explodeSprite(t){this.frame=0,this.spriteManager.makeExplosionAt(this.x,this.y),t.sendMessage(R.HELICOPTER_CRASHED)}},g[e.SPRITE_AIRPLANE]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_AIRPLANE,t,i,s,a),this.width=48,this.height=48,this.xOffset=-24,this.yOffset=-24,s>m.worldToPix(t.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]}move(t,i,s,o){let r=this.frame;if(t%5==0)if(r>8)r--,r<9&&(r=3),this.frame=r;else{let t=m.getDir(this.x,this.y,this.destX,this.destY);r=m.turnTo(r,t),this.frame=r}if(m.absoluteDistance(this.x,this.y,this.destX,this.destY)<50&&(this.destX=a.getRandom(m.worldToPix(this.map.width))+8,this.destY=a.getRandom(m.worldToPix(this.map.height))+8),s.enableDisasters){let t=!1,s=this.spriteManager.getSpriteList();for(let a=0;a<s.length;a++){let o=s[a];0!==o.frame&&(o.type!==e.SPRITE_HELICOPTER&&o.type!==e.SPRITE_AIRPLANE||!m.checkSpriteCollision(this,o)||(o.explodeSprite(i),t=!0))}t&&this.explodeSprite(i)}this.x+=this.xDelta[r],this.y+=this.yDelta[r],this.spriteNotInBounds()&&(this.frame=0)}explodeSprite(t){this.frame=0,this.spriteManager.makeExplosionAt(this.x,this.y),t.sendMessage(R.PLANE_CRASHED)}},g[e.SPRITE_TORNADO]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_TORNADO,t,i,s,a),this.width=48,this.height=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]}move(t,i,s,a){let o;o=this.frame,2===o?o=this.flag?3:1:(this.flag=1===o?1:0,o=2),this.count>0&&this.count--,this.frame=o;let r=this.spriteManager.getSpriteList();for(let t=0;t<r.length;t++){let s=r[t];0===s.frame||s.type!==e.SPRITE_AIRPLANE&&s.type!==e.SPRITE_HELICOPTER&&s.type!==e.SPRITE_SHIP&&s.type!==e.SPRITE_TRAIN||!m.checkSpriteCollision(this,s)||s.explodeSprite(i)}o=Random.getRandom(5),this.x+=this.xDelta[o],this.y+=this.yDelta[o],this.spriteNotInBounds()&&(this.frame=0),0!==this.count&&0===Random.getRandom(500)&&(this.frame=0),m.destroyMapTile(this.spriteManager,this.map,a,this.x,this.y)}},g[e.SPRITE_EXPLOSION]=class extends A{constructor(t,i,s,a){super(),this.init(e.SPRITE_EXPLOSION,t,i,s,a),this.width=48,this.height=48,this.xOffset=-24,this.yOffset=-24,this.frame=1}startFire(t,e){if(t=o.pixToWorld(t),e=o.pixToWorld(e),!this.map.testBounds(t,e))return;let i=this.map.getTile(t,e),s=i.getValue();(i.isCombustible()||s===n.DIRT)&&(i.isZone()||this.map.setTo(t,e,o.randomFire()))}move(t,e,i,s){if(0==(1&t)){if(1===this.frame){let t=o.pixToWorld(this.x),i=o.pixToWorld(this.y);e.sendMessage(R.SOUND_EXPLOSIONHIGH),e.sendMessage(R.EXPLOSION_REPORTED,{x:t,y:i})}this.frame++}this.frame>6&&(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))}};class f{constructor(t){this.spriteList=[],this.map=t,this.spriteCycle=0}getSprite(t){let e=this.spriteList.filter((function(e){return 0!==e.frame&&e.type===t}));return 0===e.length?null:e[0]}getSpriteList(){return this.spriteList.slice()}getSpritesInView(t,e,i,s){return t=m.worldToPix(t),e=m.worldToPix(e),i=m.worldToPix(i),s=m.worldToPix(s),this.spriteList.filter((function(a){return a.x+a.xOffset>=t&&a.y+a.yOffset>=e&&!(a.x+a.xOffset>=i&&a.y+a.yOffset>=s)}))}moveObjects(t){t||(t=e.simData);let i=t.messageManager,s=t.disasterManager,a=t.blockMaps;this.spriteCycle+=1;let o=this.spriteList.slice(),r=o.length;for(;r--;){let t=o[r];0!==t.frame&&t.move(this.spriteCycle,i,s,a)}this.pruneDeadSprites()}makeSprite(t,e,i){this.spriteList.push(new g[t](this.map,this,e,i))}makeTornado(t){let i=this.getSprite(e.SPRITE_TORNADO);if(null!==i)return void(i.count=200);let s=a.getRandom(m.worldToPix(this.map.width)-800)+400,o=a.getRandom(m.worldToPix(this.map.height)-200)+100;this.makeSprite(e.SPRITE_TORNADO,s,o),t.sendMessage(R.TORNADO_SIGHTED,{x:m.pixToWorld(s),y:m.pixToWorld(o)})}makeExplosion(t,e){this.map.testBounds(t,e)&&this.makeExplosionAt(m.worldToPix(t),m.worldToPix(e))}makeExplosionAt(t,i){this.makeSprite(e.SPRITE_EXPLOSION,t,i)}generatePlane(t,i){null===this.getSprite(e.SPRITE_AIRPLANE)&&this.makeSprite(e.SPRITE_AIRPLANE,m.worldToPix(t),m.worldToPix(i))}generateTrain(t,i,s){t.totalPop>20&&null===this.getSprite(e.SPRITE_TRAIN)&&0===a.getRandom(25)&&this.makeSprite(e.SPRITE_TRAIN,m.worldToPix(i)+8,m.worldToPix(s)+8)}generateShip(){let t,e;if(a.getChance(3))for(t=4;t<this.map.width-2;t++)if(this.map.getTileValue(t,0)===n.CHANNEL)return void this.makeShipHere(t,0);if(a.getChance(3))for(e=1;e<this.map.height-2;e++)if(this.map.getTileValue(0,e)===n.CHANNEL)return void this.makeShipHere(0,e);if(a.getChance(3))for(t=4;t<this.map.width-2;t++)if(this.map.getTileValue(t,this.map.height-1)===n.CHANNEL)return void this.makeShipHere(t,this.map.height-1);if(a.getChance(3))for(e=1;e<this.map.height-2;e++)if(this.map.getTileValue(this.map.width-1,e)===n.CHANNEL)return void this.makeShipHere(this.map.width-1,e)}getBoatDistance(t,i){let s,a=99999,o=m.worldToPix(t)+8,r=m.worldToPix(i)+8;for(let t=0,i=this.spriteList.length;t<i;t++)if(s=this.spriteList[t],s.type===e.SPRITE_SHIP&&0!==s.frame){let t=Math.abs(s.x-o)+Math.abs(s.y-r);a=Math.min(a,t)}return a}makeShipHere(t,i){this.makeSprite(e.SPRITE_SHIP,m.worldToPix(t),m.worldToPix(i))}generateCopter(t,i){null===this.getSprite(e.SPRITE_HELICOPTER)&&this.makeSprite(e.SPRITE_HELICOPTER,m.worldToPix(t),m.worldToPix(i))}makeMonsterAt(t,i,s){this.makeSprite(e.SPRITE_MONSTER,m.worldToPix(i),m.worldToPix(s)),t.sendMessage(R.MONSTER_SIGHTED,{x:i,y:s})}makeMonster(t){let i=this.getSprite(e.SPRITE_MONSTER);null!==i&&(i.soundCount=1,i.count=1e3,i.destX=m.worldToPix(this.map.pollutionMaxX),i.destY=m.worldToPix(this.map.pollutionMaxY));let s=0;for(let e=0;e<300;e++){let e=a.getRandom(this.map.width-20)+10,i=a.getRandom(this.map.height-10)+5;if(this.map.getTile(e,i).getValue()===n.RIVER){this.makeMonsterAt(t,e,i),s=1;break}}0===s&&this.makeMonsterAt(t,60,50)}pruneDeadSprites(t){this.spriteList=this.spriteList.filter((function(t){return 0!==t.frame}))}}class O{static getTrafficAverage(t,e){for(var i=t.trafficDensityMap,s=t.landValueMap,a=0,o=1,r=0;r<s.gameMapWidth;r+=s.blockSize)for(var n=0;n<s.gameMapHeight;n+=s.blockSize)s.worldGet(r,n)>0&&(a+=i.worldGet(r,n),o++);return 2.4*Math.floor(a/o)}static getUnemployment(t){var e=8*(t.comPop+t.indPop);if(0===e)return 0;var i=t.resPop/e;return e=Math.round(255*(i-1)),Math.min(e,255)}static getFireSeverity(t){return Math.min(5*t.firePop,255)}}class S{constructor(t){this.problemVotes=[],this.problemOrder=[],this.evalInit(),this.gameLevel=""+t,this.changed=!1}save(t){for(var i=0,s=e.EvalProps.length;i<s;i++)t[e.EvalProps[i]]=this[e.EvalProps[i]]}load(t){for(var i=0,s=e.EvalProps.length;i<s;i++)this[e.EvalProps[i]]=t[e.EvalProps[i]]}cityEvaluation(t){t||(t=e.simData);var i=t.census;if(i.totalPop>0){e.problemData=[];for(var s=0;s<e.NUMPROBLEMS;s++)e.problemData.push(0);this.getAssessedValue(i),this.getPopulation(i),this.doProblems(t.census,t.budget,t.blockMaps),this.getScore(t),this.doVotes(),this.changeEval()}else this.evalInit(),this.cityYes=50,this.changeEval()}evalInit(){let t;for(this.cityYes=0,this.cityPop=0,this.cityPopDelta=0,this.cityAssessedValue=0,this.cityClass=e.CC_VILLAGE,this.cityClassLast=e.CC_VILLAGE,this.cityScore=500,this.cityScoreDelta=0,t=0;t<e.NUMPROBLEMS;t++)this.problemVotes[t]={index:t,voteCount:0};for(t=0;t<e.NUM_COMPLAINTS;t++)this.problemOrder[t]=e.NUMPROBLEMS}getAssessedValue(t){var e;e=5*t.roadTotal,e+=10*t.railTotal,e+=1e3*t.policeStationPop,e+=1e3*t.fireStationPop,e+=400*t.hospitalPop,e+=3e3*t.stadiumPop,e+=5e3*t.seaportPop,e+=1e4*t.airportPop,e+=3e3*t.coalPowerPop,e+=6e3*t.nuclearPowerPop,this.cityAssessedValue=1e3*e}getPopulation(t){let e=this.cityPop;return this.cityPop=20*(t.resPop+8*(t.comPop+t.indPop)),this.cityPopDelta=this.cityPop-e,0!==this.cityPopDelta&&i.emitEvent(R.POPULATION_UPDATED,this.cityPop),this.cityPop}getCityClass(t){return this.cityClass=e.CC_VILLAGE,t>2e3&&(this.cityClass=e.CC_TOWN),t>1e4&&(this.cityClass=e.CC_CITY),t>5e4&&(this.cityClass=e.CC_CAPITAL),t>1e5&&(this.cityClass=e.CC_METROPOLIS),t>5e5&&(this.cityClass=e.CC_MEGALOPOLIS),this.cityClass!==this.cityClassLast&&(this.cityClassLast=this.cityClass,i.emitEvent(R.CLASSIFICATION_UPDATED,this.cityClass)),this.cityClass}voteProblems(){for(var t=0;t<e.NUMPROBLEMS;t++)this.problemVotes[t].index=t,this.problemVotes[t].voteCount=0;for(var i=0,s=0,o=0;s<100&&o<600;){var r=a.getRandom(300);e.problemData[i]>r&&(this.problemVotes[i].voteCount+=1,s++),i=(i+1)%e.NUMPROBLEMS,o++}}doProblems(t,i,s){e.problemData[e.CRIME]=t.crimeAverage,e.problemData[e.POLLUTION]=t.pollutionAverage,e.problemData[e.HOUSING]=7*t.landValueAverage/10,e.problemData[e.TAXES]=10*i.cityTax,e.problemData[e.TRAFFIC]=O.getTrafficAverage(s,t),e.problemData[e.UNEMPLOYMENT]=O.getUnemployment(t),e.problemData[e.FIRE]=O.getFireSeverity(t),this.voteProblems(),this.problemVotes.sort((function(t,e){return e.voteCount-t.voteCount})),this.problemOrder=this.problemVotes.map((function(t,i){return i>=e.NUM_COMPLAINTS||0===t.voteCount?null:t.index}))}getScore(t){var s,o=t.census,r=t.budget,n=t.valves;s=this.cityScore;for(var h=0,l=0;l<e.NUMPROBLEMS;l++)h+=e.problemData[l];h=Math.floor(h/3),h=4*(250-Math.min(h,250));let d=.85;n.resCap&&(h=Math.round(h*d)),n.comCap&&(h=Math.round(h*d)),n.indCap&&(h=Math.round(h*d)),r.roadEffect<r.MAX_ROAD_EFFECT&&(h-=r.MAX_ROAD_EFFECT-r.roadEffect),r.policeEffect<r.MAX_POLICE_STATION_EFFECT&&(h=Math.round(h*(.9+r.policeEffect/(10*r.MAX_POLICE_STATION_EFFECT)))),r.fireEffect<r.MAX_FIRE_STATION_EFFECT&&(h=Math.round(h*(.9+r.fireEffect/(10*r.MAX_FIRE_STATION_EFFECT)))),n.resValve<-1e3&&(h=Math.round(.85*h)),n.comValve<-1e3&&(h=Math.round(.85*h)),n.indValve<-1e3&&(h=Math.round(.85*h));var E=1;0===this.cityPop||0===this.cityPopDelta||this.cityPopDelta===this.cityPop?E=1:this.cityPopDelta>0?E=this.cityPopDelta/this.cityPop+1:this.cityPopDelta<0&&(E=.95+Math.floor(this.cityPopDelta/(this.cityPop-this.cityPopDelta))),h=(h=Math.round(h*E))-O.getFireSeverity(o)-r.cityTax,(E=o.unpoweredZoneCount+o.poweredZoneCount)>0&&(h=Math.round(h*(o.poweredZoneCount/E))),h=a.clamp(h,0,1e3),this.cityScore=Math.round((this.cityScore+h)/2),this.cityScoreDelta=this.cityScore-s,0!==this.cityScoreDelta&&i.emitEvent(R.SCORE_UPDATED,this.cityScore)}doVotes(){this.cityYes=0;for(let t=0;t<100;t++){let t=a.getRandom(1e3);this.cityScore>t&&this.cityYes++}}changeEval(){this.changed=!0}countProblems(){var t;for(t=0;t<e.NUM_COMPLAINTS&&this.problemOrder[t]!==e.NUMPROBLEMS;t++);return t}getProblemNumber(t){return t<0||t>=e.NUM_COMPLAINTS||this.problemOrder[t]===e.NUMPROBLEMS?-1:this.problemOrder[t]}getProblemVotes(t){return t<0||t>=e.NUM_COMPLAINTS||this.problemOrder[t]==e.NUMPROBLEMS?-1:this.problemVotes[this.problemOrder[t]].voteCount}}class I{constructor(){this.resValve=0,this.comValve=0,this.indValve=0,this.resCap=!1,this.comCap=!1,this.indCap=!1}save(t){t.resValve=this.resValve,t.comValve=this.comValve,t.indValve=this.indValve}load(t){this.resValve=t.resValve,this.comValve=t.comValve,this.indValve=t.indValve,i.emitEvent(R.VALVES_UPDATED,{residential:this.resValve,commercial:this.comValve,industrial:this.indValve})}setValves(t,s,o){var r,n=s.resPop/8;s.totalPop=Math.round(n+s.comPop+s.indPop);var h=n+n*((s.resPop>0?(s.comHist10[1]+s.indHist10[1])/n:1)-1)+.02*n;r=(r=s.comHist10[1]+s.indHist10[1])>0?s.resHist10[1]/r:1,r=a.clamp(r,0,1.3);var l,d,E,c=(n+s.comPop+s.indPop)/3.7*r,u=s.indPop*r*e.extMarketParamTable[t];u=Math.max(u,5),l=n>0?h/n:1.3,d=s.comPop>0?c/s.comPop:c,E=s.indPop>0?u/s.indPop:u,l=Math.min(l,2),d=Math.min(d,2),E=Math.min(E,2);var T=Math.min(o.cityTax+t,20);l=600*(l-1)+e.taxTable[T],d=600*(d-1)+e.taxTable[T],E=600*(E-1)+e.taxTable[T],this.resValve=a.clamp(this.resValve+Math.round(l),-e.RES_VALVE_RANGE,e.RES_VALVE_RANGE),this.comValve=a.clamp(this.comValve+Math.round(d),-e.COM_VALVE_RANGE,e.COM_VALVE_RANGE),this.indValve=a.clamp(this.indValve+Math.round(E),-e.IND_VALVE_RANGE,e.IND_VALVE_RANGE),this.resCap&&this.resValve>0&&(this.resValve=0),this.comCap&&this.comValve>0&&(this.comValve=0),this.indCap&&this.indValve>0&&(this.indValve=0),i.emitEvent(R.VALVES_UPDATED,{residential:this.resValve,commercial:this.comValve,industrial:this.indValve})}}class L{constructor(){this.roadEffect=e.MAX_ROAD_EFFECT,this.policeEffect=e.MAX_POLICESTATION_EFFECT,this.fireEffect=e.MAX_FIRESTATION_EFFECT,this.totalFunds=0,this.cityTax=7,this.cashFlow=0,this.taxFund=0,this.roadMaintenanceBudget=0,this.fireMaintenanceBudget=0,this.policeMaintenanceBudget=0,this.roadPercent=1,this.firePercent=1,this.policePercent=1,this.roadSpend=0,this.fireSpend=0,this.policeSpend=0,this.awaitingValues=!1,this.autoBudget=!0}save(t){for(var i=0,s=e.BudgetProps.length;i<s;i++)t[e.BudgetProps[i]]=this[e.BudgetProps[i]]}load(t){for(var s=0,a=e.BudgetProps.length;s<a;s++)this[e.BudgetProps[s]]=t[e.BudgetProps[s]];i.emitEvent(R.AUTOBUDGET_CHANGED,this.autoBudget),i.emitEvent(R.FUNDS_CHANGED,this.totalFunds)}setAutoBudget(t){this.autoBudget=t,i.emitEvent(R.AUTOBUDGET_CHANGED,this.autoBudget)}_calculateBestPercentages(){if(this.roadSpend=Math.round(this.roadMaintenanceBudget*this.roadPercent),this.fireSpend=Math.round(this.fireMaintenanceBudget*this.firePercent),this.policeSpend=Math.round(this.policeMaintenanceBudget*this.policePercent),0===this.roadSpend+this.fireSpend+this.policeSpend)return this.roadPercent=1,this.firePercent=1,this.policePercent=1,{road:1,fire:1,police:1};var t=0,e=0,i=0,s=this.totalFunds+this.taxFund;return s-=t=s>=this.roadSpend?this.roadSpend:s,s-=e=s>=this.fireSpend?this.fireSpend:s,s-=i=s>=this.policeSpend?this.policeSpend:s,this.roadMaintenanceBudget>0?this.roadPercent=(t/this.roadMaintenanceBudget).toPrecision(2)-0:this.roadPercent=1,this.fireMaintenanceBudget>0?this.firePercent=(e/this.fireMaintenanceBudget).toPrecision(2)-0:this.firePercent=1,this.policeMaintenanceBudget>0?this.policePercent=(i/this.policeMaintenanceBudget).toPrecision(2)-0:this.policePercent=1,{road:t,police:i,fire:e}}doBudgetWindow(){return this.doBudgetNow(!0)}doBudgetNow(t){var e=this._calculateBestPercentages();if(!this.autoBudget&&!t)return this.autoBudget=!1,this.awaitingValues=!0,void i.emitEvent(R.BUDGET_NEEDED);var s=e.road,a=e.police,o=e.fire,r=s+a+o;if(this.totalFunds+this.taxFund-r>0&&this.autoBudget||t)return this.awaitingValues=!1,void this.doBudgetSpend(s,o,a);this.setAutoBudget(!1),this.awaitingValues=!0,i.emitEvent(R.BUDGET_NEEDED),i.emitEvent(R.NO_MONEY)}doBudgetSpend(t,e,i){this.roadSpend=t,this.fireSpend=e,this.policeSpend=i;var s=this.roadSpend+this.fireSpend+this.policeSpend;this.spend(-(this.taxFund-s)),this.updateFundEffects()}updateFundEffects(){this.roadSpend=Math.round(this.roadMaintenanceBudget*this.roadPercent),this.fireSpend=Math.round(this.fireMaintenanceBudget*this.firePercent),this.policeSpend=Math.round(this.policeMaintenanceBudget*this.policePercent),this.roadEffect=e.MAX_ROAD_EFFECT,this.policeEffect=e.MAX_POLICESTATION_EFFECT,this.fireEffect=e.MAX_FIRESTATION_EFFECT,this.roadMaintenanceBudget>0&&(this.roadEffect=Math.floor(this.roadEffect*this.roadSpend/this.roadMaintenanceBudget)),this.fireMaintenanceBudget>0&&(this.fireEffect=Math.floor(this.fireEffect*this.fireSpend/this.fireMaintenanceBudget)),this.policeMaintenanceBudget>0&&(this.policeEffect=Math.floor(this.policeEffect*this.policeSpend/this.policeMaintenanceBudget))}collectTax(t,i){this.cashFlow=0,this.policeMaintenanceBudget=i.policeStationPop*e.policeMaintenanceCost,this.fireMaintenanceBudget=i.fireStationPop*e.fireMaintenanceCost;var s=i.roadTotal*e.roadMaintenanceCost,a=i.railTotal*e.railMaintenanceCost;this.roadMaintenanceBudget=Math.floor((s+a)*e.RLevels[t]),this.taxFund=Math.floor(Math.floor(i.totalPop*i.landValueAverage/120)*this.cityTax*e.FLevels[t]),i.totalPop>0?(this.cashFlow=this.taxFund-(this.policeMaintenanceBudget+this.fireMaintenanceBudget+this.roadMaintenanceBudget),this.doBudgetNow(!1)):(this.roadEffect=e.MAX_ROAD_EFFECT,this.policeEffect=e.MAX_POLICESTATION_EFFECT,this.fireEffect=e.MAX_FIRESTATION_EFFECT)}setTax(t){t!==this.cityTax&&(this.cityTax=t)}setFunds(t){t!==this.totalFunds&&(this.totalFunds=Math.max(0,t),i.emitEvent(R.FUNDS_CHANGED,this.totalFunds),0===this.totalFunds&&i.emitEvent(R.NO_MONEY))}spend(t){this.setFunds(this.totalFunds-t)}shouldDegradeRoad(){return this.roadEffect<Math.floor(15*this.MAX_ROAD_EFFECT/16)}}class D{constructor(){this.clearCensus(),this.changed=!1,this.crimeRamp=0,this.pollutionRamp=0,this.landValueAverage=0,this.pollutionAverage=0,this.crimeAverage=0,this.totalPop=0;var t=function(t){this[t]=[];for(var e=120;e--;)this[t][e]=0};let i=e.arrs.length;for(;i--;){var s=e.arrs[i]+"Hist10",a=e.arrs[i]+"Hist120";t.call(this,s),t.call(this,a)}}save(t){for(var i=0,s=e.CensusProps.length;i<s;i++)t[e.CensusProps[i]]=this[e.CensusProps[i]]}load(t){for(var i=0,s=e.CensusProps.length;i<s;i++)this[e.CensusProps[i]]=t[e.CensusProps[i]]}clearCensus(){this.poweredZoneCount=0,this.unpoweredZoneCount=0,this.firePop=0,this.roadTotal=0,this.railTotal=0,this.resPop=0,this.comPop=0,this.indPop=0,this.resZonePop=0,this.comZonePop=0,this.indZonePop=0,this.hospitalPop=0,this.churchPop=0,this.policeStationPop=0,this.fireStationPop=0,this.stadiumPop=0,this.coalPowerPop=0,this.nuclearPowerPop=0,this.seaportPop=0,this.airportPop=0}take10Census(t){s.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);var e=Math.floor(t.cashFlow/20)+128;this.moneyHist10[0]=a.clamp(e,0,255),this.resPop,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(){s.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}}class _{constructor(t,e,i){if(void 0===t||void 0===e||void 0===i)throw new Error("Invalid dimensions for block map");this.isBlockMap=!0,this.blockSize=i,this.gameMapWidth=t,this.gameMapHeight=e,this.width=Math.floor((t+i-1)/i),this.height=Math.floor((e+i-1)/i),this.data=[],this.clear()}clear(){let t,e=this.height;for(;e--;)for(t=this.width;t--;)this.data[this.width*e+t]=0}copyFrom(t,e){t.width===this.width&&t.height===this.height&&t.blockSize===this.blockSize||console.warn("Copying from incompatible blockMap!");let i,s,a=t.height,o=t.width;for(s=0;s<a;s++)for(i=0;i<o;i++)this.data[o*s+i]=e(t.data[o*s+i])}get(t,e){return this.data[this.width*e+t]}set(t,e,i){this.data[this.width*e+t]=i}toBlock(t){return Math.floor(t/this.blockSize)}worldGet(t,e){return this.get(this.toBlock(t),this.toBlock(e))}worldSet(t,e,i){this.set(this.toBlock(t),this.toBlock(e),i)}}const P={INVALID:-1,NORTH:0,NORTHEAST:1,EAST:2,SOUTHEAST:3,SOUTH:4,SOUTHWEST:5,WEST:6,NORTHWEST:7,BEGIN:0,END:8,increment45:function(t,e){if(arguments.length<1)throw new TypeError;return t==P.INVALID?t:(e||0===e||(e=1),t+e)},increment90:function(t){if(arguments.length<1)throw new TypeError;return P.increment45(t,2)},rotate45:function(t,e){if(arguments.length<1)throw new TypeError;return t==P.INVALID?t:(e||0===e||(e=1),(t-P.NORTH+e&7)+P.NORTH)},rotate90:function(t){if(arguments.length<1)throw new TypeError;return P.rotate45(t,2)},rotate180:function(t){if(arguments.length<1)throw new TypeError;return P.rotate45(t,4)}};class M{constructor(t,i,s){if(this.isPosition=!0,this.width=e.MAP_WIDTH,this.height=e.MAP_HEIGHT,this.x=0,this.y=0,this.validDirs=[P.NORTH,P.NORTHEAST,P.EAST,P.SOUTHEAST,P.SOUTH,P.SOUTHWEST,P.WEST,P.NORTHWEST,P.INVALID],0===arguments.length)return this;if(1===arguments.length&&!t.isPosition)throw new Error("Position constructor called with invalid pos "+t);if(3===arguments.length&&!t.isPosition)throw new Error("Position constructor called with invalid pos "+t);if(!(3!==arguments.length||this.isNumber(i)&&this.isNumber(s)))throw new Error("Position constructor called with invalid deltas "+i+" "+s);if(2===arguments.length&&this.isNumber(t)&&!this.isNumber(i))throw new Error("Position constructor called with invalid y coordinate "+t+" "+i);if(2===arguments.length&&t.isPosition&&(!this.isNumber(i)||!this.isDirection(i)))throw new Error("Position constructor called with invalid direction "+t+" "+i);if(2===arguments.length&&!this.isNumber(t)&&!t.isPosition)throw new Error("Position constructor called with bad existing position "+t+" "+i);let a=!0;if(this.isNumber(t)?(this.x=t,this.y=i):(this.set(t),2===arguments.length?a=this.move(i):3===arguments.length&&(this.x+=i,this.y+=s)),this.x<0||this.x>=this.width||this.y<0||this.y>=this.height||!a)throw new Error("Invalid parameter")}isNumber(t){return!isNaN(t)}isDirection(t){return this.isNumber(t)&&-1!==this.validDirs.indexOf(t)}set(t){this.x=t.x,this.y=t.y}toString(){return"("+this.x+", "+this.y+")"}toInt(){return this.y*this.width+this.x}move(t){let e=!1;switch(t){case P.INVALID:return!0;case P.NORTH:this.y>0&&(this.y--,e=!0);break;case P.NORTHEAST:this.y>0&&this.x<this.width-1&&(this.y--,this.x++,e=!0);break;case P.EAST:this.x<this.width-1&&(this.x++,e=!0);break;case P.SOUTHEAST:this.y<this.height-1&&this.x<this.width-1&&(this.x++,this.y++,e=!0);break;case P.SOUTH:this.y<this.height-1&&(this.y++,e=!0);break;case P.SOUTHWEST:this.y<this.height-1&&this.x>0&&(this.y++,this.x--,e=!0);break;case P.WEST:this.x>0&&(this.x--,e=!0);break;case P.NORTHWEST:this.y>0&&this.x>0&&(this.y--,this.x--,e=!0)}return e}}class N{constructor(t){this._map=t,this._powerStack=[],this.powerGridMap=new _(this._map.width,this._map.height,1,0)}setTilePower(t,e){var i=this._map.getTile(t,e),s=i.getValue();s===n.NUCLEAR||s===n.POWERPLANT||this.powerGridMap.worldGet(t,e)>0?i.addFlags(n.POWERBIT):i.removeFlags(n.POWERBIT)}clearPowerStack(){this._powerStackPointer=0,this._powerStack=[]}testForConductive(t,e){var i=new M(t);return!(!i.move(e)||!this._map.getTile(i.x,i.y).isConductive()||0!==this.powerGridMap.worldGet(i.x,i.y))}doPowerScan(t){this.powerGridMap.clear();let s=t.coalPowerPop*e.COAL_POWER_STRENGTH+t.nuclearPowerPop*e.NUCLEAR_POWER_STRENGTH,a=0;for(;this._powerStack.length>0;){var o,r=this._powerStack.pop(),n=P.INVALID;do{if(a++,a>s)return void i.emitEvent(R.NOT_ENOUGH_POWER);n!==P.INVALID&&r.move(n),this.powerGridMap.worldSet(r.x,r.y,1),o=0;for(var h=P.BEGIN;h<P.END&&o<2;)this.testForConductive(r,h)&&(o++,n=h),h=P.increment90(h);o>1&&this._powerStack.push(new M(r))}while(o)}}coalPowerFound(t,i,s,a){a||(a=e.simData),a.census.coalPowerPop+=1,this._powerStack.push(new M(i,s));var o=[-1,2,1,2],r=[-1,-1,0,0];if(!a.is3D)for(var h=0;h<4;h++)t.addTileFlags(i+o[h],s+r[h],n.ANIMBIT)}nuclearPowerFound(t,i,s,o){o||(o=e.simData);if(!(o.disasterManager.disastersEnabled&&0===a.getRandom([3e4,2e4,1e4][o.gameLevel])||(o.census.nuclearPowerPop+=1,this._powerStack.push(new M(i,s)),o.is3D)))for(var r=0;r<4;r++)t.addTileFlags(i,s,n.ANIMBIT|n.CONDBIT|n.POWERBIT|n.BURNBIT)}registerHandlers(t,e){t.addAction(n.POWERPLANT,this.coalPowerFound.bind(this)),t.addAction(n.NUCLEAR,this.nuclearPowerFound.bind(this)),e.addAction(n.POWERPLANT,7,4),e.addAction(n.NUCLEAR,7,4)}}class C{constructor(t){this._map=t,this._actions=[]}addAction(t,e){this._actions.push({criterion:t,action:e})}mapScan(t,i,a){a||(a=e.simData);let o,h,l,d,E,c,R,u=this._map.height;for(;u--;)for(o=t;o<i;o++)if(l=this._map.getId(o,u),d=this._map.data[l]||new r,E=d.getValue(),!(E<n.FLOOD))for(d.isConductive()&&a.powerManager.setTilePower(o,u),d.isZone()&&(a.repairManager.checkTile(o,u,a.cityTime),d.isPowered()?(a.census.poweredZoneCount+=1,this._map.powered({v:1,id:l})):(a.census.unpoweredZoneCount+=1,this._map.powered({v:2,id:l}))),h=this._actions.length;h--;){if(c=this._actions[h],R=s.isCallable(c.criterion),R&&c.criterion.call(null,d)){c.action.call(null,this._map,o,u,a);break}if(!R&&c.criterion===E){c.action.call(null,this._map,o,u,a);break}}}}class B{constructor(t){this._map=t,this._actions=[]}addAction(t,e,i){this._actions.push({criterion:t,period:e,zoneSize:i})}repairZone(t,e,i){let s,a,o,r,h=this._map.getTileValue(t,e)-i-2;for(a=-1;a<i-1;a++)for(s=-1;s<i-1;s++)h++,o=this._map.getTile(t+s,e+a),o.isZone()||o.isAnimated()||(r=o.getValue(),(r<n.RUBBLE||r>=n.ROADBASE)&&this._map.setTile(t+s,e+a,h,n.CONDBIT|n.BURNBIT))}checkTile(t,e,i){let a,o,r,n,h,l=this._actions.length;for(;l--;)a=this._actions[l],o=a.period,0==(i&o)&&(r=this._map.getTile(t,e),n=r.getValue(),h=s.isCallable(a.criterion),h&&a.criterion.call(null,r)?this.repairZone(t,e,a.zoneSize):h||a.criterion!==n||this.repairZone(t,e,a.zoneSize))}}class w{constructor(t,e){this._map=t,this._stack=[],this._spriteManager=e}makeTraffic(t,i,s,a){this._stack=[];let o=new M(t,i);return this.findPerimeterRoad(o)?this.tryDrive(o,a)?(this.addToTrafficDensityMap(s),e.ROUTE_FOUND):e.NO_ROUTE_FOUND:e.NO_ROAD_FOUND}addToTrafficDensityMap(t){let i=t.trafficDensityMap;for(;this._stack.length>0;){let t=this._stack.pop();if(!this._map.testBounds(t.x,t.y))continue;let s=this._map.getTileValue(t.x,t.y);if(s>=n.ROADBASE&&s<n.POWERBASE){let s=i.worldGet(t.x,t.y);if(s+=50,s=Math.min(s,240),i.worldSet(t.x,t.y,s),s>=240&&0===a.getRandom(5)){let i=this._spriteManager.getSprite(e.SPRITE_HELICOPTER);null!==i&&(i.destX=o.worldToPix(t.x),i.destY=o.worldToPix(t.y))}}}}findPerimeterRoad(t){for(let i=0;i<12;i++){let s=t.x+e.perimX[i],a=t.y+e.perimY[i];if(this._map.testBounds(s,a)&&o.isDriveable(this._map.getTileValue(s,a)))return t.x=s,t.y=a,!0}return!1}tryDrive(t,i){let s=P.INVALID,a=new M(t);for(let t=0;t<e.MAX_TRAFFIC_DISTANCE;t++){let e=this.tryGo(a,s);if(e!=P.INVALID){if(a.move(e),s=P.rotate180(e),1&t&&this._stack.push(new M(a)),this.driveDone(a,i))return!0}else{if(!(this._stack.length>0))return!1;this._stack.pop(),t+=3}}return!1}tryGo(t,e){let i,s=[],r=P.NORTH,h=0;for(i=0;i<4;i++)r!=e&&o.isDriveable(this._map.getTileFromMapOrDefault(t,r,n.DIRT))?(s[i]=r,h++):s[i]=P.INVALID,r=P.rotate90(r);if(0===h)return P.INVALID;if(1===h)for(i=0;i<4;i++)if(s[i]!=P.INVALID)return s[i];for(i=3&a.getRandom16();s[i]===P.INVALID;)i=i+1&3;return s[i]}driveDone(t,e){return!!(t.y>0&&e(this._map.getTileValue(t.x,t.y-1)))||(!!(t.x<this._map.width-1&&e(this._map.getTileValue(t.x+1,t.y)))||(!!(t.y<this._map.height-1&&e(this._map.getTileValue(t.x,t.y+1)))||!!(t.x>0&&e(this._map.getTileValue(t.x-1,t.y)))))}}const V=function(t){let e=t.getValue();return!(e<n.RESBASE||e>n.LASTZONE||t.isZone())};class H{constructor(t,e,i){this._map=t,this._spriteManager=e,this._gameLevel=i,this._floodCount=0,this.disastersEnabled=!1,this.Dx=[0,1,0,-1],this.Dy=[-1,0,1,0]}doDisasters(t){if(this._floodCount&&this._floodCount--,this.disastersEnabled&&a.getRandom(e.DisChance[this._gameLevel]))switch(a.getRandom(8)){case 0:case 1:this.setFire();break;case 2:case 3:this.makeFlood();break;case 4:break;case 5:this._spriteManager.makeTornado();break;case 6:break;case 7:case 8:t.pollutionAverage>60&&this._spriteManager.makeMonster()}}setDifficulty(t){this._gameLevel=t}scenarioDisaster(){}makeMeltdown(){for(let t=0;t<this._map.width-1;t++)for(let e=0;e<this._map.height-1;e++)if(this._map.getTileValue(t,e)===n.NUCLEAR)return void this.doMeltdown(t,e)}makeEarthquake(){let t,e,s,r=a.getRandom(700)+300;for(this.doEarthquake(r),i.emitEvent(R.EARTHQUAKE,{x:this._map.cityCenterX,y:this._map.cityCenterY}),t=0;t<r;t++)e=a.getRandom(this._map.width-1),s=a.getRandom(this._map.height-1),V(this._map.getTile(e,s))&&(0!=(3&t)?this._map.setTo(e,s,o.randomRubble()):this._map.setTo(e,s,o.randomFire()))}setFire(t=1,e=!1){let s,r,h,l,d;for(s=0;s<t;s++)if(r=a.getRandom(this._map.width-1),h=a.getRandom(this._map.height-1),this._map.testBounds(r,h)&&(l=this._map.getTile(r,h),!l.isZone()&&(l=l.getValue(),d=e?n.LHTHR:n.TREEBASE,l>d&&l<n.LASTZONE)))return this._map.setTo(r,h,o.randomFire()),void i.emitEvent(R.FIRE_REPORTED,{showable:!0,x:r,y:h})}makeCrash(){let t=this._spriteManager.getSprite(e.SPRITE_AIRPLANE);if(null!==t)return void t.explodeSprite();let i=a.getRandom(this._map.width-1),s=a.getRandom(this._map.height-1);this._spriteManager.generatePlane(i,s),t=this._spriteManager.getSprite(e.SPRITE_AIRPLANE),t.explodeSprite()}makeFire(){this.setFire(40,!1)}makeFlood(){let t,e,s,o,h,l,d,E;for(t=0;t<300;t++)if(e=a.getRandom(this._map.width-1),s=a.getRandom(this._map.height-1),this._map.testBounds(e,s)&&(o=this._map.getTileValue(e,s),o>n.CHANNEL&&o<=n.WATER_HIGH))for(h=0;h<4;h++)if(l=e+this.Dx[h],d=s+this.Dy[h],this._map.testBounds(l,d)&&(E=this._map.getTile(l,d),o=E.getValue(),E===n.DIRT||E.isBulldozable()&&E.isCombustible))return this._map.setTo(l,d,new r(n.FLOOD)),this._floodCount=30,void i.emitEvent(R.FLOODING_REPORTED,{showable:!0,x:l,y:d})}doFlood(t,e,i){let s,r,h,l,d;if(this._floodCount>0)for(s=0;s<4;s++)a.getChance(7)&&(r=t+this.Dx[s],h=e+this.Dy[s],this._map.testBounds(r,h)&&(l=this._map.getTile(r,h),d=l.getValue(),(l.isCombustible()||d===n.DIRT||d>=n.WOODS5&&d<n.FLOOD)&&(l.isZone()&&o.fireZone(this.map,r,h,i),this._map.setTile(r,h,n.FLOOD+a.getRandom(2),0))));else a.getChance(15)&&this._map.setTile(t,e,n.DIRT,0)}doMeltdown(t,e){let s,r,h,l;for(this._spriteManager.makeExplosion(t-1,e-1),this._spriteManager.makeExplosion(t-1,e+2),this._spriteManager.makeExplosion(t+2,e-1),this._spriteManager.makeExplosion(t+2,e+2),h=t-1;h<t+3;h++)for(r=e-1;r<e+3;r++)this._map.setTo(h,r,o.randomFire());for(s=0;s<200;s++)h=t-20+a.getRandom(40),r=e-15+a.getRandom(30),this._map.testBounds(h,r)&&(l=this._map.getTile(h,r),l.isZone()||(l.isCombustible()||l.getValue()===n.DIRT)&&this._map.setTile(h,r,n.RADTILE,0));i.emitEvent(R.NUCLEAR_MELTDOWN,{showable:!0,x:t,y:e})}}const y=[0,3,6,1,4,7,2,5,8],v={registerHandlers:function(t,e){t.addAction(o.isResidentialZone,v.residentialFound),t.addAction(o.HOSPITAL,v.hospitalFound),e.addAction(n.HOSPITAL,15,3)},placeResidential:function(t,e,i,s,a,r){let h=9*(4*a+s)+n.RZB;o.putZone(t,e,i,h,r)},getFreeZonePopulation:function(t,e,i,s){let a,o,r=0;for(a=e-1;a<=e+1;a++)for(o=i-1;o<=i+1;o++)a===e&&o===i||(s=t.getTileValue(a,o))>=n.LHTHR&&s<=n.HHTHR&&(r+=1);return r},getZonePopulation:function(t,e,i,s){if(s===n.FREEZ)return v.getFreeZonePopulation(t,e,i,s);return 8*(Math.floor((s-n.RZB)/9)%4+1)+16},evalLot:function(t,e,i){let s=[0,1,0,-1],a=[-1,0,1,0];if(!t.testBounds(e,i))return-1;let o=t.getTileValue(e,i);if(o<n.RESBASE||o>n.RESBASE+8)return-1;let r,h,l,d=1;for(r=0;r<4;r++)h=e+s[r],l=i+a[r],h<0||h>=t.width||l<0||l>=t.height||(o=t.getTileValue(h,l),o!==n.DIRT&&o<=n.LASTROAD&&(d+=1));return d},buildHouse:function(t,e,i,s){let o,r,h,l,d=0,E=0,c=[0,-1,0,1,-1,1,-1,0,1],R=[0,-1,-1,-1,0,0,1,1,1];for(o=0;o<9;o++)r=e+c[o],h=i+R[o],l=v.evalLot(t,r,h),l>E?(E=l,d=o):l===E&&a.getChance(7)&&(d=o);d>0&&t.testBounds(e+c[d],i+R[d])&&t.setTile(e+c[d],i+R[d],n.HOUSE+a.getRandom(2)+3*s,n.BLBNCNBIT)},growZone:function(t,e,i,s,a,r,h){s.pollutionDensityMap.worldGet(e,i)>128||(t.getTileValue(e,i)!==n.FREEZ?a<40&&(v.placeResidential(t,e,i,Math.floor(a/8)-1,r,h),o.incRateOfGrowth(s,e,i,8)):a<8?(v.buildHouse(t,e,i,r),o.incRateOfGrowth(s,e,i,1)):s.populationDensityMap.worldGet(e,i)>64&&(v.placeResidential(t,e,i,0,r,h),o.incRateOfGrowth(s,e,i,8)))},degradeZone:function(t,e,i,s,h,l,d){let E,c;if(0===h)return;if(h>16)return v.placeResidential(t,e,i,Math.floor((h-24)/8),l,d),void o.incRateOfGrowth(s,e,i,-8);if(16===h){for(t.setTo(e,i,new r(n.FREEZ,n.BLBNCNBIT|n.ZONEBIT)),c=i-1;c<=i+1;c++)for(E=e-1;E<=e+1;E++)E===e&&c===i||t.setTile(e,i,n.LHTHR+l+a.getRandom(2),n.BLBNCNBIT);return void o.incRateOfGrowth(s,e,i,-8)}let R=0;for(o.incRateOfGrowth(s,e,i,-1),E=e-1;E<=e+1;E++)for(c=i-1;c<=i+1;c++){let e=t.getTileValue(E,c);if(e>=n.LHTHR&&e<=n.HHTHR)return void t.setTile(E,c,y[R]+n.RESBASE,n.BLBNCNBIT);R+=1}},evalResidential:function(t,i,s,a){if(a===e.NO_ROAD_FOUND)return-3e3;let o=t.landValueMap.worldGet(i,s);return o-=t.pollutionDensityMap.worldGet(i,s),o=o<0?0:Math.min(32*o,6e3),o-3e3},residentialFound:function(t,i,s,r){let h;r||(r=e.simData),r.census.resZonePop+=1;let l=t.getTileValue(i,s),d=v.getZonePopulation(t,i,s,l);r.census.resPop+=d;let E=t.getTile(i,s).isPowered(),c=e.ROUTE_FOUND;if(d>a.getRandom(35)&&(c=r.traffic.makeTraffic(i,s,r.blockMaps,o.isCommercial),c===e.NO_ROAD_FOUND))return h=o.getLandPollutionValue(r.blockMaps,i,s),void v.degradeZone(t,i,s,r.blockMaps,d,h,E);if(l===n.FREEZ||a.getChance(7)){let e=v.evalResidential(r.blockMaps,i,s,c),n=r.valves.resValve+e;if(E||(n=-500),n>-350&&n-26380>a.getRandom16Signed())return 0===d&&a.getChance(3)?void v.makeHospital(t,i,s,r,E):(h=o.getLandPollutionValue(r.blockMaps,i,s),void v.growZone(t,i,s,r.blockMaps,d,h,E));n<350&&n+26380<a.getRandom16Signed()&&(h=o.getLandPollutionValue(r.blockMaps,i,s),v.degradeZone(t,i,s,r.blockMaps,d,h,E))}},makeHospital:function(t,i,s,a,r){if(a||(a=e.simData),a.census.needHospital>0)return o.putZone(t,i,s,n.HOSPITAL,r),void(a.census.needHospital=0)},hospitalFound:function(t,i,s,r){r||(r=e.simData),r.census.hospitalPop+=1,-1===r.census.needHospital&&0===a.getRandom(20)&&o.putZone(t,i,s,n.FREEZ,t.getTile(i,s).isPowered())}},b={registerHandlers:function(t,e){t.addAction(o.isCommercialZone,b.commercialFound)},getZonePopulation:function(t,e,i,s){return s===n.COMCLR?0:Math.floor((s-n.CZB)/9)%5+1},placeCommercial:function(t,e,i,s,a,r){var h=9*(5*a+s)+n.CZB;o.putZone(t,e,i,h,r)},growZone:function(t,e,i,s,a,r,n){var h=s.landValueMap.worldGet(e,i);a>(h>>=5)||a<5&&(b.placeCommercial(t,e,i,a,r,n),o.incRateOfGrowth(s,e,i,8))},degradeZone:function(t,e,i,s,a,r,h){a>1?b.placeCommercial(t,e,i,a-2,r,h):o.putZone(t,e,i,n.COMCLR,h),o.incRateOfGrowth(s,e,i,-8)},commercialFound:function(t,i,s,r){var n;r||(r=e.simData),r.census.comZonePop+=1;var h=t.getTileValue(i,s),l=b.getZonePopulation(t,i,s,h);r.census.comPop+=l;var d=t.getTile(i,s).isPowered(),E=e.ROUTE_FOUND;if(l>a.getRandom(5)&&(E=r.traffic.makeTraffic(i,s,r.blockMaps,o.isIndustrial))===e.NO_ROAD_FOUND)return n=o.getLandPollutionValue(r.blockMaps,i,s),void b.degradeZone(t,i,s,r.blockMaps,l,n,d);if(a.getChance(7)){var c=E===e.NO_ROAD_FOUND?-3e3:r.blockMaps.cityCentreDistScoreMap.worldGet(i,s),R=r.valves.comValve+c;if(d||(R=-500),d&&R>-350&&R-26380>a.getRandom16Signed())return n=o.getLandPollutionValue(r.blockMaps,i,s),void b.growZone(t,i,s,r.blockMaps,l,n,d);R<350&&R+26380<a.getRandom16Signed()&&(n=o.getLandPollutionValue(r.blockMaps,i,s),b.degradeZone(t,i,s,r.blockMaps,l,n,d))}}},U=[!0,!1,!0,!0,!1,!1,!0,!0],F=[-1,0,1,0,0,0,0,1],W=[-1,0,-1,-1,0,0,-1,-1],x={registerHandlers:function(t,e){t.addAction(o.isIndustrialZone,x.industrialFound)},getZonePopulation:function(t,e,i,s){return s===n.INDCLR?0:Math.floor((s-n.IZB)/9)%4+1},placeIndustrial:function(t,e,i,s,a,r){var h=9*(4*a+s)+n.IZB;o.putZone(t,e,i,h,r)},growZone:function(t,e,i,s,a,r,n){a<4&&(x.placeIndustrial(t,e,i,a,r,n),o.incRateOfGrowth(s,e,i,8))},degradeZone:function(t,e,i,s,a,r,h){a>1?x.placeIndustrial(t,e,i,a-2,r,h):o.putZone(t,e,i,n.INDCLR,h),o.incRateOfGrowth(s,e,i,-8)},setAnimation:function(t,e,i,s,a){if(!(s<n.IZB)){var o=s-n.IZB>>3;U[o]&&a?t.addTileFlags(e+F[o],i+W[o],n.ASCBIT):(t.addTileFlags(e+F[o],i+W[o],n.BNCNBIT),t.removeTileFlags(e+F[o],i+W[o],n.ANIMBIT))}},industrialFound:function(t,i,s,r){r||(r=e.simData),r.census.indZonePop+=1;var n=t.getTileValue(i,s),h=x.getZonePopulation(t,i,s,n);r.census.indPop+=h;var l=t.getTile(i,s).isPowered();r.is3D||x.setAnimation(t,i,s,n,l);var d=e.ROUTE_FOUND;if(h>a.getRandom(5)&&(d=r.traffic.makeTraffic(i,s,r.blockMaps,o.isResidential))===e.NO_ROAD_FOUND){var E=1&a.getRandom16();x.degradeZone(t,i,s,r.blockMaps,h,E,l)}else if(a.getChance(7)){var c=r.valves.indValve+(d===e.NO_ROAD_FOUND?-1e3:0);if(l||(c=-500),c>-350&&c-26380>a.getRandom16Signed())return void x.growZone(t,i,s,r.blockMaps,h,1&a.getRandom16(),l);c<350&&c+26380<a.getRandom16Signed()&&x.degradeZone(t,i,s,r.blockMaps,h,1&a.getRandom16(),l)}}},k=[0,1,0,0,0,0,1],G=[-2,-2,-1,0,1,2,2],z=[-2,2,-2,-1,0,1,2],Y=[-1,-1,0,0,0,0,0],X=[n.VBRDG0,n.VBRDG1,n.RIVER,n.BRWV,n.RIVER,n.VBRDG2,n.VBRDG3],Z=[n.VBRIDGE,n.RIVER,n.VBRIDGE,n.VBRIDGE,n.VBRIDGE,n.VBRIDGE,n.RIVER],K=[n.HBRDG1,n.HBRDG3,n.HBRDG0,n.RIVER,n.BRWH,n.RIVER,n.HBRDG2],q=[n.RIVER,n.RIVER,n.HBRIDGE,n.HBRIDGE,n.HBRIDGE,n.HBRIDGE,n.HBRIDGE],Q=[n.ROADBASE,n.LTRFBASE,n.HTRFBASE],j={registerHandlers:function(t,e){t.addAction(o.isRoad,j.roadFound)},openBridge:function(t,e,i,s,a,o,r){let h,l,d;for(h=0;h<7;h++)l=e+s[h],d=i+a[h],t.testBounds(l,d)&&t.getTileValue(l,d)===(o[h]&n.BIT_MASK)&&t.setTileValue(l,d,r[h])},closeBridge:function(t,e,i,s,a,o,r){let h,l,d,E;for(h=0;h<7;h++)l=e+s[h],d=i+a[h],t.testBounds(l,d)&&(E=t.getTileValue(l,d),E!==n.CHANNEL&&(15&E)!=(15&o[h])||t.setTileValue(l,d,r[h]))},doBridge:function(t,i,s,o,r){if(r||(r=e.simData),o===n.BRWV)return a.getChance(3)&&r.spriteManager.getBoatDistance(i,s)>340&&j.closeBridge(t,i,s,k,G,X,Z),!0;if(o==n.BRWH)return a.getChance(3)&&r.spriteManager.getBoatDistance(i,s)>340&&j.closeBridge(t,i,s,z,Y,K,q),!0;if(r.spriteManager.getBoatDistance(i,s)<300||a.getChance(7)){if(1&o)return i<t.width-1&&t.getTileValue(i+1,s)===n.CHANNEL&&(j.openBridge(t,i,s,k,G,Z,X),!0);if(s>0&&t.getTileValue(i,s-1)===n.CHANNEL)return j.openBridge(t,i,s,z,Y,q,K),!0}return!1},roadFound:function(t,i,s,h){h||(h=e.simData),h.census.roadTotal+=1;let l=t.getTile(i,s),d=l.getValue();if(h.budget.shouldDegradeRoad()&&a.getChance(511)&&!l.isConductive()&&h.budget.roadEffect<(31&a.getRandom16()))return void((15&d)<2||15==(15&d)?t.setTile(i,s,n.RIVER):t.setTo(i,s,o.randomRubble()));l.isCombustible()||(h.census.roadTotal+=4);let E=0;d<n.LTRFBASE?E=0:d<n.HTRFBASE?E=1:(h.census.roadTotal+=1,E=2);let c=h.blockMaps.trafficDensityMap.worldGet(i,s)>>6;if(c>1&&(c-=1),c===E)return;let R=(d-n.ROADBASE&15)+Q[c],u=l.getFlags()&~n.ANIMBIT;c>0&&(u|=n.ANIMBIT),t.setTo(i,s,new r(R,u))}},J={registerHandlers:function(t,e){t.addAction(o.isRail,J.railFound),t.addAction(n.PORT,J.portFound),t.addAction(n.AIRPORT,J.airportFound),e.addAction(n.PORT,15,4),e.addAction(n.AIRPORT,7,6)},railFound:function(t,i,s,r){if(r||(r=e.simData),r.census.railTotal+=1,r.spriteManager.generateTrain(r.census,i,s),r.budget.shouldDegradeRoad()&&a.getChance(511)){let e=t.getTile(i,s);if(e.isConductive())return;if(r.budget.roadEffect<(31&a.getRandom16())){e.getValue()<n.RAILBASE+2?t.setTile(i,s,n.RIVER,0):t.setTo(i,s,o.randomRubble())}}},airportFound:function(t,i,s,o){if(o||(o=e.simData),o.census.airportPop+=1,t.getTile(i,s).isPowered()){if(t.getTileValue(i+1,s-1)===n.RADAR&&t.setTile(i+1,s-1,n.RADAR0,n.CONDBIT|n.ANIMBIT|n.BURNBIT),0===a.getRandom(5))return void o.spriteManager.generatePlane(i,s);0===a.getRandom(12)&&o.spriteManager.generateCopter(i,s)}else t.setTile(i+1,s-1,n.RADAR,n.CONDBIT|n.BURNBIT)},portFound:function(t,i,s,a){a||(a=e.simData),a.census.seaportPop+=1,t.getTile(i,s).isPowered()&&null===a.spriteManager.getSprite(e.SPRITE_SHIP)&&a.spriteManager.generateShip()}},$=function(t,i,s){return function(a,o,r,n){n||(n=e.simData),n.census[t]+=1;var h=n.budget[i];a.getTile(o,r).isPowered()||(h=Math.floor(h/2));var l=new M(o,r);n.traffic.findPerimeterRoad(l)||(h=Math.floor(h/2));var d=n.blockMaps[s].worldGet(o,r);d+=h,n.blockMaps[s].worldSet(o,r,d)}},tt={registerHandlers:function(t,e){t.addAction(n.POLICESTATION,tt.policeStationFound),t.addAction(n.FIRESTATION,tt.fireStationFound)},policeStationFound:$("policeStationPop","policeEffect","policeStationMap"),fireStationFound:$("fireStationPop","fireEffect","fireStationMap")},et=[-1,0,1,0],it=[0,-1,0,1],st={registerHandlers:function(t,e){t.addAction(o.isFire,st.fireFound,!0),t.addAction(n.RADTILE,st.radiationFound,!0),t.addAction(o.isFlood,st.floodFound,!0)},fireFound:function(t,i,s,r){if(r||(r=e.simData),r.census.firePop+=1,0!=(3&a.getRandom16()))return;let h,l,d,E;for(h=0;h<4;h++)if(a.getChance(7)&&(l=i+et[h],d=s+it[h],t.testBounds(l,d))){if(E=t.getTile(i,s),!E.isCombustible())continue;E.isZone()&&(o.fireZone(t,i,s,r.blockMaps),E.getValue()>n.IZB&&r.spriteManager.makeExplosionAt(i,s)),t.setTo(o.randomFire())}let c=10;h=r.blockMaps.fireStationEffectMap.worldGet(i,s),h>100?c=1:h>20?c=2:h>0&&(c=3),0===a.getRandom(c)&&t.setTo(i,s,o.randomRubble())},radiationFound:function(t,e,i,s){a.getChance(4095)&&t.setTile(e,i,n.DIRT,0)},floodFound:function(t,i,s,a){a||(a=e.simData),a.disasterManager.doFlood(i,s,a.blockMaps)}},at={registerHandlers:function(t,e){t.addAction(n.STADIUM,at.emptyStadiumFound),t.addAction(n.FULLSTADIUM,at.fullStadiumFound),e.addAction(n.STADIUM,15,4)},emptyStadiumFound:function(t,i,s,a){a||(a=e.simData),a.census.stadiumPop+=1,t.getTile(i,s).isPowered()&&0==(a.cityTime+i+s&31)&&(t.putZone(i,s,n.FULLSTADIUM,4),t.addTileFlags(i,s,n.POWERBIT),t.setTo(i+1,s,new r(n.FOOTBALLGAME1,n.ANIMBIT)),t.setTo(i+1,s+1,new r(n.FOOTBALLGAME2,n.ANIMBIT)))},fullStadiumFound:function(t,i,s,a){a||(a=e.simData),a.census.stadiumPop+=1;let o=t.getTile(i,s).isPowered();0==(a.cityTime+i+s&7)&&(t.putZone(i,s,n.STADIUM,4),o&&t.addTileFlags(i,s,n.POWERBIT))}};class ot{static smoothMap(t,i,s){let a,o,r=t.width;for(;r--;)for(a=t.height;a--;)o=0,r>0&&(o+=t.get(r-1,a)),r<t.width-1&&(o+=t.get(r+1,a)),a>0&&(o+=t.get(r,a-1)),a<t.height-1&&(o+=t.get(r,a+1)),s===e.SMOOTH_NEIGHBOURS_THEN_BLOCK?(o=t.get(r,a)+Math.floor(o/4),i.set(r,a,Math.floor(o/2))):(o=o+t.get(r,a)>>2,o>255&&(o=255),i.set(r,a,o))}static neutraliseRateOfGrowthMap(t){let e,i,s=t.rateOfGrowthMap,o=s.width;for(;o--;)for(e=s.height;e--;)i=s.get(o,e),0!==i&&(i>0?i--:i++,i=a.clamp(i,-200,200),s.set(o,e,i))}static neutraliseTrafficMap(t){let e,i,s=t.trafficDensityMap,a=s.width;for(;a--;)for(e=s.height;e--;)i=s.get(a,e),0!==i&&(i<=24?i=0:i-=i>200?34:24,s.set(a,e,i))}static getPollutionValue(t){if(t<n.POWERBASE){if(t>=n.HTRFBASE)return 75;if(t>=n.LTRFBASE)return 50;if(t<n.ROADBASE){if(t>n.FIREBASE)return 90;if(t>=n.RADTILE)return 255}return 0}return t<=n.LASTIND?0:t<n.PORTBASE?50:t<=n.LASTPOWERPLANT?100:0}static getCityCentreDistance(t,e,i){let s,a;return s=e>t.cityCentreX?e-t.cityCentreX:t.cityCentreX-e,a=i>t.cityCentreY?i-t.cityCentreY:t.cityCentreY-i,Math.min(s+a,64)}static pollutionTerrainLandValueScan(t,i,s){let o=s.tempMap1,r=s.tempMap2,h=s.tempMap3;h.clear();let l,d,E,c,R,u,T,p,m,A,g=s.landValueMap,f=s.terrainDensityMap,O=s.pollutionDensityMap,S=s.crimeRateMap,I=0,L=0,D=g.width;for(;D--;)for(l=g.height;l--;){for(d=0,E=!1,c=2*D,R=2*l,u=c;u<=c+1;u++)for(T=R;T<=R+1;T++)p=t.getTileValue(u,T),p!==n.DIRT&&(p<n.RUBBLE?(m=h.worldGet(u,T),h.worldSet(u,T,m+15)):(d+=ot.getPollutionValue(p),p>=n.ROADBASE&&(E=!0)));d=Math.min(d,255),o.set(D,l,d),E?(A=34-Math.floor(ot.getCityCentreDistance(t,c,R)/2),A<<=2,A+=f.get(D>>1,l>>1),A-=O.get(D,l),S.get(D,l)>190&&(A-=20),A=a.clamp(A,1,250),g.set(D,l,A),I+=A,L++):g.set(D,l,0)}i.landValueAverage=L>0?Math.floor(I/L):0,ot.smoothMap(o,r,e.SMOOTH_ALL_THEN_CLAMP),ot.smoothMap(r,o,e.SMOOTH_ALL_THEN_CLAMP);let _,P=0,M=0,N=0;for(D=0;D<t.width;D+=O.blockSize)for(l=0;l<t.height;l+=O.blockSize)_=o.worldGet(D,l),O.worldSet(D,l,_),0!==_&&(M++,N+=_,(_>P||_===P&&a.getChance(3))&&(P=_,t.pollutionMaxX=D,t.pollutionMaxY=l));i.pollutionAverage=M?Math.floor(N/M):0,ot.smoothMap(h,f,e.SMOOTH_NEIGHBOURS_THEN_BLOCK)}static crimeScan(t,i){let s=i.policeStationMap,o=i.policeStationEffectMap,r=i.crimeRateMap,n=i.landValueMap,h=i.populationDensityMap;ot.smoothMap(s,o,e.SMOOTH_NEIGHBOURS_THEN_BLOCK),ot.smoothMap(o,s,e.SMOOTH_NEIGHBOURS_THEN_BLOCK),ot.smoothMap(s,o,e.SMOOTH_NEIGHBOURS_THEN_BLOCK);let l,d,E,c=0,R=0,u=r.mapWidth,T=r.mapHeight;for(l=0;l<u;l+=blockSize)for(d=0;d<T;d+=blockSize)E=n.worldGet(l,d),E>0?(R+=1,E=128-E,E+=h.worldGet(l,d),E=Math.min(E,300),E-=s.worldGet(l,d),E=a.clamp(E,0,250),r.worldSet(l,d,E),c+=E):r.worldSet(l,d,0);t.crimeAverage=R>0?Math.floor(c/R):0}static fillCityCentreDistScoreMap(t,e){let i,s,a=e.cityCentreDistScoreMap,o=a.width;for(;o--;)for(i=a.height;i--;)s=Math.floor(ot.getCityCentreDistance(t,8*o,8*i)/2),s*=4,s=64-s,a.set(o,i,s)}static getPopulationDensity(t,e,i,s){return s<n.COMBASE?v.getZonePopulation(t,e,i,s):s<n.INDBASE?8*b.getZonePopulation(t,e,i,s):s<n.PORTBASE?8*x.getZonePopulation(t,e,i,s):0}static populationDensityScan(t,i){let s=i.tempMap1,a=i.tempMap2;i.populationDensityMap;let o=0,r=0,n=0;s.clear();let h,l,d,E,c=t.width;for(;c--;)for(h=t.height;h--;)l=t.getTile(c,h),l.isZone()&&(d=l.getValue(),E=8*ot.getPopulationDensity(t,c,h,d),E=Math.min(E,254),s.worldSet(c,h,E),o+=c,r+=h,n++);ot.smoothMap(s,a,e.SMOOTH_ALL_THEN_CLAMP),ot.smoothMap(a,s,e.SMOOTH_ALL_THEN_CLAMP),ot.smoothMap(s,a,e.SMOOTH_ALL_THEN_CLAMP),i.populationDensityMap.copyFrom(a,(function(t){return 2*t})),ot.fillCityCentreDistScoreMap(t,i),n>0?(t.cityCentreX=Math.floor(o/n),t.cityCentreY=Math.floor(r/n)):(t.cityCentreX=Math.floor(.5*t.width),t.cityCentreY=Math.floor(.5*t.height))}static fireAnalysis(t){let i=t.fireStationMap,s=t.fireStationEffectMap;ot.smoothMap(i,s,e.SMOOTH_NEIGHBOURS_THEN_BLOCK),ot.smoothMap(s,i,e.SMOOTH_NEIGHBOURS_THEN_BLOCK),ot.smoothMap(i,s,e.SMOOTH_NEIGHBOURS_THEN_BLOCK)}}class rt{constructor(t,i,s,a,o){if(i!==e.LEVEL_EASY&&i!==e.LEVEL_MED&&i!==e.LEVEL_HARD)throw new Error("Invalid level!");this.map=t,this.gameLevel=i,this.div=this.map.width/8,this.is3D=a||!1,this.time="undefined"==typeof performance?Date:performance,this.speed=s,this.speedCycle=0,this.phaseCycle=0,this.simCycle=0,this.doInitialEval=!0,this.cityTime=50,this.cityPopLast=0,this.messageLast=R.VILLAGE_REACHED,this.startingYear=1900,this.resValveLast=0,this.comValveLast=0,this.indValveLast=0,this._cityYearLast=-1,this._cityMonthLast=-1,this._lastPowerMessage=null,this.infos=[],this.evaluation=new S(this.gameLevel),this.valves=new I,this.budget=new L,this.census=new D,this.powerManager=new N(this.map),this.spriteManager=new f(this.map),this.mapScanner=new C(this.map),this.repairManager=new B(this.map),this.traffic=new w(this.map,this.spriteManager),this.disasterManager=new H(this.map,this.spriteManager,this.gameLevel),this.messageManager=new E,e.messageManager=this.messageManager;let r=this.map.width,n=this.map.height;this.blockMaps={cityCentreDistScoreMap:new _(r,n,8),crimeRateMap:new _(r,n,2),fireStationMap:new _(r,n,8),fireStationEffectMap:new _(r,n,8),landValueMap:new _(r,n,2),policeStationMap:new _(r,n,8),policeStationEffectMap:new _(r,n,8),pollutionDensityMap:new _(r,n,2),populationDensityMap:new _(r,n,2),rateOfGrowthMap:new _(r,n,8),terrainDensityMap:new _(r,n,4),trafficDensityMap:new _(r,n,2),tempMap1:new _(r,n,2),tempMap2:new _(r,n,2),tempMap3:new _(r,n,4)},this.clearCensus(),o?this.load(o):(this.budget.setFunds(2e4),this.census.totalPop=1),e.simData=this,this.init()}save(t){for(let i=0,s=e.savePropsVar.length;i<s;i++)t[e.savePropsVar[i]]=this[e.savePropsVar[i]];this.map.save(t),this.evaluation.save(t),this.valves.save(t),this.budget.save(t),this.census.save(t)}load(t){this.messageManager.clear();for(let i=0,s=e.savePropsVar.length;i<s;i++)this[e.savePropsVar[i]]=t[e.savePropsVar[i]];this.evaluation.load(t),this.valves.load(t),this.budget.load(t),this.census.load(t)}setSpeed(t){this.speed=t}setDifficulty(t){if(t!==e.LEVEL_EASY&&t!==e.LEVEL_MED&&t!==e.LEVEL_HARD)throw new Error("Invalid level!");this.gameLevel=t,this.disasterManager.setDifficulty(this.gameLevel)}isPaused(){return this.speed===e.SPEED_PAUSED}simTick(){let t=this.simFrame();return t&&(this.updateTime(),this.updateInfo()),t}updateInfo(){return this.infos[0]=[p.months[this._cityMonthLast],this._cityYearLast].join(" "),this.infos[1]=p.cityClass[this.evaluation.cityScore],this.infos[2]=this.evaluation.cityScore,this.infos[3]=this.evaluation.cityPop,this.infos[4]=this.budget.totalFunds,this.infos[5]=this.valves.resValve,this.infos[6]=this.valves.comValve,this.infos[7]=this.valves.indValve,this.infos[9]=this.map.powerChange,this.map.powerChange=!1,this.infos}simFrame(){if(this.budget.awaitingValues)return!1;if(this.speed===e.SPEED_PAUSED)return!1;let t=100;this.speed===e.SPEED_MED&&(t=50),this.speed===e.SPEED_FAST&&(t=10),this.speed===e.SPEED_ULTRA&&(t=5);let i=this.time.now();return!(i-this.prevTime<t)&&(this.messageManager.clear(),this.simulate(),this.prevTime=i,!0)}clearCensus(){this.census.clearCensus(),this.powerManager.clearPowerStack(),this.blockMaps.fireStationMap.clear(),this.blockMaps.policeStationMap.clear()}init(){this.prevTime=-1,this.powerManager.registerHandlers(this.mapScanner,this.repairManager),b.registerHandlers(this.mapScanner,this.repairManager),tt.registerHandlers(this.mapScanner,this.repairManager),x.registerHandlers(this.mapScanner,this.repairManager),st.registerHandlers(this.mapScanner,this.repairManager),j.registerHandlers(this.mapScanner,this.repairManager),v.registerHandlers(this.mapScanner,this.repairManager),at.registerHandlers(this.mapScanner,this.repairManager),J.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),ot.pollutionTerrainLandValueScan(this.map,this.census,this.blockMaps),ot.crimeScan(this.census,this.blockMaps),ot.populationDensityScan(this.map,this.blockMaps),ot.fireAnalysis(this.blockMaps)}simulate(){this.phaseCycle&=15;let t=this.speed-1;switch(this.phaseCycle){case 0:++this.simCycle>1023&&(this.simCycle=0),this.doInitialEval&&(this.doInitialEval=!1,this.evaluation.cityEvaluation()),this.cityTime++,0==(1&this.simCycle)&&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:this.cityTime%e.CENSUS_FREQUENCY_10==0&&this.census.take10Census(this.budget),this.cityTime%e.CENSUS_FREQUENCY_120==0&&this.census.take120Census(this.budget),this.cityTime%e.TAX_FREQUENCY==0&&(this.budget.collectTax(this.gameLevel,this.census),this.evaluation.cityEvaluation());break;case 10:this.simCycle%5==0&&ot.neutraliseRateOfGrowthMap(this.blockMaps),ot.neutraliseTrafficMap(this.blockMaps),this.sendMessages();break;case 11:this.simCycle%e.speedPowerScan[t]==0&&this.powerManager.doPowerScan(this.census);break;case 12:this.simCycle%e.speedPollutionTerrainLandValueScan[t]==0&&ot.pollutionTerrainLandValueScan(this.map,this.census,this.blockMaps);break;case 13:this.simCycle%e.speedCrimeScan[t]==0&&ot.crimeScan(this.census,this.blockMaps);break;case 14:this.simCycle%e.speedPopulationDensityScan[t]==0&&ot.populationDensityScan(this.map,this.blockMaps);break;case 15:this.simCycle%e.speedFireAnalysis[t]==0&&ot.fireAnalysis(this.blockMaps),this.disasterManager.doDisasters(this.census)}this.phaseCycle=this.phaseCycle+1&15}sendMessages(){this.checkGrowth();let t=this.census.resZonePop+this.census.comZonePop+this.census.indZonePop,e=this.census.nuclearPowerPop+this.census.coalPowerPop;switch(63&this.cityTime){case 1:Math.floor(t/4)>=this.census.resZonePop&&this.messageManager.sendMessage(R.NEED_MORE_RESIDENTIAL);break;case 5:Math.floor(t/8)>=this.census.comZonePop&&this.messageManager.sendMessage(R.NEED_MORE_COMMERCIAL);break;case 10:Math.floor(t/8)>=this.census.indZonePop&&this.messageManager.sendMessage(R.NEED_MORE_INDUSTRIAL);break;case 14:t>10&&2*t>this.census.roadTotal&&this.messageManager.sendMessage(R.NEED_MORE_ROADS);break;case 18:t>50&&t>this.census.railTotal&&this.messageManager.sendMessage(R.NEED_MORE_RAILS);break;case 22:t>10&&0==e&&this.messageManager.sendMessage(R.NEED_ELECTRICITY);break;case 26:this.census.resPop>500&&0===this.census.stadiumPop?(this.messageManager.sendMessage(R.NEED_STADIUM),this.valves.resCap=!0):this.valves.resCap=!1;break;case 28:this.census.indPop>70&&0===this.census.seaportPop?(this.messageManager.sendMessage(R.NEED_SEAPORT),this.valves.indCap=!0):this.valves.indCap=!1;break;case 30:this.census.comPop>100&&0===this.census.airportPop?(this.messageManager.sendMessage(R._NEED_AIRPORT),this.valves.comCap=!0):this.valves.comCap=!1;break;case 32:let i=this.census.unpoweredZoneCount+this.census.poweredZoneCount;i>0&&this.census.poweredZoneCount/i<.7&&this.messageManager.sendMessage(R.BLACKOUTS_REPORTED);break;case 35:this.census.pollutionAverage>60&&this.messageManager.sendMessage(R.HIGH_POLLUTION);break;case 42:this.census.crimeAverage>100&&this.messageManager.sendMessage(R.HIGH_CRIME);break;case 45:this.census.totalPop>60&&0===this.census.fireStationPop&&this.messageManager.sendMessage(R.NEED_FIRE_STATION);break;case 48:this.census.totalPop>60&&0===this.census.policeStationPop&&this.messageManager.sendMessage(R.NEED_POLICE_STATION);break;case 51:this.budget.cityTax>12&&this.messageManager.sendMessage(R.TAX_TOO_HIGH);break;case 54:this.budget.roadEffect<Math.floor(5*this.budget.MAX_ROAD_EFFECT/8)&&this.census.roadTotal>30&&this.messageManager.sendMessage(R.ROAD_NEEDS_FUNDING);break;case 57:this.budget.fireEffect<Math.floor(7*this.budget.MAX_FIRE_STATION_EFFECT/10)&&this.census.totalPop>20&&this.messageManager.sendMessage(R.FIRE_STATION_NEEDS_FUNDING);break;case 60:this.budget.policeEffect<Math.floor(7*this.budget.MAX_POLICE_STATION_EFFECT/10)&&this.census.totalPop>20&&this.messageManager.sendMessage(R.POLICE_NEEDS_FUNDING);break;case 63:this.census.trafficAverage>60&&this.messageManager.sendMessage(R.TRAFFIC_JAMS,-1,-1,!0)}}checkGrowth(){if(0!=(3&this.cityTime))return;let t="",i=this.evaluation.getPopulation(this.census);if(i!==this.cityPopLast){let s=this.evaluation.getCityClass(this.cityPopLast),a=this.evaluation.getCityClass(i);if(s!==a)switch(a){case e.CC_VILLAGE:break;case e.CC_TOWN:t=R.REACHED_TOWN;break;case e.CC_CITY:t=R.REACHED_CITY;break;case e.CC_CAPITAL:t=R.REACHED_CAPITAL;break;case e.CC_METROPOLIS:t=R.REACHED_METROPOLIS;break;case e.CC_MEGALOPOLIS:t=R.REACHED_MEGALOPOLIS}}""!==t&&t!==this.messageLast&&(this.messageManager.sendMessage(t),this.messageLast=t),this.cityPopLast=i}setYear(t){t<this.startingYear&&(t=this.startingYear),t=t-this.startingYear-this.cityTime/48,this.cityTime+=48*t,this.updateTime()}updateTime(){let t=Math.floor(this.cityTime/48)+this.startingYear,e=Math.floor(this.cityTime%48)>>2;t>=1e6?this.setYear(this.startingYear):this._cityYearLast===t&&this._cityMonthLast===e||(this._cityYearLast=t,this._cityMonthLast=e,this.messageManager.sendMessage(R.DATE_UPDATED,{month:e,year:t}))}}class nt{constructor(){this.clear()}clear(){this.data={}}toKey(t,e){return[t,e].join(",")}getTile(t,e){let i=this.toKey(t,e);return this.data[i]}setTile(t,e,i){let s=this.toKey(t,e);this.data[s]=i}}class ht{constructor(t,e,i){e=e||5,i=i||30,this._map=t,this.animationPeriod=e,this.blinkPeriod=i,this.shouldBlink=!1,this.count=1,this._lastPainted=null,this._data=[],this.initArray(),this.registerAnimations()}initArray(){for(let t=0;t<n.TILE_COUNT;t++)this._data[t]=t}inSequence(t,e){let i=[t],s=this._data[t];for(;-1===i.indexOf(s);){if(s===e)return!0;i.push(s),s=this._data[s]}return!1}getTiles(t,e,i,s,a=!1){let r=!1;a||(this.count+=1),this.count%this.blinkPeriod==0&&(this.shouldBlink=!this.shouldBlink),this.count%this.animationPeriod!=0||a||(r=!0);let h=new nt,l=[];for(let a=t;a<i;a++)for(let t=e;t<s;t++){if(a<0||a>=this._map.width||t<0||t>=this._map.height)continue;let e=this._map.getTile(a,t);if(!e.isAnimated())continue;let i,s=e.getValue(),d=n.TILE_INVALID;this._lastPainted&&(i=this._lastPainted.getTile(a,t)),r?i&&this.inSequence(s,i)?(d=this._data[i],i===n.LASTTINYEXP?(this._map.setTo(a,t,o.randomRubble()),d=this._map.getTileValue(a,t)):d=this._data[i]):d=this._data[s]:i&&this.inSequence(s,i)&&(d=i),d!==n.TILE_INVALID&&(l.push({x:a,y:t,tileValue:d}),h.setTile(a,t,d),this._map.setPaintValue(a,t,d))}return this._lastPainted=h,l}registerSingleAnimation(t){for(let e=1;e<t.length;e++)this._data[t[e-1]]=t[e]}registerAnimations(){this.registerSingleAnimation([56,57,58,59,60,61,62,63,56]),this.registerSingleAnimation([860,861,862,863,864,865,866,867]),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])}}class lt{constructor(t=128,i=128,s){this.isIsland=!1,this.pp=[],this.width=t,this.height=i,this.fsize=this.width*this.height,this.defaultValue=(new r).getValue(),this.data=[],this.tilesData=new e.M_ARRAY_TYPE(this.fsize),this.powerData=new e.M_ARRAY_TYPE(this.fsize);let a=this.fsize;for(;a--;)this.data[a]=new r(this.defaultValue),this.tilesData[a]=this.defaultValue;this.cityCentreX=Math.floor(.5*this.width),this.cityCentreY=Math.floor(.5*this.height),this.pollutionMaxX=this.cityCentreX,this.pollutionMaxY=this.cityCentreY,this.powerChange=!1,this.layer=[],this.resetLayer(),this.makePP()}upLayer(t,e,i,s){e>=n.TINYEXP&&e<=n.TINYEXPLAST&&(e-=825),this.tilesData[t]=e,this.layer[this.findLayer(i,s)]=1}resetLayer(){let t=64;for(;t--;)this.layer[t]=0}findLayer(t,e){return Math.floor(t/16)+8*Math.floor(e/16)}goodValue(t){return 0===t||t>1&&t<240}makePP(){let t,e=this.width,i=0,s=[];for(;e--;)for(t=this.height;t--;)s[i]=[e,t],i++;this.pp=s}powered(t){let e=t.id||this.getId(t.x,t.y);this.powerData[e]=t.v,this.powerChange=!0}save(t){let i,s=0;for(i=e.GameMapProps.length;s<i;)t[e.GameMapProps[s]]=this[e.GameMapProps[s]],s++;for(t.map=[],s=0,i=this.fsize;s<i;)t.map[s]=this.data[s].getRawValue(),s++;for(t.tileValue=[],s=0,i=this.fsize;s<i;)t.tileValue[s]=this.tilesData[s],s++}load(t){let i,s,a,o=0,r=t.map,n=t.tileValue;for(a=e.GameMapProps.length;o<a;)this[e.GameMapProps[o]]=t[e.GameMapProps[o]],o++;let h=void 0!==r[0].value;for(o=0,a=this.fsize;o<a;)i=o%this.width,s=Math.floor(o/this.width),h?this.setTileValue(i,s,r[o].value):this.setTileValue(i,s,r[o]),o++;for(o=0,a=this.fsize;o<a;)this.tilesData[o]=n[o],o++}testBounds(t,e){return t>=0&&e>=0&&t<this.width&&e<this.height}getId(t,e){return t+e*this.width}getTile(t,e,i){"object"==typeof t&&(e=t.y,t=t.x);let s=this.width,a=this.height;if(t<0||e<0||t>=s||e>=a)return console.warn("getTile called with bad bounds",t,e),new r(n.TILE_INVALID);let o=this.getId(t,e),h=this.data[o];return i?(i.set(h),h):h}getTileValue(t,e){let i=new Error("Invalid parameter");if(arguments.length<1)throw i;if("object"==typeof t&&(e=t.y,t=t.x),!this.testBounds(t,e))throw i;let s=this.getId(t,e);return s in this.data||(this.data[s]=new r(this.defaultValue)),this.data[s].getValue()}getTileFlags(t,e){let i=new Error("Invalid parameter");if(arguments.length<1)throw i;if("object"==typeof t&&(e=t.y,t=t.x),!this.testBounds(t,e))throw i;let s=this.getId(t,e);return s in this.data||(this.data[s]=new r(this.defaultValue)),this.data[s].getFlags()}getTiles(t,e,i,s){let a=new Error("Invalid parameter");if(arguments.length<3)throw a;if(3===arguments.length&&(s=i,i=e,e=t.y,t=t.x),!this.testBounds(t,e))throw a;let o=[];for(let a=e,r=e+s;a<r;a++){o[a-e]=[];for(let s=t,r=t+i;s<r;s++){let t=this.getId(s,a);o[a-e].push(this.data[t])}}return o}getTileValues(t,e,i,s,a){a=a||[];let o=new Error("Invalid parameter");if(arguments.length<3)throw o;3===arguments.length&&(s=i,i=e,e=t.y,t=t.x);let r=this.width,h=this.height;for(let o=e,l=e+s;o<l;o++)for(let s=t,l=t+i;s<l;s++){if(o<0||s<0||o>=h||s>=r){a[(o-e)*i+(s-t)]=n.TILE_INVALID;continue}let l=s+o*r;a[(o-e)*i+(s-t)]=this.data[l].getRawValue()}return a}getTileFromMapOrDefault(t,e,i){switch(e){case P.NORTH:return t.y>0?this.getTileValue(t.x,t.y-1):i;case P.EAST:return t.x<this.width-1?this.getTileValue(t.x+1,t.y):i;case P.SOUTH:return t.y<this.height-1?this.getTileValue(t.x,t.y+1):i;case P.WEST:return t.x>0?this.getTileValue(t.x-1,t.y):i;default:return i}}testOld(t,e){return this.data[t].getValue()!==e}setTile(t,e,i,s){3===arguments.length&&(s=i,i=e,e=t.y,t=t.x);let a=this.getId(t,e),o=this.testOld(a,i);this.data[a].set(i,s),o&&this.upLayer(a,i,t,e)}setTo(t,e,i){void 0===i&&(i=e,e=t.y,t=t.x);let s=this.getId(t,e),a=i.getValue(),o=this.testOld(s,a);this.data[s]=i,o&&this.upLayer(s,a,t,e)}setTileValue(t,e,i){2===arguments.length&&(i=e,e=t.y,t=t.x);let s=this.getId(t,e),a=this.testOld(s,i);this.data[s].setValue(i),a&&this.upLayer(s,i,t,e)}setPaintValue(t,e,i){2===arguments.length&&(i=e,e=t.y,t=t.x);let s=this.getId(t,e);this.upLayer(s,i,t,e)}setTileFlags(t,e,i){let s=new Error("Invalid flag parameter");if(arguments.length<2)throw s;if(2===arguments.length&&(i=e,e=t.y,t=t.x),!this.testBounds(t,e))throw s;let a=this.getId(t,e);this.data[a].setFlags(i)}addTileFlags(t,e,i){let s=new Error("Invalid flag parameter");if(arguments.length<2)throw s;if(2===arguments.length&&(i=e,e=t.y,t=t.x),!this.testBounds(t,e))throw s;let a=this.getId(t,e);this.data[a].addFlags(i)}removeTileFlags(t,e,i){if(arguments.length<2)throw new Error("GameMap removeTileFlags called with too few arguments");if(2===arguments.length&&(i=e,e=t.y,t=t.x),!this.testBounds(t,e))throw new Error("GameMap removeTileFlags called with invalid bounds"+t+", "+e);let s=this.getId(t,e);this.data[s].removeFlags(i)}putZone(t,e,i,s){if(!this.testBounds(t,e)||!this.testBounds(t-1+s,e-1+s))throw new Error("GameMap putZone called with invalid bounds");let a,o,h=i-1-s,l=t-1,d=e-1;for(o=d;o<d+s;o++)for(a=l;a<l+s;a++)a===t&&o===e?this.setTo(a,o,new r(h,n.BNCNBIT|n.ZONEBIT)):this.setTo(a,o,new r(h,n.BNCNBIT)),h+=1}}class dt{constructor(){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],this.treeTable=[0,0,0,34,0,0,36,35,0,32,0,33,30,31,29,37]}construct(t,i,s=!1){if(e.TERRAIN_TREE_LEVEL=-1,e.TERRAIN_LAKE_LEVEL=-1,e.TERRAIN_CURVE_LEVEL=-1,e.ISLAND_RADIUS=18,s&&console.time("start newmap"),this.map=new lt(t||e.MAP_WIDTH,i||e.MAP_HEIGHT),e.TERRAIN_CREATE_ISLAND=a.getRandom(2)-1,e.TERRAIN_CREATE_ISLAND<0&&a.getRandom(100)<10)return this.makeIsland(),this.map;if(1===e.TERRAIN_CREATE_ISLAND?this.makeNakedIsland():this.clearMap(),0!==e.TERRAIN_CURVE_LEVEL){let t=40+a.getRandom(this.map.width-79),e=33+a.getRandom(this.map.height-66),i=new M(t,e);this.doRivers(i)}return 0!==e.TERRAIN_LAKE_LEVEL&&this.makeLakes(),this.smoothRiver(),this.cleanBorder(),0!==e.TERRAIN_TREE_LEVEL&&this.doTrees(),s&&console.timeEnd("start newmap"),this.map}cleanBorder(){let t,e,i,s,a,o=this.map;if(!o.isIsland){for(t=0;t<o.width;t++)i=t+1,i>o.width-1&&(i=o.width-1),s=t-1,s<0&&(s=0),a=1,o.getTileValue(t,a)+o.getTileValue(i,a)+o.getTileValue(s,a)===6&&o.setTile(t,0,n.RIVER,0),a=o.height-2,o.getTileValue(t,a)+o.getTileValue(i,a)+o.getTileValue(s,a)===6&&o.setTile(t,o.height-1,n.RIVER,0);for(e=0;e<o.height;e++)i=e+1,i>o.height-1&&(i=o.height-1),s=e-1,s<0&&(s=0),a=1,o.getTileValue(a,e)+o.getTileValue(a,i)+o.getTileValue(a,s)===6&&o.setTile(0,e,n.RIVER,0),a=o.width-2,o.getTileValue(a,e)+o.getTileValue(a,i)+o.getTileValue(a,s)===6&&o.setTile(o.width-1,e,n.RIVER,0)}}clearMap(){let t=this.map;t.pp.forEach((e=>{t.setTile(e[0],e[1],n.DIRT,0)}))}clearUnnatural(){let t,e=this.map;e.pp.forEach((i=>{t=e.getTileValue(i[0],i[1]),t>n.WOODS&&e.setTile(i[0],i[1],n.DIRT,0)}))}makeNakedIsland(){let t,i,s,o,r=this.map,h=e.ISLAND_RADIUS;for(r.isIsland=!0,r.pp.forEach((e=>{t=e[0],i=e[1],t<5||t>=r.width-5||i<5||i>=r.height-5?r.setTile(t,i,n.RIVER,0):r.setTile(t,i,n.DIRT,0)})),t=0;t<r.width-5;t+=2)o=a.getERandom(h),this.plopBRiver({x:t,y:o}),o=r.height-10-a.getERandom(h),this.plopBRiver({x:t,y:o}),this.plopSRiver({x:t,y:0}),this.plopSRiver({x:t,y:r.height-6});for(i=0;i<r.height-5;i+=2)s=a.getERandom(h),this.plopBRiver({x:s,y:i}),s=r.width-10-a.getERandom(h),this.plopBRiver({x:s,y:i}),this.plopSRiver({x:0,y:i}),this.plopSRiver({x:r.width-6,y:i})}makeIsland(){this.makeNakedIsland(),this.smoothRiver(),this.doTrees()}makeLakes(){let t,i,s=e.TERRAIN_LAKE_LEVEL<0?a.getRandom(10):.5*e.TERRAIN_LAKE_LEVEL;for(;s>0;)t=a.getRandom(this.map.width-21)+10,i=a.getRandom(this.map.height-20)+10,this.makeSingleLake(new M(t,i)),s--}makeSingleLake(t){let e,i=a.getRandom(12)+2;for(;i>0;)e=new M(t,a.getRandom(12)-6,a.getRandom(12)-6),a.getRandom(4)?this.plopSRiver(e):this.plopBRiver(e),i--}treeSplash(t,i){let s,o=e.TERRAIN_TREE_LEVEL<0?a.getRandom(150)+50:a.getRandom(100+2*e.TERRAIN_TREE_LEVEL)+50,r=new M(t,i);for(;o>0;){if(s=P.NORTH+a.getRandom(7),r.move(s),!this.map.testBounds(r.x,r.y))return;this.map.getTileValue(r)===n.DIRT&&this.map.setTile(r,n.WOODS,n.BLBNBIT),o--}}doTrees(){let t=e.TERRAIN_TREE_LEVEL<0?a.getRandom(100)+50:e.TERRAIN_TREE_LEVEL+3;for(;t--;)this.treeSplash(a.getRandom(this.map.width-1),a.getRandom(this.map.height-1));this.smoothTrees(),this.smoothTrees()}smoothRiver(){let t,e,i,s,o,r,h,l,d=this.map,E=this.riverEdge,c=[-1,0,1,0],R=[0,1,0,-1];d.pp.forEach((u=>{if(t=u[0],e=u[1],d.getTileValue(t,e)===n.REDGE){for(h=0,i=0;i<4;i++)h<<=1,s=t+c[i],o=e+R[i],d.testBounds(s,o)&&(r=d.getTileValue(s,o),r!==n.DIRT&&(r<n.WOODS_LOW||r>n.WOODS_HIGH)&&h++);l=E[15&h],l!==n.RIVER&&a.getRandom(1)&&l++,d.setTile(t,e,l,n.BULLBIT)}}))}isTree(t){return t>=n.WOODS_LOW&&t<=n.WOODS_HIGH}smoothTrees(){let t,e,i=this.map;i.pp.forEach((s=>{t=s[0],e=s[1],this.isTree(i.getTileValue(t,e))&&this.smoothTreesAt(t,e,!1)}))}smoothTreesAt(t,e,i){let s=this.map,a=[-1,0,1,0],o=[0,1,0,-1];if(!this.isTree(this.map.getTileValue(t,e)))return;let r,h,l,d,E=0;for(r=0;r<4;r++)E<<=1,h=t+a[r],l=e+o[r],s.testBounds(h,l)&&this.isTree(s.getTileValue(h,l))&&E++;d=this.treeTable[15&E],d?(d!==n.WOODS&&t+e&1&&(d-=8),d>28&&d<38&&(d-=8),s.setTile(t,e,d,n.BLBNBIT)):i||(d>28&&d<38&&(d-=8),s.setTileValue(t,e,d,0))}doRivers(t){let e=P.NORTH+2*a.getRandom(3);this.doBRiver(t,e,e),e=P.rotate180(e);let i=this.doBRiver(t,e,e);e=P.NORTH+2*a.getRandom(3),this.doSRiver(t,e,i)}doBRiver(t,i,s){let o,r;e.TERRAIN_CURVE_LEVEL<0?(o=100,r=200):(o=e.TERRAIN_CURVE_LEVEL+10,r=e.TERRAIN_CURVE_LEVEL+100);let n=new M(t);for(;this.map.testBounds(n.x+4,n.y+4);)this.plopBRiver(n),a.getRandom(o+1)<10?s=i:(a.getRandom(r+1)>90&&(s=P.rotate45(s)),a.getRandom(r+1)>90&&(s=P.rotate45(s,7))),n.move(s);return s}doSRiver(t,i,s){let o,r;e.TERRAIN_CURVE_LEVEL<0?(o=100,r=200):(o=e.TERRAIN_CURVE_LEVEL+10,r=e.TERRAIN_CURVE_LEVEL+100);let n=new M(t);for(;this.map.testBounds(n.x+3,n.y+3);)this.plopSRiver(n),a.getRandom(o+1)<10?s=i:(a.getRandom(r+1)>90&&(s=P.rotate45(s)),a.getRandom(r+1)>90&&(s=P.rotate45(s,7))),n.move(s);return s}putOnMap(t,e,i){if(0===t)return;if(!this.map.testBounds(e,i))return;let s=this.map.getTileValue(e,i);if(s!==n.DIRT){if(s===n.RIVER&&t!==n.CHANNEL)return;if(s===n.CHANNEL)return}this.map.setTile(e,i,t,0)}plopBRiver(t){let e,i=9;for(;i--;)for(e=9;e--;)this.putOnMap(this.BRMatrix[e][i],t.x+i,t.y+e)}plopSRiver(t){let e,i=6;for(;i--;)for(e=6;e--;)this.putOnMap(this.SRMatrix[e][i],t.x+i,t.y+e)}smoothWater(){let t,e,i,s,a,o,r=this.map;r.pp.forEach((o=>{if(s=o[0],a=o[1],t=r.getTileValue(s,a),t>=n.WATER_LOW&&t<=n.WATER_HIGH)for(e=new M(s,a),i=P.BEGIN;i<P.END;i=P.increment90(i))if(t=r.getTileFromMap(e,i,n.WATER_LOW),t<n.WATER_LOW||t>n.WATER_HIGH){r.setTileValue(s,a,n.REDGE,0);break}})),r.pp.forEach((h=>{if(s=h[0],a=h[1],t=r.getTileValue(s,a),t!==n.CHANNEL&&t>=n.WATER_LOW&&t<=n.WATER_HIGH){for(o=!0,e=new M(s,a),i=P.BEGIN;i<P.END;i=P.increment90(i))if(t=r.getTileFromMap(e,i,n.WATER_LOW),t<n.WATER_LOW||t>n.WATER_HIGH){o=!1;break}o&&r.setTileValue(s,a,n.RIVER,0)}})),r.pp.forEach((o=>{if(s=o[0],a=o[1],t=r.getTileValue(s,a),t>=n.WOODS_LOW&&t<=n.WOODS_HIGH)for(e=new M(s,a),i=P.BEGIN;i<P.END;i=P.increment90(i))if(t=r.getTileFromMap(e,i,TILE_INVALID),t===n.RIVER||t===n.CHANNEL){r.setTileValue(s,a,n.REDGE,0);break}}))}}class Et{constructor(t){this._map=t,this._data={}}toKey(t,e){return[t,e].join(",")}fromKey(t){return{x:(t=t.split(","))[0]-0,y:t[1]-0}}clear(){this._data=[]}getTile(t,e){let i=this.toKey(t,e),s=this._data[i];return void 0===s&&(s=this._map.getTile(t,e)),s}getTileValue(t,e){return this.getTile(t,e).getValue()}setTile(t,e,i,s){if(void 0!==s&&i.isTile)throw new Error("Flags supplied with already defined tile");void 0!==s||i.isTile?void 0!==s&&(i=new r(i,s)):i=new r(i);let a=this.toKey(t,e);this._data[a]=i}apply(){let t=Object.keys(this._data);for(let e=0,i=t.length;e<i;e++){let i=this.fromKey(t[e]);this._map.setTo(i,this._data[t[e]])}}}class ct{constructor(){this.TOOLRESULT_OK=0,this.TOOLRESULT_FAILED=1,this.TOOLRESULT_NO_MONEY=2,this.TOOLRESULT_NEEDS_BULLDOZE=3,this.autoBulldoze=!0,this.bulldozerCost=1}init(t,e,i,s=!1){this.toolCost=t,this.result=null,this.isDraggable=s,this._shouldAutoBulldoze=i,this._map=e,this._worldEffects=new Et(e),this._applicationCost=0}clear(){this._applicationCost=0,this._worldEffects.clear()}addCost(t){this._applicationCost+=t}doAutoBulldoze(t,e){let i=this._worldEffects.getTile(t,e);i.isBulldozable()&&(i=o.normalizeRoad(i),(i>=n.TINYEXP&&i<=n.LASTTINYEXP||i<n.HBRIDGE&&i!==n.DIRT)&&(this.addCost(1),this._worldEffects.setTile(t,e,n.DIRT)))}apply(t){this._worldEffects.apply(),t.spend(this._applicationCost),this.clear()}modifyIfEnoughFunding(t){return this.result!==this.TOOLRESULT_OK?(this.clear(),!1):t.totalFunds<this._applicationCost?(this.result=this.TOOLRESULT_NO_MONEY,this.clear(),!1):(this.apply.call(this,t),this.clear(),!0)}setAutoBulldoze(t){this.autoBulldoze=t}getAutoBulldoze(){return this.autoBulldoze}}class Rt extends ct{constructor(){super()}fixSingle(t,e){let i=0,s=this._worldEffects.getTile(t,e);return s=o.normalizeRoad(s),s>=n.ROADS&&s<=n.INTERSECTION?(e>0&&(s=this._worldEffects.getTile(t,e-1),s=o.normalizeRoad(s),(s===n.HRAILROAD||s>=n.ROADBASE&&s<=n.VROADPOWER)&&s!==n.HROADPOWER&&s!==n.VRAILROAD&&s!==n.ROADBASE&&(i|=1)),t<this._map.width-1&&(s=this._worldEffects.getTile(t+1,e),s=o.normalizeRoad(s),(s===n.VRAILROAD||s>=n.ROADBASE&&s<=n.VROADPOWER)&&s!==n.VROADPOWER&&s!==n.HRAILROAD&&s!==n.VBRIDGE&&(i|=2)),e<this._map.height-1&&(s=this._worldEffects.getTile(t,e+1),s=o.normalizeRoad(s),(s===n.HRAILROAD||s>=n.ROADBASE&&s<=n.VROADPOWER)&&s!==n.HROADPOWER&&s!==n.VRAILROAD&&s!==n.ROADBASE&&(i|=4)),t>0&&(s=this._worldEffects.getTile(t-1,e),s=o.normalizeRoad(s),(s===n.VRAILROAD||s>=n.ROADBASE&&s<=n.VROADPOWER)&&s!==n.VROADPOWER&&s!==n.HRAILROAD&&s!==n.VBRIDGE&&(i|=8)),void this._worldEffects.setTile(t,e,h[i]|n.BULLBIT|n.BURNBIT)):s>=n.LHRAIL&&s<=n.LVRAIL10?(e>0&&(s=this._worldEffects.getTile(t,e-1),s=o.normalizeRoad(s),s>=n.RAILHPOWERV&&s<=n.VRAILROAD&&s!==n.RAILHPOWERV&&s!==n.HRAILROAD&&s!==n.HRAIL&&(i|=1)),t<this._map.width-1&&(s=this._worldEffects.getTile(t+1,e),s=o.normalizeRoad(s),s>=n.RAILHPOWERV&&s<=n.VRAILROAD&&s!==n.RAILVPOWERH&&s!==n.VRAILROAD&&s!==n.VRAIL&&(i|=2)),e<this._map.height-1&&(s=this._worldEffects.getTile(t,e+1),s=o.normalizeRoad(s),s>=n.RAILHPOWERV&&s<=n.VRAILROAD&&s!==n.RAILHPOWERV&&s!==n.HRAILROAD&&s!==n.HRAIL&&(i|=4)),t>0&&(s=this._worldEffects.getTile(t-1,e),s=o.normalizeRoad(s),s>=n.RAILHPOWERV&&s<=n.VRAILROAD&&s!==n.RAILVPOWERH&&s!==n.VRAILROAD&&s!==n.VRAIL&&(i|=8)),void this._worldEffects.setTile(t,e,l[i]|n.BULLBIT|n.BURNBIT)):s>=n.LHPOWER&&s<=n.LVPOWER10?(e>0&&(s=this._worldEffects.getTile(t,e-1),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!==n.VPOWER&&s!==n.VROADPOWER&&s!==n.RAILVPOWERH&&(i|=1))),t<this._map.width-1&&(s=this._worldEffects.getTile(t+1,e),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!==n.HPOWER&&s!==n.HROADPOWER&&s!==n.RAILHPOWERV&&(i|=2))),e<this._map.height-1&&(s=this._worldEffects.getTile(t,e+1),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!==n.VPOWER&&s!==n.VROADPOWER&&s!==n.RAILVPOWERH&&(i|=4))),t>0&&(s=this._worldEffects.getTile(t-1,e),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!==n.HPOWER&&s!==n.HROADPOWER&&s!==n.RAILHPOWERV&&(i|=8))),void this._worldEffects.setTile(t,e,d[i]|n.BLBNCNBIT)):void 0}checkZoneConnections(t,e){this.fixSingle(t,e),e>0&&this.fixSingle(t,e-1),t<this._map.width-1&&this.fixSingle(t+1,e),e<this._map.height-1&&this.fixSingle(t,e+1),t>0&&this.fixSingle(t-1,e)}checkBorder(t,e,i){let s;for(t-=1,e-=1,s=0;s<i;s++)this.fixZone(t+s,e-1);for(s=0;s<i;s++)this.fixZone(t-1,e+s);for(s=0;s<i;s++)this.fixZone(t+s,e+i);for(s=0;s<i;s++)this.fixZone(t+i,e+s)}}class ut extends Rt{constructor(t,e,i,s,a){super(),this.init(t,i,!1),this.centreTile=e,this.size=s,this.animated=a}putBuilding(t,e){let i,s,a,o,r=this.centreTile-this.size-1;for(let h=0;h<this.size;h++){s=e+h;for(let e=0;e<this.size;e++)i=t+e,a=r,o=n.BNCNBIT,1===e&&(1===h?o|=n.ZONEBIT:2===h&&this.animated&&(o|=n.ANIMBIT)),this._worldEffects.setTile(i,s,a,o),r++}}prepareBuildingSite(t,e){if(t<0||t+this.size>this._map.width)return this.TOOLRESULT_FAILED;if(e<0||e+this.size>this._map.height)return this.TOOLRESULT_FAILED;let i,s,a;for(let r=0;r<this.size;r++){s=e+r;for(let e=0;e<this.size;e++)if(i=t+e,a=this._worldEffects.getTileValue(i,s),a!==n.DIRT){if(!this.autoBulldoze)return this.TOOLRESULT_NEEDS_BULLDOZE;if(!o.canBulldoze(a))return this.TOOLRESULT_NEEDS_BULLDOZE;this._worldEffects.setTile(i,s,n.DIRT),this.addCost(this.bulldozerCost)}}return this.TOOLRESULT_OK}buildBuilding(t,e){t--,e--;let i=this.prepareBuildingSite(t,e);return i!==this.TOOLRESULT_OK?i:(this.addCost(this.toolCost),this.putBuilding(t,e),this.checkBorder(t,e),this.TOOLRESULT_OK)}doTool(t,e,i){this.result=this.buildBuilding(t,e)}}class Tt extends Rt{constructor(t){super(),this.init(10,t,!0)}putRubble(t,e,i){for(let s=t;s<t+i;s++)for(let t=e;t<e+i;t++)if(this._map.testBounds(s,t)){let e=this._worldEffects.getTile(s,t);e!==n.RADTILE&&e!==n.DIRT&&this._worldEffects.setTile(s,t,n.TINYEXP+a.getRandom(2),n.ANIMBIT|n.BULLBIT)}}layDoze(t,e){let i=this._worldEffects.getTile(t,e);if(!i.isBulldozable())return this.TOOLRESULT_FAILED;switch(i=i.getValue(),i=o.normalizeRoad(i),i){case n.HBRIDGE:case n.VBRIDGE:case n.BRWV:case n.BRWH:case n.HBRDG0:case n.HBRDG1:case n.HBRDG2:case n.HBRDG3:case n.VBRDG0:case n.VBRDG1:case n.VBRDG2:case n.VBRDG3:case n.HPOWER:case n.VPOWER:case n.HRAIL:case n.VRAIL:this._worldEffects.setTile(t,e,n.RIVER);break;default:this._worldEffects.setTile(t,e,n.DIRT)}return this.addCost(1),this.TOOLRESULT_OK}doTool(t,e,i,s){this._map.testBounds(t,e)||(this.result=this.TOOLRESULT_FAILED);let a,r,h,l=this._worldEffects.getTile(t,e),d=l.getValue(),E=0;if(l.isZone())E=o.checkZoneSize(d),a=0,r=0;else{let t=o.checkBigZone(d);E=t.zoneSize,a=t.deltaX,r=t.deltaY}if(E>0){this.addCost(this.bulldozerCost),this._map.powered({v:1,x:t,y:e});let i=t+a,s=e+r;switch(E){case 3:this.putRubble(i-1,s-1,3);break;case 4:this.putRubble(i-1,s-1,4);break;case 6:this.putRubble(i-1,s-1,6)}this.result=this.TOOLRESULT_OK}d===n.RIVER||d===n.REDGE||d===n.CHANNEL?(h=this.layDoze(t,e),d!==this._worldEffects.getTileValue(t,e)&&this.addCost(5)):(h=this.layDoze(t,e),this.checkZoneConnections(t,e)),this.result=h}}class pt extends ct{constructor(t){super(),this.init(10,t,!0)}doTool(t,e,i){if(this._worldEffects.getTileValue(t,e)!==n.DIRT)return void(this.result=this.TOOLRESULT_NEEDS_BULLDOZE);let s,o=a.getRandom(4),r=n.BURNBIT|n.BULLBIT;4===o?(s=n.FOUNTAIN,r|=n.ANIMBIT):s=o+n.WOODS2,this._worldEffects.setTile(t,e,s,r),this.addCost(10),this.result=this.TOOLRESULT_OK}}class mt extends Rt{constructor(t){super(),this.init(20,t,!0,!0)}layRail(t,e){this.doAutoBulldoze(t,e);let i=this.toolCost,s=this._worldEffects.getTileValue(t,e);switch(s=o.normalizeRoad(s),s){case n.DIRT:this._worldEffects.setTile(t,e,n.LHRAIL|n.BULLBIT|n.BURNBIT);break;case n.RIVER:case n.REDGE:case n.CHANNEL:if(i=100,t<this._map.width-1&&(s=this._worldEffects.getTileValue(t+1,e),s=o.normalizeRoad(s),s==n.RAILHPOWERV||s==n.HRAIL||s>=n.LHRAIL&&s<=n.HRAILROAD)){this._worldEffects.setTile(t,e,n.HRAIL,n.BULLBIT);break}if(t>0&&(s=this._worldEffects.getTileValue(t-1,e),s=o.normalizeRoad(s),s==n.RAILHPOWERV||s==n.HRAIL||s>n.VRAIL&&s<n.VRAILROAD)){this._worldEffects.setTile(t,e,n.HRAIL,n.BULLBIT);break}if(e<this._map.height-1&&(s=this._worldEffects.getTileValue(t,e+1),s=o.normalizeRoad(s),s==n.RAILVPOWERH||s==n.VRAILROAD||s>n.HRAIL&&s<n.HRAILROAD)){this._worldEffects.setTile(t,e,n.VRAIL,n.BULLBIT);break}if(e>0&&(s=this._worldEffects.getTileValue(t,e-1),s=o.normalizeRoad(s),s==n.RAILVPOWERH||s==n.VRAILROAD||s>n.HRAIL&&s<n.HRAILROAD)){this._worldEffects.setTile(t,e,n.VRAIL,n.BULLBIT);break}return this.TOOLRESULT_FAILED;case n.LHPOWER:this._worldEffects.setTile(t,e,n.RAILVPOWERH,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.LVPOWER:this._worldEffects.setTile(t,e,n.RAILHPOWERV,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.ROADS:this._worldEffects.setTile(t,e,n.VRAILROAD,n.BURNBIT|n.BULLBIT);break;case n.ROADS2:this._worldEffects.setTile(t,e,n.HRAILROAD,n.BURNBIT|n.BULLBIT);break;default:return this.TOOLRESULT_FAILED}return this.addCost(i),this.checkZoneConnections(t,e),this.TOOLRESULT_OK}doTool(t,e,i){this.result=this.layRail(t,e)}}class At extends Rt{constructor(t){super(),this.doTool=function(t,e,i){this.result=this.layRoad(t,e)},this.init(10,t,!0,!0)}layRoad(t,e){this.doAutoBulldoze(t,e);let i=this._worldEffects.getTileValue(t,e),s=this.toolCost;switch(i){case n.DIRT:this._worldEffects.setTile(t,e,n.ROADS,n.BULLBIT|n.BURNBIT);break;case n.RIVER:case n.REDGE:case n.CHANNEL:if(s=50,t<this._map.width-1&&(i=this._worldEffects.getTileValue(t+1,e),i=o.normalizeRoad(i),i===n.VRAILROAD||i===n.HBRIDGE||i>=n.ROADS&&i<=n.HROADPOWER)){this._worldEffects.setTile(t,e,n.HBRIDGE,n.BULLBIT);break}if(t>0&&(i=this._worldEffects.getTileValue(t-1,e),i=o.normalizeRoad(i),i===n.VRAILROAD||i===n.HBRIDGE||i>=n.ROADS&&i<=n.INTERSECTION)){this._worldEffects.setTile(t,e,n.HBRIDGE,n.BULLBIT);break}if(e<this._map.height-1&&(i=this._worldEffects.getTileValue(t,e+1),i=o.normalizeRoad(i),i===n.HRAILROAD||i===n.VROADPOWER||i>=n.VBRIDGE&&i<=n.INTERSECTION)){this._worldEffects.setTile(t,e,n.VBRIDGE,n.BULLBIT);break}if(e>0&&(i=this._worldEffects.getTileValue(t,e-1),i=o.normalizeRoad(i),i===n.HRAILROAD||i===n.VROADPOWER||i>=n.VBRIDGE&&i<=n.INTERSECTION)){this._worldEffects.setTile(t,e,n.VBRIDGE,n.BULLBIT);break}return this.TOOLRESULT_FAILED;case n.LHPOWER:this._worldEffects.setTile(t,e,n.VROADPOWER|n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.LVPOWER:this._worldEffects.setTile(t,e,n.HROADPOWER|n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.LHRAIL:this._worldEffects.setTile(t,e,n.HRAILROAD|n.BURNBIT|n.BULLBIT);break;case n.LVRAIL:this._worldEffects.setTile(t,e,n.VRAILROAD|n.BURNBIT|n.BULLBIT);break;default:return this.TOOLRESULT_FAILED}return this.addCost(s),this.checkZoneConnections(t,e),this.TOOLRESULT_OK}}class gt extends ct{constructor(t){super(),this.init(0,t,!1,!1),this.txt=""}classifyPopulationDensity(t,e,i){var s=i.populationDensityMap.worldGet(t,e);s>>=6,s&=3,this.txt+="Density: "+p.densityStrings[s]+"<br>"}classifyLandValue(t,e,i){var s=i.landValueMap.worldGet(t,e),a=0;s>=150?a=3:s>=80?a=2:s>=30&&(a=1),this.txt+="Value: "+p.landValueStrings[a]+"<br>"}classifyCrime(t,e,i){var s=i.crimeRateMap.worldGet(t,e);s>>=6,s&=3,this.txt+="Crime: "+p.crimeStrings[s]+"<br>"}classifyPollution(t,e,i){var s=i.pollutionDensityMap.worldGet(t,e);s>>=6,s&=3,this.txt+="Pollution: "+p.pollutionStrings[s]+"<br>"}classifyRateOfGrowth(t,e,i){var s=i.rateOfGrowthMap.worldGet(t,e);s>>=6,s&=3,this.txt+="Growth: "+p.rateStrings[s]}classifyDebug(t,e,i){}classifyZone(t,e){var i=[n.DIRT,n.RIVER,n.TREEBASE,n.RUBBLE,n.FLOOD,n.RADTILE,n.FIRE,n.ROADBASE,n.POWERBASE,n.RAILBASE,n.RESBASE,n.COMBASE,n.INDBASE,n.PORTBASE,n.AIRPORTBASE,n.COALBASE,n.FIRESTBASE,n.POLICESTBASE,n.STADIUMBASE,n.NUCLEARBASE,n.HBRDG0,n.RADAR0,n.FOUNTAIN,n.INDBASE2,n.FOOTBALLGAME1,n.VBRDG0,952],s=this._map.getTileValue(t,e);s>=n.COALSMOKE1&&s<n.FOOTBALLGAME1&&(s=n.COALBASE);var a,o=0;for(o=0,a=i.length-1;o<a&&!(s<i[o+1]);o++);this.txt="Zone: "+p.zoneTypes[o]+"<br>"}getInfo(){return this.txt}doTool(t,e,i,s){this._map.getTileValue(t,e),this._map.getTile(t,e),this.classifyZone(t,e),this.classifyPopulationDensity(t,e,i),this.classifyLandValue(t,e,i),this.classifyCrime(t,e,i),this.classifyPollution(t,e,i),this.classifyRateOfGrowth(t,e,i),this.classifyDebug(t,e,i),s.sendMessage(R.QUERY_WINDOW_NEEDED),this.result=this.TOOLRESULT_OK}}class ft extends Rt{constructor(t){super(),this.init(5,t,!0,!0)}layWire(t,e){this.doAutoBulldoze(t,e);let i=5,s=this._worldEffects.getTileValue(t,e);switch(s=o.normalizeRoad(s),s){case n.DIRT:this._worldEffects.setTile(t,e,n.LHPOWER,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.RIVER:case n.REDGE:case n.CHANNEL:if(i=25,t<this._map.width-1&&(s=this._worldEffects.getTile(t+1,e),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!=n.HROADPOWER&&s!=n.RAILHPOWERV&&s!=n.HPOWER))){this._worldEffects.setTile(t,e,n.VPOWER,n.CONDBIT|n.BULLBIT);break}if(t>0&&(s=this._worldEffects.getTile(t-1,e),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!=n.HROADPOWER&&s!=n.RAILHPOWERV&&s!=n.HPOWER))){this._worldEffects.setTile(t,e,n.VPOWER,n.CONDBIT|n.BULLBIT);break}if(e<this._map.height-1&&(s=this._worldEffects.getTile(t,e+1),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!=n.VROADPOWER&&s!=n.RAILVPOWERH&&s!=n.VPOWER))){this._worldEffects.setTile(t,e,n.HPOWER,n.CONDBIT|n.BULLBIT);break}if(e>0&&(s=this._worldEffects.getTile(t,e-1),s.isConductive()&&(s=s.getValue(),s=o.normalizeRoad(s),s!=n.VROADPOWER&&s!=n.RAILVPOWERH&&s!=n.VPOWER))){this._worldEffects.setTile(t,e,n.HPOWER,n.CONDBIT|n.BULLBIT);break}return this.TOOLRESULT_FAILED;case n.ROADS:this._worldEffects.setTile(t,e,n.HROADPOWER,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.ROADS2:this._worldEffects.setTile(t,e,n.VROADPOWER,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.LHRAIL:this._worldEffects.setTile(t,e,n.RAILHPOWERV,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;case n.LVRAIL:this._worldEffects.setTile(t,e,n.RAILVPOWERH,n.CONDBIT|n.BURNBIT|n.BULLBIT);break;default:return this.TOOLRESULT_FAILED}return this.addCost(i),this.checkZoneConnections(t,e),this.TOOLRESULT_OK}doTool(t,e,i){this.result=this.layWire(t,e)}}const Ot=self.webkitPostMessage||self.postMessage;var St,It,Lt=!0;self.onmessage=function(t){Dt.message(t)};class Dt{static message(t){var e=t.data.tell;"INIT"==e&&(t.data.returnMessage&&(It=t.data.returnMessage,Lt=!1),St=new Pt(t.data.timestep)),"NEWMAP"==e&&St.newMap(),"PLAYMAP"==e&&St.playMap(),"TOOL"==e&&St.tool(t.data.name),"MAPCLICK"==e&&St.mapClick(t.data.x,t.data.y,t.data.single||!1),"DIFFICULTY"==e&&St.changeDifficulty(t.data.n),"SPEED"==e&&St.changeSpeed(t.data.n),"BUDGET"==e&&St.handleBudgetRequest(),"NEWBUDGET"==e&&St.setBudget(t.data.budgetData),"DISASTER"==e&&St.setDisaster(t.data.disaster),"EVAL"==e&&St.getEvaluation(),"SAVEGAME"==e&&St.saveGame(t.data.saveCity),"LOADGAME"==e&&St.loadGame(t.data.isStart),"MAKELOADGAME"==e&&St.makeLoadGame(t.data.savegame,t.data.isStart)}static post(t,e){Lt?Ot(t,e):It({data:t})}}var _t=function(){St.tick()};class Pt{constructor(t){this.timestep=t,this.mapSize=[128,128],this.difficulty=1,this.speed=2,this.oldSpeed=0,this.mapGen=new dt,this.simulation=null,this.gameTools=null,this.animationManager=null,this.map=null,this.isPaused=!1,this.simNeededBudget=!1,this.currentTool=null,this.timer=null,this.infos=[],this.sprites=[],this.spritesData=null,this.animsData=null,this.spritesData=[],this.power=null,Dt.post({tell:"READY"})}next(t=0){this.timer=setTimeout(_t,t)}stop(){null!==this.timer&&(clearInterval(this.timer),this.timer=null)}tick(){this.simulation.simTick()&&(this.infos=this.simulation.infos,this.processMessages(St.simulation.messageManager.getMessages()),this.animatedTiles(),this.simulation.spriteManager.moveObjects(),this.calculateSprites(),Dt.post({tell:"RUN",infos:this.infos,tilesData:this.map.tilesData,powerData:this.map.powerData,sprites:this.spritesData,layer:this.map.layer}),this.map.resetLayer()),this.next()}newMap(){this.map=this.mapGen.construct(this.mapSize[0],this.mapSize[1]),Dt.post({tell:"NEWMAP",tilesData:this.map.tilesData,mapSize:this.mapSize,island:this.map.isIsland,trans:false})}playMap(t){var e=new E,i=2e4;1==this.difficulty&&(i=1e4),2==this.difficulty&&(i=5e3),this.gameTools={airport:new ut(1e4,n.AIRPORT,this.map,6,!1),bulldozer:new Tt(this.map),coal:new ut(3e3,n.POWERPLANT,this.map,4,!1),commercial:new ut(100,n.COMCLR,this.map,3,!1),fire:new ut(500,n.FIRESTATION,this.map,3,!1),industrial:new ut(100,n.INDCLR,this.map,3,!1),nuclear:new ut(5e3,n.NUCLEAR,this.map,4,!0),park:new pt(this.map),police:new ut(500,n.POLICESTATION,this.map,3,!1),port:new ut(3e3,n.PORT,this.map,4,!1),rail:new mt(this.map),residential:new ut(100,n.FREEZ,this.map,3,!1),road:new At(this.map),query:new gt(this.map),stadium:new ut(5e3,n.STADIUM,this.map,4,!1),wire:new ft(this.map)},this.animationManager=new ht(this.map),t?(i=this.savedGame.totalFunds,this.speed=this.savedGame.speed,this.difficulty=this.savedGame.difficulty,this.simulation=new rt(this.map,this.difficulty,this.speed,!0,this.savedGame),e.sendMessage(R.WELCOMEBACK)):(this.simulation=new rt(this.map,this.difficulty,this.speed,!0),e.sendMessage(R.WELCOME)),this.simulation.budget.setFunds(i),this.processMessages(e.getMessages()),this.isPaused=!1,this.tick()}changeSpeed(t){this.speed=t,this.simulation.setSpeed(this.speed),0===this.speed?(this.isPaused=!0,this.stop()):this.isPaused&&(this.isPaused=!1,this.stop(),this.tick())}changeDifficulty(t){this.difficulty=t,this.simulation&&this.simulation.setDifficulty(this.difficulty)}animatedTiles(){var t=this.animationManager.getTiles(0,0,this.mapSize[0]+1,this.mapSize[1]+1,this.isPaused),i=t.length;for(this.animsData=new e.M_ARRAY_TYPE(i);i--;){var s=t[i];this.animsData[i]=[s.tileValue,s.x,s.y]}}calculateSprites(){this.sprites=this.simulation.spriteManager.getSpritesInView(0,0,this.mapSize[0]+1,this.mapSize[1]+1);for(var t=this.sprites.length;t--;){var e=this.sprites[t];this.spritesData[t]=[e.type,e.frame,e.x||0,e.y||0]}}processMessages(t){for(var e=!1,i=0,s=t.length;i<s;i++){var a=t[i];switch(a.message){case R.BUDGET_NEEDED:this.simNeededBudget=!0,this.handleBudgetRequest();break;case R.QUERY_WINDOW_NEEDED:Dt.post({tell:"QUERY",queryTxt:this.currentTool.getInfo()});break;default:if(!e&&void 0!==p.goodMessages[a.message]){this.infos[8]=p.goodMessages[a.message];break}if(!e&&void 0!==p.badMessages[a.message]){e=!0,this.infos[8]=p.badMessages[a.message];break}if(!e&&void 0!==p.neutralMessages[a.message]){e=!0,this.infos[8]=p.neutralMessages[a.message];break}}}}tool(t){null!==this.currentTool&&this.currentTool.clear(),this.currentTool="none"!==t?this.gameTools[t]:null}destroy(t,e){console.log("isDestroy")}findId(t,e){return t+e*this.mapSize[1]}mapClick(t,e,i){if(null!==this.currentTool){var s=this.simulation.budget;this.simulation.evaluation;var a=new E;switch(this.currentTool.doTool(t,e,this.simulation.blockMaps,a),this.currentTool.modifyIfEnoughFunding(s,a),this.currentTool.result){case this.currentTool.TOOLRESULT_NEEDS_BULLDOZE:p.toolMessages.needsDoze;break;case this.currentTool.TOOLRESULT_NO_MONEY:p.toolMessages.noMoney;break;default:i||Dt.post({tell:"BUILD",x:t,y:e})}this.processMessages(a.getMessages())}}setDisaster(t){if(t!==e.DISASTER_NONE){var i=new E;switch(t){case e.DISASTER_MONSTER:this.simulation.spriteManager.makeMonster(i);break;case e.DISASTER_FIRE:this.simulation.disasterManager.makeFire(i);break;case e.DISASTER_FLOOD:this.simulation.disasterManager.makeFlood(i);break;case e.DISASTER_CRASH:this.simulation.disasterManager.makeCrash(i);break;case e.DISASTER_MELTDOWN:this.simulation.disasterManager.makeMeltdown(i);break;case e.DISASTER_TORNADO:this.simulation.spriteManager.makeTornado(i)}this.processMessages(i.getMessages())}}setBudget(t){this.simulation.budget.cityTax=t[0],this.simulation.budget.roadPercent=t[1]/100,this.simulation.budget.firePercent=t[2]/100,this.simulation.budget.policePercent=t[3]/100}handleBudgetRequest(){this.budgetShowing=!0;let t={roadFund:this.simulation.budget.roadFund,roadRate:Math.floor(100*this.simulation.budget.roadPercent),fireFund:this.simulation.budget.fireFund,fireRate:Math.floor(100*this.simulation.budget.firePercent),policeFund:this.simulation.budget.policeFund,policeRate:Math.floor(100*this.simulation.budget.policePercent),taxRate:this.simulation.budget.cityTax,totalFunds:this.simulation.budget.totalFunds,taxesCollected:this.simulation.budget.taxFund};Dt.post({tell:"BUDGET",budgetData:t}),this.simNeededBudget?(this.simulation.budget.doBudgetWindow(),this.simNeededBudget=!1):this.simulation.budget.updateFundEffects()}getEvaluation(){let t=this.simulation.evaluation,e="";for(var i=0;i<4;i++){let s=t.getProblemNumber(i),a="";-1!==s&&(a=p.problems[s]),e+=a+"<br>"}let s=[t.cityYes,e];Dt.post({tell:"EVAL",evalData:s})}saveGame(t){let i={name:"Yoooooo",everClicked:!0};i.speed=this.speed,i.difficulty=this.difficulty,i.version=e.CURRENT_VERSION,i.city=t,this.simulation.save(i),i=JSON.stringify(i),Dt.post({tell:"SAVEGAME",gameData:i,key:e.KEY})}loadGame(t){var i=t||!1;Dt.post({tell:"LOADGAME",key:e.KEY,isStart:i})}makeLoadGame(t,i){let s=i||!1;clearInterval(this.timer),this.savedGame=JSON.parse(t),this.map=new lt(e.MAP_WIDTH,e.MAP_HEIGHT),this.map.load(this.savedGame),Dt.post({tell:"FULLREBUILD",tilesData:this.map.tilesData,mapSize:this.mapSize,island:this.map.isIsland,cityData:this.savedGame.city,isStart:s})}transitionOldSave(t){switch(t.version){case 1:t.everClicked=!1;case 2:t.pollutionMaxX=Math.floor(t.width/2),t.pollutionMaxY=Math.floor(t.height/2),t.cityCentreX=Math.floor(t.width/2),t.cityCentreY=Math.floor(t.height/2)}}}t.CityGame=Dt,t.MainGame=Pt,Object.defineProperty(t,"__esModule",{value:!0})}));
|