Advertisement
Guest User

dank memes for legacy orteil

a guest
Mar 27th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 147.17 KB | None | 0 0
  1. G.AddData({
  2. name:'Default dataset',
  3. author:'Orteil',
  4. desc:'The default dataset for Legacy.',
  5. engineVersion:1,
  6. manifest:0,
  7. func:function()
  8. {
  9. /*
  10. Note : unlike some other strategy games, this dataset does not attempt to replicate Earth human history. In fact, care has been taken not to mention any existing civilizations; other topics consciously avoided are the player's species (no "mankind" or "humans") and gender ("they" is used when referring to any single individual).
  11. Similarly, technologies do not necessarily follow the order in which they were invented in real life, if it makes sense for them to do so.
  12. Mods should feel free to follow along these guidelines or to implement real-world civilizations, species, and genders into the game if they wish to.
  13. -Playable species may be added as a game concept at some point in the future.
  14. */
  15.  
  16. /*=====================================================================================
  17. PROPS & FUNCTIONS
  18. =======================================================================================*/
  19.  
  20. G.props['fastTicksOnResearch']=150;
  21.  
  22. G.funcs['new game blurb']=function()
  23. {
  24. var str=
  25. '<b>Your tribe :</b><div class="thingBox">'+
  26. G.textWithTooltip('<div class="icon freestanding" style="'+G.getIconUsedBy(G.getRes('adult'))+'"></div><div class="freelabel">x5</div>','5 Adults')+
  27. G.textWithTooltip('<div class="icon freestanding" style="'+G.getIconUsedBy(G.getRes('elder'))+'"></div><div class="freelabel">x1</div>','1 Elder')+
  28. G.textWithTooltip('<div class="icon freestanding" style="'+G.getIconUsedBy(G.getRes('child'))+'"></div><div class="freelabel">x2</div>','2 Children')+
  29. G.textWithTooltip('<div class="icon freestanding" style="'+G.getIconUsedBy(G.getRes('herb'))+'"></div><div class="freelabel">x250</div>','250 Herbs')+
  30. G.textWithTooltip('<div class="icon freestanding" style="'+G.getIconUsedBy(G.getRes('water'))+'"></div><div class="freelabel">x250</div>','250 Water')+
  31. '</div>'+
  32. '<div class="par fancyText bitBiggerText">Your tribe finds a place to settle in the wilderness.<br>Resources are scarce, and everyone starts foraging.</div>'+
  33. '<div class="par fancyText bitBiggerText">You emerge as the tribe\'s leader. They call you :</div>';
  34. return str;
  35. }
  36.  
  37. G.funcs['new game']=function()
  38. {
  39. var str='Your name is '+G.getName('ruler')+''+(G.getName('ruler').toLowerCase()=='orteil'?' <i>(but that\'s not you, is it?)</i>':'')+', ruler of '+G.getName('civ')+'. Your tribe is primitive, but full of hope.<br>The first year of your legacy has begun. May it stand the test of time.';
  40. G.Message({type:'important tall',text:str,icon:[0,3]});
  41. }
  42. G.funcs['game over']=function()
  43. {
  44. var str=G.getName('civ')+' is no more, and your legacy is but a long-lost memory, merely a sidenote in a history book.<br>Everyone is dead.';
  45. G.Message({type:'bad',text:str,icon:[5,4]});
  46. }
  47. G.funcs['game loaded']=function()
  48. {
  49. G.Message({type:'important tall',text:'Welcome back, '+G.getName('ruler')+', ruler of '+G.getName('civ')+'.',icon:[0,3]});
  50. }
  51. G.funcs['new year']=function()
  52. {
  53. if (G.on)
  54. {
  55. var str='';
  56. str+='It is now the year '+(G.year+1)+'.<br>';
  57. str+='Report for last year :<br>';
  58. str+='&bull; Births : '+B(G.getRes('born this year').amount)+'<br>';
  59. str+='&bull; Deaths : '+B(G.getRes('died this year').amount)+'<br>';
  60. G.getRes('born this year').amount=0;
  61. G.getRes('died this year').amount=0;
  62. G.Message({type:'important',text:str,icon:[0,3]});
  63.  
  64. //influence trickle
  65. if (G.getRes('influence').amount<=G.getRes('authority').amount-1)G.gain('influence',1);
  66. }
  67. }
  68.  
  69. G.props['new day lines']=[
  70. 'Creatures are lurking.',
  71. 'Danger abounds.',
  72. 'Wild beasts are on the prowl.',
  73. 'Large monsters roam, unseen.',
  74. 'This is a cold night.',
  75. 'No sound but the low hum of a gray sky.',
  76. 'The darkness is terrifying.',
  77. 'Clouds twist in complicated shapes.',
  78. 'It is raining.',
  79. 'Dark birds caw ominously in the distance.',
  80. 'There is a storm on the horizon.',
  81. 'The night is unforgiving.',
  82. 'Creatures crawl in the shadows.',
  83. 'A stream burbles quietly nearby.',
  84. 'In the distance, a prey falls to a pack of beasts.',
  85. 'An unexplained sound echoes on the horizon.',
  86. 'Everything stands still in the morning air.',
  87. 'A droning sound fills the sky.',
  88. 'The night sky sparkles, its mysteries unbroken.',
  89. 'Dry bones crack and burst underfoot.',
  90. 'Wild thorns scratch the ankles.',
  91. 'Something howls in the distance.',
  92. 'Strange ashes snow down slowly from far away.',
  93. 'A blood-curdling wail is heard.',
  94. 'Unknown creatures roll and scurry in the dirt.',
  95. 'The air carries a peculiar smell today.',
  96. 'Wild scents flow in from elsewhere.',
  97. 'The dust is oppressive.',
  98. 'An eerie glow from above illuminates the night.',
  99. 'Distant lands lay undisturbed.'
  100. ];
  101.  
  102. shuffle(G.props['new day lines']);
  103. G.funcs['new day']=function()
  104. {
  105. if (G.on)
  106. {
  107. if (G.getSetting('atmosphere') && Math.random()<0.01)
  108. {
  109. //show a random atmospheric message occasionally on new days
  110. //we pick one of the first 5 lines in the array, then push that line back at the end; this means we get a semi-random stream of lines with no frequent repetitions
  111. var i=Math.floor(Math.random()*5);
  112. var msg=G.props['new day lines'].splice(i,1)[0];
  113. G.props['new day lines'].push(msg);
  114. G.Message({text:msg});
  115. }
  116.  
  117. //possibility to gain random traits everyday
  118. for (var i in G.trait)
  119. {
  120. var me=G.trait[i];
  121. if (!G.has(me.name))
  122. {
  123. if (Math.random()<1/(me.chance*300))
  124. {
  125. if (G.checkReq(me.req) && G.testCost(me.cost,1))
  126. {
  127. G.doCost(me.cost,1);
  128. G.gainTrait(me);
  129. G.Message({type:'important tall',text:'Your people have adopted the trait <b>'+me.displayName+'</b>.',icon:me.icon});
  130. }
  131. }
  132. }
  133. }
  134.  
  135. G.trackedStat=Math.max(G.trackedStat,G.getRes('population').amount);
  136. }
  137. }
  138.  
  139. G.funcs['tracked stat str']=function()
  140. {
  141. return 'Most population ruled';
  142. }
  143.  
  144. G.funcs['civ blurb']=function()
  145. {
  146. var str='';
  147. str+='<div class="fancyText shadowed">'+
  148. '<div class="barred infoTitle">The land of '+G.getName('civ')+'</div>'+
  149. '<div class="barred">ruler : '+G.getName('ruler')+'</div>';
  150. var toParse='';
  151. var pop=G.getRes('population').amount;
  152. if (pop>0)
  153. {
  154. toParse+='Population : <b>'+B(pop)+' [population,'+G.getName((pop==1?'inhab':'inhabs'))+']</b>//';
  155. var stat=G.getRes('happiness').amount/pop;
  156. var text='unknown';if (stat<=-200) text='miserable'; else if (stat<=-100) text='mediocre'; else if (stat<=-50) text='low'; else if (stat<50) text='average'; else if (stat<100) text='pleasant'; else if (stat<=200) text='high'; else if (stat>=200) text='euphoric';
  157. toParse+='Happiness : <b>'+text+'</b>//';
  158. var stat=G.getRes('health').amount/pop;
  159. var text='unknown';if (stat<=-200) text='dreadful'; else if (stat<=-100) text='sickly'; else if (stat<=-50) text='low'; else if (stat<50) text='average'; else if (stat<100) text='good'; else if (stat<=200) text='gleaming'; else if (stat>=200) text='examplary';
  160. toParse+='Health : <b>'+text+'</b>//';
  161. }
  162. else toParse+='All '+G.getName('inhabs')+' have died out.';
  163. str+=G.parse(toParse);
  164. str+='</div>';
  165. return str;
  166. }
  167.  
  168. G.funcs['found tile']=function(tile)
  169. {
  170. G.Message({type:'good',mergeId:'foundTile',textFunc:function(args){
  171. if (args.count==1) return 'Our explorers have found a new tile : <b>'+args.tile.land.displayName+'</b>.';
  172. else return 'Our explorers have found '+B(args.count)+' new tiles; the latest is <b>'+args.tile.land.displayName+'</b>.';
  173. },args:{tile:tile,count:1},icon:[14,4]});
  174.  
  175. }
  176.  
  177. G.funcs['production multiplier']=function()
  178. {
  179. var mult=1;
  180. if (G.getRes('population').amount>0)
  181. {
  182. var happiness=(G.getRes('happiness').amount/G.getRes('population').amount)/100;
  183. happiness=Math.max(-2,Math.min(2,happiness));
  184. if (happiness>=0) mult=(Math.pow(2,happiness+1)/2);
  185. else mult=1/(Math.pow(2,-happiness+1)/2);
  186. }
  187. return mult;
  188. }
  189.  
  190. /*=====================================================================================
  191. RESOURCES
  192. =======================================================================================*/
  193. G.resCategories={
  194. 'main':{
  195. name:'Essentials',
  196. base:[],
  197. side:['population','worker','happiness','health','land','coin'],
  198. },
  199. 'demog':{
  200. name:'Demographics',
  201. base:['baby','child','adult','elder','worker','sick','wounded'],
  202. side:['population','housing','corpse','burial space'],
  203. },
  204. 'food':{
  205. name:'Food & Water',
  206. base:[],
  207. side:['food','spoiled food','water','muddy water','food storage'],
  208. },
  209. 'build':{
  210. name:'Crafting & Construction',
  211. base:[],
  212. side:['archaic building materials','basic building materials','advanced building materials','precious building materials','material storage'],
  213. },
  214. 'gear':{
  215. name:'Gear',
  216. base:[],
  217. side:[],
  218. },
  219. 'misc':{
  220. name:'Miscellaneous',
  221. base:[],
  222. },
  223. };
  224.  
  225. new G.Res({name:'died this year',hidden:true});
  226. new G.Res({name:'born this year',hidden:true});
  227.  
  228. var numbersInfo='//The number on the left is how many are in use, while the number on the right is how many you have in total.';
  229.  
  230. new G.Res({
  231. name:'coin',
  232. displayName:'Coins',
  233. desc:'[#coin,Currency] has a multitude of uses, from paying the upkeep on units to purchasing various things.//Before the invention of currency, [food] is used instead.',
  234. icon:[13,1],
  235. replacement:'food',
  236. tick:function(me,tick)
  237. {
  238. if (me.replacement) me.hidden=true; else me.hidden=false;
  239. }
  240. });
  241.  
  242. new G.Res({
  243. name:'population',
  244. desc:'Your [population] represents everyone living under your rule. These are the people that look to you for protection, survival, and glory.',
  245. meta:true,
  246. visible:true,
  247. icon:[0,3],
  248. tick:function(me,tick)
  249. {
  250. if (me.amount>0)
  251. {
  252. //note : we also sneak in some stuff unrelated to population here
  253. //policy ticks
  254. if (tick%50==0)
  255. {
  256. var rituals=['fertility rituals','harvest rituals','flower rituals','wisdom rituals'];
  257. for (var i in rituals)
  258. {
  259. if (G.checkPolicy(rituals[i])=='on')
  260. {
  261. if (G.getRes('faith').amount<=0) G.setPolicyModeByName(rituals[i],'off');
  262. else G.lose('faith',1,'rituals');
  263. }
  264. }
  265. }
  266.  
  267. var deathUnhappinessMult=1;
  268. if (G.has('fear of death')) deathUnhappinessMult*=2;
  269. if (G.has('belief in the afterlife')) deathUnhappinessMult/=2;
  270. if (tick%3==0 && G.checkPolicy('disable eating')=='off')
  271. {
  272. //drink water
  273. var toConsume=0;
  274. var weights={'baby':0.1,'child':0.3,'adult':0.5,'elder':0.5,'sick':0.4,'wounded':0.4};
  275. for (var i in weights)
  276. {toConsume+=G.getRes(i).amount*weights[i];}
  277. var rations=G.checkPolicy('water rations');
  278. if (rations=='none') {toConsume=0;G.gain('happiness',-me.amount*3,'water rations');G.gain('health',-me.amount*2,'water rations');}
  279. else if (rations=='meager') {toConsume*=0.5;G.gain('happiness',-me.amount*1,'water rations');G.gain('health',-me.amount*0.5,'water rations')}
  280. else if (rations=='plentiful') {toConsume*=1.5;G.gain('happiness',me.amount*1,'water rations');}
  281. toConsume=randomFloor(toConsume);
  282. var lacking=toConsume-G.lose('water',toConsume,'drinking');
  283. if (rations=='none') lacking=me.amount*0.5;
  284. if (lacking>0)//are we out of water?
  285. {
  286. //resort to muddy water
  287. if (rations!='none' && G.checkPolicy('drink muddy water')=='on') lacking=lacking-G.lose('muddy water',lacking,'drinking');
  288. if (lacking>0 && G.checkPolicy('disable aging')=='off')//are we also out of muddy water?
  289. {
  290. G.gain('happiness',-lacking*5,'no water');
  291. //die off
  292. var toDie=(lacking/5)*0.05;
  293. if (G.year<1) toDie/=5;//less deaths in the first year
  294. var died=0;
  295. var weights={'baby':0.1,'child':0.2,'adult':0.5,'elder':1,'sick':0.3,'wounded':0.3};//the elderly are the first to starve off
  296. var sum=0;for (var i in weights){sum+=weights[i];}for (var i in weights){weights[i]/=sum;}//normalize
  297. for (var i in weights){var ratio=(G.getRes(i).amount/me.amount);weights[i]=ratio+(1-ratio)*weights[i];}
  298. for (var i in weights)
  299. {var n=G.lose(i,randomFloor((Math.random()*0.8+0.2)*toDie*weights[i]),'dehydration');died+=n;}
  300. G.gain('corpse',died,'dehydration');
  301. G.gain('happiness',-died*20*deathUnhappinessMult,'dehydration');
  302. G.getRes('died this year').amount+=died;
  303. if (died>0) G.Message({type:'bad',mergeId:'diedDehydration',textFunc:function(args){return B(args.died)+' '+(args.died==1?'person':'people')+' died from dehydration.';},args:{died:died},icon:[5,4]});
  304. }
  305. }
  306.  
  307. //eat food
  308. var toConsume=0;
  309. var consumeMult=1;
  310. var happinessAdd=0;
  311. if (G.has('culture of moderation')) {consumeMult*=0.85;happinessAdd-=0.1;}
  312. else if (G.has('joy of eating')) {consumeMult*=1.15;happinessAdd+=0.1;}
  313. var weights={'baby':0.2,'child':0.5,'adult':1,'elder':1,'sick':0.75,'wounded':0.75};
  314. for (var i in weights)
  315. {toConsume+=G.getRes(i).amount*weights[i];}
  316. var rations=G.checkPolicy('food rations');
  317. if (rations=='none') {toConsume=0;G.gain('happiness',-me.amount*3,'food rations');G.gain('health',-me.amount*2,'food rations');}
  318. else if (rations=='meager') {toConsume*=0.5;G.gain('happiness',-me.amount*1,'food rations');G.gain('health',-me.amount*0.5,'food rations');}
  319. else if (rations=='plentiful') {toConsume*=1.5;G.gain('happiness',me.amount*1,'food rations');}
  320. toConsume=randomFloor(toConsume*consumeMult);
  321. var consumed=G.lose('food',toConsume,'eating');
  322. G.gain('happiness',G.lose('salt',randomFloor(consumed*0.1),'eating')*5,'salting food');//use salt
  323. G.gain('happiness',consumed*happinessAdd,'food culture');
  324. var lacking=toConsume-consumed;
  325. if (rations=='none') lacking=me.amount*1;
  326.  
  327. if (lacking>0)//are we out of food?
  328. {
  329. //resort to spoiled food
  330. if (rations!='none' && G.checkPolicy('eat spoiled food')=='on') lacking=lacking-G.lose('spoiled food',lacking,'eating');
  331. if (lacking>0 && G.checkPolicy('disable aging')=='off')//are we also out of spoiled food?
  332. {
  333. G.gain('happiness',-lacking*5,'no food');
  334. //die off
  335. var toDie=(lacking/5)*0.05;
  336. if (G.year<1) toDie/=5;//less deaths in the first year
  337. var died=0;
  338. var weights={'baby':0.1,'child':0.2,'adult':0.5,'elder':1,'sick':0.3,'wounded':0.3};//the elderly are the first to starve off
  339. var sum=0;for (var i in weights){sum+=weights[i];}for (var i in weights){weights[i]/=sum;}//normalize
  340. for (var i in weights){var ratio=(G.getRes(i).amount/me.amount);weights[i]=ratio+(1-ratio)*weights[i];}
  341. for (var i in weights)
  342. {var n=G.lose(i,randomFloor((Math.random()*0.8+0.2)*toDie*weights[i]),'starvation');died+=n;}
  343. G.gain('corpse',died,'starvation');
  344. G.gain('happiness',-died*20*deathUnhappinessMult,'starvation');
  345. G.getRes('died this year').amount+=died;
  346. if (died>0) G.Message({type:'bad',mergeId:'diedStarvation',textFunc:function(args){return B(args.died)+' '+(args.died==1?'person':'people')+' died from starvation.';},args:{died:died},icon:[5,4]});
  347. }
  348. }
  349. }
  350.  
  351. //clothing
  352. var objects={'basic clothes':[0.1,0.1],'primitive clothes':[0,0]};
  353. var leftout=me.amount;
  354. var prev=leftout;
  355. var fulfilled=0;
  356. for (var i in objects)
  357. {
  358. fulfilled=Math.min(me.amount,Math.min(G.getRes(i).amount,leftout));
  359. G.gain('happiness',fulfilled*objects[i][0],'clothing');
  360. G.gain('health',fulfilled*objects[i][1],'clothing');
  361. leftout-=fulfilled;
  362. }
  363. G.gain('happiness',-leftout*0.15,'no clothing');
  364. G.gain('health',-leftout*0.15,'no clothing');
  365.  
  366. //fire
  367. var objects={'fire pit':[10,0.1,0.1]};
  368. var leftout=me.amount;
  369. var prev=leftout;
  370. var fulfilled=0;
  371. for (var i in objects)
  372. {
  373. fulfilled=Math.min(me.amount,Math.min(G.getRes(i).amount*objects[i][0],leftout));
  374. G.gain('happiness',fulfilled*objects[i][1],'warmth & light');
  375. G.gain('health',fulfilled*objects[i][2],'warmth & light');
  376. leftout-=fulfilled;
  377. }
  378. G.gain('happiness',-leftout*0.1,'cold & darkness');
  379. G.gain('health',-leftout*0.1,'cold & darkness');
  380.  
  381. //homelessness
  382. var homeless=Math.max(0,(me.amount)-G.getRes('housing').amount);
  383. if (G.has('sedentism') && me.amount>15 && homeless>0)
  384. {
  385. if (tick%10==0) G.Message({type:'bad',mergeId:'homeless',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person is':'people are')+' homeless.<br>Homelessness with more than 15 population leads to lower birth rates.';},args:{n:homeless},replaceOnly:true,icon:[12,4]});
  386. }
  387.  
  388. //age
  389. if (G.checkPolicy('disable aging')=='off')
  390. {
  391. if (G.year>=10)//no deaths of old age the first 10 years
  392. {
  393. var n=randomFloor(G.getRes('elder').amount*0.00035);
  394. G.gain('corpse',n,'old age');
  395. G.lose('elder',n,'old age');
  396. G.gain('happiness',-n*5*deathUnhappinessMult,'death');
  397. if (n>0) G.Message({type:'bad',mergeId:'diedAge',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' died of old age.';},args:{n:n},icon:[13,4]});
  398.  
  399. G.getRes('died this year').amount+=n;
  400. }
  401. if (G.year>=5)//no aging adults the first 5 years
  402. {
  403. var n=randomFloor(G.getRes('adult').amount*0.0002);
  404. G.gain('elder',n,'-');G.lose('adult',n,'aging up');
  405. }
  406. var n=randomFloor(G.getRes('child').amount*0.002);G.gain('adult',n,'aging up');G.lose('child',n,'aging up');
  407. var n=randomFloor(G.getRes('baby').amount*0.005);G.gain('child',n,'aging up');G.lose('baby',n,'aging up');
  408.  
  409. //births
  410. var parents=G.getRes('adult').amount+G.getRes('elder').amount;
  411. if (parents>=2)//can't make babies by yourself
  412. {
  413. var born=0;
  414. var birthRate=1;
  415. if (me.amount<100) birthRate*=3;//more births if low pop
  416. if (me.amount<10) birthRate*=3;//even more births if very low pop
  417. if (G.checkPolicy('fertility rituals')=='on') birthRate*=1.2;
  418. if (G.checkPolicy('population control')=='forbidden') birthRate*=0;
  419. else if (G.checkPolicy('population control')=='limited') birthRate*=0.5;
  420. if (homeless>0 && me.amount>15) birthRate*=0.05;//harder to make babies if you have more than 15 people and some of them are homeless
  421. var n=randomFloor(G.getRes('adult').amount*0.0005*birthRate);G.gain('baby',n,'birth');G.gain('happiness',n*10,'birth');born+=n;
  422. var n=randomFloor(G.getRes('elder').amount*0.00005*birthRate);G.gain('baby',n,'birth');G.gain('happiness',n*10,'birth');born+=n;
  423. G.getRes('born this year').amount+=born;
  424. if (born>0) G.Message({type:'good',mergeId:'born',textFunc:function(args){return B(args.born)+' '+(args.born==1?'baby has':'babies have')+' been born.';},args:{born:born},icon:[2,3]});
  425. }
  426.  
  427. //health (diseases and wounds)
  428. //note : when a sick or wounded person recovers, they turn into adults; this means you could get a community of old people fall sick, then miraculously age back. life is a mystery
  429.  
  430. //sickness
  431. var toChange=0.00003;
  432. if (G.getRes('health').amount<0)
  433. {
  434. toChange*=(1+Math.abs(G.getRes('health').amount/me.amount));
  435. }
  436. if (toChange>0)
  437. {
  438. if (G.year<5) toChange*=0.5;//less disease the first 5 years
  439. if (me.amount<=15) toChange*=0.5;
  440. if (G.checkPolicy('flower rituals')=='on') toChange*=0.8;
  441. var changed=0;
  442. var weights={'baby':2,'child':1.5,'adult':1,'elder':2};
  443. if (G.checkPolicy('child workforce')=='on') weights['child']*=2;
  444. if (G.checkPolicy('elder workforce')=='on') weights['elder']*=2;
  445. if (G.year<5) weights['adult']=0;//adults don't fall sick the first 5 years
  446. for (var i in weights)
  447. {var n=G.lose(i,randomFloor(Math.random()*G.getRes(i).amount*toChange*weights[i]),'-');changed+=n;}
  448. G.gain('sick',changed,'disease');
  449. if (changed>0) G.Message({type:'bad',mergeId:'fellSick',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' fell sick.';},args:{n:changed},icon:[6,3]});
  450. }
  451. //sickness : death and recovery
  452. var sickMortality=0.005;
  453. var changed=0;
  454. var n=G.lose('sick',randomFloor(Math.random()*G.getRes('sick').amount*sickMortality),'disease');G.gain('corpse',n,'disease');changed+=n;
  455. G.gain('happiness',-changed*15*deathUnhappinessMult,'death');
  456. G.getRes('died this year').amount+=changed;
  457. if (changed>0) G.Message({type:'bad',mergeId:'diedSick',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' died from disease.';},args:{n:changed},icon:[5,4]});
  458.  
  459. var sickHealing=0.01;
  460. if (G.checkPolicy('flower rituals')=='on') sickHealing*=1.2;
  461. var changed=0;
  462. var n=G.lose('sick',randomFloor(Math.random()*G.getRes('sick').amount*sickHealing),'healing');G.gain('adult',n,'-');changed+=n;
  463. G.gain('happiness',changed*10,'recovery');
  464. if (changed>0) G.Message({type:'good',mergeId:'sickRecovered',textFunc:function(args){return B(args.n)+' sick '+(args.n==1?'person':'people')+' got better.';},args:{n:changed},icon:[4,3]});
  465.  
  466. //wounds
  467. var toChange=0.00003;
  468. if (toChange>0)
  469. {
  470. if (G.year<5) toChange*=0.5;//less wounds the first 5 years
  471. if (me.amount<=15) toChange*=0.5;
  472. var changed=0;
  473. var weights={'baby':2,'child':1.5,'adult':1,'elder':2};
  474. if (G.checkPolicy('child workforce')=='on') weights['child']*=3;
  475. if (G.checkPolicy('elder workforce')=='on') weights['elder']*=3;
  476. if (G.year<5) weights['adult']=0;//adults don't get wounded the first 5 years
  477. for (var i in weights)
  478. {var n=G.lose(i,randomFloor(Math.random()*G.getRes(i).amount*toChange*weights[i]),'-');changed+=n;}
  479. G.gain('wounded',changed,'accident');
  480. if (changed>0) G.Message({type:'bad',mergeId:'gotWounded',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' got wounded.';},args:{n:changed},icon:[7,3]});
  481. }
  482. //wounds : death and recovery
  483. var woundMortality=0.005;
  484. var changed=0;
  485. var n=G.lose('wounded',randomFloor(Math.random()*G.getRes('wounded').amount*woundMortality),'wounds');G.gain('corpse',n,'wounds');changed+=n;
  486. G.gain('happiness',-changed*15*deathUnhappinessMult,'death');
  487. G.getRes('died this year').amount+=changed;
  488. if (changed>0) G.Message({type:'bad',mergeId:'diedWounded',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' died from their wounds.';},args:{n:changed},icon:[5,4]});
  489.  
  490. var sickHealing=0.005;
  491. var changed=0;
  492. var n=G.lose('wounded',randomFloor(Math.random()*G.getRes('wounded').amount*sickHealing),'healing');G.gain('adult',n,'-');changed+=n;
  493. G.gain('happiness',changed*10,'recovery');
  494. if (changed>0) G.Message({type:'good',mergeId:'woundedRecovered',textFunc:function(args){return B(args.n)+' '+(args.n==1?'person':'people')+' recovered from their wounds.';},args:{n:changed},icon:[4,3]});
  495. }
  496. }
  497. else if (G.T>0) {G.GameOver();}
  498. },
  499. });
  500. new G.Res({
  501. name:'baby',
  502. desc:'[baby,Babies] are what happens when you have 2 or more [adult,Adults] left to their own devices.//Over time, babies will grow into [child,Children].//Babies drink and eat half as much as children.',
  503. startWith:0,
  504. visible:true,
  505. partOf:'population',
  506. icon:[2,3],
  507. });
  508. new G.Res({
  509. name:'child',
  510. desc:'[child,Children] grow from [baby,Babies] over time.//After a while, they will grow up into [adult,Adults].//Children drink and eat half as much as adults.//Children do not count as [worker,Workers], unless special measures are in place.',
  511. startWith:2,
  512. visible:true,
  513. partOf:'population',
  514. icon:[3,3],
  515. });
  516. new G.Res({
  517. name:'adult',
  518. desc:'[adult,Adults] grow from [child,Children] over time.//They eventually age into [elder,Elders].//Generally, adults make up most of your [worker,workforce].',
  519. startWith:5,
  520. visible:true,
  521. partOf:'population',
  522. icon:[4,3],
  523. });
  524. new G.Res({
  525. name:'elder',
  526. desc:'[adult,Adults] that grow old are [elder,Elders].//Elders may end up [corpse,dying] of old age.//Elders do not count as [worker,Workers], unless special measures are in place.',
  527. startWith:1,
  528. visible:true,
  529. partOf:'population',
  530. icon:[5,3],
  531. });
  532. new G.Res({
  533. name:'grand dad',
  534. desc:'I will meme you.',
  535. startWith:1,
  536. visible:true,
  537. partOf:'population',
  538. icon:[5,3],
  539. });
  540. new G.Res({
  541. name:'sick',
  542. desc:'[adult,People] can fall [sick,sick] when your [health] levels are too low. They do not [worker,work], but may be healed over time.',
  543. partOf:'population',
  544. icon:[6,3],
  545. });
  546. new G.Res({
  547. name:'wounded',
  548. desc:'[adult,People] may get [wounded,wounded] due to work injuries, or from war. They do not [worker,work], but may slowly get better over time.',
  549. partOf:'population',
  550. icon:[7,3],
  551. });
  552. new G.Res({
  553. name:'corpse',
  554. desc:'[corpse,Corpses] are the remains of [population,People] that died, whether from old age, accident, disease, starvation or war.//Corpses left in the open air tend to spread diseases and make people unhappy, which gets even worse as superstitions develop. To mitigate this, you need a [burial space,Burial spot] for each corpse.',
  555. startWith:0,
  556. icon:[8,3],
  557. tick:function(me,tick)
  558. {
  559. var graves=G.getRes('burial space');
  560. if (G.getRes('population').amount>0)
  561. {
  562. if (G.has('ritual necrophagy'))//butcher 1% of corpses every day, you weirdo
  563. {
  564. var changed=0;
  565. var n=G.lose('corpse',randomFloor(G.getRes('corpse').amount*0.1),'necrophagy');G.gain('meat',n*30,'necrophagy');G.gain('bone',n*5,'necrophagy');changed+=n;
  566. G.pseudoGather(G.getRes('faith'),changed);
  567. G.gain('health',-changed*0.1,'necrophagy');
  568. }
  569. if (me.amount>0)
  570. {
  571. //bury slowly
  572. if (graves.amount>graves.used)
  573. {
  574. var amount=Math.min(graves.amount-graves.used,Math.max(1,randomFloor(me.amount*0.1)));
  575. graves.used+=amount;G.lose('corpse',amount,'burial');
  576. G.gain('happiness',amount*2,'burial');
  577. }
  578. }
  579. }
  580. if (graves.amount<graves.used)
  581. {
  582. //more occupied burial spots than total burial spots? this means we've been deleting burial space that was already containing corpses; exhume those suckers
  583. var toExhume=randomFloor((graves.used-graves.amount)*0.1);
  584. graves.used-=toExhume;
  585. me.amount+=toExhume;
  586. }
  587. var unhappiness=0.01;
  588. if (G.has('burial')) unhappiness*=2;
  589. if (G.has('belief in revenants')) unhappiness*=2;
  590. G.gain('happiness',-me.amount*unhappiness,'corpses');
  591. G.gain('health',-me.amount*0.02,'corpses');
  592. },
  593. });
  594. new G.Res({
  595. name:'burial space',
  596. desc:'Each [burial space] has enough room for one [corpse], letting you prevent the spread of disease and unhappiness.//By default, corpses are buried at the rate of 1 per day.//The number on the left is how many burial spots are occupied, while the number on the right is how many you have in total.',
  597. icon:[13,4],
  598. displayUsed:true,
  599. });
  600. new G.Res({
  601. name:'housing',
  602. desc:'Each [housing,Housing spot] accommodates one [population,Person].//Beyond the 15 people a nomad tribe can support, your population will only grow if you have empty housing.//Homelessness (having less housing than population) will lead to unhappiness and disease.//The number on the left is how much housing is occupied, while the number on the right is how much housing room you have in total.',
  603. icon:[12,4],
  604. getDisplayAmount:function()
  605. {
  606. return B(Math.min(this.displayedAmount,G.getRes('population').displayedAmount))+'<wbr>/'+B(this.displayedAmount);
  607. },
  608. });
  609. new G.Res({
  610. name:'land',
  611. desc:'Each tile of territory you own grants you some [land] (100 per fully-explored non-ocean tile, by default) upon which you can construct buildings. If for some reason you find yourself with less land than your buildings are using, some of them will start to slowly crumble away.//The number on the left is how much land is occupied, while the number on the right is how much land you have in total.',
  612. icon:[14,4],
  613. displayUsed:true,
  614. tick:function(me)
  615. {
  616. me.amount=Math.ceil(G.currentMap.territoryByOwner[1]*100);
  617. //me.amount=G.tiles;
  618. //TODO : this stuff
  619. /*
  620. concept :
  621. -each tile owned can be explored to 100%
  622. -you get one land per explored percent per tile
  623. -some techs also add a +10 etc bonus to the max of 100 land per full tile
  624. -we need to setup a system to recalculate this when appropriate
  625. */
  626. },
  627. getDisplayAmount:function()
  628. {
  629. return B(this.displayedUsedAmount)+'<wbr>/'+B(this.displayedAmount);
  630. },
  631. });
  632. new G.Res({
  633. name:'worker',
  634. desc:'Your [worker,Workforce] is the part of your [population] that is ready to work.//The number on the left is how many are currently being employed, while the number on the right is your total amount of workers.',
  635. startWith:0,
  636. visible:true,
  637. icon:[1,3],
  638. displayUsed:true,
  639. tick:function(me,tick)
  640. {
  641. me.amount=G.getRes('adult').amount;
  642. if (G.checkPolicy('elder workforce')=='on') me.amount+=G.getRes('elder').amount;
  643. if (G.checkPolicy('child workforce')=='on') me.amount+=G.getRes('child').amount;
  644. if (me.used>me.amount)
  645. {
  646. //TODO maybe ?
  647. //select all units that require workers
  648. //pick some at random until we have enough people to reach the difference between workers and workers needed
  649. //kill them if the unit has no gizmos, otherwise reduce the unit's percent by 1 rank
  650. //maybe this could be generalized to work will all requirements
  651. //or not ? some requirements have unique conditions, such as : 10 factories running at 50% only use half the workers and tools, but still need 10 land
  652. //maybe this could just be a flag on land, reqIgnoresPercent=true
  653. //but then how do we deal with the situation where we have less land available than land used (like after a war where we lost tiles) ? the desired behavior would be that buildings slowly die off until we're under the threshold
  654. //maybe just implement a "onReqFail" function that overrides the default behavior
  655. }
  656. },
  657. });
  658.  
  659. new G.Res({
  660. name:'happiness',
  661. desc:'[happiness] describes the global level of well-being of your [population].//Happy people work even harder, while unhappy people tend to slack off; at +100% happiness, most of your workers will work twice as fast, while at -100% happiness, they will work twice as slow. This goes on up to +200% and -200%.//Several things improve happiness, such as good [food,food], entertainment, or luxury items; things that bring down happiness are spoiled food, starvation, disease, death and harsh policies.//Happiness and unhappiness both tend to level off over time.',
  662. startWith:0,
  663. visible:true,
  664. icon:[3,4],
  665. fractional:true,
  666. tick:function(me,tick)
  667. {
  668. if (G.getRes('population').amount>0 && tick%2==0)
  669. {
  670. me.amount*=0.99;
  671. }
  672. },
  673. getDisplayAmount:function()
  674. {
  675. if (G.getRes('population').amount<=0) return '-';
  676. return B(this.displayedAmount/G.getRes('population').displayedAmount)+'%';
  677. },
  678. getIcon:function(me)
  679. {
  680. if (G.getRes('population').amount<=0) return [5,4];
  681. else
  682. {
  683. var amount=me.amount/G.getRes('population').amount;
  684. if (amount>=100) return [4,4];
  685. else if (amount>=50) return [3,4];
  686. else if (amount>=-50) return [2,4];
  687. else if (amount>=-100) return [1,4];
  688. else return [0,4];
  689. }
  690. },
  691. });
  692.  
  693. new G.Res({
  694. name:'health',
  695. desc:'[health] represents the average physical condition of your [population].//Lower health tends to make people [sick] and unhappy, while higher health will make people happier.//Health can be affected by a number of things : eating raw or spoiled [spoiled food,Food], drinking [muddy water], poor living conditions, and ongoing plagues.',
  696. startWith:0,
  697. visible:true,
  698. icon:[3,5],
  699. fractional:true,
  700. tick:function(me,tick)
  701. {
  702. if (G.getRes('population').amount>0 && tick%2==0)
  703. {
  704. //note : this is "soft" sickness; it affects the chance of people falling sick
  705. //G.getRes('happiness').amount+=(me.amount-G.getRes('happiness').amount)*0.01;
  706. G.gain('happiness',me.amount*0.001,'health');
  707.  
  708. var sickness=0.1;
  709. sickness+=Math.pow(Math.max(0,G.getRes('population').amount-50),0.1)*0.1;//more people means more contagion
  710. G.gain('health',-G.getRes('population').amount*(Math.random()*sickness),'disease');//people randomly get sick
  711. var recovery=0.98;
  712. me.amount*=recovery;//people recover over time
  713. }
  714. },
  715. getDisplayAmount:function()
  716. {
  717. if (G.getRes('population').amount<=0) return '-';
  718. return B(this.displayedAmount/G.getRes('population').displayedAmount)+'%';
  719. },
  720. getIcon:function(me)
  721. {
  722. if (G.getRes('population').amount<=0) return [5,5];
  723. else
  724. {
  725. var amount=me.amount/G.getRes('population').amount;
  726. if (amount>=100) return [4,5];
  727. else if (amount>=50) return [3,5];
  728. else if (amount>=-50) return [2,5];
  729. else if (amount>=-100) return [1,5];
  730. else return [0,5];
  731. }
  732. },
  733. });
  734.  
  735. new G.Res({
  736. name:'food storage',
  737. desc:'Each [food storage] unit slows down decay for one [food] unit.//The number on the left is how much food storage is occupied, while the number on the right is how much you have in total.',
  738. icon:[12,5],
  739. tick:function(me,tick)
  740. {
  741. var amount=0;
  742. amount+=G.getRes('basket').amount*10;
  743. amount+=G.getRes('pot').amount*25;
  744. amount+=G.getRes('ice').amount;
  745. amount+=G.getRes('added food storage').amount;
  746. me.amount=amount;
  747. },
  748. getDisplayAmount:function()
  749. {
  750. return B(Math.min(this.displayedAmount,G.getRes('food').displayedAmount))+'<wbr>/'+B(this.displayedAmount);
  751. },
  752. });
  753. new G.Res({
  754. name:'added food storage',
  755. //food storage added by buildings
  756. desc:'',
  757. icon:[12,5],
  758. hidden:true,
  759. });
  760.  
  761. new G.Res({
  762. name:'material storage',
  763. desc:'Each [material storage] unit lowers the rate of decay or theft for one unit of your materials.//The number on the left is how much material storage is occupied, while the number on the right is how much you have in total.',
  764. icon:[14,5],
  765. tick:function(me,tick)
  766. {
  767. var amount=0;
  768. amount+=G.getRes('added material storage').amount;
  769. me.amount=amount;
  770.  
  771. var materials=0;
  772. for (var i in G.props['perishable materials list'])
  773. {
  774. var mat=G.props['perishable materials list'][i];
  775. materials+=mat.amount;
  776. }
  777. me.used=materials;
  778.  
  779. if (materials>0)
  780. {
  781. var stored=Math.min(materials,amount)/materials;
  782. var notStored=1-stored;
  783.  
  784. for (var i in G.props['perishable materials list'])
  785. {
  786. var mat=G.props['perishable materials list'][i];
  787.  
  788. var toSpoil=mat.amount*0.002*notStored+mat.amount*0.0001*stored;
  789. var spent=G.lose(mat.name,randomFloor(toSpoil),'decay');
  790. }
  791. }
  792.  
  793. G.props['perishable materials list']=[];
  794. },
  795. getDisplayAmount:function()
  796. {
  797. return B(Math.min(this.displayedAmount,this.displayedUsedAmount))+'<wbr>/'+B(this.displayedAmount);
  798. },
  799. displayUsed:true,
  800. });
  801. new G.Res({
  802. name:'added material storage',
  803. //maaterial storage added by buildings
  804. desc:'',
  805. icon:[14,5],
  806. hidden:true,
  807. });
  808.  
  809. new G.Res({
  810. name:'water',
  811. desc:'[water] is required to keep your [population,people] hydrated, at the rate of half a unit per person every 3 ticks (although babies and children drink less).//Without water, people will resort to drinking [muddy water], which is unhealthy; if that runs out too, your people will simply die off.//Most terrains have some fresh water up for gathering - from ponds, streams and rain; drier locations will have to rely on well digging.//Water turns into [muddy water] over time, if your water storage is insufficient.',
  812. icon:[7,6],
  813. startWith:250,
  814. visible:true,
  815. turnToByContext:{'drinking':{'health':0.01,'happiness':0}},
  816. tick:function(me,tick)
  817. {
  818. if (G.checkPolicy('disable spoiling')=='off')
  819. {
  820. var toSpoil=me.amount*0.02;
  821. var spent=G.lose('water',randomFloor(toSpoil),'decay');
  822. G.gain('muddy water',randomFloor(spent),'decay');
  823. }
  824. },
  825. });
  826. new G.Res({
  827. name:'muddy water',
  828. desc:'[muddy water] tastes awful and is unhealthy, but is better than dying of thirst. Your people will default to drinking it in the absence of fresh [water].//Muddy water can be collected while gathering, from stagnant pools or old rainwater; [water] also turns into muddy water over time, if not stored properly. Additionally, muddy water itself will slowly dry out.',
  829. icon:[8,6],
  830. visible:true,
  831. turnToByContext:{'drinking':{'health':-0.03,'happiness':-0.05}},
  832. tick:function(me,tick)
  833. {
  834. if (G.checkPolicy('disable spoiling')=='off')
  835. {
  836. var toSpoil=me.amount*0.01;
  837. var spent=G.lose('muddy water',randomFloor(toSpoil),'decay');
  838. }
  839. },
  840. });
  841.  
  842. new G.Res({
  843. name:'food',
  844. desc:'[food] is consumed by your [population,people] when they get hungry, at the rate of 1 unit per person every 3 ticks (although babies and children eat less).//Some types of food are tastier or healthier than others.//Note that some food types may or may not be eaten depending on policies in place.//Food will slowly decay into [spoiled food] if you lack proper food storage.',
  845. meta:true,
  846. visible:true,
  847. icon:[3,6],
  848. tick:function(me,tick)
  849. {
  850. if (me.amount>0 && G.checkPolicy('disable spoiling')=='off')
  851. {
  852. var stored=Math.min(me.amount,G.getRes('food storage').amount)/me.amount;
  853. var notStored=1-stored;
  854.  
  855. var toSpoil=me.amount*0.01*notStored+me.amount*0.0005*stored;
  856. var spent=G.lose('food',randomFloor(toSpoil),'decay');
  857. //G.gain('spoiled food',randomFloor(spent));
  858. }
  859. },
  860. });
  861. new G.Res({
  862. name:'spoiled food',
  863. desc:'[spoiled food] is eaten when no other [food] is available, in a last-ditch effort to fend off starvation.//Spoiled food is terribly unhealthy and tastes just as bad. Over time, it will decay even further into inedibility.',
  864. icon:[3,7],
  865. visible:true,
  866. turnToByContext:{'eating':{'health':-0.3,'happiness':-0.5}},
  867. tick:function(me,tick)
  868. {
  869. if (G.checkPolicy('disable spoiling')=='off')
  870. {
  871. var toSpoil=me.amount*0.001;
  872. var spent=G.lose('spoiled food',randomFloor(toSpoil),'decay');
  873. }
  874. },
  875. });
  876.  
  877. //a trick to make different food types spoil at different speeds : turnToByContext:{'decay':{'fruit':0.2}} would make fruit last 20% longer (note : the food may still produce spoiled food)
  878.  
  879. new G.Res({
  880. name:'herb',
  881. desc:'[herb,Herbs] are various plants, roots and mushrooms that can be collected by simply foraging around. While relatively healthy to eat, they tend to taste fairly unpleasant.',
  882. icon:[4,6],
  883. startWith:250,
  884. turnToByContext:{'eating':{'health':0.005,'happiness':-0.03},'decay':{'herb':0.2,'spoiled food':0.8}},
  885. partOf:'food',
  886. category:'food',
  887. });
  888. new G.Res({
  889. name:'fruit',
  890. desc:'[fruit,Fruits], whether gathered from berry bushes or fruit trees, are both sweet-tasting and good for you.',
  891. icon:[4,7],
  892. turnToByContext:{'eating':{'health':0.02,'happiness':0.01},'decay':{'spoiled food':1}},
  893. partOf:'food',
  894. category:'food',
  895. });
  896. new G.Res({
  897. name:'meat',
  898. desc:'[meat,Raw meat] is gathered from dead animals and, while fairly tasty, can harbor a variety of diseases.',
  899. icon:[5,7],
  900. turnToByContext:{'eating':{'health':-0.03,'happiness':0.02,'bone':0.1},'decay':{'spoiled food':1}},
  901. partOf:'food',
  902. category:'food',
  903. });
  904. new G.Res({
  905. name:'cooked meat',
  906. desc:'Eating [cooked meat] is deeply satisfying and may even produce a [bone].',
  907. icon:[6,7],
  908. turnToByContext:{'eating':{'health':0.02,'happiness':0.04,'bone':0.1},'decay':{'cooked meat':0.2,'spoiled food':0.8}},
  909. partOf:'food',
  910. category:'food',
  911. });
  912. new G.Res({
  913. name:'cured meat',
  914. desc:'[cured meat] is interestingly tough and can keep for months without spoiling.',
  915. icon:[11,6],
  916. turnToByContext:{'eating':{'health':0.02,'happiness':0.05,'bone':0.1},'decay':{'cured meat':0.95,'spoiled food':0.05}},
  917. partOf:'food',
  918. category:'food',
  919. });
  920. new G.Res({
  921. name:'seafood',
  922. desc:'[seafood,Raw seafood] such as fish, clams, or shrimps, is both bland-tasting and several kinds of nasty.',
  923. icon:[5,6],
  924. turnToByContext:{'eating':{'health':-0.02,'happiness':0.01,'bone':0.02},'decay':{'spoiled food':1}},
  925. partOf:'food',
  926. category:'food',
  927. });
  928. new G.Res({
  929. name:'cooked seafood',
  930. desc:'[cooked seafood] tastes pretty good and has various health benefits.',
  931. icon:[6,6],
  932. turnToByContext:{'eating':{'health':0.03,'happiness':0.03,'bone':0.02},'decay':{'cooked seafood':0.2,'spoiled food':0.8}},
  933. partOf:'food',
  934. category:'food',
  935. });
  936. new G.Res({
  937. name:'cured seafood',
  938. desc:'[cured seafood] has a nice smoky flavor and lasts terribly long.',
  939. icon:[12,6],
  940. turnToByContext:{'eating':{'health':0.02,'happiness':0.04,'bone':0.02},'decay':{'cured seafood':0.95,'spoiled food':0.05}},
  941. partOf:'food',
  942. category:'food',
  943. });
  944.  
  945. new G.Res({
  946. name:'bread',
  947. desc:'[bread] is filling, nutritious, and usually not unpleasant to eat; for these reasons, it is often adopted as staple food by those who can produce it.',
  948. icon:[7,7],
  949. turnToByContext:{'eating':{'health':0.02,'happiness':0.02},'decay':{'spoiled food':1}},
  950. partOf:'food',
  951. category:'food',
  952. });
  953.  
  954. new G.Res({
  955. name:'bugs',
  956. desc:'Worms, insects, spiders - [bugs] are easily caught, but are usually not considered [food].',
  957. icon:[8,11],
  958. turnToByContext:{'eating':{'health':0,'happiness':-0.05},'decay':{'spoiled food':0.5}},
  959. //partOf:'food',
  960. category:'food',
  961. tick:function(me,tick)
  962. {
  963. var toLose=me.amount*0.003;//bugs don't like to stick around
  964. var spent=G.lose(me.name,randomFloor(toLose),'decay');
  965. }
  966. });
  967.  
  968.  
  969. G.props['perishable materials list']=[];
  970.  
  971. var loseMaterialsTick=function(me,tick)
  972. {
  973. if (G.checkPolicy('disable spoiling')=='off')
  974. {
  975. G.props['perishable materials list'].push(me);
  976. }
  977. };
  978.  
  979. new G.Res({
  980. //hidden, used for every material that can be stored in a warehouse that isn't part of any other material
  981. name:'misc materials',
  982. meta:true,
  983. tick:loseMaterialsTick,
  984. hidden:true,
  985. });
  986.  
  987. new G.Res({
  988. name:'archaic building materials',
  989. desc:'Materials such as [stick]s and [stone]s, used to build rudimentary structures.',
  990. icon:[2,7],
  991. meta:true,
  992. tick:loseMaterialsTick,
  993. });
  994. new G.Res({
  995. name:'stone',
  996. desc:'Just a simple rock. Found regularly when foraging, and even more commonly when digging, mining or quarrying.',
  997. icon:[2,6],
  998. partOf:'archaic building materials',
  999. category:'build',
  1000. });
  1001. new G.Res({
  1002. name:'stick',
  1003. desc:'A short but sturdy branch. Obtained when foraging or when felling a tree.',
  1004. icon:[0,6],
  1005. partOf:'archaic building materials',
  1006. category:'build',
  1007. });
  1008. new G.Res({
  1009. name:'limestone',
  1010. desc:'A fairly soft mineral. Can be foraged from some places, but is more commonly extracted while mining or quarrying.',
  1011. icon:[6,8],
  1012. partOf:'archaic building materials',
  1013. category:'build',
  1014. });
  1015. new G.Res({
  1016. name:'mud',
  1017. desc:'Dirt saturated with water; found often when foraging or digging.',
  1018. icon:[0,7],
  1019. partOf:'archaic building materials',
  1020. category:'build',
  1021. });
  1022.  
  1023. new G.Res({
  1024. name:'basic building materials',
  1025. desc:'Processed materials such as [cut stone,Stone blocks], [brick]s and [lumber], used to build basic structures.',
  1026. icon:[2,8],
  1027. meta:true,
  1028. tick:loseMaterialsTick,
  1029. });
  1030. new G.Res({
  1031. name:'cut stone',
  1032. desc:'[stone]s carved into blocks for easier hauling and building.',
  1033. icon:[0,8],
  1034. partOf:'basic building materials',
  1035. category:'build',
  1036. });
  1037. new G.Res({
  1038. name:'log',
  1039. desc:'Chopped wood that can be directly used in construction, but can also be processed into [lumber].',
  1040. icon:[1,6],
  1041. partOf:'basic building materials',
  1042. category:'build',
  1043. });
  1044. new G.Res({
  1045. name:'lumber',
  1046. desc:'[log]s that have been processed into planks, making them an adaptable and resilient building material.',
  1047. icon:[1,8],
  1048. partOf:'basic building materials',
  1049. category:'build',
  1050. });
  1051. new G.Res({
  1052. name:'clay',
  1053. desc:'Found by digging in damp soil; can be baked into [brick]s.',
  1054. icon:[1,7],
  1055. partOf:'misc materials',
  1056. category:'build',
  1057. });
  1058. new G.Res({
  1059. name:'brick',
  1060. desc:'Made from fired [clay]; can be used to construct solid walls efficiently.',
  1061. icon:[3,8],
  1062. partOf:'basic building materials',
  1063. category:'build',
  1064. });
  1065.  
  1066. new G.Res({
  1067. name:'advanced building materials',
  1068. desc:'Building materials such as [concrete] and [glass], used to build advanced structures.',
  1069. icon:[3,9],
  1070. meta:true,
  1071. tick:loseMaterialsTick,
  1072. });
  1073. new G.Res({
  1074. name:'sand',
  1075. desc:'Easily harvested from deserts and beaches; may be processed into [glass].',
  1076. icon:[4,9],
  1077. partOf:'misc materials',
  1078. category:'build',
  1079. });
  1080. new G.Res({
  1081. name:'glass',
  1082. desc:'Obtained by melting [sand]; can be used to construct windows, which are part of most advanced buildings.',
  1083. icon:[4,8],
  1084. partOf:'advanced building materials',
  1085. category:'build',
  1086. });
  1087. new G.Res({
  1088. name:'concrete',
  1089. desc:'An exceptionally sturdy construction material, made by mixing [limestone] with [water] and letting it set.',
  1090. icon:[5,8],
  1091. partOf:'advanced building materials',
  1092. category:'build',
  1093. });
  1094.  
  1095. new G.Res({
  1096. name:'precious building materials',
  1097. desc:'Building materials such as [marble], used to build monuments.',
  1098. icon:[16,8],
  1099. meta:true,
  1100. tick:loseMaterialsTick,
  1101. });
  1102. new G.Res({
  1103. name:'marble',
  1104. desc:'A construction material prized for its decorative properties, that can also be employed in sculptures.',
  1105. icon:[7,8],
  1106. partOf:'precious building materials',
  1107. category:'build',
  1108. });
  1109. new G.Res({
  1110. name:'gold block',
  1111. desc:'A valuable, if unreliable construction material.',
  1112. icon:[14,8],
  1113. partOf:'precious building materials',
  1114. category:'build',
  1115. });
  1116. new G.Res({
  1117. name:'gem block',
  1118. desc:'A precious building material used only for the finest monuments.',
  1119. icon:[choose([17,18]),8],//i can't pick
  1120. partOf:'precious building materials',
  1121. category:'build',
  1122. });
  1123.  
  1124. new G.Res({
  1125. name:'copper ore',
  1126. desc:'Ore that can be processed into [soft metal ingot]s.',
  1127. icon:[9,8],
  1128. partOf:'misc materials',
  1129. category:'build',
  1130. });
  1131. new G.Res({
  1132. name:'iron ore',
  1133. desc:'Ore that can be processed into [hard metal ingot]s.',
  1134. icon:[10,8],
  1135. partOf:'misc materials',
  1136. category:'build',
  1137. });
  1138. new G.Res({
  1139. name:'gold ore',
  1140. desc:'Ore that can be processed into [precious metal ingot]s.',
  1141. icon:[11,8],
  1142. partOf:'misc materials',
  1143. category:'build',
  1144. });
  1145. new G.Res({
  1146. name:'tin ore',
  1147. desc:'Ore that can be processed into [soft metal ingot]s.',
  1148. icon:[13,8],
  1149. partOf:'misc materials',
  1150. category:'build',
  1151. });
  1152.  
  1153. new G.Res({
  1154. name:'gems',
  1155. desc:'Shiny, valuable minerals from deep under the earth.',
  1156. icon:[7,9],
  1157. partOf:'misc materials',
  1158. category:'build',
  1159. });
  1160.  
  1161. new G.Res({
  1162. name:'coal',
  1163. desc:'Extracted from mines; makes a good source of energy, and can be used in alloying.',
  1164. icon:[12,8],
  1165. partOf:'misc materials',
  1166. category:'build',
  1167. });
  1168.  
  1169. new G.Res({
  1170. name:'soft metal ingot',
  1171. desc:'Soft, malleable metal that can be used to make basic [metal tools].//Includes tin and copper.',
  1172. icon:[9,9],
  1173. partOf:'misc materials',
  1174. category:'build',
  1175. });
  1176. new G.Res({
  1177. name:'hard metal ingot',
  1178. desc:'Tough, durable metal that can be used to craft [metal tools] and weapons.//Includes iron and bronze.',
  1179. icon:[10,9],
  1180. partOf:'misc materials',
  1181. category:'build',
  1182. });
  1183. new G.Res({
  1184. name:'strong metal ingot',
  1185. desc:'Solid metal possessing high tensile strength.//Includes steel.',
  1186. icon:[12,9],
  1187. partOf:'misc materials',
  1188. category:'build',
  1189. });
  1190. new G.Res({
  1191. name:'precious metal ingot',
  1192. desc:'Metal with little industrial usefulness but imbued with valuable aesthetics.//Includes gold and silver.',
  1193. icon:[11,9],
  1194. partOf:'misc materials',
  1195. category:'build',
  1196. });
  1197.  
  1198. new G.Res({
  1199. name:'knapped tools',
  1200. desc:'Rudimentary tools made by hitting [stone]s, usually flint, until their edges are sharp enough.'+numbersInfo,
  1201. icon:[0,9],
  1202. displayUsed:true,
  1203. category:'gear',
  1204. });
  1205. new G.Res({
  1206. name:'stone tools',
  1207. desc:'Simple tools made of [stone]s and [stick]s for a variety of purposes - hammering, cutting, piercing, crushing.'+numbersInfo,
  1208. icon:[1,9],
  1209. displayUsed:true,
  1210. category:'gear',
  1211. });
  1212. new G.Res({
  1213. name:'metal tools',
  1214. desc:'Solid, durable tools made of metal and wood.'+numbersInfo,
  1215. icon:[2,9],
  1216. displayUsed:true,
  1217. category:'gear',
  1218. });
  1219.  
  1220. new G.Res({
  1221. name:'stone weapons',
  1222. desc:'Simple weapons made of [stone]s and [stick]s.'+numbersInfo,
  1223. icon:[5,9],
  1224. displayUsed:true,
  1225. category:'gear',
  1226. });
  1227. new G.Res({
  1228. name:'bow',
  1229. desc:'A weapon made of [stick,Wood] that fires [stone]-tipped arrows at a distance.'+numbersInfo,
  1230. icon:[6,9],
  1231. displayUsed:true,
  1232. category:'gear',
  1233. });
  1234.  
  1235. var clothesInfo='//Your people automatically wear the highest-quality clothing available, moving on to the next type if there isn\'t enough.';
  1236. new G.Res({
  1237. name:'primitive clothes',
  1238. desc:'Made out of rudimentary materials such as [hide]s or [herb]s.//Each [population,Person] wearing clothing is slightly happier and healthier.'+clothesInfo,
  1239. icon:[15,7],
  1240. category:'gear',
  1241. tick:function(me,tick)
  1242. {
  1243. var toSpoil=me.amount*0.005;
  1244. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1245. },
  1246. });
  1247. new G.Res({
  1248. name:'basic clothes',
  1249. desc:'Sewn together from [leather] or textile fiber.//Each [population,Person] wearing clothing is slightly happier and healthier.'+clothesInfo,
  1250. icon:[16,7],
  1251. category:'gear',
  1252. tick:function(me,tick)
  1253. {
  1254. var toSpoil=me.amount*0.002;
  1255. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1256. },
  1257. });
  1258.  
  1259. new G.Res({
  1260. name:'bone',
  1261. desc:'Obtained from the corpse of an animal, or discarded from eating flesh.',
  1262. icon:[8,7],
  1263. partOf:'misc materials',
  1264. category:'build',
  1265. });
  1266. new G.Res({
  1267. name:'hide',
  1268. desc:'A pelt obtained by slicing the skin off a dead animal.',
  1269. icon:[9,7],
  1270. partOf:'misc materials',
  1271. category:'build',
  1272. });
  1273. new G.Res({
  1274. name:'leather',
  1275. desc:'[hide] that has been cured and worked to make it strong and durable for a variety of uses.',
  1276. icon:[10,7],
  1277. partOf:'misc materials',
  1278. category:'build',
  1279. });
  1280. new G.Res({
  1281. name:'statuette',
  1282. desc:'A small idol that was rudimentarily carved from [stone] or [bone].//May be used up over time, creating [culture].',
  1283. icon:[8,9],
  1284. partOf:'misc materials',
  1285. category:'misc',
  1286. tick:function(me,tick)
  1287. {
  1288. var toSpoil=me.amount*0.01;
  1289. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1290. G.pseudoGather(G.getRes('culture'),randomFloor(spent));
  1291. },
  1292. });
  1293. new G.Res({
  1294. name:'salt',
  1295. desc:'Gives flavor to [food], rendering it more enjoyable to eat; may also be used to preserve food and make it last longer.',
  1296. icon:[11,7],
  1297. partOf:'misc materials',
  1298. category:'misc',
  1299. });
  1300. new G.Res({
  1301. name:'ice',
  1302. desc:'Can be used to preserve [food] longer.//Will melt into [water] over time.',
  1303. icon:[12,7],
  1304. partOf:'misc materials',
  1305. category:'misc',
  1306. tick:function(me,tick)
  1307. {
  1308. var toSpoil=me.amount*0.01;
  1309. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1310. G.gain('water',randomFloor(spent*10),'ice melting');
  1311. },
  1312. });
  1313.  
  1314. new G.Res({
  1315. name:'basket',
  1316. desc:'Each basket stores 10 [food].//Will decay over time.',
  1317. icon:[14,7],
  1318. category:'misc',
  1319. tick:function(me,tick)
  1320. {
  1321. var toSpoil=me.amount*0.005;
  1322. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1323. },
  1324. });
  1325. new G.Res({
  1326. name:'pot',
  1327. desc:'Each pot stores 25 [food].//Will decay slowly over time.',
  1328. icon:[13,5],
  1329. category:'misc',
  1330. tick:function(me,tick)
  1331. {
  1332. var toSpoil=me.amount*0.0005;
  1333. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1334. },
  1335. });
  1336.  
  1337. new G.Res({
  1338. name:'fire pit',
  1339. //desc:'Keeps your tribe warm and may prevent animals from attacking.//Used by some types of crafting.//Will burn out over time.',
  1340. desc:'Keeps your tribe warm; each fire reduces illness for 10 people.//Used by some types of crafting.//Will burn out over time.',
  1341. icon:[13,7],
  1342. category:'misc',
  1343. tick:function(me,tick)
  1344. {
  1345. var toSpoil=me.amount*0.01;
  1346. var spent=G.lose(me.name,randomFloor(toSpoil),'decay');
  1347. },
  1348. });
  1349.  
  1350.  
  1351. var limitDesc=function(limit){return 'It is limited by your '+limit+'; the closer to the limit, the slower it is to produce more.';};
  1352. var researchGetDisplayAmount=function()
  1353. {
  1354. var limit=G.getDict(this.limit).displayedAmount;
  1355. return B(this.displayedAmount)+'<wbr>/'+B(limit);
  1356. };
  1357. var researchWhenGathered=function(me,amount,by)
  1358. {
  1359. var limit=G.getDict(this.limit).amount;
  1360. if (limit>0)
  1361. {
  1362. var mult=1;
  1363. if (G.year<5) mult=1.5;//faster research the first 5 years
  1364. me.amount+=randomFloor(Math.pow(1-me.amount/limit,2)*(Math.random()*amount*me.mult*mult));
  1365. me.amount=Math.min(me.amount,limit);
  1366. }
  1367. };
  1368.  
  1369. new G.Res({
  1370. name:'insight',
  1371. desc:'[insight] represents your people\'s ideas and random sparks of intuition.//'+limitDesc('[wisdom]')+'//Many technologies require insight to be researched.',
  1372. icon:[8,4],
  1373. category:'main',
  1374. limit:'wisdom',
  1375. getDisplayAmount:researchGetDisplayAmount,
  1376. whenGathered:researchWhenGathered,
  1377. });
  1378. new G.Res({
  1379. name:'wisdom',
  1380. hidden:true,
  1381. icon:[8,5],
  1382. category:'main',
  1383. });
  1384.  
  1385. new G.Res({
  1386. name:'science',
  1387. desc:'[science] is the product of experiments and discoveries.//'+limitDesc('[education]')+'//Many technologies require science to be researched.',
  1388. icon:[6,4],
  1389. category:'main',
  1390. limit:'education',
  1391. getDisplayAmount:researchGetDisplayAmount,
  1392. whenGathered:researchWhenGathered,
  1393. });
  1394. new G.Res({
  1395. name:'education',
  1396. hidden:true,
  1397. icon:[6,5],
  1398. category:'main',
  1399. });
  1400.  
  1401. new G.Res({
  1402. name:'culture',
  1403. desc:'[culture] is produced when your people create beautiful and thought-provoking things.//'+limitDesc('[inspiration]')+'//Culture is used to develop cultural traits.',
  1404. icon:[10,4],
  1405. category:'main',
  1406. limit:'inspiration',
  1407. getDisplayAmount:researchGetDisplayAmount,
  1408. whenGathered:researchWhenGathered,
  1409. });
  1410. new G.Res({
  1411. name:'inspiration',
  1412. hidden:true,
  1413. icon:[10,5],
  1414. category:'main',
  1415. });
  1416.  
  1417. new G.Res({
  1418. name:'faith',
  1419. desc:'[faith] derives from all things divine, from meditation to sacrifices.//'+limitDesc('[spirituality]')+'//Some cultural traits and technologies depend on faith.',
  1420. icon:[7,4],
  1421. category:'main',
  1422. limit:'spirituality',
  1423. getDisplayAmount:researchGetDisplayAmount,
  1424. whenGathered:researchWhenGathered,
  1425. });
  1426. new G.Res({
  1427. name:'spirituality',
  1428. hidden:true,
  1429. icon:[7,5],
  1430. category:'main',
  1431. });
  1432.  
  1433. new G.Res({
  1434. name:'influence',
  1435. desc:'[influence] is generated by power structures.//You also get 1 influence point at the start of every year.//'+limitDesc('[authority]')+'//Influence is required to enact most policies or remove traits.',
  1436. icon:[11,4],
  1437. category:'main',
  1438. limit:'authority',
  1439. startWith:5,
  1440. getDisplayAmount:researchGetDisplayAmount,
  1441. whenGathered:researchWhenGathered,
  1442. });
  1443. new G.Res({
  1444. name:'authority',
  1445. hidden:true,
  1446. icon:[11,5],
  1447. category:'main',
  1448. });
  1449.  
  1450. /*=====================================================================================
  1451. UNITS
  1452. =======================================================================================*/
  1453. G.unitCategories.push(
  1454. {id:'debug',name:'Debug'},
  1455. {id:'housing',name:'Housing'},
  1456. {id:'civil',name:'Civil'},
  1457. {id:'crafting',name:'Crafting'},
  1458. {id:'production',name:'Gathering'},
  1459. {id:'political',name:'Political'},
  1460. {id:'discovery',name:'Discovery'},
  1461. {id:'cultural',name:'Cultural'},
  1462. {id:'spiritual',name:'Spiritual'},
  1463. {id:'exploration',name:'Exploration'},
  1464. {id:'storage',name:'Storage'},
  1465. {id:'wonder',name:'Wonders'}
  1466. );
  1467.  
  1468. G.MODE_OFF={name:'Off',desc:'The unit will not produce anything.'};
  1469.  
  1470. var unitGetsConverted=function(into,min,max,message,single,plural)
  1471. {
  1472. //the unit is destroyed and its workers are converted into something else (such as wounded or dead)
  1473. //min and max define the random percent of the unit's amount that gets wounded every day
  1474. return function(me)
  1475. {
  1476. var toChange=Math.min(1,Math.random()*(max-min)+min);
  1477. toChange=randomFloor(me.amount*toChange);
  1478. var workers=0;
  1479. if (me.mode && me.mode.use && me.mode.use['worker']) workers+=me.mode.use['worker'];
  1480. if (me.unit.use['worker']) workers+=me.unit.use['worker'];
  1481. if (me.unit.staff['worker']) workers+=me.unit.staff['worker'];
  1482. if (toChange>0 && workers>0)
  1483. {
  1484. peopleToChange=toChange*workers;
  1485. var changed=0;
  1486. if (true) {var i='adult';var n=G.lose(i,peopleToChange);changed+=n;}
  1487. if (changed<peopleToChange && G.checkPolicy('elder workforce')=='on') {var i='elder';var n=G.lose(i,peopleToChange);changed+=n;}
  1488. if (changed<peopleToChange && G.checkPolicy('child workforce')=='on') {var i='child';var n=G.lose(i,peopleToChange);changed+=n;}
  1489.  
  1490. for (var i in into)
  1491. {
  1492. G.gain(i,randomFloor(changed*into[i]),me.unit.displayName+' accident');
  1493. }
  1494. changed/=workers;
  1495. G.wasteUnit(me,changed);
  1496.  
  1497. if (changed>0) G.Message({type:'bad',mergeId:'unitGotConverted-'+me.unit.name,textFunc:function(args){
  1498. return args.str.replaceAll('\\[people\\]',(args.n==1?args.single:args.plural)).replaceAll('\\[X\\]',B(args.n));
  1499. },args:{n:changed,str:message,single:single,plural:plural},icon:me.unit.icon});
  1500. }
  1501. }
  1502. }
  1503.  
  1504. new G.Unit({
  1505. name:'gatherer',
  1506. startWith:5,
  1507. desc:'@forages for basic [food], [water] and [archaic building materials,Various interesting things]<>A vital part of an early tribe, [gatherer]s venture in the wilderness to gather food, wood, and other things of note.',
  1508. icon:[0,2],
  1509. cost:{},
  1510. use:{'worker':1},
  1511. //upkeep:{'food':0.2},
  1512. //alternateUpkeep:{'food':'spoiled food'},
  1513. effects:[
  1514. {type:'gather',context:'gather',amount:1.5,max:4},//,multMax:{'leather pouches':1.1}//TODO
  1515. //{type:'gather',context:'gather',what:{'water':1,'muddy water':1},amount:1,max:3,req:{'gathering focus':'water'}},
  1516. {type:'gather',context:'gather',what:{'water':1,'muddy water':1},amount:1,max:3},
  1517. {type:'gather',context:'gather',what:{'herb':0.5,'fruit':0.5},amount:1,max:1,req:{'plant lore':true}},
  1518. {type:'addFree',what:{'worker':0.1},req:{'scavenging':true}},
  1519. {type:'mult',value:1.2,req:{'harvest rituals':'on'}}
  1520. ],
  1521. req:{'tribalism':true},
  1522. category:'production',
  1523. });
  1524.  
  1525. new G.Unit({
  1526. name:'dreamer',
  1527. desc:'@generates [insight] every now and then, which you can use to research early technologies<>A [dreamer] spends their time observing, thinking, and wondering why things are the way they are.',
  1528. icon:[1,2],
  1529. cost:{},
  1530. use:{'worker':1},
  1531. //upkeep:{'coin':0.2},
  1532. effects:[
  1533. {type:'gather',what:{'insight':0.1}},
  1534. {type:'gather',what:{'insight':0.05},req:{'symbolism':true}},
  1535. {type:'mult',value:1.2,req:{'wisdom rituals':'on'}}
  1536. ],
  1537. req:{'speech':true},
  1538. category:'discovery',
  1539. });
  1540.  
  1541. new G.Unit({
  1542. name:'storyteller',
  1543. desc:'@generates [culture] every now and then<>[storyteller]s gather the tribe around at nightfall to tell the tales of their ancestors.',
  1544. icon:[14,2],
  1545. cost:{},
  1546. use:{'worker':1},
  1547. upkeep:{'coin':0.1},
  1548. effects:[
  1549. {type:'gather',what:{'culture':0.1}},
  1550. {type:'gather',what:{'culture':0.05},req:{'symbolism':true}},
  1551. {type:'mult',value:1.3,req:{'artistic thinking':true}},
  1552. {type:'mult',value:1.2,req:{'wisdom rituals':'on'}}
  1553. ],
  1554. req:{'oral tradition':true},
  1555. category:'cultural',
  1556. });
  1557.  
  1558. new G.Unit({
  1559. name:'artisan',
  1560. desc:'@starts with the ability to turn [stone]s into [knapped tools]@gains more modes as technology progresses<>An [artisan] dedicates their life to crafting various little objects by hand.//Note : artisans will gain new modes of operation when you discover new technologies, such as crafting stone tools; you can press the button with 3 dots on the side of this unit to switch between those modes.',
  1561. icon:[6,2],
  1562. cost:{},
  1563. use:{'worker':1},
  1564. upkeep:{'coin':0.1},
  1565. gizmos:true,
  1566. modes:{
  1567. 'knap':{name:'Knap flint',desc:'Turn [stone]s into [knapped tools].'},
  1568. 'knap bone':{name:'Knap bone',desc:'Turn [bone]s into [knapped tools].',req:{'bone-working':true}},
  1569. 'stone tools':{name:'Craft stone tools',desc:'Turn [stone]s and [stick]s into [stone tools].',req:{'tool-making':true},use:{'knapped tools':1}},
  1570. 'stone weapons':{name:'Craft stone weapons',desc:'Turn [stone]s and [stick]s into [stone weapons].',req:{'spears':true},use:{'knapped tools':1}},
  1571. 'bows':{name:'Craft bows',desc:'Turn [stone]s and [stick]s into [bow]s.',req:{'bows':true},use:{'stone tools':1}},
  1572. 'baskets':{name:'Weave baskets',desc:'Turn [stick]s into [basket]s.',req:{'basket-weaving':true},use:{'knapped tools':1}},
  1573. },
  1574. effects:[
  1575. {type:'convert',from:{'stone':1},into:{'knapped tools':1},every:5,mode:'knap'},
  1576. {type:'convert',from:{'bone':1},into:{'knapped tools':1},every:5,mode:'knap bone'},
  1577. {type:'convert',from:{'stick':1,'stone':1},into:{'stone tools':1},every:8,mode:'stone tools'},
  1578. {type:'convert',from:{'stick':1,'stone':1},into:{'stone weapons':1},every:8,mode:'stone weapons'},
  1579. {type:'convert',from:{'stick':1,'stone':1},into:{'bow':1},every:10,mode:'bows'},
  1580. {type:'convert',from:{'stick':15},into:{'basket':1},every:10,mode:'baskets'},
  1581. {type:'mult',value:1.2,req:{'ground stone tools':true}}
  1582. ],
  1583. req:{'stone-knapping':true},
  1584. category:'crafting',
  1585. });
  1586.  
  1587. new G.Unit({
  1588. name:'carver',
  1589. desc:'@starts with the ability to turn [stone]s or [bone]s into [statuette]s@gains more modes as technology progresses<>A [carver] uses fine hand-crafting to produce goods out of wood, stone and bone.',
  1590. icon:[21,2],
  1591. cost:{},
  1592. use:{'worker':1},
  1593. upkeep:{'coin':0.1},
  1594. gizmos:true,
  1595. modes:{
  1596. 'stone statuettes':{name:'Carve stone statuettes',desc:'Turn [stone]s into [statuette]s.',use:{'knapped tools':1}},
  1597. 'bone statuettes':{name:'Carve bone statuettes',desc:'Turn [bone]s into [statuette]s.',use:{'knapped tools':1}},
  1598. 'cut stone':{name:'Cut stones',desc:'Slowly turn 10 [stone]s into 1 [cut stone].',req:{'masonry':true},use:{'stone tools':1}},
  1599. 'smash cut stone':{name:'Smash stone blocks',desc:'Turn [cut stone]s into 9 [stone]s each.',req:{'quarrying':true},use:{'stone tools':1}},
  1600. 'gem blocks':{name:'Carve gem blocks',desc:'Slowly turn 10 [gems] into 1 [gem block].',req:{'gem-cutting':true},use:{'stone tools':1}}
  1601. },
  1602. effects:[
  1603. {type:'convert',from:{'stone':1},into:{'statuette':1},every:5,mode:'stone statuettes'},
  1604. {type:'convert',from:{'bone':1},into:{'statuette':1},every:5,mode:'bone statuettes'},
  1605. {type:'convert',from:{'stone':10},into:{'cut stone':1},every:15,mode:'cut stone'},
  1606. {type:'convert',from:{'cut stone':1},into:{'stone':9},every:5,mode:'smash cut stone'},
  1607. {type:'convert',from:{'gems':10},into:{'gem block':1},every:15,mode:'gem blocks'},
  1608. {type:'mult',value:1.2,req:{'ground stone tools':true}}
  1609. ],
  1610. req:{'carving':true},
  1611. category:'crafting',
  1612. });
  1613.  
  1614. new G.Unit({
  1615. name:'clothier',
  1616. desc:'@works with textiles, notably producing all kinds of clothes<>A [clothier] can make and use fabrics to keep your people clothed, and therefore warm and happy.',
  1617. icon:[19,2],
  1618. cost:{},
  1619. use:{'worker':1},
  1620. upkeep:{'coin':0.2},
  1621. gizmos:true,
  1622. modes:{
  1623. 'sew grass clothing':{name:'Sew grass clothing',desc:'Craft [primitive clothes] from 30 [herb]s each.',use:{'stone tools':1}},
  1624. 'sew hide clothing':{name:'Sew hide clothing',desc:'Craft [primitive clothes] from 3 [hide]s each.',use:{'stone tools':1}},
  1625. 'weave fiber clothing':{name:'Weave fiber clothing',desc:'Craft [basic clothes] from 50 [herb]s each.',use:{'stone tools':1},req:{'weaving':true}},//TODO : implement fibers
  1626. 'weave leather clothing':{name:'Weave leather clothing',desc:'Craft [basic clothes] from 2 [leather] each.',use:{'stone tools':1},req:{'weaving':true,'leather-working':true}},
  1627. 'make leather':{name:'Make leather',desc:'Produce [leather] from [hide]s, [water], [salt] and [log]s.',use:{'stone tools':1},req:{'leather-working':true}},
  1628. 'cheap make leather':{name:'Make leather (cheap)',desc:'Slowly produce [leather] from [hide]s, [muddy water] and [herb]s.',use:{'stone tools':1}},
  1629. },
  1630. effects:[
  1631. {type:'convert',from:{'hide':3},into:{'primitive clothes':1},every:8,mode:'sew hide clothing'},
  1632. {type:'convert',from:{'herb':30},into:{'primitive clothes':1},every:20,mode:'sew grass clothing'},
  1633. {type:'convert',from:{'leather':2},into:{'basic clothes':1},every:8,mode:'weave leather clothing'},
  1634. {type:'convert',from:{'herb':50},into:{'basic clothes':1},every:20,mode:'weave fiber clothing'},
  1635. {type:'convert',from:{'hide':1,'water':5,'salt':1,'log':0.1},into:{'leather':1},every:15,mode:'make leather'},
  1636. {type:'convert',from:{'hide':1,'muddy water':5,'herb':10},into:{'leather':1},every:30,mode:'cheap make leather'},
  1637. ],
  1638. req:{'sewing':true},
  1639. category:'crafting',
  1640. });
  1641.  
  1642. new G.Unit({
  1643. name:'hunter',
  1644. desc:'@hunts wild animals for [meat], [bone]s and [hide]s@may get wounded<>[hunter]s go out into the wilderness and come back days later covered in blood and the meat of a fresh kill.',
  1645. icon:[18,2],
  1646. cost:{},
  1647. use:{'worker':1},
  1648. //upkeep:{'coin':0.2},
  1649. gizmos:true,
  1650. modes:{
  1651. 'endurance hunting':{name:'Endurance hunting',desc:'Hunt animals by simply running after them until they get exhausted.//Slow and tedious.'},
  1652. 'spear hunting':{name:'Spear hunting',desc:'Hunt animals with spears.',use:{'stone weapons':1},req:{'spears':true}},
  1653. 'bow hunting':{name:'Bow hunting',desc:'Hunt animals with bows.',use:{'bow':1},req:{'bows':true}},
  1654. },
  1655. effects:[
  1656. {type:'gather',context:'hunt',amount:1,max:5,mode:'endurance hunting'},
  1657. {type:'gather',context:'hunt',amount:2.5,max:5,mode:'spear hunting'},
  1658. {type:'gather',context:'hunt',amount:4,max:5,mode:'bow hunting'},//TODO : consuming arrows?
  1659. {type:'function',func:unitGetsConverted({'wounded':1},0.001,0.03,'[X] [people] wounded while hunting.','hunter was','hunters were'),chance:1/30},
  1660. {type:'mult',value:1.2,req:{'harvest rituals':'on'}}
  1661. ],
  1662. req:{'hunting':true},
  1663. category:'production',
  1664. });
  1665. new G.Unit({
  1666. name:'fisher',
  1667. desc:'@catches [seafood] from rivers and shores<>[fisher]s arm themselves with patience and whatever bait they can find, hoping to trick another creature into becoming dinner.',
  1668. icon:[17,2],
  1669. cost:{},
  1670. use:{'worker':1},
  1671. //upkeep:{'coin':0.2},
  1672. gizmos:true,
  1673. modes:{
  1674. 'catch by hand':{name:'Catch by hand',desc:'Catch fish with nothing but bare hands.//Slow and tedious.'},
  1675. 'spear fishing':{name:'Spear fishing',desc:'Catch fish with spears.',use:{'stone weapons':1},req:{'spears':true}},
  1676. 'line fishing':{name:'Line fishing',desc:'Catch fish with fishing poles.',use:{'stone tools':1},req:{'fishing hooks':true}},
  1677. //TODO : nets
  1678. },
  1679. effects:[
  1680. {type:'gather',context:'fish',amount:1,max:5,mode:'catch by hand'},
  1681. {type:'gather',context:'fish',amount:2.5,max:5,mode:'spear fishing'},
  1682. {type:'gather',context:'fish',amount:4,max:5,mode:'line fishing'},
  1683. {type:'mult',value:1.2,req:{'harvest rituals':'on'}}
  1684. ],
  1685. req:{'fishing':true},
  1686. category:'production',
  1687. });
  1688. new G.Unit({
  1689. name:'firekeeper',
  1690. desc:'@creates [fire pit]s from fuel@gains more fuel types as technology progresses@handles other fire-related tasks<>The [firekeeper] is tasked with starting and maintaining fires to keep the tribe warm.',
  1691. icon:[16,2],
  1692. cost:{},
  1693. use:{'worker':1},
  1694. staff:{'knapped tools':1},
  1695. upkeep:{'coin':0.1},
  1696. gizmos:true,
  1697. modes:{
  1698. 'stick fires':{name:'Start fires from sticks',desc:'Craft [fire pit]s from 20 [stick]s each.'},
  1699. 'cook':{name:'Cook',desc:'Turn [meat] and [seafood] into [cooked meat] and [cooked seafood] in the embers of [fire pit]s',req:{'cooking':true}},
  1700. 'cure':{name:'Cure & smoke',desc:'Turn 1 [meat] or [seafood] into 2 [cured meat] or [cured seafood] using [salt] in the embers of [fire pit]s',req:{'curing':true}},
  1701. },
  1702. effects:[
  1703. {type:'convert',from:{'stick':20},into:{'fire pit':1},every:5,mode:'stick fires'},
  1704. {type:'convert',from:{'meat':1,'fire pit':0.01},into:{'cooked meat':1},every:1,repeat:5,mode:'cook'},
  1705. {type:'convert',from:{'seafood':1,'fire pit':0.01},into:{'cooked seafood':1},every:1,repeat:5,mode:'cook'},
  1706. {type:'convert',from:{'meat':1,'salt':1,'fire pit':0.01},into:{'cured meat':2},every:1,repeat:10,mode:'cure'},
  1707. {type:'convert',from:{'seafood':1,'salt':1,'fire pit':0.01},into:{'cured seafood':2},every:1,repeat:10,mode:'cure'},
  1708. ],
  1709. req:{'fire-making':true},
  1710. category:'crafting',
  1711. });
  1712.  
  1713. new G.Unit({
  1714. name:'potter',
  1715. desc:'@uses [clay] or [mud] to craft goods<>The [potter] shapes their clay with great care, for it might mean the difference between fresh water making it to their home safely - or spilling uselessly into the dirt.',
  1716. icon:[20,2],
  1717. cost:{},
  1718. use:{'worker':1},
  1719. staff:{'stone tools':1},
  1720. upkeep:{'coin':0.2},
  1721. gizmos:true,
  1722. modes:{
  1723. 'clay pots':{name:'Craft pots out of clay',desc:'Craft [pot]s from 3 [clay] each; requires [fire pit]s.'},
  1724. 'mud pots':{name:'Craft pots out of mud',desc:'Craft [pot]s from 10 [mud] each; requires [fire pit]s.'},
  1725. },
  1726. effects:[
  1727. {type:'convert',from:{'clay':3,'fire pit':0.01},into:{'pot':1},every:3,repeat:2,mode:'clay pots'},
  1728. {type:'convert',from:{'mud':10,'fire pit':0.01},into:{'pot':1},every:6,mode:'mud pots'}
  1729. ],
  1730. req:{'pottery':true},
  1731. category:'crafting',
  1732. });
  1733. new G.Unit({
  1734. name:'kiln',
  1735. desc:'@processes goods with fire<>A [kiln] is an impressive edifice for those not yet accustomed to its roaring fire.',//TODO : desc
  1736. icon:[23,2],
  1737. cost:{'archaic building materials':50,'basic building materials':20},
  1738. use:{'land':1},
  1739. //require:{'worker':1,'stone tools':1},
  1740. //upkeep:{'stick':3},//TODO : some fuel system
  1741. modes:{
  1742. 'off':G.MODE_OFF,
  1743. 'bricks':{name:'Fire bricks',desc:'Produce 10 [brick]s out of 1 [clay].',use:{'worker':1,'stone tools':1},req:{}},
  1744. },
  1745. effects:[
  1746. {type:'convert',from:{'clay':1},into:{'brick':10},every:5,mode:'bricks'},
  1747. ],
  1748. gizmos:true,
  1749. req:{'masonry':true},
  1750. category:'crafting',
  1751. });
  1752.  
  1753. new G.Unit({
  1754. name:'well',
  1755. desc:'@produces fresh [water], up to 20 per day<>The [well] is a steady source of drinkable water.',
  1756. icon:[25,3],
  1757. cost:{'stone':50,'archaic building materials':20},
  1758. use:{'land':1},
  1759. //require:{'worker':2,'stone tools':2},
  1760. //upkeep:{'coin':0.2},
  1761. effects:[
  1762. {type:'gather',what:{'water':20}},
  1763. ],
  1764. category:'production',
  1765. req:{'well-digging':true},
  1766. limitPer:{'land':10},
  1767. });
  1768.  
  1769. new G.Unit({
  1770. name:'digger',
  1771. desc:'@digs the soil for [mud] and [stone]<>[digger]s yield various materials that can be used for tool-making and rudimentary construction.',
  1772. icon:[7,2],
  1773. cost:{},
  1774. use:{'worker':1},
  1775. staff:{'knapped tools':1},
  1776. upkeep:{'coin':0.1},
  1777. effects:[
  1778. {type:'gather',context:'dig',amount:1,max:1},
  1779. {type:'gather',context:'dig',what:{'clay':5},max:1,req:{'pottery':true}}
  1780. ],
  1781. req:{'digging':true},
  1782. category:'production',
  1783. });
  1784. new G.Unit({
  1785. name:'quarry',
  1786. desc:'@carves [cut stone] out of the ground@may find other minerals such as [limestone] and [marble]<>The [quarry] dismantles the ground we stand on so that our children may reach higher heights.',
  1787. icon:[22,3],
  1788. cost:{'archaic building materials':100},
  1789. use:{'land':4},
  1790. //require:{'worker':3,'stone tools':3},
  1791. modes:{
  1792. 'off':G.MODE_OFF,
  1793. 'quarry':{name:'Quarry stone',desc:'Produce [cut stone] and other minerals.',use:{'worker':3,'stone tools':3}},
  1794. 'advanced quarry':{name:'Advanced quarry stone',desc:'Produce [cut stone] and other minerals at a superior rate with metal tools.',use:{'worker':3,'metal tools':3}},
  1795. },
  1796. effects:[
  1797. {type:'gather',context:'quarry',amount:5,max:10,every:3,mode:'quarry'},
  1798. {type:'gather',context:'quarry',what:{'cut stone':1},max:5,notMode:'off'},
  1799. {type:'gather',context:'mine',amount:0.005,max:0.05,notMode:'off'},
  1800. {type:'gather',context:'quarry',amount:10,max:30,every:3,mode:'advanced quarry'},
  1801. {type:'function',func:unitGetsConverted({'wounded':1},0.001,0.01,'[X] [people].','quarry collapsed, wounding its workers','quarries collapsed, wounding their workers'),chance:1/50}
  1802. ],
  1803. gizmos:true,
  1804. req:{'quarrying':true},
  1805. category:'production',
  1806. });
  1807. new G.Unit({
  1808. name:'mine',
  1809. desc:'@extracts ores, [coal] and [stone] out of the ground@may occasionally collapse<>The workers in [mine]s burrow deep into the earth to provide all kinds of minerals.',
  1810. icon:[22,2],
  1811. cost:{'archaic building materials':100},
  1812. use:{'land':3},
  1813. //require:{'worker':3,'stone tools':3},
  1814. modes:{
  1815. 'off':G.MODE_OFF,
  1816. 'any':{name:'Any',desc:'Mine without focusing on specific ores.',use:{'worker':3,'stone tools':3}},
  1817. 'coal':{name:'Coal',desc:'Mine for [coal] with x5 efficiency.',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1818. 'salt':{name:'Salt',desc:'Mine for [salt].',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1819. 'copper':{name:'Copper',desc:'Mine for [copper ore] with x5 efficiency.',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1820. 'tin':{name:'Tin',desc:'Mine for [tin ore] with x5 efficiency.',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1821. 'iron':{name:'Iron',desc:'Mine for [iron ore] with x5 efficiency.',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1822. 'gold':{name:'Gold',desc:'Mine for [gold ore] with x5 efficiency.',req:{'prospecting':true},use:{'worker':3,'metal tools':3}},
  1823. },
  1824. effects:[
  1825. {type:'gather',context:'mine',amount:10,max:30,mode:'any'},
  1826. {type:'gather',context:'mine',what:{'stone':10},max:30,notMode:'off'},
  1827. {type:'gather',context:'mine',what:{'coal':50},max:30,mode:'coal'},
  1828. {type:'gather',context:'mine',what:{'salt':50},max:30,mode:'salt'},
  1829. {type:'gather',context:'mine',what:{'copper ore':50},max:30,mode:'copper'},
  1830. {type:'gather',context:'mine',what:{'tin ore':50},max:30,mode:'tin'},
  1831. {type:'gather',context:'mine',what:{'iron ore':50},max:30,mode:'iron'},
  1832. {type:'gather',context:'mine',what:{'gold ore':50},max:30,mode:'gold'},
  1833. {type:'function',func:unitGetsConverted({'wounded':1},0.001,0.01,'[X] [people].','mine collapsed, wounding its miners','mines collapsed, wounding their miners'),chance:1/50}
  1834. ],
  1835. gizmos:true,
  1836. req:{'mining':true},
  1837. category:'production',
  1838. });
  1839. new G.Unit({
  1840. name:'furnace',
  1841. desc:'@converts metal ores into ingots that can be used for further crafting<>The [furnace] is employed in various processes to extract the metal in raw ore, as well as for alloying those metals.',
  1842. icon:[24,2],
  1843. cost:{'basic building materials':100},
  1844. use:{'land':1},
  1845. //require:{'worker':2,'stone tools':2},
  1846. modes:{
  1847. 'off':G.MODE_OFF,
  1848. 'copper':{name:'Copper smelting',desc:'Cast [soft metal ingot]s out of 5 [copper ore]s each.',use:{'worker':2,'stone tools':2},req:{}},
  1849. 'tin':{name:'Tin smelting',desc:'Cast [soft metal ingot]s out of 10 [tin ore]s each.',use:{'worker':2,'stone tools':2},req:{}},
  1850. 'iron':{name:'Iron smelting',desc:'Cast [hard metal ingot]s out of 5 [iron ore]s each.',use:{'worker':2,'metal tools':2},req:{'iron-working':true}},
  1851. 'gold':{name:'Gold smelting',desc:'Cast [precious metal ingot]s out of 5 [gold ore]s each.',use:{'worker':2,'metal tools':2},req:{'gold-working':true}},
  1852. 'bronze':{name:'Bronze alloying',desc:'Cast [hard metal ingot]s out of 8 [copper ore]s and 2 [tin ore]s each.',use:{'worker':2,'metal tools':2},req:{'bronze-working':true}},
  1853. 'steel':{name:'Steel alloying',desc:'Cast [strong metal ingot]s out of 19 [iron ore]s and 1 [coal] each.',use:{'worker':2,'metal tools':2},req:{'steel-making':true}},
  1854. },
  1855. effects:[
  1856. {type:'convert',from:{'copper ore':5},into:{'soft metal ingot':1},repeat:3,mode:'copper'},
  1857. {type:'convert',from:{'tin ore':10},into:{'soft metal ingot':1},repeat:3,mode:'tin'},
  1858. {type:'convert',from:{'iron ore':5},into:{'hard metal ingot':1},repeat:3,mode:'iron'},
  1859. {type:'convert',from:{'gold ore':5},into:{'precious metal ingot':1},repeat:1,mode:'gold'},
  1860. {type:'convert',from:{'tin ore':2,'copper ore':8},into:{'hard metal ingot':1},repeat:3,mode:'bronze'},
  1861. {type:'convert',from:{'iron ore':19,'coal':1},into:{'strong metal ingot':1},repeat:1,mode:'steel'},
  1862. {type:'waste',chance:0.001/1000},
  1863. ],
  1864. gizmos:true,
  1865. req:{'smelting':true},
  1866. category:'crafting',
  1867. });
  1868. new G.Unit({
  1869. name:'blacksmith workshop',
  1870. desc:'@forges metal goods out of ingots<>The [blacksmith workshop,Blacksmith] takes the same pride in shaping the tool that tills as they do the sword that slays.',
  1871. icon:[26,2,25,2],
  1872. cost:{'basic building materials':100},
  1873. use:{'land':1},
  1874. //require:{'worker':2,'stone tools':2},
  1875. modes:{
  1876. 'off':G.MODE_OFF,
  1877. 'metal tools':{name:'Forge tools from soft metals',desc:'Forge [metal tools] out of 2 [soft metal ingot]s each.',use:{'worker':1,'stone tools':1},req:{}},
  1878. 'hard metal tools':{name:'Forge tools from hard metals',desc:'Forge 3 [metal tools] out of 1 [hard metal ingot].',use:{'worker':1,'metal tools':1},req:{}},
  1879. 'gold blocks':{name:'Forge gold blocks',desc:'Forge [gold block]s out of 10 [precious metal ingot]s each.',use:{'worker':1,'stone tools':1},req:{'gold-working':true}},
  1880. },
  1881. effects:[
  1882. {type:'convert',from:{'soft metal ingot':2},into:{'metal tools':1},repeat:3,mode:'metal tools'},
  1883. {type:'convert',from:{'hard metal ingot':1},into:{'metal tools':3},repeat:3,mode:'hard metal tools'},
  1884. {type:'convert',from:{'precious metal ingot':10},into:{'gold block':1},mode:'gold blocks'},
  1885. {type:'waste',chance:0.001/1000},
  1886. //TODO : better metal tools, weapons etc
  1887. ],
  1888. gizmos:true,
  1889. req:{'smelting':true},
  1890. category:'crafting',
  1891. });
  1892.  
  1893. new G.Unit({
  1894. name:'woodcutter',
  1895. desc:'@cuts trees, producing [log]s<>[woodcutter]s turn forests into precious wood that can be used as fuel or construction materials.',
  1896. icon:[8,2],
  1897. cost:{},
  1898. use:{'worker':1},
  1899. staff:{'knapped tools':1},
  1900. upkeep:{'coin':0.1},
  1901. effects:[
  1902. {type:'gather',context:'chop',amount:1,max:1}
  1903. ],
  1904. req:{'woodcutting':true},
  1905. category:'production',
  1906. });
  1907. new G.Unit({
  1908. name:'carpenter workshop',
  1909. desc:'@processes wood<>The [carpenter workshop,Carpenter] is equipped with all kinds of tools to coerce wood into more useful shapes.',
  1910. icon:[27,2,25,2],
  1911. cost:{'basic building materials':100},
  1912. use:{'land':1},
  1913. //require:{'worker':2,'stone tools':2},
  1914. modes:{
  1915. 'off':G.MODE_OFF,
  1916. 'lumber':{name:'Cut logs into lumber',desc:'Cut [log]s into 3 [lumber] each.',use:{'worker':1,'stone tools':1},req:{}},
  1917. },
  1918. effects:[
  1919. {type:'convert',from:{'log':1},into:{'lumber':3},repeat:2,mode:'lumber'},
  1920. {type:'waste',chance:0.001/1000},
  1921. ],
  1922. gizmos:true,
  1923. req:{'carpentry':true},
  1924. category:'crafting',
  1925. });
  1926.  
  1927. new G.Unit({
  1928. name:'soothsayer',
  1929. desc:'@generates [faith] and [happiness] every now and then<>[soothsayer]s tell the tales of the dead, helping tribespeople deal with grief.',
  1930. icon:[15,2],
  1931. cost:{},
  1932. use:{'worker':1},
  1933. upkeep:{'coin':0.2},
  1934. effects:[
  1935. {type:'gather',what:{'faith':0.1,'happiness':0.2}},
  1936. {type:'gather',what:{'faith':0.05},req:{'symbolism':true}}
  1937. ],
  1938. req:{'ritualism':true},
  1939. category:'spiritual',
  1940. });
  1941. new G.Unit({
  1942. name:'healer',
  1943. desc:'@uses [herb]s to heal the [sick] and the [wounded] slowly<>The [healer] knows the secrets of special plants that make illness stay away.',
  1944. icon:[23,3],
  1945. cost:{},
  1946. use:{'worker':1},
  1947. staff:{'knapped tools':1},
  1948. upkeep:{'coin':0.2},
  1949. effects:[
  1950. {type:'convert',from:{'sick':1,'herb':2.5},into:{'adult':1},chance:1/2,every:3},
  1951. {type:'convert',from:{'wounded':1,'herb':2.5},into:{'adult':1},chance:1/5,every:10},
  1952. ],
  1953. req:{'healing':true},
  1954. category:'spiritual',
  1955. });
  1956.  
  1957. new G.Unit({
  1958. name:'chieftain',
  1959. desc:'@generates [influence] every now and then<>The [chieftain] leads over a small group of people, guiding them in their decisions.',
  1960. icon:[18,3],
  1961. cost:{'food':50},
  1962. use:{'worker':1},
  1963. upkeep:{'coin':0.5},
  1964. effects:[
  1965. {type:'gather',what:{'influence':0.1}},
  1966. {type:'gather',what:{'influence':0.05},req:{'code of law':true}}
  1967. ],
  1968. limitPer:{'population':100},
  1969. req:{'chieftains':true},
  1970. category:'political',
  1971. });
  1972. new G.Unit({
  1973. name:'clan leader',
  1974. desc:'@generates [influence] every now and then<>The [clan leader] is followed by many, and is trusted with defending the honor and safety of their people.',
  1975. icon:[19,3],
  1976. cost:{'food':100},
  1977. use:{'worker':1},
  1978. upkeep:{'coin':0.75},
  1979. effects:[
  1980. {type:'gather',what:{'influence':0.2}},
  1981. {type:'gather',what:{'influence':0.05},req:{'code of law':true}}
  1982. ],
  1983. limitPer:{'population':500},
  1984. req:{'clans':true},
  1985. category:'political',
  1986. });
  1987.  
  1988. new G.Unit({
  1989. name:'grave',
  1990. desc:'@provides 1 [burial space], in which the [corpse,dead] are automatically interred one by one@graves with buried corpses decay over time, freeing up land for more graves<>A simple grave dug into the earth, where the dead may find rest.//Burying your dead helps prevent [health,disease] and makes your people slightly [happiness,happier].',
  1991. icon:[13,2],
  1992. cost:{},
  1993. use:{'land':1},
  1994. //require:{'worker':1,'knapped tools':1},
  1995. effects:[
  1996. {type:'provide',what:{'burial space':1},noTakeBack:true},
  1997. //{type:'waste',chance:1/100,desired:true},
  1998. {type:'function',func:function(me){
  1999. var buried=G.getRes('burial space').used;
  2000. if (buried>0 && G.getRes('burial space').amount>=buried)
  2001. {
  2002. var toDie=Math.min(me.amount,randomFloor(buried*0.001));
  2003. me.targetAmount-=toDie;
  2004. G.wasteUnit(me,toDie);
  2005. G.getRes('burial space').amount-=toDie;
  2006. G.getRes('burial space').used-=toDie;
  2007. }
  2008. }}
  2009. ],
  2010. req:{'burial':true},
  2011. category:'civil',
  2012. });
  2013.  
  2014. new G.Unit({
  2015. name:'mud shelter',
  2016. desc:'@provides 3 [housing]<>Basic, frail dwelling in which a small family can live.',
  2017. icon:[9,2],
  2018. cost:{'mud':50},
  2019. use:{'land':1},
  2020. //require:{'worker':1,'knapped tools':1},
  2021. effects:[
  2022. {type:'provide',what:{'housing':3}},
  2023. {type:'waste',chance:1/1000}
  2024. ],
  2025. req:{'sedentism':true},
  2026. category:'housing',
  2027. });
  2028. new G.Unit({
  2029. name:'branch shelter',
  2030. desc:'@provides 3 [housing]<>Basic, very frail dwelling in which a small family can live.',
  2031. icon:[10,2],
  2032. cost:{'stick':50},
  2033. use:{'land':1},
  2034. //require:{'worker':1,'knapped tools':1},
  2035. effects:[
  2036. {type:'provide',what:{'housing':3}},
  2037. {type:'waste',chance:3/1000}
  2038. ],
  2039. req:{'sedentism':true},
  2040. category:'housing',
  2041. });
  2042. new G.Unit({
  2043. name:'hut',
  2044. desc:'@provides 5 [housing]<>Small dwelling built out of hardened mud and branches.',
  2045. icon:[11,2],
  2046. cost:{'archaic building materials':100},
  2047. use:{'land':1},
  2048. //require:{'worker':2,'stone tools':2},
  2049. effects:[
  2050. {type:'provide',what:{'housing':5}},
  2051. {type:'waste',chance:0.1/1000}
  2052. ],
  2053. req:{'building':true},
  2054. category:'housing',
  2055. });
  2056. new G.Unit({
  2057. name:'hovel',
  2058. desc:'@provides 8 [housing]<>A simple home for a family of villagers.',
  2059. icon:[20,3],
  2060. cost:{'basic building materials':75},
  2061. use:{'land':1},
  2062. //require:{'worker':2,'stone tools':2},
  2063. effects:[
  2064. {type:'provide',what:{'housing':8}},
  2065. {type:'waste',chance:0.03/1000}
  2066. ],
  2067. req:{'cities':true},
  2068. category:'housing',
  2069. });
  2070. new G.Unit({
  2071. name:'house',
  2072. desc:'@provides 10 [housing]<>A sturdy home built to last.',
  2073. icon:[21,3],
  2074. cost:{'basic building materials':100},
  2075. use:{'land':1},
  2076. //require:{'worker':3,'metal tools':3},
  2077. effects:[
  2078. {type:'provide',what:{'housing':10}},
  2079. {type:'waste',chance:0.01/1000}
  2080. ],
  2081. req:{'construction':true},
  2082. category:'housing',
  2083. });
  2084.  
  2085. new G.Unit({
  2086. name:'storage pit',
  2087. desc:'@provides 400 [food storage] and 400 [material storage]<>A simple hole in the ground, lined with stones.//Prevents some amount of food from perishing and some goods from being stolen, but may crumble away over time.',
  2088. icon:[12,2],
  2089. cost:{'archaic building materials':50},
  2090. use:{'land':2},
  2091. //require:{'worker':2,'knapped tools':2},
  2092. effects:[
  2093. {type:'provide',what:{'added food storage':400}},
  2094. {type:'provide',what:{'added material storage':400}},
  2095. {type:'waste',chance:0.8/1000}
  2096. ],
  2097. req:{'stockpiling':true},
  2098. category:'storage',
  2099. });
  2100. new G.Unit({
  2101. name:'stockpile',
  2102. desc:'@provides 1000 [material storage]<>A simple building where resources are stored.//Slows material decay and deters theft somewhat, but may itself decay over time.',
  2103. icon:[22,4],
  2104. cost:{'archaic building materials':100},
  2105. use:{'land':2},
  2106. //require:{'worker':2,'stone tools':2},
  2107. effects:[
  2108. {type:'provide',what:{'added material storage':1000}},
  2109. {type:'waste',chance:0.1/1000}
  2110. ],
  2111. req:{'stockpiling':true,'building':true},
  2112. category:'storage',
  2113. });
  2114. new G.Unit({
  2115. name:'warehouse',
  2116. desc:'@provides 4000 [material storage]<>A large building for storing materials. Staffed with two guards to prevent theft.',
  2117. icon:[25,4],
  2118. cost:{'basic building materials':500},
  2119. use:{'land':3},
  2120. staff:{'worker':2},
  2121. //require:{'worker':3,'stone tools':3},
  2122. effects:[
  2123. {type:'provide',what:{'added material storage':4000}},
  2124. {type:'waste',chance:0.001/1000}
  2125. ],
  2126. req:{'stockpiling':true,'construction':true},
  2127. category:'storage',
  2128. });
  2129. new G.Unit({
  2130. name:'granary',
  2131. desc:'@provides 1000 [food storage]<>A grain storage building built on stilts to prevent pests from getting in.',
  2132. icon:[23,4],
  2133. cost:{'archaic building materials':50,'basic building materials':50,'pot':15},
  2134. use:{'land':2},
  2135. //require:{'worker':2,'stone tools':2},
  2136. effects:[
  2137. {type:'provide',what:{'added food storage':1000}},
  2138. {type:'waste',chance:0.01/1000}
  2139. ],
  2140. req:{'stockpiling':true,'pottery':true},
  2141. category:'storage',
  2142. });
  2143. new G.Unit({
  2144. name:'barn',
  2145. desc:'@provides 4000 [food storage]<>A large wooden building for storing food. A worker manages the grain to prevent rot.',
  2146. icon:[24,4],
  2147. cost:{'basic building materials':500},
  2148. use:{'land':2},
  2149. staff:{'worker':1},
  2150. //require:{'worker':2,'stone tools':2},
  2151. effects:[
  2152. {type:'provide',what:{'added food storage':4000}},
  2153. {type:'waste',chance:0.001/1000}
  2154. ],
  2155. req:{'stockpiling':true,'carpentry':true},
  2156. category:'storage',
  2157. });
  2158.  
  2159. new G.Unit({
  2160. name:'architect',
  2161. desc:'@can be set to manage automatic building construction<>The [architect] is tasked with fulfilling your people\'s housing needs so that you don\'t have to worry about it too much.',
  2162. icon:[26,4],
  2163. cost:{},
  2164. use:{'worker':1},
  2165. upkeep:{'coin':0.5},
  2166. gizmos:true,
  2167. modes:{
  2168. 'off':G.MODE_OFF,
  2169. 'house building':{name:'House building',desc:'Build [house]s as long as there is homelessness and the right materials are available.'},
  2170. 'undertaker':{name:'Undertaker',desc:'Dig [grave]s as long as there are unburied corpses.'},
  2171. },
  2172. effects:[
  2173. {type:'function',func:function(me){
  2174. var wiggleRoom=10;
  2175. var homeless=Math.max(0,(G.getRes('population').amount+wiggleRoom)-G.getRes('housing').amount);
  2176. var toMake=me.amount-me.idle;
  2177. if (homeless>0 && toMake>0 && G.canBuyUnitByName('house',toMake))
  2178. {
  2179. G.buyUnitByName('house',toMake,true);
  2180. }
  2181. },mode:'house building'},
  2182. {type:'function',func:function(me){
  2183. var wiggleRoom=5;
  2184. var toMake=Math.min(me.amount-me.idle,Math.max(0,(G.getRes('corpse').amount+wiggleRoom)-(G.getRes('burial space').amount-G.getRes('burial space').used)));
  2185. if (toMake>0 && G.canBuyUnitByName('house',toMake))
  2186. {
  2187. G.buyUnitByName('grave',toMake,true);
  2188. }
  2189. },mode:'undertaker'}
  2190. ],
  2191. limitPer:{'land':100},
  2192. req:{'city planning':true},
  2193. category:'civil',
  2194. });
  2195.  
  2196. new G.Unit({
  2197. name:'lodge',
  2198. desc:'@NOTE : modes are disabled for now.@can be set to manage automatic recruitment for units such as [gatherer]s, [hunter]s or [woodcutter]s<>A [lodge] is where people of all professions gather to rest and store their tools.//Lodges let you automate your tribe somewhat; should a worker fall sick or die, they will be automatically replaced if a lodge is tasked for it.',
  2199. icon:[17,3],
  2200. cost:{'archaic building materials':50},
  2201. use:{'land':1},
  2202. //require:{'worker':1,'knapped tools':1},
  2203. //upkeep:{'coin':0.5},
  2204. gizmos:true,
  2205. modes:{
  2206. 'off':G.MODE_OFF,
  2207. 'gatherers':{name:'Gatherer\'s lodge',desc:'Hire [gatherer]s until there are 5 for each of this lodge.',req:{'tribalism':true}},
  2208. 'hunters':{name:'Hunter\'s lodge',desc:'Hire [hunter]s until there are 5 for each of this lodge.',req:{'hunting':true}},
  2209. 'fishers':{name:'Fisher\'s lodge',desc:'Hire [fisher]s until there are 5 for each of this lodge.',req:{'fishing':true}},
  2210. 'diggers':{name:'Digger\'s lodge',desc:'Hire [digger]s until there are 5 for each of this lodge.',req:{'digging':true}},
  2211. 'woodcutters':{name:'Woodcutter\'s lodge',desc:'Hire [woodcutter]s until there are 5 for each of this lodge.',req:{'woodcutting':true}},
  2212. 'artisans':{name:'Artisan\'s lodge',desc:'Hire [artisan]s until there are 5 for each of this lodge.',req:{'stone-knapping':true}},
  2213. },
  2214. effects:[
  2215. /*{type:'function',func:function(me){
  2216. if (me.amount*5>G.getUnitAmount('gatherer')) G.buyUnitByName('gatherer',1,true);
  2217. },mode:'gatherers'},
  2218. {type:'function',func:function(me){
  2219. if (me.amount*5>G.getUnitAmount('hunter')) G.buyUnitByName('hunter',1,true);
  2220. },mode:'hunters'},
  2221. {type:'function',func:function(me){
  2222. if (me.amount*5>G.getUnitAmount('fisher')) G.buyUnitByName('fisher',1,true);
  2223. },mode:'fishers'},
  2224. {type:'function',func:function(me){
  2225. if (me.amount*5>G.getUnitAmount('digger')) G.buyUnitByName('digger',1,true);
  2226. },mode:'diggers'},
  2227. {type:'function',func:function(me){
  2228. if (me.amount*5>G.getUnitAmount('woodcutter')) G.buyUnitByName('woodcutter',1,true);
  2229. },mode:'woodcutters'},
  2230. {type:'function',func:function(me){
  2231. if (me.amount*5>G.getUnitAmount('artisan')) G.buyUnitByName('artisan',1,true);
  2232. },mode:'artisans'},*/
  2233. ],
  2234. req:{'sedentism':true},
  2235. category:'civil',
  2236. });
  2237. new G.Unit({
  2238. name:'guild quarters',
  2239. desc:'@NOTE : modes are disabled for now.@can be set to manage automatic recruitment for units such as [blacksmith workshop]s or [carpenter workshop]s<>[guild quarters,Guilds] -that is, associations of people sharing the same profession- meet in these to share their craft and trade secrets.//They can coordinate the building of new workshops should the need arise.',
  2240. icon:[26,3,25,2],
  2241. cost:{'basic building materials':75},
  2242. use:{'land':1},
  2243. staff:{'worker':1},
  2244. //require:{'worker':2,'stone tools':2},
  2245. upkeep:{'coin':0.5},
  2246. gizmos:true,
  2247. modes:{
  2248. 'off':G.MODE_OFF,
  2249. 'potters':{name:'Potters\' guild',desc:'Hire [potter]s until there are 5 for each of this guild.',req:{'pottery':true}},
  2250. 'carpenters':{name:'Carpenters\' guild',desc:'Build [carpenter workshop]s until there are 5 for each of this guild.',req:{'carpentry':true}},
  2251. 'blacksmiths':{name:'Blacksmiths\' guild',desc:'Build [blacksmith workshop]s until there are 5 for each of this guild.',req:{'smelting':true}},
  2252. },
  2253. effects:[
  2254. /*{type:'function',func:function(me){
  2255. if (me.amount*5>G.getUnitAmount('potter')) G.buyUnitByName('potter',1,true);
  2256. },mode:'potters'},
  2257. {type:'function',func:function(me){
  2258. if (me.amount*5>G.getUnitAmount('carpenter workshop')) G.buyUnitByName('carpenter workshop',1,true);
  2259. },mode:'carpenters'},
  2260. {type:'function',func:function(me){
  2261. if (me.amount*5>G.getUnitAmount('blacksmith workshop')) G.buyUnitByName('blacksmith workshop',1,true);
  2262. },mode:'blacksmiths'}*/
  2263. ],
  2264. req:{'guilds':true},
  2265. category:'civil',
  2266. });
  2267.  
  2268. new G.Unit({
  2269. name:'wanderer',
  2270. desc:'@explores occupied tiles for [land]@cannot discover new tiles@may sometimes get lost<>[wanderer]s walk about in search of new places to settle, reporting what they saw when they come back.',
  2271. icon:[2,2],
  2272. cost:{'food':20},
  2273. use:{'worker':1},
  2274. effects:[
  2275. {type:'explore',explored:0.1,unexplored:0},
  2276. {type:'function',func:unitGetsConverted({},0.01,0.05,'[X] [people].','wanderer got lost','wanderers got lost'),chance:1/100}
  2277. ],
  2278. req:{'speech':true},
  2279. category:'exploration',
  2280. });
  2281. new G.Unit({
  2282. name:'scout',
  2283. desc:'@discovers new tiles for [land]@cannot explore occupied tiles@may sometimes get lost<>[scout]s explore the world in search of new territories.',
  2284. icon:[24,3],
  2285. cost:{'food':100},
  2286. use:{'worker':1},
  2287. staff:{'stone tools':1},
  2288. effects:[
  2289. {type:'explore',explored:0,unexplored:0.01},
  2290. {type:'function',func:unitGetsConverted({},0.01,0.05,'[X] [people].','scout got lost','scouts got lost'),chance:1/300}
  2291. ],
  2292. req:{'scouting':true},
  2293. category:'exploration',
  2294. });
  2295.  
  2296. //wonders
  2297.  
  2298. new G.Unit({
  2299. name:'mausoleum',
  2300. desc:'@leads to the <b>Mausoleum Victory</b><>A mystical monument where the dead lie.//A temple housing a tomb deep under its rocky platform, the Mausoleum stands tall, its eternal shadow forever reminding your people of your greatness.',
  2301. wonder:'mausoleum',
  2302. icon:[1,14],
  2303. wideIcon:[0,14],
  2304. cost:{'basic building materials':1000},
  2305. costPerStep:{'basic building materials':200,'precious building materials':20},
  2306. steps:100,
  2307. messageOnStart:'You begin the construction of the Mausoleum. Its towering mass already dominates the city, casting fear and awe wherever its shadow reaches.',
  2308. finalStepCost:{'population':100},
  2309. finalStepDesc:'To complete the Mausoleum, 100 of your [population,People] must be sacrificed to accompany you as servants in the afterlife.',
  2310. use:{'land':10},
  2311. //require:{'worker':10,'stone tools':10},
  2312. req:{'monument-building':true},
  2313. category:'wonder',
  2314. });
  2315.  
  2316. //debug units
  2317. new G.Unit({
  2318. name:'auto nanny',
  2319. desc:'@generates 50 [fruit], 50 [cooked meat,Meat], and 100 [water]<>Keeps your people fed so you don\'t have to.//Powered by strange energies.',
  2320. icon:[4,2],
  2321. cost:{},
  2322. effects:[
  2323. {type:'gather',what:{'fruit':50,'cooked meat':50,'water':100}}
  2324. ],
  2325. category:'debug',
  2326. });
  2327. new G.Unit({
  2328. name:'auto brain',
  2329. desc:'@generates 50 of [insight], [culture], [faith], [science] and [influence]<>Educates your people so you don\'t have to.//Powered by strange energies.',
  2330. icon:[5,2],
  2331. cost:{},
  2332. effects:[
  2333. {type:'gather',what:{'insight':50,'culture':50,'faith':50,'science':50,'influence':50}}
  2334. ],
  2335. category:'debug',
  2336. });
  2337.  
  2338.  
  2339. /*=====================================================================================
  2340. TECH & TRAIT CATEGORIES
  2341. =======================================================================================*/
  2342. G.knowCategories.push(
  2343. {id:'main',name:'General'},
  2344. {id:'misc',name:'Miscellaneous'},
  2345. {id:'knowledge',name:'Knowledge'},
  2346. {id:'culture',name:'Cultural'},
  2347. {id:'religion',name:'Religious'},
  2348. {id:'short',name:'Short-term'},//you can only have so many traits with this category; if the player gains a new "short" trait, the oldest "short" trait is removed
  2349. {id:'long',name:'Long-term'}//you can only have so many traits with this category; if the player gains a new "long" trait, the oldest "long" trait is removed
  2350. );
  2351.  
  2352. /*=====================================================================================
  2353. TECHS
  2354. =======================================================================================*/
  2355.  
  2356. new G.ChooseBox({
  2357. name:'research box',
  2358. context:'tech',
  2359. choicesN:5,
  2360. getCosts:function()
  2361. {
  2362. var cost=Math.floor(G.getRes('wisdom').amount*(0.025+0.05*this.roll));
  2363. return {'insight':cost};
  2364. },
  2365. getCardCosts:function(what)
  2366. {
  2367. return what.cost;
  2368. },
  2369. getCards:function()
  2370. {
  2371. var choices=[];
  2372. var n=G.tech.length;
  2373. for (var i=0;i<n;i++)
  2374. {
  2375. var tech=G.tech[i];
  2376. if (!G.techsOwnedNames.includes(tech.name) && G.checkReq(tech.req))
  2377. {
  2378. if (tech.chance)
  2379. {
  2380. var chance=randomFloor(tech.chance);
  2381. for (var ii=0;ii<chance;ii++)
  2382. {
  2383. choices.push(tech);
  2384. }
  2385. }
  2386. else choices.push(tech);
  2387. }
  2388. }
  2389. return choices;
  2390. },
  2391. onBuy:function(what,index)
  2392. {
  2393. G.fastTicks+=G.props['fastTicksOnResearch'];
  2394. G.gainTech(what);
  2395. G.Message({type:'good tall',text:'Your people have discovered the secrets of <b>'+what.displayName+'</b>.',icon:what.icon})
  2396. G.update['tech']();
  2397. G.popupSquares.spawn(l('chooseOption-'+index+'-'+this.id),l('techBox').children[0]);
  2398. l('techBox').children[0].classList.add('popIn');
  2399. },
  2400. onReroll:function()
  2401. {
  2402. this.roll+=1;
  2403. G.update['tech']();
  2404. G.popupSquares.spawn(l('chooseIgniter-'+this.id),l('chooseBox-'+this.id));
  2405. },
  2406. onTick:function()
  2407. {
  2408. this.roll-=0.01;
  2409. this.roll=Math.max(this.roll,0);
  2410. },
  2411. buttonText:function()
  2412. {
  2413. var str='';
  2414. if (this.choices.length>0) str+='Reroll';
  2415. else str+='Research';
  2416. var costs=this.getCosts();
  2417. var costsStr=G.getCostString(costs);
  2418. if (costsStr) str+=' ('+costsStr+')';
  2419. return str;
  2420. },
  2421. buttonTooltip:function()
  2422. {
  2423. return '<div class="info"><div class="par">'+(this.choices.length==0?'Generate new research opportunities.<br>The cost scales with your Wisdom resource.':'Reroll into new research opportunities if none of the available choices suit you.<br>Cost increases with each reroll, but will decrease again over time.')+'</div><div>Cost : '+G.getCostString(this.getCosts(),true)+'.</div></div>';
  2424. }
  2425. });
  2426.  
  2427.  
  2428. new G.Tech({
  2429. name:'tribalism',
  2430. desc:'@unlocks [gatherer]@provides 5 [authority]<>Taking its roots in wild animal packs, [tribalism] is the organization of individuals into simple social structures with little hierarchy.',
  2431. icon:[0,1],
  2432. startWith:true,
  2433. effects:[
  2434. {type:'provide res',what:{'authority':5}},
  2435. {type:'show res',what:['influence']},
  2436. {type:'show context',what:['gather']},
  2437. ],
  2438. });
  2439. new G.Tech({
  2440. name:'speech',
  2441. desc:'@unlocks [dreamer]@unlocks [wanderer]@provides 50 [wisdom]<>[speech], in its most primitive form, is a series of groans and grunts that makes it possible to communicate things, events, and concepts.',
  2442. icon:[1,1],
  2443. startWith:true,
  2444. effects:[
  2445. {type:'provide res',what:{'wisdom':50}},
  2446. {type:'show res',what:['insight']},
  2447. ],
  2448. });
  2449. new G.Tech({
  2450. name:'language',
  2451. desc:'@provides 30 [inspiration]@provides 30 [wisdom]<>[language] improves on [speech] by combining complex grammar with a rich vocabulary, allowing for better communication and the first signs of culture.',
  2452. icon:[2,1],
  2453. cost:{'insight':10},
  2454. req:{'speech':true},
  2455. effects:[
  2456. {type:'provide res',what:{'inspiration':30,'wisdom':30}},
  2457. ],
  2458. chance:3,
  2459. });
  2460.  
  2461. new G.Tech({
  2462. name:'oral tradition',
  2463. desc:'@unlocks [storyteller]@provides 20 [inspiration]@provides 20 [wisdom]<>[oral tradition] emerges when the members of a tribe gather at night to talk about their day. Stories, ideas, and myths are all shared and passed on from generation to generation.',
  2464. icon:[5,1],
  2465. cost:{'insight':10},
  2466. req:{'language':true},
  2467. effects:[
  2468. {type:'provide res',what:{'inspiration':20,'wisdom':20}},
  2469. ],
  2470. });
  2471.  
  2472. new G.Tech({
  2473. name:'stone-knapping',
  2474. desc:'@unlocks [artisan]s, which can create [knapped tools]<>[stone-knapping] allows you to make your very first tools - simple rocks that have been smashed against each other to fashion rather crude cleavers, choppers, and hand axes.//Tools have little use by themselves, but may be used in many other industries.',
  2475. icon:[3,1],
  2476. cost:{'insight':5},
  2477. req:{'tribalism':true},
  2478. effects:[
  2479. ],
  2480. chance:3,
  2481. });
  2482.  
  2483. new G.Tech({
  2484. name:'tool-making',
  2485. desc:'@[artisan]s can now create [stone tools]<>With proper [tool-making], new procedures arise to craft a multitude of specialized tools out of cheap materials - such as hammers, knives, and axes.',
  2486. icon:[4,1],
  2487. cost:{'insight':10},
  2488. req:{'stone-knapping':true,'carving':true},
  2489. effects:[
  2490. ],
  2491. chance:3,
  2492. });
  2493.  
  2494. new G.Tech({
  2495. name:'basket-weaving',
  2496. desc:'@[artisan]s can now craft [basket]s<>Baskets are a cheap, if flimsy means of storing food.',
  2497. icon:[7,1],
  2498. cost:{'insight':10},
  2499. req:{'tool-making':true},
  2500. effects:[
  2501. ],
  2502. });
  2503.  
  2504. new G.Tech({
  2505. name:'scouting',
  2506. desc:'@unlocks [scout]s, which can discover new territory<>The [scout] is an intrepid traveler equipped to deal with the unknown.',
  2507. icon:[24,7],
  2508. cost:{'insight':10},
  2509. req:{'tool-making':true,'language':true},
  2510. effects:[
  2511. ],
  2512. chance:2,
  2513. });
  2514. new G.Tech({
  2515. name:'canoes',
  2516. //TODO : fishing boats
  2517. desc:'@allows exploring through ocean shores<>',
  2518. icon:[26,7],
  2519. cost:{'insight':15},
  2520. req:{'tool-making':true,'woodcutting':true},
  2521. effects:[
  2522. {type:'allow',what:['shore exploring']},
  2523. ],
  2524. });
  2525. new G.Tech({
  2526. name:'boat building',
  2527. //TODO : in the future, boats will be units or resources
  2528. desc:'@allows full ocean exploring<>',
  2529. icon:[28,7],
  2530. cost:{'insight':40},
  2531. req:{'canoes':true,'carpentry':true},
  2532. effects:[
  2533. {type:'allow',what:['ocean exploring']},
  2534. ],
  2535. });
  2536.  
  2537. new G.Tech({
  2538. name:'sedentism',
  2539. desc:'@unlocks [mud shelter]s and [branch shelter]s@unlocks [lodge]s<>To stay in one place when food is scarce is a bold gamble, especially to those without knowledge of agriculture.',//TODO : this should unlock a policy that lets you switch between nomadism (housing and food storage have no effect) and sedentism (gathering and hunting are much less efficient)
  2540. icon:[8,1],
  2541. cost:{'insight':20},
  2542. req:{'stone-knapping':true,'digging':true,'language':true},
  2543. effects:[
  2544. ],
  2545. chance:3,
  2546. });
  2547. new G.Tech({
  2548. name:'building',
  2549. desc:'@unlocks [hut]s@unlocks [stockpile]s (with [stockpiling])<>The [building,Hut] is only slightly more sophisticated than simple shelters, but is more spacious and can withstand wear longer.',
  2550. icon:[9,1],
  2551. cost:{'insight':20},
  2552. req:{'sedentism':true,'tool-making':true},
  2553. effects:[
  2554. ],
  2555. chance:3,
  2556. });
  2557. new G.Tech({
  2558. name:'cities',
  2559. desc:'@unlocks [hovel]s<>',
  2560. icon:[29,7],
  2561. cost:{'insight':25},
  2562. req:{'building':true},
  2563. effects:[
  2564. ],
  2565. });
  2566. new G.Tech({
  2567. name:'construction',
  2568. desc:'@unlocks [house]s@unlocks [warehouse]s (with [stockpiling])<>',
  2569. icon:[30,7],
  2570. cost:{'insight':30},
  2571. req:{'cities':true,'masonry':true,'carpentry':true,'quarrying':true},
  2572. effects:[
  2573. ],
  2574. chance:3,
  2575. });
  2576. new G.Tech({
  2577. name:'city planning',
  2578. desc:'@unlocks [architect]s<>',
  2579. icon:[22,8],
  2580. cost:{'insight':25},
  2581. req:{'construction':true,'cities':true},
  2582. effects:[
  2583. ],
  2584. });
  2585. new G.Tech({
  2586. name:'guilds',
  2587. desc:'@unlocks [guild quarters]<>NOTE : useless for now.',
  2588. icon:[23,8],
  2589. cost:{'insight':20},
  2590. req:{'cities':true,'construction':true,'code of law':true},
  2591. effects:[
  2592. ],
  2593. });
  2594. new G.Tech({
  2595. name:'stockpiling',
  2596. desc:'@unlocks [storage pit]s<>The foresight to store sustenance and materials ahead of time can make or break a budding civilization.',
  2597. icon:[10,1],
  2598. cost:{'insight':10},
  2599. req:{'sedentism':true},
  2600. effects:[
  2601. {type:'show res',what:['food storage']},
  2602. {type:'show res',what:['material storage']},
  2603. ],
  2604. chance:2,
  2605. });
  2606.  
  2607. new G.Tech({
  2608. name:'digging',
  2609. desc:'@unlocks [digger]s@paves the way for simple buildings<>The earth is full of riches - to those who can find them.',
  2610. icon:[11,1],
  2611. cost:{'insight':10},
  2612. req:{'stone-knapping':true},
  2613. effects:[
  2614. {type:'show context',what:['dig']},
  2615. ],
  2616. });
  2617. new G.Tech({
  2618. name:'well-digging',
  2619. desc:'@unlocks [well]s<>It takes some thinking to figure out that water can be found if you dig deep enough.//It takes a lot of bravery, however, to find out if it is safe to drink.',
  2620. icon:[22,7],
  2621. cost:{'insight':10},
  2622. req:{'digging':true,'sedentism':true,'tool-making':true},
  2623. effects:[
  2624. ],
  2625. });
  2626. new G.Tech({
  2627. name:'woodcutting',
  2628. desc:'@unlocks [woodcutter]s<>',//TODO : desc
  2629. icon:[23,5],
  2630. cost:{'insight':10},
  2631. req:{'stone-knapping':true},
  2632. effects:[
  2633. {type:'show context',what:['chop']},
  2634. ],
  2635. });
  2636.  
  2637. new G.Tech({
  2638. name:'plant lore',
  2639. desc:'@[gatherer]s find more [herb]s and [fruit]s<>The knowledge of which plants are good to eat and which mean certain death is a slow and perilous one to learn.',
  2640. icon:[23,7],
  2641. cost:{'insight':5},
  2642. req:{'oral tradition':true},
  2643. effects:[
  2644. ],
  2645. });
  2646. new G.Tech({
  2647. name:'healing',
  2648. desc:'@unlocks [healer]s<>',
  2649. icon:[25,7],
  2650. cost:{'insight':10},
  2651. req:{'plant lore':true,'stone-knapping':true},
  2652. effects:[
  2653. ],
  2654. chance:2,
  2655. });
  2656.  
  2657. new G.Tech({
  2658. name:'ritualism',
  2659. desc:'@provides 10 [spirituality]@unlocks [soothsayer]s@unlocks some ritual policies<>Simple practices, eroded and polished by time, turn into rites and traditions.',
  2660. icon:[12,1],
  2661. cost:{'culture':5},
  2662. req:{'oral tradition':true},
  2663. effects:[
  2664. {type:'provide res',what:{'spirituality':10}},
  2665. ],
  2666. });
  2667.  
  2668. new G.Tech({
  2669. name:'symbolism',
  2670. desc:'@[dreamer]s produce 50% more [insight]@[storyteller]s produce 50% more [culture]@[soothsayer]s produce 50% more [faith]<>The manifestation of one thing for the meaning of another - to make the cosmos relate to itself.',
  2671. icon:[13,1],
  2672. cost:{'culture':10,'insight':10},
  2673. req:{'oral tradition':true},
  2674. effects:[
  2675. ],
  2676. });
  2677.  
  2678. new G.Tech({
  2679. name:'burial',
  2680. desc:'@unlocks [grave]s@exposed [corpse]s make people even more unhappy<>It is the belief that there might be more to death than is first apparent that drives us to bury our deceased.',
  2681. icon:[14,1],
  2682. cost:{'insight':5},
  2683. req:{'ritualism':true,'digging':true},
  2684. effects:[
  2685. ],
  2686. chance:2,
  2687. });
  2688.  
  2689. new G.Tech({
  2690. name:'hunting',
  2691. desc:'@unlocks [hunter]s<>It is a common tragedy that a creature should die so that another may survive.',
  2692. icon:[15,1],
  2693. cost:{'insight':5},
  2694. req:{'language':true,'tribalism':true},
  2695. effects:[
  2696. {type:'show context',what:['hunt']},
  2697. ],
  2698. });
  2699.  
  2700. new G.Tech({
  2701. name:'fishing',
  2702. desc:'@unlocks [fisher]s<>Fishing is more than simply catching fish; it involves knowing where the fish like to gather and which ones are good to eat.//It would be wise to check whether any of your territory contains fish before investing in this technology.',
  2703. icon:[25,1],
  2704. cost:{'insight':5},
  2705. req:{'tribalism':true},
  2706. effects:[
  2707. {type:'show context',what:['fish']},
  2708. ],
  2709. });
  2710.  
  2711. new G.Tech({
  2712. name:'bone-working',
  2713. desc:'@[artisan]s can now make [knapped tools] out of [bone]@[bone]s can now be used as [archaic building materials]<>',
  2714. icon:[22,5],
  2715. cost:{'insight':5},
  2716. req:{'stone-knapping':true},
  2717. effects:[
  2718. {type:'make part of',what:['bone'],parent:'archaic building materials'},
  2719. ],
  2720. });
  2721.  
  2722. new G.Tech({
  2723. name:'spears',
  2724. displayName:'Spears and maces',
  2725. desc:'@[artisan]s can now craft [stone weapons]@unlocks new modes for [hunter]s and [fisher]s<>Using tools as weapons opens a world of possibilities, from hunting to warfare.',
  2726. icon:[26,1],
  2727. cost:{'insight':10},
  2728. req:{'tool-making':true},
  2729. });
  2730. new G.Tech({
  2731. name:'bows',
  2732. desc:'@[artisan]s can now craft [bow]s@unlocks new modes for [hunter]s<>',//TODO : desc
  2733. icon:[27,1],
  2734. cost:{'insight':20},
  2735. req:{'spears':true},
  2736. });
  2737. new G.Tech({
  2738. name:'fishing hooks',
  2739. desc:'@unlocks new modes for [fisher]s<>',//TODO : desc
  2740. icon:[28,1],
  2741. cost:{'insight':15},
  2742. req:{'fishing':true,'spears':true},
  2743. });
  2744.  
  2745. new G.Tech({
  2746. name:'fire-making',
  2747. desc:'@unlocks [firekeeper]s<>Fire keeps you warm and makes animal attacks much less frequent.',
  2748. icon:[16,1],
  2749. cost:{'insight':15},
  2750. req:{'stone-knapping':true},
  2751. effects:[
  2752. ],
  2753. chance:3,
  2754. });
  2755.  
  2756. new G.Tech({
  2757. name:'cooking',
  2758. desc:'@[firekeeper]s can now cook [cooked meat] and [cooked seafood]<>Tossing fish and meat over a sizzling fire without reducing them to a heap of ash takes a bit of practice.',
  2759. icon:[17,1],
  2760. cost:{'insight':10},
  2761. req:{'fire-making':true},
  2762. });
  2763. new G.Tech({
  2764. name:'curing',
  2765. desc:'@[firekeeper]s can now prepare [cured meat] and [cured seafood] with [salt], which last much longer<>Storing food with special preparations seems to ward off rot, and comes along with the advent of delicious jerky.',
  2766. icon:[27,7],
  2767. cost:{'insight':15},
  2768. req:{'cooking':true,'stockpiling':true},
  2769. });
  2770.  
  2771. new G.Tech({
  2772. name:'sewing',
  2773. desc:'@unlocks [clothier]s, who work with fabric and can sew [primitive clothes]<>',//TODO : desc
  2774. icon:[29,1],
  2775. cost:{'insight':10},
  2776. req:{'tool-making':true},
  2777. effects:[
  2778. ],
  2779. });
  2780. new G.Tech({
  2781. name:'weaving',
  2782. desc:'@[clothier]s can now sew [basic clothes]<>',
  2783. icon:[30,1],
  2784. cost:{'insight':20},
  2785. req:{'sewing':true},
  2786. });
  2787. new G.Tech({
  2788. name:'leather-working',
  2789. desc:'@[clothier]s can now cure [hide]s into [leather] and use leather in cloth-making (with [weaving])<>',
  2790. icon:[31,1],
  2791. cost:{'insight':20},
  2792. req:{'sewing':true},
  2793. });
  2794.  
  2795. new G.Tech({
  2796. name:'smelting',
  2797. desc:'@unlocks [furnace]s, which turn ore into metal ingots@unlocks [blacksmith workshop]s, which forge metal ingots into metal goods<>',//TODO : desc
  2798. icon:[26,5],
  2799. cost:{'insight':30},
  2800. req:{'fire-making':true,'building':true},
  2801. effects:[
  2802. ],
  2803. });
  2804.  
  2805. new G.Tech({
  2806. name:'bronze-working',
  2807. desc:'@[furnace]s can now make [hard metal ingot]s from [copper ore] and [tin ore]<>',//TODO : desc
  2808. icon:[28,5],
  2809. cost:{'insight':30},
  2810. req:{'smelting':true},
  2811. effects:[
  2812. ],
  2813. });
  2814. new G.Tech({
  2815. name:'iron-working',
  2816. desc:'@[furnace]s can now make [hard metal ingot]s from [iron ore]<>',//TODO : desc
  2817. icon:[27,5],
  2818. cost:{'insight':30},
  2819. req:{'smelting':true},
  2820. effects:[
  2821. ],
  2822. });
  2823. new G.Tech({
  2824. name:'gold-working',
  2825. desc:'@[furnace]s can now make [precious metal ingot]s from [gold ore]@[blacksmith workshop]s can now forge [gold block]s out of [precious metal ingot]s<>',//TODO : desc
  2826. icon:[29,5],
  2827. cost:{'insight':40},
  2828. req:{'smelting':true},
  2829. effects:[
  2830. ],
  2831. });
  2832. new G.Tech({
  2833. name:'steel-making',
  2834. desc:'@[furnace]s can now make [strong metal ingot]s from [iron ore] and [coal]<>',//TODO : desc
  2835. icon:[30,5],
  2836. cost:{'insight':40},
  2837. req:{'iron-working':true},
  2838. effects:[
  2839. ],
  2840. });
  2841.  
  2842. new G.Tech({
  2843. name:'chieftains',
  2844. desc:'@unlocks [chieftain]s, which generate [influence]@provides 5 [authority]<>',//TODO : desc
  2845. icon:[22,6],
  2846. cost:{'insight':10},
  2847. req:{'oral tradition':true},
  2848. effects:[
  2849. {type:'provide res',what:{'authority':5}},
  2850. ],
  2851. });
  2852. new G.Tech({
  2853. name:'clans',
  2854. desc:'@unlocks [clan leader]s, which generate [influence]@provides 5 [authority]<>',//TODO : desc
  2855. icon:[23,6],
  2856. cost:{'insight':25},
  2857. req:{'chieftains':true,'code of law':true},
  2858. effects:[
  2859. {type:'provide res',what:{'authority':5}},
  2860. ],
  2861. });
  2862. new G.Tech({
  2863. name:'code of law',
  2864. desc:'@provides 15 [authority]@political units generate more [influence]<>',//TODO : desc
  2865. icon:[24,6],
  2866. cost:{'insight':20},
  2867. req:{'symbolism':true,'sedentism':true},
  2868. effects:[
  2869. {type:'provide res',what:{'authority':15}},
  2870. ],
  2871. });
  2872.  
  2873. new G.Tech({
  2874. name:'mining',
  2875. desc:'@unlocks [mine]s<>Strike the earth!',
  2876. icon:[24,5],
  2877. cost:{'insight':20},
  2878. req:{'digging':true,'building':true},
  2879. effects:[
  2880. {type:'show context',what:['mine']}
  2881. ],
  2882. });
  2883. new G.Tech({
  2884. name:'prospecting',
  2885. desc:'@[mine]s can now be set to mine for specific ores',
  2886. icon:[25,5],
  2887. cost:{'insight':35},
  2888. req:{'mining':true},
  2889. effects:[
  2890. ],
  2891. });
  2892.  
  2893. new G.Tech({
  2894. name:'quarrying',
  2895. desc:'@unlocks [quarry,Quarries]<>',
  2896. icon:[25,6],
  2897. cost:{'insight':20},
  2898. req:{'digging':true,'building':true},
  2899. effects:[
  2900. {type:'show context',what:['quarry']}
  2901. ],
  2902. });
  2903.  
  2904. new G.Tech({
  2905. name:'carving',
  2906. desc:'@unlocks [carver]s, which can produce a variety of goods out of stone, wood and bone@may lead to the knowledge of better tools<>',
  2907. icon:[26,6],
  2908. cost:{'insight':5},
  2909. req:{'stone-knapping':true},
  2910. effects:[
  2911. ],
  2912. chance:3,
  2913. });
  2914.  
  2915. new G.Tech({
  2916. name:'gem-cutting',
  2917. desc:'@[carver]s can now make [gem block]s out of [gems]<>',//TODO : desc
  2918. icon:[27,6],
  2919. cost:{'insight':20},
  2920. req:{'carving':true,'tool-making':true},
  2921. effects:[
  2922. ],
  2923. });
  2924.  
  2925. new G.Tech({
  2926. name:'pottery',
  2927. desc:'@unlocks [potter]s, which produce goods such as [pot]s out of [clay] and [mud]@unlocks [granary,Granaries] (with [stockpiling])@[digger]s find more [clay]<>',
  2928. icon:[28,6],
  2929. cost:{'insight':20},
  2930. req:{'fire-making':true,'digging':true,'tool-making':true},
  2931. effects:[
  2932. ],
  2933. });
  2934. new G.Tech({
  2935. name:'masonry',
  2936. desc:'@unlocks [kiln]s, which produce a variety of goods such as [brick]s@[carver]s can now turn [stone]s into [cut stone] slowly<>',
  2937. icon:[29,6],
  2938. cost:{'insight':35},
  2939. req:{'building':true,'pottery':true},
  2940. effects:[
  2941. ],
  2942. });
  2943. new G.Tech({
  2944. name:'carpentry',
  2945. desc:'@unlocks [carpenter workshop]s, which can process [log]s into [lumber] and produce wooden goods@unlocks [barn]s (with [stockpiling])<>',
  2946. icon:[30,6],
  2947. cost:{'insight':35},
  2948. req:{'building':true,'woodcutting':true},
  2949. effects:[
  2950. ],
  2951. });
  2952.  
  2953. new G.Tech({
  2954. name:'monument-building',
  2955. desc:'@unlocks the [mausoleum], an early wonder<>',
  2956. icon:[24,8],
  2957. cost:{'insight':90,'culture':40},
  2958. req:{'construction':true,'burial':true,'belief in the afterlife':true},
  2959. effects:[
  2960. ],
  2961. });
  2962.  
  2963. /*=====================================================================================
  2964. TRAITS
  2965. =======================================================================================*/
  2966. //chances are evaluated every day and represent how many years (on average) it takes to randomly discover them once they fulfill the requirements
  2967.  
  2968. new G.Trait({
  2969. name:'scavenging',
  2970. desc:'@idle [worker]s gather resources with a tenth of the efficiency of a [gatherer]',
  2971. icon:[20,1],
  2972. chance:1,
  2973. req:{'tribalism':true},
  2974. });
  2975. new G.Trait({
  2976. name:'rules of food',
  2977. desc:'@unlocks policies that manage which food types can be eaten',
  2978. icon:[19,1],
  2979. chance:1,
  2980. req:{'tribalism':true},
  2981. //TODO
  2982. });
  2983. new G.Trait({
  2984. name:'ground stone tools',
  2985. desc:'@[artisan]s and [carver]s craft 20% faster',
  2986. icon:[4,1],
  2987. cost:{'insight':3},
  2988. chance:10,
  2989. req:{'stone-knapping':true/*,'some future tool tech':false (TODO)*/},
  2990. });
  2991. new G.Trait({
  2992. name:'artistic thinking',
  2993. desc:'@[storyteller]s are 30% more efficient@opens the way for more art forms',
  2994. icon:[12,1],
  2995. cost:{'culture':5},
  2996. chance:10,
  2997. req:{'symbolism':true},
  2998. });
  2999. //TODO : how these interact with techs such as symbolism, ritualism and burial
  3000. new G.Trait({
  3001. name:'fear of death',
  3002. desc:'@unhappiness from death is doubled@may evolve into more complex spiritual thinking',
  3003. icon:[18,1],
  3004. cost:{'culture':5},
  3005. chance:10,
  3006. req:{'language':true},
  3007. });
  3008. new G.Trait({
  3009. name:'belief in the afterlife',
  3010. desc:'@unhappiness from death is halved',
  3011. icon:[21,1],
  3012. cost:{'culture':5,'faith':2},
  3013. chance:10,
  3014. req:{'fear of death':true,'oral tradition':true},
  3015. });
  3016. new G.Trait({
  3017. name:'belief in revenants',
  3018. desc:'@unhappiness from unburied [corpse]s is doubled',
  3019. icon:[18,1],
  3020. cost:{'culture':5,'faith':2},
  3021. chance:100,
  3022. req:{'belief in the afterlife':true},
  3023. });
  3024. new G.Trait({
  3025. name:'ritual necrophagy',
  3026. desc:'@[corpse]s are slowly turned into [meat] and [bone]s, creating some [faith] but harming [health]',
  3027. icon:[18,1],
  3028. cost:{'culture':5},
  3029. chance:500,
  3030. req:{'tribalism':true,'ritualism':true},
  3031. });
  3032. new G.Trait({
  3033. name:'culture of moderation',
  3034. desc:'@people consume 15% less [food], but derive less joy from eating',
  3035. icon:[3,12,19,1],
  3036. cost:{'culture':5},
  3037. chance:50,
  3038. req:{'tribalism':true,'joy of eating':false},
  3039. });
  3040. new G.Trait({
  3041. name:'joy of eating',
  3042. desc:'@people consume 15% more [food], but are happier when eating',
  3043. icon:[4,12,19,1],
  3044. cost:{'culture':5},
  3045. chance:50,
  3046. req:{'tribalism':true,'culture of moderation':false},
  3047. });
  3048. new G.Trait({
  3049. name:'insect-eating',
  3050. desc:'@your people are no longer unhappy when eating [bugs]',
  3051. icon:[8,11,22,1],
  3052. chance:5,
  3053. req:{'insects as food':'on'},
  3054. effects:[
  3055. {type:'function',func:function(){G.getDict('bugs').turnToByContext['eating']['happiness']=0.03;}},
  3056. ],
  3057. });
  3058.  
  3059. /*=====================================================================================
  3060. POLICIES
  3061. =======================================================================================*/
  3062. G.policyCategories.push(
  3063. {id:'debug',name:'Debug'},
  3064. {id:'food',name:'Food'},
  3065. {id:'work',name:'Work'},
  3066. {id:'population',name:'Population'},
  3067. {id:'faith',name:'Faith'}
  3068. );
  3069.  
  3070. new G.Policy({
  3071. name:'disable aging',
  3072. desc:'Aging, disease, births, and deaths are disabled.',
  3073. icon:[3,12,8,3],
  3074. cost:{},
  3075. startWith:true,
  3076. category:'debug',
  3077. });
  3078. new G.Policy({
  3079. name:'disable eating',
  3080. desc:'Eating and drinking are disabled.',
  3081. icon:[3,12,3,6],
  3082. cost:{},
  3083. startWith:true,
  3084. category:'debug',
  3085. });
  3086. new G.Policy({
  3087. name:'disable spoiling',
  3088. desc:'All resource spoilage is disabled.',
  3089. icon:[3,12,3,7],
  3090. cost:{},
  3091. startWith:true,
  3092. category:'debug',
  3093. });
  3094. new G.Policy({
  3095. name:'child workforce',
  3096. desc:'[child,Children] now count as [worker]s; working children are more prone to accidents and receive lower education.',
  3097. icon:[7,12,3,3],
  3098. cost:{'influence':2},
  3099. req:{'tribalism':true},
  3100. category:'work',
  3101. });
  3102. new G.Policy({
  3103. name:'elder workforce',
  3104. desc:'[elder]s now count as [worker]s; working elders are more prone to accidents and early death.',
  3105. //an interesting side-effect of this and how population is coded is that elders are now much more prone to illness and wounds, and should they recover they will magically turn back into adults, thus blessing your civilization with a morally dubious way of attaining eternal life
  3106. icon:[7,12,5,3],
  3107. cost:{'influence':2},
  3108. req:{'tribalism':true},
  3109. category:'work',
  3110. });
  3111. new G.Policy({
  3112. name:'food rations',
  3113. desc:'Define how much [food] your people are given each day.//Bigger rations will make your people happier, while smaller ones may lead to sickness and starvation.',
  3114. icon:[5,12,3,6],
  3115. cost:{'influence':2},
  3116. startMode:'sufficient',
  3117. req:{'rules of food':true},
  3118. modes:{
  3119. 'none':{name:'None',desc:'Eating food is forbidden.<br>Your people will start to starve.'},
  3120. 'meager':{name:'Meager',desc:'Your people receive half a portion per day.'},
  3121. 'sufficient':{name:'Sufficient',desc:'Your people receive a full portion per day.'},
  3122. 'plentiful':{name:'Plentiful',desc:'Your people receive a portion and a half per day.'},
  3123. },
  3124. category:'food',
  3125. });
  3126. new G.Policy({
  3127. name:'water rations',
  3128. desc:'Define how much [water] your people are given each day.//Bigger rations will make your people happier, while smaller ones may lead to sickness and dehydration.',
  3129. icon:[5,12,7,6],
  3130. cost:{'influence':2},
  3131. startMode:'sufficient',
  3132. req:{'rules of food':true},
  3133. modes:{
  3134. 'none':{name:'None',desc:'Drinking water is forbidden.<br>Your people will start to die from dehydration.'},
  3135. 'meager':{name:'Meager',desc:'Your people receive half a portion per day.'},
  3136. 'sufficient':{name:'Sufficient',desc:'Your people receive a full portion per day.'},
  3137. 'plentiful':{name:'Plentiful',desc:'Your people receive a portion and a half per day.'},
  3138. },
  3139. category:'food',
  3140. });
  3141. new G.Policy({
  3142. name:'eat spoiled food',
  3143. desc:'Your people will eat [spoiled food] when other [food] gets scarce, with dire consequences for health and morale.',
  3144. icon:[6,12,3,7],
  3145. cost:{'influence':1},
  3146. startMode:'on',
  3147. req:{'rules of food':true},
  3148. category:'food',
  3149. });
  3150. new G.Policy({
  3151. name:'drink muddy water',
  3152. desc:'Your people will drink [muddy water] when clean [water] gets scarce, with dire consequences for health and morale.',
  3153. icon:[6,12,8,6],
  3154. cost:{'influence':1},
  3155. startMode:'on',
  3156. req:{'rules of food':true},
  3157. category:'food',
  3158. });
  3159. new G.Policy({
  3160. name:'insects as food',
  3161. desc:'[bugs] now count as [food], although most people find them unpalatable.',
  3162. icon:[6,12,8,11],
  3163. cost:{'influence':1},
  3164. req:{'rules of food':true},
  3165. effects:[
  3166. {type:'make part of',what:['bugs'],parent:'food'},
  3167. ],
  3168. effectsOff:[
  3169. {type:'make part of',what:['bugs'],parent:''},
  3170. ],
  3171. category:'food',
  3172. });
  3173. new G.Policy({
  3174. name:'eat raw meat and fish',
  3175. desc:'[meat] and [seafood] are eaten raw, which may be unhealthy.',
  3176. icon:[6,12,5,7],
  3177. cost:{'influence':1},
  3178. startMode:'on',
  3179. req:{'rules of food':true},
  3180. effects:[
  3181. {type:'make part of',what:['meat','seafood'],parent:'food'},
  3182. ],
  3183. effectsOff:[
  3184. {type:'make part of',what:['meat','seafood'],parent:''},
  3185. ],
  3186. category:'food',
  3187. });
  3188. new G.Policy({
  3189. name:'fertility rituals',
  3190. desc:'Improves birth rate by 20%. Consumes 1 [faith] every 20 days; will stop if you run out.',
  3191. icon:[8,12,2,3],
  3192. cost:{'faith':1},
  3193. startMode:'off',
  3194. req:{'ritualism':true},
  3195. category:'faith',
  3196. });
  3197. new G.Policy({
  3198. name:'harvest rituals',
  3199. desc:'Improves [gatherer], [hunter] and [fisher] efficiency by 20%. Consumes 1 [faith] every 20 days; will stop if you run out.',
  3200. icon:[8,12,4,7],
  3201. cost:{'faith':1},
  3202. startMode:'off',
  3203. req:{'ritualism':true},
  3204. category:'faith',
  3205. });
  3206. new G.Policy({
  3207. name:'flower rituals',
  3208. desc:'People get sick slower and recover faster. Consumes 1 [faith] every 20 days; will stop if you run out.',
  3209. icon:[8,12,4,5],
  3210. cost:{'faith':1},
  3211. startMode:'off',
  3212. req:{'ritualism':true},
  3213. category:'faith',
  3214. });
  3215. new G.Policy({
  3216. name:'wisdom rituals',
  3217. desc:'Improves [dreamer] and [storyteller] efficiency by 20%. Consumes 1 [faith] every 20 days; will stop if you run out.',
  3218. icon:[8,12,8,5],
  3219. cost:{'faith':1},
  3220. startMode:'off',
  3221. req:{'ritualism':true},
  3222. category:'faith',
  3223. });
  3224.  
  3225. new G.Policy({
  3226. name:'population control',
  3227. desc:'Set rules on how many children your people are allowed to have.',
  3228. icon:[4,12,2,3],
  3229. cost:{'influence':3},
  3230. startMode:'normal',
  3231. req:{'tribalism':true},
  3232. modes:{
  3233. 'forbidden':{name:'Forbidden',desc:'Your people are not allowed to make children.//Your population will not grow.'},
  3234. 'limited':{name:'Limited',desc:'Your people are only allowed to have one child.//Your population will grow slowly.'},
  3235. 'normal':{name:'Normal',desc:'You have no specific rules regarding children.//Your population will grow normally.'},
  3236. },
  3237. category:'population',
  3238. });
  3239.  
  3240. /*=====================================================================================
  3241. LANDS
  3242. =======================================================================================*/
  3243.  
  3244. new G.Land({
  3245. name:'ocean',
  3246. names:['Ocean'],
  3247. goods:[
  3248. {type:'saltwater fish',min:1,max:4},
  3249. {type:'saltwater'},
  3250. ],
  3251. ocean:true,
  3252. image:3,
  3253. score:0,
  3254. });
  3255. new G.Land({
  3256. name:'arctic ocean',
  3257. names:['Icesheet'],
  3258. goods:[
  3259. {type:'saltwater fish',min:1,max:3},
  3260. {type:'snow cover'},
  3261. {type:'saltwater'},
  3262. ],
  3263. ocean:true,
  3264. image:2,
  3265. score:0,
  3266. });
  3267. new G.Land({
  3268. name:'tropical ocean',
  3269. names:['Tropical ocean'],
  3270. goods:[
  3271. {type:'saltwater fish',min:1,max:4},
  3272. {type:'saltwater'},
  3273. ],
  3274. ocean:true,
  3275. image:4,
  3276. score:0,
  3277. });
  3278. new G.Land({
  3279. name:'prairie',
  3280. names:['Prairie','Grassland','Plain','Steppe','Meadow'],
  3281. goods:[
  3282. {type:['oak','birch'],chance:1,min:0.1,max:0.2},
  3283. {type:['oak','birch'],chance:0.5,min:0.1,max:0.4},
  3284. {type:'berry bush',chance:0.9},
  3285. {type:'grass',amount:2},
  3286. {type:['wild rabbits','stoats'],chance:0.9},
  3287. {type:['foxes'],chance:0.5,amount:0.5},
  3288. {type:['wolves','bears'],chance:0.2,amount:0.5},
  3289. {type:['deer'],chance:0.2,amount:0.2},
  3290. {type:'wild bugs'},
  3291. {type:'freshwater fish',chance:0.8,min:0.1,max:0.5},
  3292. {type:'freshwater',amount:1},
  3293. {type:'rocky substrate'},
  3294. ],
  3295. modifiers:{'river':0.4,'volcano':0.2,},
  3296. image:6,
  3297. score:10,
  3298. });
  3299. new G.Land({
  3300. name:'shrubland',
  3301. names:['Shrubland','Drylands','Highlands','Heath'],
  3302. goods:[
  3303. {type:['oak','birch'],chance:0.5,min:0.2,max:0.4},
  3304. {type:'dead tree',amount:0.5},
  3305. {type:'berry bush',chance:0.2},
  3306. {type:'grass',amount:1.5},
  3307. {type:['wild rabbits','stoats'],chance:0.6},
  3308. {type:['foxes'],chance:0.4,amount:0.3},
  3309. {type:['wolves','bears'],chance:0.1,amount:0.2},
  3310. {type:'wild bugs'},
  3311. {type:'freshwater fish',chance:0.3,min:0.1,max:0.3},
  3312. {type:'freshwater',amount:0.8},
  3313. {type:'rocky substrate'},
  3314. ],
  3315. modifiers:{'river':0.4,'volcano':0.2,},
  3316. image:5,
  3317. score:7,
  3318. });
  3319. new G.Land({
  3320. name:'forest',
  3321. names:['Forest','Forest','Woodland','Swamp','Marsh'],
  3322. goods:[
  3323. {type:['oak','birch'],amount:3},
  3324. {type:['oak','birch','dead tree'],chance:0.5},
  3325. {type:'berry bush',chance:0.6},
  3326. {type:'forest mushrooms',chance:0.8},
  3327. {type:'grass'},
  3328. {type:['wild rabbits','stoats'],chance:0.2},
  3329. {type:['foxes'],chance:0.2,amount:0.2},
  3330. {type:['wolves','bears'],chance:0.5,min:0.5,max:1},
  3331. {type:['boars'],chance:0.5,amount:0.5},
  3332. {type:'deer',chance:0.7,amount:0.5},
  3333. {type:'wild bugs',min:1,max:1.5},
  3334. {type:'freshwater fish',chance:0.1,min:0.1,max:0.3},
  3335. {type:'freshwater',amount:1},
  3336. {type:'rocky substrate'},
  3337. ],
  3338. image:7,
  3339. score:8,
  3340. });
  3341. new G.Land({
  3342. name:'tundra',
  3343. names:['Tundra','Cold plain','Cold steppe'],
  3344. goods:[
  3345. {type:['fir tree'],amount:1},
  3346. {type:'berry bush',chance:0.8},
  3347. {type:'grass'},
  3348. {type:['wild rabbits','stoats'],chance:0.1},
  3349. {type:['foxes'],chance:0.3,amount:0.4},
  3350. {type:['wolves'],chance:0.5,min:0.5,max:1},
  3351. {type:['seals'],chance:0.2,amount:0.5},
  3352. {type:'deer',chance:0.2,amount:0.1},
  3353. {type:['polar bears'],chance:0.3,min:0.1,max:0.5},
  3354. {type:'wild bugs'},
  3355. {type:'freshwater fish',chance:0.8,min:0.1,max:0.5},
  3356. {type:'freshwater',amount:1},
  3357. {type:'snow cover'},
  3358. {type:'rocky substrate'},
  3359. ],
  3360. image:9,
  3361. score:7,
  3362. });
  3363. new G.Land({
  3364. name:'ice desert',
  3365. names:['Ice desert','Cold desert'],
  3366. goods:[
  3367. {type:'dead tree',amount:0.5},
  3368. {type:['fir tree'],amount:0.2},
  3369. {type:'berry bush',chance:0.5,amount:0.2},
  3370. {type:'grass',chance:0.4,amount:0.2},
  3371. {type:['wild rabbits','stoats'],chance:0.05},
  3372. {type:['wolves'],chance:0.1,min:0.1,max:0.5},
  3373. {type:['seals'],chance:0.2,amount:0.4},
  3374. {type:['polar bears'],chance:0.5,min:0.1,max:0.5},
  3375. {type:'wild bugs',amount:0.05},
  3376. {type:'freshwater fish',chance:0.3,min:0.1,max:0.3},
  3377. {type:'freshwater',amount:0.2},
  3378. {type:'snow cover'},
  3379. {type:'rocky substrate'},
  3380. ],
  3381. image:8,
  3382. score:2,
  3383. });
  3384. new G.Land({
  3385. name:'boreal forest',
  3386. names:['Boreal forest','Pine forest','Taiga'],
  3387. goods:[
  3388. {type:['fir tree'],amount:3},
  3389. {type:'berry bush',chance:0.9},
  3390. {type:'forest mushrooms',chance:0.4},
  3391. {type:'grass'},
  3392. {type:['wild rabbits','stoats'],chance:0.2},
  3393. {type:['wolves'],chance:0.5,min:0.5,max:1},
  3394. {type:['polar bears','bears'],chance:0.3,amount:0.5},
  3395. {type:'deer',chance:0.7,amount:0.5},
  3396. {type:'wild bugs'},
  3397. {type:'freshwater fish',chance:0.1,min:0.1,max:0.3},
  3398. {type:'freshwater',amount:1},
  3399. {type:'snow cover'},
  3400. {type:'rocky substrate'},
  3401. ],
  3402. image:10,
  3403. score:8,
  3404. });
  3405. new G.Land({
  3406. name:'savanna',
  3407. names:['Savannah','Savannah','Sun prairie'],
  3408. goods:[
  3409. {type:'acacia',amount:1},
  3410. {type:'palm tree',chance:0.4,amount:0.3},
  3411. {type:'berry bush',chance:0.6},
  3412. {type:'succulents',chance:0.4,min:0.1,max:0.3},
  3413. {type:'grass',amount:1.5},
  3414. {type:['wild rabbits','stoats'],chance:0.3},
  3415. {type:['foxes'],chance:0.4,amount:0.5},
  3416. {type:['boars'],chance:0.3,amount:0.5},
  3417. {type:'wild bugs'},
  3418. {type:'freshwater fish',chance:0.6,min:0.1,max:0.5},
  3419. {type:'freshwater',amount:0.8},
  3420. {type:'sandy soil',chance:0.3},
  3421. {type:'rocky substrate'},
  3422. ],
  3423. image:12,
  3424. score:7,
  3425. });
  3426. new G.Land({
  3427. name:'desert',
  3428. names:['Desert','Scorched land'],
  3429. goods:[
  3430. {type:'dead tree',amount:0.5},
  3431. {type:'acacia',amount:0.2,chance:0.4},
  3432. {type:'succulents',min:0.1,max:0.6},
  3433. {type:'grass',chance:0.3,amount:0.1},
  3434. {type:'wild rabbits',chance:0.05},
  3435. {type:['foxes'],chance:0.3,min:0.1,max:0.3},
  3436. {type:['wolves'],chance:0.1,min:0.1,max:0.3},
  3437. {type:'wild bugs',amount:0.15},
  3438. {type:'freshwater',amount:0.1},
  3439. {type:'sandy soil'},
  3440. {type:'rocky substrate'},
  3441. ],
  3442. image:11,
  3443. score:2,
  3444. });
  3445. new G.Land({
  3446. name:'jungle',
  3447. names:['Jungle','Tropical forest','Mangrove'],
  3448. goods:[
  3449. {type:['palm tree'],amount:3},
  3450. {type:'jungle fruits',chance:1},
  3451. {type:'grass'},
  3452. {type:'koalas',chance:0.3},
  3453. {type:['boars'],chance:0.2,amount:0.5},
  3454. {type:'wild bugs',min:1,max:2},
  3455. {type:'freshwater fish',chance:0.1,min:0.1,max:0.3},
  3456. {type:'freshwater',amount:1},
  3457. {type:'rocky substrate'},
  3458. ],
  3459. image:13,
  3460. score:8,
  3461. });
  3462.  
  3463. //TODO : all the following
  3464. new G.Land({
  3465. name:'mountain',
  3466. names:['Mountain'],
  3467. modifier:true,
  3468. goods:[
  3469. ],
  3470. });
  3471. new G.Land({
  3472. name:'volcano',
  3473. names:['Volcano'],
  3474. modifier:true,
  3475. goods:[
  3476. ],
  3477. });
  3478. new G.Land({
  3479. name:'hills',
  3480. names:['Hills'],
  3481. modifier:true,
  3482. goods:[
  3483. ],
  3484. });
  3485. new G.Land({
  3486. name:'canyon',
  3487. names:['Canyon','Rift','Gorge','Ravine'],
  3488. modifier:true,
  3489. goods:[
  3490. ],
  3491. });
  3492. new G.Land({
  3493. name:'cliffs',
  3494. names:['Cliffs'],
  3495. modifier:true,
  3496. goods:[
  3497. //TODO : some limestone source here
  3498. ],
  3499. });
  3500. new G.Land({
  3501. name:'beach',
  3502. names:['Beach'],
  3503. modifier:true,
  3504. goods:[
  3505. {type:'saltwater fish',min:0.3,max:1},
  3506. {type:['crabs','clams'],chance:0.1,min:0.1,max:0.5},
  3507. {type:'sandy soil'},
  3508. ],
  3509. });
  3510. new G.Land({
  3511. name:'river',
  3512. names:['River'],
  3513. modifier:true,
  3514. goods:[
  3515. {type:'freshwater fish',min:0.2,max:1},
  3516. {type:['crabs','clams'],chance:0.2,min:0.1,max:0.3},
  3517. {type:'freshwater',min:0.5,max:1.5},
  3518. ],
  3519. });
  3520.  
  3521. /*=====================================================================================
  3522. GOODS
  3523. =======================================================================================*/
  3524.  
  3525. G.contextNames['gather']='Gathering';
  3526. G.contextNames['fish']='Fishing';
  3527. G.contextNames['hunt']='Hunting';
  3528. G.contextNames['chop']='Chopping';
  3529. G.contextNames['dig']='Digging';
  3530. G.contextNames['mine']='Mining';
  3531. G.contextNames['quarry']='Quarrying';
  3532.  
  3533. //plants
  3534. new G.Goods({
  3535. name:'grass',
  3536. desc:'[grass] is a good source of [herb]s; you may also occasionally find some [fruit]s and [stick]s while foraging.',
  3537. icon:[10,10],
  3538. res:{
  3539. 'gather':{'herb':10,'fruit':0.5,'stick':0.5},
  3540. },
  3541. });
  3542. new G.Goods({
  3543. name:'oak',
  3544. desc:'The [oak] is a mighty tree that thrives in temperate climates, rich in [log]s and [stick]s.',
  3545. icon:[0,10],
  3546. res:{
  3547. 'chop':{'log':3,'stick':6},
  3548. 'gather':{'stick':1},
  3549. },
  3550. affectedBy:['deforestation'],
  3551. });
  3552. new G.Goods({
  3553. name:'birch',
  3554. desc:'[birch,Birch trees] have white bark and are rather frail, but are a good source of [log]s and [stick]s.',
  3555. icon:[1,10],
  3556. res:{
  3557. 'chop':{'log':2,'stick':4},
  3558. 'gather':{'stick':1},
  3559. },
  3560. affectedBy:['deforestation'],
  3561. });
  3562. new G.Goods({
  3563. name:'palm tree',
  3564. desc:'[palm tree]s prefer warm climates and provide [log]s when chopped; harvesting them may also yield [stick]s and [fruit]s such as bananas and coconuts.',
  3565. icon:[2,10],
  3566. res:{
  3567. 'chop':{'log':2,'stick':4},
  3568. 'gather':{'fruit':0.3,'stick':1},
  3569. },
  3570. affectedBy:['deforestation'],
  3571. });
  3572. new G.Goods({
  3573. name:'acacia',
  3574. desc:'The [acacia,Acacia tree] tends to grow in warm, dry climates, and can be chopped for [log]s and harvested for [stick]s.',
  3575. icon:[8,10],
  3576. res:{
  3577. 'chop':{'log':2,'stick':4},
  3578. 'gather':{'stick':1},
  3579. },
  3580. affectedBy:['deforestation'],
  3581. });
  3582. new G.Goods({
  3583. name:'fir tree',
  3584. desc:'[fir tree]s can endure cold climates and keep their needles year-long; they can provide [log]s and [stick]s.',
  3585. icon:[3,10],
  3586. res:{
  3587. 'chop':{'log':2,'stick':6},
  3588. 'gather':{'stick':1},
  3589. },
  3590. affectedBy:['deforestation'],
  3591. });
  3592. new G.Goods({
  3593. name:'dead tree',
  3594. desc:'While an ornery sight, [dead tree]s are an adequate source of dry [log]s and [stick]s.',
  3595. icon:[9,10],
  3596. res:{
  3597. 'chop':{'log':1,'stick':2},
  3598. 'gather':{'stick':0.5},
  3599. },
  3600. affectedBy:['deforestation'],
  3601. });
  3602. new G.Goods({
  3603. name:'berry bush',
  3604. desc:'[berry bush,Berry bushes] can be foraged for [fruit]s, [stick]s and sometimes [herb]s.',
  3605. icon:[4,10],
  3606. res:{
  3607. 'gather':{'fruit':3,'stick':0.5,'herb':0.25},
  3608. },
  3609. affectedBy:['scarce forageables'],
  3610. });
  3611. new G.Goods({
  3612. name:'forest mushrooms',
  3613. desc:'[forest mushrooms] grow in the penumbra of the underbrush, and often yield all sorts of interesting [herb]s.',
  3614. icon:[5,10],
  3615. res:{
  3616. 'gather':{'herb':4},
  3617. },
  3618. affectedBy:['scarce forageables'],
  3619. });
  3620. new G.Goods({
  3621. name:'succulents',
  3622. desc:'Hardy cactii that grow in the desert. While tricky to harvest, [succulents] can provide [herb]s and [fruit]s.',
  3623. icon:[6,10],
  3624. res:{
  3625. 'gather':{'fruit':1,'herb':3},
  3626. },
  3627. affectedBy:['scarce forageables'],
  3628. });
  3629. new G.Goods({
  3630. name:'jungle fruits',
  3631. desc:'[jungle fruits] come in all shapes, colors and sizes, and will yield [fruit]s and [herb]s to those who forage them.',
  3632. icon:[7,10],
  3633. res:{
  3634. 'gather':{'fruit':2,'herb':1},
  3635. },
  3636. affectedBy:['scarce forageables'],
  3637. });
  3638. //animals
  3639. new G.Goods({
  3640. name:'wild rabbits',
  3641. desc:'[wild rabbits] are quick and hard to catch, and yield a little [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3642. icon:[0,11],
  3643. res:{
  3644. 'gather':{'spoiled food':0.5},
  3645. 'hunt':{'meat':2,'bone':0.2,'hide':0.2},
  3646. },
  3647. affectedBy:['over hunting'],
  3648. });
  3649. new G.Goods({
  3650. name:'stoats',
  3651. desc:'Besides being a source of high-quality [hide,Furs], these carnivorous mammals can provide [meat] and [bone]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3652. icon:[1,11],
  3653. res:{
  3654. 'gather':{'spoiled food':0.5},
  3655. 'hunt':{'meat':2,'bone':0.2,'hide':1},
  3656. },
  3657. affectedBy:['over hunting'],
  3658. });
  3659. new G.Goods({
  3660. name:'koalas',
  3661. desc:'While they are placid leaf-eaters, these tree-dwelling mammals have been rumored to drop down on unsuspecting passersby. They can be hunted for [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3662. icon:[2,11],
  3663. res:{
  3664. 'gather':{'spoiled food':0.5},
  3665. 'hunt':{'meat':2,'bone':0.2,'hide':0.2},
  3666. },
  3667. affectedBy:['over hunting'],
  3668. });
  3669. new G.Goods({
  3670. name:'deer',
  3671. desc:'Forest herbivores that live in herds; good source of [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3672. icon:[3,11],
  3673. res:{
  3674. 'gather':{'spoiled food':1},
  3675. 'hunt':{'meat':4,'bone':1,'hide':0.6},
  3676. },
  3677. affectedBy:['over hunting'],
  3678. });
  3679. new G.Goods({
  3680. name:'bears',
  3681. desc:'Large omnivorous mammals that hibernate in cold seasons; fearsome in battle. Yield plenty of [meat], [bone]s and large [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3682. icon:[5,11],
  3683. res:{
  3684. 'gather':{'spoiled food':1},
  3685. 'hunt':{'meat':4,'bone':1,'hide':1},
  3686. },
  3687. affectedBy:['over hunting'],
  3688. });
  3689. new G.Goods({
  3690. name:'polar bears',
  3691. desc:'Large omnivorous mammals that live in snowy regions; fierce hunters. Yield plenty of [meat], [bone]s and large [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3692. icon:[10,11],
  3693. res:{
  3694. 'gather':{'spoiled food':1},
  3695. 'hunt':{'meat':4,'bone':1,'hide':1},
  3696. },
  3697. affectedBy:['over hunting'],
  3698. });
  3699. new G.Goods({
  3700. name:'boars',
  3701. desc:'Omnivorous mammals armed with tusks; provide [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3702. icon:[4,11],
  3703. res:{
  3704. 'gather':{'spoiled food':1},
  3705. 'hunt':{'meat':3,'bone':1,'hide':0.5},
  3706. },
  3707. affectedBy:['over hunting'],
  3708. });
  3709. new G.Goods({
  3710. name:'foxes',
  3711. desc:'These sly hunters can be butchered for [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3712. icon:[6,11],
  3713. res:{
  3714. 'gather':{'spoiled food':0.5},
  3715. 'hunt':{'meat':2,'bone':0.2,'hide':0.5},
  3716. },
  3717. affectedBy:['over hunting'],
  3718. });
  3719. new G.Goods({
  3720. name:'wolves',
  3721. desc:'Ferocious carnivores that hunt in packs; a dangerous source of [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3722. icon:[7,11],
  3723. res:{
  3724. 'gather':{'spoiled food':0.5},
  3725. 'hunt':{'meat':3,'bone':0.5,'hide':0.5},
  3726. },
  3727. affectedBy:['over hunting'],
  3728. });
  3729. new G.Goods({
  3730. name:'seals',
  3731. desc:'Carnivorous semi-aquatic mammal; provides [meat], [bone]s and [hide]s.//Carcasses can sometimes be gathered for [spoiled food].',
  3732. icon:[9,11],
  3733. res:{
  3734. 'gather':{'spoiled food':1},
  3735. 'hunt':{'meat':3,'bone':0.5,'hide':0.5},
  3736. },
  3737. affectedBy:['over hunting'],
  3738. });
  3739. new G.Goods({
  3740. name:'wild bugs',
  3741. displayName:'Bugs',
  3742. desc:'[wild bugs,Bugs] are ubiquitious and easy to capture.',
  3743. icon:[8,11],
  3744. res:{
  3745. 'gather':{'bugs':2},
  3746. },
  3747. //affectedBy:['over hunting'],
  3748. });
  3749. new G.Goods({
  3750. name:'saltwater fish',
  3751. desc:'Fish of every size and color.//A source of [seafood].',
  3752. icon:[11,11],
  3753. res:{
  3754. 'gather':{'seafood':0.03},
  3755. 'fish':{'seafood':3},
  3756. },
  3757. affectedBy:['over fishing'],
  3758. });
  3759. new G.Goods({
  3760. name:'freshwater fish',
  3761. desc:'Fish that live in streams and rivers.//A source of [seafood].',
  3762. icon:[12,11],
  3763. res:{
  3764. 'gather':{'seafood':0.03},
  3765. 'fish':{'seafood':3},
  3766. },
  3767. affectedBy:['over fishing'],
  3768. });
  3769. new G.Goods({
  3770. //TODO
  3771. name:'clams',
  3772. desc:'Bivalves and other assorted shells.//A source of [seafood], fairly easy to gather.',
  3773. icon:[0,0],
  3774. res:{
  3775. 'gather':{'seafood':0.5},
  3776. 'fish':{'seafood':1},
  3777. },
  3778. affectedBy:['over fishing'],
  3779. });
  3780. new G.Goods({
  3781. //TODO
  3782. name:'crabs',
  3783. desc:'Skittish crustaceans that walk sideways.//A source of [seafood].',
  3784. icon:[0,0],
  3785. res:{
  3786. 'gather':{'seafood':0.1},
  3787. 'fish':{'seafood':2},
  3788. },
  3789. affectedBy:['over fishing'],
  3790. });
  3791. //substrates
  3792. new G.Goods({
  3793. name:'rocky substrate',
  3794. desc:'A [rocky substrate] is found underneath most terrain types.//Surface [stone]s may be gathered by hand.//Digging often produces [mud], more [stone]s and occasionally [copper ore,Ores] and [clay].//Mining provides the best results, outputting a variety of [stone]s, rare [gold ore,Ores], and precious [gems].',
  3795. icon:[11,10],
  3796. res:{
  3797. 'gather':{'stone':0.25,'clay':0.005,'limestone':0.005},
  3798. 'dig':{'mud':2,'clay':0.15,'stone':0.6,'copper ore':0.01,'tin ore':0.01,'limestone':0.1,'salt':0.05},
  3799. 'mine':{'stone':1,'copper ore':0.1,'tin ore':0.1,'iron ore':0.05,'gold ore':0.005,'coal':0.1,'salt':0.1,'gems':0.005},
  3800. 'quarry':{'cut stone':1,'limestone':0.5,'marble':0.01},
  3801. },
  3802. affectedBy:['mineral depletion'],
  3803. noAmount:true,
  3804. });
  3805. new G.Goods({
  3806. name:'snow cover',
  3807. desc:'A [snow cover] is often available year-long in cold environments, and is a good source of [water]; it may also conceal [ice], which must be dug out.',
  3808. icon:[13,10],
  3809. res:{
  3810. 'gather':{'water':4,'muddy water':8},
  3811. 'dig':{'ice':0.2},
  3812. },
  3813. });
  3814. new G.Goods({
  3815. name:'sandy soil',
  3816. desc:'[sandy soil] is the result of a [rocky substrate] eroded by wind over long periods of time. [sand] is plentiful here.',
  3817. icon:[12,10],
  3818. res:{
  3819. 'dig':{'sand':1},
  3820. },
  3821. noAmount:true,
  3822. });
  3823. //liquids
  3824. new G.Goods({
  3825. name:'saltwater',
  3826. desc:'[saltwater] cannot be collected for [water], but may produce [salt] deposits.',
  3827. icon:[14,10],
  3828. res:{
  3829. 'gather':{'salt':0.05},
  3830. },
  3831. noAmount:true,
  3832. });
  3833. new G.Goods({
  3834. name:'freshwater',
  3835. desc:'[freshwater], whether found in streams or from rainwater, can be collected for [water] and [muddy water].',
  3836. icon:[15,10],
  3837. res:{
  3838. 'gather':{'water':8,'muddy water':8},
  3839. },
  3840. });
  3841.  
  3842. /*=====================================================================================
  3843. TILE EFFECTS
  3844. =======================================================================================*/
  3845. //TODO : implement
  3846. new G.TileEffect({
  3847. name:'deforestation',
  3848. desc:'This is the result of too much woodcutting in an area.//Having this effect on a tile lowers the quantity of trees it provides.//If woodcutting is halted, this effect will slowly subside as trees grow back over time, if the deforestation isn\'t too severe.',
  3849. visibleAt:100,
  3850. });
  3851. new G.TileEffect({
  3852. name:'mineral depletion',
  3853. desc:'This is the result of too much mining and digging in an area.//Having this effect on a tile lowers the quantity of minerals it provides.//If mining and digging are halted, this effect will slowly subside as more ore nodes are discovered.',
  3854. visibleAt:100,
  3855. });
  3856. new G.TileEffect({
  3857. name:'over hunting',
  3858. desc:'This is the result of too much hunting in an area.//Having this effect on a tile lowers the quantity of animals it provides.//If hunting is halted, this effect will slowly subside as animal population recovers over time, if there is enough of it left.',
  3859. visibleAt:100,
  3860. });
  3861. new G.TileEffect({
  3862. name:'over fishing',
  3863. desc:'This is the result of too much fishing in an area.//Having this effect on a tile lowers the quantity of sea creatures it provides.//If fishing is halted, this effect will slowly subside as wildlife population recovers over time, if there is enough of it left.',
  3864. visibleAt:100,
  3865. });
  3866. new G.TileEffect({
  3867. name:'scarce forageables',
  3868. desc:'This is the result of too much foraging in an area.//Having this effect on a tile lowers the quantity of all forageables it provides.//If foraging is halted, this effect will slowly subside.',
  3869. visibleAt:100,
  3870. });
  3871. new G.TileEffect({
  3872. name:'reserve',
  3873. desc:'A [reserve] prevents any resource extraction from this tile, letting depleted resources heal over.',
  3874. });
  3875.  
  3876. /*=====================================================================================
  3877. LEGACY
  3878. =======================================================================================*/
  3879.  
  3880. G.legacyBonuses.push(
  3881. {id:'addFastTicksOnStart',name:'+[X] free fast ticks',desc:'Additional fast ticks when starting a new game.',icon:[0,0],func:function(obj){G.fastTicks+=obj.amount;},context:'new'},
  3882. {id:'addFastTicksOnResearch',name:'+[X] fast ticks from research',desc:'Additional fast ticks when completing research.',icon:[0,0],func:function(obj){G.props['fastTicksOnResearch']+=obj.amount;}}
  3883. );
  3884.  
  3885. //do NOT remove or reorder victory types or saves WILL get corrupted
  3886.  
  3887. new G.Victory({
  3888. tier:0,
  3889. name:'mausoleum',
  3890. desc:'You have been laid to rest in the Mausoleum, an ancient stone monument the purpose of which takes root in archaic religious thought.',
  3891. fromUnit:'mausoleum',
  3892. effects:[
  3893. {type:'addFastTicksOnStart',amount:300*3},
  3894. {type:'addFastTicksOnResearch',amount:150}
  3895. ],
  3896. });
  3897.  
  3898. /*=====================================================================================
  3899. MAP GENERATOR
  3900. =======================================================================================*/
  3901. G.funcs['create map']=function(w,h)
  3902. {
  3903. //generate basic geography using Conway's Game of Life (rule : births from 4 to 9 neighbors, survival from 6 to 9 neighbors)
  3904.  
  3905. var generate=function(w,h)
  3906. {
  3907. var getAt=function(map,x,y)
  3908. {
  3909. //if (x<0||x>=map.length||y<0||y>=map[0].length) return 0;
  3910. //wrap around so we don't get big empty spots on the edges (as a bonus, this creates donut-shaped worlds)
  3911. if (x<0) x+=map.length;
  3912. else if (x>=map.length) x-=map.length;
  3913. if (y<0) y+=map[0].length;
  3914. else if (y>=map[0].length) y-=map[0].length;
  3915. return map[x][y];
  3916. }
  3917.  
  3918. //init map
  3919. var lvl=[];
  3920. for (var x=0;x<w;x++)
  3921. {
  3922. lvl[x]=[];
  3923. for (var y=0;y<h;y++)
  3924. {
  3925. lvl[x][y]=Math.random()<0.5?1:0;
  3926. }
  3927. }
  3928.  
  3929. //init buffer
  3930. var lvlBuffer=[];
  3931. for (var x=0;x<w;x++){lvlBuffer[x]=[];for (var y=0;y<h;y++){lvlBuffer[x][y]=0;}}
  3932.  
  3933. var passes=1;
  3934. for (var i=0;i<passes;i++)
  3935. {
  3936. //live
  3937. for (var x=0;x<w;x++)
  3938. {
  3939. for (var y=0;y<h;y++)
  3940. {
  3941. var n=getAt(lvl,x-1,y)+getAt(lvl,x-1,y-1)+getAt(lvl,x,y-1)+getAt(lvl,x+1,y-1)+getAt(lvl,x+1,y)+getAt(lvl,x+1,y+1)+getAt(lvl,x,y+1)+getAt(lvl,x-1,y+1);
  3942. var on=lvl[x][y];
  3943. if (on && n>=4 && n<=9) on=1; else on=0;
  3944. if (!on && n>=6 && n<=9) on=1;
  3945. if (Math.random()<0.05) on=Math.random()<0.5?1:0;//just a bit of extra randomness
  3946. lvlBuffer[x][y]=on;
  3947. }
  3948. }
  3949. //copy buffer back
  3950. for (var x=0;x<w;x++){for (var y=0;y<h;y++){lvl[x][y]=lvlBuffer[x][y];}}
  3951. }
  3952.  
  3953. return lvl;
  3954. }
  3955.  
  3956. var getStrAt=function(map,x,y)
  3957. {
  3958. if (x<0||x>=map.length-1||y<0||y>=map[0].length-1) return 'out';
  3959. return map[x][y];
  3960. }
  3961. var getAt=function(map,x,y)
  3962. {
  3963. if (x<0||x>=map.length-1||y<0||y>=map[0].length-1) return 0.5;
  3964. return map[x][y];
  3965. }
  3966.  
  3967. var landTiles=[];
  3968. var seaTiles=[];
  3969. var fit=false;
  3970. i=0;
  3971. while (i<20 && fit==false)//discard any map with less than 30% or more than 50% land
  3972. {
  3973. var lvl=generate(w,h);
  3974.  
  3975. landTiles=[];
  3976. seaTiles=[];
  3977. for (var x=0;x<w;x++)
  3978. {
  3979. for (var y=0;y<h;y++)
  3980. {
  3981. if (lvl[x][y]==0) seaTiles.push([x,y]);
  3982. else landTiles.push([x,y]);
  3983. }
  3984. }
  3985. var total=landTiles.length+seaTiles.length;
  3986. if (landTiles.length/total>0.3 && landTiles.length/total<0.5) fit=true;
  3987. i++;
  3988. }
  3989.  
  3990. //translate into terrain
  3991. for (var x=0;x<w;x++)
  3992. {
  3993. for (var y=0;y<h;y++)
  3994. {
  3995. var land='ocean';
  3996. if (lvl[x][y]==0) land='ocean';
  3997. else if (lvl[x][y]==1)
  3998. {
  3999. land='none';
  4000. }
  4001. lvl[x][y]=land;
  4002. }
  4003. }
  4004.  
  4005. //precipitation map
  4006. //generate more humidity over sea, less in land - with some variance
  4007. //on tiles with low humidity, 30% of the time, add some huge variance
  4008. //then, blur the map so that coasts get some humidity and variance can spread
  4009. var wet=[];
  4010. for (var x=0;x<w;x++)
  4011. {
  4012. wet[x]=[];
  4013. for (var y=0;y<h;y++)
  4014. {
  4015. wet[x][y]=(lvl[x][y]=='ocean'?0.8:0.2)+Math.random()*0.1-0.1/2;
  4016. if (Math.random()<0.3 && wet[x][y]<0.5) wet[x][y]+=Math.random()*5-2.5;
  4017. }
  4018. }
  4019. for (var x=0;x<w;x++)//blur
  4020. {
  4021. for (var y=0;y<h;y++)
  4022. {
  4023. var variance=0.05;
  4024. var n=getAt(wet,x-1,y)+getAt(wet,x-1,y-1)+getAt(wet,x,y-1)+getAt(wet,x+1,y-1)+getAt(wet,x+1,y)+getAt(wet,x+1,y+1)+getAt(wet,x,y+1)+getAt(wet,x-1,y+1);
  4025. wet[x][y]=(wet[x][y]+n)/9+Math.random()*variance-variance/2;
  4026. }
  4027. }
  4028. //temperature map. why not
  4029. var jumble=false;
  4030. if (!jumble)
  4031. {
  4032. //vertical sine wave (so we get hot equator and cold poles), with some variance
  4033. //humidity lowers temperature by a bit
  4034. var temp=[];
  4035. for (var x=0;x<w;x++)
  4036. {
  4037. temp[x]=[];
  4038. for (var y=0;y<h;y++)
  4039. {
  4040. var variance=0.15;
  4041. temp[x][y]=Math.sin(((y+0.5)/h-0.25)*Math.PI*2)/2+(lvl[x][y]=='ocean'?0.6:0.5)-(wet[x][y])*0.15+Math.random()*variance-variance/2;
  4042. }
  4043. }
  4044. }
  4045. else
  4046. {
  4047. //temperature spawns in big blobs of cold and hot
  4048. var temp=[];
  4049. for (var x=0;x<w;x++)
  4050. {
  4051. temp[x]=[];
  4052. for (var y=0;y<h;y++)
  4053. {
  4054. temp[x][y]=0.65+Math.random()*0.1-0.1/2-wet[x][y]*0.15;
  4055. if (Math.random()<0.5) temp[x][y]+=Math.random()*10-5;
  4056. }
  4057. }
  4058. for (var i=0;i<2;i++)//blur
  4059. {
  4060. for (var x=0;x<w;x++)
  4061. {
  4062. for (var y=0;y<h;y++)
  4063. {
  4064. var variance=0.05;
  4065. var n=getAt(temp,x-1,y)+getAt(temp,x-1,y-1)+getAt(temp,x,y-1)+getAt(temp,x+1,y-1)+getAt(temp,x+1,y)+getAt(temp,x+1,y+1)+getAt(temp,x,y+1)+getAt(temp,x-1,y+1);
  4066. temp[x][y]=(temp[x][y]+n)/9+Math.random()*variance-variance/2;
  4067. }
  4068. }
  4069. }
  4070. }
  4071.  
  4072. //biomes
  4073. for (var x=0;x<w;x++)
  4074. {
  4075. for (var y=0;y<h;y++)
  4076. {
  4077. var tempTile=temp[x][y];
  4078. var wetTile=wet[x][y];
  4079. var landTile=lvl[x][y];
  4080.  
  4081. var biomes=[];
  4082. if (tempTile<-0.1)
  4083. {
  4084. if (landTile=='ocean') biomes.push('arctic ocean');
  4085. else biomes.push('ice desert');
  4086. }
  4087. else if (tempTile<0.15)
  4088. {
  4089. if (landTile=='ocean') biomes.push('arctic ocean');
  4090. else if (wetTile<0.25) biomes.push('ice desert');
  4091. else if (wetTile>0.5) biomes.push('boreal forest');
  4092. else biomes.push('tundra');
  4093. }
  4094. else if (tempTile>1.1)
  4095. {
  4096. if (landTile=='ocean') biomes.push('tropical ocean');
  4097. else biomes.push('desert');
  4098. }
  4099. else if (tempTile>0.85)
  4100. {
  4101. if (landTile=='ocean') biomes.push('tropical ocean');
  4102. else if (wetTile<0.25) biomes.push('desert');
  4103. else if (wetTile>0.5) biomes.push('jungle');
  4104. else biomes.push('savanna');
  4105. }
  4106. else
  4107. {
  4108. if (landTile=='ocean') biomes.push('ocean');
  4109. else if (wetTile<0.25) biomes.push('shrubland');
  4110. else if (wetTile>0.5) biomes.push('forest');
  4111. else biomes.push('prairie');
  4112. }
  4113. if (biomes.length==0) biomes.push('prairie');
  4114. lvl[x][y]=choose(biomes);
  4115. }
  4116. }
  4117.  
  4118. for (var x=0;x<w;x++)//clean all tiles with no terrain
  4119. {
  4120. for (var y=0;y<h;y++)
  4121. {
  4122. if (lvl[x][y]=='none') lvl[x][y]='forest';
  4123. }
  4124. }
  4125. return lvl;
  4126. }
  4127. }
  4128. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement