added base files
|
@ -0,0 +1,871 @@
|
|||
/*
|
||||
Orteil's crappy dungeon generation library, 2013
|
||||
Unfinished and buggy, use at your own risk (please credit)
|
||||
http://orteil.dashnet.org
|
||||
|
||||
Rough process (might or might not be what actually happens) :
|
||||
1 make a room in the middle
|
||||
2 pick one of its walls (not corners)
|
||||
3 select a free tile on the other side of that wall
|
||||
4 iteratively expand the selection in one (corridors) or two (rooms) directions, stopping when we meet a wall or when we're above the size threshold
|
||||
5 compute that selection into a room
|
||||
6 add decorations to the room (pillars, water) but only on the center tiles, as to leave free passages (sprinkle destructible decorations anywhere)
|
||||
7 take a random floor tile in the room and repeat step 4, but don't stop at the walls of this room (this creates branching) - repeat about 5 times for interesting shapes
|
||||
8 add those branches to the room
|
||||
9 carve the room into the map, and set the initially selected wall as a door - set the new room's parent to the previous room, and add it to its parent's children
|
||||
10 repeat step 2 with any free wall on the map until the amount of tiles dug is above the desired fill ratio
|
||||
|
||||
Note : I should probably switch the rendering to canvas to allow stuff like occlusion shadows and lights
|
||||
*/
|
||||
|
||||
if (1==1 || undefined==Math.seedrandom)
|
||||
{
|
||||
//seeded random function, courtesy of http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html
|
||||
(function(a,b,c,d,e,f){function k(a){var b,c=a.length,e=this,f=0,g=e.i=e.j=0,h=e.S=[];for(c||(a=[c++]);d>f;)h[f]=f++;for(f=0;d>f;f++)h[f]=h[g=j&g+a[f%c]+(b=h[f])],h[g]=b;(e.g=function(a){for(var b,c=0,f=e.i,g=e.j,h=e.S;a--;)b=h[f=j&f+1],c=c*d+h[j&(h[f]=h[g=j&g+b])+(h[g]=b)];return e.i=f,e.j=g,c})(d)}function l(a,b){var e,c=[],d=(typeof a)[0];if(b&&"o"==d)for(e in a)try{c.push(l(a[e],b-1))}catch(f){}return c.length?c:"s"==d?a:a+"\0"}function m(a,b){for(var d,c=a+"",e=0;c.length>e;)b[j&e]=j&(d^=19*b[j&e])+c.charCodeAt(e++);return o(b)}function n(c){try{return a.crypto.getRandomValues(c=new Uint8Array(d)),o(c)}catch(e){return[+new Date,a,a.navigator.plugins,a.screen,o(b)]}}function o(a){return String.fromCharCode.apply(0,a)}var g=c.pow(d,e),h=c.pow(2,f),i=2*h,j=d-1;c.seedrandom=function(a,f){var j=[],p=m(l(f?[a,o(b)]:0 in arguments?a:n(),3),j),q=new k(j);return m(o(q.S),b),c.random=function(){for(var a=q.g(e),b=g,c=0;h>a;)a=(a+c)*d,b*=d,c=q.g(1);for(;a>=i;)a/=2,b/=2,c>>>=1;return(a+c)/b},p},m(c.random(),b)})(this,[],Math,256,6,52);
|
||||
}
|
||||
|
||||
if (1==1 || undefined==choose) {function choose(arr) {if (arr.length==0) return 0; else return arr[Math.floor(Math.random()*arr.length)];}}
|
||||
|
||||
|
||||
var DungeonGen=function()
|
||||
{
|
||||
var TILE_EMPTY=0;//solid
|
||||
var TILE_LIMIT=-100;//can't build anything here; edges of map
|
||||
var TILE_FLOOR_EDGE=100;
|
||||
var TILE_FLOOR_CENTER=110;
|
||||
var TILE_DOOR=200;
|
||||
var TILE_PILLAR=300;//not just pillars, could be any type of repetitive decoration
|
||||
var TILE_WATER=400;
|
||||
var TILE_WALL=500;
|
||||
var TILE_WALL_CORNER=510;
|
||||
var TILE_ENTRANCE=250;
|
||||
var TILE_EXIT=260;
|
||||
|
||||
var colors=[];
|
||||
colors[TILE_EMPTY]='000';
|
||||
colors[TILE_LIMIT]='900';
|
||||
colors[TILE_FLOOR_EDGE]='ffc';
|
||||
colors[TILE_FLOOR_CENTER]='ff9';
|
||||
colors[TILE_DOOR]='f9f';
|
||||
colors[TILE_PILLAR]='990';
|
||||
colors[TILE_WATER]='99f';
|
||||
colors[TILE_WALL]='960';
|
||||
colors[TILE_WALL_CORNER]='630';
|
||||
colors[TILE_ENTRANCE]='f9f';
|
||||
colors[TILE_EXIT]='f9f';
|
||||
|
||||
var rand=function(a,b){return Math.floor(Math.random()*(b-a+1)+a);}//return random value between a and b
|
||||
|
||||
var Patterns=[];
|
||||
this.Pattern=function(name,func)
|
||||
{
|
||||
this.name=name;
|
||||
this.func=func;
|
||||
Patterns.push(this);
|
||||
}
|
||||
new this.Pattern('Pillars',function(x,y,room)
|
||||
{
|
||||
if ((x+room.x)%2==0 && (y+room.y)%2==0 && Math.random()<0.8) return TILE_PILLAR;
|
||||
return 0;
|
||||
});
|
||||
new this.Pattern('Large pillars',function(x,y,room)
|
||||
{
|
||||
if ((x+room.x)%3<2 && (y+room.y)%3<2 && Math.random()<0.8) return TILE_PILLAR;
|
||||
return 0;
|
||||
});
|
||||
new this.Pattern('Sparse pillars',function(x,y,room)
|
||||
{
|
||||
if ((x+room.x)%3==0 && (y+room.y)%3==0 && Math.random()<0.8) return TILE_PILLAR;
|
||||
return 0;
|
||||
});
|
||||
new this.Pattern('Lines',function(x,y,room)
|
||||
{
|
||||
if (room.x%2==0) if ((x+room.x)%2==0 && Math.random()<0.98) return TILE_PILLAR;
|
||||
if (room.x%2==1) if ((y+room.y)%2==0 && Math.random()<0.98) return TILE_PILLAR;
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
var getRandomPattern=function()
|
||||
{return choose(Patterns);}
|
||||
|
||||
var defaultGenerator=function(me)
|
||||
{
|
||||
me.roomSize=10;
|
||||
me.corridorSize=5;
|
||||
me.fillRatio=1/3;
|
||||
me.corridorRatio=0.2;
|
||||
me.pillarRatio=0.2;
|
||||
me.waterRatio=0;
|
||||
me.branching=4;
|
||||
me.sizeVariance=0.2;
|
||||
|
||||
me.fillRatio=0.1+Math.random()*0.4;
|
||||
me.roomSize=Math.ceil(rand(5,15)*me.fillRatio*2);
|
||||
me.corridorSize=Math.ceil(rand(1,7)*me.fillRatio*2);
|
||||
me.corridorRatio=Math.random()*0.8+0.1;
|
||||
me.pillarRatio=Math.random()*0.5+0.5;
|
||||
me.waterRatio=Math.pow(Math.random(),2);
|
||||
me.branching=Math.floor(Math.random()*6);
|
||||
me.sizeVariance=Math.random();
|
||||
}
|
||||
|
||||
|
||||
this.Map=function(w,h,seed,params)
|
||||
{
|
||||
//create a new map
|
||||
//leave the seed out for a random seed
|
||||
//params is an object that contains custom parameters as defined in defaultGenerator
|
||||
//example : MyMap=new DungeonGen.Map(30,30,MySeed,{waterRatio:0.8}); (80 percent of the rooms will contain water)
|
||||
if (undefined!=seed) this.seed=seed; else {Math.seedrandom();this.seed=Math.random();}
|
||||
Math.seedrandom(this.seed);
|
||||
this.seedState=Math.random;
|
||||
this.w=w||20;
|
||||
this.h=h||20;
|
||||
|
||||
this.roomsAreHidden=0;
|
||||
|
||||
this.rooms=[];
|
||||
this.freeWalls=[];//all walls that would be a good spot for a door
|
||||
this.freeTiles=[];//all passable floor tiles
|
||||
this.doors=[];
|
||||
this.tiles=this.w*this.h;
|
||||
this.tilesDug=0;
|
||||
this.digs=0;//amount of digging steps
|
||||
this.stuck=0;//how many times we ran into a problem; stop digging if we get too many of these
|
||||
|
||||
this.data=[];//fill the map with 0
|
||||
for (var x=0;x<this.w;x++)
|
||||
{
|
||||
this.data[x]=[];
|
||||
for (var y=0;y<this.h;y++)
|
||||
{
|
||||
this.data[x][y]=[TILE_EMPTY,-1,0];//data is stored as [tile system type,room id,tile displayed type] (-1 is no room)
|
||||
if (x==0 || y==0 || x==this.w-1 || y==this.h-1) this.data[x][y]=[TILE_LIMIT,-1,0];
|
||||
}
|
||||
}
|
||||
|
||||
defaultGenerator(this);
|
||||
if (params)
|
||||
{
|
||||
for (var i in params)
|
||||
{
|
||||
this[i]=params[i];
|
||||
}
|
||||
}
|
||||
Math.seedrandom();
|
||||
|
||||
}
|
||||
|
||||
this.Map.prototype.getType=function(x,y){return this.data[x][y][0];}
|
||||
this.Map.prototype.getRoom=function(x,y){if (this.data[x][y][1]!=-1) return this.rooms[this.data[x][y][1]]; else return -1;}
|
||||
this.Map.prototype.getTile=function(x,y){return this.rooms[this.data[x][y][2]];}
|
||||
|
||||
this.Map.prototype.isWall=function(x,y)
|
||||
{
|
||||
var n=0;
|
||||
for (var i in this.freeWalls){if (this.freeWalls[i][0]==x && this.freeWalls[i][1]==y) return n; else n++;}
|
||||
return -1;
|
||||
}
|
||||
this.Map.prototype.isFloor=function(x,y)
|
||||
{
|
||||
var n=0;
|
||||
for (var i in this.freeTiles){if (this.freeTiles[i][0]==x && this.freeTiles[i][1]==y) return n; else n++;}
|
||||
return -1;
|
||||
}
|
||||
this.Map.prototype.removeFreeTile=function(x,y)
|
||||
{
|
||||
this.freeTiles.splice(this.isFloor(x,y),1);
|
||||
}
|
||||
|
||||
this.Map.prototype.fill=function(what)
|
||||
{
|
||||
//fill with something (either a set value, or a function that takes the map, a position X and a position Y as arguments)
|
||||
//NOTE : this also resets the rooms!
|
||||
//example : MyMap.fill(function(m,x,y){return Math.floor((Math.random());});
|
||||
//...will fill the map with 0s and 1s
|
||||
var func=0;
|
||||
if (typeof(what)=='function') func=1;
|
||||
for (var x=0;x<this.w;x++){for (var y=0;y<this.h;y++){
|
||||
if (func) this.data[x][y]=[what(this,x,y),-1,0]; else this.data[x][y]=[what,-1,0];
|
||||
}}
|
||||
this.rooms=[];
|
||||
}
|
||||
|
||||
this.Map.prototype.fillZone=function(X,Y,W,H,what)
|
||||
{
|
||||
//just plain fill a rectangle
|
||||
for (var x=X;x<X+W;x++){for (var y=Y;y<Y+H;y++){
|
||||
this.data[x][y][0]=what;
|
||||
}}
|
||||
}
|
||||
|
||||
this.Map.prototype.getRoomTile=function(room,x,y)
|
||||
{
|
||||
var n=0;
|
||||
for (var i in room.tiles) {if (room.tiles[i].x==x && room.tiles[i].y==y) return n; else n++;}
|
||||
return -1;
|
||||
}
|
||||
|
||||
this.Map.prototype.getFloorTileInRoom=function(room)
|
||||
{
|
||||
var tiles=[];
|
||||
for (var i in room.tiles) {if (room.tiles[i].type==TILE_FLOOR_EDGE || room.tiles[i].type==TILE_FLOOR_CENTER) tiles.push(room.tiles[i]);}
|
||||
return choose(tiles);
|
||||
}
|
||||
|
||||
this.Map.prototype.canPlaceRoom=function(rx,ry,rw,rh)
|
||||
{
|
||||
if (rx<2 || ry<2 || rx+rw>=this.w-1 || ry+rh>=this.h-1) return false;
|
||||
for (var x=rx;x<rx+rw;x++)
|
||||
{
|
||||
for (var y=ry;y<ry+rh;y++)
|
||||
{
|
||||
var tile=this.getType(x,y);
|
||||
var room=this.getRoom(x,y);
|
||||
if (tile==TILE_LIMIT) return false;
|
||||
if (room!=-1) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
this.Map.prototype.setRoomTile=function(room,x,y,tile)
|
||||
{
|
||||
//var mapTile=this.getType(x,y);
|
||||
var oldTile=this.getRoomTile(room,x,y);
|
||||
var oldTileType=oldTile!=-1?room.tiles[oldTile].type:-1;
|
||||
if (oldTile!=-1 && (
|
||||
//(tile!=TILE_FLOOR_EDGE && tile!=TILE_FLOOR_CENTER) ||// && (oldTileType!=TILE_FLOOR_EDGE && oldTileType!=TILE_FLOOR_CENTER)) ||
|
||||
//(tile!=TILE_FLOOR_EDGE && tile!=TILE_FLOOR_CENTER && (oldTileType!=TILE_FLOOR_EDGE && oldTileType!=TILE_FLOOR_CENTER)) ||
|
||||
(tile==TILE_WALL || tile==TILE_WALL_CORNER) ||//don't place a wall over an existing room
|
||||
(tile==TILE_FLOOR_EDGE && oldTileType==TILE_FLOOR_CENTER)//don't place an edge floor over a center floor
|
||||
)) {return false;}
|
||||
else
|
||||
{
|
||||
if (oldTile!=-1) room.tiles.splice(oldTile,1);
|
||||
room.tiles.push({x:x,y:y,type:tile,score:0});
|
||||
if ((tile==TILE_FLOOR_EDGE || tile==TILE_FLOOR_CENTER) && (oldTileType!=TILE_FLOOR_EDGE && oldTileType!=TILE_FLOOR_CENTER)) room.freeTiles++;
|
||||
else if (tile!=TILE_FLOOR_EDGE && tile!=TILE_FLOOR_CENTER && (oldTileType==TILE_FLOOR_EDGE || oldTileType==TILE_FLOOR_CENTER)) room.freeTiles--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.Map.prototype.expandRoom=function(room,rx,ry,rw,rh)
|
||||
{
|
||||
var x=0;var y=0;
|
||||
//floor
|
||||
for (var x=rx;x<rx+rw;x++){for (var y=ry;y<ry+rh;y++){
|
||||
this.setRoomTile(room,x,y,TILE_FLOOR_EDGE);
|
||||
}}
|
||||
for (var x=rx+1;x<rx+rw-1;x++){for (var y=ry+1;y<ry+rh-1;y++){
|
||||
this.setRoomTile(room,x,y,TILE_FLOOR_CENTER);
|
||||
}}
|
||||
//walls
|
||||
y=ry-1;
|
||||
for (var x=rx;x<rx+rw;x++){
|
||||
this.setRoomTile(room,x,y,TILE_WALL);
|
||||
}
|
||||
y=ry+rh;
|
||||
for (var x=rx;x<rx+rw;x++){
|
||||
this.setRoomTile(room,x,y,TILE_WALL);
|
||||
}
|
||||
x=rx-1;
|
||||
for (var y=ry;y<ry+rh;y++){
|
||||
this.setRoomTile(room,x,y,TILE_WALL);
|
||||
}
|
||||
x=rx+rw;
|
||||
for (var y=ry;y<ry+rh;y++){
|
||||
this.setRoomTile(room,x,y,TILE_WALL);
|
||||
}
|
||||
//corners
|
||||
x=rx-1;y=ry-1;
|
||||
this.setRoomTile(room,x,y,TILE_WALL_CORNER);
|
||||
x=rx+rw;y=ry-1;
|
||||
this.setRoomTile(room,x,y,TILE_WALL_CORNER);
|
||||
x=rx-1;y=ry+rh;
|
||||
this.setRoomTile(room,x,y,TILE_WALL_CORNER);
|
||||
x=rx+rw;y=ry+rh;
|
||||
this.setRoomTile(room,x,y,TILE_WALL_CORNER);
|
||||
|
||||
//decoration
|
||||
var water=Math.random()<this.waterRatio?1:0;
|
||||
var pattern=Math.random()<this.pillarRatio?getRandomPattern():0;
|
||||
for (var x=rx;x<rx+rw;x++){for (var y=ry;y<ry+rh;y++){
|
||||
if (room.tiles[this.getRoomTile(room,x,y)].type==TILE_FLOOR_CENTER)
|
||||
{
|
||||
var tile=0;
|
||||
if (water!=0) tile=TILE_WATER;
|
||||
if (pattern!=0)
|
||||
{
|
||||
tile=pattern.func(x,y,room)||tile;
|
||||
}
|
||||
if (tile!=0) this.setRoomTile(room,x,y,tile);
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
this.Map.prototype.newRoom=function(x,y,w,h,parent)
|
||||
{
|
||||
//create a new abstract room, ready to be carved
|
||||
var room={};
|
||||
room.id=this.rooms.length;
|
||||
room.w=w;//||rand(2,this.roomSize);
|
||||
room.h=h;//||rand(2,this.roomSize);
|
||||
room.x=x||rand(1,this.w-room.w-1);
|
||||
room.y=y||rand(1,this.h-room.h-1);
|
||||
room.tiles=[];
|
||||
room.freeTiles=0;
|
||||
room.parent=parent?parent:-1;
|
||||
room.children=[];
|
||||
room.gen=0;
|
||||
room.door=0;
|
||||
room.corridor=Math.random()<this.corridorRatio?1:0;
|
||||
room.hidden=this.roomsAreHidden;//if 1, don't draw
|
||||
//if (room.parent!=-1) room.corridor=!room.parent.corridor;//alternate rooms and corridors
|
||||
|
||||
return room;
|
||||
}
|
||||
this.Map.prototype.planRoom=function(room)
|
||||
{
|
||||
var branches=this.branching+1;
|
||||
var forcedExpansions=[];
|
||||
var w=room.w;
|
||||
var h=room.h;
|
||||
while (w>0 && h>0)
|
||||
{
|
||||
if (w>0) {forcedExpansions.push(1,3);w--;}
|
||||
if (h>0) {forcedExpansions.push(2,4);h--;}
|
||||
}
|
||||
|
||||
for (var i=0;i<branches;i++)
|
||||
{
|
||||
var steps=0;
|
||||
var expansions=[];
|
||||
if (!room.corridor)
|
||||
{
|
||||
expansions=[1,2,3,4];
|
||||
steps=this.roomSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
expansions=choose([[1,3],[2,4]]);
|
||||
steps=this.corridorSize;
|
||||
}
|
||||
steps=Math.max(room.w+room.h,Math.ceil(steps*(1-Math.random()*this.sizeVariance)));
|
||||
if (room.tiles.length==0) {var rx=room.x;var ry=room.y;var rw=1;var rh=1;}
|
||||
else {var randomTile=this.getFloorTileInRoom(room);var rx=randomTile.x;var ry=randomTile.y;var rw=1;var rh=1;}
|
||||
for (var ii=0;ii<steps;ii++)
|
||||
{
|
||||
if (expansions.length==0) break;
|
||||
var xd=0;var yd=0;var wd=0;var hd=0;
|
||||
var side=choose(expansions);
|
||||
if (forcedExpansions.length>0) side=forcedExpansions[0];
|
||||
if (side==1) {xd=-1;wd=1;}
|
||||
else if (side==2) {yd=-1;hd=1;}
|
||||
else if (side==3) {wd=1;}
|
||||
else if (side==4) {hd=1;}
|
||||
if (this.canPlaceRoom(rx+xd,ry+yd,rw+wd,rh+hd)) {rx+=xd;ry+=yd;rw+=wd;rh+=hd;} else expansions.splice(expansions.indexOf(side),1);
|
||||
if (forcedExpansions.length>0) forcedExpansions.splice(0,1);
|
||||
}
|
||||
if (rw>1 || rh>1)
|
||||
{
|
||||
this.expandRoom(room,rx,ry,rw,rh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.Map.prototype.carve=function(room)
|
||||
{
|
||||
//carve a room into the map
|
||||
for (var i in room.tiles)
|
||||
{
|
||||
var thisTile=room.tiles[i];
|
||||
var x=thisTile.x;var y=thisTile.y;
|
||||
var myType=this.data[x][y][0];
|
||||
var type=thisTile.type;
|
||||
|
||||
if ((type==TILE_WALL || type==TILE_WALL_CORNER) && this.isWall(x,y)!=-1) {this.freeWalls.splice(this.isWall(x,y),1);}
|
||||
|
||||
if (this.data[x][y][1]!=-1 && (type==TILE_WALL || type==TILE_WALL_CORNER)) {}
|
||||
else
|
||||
{
|
||||
if (this.data[x][y][1]==-1) this.tilesDug++;
|
||||
this.data[x][y]=[thisTile.type,room.id,0];
|
||||
if (x>1 && y>1 && x<this.w-2 && y<this.h-2 && type==TILE_WALL) this.freeWalls.push([x,y]);
|
||||
if (type==TILE_FLOOR_EDGE || type==TILE_FLOOR_CENTER) this.freeTiles.push([x,y]);
|
||||
}
|
||||
var pos=[x,y];
|
||||
}
|
||||
this.rooms[room.id]=room;
|
||||
}
|
||||
|
||||
this.Map.prototype.newRandomRoom=function(params)
|
||||
{
|
||||
var success=1;
|
||||
params=params||{};//params is an object such as {corridor:1}
|
||||
var door=choose(this.freeWalls);//select a free wall to use as a door
|
||||
if (!door) {success=0;}
|
||||
else
|
||||
{
|
||||
//this.data[door[0]][door[1]][0]=TILE_LIMIT;//not door
|
||||
var parentRoom=this.getRoom(door[0],door[1]);
|
||||
var sides=[];//select a free side of that door
|
||||
if (this.getType(door[0]-1,door[1])==TILE_EMPTY) sides.push([-1,0]);
|
||||
if (this.getType(door[0]+1,door[1])==TILE_EMPTY) sides.push([1,0]);
|
||||
if (this.getType(door[0],door[1]-1)==TILE_EMPTY) sides.push([0,-1]);
|
||||
if (this.getType(door[0],door[1]+1)==TILE_EMPTY) sides.push([0,1]);
|
||||
var side=choose(sides);
|
||||
if (!side) {success=0;this.freeWalls.splice(this.isWall(door[0],door[1]),1);}
|
||||
else
|
||||
{
|
||||
var room=this.newRoom(door[0]+side[0],door[1]+side[1],0,0,parentRoom);//try a new room from this spot
|
||||
for (var i in params)
|
||||
{
|
||||
room[i]=params[i];
|
||||
}
|
||||
this.planRoom(room);
|
||||
if (room.tiles.length>0 && room.freeTiles>0)//we got a decent room
|
||||
{
|
||||
this.carve(room);
|
||||
this.data[door[0]][door[1]][0]=TILE_DOOR;//place door
|
||||
room.door=[door[0],door[1]];
|
||||
this.data[door[0]][door[1]][1]=room.id;//set ID
|
||||
this.freeWalls.splice(this.isWall(door[0],door[1]),1);//the door isn't a wall anymore
|
||||
this.doors.push([door[0],door[1],room]);
|
||||
//remove free tiles on either side of the door
|
||||
if (this.isFloor(door[0]+side[0],door[1]+side[1])!=-1) this.removeFreeTile(door[0]+side[0],door[1]+side[1]);
|
||||
if (this.isFloor(door[0]-side[0],door[1]-side[1])!=-1) this.removeFreeTile(door[0]-side[0],door[1]-side[1]);
|
||||
room.parent=parentRoom;
|
||||
parentRoom.children.push(room);
|
||||
room.gen=parentRoom.gen+1;
|
||||
}
|
||||
else//not a good spot; remove this tile from the list of walls
|
||||
{
|
||||
this.freeWalls.splice(this.isWall(door[0],door[1]),1);
|
||||
success=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success) return room;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
this.Map.prototype.getRandomSpotInRoom=function(room)
|
||||
{
|
||||
var listOfTiles=[];
|
||||
for (var i in room.tiles)
|
||||
{
|
||||
if ((room.tiles[i].type==TILE_FLOOR_EDGE || room.tiles[i].type==TILE_FLOOR_CENTER) && this.isFloor(room.tiles[i].x,room.tiles[i].y)!=-1)
|
||||
{
|
||||
listOfTiles.push(room.tiles[i]);
|
||||
}
|
||||
}
|
||||
if (listOfTiles.length==0) return -1;
|
||||
return choose(listOfTiles);
|
||||
}
|
||||
this.Map.prototype.getBestSpotInRoom=function(room)
|
||||
{
|
||||
var highest=-1;
|
||||
var listOfHighest=[];
|
||||
for (var i in room.tiles)
|
||||
{
|
||||
if ((room.tiles[i].type==TILE_FLOOR_EDGE || room.tiles[i].type==TILE_FLOOR_CENTER) && this.isFloor(room.tiles[i].x,room.tiles[i].y)!=-1)
|
||||
{
|
||||
if (room.tiles[i].score>highest)
|
||||
{
|
||||
listOfHighest=[];
|
||||
highest=room.tiles[i].score;
|
||||
listOfHighest.push(room.tiles[i]);
|
||||
}
|
||||
else if (room.tiles[i].score==highest)
|
||||
{
|
||||
listOfHighest.push(room.tiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (listOfHighest.length==0) return -1;
|
||||
return choose(listOfHighest);
|
||||
}
|
||||
this.Map.prototype.getEarliestRoom=function()
|
||||
{
|
||||
return this.rooms[0];
|
||||
}
|
||||
this.Map.prototype.getDeepestRoom=function()
|
||||
{
|
||||
var deepest=0;
|
||||
var deepestRoom=this.rooms[0];
|
||||
for (var i in this.rooms)
|
||||
{
|
||||
if ((this.rooms[i].gen+Math.sqrt(this.rooms[i].freeTiles)*0.05)>=deepest && this.rooms[i].corridor==0 && this.rooms[i].freeTiles>4) {deepest=(this.rooms[i].gen+Math.sqrt(this.rooms[i].freeTiles)*0.05);deepestRoom=this.rooms[i];}
|
||||
}
|
||||
return deepestRoom;
|
||||
}
|
||||
|
||||
this.Map.prototype.dig=function()
|
||||
{
|
||||
//one step in which we try to carve new stuff
|
||||
//returns 0 when we couldn't dig this step, 1 when we could, and 2 when the digging is complete
|
||||
Math.random=this.seedState;
|
||||
|
||||
var badDig=0;
|
||||
|
||||
if (this.digs==0)//first dig : build a starting room in the middle of the map
|
||||
{
|
||||
var w=rand(3,7);
|
||||
var h=rand(3,7);
|
||||
var room=this.newRoom(Math.floor(this.w/2-w/2),Math.floor(this.h/2-h/2),w,h);
|
||||
room.corridor=0;
|
||||
this.planRoom(room);
|
||||
this.carve(room);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.newRandomRoom()==0) badDig++;
|
||||
}
|
||||
if (badDig>0) this.stuck++;
|
||||
|
||||
this.digs++;
|
||||
|
||||
var finished=0;
|
||||
if (this.tilesDug>=this.tiles*this.fillRatio) finished=1;
|
||||
if (this.stuck>100) finished=1;
|
||||
|
||||
if (finished==1)//last touch : try to add a whole room at the end
|
||||
{
|
||||
for (var i=0;i<10;i++)
|
||||
{
|
||||
var newRoom=this.newRandomRoom({corridor:0,w:rand(3,7),h:rand(3,7)});
|
||||
if (newRoom!=0 && newRoom.freeTiles>15) break;
|
||||
}
|
||||
}
|
||||
|
||||
Math.seedrandom();
|
||||
if (finished==1) return 1; else if (badDig>0) return -1; else return 0;
|
||||
}
|
||||
|
||||
this.Map.prototype.finish=function()
|
||||
{
|
||||
//touch up the map : add pillars in corners etc
|
||||
/*
|
||||
//set paths
|
||||
for (var i in this.rooms)
|
||||
{
|
||||
var me=this.rooms[i];
|
||||
if (me.door!=0)
|
||||
{
|
||||
var doors=[];
|
||||
doors.push(me.door);
|
||||
for (var ii in me.children)
|
||||
{
|
||||
if (me.children[ii].door!=0) doors.push(me.children[ii].door);
|
||||
}
|
||||
for (var ii in doors)
|
||||
{
|
||||
this.data[doors[ii][0]][doors[ii][1]][0]=TILE_LIMIT;
|
||||
//ideally we should run agents that step from each door to the next
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (var i in this.rooms)
|
||||
{
|
||||
var pillars=Math.random()<this.pillarRatio;
|
||||
for (var ii in this.rooms[i].tiles)
|
||||
{
|
||||
var x=this.rooms[i].tiles[ii].x;
|
||||
var y=this.rooms[i].tiles[ii].y;
|
||||
var me=this.data[x][y][0];
|
||||
var x1=this.data[x-1][y][0];
|
||||
var x2=this.data[x+1][y][0];
|
||||
var y1=this.data[x][y-1][0];
|
||||
var y2=this.data[x][y+1][0];
|
||||
var xy1=this.data[x-1][y-1][0];
|
||||
var xy2=this.data[x+1][y-1][0];
|
||||
var xy3=this.data[x-1][y+1][0];
|
||||
var xy4=this.data[x+1][y+1][0];
|
||||
|
||||
var walls=0;
|
||||
if ((x1==TILE_WALL||x1==TILE_WALL_CORNER)) walls++;
|
||||
if ((y1==TILE_WALL||y1==TILE_WALL_CORNER)) walls++;
|
||||
if ((x2==TILE_WALL||x2==TILE_WALL_CORNER)) walls++;
|
||||
if ((y2==TILE_WALL||y2==TILE_WALL_CORNER)) walls++;
|
||||
if ((xy1==TILE_WALL||xy1==TILE_WALL_CORNER)) walls++;
|
||||
if ((xy2==TILE_WALL||xy2==TILE_WALL_CORNER)) walls++;
|
||||
if ((xy3==TILE_WALL||xy3==TILE_WALL_CORNER)) walls++;
|
||||
if ((xy4==TILE_WALL||xy4==TILE_WALL_CORNER)) walls++;
|
||||
|
||||
var floors=0;
|
||||
if ((x1==TILE_FLOOR_CENTER||x1==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((y1==TILE_FLOOR_CENTER||y1==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((x2==TILE_FLOOR_CENTER||x2==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((y2==TILE_FLOOR_CENTER||y2==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((xy1==TILE_FLOOR_CENTER||xy1==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((xy2==TILE_FLOOR_CENTER||xy2==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((xy3==TILE_FLOOR_CENTER||xy3==TILE_FLOOR_EDGE)) floors++;
|
||||
if ((xy4==TILE_FLOOR_CENTER||xy4==TILE_FLOOR_EDGE)) floors++;
|
||||
|
||||
var complete=0;
|
||||
if (walls+floors==8) complete=1;
|
||||
|
||||
var angle=0;
|
||||
if (complete)
|
||||
{
|
||||
var top=0;
|
||||
var left=0;
|
||||
var right=0;
|
||||
var bottom=0;
|
||||
if ((xy1==TILE_WALL||xy1==TILE_WALL_CORNER) && (y1==TILE_WALL||y1==TILE_WALL_CORNER) && (xy2==TILE_WALL||xy2==TILE_WALL_CORNER)) top=1;
|
||||
else if ((xy1==TILE_FLOOR_CENTER||xy1==TILE_FLOOR_EDGE) && (y1==TILE_FLOOR_CENTER||y1==TILE_FLOOR_EDGE) && (xy2==TILE_FLOOR_CENTER||xy2==TILE_FLOOR_EDGE)) top=-1;
|
||||
if ((xy2==TILE_WALL||xy2==TILE_WALL_CORNER) && (x2==TILE_WALL||x2==TILE_WALL_CORNER) && (xy4==TILE_WALL||xy4==TILE_WALL_CORNER)) right=1;
|
||||
else if ((xy2==TILE_FLOOR_CENTER||xy2==TILE_FLOOR_EDGE) && (x2==TILE_FLOOR_CENTER||x2==TILE_FLOOR_EDGE) && (xy4==TILE_FLOOR_CENTER||xy4==TILE_FLOOR_EDGE)) right=-1;
|
||||
if ((xy1==TILE_WALL||xy1==TILE_WALL_CORNER) && (x1==TILE_WALL||x1==TILE_WALL_CORNER) && (xy3==TILE_WALL||xy3==TILE_WALL_CORNER)) left=1;
|
||||
else if ((xy1==TILE_FLOOR_CENTER||xy1==TILE_FLOOR_EDGE) && (x1==TILE_FLOOR_CENTER||x1==TILE_FLOOR_EDGE) && (xy3==TILE_FLOOR_CENTER||xy3==TILE_FLOOR_EDGE)) left=-1;
|
||||
if ((xy3==TILE_WALL||xy3==TILE_WALL_CORNER) && (y2==TILE_WALL||y2==TILE_WALL_CORNER) && (xy4==TILE_WALL||xy4==TILE_WALL_CORNER)) bottom=1;
|
||||
else if ((xy3==TILE_FLOOR_CENTER||xy3==TILE_FLOOR_EDGE) && (y2==TILE_FLOOR_CENTER||y2==TILE_FLOOR_EDGE) && (xy4==TILE_FLOOR_CENTER||xy4==TILE_FLOOR_EDGE)) bottom=-1;
|
||||
if ((top==1 && bottom==-1) || (top==-1 && bottom==1) || (left==1 && right==-1) || (left==-1 && right==1)) angle=1;
|
||||
}
|
||||
|
||||
if (pillars && Math.random()<0.8 && this.rooms[i].freeTiles>4)
|
||||
{
|
||||
if ((angle==1 || (complete && walls==7)) && me==TILE_FLOOR_EDGE && x1!=TILE_DOOR && x2!=TILE_DOOR && y1!=TILE_DOOR && y2!=TILE_DOOR)
|
||||
{
|
||||
this.data[x][y][0]=TILE_PILLAR;
|
||||
me=TILE_PILLAR;
|
||||
this.removeFreeTile(x,y);
|
||||
this.rooms[i].freeTiles--;
|
||||
}
|
||||
}
|
||||
|
||||
//calculate score (for placing items and exits)
|
||||
if (top==1 || bottom==1 || left==1 || right==1)
|
||||
{
|
||||
this.rooms[i].tiles[ii].score+=2;
|
||||
}
|
||||
if (walls>5 || floors>5)
|
||||
{
|
||||
this.rooms[i].tiles[ii].score+=1;
|
||||
}
|
||||
if (walls==7 || floors==8)
|
||||
{
|
||||
this.rooms[i].tiles[ii].score+=5;
|
||||
}
|
||||
if ((me!=TILE_FLOOR_CENTER && me!=TILE_FLOOR_EDGE) || x1==TILE_DOOR || x2==TILE_DOOR || y1==TILE_DOOR || y2==TILE_DOOR) this.rooms[i].tiles[ii].score=-1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//carve entrance and exit
|
||||
var entrance=this.getBestSpotInRoom(this.getEarliestRoom());
|
||||
this.data[entrance.x][entrance.y][0]=TILE_ENTRANCE;
|
||||
this.entrance=[entrance.x,entrance.y];
|
||||
entrance.score=0;
|
||||
this.removeFreeTile(entrance.x,entrance.y);
|
||||
var exit=this.getBestSpotInRoom(this.getDeepestRoom());
|
||||
this.data[exit.x][exit.y][0]=TILE_EXIT;
|
||||
this.exit=[exit.x,exit.y];
|
||||
this.removeFreeTile(exit.x,exit.y);
|
||||
exit.score=0;
|
||||
|
||||
/*
|
||||
for (var i in this.doors)//remove door tiles (to add later; replace the tiles by entities that delete themselves when opened)
|
||||
{
|
||||
this.data[this.doors[i][0]][this.doors[i][1]][0]=TILE_FLOOR_EDGE;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
this.Map.prototype.isObstacle=function(x,y)
|
||||
{
|
||||
var free=[TILE_FLOOR_EDGE,TILE_FLOOR_CENTER,TILE_DOOR,TILE_ENTRANCE,TILE_EXIT];
|
||||
for (var i in free)
|
||||
{
|
||||
if (this.data[x][y][0]==free[i]) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
var joinTile=function(map,x,y,joinWith)
|
||||
{
|
||||
//for the tile at x,y, return 2 if it joins with its horizontal neighbors, 3 if it joins with its vertical neighbors, 1 if it joins with either both or neither.
|
||||
//joinWith contains the tile types that count as joinable, in addition to this tile. (don't add the tested tile to joinWith!)
|
||||
var p=1;
|
||||
var me=map.data[x][y][0];
|
||||
var x1=map.data[x-1][y][0];
|
||||
var x2=map.data[x+1][y][0];
|
||||
var y1=map.data[x][y-1][0];
|
||||
var y2=map.data[x][y+1][0];
|
||||
joinWith.push(me);
|
||||
var joinsX=0;
|
||||
for (var i in joinWith)
|
||||
{
|
||||
if (x1==joinWith[i]) joinsX++;
|
||||
if (x2==joinWith[i]) joinsX++;
|
||||
}
|
||||
var joinsY=0;
|
||||
for (var i in joinWith)
|
||||
{
|
||||
if (y1==joinWith[i]) joinsY++;
|
||||
if (y2==joinWith[i]) joinsY++;
|
||||
}
|
||||
if (joinsX==2 && joinsY==2) p=1;
|
||||
else if (joinsX==2) p=2;
|
||||
else if (joinsY==2) p=3;
|
||||
return p;
|
||||
}
|
||||
this.Map.prototype.getPic=function(x,y)
|
||||
{
|
||||
//return a position [x,y] in the tiles (as 0, 1, 2...) for the tile on the map at position x,y
|
||||
if (Tiles[this.data[x][y][2]])
|
||||
{
|
||||
if (Tiles[this.data[x][y][2]].joinType=='join')
|
||||
{
|
||||
var thisPic=Tiles[this.data[x][y][2]].pic;
|
||||
thisPic=[thisPic[0],thisPic[1]];//why is this even necessary?
|
||||
var joinWith=[];
|
||||
if (this.data[x][y][0]==TILE_WALL) joinWith.push(TILE_WALL_CORNER);
|
||||
else if (this.data[x][y][0]==TILE_DOOR) joinWith.push(TILE_WALL,TILE_WALL_CORNER);
|
||||
thisPic[0]+=joinTile(this,x,y,joinWith)-1;
|
||||
return thisPic;
|
||||
}
|
||||
else if (Tiles[this.data[x][y][2]].joinType=='random3')
|
||||
{
|
||||
var thisPic=Tiles[this.data[x][y][2]].pic;
|
||||
thisPic=[thisPic[0],thisPic[1]];
|
||||
thisPic[0]+=Math.floor(Math.random()*3);
|
||||
return thisPic;
|
||||
}
|
||||
return Tiles[this.data[x][y][2]].pic;
|
||||
}
|
||||
return [0,0];
|
||||
}
|
||||
|
||||
var Tiles=[];
|
||||
var TilesByName=[];
|
||||
this.Tile=function(name,pic,joinType)
|
||||
{
|
||||
this.name=name;
|
||||
this.pic=pic;
|
||||
this.joinType=joinType||'none';
|
||||
this.id=Tiles.length;
|
||||
Tiles[this.id]=this;
|
||||
TilesByName[this.name]=this;
|
||||
}
|
||||
new this.Tile('void',[0,0]);
|
||||
this.loadTiles=function(tiles)
|
||||
{
|
||||
for (var i in tiles)
|
||||
{
|
||||
var name=tiles[i][0];
|
||||
var pic=tiles[i][1];
|
||||
var joinType=tiles[i][2];
|
||||
new this.Tile(name,pic,joinType);
|
||||
}
|
||||
}
|
||||
|
||||
var computeTile=function(tile,tiles,value,name)
|
||||
{
|
||||
if (tile==value && tiles[name]) return TilesByName[tiles[name]];
|
||||
return 0;
|
||||
}
|
||||
this.Map.prototype.assignTiles=function(room,tiles)
|
||||
{
|
||||
//set the displayed tiles for this room
|
||||
for (var i in room.tiles)
|
||||
{
|
||||
var type=Tiles[0];
|
||||
var me=room.tiles[i];
|
||||
var tile=this.data[me.x][me.y][0];
|
||||
type=computeTile(tile,tiles,TILE_WALL_CORNER,'wall corner')||type;
|
||||
type=computeTile(tile,tiles,TILE_WALL,'wall')||type;
|
||||
type=computeTile(tile,tiles,TILE_FLOOR_EDGE,'floor edges')||type;
|
||||
type=computeTile(tile,tiles,TILE_FLOOR_CENTER,'floor')||type;
|
||||
type=computeTile(tile,tiles,TILE_PILLAR,'pillar')||type;
|
||||
type=computeTile(tile,tiles,TILE_DOOR,'door')||type;
|
||||
type=computeTile(tile,tiles,TILE_WATER,'water')||type;
|
||||
type=computeTile(tile,tiles,TILE_ENTRANCE,'entrance')||type;
|
||||
type=computeTile(tile,tiles,TILE_EXIT,'exit')||type;
|
||||
|
||||
this.data[me.x][me.y][2]=type.id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.Map.prototype.draw=function(size)
|
||||
{
|
||||
//return a string containing a rough visual representation of the map
|
||||
var str='';
|
||||
var size=size||10;
|
||||
for (var y=0;y<this.h;y++){for (var x=0;x<this.w;x++){
|
||||
var text='';
|
||||
if (this.isFloor(x,y)!=-1) text='o';
|
||||
if (this.isWall(x,y)!=-1) text+='x';
|
||||
var room=this.getRoom(x,y);
|
||||
var opacity=Math.max(0.1,1-(this.getRoom(x,y).gen/10));
|
||||
var title=room.freeTiles;//this.data[x][y][0].toString();
|
||||
text='';
|
||||
str+='<div style="opacity:'+opacity+';width:'+size+'px;height:'+size+'px;position:absolute;left:'+(x*size)+'px;top:'+(y*size)+'px;display:block;padding:0px;margin:0px;background:#'+colors[this.data[x][y][0]]+';color:#999;" title="'+title+'">'+text+'</div>';
|
||||
}
|
||||
str+='<br>';
|
||||
}
|
||||
str='<div style="position:relative;width:'+(this.w*size)+'px;height:'+(this.h*size)+'px;background:#000;font-family:Courier;font-size:'+size+'px;float:left;margin:10px;">'+str+'</div>';
|
||||
return str;
|
||||
}
|
||||
|
||||
this.Map.prototype.drawDetailed=function()
|
||||
{
|
||||
//return a string containing a rough visual representation of the map (with graphics)
|
||||
var str='';
|
||||
var size=16;
|
||||
for (var y=0;y<this.h;y++){for (var x=0;x<this.w;x++){
|
||||
var room=this.getRoom(x,y);
|
||||
//var opacity=Math.max(0.1,room.tiles[this.getRoomTile(room,x,y)].score);
|
||||
var opacity=1;
|
||||
var title='void';
|
||||
if (room!=-1)
|
||||
{
|
||||
opacity=Math.max(0.1,1-room.gen/5);
|
||||
if (this.data[x][y][0]==TILE_ENTRANCE || this.data[x][y][0]==TILE_EXIT) opacity=1;
|
||||
title=(room.corridor?'corridor':'room')+' '+room.id+' | depth : '+room.gen+' | children : '+room.children.length;
|
||||
}
|
||||
var pic=this.getPic(x,y);
|
||||
str+='<div style="opacity:'+opacity+';width:'+size+'px;height:'+size+'px;position:absolute;left:'+(x*size)+'px;top:'+(y*size)+'px;display:block;padding:0px;margin:0px;background:#'+colors[this.data[x][y][0]]+' url(img/dungeonTiles.png) '+(-pic[0]*16)+'px '+(-pic[1]*16)+'px;color:#999;" title="'+title+'"></div>';
|
||||
}
|
||||
str+='<br>';
|
||||
}
|
||||
str='<div style="box-shadow:0px 0px 12px 6px #00061b;position:relative;width:'+(this.w*size)+'px;height:'+(this.h*size)+'px;background:#00061b;font-family:Courier;font-size:'+size+'px;float:left;margin:10px;">'+str+'</div>';
|
||||
return str;
|
||||
}
|
||||
|
||||
this.Map.prototype.getStr=function()
|
||||
{
|
||||
//return a string containing the map with tile graphics, ready to be pasted in a wrapper
|
||||
var str='';
|
||||
var size=16;
|
||||
for (var y=0;y<this.h;y++){for (var x=0;x<this.w;x++){
|
||||
var room=this.getRoom(x,y);
|
||||
//var opacity=Math.max(0.1,room.tiles[this.getRoomTile(room,x,y)].score);
|
||||
var opacity=1;
|
||||
var title='void';
|
||||
var pic=this.getPic(x,y);
|
||||
if (room!=-1)
|
||||
{
|
||||
/*
|
||||
opacity=Math.max(0.1,1-room.gen/5);
|
||||
if (room.hidden) opacity=0;
|
||||
if (this.data[x][y][0]==TILE_ENTRANCE || this.data[x][y][0]==TILE_EXIT) opacity=1;
|
||||
*/
|
||||
if (room.hidden) pic=[0,0];
|
||||
title=(room.corridor?'corridor':'room')+' '+room.id+' | depth : '+room.gen+' | children : '+room.children.length;
|
||||
}
|
||||
str+='<div style="opacity:'+opacity+';width:'+size+'px;height:'+size+'px;position:absolute;left:'+(x*size)+'px;top:'+(y*size)+'px;display:block;padding:0px;margin:0px;background:#'+colors[this.data[x][y][0]]+' url(img/dungeonTiles.png) '+(-pic[0]*16)+'px '+(-pic[1]*16)+'px;color:#999;" title="'+title+'"></div>';
|
||||
}
|
||||
str+='<br>';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
# cookieclicker
|
||||
|
||||
<img src="img/perfectCookie.png" width="128">
|
||||
|
||||
The original game can be found at http://orteil.dashnet.org/cookieclicker/
|
||||
|
||||
This mirror for, errrr, like, educational purpose, either to download for your own offline education or to be played online from http://ozh.github.io/cookieclicker/ if you cannot "educate" yourself on the original URL
|
||||
|
||||
### How to update
|
||||
|
||||
If the original game updates, here is how you can update the mirror:
|
||||
|
||||
#### 1. Fetch all new images :
|
||||
|
||||
From the root,
|
||||
|
||||
* `cd img/`
|
||||
* `wget --convert-links -O index.html http://orteil.dashnet.org/cookieclicker/img/`
|
||||
* `grep -v PARENTDIR index.html | grep '\[IMG' | grep -Po 'a href="\K.*?(?=")' | sed 's/\?.*//' > _imglist.txt`
|
||||
* `wget -N -i _imglist.txt -B http://orteil.dashnet.org/cookieclicker/img/`
|
||||
|
||||
#### 2. Fetch all new sounds :
|
||||
|
||||
Similarly, from the root :
|
||||
|
||||
* `cd snd/`
|
||||
* `wget --convert-links -O index.html http://orteil.dashnet.org/cookieclicker/snd/`
|
||||
* `grep -v PARENTDIR index.html | grep '\[SND' | grep -Po 'a href="\K.*?(?=")' | sed 's/\?.*//' > _sndlist.txt`
|
||||
* `wget -N -i _sndlist.txt -B http://orteil.dashnet.org/cookieclicker/snd/`
|
||||
|
||||
#### 3. Fetch all new translations :
|
||||
|
||||
Similarly, from the root :
|
||||
|
||||
* `cd loc/`
|
||||
* `wget --convert-links -O index.html http://orteil.dashnet.org/cookieclicker/loc/`
|
||||
* `grep -v PARENTDIR index.html | grep '\[ ' | grep -Po 'a href="\K.*?(?=")' | sed 's/\?.*//' > _loclist.txt`
|
||||
* `wget -N -i _loclist.txt -B http://orteil.dashnet.org/cookieclicker/loc/`
|
||||
|
||||
#### 4. Update `js` and `html` files :
|
||||
|
||||
From the root directory :
|
||||
|
||||
* Fetch the updated `index.html` file: `wget -O index.html http://orteil.dashnet.org/cookieclicker/`
|
||||
* Fetch the updated `style.css` file: `wget -O style.css http://orteil.dashnet.org/cookieclicker/style.css`
|
||||
* Fetch updated `js` files : `wget -N -i _jslist.txt -B http://orteil.dashnet.org/cookieclicker/`
|
||||
* Scan `index.html` for any new `<script src` and also `main.js` for any new local javascript (eg `Game.last.minigameUrl`). If there are new scripts, update the `_jslist.txt` accordingly.
|
||||
* In `main.js` there is a call to a remote script we need to modify:
|
||||
* Look for `ajax('/patreon/grab.php'` and replace it with `ajax('grab.txt'`
|
||||
* In the root: `wget -O grab.txt http://orteil.dashnet.org/patreon/grab.php`
|
||||
|
||||
#### 5. Report update here :)
|
||||
|
||||
If you happen to update, please make a pull request for others to benefit, thanks!
|
|
@ -0,0 +1,11 @@
|
|||
ajax.js
|
||||
showads.js
|
||||
base64.js
|
||||
DungeonGen.js
|
||||
dungeons.js
|
||||
excanvas.compiled.js
|
||||
main.js
|
||||
minigameGarden.js
|
||||
minigameGrimoire.js
|
||||
minigamePantheon.js
|
||||
minigameMarket.js
|
|
@ -0,0 +1,6 @@
|
|||
function ajax(url,callback){
|
||||
var ajaxRequest;
|
||||
try{ajaxRequest = new XMLHttpRequest();} catch (e){try{ajaxRequest=new ActiveXObject('Msxml2.XMLHTTP');} catch (e) {try{ajaxRequest=new ActiveXObject('Microsoft.XMLHTTP');} catch (e){alert("Something broke!");return false;}}}
|
||||
if (callback){ajaxRequest.onreadystatechange=function(){if(ajaxRequest.readyState==4){callback(ajaxRequest.responseText);}}}
|
||||
ajaxRequest.open('GET',url+'&nocache='+(new Date().getTime()),true);ajaxRequest.send(null);
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
*
|
||||
* Base64 encode / decode
|
||||
* http://www.webtoolkit.info/
|
||||
*
|
||||
**/
|
||||
|
||||
var Base64 = {
|
||||
|
||||
// private property
|
||||
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
|
||||
// public method for encoding
|
||||
encode : function (input) {
|
||||
var output = "";
|
||||
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
||||
var i = 0;
|
||||
|
||||
input = Base64._utf8_encode(input);
|
||||
|
||||
while (i < input.length) {
|
||||
|
||||
chr1 = input.charCodeAt(i++);
|
||||
chr2 = input.charCodeAt(i++);
|
||||
chr3 = input.charCodeAt(i++);
|
||||
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc4 = 64;
|
||||
}
|
||||
|
||||
output = output +
|
||||
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
|
||||
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
// public method for decoding
|
||||
decode : function (input) {
|
||||
var output = "";
|
||||
var chr1, chr2, chr3;
|
||||
var enc1, enc2, enc3, enc4;
|
||||
var i = 0;
|
||||
|
||||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
||||
|
||||
while (i < input.length) {
|
||||
|
||||
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output = output + String.fromCharCode(chr1);
|
||||
|
||||
if (enc3 != 64) {
|
||||
output = output + String.fromCharCode(chr2);
|
||||
}
|
||||
if (enc4 != 64) {
|
||||
output = output + String.fromCharCode(chr3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
output = Base64._utf8_decode(output);
|
||||
|
||||
return output;
|
||||
|
||||
},
|
||||
|
||||
// private method for UTF-8 encoding
|
||||
_utf8_encode : function (string) {
|
||||
string = string.replace(/\r\n/g,"\n");
|
||||
var utftext = "";
|
||||
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
|
||||
var c = string.charCodeAt(n);
|
||||
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
}
|
||||
else if((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return utftext;
|
||||
},
|
||||
|
||||
// private method for UTF-8 decoding
|
||||
_utf8_decode : function (utftext) {
|
||||
var string = "";
|
||||
var i = 0;
|
||||
var c = c1 = c2 = 0;
|
||||
|
||||
while ( i < utftext.length ) {
|
||||
|
||||
c = utftext.charCodeAt(i);
|
||||
|
||||
if (c < 128) {
|
||||
string += String.fromCharCode(c);
|
||||
i++;
|
||||
}
|
||||
else if((c > 191) && (c < 224)) {
|
||||
c2 = utftext.charCodeAt(i+1);
|
||||
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
||||
i += 2;
|
||||
}
|
||||
else {
|
||||
c2 = utftext.charCodeAt(i+1);
|
||||
c3 = utftext.charCodeAt(i+2);
|
||||
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
||||
i += 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2006 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
document.createElement("canvas").getContext||(function(){var s=Math,j=s.round,F=s.sin,G=s.cos,V=s.abs,W=s.sqrt,k=10,v=k/2;function X(){return this.context_||(this.context_=new H(this))}var L=Array.prototype.slice;function Y(b,a){var c=L.call(arguments,2);return function(){return b.apply(a,c.concat(L.call(arguments)))}}var M={init:function(b){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var a=b||document;a.createElement("canvas");a.attachEvent("onreadystatechange",Y(this.init_,this,a))}},init_:function(b){b.namespaces.g_vml_||
|
||||
b.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML");b.namespaces.g_o_||b.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML");if(!b.styleSheets.ex_canvas_){var a=b.createStyleSheet();a.owningElement.id="ex_canvas_";a.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=b.getElementsByTagName("canvas"),d=0;for(;d<c.length;d++)this.initElement(c[d])},
|
||||
initElement:function(b){if(!b.getContext){b.getContext=X;b.innerHTML="";b.attachEvent("onpropertychange",Z);b.attachEvent("onresize",$);var a=b.attributes;if(a.width&&a.width.specified)b.style.width=a.width.nodeValue+"px";else b.width=b.clientWidth;if(a.height&&a.height.specified)b.style.height=a.height.nodeValue+"px";else b.height=b.clientHeight}return b}};function Z(b){var a=b.srcElement;switch(b.propertyName){case "width":a.style.width=a.attributes.width.nodeValue+"px";a.getContext().clearRect();
|
||||
break;case "height":a.style.height=a.attributes.height.nodeValue+"px";a.getContext().clearRect();break}}function $(b){var a=b.srcElement;if(a.firstChild){a.firstChild.style.width=a.clientWidth+"px";a.firstChild.style.height=a.clientHeight+"px"}}M.init();var N=[],B=0;for(;B<16;B++){var C=0;for(;C<16;C++)N[B*16+C]=B.toString(16)+C.toString(16)}function I(){return[[1,0,0],[0,1,0],[0,0,1]]}function y(b,a){var c=I(),d=0;for(;d<3;d++){var f=0;for(;f<3;f++){var h=0,g=0;for(;g<3;g++)h+=b[d][g]*a[g][f];c[d][f]=
|
||||
h}}return c}function O(b,a){a.fillStyle=b.fillStyle;a.lineCap=b.lineCap;a.lineJoin=b.lineJoin;a.lineWidth=b.lineWidth;a.miterLimit=b.miterLimit;a.shadowBlur=b.shadowBlur;a.shadowColor=b.shadowColor;a.shadowOffsetX=b.shadowOffsetX;a.shadowOffsetY=b.shadowOffsetY;a.strokeStyle=b.strokeStyle;a.globalAlpha=b.globalAlpha;a.arcScaleX_=b.arcScaleX_;a.arcScaleY_=b.arcScaleY_;a.lineScale_=b.lineScale_}function P(b){var a,c=1;b=String(b);if(b.substring(0,3)=="rgb"){var d=b.indexOf("(",3),f=b.indexOf(")",d+
|
||||
1),h=b.substring(d+1,f).split(",");a="#";var g=0;for(;g<3;g++)a+=N[Number(h[g])];if(h.length==4&&b.substr(3,1)=="a")c=h[3]}else a=b;return{color:a,alpha:c}}function aa(b){switch(b){case "butt":return"flat";case "round":return"round";case "square":default:return"square"}}function H(b){this.m_=I();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.fillStyle=this.strokeStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=k*1;this.globalAlpha=1;this.canvas=b;
|
||||
var a=b.ownerDocument.createElement("div");a.style.width=b.clientWidth+"px";a.style.height=b.clientHeight+"px";a.style.overflow="hidden";a.style.position="absolute";b.appendChild(a);this.element_=a;this.lineScale_=this.arcScaleY_=this.arcScaleX_=1}var i=H.prototype;i.clearRect=function(){this.element_.innerHTML=""};i.beginPath=function(){this.currentPath_=[]};i.moveTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"moveTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};
|
||||
i.lineTo=function(b,a){var c=this.getCoords_(b,a);this.currentPath_.push({type:"lineTo",x:c.x,y:c.y});this.currentX_=c.x;this.currentY_=c.y};i.bezierCurveTo=function(b,a,c,d,f,h){var g=this.getCoords_(f,h),l=this.getCoords_(b,a),e=this.getCoords_(c,d);Q(this,l,e,g)};function Q(b,a,c,d){b.currentPath_.push({type:"bezierCurveTo",cp1x:a.x,cp1y:a.y,cp2x:c.x,cp2y:c.y,x:d.x,y:d.y});b.currentX_=d.x;b.currentY_=d.y}i.quadraticCurveTo=function(b,a,c,d){var f=this.getCoords_(b,a),h=this.getCoords_(c,d),g={x:this.currentX_+
|
||||
0.6666666666666666*(f.x-this.currentX_),y:this.currentY_+0.6666666666666666*(f.y-this.currentY_)};Q(this,g,{x:g.x+(h.x-this.currentX_)/3,y:g.y+(h.y-this.currentY_)/3},h)};i.arc=function(b,a,c,d,f,h){c*=k;var g=h?"at":"wa",l=b+G(d)*c-v,e=a+F(d)*c-v,m=b+G(f)*c-v,r=a+F(f)*c-v;if(l==m&&!h)l+=0.125;var n=this.getCoords_(b,a),o=this.getCoords_(l,e),q=this.getCoords_(m,r);this.currentPath_.push({type:g,x:n.x,y:n.y,radius:c,xStart:o.x,yStart:o.y,xEnd:q.x,yEnd:q.y})};i.rect=function(b,a,c,d){this.moveTo(b,
|
||||
a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath()};i.strokeRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.stroke();this.currentPath_=f};i.fillRect=function(b,a,c,d){var f=this.currentPath_;this.beginPath();this.moveTo(b,a);this.lineTo(b+c,a);this.lineTo(b+c,a+d);this.lineTo(b,a+d);this.closePath();this.fill();this.currentPath_=f};i.createLinearGradient=function(b,
|
||||
a,c,d){var f=new D("gradient");f.x0_=b;f.y0_=a;f.x1_=c;f.y1_=d;return f};i.createRadialGradient=function(b,a,c,d,f,h){var g=new D("gradientradial");g.x0_=b;g.y0_=a;g.r0_=c;g.x1_=d;g.y1_=f;g.r1_=h;return g};i.drawImage=function(b){var a,c,d,f,h,g,l,e,m=b.runtimeStyle.width,r=b.runtimeStyle.height;b.runtimeStyle.width="auto";b.runtimeStyle.height="auto";var n=b.width,o=b.height;b.runtimeStyle.width=m;b.runtimeStyle.height=r;if(arguments.length==3){a=arguments[1];c=arguments[2];h=g=0;l=d=n;e=f=o}else if(arguments.length==
|
||||
5){a=arguments[1];c=arguments[2];d=arguments[3];f=arguments[4];h=g=0;l=n;e=o}else if(arguments.length==9){h=arguments[1];g=arguments[2];l=arguments[3];e=arguments[4];a=arguments[5];c=arguments[6];d=arguments[7];f=arguments[8]}else throw Error("Invalid number of arguments");var q=this.getCoords_(a,c),t=[];t.push(" <g_vml_:group",' coordsize="',k*10,",",k*10,'"',' coordorigin="0,0"',' style="width:',10,"px;height:",10,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var E=[];E.push("M11=",
|
||||
this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",j(q.x/k),",","Dy=",j(q.y/k),"");var p=q,z=this.getCoords_(a+d,c),w=this.getCoords_(a,c+f),x=this.getCoords_(a+d,c+f);p.x=s.max(p.x,z.x,w.x,x.x);p.y=s.max(p.y,z.y,w.y,x.y);t.push("padding:0 ",j(p.x/k),"px ",j(p.y/k),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",E.join(""),", sizingmethod='clip');")}else t.push("top:",j(q.y/k),"px;left:",j(q.x/k),"px;");t.push(' ">','<g_vml_:image src="',b.src,
|
||||
'"',' style="width:',k*d,"px;"," height:",k*f,'px;"',' cropleft="',h/n,'"',' croptop="',g/o,'"',' cropright="',(n-h-l)/n,'"',' cropbottom="',(o-g-e)/o,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};i.stroke=function(b){var a=[],c=P(b?this.fillStyle:this.strokeStyle),d=c.color,f=c.alpha*this.globalAlpha;a.push("<g_vml_:shape",' filled="',!!b,'"',' style="position:absolute;width:',10,"px;height:",10,'px;"',' coordorigin="0 0" coordsize="',k*10," ",k*10,'"',' stroked="',
|
||||
!b,'"',' path="');var h={x:null,y:null},g={x:null,y:null},l=0;for(;l<this.currentPath_.length;l++){var e=this.currentPath_[l];switch(e.type){case "moveTo":a.push(" m ",j(e.x),",",j(e.y));break;case "lineTo":a.push(" l ",j(e.x),",",j(e.y));break;case "close":a.push(" x ");e=null;break;case "bezierCurveTo":a.push(" c ",j(e.cp1x),",",j(e.cp1y),",",j(e.cp2x),",",j(e.cp2y),",",j(e.x),",",j(e.y));break;case "at":case "wa":a.push(" ",e.type," ",j(e.x-this.arcScaleX_*e.radius),",",j(e.y-this.arcScaleY_*e.radius),
|
||||
" ",j(e.x+this.arcScaleX_*e.radius),",",j(e.y+this.arcScaleY_*e.radius)," ",j(e.xStart),",",j(e.yStart)," ",j(e.xEnd),",",j(e.yEnd));break}if(e){if(h.x==null||e.x<h.x)h.x=e.x;if(g.x==null||e.x>g.x)g.x=e.x;if(h.y==null||e.y<h.y)h.y=e.y;if(g.y==null||e.y>g.y)g.y=e.y}}a.push(' ">');if(b)if(typeof this.fillStyle=="object"){var m=this.fillStyle,r=0,n={x:0,y:0},o=0,q=1;if(m.type_=="gradient"){var t=m.x1_/this.arcScaleX_,E=m.y1_/this.arcScaleY_,p=this.getCoords_(m.x0_/this.arcScaleX_,m.y0_/this.arcScaleY_),
|
||||
z=this.getCoords_(t,E);r=Math.atan2(z.x-p.x,z.y-p.y)*180/Math.PI;if(r<0)r+=360;if(r<1.0E-6)r=0}else{var p=this.getCoords_(m.x0_,m.y0_),w=g.x-h.x,x=g.y-h.y;n={x:(p.x-h.x)/w,y:(p.y-h.y)/x};w/=this.arcScaleX_*k;x/=this.arcScaleY_*k;var R=s.max(w,x);o=2*m.r0_/R;q=2*m.r1_/R-o}var u=m.colors_;u.sort(function(ba,ca){return ba.offset-ca.offset});var J=u.length,da=u[0].color,ea=u[J-1].color,fa=u[0].alpha*this.globalAlpha,ga=u[J-1].alpha*this.globalAlpha,S=[],l=0;for(;l<J;l++){var T=u[l];S.push(T.offset*q+
|
||||
o+" "+T.color)}a.push('<g_vml_:fill type="',m.type_,'"',' method="none" focus="100%"',' color="',da,'"',' color2="',ea,'"',' colors="',S.join(","),'"',' opacity="',ga,'"',' g_o_:opacity2="',fa,'"',' angle="',r,'"',' focusposition="',n.x,",",n.y,'" />')}else a.push('<g_vml_:fill color="',d,'" opacity="',f,'" />');else{var K=this.lineScale_*this.lineWidth;if(K<1)f*=K;a.push("<g_vml_:stroke",' opacity="',f,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',aa(this.lineCap),
|
||||
'"',' weight="',K,'px"',' color="',d,'" />')}a.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",a.join(""))};i.fill=function(){this.stroke(true)};i.closePath=function(){this.currentPath_.push({type:"close"})};i.getCoords_=function(b,a){var c=this.m_;return{x:k*(b*c[0][0]+a*c[1][0]+c[2][0])-v,y:k*(b*c[0][1]+a*c[1][1]+c[2][1])-v}};i.save=function(){var b={};O(this,b);this.aStack_.push(b);this.mStack_.push(this.m_);this.m_=y(I(),this.m_)};i.restore=function(){O(this.aStack_.pop(),
|
||||
this);this.m_=this.mStack_.pop()};function ha(b){var a=0;for(;a<3;a++){var c=0;for(;c<2;c++)if(!isFinite(b[a][c])||isNaN(b[a][c]))return false}return true}function A(b,a,c){if(!!ha(a)){b.m_=a;if(c)b.lineScale_=W(V(a[0][0]*a[1][1]-a[0][1]*a[1][0]))}}i.translate=function(b,a){A(this,y([[1,0,0],[0,1,0],[b,a,1]],this.m_),false)};i.rotate=function(b){var a=G(b),c=F(b);A(this,y([[a,c,0],[-c,a,0],[0,0,1]],this.m_),false)};i.scale=function(b,a){this.arcScaleX_*=b;this.arcScaleY_*=a;A(this,y([[b,0,0],[0,a,
|
||||
0],[0,0,1]],this.m_),true)};i.transform=function(b,a,c,d,f,h){A(this,y([[b,a,0],[c,d,0],[f,h,1]],this.m_),true)};i.setTransform=function(b,a,c,d,f,h){A(this,[[b,a,0],[c,d,0],[f,h,1]],true)};i.clip=function(){};i.arcTo=function(){};i.createPattern=function(){return new U};function D(b){this.type_=b;this.r1_=this.y1_=this.x1_=this.r0_=this.y0_=this.x0_=0;this.colors_=[]}D.prototype.addColorStop=function(b,a){a=P(a);this.colors_.push({offset:b,color:a.color,alpha:a.alpha})};function U(){}G_vmlCanvasManager=
|
||||
M;CanvasRenderingContext2D=H;CanvasGradient=D;CanvasPattern=U})();
|
|
@ -0,0 +1 @@
|
|||
{"herald":41,"grandma":"Patreona|Janice|Gabrielle|Grandma McGrandmaface|Charlie|\"egg\" Sr.|Jet-dayo|Natsuki|Ivy|Rose|Babayaga|Grandma #42|SneakySquid|Swad Plan|Meep Moop|Psychedelic Rapper Andrew JD|Telos|Moondoge|Lily Bowen|Mrs PoopyButthole|Mrs Sugai Kirin|Survivor of the Stale|Betty Ann Niemi|Tjien Nio|The First Baker|Mamichette|dQw4w9WgXcQ|Carmelina Calabrese|The GrandNut|La mere Michel|Aune Mummo|Jeff Junior|Her?|Rydh|Euphegenia Doubtfire|Bear|How did you find me, JUNESUK?|Ahtelo|Steve...?|Fanny|DAF Pvnk - Mother of trucks|Koisuru Fortune Grandma|Lieselotte|Izual Rebirth|Cosma-Tanti|Starco|Knitting Slave|Forgotten Abbey|Granny Rags|Mrs. Fizzwidget|Nakamoto|Zan Tart-izanne|The Roach Queen|Khookiesi, Grandmother of Dragonflights|Hey guys, Dexterfan99 here|Aryll|Ms. Chievous|Don't Stop Me Now|Dauna|Gerry|Erina Pendleton-Joestar|Stacy's Grandma|Benyboy|Rosie Beestinger|Tesco employee #65|Oda|Grandma Jones|Dan|Krieg|Chris|Kamilla|Tandy|Elisabeth|MinionMemer|Eanydo Erdman|Cookieatron4000|TechhX|Turtlenator|Carmelina|Shiny Blue Grandma|Anne|Penka|\"Hey guys, it's Nicole\"|Cora|Freya28|Kiwibajs|EEEEEE|Ms. Denis Gur Arie|Idling Vasha|?????|Tammie|Grandma Kara|Sanda Reiss|Alex|Mirle|Audrey|Ittle Dew|You're Killing Me Smols|Baker? I hardly know her!|A Duplicate Grandma|Betty Margaret Davis|Chlorophyte Grandma|Felpinhazinha|Satan's grandmother|Ruby Rose|Miyori Grandma|Geuser|Anneliese|Pielak|Swamper|Pikachi|Grackitz|Deborah Wright|BUT IT WAS ME, DIO!|Barbara|SERAS FAMO!!!|Audrey Porter|Benny Zhy|Doctergreen|Kage|Jarvis Fishwick|Elder Pledge 666x in a row...|Tell Cersei, it was me.|Kimahri|Henrietta Gertrude|Tyler Liddick|noisypineapples|Linda-Bea Dolvoy|DevilishWarrior|Exterminator|Matthue Loose|Caden|moist butterscotch lips|Alireah|Fey Yoshida|Aviators|Ashlee <3|He Had Boxing Gloves On|Falling Collin|Error 404: Name not Found|Groz|Granny Jonathan|Hanna Highmark|Nonmoving Osmond|The Worm Which Waits|Lurking Tealeaf|Ruby Wrinkle|Her|\"Eggy Grandma\"|Cookie maker 100|Addison Bennett|Nasus|Only 30 characters, huh? Fine.|Matt Was Here|ScartTheWaz|Tanyac Crimson|Ume Ito|VenMissa|Velma Francis|amdnarG|Leota Marie|Nikola|Grandmommy Celestine|Annuziatta|hosh...|E|Joe Grandmomma|Granny Grearest|Vivian|Vovó Dal|Baker of Steak Cookies|Aku daikan|SkeletonJoke|David loves Rachel! <3|Polar|Loremaster Rawlins|lickin my cookie|Fmaily Gyu funy momens #420|Ms. Cppkies|WillStreet|Ian's Mom|Grandma Divah|Betty BeardPuller|Mamie Cobol|200rassberris|ipm1234|Galadion|Olive Gardenia|Megan I. McIntosh|Lady Sweets|Rivne|Autosuffisant|BoShek|Brooke Chumbers|Cthulhu|ɐɯpuɐɹפ|binbinuser|Amma Jóna|the book was empty|Berit|DRIFTER1117|Yackemflam|Help me|YeOl'GrammityGram|Mason W|Peggy Hattenfels|majik|latte|amogus|Samuel Robertson|Anneliese Albina Emma|Barack Obama|Gramma Margaret"}
|
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,292 @@
|
|||
BGgarden.jpg
|
||||
BGgrimoire.jpg
|
||||
BGmarket.jpg
|
||||
BGpantheon.jpg
|
||||
alchemylab.png
|
||||
alchemylabBackground.png
|
||||
alteredGrandma.png
|
||||
alternateGrandma.png
|
||||
antiGrandma.png
|
||||
antimattercondenser.png
|
||||
antimattercondenserBackground.png
|
||||
aqworldsbanner.jpg
|
||||
ascendBox.png
|
||||
ascendInfo.png
|
||||
ascendSlot.png
|
||||
ascendWisp.png
|
||||
ascendedBakingPod.png
|
||||
bank.png
|
||||
bankBackground.png
|
||||
bankGrandma.png
|
||||
bgBW.jpg
|
||||
bgBlack.jpg
|
||||
bgBlue.jpg
|
||||
bgCandy.jpg
|
||||
bgChoco.jpg
|
||||
bgChocoDark.jpg
|
||||
bgCoarse.jpg
|
||||
bgFoil.jpg
|
||||
bgGold.jpg
|
||||
bgMint.jpg
|
||||
bgMoney.jpg
|
||||
bgMoneyChart.jpg
|
||||
bgPaint.jpg
|
||||
bgPink.jpg
|
||||
bgPurple.jpg
|
||||
bgRed.jpg
|
||||
bgSilver.jpg
|
||||
bgSky.jpg
|
||||
bgSnowy.jpg
|
||||
bgSpectrum.jpg
|
||||
bgStars.jpg
|
||||
bgWhite.jpg
|
||||
bgYellowBlue.jpg
|
||||
blackGradient.png
|
||||
blackGradientLeft.png
|
||||
blackGradientSmallTop.png
|
||||
bracketPanelLeftS.png
|
||||
bracketPanelRightS.png
|
||||
brainyGrandma.png
|
||||
brokenCookie.png
|
||||
brokenCookieHalo.png
|
||||
brownStripes.png
|
||||
brownStripesLeftEdge.png
|
||||
buildings.png
|
||||
bunnies.png
|
||||
bunnyGrandma.png
|
||||
buttonTile.jpg
|
||||
caramelWave.png
|
||||
chancemaker.png
|
||||
chancemakerBackground.png
|
||||
chocolateMilkWave.png
|
||||
clayBG.jpg
|
||||
contract.png
|
||||
control.png
|
||||
cookieShadow.png
|
||||
cookieShower1.png
|
||||
cookieShower2.png
|
||||
cookieShower3.png
|
||||
cortex.png
|
||||
cortexBackground.png
|
||||
cosmicGrandma.png
|
||||
cursor.png
|
||||
darkNoise.jpg
|
||||
darkNoise.png
|
||||
darkNoiseTopBar.jpg
|
||||
dashnetLogo.png
|
||||
discord.png
|
||||
dragon.png
|
||||
dragonBG.png
|
||||
dragonFrame.png
|
||||
dungeonDot.png
|
||||
dungeonFactory.png
|
||||
dungeonFoes.png
|
||||
dungeonHeroes.png
|
||||
dungeonIcons.png
|
||||
dungeonItems.png
|
||||
dungeonMapFactory.jpg
|
||||
dungeonOverlay.png
|
||||
dungeonPictos.png
|
||||
dungeonTiles.png
|
||||
easterEggs.png
|
||||
elfGrandma.png
|
||||
empty.png
|
||||
emptyFrame.png
|
||||
factory.png
|
||||
factoryBackground.png
|
||||
farm.png
|
||||
farmBackground.png
|
||||
farmerGrandma.png
|
||||
favicon.ico
|
||||
featherLeft.png
|
||||
featherRight.png
|
||||
filler.png
|
||||
fractalEngine.png
|
||||
fractalEngineBackground.png
|
||||
frameBorder.png
|
||||
frostedReindeer.png
|
||||
gardenPlants.png
|
||||
gardenPlots.png
|
||||
gardenTip.png
|
||||
girlscoutChip.png
|
||||
girlscoutCrumb.png
|
||||
girlscoutDoe.png
|
||||
girlscoutLucky.png
|
||||
glint.jpg
|
||||
goldCookie.png
|
||||
grandma.png
|
||||
grandmaBackground.png
|
||||
grandmas1.jpg
|
||||
grandmas2.jpg
|
||||
grandmas3.jpg
|
||||
grandmasGrandma.png
|
||||
grimoireBG.png
|
||||
heartStorm.png
|
||||
hearts.png
|
||||
heavenRing1.jpg
|
||||
heavenRing2.jpg
|
||||
heavenlyMoney.png
|
||||
heraldFlag.png
|
||||
icon.ico
|
||||
icon.png
|
||||
icons.png
|
||||
idleverse.png
|
||||
idleverseBackground.png
|
||||
imperfectCookie.png
|
||||
infoBG.png
|
||||
infoBGfade.png
|
||||
javascriptconsole.png
|
||||
javascriptconsoleBackground.png
|
||||
levelUp.png
|
||||
linkDash.png
|
||||
linkPulse.gif
|
||||
linkPulse.png
|
||||
lockOff.png
|
||||
lockOn.png
|
||||
luckyGrandma.png
|
||||
mapBG.jpg
|
||||
mapIcons.png
|
||||
marbleBG.jpg
|
||||
marshmallows.png
|
||||
metaGrandma.png
|
||||
milk.png
|
||||
milkBanana.png
|
||||
milkBlack.png
|
||||
milkBlackcurrant.png
|
||||
milkBlood.png
|
||||
milkBlueFire.png
|
||||
milkBlueberry.png
|
||||
milkCaramel.png
|
||||
milkCherry.png
|
||||
milkChocolate.png
|
||||
milkCoconut.png
|
||||
milkCoffee.png
|
||||
milkDragonfruit.png
|
||||
milkFire.png
|
||||
milkGold.png
|
||||
milkGreenFire.png
|
||||
milkHoney.png
|
||||
milkLicorice.png
|
||||
milkLime.png
|
||||
milkMaple.png
|
||||
milkMelon.png
|
||||
milkMint.png
|
||||
milkOrange.png
|
||||
milkPlain.png
|
||||
milkRaspberry.png
|
||||
milkRose.png
|
||||
milkSoy.png
|
||||
milkSpiced.png
|
||||
milkStars.png
|
||||
milkStrawberry.png
|
||||
milkTea.png
|
||||
milkVanilla.png
|
||||
milkWave.png
|
||||
milkZebra.png
|
||||
mine.png
|
||||
mineBackground.png
|
||||
minerGrandma.png
|
||||
money.png
|
||||
mysticBG.jpg
|
||||
nest.png
|
||||
orangeWave.png
|
||||
panelBG.png
|
||||
panelGradientBottom.png
|
||||
panelGradientLeft.png
|
||||
panelGradientRight.png
|
||||
panelGradientTop.png
|
||||
panelHorizontal.png
|
||||
panelMenu.png
|
||||
panelMenu2.png
|
||||
panelMenu3.png
|
||||
panelVertical.png
|
||||
pantheonBG.png
|
||||
patreon.png
|
||||
perfectCookie.png
|
||||
pieFill.png
|
||||
playsaurusLogo.png
|
||||
pointGlow.gif
|
||||
pointyLad.png
|
||||
portal.png
|
||||
portalBackground.png
|
||||
portraitChip.png
|
||||
portraitCrumb.png
|
||||
portraitDoe.png
|
||||
portraitLucky.png
|
||||
prestigeBar.jpg
|
||||
prestigeBarCap.png
|
||||
prism.png
|
||||
prismBackground.png
|
||||
rainbowGrandma.png
|
||||
raspberryWave.png
|
||||
roundFrameBorder.png
|
||||
roundedPanelBG.png
|
||||
roundedPanelBGS.png
|
||||
roundedPanelLeft.png
|
||||
roundedPanelLeftS.png
|
||||
roundedPanelRight.png
|
||||
roundedPanelRightS.png
|
||||
santa.png
|
||||
scriptGrandma.png
|
||||
selectTarget.png
|
||||
sentientFurnace.png
|
||||
shadedBorders.png
|
||||
shadedBordersGold.png
|
||||
shadedBordersRed.png
|
||||
shadedBordersSoft.png
|
||||
shine.png
|
||||
shineGold.png
|
||||
shineRed.png
|
||||
shineSpoke.png
|
||||
shinyWinkler.png
|
||||
shinyWrinkler.png
|
||||
shinyWrinklerBits.png
|
||||
shipment.png
|
||||
shipmentBackground.png
|
||||
smallCookies.png
|
||||
smallDollars.png
|
||||
snow.jpg
|
||||
snow2.jpg
|
||||
sparkles.jpg
|
||||
spellBG.png
|
||||
spinnyBig.png
|
||||
spinnySmall.png
|
||||
spookyCookie.png
|
||||
starbg.jpg
|
||||
storeTile.jpg
|
||||
sugarLump.png
|
||||
temple.png
|
||||
templeBackground.png
|
||||
templeGrandma.png
|
||||
timemachine.png
|
||||
timemachineBackground.png
|
||||
timerBars.png
|
||||
tinyEyeEmpty.png
|
||||
tinyEyeOff.png
|
||||
tinyEyeOn.png
|
||||
transmutedGrandma.png
|
||||
turnInto.png
|
||||
upgradeFrame.png
|
||||
upgradeFrameHeavenly.png
|
||||
upgradeFrameOld.png
|
||||
upgradeFrameShadowOld.png
|
||||
upgradeHighlight.jpg
|
||||
upgradeHighlight.png
|
||||
upgradeSelector.png
|
||||
weeHoodie.png
|
||||
winkler.png
|
||||
winterFrame.png
|
||||
winterWinkler.png
|
||||
winterWrinkler.png
|
||||
witchGrandma.png
|
||||
wizardtower.png
|
||||
wizardtowerBackground.png
|
||||
workerGrandma.png
|
||||
wrathContract.png
|
||||
wrathCookie.png
|
||||
wrinkler.png
|
||||
wrinklerBits.png
|
||||
wrinklerBitsOld.png
|
||||
wrinklerBlink.png
|
||||
wrinklerGooglies.png
|
||||
wrinklerShadow.png
|
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 820 B |
After Width: | Height: | Size: 472 B |
After Width: | Height: | Size: 854 B |
After Width: | Height: | Size: 313 B |
After Width: | Height: | Size: 470 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 498 B |
After Width: | Height: | Size: 526 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 966 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 303 B |
After Width: | Height: | Size: 501 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 61 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 971 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 713 B |
After Width: | Height: | Size: 523 B |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 426 B |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 616 B |
After Width: | Height: | Size: 597 B |
After Width: | Height: | Size: 820 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 378 B |
After Width: | Height: | Size: 297 B |
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 2.3 KiB |