var Incremancer;(()=>{"use strict";var e={};function t(e,t){return Math.sqrt(e*e+t*t)}function s(e,t,s,i){return Math.sqrt((e-s)*(e-s)+(t-i)*(t-i))}function i(e,t,s,i){const a=Math.abs(e-s),r=Math.abs(t-i);return.4*(a+r)+.56*Math.max(a,r)}function a(e,t){return e[Math.floor(t*e.length)]}function r(e){return o(e,2)}function n(e){return o(e,e>1e3?2:0)}function o(e,t){return e||(e=0),e>=1e15?e.toExponential(t).replace("+",""):e>=1e12?(e/1e12).toFixed(t)+"T":e>=1e9?(e/1e9).toFixed(t)+"B":e>=1e6?(e/1e6).toFixed(t)+"M":e>=1e3?(e/1e3).toFixed(t)+"K":e.toFixed(t)}function h(e,t,s,i){return 1==t?Math.floor(i/e):Math.floor(Math.log(i*(t-1)/(e*Math.pow(t,s))+1)/Math.log(t))}function l(e,t,s,i){return 1==t?e*i:e*(Math.pow(t,s)*(Math.pow(t,i)-1)/(t-1))}function d(e,t){const s=document.getElementById("champ-hold").getBoundingClientRect();let i=e.clientX-s.x;const a=e.clientY-s.y;i>s.width/2&&(i-=t.getElementsByClassName("tooltip")[0].getBoundingClientRect().width),t.getElementsByClassName("tooltip")[0].style.top=a+20+"px",t.getElementsByClassName("tooltip")[0].style.left=i+20+"px"}let c,u,p,g,m,b,f,y,x;(e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})})(e);let v,S,M,k,w,T,C,D={x:800,y:600,defaultScale:1},P={x:600,y:600};function z(e){this.data=e.data,this.dragging=!0,this.dragOffset=this.data.getLocalPosition(this),this.dragOffset.x*=this.scale.x,this.dragOffset.y*=this.scale.y,this.dragStartX=this.x,this.dragStartY=this.y,B=0}function I(){this.dragging=!1,this.data=null,B=0}let B=0,R=0;function H(e){if(T.zombieCursor){T.zombieCursor.position=e.data.getLocalPosition(this.parent);const t=e.data.getLocalPosition(x);T.mouseOutOfBounds=t.x<0||t.y<0||t.x>x.width||t.y>x.height}if(e.data.originalEvent.touches&&e.data.originalEvent.touches.length>1)!function(e){const t=Math.abs(e.data.originalEvent.touches[0].clientX-e.data.originalEvent.touches[1].clientX);B?R+5010&&(A(t>B?1:-1,null),R=Date.now(),B=t):B=t}(e);else if(this.dragging){const e=this.data.getLocalPosition(this.parent);this.x=e.x-this.dragOffset.x,this.y=e.y-this.dragOffset.y,F(this),s(this.dragStartX,this.dragStartY,this.x,this.y)>5&&(this.hasMoved=!0)}}function F(e){const t=P.x*e.scale.x,s=P.y*e.scale.y;e.x>.5*D.x&&(e.x=.5*D.x),e.x+t<.5*D.x&&(e.x=.5*D.x-t),e.y>.5*D.y&&(e.y=.5*D.y),e.y+s<.5*D.y&&(e.y=.5*D.y-s)}function E(e){this.hasMoved||v.currentState!=v.states.playingLevel||(Y.shift?T.spawnAllZombies(e.data.getLocalPosition(this).x,e.data.getLocalPosition(this).y):T.spawnZombie(e.data.getLocalPosition(this).x,e.data.getLocalPosition(this).y)),this.hasMoved=!1}function A(e,t){if(R+50>Date.now())return;R=Date.now();const s=c;t||(t={x:.5*D.x,y:.5*D.y});const i=P.x*s.scale.x,a=P.y*s.scale.y;t.x>s.x+i&&(t.x=s.x+i),t.xs.y+a&&(t.y=s.y+a);const r=(t.x-s.x)/s.scale.x,n=(t.y-s.y)/s.scale.y;e>0?s.scale.x<10&&(s.scale.x=s.scale.y=1.1*s.scale.x,T.zombieCursor&&T.zombieCursor.scale&&(T.zombieCursor.scale.x=T.zombieCursor.scale.y=1.1*T.zombieCursor.scale.x)):Math.max(i,a)>.8*Math.min(D.y,D.x)&&(s.scale.x=s.scale.y=.9*s.scale.x,T.zombieCursor&&T.zombieCursor.scale&&(T.zombieCursor.scale.x=T.zombieCursor.scale.y=.9*T.zombieCursor.scale.x)),s.x=t.x-r*s.scale.x,s.y=t.y-n*s.scale.y,F(s)}function L(e){e.preventDefault();const t={x:e.clientX*(D.x/document.body.clientWidth),y:e.clientY*(D.y/document.body.clientHeight)};e.deltaY<0||e.deltaX<0?A(1,t):A(-1,t)}function Z(e=!1){e&&(c.scale.x=D.defaultScale,c.scale.y=D.defaultScale,T.zombieCursor&&(T.zombieCursor.scale.x=T.zombieCursor.scale.y=T.zombieCursorScale*D.defaultScale)),c.x=(D.x-P.x*c.scale.x)/2,c.y=(D.y-P.y*c.scale.y)/2}const G={x:0,y:0,width:1e3,height:1e3,hideParticle(e,t){return ethis.x+this.width||t>this.y+this.height},update(){this.x=-c.x/c.scale.x,this.y=-c.y/c.scale.y,this.width=D.x/c.scale.x,this.height=D.y/c.scale.y}},X=new PIXI.Matrix;function U(e,t){!function(e){const t=Y;let s=!1;const i=c;t.w&&(i.y+=t.scrollSpeed*e,s=!0),t.a&&(i.x+=t.scrollSpeed*e,s=!0),t.s&&(i.y-=t.scrollSpeed*e,s=!0),t.d&&(i.x-=t.scrollSpeed*e,s=!0),s&&F(i)}(e),G.update(),e*=v.gameSpeed,M.update(e),C.update(e),T.update(e),k.update(e),w.update(e),S.update(e),function(e,t){if(C.vipEscaping&&void 0!==C.vip?y.alpha+=e:(y.alpha-=e,y.alpha<0&&(y.alpha=0)),y.alpha>0){y.alpha>1&&(y.alpha=1),y.visible=!0,y.x=5,y.y=D.y-305;const e=c.scale.x,s=c.scale.y,i=c.x,a=c.y;c.position.set(0,0),C.vip&&(X.tx=-2*C.vip.x+150,X.ty=-2*C.vip.y+150),c.scale.set(2,2),t.renderer.render(c,f,void 0,X),c.scale.set(e,s),c.position.set(i,a)}else y.visible=!1}(e,t)}function N(){const e=Math.min(500+50*v.level,1500),t=Math.random()*e/3;P={x:e+t,y:e-t},x&&(x.width=P.x,x.height=P.y),c.hitArea=new PIXI.Rectangle(0,0,P.x,P.y)}function O(){const e=document.body.clientWidth,t=document.body.clientHeight;D={x:e,y:t,defaultScale:Math.max(e,t)/1e3},Y.scrollSpeed=Math.max(e,t)/4}new Map,window.onload=function(){v=ne.getInstance(),S=new Qe,M=new Oe,k=new Ue,w=new Xe,T=new Ae,C=new Se,v.loadData(),v.onReady(),O(),function(){PIXI.settings.SCALE_MODE=PIXI.SCALE_MODES.NEAREST;const e=new PIXI.Application({width:D.x,height:D.y,backgroundColor:1066256,resolution:v.persistentData.resolution||1,antialias:!1,resizeTo:window});document.body.appendChild(e.view),PIXI.utils.isWebGLSupported()||console.error("Warning: WebGL support not detected. Game performance may be slower."),function(e){c=new PIXI.Container,u=new PIXI.Container,p=new PIXI.Container,g=new PIXI.Container,g.sortableChildren=!0,b=new PIXI.Container,m=new PIXI.Container,f=PIXI.RenderTexture.create({width:300,height:300}),y=new PIXI.Sprite(f),y.visible=!1,y.alpha=0,m.addChild(y),c.addChild(u),c.addChild(p),c.addChild(g),c.addChild(b),e.stage.addChild(c),e.stage.addChild(m),c.interactive=!0,c.interactiveChildren=!1,c.on("pointerdown",z),c.on("pointerup",I),c.on("pointerupoutside",I),c.on("pointermove",H),c.on("click",E),c.on("tap",E),document.getElementsByTagName("canvas")[0].onwheel=L,document.getElementsByTagName("canvas")[0].oncontextmenu=function(e){e.preventDefault()}}(e),e.loader.add("sprites/ground.json").add("sprites/megagraveyard.png").add("sprites/graveyard.json").add("sprites/buildings.json").add("sprites/humans.json").add("sprites/cop.json").add("sprites/dogs.json").add("sprites/army.json").add("sprites/doctor.json").add("sprites/zombie.json").add("sprites/golem.json").add("sprites/bonecollector.json").add("sprites/harpy.json").add("sprites/objects2.json").add("sprites/fenceposts.json").add("sprites/trees2.json").add("sprites/fortress.json").add("sprites/tank.json").add("sprites/skeleton.json").load((function(){v.app=e,N(),x=new PIXI.TilingSprite(PIXI.Texture.from("grass.png")),x.texture.baseTexture.mipmap=PIXI.MIPMAP_MODES.OFF,x.width=P.x,x.height=P.y,u.addChild(x),v.setupLevel(),setTimeout((function(){Z(!0)})),e.ticker.add((t=>{U(e.ticker.deltaMS/1e3,e),v.frameRate=e.ticker.FPS}))}))}(),window.self!==window.top&&(""!=document.referrer&&-1==document.referrer.indexOf("kongregate.com")&&-1==document.referrer.indexOf("konggames.com")&&-1==document.referrer.indexOf("gti.nz")?{}:-1===document.referrer.indexOf("kongregate.com")&&-1===document.referrer.indexOf("konggames.com")||kongregateAPI.loadAPI((function(){window.kongregate=kongregateAPI.getAPI(),v.kongregate=!0,v.loginInUsingPlayFab()}))),document.addEventListener("visibilitychange",(function(){"hidden"==document.visibilityState?v.hidden=!0:v.hidden=!1}),!1)},window.onresize=function(){O()};const Y={scrollSpeed:200,w:!1,a:!1,s:!1,d:!1,shift:!1};window.onblur=function(){Y.w=Y.a=Y.s=Y.d=!1,Y.shift=!1},window.onkeydown=function(e){switch(e.keyCode){case 16:case 17:Y.shift=!0;break;case 87:case 38:Y.w=!0;break;case 65:case 37:Y.a=!0;break;case 83:case 40:Y.s=!0;break;case 68:case 39:Y.d=!0;break;default:return!0}return!1},window.onkeyup=function(e){switch(e.keyCode){case 16:case 17:Y.shift=!1;break;case 87:case 38:Y.w=!1;break;case 65:case 37:Y.a=!1;break;case 83:case 40:Y.s=!1;break;case 68:case 39:Y.d=!1;break;default:return!0}return!1};class W{constructor(e,t,s,i,a,r,n,o,h){this.id=e,this.name=t,this.tooltip=s,this.itemText=i,this.cooldown=a,this.duration=r,this.energyCost=n,this.start=o,this.end=h,this.timer=0,this.onCooldown=!1,this.active=!1,this.cooldownLeft=0}}class q{constructor(){if(this.cooldownReduction=0,this.timeExtension=0,this.costReduction=0,this.skeleton=new Xe,this.zombies=new Ae,this.humans=new Se,this.spellMap=new Map,this.spells=[new W(1,"Time Warp","Speed up the flow of time for 30 seconds","",90,30,0,(function(){ne.getInstance().gameSpeed=2}),(function(){ne.getInstance().gameSpeed=1})),new W(2,"Energy Charge","5x Energy rate for 20 seconds, cost 50 energy","",160,20,50,(function(){ne.getInstance().energySpellMultiplier=5}),(function(){ne.getInstance().energySpellMultiplier=1})),new W(3,"Detonate","Turns your zombies into fast moving living bombs, cost 69 energy... nice","",80,8,69,(function(){(new q).zombies.detonate=!0}),(function(){(new q).zombies.detonate=!1})),new W(4,"Earth Freeze","Freeze all humans in place preventing them from moving for 15 seconds, cost 75 energy","",50,15,75,(function(){(new q).humans.frozen=!0}),(function(){(new q).humans.frozen=!1})),new W(5,"Gigazombies","For 5 seconds any zombies spawned will be giants with 10x health and attack damage, cost 100 energy","",260,5,100,(function(){(new q).zombies.super=!0}),(function(){(new q).zombies.super=!1})),new W(6,"Incinerate","Burns humans near the skeleton champion","Has a chance to cast Incinerate when attacking, burning all humans within a large radius of the Skeleton",1,10,10,(function(){(new q).skeleton.incinerate(),this.timer=1}),(function(){})),new W(7,"Pandemic","Causes plague to spread","Has a chance to cast Pandemic when attacking, causing infected humans to spread the plague to each other for 20 seconds",10,20,10,(function(){(new q).humans.pandemic=!0}),(function(){(new q).humans.pandemic=!1})),new W(8,"Part Storm","Doubles parts","Has a chance to cast Part Storm when attacking, doubling the parts production of your factory machines for 15 seconds",10,15,10,(function(){(new se).storm=!0}),(function(){(new se).storm=!1}))],q.instance)return q.instance;q.instance=this,this.spells.forEach((e=>this.spellMap.set(e.id,e)))}lockAllSpells(){for(let e=0;ee.unlocked))}castSpell(e){const t=ne.getInstance();e.onCooldown||e.active||!e.unlocked||e.energyCost-this.costReduction>t.energy||(t.energy-=e.energyCost-this.costReduction,e.onCooldown=!0,e.cooldownLeft=e.cooldown*this.cooldownReduction,e.active=!0,e.timer=e.duration+this.timeExtension,e.start(),t.sendMessage(e.name))}castSpellNoMana(e){const t=this.spellMap.get(e);t&&!t.active&&(t.active=!0,t.timer=t.duration+this.timeExtension,t.start(),ne.getInstance().sendMessage(t.name))}updateSpells(e){for(let t=0;t0){const e=this.discardedSprites.pop();return e.visible=!0,e}const e=this.create(this.texture);return this.container.addChild(e),this.sprites.push(e),e}}class ee{constructor(){if(this.gameModel=ne.getInstance(),this.humans=new Se,this.discardedWalls=[],this.discardedContainers=[],this.discardedFloorSprites=[],this.buildings=[],this.buildingsByPopularity=[],this.buildingMap=[],this.roadSprite=null,this.roadTexture=null,this.entranceWidth=16,this.entranceDepth=16,this.cornerDistance=16,this.minBuildings=3,this.wallWidth=4,this.graveyardCollision=null,this.graveYardLocation={x:0,y:0},this.graveYardPosition=null,this.wallCollisionBuffer=3,this.fastDistance=i,this.pathFindStepSize=5,this.dx=0,this.dy=0,this.stepsToTake=10,this.hasHit=!1,this.vector=null,this.corner=null,this.hitbuilding=!1,this.insideBuilding=!1,this.treeSprites=[],this.treeTextures=[],this.armyTextures=[],ee.instance)return ee.instance;ee.instance=this}getRandomBuilding(){return a(this.buildingsByPopularity,Math.random())}roomNoOverlap(e,t){return e.x>t.x+t.width+50||e.x+e.width+50t.y+t.height+50||e.y+e.height+50this.roadSprite.y)}getWall(e){if(this.discardedWalls.length>0){const t=this.discardedWalls.pop();return t.texture=e,t}return new V(e)}makeHorizontalWall(e,t,s,i,a,r){if(s){const s=this.getWall(t);s.x=i,s.y=a,s.width=r/2-this.entranceWidth,s.height=4,e.push(s);const n=this.getWall(t);n.x=i+r/2+this.entranceWidth,n.y=a,n.width=r/2-this.entranceWidth,n.height=4,e.push(n)}else{const s=this.getWall(t);s.x=i,s.y=a,s.width=r,s.height=4,e.push(s)}}makeVerticalWall(e,t,s,i,a,r){if(s){const s=this.getWall(t);s.x=i,s.y=a,s.width=4,s.height=r/2-this.entranceWidth,e.push(s);const n=this.getWall(t);n.x=i,n.y=a+r/2+this.entranceWidth,n.width=4,n.height=r/2-this.entranceWidth,e.push(n)}else{const s=this.getWall(t);s.x=i,s.y=a,s.width=4,s.height=r,e.push(s)}}getContainer(){return this.discardedContainers.length>0?this.discardedContainers.pop():new PIXI.Container}getFloorSprite(){return this.discardedFloorSprites.length>0?this.discardedFloorSprites.pop():new PIXI.TilingSprite(PIXI.Texture.WHITE)}addBuilding(e){var t,s;e.container=this.getContainer(),e.container.cacheAsBitmap=!1,e.floorSprite=this.getFloorSprite(),e.floorSprite.tint=(t=10+Math.round(50*Math.random()),s=10+Math.round(50*Math.random()),10+Math.round(50*Math.random())|s<<8|t<<16),e.floorSprite.alpha=.2,e.container.x=e.x,e.container.y=e.y,e.floorSprite.width=e.width,e.floorSprite.height=e.height,e.container.addChild(e.floorSprite);const r=[{x:e.x+e.width/2,y:e.y,north:!0,inside:{x:e.x+e.width/2,y:e.y+this.entranceDepth,entrance:!0},outside:{x:e.x+e.width/2,y:e.y-this.entranceDepth,entrance:!0}},{x:e.x+e.width/2,y:e.y+e.height,south:!0,inside:{x:e.x+e.width/2,y:e.y+e.height-this.entranceDepth,entrance:!0},outside:{x:e.x+e.width/2,y:e.y+e.height+this.entranceDepth,entrance:!0}},{x:e.x,y:e.y+e.height/2,west:!0,inside:{x:e.x+this.entranceDepth,y:e.y+e.height/2,entrance:!0},outside:{x:e.x-this.entranceDepth,y:e.y+e.height/2,entrance:!0}},{x:e.x+e.width,y:e.y+e.height/2,east:!0,inside:{x:e.x+e.width-this.entranceDepth,y:e.y+e.height/2,entrance:!0},outside:{x:e.x+e.width+this.entranceDepth,y:e.y+e.height/2,entrance:!0}}];let n;const o={x:P.x/2,y:P.y/2};let h=2e3;for(let e=0;ee.south))[0]:e.entrance=r.filter((e=>e.north))[0]),e.walls=[];const l=a(this.buildingTextures,Math.random());this.makeHorizontalWall(e.walls,l,e.entrance.north,-4,-4,e.width+8),this.makeHorizontalWall(e.walls,l,e.entrance.south,-4,e.height,e.width+8),this.makeVerticalWall(e.walls,l,e.entrance.west,-4,-4,e.height+8),this.makeVerticalWall(e.walls,l,e.entrance.east,e.width,-4,e.height+8);for(let t=0;t.5?.25*P.y:.75*P.y)-50,width:100,height:100},this.graveYardLocation={x:this.graveYardPosition.x+50,y:this.graveYardPosition.y+50}}populatePois(){if(this.setGraveyardPosition(),!this.buildingTextures){this.buildingTextures=[];for(let e=0;e<2;e++)this.buildingTextures.push(PIXI.Texture.from("floor"+(e+1)+".png"));for(let e=0;e<2;e++)this.buildingTextures.push(PIXI.Texture.from("wall"+(e+1)+".png"));this.roadSprite=new PIXI.TilingSprite(PIXI.Texture.from("road.png")),this.roadSprite.texture.baseTexture.mipmap=PIXI.MIPMAP_MODES.OFF,this.roadSprite.width=P.x,this.roadSprite.tileScale.set(3,3),this.roadSprite.height=96,u.addChild(this.roadSprite),this.roadSprite.visible=!1,this.roadSprite.anchor.set(0,0)}if(this.buildings.length>0)for(let e=0;e{this.discardedWalls.push(t),this.buildings[e].container.removeChild(t)})),this.buildings[e].container.removeChild(this.buildings[e].floorSprite),this.discardedFloorSprites.push(this.buildings[e].floorSprite),this.discardedContainers.push(this.buildings[e].container);let e=1;this.buildingsByPopularity=[],this.buildings=[];let t=this.minBuildings,s=this.humans.getMaxHumans();const i=Math.max(Math.min(50,Math.round(s/3)),10);for(this.roadSprite.visible=!1,this.gameModel.isBossStage(this.gameModel.level)?(s=0,t=0):this.gameModel.level%5==0&&(this.roadSprite.visible=!0,this.roadSprite.width=P.x,this.roadSprite.x=0,this.roadSprite.y=P.y/2-48);s>0||t>0;){t--;const a=Math.round(5+Math.random()*(i-5)),r=Math.sqrt(500*a);s-=a;let n,o=!1,h=1e3;const l=10;for(;!o&&h>0;)h--,n=this.gameModel.level%5==0?Math.random()>.7?{x:l+Math.random()*(P.x-(2*l+r)),y:l+Math.random()*(P.y-(2*l+r)),width:r,height:r}:{x:l+Math.random()*(P.x-(2*l+r)),y:Math.random()>.5?P.y/2+this.roadSprite.height/2+8:P.y/2-this.roadSprite.height/2-8-r,width:r,height:r}:{x:l+Math.random()*(P.x-(2*l+r)),y:l+Math.random()*(P.y-(2*l+r)),width:r,height:r},o=this.isValidPosition(n);if(o){const t=new j(e++,n.x,n.y,r,r);this.addBuilding(t);const s=Math.max(Math.round(r/10),1);for(let e=0;e.5?-1:1,t=Math.random()>.5?-1:1,s=P.x/4,i=P.y/4;return Math.random()>.5?{x:Math.random()*P.x,y:P.y/2+t*i+Math.random()*t*i}:{x:P.x/2+e*s+Math.random()*e*s,y:Math.random()*P.y}}return{x:e.x+5+Math.random()*(e.width-10),y:e.y+5+Math.random()*(e.height-10)}}isInsidePoi(e,t,s,i=0){return e>s.x-i&&es.y-i&&te.collisionY&&t.ye.collisionX-this.wallCollisionBuffer&&(i.x=!0,i.validX=e.collisionX-this.wallCollisionBuffer-1),t.x>e.collisionX+e.collisionWidth+this.wallCollisionBuffer&&s.xe.collisionX&&t.xe.collisionY-this.wallCollisionBuffer&&(i.y=!0,i.validY=e.collisionY-this.wallCollisionBuffer-1),t.y>e.collisionY+e.collisionHeight+this.wallCollisionBuffer&&s.y0?1:-1),y:s.y+(e.y>0?1:-1)};if(t)for(let e=0;e0&&e.x>s.x+s.width+4)return!1;if(this.dy<0&&e.y0&&e.y>s.y+s.width+4)return!1;for(this.step=this.pathStepCalc(e,t),this.stepsToTake=Math.min(i/this.pathFindStepSize-this.pathFindStepSize,30),this.hasHit=!1,this.testPosition={x:e.x,y:e.y};!this.hasHit&&this.stepsToTake>0;)this.stepsToTake--,this.testPosition.x+=this.step.x,this.testPosition.y+=this.step.y,this.isInsidePoi(this.testPosition.x,this.testPosition.y,s,4)&&(this.hasHit=!0);return this.hasHit}findNearestCorner(e,t){let s=null,i=1e4;for(let a=0;a0)for(let e=0;e0;){let s,i=!1,r=1e3;const n=8,o=2;for(;!i&&r>0;)r--,s={x:n+Math.random()*(P.x-2*n),y:n+Math.random()*(P.y-2*n),width:o,height:o},i=this.isValidTreePosition(s);if(i){let e=.4+.6*Math.random();this.gameModel.constructions.graveyard&&(e=Math.min((this.fastDistance(s.x,s.y,this.graveYardLocation.x,this.graveYardLocation.y)-90)/400,1));let i,r=this.treeTextures[this.treeTextures.length-1-Math.round((this.treeTextures.length-1)*e)];this.gameModel.isBossStage(this.gameModel.level)&&Math.random()>.7&&(r=a(this.armyTextures,Math.random())),this.treeSprites.length>t?(i=this.treeSprites[t],i.texture=r,i.visible=!0):(i=new PIXI.Sprite(r),this.treeSprites.push(i),g.addChild(i)),t++,i.anchor.set(.5,1),i.x=s.x,i.y=s.y,i.zIndex=i.y,i.scale.x=i.scale.y=2,i.scale.x=Math.random()>.5?i.scale.x:-1*i.scale.x}e--}}}class te{constructor(){this.x=!1,this.y=!1,this.validX=0,this.validY=0}}class se{constructor(){if(this.storm=!1,this.gameModel=ne.getInstance(),this.costs={blood:"blood",parts:"parts"},this.generatorsApplied=[],this.generators=[new ie(1,"Simple Machine",this.costs.blood,1e6,1.08,1,2,"A simple device that produces 1 part every 2 seconds"),new ie(2,"Part Duplicator",this.costs.parts,100,1.09,4,3,"A more advanced device that produces 4 parts every 3 seconds"),new ie(3,"Stamp Press",this.costs.parts,1e3,1.1,16,5,"An industrial press that produces 16 parts every 5 seconds"),new ie(4,"Conveyor",this.costs.parts,1e4,1.11,64,8,"A fantastic new invention that produces 64 parts every 8 seconds"),new ie(5,"Splitter Combiner",this.costs.parts,1e5,1.12,192,10,"A wondrous machine that produces 192 parts every 10 seconds"),new ie(6,"Batch Converter",this.costs.parts,5e5,1.13,512,12,"An astounding contraption that produces 512 parts every 12 seconds")],se.instance)return se.instance;se.instance=this}factoryStats(){let e=0,t=0;for(let s=0;s=this.purchasePrice(e);case this.costs.parts:return this.gameModel.persistentData.parts>=this.purchasePrice(e)}return!1}purchaseMaxGenerators(e){const t=this.upgradeMaxAffordable(e);for(let s=0;s0&&this.applyGenerator(this.generators[e],t)}}}class ie{constructor(e,t,s,i,a,r,n,o){this.id=e,this.name=t,this.costType=s,this.basePrice=i,this.multi=a,this.produces=r,this.time=n,this.description=o,this.cap=0}}class ae{constructor(){if(this.gameModel=ne.getInstance(),this.spawnedSavedCreatures=!1,this.types={earthGolem:1,airGolem:2,fireGolem:3,waterGolem:4},this.creatures=[new re(1,this.types.earthGolem,"Earth Golem",3e3,75,30,800,"A golem born from rocks and mud, able to take a lot of punishment and taunt enemies to attack it"),new re(2,this.types.airGolem,"Air Golem",1200,110,45,900,"A fast moving golem able to cover large distances and chase targets down"),new re(3,this.types.fireGolem,"Fire Golem",1200,130,32,1e3,"A fireball spewing golem that ignites everything it touches"),new re(4,this.types.waterGolem,"Water Golem",1500,90,30,1100,"A calming golem that restores health to nearby units")],this.creatureScaling=1.75,this.creatureCostScaling=2,this.creatureCostReduction=1,ae.instance)return ae.instance;ae.instance=this}update(e){const t=(new Ue).creatureCount;for(let s=0;s=this.gameModel.creatureLimit||(e.building=!0,e.timeLeft=e.time,this.gameModel.persistentData.parts-=this.purchasePrice(e)))}creatureAutoBuildNumber(e,t){e.autobuild+t>=0&&(e.autobuild+=t,this.gameModel.persistentData.creatureAutobuild[e.id]=e.autobuild)}updateAutoBuild(){for(let e=0;et.type==e.t))[0];s.level=e.l,this.spawnCreature(s)}this.spawnedSavedCreatures=!0}}creatureStats(e){return{thisLevel:{level:e.level,health:e.baseHealth*Math.pow(this.creatureScaling,e.level-1)*this.gameModel.golemHealthPCMod,damage:e.baseDamage*Math.pow(this.creatureScaling,e.level-1)*this.gameModel.golemDamagePCMod,cost:e.baseCost*Math.pow(this.creatureCostScaling,e.level-1)},nextLevel:{level:e.level+1,health:e.baseHealth*Math.pow(this.creatureScaling,e.level)*this.gameModel.golemHealthPCMod,damage:e.baseDamage*Math.pow(this.creatureScaling,e.level)*this.gameModel.golemDamagePCMod,cost:e.baseCost*Math.pow(this.creatureCostScaling,e.level)}}}}class re{constructor(e,t,s,i,a,r,n,o){this.id=e,this.type=t,this.name=s,this.baseHealth=i,this.baseDamage=a,this.speed=r,this.baseCost=n,this.description=o,this.time=3,this.building=!1,this.timeLeft=10,this.autobuild=0,this.level=1}}class ne{constructor(){this.storageName="ZombieData",this.kongregate=null,this.playFabId=null,this.titleId="772D8",this.hidden=!1,this.autoShatter=!1,this.energy=0,this.energyMax=10,this.energyRate=1,this.brainsRate=0,this.bonesRate=0,this.endLevelBones=0,this.energySpellMultiplier=1,this.prestigePointsEarned=0,this.zombieCost=10,this.bonesPCMod=1,this.partsPCMod=1,this.bloodMax=1e3,this.bloodPCMod=1,this.bloodStorePCMod=1,this.brainsMax=50,this.brainsPCMod=1,this.brainsStorePCMod=1,this.zombieHealth=100,this.zombieHealthPCMod=1,this.zombieDamage=10,this.zombieDamagePCMod=1,this.zombieSpeed=10,this.zombieCages=0,this.zombiesInCages=0,this.golemDamagePCMod=1,this.golemHealthPCMod=1,this.plagueDamageMod=0,this.plagueticks=2,this.graveyardHealthMod=1,this.burningSpeedMod=1,this.startingResources=0,this.blastHealing=0,this.plagueDmgReduction=0,this.brainRecoverChance=0,this.riseFromTheDeadChance=0,this.infectedBiteChance=0,this.infectedBlastChance=0,this.spitDistance=0,this.spikeDelay=5,this.startTimer=0,this.fenceRadius=50,this.constructions={},this.construction=0,this.boneCollectorCapacity=10,this.frameRate=0,this.humanCount=50,this.zombieCount=0,this.creatureCount=0,this.creatureLimit=1,this.harpySpeed=75,this.tankBuster=!1,this.harpyBombs=1,this.stats=null,this.runicSyphon={percentage:0,blood:0,bones:0,brains:0},this.gigazombies=!1,this.endLevelTimer=3,this.endLevelDelay=3,this.messageQueue=[],this.offlineMessage="",this.runeEffects={attackSpeed:1,critChance:0,critDamage:0,damageReduction:1,healthRegen:0,damageReflection:0},this.encodedContent="",this.savefilename="",this.autoUpgrades=!1,this.autoconstruction=!1,this.autoconstructionUnlocked=!1,this.levelResourcesAdded=!1,this.bulletproofChance=0,this.gameSpeed=1,this.level=1,this.currentState="startGame",this.states={playingLevel:"playingLevel",levelCompleted:"levelCompleted",startGame:"startGame",prestiged:"prestiged",failed:"failed"},this.baseStats={energyRate:1,brainsRate:0,bonesRate:0,energyMax:10,bloodMax:1e3,brainsMax:50,zombieCost:10,zombieHealth:100,zombieDamage:10,zombieSpeed:10,level:1,graveyard:0,construction:0,boneCollectorCapacity:10},this.zoom=A,this.centerGameContainer=Z,this.lastSave=0,this.lastPlayFabSave=Date.now()-15e3,this.persistentData={saveCreated:Date.now(),dateOfSave:Date.now(),autoStart:!1,levelUnlocked:1,allTimeHighestLevel:0,blood:0,brains:0,bones:0,parts:0,bonesTotal:0,upgrades:[],constructions:[],prestigePointsEarned:0,prestigePointsToSpend:0,boneCollectors:0,graveyardZombies:1,harpies:0,resolution:1,zoomButtons:!1,particles:!0,generators:[],currentConstruction:null,creatureLevels:[],creatures:[],creatureAutobuild:[],savedCreatures:[],levelsCompleted:[],showfps:!1,runeshatter:0,runes:{life:{blood:0,brains:0,bones:0},death:{blood:0,brains:0,bones:0}},trophies:[],vipEscaped:[],autoRelease:!1,skeleton:null,skeletonTalents:[]}}static getInstance(){return ne.instance||(ne.instance=new ne,ne.instance.particles=new Qe,ne.instance.trophies=new de,ne.instance.bones=new tt,ne.instance.creatureFactory=new ae,ne.instance.creatures=new Ue,ne.instance.boneCollectors=new Ve,ne.instance.graveyard=new Oe,ne.instance.spells=new q,ne.instance.partFactory=new se,ne.instance.skeleton=new Xe,ne.instance.upgrades=new oe,ne.instance.zombies=new Ae,ne.instance.humans=new Se,ne.instance.police=new ke,ne.instance.army=new Te),ne.instance}resetToBaseStats(){this.energyRate=this.baseStats.energyRate,this.brainsRate=this.baseStats.brainsRate,this.bonesRate=this.baseStats.bonesRate,this.energyMax=this.baseStats.energyMax,this.bloodMax=this.baseStats.bloodMax,this.brainsMax=this.baseStats.brainsMax,this.zombieHealth=this.baseStats.zombieHealth,this.zombieDamage=this.baseStats.zombieDamage,this.zombieSpeed=this.baseStats.zombieSpeed,this.zombieCost=this.baseStats.zombieCost,this.zombieCages=0,this.brainRecoverChance=0,this.riseFromTheDeadChance=0,this.infectedBiteChance=0,this.infectedBlastChance=0,this.construction=this.baseStats.construction,this.constructions={},this.boneCollectorCapacity=this.baseStats.boneCollectorCapacity,this.bonesPCMod=1,this.partsPCMod=1,this.bloodPCMod=1,this.bloodStorePCMod=1,this.brainsPCMod=1,this.brainsStorePCMod=1,this.zombieHealthPCMod=1,this.zombieDamagePCMod=1,this.golemHealthPCMod=1,this.golemDamagePCMod=1,this.plagueDamageMod=0,this.plagueticks=2,this.burningSpeedMod=1,this.startingResources=0,this.fenceRadius=50,this.spitDistance=0,this.spikeDelay=5,this.blastHealing=0,this.plagueDmgReduction=1,this.creatureLimit=1,this.runicSyphon.percentage=0,this.autoconstructionUnlocked=!1,this.autoUpgrades=!1,this.graveyardHealthMod=1,this.bulletproofChance=0,this.gigazombies=!1,this.harpySpeed=75,this.tankBuster=!1,this.harpyBombs=1}addEnergy(e){this.energy+=e,this.energy>this.energyMax&&(this.energy=this.energyMax)}addBlood(e){isNaN(this.persistentData.blood)&&(this.persistentData.blood=0),isNaN(e)||(this.persistentData.blood+=e*this.bloodPCMod,this.persistentData.blood>this.bloodMax&&(this.persistentData.blood=this.bloodMax,this.constructions.runesmith&&this.runicSyphon.percentage>0&&(this.runicSyphon.blood+=e*this.bloodPCMod)),this.runicSyphon.percentage>0&&(this.runicSyphon.blood+=e*this.bloodPCMod*this.runicSyphon.percentage))}addBrains(e){isNaN(this.persistentData.brains)&&(this.persistentData.brains=0),isNaN(e)||(this.persistentData.brains+=e*this.brainsPCMod,this.persistentData.brains>this.brainsMax&&(this.persistentData.brains=this.brainsMax,this.constructions.runesmith&&this.runicSyphon.percentage>0&&(this.runicSyphon.brains+=e*this.brainsPCMod)),this.runicSyphon.percentage>0&&(this.runicSyphon.brains+=e*this.brainsPCMod*this.runicSyphon.percentage))}addBones(e){isNaN(this.persistentData.bones)&&(this.persistentData.bones=0),isNaN(e)||(this.persistentData.bones+=e*this.bonesPCMod,this.persistentData.bonesTotal+=e*this.bonesPCMod,this.runicSyphon.percentage>0&&(this.runicSyphon.bones+=e*this.bonesPCMod*this.runicSyphon.percentage))}getHumanCount(){return this.humanCount}getEnergyRate(){return this.energySpellMultiplier*this.energyRate-(this.persistentData.boneCollectors+this.persistentData.harpies)}update(e,t){this.spells.updateSpells(e),e*=this.gameSpeed,this.hidden&&U(e,this.app),this.partFactory.update(e),this.autoRemoveCollectorsHarpies(),this.addEnergy(this.getEnergyRate()*e),this.currentState==this.states.playingLevel&&(this.addBones(this.bonesRate*e),this.addBrains(this.brainsRate*e),this.upgrades.updateRunicSyphon(this.runicSyphon),this.lastSave+3e4this.persistentData.allTimeHighestLevel)&&(this.persistentData.allTimeHighestLevel=this.level,window.kongregate&&window.kongregate.stats.submit("level",this.persistentData.allTimeHighestLevel)),this.startTimer=2):this.endLevelTimer-=e),this.upgrades.updateConstruction(e),this.upgrades.updateAutoUpgrades(),this.creatureFactory.update(e)),this.currentState==this.states.levelCompleted&&(this.startTimer-=e,this.startTimer<0&&this.persistentData.autoStart&&this.nextLevel()),this.currentState==this.states.failed&&(this.startTimer-=e,this.startTimer<0&&this.persistentData.autoStart&&this.startLevel(this.level-1)),this.updateStats()}calculateEndLevelBones(){this.endLevelBones=0,this.persistentData.boneCollectors>0&&this.bones.uncollected&&(this.endLevelBones=this.bones.uncollected.map((e=>e.value)).reduce(((e,t)=>e+t),0),this.addBones(this.endLevelBones))}calculateEndLevelZombieCages(){this.zombieCages>0&&(this.zombiesInCages+=this.zombieCount,this.zombiesInCages>this.zombieCages&&(this.zombiesInCages=this.zombieCages))}autoRemoveCollectorsHarpies(){if(this.getEnergyRate()<0){const e=this.getEnergyRate();this.persistentData.harpies>0&&(this.persistentData.harpies-=Math.ceil(Math.abs(e)),this.persistentData.harpies<0&&(this.persistentData.harpies=0)),this.getEnergyRate()<0&&this.persistentData.boneCollectors>0&&this.persistentData.boneCollectors--}}releaseCagedZombies(){if(this.currentState==this.states.playingLevel){for(let e=0;e0,health:10*this.zombieHealth,damage:10*this.zombieDamage,speed:this.skeleton.moveSpeed},zombie:{health:this.zombieHealth,damage:this.zombieDamage,speed:this.zombieSpeed},human:{health:this.humans.getMaxHealth(this.level),damage:this.humans.attackDamage,speed:this.humans.maxRunSpeed},police:{show:this.police.getMaxPolice()>0,health:this.police.getMaxHealth(),damage:this.police.attackDamage,speed:this.police.maxRunSpeed},army:{show:this.army.getMaxArmy()>0,health:this.army.getMaxHealth(),damage:this.army.attackDamage,speed:this.army.maxRunSpeed}}}updateStats(){this.stats&&(this.stats.zombie.health=this.zombieHealth,this.stats.zombie.damage=this.zombieDamage,this.stats.zombie.speed=this.zombieSpeed,this.stats.zombie.count=this.zombieCount,this.stats.skeleton.health=10*this.zombieHealth,this.stats.skeleton.damage=10*this.zombieDamage,this.stats.skeleton.speed=this.skeleton.moveSpeed)}vipEscaped(){this.persistentData.vipEscaped||(this.persistentData.vipEscaped=[]),this.persistentData.vipEscaped.push(this.level),this.saveData()}updatePlayingLevel(){this.saveData()}addStartLevelResources(){this.energy=this.energyMax,this.levelResourcesAdded||(this.persistentData.blood+=500*this.startingResources,this.persistentData.blood>this.bloodMax&&(this.persistentData.blood=this.bloodMax),this.persistentData.brains+=50*this.startingResources,this.persistentData.brains>this.brainsMax&&(this.persistentData.brains=this.brainsMax),this.persistentData.bones+=200*this.startingResources,this.persistentData.bonesTotal+=200*this.startingResources,this.levelResourcesAdded=!0)}onReady(){this.upgrades.upgradeIdCheck()}addPrestigePoints(e){void 0===this.persistentData.prestigePointsEarned&&(this.persistentData.prestigePointsEarned=0,this.persistentData.prestigePointsToSpend=0),this.persistentData.prestigePointsEarned+=e}prestige(){if(this.persistentData.prestigePointsEarned>0){this.persistentData.levelUnlocked=1,this.persistentData.blood=0,this.persistentData.brains=0,this.persistentData.bones=0,this.persistentData.parts=0,this.persistentData.generators=[],this.persistentData.bonesTotal=0,this.persistentData.upgrades=this.persistentData.upgrades.filter((e=>e.costType==this.upgrades.costs.prestigePoints)),this.persistentData.constructions=[],this.persistentData.boneCollectors=0,this.persistentData.currentConstruction=!1,this.persistentData.harpies=0,this.persistentData.graveyardZombies=1,this.persistentData.prestigePointsToSpend+=this.persistentData.prestigePointsEarned,this.persistentData.prestigePointsEarned=0,this.persistentData.runes=null,this.persistentData.vipEscaped=[],this.persistentData.creatureLevels=[],this.persistentData.creatureAutobuild=[],this.persistentData.levelsCompleted=[],this.persistentData.runeshatter=0,this.zombiesInCages=0,this.autoconstruction=!1,this.levelResourcesAdded=!1,this.gigazombies=!1,this.runeEffects={attackSpeed:1,critChance:0,critDamage:0,damageReduction:1,healthRegen:0,damageReflection:0},this.boneCollectors.update(.1),this.partFactory.generatorsApplied=[],this.creatureFactory.updateAutoBuild(),this.creatureFactory.resetLevels(),this.level=1,this.currentState=this.states.prestiged,this.skeleton.persistent.talentReset=!0,this.setupLevel(),this.saveData();for(let e=0;e0&&(this.offlineMessage="Your factory has generated "+n(t)+" parts while you were away",this.persistentData.parts+=t)}}resetData(){try{localStorage.removeItem(this.storageName),localStorage.removeItem(this.skeleton.storageName),localStorage.removeItem(this.skeleton.talentsStorageName),this.saveToPlayFab(!0)}catch(e){console.log(e)}}updatePersistentData(){this.persistentData.constructions||(this.persistentData.constructions=[]),this.persistentData.generators||(this.persistentData.generators=[]),this.persistentData.parts||(this.persistentData.parts=0),this.persistentData.creatureLevels||(this.persistentData.creatureLevels=[]),this.persistentData.creatureAutobuild||(this.persistentData.creatureAutobuild=[]),this.persistentData.savedCreatures||(this.persistentData.savedCreatures=[]),this.persistentData.levelsCompleted||(this.persistentData.levelsCompleted=[]),this.persistentData.saveCreated||(this.persistentData.saveCreated=Date.now()),void 0===this.persistentData.particles&&(this.persistentData.particles=!0),this.persistentData.runeshatter||(this.persistentData.runeshatter=0),this.creatureFactory.updateAutoBuild()}sendMessage(e){this.messageQueue.includes(e)||this.messageQueue.push(e)}setResolution(e){this.app&&(this.app.renderer.resolution=e,this.app.renderer.rootRenderTarget&&(this.app.renderer.rootRenderTarget.resolution=e),this.app.renderer.plugins.interaction.resolution=e,this.app.renderer.resize(document.body.clientWidth,document.body.clientHeight))}downloadSaveGame(){this.persistentData.skeleton=this.skeleton.persistent,this.persistentData.skeletonTalents=this.skeleton.talents,this.blob=new Blob([LZString.compressToEncodedURIComponent(JSON.stringify(this.persistentData))],{type:"octet/stream"}),delete this.persistentData.skeleton,this.encodedContent=window.URL.createObjectURL(this.blob);const e=(new Date).toISOString().replace(/:|T|Z|\./g,"");this.savefilename="incremancer-"+e+".sav"}importFile(){const e=document.getElementById("import-file").files;if(e&&1==e.length){const t=e[0],s=new FileReader,i=ne.getInstance();s.onload=function(e){const t=JSON.parse(LZString.decompressFromEncodedURIComponent(e.target.result));t.dateOfSave?(t.skeleton&&(i.skeleton.persistent=t.skeleton,delete t.skeleton),t.skeletonTalents?(i.skeleton.talents=t.skeletonTalents,delete t.skeletonTalents):i.skeleton.talents=[],i.persistentData=t,i.updatePersistentData(),i.saveToPlayFab(),i.level=i.persistentData.levelUnlocked,i.creatureFactory.spawnedSavedCreatures=!1,i.setupLevel()):alert("Error loading save game")},s.readAsText(t)}}toggleFullscreen(){if(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)document.exitFullscreen?document.exitFullscreen():document.webkitExitFullscreen?document.webkitExitFullscreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.msExitFullscreen&&document.msExitFullscreen();else{const e=document.body;e.requestFullscreen?e.requestFullscreen():e.webkitRequestFullscreen?e.webkitRequestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.msRequestFullscreen&&e.msRequestFullscreen()}}prestigePointsForLevel(e){return this.persistentData.levelsCompleted.includes(e)?0:e}bossCompleted(e){const t=50*Math.floor((e-1)/50);return t<50||this.persistentData.levelsCompleted.includes(t)}levelLocked(e){return e>this.persistentData.allTimeHighestLevel+1||!this.bossCompleted(e)}isBossStage(e){return e>0&&e%50==0}levelInfo(e){return{level:e,bossStage:this.isBossStage(e),completed:this.persistentData.levelsCompleted.includes(e),locked:this.levelLocked(e),trophy:this.trophies.doesLevelHaveTrophy(e)}}loginInUsingPlayFab(){if(window.kongregate)try{PlayFab.settings.titleId=this.titleId;const e={TitleId:PlayFab.settings.titleId,AuthTicket:window.kongregate.services.getGameAuthToken(),KongregateId:window.kongregate.services.getUserId(),CreateAccount:!0},t=this;PlayFabClientSDK.LoginWithKongregate(e,(function(e){e&&e.data&&e.data.PlayFabId&&(t.playFabId=e.data.PlayFabId,t.loadFromPlayFab())}),(function(e){console.log(e)}))}catch(e){console.error(e)}}saveToPlayFab(e=!1){if(this.lastPlayFabSave=Date.now(),this.playFabId){const t=this.persistentData.trophies;delete this.persistentData.trophies;const s={TitleId:this.titleId,PlayFabId:this.playFabId,Data:{save:!e&&LZString.compressToEncodedURIComponent(JSON.stringify(this.persistentData)),trophies:!e&&LZString.compressToEncodedURIComponent(JSON.stringify(t)),skeleton:!e&&LZString.compressToEncodedURIComponent(JSON.stringify(this.skeleton.persistent)),talents:!e&&LZString.compressToEncodedURIComponent(JSON.stringify(this.skeleton.talents))}};this.persistentData.trophies=t;try{const t=this;PlayFab.ClientApi.UpdateUserData(s,(function(s){e?(t.resetToBaseStats(),t.setupLevel(),window.location.reload()):t.messageQueue.push("Game Saved to Cloud")}),(function(e){console.log(e)}))}catch(e){console.log(e)}}else e&&(this.resetToBaseStats(),this.setupLevel(),window.location.reload())}loadFromPlayFab(e=!1){if(this.playFabId){const t={TitleId:this.titleId,PlayFabId:this.playFabId,Keys:["save","trophies","skeleton","talents"]};try{const s=this;PlayFab.ClientApi.GetUserData(t,(function(t){if(t.data.Data.save){const i=JSON.parse(LZString.decompressFromEncodedURIComponent(t.data.Data.save.Value));(e||i.saveCreateds.persistentData.dateOfSave)&&(s.persistentData=i,t.data.Data.trophies&&(s.persistentData.trophies=JSON.parse(LZString.decompressFromEncodedURIComponent(t.data.Data.trophies.Value))),t.data.Data.skeleton&&(s.skeleton.persistent=JSON.parse(LZString.decompressFromEncodedURIComponent(t.data.Data.skeleton.Value))),t.data.Data.talents?s.skeleton.talents=JSON.parse(LZString.decompressFromEncodedURIComponent(t.data.Data.talents.Value)):s.skeleton.talents=[],s.level=s.persistentData.levelUnlocked,s.updatePersistentData(),s.calcOfflineProgress(),s.setupLevel(),s.messageQueue.push("Game Loaded from Cloud"))}}),(function(e){console.log(e)}))}catch(e){console.log(e)}}}allowPlayFabAction(){return this.lastPlayFabSave+15e3t.id==e.requires)).length}getUpgrades(e){switch(e){case this.costs.blood:case this.costs.brains:case this.costs.bones:case this.costs.parts:return this.upgrades.filter((t=>t.costType==e&&(0==t.cap||this.currentRank(t)e.cap>0&&this.currentRank(e)>=e.cap))}}applyUpgrades(){this.gameModel.resetToBaseStats(),this.spells.lockAllSpells();for(let e=0;et.id==this.gameModel.persistentData.upgrades[e].id))[0];t||(t=this.prestigeUpgrades.filter((t=>t.id==this.gameModel.persistentData.upgrades[e].id))[0]),t&&this.applyUpgrade(t,this.gameModel.persistentData.upgrades[e].rank)}for(let e=0;e0?"You have unlocked Unholy Construction":"You have yet to unlock Unholy Construction";case this.types.boneCollectorCapacity:return"Bone collector capacity: "+n(this.gameModel.boneCollectorCapacity);case this.types.bonesGainPC:return"Bones: "+n(Math.round(100*this.gameModel.bonesPCMod))+"%";case this.types.partsGainPC:return"Parts: "+n(Math.round(100*this.gameModel.partsPCMod))+"%";case this.types.bloodGainPC:return"Blood: "+n(Math.round(100*this.gameModel.bloodPCMod))+"%";case this.types.bloodStoragePC:return"Blood Storage: "+n(100*this.gameModel.bloodStorePCMod)+"%";case this.types.brainsGainPC:return"Brains: "+n(Math.round(100*this.gameModel.brainsPCMod))+"%";case this.types.brainsStoragePC:return"Brains Storage: "+n(100*this.gameModel.brainsStorePCMod)+"%";case this.types.zombieDmgPC:return"Zombie Damage: "+Math.round(100*this.gameModel.zombieDamagePCMod)+"%";case this.types.zombieHealthPC:return"Zombie Health: "+Math.round(100*this.gameModel.zombieHealthPCMod)+"%";case this.types.golemDamagePC:return"Golem Damage: "+Math.round(100*this.gameModel.golemDamagePCMod)+"%";case this.types.golemHealthPC:return"Golem Health: "+Math.round(100*this.gameModel.golemHealthPCMod)+"%";case this.types.startingPC:return Math.round(500*this.gameModel.startingResources)+" blood, "+Math.round(50*this.gameModel.startingResources)+" brains, "+Math.round(200*this.gameModel.startingResources)+" bones";case this.types.unlockSpell:return this.currentRank(e)>0?"You have learned this spell":"You have yet to learn this spell";case this.types.energyCost:return"Zombie Cost: "+this.gameModel.zombieCost+" energy";case this.types.burningSpeedPC:return"Burning zombie speed: "+Math.round(100*this.gameModel.burningSpeedMod)+"%";case this.types.blastHealing:return"Plague heal: "+Math.round(100*this.gameModel.blastHealing)+"%";case this.types.spitDistance:return"Zombie spit distance: "+this.gameModel.spitDistance;case this.types.plagueArmor:return"Infected damage reduction: "+Math.round(100-100*this.gameModel.plagueDmgReduction)+"%";case this.types.monsterLimit:return"Creature limit: "+this.gameModel.creatureLimit;case this.types.runicSyphon:return"Syphon amount: "+Math.round(100*this.gameModel.runicSyphon.percentage)+"%";case this.types.autoconstruction:return this.currentRank(e)>0?"You have unlocked automatic construction":"You have yet to unlock automatic construction";case this.types.autoshop:return this.currentRank(e)>0?"You have unlocked automatic shop purchases":"You have yet to unlock automatic shop purchases";case this.types.graveyardHealth:return"Graveyard health: "+Math.round(100*this.gameModel.graveyardHealthMod)+"%";case this.types.harpySpeed:return"Harpy speed: "+n(this.gameModel.harpySpeed);case this.types.harpyBombs:return"Harpy bombs: "+n(this.gameModel.harpyBombs);case this.types.tankBuster:return this.currentRank(e)>0?"You have unlocked tank buster":"You have yet to unlock tank buster";case this.types.spikeDelay:return"Current spike delay: "+(5-this.currentRank(e))+" seconds"}}currentRank(e){for(let t=0;t0&&this.currentRank(e)>=e.cap)return e.auto=!1,!1;switch(e.costType){case this.costs.energy:return this.gameModel.energy>=this.upgradePrice(e);case this.costs.blood:return this.gameModel.persistentData.blood>=this.upgradePrice(e);case this.costs.brains:return this.gameModel.persistentData.brains>=this.upgradePrice(e);case this.costs.bones:return this.gameModel.persistentData.bones>=this.upgradePrice(e);case this.costs.parts:return this.gameModel.persistentData.parts>=this.upgradePrice(e);case this.costs.prestigePoints:return this.gameModel.persistentData.prestigePointsToSpend>=this.upgradePrice(e)}return!1}constructionLeadsTo(e){let t=this.constructionUpgrades.filter((t=>t.requires==e.id)).map((e=>e.name)).join(", ");return t+=this.upgrades.filter((t=>t.requires==e.id)).map((e=>e.name)).join(", "),t}purchaseMaxUpgrades(e){const t=this.upgradeMaxAffordable(e);for(let s=0;sthis.gameModel.energy&&(t=!1,this.gameModel.persistentData.currentConstruction.shortfall.energy=!0),e.blood&&e.blood>this.gameModel.persistentData.blood&&(t=!1,this.gameModel.persistentData.currentConstruction.shortfall.blood=!0),e.brains&&e.brains>this.gameModel.persistentData.brains&&(t=!1,this.gameModel.persistentData.currentConstruction.shortfall.brains=!0),e.bones&&e.bones>this.gameModel.persistentData.bones&&(t=!1,this.gameModel.persistentData.currentConstruction.shortfall.bones=!0),e.parts&&e.parts>this.gameModel.persistentData.parts&&(t=!1,this.gameModel.persistentData.currentConstruction.shortfall.parts=!0),!!t&&(this.gameModel.persistentData.currentConstruction.shortfall=!1,e.energy&&(this.gameModel.energy-=e.energy),e.blood&&(this.gameModel.persistentData.blood-=e.blood),e.brains&&(this.gameModel.persistentData.brains-=e.brains),e.bones&&(this.gameModel.persistentData.bones-=e.bones),e.parts&&(this.gameModel.persistentData.parts-=e.parts),!0)}completeConstruction(){const e=this.constructionUpgrades.filter((e=>e.id==this.gameModel.persistentData.currentConstruction.id))[0];let t;for(let s=0;sthis.startConstruction(t)))}}startConstruction(e){if(this.gameModel.persistentData.currentConstruction)return;const t=this.gameModel.persistentData.blood>=(e.costs.blood||0)&&this.gameModel.persistentData.brains>=(e.costs.brains||0)&&this.gameModel.persistentData.bones>=(e.costs.bones||0)&&this.gameModel.persistentData.parts>=(e.costs.parts||0)&&this.gameModel.energy>=(e.costs.energy||0),s={energy:0,blood:0,brains:0,bones:0,parts:0};e.costs.energy&&(s.energy=e.costs.energy/(t?5:e.time)),e.costs.blood&&(s.blood=e.costs.blood/(t?5:e.time)),e.costs.brains&&(s.brains=e.costs.brains/(t?5:e.time)),e.costs.bones&&(s.bones=e.costs.bones/(t?5:e.time)),e.costs.parts&&(s.parts=e.costs.parts/(t?5:e.time)),this.gameModel.persistentData.currentConstruction={state:this.constructionStates.building,name:e.name,id:e.id,timeRemaining:t?5:e.time,time:t?5:e.time,costPerTick:s}}playPauseConstruction(){this.gameModel.persistentData.currentConstruction&&(this.gameModel.persistentData.currentConstruction.state==this.constructionStates.paused?this.gameModel.persistentData.currentConstruction.state=this.constructionStates.building:this.gameModel.persistentData.currentConstruction.state=this.constructionStates.paused)}cancelConstruction(){this.gameModel.persistentData.currentConstruction=!1}constructionAvailable(e){return!(this.gameModel.persistentData.currentConstruction&&this.gameModel.persistentData.currentConstruction.id==e.id||this.currentRankConstruction(e)>=e.cap||e.requires&&0==this.gameModel.persistentData.constructions.filter((t=>t.id==e.requires)).length)}constructionComplete(e){return this.currentRankConstruction(e)>=e.cap}getAvailableConstructions(){return this.constructionUpgrades.filter((e=>this.constructionAvailable(e)))}getCompletedConstructions(){return this.constructionUpgrades.filter((e=>this.constructionComplete(e)))}upgradeIdCheck(){const e=[];this.upgrades.forEach((function(t){e[t.id]&&console.error("ID "+t.id+" already used"),e[t.id]=!0})),this.prestigeUpgrades.forEach((function(t){e[t.id]&&console.error("ID "+t.id+" already used"),e[t.id]=!0})),this.constructionUpgrades.forEach((function(t){e[t.id]&&console.error("ID "+t.id+" already used"),e[t.id]=!0}))}updateRunicSyphon(e){e.percentage>0&&(this.gameModel.persistentData.runes.life.blood+=e.blood/2,this.gameModel.persistentData.runes.death.blood+=e.blood/2,this.gameModel.persistentData.runes.life.brains+=e.brains/2,this.gameModel.persistentData.runes.death.brains+=e.brains/2,this.gameModel.persistentData.runes.life.bones+=e.bones/2,this.gameModel.persistentData.runes.death.bones+=e.bones/2,e.blood=0,e.brains=0,e.bones=0,this.updateRuneEffects())}shatterPercent(e){const t=1e8*Math.pow(1.5,this.gameModel.persistentData.runeshatter);return Math.floor(100*Math.min(1,e.blood/t))}shatterBloodCost(e){return Math.max(0,1e8*Math.pow(1.5,this.gameModel.persistentData.runeshatter)-e.blood)}shatterEffect(){return Math.pow(1.1,this.gameModel.persistentData.runeshatter)}canShatter(){return!!this.gameModel.persistentData.runes&&this.shatterPercent(this.gameModel.persistentData.runes.life)+this.shatterPercent(this.gameModel.persistentData.runes.death)==200}doShatter(){this.canShatter()&&(this.gameModel.persistentData.runeshatter++,this.gameModel.persistentData.runes.life.blood=0,this.gameModel.persistentData.runes.death.blood=0,this.gameModel.persistentData.runes.life.brains=0,this.gameModel.persistentData.runes.death.brains=0,this.gameModel.persistentData.runes.life.bones=0,this.gameModel.persistentData.runes.death.bones=0,this.updateRuneEffects(),this.applyUpgrades())}infuseRune(e,t,s){const i="life"==e?this.gameModel.persistentData.runes.life:this.gameModel.persistentData.runes.death;switch(t){case"blood":this.gameModel.persistentData.blood>=s&&(i.blood+=s,this.gameModel.persistentData.blood-=s);break;case"brains":this.gameModel.persistentData.brains>=s&&(i.brains+=s,this.gameModel.persistentData.brains-=s);break;case"bones":this.gameModel.persistentData.bones>=s&&(i.bones+=s,this.gameModel.persistentData.bones-=s)}this.updateRuneEffects()}updateRuneEffects(){if(!this.gameModel.persistentData.runes)return;const e={attackSpeed:1,critChance:0,critDamage:1,damageReduction:1,healthRegen:0,damageReflection:0};for(let t=0;t0){let t=(Math.log(i)/Math.log(s.logBase)+s.adjustment)/100;t>0&&(s.cap&&t>s.cap&&(t=s.cap),s.subtract?e[s.effect]-=t:e[s.effect]+=t)}}this.gameModel.runeEffects=e}}class he{constructor(e,t,s,i,a,r,n,o,h,l,d){this.id=e,this.name=t,this.type=s,this.costs=i,this.time=a,this.multiplier=r,this.effect=n,this.cap=o,this.requires=h,this.description=l,this.completeMessage=d}}class le{constructor(e,t,s,i,a,r,n,o,h,l,d){this.id=e,this.name=t,this.type=s,this.costType=i,this.basePrice=a,this.multiplier=r,this.effect=n,this.cap=o,this.description=h,this.rank=1,this.purchaseMessage=l,this.requires=d}}class de{constructor(){if(this.gameModel=ne.getInstance(),this.upgrades=new oe,this.trophyStats=[{type:this.upgrades.types.health,value:50,percentage:!1},{type:this.upgrades.types.damage,value:7,percentage:!1},{type:this.upgrades.types.energyCap,value:10,percentage:!1},{type:this.upgrades.types.energyRate,value:.5,percentage:!1},{type:this.upgrades.types.plagueTicks,value:1,percentage:!1,static:!0},{type:this.upgrades.types.plagueDamage,value:50,percentage:!1},{type:this.upgrades.types.bloodCap,value:5e3,percentage:!1},{type:this.upgrades.types.brainsRate,value:2,percentage:!1},{type:this.upgrades.types.zombieHealthPC,value:.02,percentage:!0},{type:this.upgrades.types.bonesRate,value:2,percentage:!1},{type:this.upgrades.types.zombieDmgPC,value:.02,percentage:!0}],de.instance)return de.instance;de.instance=this}isPercentage(e){for(let t=0;tt&&(t=this.gameModel.persistentData.trophies[e]);for(let s=5;s<=t;s+=5)e.push(this.createTrophy(s,this.gameModel.persistentData.trophies.includes(s),this.gameModel.persistentData.vipEscaped.includes(s)));return e}getTrophyTotals(){const e=this.getTrophyList().filter((e=>e.owned)),t=[];for(let s=0;st.type==e[s].type)).length?t.push(e[s]):this.isPercentage(e[s].type)?t.filter((t=>t.type==e[s].type))[0].effect=(t.filter((t=>t.type==e[s].type))[0].effect+1)*(1+e[s].effect)-1:t.filter((t=>t.type==e[s].type))[0].effect+=e[s].effect;return t}getAquiredTrophyList(){this.gameModel.persistentData.trophies||(this.gameModel.persistentData.trophies=[]);const e=[];for(let t=0;t{this.vipEscaping=!1}),2e3))),this.army.assaultStarted||Math.random()>.9&&this.gameModel.isBossStage(this.gameModel.level)&&(this.army.assaultStarted=!0,this.gameModel.sendMessage("The assault has begun!"))}updateBurns(e,t){e.timer.burnTick-=t,e.timer.smoke-=t,e.timer.smoke<0&&(this.smoke.newFireSmoke(e.x,e.y-14),e.timer.smoke=this.smokeTimer),e.timer.burnTick<0&&(this.damageHuman(e,e.burnDamage),e.timer.burnTick=this.burnTickTimer,this.exclamations.newFire(e))}assignRandomTarget(e){(Math.random()>this.chanceToStayInCurrentBuilding||e.timer.flee>0)&&(e.currentPoi=this.map.getRandomBuilding()),e.target=this.map.randomPositionInBuilding(e.currentPoi),e.maxSpeed=e.timer.flee>0?this.maxRunSpeed:this.maxWalkSpeed,e.xSpeed=0,e.ySpeed=0}getMaxNpcs(){return Math.min(this.humansPerLevel*this.gameModel.level,this.maxHumans)}getMaxHumans(){return this.gameModel.isBossStage(this.gameModel.level)?0:this.getMaxNpcs()-(this.police.police.length+this.army.armymen.length)}getMaxDoctors(){return this.gameModel.level<18?0:Math.min(Math.round(.7*this.gameModel.level),75)}getTorchChance(){return this.gameModel.level<10?0:.02*Math.min(this.gameModel.level-10,40)}getMaxHealth(e){return e<7?10*(e+4):e<12?20*(e-1):e<16?25*(e-3):e<29?50*(e-9):e<49?100*(e-19):e<64?300*(e-39):e<85?500*(e-49):e>499?85e5*Math.pow(1.03,e-499):17800*Math.pow(1.015,e-84)}getAttackDamage(){1!=this.gameModel.level?2!=this.gameModel.level?3!=this.gameModel.level?this.attackDamage=Math.round(this.getMaxHealth(this.gameModel.level)/10):this.attackDamage=5:this.attackDamage=4:this.attackDamage=2}setupVipText(e){this.vipText||(this.vipText=new fe("VIP",{fontFamily:"sans-serif",fontSize:64,fill:"#FC0",stroke:"#000",strokeThickness:5,align:"center"}),this.vipText.anchor.set(.5,1),this.vipText.scale.x=.25,this.vipText.scale.y=.25,b.addChild(this.vipText)),this.vipText.visible=!0,this.vipText.human=e,this.vipText.yOffset=-20,this.vipText.x=e.x,this.vipText.y=e.y+this.vipText.yOffset}populate(){if(this.map=new ee,this.zombies=new Ae,this.gameModel=ne.getInstance(),this.blood=new _e,this.smoke=new ot,this.bones=new tt,this.skeleton=new Xe,this.blasts=new nt,this.fragments=new lt,this.trophies=new de,this.exclamations=new it,this.bullets=new rt,this.police=new ke,this.army=new Te,this.tanks=new De,this.map.populatePois(),0==this.textures.length)for(let e=0;e<6;e++){const t=[];for(let s=0;s<3;s++)t.push(PIXI.Texture.from("human"+(e+1)+"_"+(s+1)+".png"));this.textures.push({animated:t,dead:[PIXI.Texture.from("human"+(e+1)+"_dead.png")]})}if(0==this.doctorTextures.length){for(let e=0;e<3;e++)this.doctorTextures.push(PIXI.Texture.from("doctor"+(e+1)+".png"));this.doctorDeadTexture=[PIXI.Texture.from("doctor4.png")]}if(this.humans.length>0){for(let e=0;e0)this.discardedHumans.length>0?(e=this.discardedHumans.pop(),e.textures=this.doctorTextures):e=new ve(this.doctorTextures),e.deadTexture=this.doctorDeadTexture,e.flags.doctor=!0,e.flags.torchBearer=!1,e.timer.healTick=Math.random()*this.healTickTimer,t--;else{const t=Math.random()0?(e=this.discardedHumans.pop(),e.textures=this.textures[s].animated):e=new ve(this.textures[s].animated),e.flags.torchBearer=t,e.deadTexture=this.textures[s].dead,e.flags.doctor=!1}e.reset(),e.flags.vip=!1,e.flags.dead=!1,e.flags.burning=!1,e.flags.infected=!1,e.burnDamage=0,e.plagueDamage=0,e.plagueTicks=0,e.animationSpeed=.15,e.anchor.set(35/80,1),e.currentPoi=this.map.getRandomBuilding(),e.position.copyFrom(this.map.randomPositionInBuilding(e.currentPoi)),e.zIndex=e.position.y,e.xSpeed=0,e.ySpeed=0,e.timer.plagueTick=Math.random()*this.plagueTickTimer,e.target=!1,e.speedMod=1,e.zombieTarget=null,e.lastKnownBuilding=null,e.visionDistance=this.visionDistance,e.visible=!0,e.alpha=1,e.maxHealth=e.health=s,i&&!e.flags.doctor&&(e.flags.vip=!0,this.vip=e,i=!1,e.maxHealth=e.health=2*s,this.setupVipText(e)),e.timer.scan=Math.random()*this.scanTime,e.timer.flee=0,this.changeState(e,ce.standing),e.timer.standing=Math.random()*this.randomSecondsToStand(),e.timer.attack=this.attackSpeed,e.scale.set(Math.random()>.5?this.scaling:-1*this.scaling,this.scaling),this.humans.push(e),g.addChild(e)}}updateHumanSpeed(e,t){if(this.frozen)return void e.gotoAndStop(0);if(e.playing||e.play(),e.timer.dogStun&&e.timer.dogStun>0)return void(e.timer.dogStun-=t);0==e.timer.target&&e.targetVector||(e.timer.target=0),e.timer.target-=t,e.timer.target<=0&&(e.targetVector=this.map.howDoIGetToMyTarget(e,e.target),e.timer.target=.2);const s=e.speedMod*e.maxSpeed;e.xSpeed=e.targetVector.x*s,e.ySpeed=e.targetVector.y*s,(isNaN(e.xSpeed)||isNaN(e.ySpeed))&&(e.xSpeed=0,e.ySpeed=0),e.position.x+=e.xSpeed*t,e.position.y+=e.ySpeed*t,e.zIndex=e.position.y,Math.abs(e.xSpeed)>1&&!e.flags.tank&&(e.scale.x=e.xSpeed>0?this.scaling:-this.scaling)}update(e){if(this.gameModel.currentState!=this.gameModel.states.playingLevel)return;const t=[],s=this.zombies.aliveZombies;this.graveyardAttackers.length=0;for(let i=0;i.5&&e.alpha-this.fadeSpeed*t<=.5&&!e.flags.tank&&Math.random()0&&e.plagueTicks--,e.health+=2*this.attackDamage,e.health>e.maxHealth&&(e.health=e.maxHealth,e.speedMod=Math.max(Math.min(1,e.health/e.maxHealth),.25)),this.exclamations.newHealing(e))}doHeal(e,t){if(e.timer.healTick-=t,e.timer.healTick<0){const t=100;e.timer.healTick=this.healTickTimer;for(let s=0;s0&&(e.flags.vip?e.state!==ce.escaping&&this.changeState(e,ce.escaping):Math.random(){this.vipEscaping=!1}),2e3)):this.updateHumanSpeed(e,t);break;case ce.attacking:e.scale.x=e.target.x>e.x?this.scaling:-this.scaling,e.zombieTarget&&!e.zombieTarget.flags.dead?this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y)9))return s;return s}}class Me extends ve{constructor(){super(...arguments),this.radioTime=0,this.followTimer=0}}!function(e){e[e.shooting=0]="shooting",e[e.attacking=1]="attacking",e[e.walking=2]="walking",e[e.running=3]="running",e[e.standing=4]="standing",e[e.following=5]="following",e[e.hunting=6]="hunting"}(ue||(ue={}));class ke{constructor(){if(this.maxWalkSpeed=15,this.maxRunSpeed=40,this.police=[],this.discardedPolice=[],this.walkTexture=[],this.deadTexture=[],this.dogTexture=[],this.deadDogTexture=[],this.policeDogLevel=20,this.policePerLevel=1,this.attackSpeed=2,this.attackDamage=16,this.attackDistance=20,this.moveTargetDistance=5,this.shootDistance=110,this.visionDistance=150,this.scaling=2,this.dogScaling=1.3,this.radioTime=30,ke.instance)return ke.instance;ke.instance=this}isExtraPolice(){return(this.gameModel.level+10)%20==0}getMaxPolice(){const e=Math.min(Math.round(this.policePerLevel*this.gameModel.level),100);return this.gameModel.level<3?0:this.isExtraPolice()?Math.max(2*e,150):e}getMaxHealth(){return Math.round(1.1*this.humans.getMaxHealth(this.gameModel.level))}getAttackDamage(){this.attackDamage=Math.round(this.getMaxHealth()/10)}populate(){if(this.map=new ee,this.gameModel=ne.getInstance(),this.humans=new Se,this.exclamations=new it,this.zombies=new Ae,this.bullets=new rt,0==this.walkTexture.length){for(let e=0;e<3;e++)this.walkTexture.push(PIXI.Texture.from("cop"+(e+1)+".png"));this.deadTexture=[PIXI.Texture.from("cop4.png")];for(let e=0;e<2;e++)this.dogTexture.push(PIXI.Texture.from("dog"+(e+1)+".png"));this.deadDogTexture=[PIXI.Texture.from("dogdead.png")]}if(this.police.length>0){for(let e=0;e0?(e=this.discardedPolice.pop(),e.alpha=1,e.textures=this.walkTexture):e=new Me(this.walkTexture),e.reset(),e.flags.dog=!1,e.flags.dead=!1,e.flags.infected=!1,e.flags.burning=!1,e.burnDamage=0,e.plagueDamage=0,e.plagueTicks=0,e.deadTexture=this.deadTexture,e.animationSpeed=.2,e.anchor.set(35/80,1),e.currentPoi=this.map.getRandomBuilding(),e.position.copyFrom(this.map.randomPositionInBuilding(e.currentPoi)),e.zIndex=e.position.y,e.xSpeed=0,e.ySpeed=0,e.radioTime=5,e.speedMod=1,e.lastKnownBuilding=void 0,e.timer.plagueTick=Math.random()*this.humans.plagueTickTimer,e.maxSpeed=this.maxWalkSpeed,e.visionDistance=this.visionDistance,e.visible=!0,e.maxHealth=e.health=t,e.timer.scan=Math.random()*this.humans.scanTime,e.timer.standing=Math.random()*this.humans.randomSecondsToStand(),e.target=!1,e.zombieTarget=void 0,e.policeState=ue.standing,e.timer.attack=this.attackSpeed,e.scale.set(Math.random()>.5?this.scaling:-1*this.scaling,this.scaling),this.police.push(e),g.addChild(e),this.gameModel.level>=this.policeDogLevel&&Math.random()>.5&&this.createPoliceDog(e,s)}this.isExtraPolice()&&this.gameModel.sendMessage("Warning: High Police Activity!")}createPoliceDog(e,t){let s;this.discardedPolice.length>0?(s=this.discardedPolice.pop(),s.alpha=1,s.textures=this.dogTexture):s=new Me(this.dogTexture),s.reset(),s.owner=e,s.flags.dog=!0,s.flags.dead=!1,s.flags.infected=!1,s.flags.burning=!1,s.burnDamage=0,s.plagueDamage=0,s.plagueTicks=0,s.deadTexture=this.deadDogTexture,s.animationSpeed=.15,s.anchor.set(.5,1),s.position.set(e.position.x+3,e.position.y),s.zIndex=s.position.y,s.xSpeed=0,s.ySpeed=0,s.speedMod=1,s.lastKnownBuilding=null,s.timer.plagueTick=Math.random()*this.humans.plagueTickTimer,s.maxSpeed=this.maxRunSpeed,s.visionDistance=this.visionDistance,s.visible=!0,s.maxHealth=s.health=t,s.timer.scan=Math.random()*this.humans.scanTime,s.target=e,s.zombieTarget=null,s.policeState=ue.following,s.followTimer=0,s.timer.attack=this.attackSpeed,s.scale.set(Math.random()>.5?this.dogScaling:-1*this.dogScaling,this.dogScaling),this.police.push(s),g.addChild(s)}update(e,t){let s=0;for(let i=0;ithis.shootDistance)return void this.changeState(e,ue.running);if(te.x?this.scaling:-this.scaling,e.timer.attack<0&&(this.zombies.damageZombie(e.zombieTarget,this.attackDamage,e),e.timer.attack=this.attackSpeed)):this.changeState(e,ue.standing);break;case ue.shooting:e.zombieTarget&&!e.zombieTarget.flags.dead?(e.scale.x=e.zombieTarget.x>e.x?this.scaling:-this.scaling,e.timer.attack<0&&(this.bullets.newBullet(e,e.zombieTarget,this.attackDamage),e.timer.attack=this.attackSpeed)):this.changeState(e,ue.standing)}}updateDogSpeed(e,t){this.humans.updateHumanSpeed(e,t),Math.abs(e.xSpeed)>1&&(e.scale.x=e.xSpeed>0?this.dogScaling:-this.dogScaling)}updatePoliceDog(e,t,s){if(e.flags.dead)return this.humans.updateDeadHumanFading(e,t);switch(e.timer.attack-=t,e.timer.scan-=t,e.flags.infected&&this.humans.updatePlague(e,t),e.flags.burning&&this.humans.updateBurns(e,t),e.policeState){case ue.following:if(e.owner.flags.dead){e.policeState=ue.hunting,e.play();break}if(e.owner.zombieTarget&&!e.owner.zombieTarget.flags.dead){e.policeState=ue.attacking,e.play(),e.target=e.owner.zombieTarget;break}e.target=e.owner,i(e.position.x,e.position.y,e.target.x,e.target.y)e.x?this.dogScaling:-this.dogScaling,e.timer.attack<0&&(this.zombies.damageZombie(e.zombieTarget,this.attackDamage,e),e.target.dogStun=1,e.timer.attack=this.attackSpeed)):(e.target=e.zombieTarget,this.updateDogSpeed(e,t)):e.policeState=ue.following;break;case ue.hunting:(!e.zombieTarget||e.zombieTarget.flags.dead)&&e.timer.scan<0&&(this.humans.scanForZombies(e,s),e.zombieTarget&&(e.policeState=ue.attacking)),i(e.position.x,e.position.y,e.target.x,e.target.y)0){for(let e=0;e=25;for(let s=0;s35&&Math.random()<.3&&(s=1),(this.gameModel.level>45&&Math.random()<.3||this.gameModel.isBossStage(this.gameModel.level)&&Math.random()<.5)&&(s=2),this.discardedArmymen.length>0?(e=this.discardedArmymen.pop(),e.alpha=1,e.textures=this.textures[s].animated):e=new we(this.textures[s].animated),e.reset(),e.flags.dead=!1,e.flags.infected=!1,e.flags.burning=!1,e.burnDamage=0,e.plagueDamage=0,e.minigun=1==s,e.rocketlauncher=2==s,e.deadTexture=this.textures[s].dead,e.animationSpeed=.2,e.anchor.set(35/80,1),e.currentPoi=this.map.getRandomBuilding(),e.position.copyFrom(this.map.randomPositionInBuilding(e.currentPoi)),e.zIndex=e.position.y,e.xSpeed=0,e.ySpeed=0,e.speedMod=1,e.lastKnownBuilding=null,e.maxSpeed=this.maxWalkSpeed,e.visionDistance=this.visionDistance,e.visible=!0,e.maxHealth=e.health=t,e.timer.attack=this.attackSpeed,e.timer.plagueTick=Math.random()*this.humans.plagueTickTimer,e.timer.scan=Math.random()*this.humans.scanTime,e.timer.standing=Math.random()*this.humans.randomSecondsToStand(),e.target=!1,e.zombieTarget=null,e.graveYardTarget=null,e.armyState=pe.standing,e.attackingGraveyard=!1,e.scale.set(Math.random()>.5?this.scaling:-1*this.scaling,this.scaling),this.armymen.push(e),g.addChild(e)}this.isExtraArmy()&&this.gameModel.sendMessage("Warning: High Military Activity!")}update(e,t){let s=0;this.aliveZombies=t,this.droneActive&&(this.droneStrikeTimer-=e);for(let i=0;ithis.shootDistance&&!e.rocketlauncher)return void this.changeState(e,pe.running);if(s>1.2*this.shootDistance&&e.rocketlauncher)return void this.changeState(e,pe.running);if(s3&&this.droneActive&&this.droneStrikeTimer<0&&this.callDroneStrike(e,s),this.assaultStarted&&e.rocketlauncher&&Math.random()>.98&&(e.graveYardTarget=this.graveyard.target,e.attackingGraveyard=!0)),this.decideStateOnZombieDistance(e),e.armyState){case pe.standing:e.timer.standing-=t,e.timer.standing<0&&(this.humans.assignRandomTarget(e),this.changeState(e,pe.walking));break;case pe.walking:i(e.position.x,e.position.y,e.target.x,e.target.y)e.x?this.scaling:-this.scaling,e.timer.attack<0&&(this.zombies.damageZombie(e.zombieTarget,this.attackDamage,e),e.timer.attack=this.attackSpeed)):this.changeState(e,pe.standing);break;case pe.shooting:e.graveYardTarget||e.zombieTarget&&!e.zombieTarget.flags.dead?(e.target=null!==(r=e.graveYardTarget)&&void 0!==r?r:e.zombieTarget,e.scale.x=e.target.x>e.x?this.scaling:-this.scaling,e.timer.attack<0&&(e.shotsLeft=this.shotsPerBurst,e.minigun&&(e.shotsLeft=3*this.shotsPerBurst),e.rocketlauncher&&(e.shotsLeft=1),e.timer.attack=e.rocketlauncher?1.5*this.attackSpeed:this.attackSpeed,e.shotTimer=0),e.shotsLeft>0&&(e.shotTimer-=t,e.shotTimer<0&&(e.shotTimer=.15,e.minigun&&(e.shotTimer=.08),this.bullets.newBullet(e,e.target,e.rocketlauncher?1.2*this.attackDamage:e.minigun?this.attackDamage/2:this.attackDamage,!1,e.rocketlauncher),e.shotsLeft--))):this.changeState(e,pe.standing)}}callDroneStrike(e,t){let s=0;for(let i=0;ie.zombieTarget.x-this.droneBlastRadius&&t[i].xe.zombieTarget.y-this.droneBlastRadius&&t[i].ye.zombieTarget.x-this.droneBlastRadius&&a[t].xe.zombieTarget.y-this.droneBlastRadius&&a[t].y1&&0==i&&(this.exclamations.newRadio(e),this.droneStrikeTimer=this.droneStrikeTime,this.droneStrike={caller:e,target:e.zombieTarget,timer:3,bombsLeft:3})}droneBomb(e){this.droneExplosion(this.droneStrike.target.x+32*(Math.random()-1),this.droneStrike.target.y+32*(Math.random()-1),e,3*this.attackDamage),this.droneStrike.timer=.3,this.droneStrike.bombsLeft--}droneExplosion(e,t,s,i){s||(s=this.aliveZombies),this.blasts.newDroneBlast(e,t);for(let a=0;ae-this.droneBlastRadius&&s[a].xt-this.droneBlastRadius&&s[a].y0){for(let e=0;e.9&&(e.graveYardTarget=this.graveyard.target,e.attackingGraveyard=!0)),this.decideStateOnZombieDistance(e),e.tankState){case ge.patrolling:e.target||(e.target=this.map.randomPositionInBuilding(null)),i(e.position.x,e.position.y,e.target.x,e.target.y)Math.abs(e.ySpeed)?e.currentDirection!=me.horizontal&&(e.currentDirection=me.horizontal,e.textures=this.textures.horizontal,e.play(),e.turretSprite.y=-7):e.currentDirection!=me.vertical&&(e.currentDirection=me.vertical,e.textures=this.textures.vertical,e.play(),e.turretSprite.y=-8),e.graveYardTarget||e.zombieTarget){e.target=null!==(s=e.graveYardTarget)&&void 0!==s?s:e.zombieTarget;const i=Math.atan2(e.target.x-e.x,e.y-e.target.y)+Math.PI/2;e.turretSprite.rotation>i?e.turretSprite.rotation-=3*t:e.turretSprite.rotation+=3*t}}decideStateOnZombieDistance(e){var t;if(e.graveYardTarget||e.zombieTarget&&!e.zombieTarget.flags.dead){if(e.target=null!==(t=e.graveYardTarget)&&void 0!==t?t:e.zombieTarget,i(e.position.x,e.position.y,e.target.x,e.target.y)>this.shootDistance)return void this.changeState(e,ge.attacking);this.changeState(e,ge.shooting)}}changeState(e,t){switch(t){case ge.patrolling:case ge.attacking:e.play();break;case ge.shooting:e.gotoAndStop(0)}e.tankState=t}}class Pe extends Q{constructor(){super(...arguments),this.currentDirection=0,this.bulletReflect=0,this.zombieId=0,this.lastKnownBuilding=null,this.maxSpeed=0,this.graveyard=!1,this.regenTimer=0,this.bloodbornTimer=0,this.level=0,this.creatureType=0,this.scaling=0,this.attackDamage=0,this.speedMultiplier=1,this.price=0,this.immuneToBurns=!1,this.zombie=!0,this.textureSet={set:!1,down:[],up:[],left:[],right:[],dead:[]}}}!function(e){e[e.lookingForTarget=0]="lookingForTarget",e[e.movingToTarget=1]="movingToTarget",e[e.attackingTarget=2]="attackingTarget"}(be||(be={}));class ze extends PIXI.Text{constructor(){super(...arguments),this.speed=30,this.fadeTime=.5}updateCritText(e){this.visible&&(this.y-=this.speed*e,this.fadeTime-=e,this.fadeTime<0&&(this.alpha-=2*e,this.alpha<0&&(this.visible=!1,Re.push(this))))}reset(){this.fadeTime=.5,this.alpha=1,this.visible=!0}}const Ie=new PIXI.TextStyle({fill:"#ef0",fontSize:64}),Be=[],Re=[];function He(e,t,s){if(ne.getInstance().persistentData.particles)if(Re.length>0){const i=Re.pop();i.reset(),i.text=r(s),i.position.set(e,t)}else{const i=new ze(r(s),Ie);b.addChild(i),i.position.set(e,t),i.anchor.set(.5,1),i.scale.set(.2,.2),Be.push(i)}}class Fe extends K{constructor(){super(...arguments),this.dog=!1,this.super=!1}}class Ee extends Pe{constructor(){super(...arguments),this.flags=new Fe,this.mod=1,this.scaleMod=1,this.textureId=0,this.turnTimer=0}}class Ae{constructor(){if(this.zombies=[],this.discardedZombies=[],this.aliveZombies=[],this.aliveHumans=[],this.zombiePartition=[],this.scaling=2,this.moveTargetDistance=15,this.attackDistance=15,this.attackSpeed=3,this.targetDistance=100,this.fadeSpeed=.1,this.refundChance=0,this.currId=1,this.scanTime=3,this.textures=[],this.dogTexture=[],this.deadDogTexture=[],this.maxSpeed=10,this.zombieCursor=null,this.zombieCursorText=null,this.zombieCursorScale=3,this.mouseOutOfBounds=!1,this.burnTickTimer=5,this.bloodpact=1,this.bloodborn=0,this.gigamutagen=0,this.gigamutationTimer=10,this.smokeTimer=.3,this.fastDistance=i,this.magnitude=t,this.detonate=!1,this.super=!1,this.reactionTime=0,this.graveyardAttackers=[],this.spaceNeeded=3,Ae.instance)return Ae.instance;Ae.instance=this}populate(){if(this.map=new ee,this.model=ne.getInstance(),this.humans=new Se,this.graveyard=new Oe,this.creatureFactory=new ae,this.smoke=new ot,this.blood=new _e,this.bones=new tt,this.exclamations=new it,this.blasts=new nt,this.bullets=new rt,this.model.zombieCount=0,0==this.textures.length){for(let e=0;e<3;e++){const t=[];for(let s=0;s<3;s++)t.push(PIXI.Texture.from("zombie"+(e+1)+"_"+(s+1)+".png"));this.textures.push({animated:t,dead:[PIXI.Texture.from("zombie"+(e+1)+"_dead.png")]})}for(let e=0;e<2;e++)this.dogTexture.push(PIXI.Texture.from("zombiedog"+(e+1)+".png"));this.deadDogTexture=[PIXI.Texture.from("zombiedogdead.png")]}if(this.zombies.length>0){for(let e=0;e0?(a=this.discardedZombies.pop(),a.textures=s?this.dogTexture:this.textures[i].animated):a=new Ee(s?this.dogTexture:this.textures[i].animated),a.zombie=!0,a.mod=1,a.scaleMod=1,this.super&&(a.mod=10,a.scaleMod=1.5),a.flags=new Fe,a.flags.dog=s,a.flags.super=this.super,a.deadTexture=a.flags.dog?this.deadDogTexture:this.textures[i].dead,a.textureId=i,a.burnDamage=0,a.lastKnownBuilding=!1,a.alpha=1,a.animationSpeed=.15,a.anchor.set(35/80,1),a.bloodbornTimer=this.bloodborn,a.position.set(e,t),a.target=null,a.zIndex=a.position.y,a.visible=!0,a.maxHealth=a.health=this.model.zombieHealth*a.mod,a.regenTimer=5,a.state=be.lookingForTarget;const r=s?.7:1;a.scaling=a.scaleMod*this.scaling*r,a.scale.set(Math.random()>.5?a.scaling:-1*a.scaling,a.scaling),a.timer.attack=0,a.xSpeed=0,a.ySpeed=0,a.speedMultiplier=1,a.timer.scan=0,a.timer.burnTick=this.burnTickTimer,a.timer.smoke=this.smokeTimer,a.play(),a.zombieId=this.currId++,this.zombies.push(a),g.addChild(a),this.smoke.newZombieSpawnCloud(e,t-2)}spawnZombie(e,t){this.model.energy0&&(t*=.5,this.exclamations.newShield(e)),s&&s.flags.infected&&(t*=this.model.plagueDmgReduction),e.health-=t*this.model.runeEffects.damageReduction,this.setSpeedMultiplier(e),this.blood.newSplatter(e.x,e.y),e.health<=0&&!e.flags.dead&&(this.bones.newBones(e.x,e.y),e.flags.dead=!0,e.flags.golem&&this.refundChance>0&&(this.model.sendMessage("Golem Refunded!"),this.creatureFactory.refundParts(e,this.refundChance)),Math.random()0&&this.humans.damageHuman(s,t*this.model.runeEffects.damageReflection)}}causePlagueExplosion(e,t,s=!0,i=!1){const a=i?75:50;this.blood.newPlagueSplatter(e.x,e.y),i?this.blasts.newDetonateBlast(e.x,e.y-4):this.blasts.newZombieBlast(e.x,e.y-4),s&&(e.visible=!1,g.removeChild(e));for(let s=0;s0){const s=t*this.model.blastHealing;for(let t=0;t0&&(this.gigamutationTimer-=e);for(let i=0;i=this.model.zombieCost&&this.model.currentState==this.model.states.playingLevel)if(this.zombieCursor.visible=!this.mouseOutOfBounds,Y.shift&&!this.mouseOutOfBounds){this.zombieCursorText.visible=!0;const e=Math.min(Math.floor(this.model.energy/this.model.zombieCost),100);this.zombieCursorText.text!=e&&(this.zombieCursorText.text=e)}else this.zombieCursorText.visible=!1;else this.zombieCursor.visible=!1}detonateZombie(e){(e.state==be.attackingTarget||0==this.aliveHumans.length&&Math.random()<.05)&&(this.bones.newBones(e.x,e.y),e.flags.dead=!0,this.causePlagueExplosion(e,e.maxHealth,!0,!0),Math.random()0&&this.updateZombieRegen(e,t),this.detonate&&this.detonateZombie(e),e.flags.burning&&this.updateBurns(e,t),(!e.target||e.target.flags.dead)&&e.timer.scan<0&&(e.state=be.lookingForTarget),e.state){case be.lookingForTarget:this.searchClosestTarget(null!==(s=e.target)&&void 0!==s?s:e),e.target&&!e.target.flags.dead||this.assignRandomTarget(e),e.target&&(e.state=be.movingToTarget);break;case be.movingToTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);if(s3*this.attackDistance&&e.timer.scan<0&&this.searchClosestTarget(e),this.updateZombieSpeed(e,t);break}case be.attackingTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);se.x?e.scaling:-e.scaling,e.timer.attack<0&&(this.humans.damageHuman(e.target,this.calculateDamage(e)),e.flags.dog&&(e.target.timer.dogStun=1),Math.random()this.attackDistance/2&&this.updateZombieSpeed(e,t)):e.state=be.movingToTarget;break}}}setSpeedMultiplier(e){e.flags.burning?e.speedMultiplier=this.model.burningSpeedMod:e.speedMultiplier=Math.max(Math.min(1,e.health/e.maxHealth),.4)}updateZombieRegen(e,t){e.regenTimer-=t,e.regenTimer<0&&(e.regenTimer=5,e.healthe.maxHealth&&(e.health=e.maxHealth),this.setSpeedMultiplier(e)))}healZombie(e,t){e.healthe.maxHealth&&(e.health=e.maxHealth),this.setSpeedMultiplier(e))}calculateDamage(e){let t=this.model.zombieDamage*e.mod;return this.model.runeEffects.critChance>0&&Math.random()0&&this.model.addBlood(t*this.bloodpact),t}inflictPlague(e){e.flags.infected?(e.plagueDamage+=this.model.zombieDamage/2+this.model.plagueDamageMod,e.plagueTicks=this.model.plagueticks):(this.exclamations.newPoison(e),e.plagueDamage=this.model.zombieDamage/2+this.model.plagueDamageMod,e.plagueTicks=this.model.plagueticks),e.flags.infected=!0}updateBurns(e,t){e.timer.burnTick-=t,e.timer.smoke-=t,e.timer.smoke<0&&(this.smoke.newFireSmoke(e.x,e.y-14),e.timer.smoke=this.smokeTimer),e.timer.burnTick<0&&(this.damageZombie(e,e.burnDamage,null),e.timer.burnTick=this.burnTickTimer,this.exclamations.newFire(e))}searchClosestTarget(e){if(e.timer.scan>0)return;e.timer.scan=this.scanTime*Math.random();let t=300;if(this.model.isBossStage(this.model.level)&&Math.random()>.3)for(let s=0;s0)return void(e.timer.dogStun-=t);if(e.timer.target&&e.targetVector||(e.timer.target=0),e.timer.target-=t,e.timer.target<=0&&(e.targetVector=this.map.howDoIGetToMyTarget(e,e.target),e.timer.target=this.reactionTime),this.model.gameSpeed>1||e.flags.dog){const t=e.flags.dog?1.5:1,s=Math.max(this.maxSpeed*e.speedMultiplier*t,8);e.xSpeed=e.targetVector.x*s,e.ySpeed=e.targetVector.y*s}else{const s=5*this.maxSpeed*t;e.xSpeed+=e.targetVector.x*s,e.ySpeed+=e.targetVector.y*s;const i=this.dotProduct(e.xSpeed,e.ySpeed),a=Math.pow(Math.max(this.maxSpeed*e.speedMultiplier,8),2);i>a&&(e.xSpeed*=a/i,e.ySpeed*=a/i)}let s={x:e.position.x+e.xSpeed*t,y:e.position.y+e.ySpeed*t};if(e.turnTimer-=t,e.turnTimer<0&&(e.turnTimer=.5,!this.isSpaceToMove(e,s.x,s.y))){if(Math.random()>.5){const t={x:-e.ySpeed/2+e.xSpeed/2,y:e.xSpeed/2+e.ySpeed/2};e.xSpeed=t.x,e.ySpeed=t.y}else{const t={x:e.ySpeed/2+e.xSpeed/2,y:-e.xSpeed/2+e.ySpeed/2};e.xSpeed=t.x,e.ySpeed=t.y}s={x:e.position.x+e.xSpeed*t,y:e.position.y+e.ySpeed*t}}const i=this.map.checkCollisions(e.position,s);i&&(i.x&&(e.xSpeed=0),i.y&&(e.ySpeed=0),s={x:e.position.x+e.xSpeed*t,y:e.position.y+e.ySpeed*t},i.x&&(s.x=i.validX),i.y&&(s.y=i.validY)),e.position.set(s.x,s.y),e.zIndex=e.position.y,e.scale.x=e.xSpeed>0?e.scaling:-e.scaling}isSpaceToMove(e,t,s){const i=this.partitionGetNeighbours(e);for(let a=0;a=e.health&&i[a].zombieId!=e.zombieId&&Math.abs(i[a].x-t)this.fastDistance(e.x,e.y,i[a].x,i[a].y);return!0}}class Le extends Pe{constructor(){super(...arguments),this.boneshieldTimer=3,this.boneshield=0,this.boneshieldContainer=new Ge}}class Ze extends PIXI.Sprite{constructor(){super(...arguments),this.speed={x:0,y:0},this.flying=!1}}class Ge extends PIXI.Container{constructor(){super(...arguments),this.spacing=2*Math.PI/10,this.bones=[]}getTexture(){if(this.texture)return this.texture;const e=document.createElement("canvas");e.width=4,e.height=1;const t=e.getContext("2d");return t.fillStyle="#dddddd",t.fillRect(0,0,4,1),this.texture=PIXI.Texture.from(e),this.texture}getBone(){const e=new Ze(this.getTexture());return e.anchor.set(.5,20),this.addChild(e),this.bones.push(e),e}update(e){e>this.bones.length&&(this.getBone().rotation=this.spacing*this.bones.length);for(let t=0;te+t),0)}getAvailablePoints(){return this.talentPoints-this.getUsedPoints()}xpForNextLevel(){return 1e3*Math.pow(this.persistent.level,2)}addXp(e){if(this.isAlive()&&(this.persistent.xp+=e*this.persistent.xpRate,this.persistent.xp>this.xpForNextLevel())){this.persistent.xp-=this.xpForNextLevel(),this.persistent.level++,this.upgrades.applyUpgrades(),this.model.sendMessage("Skeleton Champion reached level "+this.persistent.level+"!");const e=document.getElementById("skeleton");e&&(e.classList.toggle("levelup"),setTimeout((function(){e.classList.toggle("levelup")}),3e3))}}isAlive(){for(let e=0;e0){this.applyItemUpgrades();const e=1+this.persistent.level/100;this.model.bloodPCMod*=e,this.model.brainsPCMod*=e,this.model.bonesPCMod*=e,this.model.partsPCMod*=e,this.model.zombieDamagePCMod*=e,this.model.zombieHealthPCMod*=e}}acceptOffer(){this.model.persistentData.trophies=[],this.persistent.skeletons<1?(this.persistent.skeletons=1,this.persistent.xpRate=1,this.model.sendMessage("Skeleton Champion joins the fight!")):this.persistent.xpRate*=2,this.upgrades.applyUpgrades(),this.model.saveData()}populate(){if(this.model=ne.getInstance(),this.map=new ee,this.graveyard=new Oe,this.exclamations=new it,this.bullets=new rt,this.spells=new q,this.smoke=new ot,this.upgrades=new oe,this.humans=new Se,this.zombies=new Ae,this.prestigePoints=new Je,this.partFactory=new se,this.bones=new tt,this.blasts=new nt,this.blood=new _e,this.damageZombie=this.zombies.damageZombie,this.searchClosestTarget=this.zombies.searchClosestTarget,this.updateBurns=this.zombies.updateBurns,this.updateZombieRegen=this.zombies.updateZombieRegen,this.causePlagueExplosion=this.zombies.causePlagueExplosion,this.inflictPlague=this.zombies.inflictPlague,this.healZombie=this.zombies.healZombie,this.setSpeedMultiplier=this.zombies.setSpeedMultiplier,!this.textures.set){this.textures.down=[],this.textures.up=[],this.textures.right=[],this.textures.dead=[];for(let e=0;e<3;e++)this.textures.down.push(PIXI.Texture.from("skeleton"+e+".png"));for(let e=3;e<6;e++)this.textures.up.push(PIXI.Texture.from("skeleton"+e+".png"));for(let e=6;e<9;e++)this.textures.right.push(PIXI.Texture.from("skeleton"+e+".png"));this.textures.dead.push(PIXI.Texture.from("skeleton9.png")),this.textures.set=!0}const e=[];for(let t=0;t2?8:0),this.skeletons[t].target=null,this.skeletons[t].state=be.lookingForTarget,this.skeletons[t].timer.scan=0);this.skeletons=e,this.aliveSkeletons=[],this.lootChance=.001,this.model.level2*this.persistent.level&&(this.lootChance*=1.5)}spawnCreature(){let e;this.discardedSprites.length>0?(e=this.discardedSprites.pop(),e.textures=this.textures.down):(e=new Le(this.textures.down),e.addChild(e.boneshieldContainer),e.boneshieldContainer.position.set(0,-16)),e.tint=15658734,e.immuneToBurns=!1,e.bulletReflect=0,e.zombie=!0,e.textureSet=this.textures,e.deadTexture=this.textures.dead,e.currentDirection=this.directions.down,e.flags=new K,e.burnDamage=0,e.lastKnownBuilding=!1,e.alpha=1,e.animationSpeed=.15,e.anchor.set(8.5/16,1),e.position.set(this.graveyard.sprite.x,this.graveyard.sprite.y+(this.graveyard.level>2?8:0)),e.target=null,e.zIndex=e.position.y,e.visible=!0,e.maxHealth=e.health=10*this.model.zombieHealth,e.attackDamage=10*this.model.zombieDamage,e.regenTimer=5,e.state=be.lookingForTarget,e.scaling=this.scaling,e.scale.set(e.scaling,e.scaling),e.timer.ability=4*Math.random(),e.timer.attack=0,e.timer.scan=0,e.timer.burnTick=this.burnTickTimer,e.timer.smoke=this.smokeTimer,e.xSpeed=0,e.ySpeed=0,e.speedMultiplier=1,e.maxSpeed=this.moveSpeed,e.play(),e.zombieId=this.currId++,this.skeletons.push(e),g.addChild(e),this.smoke.newZombieSpawnCloud(e.x,e.y-2)}skeletonTimer(){return this.aliveSkeletons.length0&&e.boneshield0&&(this.darkorbTimer-=t,this.darkorbTimer<0&&e.target&&!e.target.flags.dead&&(this.darkorbTimer=this.darkorb,this.bullets.newBullet(e,e.target,this.calculateDamage(e),!1,!1,!1,!0))),e.timer.attack-=t,e.timer.scan-=t,e.timer.ability-=t,this.model.runeEffects.healthRegen>0&&this.updateZombieRegen(e,t),e.flags.burning&&!e.immuneToBurns&&this.updateBurns(e,t),e.timer.ability<0&&(e.timer.ability=4),e.target&&!e.target.flags.dead||(e.state=be.lookingForTarget,e.timer.target=0,e.timer.scan=0),e.state){case be.lookingForTarget:this.searchClosestTarget(e),e.target&&(e.state=be.movingToTarget);break;case be.movingToTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);if(s3*this.attackDistance&&e.timer.scan<0&&this.searchClosestTarget(e),this.updateCreatureSpeed(e,t);break}case be.attackingTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);if(s0))for(let e=0;ethis.attackDistance/2&&this.updateCreatureSpeed(e,t)}else e.state=be.movingToTarget;break}}}killingBlow(e){this.killingBlowParts&&(this.model.persistentData.parts+=this.killingBlowParts*this.partFactory.factoryStats().partsPerSec),this.lastKillingBlow<=0&&(this.model.addPrestigePoints(this.persistent.level),this.lastKillingBlow=20,this.prestigePoints.newPart(e.x,e.y))}orbHit(e){if(e.flags.dead&&this.killingBlow(e),this.randomSpells.length>0)for(let e=0;eMath.abs(e.ySpeed)?e.xSpeed<0?this.directions.left:this.directions.right:e.ySpeed<0?this.directions.up:this.directions.down}changeTextureDirection(e){const t=this.getCreatureDirection(e);if(t!==e.currentDirection){switch(t){case this.directions.up:e.textures=e.textureSet.up,e.scale.x=e.scaling;break;case this.directions.down:e.textures=e.textureSet.down,e.scale.x=e.scaling;break;case this.directions.right:e.textures=e.textureSet.right,e.scale.x=e.scaling;break;case this.directions.left:e.textures=e.textureSet.right,e.scale.x=-e.scaling}e.currentDirection=t,e.play()}}updateCreatureSpeed(e,t){if(e.timer.dogStun>0)return void(e.timer.dogStun-=t);e.timer.target&&e.targetVector||(e.timer.target=0),e.timer.target-=t,e.timer.target<=0&&(e.targetVector=this.map.howDoIGetToMyTarget(e,e.target),e.timer.target=.2);const s=4*this.fastDistance(e.x,e.y,e.target.x,e.target.y),i=Math.min(e.speedMultiplier*e.maxSpeed,s);e.xSpeed=e.targetVector.x*i,e.ySpeed=e.targetVector.y*i,e.position.x+=e.xSpeed*t,e.position.y+=e.ySpeed*t,e.zIndex=e.position.y,this.changeTextureDirection(e)}calculateDamage(e){let t=e.attackDamage;return this.model.runeEffects.critChance>0&&Math.random()e.q)).forEach((e=>{e.e.forEach((t=>{switch(t){case this.stats.respawnTime.id:this.respawnTime--;break;case this.stats.speed.id:this.moveSpeed++;break;case this.stats.zombieHealth.id:this.model.zombieHealth+=e.l*this.stats.zombieHealth.scaling;break;case this.stats.zombieDamage.id:this.model.zombieDamage+=e.l*this.stats.zombieDamage.scaling;break;case this.stats.zombieSpeed.id:this.model.zombieSpeed++}})),e.se&&e.se.forEach((e=>{this.randomSpells.push(e)}))}))}getLootName(e){let t="";switch(e.r){case this.rarity.common:t=this.prefixes.commonQuality[e.p];break;case this.rarity.rare:t=this.prefixes.rareQuality[e.p];break;case this.rarity.epic:t=this.prefixes.epicQuality[e.p];break;case this.rarity.legendary:t=this.prefixes.legendaryQuality[e.p]}let s="";switch(e.s){case this.lootPositions.helmet.id:s=this.lootPositions.helmet.name;break;case this.lootPositions.chest.id:s=this.lootPositions.chest.name;break;case this.lootPositions.legs.id:s=this.lootPositions.legs.name;break;case this.lootPositions.gloves.id:s=this.lootPositions.gloves.name;break;case this.lootPositions.boots.id:s=this.lootPositions.boots.name;break;case this.lootPositions.sword.id:s=this.lootPositions.sword.name;break;case this.lootPositions.shield.id:s=this.lootPositions.shield.name}return t+" "+s}getLootClass(e){switch(e.r){case this.rarity.common:return"common";case this.rarity.rare:return"rare";case this.rarity.epic:return"epic";case this.rarity.legendary:return"legendary"}}getLootStats(e){const t=[];if(e.e)for(let s=0;st.id==e.se[s]))[0];t.push(i.itemText||"Has a chance to cast "+i.name+" when attacking, this does not cost energy or trigger a cooldown")}return t}testForLoot(){if(this.persistent.skeletons>0&&Math.random().5?this.stats.zombieHealth.id:this.stats.zombieDamage.id];for(let e=0;ee.q||e.r==this.rarity.legendary))}xpForItems(){let e=0;return this.persistent.items.filter((e=>!e.q&&e.r!=this.rarity.legendary)).forEach((function(t){e+=t.l*t.r*10})),e}}class Ue{constructor(){if(this.creatureFactory=new ae,this.zombies=new Ae,this.creatures=[],this.creatureCount=[],this.aliveCreatures=[],this.aliveZombies=[],this.graveyardAttackers=[],this.discardedSprites=[],this.aliveHumans=[],this.scaling=1.6,this.moveTargetDistance=15,this.attackDistance=20,this.attackSpeed=3,this.targetDistance=100,this.fadeSpeed=.1,this.currId=1,this.scanTime=3,this.refundChance=0,this.creatureTypes=this.creatureFactory.types,this.golemTextures={set:!1,down:[],up:[],left:[],right:[],dead:[]},this.directions={down:1,up:2,right:3,left:4,dead:5},this.burnTickTimer=5,this.smokeTimer=.3,this.fastDistance=i,this.magnitude=t,this.damageZombie=this.zombies.damageZombie,this.searchClosestTarget=this.zombies.searchClosestTarget,this.updateBurns=this.zombies.updateBurns,this.updateZombieRegen=this.zombies.updateZombieRegen,this.causePlagueExplosion=this.zombies.causePlagueExplosion,this.inflictPlague=this.zombies.inflictPlague,this.healZombie=this.zombies.healZombie,this.setSpeedMultiplier=this.zombies.setSpeedMultiplier,Ue.instance)return Ue.instance;Ue.instance=this}populate(){if(this.map=new ee,this.model=ne.getInstance(),this.graveyard=new Oe,this.smoke=new ot,this.bullets=new rt,this.humans=new Se,this.exclamations=new it,this.blood=new _e,this.bones=new tt,this.blasts=new nt,!this.golemTextures.set){this.golemTextures.down=[],this.golemTextures.up=[],this.golemTextures.right=[],this.golemTextures.dead=[];for(let e=0;e<3;e++)this.golemTextures.down.push(PIXI.Texture.from("golem"+e+".png"));for(let e=3;e<6;e++)this.golemTextures.up.push(PIXI.Texture.from("golem"+e+".png"));for(let e=6;e<9;e++)this.golemTextures.right.push(PIXI.Texture.from("golem"+e+".png"));this.golemTextures.dead.push(PIXI.Texture.from("golem9.png")),this.golemTextures.set=!0}const e=[];for(let t=0;t2?8:0),this.creatures[t].target=null,this.creatures[t].state=be.lookingForTarget):(this.discardedSprites.push(this.creatures[t]),g.removeChild(this.creatures[t]));this.creatures=e,this.aliveCreatures=[],this.creatureFactory.spawnSavedCreatures()}spawnCreature(e,t,s,i,a,r){if(this.model.creatureCount>=this.model.creatureLimit)return;let n;switch(this.discardedSprites.length>0?(n=this.discardedSprites.pop(),n.textures=this.golemTextures.down):n=new Pe(this.golemTextures.down),i){case this.creatureTypes.earthGolem:n.tint=11042610,n.bulletReflect=this.model.bulletproofChance;break;case this.creatureTypes.airGolem:n.tint=10266040;break;case this.creatureTypes.fireGolem:n.tint=14370586,n.immuneToBurns=!0;break;case this.creatureTypes.waterGolem:n.tint=5080808,n.immuneToBurns=!0}n.flags=new K,n.flags.golem=!0,n.burnDamage=0,n.level=a,n.textureSet=this.golemTextures,n.deadTexture=this.golemTextures.dead,n.currentDirection=this.directions.down,n.creatureType=i,n.price=r,n.lastKnownBuilding=!1,n.alpha=1,n.animationSpeed=.15,n.anchor.set(8.5/16,1),n.position.set(this.graveyard.sprite.x,this.graveyard.sprite.y+(this.graveyard.level>2?8:0)),n.target=null,n.zIndex=n.position.y,n.visible=!0,n.maxHealth=n.health=e,n.attackDamage=t,n.regenTimer=5,n.state=be.lookingForTarget,n.scaling=this.scaling,n.scale.set(n.scaling,n.scaling),n.xSpeed=0,n.ySpeed=0,n.speedMultiplier=1,n.maxSpeed=s,n.timer.ability=4*Math.random(),n.timer.attack=0,n.timer.scan=0,n.timer.burnTick=this.burnTickTimer,n.timer.smoke=this.smokeTimer,n.play(),n.zombieId=this.currId++,this.creatures.push(n),g.addChild(n),this.smoke.newZombieSpawnCloud(n.x,n.y-2),this.model.creatureCount++}update(e){let t=0;this.aliveHumans=this.humans.aliveHumans,this.graveyardAttackers=this.humans.graveyardAttackers,this.aliveZombies=this.zombies.aliveZombies,this.creatureCount=[];for(let e=0;e0&&this.updateZombieRegen(e,t),e.flags.burning&&!e.immuneToBurns&&this.updateBurns(e,t),e.timer.ability<0)switch(e.timer.ability=4,e.creatureType){case this.creatureTypes.earthGolem:this.golemTaunt(e);break;case this.creatureTypes.waterGolem:this.golemHeal(e);break;case this.creatureTypes.fireGolem:this.golemFireball(e)}switch((!e.target||e.target.flags.dead)&&e.timer.scan<0&&(e.state=be.lookingForTarget),e.state){case be.lookingForTarget:this.searchClosestTarget(e),e.target&&(e.state=be.movingToTarget);break;case be.movingToTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);if(s3*this.attackDistance&&e.timer.scan<0&&this.searchClosestTarget(e),this.updateCreatureSpeed(e,t);break}case be.attackingTarget:{const s=this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y);se.x?e.scaling:-e.scaling,e.timer.attack<0&&(this.humans.damageHuman(e.target,this.calculateDamage(e)),e.creatureType==this.creatureTypes.fireGolem&&this.humans.burnHuman(e.target,e.attackDamage/2),e.timer.attack=this.attackSpeed*(1/this.model.runeEffects.attackSpeed),e.flags.burning&&(e.timer.attack*=1/this.model.burningSpeedMod)),s>this.attackDistance/2&&this.updateCreatureSpeed(e,t)):e.state=be.movingToTarget;break}}}getCreatureDirection(e){return Math.abs(e.xSpeed)>Math.abs(e.ySpeed)?e.xSpeed<0?this.directions.left:this.directions.right:e.ySpeed<0?this.directions.up:this.directions.down}changeTextureDirection(e){const t=this.getCreatureDirection(e);if(t!==e.currentDirection){switch(t){case this.directions.up:e.textures=e.textureSet.up,e.scale.x=e.scaling;break;case this.directions.down:e.textures=e.textureSet.down,e.scale.x=e.scaling;break;case this.directions.right:e.textures=e.textureSet.right,e.scale.x=e.scaling;break;case this.directions.left:e.textures=e.textureSet.right,e.scale.x=-e.scaling}e.currentDirection=t,e.play()}}updateCreatureSpeed(e,t){if(e.timer.dogStun&&e.timer.dogStun>0)return void(e.timer.dogStun-=t);e.timer.target&&e.targetVector||(e.timer.target=0),e.timer.target-=t,e.timer.target<=0&&(e.targetVector=this.map.howDoIGetToMyTarget(e,e.target),e.timer.target=.2);const s=e.speedMultiplier*e.maxSpeed;e.xSpeed=e.targetVector.x*s,e.ySpeed=e.targetVector.y*s,e.position.x+=e.xSpeed*t,e.position.y+=e.ySpeed*t,e.zIndex=e.position.y,this.changeTextureDirection(e)}calculateDamage(e){let t=e.attackDamage;return this.model.runeEffects.critChance>0&&Math.random()0&&Math.abs(this.aliveHumans[s].x-e.x)0&&(this.healthBar.foreground.lineStyle(8,16601682),this.healthBar.foreground.moveTo(0,0),this.healthBar.foreground.lineTo(e,0)),this.healthBar.percentage=e)}drawGraveyard(){this.spikeTexture||(this.spikeTexture=PIXI.Texture.from("spikes.png")),this.sprite&&u.removeChild(this.sprite),this.fortSprite&&(g.removeChild(this.fortSprite),this.fortSprite=null),this.level=1;let e="graveyard1.png",t="";this.gameModel.constructions.crypt&&(this.level=2,e="graveyard2.png"),this.gameModel.constructions.fort&&(this.level=3,e="sprites/megagraveyard.png",t="fort1.png"),this.gameModel.constructions.fortress&&(this.level=4,e="sprites/megagraveyard.png",t="fort2.png"),this.gameModel.constructions.citadel&&(this.level=5,e="sprites/megagraveyard.png",t="fort3.png"),this.sprite?this.sprite.texture=PIXI.Texture.from(e):this.sprite=new Ne(PIXI.Texture.from(e));const s=this.zmMap.graveYardLocation;this.sprite.width=32,this.sprite.height=32,this.sprite.anchor.set(.5,.5),this.sprite.scale.set(2,2),this.sprite.visible=!1,u.addChild(this.sprite),this.sprite.x=s.x,this.sprite.y=s.y,this.zmMap.graveyardCollision=!1,t&&(this.fortSprite?this.fortSprite.texture=PIXI.Texture.from(t):this.fortSprite=new PIXI.Sprite(PIXI.Texture.from(t)),this.fortSprite.anchor.set(.5,1),this.fortSprite.scale.set(2,2),this.fortSprite.x=s.x,this.fortSprite.zIndex=this.fortSprite.y=s.y+2,this.fortSprite.visible=!1,g.addChild(this.fortSprite))}drawFence(){if(this.fence||(this.fence=new PIXI.Container,u.addChild(this.fence)),this.fenceRadius=this.gameModel.fenceRadius,!this.fenceTextures){this.fenceTextures=[];for(let e=0;e<4;e++)this.fenceTextures.push(PIXI.Texture.from("fencepost"+(e+1)+".png"))}this.fencePosts.forEach((e=>e.visible=!1)),this.fence.cacheAsBitmap=!1;const e=Math.round(.4*this.fenceRadius),t=2*Math.PI/e;for(let r=0;r.5?1:-1;const n=10*Math.random()-5,o=(0,s=this.fenceRadius+n,i=t*r,{x:0*Math.cos(i)-s*Math.sin(i),y:0*Math.sin(i)+s*Math.cos(i)});e.position.set(o.x,o.y)}var s,i;this.fence.cacheAsBitmap=!0;const r=this.zmMap.graveYardLocation;this.fence.x=r.x,this.fence.y=r.y}update(e){if(this.boneCollectors.addAndRemoveBoneCollectors(),this.harpies.addAndRemoveHarpies(),this.gameModel.isBossStage(this.gameModel.level)&&this.updateHealthBar(),!this.gameModel.constructions.graveyard||this.gameModel.currentState!=this.gameModel.states.playingLevel)return this.sprite.visible=!1,void(this.fence.visible=!1);if((this.level<2&&this.gameModel.constructions.crypt||this.level<3&&this.gameModel.constructions.fort||this.level<4&&this.gameModel.constructions.fortress||this.level<5&&this.gameModel.constructions.citadel)&&this.drawGraveyard(),this.sprite.visible=!0,this.fortSprite&&(this.fortSprite.visible=!0),5==this.level&&Math.random()>.9&&(Math.random()>.5?this.smoke.newFireSmoke(this.sprite.x-20,this.sprite.y-113):this.smoke.newFireSmoke(this.sprite.x+20,this.sprite.y-113)),this.gameModel.energy>=this.gameModel.energyMax&&!this.gameModel.hidden)for(let e=0;e2?8:0));this.bones.update(e),this.boneCollectors.update(e),this.harpies.update(e),this.gameModel.constructions.fence&&this.gameModel.currentState==this.gameModel.states.playingLevel?(this.fenceRadius!==this.gameModel.fenceRadius&&this.drawFence(),this.fence.visible=!0):this.fence.visible=!1,this.updatePlagueSpikes(e),this.updateSpikeSprites(e)}updatePlagueSpikes(e){if(this.gameModel.constructions.plagueSpikes&&(this.spikeTimer-=e,this.spikeTimer<0)){this.spikeTimer=this.gameModel.spikeDelay;const e=this.humans.aliveHumans;for(let t=0;t.5?1.5:-1.5}updateSpikeSprites(e){for(let t=0;tthis.fence.x-this.fenceRadius&&e.xthis.fence.y-this.fenceRadius&&e.ythis.gameModel.persistentData.boneCollectors){const e=this.sprites.pop();if(e.boneList)for(let t=0;t.5?this.scaling:-1*this.scaling,this.scaling),e.xSpeed=0,e.ySpeed=0,e.bones=0,e.speedFactor=0,e.state=We.collecting,e.play(),e.boneList=[],this.sprites.push(e),g.addChild(e)}}update(e){for(let t=0;t0&&!this.bones.uncollected[e].collector){const r=this.fastDistance(t,s,this.bones.uncollected[e].x,this.bones.uncollected[e].y);r0?e.target=e.boneList.shift():e.target=!1}updateBoneCollector(e,t){switch(!e.target||e.target.graveyard&&e.state==We.collecting||this.updateSpeed(e,t),e.state){case We.collecting:if(e.target&&e.target.value&&e.target.visible||this.findNearestBone(e),e.target&&e.target.value>0&&this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y)=this.gameModel.boneCollectorCapacity||!e.target)return e.state=We.returning,void(e.target=this.graveyard.sprite);break;case We.returning:e.target||(e.target=this.graveyard.sprite),this.fastDistance(e.position.x,e.position.y,e.target.x,e.target.y)this.model.persistentData.harpies){const e=this.sprites.pop();e.target=!1,e.bomb&&(e.bomb.dropped=!0,e.bomb.floor=e.bomb.y+this.bombHeight),b.removeChild(e),this.discardedSprites.push(e)}if(this.sprites.length0?this.discardedSprites.pop():new je(this.textures);e.position.set(this.graveyard.sprite.x,this.graveyard.sprite.y-this.bombHeight),e.zIndex=e.position.y,e.scale.set(Math.random()>.5?this.scaling:-1*this.scaling,this.scaling),e.state=qe.returning,e.play(),this.sprites.push(e),b.addChild(e)}}update(e){for(let t=0;t=e.floor-2&&(e.visible=!1,this.discardedBombSprites.push(e),e.fire&&this.humans.burnHuman(e.target,.1*this.model.zombieHealth),this.zombies.causePlagueExplosion(e,.2*this.model.zombieHealth,!1,!1))):(e.x=e.harpy.x,e.y=e.harpy.y)}updateHarpy(e,t){switch(e.state){case qe.bombing:if(!e.target||e.target.graveyard||e.target.dead)if(this.model.tankBuster&&this.model.isBossStage(this.model.level)&&this.tanks.aliveTanks.length>0)e.target=a(this.tanks.aliveTanks,Math.random()),e.bomb.fire=!0;else{for(let t=0;t<8&&(e.target=a(this.humans.aliveHumans,Math.random()),e.target&&!(this.fastDistance(e.x,e.y,e.target.x,e.target.y-this.bombHeight)<500));t++);e.bomb.fire=!1}if(!e.target)return void(e.state=qe.returning);this.fastDistance(e.x,e.y,e.target.x,e.target.y-this.bombHeight)<10?(e.bombs--,e.bomb.dropped=!0,e.bomb.floor=e.target.y,e.bomb.target=e.target,e.bomb=null,e.speedFactor=0,e.target=!1,e.bombs<=0?e.state=qe.returning:this.getBomb(e)):this.updateHarpySpeed(e,t);break;case qe.returning:e.target||(e.target=this.graveyard.sprite),this.fastDistance(e.x,e.y,e.target.x,e.target.y-this.bombHeight)<10?(e.bombs=this.model.harpyBombs,e.bomb||this.getBomb(e),e.state=qe.bombing,e.speedFactor=0):this.updateHarpySpeed(e,t)}}getBomb(e){let t;this.discardedBombSprites.length>0?t=this.discardedBombSprites.pop():(t=new $e(this.bombTexture),this.bombSprites.push(t),b.addChild(t)),t.scale.x=t.scale.y=2,t.rotation=0,t.rotSpeed=Math.random()>.5?4:-4,t.ySpeed=0,t.visible=!0,t.dropped=!1,t.harpy=e,e.bomb=t}updateHarpySpeed(e,t){e.speedFactor=Math.min(1,e.speedFactor+=2*t);const s=e.target.x-e.x,i=e.target.y-this.bombHeight-e.y,a=Math.abs(s),r=Math.abs(i);if(0==Math.max(a,r))return;let n=1/Math.max(a,r);n*=1.29289-(a+r)*n*.29289,e.xSpeed=s*n*this.model.harpySpeed*e.speedFactor,e.ySpeed=i*n*this.model.harpySpeed*e.speedFactor,e.position.x+=e.xSpeed*t,e.position.y+=e.ySpeed*t,e.scale.x=e.xSpeed>0?this.scaling:-1*this.scaling}}class Qe{constructor(){if(this.blood=new _e,this.smoke=new ot,this.prestigePoints=new Je,this.bullets=new rt,this.exclamations=new it,this.blasts=new nt,this.fragments=new lt,Qe.instance)return Qe.instance;Qe.instance=this}initialize(){this.blood.initialize(),this.bullets.initialize(),this.exclamations.initialize(),this.blasts.initialize(),this.smoke.initialize(),this.fragments.initialize(),this.prestigePoints.initialize()}update(e){this.blood.update(e),this.bullets.update(e),this.exclamations.update(e),this.blasts.update(e),this.smoke.update(e),this.fragments.update(e),this.prestigePoints.update(e),function(e){for(let t=0;tnew J(e)}initialize(){this.gameModel=ne.getInstance(),this.container||(this.setup(new PIXI.Container,PIXI.Texture.from("pp.png")),b.addChild(this.container)),this.targetElement=document.getElementById("prestige-button"),this.animElement=document.getElementById("prestige-bg")}update(e){if(!this.gameModel.persistentData.particles)return void(this.container.visible=!1);this.container.visible=!0;let t={x:0,y:0};if(null!=this.targetElement){const e=this.targetElement.getBoundingClientRect();t={x:e.x+e.width/2,y:e.y+e.height/2},t.x-=c.x,t.y-=c.y,t.x=t.x/c.scale.x,t.y=t.y/c.scale.y}for(let s=0;s.5&&e.scale.set(2,2),this.container.addChild(e)}}update(e){if(this.gameModel.persistentData.particles){this.container.visible=!0,this.visibleParts=0;for(let t=0;t=e.floor&&(e.hitFloor=!0))}newPart(e,t,s){if(this.viewableArea.hideParticle(e,t))return;const i=this.sprites[this.partCounter++];this.partCounter>=this.maxParts&&(this.partCounter=0),i.texture=s?this.plagueTexture:this.texture,i.x=e,i.y=t-(8+10*Math.random()),i.floor=t,i.hitFloor=!1,i.visible=!0,i.alpha=1,i.scale.set(1,1),Math.random()>.5&&i.scale.set(2,2);const a=Math.random()*(s?1.5*this.spraySpeed:this.spraySpeed);i.xSpeed=Math.random()>.5?-1*a:a,i.ySpeed=-1*(s?1.5*this.spraySpeed:this.spraySpeed)}newSplatter(e,t){if(this.container.visible)if(this.visibleParts<.9*this.maxParts)for(let s=0;s200}updatePart(e,t){if(e.value<=0)return e.visible=!1,this.discardedSprites.push(e),void this.container.removeChild(e);e.hitFloor?(this.fadeBones&&(e.fadeTime-=t),e.fadeTime<0&&!e.collector&&(e.alpha-=this.fadeSpeed*t,e.alpha<=0&&(e.visible=!1,this.discardedSprites.push(e),this.container.removeChild(e)))):(e.ySpeed+=this.gravity*t,e.rotation+=e.rotSpeed*t,e.x+=e.xSpeed*t,e.y+=e.ySpeed*t,e.y>=e.floor&&(e.hitFloor=!0))}newPart(e,t,s){let i=null;this.discardedSprites.length>0?i=this.discardedSprites.pop():(i=new et(this.texture),this.sprites.push(i)),this.container.addChild(i),i.x=e,i.y=t-(8+10*Math.random()),i.fadeTime=Math.random()*this.fadeTime,i.rotation=5*Math.random(),i.rotSpeed=4*Math.random()-2,i.floor=t,i.hitFloor=!1,i.collector=!1,i.visible=!0,i.value=s,i.alpha=1,i.scale.set(1,1),Math.random()>.5&&i.scale.set(1.5,1.5);const a=Math.random()*this.spraySpeed;i.xSpeed=Math.random()>.5?-1*a:a,i.ySpeed=-1*this.spraySpeed}newBones(e,t){if(this.gameModel.constructions.graveyard)if(this.sprites.length-this.discardedSprites.length>this.partsLimit)this.newPart(e,t,3);else for(let s=0;s0?i=this.discardedSprites.pop():(i=new st(this.exclamationTexture),i.anchor.set(.5,1),this.sprites.push(i)),this.container.addChild(i),i.texture=t,i.target=e,i.target.hasIcon=!0,i.x=e.x,i.y=e.y-this.height,i.visible=!0,i.time=s,i.alpha=1,i.scale.set(1.5,1.5)}newHealing(e){this.newIcon(e,this.healTexture,1)}newExclamation(e){this.newIcon(e,this.exclamationTexture,2)}newRadio(e){this.newIcon(e,this.radioTexture,3)}newFire(e){this.newIcon(e,this.fireTexture,1)}newShield(e){this.newIcon(e,this.shieldTexture,1)}newPoison(e){this.newIcon(e,this.poisonTexture,1)}update(e){for(let t=0;t0?o=this.discardedSprites.pop():(o=new at(this.texture),o.scale.x=o.scale.y=2,this.sprites.push(o)),g.addChild(o),o.texture=n?this.darkOrbTexture:r?this.fireballTexture:this.texture,o.source=e,o.x=e.x,o.y=e.y-8,i&&(o.y=e.y-12),o.target=t,o.damage=s,o.visible=!0,o.alpha=1,o.hitbox=a?1.5*this.hitbox:this.hitbox,o.plague=i,o.rocket=a,o.fireball=r,o.darkorb=n,o.tint=i?65280:a?16772096:16777215,o.scale.x=o.scale.y=a?2.5:2,r&&(o.scale.x=o.scale.y=1.5);const h=t.x-o.x,l=t.y-8-o.y,d=Math.abs(h),c=Math.abs(l);let u=1/Math.max(d,c);u*=1.29289-(d+c)*u*.29289,o.xSpeed=h*u*this.speed,o.ySpeed=l*u*this.speed,o.rotation=Math.atan2(o.ySpeed,o.xSpeed)}}class nt extends _{constructor(){if(super(),this.viewableArea=null,nt.instance)return nt.instance;nt.instance=this,this.create=e=>new J(e)}getTexture(){const e=document.createElement("canvas");e.width=32,e.height=32;const t=e.getContext("2d"),s=t.createRadialGradient(16,16,0,16,16,16);return s.addColorStop(0,"rgba(255,255,255,1)"),s.addColorStop(.8,"rgba(255,255,128,0.2)"),s.addColorStop(1,"rgba(255,180,0,0)"),t.fillStyle=s,t.fillRect(0,0,32,32),PIXI.Texture.from(e)}initialize(){this.viewableArea=G,this.texture||(this.texture=this.getTexture(),this.container=new PIXI.Container,b.addChild(this.container),this.setup(this.container,this.texture))}update(e){for(let t=0;tnew J(e)}getTexture(){const e=document.createElement("canvas");e.width=12,e.height=12;const t=e.getContext("2d");t.shadowBlur=5,t.shadowColor="white";const s=t.createRadialGradient(6,6,0,6,6,4);return s.addColorStop(0,"rgba(255,255,255,0.05)"),s.addColorStop(.5,"rgba(255,255,255,0.1)"),s.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=s,t.fillRect(0,0,12,12),PIXI.Texture.from(e)}initialize(){this.gameModel=ne.getInstance(),this.viewableArea=G,this.allowTint=this.gameModel.app&&this.gameModel.app.renderer&&1==this.gameModel.app.renderer.type,this.texture||(this.setup(new PIXI.Container,this.getTexture()),b.addChild(this.container))}update(e){if(this.gameModel.persistentData.particles){this.container.visible=!0;for(let t=0;tnew ht(e)}getTexture(){const e=document.createElement("canvas");e.width=5,e.height=1;const t=e.getContext("2d");return t.fillStyle="#FFFFFF",t.fillRect(0,0,5,1),PIXI.Texture.from(e)}initialize(){this.gameModel=ne.getInstance(),this.viewableArea=G,this.container||(this.container=new PIXI.Container,p.addChild(this.container),this.texture=this.getTexture(),this.setup(this.container,this.texture))}update(e){if(this.gameModel.persistentData.particles){this.container.visible=!0;for(let t=0;t=e.floor&&(e.hitFloor=!0),e.rotation+=e.rotSpeed*t)}newPart(e,t,s){if(!this.container.visible)return;if(this.viewableArea.hideParticle(e,t))return;const i=this.getSprite();i.tint=s,i.x=e,i.y=t-(8+10*Math.random()),i.floor=t,i.hitFloor=!1,i.rotation=5*Math.random(),i.rotSpeed=4*Math.random()-2,i.alpha=1,i.scale.set(2,2);const a=Math.random()*this.spraySpeed;i.xSpeed=Math.random()>.5?-1*a:a,i.ySpeed=-1*(10+Math.random()*this.spraySpeed)}newFragmentExplosion(e,t,s){if(this.container.visible)for(let i=0;i0},this.full=function(){return dt.talents[this.id]&&10==dt.talents[this.id]},this.reset=function(){dt.talents[this.id]=0},this.max=function(){dt.talents[this.id]=this.maxPoints,dt.getAvailablePoints()<0&&(dt.talents[this.id]+=dt.getAvailablePoints())},this.set=function(e){dt.talents[this.id]||(dt.talents[this.id]=0),(e<0||e>0&&dt.getAvailablePoints()>0)&&(dt.talents[this.id]+=e,dt.talents[this.id]<0&&(dt.talents[this.id]=0),dt.talents[this.id]>this.maxPoints&&(dt.talents[this.id]=this.maxPoints))},this.id=e,this.name=t,this.description=r,this.group=s,this.maxPoints=i,this.apply=a}}class vt{constructor(e,t){this.talents=[],this.name=e,this.class=t}}const St=[new xt(1,"Efficiency",mt,10,(function(){pt.creatureCostReduction=1;const e=dt.talents[this.id];e&&e>0&&(pt.creatureCostReduction-=.05*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Golem upgrade and summoning cost reduced by ${5*e}%`:"Reduces golem upgrade and summoning cost by 5%"})),new xt(2,"Thrifty",mt,10,(function(){dt.killingBlowParts=0;const e=dt.talents[this.id];e&&e>0&&(dt.killingBlowParts=10*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Skeleton killing blows reward ${10*e}% of your current parts per second`:"Skeleton killing blows reward 10% of your current parts per second"})),new xt(3,"Fatal Bargain",mt,10,(function(){ut.refundChance=0,ct.refundChance=0;const e=dt.talents[this.id];e&&e>0&&(ut.refundChance=.08*e,ct.refundChance=.08*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?8*e+"% parts refund on golem death":"Grants 8% parts refund on golem death"})),new xt(4,"Recovery",yt,10,(function(){gt.cooldownReduction=1;const e=dt.talents[this.id];e&&e>0&&(gt.cooldownReduction=1-.05*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Spell cooldown time reduced by ${5*e}%`:"Reduces spell cooldown time by 5%"})),new xt(5,"Endurance",yt,10,(function(){gt.timeExtension=0;const e=dt.talents[this.id];e&&e>0&&(gt.timeExtension=e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Spell duration increased by ${e} seconds`:"Increases spell duration by 1 second"})),new xt(6,"Conservation",yt,10,(function(){gt.costReduction=0;const e=dt.talents[this.id];e&&e>0&&(gt.costReduction=5*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Spell cost reduced by ${5*e} energy`:"Reduces spell cost by 5 energy"})),new xt(7,"Shiny",ft,10,(function(){dt.lootChanceMod=1;const e=dt.talents[this.id];e&&e>0&&(dt.lootChanceMod=1+.1*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Rare loot chance increased by ${10*e}%`:"Increases the chance for rare loot by 10%"})),new xt(8,"Dark Orb",ft,10,(function(){dt.darkorb=0;const e=dt.talents[this.id];e&&e>0&&(dt.darkorb=12-e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Dark orb released every ${12-e} seconds`:"Releases a dark orb of energy every 11 seconds"})),new xt(9,"Bone Shield",ft,10,(function(){dt.boneshield=0;const e=dt.talents[this.id];e&&e>0&&(dt.boneshield=e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Gains a shield of ${e} bones every 10 seconds`:"Gain a shield of 1 bone to protect the skeleton every 10 seconds"})),new xt(10,"Gigamutagen",bt,10,(function(){ct.gigamutagen=0;const e=dt.talents[this.id];e&&e>0&&(ct.gigamutagen=14-e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`Gigazombie mutation every ${14-e} seconds`:"Mutates a random zombie into a gigazombie every 13 seconds"})),new xt(11,"Blood Pact",bt,10,(function(){ct.bloodpact=0;const e=dt.talents[this.id];e&&e>0&&(ct.bloodpact=.05*e)}),(function(){const e=dt.talents[this.id];return e&&e>0?5*e+"% of zombie damage converted to blood":"Converts an additional 5% of zombie damage to blood"})),new xt(12,"Blood Born",bt,10,(function(){ct.bloodborn=0;const e=dt.talents[this.id];e&&e>0&&(ct.bloodborn=e)}),(function(){const e=dt.talents[this.id];return e&&e>0?`${e} seconds of additional 50% damage reduction`:"Grants 1 second of additional 50% damage reduction to newly spawned zombies"}))],Mt=[];function kt(){St.forEach((e=>{const t=dt.talents[e.id];t&&t<0&&(dt.talents[e.id]=0)})),dt.talentPointse.apply()))}function wt(){dt.persistent.talentReset&&(St.forEach((e=>e.reset())),dt.persistent.talentReset=!1)}St.forEach((e=>{if(0==Mt.filter((t=>t.name==e.group)).length){let t="blood";e.group==mt&&(t="parts"),e.group==ft&&(t="bones"),e.group==yt&&(t="energy"),e.group==bt&&(t="brains"),Mt.push(new vt(e.group,t))}Mt.filter((t=>t.name==e.group))[0].talents.push(e),dt.talents[e.id]||(dt.talents[e.id]=0)})),angular.module("zombieApp",[]).filter("decimal",(function(){return r})).filter("whole",(function(){return n})).config(["$compileProvider",function(e){e.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript|data|blob):/),e.debugInfoEnabled(!1)}]).controller("ZombieController",["$scope","$interval","$document",function(e,t,s){const i=new Xe,a=new q,r=new se,o=new ae,h=new oe,l=new de,c=this;function u(){const e=(new Date).getTime();!function(e,t){c.model.update(e,t),c.updateMessages(e),c.sidePanels.factory&&(c.factoryStats=r.factoryStats())}(Math.min(1e3,Math.max(e-c.lastUpdate,0))/1e3,e),c.lastUpdate=e}c.model=ne.getInstance(),c.skeleton=function(){return i.persistent},c.spells=a,c.keysPressed=Y,c.files=[],c.messageTimer=4,c.message=!1,c.lastUpdate=0,c.sidePanels={},c.upgrades=[],c.currentShopFilter="blood",c.currentConstructionFilter="available",c.graveyardTab="minions",c.trophyTab="all",c.factoryTab="parts",c.factoryStats={},c.moveTooltip=d,c.confirmMessage="",c.confirmCancel=function(){c.confirmCallback=!1},c.closeSidePanels=function(){c.currentShopFilter="blood",c.currentConstructionFilter="available",c.graveyardTab="minions",c.factoryTab="parts",c.sidePanels.options=!1,c.sidePanels.graveyard=!1,c.sidePanels.runesmith=!1,c.sidePanels.prestige=!1,c.sidePanels.construction=!1,c.sidePanels.shop=!1,c.sidePanels.open=!1,c.sidePanels.factory=!1,c.levelSelect.shown=!1},c.openSidePanel=function(e){switch(c.closeSidePanels(),e){case"shop":c.filterShop(c.currentShopFilter),c.sidePanels.shop=!0;break;case"construction":c.filterConstruction(c.currentConstructionFilter),c.sidePanels.construction=!0;break;case"graveyard":c.sidePanels.graveyard=!0,c.graveyardTab="minions",c.trophyTab="all";break;case"runesmith":c.sidePanels.runesmith=!0;break;case"factory":c.sidePanels.factory=!0,c.upgrades=r.generators,c.factoryStats=r.factoryStats(),c.factory.updateDelays();break;case"prestige":c.upgrades=h.prestigeUpgrades.filter((e=>0==e.cap||c.currentRank(e)0!==e.cap&&c.currentRank(e)>=e.cap))),c.upgrades=c.upgrades.filter((e=>115!==e.id)),c.sidePanels.prestige=!0;break;case"options":c.sidePanels.options=!0,c.model.downloadSaveGame()}c.sidePanels.open=!0},c.graveyardTabSelect=function(e){c.graveyardTab=e,"trophies"==e&&(c.trophies=l.getTrophyList(),c.trophyTab="all")},c.trophyTabSelect=function(e){switch(c.trophyTab=e,e){case"all":c.trophies=l.getTrophyList();break;case"collected":c.trophies=l.getTrophyList().filter((e=>e.owned));break;case"uncollected":c.trophies=l.getTrophyList().filter((e=>!e.owned));break;case"totals":c.trophies=l.getTrophyTotals()}},c.filterShop=function(e){c.currentShopFilter=e,c.upgrades=h.getUpgrades(e)},c.filterConstruction=function(e){switch(c.currentConstructionFilter=e,e){case"available":c.upgrades=h.getAvailableConstructions();break;case"completed":c.upgrades=h.getCompletedConstructions()}},c.resetGame=function(){c.confirmMessage="Are you sure you want to reset everything? If you have a cloud save it will also be deleted. Make sure you export your save game first.",c.confirmCallback=function(){c.model.resetData(),c.confirmCallback=!1}},c.addBoneCollector=function(){c.model.getEnergyRate()>=1&&c.model.persistentData.boneCollectors++},c.subtractBoneCollector=function(){c.model.persistentData.boneCollectors>0&&c.model.persistentData.boneCollectors--},c.maxBoneCollectors=function(){return Math.floor(c.model.getEnergyRate()+c.model.persistentData.boneCollectors)},c.setBoneCollectors=function(e){e>=0&&c.model.getEnergyRate()>=e-c.model.persistentData.boneCollectors&&(c.model.persistentData.boneCollectors=e)},c.setHarpies=function(e){(e>=0&&e=1&&e>0)&&(c.model.persistentData.harpies=e)},c.maxHarpies=function(){return Math.floor(c.model.getEnergyRate()+c.model.persistentData.harpies)},c.setGraveyardZombies=function(e){e<=c.maxGraveyardZombies()&&e>=0&&(c.model.persistentData.graveyardZombies=e)},c.maxGraveyardZombies=function(){return Math.floor(c.model.energyMax/c.model.zombieCost)},c.upgradePrice=function(e){return c.sidePanels.factory&&"prestigePoints"!=e.costType?r.purchasePrice(e):h.upgradePrice(e)},c.factory={delays:[],changeFactoryTab(e){c.factoryTab=e,"parts"==e?(c.upgrades=r.generators,this.updateDelays()):c.upgrades=o.creatures},buyGenerator(e){c.keysPressed.shift?r.purchaseMaxGenerators(e):r.purchaseGenerator(e),c.factoryStats=r.factoryStats()},generatorPrice:e=>r.purchasePrice(e),creaturePrice:e=>o.purchasePrice(e),creatureLevelPrice:e=>o.levelPrice(e),creaturePercent(e){return Math.min(Math.round(c.model.persistentData.parts/this.creaturePrice(e)*100),100)},creatureLevelPercent(e){return Math.min(Math.round(c.model.persistentData.parts/this.creatureLevelPrice(e)*100),100)},buyCreature:e=>o.startBuilding(e),creatureTooExpensive:e=>!o.canAffordCreature(e),creatureButtonText(e){return e.building?"Building...":this.creatureTooExpensive(e)?n(this.creaturePrice(e)-c.model.persistentData.parts)+" parts required":"Build ("+n(this.creaturePrice(e))+" parts)"},creatureLevelButtonText(e){return this.canLevelCreature(e)?"Upgrade Level "+(e.level+1)+" ("+n(this.creatureLevelPrice(e))+" parts)":n(this.creatureLevelPrice(e)-c.model.persistentData.parts)+" parts required"},canBuildCreature(e){return!this.creatureTooExpensive(e)&&!e.building&&o.creaturesBuildingCount()+c.model.creatureCount=0&&e.autobuild+t<=c.model.creatureLimit&&o.creatureAutoBuildNumber(e,t)},creatureStats:e=>o.creatureStats(e),updateDelays(){this.delays=[];for(let e=0;ec.model.persistentData.allTimeHighestLevel>1,show(){this.shown?this.shown=!1:(c.closeSidePanels(),this.shown=!0,this.level=c.model.levelInfo(c.model.level),this.start=Math.floor((this.level.level-1)/this.levelsPerPage)*this.levelsPerPage+1,this.populate())},populate(){this.levels=[],this.levelRanges=[],this.start>this.levelsPerPage&&this.levelRanges.push(this.start-this.levelsPerPage),this.levelRanges.push(this.start),this.start+this.levelsPerPage<=c.model.persistentData.allTimeHighestLevel+1&&this.levelRanges.push(this.start+this.levelsPerPage);for(let e=this.start;e=e.cap},c.requiredForUpgrade=function(e){const t=c.upgradePrice(e);switch(e.costType){case h.costs.energy:return n(t-c.model.energy)+" energy required";case h.costs.blood:case r.costs.blood:return n(t-c.model.persistentData.blood)+" blood required";case h.costs.brains:return n(t-c.model.persistentData.brains)+" brains required";case h.costs.bones:return n(t-c.model.persistentData.bones)+" bones required";case h.costs.prestigePoints:return n(t-c.model.persistentData.prestigePointsToSpend)+" prestige points required";case r.costs.parts:return n(t-c.model.persistentData.parts)+" parts required"}},c.purchaseText=function(e){if(c.keysPressed.shift){if(c.sidePanels.factory){const t=r.upgradeMaxAffordable(e);return"Purchase "+t+" ("+n(r.upgradeMaxPrice(e,t))+" "+c.costTranslate(e.costType)+")"}{const t=h.upgradeMaxAffordable(e);return"Purchase "+t+" ("+n(h.upgradeMaxPrice(e,t))+" "+c.costTranslate(e.costType)+")"}}return"Purchase ("+n(c.upgradePrice(e))+" "+c.costTranslate(e.costType)+")"},c.costTranslate=function(e){return e==h.costs.prestigePoints?"points":e},c.buyUpgrade=function(e){c.keysPressed.shift?h.purchaseMaxUpgrades(e):h.purchaseUpgrade(e)},c.destroyUpgrade=function(e){h.removeUpgrade(e)},c.upgradeStatInfo=function(e){return h.displayStatValue(e)},c.startGame=function(){c.model.startGame()},c.nextLevel=function(){c.model.nextLevel()},c.toggleAutoStart=function(){c.model.persistentData.autoStart?c.model.persistentData.autoStart=!1:c.model.persistentData.autoStart=!0},c.toggleResolution=function(e){c.model.persistentData.resolution=e,c.model.setResolution(c.model.persistentData.resolution)},c.getResolution=function(){return c.model.persistentData.resolution||1},c.toggleZoomButtons=function(){c.model.persistentData.zoomButtons=!c.model.persistentData.zoomButtons},c.zoom=function(e){c.model.zoom(e)},c.resetZoom=function(){c.model.centerGameContainer(!0)},c.toggleShowFps=function(){c.model.persistentData.showfps=!c.model.persistentData.showfps},c.toggleParticles=function(){c.model.persistentData.particles=!c.model.persistentData.particles},c.isShowPrestige=function(){return void 0!==c.model.persistentData.prestigePointsEarned&&c.model.persistentData.allTimeHighestLevel>5},c.doPrestige=function(){c.confirmMessage="Are you sure you want to prestige now?",c.confirmCallback=function(){c.model.prestige(),c.confirmCallback=!1}},c.constructionLeadsTo=function(e){return h.constructionLeadsTo(e)},c.howToPlay=["Energy refills over time. You need 10 energy to spawn a zombie by clicking on the ground.","Hold shift or control to spawn multiple zombies with a single click.","Whenever one of your zombies attacks a human you will collect some blood.","Killing a human or turning them into a zombie will earn you 1 brain.","You can spend these currencies in the shop to purchase upgrades for your zombie horde.","Hold shift to buy the maximum affordable number of upgrades.","The world can be dragged with the mouse to explore it. Or by using the WASD or arrow keys.","You can zoom in and out using your mouse wheel. Pinch to zoom on mobile."],c.updateMessages=function(e){c.message?(c.messageTimer-=e,c.model.messageQueue.length>0&&(c.messageTimer-=e),c.messageTimer<0&&(c.message=!1,c.messageTimer=4)):c.model.messageQueue.length>0&&(c.message=c.model.messageQueue.shift(),c.messageTimer=4)},c.infusionAmount=1e3,c.infusionMax=!1,c.infuseRune=function(e,t){if(c.infusionMax)switch(t){case"blood":h.infuseRune(e,t,c.model.persistentData.blood);break;case"brains":h.infuseRune(e,t,c.model.persistentData.brains);break;case"bones":h.infuseRune(e,t,c.model.persistentData.bones)}else h.infuseRune(e,t,c.infusionAmount)},c.shatterPercent=function(e){return h.shatterPercent(e)},c.shatterBloodCost=function(e){return h.shatterBloodCost(e)},c.shatterSatiate=function(e,t){h.infuseRune(e,"blood",this.shatterBloodCost(t))},c.canShatter=function(){return h.canShatter()},c.doShatter=function(){h.doShatter()},c.shatterEffect=function(){return 100*h.shatterEffect()},c.infuseButtonText=function(){return c.infusionMax?"Max":n(c.infusionAmount)},c.energyPercent=function(){return Math.min(Math.round(c.model.energy/c.model.energyMax*100),100)},c.bloodPercent=function(){return Math.min(Math.round(c.model.persistentData.blood/c.model.bloodMax*100),100)},c.brainsPercent=function(){return Math.min(Math.round(c.model.persistentData.brains/c.model.brainsMax*100),100)},c.costAboveCap=function(e,t){switch(e.costType){case"blood":if(t>c.model.bloodMax)return"Blood capacity too low";break;case"brains":if(t>c.model.brainsMax)return"Brains capacity too low"}return!1},c.upgradeButtonText=function(e){if(0!=e.cap&&c.currentRank(e)>=e.cap)return"Sold Out";const t=c.upgradePrice(e);if(c.upgradeTooExpensive(e)){return c.costAboveCap(e,t)||c.requiredForUpgrade(e)}return c.purchaseText(e,t)},c.upgradePercent=function(e){switch(e.costType){case"blood":return Math.round(100*Math.min(1,c.model.persistentData.blood/c.upgradePrice(e)));case"brains":return Math.round(100*Math.min(1,c.model.persistentData.brains/c.upgradePrice(e)));case"bones":return Math.round(100*Math.min(1,c.model.persistentData.bones/c.upgradePrice(e)));case"parts":return Math.round(100*Math.min(1,c.model.persistentData.parts/c.upgradePrice(e)));case"prestigePoints":return Math.round(100*Math.min(1,c.model.persistentData.prestigePointsToSpend/c.upgradePrice(e)))}},c.skeletonTimer=function(){return i.skeletonTimer()},c.skeletonMenu={isShown:!1,tab:"inventory",changeTab(e){this.tab=e},equipped:[],show(){this.tab="inventory",this.upgrade=h.prestigeUpgrades.filter((e=>115==e.id))[0],this.upgrades=Mt,this.isShown=!this.isShown,this.isShown&&this.updateEquippedItems()},acceptOffer(){i.acceptOffer(),this.isShown=!1},anotherOffer:()=>i.persistent.skeletons>0&&c.model.persistentData.trophies.length>=20*i.persistent.xpRate,trophies:()=>i.persistent.skeletons>0?` - ${c.model.persistentData.trophies.length} / ${20*i.persistent.xpRate} Trophies`:"",talentPoints:()=>i.talentPoints,talentsAssigned:()=>i.getUsedPoints(),talentValue:e=>i.talents[e.id]+" / "+e.maxPoints,talentSet(e,t){e.set(t),kt()},talentReset(e){e.reset(),kt()},canReset:()=>i.persistent.talentReset,talentsReset(){wt(),kt()},talentMax(e){e.max(),kt()},xpPercent:()=>Math.round(100*Math.min(1,c.skeleton().xp/i.xpForNextLevel())),xpForNextLevel:()=>i.xpForNextLevel(),xpRate:()=>100*i.persistent.xpRate,isAlive:()=>i.isAlive(),timer:()=>Math.ceil(i.skeletonTimer()),updateEquippedItems(){this.equipped=[];const e=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.helmet.id));e.length>0?this.equipped.push([e[0]]):this.equipped.push([{name:"Helmet Slot",s:i.lootPositions.helmet.id,id:-1}]);const t=[],s=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.sword.id));s.length>0?t.push(s[0]):t.push({name:"Sword Slot",s:i.lootPositions.sword.id,id:-2});const a=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.chest.id));a.length>0?t.push(a[0]):t.push({name:"Chest Slot",s:i.lootPositions.chest.id,id:-3});const r=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.shield.id));r.length>0?t.push(r[0]):t.push({name:"Shield Slot",s:i.lootPositions.shield.id,id:-4}),this.equipped.push(t);const n=[],o=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.gloves.id));o.length>0?n.push(o[0]):n.push({name:"Gloves Slot",s:i.lootPositions.gloves.id,id:-5});const h=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.legs.id));h.length>0?n.push(h[0]):n.push({name:"Legs Slot",s:i.lootPositions.legs.id,id:-6});const l=i.persistent.items.filter((e=>e.q&&e.s==i.lootPositions.boots.id));l.length>0?n.push(l[0]):n.push({name:"Boots Slot",s:i.lootPositions.boots.id,id:-7}),this.equipped.push(n),this.equipped.push([{name:"Destroy Items",s:-1,id:-8}])},inventoryItems:()=>i.persistent.items.filter((e=>!e.q)).sort(((e,t)=>t.r*t.l-e.r*e.l)),itemName:e=>e.name||i.getLootName(e),itemSubName(e){if(!e.name)switch(e.r){case i.rarity.common:return"Common level "+e.l+" "+this.itemType(e);case i.rarity.rare:return"Rare level "+e.l+" "+this.itemType(e);case i.rarity.epic:return"Epic level "+e.l+" "+this.itemType(e);case i.rarity.legendary:return"Legendary level "+e.l+" "+this.itemType(e)}if(-1==e.s)return"Click this to destroy all non-equipped items (legendary items will not be automatically destroyed). Or drag items here to destroy them."},itemStats:e=>i.getLootStats(e),itemEffects:e=>i.getSpecialEffects(e),itemType(e){switch(e.s){case-1:return"trash";case i.lootPositions.helmet.id:return"helmet";case i.lootPositions.chest.id:return"chest";case i.lootPositions.gloves.id:return"gloves";case i.lootPositions.legs.id:return"legs";case i.lootPositions.boots.id:return"boots";case i.lootPositions.sword.id:return"sword";case i.lootPositions.shield.id:return"shield"}},itemClass:e=>e.name?"empty":i.getLootClass(e),itemById(e){let t=null;return i.persistent.items.forEach((function(s){s.id==e&&(t=s)})),t},itemDropped(e,t){let s=null;i.persistent.items.forEach((function(t){t.id==e&&(s=t)})),-1==t?i.destroyItem(s):(s.s==t&&(i.persistent.items.forEach((function(e){e.s==t&&(e.q=!1)})),s.q=!0,h.applyUpgrades()),this.updateEquippedItems())},equipItem(e){i.persistent.items.forEach((function(t){t.s==e.s&&(t.q=!1)})),e.q=!0,h.applyUpgrades(),this.updateEquippedItems()},trashAll(){c.confirmMessage="Are you sure you want to destroy all non-equipped items? You will earn "+n(i.xpForItems())+" xp",c.confirmCallback=function(){c.confirmCallback=!1,i.destroyAllItems()}}},s.ready((function(){e.updatePromise=t(u,200),h.angularModel=c,kt()}))}]).directive("levelSelect",(function(){return{templateUrl:"./templates/levelselect.html"}})).directive("levelStats",(function(){return{templateUrl:"./templates/levelstats.html"}})).directive("graveyardMenu",(function(){return{templateUrl:"./templates/graveyardmenu.html"}})).directive("runesmithMenu",(function(){return{templateUrl:"./templates/runesmithmenu.html"}})).directive("optionsMenu",(function(){return{templateUrl:"./templates/optionsmenu.html"}})).directive("shopMenu",(function(){return{templateUrl:"./templates/shopmenu.html"}})).directive("constructionMenu",(function(){return{templateUrl:"./templates/constructionmenu.html"}})).directive("prestigeMenu",(function(){return{templateUrl:"./templates/prestigemenu.html"}})).directive("championsHoldMenu",(function(){return{templateUrl:"./templates/championshold.html"}})).directive("factoryMenu",(function(){return{templateUrl:"./templates/factorymenu.html"}})).directive("customOnChange",(function(){return{restrict:"A",link:function(e,t,s){const i=e.$eval(s.customOnChange);t.on("change",i),t.on("$destroy",(function(){t.off()}))}}})).directive("draggableItem",["$rootScope",function(e){return{restrict:"A",link:function(t,s,i,a){const r=t.item.id;"true"==i.draggableItem&&(angular.element(s).attr("draggable","true"),s.bind("dragstart",(function(t){document.getElementById("champ-hold").classList.toggle("no-tooltip"),t.dataTransfer.setData("text",r);const i=s[0].getBoundingClientRect();t.dataTransfer.setDragImage(s[0],i.width/2,i.height/2),e.$emit("item-drag-start",r),setTimeout((function(){angular.element(s)[0].style.opacity="0.3"}))})),s.bind("dragend",(function(t){document.getElementById("champ-hold").classList.toggle("no-tooltip"),angular.element(s)[0].style.opacity="",e.$emit("item-drag-end",r)})))}}}]).directive("droppableTarget",["$rootScope",function(e){return{restrict:"A",link:function(t,s,i,a){const r=t.item.s;s.bind("dragover",(function(e){return e.preventDefault&&e.preventDefault(),e.dataTransfer.dropEffect="move",!1})),s.bind("dragenter",(function(e){e.target&&e.target.classList&&e.target.classList.contains("icon")&&angular.element(e.target.parentElement).addClass("over")})),s.bind("dragleave",(function(e){e.target&&e.target.classList&&e.target.classList.contains("icon")&&angular.element(e.target.parentElement).removeClass("over")})),s.bind("drop",(function(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.target.classList.contains("icon")&&angular.element(e.target.parentElement).removeClass("over");const s=e.dataTransfer.getData("text"),i=t.zm.skeletonMenu.itemById(s);if(i){const e=t.zm.skeletonMenu.itemType(i);document.getElementsByClassName("equipped")[0].classList.remove(e)}t.zm.skeletonMenu.itemDropped(s,r)})),e.$on("item-drag-start",(function(e,s){const i=t.zm.skeletonMenu.itemById(s);if(i){const e=t.zm.skeletonMenu.itemType(i);document.getElementsByClassName("equipped")[0].classList.add(e)}})),e.$on("item-drag-end",(function(e,s){const i=t.zm.skeletonMenu.itemById(s);if(i){const e=t.zm.skeletonMenu.itemType(i);document.getElementsByClassName("equipped")[0].classList.remove(e)}}))}}}]),Incremancer=e})(); //# sourceMappingURL=bundle.js.map