From b6c829c32c7bb6bababf6237a4147d5ae7a408d2 Mon Sep 17 00:00:00 2001 From: avinashv Date: Mon, 4 Sep 2023 18:52:16 +0000 Subject: [PATCH] deploy: bbb2255bd3867b666aa5684b5a1ce470e3b4dca3 --- assets/{index-dd5edf46.js => index-6f0cc5f2.js} | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename assets/{index-dd5edf46.js => index-6f0cc5f2.js} (79%) diff --git a/assets/index-dd5edf46.js b/assets/index-6f0cc5f2.js similarity index 79% rename from assets/index-dd5edf46.js rename to assets/index-6f0cc5f2.js index d7090a7..f95dca4 100644 --- a/assets/index-dd5edf46.js +++ b/assets/index-6f0cc5f2.js @@ -26,4 +26,4 @@ and limitations under the License. right: 0; text-align: center; top: 0; - `,e.innerHTML=`Open ECSY devtools to connect to this page using the code: ${t} `,document.body.appendChild(e),e}function enableRemoteDevtools(remoteId){if(!hasWindow){console.warn("Remote devtools not available outside the browser");return}window.generateNewCode=()=>{window.localStorage.clear(),remoteId=generateId(6),window.localStorage.setItem("ecsyRemoteId",remoteId),window.location.reload(!1)},remoteId=remoteId||window.localStorage.getItem("ecsyRemoteId"),remoteId||(remoteId=generateId(6),window.localStorage.setItem("ecsyRemoteId",remoteId));let infoDiv=includeRemoteIdHTML(remoteId);window.__ECSY_REMOTE_DEVTOOLS_INJECTED=!0,window.__ECSY_REMOTE_DEVTOOLS={};let Version="",worldsBeforeLoading=[],onWorldCreated=t=>{var e=t.detail.world;Version=t.detail.version,worldsBeforeLoading.push(e)};window.addEventListener("ecsy-world-created",onWorldCreated);let onLoaded=()=>{var peer=new Peer(remoteId,{host:"peerjs.ecsy.io",secure:!0,port:443,config:{iceServers:[{url:"stun:stun.l.google.com:19302"},{url:"stun:stun1.l.google.com:19302"},{url:"stun:stun2.l.google.com:19302"},{url:"stun:stun3.l.google.com:19302"},{url:"stun:stun4.l.google.com:19302"}]},debug:3});peer.on("open",()=>{peer.on("connection",connection=>{window.__ECSY_REMOTE_DEVTOOLS.connection=connection,connection.on("open",function(){infoDiv.innerHTML="Connected",connection.on("data",function(data){if(data.type==="init"){var script=document.createElement("script");script.setAttribute("type","text/javascript"),script.onload=()=>{script.parentNode.removeChild(script),window.removeEventListener("ecsy-world-created",onWorldCreated),worldsBeforeLoading.forEach(t=>{var e=new CustomEvent("ecsy-world-created",{detail:{world:t,version:Version}});window.dispatchEvent(e)})},script.innerHTML=data.script,(document.head||document.documentElement).appendChild(script),script.onload(),hookConsoleAndErrors(connection)}else if(data.type==="executeScript"){let value=eval(data.script);data.returnEval&&connection.send({method:"evalReturn",value})}})})})})};injectScript("https://cdn.jsdelivr.net/npm/peerjs@0.3.20/dist/peer.min.js",onLoaded)}hasWindow&&new URLSearchParams(window.location.search).has("enable-remote-devtools")&&enableRemoteDevtools();const MAP_WIDTH=100,MAP_HEIGHT=100,DISPLAY_WIDTH=80,DISPLAY_HEIGHT=50,VIEWPORT_WIDTH=80,VIEWPORT_HEIGHT=42,TILE_WIDTH=16,TILE_HEIGHT=16,TILESET="Anikki_square_"+TILE_WIDTH+"x"+TILE_HEIGHT+".png",PLAYER_FOV_RANGE=7,MONSTER_FOV_RANGE=5,MAX_ROOMS=30,MIN_SIZE=6,MAX_SIZE=10,UI_STARTING_X=2,LOG_ENTRIES=DISPLAY_HEIGHT-VIEWPORT_HEIGHT-4,LOG_FADE=20;class Player extends Component{}class Enemy extends Component{}class Item extends Component{}class Position extends Component{constructor(){super(...arguments);c(this,"x",0);c(this,"y",0)}}c(Position,"schema",{x:{type:Types.Number},y:{type:Types.Number}});class Name extends Component{constructor(){super(...arguments);c(this,"name","Unknown")}}c(Name,"schema",{name:{type:Types.String}});class Renderable extends Component{constructor(){super(...arguments);c(this,"glyph");c(this,"zIndex",0)}}c(Renderable,"schema",{glyph:{type:Types.Ref},zIndex:{type:Types.Number}});class Viewshed extends Component{constructor(){super(...arguments);c(this,"visibleTiles",[]);c(this,"range",0);c(this,"dirty",!0)}containsTile(n){for(const i of this.visibleTiles)if(i.x===n.x&&i.y===n.y)return!0;return!1}}c(Viewshed,"schema",{visibleTiles:{type:Types.Array},range:{type:Types.Number},dirty:{type:Types.Boolean}});class BlocksTile extends Component{}class Attributes extends Component{constructor(){super(...arguments);c(this,"hp",10);c(this,"maxHp",10);c(this,"attack",1);c(this,"defense",0)}}c(Attributes,"schema",{hp:{type:Types.Number},maxHp:{type:Types.Number},attack:{type:Types.Number},defense:{type:Types.Number}});class Inventory extends Component{constructor(){super(...arguments);c(this,"items",[])}}c(Inventory,"schema",{owner:{type:Types.Ref}});class IncomingDamage extends Component{constructor(){super(...arguments);c(this,"amount",0)}}c(IncomingDamage,"schema",{amount:{type:Types.Number}});class AttemptToMelee extends Component{constructor(){super(...arguments);c(this,"defender")}}c(AttemptToMelee,"schema",{defender:{type:Types.Ref}});class AttemptToPickupItem extends Component{constructor(){super(...arguments);c(this,"item")}}c(AttemptToPickupItem,"schema",{item:{type:Types.Ref}});var TileType=(t=>(t[t.Floor=1]="Floor",t[t.Wall=2]="Wall",t))(TileType||{});class GameMap{constructor(e,n,i,r){c(this,"tiles");c(this,"visibleTiles");c(this,"exploredTiles");c(this,"blockedTiles");c(this,"tileContent");c(this,"rooms",[]);c(this,"width");c(this,"height");this.tiles=e,this.rooms=n,this.width=i,this.height=r,this.visibleTiles=new index$2.Table(i,r),this.exploredTiles=new index$2.Table(i,r),this.blockedTiles=new index$2.Table(i,r),this.tileContent=new index$2.Table(i,r),this.visibleTiles.fill(!1),this.exploredTiles.fill(!1),this.blockedTiles.fill(!1)}clearTileContent(){this.tileContent.fill([])}getTileContent(e){return this.tileContent.get(e)||[]}addTileContent(e,...n){const i=this.getTileContent(e);this.tileContent.set(e,i.concat(...n))}static GenMapRoomsAndCorridors(e,n){const i=new index$2.Table(e,n);i.fill(2);const r=[],a=new GameMap(i,r,e,n),o=new index$3.AleaRNG,h=MAX_ROOMS,s=MIN_SIZE,l=MAX_SIZE;for(let u=0;uy.intersects(f))){if(a.applyRoomToMap(f),r.length>0){const y=f.center(),v=r[r.length-1].center();o.nextBoolean()?(a.applyHTunnel(v.x,y.x,v.y),a.applyVTunnel(v.y,y.y,y.x)):(a.applyVTunnel(v.y,y.y,v.x),a.applyHTunnel(v.x,y.x,y.y))}r.push(f)}}return a}applyRoomToMap(e){for(let n=e.v1.x;n<=e.v2.x;n++)for(let i=e.v1.y;i<=e.v2.y;i++)this.tiles.set({x:n,y:i},1)}applyHTunnel(e,n,i){const r=Math.min(e,n),a=Math.max(e,n);for(let o=r;o<=a;o++)this.tiles.set({x:o,y:i},1)}applyVTunnel(e,n,i){const r=Math.min(e,n),a=Math.max(e,n);for(let o=r;o<=a;o++)this.tiles.set({x:i,y:o},1)}isRevealedAndWall(e,n){return!!(this.tiles.get({x:e,y:n})===2&&this.exploredTiles.get({x:e,y:n}))}wallGlyph(e,n){if(e<1||e>MAP_WIDTH-2||n<1||n>MAP_HEIGHT-2)return 35;let i=0,r=[7,11,13,14,15];this.isRevealedAndWall(e,n-1)&&(i+=1),this.isRevealedAndWall(e,n+1)&&(i+=2),this.isRevealedAndWall(e-1,n)&&(i+=4),this.isRevealedAndWall(e+1,n)&&(i+=8),r.includes(i)&&(this.isRevealedAndWall(e+1,n-1)&&(i+=16),this.isRevealedAndWall(e-1,n-1)&&(i+=32),this.isRevealedAndWall(e+1,n+1)&&(i+=64),this.isRevealedAndWall(e-1,n+1)&&(i+=128));let a=35;switch(i){case 0:a=CharCode.whiteCircle;break;case 1:a=CharCode.boxDrawingsDoubleVertical;break;case 2:a=CharCode.boxDrawingsDoubleVertical;break;case 3:a=CharCode.boxDrawingsDoubleVertical;break;case 4:a=CharCode.boxDrawingsDoubleHorizontal;break;case 5:a=CharCode.boxDrawingsDoubleUpAndLeft;break;case 6:a=CharCode.boxDrawingsDoubleDownAndLeft;break;case 7:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 8:a=CharCode.boxDrawingsDoubleHorizontal;break;case 9:a=CharCode.boxDrawingsDoubleUpAndRight;break;case 10:a=CharCode.boxDrawingsDoubleDownAndRight;break;case 11:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 12:a=CharCode.boxDrawingsDoubleHorizontal;break;case 13:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 14:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 15:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 29:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 31:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 45:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 46:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 47:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 55:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 59:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 63:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 87:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 126:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 143:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 77:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 171:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 187:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 215:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 190:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 237:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 30:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 110:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 111:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 119:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 142:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 158:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 235:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 93:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 109:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 94:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 174:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 159:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 221:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 157:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 79:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 95:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 23:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 39:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 71:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 103:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 135:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 151:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 199:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 78:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 27:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 43:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 75:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 107:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 139:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 155:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 173:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 141:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 205:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 175:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 203:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 61:a=CharCode.boxDrawingsDoubleHorizontal;break;case 125:a=CharCode.boxDrawingsDoubleHorizontal;break;case 189:a=CharCode.boxDrawingsDoubleHorizontal;break;case 206:a=CharCode.boxDrawingsDoubleHorizontal;break;case 207:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 222:a=CharCode.boxDrawingsDoubleHorizontal;break;case 238:a=CharCode.boxDrawingsDoubleHorizontal;break;case 253:a=CharCode.boxDrawingsDoubleHorizontal;break;case 254:a=CharCode.boxDrawingsDoubleHorizontal;break;case 167:a=CharCode.boxDrawingsDoubleVertical;break;case 91:a=CharCode.boxDrawingsDoubleVertical;break;case 183:a=CharCode.boxDrawingsDoubleVertical;break;case 123:a=CharCode.boxDrawingsDoubleVertical;break;case 231:a=CharCode.boxDrawingsDoubleVertical;break;case 219:a=CharCode.boxDrawingsDoubleVertical;break;case 247:a=CharCode.boxDrawingsDoubleVertical;break;case 251:a=CharCode.boxDrawingsDoubleVertical;break;case 127:a=CharCode.boxDrawingsDoubleDownAndLeft;break;case 191:a=CharCode.boxDrawingsDoubleDownAndRight;break;case 223:a=CharCode.boxDrawingsDoubleUpAndLeft;break;case 239:a=CharCode.boxDrawingsDoubleUpAndRight;break;default:a=35;break}return a}populateBlocked(){for(let e=0;e{const l=this.game.player.getComponent(Attributes);return{text:l?` HP ${l.hp}/${l.maxHp} `:""}}),o=new index$7.TextWidget({origin:{x:a.getOrigin().x+a.getState().text.length+1,y:0},initialState:{text:" ATK # "}}).setParent(r).setUpdateFunc(()=>{const l=this.game.player.getComponent(Attributes);return{text:l?` ATK ${l.attack} `:""}});return new index$7.TextWidget({origin:{x:o.getOrigin().x+o.getState().text.length+1,y:0},initialState:{text:" DEF # "}}).setUpdateFunc(()=>{const l=this.game.player.getComponent(Attributes);return{text:l?` DEF ${l.defense} `:""}}).setParent(r),i}execute(){const{results:n}=this.queries.renderables,i=new index.Glyph(".",Color.Green),r=new index.Glyph(".",Color.Gray);this.game.terminal.clear(),this.gui.cascadeUpdate(),this.gui.cascadeDraw();for(let h=this.game.camera.xLeft;h{const l=h.getComponent(Renderable),u=s.getComponent(Renderable);return l.zIndex-u.zIndex});for(const h of a){const s=h.getComponent(Position),l=h.getComponent(Renderable);this.game.map.visibleTiles.get(s)&&this.game.terminal.drawGlyph({x:s.x-this.game.camera.xLeft,y:s.y-this.game.camera.yTop},l.glyph)}const o=this.game.log.getLastMessages(LOG_ENTRIES);for(let h=0;hthis.game.map.tiles.get(r)===TileType.Floor,cartesianRange:!0})}execute(){const{results:n}=this.queries.viewers;for(const i of n){const r=i.getMutableComponent(Viewshed);if(r.dirty)r.dirty=!1;else continue;const a=i.getComponent(Position),o=this.fov.calculateArray(a,r.range),h=i.getComponent(Player);r.visibleTiles=o.map(s=>s.pos).filter(s=>s.x>=0&&s.x<=this.game.map.width&&s.y>=0&&s.y<=this.game.map.height),h&&(this.game.map.visibleTiles.fill(!1),r.visibleTiles.forEach(s=>{this.game.map.visibleTiles.set(s,!0),this.game.map.exploredTiles.set(s,!0)}))}}}c(VisibilitySystem,"queries",{viewers:{components:[Position,Viewshed]}});class Camera{constructor(e){c(this,"xLeft",0);c(this,"xRight",0);c(this,"yTop",0);c(this,"yBottom",0);this.onPlayerMove(e)}onPlayerMove(e){this.xLeft=e.x-VIEWPORT_WIDTH/2,this.xRight=e.x+VIEWPORT_WIDTH/2,this.yTop=e.y-VIEWPORT_HEIGHT/2,this.yBottom=e.y+VIEWPORT_HEIGHT/2}}function tryMoveEntity(t,e,n,i=!1){const r=e.getMutableComponent(Position);if(!r){console.warn("WARNING: Can't move an entity without a Position!");return}const a=i?n:{x:r.x+n.x,y:r.y+n.y};for(const o of t.map.getTileContent(a))if(o.getComponent(Attributes)){e.addComponent(AttemptToMelee,{defender:o});return}if(!t.map.isBlocked(a)){t.map.setBlocked(r,!1),t.map.setBlocked(a),r.x=a.x,r.y=a.y;const o=e.getMutableComponent(Viewshed);o&&(o.dirty=!0),e.getComponent(Player)&&(t.camera=new Camera(a))}}function inflictDamage(t,e){if(!t.hasComponent(IncomingDamage))t.addComponent(IncomingDamage,{amount:e});else{const n=t.getMutableComponent(IncomingDamage);n.amount+=e}}function investigatePosition(t,e){var i;const n=t.map.getTileContent(e).filter(r=>r.hasComponent(Item));if(n.length===0)t.log.addMessage("There's nothing here.");else for(const r of n){const a=((i=r.getComponent(Name))==null?void 0:i.name)||"mysterious thing";t.log.addMessage(`There's a ${a} here.`)}}function attemptToPickUp(t,e,n){const r=t.map.getTileContent(n).filter(a=>a.hasComponent(Item))[0];r===void 0?t.log.addMessage("No item to pick up here."):e.addComponent(AttemptToPickupItem,{item:r})}var GameStates=(t=>(t[t.INIT=0]="INIT",t[t.PLAYER_TURN=1]="PLAYER_TURN",t[t.ENEMY_TURN=2]="ENEMY_TURN",t[t.AWAITING_INPUT=3]="AWAITING_INPUT",t))(GameStates||{});class EnemyAISystem extends System{constructor(n,i){super(n,i);c(this,"game");c(this,"pathfinding");this.game=i,this.pathfinding=new index$6.Dijkstra({topology:"four",isBlockedCallback:r=>this.game.map.tiles.get(r)===TileType.Wall})}execute(){if(this.game.gameState!==GameStates.ENEMY_TURN)return;const{results:n}=this.queries.enemies,i=this.game.player,r=i.getComponent(Position);for(const a of n){const o=a.getMutableComponent(Viewshed),h=a.getMutableComponent(Position);if(o.containsTile(r)){const s=this.pathfinding.compute(h,r);if(s&&s[1]){const l=s[1];l.x===r.x&&l.y===r.y?a.addComponent(AttemptToMelee,{defender:i}):tryMoveEntity(this.game,a,l,!0)}}}}}c(EnemyAISystem,"queries",{enemies:{components:[Enemy,Position,Viewshed]}});class MapIndexing extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.entities;this.game.map.clearTileContent(),this.game.map.populateBlocked();for(const i of n){const r=i.getComponent(Position),a=i.getComponent(BlocksTile);this.game.map.addTileContent(r,i),a&&this.game.map.setBlocked(r)}}}c(MapIndexing,"queries",{entities:{components:[Position]}});class MeleeCombat extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.attemptsToMelee;for(const i of n){const a=i.getComponent(AttemptToMelee).defender,o=i.getComponent(Attributes),h=a.getComponent(Attributes);if(!o)throw new Error("Attacker does not have Attributes!");if(!h)throw new Error("Defender does not have Attributes!");const s=i.getComponent(Name),l=a.getComponent(Name),u=s?s.name:"An unknown attacker",p=l?l.name:"An unknown defender";i.removeComponent(AttemptToMelee);const g=Math.max(0,o.attack-h.defense);g===0?this.game.log.addMessage(`${u} didn't hurt ${p}!`):(this.game.log.addMessage(`${u} attacked ${p} for ${g} damage.`),inflictDamage(a,g))}}}c(MeleeCombat,"queries",{attemptsToMelee:{components:[AttemptToMelee,Position]}});class DamageSystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.damaged;for(const i of n){const r=i.getMutableComponent(Attributes),a=i.getMutableComponent(IncomingDamage);r.hp-=a.amount,a.amount=0}}}c(DamageSystem,"queries",{damaged:{components:[Attributes,IncomingDamage]}});class DeathSystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.canDie,i=[];for(const r of n)r.getComponent(Attributes).hp<=0&&i.push(r);for(const r of i){const a=r.getComponent(Name),o=a?a.name:"An unknown creature";this.game.log.addMessage(`${o} died!`),r.remove(!0)}}}c(DeathSystem,"queries",{canDie:{components:[Attributes]}});class InventorySystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){var i,r;const{results:n}=this.queries.wantsToPickup;for(const a of n){const o=a.getComponent(AttemptToPickupItem),h=a.getComponent(Inventory),s=((i=a.getComponent(Name))==null?void 0:i.name)||"Someone",l=((r=o.item.getComponent(Name))==null?void 0:r.name)||"something";h&&(h.items.push(o.item),o.item.removeComponent(Position),this.game.log.addMessage(`${s} picked up ${l}.`)),a.removeComponent(AttemptToPickupItem)}}}c(InventorySystem,"queries",{wantsToPickup:{components:[AttemptToPickupItem]}});class GameLog{constructor(e=10){c(this,"maxHistory");c(this,"logs");this.maxHistory=e,this.logs=[]}addMessage(...e){for(this.logs.push(...e);this.logs.length>this.maxHistory;)this.logs.shift()}getLastMessages(e){return this.logs.slice().reverse().slice(0,e)}}function generateLevel(t){const{world:e,width:n,height:i}=t,r=new index$3.AleaRNG,a=GameMap.GenMapRoomsAndCorridors(n,i),o=a.rooms[0],h=e.createEntity().addComponent(Player).addComponent(Position,o.center()).addComponent(Renderable,{glyph:Glyph.fromCharCode(CharCode.at,Color.Yellow),zIndex:10}).addComponent(Viewshed,{range:PLAYER_FOV_RANGE}).addComponent(BlocksTile).addComponent(Name,{name:"Player"}).addComponent(Inventory).addComponent(Attributes,{hp:30,maxHp:30,attack:5,defense:2});for(let s=1;s{if(this.gameState===GameStates.AWAITING_INPUT)switch(n.key){case index$1.KeyCode.Period:{this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.I:{investigatePosition(this,this.player.getComponent(Position));break}case index$1.KeyCode.P:{attemptToPickUp(this,this.player,this.player.getComponent(Position));break}case index$1.KeyCode.LeftArrow:{tryMoveEntity(this,this.player,{x:-1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.RightArrow:{tryMoveEntity(this,this.player,{x:1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.UpArrow:{tryMoveEntity(this,this.player,{x:0,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.DownArrow:{tryMoveEntity(this,this.player,{x:0,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.H:{tryMoveEntity(this,this.player,{x:-1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.L:{tryMoveEntity(this,this.player,{x:1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.K:{tryMoveEntity(this,this.player,{x:0,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.J:{tryMoveEntity(this,this.player,{x:0,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.Y:{tryMoveEntity(this,this.player,{x:-1,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.U:{tryMoveEntity(this,this.player,{x:1,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.B:{tryMoveEntity(this,this.player,{x:-1,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.N:{tryMoveEntity(this,this.player,{x:1,y:1}),this.gameState=GameStates.PLAYER_TURN;break}}})}tick(e,n){this.world.execute(e,n),this.gameState===GameStates.INIT?this.gameState=GameStates.PLAYER_TURN:this.gameState===GameStates.PLAYER_TURN?this.gameState=GameStates.ENEMY_TURN:this.gameState===GameStates.ENEMY_TURN&&(this.gameState=GameStates.AWAITING_INPUT)}run(){const n=performance.now()-this.lastTime;this.tick(n,this.lastTime),window.requestAnimationFrame(this.run.bind(this))}}window.addEventListener("DOMContentLoaded",()=>{window.game=new Game,window.game.run()}); + `,e.innerHTML=`Open ECSY devtools to connect to this page using the code: ${t} `,document.body.appendChild(e),e}function enableRemoteDevtools(remoteId){if(!hasWindow){console.warn("Remote devtools not available outside the browser");return}window.generateNewCode=()=>{window.localStorage.clear(),remoteId=generateId(6),window.localStorage.setItem("ecsyRemoteId",remoteId),window.location.reload(!1)},remoteId=remoteId||window.localStorage.getItem("ecsyRemoteId"),remoteId||(remoteId=generateId(6),window.localStorage.setItem("ecsyRemoteId",remoteId));let infoDiv=includeRemoteIdHTML(remoteId);window.__ECSY_REMOTE_DEVTOOLS_INJECTED=!0,window.__ECSY_REMOTE_DEVTOOLS={};let Version="",worldsBeforeLoading=[],onWorldCreated=t=>{var e=t.detail.world;Version=t.detail.version,worldsBeforeLoading.push(e)};window.addEventListener("ecsy-world-created",onWorldCreated);let onLoaded=()=>{var peer=new Peer(remoteId,{host:"peerjs.ecsy.io",secure:!0,port:443,config:{iceServers:[{url:"stun:stun.l.google.com:19302"},{url:"stun:stun1.l.google.com:19302"},{url:"stun:stun2.l.google.com:19302"},{url:"stun:stun3.l.google.com:19302"},{url:"stun:stun4.l.google.com:19302"}]},debug:3});peer.on("open",()=>{peer.on("connection",connection=>{window.__ECSY_REMOTE_DEVTOOLS.connection=connection,connection.on("open",function(){infoDiv.innerHTML="Connected",connection.on("data",function(data){if(data.type==="init"){var script=document.createElement("script");script.setAttribute("type","text/javascript"),script.onload=()=>{script.parentNode.removeChild(script),window.removeEventListener("ecsy-world-created",onWorldCreated),worldsBeforeLoading.forEach(t=>{var e=new CustomEvent("ecsy-world-created",{detail:{world:t,version:Version}});window.dispatchEvent(e)})},script.innerHTML=data.script,(document.head||document.documentElement).appendChild(script),script.onload(),hookConsoleAndErrors(connection)}else if(data.type==="executeScript"){let value=eval(data.script);data.returnEval&&connection.send({method:"evalReturn",value})}})})})})};injectScript("https://cdn.jsdelivr.net/npm/peerjs@0.3.20/dist/peer.min.js",onLoaded)}hasWindow&&new URLSearchParams(window.location.search).has("enable-remote-devtools")&&enableRemoteDevtools();const MAP_WIDTH=100,MAP_HEIGHT=100,DISPLAY_WIDTH=80,DISPLAY_HEIGHT=50,VIEWPORT_WIDTH=80,VIEWPORT_HEIGHT=42,TILE_WIDTH=16,TILE_HEIGHT=16,TILESET="Anikki_square_"+TILE_WIDTH+"x"+TILE_HEIGHT+".png",PLAYER_FOV_RANGE=7,MONSTER_FOV_RANGE=5,MAX_ROOMS=30,MIN_SIZE=6,MAX_SIZE=10,UI_STARTING_X=2,UI_STARTING_Y=2,LOG_ENTRIES=DISPLAY_HEIGHT-VIEWPORT_HEIGHT-4,LOG_FADE=20,INVENTORY_MARGIN_X=20,INVENTORY_MARGIN_Y=10;class Player extends Component{}class Enemy extends Component{}class Item extends Component{}class Position extends Component{constructor(){super(...arguments);c(this,"x",0);c(this,"y",0)}}c(Position,"schema",{x:{type:Types.Number},y:{type:Types.Number}});class Name extends Component{constructor(){super(...arguments);c(this,"name","Unknown")}}c(Name,"schema",{name:{type:Types.String}});class Renderable extends Component{constructor(){super(...arguments);c(this,"glyph");c(this,"zIndex",0)}}c(Renderable,"schema",{glyph:{type:Types.Ref},zIndex:{type:Types.Number}});class Viewshed extends Component{constructor(){super(...arguments);c(this,"visibleTiles",[]);c(this,"range",0);c(this,"dirty",!0)}containsTile(n){for(const i of this.visibleTiles)if(i.x===n.x&&i.y===n.y)return!0;return!1}}c(Viewshed,"schema",{visibleTiles:{type:Types.Array},range:{type:Types.Number},dirty:{type:Types.Boolean}});class BlocksTile extends Component{}class Attributes extends Component{constructor(){super(...arguments);c(this,"hp",10);c(this,"maxHp",10);c(this,"attack",1);c(this,"defense",0)}}c(Attributes,"schema",{hp:{type:Types.Number},maxHp:{type:Types.Number},attack:{type:Types.Number},defense:{type:Types.Number}});class Inventory extends Component{constructor(){super(...arguments);c(this,"items",[])}}c(Inventory,"schema",{owner:{type:Types.Ref}});class IncomingDamage extends Component{constructor(){super(...arguments);c(this,"amount",0)}}c(IncomingDamage,"schema",{amount:{type:Types.Number}});class AttemptToMelee extends Component{constructor(){super(...arguments);c(this,"defender")}}c(AttemptToMelee,"schema",{defender:{type:Types.Ref}});class AttemptToPickupItem extends Component{constructor(){super(...arguments);c(this,"item")}}c(AttemptToPickupItem,"schema",{item:{type:Types.Ref}});var TileType=(t=>(t[t.Floor=1]="Floor",t[t.Wall=2]="Wall",t))(TileType||{});class GameMap{constructor(e,n,i,r){c(this,"tiles");c(this,"visibleTiles");c(this,"exploredTiles");c(this,"blockedTiles");c(this,"tileContent");c(this,"rooms",[]);c(this,"width");c(this,"height");this.tiles=e,this.rooms=n,this.width=i,this.height=r,this.visibleTiles=new index$2.Table(i,r),this.exploredTiles=new index$2.Table(i,r),this.blockedTiles=new index$2.Table(i,r),this.tileContent=new index$2.Table(i,r),this.visibleTiles.fill(!1),this.exploredTiles.fill(!1),this.blockedTiles.fill(!1)}clearTileContent(){this.tileContent.fill([])}getTileContent(e){return this.tileContent.get(e)||[]}addTileContent(e,...n){const i=this.getTileContent(e);this.tileContent.set(e,i.concat(...n))}static GenMapRoomsAndCorridors(e,n){const i=new index$2.Table(e,n);i.fill(2);const r=[],a=new GameMap(i,r,e,n),o=new index$3.AleaRNG,h=MAX_ROOMS,s=MIN_SIZE,l=MAX_SIZE;for(let u=0;uy.intersects(f))){if(a.applyRoomToMap(f),r.length>0){const y=f.center(),v=r[r.length-1].center();o.nextBoolean()?(a.applyHTunnel(v.x,y.x,v.y),a.applyVTunnel(v.y,y.y,y.x)):(a.applyVTunnel(v.y,y.y,v.x),a.applyHTunnel(v.x,y.x,y.y))}r.push(f)}}return a}applyRoomToMap(e){for(let n=e.v1.x;n<=e.v2.x;n++)for(let i=e.v1.y;i<=e.v2.y;i++)this.tiles.set({x:n,y:i},1)}applyHTunnel(e,n,i){const r=Math.min(e,n),a=Math.max(e,n);for(let o=r;o<=a;o++)this.tiles.set({x:o,y:i},1)}applyVTunnel(e,n,i){const r=Math.min(e,n),a=Math.max(e,n);for(let o=r;o<=a;o++)this.tiles.set({x:i,y:o},1)}isRevealedAndWall(e,n){return!!(this.tiles.get({x:e,y:n})===2&&this.exploredTiles.get({x:e,y:n}))}wallGlyph(e,n){if(e<1||e>MAP_WIDTH-2||n<1||n>MAP_HEIGHT-2)return 35;let i=0,r=[7,11,13,14,15];this.isRevealedAndWall(e,n-1)&&(i+=1),this.isRevealedAndWall(e,n+1)&&(i+=2),this.isRevealedAndWall(e-1,n)&&(i+=4),this.isRevealedAndWall(e+1,n)&&(i+=8),r.includes(i)&&(this.isRevealedAndWall(e+1,n-1)&&(i+=16),this.isRevealedAndWall(e-1,n-1)&&(i+=32),this.isRevealedAndWall(e+1,n+1)&&(i+=64),this.isRevealedAndWall(e-1,n+1)&&(i+=128));let a=35;switch(i){case 0:a=CharCode.whiteCircle;break;case 1:a=CharCode.boxDrawingsDoubleVertical;break;case 2:a=CharCode.boxDrawingsDoubleVertical;break;case 3:a=CharCode.boxDrawingsDoubleVertical;break;case 4:a=CharCode.boxDrawingsDoubleHorizontal;break;case 5:a=CharCode.boxDrawingsDoubleUpAndLeft;break;case 6:a=CharCode.boxDrawingsDoubleDownAndLeft;break;case 7:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 8:a=CharCode.boxDrawingsDoubleHorizontal;break;case 9:a=CharCode.boxDrawingsDoubleUpAndRight;break;case 10:a=CharCode.boxDrawingsDoubleDownAndRight;break;case 11:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 12:a=CharCode.boxDrawingsDoubleHorizontal;break;case 13:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 14:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 15:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 29:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 31:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 45:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 46:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 47:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 55:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 59:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 63:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 87:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 126:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 143:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 77:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 171:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 187:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 215:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 190:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 237:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 30:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 110:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 111:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 119:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 142:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 158:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 235:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 93:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 109:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 94:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 174:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 159:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 221:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 157:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 79:a=CharCode.boxDrawingsDoubleVerticalAndHorizontal;break;case 95:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 23:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 39:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 71:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 103:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 135:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 151:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 199:a=CharCode.boxDrawingsDoubleVerticalAndLeft;break;case 78:a=CharCode.boxDrawingsDoubleDownAndHorizontal;break;case 27:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 43:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 75:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 107:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 139:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 155:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 173:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 141:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 205:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 175:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 203:a=CharCode.boxDrawingsDoubleVerticalAndRight;break;case 61:a=CharCode.boxDrawingsDoubleHorizontal;break;case 125:a=CharCode.boxDrawingsDoubleHorizontal;break;case 189:a=CharCode.boxDrawingsDoubleHorizontal;break;case 206:a=CharCode.boxDrawingsDoubleHorizontal;break;case 207:a=CharCode.boxDrawingsDoubleUpAndHorizontal;break;case 222:a=CharCode.boxDrawingsDoubleHorizontal;break;case 238:a=CharCode.boxDrawingsDoubleHorizontal;break;case 253:a=CharCode.boxDrawingsDoubleHorizontal;break;case 254:a=CharCode.boxDrawingsDoubleHorizontal;break;case 167:a=CharCode.boxDrawingsDoubleVertical;break;case 91:a=CharCode.boxDrawingsDoubleVertical;break;case 183:a=CharCode.boxDrawingsDoubleVertical;break;case 123:a=CharCode.boxDrawingsDoubleVertical;break;case 231:a=CharCode.boxDrawingsDoubleVertical;break;case 219:a=CharCode.boxDrawingsDoubleVertical;break;case 247:a=CharCode.boxDrawingsDoubleVertical;break;case 251:a=CharCode.boxDrawingsDoubleVertical;break;case 127:a=CharCode.boxDrawingsDoubleDownAndLeft;break;case 191:a=CharCode.boxDrawingsDoubleDownAndRight;break;case 223:a=CharCode.boxDrawingsDoubleUpAndLeft;break;case 239:a=CharCode.boxDrawingsDoubleUpAndRight;break;default:a=35;break}return a}populateBlocked(){for(let e=0;e(t[t.INIT=0]="INIT",t[t.PLAYER_TURN=1]="PLAYER_TURN",t[t.ENEMY_TURN=2]="ENEMY_TURN",t[t.AWAITING_INPUT=3]="AWAITING_INPUT",t[t.INVENTORY=4]="INVENTORY",t))(GameStates||{});class RenderSystem extends System{constructor(n,i){super(n,i);c(this,"game");c(this,"gui");c(this,"inventory");this.game=i,this.gui=this.constructGUI(i),this.inventory=this.constructInventory(i)}constructGUI(n){const i=new index$7.ContainerWidget().setTerminal(n.terminal),r=new index$7.PanelWidget({origin:{x:0,y:VIEWPORT_HEIGHT},initialState:{width:DISPLAY_WIDTH,height:DISPLAY_HEIGHT-VIEWPORT_HEIGHT,borderStyle:"double-bar"}}).setParent(i),a=new index$7.TextWidget({origin:{x:UI_STARTING_X,y:0},initialState:{text:" HP ##/## "}}).setParent(r).setUpdateFunc(()=>{const l=this.game.player.getComponent(Attributes);return{text:l?` HP ${l.hp}/${l.maxHp} `:""}}),o=new index$7.TextWidget({origin:{x:a.getOrigin().x+a.getState().text.length+1,y:0},initialState:{text:" ATK # "}}).setParent(r).setUpdateFunc(()=>{const l=this.game.player.getComponent(Attributes);return{text:l?` ATK ${l.attack} `:""}});return new index$7.TextWidget({origin:{x:o.getOrigin().x+o.getState().text.length+1,y:0},initialState:{text:" DEF # "}}).setUpdateFunc(()=>{const l=this.game.player.getComponent(Attributes);return{text:l?` DEF ${l.defense} `:""}}).setParent(r),i}constructInventory(n){const i=new index$7.ContainerWidget().setTerminal(n.terminal),r=new index$7.PanelWidget({origin:{x:INVENTORY_MARGIN_X,y:INVENTORY_MARGIN_Y},initialState:{width:VIEWPORT_WIDTH-2*INVENTORY_MARGIN_X,height:VIEWPORT_HEIGHT-2*INVENTORY_MARGIN_Y,borderStyle:"double-bar"}});return r.setParent(i),new index$7.TextWidget({origin:{x:UI_STARTING_X,y:UI_STARTING_Y},initialState:{text:"Inventory"}}).setParent(r),i}renderWorld(){const{results:n}=this.queries.renderables,i=new index.Glyph(".",Color.Green),r=new index.Glyph(".",Color.Gray);this.gui.cascadeUpdate(),this.gui.cascadeDraw();for(let h=this.game.camera.xLeft;h{const l=h.getComponent(Renderable),u=s.getComponent(Renderable);return l.zIndex-u.zIndex});for(const h of a){const s=h.getComponent(Position),l=h.getComponent(Renderable);this.game.map.visibleTiles.get(s)&&this.game.terminal.drawGlyph({x:s.x-this.game.camera.xLeft,y:s.y-this.game.camera.yTop},l.glyph)}const o=this.game.log.getLastMessages(LOG_ENTRIES);for(let h=0;hthis.game.map.tiles.get(r)===TileType.Floor,cartesianRange:!0})}execute(){const{results:n}=this.queries.viewers;for(const i of n){const r=i.getMutableComponent(Viewshed);if(r.dirty)r.dirty=!1;else continue;const a=i.getComponent(Position),o=this.fov.calculateArray(a,r.range),h=i.getComponent(Player);r.visibleTiles=o.map(s=>s.pos).filter(s=>s.x>=0&&s.x<=this.game.map.width&&s.y>=0&&s.y<=this.game.map.height),h&&(this.game.map.visibleTiles.fill(!1),r.visibleTiles.forEach(s=>{this.game.map.visibleTiles.set(s,!0),this.game.map.exploredTiles.set(s,!0)}))}}}c(VisibilitySystem,"queries",{viewers:{components:[Position,Viewshed]}});class Camera{constructor(e){c(this,"xLeft",0);c(this,"xRight",0);c(this,"yTop",0);c(this,"yBottom",0);this.onPlayerMove(e)}onPlayerMove(e){this.xLeft=e.x-VIEWPORT_WIDTH/2,this.xRight=e.x+VIEWPORT_WIDTH/2,this.yTop=e.y-VIEWPORT_HEIGHT/2,this.yBottom=e.y+VIEWPORT_HEIGHT/2}}function tryMoveEntity(t,e,n,i=!1){const r=e.getMutableComponent(Position);if(!r){console.warn("WARNING: Can't move an entity without a Position!");return}const a=i?n:{x:r.x+n.x,y:r.y+n.y};for(const o of t.map.getTileContent(a))if(o.getComponent(Attributes)){e.addComponent(AttemptToMelee,{defender:o});return}if(!t.map.isBlocked(a)){t.map.setBlocked(r,!1),t.map.setBlocked(a),r.x=a.x,r.y=a.y;const o=e.getMutableComponent(Viewshed);o&&(o.dirty=!0),e.getComponent(Player)&&(t.camera=new Camera(a))}}function inflictDamage(t,e){if(!t.hasComponent(IncomingDamage))t.addComponent(IncomingDamage,{amount:e});else{const n=t.getMutableComponent(IncomingDamage);n.amount+=e}}function investigatePosition(t,e){var i;const n=t.map.getTileContent(e).filter(r=>r.hasComponent(Item));if(n.length===0)t.log.addMessage("There's nothing here.");else for(const r of n){const a=((i=r.getComponent(Name))==null?void 0:i.name)||"mysterious thing";t.log.addMessage(`There's a ${a} here.`)}}function attemptToPickUp(t,e,n){const r=t.map.getTileContent(n).filter(a=>a.hasComponent(Item))[0];r===void 0?t.log.addMessage("No item to pick up here."):e.addComponent(AttemptToPickupItem,{item:r})}class EnemyAISystem extends System{constructor(n,i){super(n,i);c(this,"game");c(this,"pathfinding");this.game=i,this.pathfinding=new index$6.Dijkstra({topology:"four",isBlockedCallback:r=>this.game.map.tiles.get(r)===TileType.Wall})}execute(){if(this.game.gameState!==GameStates.ENEMY_TURN)return;const{results:n}=this.queries.enemies,i=this.game.player,r=i.getComponent(Position);for(const a of n){const o=a.getMutableComponent(Viewshed),h=a.getMutableComponent(Position);if(o.containsTile(r)){const s=this.pathfinding.compute(h,r);if(s&&s[1]){const l=s[1];l.x===r.x&&l.y===r.y?a.addComponent(AttemptToMelee,{defender:i}):tryMoveEntity(this.game,a,l,!0)}}}}}c(EnemyAISystem,"queries",{enemies:{components:[Enemy,Position,Viewshed]}});class MapIndexing extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.entities;this.game.map.clearTileContent(),this.game.map.populateBlocked();for(const i of n){const r=i.getComponent(Position),a=i.getComponent(BlocksTile);this.game.map.addTileContent(r,i),a&&this.game.map.setBlocked(r)}}}c(MapIndexing,"queries",{entities:{components:[Position]}});class MeleeCombat extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.attemptsToMelee;for(const i of n){const a=i.getComponent(AttemptToMelee).defender,o=i.getComponent(Attributes),h=a.getComponent(Attributes);if(!o)throw new Error("Attacker does not have Attributes!");if(!h)throw new Error("Defender does not have Attributes!");const s=i.getComponent(Name),l=a.getComponent(Name),u=s?s.name:"An unknown attacker",p=l?l.name:"An unknown defender";i.removeComponent(AttemptToMelee);const g=Math.max(0,o.attack-h.defense);g===0?this.game.log.addMessage(`${u} didn't hurt ${p}!`):(this.game.log.addMessage(`${u} attacked ${p} for ${g} damage.`),inflictDamage(a,g))}}}c(MeleeCombat,"queries",{attemptsToMelee:{components:[AttemptToMelee,Position]}});class DamageSystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.damaged;for(const i of n){const r=i.getMutableComponent(Attributes),a=i.getMutableComponent(IncomingDamage);r.hp-=a.amount,a.amount=0}}}c(DamageSystem,"queries",{damaged:{components:[Attributes,IncomingDamage]}});class DeathSystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){const{results:n}=this.queries.canDie,i=[];for(const r of n)r.getComponent(Attributes).hp<=0&&i.push(r);for(const r of i){const a=r.getComponent(Name),o=a?a.name:"An unknown creature";this.game.log.addMessage(`${o} died!`),r.remove(!0)}}}c(DeathSystem,"queries",{canDie:{components:[Attributes]}});class InventorySystem extends System{constructor(n,i){super(n,i);c(this,"game");this.game=i}execute(){var i,r;const{results:n}=this.queries.wantsToPickup;for(const a of n){const o=a.getComponent(AttemptToPickupItem),h=a.getComponent(Inventory),s=((i=a.getComponent(Name))==null?void 0:i.name)||"Someone",l=((r=o.item.getComponent(Name))==null?void 0:r.name)||"something";h&&(h.items.push(o.item),o.item.removeComponent(Position),this.game.log.addMessage(`${s} picked up ${l}.`)),a.removeComponent(AttemptToPickupItem)}}}c(InventorySystem,"queries",{wantsToPickup:{components:[AttemptToPickupItem]}});class GameLog{constructor(e=10){c(this,"maxHistory");c(this,"logs");this.maxHistory=e,this.logs=[]}addMessage(...e){for(this.logs.push(...e);this.logs.length>this.maxHistory;)this.logs.shift()}getLastMessages(e){return this.logs.slice().reverse().slice(0,e)}}function generateLevel(t){const{world:e,width:n,height:i}=t,r=new index$3.AleaRNG,a=GameMap.GenMapRoomsAndCorridors(n,i),o=a.rooms[0],h=e.createEntity().addComponent(Player).addComponent(Position,o.center()).addComponent(Renderable,{glyph:Glyph.fromCharCode(CharCode.at,Color.Yellow),zIndex:10}).addComponent(Viewshed,{range:PLAYER_FOV_RANGE}).addComponent(BlocksTile).addComponent(Name,{name:"Player"}).addComponent(Inventory).addComponent(Attributes,{hp:30,maxHp:30,attack:5,defense:2});for(let s=1;s{if(!(this.gameState!==GameStates.AWAITING_INPUT&&this.gameState!==GameStates.INVENTORY))switch(n.key){case index$1.KeyCode.Period:{this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.I:{investigatePosition(this,this.player.getComponent(Position));break}case index$1.KeyCode.P:{attemptToPickUp(this,this.player,this.player.getComponent(Position));break}case index$1.KeyCode.LeftArrow:{tryMoveEntity(this,this.player,{x:-1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.RightArrow:{tryMoveEntity(this,this.player,{x:1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.UpArrow:{tryMoveEntity(this,this.player,{x:0,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.DownArrow:{tryMoveEntity(this,this.player,{x:0,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.H:{tryMoveEntity(this,this.player,{x:-1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.L:{tryMoveEntity(this,this.player,{x:1,y:0}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.K:{tryMoveEntity(this,this.player,{x:0,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.J:{tryMoveEntity(this,this.player,{x:0,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.Y:{tryMoveEntity(this,this.player,{x:-1,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.U:{tryMoveEntity(this,this.player,{x:1,y:-1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.B:{tryMoveEntity(this,this.player,{x:-1,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.N:{tryMoveEntity(this,this.player,{x:1,y:1}),this.gameState=GameStates.PLAYER_TURN;break}case index$1.KeyCode.E:this.gameState===GameStates.AWAITING_INPUT?this.gameState=GameStates.INVENTORY:this.gameState===GameStates.INVENTORY&&(this.gameState=GameStates.AWAITING_INPUT)}})}tick(e,n){this.world.execute(e,n),this.gameState===GameStates.INIT?this.gameState=GameStates.PLAYER_TURN:this.gameState===GameStates.PLAYER_TURN?this.gameState=GameStates.ENEMY_TURN:this.gameState===GameStates.ENEMY_TURN&&(this.gameState=GameStates.AWAITING_INPUT)}run(){const n=performance.now()-this.lastTime;this.tick(n,this.lastTime),window.requestAnimationFrame(this.run.bind(this))}}window.addEventListener("DOMContentLoaded",()=>{window.game=new Game,window.game.run()}); diff --git a/index.html b/index.html index decca00..9904dc0 100644 --- a/index.html +++ b/index.html @@ -11,7 +11,7 @@ align-items: center; } - +