From d4065da159cb407f1680de9f03596cd397ded525 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Mon, 28 May 2007 11:28:11 +0000 Subject: Added new orc entries and vaults (Lemuel). Added support to the map designer for specifying the monster-type for zombies, skeletons, simulacra and spectral things. Also allow specifying the number of heads for hydras ("12-headed hydra"). Fixed lexer rule bug (IDENTIFIER). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1490 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/Kills.cc | 18 ------- crawl-ref/source/dat/ebranch.des | 111 ++++++++++++++++++++++++++++++++++++++ crawl-ref/source/dat/vaults.des | 106 ++++++++++++++++++++++++++++++++++++ crawl-ref/source/dungeon.cc | 17 +++--- crawl-ref/source/libutil.cc | 19 +++++++ crawl-ref/source/libutil.h | 7 +++ crawl-ref/source/mapdef.cc | 100 ++++++++++++++++++++++++++++------ crawl-ref/source/mapdef.h | 15 ++++-- crawl-ref/source/util/levcomp.lpp | 2 +- 9 files changed, 347 insertions(+), 48 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/Kills.cc b/crawl-ref/source/Kills.cc index 272d91be61..b8da6d4b82 100644 --- a/crawl-ref/source/Kills.cc +++ b/crawl-ref/source/Kills.cc @@ -329,24 +329,6 @@ kill_def::kill_def(const struct monsters *mon) : kills(0), exp(0) add_kill(mon, get_packed_place()); } -static bool ends_with(const std::string &s, const char *suffix) -{ - std::string other = suffix; - if (s.length() < other.length()) return false; - return (s.substr(s.length() - other.length()) == other); -} - -static bool ends_with(const std::string &s, const char *suffixes[]) -{ - if (!suffixes) return false; - for ( ; *suffixes; suffixes++) - { - if (ends_with(s, *suffixes)) - return true; - } - return false; -} - std::string apostrophise(const std::string &name) { if (name.empty()) diff --git a/crawl-ref/source/dat/ebranch.des b/crawl-ref/source/dat/ebranch.des index a6444ed2f1..e3e069278e 100644 --- a/crawl-ref/source/dat/ebranch.des +++ b/crawl-ref/source/dat/ebranch.des @@ -515,6 +515,117 @@ MAP .............................. ENDMAP +######################### +# Orcs are a clue, episode I +# +NAME: hiddenorc1_lemuel +TAGS: orc_entry +ORIENT: float +MONS: orc w:40/orc wizard w:2/orc priest w:2, orc warrior +SUBST: ? = .x +SUBST: ! : .$ +MAP +x??@....@....@??x +xx??.........??xx +xxx??1111111??xxx +xxxx??11111??xxxx +xxxxx??111??xxxxx +xxxxxx??1??xxxxxx +xxxxxxx?2?xxxxxxx +xxxxxxxv=vxxxxxxx +xxxxxxx!!!xxxxxxx +xxxxxxx!O!xxxxxxx +xxxxxxx!!!xxxxxxx +xxxxxxxxxxxxxxxxx +ENDMAP + +######################### +# Orcs are a clue, episode II +# +NAME: hiddenorc2_lemuel +TAGS: orc_entry +ORIENT: float +MONS: orc w:20/orc wizard w:2/orc priest w:2/orc warrior w:1 +SUBST: a : x. +SUBST: b : x. +SUBST: c : x. +SUBST: d : x. +SUBST: ? = @ x:20 + = +SUBST: ! : .$ +MAP +xx?xxxxxxx?xx +x111xxxxx111x +?111aaaaa111? +x111xxxxx111x +xxbx=xxx=xcxx +xxbxx!!!xxcxx +xxbxx!O!xxcxx +xxbxx!!!xxcxx +xxbx=xxx=xcxx +x111xxxxx111x +?111ddddd111x +x111xxxxx111? +xx?xxxxxxx@xx +ENDMAP + +####################### +# Haunted orc entrance +# +NAME: zombieorc1_lemuel +TAGS: orc_entry +ORIENT: float +MONS: orc zombie/orc skeleton w:2/goblin zombie w:2/hobgoblin zombie w:2/goblin skeleton w:1/hobgoblin skeleton w:1 +MONS: ogre zombie/troll zombie w:3/hill giant zombie w:1 +MONS: hungry ghost/phantom/wraith, orc sorcerer/orc priest/nothing +SUBST: ? = x . $:1 +MAP +xxx.xxxxxxxxxxxxxxxxxxx +xxx?.x?x?xx?xxx??xx?xxx +xx..xxx..1.xxx....11xxx +xx.x??x.x1xx?x.21xx?..x +xx...x..xxx.2..1.x.x??. +xx?x.....?x.x..x.x1?.xx +xx..??12x?x31.1?x.x??xx +xxx..x..x??O3x..x.xx.xx +x?..?x....34x?.x.??x.xx +xx.x??.x.x..?x..xx.x?xx +x?xx?xx.x??...x.1x.1??x +xx..xxx...x.x.x.1?1.xxx +x?.2....xx2.x...xx.x??x +xxx??xx..xx.xx.x?..xxxx +xx..1.x.x.1...x2.x1..xx +..x??x.xxx..xxxx??.??xx +xx?.??.11.x?xxx..x..xxx +x??xxxx???xx?xxx??x.?xx +xxxxxxxxxxxxxxxxxxxx.xx +ENDMAP + +####################### +# Haunted orc entrance +# +NAME: zombieorc2_lemuel +TAGS: orc_entry +ORIENT: float +MONS: orc zombie/orc skeleton w:2/goblin zombie w:2/hobgoblin zombie w:2/goblin skeleton w:1/hobgoblin skeleton w:1 +MONS: ogre zombie/troll zombie w:3/hill giant zombie w:1 +MONS: hungry ghost/phantom/wraith, orc sorcerer/orc priest +SUBST: 4 = 34 +SUBST: ? = x . $:1 +MAP +MAP +xxxxx..@..xxxxx +x21....I....12x +x11...111...11x +x.............x +..1...343...1.. +@I1...2O2...1I@ +..1...212...1.. +x.............x +x11...111...11x +x21....I....12x +xxxxx..@..xxxxx +ENDMAP + ############################################################################## # Vaults entries ############################################################################## diff --git a/crawl-ref/source/dat/vaults.des b/crawl-ref/source/dat/vaults.des index 56699ad926..39775f66ce 100644 --- a/crawl-ref/source/dat/vaults.des +++ b/crawl-ref/source/dat/vaults.des @@ -423,6 +423,69 @@ xxxxx...........................xxwwwx xxxxx...........................xxxxxx ENDMAP +################################# +# An Ice Statue vault +NAME: ice1_lemuel +MONS: ice statue +TAGS: no_pool_fixup +ORIENT: float +SUBST: * : *$ +SUBST: * = |:5 * . +SUBST: T = TU +SHUFFLE: xb/cc +MAP +xxxxxxxxx +xbbbbbbbx +xb*****bx +xb*****bx +xb.....bx +xb.....bx +xb.....bx +xb.....bx +xbwwwwwbx +xbww1wwbx +xbwwwwwbx +xb.....bx +xb.....bx +xb.....bx +xb.....bx +xb.....bx +xbT.@.Tbx +ENDMAP + +################################# +#Another Ice Statue vault +NAME: ice2_lemuel +DEPTH: D:12-27, Lair, Swamp, Coc +TAGS: no_pool_fixup no_mons_gen +ORIENT: float +SUBST: T = TU +SUBST: W = w:20 W .:5 +MONS: ice statue +MONS: ice devil w:5/blue devil w:5/ice dragon/freezing wraith/nothing w:30 +MONS: white imp/ice beast w:30/polar bear/nothing w:50 +MAP +T..................T +..WWW..........WWW.. +.WWWWW........WWWWW. +WWWWWWwww..wwwWWWWWW +WWW3WwwwwwwwwwwW3WWW +WW333wwwwwwwwww333WW +.WW3WwwwwwwwwwwW3WW. +.WWWWwwwwwwwwwwWWWW. +..WWWwww||||wwwWWW.. +...WWwww|12|wwwwW... +..WWWwww||||wwwWWW.. +.WWWWwwwwwwwwwwWWWW. +.WW3WwwwwwwwwwwW3WW. +WW333wwwwwwwwww333WW +WWW3WwwwwwwwwwwW3WWW +WWWWWWwww..wwwWWWWWW +.WWWWW........WWWWW. +..WWW..........WWW.. +T..................T +ENDMAP + ############################################################################# # Oklob assault @@ -2324,3 +2387,46 @@ MAP .xxxx+xxxx. ........... ENDMAP + +############################# +# Pond minivault +NAME: pond +DEPTH: D:8-27, Lair +MONS: plant w:30/fungus +MONS: giant frog w:30/giant brown frog/snake/rat/green rat/swamp drake w:2 +MONS: giant mosquito +SUBST: ! : w. +SUBST: 2 : 23 +SUBST: 2 = 2. +SUBST: 3 = 3. +SUBST: . = . 1:1 +KFEAT: ? = * +KMONS: ? = plant +TAGS: no_monster_gen +MAP +..wwwww... +.wwwwwwww2 +.wwwwwwwww +.2wwwwwwww +..ww222ww. +.wwww222w. +wwww!!22ww +www!!!?ww. +.ww!!!www. +.2w!!!ww2. +....!!w... +ENDMAP + +############################## +# Secret library minivault +NAME: library +DEPTH: 1-27 +ITEM: any book w:20/any scroll/nothing +MAP +...... +.x=xx. +.xddx. +.xddx. +.xxxx. +...... +ENDMAP diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index c5538fcb7a..e3dc982dfd 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -3183,20 +3183,17 @@ static void dngn_place_item_explicit(int index, int x, int y, static bool dngn_place_monster( const vault_placement &place, - const mons_spec &monster_type_thing, + const mons_spec &mspec, int monster_level, int vx, int vy) { - if (monster_type_thing.mid != -1) + if (mspec.mid != -1) { - const int mid = monster_type_thing.mid; + const int mid = mspec.mid; const bool generate_awake = - monster_type_thing.generate_awake - || place.map.has_tag("generate_awake"); + mspec.generate_awake || place.map.has_tag("generate_awake"); - int not_used; - - const int mlev = monster_type_thing.mlevel; + const int mlev = mspec.mlevel; if (mlev) { if (mlev > 0) @@ -3217,9 +3214,11 @@ static bool dngn_place_monster( grd[vx][vy] = habitat; } + int not_used; return (place_monster( not_used, mid, monster_level, generate_awake? BEH_WANDER : BEH_SLEEP, - MHITNOT, true, vx, vy, false )); + MHITNOT, true, vx, vy, false, + PROX_ANYWHERE, mspec.monnum)); } return (false); } diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc index a2fa623530..6bf33921ba 100644 --- a/crawl-ref/source/libutil.cc +++ b/crawl-ref/source/libutil.cc @@ -193,6 +193,25 @@ void lowercase(std::string &s) s[i] = tolower(s[i]); } +bool ends_with(const std::string &s, const std::string &suffix) +{ + if (s.length() < suffix.length()) + return false; + return (s.substr(s.length() - suffix.length()) == suffix); +} + +int ends_with(const std::string &s, const char *suffixes[]) +{ + if (!suffixes) + return (0); + for (int i = 0; suffixes[i]; ++i) + { + if (ends_with(s, suffixes[i])) + return (1 + i); + } + return (0); +} + std::string replace_all(std::string s, const std::string &find, const std::string &repl) diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h index 3cd5c6c5c9..a36d632c81 100644 --- a/crawl-ref/source/libutil.h +++ b/crawl-ref/source/libutil.h @@ -29,6 +29,13 @@ int unmangle_direction_keys(int keyin, int keymap = 0, void lowercase(std::string &s); void uppercase(std::string &s); +bool ends_with(const std::string &s, const std::string &suffix); + +/** + * Returns 1 + the index of the first suffix that matches the given string, + * 0 if no suffixes match. + */ +int ends_with(const std::string &s, const char *suffixes[]); std::string strip_filename_unsafe_chars(const std::string &s); diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 67a4257f47..13d4b68532 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -1042,37 +1042,38 @@ mons_list::mons_spec_slot mons_list::parse_mons_spec(std::string spec) for (int i = 0, ssize = specs.size(); i < ssize; ++i) { std::string s = specs[i]; - int weight = find_weight(s); - int mlevel = 0; - if (weight == TAG_UNFOUND || weight <= 0) - weight = 10; + mons_spec mspec; - bool fixmons = strip_tag(s, "fix_mons"); - const bool generate_awake = strip_tag(s, "generate_awake"); + mspec.genweight = find_weight(s); + if (mspec.genweight == TAG_UNFOUND || mspec.genweight <= 0) + mspec.genweight = 10; - trim_string(s); + mspec.fix_mons = strip_tag(s, "fix_mons"); + mspec.generate_awake = strip_tag(s, "generate_awake"); - int mid = RANDOM_MONSTER; + trim_string(s); if (s == "8") - mlevel = -8; + mspec.mlevel = -8; else if (s == "9") - mlevel = -9; - else if (check_mimic(s, &mid, &fixmons)) + mspec.mlevel = -9; + else if (check_mimic(s, &mspec.mid, &mspec.fix_mons)) ; else if (s != "0") { - mid = mons_by_name(s); + const mons_spec nspec = mons_by_name(s); - if (mid == MONS_PROGRAM_BUG) + if (mspec.mid == MONS_PROGRAM_BUG) { error = make_stringf("unrecognised monster \"%s\"", s.c_str()); return (slot); } + + mspec.mid = nspec.mid; + mspec.monnum = nspec.monnum; } - slot.mlist.push_back( - mons_spec(mid, weight, mlevel, fixmons, generate_awake) ); + slot.mlist.push_back(mspec); } return (slot); @@ -1094,7 +1095,66 @@ std::string mons_list::add_mons(const std::string &s, bool fix) return (error); } -int mons_list::mons_by_name(std::string name) const +void mons_list::get_zombie_type(std::string s, mons_spec &spec) const +{ + static const char *zombie_types[] = + { + " zombie", " skeleton", " simulacrum", NULL + }; + + // This order must match zombie_types, indexed from one. + static const monster_type zombie_montypes[][2] = + { + { MONS_PROGRAM_BUG, MONS_PROGRAM_BUG }, + { MONS_ZOMBIE_SMALL, MONS_ZOMBIE_LARGE }, + { MONS_SKELETON_SMALL, MONS_SKELETON_LARGE }, + { MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE } + }; + + const int mod = ends_with(s, zombie_types); + if (!mod) + { + const std::string &spectre = "spectral "; + if (s.find(spectre) == 0) + { + s = s.substr(spectre.length()); + spec.mid = MONS_SPECTRAL_THING; + spec.monnum = get_monster_by_name(s, true); + if (!mons_zombie_size(spec.monnum)) + spec.mid = MONS_PROGRAM_BUG; + return; + } + spec.mid = MONS_PROGRAM_BUG; + return; + } + + s = s.substr(0, s.length() - strlen(zombie_types[mod - 1])); + trim_string(s); + + spec.monnum = get_monster_by_name(s, true); + + const int zombie_size = mons_zombie_size(spec.monnum); + if (!zombie_size) + { + spec.mid = MONS_PROGRAM_BUG; + return; + } + + spec.mid = zombie_montypes[mod][zombie_size - 1]; +} + +mons_spec mons_list::get_hydra_spec(const std::string &name) const +{ + int nheads = atoi(name.c_str()); + if (nheads < 1) + nheads = 250; // Choose randomly, doesn't mean a 250-headed hydra. + else if (nheads > 19) + nheads = 19; + + return mons_spec(MONS_HYDRA, nheads); +} + +mons_spec mons_list::mons_by_name(std::string name) const { lowercase(name); @@ -1149,6 +1209,14 @@ int mons_list::mons_by_name(std::string name) const if (name == "large abomination") return (MONS_ABOMINATION_LARGE); + if (ends_with(name, "-headed hydra")) + return get_hydra_spec(name); + + mons_spec spec; + get_zombie_type(name, spec); + if (spec.mid != MONS_PROGRAM_BUG) + return (spec); + return (get_monster_by_name(name, true)); } diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index 1f6cc05fa4..6b951237a7 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -176,14 +176,17 @@ private: struct mons_spec { - int mid; + int mid; + int monnum; // The zombified monster for zombies, or head + // count for hydras. int genweight, mlevel; bool fix_mons; bool generate_awake; - mons_spec(int id = RANDOM_MONSTER, int gw = 10, int ml = 0, + mons_spec(int id = RANDOM_MONSTER, int num = 250, + int gw = 10, int ml = 0, bool _fixmons = false, bool awaken = false) - : mid(id), genweight(gw), mlevel(ml), fix_mons(_fixmons), + : mid(id), monnum(num), genweight(gw), mlevel(ml), fix_mons(_fixmons), generate_awake(awaken) { } @@ -223,7 +226,11 @@ private: }; private: - int mons_by_name(std::string name) const; + mons_spec mons_by_name(std::string name) const; + void get_zombie_type(std::string s, mons_spec &spec) const; + mons_spec get_hydra_spec(const std::string &name) const; + mons_spec get_zombified_monster(const std::string &name, + monster_type zomb) const; mons_spec_slot parse_mons_spec(std::string spec); mons_spec pick_monster(mons_spec_slot &slot); int fix_demon(int id) const; diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp index 6db707ddcb..a97e58c6da 100644 --- a/crawl-ref/source/util/levcomp.lpp +++ b/crawl-ref/source/util/levcomp.lpp @@ -193,7 +193,7 @@ float return FLOAT; \* return STAR; ! return NOT; -[a-zA-Z_][a-zA-Z_0-9]+ { +[a-zA-Z_][a-zA-Z_0-9]* { settext(); return IDENTIFIER; } -- cgit v1.2.3-54-g00ecf