configparser.rl 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  1. #ifndef __CONFIGPARSER_H
  2. #define __CONFIGPARSER_H
  3. // This file needs to be preprocessed with the 'ragel' tool.
  4. // Run it like this:
  5. //
  6. // ragel -G2 configparser.rl -o configparser.h
  7. //
  8. #include <string>
  9. #include <stdexcept>
  10. #include <iostream>
  11. #include <string.h>
  12. #include <stdio.h>
  13. namespace configparser {
  14. struct ragel_state {
  15. /** Ragel scanner cruft. **/
  16. // Iterators for start and end of buffer data.
  17. char* p;
  18. char* pe;
  19. // Iterator for 'end of file'.
  20. char* eof;
  21. // Internal state and rollback variables.
  22. int cs, act;
  23. // Stack for ragel machine states.
  24. int stack[256];
  25. int top;
  26. // Not part of ragel's variables; this is a buffer to hold the current match.
  27. std::string match;
  28. };
  29. inline void init_species(const Species& s) {
  30. init_species_copy(s);
  31. }
  32. inline void init_design(const Design& d) {
  33. init_design_copy(d);
  34. }
  35. inline void init_terrain(const Terrain& t) {
  36. init_terrain_copy(t);
  37. }
  38. inline void init_vault(const Vault& v) {
  39. init_vault_copy(v);
  40. }
  41. inline void init_celauto(const CelAuto& c) {
  42. init_celauto_copy(c);
  43. }
  44. inline void init_levelskin_(const Levelskin& l) {
  45. init_levelskin(l);
  46. }
  47. inline void init_damage(const Damage& d) {
  48. init_damage_copy(d);
  49. }
  50. inline void init_stat(const Stat& s) {
  51. init_stat_copy(s);
  52. }
  53. inline void init_count(const Count& s) {
  54. init_count_copy(s);
  55. }
  56. inline void add_color(maudit::color& c, unsigned int i) {
  57. c = (maudit::color)((uint32_t)c + i);
  58. }
  59. inline int toint(const std::string& s) {
  60. return ::atoi(s.c_str());
  61. }
  62. inline double toreal(const std::string& s) {
  63. return ::atof(s.c_str());
  64. }
  65. void parse_config(const std::string& filename, tag_mem_t& tagmem) {
  66. /** File reading cruft. **/
  67. char buf[4096];
  68. FILE* fn = ::fopen(filename.c_str(), "r");
  69. if (fn == NULL) {
  70. throw std::runtime_error("Could not open: \"" + filename + "\"");
  71. }
  72. ragel_state state;
  73. Species spe;
  74. Design des;
  75. Terrain ter;
  76. Vault vau;
  77. CelAuto cel;
  78. Levelskin lev;
  79. Damage dam;
  80. Stat sta;
  81. Count cou;
  82. ConstantsBank::ailment_t ail;
  83. damage::val_t dmgval;
  84. mean_deviation_t meandev;
  85. maudit::glyph skin;
  86. maudit::glyph skin_b;
  87. maudit::glyph skin_c;
  88. size_t bitmask_v;
  89. #define SKINS skin, skin_b, skin_c
  90. Vault::brush vbrush;
  91. unsigned char shortcut_key;
  92. tag_t genus_tag;
  93. tag_t flavor_tag;
  94. tag_t ach_tag;
  95. tag_t ail_tag;
  96. tag_t tmp_tag;
  97. unsigned int starsign_n;
  98. uint64_t hash;
  99. ui_symbols_t* ui_syms = NULL;
  100. %%{
  101. machine ConfigParser;
  102. access state.;
  103. variable p state.p;
  104. variable pe state.pe;
  105. variable eof state.eof;
  106. action start {
  107. state.match.clear();
  108. }
  109. action push {
  110. state.match += fc;
  111. }
  112. onews = [ \t\r\n];
  113. ws = onews*;
  114. ws1 = onews+;
  115. sep = '_' | ws;
  116. number = [0-9]+
  117. >start $push;
  118. snumber = ('-'? [0-9]+)
  119. >start $push;
  120. real = (('-'?) (([0-9]+ '\.' [0-9]+) | ([0-9]+)))
  121. >start $push;
  122. tag = [a-zA-Z0-9_]+
  123. >start $push;
  124. #/* 34 is the double quote character, the only reason for writing it like this is to make Emacs happy */
  125. quote = 34;
  126. strchar_escape :=
  127. ( ('"' ${ state.match += '"'; fret; }) |
  128. ('n' ${ state.match += '\n'; fret; }) |
  129. ('1' ${ state.match += '\1'; fret; }) |
  130. ('2' ${ state.match += '\2'; fret; }) |
  131. ('3' ${ state.match += '\3'; fret; }) |
  132. ('\\' ${ state.match += '\\'; fret; }) )
  133. ;
  134. strchar = ( (^ (quote | '\\') $push ) |
  135. ('\\' ${fcall strchar_escape;} ) );
  136. strdata = strchar*;
  137. string = '"' >start strdata '"';
  138. mean_dev = real %{ meandev.mean = toreal(state.match); } ws '|' ws
  139. real %{ meandev.deviation = toreal(state.match); };
  140. colorname =
  141. 'black' |
  142. 'red' %{ add_color(skin.fore, 1); } |
  143. 'green' %{ add_color(skin.fore, 2); } |
  144. 'yellow' %{ add_color(skin.fore, 3); } |
  145. 'blue' %{ add_color(skin.fore, 4); } |
  146. 'magenta' %{ add_color(skin.fore, 5); } |
  147. 'cyan' %{ add_color(skin.fore, 6); } |
  148. 'white' %{ add_color(skin.fore, 7); } ;
  149. color =
  150. ('none' %{ skin.fore = maudit::color::none; } ) |
  151. ('dim' %{ skin.fore = maudit::color::dim_black; } sep colorname) |
  152. ('bright' %{ skin.fore = maudit::color::bright_black; } sep colorname) ;
  153. back_color =
  154. 'none' %{ skin.back = maudit::color::none; } |
  155. 'black' %{ skin.back = maudit::color::bright_black; } |
  156. 'red' %{ skin.back = maudit::color::bright_red; } |
  157. 'green' %{ skin.back = maudit::color::bright_green; } |
  158. 'yellow' %{ skin.back = maudit::color::bright_yellow; } |
  159. 'blue' %{ skin.back = maudit::color::bright_blue; } |
  160. 'magenta' %{ skin.back = maudit::color::bright_magenta; } |
  161. 'cyan' %{ skin.back = maudit::color::bright_cyan; } |
  162. 'white' %{ skin.back = maudit::color::bright_white; } ;
  163. skin = string %{ skin.set_text(state.match);
  164. skin.back = maudit::color::bright_black;
  165. skin.fore = maudit::color::bright_white;
  166. skin.underline = false; }
  167. ws
  168. (color ws)?
  169. ('back' ws1 back_color ws)?
  170. ('underline' %{ skin.underline = true; } ws)?
  171. %{ skin_b = skin; skin_c = skin; }
  172. (('|' ws string %{ skin_b.set_text(state.match); })
  173. ws
  174. ('|' ws string %{ skin_c.set_text(state.match); })?)?
  175. ;
  176. bitmask = '' %{ bitmask_v = 0; }
  177. ( number %{ bitmask_v |= (1 << toint(state.match)); } ws)* ;
  178. ####
  179. damage_val =
  180. tag %{ dmgval.type = tag_t(state.match, tagmem); }
  181. ws1 real %{ dmgval.val = toreal(state.match); }
  182. ;
  183. ####
  184. habitat =
  185. 'walk' %{ spe.habitat = Species::habitat_t::walk; } |
  186. 'floor' %{ spe.habitat = Species::habitat_t::floor; } |
  187. 'water' %{ spe.habitat = Species::habitat_t::water; } |
  188. 'corner' %{ spe.habitat = Species::habitat_t::corner; } |
  189. 'shoreline' %{ spe.habitat = Species::habitat_t::shoreline; } ;
  190. ai =
  191. 'none' %{ spe.ai = Species::ai_t::none; } |
  192. 'seek' %{ spe.ai = Species::ai_t::seek; } |
  193. 'random' %{ spe.ai = Species::ai_t::random; } |
  194. 'seek_awake' %{ spe.ai = Species::ai_t::seek_awake; } |
  195. 'magic_none' %{ spe.ai = Species::ai_t::magic_none; } |
  196. 'magic_none_awake' %{ spe.ai = Species::ai_t::magic_none_awake; } |
  197. 'suicide' %{ spe.ai = Species::ai_t::suicide; } |
  198. 'magic_random' %{ spe.ai = Species::ai_t::magic_random; } ;
  199. idle_ai =
  200. 'none' %{ spe.idle_ai = Species::idle_ai_t::none; } |
  201. 'random' %{ spe.idle_ai = Species::idle_ai_t::random; } ;
  202. move =
  203. 'walk' %{ spe.move = Species::move_t::walk; } |
  204. 'floor' %{ spe.move = Species::move_t::floor; } |
  205. 'water' %{ spe.move = Species::move_t::water; } |
  206. 'corner' %{ spe.move = Species::move_t::corner; } |
  207. 'shoreline' %{ spe.move = Species::move_t::shoreline; } ;
  208. species_count = 'count' ws1 number %{ spe.count = toint(state.match); } ;
  209. species_name = 'name' ws1 string %{ spe.name = state.match; } ;
  210. species_skin = 'skin' ws1 skin %{ spe.skin.set(SKINS); } ;
  211. species_true_level = 'true_level' ws1 number %{ spe.true_level = toint(state.match); } ;
  212. species_genus = 'genus' ws1 tag %{ spe.genus = tag_t(state.match, tagmem); } ;
  213. species_descr = 'descr' ws1 string %{ spe.descr = state.match; } ;
  214. species_habitat = 'habitat' ws1 habitat ;
  215. species_ai = 'ai' ws1 ai ;
  216. species_idle_ai = 'idle_ai' ws1 idle_ai ;
  217. species_move = 'move' ws1 move ;
  218. species_range = 'range' ws1 number %{ spe.range = toint(state.match); } ;
  219. species_attack = 'attack' ws1 damage_val %{ spe.attacks.add(dmgval); } ;
  220. species_defense = 'defense' ws1 damage_val %{ spe.defenses.add(dmgval); } ;
  221. species_stat = 'stat'
  222. ws1 tag %{ tmp_tag = tag_t(state.match, tagmem); }
  223. ws1 real %{ spe.stats.stats[tmp_tag].val = toreal(state.match); } ;
  224. species_digging = 'digging' ws1 real %{ spe.digging = toreal(state.match); } ;
  225. species_clumpsize = 'clumpsize' ws1 mean_dev %{ spe.clumpsize = meandev; };
  226. species_companion = 'companion' %{ spe.companion.push_back(Species::companion_t()); }
  227. ws1 real %{ spe.companion.back().chance = toreal(state.match); }
  228. ws1 tag %{ spe.companion.back().tag = tag_t(state.match, tagmem); }
  229. ;
  230. species_drop = 'drop' %{ spe.drop.push_back(Species::drop_t()); }
  231. ws1 tag %{ spe.drop.back().tag = tag_t(state.match, tagmem); }
  232. ws1 real %{ spe.drop.back().chance = toreal(state.match); }
  233. ( ws1 tag %{ spe.drop.back().damage_type = tag_t(state.match, tagmem); } )?
  234. ;
  235. species_drop_random = 'drop_random' %{ spe.drop.push_back(Species::drop_t()); }
  236. ws1 number %{ spe.drop.back().level = toint(state.match); }
  237. ws1 real %{ spe.drop.back().chance = toreal(state.match); }
  238. ( ws1 tag %{ spe.drop.back().damage_type = tag_t(state.match, tagmem); } )?
  239. ;
  240. species_cast_cloud = 'cast_cloud' %{ spe.cast_cloud.push_back(Species::cloud_t()); }
  241. ws1 real %{ spe.cast_cloud.back().chance = toreal(state.match); }
  242. ws1 tag %{ spe.cast_cloud.back().terraintag = tag_t(state.match, tagmem); }
  243. ws1 number %{ spe.cast_cloud.back().radius = toint(state.match); }
  244. ws1 number %{ spe.cast_cloud.back().turns = toint(state.match); }
  245. ws1 string %{ spe.cast_cloud.back().name = state.match; }
  246. ;
  247. species_summon = 'summon' %{ spe.summon.push_back(Species::summon_t()); }
  248. ws1 real %{ spe.summon.back().chance = toreal(state.match); }
  249. ws1 tag %{ spe.summon.back().speciestag = tag_t(state.match, tagmem); }
  250. ws1 number %{ spe.summon.back().turns = toint(state.match); }
  251. ws1 string %{ spe.summon.back().msg = state.match; }
  252. ;
  253. species_death_summon = 'death_summon' ws1 tag %{ spe.death_summon = tag_t(state.match, tagmem); } ;
  254. species_spawn = 'spawn' %{ spe.spawns.push_back(Species::spawn_t()); }
  255. ws1 real %{ spe.spawns.back().chance = toreal(state.match); }
  256. ws1 number %{ spe.spawns.back().level = toint(state.match); }
  257. ws1 number %{ spe.spawns.back().turns = toint(state.match); }
  258. ws1 string %{ spe.spawns.back().msg = state.match; }
  259. ;
  260. species_blast = 'blast' %{ spe.blast.push_back(Species::blast_t()); }
  261. ws1 real %{ spe.blast.back().chance = toreal(state.match); }
  262. ws1 number %{ spe.blast.back().radius = toint(state.match); }
  263. ws1 number %{ spe.blast.back().range = toint(state.match); }
  264. ws1 number %{ spe.blast.back().turns = toint(state.match); }
  265. ws1 string %{ spe.blast.back().name = state.match; }
  266. (ws1 'attack'
  267. ws1 damage_val
  268. %{ spe.blast.back().attacks.add(dmgval); })+
  269. ;
  270. species_animal = 'animal' %{ spe.flags.animal = true; } ;
  271. species_undead = 'undead' %{ spe.flags.undead = true; } ;
  272. species_magic = 'magic' %{ spe.flags.magic = true; } ;
  273. species_plant = 'plant' %{ spe.flags.plant = true; } ;
  274. species_robot = 'robot' %{ spe.flags.robot = true; } ;
  275. species_cosmic = 'cosmic' %{ spe.flags.cosmic = true; } ;
  276. species_player = 'player' %{ spe.flags.player = true; } ;
  277. species_stealthy = 'stealthy' %{ spe.flags.stealthy = true; } ;
  278. species_terrain_immune = 'terrain_immune' %{ spe.flags.terrain_immune = true; } ;
  279. species_eyeless = 'eyeless' %{ spe.flags.eyeless = true; } ;
  280. species_trail = 'trail'
  281. ws1 tag %{ spe.trail.terrain = tag_t(state.match, tagmem); }
  282. ws1 tag %{ spe.trail.stat = tag_t(state.match, tagmem); }
  283. ws1 mean_dev %{ spe.trail.cost = meandev; }
  284. ;
  285. species_steal = 'steal' ws1 tag %{ spe.steal = tag_t(state.match, tagmem); } ;
  286. species_morph = 'morph'
  287. ws1 tag %{ spe.morph.species = tag_t(state.match, tagmem); }
  288. ws1 real %{ spe.morph.chance = toreal(state.match); }
  289. ;
  290. species_inc_stat = 'inc_stat'
  291. ws1 tag %{ tmp_tag = tag_t(state.match, tagmem); }
  292. ws1 real %{ spe.inc_stat[tmp_tag] += toreal(state.match); };
  293. species_ally = 'ally' ws1 tag %{ spe.ally = tag_t(state.match, tagmem); };
  294. species_magic_cost = 'magic_cost'
  295. ws1 tag %{ spe.magic_cost.stat = tag_t(state.match, tagmem); }
  296. ws1 real %{ spe.magic_cost.cost = toreal(state.match); };
  297. species_one_data =
  298. (species_count | species_name | species_skin | species_habitat | species_ai |
  299. species_genus | species_descr | species_idle_ai | species_move | species_range | species_clumpsize |
  300. species_companion | species_attack | species_defense | species_drop | species_drop_random |
  301. species_cast_cloud | species_summon | species_death_summon | species_spawn |
  302. species_animal | species_undead | species_magic | species_plant | species_magic_cost |
  303. species_robot | species_cosmic | species_terrain_immune | species_eyeless | species_player |
  304. species_stat | species_blast | species_true_level | species_trail | species_steal |
  305. species_morph | species_inc_stat | species_ally | species_stealthy | species_digging |
  306. '}'
  307. ${ fret; })
  308. ;
  309. one_species := (ws species_one_data ws ';')+
  310. ;
  311. species_level = number %{ spe.level = toint(state.match); }
  312. ;
  313. species_tag = tag %{ spe.tag = tag_t(state.match, tagmem); }
  314. ;
  315. species =
  316. 'species' %{ spe = Species(); }
  317. ws1 species_level ws1 species_tag ws
  318. '{' ${fcall one_species;}
  319. %{ init_species(spe); }
  320. ;
  321. ####
  322. design_count = 'count' ws1 number %{ des.count = toint(state.match); } ;
  323. design_bonus_a = 'bonus_a' ws1 number %{ des.bonus_a_count = toint(state.match); } ;
  324. design_bonus_b = 'bonus_b' ws1 number %{ des.bonus_b_count = toint(state.match); } ;
  325. design_name = 'name' ws1 string %{ des.name = state.match; } ;
  326. design_skin = 'skin' ws1 skin %{ des.skin.set(SKINS); };
  327. design_slot = 'slot' ws1 tag %{ des.slot = tag_t(state.match, tagmem); } ;
  328. design_descr = 'descr' ws1 string %{ des.descr = state.match; } ;
  329. design_attack = 'attack' ws1 damage_val %{ des.attacks.add(dmgval); } ;
  330. design_defense = 'defense' ws1 damage_val %{ des.defenses.add(dmgval); } ;
  331. design_stackrange = 'stackrange' ws1 number %{ des.stackrange = toint(state.match); };
  332. design_usable = 'usable' %{ des.usable = true; };
  333. design_melee = 'melee' %{ des.melee = true; };
  334. design_throwrange = 'throwrange' ws1 number %{ des.throwrange = toint(state.match); };
  335. design_lightradius = 'lightradius' ws1 number %{ des.lightradius = toint(state.match); };
  336. design_digging = 'digging' ws1 real %{ des.digging = toreal(state.match); };
  337. design_descend = 'descend' ws1 snumber %{ des.descend = toint(state.match); };
  338. design_inc_stat = 'inc_stat' %{ des.inc_stat.push_back(Design::inc_stat_t()); }
  339. ws1 tag %{ des.inc_stat.back().stat = tag_t(state.match, tagmem); }
  340. ws1 real %{ des.inc_stat.back().val = toreal(state.match); }
  341. (ws1 string %{ des.inc_stat.back().msg = state.match; })?
  342. ;
  343. design_inc_count = 'inc_count' %{ des.inc_count.push_back(Design::inc_count_t()); }
  344. ws1 tag %{ des.inc_count.back().stat = tag_t(state.match, tagmem); }
  345. ws1 snumber %{ des.inc_count.back().val = toint(state.match); }
  346. (ws1 string %{ des.inc_count.back().msg_a = state.match; }
  347. ws1 string %{ des.inc_count.back().msg_b = state.match; })?
  348. ;
  349. design_zero_stat = 'zero_stat' %{ des.zero_stat.push_back(Design::zero_stat_t()); }
  350. ws1 tag %{ des.zero_stat.back().stat = tag_t(state.match, tagmem); }
  351. (ws1 string %{ des.zero_stat.back().msg = state.match; })?
  352. ;
  353. design_use_for_free = 'use_for_free' %{ des.use_for_free = true; };
  354. design_destructible = 'destructible' %{ des.destructible = true; };
  355. design_count_is_only_one = 'count_is_only_one' %{ des.count_is_only_one = true; };
  356. design_safe_descend = 'safe_descend' ws1 snumber %{ des.safe_descend = toint(state.match); };
  357. design_blink = 'blink' %{ des.flags.blink = true; };
  358. design_dowsing = 'dowsing' %{ des.flags.dowsing = true; };
  359. design_blast = 'blast'
  360. ws1 number %{ des.blast.radius = toint(state.match); }
  361. ws1 number %{ des.blast.range = toint(state.match); }
  362. ;
  363. design_attack_level = 'attack_level' ws1 number %{ des.attack_level = toint(state.match); };
  364. design_cast_cloud = 'cast_cloud'
  365. ws1 tag %{ des.cast_cloud.terraintag = tag_t(state.match, tagmem); }
  366. ws1 number %{ des.cast_cloud.radius = toint(state.match); }
  367. ws1 number %{ des.cast_cloud.range = toint(state.match); }
  368. ;
  369. design_gencount = 'gencount' ws1 mean_dev %{ des.gencount = meandev; };
  370. design_worth = 'worth' ws1 real %{ des.worth = toreal(state.match); };
  371. design_is_lit = 'is_lit' %{ des.is_lit = true; };
  372. design_place_permafeat = 'place_permafeat'
  373. ws1 tag %{ des.place_permafeat.feat = tag_t(state.match, tagmem); };
  374. design_place_permafloor_flag =
  375. ('+walk' %{ des.place_permafeat.walk = 1; } ) |
  376. ('-walk' %{ des.place_permafeat.walk = 0; } ) |
  377. ('+water' %{ des.place_permafeat.water = 1; } ) |
  378. ('-water' %{ des.place_permafeat.water = 0; } );
  379. design_place_permafloor = 'place_permafloor'
  380. ws1 (ws design_place_permafloor_flag)*;
  381. design_tickstat_moon = 'tickstat_moon' %{ des.tickstat_moon.push_back(Design::tickstat_moon_t()); }
  382. ws1 tag %{ des.tickstat_moon.back().stat = tag_t(state.match, tagmem); }
  383. ws1 real %{ des.tickstat_moon.back().height = toreal(state.match); }
  384. ws1 mean_dev %{ des.tickstat_moon.back().v = meandev; }
  385. ;
  386. design_tickstat = 'tickstat' %{ des.tickstat.push_back(Design::tickstat_t()); }
  387. ws1 tag %{ des.tickstat.back().stat = tag_t(state.match, tagmem); }
  388. ws1 real %{ des.tickstat.back().add = toreal(state.match); }
  389. ws1 real %{ des.tickstat.back().mul = toreal(state.match); }
  390. (ws1 'apply_count' %{ des.tickstat.back().apply_count = true; })?
  391. ;
  392. design_enable_spells = 'enable_spells' %{ des.flags.enable_spells = true; };
  393. design_random_spell = 'random_spell' %{ des.flags.random_spell = true; };
  394. design_grant_spell = 'grant_spell' %{ des.spells.push_back(Design::spell_t()); }
  395. ws1 tag %{ des.spells.back().ca_tag = tag_t(state.match, tagmem); }
  396. ws1 string %{ des.spells.back().name = state.match; }
  397. ;
  398. design_count_is_rcode = 'count_is_rcode'
  399. %{ des.count_is_rcode = true; des.count_is_only_one = true; }
  400. ;
  401. design_genocide = 'genocide' ws1 tag %{ des.genocide = tag_t(state.match, tagmem); };
  402. design_wish = 'wish' ws1 ('simple' %{ des.wishing = Design::SIMPLE_WISH; } |
  403. 'special' %{ des.wishing = Design::SPECIAL_WISH; })
  404. ;
  405. design_magic_mapping = 'magic_mapping' %{ des.magic_mapping = true; };
  406. design_heal_ailments = 'heal_ailments' %{ des.heal_ailments = true; };
  407. design_heal_polymorph = 'heal_polymorph' %{ des.heal_polymorph = true; };
  408. design_action_name = 'action_name' ws1 string %{ des.action_name = state.match; };
  409. design_flavor = 'flavor' ws1 tag %{ des.flavor = tag_t(state.match, tagmem); };
  410. design_take_summon = 'take_summon'
  411. ws1 tag %{ des.take_summon.species = tag_t(state.match, tagmem); }
  412. ws1 number %{ des.take_summon.needs_count = toint(state.match); }
  413. ;
  414. design_forbid_wish = 'forbid_wish' %{ des.forbid_wish = true; };
  415. design_forbid_buy = 'forbid_buy' %{ des.forbid_buy = true; };
  416. design_change_count = 'change_count' ws1 snumber %{ des.change_count = toint(state.match); };
  417. design_starsign = 'starsign'
  418. ws1 number %{ des.starsign.day = toint(state.match); }
  419. ws1 number %{ des.starsign.sign = toint(state.match); }
  420. ;
  421. design_summon = 'summon'
  422. ws1 tag %{ des.summon.species = tag_t(state.match, tagmem); }
  423. ws1 number %{ des.summon.count = toint(state.match); }
  424. ;
  425. design_polymorph = 'polymorph'
  426. ws1 tag %{ des.polymorph.species = tag_t(state.match, tagmem); }
  427. ws1 mean_dev %{ des.polymorph.turns = meandev; }
  428. ws1 string %{ des.polymorph.msg = state.match; }
  429. ;
  430. design_fast = 'fast'
  431. ws1 number %{ des.fast.slice = toint(state.match); }
  432. ws1 mean_dev %{ des.fast.turns = meandev; }
  433. ;
  434. design_monster_raised = 'monster_raised' ws1 tag %{ des.monster_raised = tag_t(state.match, tagmem); };
  435. design_raise_monsters = 'raise_monsters' ws1 tag %{ des.raise_monsters = tag_t(state.match, tagmem); };
  436. design_charm = 'charm'
  437. ws1 number %{ des.charm.range = toint(state.match); }
  438. ws1 string %{ des.charm.msg = state.match; }
  439. ;
  440. design_label_spot = 'label_spot' %{ des.label_spot = true; };
  441. design_lucky_free_apply = 'lucky_free_apply'
  442. ws1 tag %{ des.lucky_free_apply.stat = tag_t(state.match, tagmem); }
  443. ws1 real %{ des.lucky_free_apply.factor = toreal(state.match); }
  444. ws1 real %{ des.lucky_free_apply.threshold = toreal(state.match); }
  445. ;
  446. design_one_data =
  447. (design_count | design_bonus_a | design_bonus_b | design_name | design_skin | design_slot | design_descr |
  448. design_attack | design_defense | design_stackrange | design_usable | design_destructible |
  449. design_throwrange | design_blast | design_attack_level | design_gencount | design_melee |
  450. design_tickstat_moon | design_lightradius | design_digging | design_descend | design_blink |
  451. design_cast_cloud | design_worth | design_safe_descend | design_is_lit | design_count_is_only_one |
  452. design_place_permafeat | design_place_permafloor | design_tickstat |
  453. design_dowsing | design_use_for_free |
  454. design_enable_spells | design_grant_spell | design_count_is_rcode |
  455. design_random_spell | design_genocide | design_wish | design_magic_mapping |
  456. design_action_name | design_flavor | design_take_summon |
  457. design_heal_ailments | design_heal_polymorph | design_forbid_buy |
  458. design_forbid_wish | design_change_count | design_inc_stat | design_inc_count | design_zero_stat |
  459. design_starsign | design_summon | design_polymorph | design_fast | design_lucky_free_apply |
  460. design_monster_raised | design_raise_monsters | design_charm | design_label_spot |
  461. '}'
  462. ${ fret; })
  463. ;
  464. one_design := (ws design_one_data ws ';')+
  465. ;
  466. design_level = number %{ des.level = toint(state.match); }
  467. ;
  468. design_tag = tag %{ des.tag = tag_t(state.match, tagmem); }
  469. ;
  470. design =
  471. 'design' %{ des = Design(); }
  472. ws1 design_level ws1 design_tag ws
  473. '{' ${fcall one_design;}
  474. %{ init_design(des); }
  475. ;
  476. ####
  477. tplacement =
  478. 'floor' %{ ter.placement = Terrain::placement_t::floor; } |
  479. 'water' %{ ter.placement = Terrain::placement_t::water; } |
  480. 'corner' %{ ter.placement = Terrain::placement_t::corner; } |
  481. 'shoreline' %{ ter.placement = Terrain::placement_t::shoreline; } |
  482. 'lowlands' %{ ter.placement = Terrain::placement_t::lowlands; } ;
  483. terrain_tunnel = 'tunnel'
  484. ws1 snumber %{ ter.tunnel_x = toint(state.match); }
  485. ws1 snumber %{ ter.tunnel_y = toint(state.match); }
  486. ;
  487. terrain_count = 'count' ws1 number %{ ter.count = toint(state.match); } ;
  488. terrain_name = 'name' ws1 string %{ ter.name = state.match; } ;
  489. terrain_descr = 'descr' ws1 string %{ ter.descr = state.match; } ;
  490. terrain_skin = 'skin' ws1 skin %{ ter.skin.set(SKINS); };
  491. terrain_placement = 'placement' ws1 tplacement ;
  492. terrain_stairs = 'stairs' ws1 snumber %{ ter.stairs = toint(state.match); } ;
  493. terrain_viewblock = 'viewblock' %{ ter.viewblock = true; } ;
  494. terrain_walkblock = 'walkblock' %{ ter.walkblock = true; } ;
  495. terrain_decay = 'decay' ws1 number %{ ter.decay = toint(state.match); } ;
  496. terrain_attack = 'attack' ws1 damage_val %{ ter.attacks.add(dmgval); } ;
  497. terrain_sticky = 'sticky' %{ ter.sticky = true; } ;
  498. terrain_charges = 'charges' ws1 number %{ ter.charges = toint(state.match); } ;
  499. terrain_is_lit = 'is_lit' %{ ter.is_lit = true; } ;
  500. terrain_is_lightsource = 'is_lightsource' %{ ter.is_lightsource = true; } ;
  501. terrain_air = 'air' %{ ter.air = true; };
  502. terrain_safebox = 'safebox' %{ ter.safebox = true; };
  503. terrain_attack_level = 'attack_level' ws1 number %{ ter.attack_level = toint(state.match); } ;
  504. terrain_victory_item = 'victory_item' ws1 tag %{ ter.victory_item = tag_t(state.match, tagmem); } ;
  505. terrain_grant_spell = 'grant_spell'
  506. ws1 tag %{ ter.grant_spell.stat = tag_t(state.match, tagmem); }
  507. ws1 real %{ ter.grant_spell.stat_min = toreal(state.match); }
  508. ws1 real %{ ter.grant_spell.stat_max = toreal(state.match); }
  509. ws1 tag %{ ter.grant_spell.ca_tag = tag_t(state.match, tagmem); }
  510. ws1 real %{ ter.grant_spell.timeout = toreal(state.match); }
  511. ws1 string %{ ter.grant_spell.name = state.match; } ;
  512. terrain_banking = 'banking'
  513. ws1 real %{ ter.banking.buy_margin = toreal(state.match); }
  514. ws1 real %{ ter.banking.sell_margin = toreal(state.match); }
  515. ws1 tag %{ ter.banking.bonus_stat = tag_t(state.match, tagmem); }
  516. ws1 real %{ ter.banking.stat_bonus = toreal(state.match); }
  517. ws1 real %{ ter.banking.money_curse = toreal(state.match); }
  518. ws1 real %{ ter.banking.gives_change = toreal(state.match); }
  519. ;
  520. terrain_uncharge_flag = ('attack' %{ ter.uncharge.attack = true; } ) |
  521. ('use' %{ ter.uncharge.use = true; } ) |
  522. ('move' %{ ter.uncharge.move = true; } ) |
  523. ('bump' %{ ter.uncharge.bump = true; } ) |
  524. ('sensor' %{ ter.uncharge.sensor = true; } ) ;
  525. terrain_uncharge = 'uncharge' ws1 (ws terrain_uncharge_flag)* ;
  526. terrain_crafting = 'crafting' %{ ter.crafting.push_back(Terrain::craft_t()); }
  527. ws1 tag %{ ter.crafting.back().from = tag_t(state.match, tagmem); }
  528. ws1 tag %{ ter.crafting.back().to = tag_t(state.match, tagmem); }
  529. ws1 string %{ ter.crafting.back().msg = state.match; }
  530. ;
  531. terrain_wish = 'wish' ws1 ('simple' %{ ter.wishing = Terrain::SIMPLE_WISH; } |
  532. 'special' %{ ter.wishing = Terrain::SPECIAL_WISH; })
  533. ;
  534. terrain_important = 'important' %{ ter.important = true; } ;
  535. terrain_view_radius = 'view_radius' ws1 number %{ ter.view_radius = toint(state.match); } ;
  536. terrain_sensor_toggle = 'sensor_toggle'
  537. ws1 tag %{ tmp_tag = tag_t(state.match, tagmem); }
  538. ws1 tag %{ ter.sensor_toggle[tmp_tag] = tag_t(state.match, tagmem); }
  539. ;
  540. terrain_inc_stat = 'inc_stat' %{ ter.inc_stat.push_back(Terrain::inc_stat_t()); }
  541. ws1 tag %{ ter.inc_stat.back().stat = tag_t(state.match, tagmem); }
  542. ws1 real %{ ter.inc_stat.back().val = toreal(state.match); }
  543. (ws1 string %{ ter.inc_stat.back().msg = state.match; })?
  544. ;
  545. terrain_preserve = 'preserve' %{ ter.preserve = true; } ;
  546. terrain_message = 'message' ws1 string %{ ter.message = state.match; } ;
  547. terrain_player_attack = 'player_attack' %{ ter.player_attack = true; } ;
  548. terrain_one_data =
  549. (terrain_count | terrain_name | terrain_skin | terrain_placement | terrain_descr |
  550. terrain_stairs | terrain_tunnel | terrain_viewblock | terrain_walkblock |
  551. terrain_decay | terrain_attack | terrain_attack_level | terrain_sticky |
  552. terrain_charges | terrain_grant_spell | terrain_is_lit | terrain_is_lightsource | terrain_air |
  553. terrain_victory_item | terrain_safebox | terrain_banking | terrain_player_attack |
  554. terrain_uncharge | terrain_crafting | terrain_wish | terrain_important | terrain_inc_stat |
  555. terrain_view_radius | terrain_sensor_toggle | terrain_preserve | terrain_message |
  556. '}'
  557. ${ fret; })
  558. ;
  559. one_terrain := (ws terrain_one_data ws ';')+
  560. ;
  561. terrain_tag = tag %{ ter.tag = tag_t(state.match, tagmem); }
  562. ;
  563. terrain =
  564. 'terrain' %{ ter = Terrain(); }
  565. ws1 terrain_tag ws
  566. '{' ${fcall one_terrain;}
  567. %{ init_terrain(ter); }
  568. ;
  569. ####
  570. vplacement =
  571. 'floor' %{ vau.placement = Vault::placement_t::floor; } |
  572. 'water' %{ vau.placement = Vault::placement_t::water; } |
  573. 'corner' %{ vau.placement = Vault::placement_t::corner; } |
  574. 'shoreline' %{ vau.placement = Vault::placement_t::shoreline; } |
  575. 'lowlands' %{ vau.placement = Vault::placement_t::lowlands; } |
  576. 'packing' %{ vau.placement = Vault::placement_t::packing; } ;
  577. vault_count = 'count' ws1 number %{ vau.count = toint(state.match); } ;
  578. vault_placement = 'placement' ws1 vplacement ;
  579. vault_anchor = 'anchor'
  580. ws1 number %{ vau.ax = toint(state.match); }
  581. ws1 number %{ vau.ay = toint(state.match); }
  582. ;
  583. vault_set_player = 'set_player'
  584. ws1 number %{ vau.px = toint(state.match); }
  585. ws1 number %{ vau.py = toint(state.match); }
  586. ;
  587. vault_brush_terrain =
  588. ('-' %{ vbrush.terrain = tag_t(); } |
  589. tag %{ vbrush.terrain = tag_t(state.match, tagmem); });
  590. vault_brush_design =
  591. ('-' %{ vbrush.design.type = Vault::brush::design_t::type_t::NONE; } |
  592. 'specific' %{ vbrush.design.type = Vault::brush::design_t::type_t::SPECIFIC; }
  593. ws '(' ws tag %{ vbrush.design.tag = tag_t(state.match, tagmem); } ws ')' |
  594. 'level' %{ vbrush.design.type = Vault::brush::design_t::type_t::LEVEL; }
  595. ws '(' ws number %{ vbrush.design.level = toint(state.match); } ws ')' |
  596. 'level_any' %{ vbrush.design.type = Vault::brush::design_t::type_t::LEVEL_ANY; }
  597. ws '(' ws number %{ vbrush.design.level = toint(state.match); } ws ')');
  598. vault_brush_species =
  599. ('-' %{ vbrush.species.type = Vault::brush::species_t::type_t::NONE; } |
  600. 'specific' %{ vbrush.species.type = Vault::brush::species_t::type_t::SPECIFIC; }
  601. ws '(' ws tag %{ vbrush.species.tag = tag_t(state.match, tagmem); } ws ')' |
  602. 'level' %{ vbrush.species.type = Vault::brush::species_t::type_t::LEVEL; }
  603. ws '(' ws number %{ vbrush.species.level = toint(state.match); } ws ')' |
  604. 'genus' %{ vbrush.species.type = Vault::brush::species_t::type_t::GENUS; }
  605. ws '(' ws tag %{ vbrush.species.tag = tag_t(state.match, tagmem); }
  606. ws1 number %{ vbrush.species.level = toint(state.match); } ws ')');
  607. vault_brush = 'brush' %{ vbrush = Vault::brush(); }
  608. ws1 ('blank' ${ vbrush.is_blank = true; } |
  609. 'floor' ${ vbrush.is_walk = true; vbrush.is_water = false; } |
  610. 'water' ${ vbrush.is_walk = true; vbrush.is_water = true; } |
  611. 'wall' ${ vbrush.is_walk = false; vbrush.is_water = false; } |
  612. 'wwall' ${ vbrush.is_walk = false; vbrush.is_water = true; })
  613. ws1 vault_brush_terrain
  614. ws1 vault_brush_design
  615. ws1 vault_brush_species
  616. ws1 '\'' any ${ vau.brushes[fc] = vbrush; } '\''
  617. ;
  618. vault_line = 'l' ws1 string %{ vau.pic.push_back(state.match); } ;
  619. vault_cloud = 'cloud' ws1 number %{ vau.cloud.n = toint(state.match); }
  620. ws1 mean_dev %{ vau.cloud.distrib = meandev; }
  621. (ws1 '\'' any ${ vau.cloud.brushes.push_back(fc); } '\''
  622. ws1 real %{ vau.cloud.chances.push_back(toreal(state.match)); } )+
  623. ;
  624. vbplacement =
  625. 'floor' %{ vau.blob.placement = Vault::placement_t::floor; } |
  626. 'water' %{ vau.blob.placement = Vault::placement_t::water; } |
  627. 'corner' %{ vau.blob.placement = Vault::placement_t::corner; } |
  628. 'shoreline' %{ vau.blob.placement = Vault::placement_t::shoreline; } |
  629. 'lowlands' %{ vau.blob.placement = Vault::placement_t::lowlands; } ;
  630. vault_blob = 'blob' ws1 number %{ vau.blob.n = toint(state.match); }
  631. ws1 vbplacement
  632. ws1 '\'' any ${ vau.blob.brush = fc; } '\''
  633. ;
  634. vault_river = 'river' ws1 number %{ vau.river.n = toint(state.match); }
  635. ws1 mean_dev %{ vau.river.angle = meandev; }
  636. ws1 mean_dev %{ vau.river.width = meandev; }
  637. ws1 number %{ vau.river.splitchance = toint(state.match); }
  638. ws1 '\'' any ${ vau.river.brush = fc; } '\''
  639. ;
  640. vault_room = 'room'
  641. ws1 number %{ vau.room.w1 = toint(state.match); }
  642. ws1 number %{ vau.room.w2 = toint(state.match); }
  643. ws1 number %{ vau.room.h1 = toint(state.match); }
  644. ws1 number %{ vau.room.h2 = toint(state.match); }
  645. ws1 '\'' any ${ vau.room.brush = fc; } '\''
  646. ;
  647. vault_tunnel = 'tunnel' %{ vau.tunnel.enabled = true; }
  648. ws1 '\'' any ${ vau.tunnel.plain_brush = fc; } '\''
  649. ws1 '\'' any ${ vau.tunnel.b_brush = fc; } '\''
  650. ws1 '\'' any ${ vau.tunnel.a_brush = fc; } '\''
  651. ;
  652. vault_inherit = 'inherit' ws1 tag %{ vau.inherit = tag_t(state.match, tagmem); };
  653. vault_transpose = 'transpose' %{ vau.transpose = true; };
  654. vault_priority = 'priority' ws1 number %{ vau.priority = toint(state.match); };
  655. vault_use_species_counts = 'use_monster_counts' %{ vau.use_species_counts = true; };
  656. vault_width = 'width' ws1 number %{ vau.w = toint(state.match); };
  657. vault_height = 'height' ws1 number %{ vau.h = toint(state.match); };
  658. vault_fixed = 'fixed' %{ vau.type = Vault::type_t::FIXED; };
  659. vault_semirandom = 'semirandom' %{ vau.type = Vault::type_t::SEMIRANDOM; };
  660. vault_random = 'random' %{ vau.type = Vault::type_t::RANDOM; };
  661. vault_one_data =
  662. (vault_count | vault_placement | vault_anchor | vault_brush | vault_line |
  663. vault_inherit | vault_transpose | vault_priority | vault_set_player |
  664. vault_use_species_counts | vault_fixed | vault_semirandom | vault_random |
  665. vault_cloud | vault_width | vault_height | vault_blob | vault_river |
  666. vault_room | vault_tunnel | '}'
  667. ${ fret; })
  668. ;
  669. one_vault := (ws vault_one_data ws ';')+
  670. ;
  671. vault_level = number %{ vau.level = toint(state.match); }
  672. ;
  673. vault_tag = tag %{ vau.tag = tag_t(state.match, tagmem); }
  674. ;
  675. vault =
  676. 'vault' %{ vau = Vault(); }
  677. ws1 vault_level ws1 vault_tag ws
  678. '{' ${fcall one_vault;}
  679. %{ vau.postprocess(); init_vault(vau); }
  680. ;
  681. ####
  682. celauto_s = 's' ws1 bitmask %{ cel.survive = bitmask_v; };
  683. celauto_b = 'b' ws1 bitmask %{ cel.born = bitmask_v; };
  684. celauto_a = 'a' ws1 number %{ cel.age = toint(state.match); } ;
  685. celauto_terrain = 'terrain' ws1 tag %{ cel.terrain = tag_t(state.match, tagmem); } ;
  686. celauto_is_walk = 'is_walk' %{ cel.is_walk = true; } ;
  687. celauto_make_walk = 'make_walk' %{ cel.make_walk = true; } ;
  688. celauto_karma_scale = 'karma_scale' ws1 real %{ cel.karma_scale = toreal(state.match); } ;
  689. celauto_karma_step = 'karma_step' ws1 real %{ cel.karma_step = toreal(state.match); } ;
  690. celauto_seed = 'seed' %{ cel.seed.push_back(std::make_pair(0,0)); }
  691. ws1 snumber %{ cel.seed.back().first = toint(state.match); }
  692. ws1 snumber %{ cel.seed.back().second = toint(state.match); }
  693. ;
  694. celauto_debug_name = 'debug_name' ws1 string %{ cel.debug_name = state.match; } ;
  695. celauto_one_data =
  696. (celauto_s | celauto_b | celauto_a | celauto_terrain |
  697. celauto_is_walk | celauto_make_walk | celauto_karma_scale |
  698. celauto_karma_step | celauto_seed | celauto_debug_name |
  699. '}' ${ fret; })
  700. ;
  701. one_celauto := (ws celauto_one_data ws ';')+
  702. ;
  703. celauto_tag = tag %{ cel.tag = tag_t(state.match, tagmem); }
  704. ;
  705. celauto =
  706. 'celauto' %{ cel = CelAuto(); }
  707. ws1 celauto_tag ws
  708. '{' ${fcall one_celauto;}
  709. %{ init_celauto(cel); }
  710. ;
  711. ####
  712. levelskin_deep_water = 'deep_water' ws1 skin %{ lev.deep_water.set(SKINS); };
  713. levelskin_shallow_water = 'shallow_water' ws1 skin %{ lev.shallow_water.set(SKINS); };
  714. levelskin_wall = 'wall' ws1 skin %{ lev.wall.set(SKINS); };
  715. levelskin_water_wall = 'water_wall' ws1 skin %{ lev.water_wall.set(SKINS); };
  716. levelskin_floor1 = 'floor1' ws1 skin %{ lev.floor1.set(SKINS); };
  717. levelskin_floor2 = 'floor2' ws1 skin %{ lev.floor2.set(SKINS); };
  718. levelskin_floor3 = 'floor3' ws1 skin %{ lev.floor3.set(SKINS); };
  719. levelskin_floor4 = 'floor4' ws1 skin %{ lev.floor4.set(SKINS); };
  720. levelskin_floor5 = 'floor5' ws1 skin %{ lev.floor5.set(SKINS); };
  721. levelskin_floor6 = 'floor6' ws1 skin %{ lev.floor6.set(SKINS); };
  722. levelskin_floor7 = 'floor7' ws1 skin %{ lev.floor7.set(SKINS); };
  723. levelskin_floor8 = 'floor8' ws1 skin %{ lev.floor8.set(SKINS); };
  724. levelskin_lightradius = 'lightradius' ws1 number %{ lev.lightradius = toint(state.match); };
  725. levelskin_lightradius_max = 'lightradius_max' ws1 number %{ lev.lightradius_max = toint(state.match); };
  726. levelskin_ailment = 'ailment' ws1 tag %{ lev.ailment = tag_t(state.match, tagmem); };
  727. levelskin_exclusive_monsters = 'exclusive_monsters' %{ lev.exclusive_monsters = true; };
  728. levelskin_exclusive_items = 'exclusive_items' %{ lev.exclusive_items = true; };
  729. levelskin_no_phase_level = 'no_phase_level' %{ lev.no_phase_level = true; };
  730. levelskin_species_level = 'species_level' ws1 number %{ lev.species_level = toint(state.match); };
  731. levelskin_designs_level = 'designs_level' ws1 number %{ lev.designs_level = toint(state.match); };
  732. levelskin_vaults_level = 'vaults_level' ws1 number %{ lev.vaults_level = toint(state.match); };
  733. levelskin_number_fixed_vaults = 'number_fixed_vaults' ws1 number
  734. %{ lev.number_fixed_vaults = toint(state.match); };
  735. levelskin_number_semirandom_vaults = 'number_semirandom_vaults' ws1 number
  736. %{ lev.number_semirandom_vaults = toint(state.match); };
  737. levelskin_number_random_vaults = 'number_random_vaults' ws1 number
  738. %{ lev.number_random_vaults = toint(state.match); };
  739. levelskin_number_monsters = 'number_monsters' ws1 mean_dev %{ lev.number_monsters = meandev; };
  740. levelskin_number_items = 'number_items' ws1 mean_dev %{ lev.number_items = meandev; };
  741. levelskin_number_features = 'number_features' ws1 mean_dev %{ lev.number_features = meandev; };
  742. levelskin_name = 'name' ws1 string %{ lev.name = state.match; };
  743. levelskin_treasure_level = 'treasure_level' ws1 real %{ lev.has_treasure = true; lev.treasure_level = toreal(state.match); };
  744. levelskin_flow_epsilon = 'flow_epsilon' ws1 real %{ lev.genparams.flow_epsilon = toreal(state.match); };
  745. levelskin_flow_n_freq = 'flow_n_freq' ws1 number %{ lev.genparams.flow_n_freq = toint(state.match); };
  746. levelskin_flow_volume = 'flow_volume' ws1 real %{ lev.genparams.flow_volume = toreal(state.match); };
  747. levelskin_flow_erosion = 'flow_erosion' ws1 real %{ lev.genparams.flow_erosion = toreal(state.match); };
  748. levelskin_flow_renorm_freq = 'flow_renorm_freq' ws1 number %{ lev.genparams.flow_renorm_freq = toint(state.match); };
  749. levelskin_flow_renorm_scale = 'flow_renorm_scale' ws1 real %{ lev.genparams.flow_renorm_scale = toreal(state.match); };
  750. levelskin_walk_threshold = 'walk_threshold' ws1 real %{ lev.genparams.walk_threshold = toreal(state.match); };
  751. levelskin_lowlands_threshold = 'lowlands_threshold' ws1 number %{ lev.genparams.lowlands_threshold = toint(state.match); };
  752. levelskin_water_quantile_mean = 'water_quantile_mean' ws1 real %{ lev.genparams.water_quantile_mean = toreal(state.match); };
  753. levelskin_water_quantile_dev = 'water_quantile_dev' ws1 real %{ lev.genparams.water_quantile_dev = toreal(state.match); };
  754. levelskin_flatten_walk_ng = 'flatten_walk_ng' ws1 bitmask %{ lev.genparams.flatten_walk_ng = bitmask_v; };
  755. levelskin_flatten_water_ng = 'flatten_water_ng' ws1 bitmask %{ lev.genparams.flatten_water_ng = bitmask_v; };
  756. levelskin_unflow_ng = 'unflow_ng' ws1 bitmask %{ lev.genparams.unflow_ng = bitmask_v; };
  757. levelskin_karma_mean = 'karma_mean' ws1 real %{ lev.genparams.karma_mean = toreal(state.match); };
  758. levelskin_karma_dev = 'karma_dev' ws1 real %{ lev.genparams.karma_dev = toreal(state.match); };
  759. levelskin_nflatten_walk = 'nflatten_walk' ws1 number %{ lev.genparams.nflatten_walk = toint(state.match); };
  760. levelskin_nflatten_water = 'nflatten_water' ws1 number %{ lev.genparams.nflatten_water = toint(state.match); };
  761. levelskin_nunflow = 'nunflow' ws1 number %{ lev.genparams.nunflow = toint(state.match); };
  762. levelskin_one_data =
  763. (levelskin_deep_water | levelskin_shallow_water | levelskin_wall |
  764. levelskin_water_wall | levelskin_floor1 | levelskin_floor2 |
  765. levelskin_floor3 | levelskin_floor4 | levelskin_floor5 |
  766. levelskin_floor6 | levelskin_floor7 | levelskin_floor8 |
  767. levelskin_lightradius | levelskin_lightradius_max | levelskin_ailment |
  768. levelskin_exclusive_monsters | levelskin_exclusive_items | levelskin_no_phase_level |
  769. levelskin_species_level | levelskin_designs_level | levelskin_vaults_level |
  770. levelskin_number_fixed_vaults | levelskin_number_semirandom_vaults | levelskin_number_random_vaults |
  771. levelskin_number_monsters |
  772. levelskin_number_items | levelskin_number_features | levelskin_name | levelskin_treasure_level |
  773. levelskin_flow_epsilon | levelskin_flow_n_freq | levelskin_flow_volume |
  774. levelskin_flow_erosion | levelskin_flow_renorm_freq | levelskin_flow_renorm_scale |
  775. levelskin_walk_threshold | levelskin_lowlands_threshold | levelskin_water_quantile_mean |
  776. levelskin_water_quantile_dev | levelskin_flatten_walk_ng | levelskin_flatten_water_ng |
  777. levelskin_unflow_ng | levelskin_karma_mean | levelskin_karma_dev |
  778. levelskin_nflatten_walk | levelskin_nflatten_water | levelskin_nunflow |
  779. '}'
  780. ${ fret; })
  781. ;
  782. one_levelskin := (ws levelskin_one_data ws ';')+
  783. ;
  784. levelskin_level = snumber %{ lev.level = toint(state.match); }
  785. ;
  786. levelskin =
  787. 'levelskin' %{ lev = Levelskin(); }
  788. ws1 levelskin_level ws
  789. '{' ${fcall one_levelskin;}
  790. %{ init_levelskin_(lev); }
  791. ;
  792. ####
  793. constant_max_permafeats = 'max_permafeats' ws1 number %{ __constants__().max_permafeats = toint(state.match); };
  794. constant_max_bones = 'max_bones' ws1 number %{ __constants__().max_bones = toint(state.match); };
  795. constant_starvation_damage = 'starvation_damage'
  796. ws1 real %{ __constants__().starvation_damage = toreal(state.match); };
  797. constant_grave = 'grave' ws1 tag %{ __constants__().grave = tag_t(state.match, tagmem); };
  798. constant_pit = 'pit' ws1 tag %{ __constants__().pit = tag_t(state.match, tagmem); };
  799. constant_bad_grave = 'bad_grave' ws1 tag %{ __constants__().bad_grave = tag_t(state.match, tagmem); };
  800. constant_ghost = 'ghost' ws1 tag %{ __constants__().ghost = tag_t(state.match, tagmem); };
  801. constant_money = 'money'
  802. (ws1 tag %{ __constants__().money.insert(tag_t(state.match, tagmem)); } )+ ;
  803. constant_unique_item = 'unique_item' ws1 tag %{ __constants__().unique_item = tag_t(state.match, tagmem); };
  804. constant_uniques_timeout = 'uniques_timeout' ws1 number %{ __constants__().uniques_timeout = toint(state.match); };
  805. constant_player_species = 'player_species' ws1 tag %{ __constants__().player_species = tag_t(state.match, tagmem); } ;
  806. constant_min_money_value = 'min_money_value'
  807. ws1 real %{ __constants__().min_money_value = toreal(state.match); };
  808. constant_max_celauto_cells = 'max_celauto_cells'
  809. ws1 number %{ __constants__().max_celauto_cells = toint(state.match); };
  810. constant_slot = 'slot' %{ __constants__().slots.push_back(ConstantsBank::slot_t()); }
  811. ws1 tag %{ __constants__().slots.back().slot = tag_t(state.match, tagmem); }
  812. ws1 '\'' any ${ __constants__().slots.back().letter = fc; } '\''
  813. ws1 string %{ __constants__().slots.back().label = state.match; }
  814. ws1 string %{ __constants__().slots.back().name = state.match; }
  815. ;
  816. constant_money_slot = 'money_slot' ws1 tag %{ __constants__().money_slot = tag_t(state.match, tagmem); };
  817. constant_shortcut_messages = 'shortcut' ws1 'messages'
  818. ws1 '\'' any ${ shortcut_key = fc; } '\''
  819. ws1 string %{ __constants__().shortcuts[shortcut_key].help_message = state.match; }
  820. ws1 string %{ __constants__().shortcuts[shortcut_key].fail_message = state.match; }
  821. ;
  822. constant_shortcut_action = 'shortcut' ws1 'action'
  823. ws1 '\'' any ${ shortcut_key = fc; } '\''
  824. ws1 tag ${ __constants__().shortcuts[shortcut_key].slot_keypress.
  825. push_back(std::make_pair(tag_t(state.match, tagmem), 0)); }
  826. ws1 '\'' any ${ __constants__().shortcuts[shortcut_key].slot_keypress.back().second = fc; } '\''
  827. ;
  828. constant_genus = 'genus' (
  829. ws1 tag %{ genus_tag = tag_t(state.match, tagmem); }
  830. ws1 string %{ __constants__().genus_names[genus_tag] = state.match; }
  831. )+
  832. ;
  833. constant_flavor = 'flavor' (
  834. ws1 tag %{ flavor_tag = tag_t(state.match, tagmem); }
  835. ws1 real %{ __constants__().flavor_moon_frequency[flavor_tag].height = toreal(state.match); }
  836. ws1 mean_dev %{ __constants__().flavor_moon_frequency[flavor_tag].curve = meandev; }
  837. )+
  838. ;
  839. constant_achievement_trigger_rate = 'achievement_trigger_rate'
  840. ws1 number %{ __constants__().achievement_trigger_rate = toint(state.match); } ;
  841. constant_treasure_chance = 'treasure_chance'
  842. ws1 mean_dev %{ __constants__().treasure_chance = meandev; }
  843. ;
  844. constant_max_ailments = 'max_ailments' ws1 number %{ __constants__().max_ailments = toint(state.match); };
  845. constant_monetary_supply_base = 'monetary_supply_base'
  846. ws1 real %{ __constants__().monetary_supply_base = toreal(state.match); }
  847. ;
  848. constant_player_level_cap = 'player_level_cap'
  849. ws1 number %{ __constants__().player_level_cap = toint(state.match); }
  850. ;
  851. constant_bonus_a_items = 'bonus_a_items'
  852. ws1 mean_dev %{ __constants__().bonus_a_items = meandev; }
  853. ;
  854. constant_bonus_b_items = 'bonus_b_items'
  855. ws1 mean_dev %{ __constants__().bonus_b_items = meandev; }
  856. ;
  857. constant_starsigns = 'starsigns'
  858. ws1 number %{ __constants__().starsigns.zero = toint(state.match); }
  859. ws1 number %{ __constants__().starsigns.nday = toint(state.match); }
  860. ws1 number %{ __constants__().starsigns.nsign = toint(state.match); }
  861. ( ws1 number %{ starsign_n = toint(state.match); }
  862. ws1 string %{ __constants__().starsigns.names[starsign_n] = state.match; } )+
  863. ;
  864. constant_ai_radius = 'ai_radius' ws1 number %{ __constants__().ai_radius = toint(state.match); };
  865. constant_hud_stats_order = 'hud_stats' (
  866. ws1 tag %{ __constants__().hud_stats_order.push_back(tag_t(state.match, tagmem)); }
  867. )+ ;
  868. constant_hud_counts_order = 'hud_counts' (
  869. ws1 tag %{ __constants__().hud_counts_order.push_back(tag_t(state.match, tagmem)); }
  870. )+ ;
  871. constant_luck_stat = 'luck_stat'
  872. ws1 tag %{ __constants__().luck.stat = tag_t(state.match, tagmem); }
  873. ws1 real %{ __constants__().luck.factor = toreal(state.match); }
  874. ws1 real %{ __constants__().luck.threshold = toreal(state.match); }
  875. ;
  876. constant_rest_count = 'rest_count' ws1 tag %{ __constants__().rest_count = tag_t(state.match, tagmem); };
  877. constant_digging_count = 'digging_count' ws1 tag %{ __constants__().digging_count = tag_t(state.match, tagmem); };
  878. one_constant = constant_max_permafeats | constant_max_bones |
  879. constant_starvation_damage |
  880. constant_grave | constant_money | constant_pit |
  881. constant_bad_grave | constant_ghost | constant_rest_count |
  882. constant_slot | constant_player_species |
  883. constant_shortcut_messages | constant_shortcut_action |
  884. constant_genus | constant_flavor | constant_unique_item | constant_uniques_timeout |
  885. constant_min_money_value | constant_max_celauto_cells |
  886. constant_achievement_trigger_rate |
  887. constant_treasure_chance | constant_digging_count |
  888. constant_monetary_supply_base | constant_money_slot | constant_player_level_cap |
  889. constant_bonus_a_items | constant_bonus_b_items | constant_max_ailments | constant_luck_stat |
  890. constant_starsigns | constant_ai_radius | constant_hud_stats_order | constant_hud_counts_order
  891. ;
  892. constant = 'constant' ws1 one_constant ws ';';
  893. ####
  894. ui_syms_circle = 'circle' ws1 skin %{ ui_syms->circle.set(SKINS); };
  895. ui_syms_fill = 'fill' ws1 skin %{ ui_syms->fill.set(SKINS); };
  896. ui_syms_line = 'line' ws1 skin %{ ui_syms->line.set(SKINS); };
  897. ui_syms_box_v = 'box_v' ws1 skin %{ ui_syms->box_v.set(SKINS); };
  898. ui_syms_box_h = 'box_h' ws1 skin %{ ui_syms->box_h.set(SKINS); };
  899. ui_syms_box_rd = 'box_rd' ws1 skin %{ ui_syms->box_rd.set(SKINS); };
  900. ui_syms_box_ru = 'box_ru' ws1 skin %{ ui_syms->box_ru.set(SKINS); };
  901. ui_syms_box_ld = 'box_ld' ws1 skin %{ ui_syms->box_ld.set(SKINS); };
  902. ui_syms_box_lu = 'box_lu' ws1 skin %{ ui_syms->box_lu.set(SKINS); };
  903. ui_syms_arrow_l = 'arrow_l' ws1 skin %{ ui_syms->arrow_l.set(SKINS); };
  904. ui_syms_arrow_r = 'arrow_r' ws1 skin %{ ui_syms->arrow_r.set(SKINS); };
  905. ui_syms_arrow_u = 'arrow_u' ws1 skin %{ ui_syms->arrow_u.set(SKINS); };
  906. ui_syms_arrow_d = 'arrow_d' ws1 skin %{ ui_syms->arrow_d.set(SKINS); };
  907. ui_syms_wspace = 'wspace' ws1 skin %{ ui_syms->wspace.set(SKINS); };
  908. ui_syms_one_sym = ui_syms_circle | ui_syms_fill | ui_syms_line | ui_syms_box_v | ui_syms_box_h |
  909. ui_syms_box_rd | ui_syms_box_ru | ui_syms_box_ld | ui_syms_box_lu |
  910. ui_syms_arrow_l | ui_syms_arrow_r | ui_syms_arrow_u | ui_syms_arrow_d |
  911. ui_syms_wspace;
  912. ui_syms = 'ui_syms' ws
  913. %{ __constants__().ui_symbols.push_back(ui_symbols_t());
  914. ui_syms = &(__constants__().ui_symbols.back()); }
  915. '{'
  916. ( ws ui_syms_one_sym ws ';')+
  917. ws '}'
  918. ;
  919. ####
  920. achievement_genus = 'genus' ws1 tag
  921. %{ __constants__().achievements[ach_tag].genus = tag_t(state.match, tagmem); } ;
  922. achievement_kills = 'kills' ws1 number
  923. %{ __constants__().achievements[ach_tag].kills = toint(state.match); } ;
  924. achievement_priority = 'priority' ws1 number
  925. %{ __constants__().achievements[ach_tag].priority = toint(state.match); } ;
  926. achievement_label = 'label' ws1 string
  927. %{ __constants__().achievements[ach_tag].label = state.match; } ;
  928. achievement_summon = 'summon' ws1 tag
  929. %{ __constants__().achievements[ach_tag].summon = tag_t(state.match, tagmem); } ;
  930. achievement_line =
  931. achievement_genus | achievement_kills | achievement_priority | achievement_label |
  932. achievement_summon
  933. ;
  934. achievement = 'achievement'
  935. ws1 tag %{ ach_tag = tag_t(state.match, tagmem); }
  936. ws '{'
  937. ( ws achievement_line ws ';')+
  938. ws '}'
  939. ;
  940. ####
  941. ailment_attack = 'attack' ws1 damage_val %{ ail.attacks.add(dmgval); } ;
  942. ailment_attack_level = 'attack_level' ws1 number %{ ail.level = toint(state.match); } ;
  943. ailment_name = 'name' ws1 string %{ ail.name = state.match; } ;
  944. ailment_triggers = 'triggers' ws1 number %{ ail.triggers = toint(state.match); } ;
  945. ailment_oneshot = 'oneshot' %{ ail.oneshot = true; } ;
  946. ailment_inc_stat = 'inc_stat'
  947. ws1 tag %{ tmp_tag = tag_t(state.match, tagmem); }
  948. ws1 real %{ ail.inc_stat[tmp_tag] += toreal(state.match); };
  949. ailment_line =
  950. ailment_attack | ailment_attack_level | ailment_name | ailment_triggers | ailment_oneshot |
  951. ailment_inc_stat ;
  952. ailment = 'ailment'
  953. ws1 tag %{ ail_tag = tag_t(state.match, tagmem); ail = ConstantsBank::ailment_t(); }
  954. ws '{'
  955. ( ws ailment_line ws ';')+
  956. ws '}' %{ __constants__().ailments[ail_tag] = ail; }
  957. ;
  958. ####
  959. damage_name = 'name' ws1 string %{ dam.name = state.match; } ;
  960. damage_inc_counts = 'inc_count' %{ dam.inc_counts.resize(dam.inc_counts.size() + 1); }
  961. ws1 tag %{ dam.inc_counts.back().first = tag_t(state.match, tagmem); }
  962. ws1 snumber %{ dam.inc_counts.back().second.scale = toint(state.match); }
  963. ws1 snumber %{ dam.inc_counts.back().second.offset = toint(state.match); }
  964. ;
  965. damage_dec_stat = 'dec_stat' ws1 tag %{ dam.dec_stats.push_back(tag_t(state.match, tagmem)); };
  966. damage_inc_stat = 'inc_stat' ws1 tag %{ dam.inc_stats.push_back(tag_t(state.match, tagmem)); };
  967. damage_transfer_stat = 'transfer_stat' ws1 tag %{ dam.transfer_stats.push_back(tag_t(state.match, tagmem)); };
  968. damage_threshold = 'threshold' ws1 real %{ dam.threshold = toreal(state.match); } ;
  969. damage_levelup_threshold = 'levelup_threshold' ws1 real %{ dam.levelup_threshold = toreal(state.match); };
  970. damage_visible_damage = 'visible_damage' %{ dam.visible_damage = true; };
  971. damage_karmic_scale = 'karmic_scale' %{ dam.karmic_scale.resize(dam.karmic_scale.size() + 1); }
  972. ws1 tag %{ dam.karmic_scale.back().first = tag_t(state.match, tagmem); }
  973. ws1 real %{ dam.karmic_scale.back().second = toreal(state.match); }
  974. ;
  975. damage_polymorph = 'polymorph' ws1 tag %{ dam.polymorph = tag_t(state.match, tagmem); } ;
  976. damage_player_poly = 'player_poly'
  977. ws1 snumber %{ dam.player_poly.scale = toint(state.match); }
  978. ws1 snumber %{ dam.player_poly.offset = toint(state.match); } ;
  979. damage_infect = 'infect'
  980. ws1 tag %{ dam.infect.first = tag_t(state.match, tagmem); }
  981. ws1 tag %{ dam.infect.second = tag_t(state.match, tagmem); } ;
  982. damage_ally = 'ally' ws1 tag %{ dam.ally = tag_t(state.match, tagmem); };
  983. damage_eyeless = 'eyeless' ws (('+' %{ dam.flags.eyeless.v = 1; }) | ('-' %{ dam.flags.eyeless.v = 0; }));
  984. damage_undead = 'undead' ws (('+' %{ dam.flags.undead.v = 1; }) | ('-' %{ dam.flags.undead.v = 0; }));
  985. damage_animal = 'animal' ws (('+' %{ dam.flags.animal.v = 1; }) | ('-' %{ dam.flags.animal.v = 0; }));
  986. damage_plant = 'plant' ws (('+' %{ dam.flags.plant.v = 1; }) | ('-' %{ dam.flags.plant.v = 0; }));
  987. damage_robot = 'robot' ws (('+' %{ dam.flags.robot.v = 1; }) | ('-' %{ dam.flags.robot.v = 0; }));
  988. damage_cosmic = 'cosmic' ws (('+' %{ dam.flags.cosmic.v = 1; }) | ('-' %{ dam.flags.cosmic.v = 0; }));
  989. damage_magic = 'magic' ws (('+' %{ dam.flags.magic.v = 1; }) | ('-' %{ dam.flags.magic.v = 0; }));
  990. damage_player = 'player' ws (('+' %{ dam.flags.player.v = 1; }) | ('-' %{ dam.flags.player.v = 0; }));
  991. damage_melee_msg =
  992. 'melee_msg' ws1 string %{ dam.melee_msg.str = state.match; }
  993. (ws '!' %{ dam.melee_msg.important = true; })?
  994. ;
  995. damage_env_msg =
  996. 'env_msg' ws1 string %{ dam.env_msg.str = state.match; }
  997. (ws '!' %{ dam.env_msg.important = true; })?
  998. ;
  999. damage_one_data =
  1000. (damage_name | damage_inc_counts | damage_dec_stat | damage_inc_stat | damage_transfer_stat |
  1001. damage_threshold | damage_levelup_threshold | damage_visible_damage | damage_karmic_scale |
  1002. damage_polymorph | damage_player_poly | damage_infect | damage_ally |
  1003. damage_eyeless | damage_undead | damage_animal | damage_plant | damage_player |
  1004. damage_robot | damage_magic | damage_melee_msg | damage_env_msg |
  1005. damage_cosmic |
  1006. '}' ${ fret; })
  1007. ;
  1008. one_damage := (ws damage_one_data ws ';')+
  1009. ;
  1010. damage_tag = tag %{ dam.tag = tag_t(state.match, tagmem); }
  1011. ;
  1012. damage =
  1013. 'damage' %{ dam = Damage(); }
  1014. ws1 damage_tag ws
  1015. '{' ${fcall one_damage;}
  1016. %{ init_damage(dam); }
  1017. ;
  1018. ####
  1019. stat_label = 'label'
  1020. ws1 string %{ sta.label.label = state.match; }
  1021. ws1 skin %{ sta.label.lskin.set(SKINS); } ;
  1022. stat_mark = 'mark'
  1023. ws1 skin %{ sta.label.pskin.set(SKINS); }
  1024. (ws1 skin %{ sta.label.nskin.set(SKINS); sta.progressbar = false; })?
  1025. (ws1 'reversed' %{ sta.reversed = true; })?;
  1026. stat_limits = 'limits'
  1027. ws1 real %{ sta.min = toreal(state.match); }
  1028. ws1 real %{ sta.max = toreal(state.match); } ;
  1029. stat_critical = 'critical' %{ sta.critical = true; } ;
  1030. stat_hidden = 'hidden' %{ sta.hidden = true; } ;
  1031. stat_chain_pos = 'chain_pos' ws1 tag %{ sta.chain_pos = tag_t(state.match, tagmem); } ;
  1032. stat_chain_neg = 'chain_neg' ws1 tag %{ sta.chain_neg = tag_t(state.match, tagmem); } ;
  1033. stat_monster_hit_msg = 'monster_hit_msg' ws1 string %{ sta.monster_hit_msg = state.match; };
  1034. stat_status_min_msg = 'status_min_msg' ws1 string %{ sta.status_min_msg = state.match; };
  1035. stat_ailment = 'ailment' ws1 tag %{ sta.ailment = tag_t(state.match, tagmem); } ;
  1036. stat_one_data =
  1037. (stat_label | stat_mark | stat_limits | stat_critical | stat_hidden | stat_status_min_msg |
  1038. stat_chain_pos | stat_chain_neg | stat_monster_hit_msg | stat_ailment |
  1039. '}' ${ fret; })
  1040. ;
  1041. one_stat := (ws stat_one_data ws ';')+
  1042. ;
  1043. stat_tag = tag %{ sta.tag = tag_t(state.match, tagmem); }
  1044. ;
  1045. stat =
  1046. 'stat' %{ sta = Stat(); }
  1047. ws1 stat_tag ws
  1048. '{' ${fcall one_stat;}
  1049. %{ init_stat(sta); }
  1050. ;
  1051. ####
  1052. count_label = 'label'
  1053. ws1 string %{ cou.label.label = state.match; }
  1054. ws1 skin %{ cou.label.lskin.set(SKINS); } ;
  1055. count_mark = 'mark'
  1056. ws1 skin %{ cou.label.pskin.set(SKINS); }
  1057. ws1 skin %{ cou.label.nskin.set(SKINS); } ;
  1058. count_max = 'max' ws1 number %{ cou.cmax = toint(state.match); } ;
  1059. count_hidden = 'hidden' %{ cou.hidden = true; } ;
  1060. count_monster_hit_msg = 'monster_hit_msg' ws1 string %{ cou.monster_hit_msg = state.match; };
  1061. count_status_msg = 'status_msg' ws1 string %{ cou.status_msg = state.match; };
  1062. count_blind = 'blind' %{ cou.blind = true; };
  1063. count_stun = 'stun' %{ cou.stun = true; };
  1064. count_fear = 'fear' %{ cou.fear = true; };
  1065. count_sleep = 'sleep' %{ cou.sleep = true; };
  1066. count_cancellable = 'cancellable' %{ cou.cancellable = true; };
  1067. count_ailment = 'ailment' ws1 tag %{ cou.ailment = tag_t(state.match, tagmem); } ;
  1068. count_one_data =
  1069. (count_label | count_mark | count_max | count_hidden |
  1070. count_monster_hit_msg | count_status_msg | count_ailment |
  1071. count_blind | count_stun | count_fear | count_sleep | count_cancellable |
  1072. '}' ${ fret; })
  1073. ;
  1074. one_count := (ws count_one_data ws ';')+
  1075. ;
  1076. count_tag = tag %{ cou.tag = tag_t(state.match, tagmem); }
  1077. ;
  1078. count =
  1079. 'count' %{ cou = Count(); }
  1080. ws1 count_tag ws
  1081. '{' ${fcall one_count;}
  1082. %{ init_count(cou); }
  1083. ;
  1084. ###
  1085. pc_include = 'include' ws1 string %{ parse_config(state.match, tagmem); } ws ';';
  1086. pc_string = 'string'
  1087. ws1 string %{ hash = fnv64a_hash(state.match.c_str(), state.match.size()); }
  1088. ws1 string %{ init_strings_copy(hash, state.match); }
  1089. ws ';';
  1090. ###
  1091. entry = species | design | terrain | vault | celauto | levelskin | constant |
  1092. achievement | ailment | ui_syms | damage | stat | count | pc_include |
  1093. pc_string;
  1094. main := (ws entry)+ ws ;
  1095. }%%
  1096. /*
  1097. */
  1098. %% write data;
  1099. %% write init;
  1100. bool done = false;
  1101. while (!done) {
  1102. int space = sizeof(buf) ;
  1103. state.p = buf;
  1104. int len = ::fread(state.p, 1, space, fn);
  1105. state.pe = state.p + len;
  1106. state.eof = 0;
  1107. if (len == 0) {
  1108. state.eof = state.pe;
  1109. done = true;
  1110. }
  1111. %% write exec;
  1112. // Avoid spurious gcc warnings.
  1113. (void)ConfigParser_first_final;
  1114. (void)ConfigParser_en_strchar_escape;
  1115. (void)ConfigParser_en_one_species;
  1116. (void)ConfigParser_en_one_design;
  1117. (void)ConfigParser_en_one_terrain;
  1118. (void)ConfigParser_en_one_vault;
  1119. (void)ConfigParser_en_one_celauto;
  1120. (void)ConfigParser_en_one_levelskin;
  1121. (void)ConfigParser_en_one_damage;
  1122. (void)ConfigParser_en_one_stat;
  1123. (void)ConfigParser_en_one_count;
  1124. (void)ConfigParser_en_main;
  1125. if (state.cs == ConfigParser_error) {
  1126. throw std::runtime_error("Parse error. Unconsumed input: " + std::string(state.p, state.pe));
  1127. }
  1128. }
  1129. }
  1130. }
  1131. #undef SKINS
  1132. #endif