Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mamayaya1
GitHub Repository: mamayaya1/game
Path: blob/main/projects/cookie-clicker/minigameMarket.js
4626 views
1
var M={};
2
M.parent=Game.Objects['Bank'];
3
M.parent.minigame=M;
4
M.launch=function()
5
{
6
var M=this;
7
M.name=M.parent.minigameName;
8
M.init=function(div)
9
{
10
//populate div with html and initialize values
11
12
M.goods={
13
'Farm':{
14
name:'Cereals',
15
symbol:'CRL',
16
company:'Old Mills',
17
desc:'<b>Old Mills</b> is a trusted staple of the grain industry. Finding their roots in humble pioneer farms centuries ago and honing their know-how ever since, the Old Mills organic crops have reached a standard of quality that even yours struggle to equal.',
18
},
19
'Mine':{
20
name:'Chocolate',
21
symbol:'CHC',
22
company:'Cocoa Excavations',
23
desc:'<b>Cocoa Excavations</b> is an international chocolate mining venture whose extraction sites always seem, somehow, to pop up in war-torn countries. Their high-grade chocolate is renowned the world over and has even been marketed, to some success, as suitable gems for engagement rings.',
24
},
25
'Factory':{
26
name:'Butter',
27
symbol:'BTR',
28
company:'Bovine Industries',
29
desc:'<b>Bovine Industries</b> is a formerly-agricultural conglomerate that now deals in mechanized dairy mass production. Whistleblowers have drawn attention to the way the milk cows employed by this company are treated, describing it as "not quite cruel or anything, but definitely unusual".',
30
},
31
'Bank':{
32
name:'Sugar',
33
symbol:'SUG',
34
company:'Candy Trust',
35
desc:'The <b>Candy Trust</b> is a corporate banking group backed by, and specialized in, the trade of high-grade sugar. The origin of said sugar is legally protected by an armada of lawyers, though some suspect they secretly scrape it off of the bank bills coming in before processing it.',
36
},
37
'Temple':{
38
name:'Nuts',
39
symbol:'NUT',
40
company:'Hazel Monastery',
41
desc:'Hidden between hills and fog somewhere, the secretive <b>Hazel Monastery</b> has, for centuries, maintained nut crops of the highest quality. The monastery nuts are carefully tended to, harvested and shelled by its monks, who are all required to take a vow of nut allergy as a lifelong test of piety.',
42
},
43
'Wizard tower':{
44
name:'Salt',
45
symbol:'SLT',
46
company:'Wacky Reagants',
47
desc:'Salt is a versatile substance, with properties both mundane and mystical. This is why the bearded crackpots at <b>Wacky Reagants</b> have perfected the art of turning magic powder into salt, which is then sold to anyone promising to put it to good use - whether it be warding off banshees and ghouls or seasoning a Sunday roast.',
48
},
49
'Shipment':{
50
name:'Vanilla',
51
symbol:'VNL',
52
company:'Cosmic Exports',
53
desc:'After the news broke of vanilla not being native to Earth, <b>Cosmic Exports</b> was the first company to discover its true origin planet - and has struck an exclusive deal with its tentacled inhabitants to ship its valuable, unadulterated beans all over the local quadrant.',
54
},
55
'Alchemy lab':{
56
name:'Eggs',
57
symbol:'EGG',
58
company:'Organic Gnostics',
59
desc:'At <b>Organic Gnostics</b>, an egg is seen as a promise. A promise of life and nourishment, of infinite potential, of calcium and protein. An egg can become many things... especially when you\'re properly funded and don\'t believe there\'s room in science for rules or ethics.',
60
},
61
'Portal':{
62
name:'Cinnamon',
63
symbol:'CNM',
64
company:'Dimensional Exchange',
65
desc:'The <b>Dimensional Exchange</b> employs a vast team of ragtag daredevils to dive into dangerous underworlds in search of strange native spices. Chief among those is cinnamon, a powder so delicious its true nature can only be unspeakably abominable.',
66
},
67
'Time machine':{
68
name:'Cream',
69
symbol:'CRM',
70
company:'Precision Aging',
71
desc:'Once specialized in cosmetics for the elderly, the eggheads at <b>Precision Aging</b> have repurposed their timeshift technology and developed a process allowing them to accelerate, slow down, and even reverse the various phase changes of milk. Their flagship offering, whole cream, is said to be within 0.002% of theoretical ripening optimums.',
72
},
73
'Antimatter condenser':{
74
name:'Jam',
75
symbol:'JAM',
76
company:'Pectin Research',
77
desc:'<b>Pectin Research</b> is a military-backed laboratory initially created with the aim of enhancing and miniaturizing army rations, but now open for public bulk trading. It has recently made forays in the field of highly-concentrated fruit jams, available in a variety of flavors.',
78
},
79
'Prism':{
80
name:'White chocolate',
81
symbol:'WCH',
82
company:'Dazzle Corp Ltd.',
83
desc:'What was once two college kids messing around with mirrors in their dad\'s garage is now a world-famous megacorporation. <b>Dazzle Corp</b>\'s groundbreaking experiments in photonic annealing have led to the creation years ago of a new kind of matter, once derided as impossible by physicists and cooks alike: white chocolate.',
84
},
85
'Chancemaker':{
86
name:'Honey',
87
symbol:'HNY',
88
company:'Prosperity Hive',
89
desc:'The folks at <b>Prosperity Hive</b> deal in honey, and it\'s always worked for them. With a work culture so relaxed you\'re almost tempted to ditch the cookie business and join them, these people have little in common with the proverbial busy bee - though their rates do sting quite a bit.',
90
},
91
'Fractal engine':{
92
name:'Cookies',
93
symbol:'CKI',
94
company:'Selfmade Bakeries',
95
desc:'Interesting. It appears there\'s still a company out there trying to sell cookies even with your stranglehold on the market. No matter - you figure <b>Selfmade Bakeries</b>\' largely inferior product will make decent fodder for the mouse traps in your factories.',
96
},
97
'Javascript console':{
98
name:'Recipes',
99
symbol:'RCP',
100
company:'Figments Associated',
101
desc:'In a post-material world, the market of ideas is where value is created. <b>Figments Associated</b> understands that, and is the prime designer (and patenter) of baking recipes, ingredient nomenclature, custom cooking procedures, and other kitchen processes.',
102
},
103
'Idleverse':{
104
name:'Subsidiaries',
105
symbol:'SBD',
106
company:'Polyvalent Acquisitions',
107
desc:'Avoid the uncouth nastiness of mass layoffs and hostile takeovers by delegating the purchase, management, and eventual dissolution of other companies to the boys at <b>Polyvalent Acquisitions</b>. Let \'em deal with it!',
108
},
109
};
110
M.goodsById=[];var n=0;
111
for (var i in M.goods){var it=M.goods[i];it.id=n;it.hidden=false;it.active=false;it.last=0;it.building=Game.Objects[i];it.stock=0;it.mode=0;it.dur=0;it.val=1;it.vals=[it.val];it.d=0;M.goodsById[n]=it;it.icon=[it.building.iconColumn,33];n++;}
112
113
M.goodTooltip=function(id)
114
{
115
return function(){
116
var me=M.goodsById[id];
117
var delta=M.goodDelta(id);
118
var val=M.getGoodPrice(me)
119
icon=me.icon||[0,0];
120
var str='<div style="padding:8px 4px;min-width:350px;">'+
121
'<div class="icon" style="float:left;margin-left:-8px;margin-top:-8px;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div>'+
122
'<div class="name">'+me.name+' <span style="font-size:12px;opacity:0.8;">(from <span style="font-variant:small-caps;">'+me.company+'</span>)</span> <span class="bankSymbol">'+me.symbol+' <span class="bankSymbolNum'+(delta>=0?' bankSymbolUp':delta<0?' bankSymbolDown':'')+'">'+(delta+''+(delta==Math.floor(delta)?'.00':(delta*10)==Math.floor(delta*10)?'0':'')+'%')+'</span></span></div>'+
123
'<div class="line"></div><div class="description">'+
124
'<q>'+me.desc+'</q>'+
125
'<div class="line"></div><div style="font-size:11px;">&bull; <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div> '+me.name+': currently worth <b>$'+Beautify(val,2)+'</b> per unit.<br>&bull; You currently own <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div> <b>'+Beautify(me.stock)+'</b>x '+me.name+' (worth <b>$'+Beautify(val*me.stock,2)+'</b>).<br>&bull; Your warehouses can store up to <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div> <b>'+Beautify(M.getGoodMaxStock(me))+'</b>x '+me.name+'.<br>&bull; You may increase your storage space by upgrading your offices and by buying more <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-me.building.iconColumn*48)+'px '+(0*48)+'px;"></div> '+me.building.plural+'. You also get 10 extra storage space per '+me.building.single+' level (currently: <b>+'+(me.building.level*10)+'</b>).<br>&bull; The average worth of this stock and how high it can peak depends on the building it is tied to, along with the level of your <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-15*48)+'px '+(0*48)+'px;"></div> banks.</div>'+
126
'<div style="font-size:11px;opacity:0.5;margin-top:3px;">Shift-click the hide button to toggle all other stocks.</div>'+
127
'</div></div>';
128
return str;
129
};
130
}
131
M.tradeTooltip=function(id,n)
132
{
133
return function(){
134
var me=M.goodsById[id];
135
var icon=me.icon||[0,0];
136
var val=M.getGoodPrice(me)
137
var cost=Game.cookiesPsRawHighest*val;
138
var buyOrSell=n>0;
139
var overhead=1;
140
var stock=me.stock;
141
var maxStock=M.getGoodMaxStock(me);
142
if (buyOrSell) overhead*=1+0.01*(20*Math.pow(0.95,M.brokers));
143
cost*=overhead;
144
if (n==10000) n=Math.floor(Game.cookies/cost);
145
else if (n==-10000) n=me.stock;
146
n=Math.abs(n);
147
if (buyOrSell) n=Math.min(n,maxStock-stock);
148
if (!buyOrSell) n=Math.min(n,stock);
149
var str='<div style="padding:8px 4px;min-width:128px;text-align:center;font-size:11px;">'+
150
'<div style="font-size:9px;opacity:0.6;">Stock: <b'+((!buyOrSell && stock==0)?' class="red"':'')+'>'+Beautify(stock)+'</b>/<b'+((buyOrSell && stock>=maxStock)?' class="red"':'')+'>'+Beautify(maxStock)+'</b></div>'+
151
'<div class="line"></div>'+
152
'<div>'+(buyOrSell?'Buy':'Sell')+' <b>'+Beautify(n)+'</b>x <div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-me.icon[0]*48)+'px '+(-me.icon[1]*48)+'px;"></div> '+me.name+'</div>'+
153
'<div>for <b>$'+Beautify(val,2)+'</b> each</div>'+
154
(overhead>1?('<div style="font-size:9px;opacity:0.6;">(+<b>'+Beautify((overhead-1)*100,2)+'%</b> overhead)</div>'):'')+
155
'<div class="line"></div>'+
156
'<div style="font-size:9px;opacity:0.6;font-weight:bold;">'+(buyOrSell?'you spend':'you earn')+':</div>'+
157
'<div><b class="hasTinyCookie '+(n<=0?'gray':(Game.cookies>=cost*n || !buyOrSell)?'green':'red')+'">'+Beautify(cost*n)+'</b></div>'+
158
(n>0?('<div style="font-size:9px;opacity:0.6;font-weight:bold;">($'+Beautify(val*overhead*n,2)+')</div>'+
159
'<div style="font-size:9px;opacity:0.6;font-weight:bold;">('+Game.sayTime(val*overhead*n*Game.fps,-1)+' of CpS)</div>'):'')+
160
(((me.last==1 && !buyOrSell) || (me.last==2 && buyOrSell))?'<div class="line"></div><div class="red">You cannot buy and sell this stock in the same tick.</div>':'')+
161
'</div>';
162
return str;
163
};
164
}
165
166
M.goodDelta=function(id,back)//if back is 0 we get the current step; else get current step -back
167
{
168
var back=back||0;
169
var me=M.goodsById[id];
170
var val=0;
171
if (me.vals.length>=(2+back))
172
{
173
val=me.vals[0+back]/me.vals[1+back]-1;
174
}
175
val=Math.floor(val*10000)/100;
176
return val;
177
}
178
179
M.getGoodMaxStock=function(good)
180
{
181
var bonus=0;
182
if (M.officeLevel>0) bonus+=25;
183
if (M.officeLevel>1) bonus+=50;
184
if (M.officeLevel>2) bonus+=75;
185
if (M.officeLevel>3) bonus+=100;
186
return Math.ceil(good.building.highest*(M.officeLevel>4?1.5:1)+bonus+good.building.level*10);
187
}
188
M.getGoodPrice=function(good)
189
{
190
return good.val;
191
}
192
M.buyGood=function(id,n)
193
{
194
var me=M.goodsById[id];
195
var costInS=M.getGoodPrice(me);
196
var cost=Game.cookiesPsRawHighest*costInS;
197
var overhead=1+0.01*(20*Math.pow(0.95,M.brokers));
198
cost*=overhead;
199
if (n==10000) n=Math.floor(Game.cookies/cost);
200
n=Math.min(n,M.getGoodMaxStock(me)-me.stock);
201
if (n>0 && me.last!=2 && Game.cookies>=cost*n && me.stock+n<=M.getGoodMaxStock(me))
202
{
203
if (costInS*overhead*n>=86400) Game.Win('Buy buy buy');
204
M.profit-=costInS*overhead*n;
205
Game.Spend(cost*n);
206
me.stock+=n;
207
var min=10000;
208
for (var i=0;i<M.goodsById.length;i++)
209
{
210
var it=M.goodsById[i];
211
min=Math.min(min,it.stock);
212
if (it.stock>=1000) Game.Win('Full warehouses');
213
}
214
if (min>=100) Game.Win('Rookie numbers');
215
if (min>=500) Game.Win('No nobility in poverty');
216
me.last=1;
217
PlaySound('snd/cashOut.mp3',0.4);
218
return true;
219
}
220
return false;
221
}
222
M.sellGood=function(id,n)
223
{
224
var me=M.goodsById[id];
225
if (n==10000) n=me.stock;
226
n=Math.min(n,me.stock);
227
if (n>0 && me.last!=1 && me.stock>0)
228
{
229
var costInS=M.getGoodPrice(me);
230
if (costInS*n>=86400) Game.Win('Make my day');
231
M.profit+=costInS*n;
232
if (M.profit>0) Game.Win('Initial public offering');
233
if (M.profit>=10000000) Game.Win('Liquid assets');
234
if (M.profit>=31536000) Game.Win('Gaseous assets');
235
//Game.Earn(Game.cookiesPsRawHighest*costInS*n);
236
Game.cookies+=Game.cookiesPsRawHighest*costInS*n;
237
Game.cookiesEarned=Math.max(Game.cookies,Game.cookiesEarned);
238
me.stock-=n;
239
me.last=2;
240
PlaySound('snd/cashIn.mp3',0.4);
241
return true;
242
}
243
return false;
244
}
245
M.getRestingVal=function(id)
246
{
247
return 10+10*id+(Game.Objects['Bank'].level-1);
248
}
249
250
M.updateGoodStyle=function(id)
251
{
252
var me=M.goodsById[id];
253
if (me.active)
254
{
255
me.l.style.display='inline-block';
256
if (!me.hidden)
257
{
258
me.viewHideL.innerHTML='Hide';
259
me.l.classList.remove('bankHidden');
260
me.graphIconL.style.display='block';
261
}
262
else
263
{
264
me.viewHideL.innerHTML='View';
265
me.l.classList.add('bankHidden');
266
me.graphIconL.style.display='none';
267
}
268
}
269
else
270
{
271
me.l.style.display='none';
272
me.graphIconL.style.display='none';
273
}
274
}
275
276
M.officeLevel=0;
277
M.offices=[
278
{name:'Credit garage',icon:[0,33],cost:[100,2],desc:'This is your starting office.<br>Upgrading will grant you:<br><b><!--&bull; +1 opportunity slot<br>-->&bull; +25 warehouse space for all goods</b>'},
279
{name:'Tiny bank',icon:[9,33],cost:[200,4],desc:'This is your office.<br>Upgrading will grant you:<br><b>&bull; +1 loan slot<br>&bull; +50 warehouse space for all goods</b>'},
280
{name:'Loaning company',icon:[10,33],cost:[350,8],desc:'This is your office.<br>Upgrading will grant you:<br><!--<b>&bull; +1 opportunity slot<br>-->&bull; +75 warehouse space for all goods</b>'},
281
{name:'Finance headquarters',icon:[11,33],cost:[500,10],desc:'This is your office.<br>Upgrading will grant you:<br><b>&bull; +1 loan slot<br>&bull; +100 warehouse space for all goods</b>'},
282
{name:'International exchange',icon:[12,33],cost:[700,12],desc:'This is your office.<br>Upgrading will grant you:<br><b>&bull; +1 loan slot<br><!--&bull; +1 opportunity slot<br>-->&bull; +50% base warehouse space for all goods</b>'},
283
{name:'Palace of Greed',icon:[18,33],cost:0,desc:'This is your office.<br>It is fully upgraded. Its lavish interiors, spanning across innumerable floors, are host to many a decadent party, owing to your nigh-unfathomable wealth.'},
284
];
285
286
M.officeTooltip=function()
287
{
288
return function(){
289
var me=M.offices[M.officeLevel];
290
var icon=me.icon||[0,0];
291
var str='<div style="padding:8px 4px;min-width:350px;">'+
292
'<div class="icon" style="float:left;margin-left:-8px;margin-top:-8px;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div>'+
293
'<div class="name">'+me.name+' <span style="font-size:11px;opacity:0.6;">[Level '+(M.officeLevel+1)+' offices]</span></div>'+
294
'<div class="line"></div><div class="description" style="font-size:11px;">'+
295
me.desc+
296
'</div>'+
297
(me.cost?('<div class="line"></div><div style="font-size:11px;padding-left:24px;position:relative;">'+
298
'<div id="bankOfficeIcon" class="icon" style="position:absolute;left:0px;top:6px;pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-11*48)+'px '+(-0*48)+'px;"></div>'+
299
'Upgrading will cost you <b class="'+(Game.Objects['Cursor'].amount>=me.cost[0]?'green':'red')+'">'+me.cost[0]+' cursors</b>.<br>'+
300
'Upgrading requires <b class="'+(Game.Objects['Cursor'].level>=me.cost[1]?'green':'red')+'">level '+me.cost[1]+' cursors</b>.'+
301
'</div>'):'')+
302
'</div>';
303
return str;
304
};
305
}
306
307
M.brokers=0;
308
309
M.getMaxBrokers=function(){return Math.ceil(Game.Objects['Grandma'].highest/10+Game.Objects['Grandma'].level);}
310
M.getBrokerPrice=function(){return Game.cookiesPsRawHighest*60*20;}
311
M.brokersTooltip=function()
312
{
313
return function(){
314
var icon=[1,33];
315
var str='<div style="padding:8px 4px;min-width:350px;">'+
316
'<div class="icon" style="float:left;margin-left:-8px;margin-top:-8px;background-position:'+(-icon[0]*48)+'px '+(-icon[1]*48)+'px;"></div>'+
317
'<div class="name">Stockbrokers <span style="font-size:11px;opacity:0.6;">(you have '+Beautify(M.brokers)+')</span></div>'+
318
'<div class="line"></div><div class="description" style="font-size:11px;">'+
319
'A nice broker to trade more cookies.<br>'+
320
'&bull; Buying goods normally incurs overhead costs of <b>20% extra</b>. Each broker you hire reduces that cost by <b>5%</b>.<br>'+
321
'&bull; Current overhead costs thanks to your '+Beautify(M.brokers)+' broker'+(M.brokers==1?'':'s')+': <b>+'+Beautify(20*Math.pow(0.95,M.brokers),2)+'%</b><br>'+
322
'&bull; Buying a broker costs <b class="hasTinyCookie '+(Game.cookies>=M.getBrokerPrice()?'green':'red')+'">20 minutes</b> of CpS (that\'s $1200).<br>'+
323
'&bull; Maximum number of brokers you can own: <b class="'+(M.brokers<M.getMaxBrokers()?'green':'red')+'">'+Beautify(M.getMaxBrokers())+'</b> (the highest amount of grandmas you\'ve owned this run, divided by 10, plus your grandma level)<br>'+
324
'<q>Brokers are Wall Street-class grandmas versed in the ways of finance. Stockbroker grandmas work hard and play hard, and will fight telephone in hand to get your clients the best possible deals - with a sizeable profit margin for you, of course.</q>'+
325
'<div class="line"></div><div style="font-size:11px;text-align:center;">'+
326
'Hiring a new broker will cost you <b class="hasTinyCookie '+(Game.cookies>=M.getBrokerPrice()?'green':'red')+'">'+Beautify(M.getBrokerPrice())+' cookies</b>.'+
327
'</div>'+
328
'</div>'+
329
'</div>';
330
return str;
331
};
332
}
333
334
M.loanTypes=[
335
//name, mult, duration, payback mult, duration, downpayment (as % of bank), quote
336
['a modest loan',1.5,60*2,0.25,60*4,0.2,'Buy that vintage car you\'ve always wanted. Just pay us back.'],
337
['a pawnshop loan',2,0.67,0.1,40,0.4,'Bad credit? No problem. It\'s your money, and you need it now.'],
338
['a retirement loan',1.2,60*24*2,0.8,60*24*5,0.5,'Finance your next house, boat, spouse, etc. You\'ve earned it.'],
339
];
340
M.loanTooltip=function(id)
341
{
342
return function(){
343
var loan=M.loanTypes[id-1];
344
var str='<div style="padding:8px 4px;min-width:350px;">'+
345
'<div class="name">Take out '+loan[0]+'</div>'+
346
'<div class="line"></div><div class="description" style="font-size:11px;">'+
347
'By taking this loan, you will get <b class="green">+'+Math.round((loan[1]-1)*100)+'%</b> CpS for the next <b>'+Game.sayTime(60*loan[2]*Game.fps)+'</b>.<br>'+
348
'However, you will get <b class="red">'+Math.round((loan[3]-1)*100)+'%</b> CpS for the next <b>'+Game.sayTime(60*loan[4]*Game.fps)+'</b> after that.<br>'+
349
'You must also pay an immediate downpayment of <b class="hasTinyCookie red">'+Beautify(Game.cookies*loan[5])+'</b> (<b>'+(loan[5]*100)+'%</b> of your current bank).<br>'+
350
'<q>'+loan[6]+'</q>'+
351
'</div>';
352
return str;
353
};
354
}
355
M.takeLoan=function(id,interest)
356
{
357
var loan=M.loanTypes[id-1];
358
if (!interest)
359
{
360
if (Game.hasBuff('Loan '+id) || Game.hasBuff('Loan '+id+' (interest)')) return false;
361
Game.Spend(Game.cookies*loan[5]);
362
Game.gainBuff('loan '+id,loan[2]*60,loan[1]);
363
}
364
else
365
{
366
Game.gainBuff('loan '+id+' interest',loan[4]*60,loan[3]);
367
Game.Notify('Loan over','Your loan has expired, and you must now repay the interest.',[1,33]);
368
}
369
return true;
370
}
371
Game.takeLoan=M.takeLoan;
372
373
M.getOppSlots=function()
374
{
375
var slots=0;
376
if (M.officeLevel>0) slots++;
377
if (M.officeLevel>2) slots++;
378
if (M.officeLevel>4) slots++;
379
return slots;
380
}
381
382
//note : opportunity system to be added later maybe
383
384
M.oppTooltip=function()
385
{
386
return function(){
387
var str='<div style="padding:8px 4px;min-width:350px;">'+
388
'<div class="name">Generate opportunity</div>'+
389
'<div class="line"></div><div class="description" style="font-size:11px;">'+
390
'Pressing this button gives you up to 3 possible actions to choose from, depending on your office level.<br>These actions will let you manipulate the stock market to some degree, though some are riskier than others.<br>You may only generate an opportunity once an hour, though this can be refreshed with a sugar lump.'+
391
'</div>';
392
return str;
393
};
394
}
395
396
M.refillTooltip=function(){
397
return '<div style="padding:8px;width:300px;font-size:11px;text-align:center;">Click to refill your opportunity timer (and give a quick burst to your economy) for <span class="price lump">1 sugar lump</span>.'+
398
(Game.canRefillLump()?'<br><small>(can be done once every '+Game.sayTime(Game.getLumpRefillMax(),-1)+')</small>':('<br><small class="red">(usable again in '+Game.sayTime(Game.getLumpRefillRemaining()+Game.fps,-1)+')</small>'))+
399
'</div>';
400
};
401
402
403
var str='';
404
str+='<style>'+
405
'#bankBG{background:url(img/shadedBorders.png),url(img/BGmarket.jpg);background-size:100% 100%,auto;position:absolute;left:0px;right:0px;top:0px;bottom:16px;}'+
406
'#bankContent{position:relative;box-sizing:border-box;padding:4px;text-align:center;}'+
407
408
'.bankGood{margin:2px;display:inline-block;width:156px;text-align:center;position:relative;left:0px;top:0px;right:0px;box-sizing:border-box;box-shadow:0px 0px 0px 1px rgba(255,255,255,0.1), 2px 2px 4px rgba(0,0,0,0.5) inset;background:rgba(0,0,0,0.9);color:rgba(255,255,255,0.7);}'+
409
'.bankHidden{opacity:0.75;background:transparent;box-shadow:none;}'+
410
'.bankButton{cursor:pointer;opacity:0.8;color:#94cd50;font-weight:bold;font-size:10px;border:1px solid #999;border-color:#94cd50 #1b7a2f #1b7a2f #94cd50;padding:2px 6px;margin:0px 1px 1px 0px;display:inline-block;}'+
411
'.bankButtonBuy{color:#a358ff;border-color:#a358ff #3a52bc #3a52bc #a358ff;}'+
412
'.bankButtonSell{color:#94cd50;border-color:#94cd50 #1b7a2f #1b7a2f #94cd50;}'+
413
//'.bankButtonLess{color:#e25142;border-color:#e25142 #9a1225 #9a1225 #e25142;}'+
414
'.bankButton:hover{opacity:1;}'+
415
'.bankButton:active{color:#fff;}'+
416
'.bankButtonOff{color:#999;border-color:#999 #666 #666 #999;opacity:0.6;}'+
417
'.bankSymbol{font-weight:bold;font-size:10px;display:inline-block;padding:2px 4px;background:#333;text-shadow:0px 1px #000;}'+
418
'.bankSymbolNum{font-weight:normal;}'+
419
'.bankSymbolNum:after{content:\'=\';}'+
420
'.bankSymbolUp{color:#73f21e;}'+
421
'.bankSymbolUp:after{content:\'\u25b2\';}'+
422
'.bankSymbolDown{color:#f21e3c;}'+
423
'.bankSymbolDown:after{content:\'\u25bc\';}'+
424
'#bankGraphBox{background:#fff;position:relative;z-index:5;overflow:hidden;height:300px;}'+
425
'.bankGraphIcon{position:absolute;right:-24px;top:-24px;z-index:10;transform:scale(0);transition:transform 0.3s;}'+
426
'.bankViewHide{position:absolute;z-index:10;padding:4px;top:-2px;right:0px;}'+
427
'.bankSimpleButton{font-weight:bold;font-size:10px;cursor:pointer;text-decoration:underline;color:rgba(255,255,255,0.9);text-shadow:0px 1px #000;}'+
428
'.bankSimpleButton:active{opacity:0.5;}'+
429
'.bankSimpleButton:hover{color:#fff;}'+
430
'</style>';
431
432
str+='<div id="bankBG"></div>';
433
str+='<div id="bankContent">';
434
435
str+='<div id="bankHeader" style="z-index:10;position:relative;">'+
436
'<div>'+
437
'<div style="padding:1px 4px;font-size:10px;color:rgba(255,255,255,0.5);">Profits: <span id="bankBalance">$0</span>. All prices are in <b style="color:#fff;">$</b>econds of your highest raw cookies per second. <span id="bankNextTick"></span></div>'+
438
'<div id="bankOffice" style="display:inline-block;padding:0px 4px;" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.officeTooltip()','this')+'><div id="bankOfficeIcon" class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -12px -14px;vertical-align:middle;background-position:'+(-0*48)+'px '+(-33*48)+'px;"></div><span id="bankOfficeName" class="bankSymbol" style="width:128px;"></span><div class="bankButton bankButtonBuy bankButtonOff" id="bankOfficeUpgrade">-</div></div>'+
439
'<div id="bankBrokers" style="display:inline-block;padding:0px 4px;" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.brokersTooltip()','this')+'><div id="bankBrokersIcon" class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -12px -14px;vertical-align:middle;background-position:'+(-1*48)+'px '+(-33*48)+'px;"></div><span id="bankBrokersText" class="bankSymbol" style="width:96px;">no brokers</span><div class="bankButton bankButtonBuy bankButtonOff" id="bankBrokersBuy">Hire</div></div>'+
440
'<div style="display:inline-block;padding:0px 4px;"><div id="bankLoan1" style="display:none;" class="bankButton bankButtonSell bankButtonOff" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.loanTooltip(1)','this')+'>1st loan</div><div id="bankLoan2" style="display:none;" class="bankButton bankButtonSell bankButtonOff" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.loanTooltip(2)','this')+'>2nd loan</div><div id="bankLoan3" style="display:none;" class="bankButton bankButtonSell bankButtonOff" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.loanTooltip(3)','this')+'>3rd loan</div></div>'+
441
/*'<div style="display:inline-block;padding:0px 4px;"><div id="bankOpp" class="bankButton bankButtonBuy bankButtonOff" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.oppTooltip()','this')+'>Generate opportunity</div> <div class="bankSymbol" style="position:relative;font-size:10px;color:rgba(255,255,255,0.6);padding-left:16px;"><div '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.refillTooltip','this')+' id="bankLumpRefill" class="usesIcon shadowFilter lumpRefill" style="left:-18px;top:-18px;background-position:'+(-29*48)+'px '+(-14*48)+'px;"></div>refresh</div></div>'+*/
442
'</div>';
443
444
for (var i=0;i<M.goodsById.length;i++)
445
{
446
var me=M.goodsById[i];
447
str+='<div class="bankGood" id="bankGood-'+me.id+'">'+
448
'<div '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.goodTooltip('+me.id+')','this')+'>'+
449
'<div class="icon" style="z-index:20;pointer-events:none;position:absolute;left:0px;top:0px;transform:scale(0.5);margin:-16px -16px;background-position:'+(-me.icon[0]*48)+'px '+(-me.icon[1]*48)+'px;"></div>'+
450
'<div class="bankSymbol" style="margin:1px 0px;display:block;padding:2px 0px;width:100%;overflow:hidden;white-space:nowrap;">'+me.symbol+' <span id="bankGood-'+me.id+'-sym" class="bankSymbolNum">-.--%</span></div>'+
451
'<div class="bankViewHide bankSimpleButton" id="bankGood-'+me.id+'-viewHide">Hide</div>'+
452
'<div class="bankSymbol" style="margin:1px 0px;display:block;font-size:10px;width:100%;background:linear-gradient(to right,transparent,#333,#333,transparent);padding:2px 0px;overflow:hidden;white-space:nowrap;">value: <span style="font-weight:bold;color:#fff;" id="bankGood-'+me.id+'-val">-</span></div>'+
453
'<div class="bankSymbol" style="margin:1px 0px;display:block;font-size:10px;width:100%;background:linear-gradient(to right,transparent,#333,#333,transparent);padding:2px 0px;overflow:hidden;white-space:nowrap;" id="bankGood-'+me.id+'-stockBox">stock: <span style="font-weight:bold;" id="bankGood-'+me.id+'-stock">-</span><span style="font-weight:bold;" id="bankGood-'+me.id+'-stockMax">/-</span></div>'+
454
'</div>'+
455
'<div style="position:relative;white-space:nowrap;">'+
456
'<div style="padding:3px 2px;width:22px;" class="bankSymbol">Buy</div>'+
457
'<div class="bankButton bankButtonBuy" id="bankGood-'+me.id+'_1" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',1)','this')+'>1</div>'+
458
'<div class="bankButton bankButtonBuy" id="bankGood-'+me.id+'_10" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',10)','this')+'>10</div>'+
459
'<div class="bankButton bankButtonBuy" id="bankGood-'+me.id+'_100" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',100)','this')+'>100</div>'+
460
'<div style="width:28px;" class="bankButton bankButtonBuy" id="bankGood-'+me.id+'_Max" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',10000)','this')+'>Max</div>'+
461
'<br>'+
462
'<div style="padding:3px 2px;width:22px;" class="bankSymbol">Sell</div>'+
463
'<div class="bankButton bankButtonSell" id="bankGood-'+me.id+'_-1" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',-1)','this')+'>1</div>'+
464
'<div class="bankButton bankButtonSell" id="bankGood-'+me.id+'_-10" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',-10)','this')+'>10</div>'+
465
'<div class="bankButton bankButtonSell" id="bankGood-'+me.id+'_-100" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',-100)','this')+'>100</div>'+
466
'<div style="width:28px;" class="bankButton bankButtonSell" id="bankGood-'+me.id+'_-All" '+Game.getDynamicTooltip('Game.ObjectsById['+M.parent.id+'].minigame.tradeTooltip('+me.id+',-10000)','this')+'>All</div>'+
467
'</div>'+
468
'</div>';
469
}
470
str+='</div>';
471
str+='<div id="bankGraphBox"></div>';
472
473
str+='</div>';
474
div.innerHTML=str;
475
476
477
478
var str='';
479
str+='<div style="position:absolute;left:2px;top:2px;z-index:10;">'+
480
'<div id="bankGraphLines" class="bankSimpleButton" style="background:rgba(0,0,0,0.5);padding:2px;border-radius:4px;">Line style</div>'+
481
'<div id="bankGraphCols" class="bankSimpleButton" style="background:rgba(0,0,0,0.5);padding:2px;border-radius:4px;">Color mode</div>'+
482
(Game.sesame?'<div id="bankCheatSpeed" class="bankSimpleButton" style="background:rgba(0,0,0,0.5);padding:2px;border-radius:4px;">Toggle speed</div>':'')+
483
'</div>'+
484
'<div style="font-family:Arial Black;font-weight:40px;letter-spacing:2px;opacity:0.15;font-weight:bold;position:absolute;left:6px;bottom:6px;z-index:10;pointer-events:none;">DOUGH JONES INDEX</div>';
485
for (var i=0;i<M.goodsById.length;i++)
486
{
487
var me=M.goodsById[i];
488
str+='<div id="bankGood-'+me.id+'-graphIcon" class="icon bankGraphIcon" style="pointer-events:none;transform:scale(0.5);background-position:'+(-me.icon[0]*48)+'px '+(-me.icon[1]*48)+'px;"></div>';
489
}
490
l('bankGraphBox').innerHTML=str;
491
492
var div=document.createElement('canvas');
493
div.id='bankGraph';
494
div.style.marginLeft='-14px';
495
div.width=64;
496
div.height=64;
497
l('bankGraphBox').appendChild(div);
498
M.graph=div;
499
M.graphCtx=M.graph.getContext('2d',{alpha:false});
500
501
AddEvent(l('bankGraphLines'),'click',function(e){
502
if (M.graphLines==0) M.graphLines=1;
503
else M.graphLines=0;
504
M.toRedraw=2;
505
PlaySound('snd/tick.mp3');
506
});
507
AddEvent(l('bankGraphCols'),'click',function(e){
508
if (M.graphCols==0) M.graphCols=1;
509
else M.graphCols=0;
510
M.setCols();
511
M.toRedraw=2;
512
PlaySound('snd/tick.mp3');
513
});
514
if (l('bankCheatSpeed'))
515
{
516
AddEvent(l('bankCheatSpeed'),'click',function(e){
517
if (M.secondsPerTick==60) M.secondsPerTick=1/10;
518
else M.secondsPerTick=60;
519
M.toRedraw=2;
520
PlaySound('snd/tick.mp3');
521
});
522
}
523
524
AddEvent(l('bankOfficeUpgrade'),'click',function(e){
525
var me=M.offices[M.officeLevel];
526
if (me.cost && Game.Objects['Cursor'].amount>=me.cost[0] && Game.Objects['Cursor'].level>=me.cost[1])
527
{
528
Game.Objects['Cursor'].sacrifice(me.cost[0]);
529
M.officeLevel+=1;
530
if (M.officeLevel>=M.offices.length-1) Game.Win('Pyramid scheme');
531
PlaySound('snd/cashIn2.mp3',0.6);
532
Game.SparkleOn(e.target);
533
}
534
});
535
AddEvent(l('bankBrokersBuy'),'click',function(e){
536
if (M.brokers<M.getMaxBrokers() && Game.cookies>=M.getBrokerPrice())
537
{
538
Game.Spend(M.getBrokerPrice());
539
M.brokers+=1;
540
PlaySound('snd/cashIn2.mp3',0.6);
541
Game.SparkleOn(e.target);
542
}
543
});
544
545
AddEvent(l('bankLoan1'),'click',function(e){
546
if (M.takeLoan(1)) {PlaySound('snd/cashIn2.mp3',0.6);Game.SparkleOn(e.target);}
547
});
548
AddEvent(l('bankLoan2'),'click',function(e){
549
if (M.takeLoan(2)) {PlaySound('snd/cashIn2.mp3',0.6);Game.SparkleOn(e.target);}
550
});
551
AddEvent(l('bankLoan3'),'click',function(e){
552
if (M.takeLoan(3)) {PlaySound('snd/cashIn2.mp3',0.6);Game.SparkleOn(e.target);}
553
});
554
555
for (var i=0;i<M.goodsById.length;i++)
556
{
557
var me=M.goodsById[i];
558
me.l=l('bankGood-'+me.id);
559
me.symbolNumL=l('bankGood-'+me.id+'-sym');
560
me.valL=l('bankGood-'+me.id+'-val');
561
me.stockBoxL=l('bankGood-'+me.id+'-stockBox');
562
me.stockL=l('bankGood-'+me.id+'-stock');
563
me.stockMaxL=l('bankGood-'+me.id+'-stockMax');
564
me.viewHideL=l('bankGood-'+me.id+'-viewHide');
565
me.graphIconL=l('bankGood-'+me.id+'-graphIcon');
566
567
AddEvent(l('bankGood-'+i),'mouseover',function(i){return function(e){
568
if (M.hoverOnGood!=i) {M.hoverOnGood=i;M.toRedraw=2;}
569
}}(i));
570
AddEvent(l('bankGood-'+i),'mouseout',function(i){return function(e){
571
if (M.hoverOnGood==i) {M.hoverOnGood=-1;M.toRedraw=2;}
572
}}(i));
573
574
AddEvent(l('bankGood-'+i+'-viewHide'),'click',function(i){return function(e){
575
if (Game.keys[16])//solo with shift-click
576
{
577
var mode=M.goodsById[i].hidden;
578
for (var ii=0;ii<M.goodsById.length;ii++)
579
{
580
if (ii==i) M.goodsById[ii].hidden=!mode;
581
else if (!mode) M.goodsById[ii].hidden=false;
582
else M.goodsById[ii].hidden=true;
583
M.updateGoodStyle(ii);
584
}
585
}
586
else
587
{
588
if (M.goodsById[i].hidden) M.goodsById[i].hidden=false;
589
else M.goodsById[i].hidden=true;
590
M.updateGoodStyle(i);
591
}
592
M.checkGraphScale();
593
M.toRedraw=2;
594
PlaySound('snd/tick.mp3');
595
}}(i));
596
597
AddEvent(l('bankGood-'+i+'_1'),'click',function(i){return function(e){
598
if (M.buyGood(i,1)) Game.SparkleOn(e.target);
599
}}(i));
600
AddEvent(l('bankGood-'+i+'_-1'),'click',function(i){return function(e){
601
if (M.sellGood(i,1)) Game.SparkleOn(e.target);
602
}}(i));
603
AddEvent(l('bankGood-'+i+'_10'),'click',function(i){return function(e){
604
if (M.buyGood(i,10)) Game.SparkleOn(e.target);
605
}}(i));
606
AddEvent(l('bankGood-'+i+'_-10'),'click',function(i){return function(e){
607
if (M.sellGood(i,10)) Game.SparkleOn(e.target);
608
}}(i));
609
AddEvent(l('bankGood-'+i+'_100'),'click',function(i){return function(e){
610
if (M.buyGood(i,100)) Game.SparkleOn(e.target);
611
}}(i));
612
AddEvent(l('bankGood-'+i+'_-100'),'click',function(i){return function(e){
613
if (M.sellGood(i,100)) Game.SparkleOn(e.target);
614
}}(i));
615
AddEvent(l('bankGood-'+i+'_Max'),'click',function(i){return function(e){
616
if (M.buyGood(i,10000)) Game.SparkleOn(e.target);
617
}}(i));
618
AddEvent(l('bankGood-'+i+'_-All'),'click',function(i){return function(e){
619
if (M.sellGood(i,10000)) Game.SparkleOn(e.target);
620
}}(i));
621
}
622
623
624
625
AddEvent(M.graph,'mousemove',function(e){
626
//get which graph line the mouse is over
627
var x=e.layerX;
628
var y=e.layerY;
629
var width=M.graph.width;
630
var height=M.graph.height;
631
var span=Math.max(4,Math.ceil(width/65));//6;
632
var isOnLine=-1;
633
var rows=Math.ceil(width/span);
634
bankGraphMouseDetect:
635
for (var i=M.goodsById.length-1;i>=0;i--)
636
{
637
var id=i;
638
var me=M.goodsById[id];
639
if (me.hidden || !me.active) continue;
640
for (var iR=0;iR<rows;iR++)
641
{
642
if (me.vals.length>=(2+iR))
643
{
644
var min=Math.max(me.vals[0+iR],me.vals[1+iR]);
645
var max=Math.abs((me.vals[0+iR]-me.vals[1+iR]));
646
if (x>=width-span*iR-span-2 && x<=width-span*iR+2 && y>=height-min*M.graphScale-6 && y<=height-min*M.graphScale+Math.max(3,max*M.graphScale)+6)
647
{
648
isOnLine=i;
649
Game.tooltip.draw(0,'<div style="width:128px;font-size:10px;text-align:center;"><div class="icon" style="pointer-events:none;display:inline-block;transform:scale(0.5);margin:-16px -18px -16px -14px;vertical-align:middle;background-position:'+(-me.icon[0]*48)+'px '+(-me.icon[1]*48)+'px;"></div> <b>'+me.name+'</b><br>valued at <b>$'+Beautify(me.vals[0+iR],2)+'</b><br>'+Game.sayTime((iR+1)*M.secondsPerTick*Game.fps)+' ago</div>','top');
650
break bankGraphMouseDetect;
651
}
652
}
653
}
654
}
655
if (isOnLine!=M.hoverOnGood)
656
{
657
M.hoverOnGood=isOnLine;
658
if (M.hoverOnGood!=-1)
659
{
660
M.graph.style.cursor='pointer';
661
}
662
else
663
{
664
M.graph.style.cursor='auto';
665
Game.tooltip.shouldHide=1;
666
}
667
M.toRedraw=2;
668
}
669
});
670
AddEvent(M.graph,'mouseout',function(e){
671
M.graph.style.cursor='auto';
672
if (M.hoverOnGood!=-1) {M.hoverOnGood=-1;M.toRedraw=2;}
673
Game.tooltip.shouldHide=1;
674
});
675
676
M.reset();
677
}
678
M.onResize=function()
679
{
680
M.graph.width=l('bankContent').offsetWidth-22;
681
M.graph.height=300;//l('bankContent').offsetHeight;
682
var ctx=M.graphCtx;
683
ctx.fillStyle='#fff';
684
ctx.fillRect(0,0,M.graph.width,M.graph.height);
685
M.checkGraphScale();
686
M.toRedraw=2;
687
}
688
M.save=function()
689
{
690
//output cannot use ",", ";" or "|"
691
var str=''+
692
parseInt(M.officeLevel)+':'+
693
parseInt(M.brokers)+':'+
694
parseInt(M.graphLines)+':'+
695
parseFloat(M.profit)+':'+
696
parseInt(M.graphCols)+':'+
697
' ';
698
for (var iG=0;iG<M.goodsById.length;iG++)
699
{
700
var it=M.goodsById[iG];
701
str+=parseInt(it.val*100)+':'+parseInt(it.mode)+':'+parseInt(it.d*100)+':'+parseInt(it.dur)+':'+parseInt(it.stock)+':'+parseInt(it.hidden?1:0)+':'+parseInt(it.last)+'!';
702
}
703
str+=' '+parseInt(M.parent.onMinigame?'1':'0');
704
return str;
705
}
706
M.load=function(str)
707
{
708
//interpret str; called after .init
709
//note : not actually called in the Game's load; see "minigameSave" in main.js
710
if (!str) return false;
711
var i=0;
712
var spl=str.split(' ');
713
var spl2=spl[i++].split(':');
714
var i2=0;
715
M.officeLevel=parseInt(spl2[i2++]||M.officeLevel);
716
M.brokers=parseInt(spl2[i2++]||M.brokers);
717
M.graphLines=parseInt(spl2[i2++]||M.graphLines);
718
M.profit=parseFloat(spl2[i2++]||0);
719
M.graphCols=parseInt(spl2[i2++]||M.graphCols);M.setCols();
720
M.tickT=0;
721
722
var goods=spl[i++].split('!');
723
for (var iG=0;iG<M.goodsById.length;iG++)
724
{
725
if (!goods[iG]) continue;
726
var it=M.goodsById[iG];
727
var itData=goods[iG].split(':');
728
it.val=parseInt(itData[0])/100;
729
it.mode=parseInt(itData[1]);
730
it.d=parseInt(itData[2])/100;
731
it.vals=[it.val,it.val-it.d];
732
it.dur=parseInt(itData[3]);
733
it.stock=parseInt(itData[4]);
734
it.hidden=parseInt(itData[5])?true:false;
735
it.active=false;
736
it.last=parseInt(itData[6]||0);
737
if (it.building.highest>0) it.active=true;
738
if (it.l) M.updateGoodStyle(it.id);
739
}
740
M.onResize();
741
742
var on=parseInt(spl[i++]||0);if (on && Game.ascensionMode!=1) M.parent.switchMinigame(1);
743
}
744
M.reset=function(hard)
745
{
746
M.tickT=0;
747
M.toRedraw=0;
748
M.officeLevel=0;
749
M.brokers=0;
750
751
if (hard) {M.graphLines=1;M.graphCols=0;}M.setCols();
752
M.hoverOnGood=-1;
753
M.ticks=0;
754
M.lastTickDrawn=0;
755
M.profit=0;
756
757
for (var i=0;i<M.goodsById.length;i++)
758
{
759
var it=M.goodsById[i];
760
it.stock=0;
761
it.mode=choose([0,1,1,2,2,3,4,5]);
762
it.dur=Math.floor(10+Math.random()*990);
763
it.val=M.getRestingVal(it.id);
764
it.d=Math.random()*0.2-0.1;
765
it.vals=[it.val,it.val-it.d];
766
it.hidden=true;
767
it.active=false;
768
it.last=0;//0 : didn't buy or sell this tick; 1 : bought this tick; 2 : sold this tick
769
if (it.l) M.updateGoodStyle(it.id);
770
}
771
M.onResize();
772
for (var i=0;i<15;i++)
773
{
774
M.tick();
775
}
776
}
777
778
M.profit=0;
779
780
M.ticks=0;
781
M.lastTickDrawn=0;
782
M.secondsPerTick=60;//1 tick every minute
783
M.tick=function()
784
{
785
for (var i=0;i<M.goodsById.length;i++)
786
{
787
var me=M.goodsById[i];
788
me.last=0;
789
790
me.d*=0.97;
791
792
if (me.mode==0) {me.d*=0.95;me.d+=0.05*(Math.random()-0.5);}
793
else if (me.mode==1) {me.d*=0.99;me.d+=0.05*(Math.random()-0.1);}
794
else if (me.mode==2) {me.d*=0.99;me.d-=0.05*(Math.random()-0.1);}
795
else if (me.mode==3) {me.d+=0.15*(Math.random()-0.1);me.val+=Math.random();}
796
else if (me.mode==4) {me.d-=0.15*(Math.random()-0.1);me.val-=Math.random();}
797
else if (me.mode==5) me.d+=0.3*(Math.random()-0.5);
798
799
me.val+=(M.getRestingVal(me.id)-me.val)*0.02;
800
me.val+=(Math.random()-0.5)*0.4;
801
me.d+=0.1*(Math.random()-0.5);
802
if (Math.random()<0.1) me.val+=(Math.random()-0.5)*3;
803
if (Math.random()<0.1) me.d+=(Math.random()-0.5)*0.3;
804
if (me.mode==5)
805
{
806
if (Math.random()<0.5) me.val+=(Math.random()-0.5)*10;
807
if (Math.random()<0.2) me.d=(Math.random()-0.5)*2;
808
}
809
if (me.mode==3 && Math.random()<0.3) {me.d+=(Math.random()-0.5)*0.1;me.val+=(Math.random()-0.7)*10;}
810
if (me.mode==3 && Math.random()<0.03) {me.mode=4;}
811
if (me.mode==4 && Math.random()<0.3) {me.d+=(Math.random()-0.5)*0.1;me.val+=(Math.random()-0.3)*10;}
812
813
if (me.val>(100+(Game.Objects['Bank'].level-1)*3) && me.d>0) me.d*=0.9;
814
815
me.val+=me.d;
816
/*if (me.val<=0 && me.d<0)
817
{
818
me.d*=0.75;
819
if (me.mode==4 && Math.random()<0.05) me.mode=2;
820
}
821
if (me.val<2) me.val+=(2-me.val)*0.1;
822
me.val=Math.max(me.val,0.01);*/
823
/*var cutoff=5;
824
var minvalue=1;
825
if (me.val<=cutoff)
826
{
827
var s=Math.max(0,me.val)/cutoff;
828
me.val=((2*minvalue-cutoff)*s+(2*cutoff-3*minvalue))*s*s+minvalue;//low soft-cap between 1 and 5
829
}*/
830
if (me.val<5) me.val+=(5-me.val)*0.5;
831
if (me.val<5 && me.d<0) me.d*=0.95;
832
me.val=Math.max(me.val,1);
833
834
me.vals.unshift(me.val);
835
if (me.vals.length>65) me.vals.pop();
836
837
me.dur--;
838
//if (Math.random()<1/me.dur)
839
if (me.dur<=0)
840
{
841
me.dur=Math.floor(10+Math.random()*990);
842
if (Math.random()<0.7 && (me.mode==3 || me.mode==4)) me.mode=5;
843
else me.mode=choose([0,1,1,2,2,3,4,5]);
844
}
845
}
846
M.checkGraphScale();
847
M.toRedraw=Math.max(M.toRedraw,1);
848
M.ticks++;
849
}
850
851
M.tickT=0;
852
M.logic=function()
853
{
854
//run each frame
855
856
M.tickT++;
857
if (M.tickT>=Game.fps*M.secondsPerTick)
858
{
859
M.tickT=0;
860
M.tick();
861
}
862
863
if (Game.T%10==0)
864
{
865
var doResize=false;
866
for (var i=0;i<M.goodsById.length;i++)
867
{
868
var me=M.goodsById[i];
869
870
if (!me.active && me.building.highest>0) {me.active=true;me.hidden=false;M.toRedraw=2;if (me.l){M.updateGoodStyle(me.id);doResize=true;}}
871
}
872
if (doResize) M.onResize();
873
}
874
}
875
M.hoverOnGood=-1;
876
M.graphScale=10;//how many units 1 vertical pixel represents
877
M.graphLines=1;
878
M.graphCols=0;
879
M.checkGraphScale=function()
880
{
881
//check if the height of the graph and the highest good value
882
//if the scale is too narrow to accommodate all goods, zoom out
883
//if the scale is too wide, zoom back in (but with a higher margin)
884
//this is done in increments of 50
885
var currentSize=M.graph.height;
886
if (!currentSize) return false;
887
var maxVal=0;
888
for (var i=0;i<M.goodsById.length;i++)
889
{
890
var me=M.goodsById[i];
891
if (me.hidden) continue;
892
//if (me.id==0) me.vals[0]=50+50*Math.sin(Date.now()*0.0002+me.id);
893
for (var ii=0;ii<me.vals.length;ii++)
894
{
895
maxVal=Math.max(maxVal,me.vals[ii]);
896
}
897
}
898
var neededSize=Math.max(maxVal,10)+10;
899
var newScale=(Math.max(1,currentSize/neededSize));
900
var dif=(currentSize/M.graphScale)/neededSize;
901
var dif=(currentSize/M.graphScale)-neededSize;
902
if (M.graphScale!=newScale && dif>5 || dif<-5)
903
{
904
M.graphScale=newScale;
905
M.toRedraw=2;
906
}
907
}
908
M.colBases=[
909
{bg:'#fff',line1:'#eee',line2:'#ccc',low:'#ce2549',high:'#79c600',highlight:'#000'},
910
{bg:'#1f2836',line1:'#273545',line2:'#384b61',low:'#3153a3',high:'#c4971a',highlight:'#a6abad'},
911
];
912
M.setCols=function()
913
{
914
if (!M.colBases[M.graphCols]) M.graphCols=0;
915
M.cols=M.colBases[M.graphCols];
916
if (l('bankGraphBox'))
917
{
918
l('bankGraphBox').style.backgroundColor=M.cols.bg;
919
l('bankGraphBox').style.color=M.cols.highlight;
920
}
921
if (M.graph) M.graph.style.backgroundColor=M.cols.bg;
922
}
923
M.setCols();
924
M.drawGraph=function(full)
925
{
926
/*
927
what this does :
928
scroll the graph left by (span)
929
draw more graph data to the right
930
if (full), do a full redraw instead
931
*/
932
var ctx=M.graphCtx;
933
var width=M.graph.width;
934
var span=Math.max(4,Math.ceil(width/65));//6;
935
var height=M.graph.height;
936
ctx.globalAlpha=1;
937
if (!full) ctx.drawImage(M.graph,-span,0);
938
ctx.fillStyle=M.cols.bg;
939
if (full) ctx.fillRect(0,0,width,height);
940
else ctx.fillRect(width-span,0,span,height);
941
ctx.lineWidth=2;
942
ctx.globalAlpha=1;
943
944
var rows=(full?Math.ceil(width/span):1);
945
946
for (var i=0;i<height/M.graphScale;i+=2)//horizontal lines (1 every 2 units)
947
{
948
if (i%10!=0) ctx.fillStyle=M.cols.line1; else ctx.fillStyle=M.cols.line2;
949
ctx.fillRect(width-span*rows,height-Math.floor(i*M.graphScale),span*rows,1);
950
}
951
for (var iR=0;iR<rows;iR++)//vertical lines (1 every 10 ticks)
952
{
953
if ((iR-M.ticks)%10!=0) continue;
954
if ((iR-M.ticks)%60!=0) ctx.fillStyle=M.cols.line1; else ctx.fillStyle=M.cols.line2;
955
ctx.fillRect(width-span*iR-1,0,1,height);
956
}
957
for (var i=0;i<M.goodsById.length+1;i++)
958
{
959
//some trickery going on here to always display the M.hoverOnGood bars above the others
960
var id=i;
961
if (i==M.goodsById.length) id=M.hoverOnGood;
962
else if (i==M.hoverOnGood) continue;
963
if (id==-1) continue;
964
var me=M.goodsById[id];
965
if (me.hidden || !me.active) continue;
966
for (var iR=0;iR<rows;iR++)
967
{
968
if (me.vals.length>=(2+iR))
969
{
970
var delta=M.goodDelta(me.id,iR);
971
972
if (M.graphLines==0)
973
{
974
var min=Math.max(me.vals[0+iR],me.vals[1+iR]);
975
var max=Math.abs((me.vals[0+iR]-me.vals[1+iR]));
976
var min2=Math.abs(Math.sin((M.ticks-iR)*11+id*137))*max*2;
977
var max2=min2+Math.abs(Math.sin((M.ticks-iR)*13+id*139))*max*2;
978
if (M.hoverOnGood==id)
979
{
980
ctx.fillStyle=M.cols.highlight;
981
ctx.fillRect(width-span*iR-span-1,Math.floor(height-min*M.graphScale)-1,span+1,Math.max(3,Math.ceil(max*M.graphScale))+2);
982
}
983
ctx.fillStyle=delta>0?M.cols.high:M.cols.low;
984
ctx.fillRect(width-span*iR-span,Math.floor(height-min*M.graphScale),span-1,Math.max(3,Math.ceil(max*M.graphScale)));
985
ctx.fillRect(width-span*iR-span/2-1,Math.floor(height-(min+min2)*M.graphScale),1,Math.max(3,Math.ceil((max+max2)*M.graphScale)));
986
}
987
else
988
{
989
if (M.hoverOnGood==id)
990
{
991
ctx.lineWidth=4;
992
ctx.strokeStyle=M.cols.highlight;
993
ctx.beginPath();
994
ctx.moveTo(width-span*iR-span-1,Math.floor(height-me.vals[1+iR]*M.graphScale)+0.5);
995
ctx.lineTo(width-span*iR-1,Math.floor(height-me.vals[0+iR]*M.graphScale)+0.5);
996
ctx.stroke();
997
ctx.lineWidth=2;
998
}
999
ctx.strokeStyle=delta>0?M.cols.high:M.cols.low;
1000
ctx.beginPath();
1001
ctx.moveTo(width-span*iR-span-1,Math.floor(height-me.vals[1+iR]*M.graphScale)+0.5);
1002
ctx.lineTo(width-span*iR-1,Math.floor(height-me.vals[0+iR]*M.graphScale)+0.5);
1003
ctx.stroke();
1004
}
1005
}
1006
}
1007
}
1008
}
1009
M.draw=function()
1010
{
1011
//run each draw frame
1012
1013
if (Game.drawT%2==0 && M.toRedraw>0 && M.graph && M.graphCtx)
1014
{
1015
if (M.lastTickDrawn<M.ticks-1) M.toRedraw=2;
1016
M.lastTickDrawn=M.ticks;
1017
M.drawGraph(M.toRedraw==2?true:false);
1018
1019
for (var i=0;i<M.goodsById.length;i++)
1020
{
1021
var me=M.goodsById[i];
1022
var val=M.goodDelta(me.id);
1023
me.symbolNumL.innerHTML=val+''+(val==Math.floor(val)?'.00':(val*10)==Math.floor(val*10)?'0':'')+'%'/*+', '+['stable','slow rise','slow fall','fast rise','fast fall','chaotic'][me.mode]*/;
1024
if (val>=0) {me.symbolNumL.classList.add('bankSymbolUp');me.symbolNumL.classList.remove('bankSymbolDown');}
1025
else if (val<0) {me.symbolNumL.classList.remove('bankSymbolUp');me.symbolNumL.classList.add('bankSymbolDown');}
1026
else {me.symbolNumL.classList.remove('bankSymbolUp');me.symbolNumL.classList.remove('bankSymbolDown');}
1027
1028
me.valL.innerHTML='$'+Beautify(me.val,2);
1029
me.stockL.innerHTML=Beautify(me.stock);
1030
//if (me.stock>0) me.stockL.style.color='#fff';
1031
//else me.stockL.style.removeProperty('color');
1032
if (me.stock>0) me.stockBoxL.classList.add('green');
1033
else me.stockBoxL.classList.remove('green');
1034
me.stockMaxL.innerHTML='/'+Beautify(M.getGoodMaxStock(me));
1035
1036
me.graphIconL.style.transform='translate(-8px,'+Math.floor((M.graph.height-me.vals[0]*M.graphScale))+'px) scale(0.5)';
1037
}
1038
M.toRedraw=0;
1039
}
1040
if (Game.drawT%10==0)
1041
{
1042
var office=M.offices[M.officeLevel];
1043
l('bankOfficeIcon').style.backgroundPosition=(-office.icon[0]*48)+'px '+(-office.icon[1]*48)+'px';
1044
l('bankOfficeName').innerHTML=office.name;
1045
l('bankOfficeUpgrade').innerHTML='Upgrade ('+office.cost[0]+' cursors)';
1046
if (!office.cost) l('bankOfficeUpgrade').style.display='none';
1047
else
1048
{
1049
l('bankOfficeUpgrade').style.removeProperty('display');
1050
if (Game.Objects['Cursor'].amount>=office.cost[0] && Game.Objects['Cursor'].level>=office.cost[1]) l('bankOfficeUpgrade').classList.remove('bankButtonOff');
1051
else l('bankOfficeUpgrade').classList.add('bankButtonOff');
1052
}
1053
l('bankBrokersText').innerHTML=M.brokers==0?'no brokers':M.brokers==1?'1 broker':(M.brokers+' brokers');
1054
if (M.brokers<M.getMaxBrokers() && Game.cookies>=M.getBrokerPrice()) l('bankBrokersBuy').classList.remove('bankButtonOff');
1055
else l('bankBrokersBuy').classList.add('bankButtonOff');
1056
1057
if (M.officeLevel<=1) l('bankLoan1').style.display='none';
1058
else l('bankLoan1').style.removeProperty('display');
1059
if (M.officeLevel<=3) l('bankLoan2').style.display='none';
1060
else l('bankLoan2').style.removeProperty('display');
1061
if (M.officeLevel<=4) l('bankLoan3').style.display='none';
1062
else l('bankLoan3').style.removeProperty('display');
1063
1064
for (var id=1;id<4;id++)
1065
{
1066
if (Game.hasBuff('Loan '+id) || Game.hasBuff('Loan '+id+' (interest)')) l('bankLoan'+id).classList.add('bankButtonOff');
1067
else l('bankLoan'+id).classList.remove('bankButtonOff');
1068
}
1069
1070
var it=l('bankBalance');
1071
it.innerHTML=(M.profit<0?'-':'')+'$'+Beautify(Math.abs(M.profit),2);
1072
if (M.profit>0) {it.classList.add('bankSymbolUp');it.classList.remove('bankSymbolDown');}
1073
else if (M.profit<0) {it.classList.add('bankSymbolDown');it.classList.remove('bankSymbolUp');}
1074
1075
l('bankNextTick').innerHTML='Next tick in '+Game.sayTime((Game.fps*M.secondsPerTick)-M.tickT+30,-1)+'.';
1076
}
1077
}
1078
M.init(l('rowSpecial'+M.parent.id));
1079
}
1080
var M=0;
1081