Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mamayaya1
GitHub Repository: mamayaya1/game
Path: blob/main/projects/cookie-clicker/dungeons.js
4626 views
1
/*
2
Orteil's sloppy Cookie Clicker dungeons
3
4
Optimizations to do (not mentioning the dozens of missing features) :
5
-use canvas instead
6
-only compute AI for mobs with 2 tiles of view
7
*/
8
var LaunchDungeons=function()
9
{
10
Game.GetWord=function(type)
11
{
12
if (type=='secret') return choose(['hidden','secret','mysterious','forgotten','forbidden','lost','sunk','buried','concealed','shrouded','invisible','elder']);
13
if (type=='ruined') return choose(['ancient','old','ruined','ravaged','destroyed','collapsed','demolished','burnt','torn-down','shattered','dilapidated','abandoned','crumbling','derelict','decaying']);
14
if (type=='magical') return choose(['arcane','magical','mystical','sacred','honed','banished','unholy','holy','demonic','enchanted','necromantic','bewitched','haunted','occult','astral']);
15
return '';
16
}
17
18
/*=====================================================================================
19
DUNGEONS
20
=======================================================================================*/
21
Game.DungeonTypes=[];
22
Game.DungeonType=function(name)
23
{
24
this.name=name;
25
this.nameGenerator=function(){return 'Mysterious dungeon';};
26
this.roomTypes=[];
27
Game.DungeonTypes[this.name]=this;
28
return this;
29
};
30
31
/*=====================================================================================
32
CREATE DUNGEON TYPES
33
=======================================================================================*/
34
new Game.DungeonType('Factory').
35
nameGenerator=function(){
36
var str='';
37
str+=Game.GetWord(choose(['secret','ruined','magical']))+' '+choose(['factory','factories','bakery','bakeries','confectionery','laboratory','research center','chocolate forge','chocolate foundry','manufactory','warehouse','machinery','works','bakeworks','workshop','assembly line']);
38
return str;
39
};
40
41
new Game.DungeonType('Mine').
42
nameGenerator=function(){
43
var str='';
44
str+=Game.GetWord(choose(['secret','ruined','magical']))+' '+choose(['chocolate','chocolate','chocolate','white chocolate','sugar','cacao'])+' '+choose(['mine','mines','pit','pits','quarry','excavation','tunnel','shaft','lode','trench','mountain','vein','cliff','peak','dome','crater','abyss','chasm','hole','burrow']);
45
return str;
46
};
47
48
new Game.DungeonType('Portal').
49
nameGenerator=function(){
50
var str='';
51
str+=Game.GetWord(choose(['secret','ruined','magical']))+' '+choose(['portal','gate','dimension','warpgate','door']);
52
return str;
53
};
54
55
new Game.DungeonType('Secret zebra level').
56
nameGenerator=function(){
57
var str='';
58
str+=Game.GetWord(choose(['secret']))+' '+choose(['zebra level']);
59
return str;
60
};
61
62
63
/*=====================================================================================
64
CREATE TILE TYPES
65
=======================================================================================*/
66
67
var D=new DungeonGen();
68
D.loadTiles([
69
['wall',[1,0],'join'],
70
['wall corner',[1,0]],
71
['floor',[1,1],'random3'],
72
['tiled floor',[1,2],'join'],
73
['round pillar',[1,4]],
74
['square pillar',[2,4]],
75
['potted plant',[3,4]],
76
['bookshelf',[4,5],'join'],
77
['door',[1,3],'join'],
78
['alt wall',[4,0],'join'],
79
['alt wall corner',[4,0]],
80
['alt floor',[4,1],'random3'],
81
['alt tiled floor',[4,2],'join'],
82
['alt round pillar',[4,4]],
83
['alt square pillar',[5,4]],
84
['alt potted plant',[6,4]],
85
['alt bookshelf',[4,6],'join'],
86
['alt door',[4,3],'join'],
87
['water',[1,5]],
88
['green water',[2,5]],
89
['dark water',[3,5]],
90
['wooden wall',[1,7],'join'],
91
['wooden floor',[1,6],'random3'],
92
['conveyor belt',[4,7],'join'],
93
['entrance',[0,1]],
94
['alt entrance',[0,3]],
95
['exit',[0,2]],
96
['alt exit',[0,4]]
97
]);
98
99
100
/*=====================================================================================
101
CREATE MONSTER TYPES
102
=======================================================================================*/
103
104
/*
105
An explanation of stats :
106
-hp : health points
107
-speed : determines who attacks first in a fight; bypasses dodging; determines how fast heroes auto-run dungeons
108
-might : determines how much damage is done to opponents
109
-guard : lowers incoming damage
110
-dodge : chance of avoiding incoming attacks completely (affected by the opponent's speed)
111
-luck : heroes only, determines drops and rare encounters
112
-rarity : monsters only, determines how often a monster is added to the spawn table
113
-level : monsters only, determines which average room depth the monster is more likely to spawn in (also determines the loot amount)
114
*/
115
Game.monsterIconY=10;//offset for dungeonItems.png monsters
116
Game.Monsters=[];
117
Game.Monster=function(name,pic,icon,level,stats,loot)
118
{
119
this.name=name;
120
this.pic=pic;
121
this.icon=icon;
122
this.level=level;
123
this.stats={};
124
for (var i in stats)
125
{this.stats[i]=stats[i];}
126
this.stats.hpm=this.stats.hp;
127
this.stats.rarity=stats.rarity||1;
128
this.loot=loot||{};
129
this.boss=0;
130
this.quotes={};
131
Game.Monsters[this.name]=this;
132
}
133
var basicLoot={cookies:{min:1,max:5,prob:0.5}};
134
var goodLoot={cookies:{min:3,max:8,prob:1},gear:{prob:0.05}};
135
var bossLoot={gear:{prob:1}};
136
var chestLoot={cookies:{min:2,max:20,prob:1},gear:{prob:0.1}};
137
var bossLoot={cookies:{min:10,max:50,prob:1},gear:{prob:0.2}};
138
139
//general monsters
140
new Game.Monster('Doughling','doughling',[0,0],1,{hp:5,might:2,guard:2,speed:6,dodge:6,rarity:0.7},basicLoot);
141
new Game.Monster('Elder doughling','elderDoughling',[1,0],7,{hp:20,might:7,guard:7,speed:4,dodge:4,rarity:0.7},goodLoot);
142
new Game.Monster('Angry sentient cookie','angrySentientCookie',[5,0],5,{hp:16,might:8,guard:4,speed:5,dodge:5,rarity:1},basicLoot);
143
new Game.Monster('Baby sentient cookie','babySentientCookie',[4,0],1,{hp:3,might:1,guard:1,speed:7,dodge:7,rarity:1},basicLoot);
144
new Game.Monster('Burnt sentient cookie','burntSentientCookie',[6,0],5,{hp:16,might:12,guard:2,speed:3,dodge:2,rarity:0.2},basicLoot);
145
new Game.Monster('Raw sentient cookie','rawSentientCookie',[5,0],5,{hp:16,might:6,guard:4,speed:7,dodge:7,rarity:0.2},basicLoot);
146
new Game.Monster('Sugar bunny','sugarBunny',[8,0],5,{hp:10,might:3,guard:8,speed:12,dodge:9,rarity:0.001},{cookies:{min:1000,max:10000}});
147
Game.Monsters['Sugar bunny'].onKill=function(){Game.Win('Follow the white rabbit');};Game.Monsters['Sugar bunny'].AI='flee';
148
149
//factory monsters
150
new Game.Monster('Crazed kneader','crazedKneader',[0,2],6,{hp:18,might:6,guard:8,speed:3,dodge:2,rarity:0.5},goodLoot);
151
new Game.Monster('Crazed chip-spurter','crazedDoughSpurter',[0,2],6,{hp:15,might:6,guard:8,speed:5,dodge:3,rarity:0.5},goodLoot);
152
new Game.Monster('Alarm bot','alarmTurret',[3,2],2,{hp:6,might:3,guard:5,speed:8,dodge:8,rarity:0.5},basicLoot);
153
new Game.Monster('Chirpy','chirpy',[4,2],3,{hp:7,might:4,guard:6,speed:9,dodge:9,rarity:0.01},{cookies:{min:500,max:5000}});
154
Game.Monsters['Chirpy'].onKill=function(){Game.Win('Chirped out');};Game.Monsters['Chirpy'].quotes={fight:'oh, hello <3'};
155
new Game.Monster('Disgruntled worker','disgruntledWorker',[1,2],4,{hp:14,might:5,guard:5,speed:6,dodge:4,rarity:0.6},basicLoot);
156
new Game.Monster('Disgruntled overseer','disgruntledOverseer',[1,2],7,{hp:22,might:7,guard:5,speed:6,dodge:4,rarity:0.5},basicLoot);
157
new Game.Monster('Disgruntled cleaning lady','disgruntledCleaningLady',[2,2],4,{hp:13,might:4,guard:5,speed:7,dodge:6,rarity:0.3},basicLoot);
158
159
new Game.Monster('Sentient Furnace','sentientFurnace',[0,3],0,{hp:60,might:14,guard:12,speed:4,dodge:0,rarity:1},bossLoot);//boss
160
Game.Monsters['Sentient Furnace'].onKill=function(){Game.Win('Getting even with the oven');};Game.Monsters['Sentient Furnace'].AI='static';Game.Monsters['Sentient Furnace'].boss=1;Game.Monsters['Sentient Furnace'].quotes={fight:'YOU ARE NOT READY!',defeat:'OH... BURN.'};
161
new Game.Monster('Ascended Baking Pod','ascendedBakingPod',[1,3],0,{hp:60,might:12,guard:14,speed:4,dodge:0,rarity:0.7},bossLoot);//boss
162
Game.Monsters['Ascended Baking Pod'].onKill=function(){Game.Win('Now this is pod-smashing');};Game.Monsters['Ascended Baking Pod'].AI='static';Game.Monsters['Ascended Baking Pod'].boss=1;Game.Monsters['Ascended Baking Pod'].quotes={fight:'rrrrrrrise.',defeat:'blrglblg.'};
163
164
165
Game.BossMonsters=[];
166
for (var i in Game.Monsters)
167
{
168
if (Game.Monsters[i].boss) Game.BossMonsters.push(Game.Monsters[i]);
169
}
170
171
/*=====================================================================================
172
ENTITY MECHANICS
173
=======================================================================================*/
174
175
Game.Entity=function(type,subtype,dungeon,pic,stats)//objects you could find on the map : doors, mobs, interactables, items, player, exits...
176
{
177
this.type=type;
178
this.subtype=subtype||'';
179
this.dungeon=dungeon;
180
this.pic=pic||[0,0];
181
this.stats={};
182
for (var i in stats)
183
{this.stats[i]=stats[i];}
184
185
this.x=-1;
186
this.y=-1;
187
this.obstacle=0;
188
this.zIndex=1;
189
if (this.type=='monster')
190
{
191
this.obstacle=1;
192
this.pic=[Game.Monsters[this.subtype].icon[0],Game.Monsters[this.subtype].icon[1]];
193
this.pic[1]+=Game.monsterIconY;
194
this.targets=[];
195
this.stuck=0;
196
this.zIndex=10;
197
this.fighting=0;
198
this.AI=Game.Monsters[this.subtype].AI||'normal';
199
this.onKill=Game.Monsters[this.subtype].onKill||function(){};
200
for (var i in Game.Monsters[this.subtype].stats){this.stats[i]=Game.Monsters[this.subtype].stats[i];}
201
}
202
else if (this.type=='hero')
203
{
204
this.obstacle=1;
205
this.pic=[Game.Heroes[this.subtype].icon[0],Game.Heroes[this.subtype].icon[1]];
206
this.targets=[];
207
this.stuck=0;
208
this.zIndex=100;
209
this.fighting=0;
210
for (var i in Game.Heroes[this.subtype].stats){this.stats[i]=Game.Heroes[this.subtype].stats[i];}
211
212
//increase stats by amount of matching building (change that later to use gear instead)
213
var mult=Math.max(0,(Game.Objects[this.dungeon.type].amount/20-1));
214
this.stats.hpm+=Math.ceil(mult*2);
215
this.stats.hp=this.stats.hpm;
216
this.stats.might+=mult;
217
this.stats.guard+=mult;
218
this.stats.speed+=mult;
219
this.stats.dodge+=mult;
220
}
221
else if (this.type=='item')
222
{
223
this.zIndex=5;
224
this.value=0;
225
}
226
else if (this.type=='destructible')//crates, doors
227
{
228
this.obstacle=1;
229
this.life=3;
230
this.zIndex=15;
231
if (this.subtype=='door') this.pic=[0,7];
232
else this.pic=[Math.floor(Math.random()*4+2),7];
233
234
this.onKill=function()
235
{
236
if (this.subtype=='random')
237
{
238
var value=Math.round(Math.pow(Math.random(),6)*(10+this.dungeon.level));
239
if (value>0)
240
{
241
var entity=this.dungeon.AddEntity('item','cookies',this.x,this.y);
242
entity.value=value;
243
}
244
}
245
}
246
}
247
else if (this.type=='special')
248
{
249
this.zIndex=5;
250
this.value='';
251
this.obstacle=1;
252
}
253
254
this.Say=function(what)
255
{
256
if (this.type=='monster')
257
{
258
if (Game.Monsters[this.subtype].quotes[what]) this.dungeon.Log(this.subtype+' : "<span style="color:#f96;">'+choose(Game.Monsters[this.subtype].quotes[what].split('|'))+'</span>"');
259
}
260
}
261
this.Draw=function()//return the string to draw this
262
{
263
var name='?';
264
if (this.subtype=='random') name='clutter'; else name=this.subtype;
265
if (this.type=='item' && this.subtype=='cookies' && this.value>0)
266
{
267
if (this.value<2) this.pic=[0,5];
268
else if (this.value<3) this.pic=[1,5];
269
else if (this.value<4) this.pic=[2,5];
270
else if (this.value<6) this.pic=[3,5];
271
else if (this.value<10) this.pic=[4,5];
272
else if (this.value<20) this.pic=[5,5];
273
else if (this.value<30) this.pic=[7,5];
274
else if (this.value<70) this.pic=[6,5];
275
else if (this.value<200) this.pic=[8,5];
276
else this.pic=[6,6];// if (this.value<1000) this.pic=[1,5];
277
}
278
else if (this.type=='special' && this.subtype=='upgrade')
279
{
280
if (this.value!='') this.pic=[7,6]; else this.pic=[8,6];
281
}
282
return '<div class="thing" title="'+name+'" style="z-index:'+(200+this.zIndex)+';left:'+(this.x*16)+'px;top:'+(this.y*16)+'px;background-position:'+(-this.pic[0]*16)+'px '+(-this.pic[1]*16)+'px;"></div>';
283
}
284
this.Wander=function()//AI to move around aimlessly
285
{
286
this.targets=[];
287
this.targets.push([-1,0],[1,0],[0,-1],[0,1]);
288
this.Move();
289
}
290
this.GoTo=function(x,y)//AI to move to a specific point
291
{
292
this.targets=[];
293
if (this.x<x) this.targets.push([1,0]);
294
if (this.x>x) this.targets.push([-1,0]);
295
if (this.y<y) this.targets.push([0,1]);
296
if (this.y>y) this.targets.push([0,-1]);
297
if (!this.Move())//really stuck? try to maneuver laterally!
298
{
299
this.targets=[];
300
if (this.x==x) this.targets.push([1,0],[-1,0]);//somehow this feels inverted... but it doesn't work the other way
301
if (this.y==y) this.targets.push([0,1],[0,-1]);//hypothesis : *MAGIC*
302
this.Move();
303
}
304
}
305
this.Flee=function(x,y)//AI to run away from a specific point
306
{
307
this.targets=[];
308
if (this.x>x) this.targets.push([1,0]);
309
if (this.x<x) this.targets.push([-1,0]);
310
if (this.y>y) this.targets.push([0,1]);
311
if (this.y<y) this.targets.push([0,-1]);
312
if (!this.Move())//really stuck? try to maneuver laterally!
313
{
314
this.targets=[];
315
if (this.x==x) this.targets.push([1,0],[-1,0]);//somehow this feels inverted... but it doesn't work the other way
316
if (this.y==y) this.targets.push([0,1],[0,-1]);//hypothesis : *MAGIC*
317
this.Move();
318
}
319
}
320
this.Move=function()//AI to move to the target
321
{
322
if (this.targets.length>0)
323
{
324
var goodTargets=[];
325
if (this.type=='hero') goodTargets=this.targets;
326
else
327
{
328
for (var i in this.targets)
329
{
330
var thisTarget=this.targets[i];
331
if (this.dungeon.CheckObstacle(this.x+thisTarget[0],this.y+thisTarget[1])!=-1) goodTargets.push([thisTarget[0],thisTarget[1]]);
332
}
333
}
334
if (goodTargets.length>0)
335
{
336
var target=choose(goodTargets);
337
var obstacle=this.dungeon.CheckObstacle(this.x+target[0],this.y+target[1]);
338
if (obstacle==this) obstacle=0;
339
if (obstacle==0 && this.AI!='static')
340
{
341
this.x+=target[0];
342
this.y+=target[1];
343
}
344
else this.stuck+=2;
345
if (obstacle!=0 && obstacle!=-1)
346
{
347
obstacle.HitBy(this);
348
}
349
if (obstacle==-1) return 0;
350
}
351
else {this.stuck+=2;return 0;}
352
if (this.AI=='static') this.stuck=0;
353
return 1;
354
}
355
return 0;
356
}
357
this.HitBy=function(by)//attacked by another entity
358
{
359
if (this.type=='destructible' && by.type=='hero')//break destructibles
360
{
361
by.stuck=0;
362
this.life--;
363
if (this.life<=0)
364
{
365
if (this.onKill) this.onKill();
366
this.Destroy();
367
}
368
else this.pic=[this.pic[0],this.pic[1]+1];
369
}
370
else if (this.type=='special' && this.subtype=='upgrade')//upgrade relic
371
{
372
this.obstacle=0;
373
if (Game.Upgrades[this.value]) Game.Upgrades[this.value].earn();
374
this.value='';
375
}
376
else if ((this.type=='monster' && by.type=='hero') || (this.type=='hero' && by.type=='monster') && this.stats.hp>0)//it's a fight!
377
{
378
by.stuck=0;
379
380
var monster=(this.type=='hero'?by:this);
381
var hero=(this.type=='hero'?this:by);
382
this.dungeon.currentOpponent=monster;
383
384
if (monster.fighting==0)//first meeting
385
{
386
Game.Heroes[hero.subtype].Say('meet '+Game.Monsters[monster.subtype].name);
387
this.Say('fight');
388
}
389
if (this.fighting==0)
390
{
391
this.fighting=1;
392
by.fighting=1;
393
}
394
395
var attackStr='';
396
var attackerName='';
397
var defenderName='';
398
if (by.type=='hero') attackerName=Game.Heroes[by.subtype].name;
399
else if (by.type=='monster') attackerName=Game.Monsters[by.subtype].name;
400
if (this.type=='hero') defenderName=Game.Heroes[this.subtype].name;
401
else if (this.type=='monster') defenderName=Game.Monsters[this.subtype].name;
402
403
//battle formulas (have fun with these)
404
attackStr+=attackerName+' swings at '+defenderName+'!';
405
var damage=Math.round(Math.max(1,Math.min(by.stats.might,Math.pow(((by.stats.might+2.5)/Math.max(1,this.stats.guard)),2)))*(0.8+Math.random()*0.4+Math.pow(Math.random()*0.8,6)));
406
var dodge=Math.random()>(by.stats.speed/Math.max(1,this.stats.dodge+2.5));
407
if (dodge)
408
{
409
attackStr+=' '+defenderName+' dodged the attack.';
410
}
411
else
412
{
413
if (by.stats.luck && by.type=='hero' && Math.random()<by.stats.luck*0.01) {damage*=2;attackStr+=' <b>It\'s a critical!</b>';}//very rare critical based on luck
414
attackStr+=' <b>'+damage+'</b> damage!';
415
416
this.stats.hp-=damage;
417
this.stats.hp=Math.max(this.stats.hp,0);
418
if (this.stats.luck && this.type=='hero')
419
{
420
if (this.stats.hp==0 && Math.random()<this.stats.luck*0.01) {this.stats.hp=1;attackStr+=' '+defenderName+' was saved from certain death!';}//very rare life-saving based on luck
421
}
422
}
423
424
if (this.type=='hero') attackStr='<span style="color:#f99;">'+attackStr+'</span>';
425
if (attackStr!='') this.dungeon.Log(attackStr);
426
427
if (this.stats.hp<=0)//die
428
{
429
this.dungeon.Log(attackerName+' crushed '+defenderName+'!');
430
if (this.type=='hero')
431
{
432
Game.Heroes[this.subtype].Say('defeat');
433
this.dungeon.Log('<span style="color:#f66;">'+Game.Heroes[this.subtype].name+' has been defeated.</span>');
434
this.dungeon.FailLevel();
435
}
436
if (this.type=='monster' && by.type=='hero')
437
{
438
l('monsterSlot'+this.dungeon.id).style.visibility='hidden';
439
this.dungeon.monstersKilledThisRun+=1;
440
if (Math.random()<0.05) Game.Heroes[by.subtype].Say('win');
441
Game.Heroes[by.subtype].Say('win against '+Game.Monsters[this.subtype].name);
442
this.Say('defeat');
443
if (Game.Monsters[this.subtype].loot)
444
{
445
var loot=Game.Monsters[this.subtype].loot;
446
if (loot.gear && (!loot.gear.prob || Math.random()<loot.gear.prob)) {}//drop gear
447
if (loot.cookies && (!loot.cookies.prob || Math.random()<loot.cookies.prob))
448
{
449
var entity=this.dungeon.AddEntity('item','cookies',this.x,this.y);//drop cookies
450
entity.value=Math.round(loot.cookies.min+Math.random()*(loot.cookies.max-loot.cookies.min));
451
}
452
}
453
if (this.onKill) this.onKill();
454
this.Destroy();
455
}
456
}
457
}
458
}
459
this.Turn=function()//do this every turn (walk around, heal up...)
460
{
461
if (this.type=='monster')
462
{
463
var howManyTurns=this.GetInitiative();
464
for (var i=0;i<howManyTurns;i++)
465
{
466
if (1==1)//this.AI!='static')
467
{
468
if (this.AI=='flee') this.Flee(this.dungeon.heroEntity.x,this.dungeon.heroEntity.y);//flee from the player
469
else
470
{
471
this.GoTo(this.dungeon.heroEntity.x,this.dungeon.heroEntity.y);//track the player
472
if (this.stuck || this.targets.length==[]) this.Wander();//can't reach the player? walk around randomly
473
}
474
}
475
}
476
}
477
if (this.type=='monster' || this.type=='hero')
478
{
479
if (this.stuck>0) this.stuck--;
480
this.stuck=Math.min(10,this.stuck);
481
this.targets=[];
482
}
483
if ((this.type=='hero' || this.type=='monster') && this.fighting==0 && this.stats.hp<this.stats.hpm) this.stats.hp++;//heal up
484
if (this.type=='hero')//collect items and cookies
485
{
486
var entities=this.dungeon.GetEntities(this.x,this.y);
487
for (var i in entities)
488
{
489
if (entities[i].type=='item' && entities[i].subtype=='cookies')
490
{
491
var entity=entities[i];
492
var value=Math.ceil(entity.value*Game.Objects[this.dungeon.type].amount*50*(1+Math.random()*((this.stats.luck)/20)));//temporary; scale with matching building CpS later
493
if (value>0)
494
{
495
this.dungeon.Log('<span style="color:#9f9;">Found <b>'+Beautify(value)+'</b> cookie'+(value==1?'':'s')+'!</span>');
496
this.dungeon.cookiesMadeThisRun+=value;
497
Game.Earn(value);
498
}
499
entity.Destroy();
500
}
501
}
502
}
503
if (this.type=='hero') this.fighting=0;
504
}
505
this.Destroy=function()
506
{
507
this.dungeon.entities.splice(this.dungeon.entities.indexOf(this),1);
508
}
509
this.GetInitiative=function()
510
{
511
return randomFloor((this.stats.speed/5)*(1/Math.max(1,(this.dungeon.heroEntity.stats.speed/5))));
512
}
513
}
514
515
/*=====================================================================================
516
DUNGEON MECHANICS
517
=======================================================================================*/
518
519
Game.Dungeons=[];
520
Game.Dungeon=function(type,id)
521
{
522
this.type=type;
523
this.id=id;
524
Game.Dungeons[this.id]=this;
525
this.log=[];
526
this.logNew=0;
527
this.name=Game.DungeonTypes[this.type].nameGenerator();
528
this.hero=null;
529
this.currentOpponent=0;
530
this.level=0;
531
this.auto=1;
532
this.portalPic='';
533
534
this.cookiesMadeThisRun=0;
535
this.monstersKilledThisRun=0;
536
537
this.Log=function(what,nested)
538
{
539
if (typeof what==='string')
540
{
541
this.log.unshift(what);
542
this.logNew++;
543
}
544
else {for (var i in what) {this.Log(what[i],1);}}
545
//if (!nested) this.UpdateLog();
546
}
547
548
this.UpdateLog=function()
549
{
550
this.log=this.log.slice(0,30);
551
var str='';
552
for (var i in this.log)
553
{
554
if (i<this.logNew) str+='<div class="new">'+this.log[i]+'</div>';
555
else str+='<div>'+this.log[i]+'</div>';
556
}
557
this.logNew=0;
558
l('dungeonLog'+this.id).innerHTML=str;
559
}
560
561
this.entities=[];
562
this.GetEntities=function(x,y)//returns the first entity found on tile x,y
563
{
564
var entities=[];
565
for (var i in this.entities) {if (this.entities[i].x==x && this.entities[i].y==y) entities.push(this.entities[i]);}
566
return entities;
567
}
568
this.AddEntity=function(type,subtype,x,y)
569
{
570
//this.RemoveEntities(x,y);
571
var entity=new Game.Entity(type,subtype,this);
572
entity.x=x;
573
entity.y=y;
574
entity.dungeon=this;
575
this.entities.push(entity);
576
return entity;
577
}
578
this.RemoveEntities=function(x,y)
579
{
580
var entities=this.GetEntities(x,y);
581
for (var i in entities)
582
{
583
entities[i].Destroy();
584
}
585
}
586
this.DrawEntities=function()
587
{
588
var str='';
589
for (var i in this.entities) {str+=this.entities[i].Draw();}
590
return str;
591
}
592
593
this.CheckObstacle=function(x,y)//returns 0 for no obstacle; -1 for a wall; an entity if there's at least one entity on this tile
594
{
595
if (x<0 || x>=this.map.w || y<0 || y>=this.map.h) return -1;
596
var entities=this.GetEntities(x,y);
597
for (var i in entities)
598
{
599
if (entities[i].obstacle) return entities[i];
600
}
601
return this.map.isObstacle(x,y)?-1:0;
602
}
603
604
605
this.map={};
606
this.Generate=function()
607
{
608
if (this.level==0) this.name=Game.DungeonTypes[this.type].nameGenerator();
609
this.entities=[];
610
var M=new D.Map(40,40,Math.random(),{
611
roomSize:10,
612
corridorSize:5,
613
fillRatio:1/2,
614
corridorRatio:0.3,
615
pillarRatio:Math.random()*0.8+0.2,
616
waterRatio:Math.random(),
617
branching:Math.ceil(Math.random()*6),
618
sizeVariance:0.4
619
});
620
r=0;
621
while (r!=1)
622
{
623
r=M.dig();
624
}
625
//all done! decorate and render.
626
M.finish();
627
//spawn treasure
628
/*
629
for (var i in M.rooms)
630
{
631
if (M.rooms[i].freeTiles>1)
632
{
633
for (var ii=0;ii<Math.ceil(Math.sqrt(M.rooms[i].freeTiles*(M.rooms[i].gen*0.25+0.1))/2);ii++)
634
{
635
if (Math.random()<0.95 && M.rooms[i].freeTiles>1)
636
{
637
var spot=M.getBestSpotInRoom(M.rooms[i]);
638
M.data[spot.x][spot.y][0]=0;
639
spot.score=0;
640
M.rooms[i].freeTiles--;
641
}
642
}
643
}
644
}*/
645
646
for (var i in M.doors)//place door entities on door positions
647
{
648
//M.data[M.doors[i][0]][M.doors[i][1]][0]=TILE_FLOOR_EDGE;
649
this.AddEntity('destructible','door',M.doors[i][0],M.doors[i][1]);
650
}
651
//set tile graphics
652
for (var i in M.rooms)
653
{
654
var altStr=choose(['alt ','','']);
655
var tiles={
656
'void':altStr+'void',
657
'wall':altStr+'wall',
658
'wall corner':altStr+'wall corner',
659
'floor':altStr+'tiled floor',
660
'floor edges':altStr+'floor',//choose([altStr+'floor',altStr+'floor edges']),
661
'door':altStr+'door',
662
'water':choose(['water','green water','dark water']),
663
'pillar':choose([altStr+'wall',altStr+'round pillar',altStr+'square pillar',altStr+'potted plant','conveyor belt']),
664
'entrance':altStr+'entrance',
665
'exit':altStr+'exit',
666
};
667
if (Math.random()<0.1) {tiles['wall corner']='wooden wall';tiles['wall']='wooden wall';tiles['floor edges']='wooden floor';tiles['pillar']='wooden wall';}
668
if (Math.random()<0.1) {tiles['wall corner']=altStr+'bookshelf';tiles['wall']=altStr+'bookshelf';tiles['pillar']=altStr+'bookshelf';}
669
M.assignTiles(M.rooms[i],tiles);
670
}
671
this.map=M;
672
this.map.str=this.map.getStr();
673
674
//place a boss
675
var tile=this.map.exit;
676
var monsters=[];
677
for (var ii in Game.BossMonsters)
678
{
679
var me=Game.BossMonsters[ii];
680
if (me.level<=(depth+this.level) && Math.random()<(me.stats.rarity||1)) monsters.push(me.name);
681
}
682
if (monsters.length==0) monsters=[choose(Game.BossMonsters).name];
683
if (monsters.length>0)
684
{
685
this.AddEntity('monster',choose(monsters),tile[0],tile[1]);
686
this.map.removeFreeTile(tile[0],tile[1]);
687
}
688
689
//place relics
690
/*
691
var tile=this.map.getBestSpotInRoom(this.map.getRoom(this.map.exit[0],this.map.exit[1]));
692
var entity=this.AddEntity('special','upgrade',tile.x,tile.y);
693
entity.value='Dungeon cookie upgrade';
694
this.map.removeFreeTile(tile.x,tile.y);
695
for (var i=0;i<Math.floor(Math.pow(Math.random(),2)*3);i++)
696
{
697
var room=choose(this.map.rooms);
698
if (room.freeTiles.length>10)
699
{
700
var tile=this.map.getBestSpotInRoom(room);
701
var entity=this.AddEntity('special','upgrade',tile.x,tile.y);
702
entity.value='Dungeon cookie upgrade';
703
this.map.removeFreeTile(tile.x,tile.y);
704
}
705
}*/
706
707
//sprinkle monsters and treasure
708
for (var i=0;i<Math.ceil(this.map.freeTiles.length*0.7);i++)//let's fill this up with A LOT of stuff
709
{
710
var tile=choose(this.map.freeTiles);
711
if (tile!=-1)
712
{
713
var room=this.map.getRoom(tile[0],tile[1]);
714
var depth=room.gen+1;
715
if (Math.random()<0.2)//2 in 10 spawns are monsters
716
{
717
var monsters=[];
718
for (var ii in Game.Monsters)
719
{
720
var me=Game.Monsters[ii];
721
if (me.level!=0 && me.level<=(depth+this.level) && Math.random()<(me.stats.rarity||1)) monsters.push(me.name);//spawn type depending on monster level and rarity
722
}
723
if (monsters.length>0)
724
{
725
this.AddEntity('monster',choose(monsters),tile[0],tile[1]);
726
this.map.removeFreeTile(tile[0],tile[1]);
727
}
728
}
729
else//the rest of the spawns are destructibles or loot
730
{
731
if (Math.random()<0.6)
732
{
733
var value=Math.round(Math.pow(Math.random(),6)*(10+this.level));
734
if (value>0)
735
{
736
var entity=this.AddEntity('item','cookies',tile[0],tile[1]);//random cookies
737
entity.value=value;
738
}
739
}
740
else this.AddEntity('destructible','random',tile[0],tile[1]);//random crates etc
741
this.map.removeFreeTile(tile[0],tile[1]);
742
}
743
}
744
}
745
}
746
747
this.onTile=-1;
748
749
this.Draw=function()
750
{
751
var str='';
752
var x=-this.hero.x;
753
var y=-this.hero.y;
754
str+='<div id="map'+this.id+'" class="map" style="width:'+(9*16)+'px;height:'+(9*16)+'px;"><div class="mapContainer" id="mapcontainer'+this.id+'" style="position:absolute;left:'+(x*16)+'px;top:'+(y*16)+'px;"><div id="mapitems'+this.id+'"></div>'+this.map.str+'</div></div>';
755
str+='<div style="position:absolute;left:'+(9*16+16)+'px;">'+
756
'<a class="control west" onclick="Game.HeroesById['+this.hero.id+'].Move(-1,0);"></a><br>'+
757
'<a class="control east" onclick="Game.HeroesById['+this.hero.id+'].Move(1,0);"></a><br>'+
758
'<a class="control north" onclick="Game.HeroesById['+this.hero.id+'].Move(0,-1);"></a><br>'+
759
'<a class="control south" onclick="Game.HeroesById['+this.hero.id+'].Move(0,1);"></a><br>'+
760
'<a class="control middle" onclick="Game.HeroesById['+this.hero.id+'].Move(0,0);"></a><br>'+
761
'</div>';
762
str+='<div style="position:absolute;left:'+(9*16+16+48*3)+'px;bottom:16px;height:100%;">'+
763
'<div class="dungeonName"><a onclick="Game.ObjectsById['+this.id+'].setSpecial(0);">Exit</a> - <span class="title" style="font-size:12px;">'+this.name+'</span> lvl.'+(this.level+1)+'</div>'+
764
'<div id="heroSlot'+this.id+'" class="mobSlot"><div id="picHero'+this.id+'" class="mobPic"></div><div id="nameHero'+this.id+'" class="title mobName"></div><div class="hpmBar"><div id="hpHero'+this.id+'" class="hpBar"></div></div></div>'+
765
'<div id="monsterSlot'+this.id+'" class="mobSlot" style="left:128px;"><div id="picMonster'+this.id+'" class="mobPic"></div><div id="nameMonster'+this.id+'" class="title mobName"></div><div class="hpmBar"><div id="hpMonster'+this.id+'" class="hpBar"></div></div></div>'+
766
'</div>'+
767
'<div id="dungeonLog'+this.id+'" class="dungeonLog"></div>';
768
l('rowSpecial'+this.id).innerHTML='<div style="width:100%;height:100%;z-index:10000;position:absolute;left:0px;top:0px;">'+str+'</div>';
769
770
l('picHero'+this.id).style.backgroundImage='url(img/'+this.hero.portrait+'.png)';
771
l('nameHero'+this.id).innerHTML=this.hero.name;
772
}
773
this.Refresh=function()
774
{
775
if (!l('mapcontainer'+this.id)) this.Draw();
776
var x=4-this.hero.x;
777
var y=4-this.hero.y;
778
l('mapcontainer'+this.id).style.left=(x*16)+'px';
779
l('mapcontainer'+this.id).style.top=(y*16)+'px';
780
l('mapitems'+this.id).innerHTML=this.DrawEntities();
781
}
782
this.RedrawMap=function()
783
{
784
this.map.str=this.map.getStr();
785
this.Draw();
786
}
787
this.Turn=function()
788
{
789
for (var i in this.entities)
790
{
791
if (this.entities[i] && this.entities[i].type) this.entities[i].Turn();
792
}
793
if (this.currentOpponent)
794
{
795
l('monsterSlot'+this.id).style.visibility='visible';
796
l('hpMonster'+this.id).style.width=Math.round((this.currentOpponent.stats.hp/this.currentOpponent.stats.hpm)*100)+'%';
797
l('picMonster'+this.id).style.backgroundImage='url(img/'+Game.Monsters[this.currentOpponent.subtype].pic+'.png)';
798
l('nameMonster'+this.id).innerHTML=Game.Monsters[this.currentOpponent.subtype].name;
799
l('picHero'+this.id).style.backgroundImage='url(img/'+this.hero.pic+'.png)';
800
}
801
else
802
{
803
l('monsterSlot'+this.id).style.visibility='hidden';
804
l('hpMonster'+this.id).style.width='100%';
805
l('picHero'+this.id).style.backgroundImage='url(img/'+this.hero.portrait+'.png)';
806
}
807
this.currentOpponent=0;
808
l('hpHero'+this.id).style.width=Math.round((this.heroEntity.stats.hp/this.heroEntity.stats.hpm)*100)+'%';
809
810
this.Refresh();
811
this.UpdateLog();
812
813
if (this.hero.x==this.map.exit[0] && this.hero.y==this.map.exit[1])
814
{
815
this.CompleteLevel();
816
}
817
}
818
819
this.DrawButton=function()
820
{
821
var str='';
822
//str+='<div style="text-align:center;margin:48px auto;color:#999;"><a onclick="Game.ObjectsById['+this.id+'].setSpecial(1);">Enter</a></div>';
823
str+='<div style="width:144px;height:144px;position:absolute;left:0px;bottom:0px;"><a class="specialButtonPic" style="background-image:url(img/'+this.portalPic+'.png);" onclick="Game.ObjectsById['+this.id+'].setSpecial(1);"><div class="specialButtonText">Enter dungeons</div></a></div>';
824
return str;
825
}
826
827
this.CompleteLevel=function()
828
{
829
this.hero.Say('completion');
830
this.level++;
831
this.Generate();
832
Game.HeroesById[0].EnterDungeon(this,this.map.entrance[0],this.map.entrance[1]);
833
this.Draw();
834
}
835
this.FailLevel=function()
836
{
837
this.Log('Cookies made this run : '+Beautify(this.cookiesMadeThisRun)+' | Monsters defeated this run : '+Beautify(this.monstersKilledThisRun));
838
this.cookiesMadeThisRun=0;
839
this.monstersKilledThisRun=0;
840
this.level=0;
841
this.Generate();
842
Game.HeroesById[0].EnterDungeon(this,this.map.entrance[0],this.map.entrance[1]);
843
this.Draw();
844
}
845
}
846
847
Game.DungeonLocationChain=function(map,x,y)//return an array of the rooms between the root room and this tile's room, inclusive
848
{//we shouldn't need all this if we used A*...
849
var room=map.getRoom(x,y);
850
var chain=[];
851
if (room!=-1)
852
{
853
while (room.parent)
854
{
855
chain.push(room);
856
room=room.parent;
857
}
858
}
859
chain.reverse();
860
return chain;
861
}
862
Game.DungeonLinkLocationChains=function(start,end)//return the room in which the first location chain should go to to get closer to the second location chain
863
{
864
/*
865
4 cases
866
-we're already in the same room
867
-the target is in a different branch
868
-the target is above in the same branch
869
-the target is below in the same branch
870
*/
871
start.reverse();
872
end.reverse();
873
if (start[0].id==end[0].id) return start[start.length-1];//same room
874
for (var i in end)
875
{
876
if (start[0]==end[i].parent) return end[i];//inferior branch, go to the inferior room
877
}
878
if (start.length>1) return start[1];//different or superior branch, go to the superior room
879
return start[0];//eeeh, let's just stay in the same room
880
}
881
882
/*=====================================================================================
883
CREATE DUNGEONS
884
=======================================================================================*/
885
Game.Objects['Factory'].special=function()
886
{
887
this.dungeon=new Game.Dungeon('Factory',this.id);
888
this.dungeon.Generate();
889
this.specialDrawFunction=function(){this.dungeon.Refresh();};
890
this.drawSpecialButton=function(){return this.dungeon.DrawButton();};
891
this.dungeon.timer=0;
892
this.dungeon.timerWarmup=5;
893
this.dungeon.portalPic='dungeonFactory';
894
895
this.EachFrame=function()
896
{
897
if (this.dungeon.auto)
898
{
899
if (this.dungeon.timer>0) this.dungeon.timer--;
900
if (this.dungeon.timer==0)
901
{
902
this.dungeon.timer=Game.fps*(Math.max(0.1,2-(this.dungeon.hero.stats.speed*0.2))+Math.max(this.dungeon.timerWarmup,0));
903
if (this.dungeon.timerWarmup>0) this.dungeon.timerWarmup--;
904
905
var dungeon=this.dungeon;
906
var hero=dungeon.heroEntity;
907
908
var targetRoom=Game.DungeonLinkLocationChains(Game.DungeonLocationChain(dungeon.map,hero.x,hero.y),Game.DungeonLocationChain(dungeon.map,dungeon.map.exit[0],dungeon.map.exit[1]));
909
var targetTile=(targetRoom.gen==0 || targetRoom.id==dungeon.map.getRoom(hero.x,hero.y).id)?[dungeon.map.exit[0],dungeon.map.exit[1]]:targetRoom.door;
910
hero.GoTo(targetTile[0],targetTile[1]);
911
if (hero.stuck) hero.Wander();
912
dungeon.hero.x=hero.x;
913
dungeon.hero.y=hero.y;
914
dungeon.Turn();
915
}
916
}
917
}
918
919
if (document.addEventListener)//clean this up later
920
{
921
l('rowSpecial'+this.dungeon.id).removeEventListener('keydown',arguments.callee,false);
922
l('rowSpecial'+this.dungeon.id).addEventListener('keydown',function(event)
923
{
924
var dungeon=Game.Objects['Factory'].dungeon;
925
var control=0;
926
if (event.keyCode==37) {dungeon.hero.Move(-1,0);control=1;}
927
else if (event.keyCode==38) {dungeon.hero.Move(0,-1);control=1;}
928
else if (event.keyCode==39) {dungeon.hero.Move(1,0);control=1;}
929
else if (event.keyCode==40) {dungeon.hero.Move(0,1);control=1;}
930
else if (event.keyCode==32) {dungeon.hero.Move(0,0);control=1;}//space
931
else if (event.keyCode==65)//A (auto)
932
{
933
if (dungeon.auto)
934
{
935
dungeon.auto=0;
936
dungeon.timerWarmup=-1;
937
}
938
else
939
{
940
dungeon.auto=1;
941
dungeon.timer=0;
942
dungeon.timerWarmup=0;
943
}
944
event.preventDefault();
945
}
946
947
if (control)
948
{
949
event.preventDefault();
950
dungeon.timer=Game.fps*10;
951
dungeon.timerWarmup=5;
952
}
953
}
954
);
955
}
956
957
var hero=choose(Game.HeroesById);
958
hero.EnterDungeon(this.dungeon,this.dungeon.map.entrance[0],this.dungeon.map.entrance[1]);
959
}
960
961
/*=====================================================================================
962
HEROES
963
=======================================================================================*/
964
Game.Heroes=[];
965
Game.HeroesById=[];
966
Game.Hero=function(name,pic,portrait,icon)
967
{
968
this.name=name;
969
this.pic=pic;
970
this.portrait=portrait;
971
this.icon=icon;
972
this.stats={
973
hp:25,
974
hpm:25,
975
might:5,
976
guard:5,
977
speed:5,
978
dodge:5,
979
luck:5
980
};
981
this.dialogue={
982
'greeting':'Oh hey.|Sup.',
983
'entrance':'Here we go.|So exciting.',
984
'completion':'That was easy.|All done here.',
985
'defeat':'Welp.|Better luck next time.'
986
};
987
this.gear={
988
'armor':-1,
989
'weapon':-1
990
};
991
this.inDungeon=-1;
992
this.completedDungeons=0;
993
994
this.x=0;
995
this.y=0;
996
997
this.EnterDungeon=function(dungeon,x,y)
998
{
999
this.inDungeon=dungeon.id;
1000
dungeon.hero=this;
1001
this.x=x;
1002
this.y=y;
1003
dungeon.heroEntity=dungeon.AddEntity('hero',dungeon.hero.name,x,y);
1004
var room=dungeon.map.getRoom(this.x,this.y);
1005
if (room!=-1 && room.hidden) {room.hidden=0;dungeon.RedrawMap();}
1006
Game.Dungeons[this.inDungeon].Refresh();
1007
dungeon.Log('--------------------');
1008
if (dungeon.level==0) this.Say('greeting');
1009
this.Say('entrance');
1010
l('monsterSlot'+dungeon.id).style.visibility='hidden';
1011
}
1012
this.Move=function(x,y)
1013
{
1014
var dungeon=Game.Dungeons[this.inDungeon];
1015
dungeon.heroEntity.targets=[[x,y]];
1016
if (dungeon.heroEntity.Move())
1017
{
1018
this.x=dungeon.heroEntity.x;
1019
this.y=dungeon.heroEntity.y;
1020
dungeon.Turn();
1021
}
1022
}
1023
1024
this.Say=function(what)
1025
{
1026
if (this.dialogue[what]) Game.Dungeons[this.inDungeon].Log(this.name+' : "<span style="color:#99f;">'+choose(this.dialogue[what].split('|'))+'</span>"');
1027
}
1028
1029
this.save=function()
1030
{
1031
var str='';
1032
str+=
1033
this.inDungeon+','+
1034
this.completedDungeons+','+
1035
this.gear.armor+','+
1036
this.gear.weapon
1037
;
1038
return str;
1039
}
1040
this.load=function(data)
1041
{
1042
var str=data.split(',');
1043
this.inDungeon=parseInt(str[0]);
1044
this.completedDungeons=parseInt(str[1]);
1045
this.gear.armor=parseInt(str[2]);
1046
this.gear.weapon=parseInt(str[3]);
1047
}
1048
this.id=Game.HeroesById.length;
1049
Game.HeroesById.push(this);
1050
Game.Heroes[this.name]=this;
1051
}
1052
1053
/*=====================================================================================
1054
CREATE HEROES
1055
=======================================================================================*/
1056
var hero=new Game.Hero('Chip','girlscoutChip','portraitChip',[1,0]);
1057
hero.dialogue={
1058
'intro':'I\'m Chip! I just really like exploring stuff. Let\'s go have an adventure!',
1059
'greeting':'Hello there!|I\'m ready!|Where are we going today?|Adventure!',
1060
'win':'Take that!|Hah!|That\'s right.',
1061
'entrance':'Chipping in!|Welp, here goes nothing!|I wonder what I\'ll find!|Hey, this place is new!|This place seems familiar.|Let\'s make it happen.',
1062
'completion':'I\'m one smart cookie.|Oh yeah!|Let\'s explore some more!|That was easy!|That sure was fun!|I\'m not lost, am I?|More exploring? Sure, why not!',
1063
'defeat':'B-better luck next time.|That really hurt!|I yield! I yield!|That went badly.|No half-baked excuses next time.|I think I scraped my knee!|Owie.|Woopsie!',
1064
'win against Sentient Furnace':'The irony, it burns! (...it\'s funny because it was burning. And made of iron. ...Moving on.)',
1065
'win against Ascended Baking Pod':'Where is your pod now?|That was disturbing.'
1066
};
1067
hero.stats={
1068
hp:30,
1069
hpm:30,
1070
might:5,
1071
guard:5,
1072
speed:5,
1073
dodge:5,
1074
luck:5
1075
};
1076
var hero=new Game.Hero('Crumb','girlscoutCrumb','portraitCrumb',[2,0]);
1077
hero.dialogue={
1078
'intro':'I\'m Crumb. I look like this because of a baking accident when I was little. Big deal. At least now I don\'t get hurt as easily as others, I guess.',
1079
'greeting':'Hi there.|Ready for adventure, I guess.|Reporting for duty.',
1080
'win':'Oh sorry, did that hurt?|Should have moved out of the way.|Oops. My bad.',
1081
'entrance':'Let\'s do this, I guess.|Well, let\'s go...|I gotta go in there?|Are we really doing this?|I hope I won\'t get lost like last time.|Let\'s get this over with.',
1082
'completion':'I... I did it...|I\'m glad that\'s over.|What, there\'s more?|In I go, I guess.|It doesn\'t end, does it?|But it\'s dark in there.',
1083
'defeat':'I, uh, ouch.|Why does that always happen to me?|I\'m just no good, am I?|Oh no.|I\'m... I\'m not crying.|Well that wasn\'t fun at all.|I\'m sorry I failed you.|Please... make them go away...',
1084
'meet Ascended Baking Pod':'That thing shouldn\'t even be alive.|Is that where they all came from?',
1085
'win against Ascended Baking Pod':'Hm. Fascinating.'
1086
};
1087
hero.stats={
1088
hp:25,
1089
hpm:25,
1090
might:5,
1091
guard:7,
1092
speed:4,
1093
dodge:4,
1094
luck:5
1095
};
1096
var hero=new Game.Hero('Doe','girlscoutDoe','portraitDoe',[3,0]);
1097
hero.dialogue={
1098
'intro':'H-hey. Name\'s Doe. I\'m pretty fast. I uh, I promise I\'ll do my best.',
1099
'greeting':'H-hey.|Oh, uh, h-hi there.|C-can I join?',
1100
'win':'Th-that looks like it hurt... awesome...|D-did I do that?|N-neat... there\'s pieces everywhere.',
1101
'entrance':'Alright, let\'s do this!|I-if I really have to.|I-in there? By myself?|...won\'t you come with me this time?|H-here I go!',
1102
'completion':'Oh... oh my.|That\'s... I uh, I\'m glad.|Y-yeah that was real easy. Piece of pie!|T-too easy, right?|S-so many cookies...|Ooh? F-fascinating.',
1103
'defeat':'I-if you can\'t beat them... join them.|I-it\'s because I stutter, isn\'t it?|W-well that\'s just no good at all.|I, uh, I meant for that to happen.|H-how embarrassing.',
1104
'meet Ascended Baking Pod':'W-whoah... it\'s... magnificent...',
1105
'win against Ascended Baking Pod':'I\'m sorry, buddy.|I... I think I hurt it...|Oh no... I-I think I broke it...'
1106
};
1107
hero.stats={
1108
hp:25,
1109
hpm:25,
1110
might:4,
1111
guard:4,
1112
speed:7,
1113
dodge:5,
1114
luck:5
1115
};
1116
var hero=new Game.Hero('Lucky','girlscoutLucky','portraitLucky',[4,0]);
1117
hero.dialogue={
1118
'intro':'Oh joy! My name\'s Lucky. Guess what I\'m good at?',
1119
'greeting':'I\'m feeling lucky!|It\'s a bright day today!|Let\'s do great things together.',
1120
'win':'Ooh lucky shot!|Pow! One more.|Damn straight!',
1121
'entrance':'Glad to be of service!|Oooh this one\'ll be interesting.|This will be a good one, I can feel it!|Here I come!',
1122
'completion':'Over already?|Let\'s explore some more!|That was lucky!|That was no luck, I\'m just that good.|Alright, let\'s move on!|I\'m just getting warmed up!',
1123
'defeat':'I can\'t believe it!|...This is a joke, right?|Hey! No fair!|B-but...|I\'m gonna need a bandaid. And some hot chocolate.|I\'ll, uh, try again later.|Bad luck! Bad luck!',
1124
'win against Ascended Baking Pod':'Golly, that was peculiar.'
1125
};
1126
hero.stats={
1127
hp:25,
1128
hpm:25,
1129
might:5,
1130
guard:4,
1131
speed:4,
1132
dodge:5,
1133
luck:7
1134
};
1135
1136
};
1137