NetHackWiki:Skill table generator
Jump to navigation
Jump to search
Here's the program I used to generate Template:Weapon skill table, Template:Combat skill table, and Template:Spell skill table. u_init_snippet.inc
should be the struct def_skill
definitions in u_init.c, from Skill_A[]
to Skill_W[]
. -- Killian 04:36, 4 November 2006 (UTC)
#include <string> #include <iostream> #include <cctype> using std::string; using std::cout; using std::endl; using std::toupper; typedef int Skill; const Skill P_DAGGER = 1; const Skill P_KNIFE = 2; const Skill P_AXE = 3; const Skill P_PICK_AXE = 4; const Skill P_SHORT_SWORD = 5; const Skill P_BROAD_SWORD = 6; const Skill P_LONG_SWORD = 7; const Skill P_TWO_HANDED_SWORD = 8; const Skill P_SCIMITAR = 9; const Skill P_SABER = 10; const Skill P_CLUB = 11; const Skill P_MACE = 12; const Skill P_MORNING_STAR = 13; const Skill P_FLAIL = 14; const Skill P_HAMMER = 15; const Skill P_QUARTERSTAFF = 16; const Skill P_POLEARMS = 17; const Skill P_SPEAR = 18; const Skill P_JAVELIN = 19; const Skill P_TRIDENT = 20; const Skill P_LANCE = 21; const Skill P_BOW = 22; const Skill P_SLING = 23; const Skill P_CROSSBOW = 24; const Skill P_DART = 25; const Skill P_SHURIKEN = 26; const Skill P_BOOMERANG = 27; const Skill P_WHIP = 28; const Skill P_UNICORN_HORN = 29; const Skill P_FIRST_WEAPON = P_DAGGER; const Skill P_LAST_WEAPON = P_UNICORN_HORN; const Skill P_ATTACK_SPELL = 30; const Skill P_HEALING_SPELL = 31; const Skill P_DIVINATION_SPELL = 32; const Skill P_ENCHANTMENT_SPELL = 33; const Skill P_CLERIC_SPELL = 34; const Skill P_ESCAPE_SPELL = 35; const Skill P_MATTER_SPELL = 36; const Skill P_FIRST_SPELL = P_ATTACK_SPELL; const Skill P_LAST_SPELL = P_MATTER_SPELL; const Skill P_BARE_HANDED_COMBAT = 37; const Skill P_MARTIAL_ARTS = 38; const Skill P_TWO_WEAPON_COMBAT = 39; const Skill P_RIDING = 40; const Skill P_FIRST_COMBAT = P_BARE_HANDED_COMBAT; const Skill P_LAST_COMBAT = P_RIDING; const Skill P_FIRST = P_DAGGER; const Skill P_LAST = P_RIDING; const Skill P_NONE = 0; typedef int Level; const Level P_RESTRICTED = 0; const Level P_BASIC = 1; const Level P_SKILLED = 2; const Level P_EXPERT = 3; const Level P_MASTER = 4; const Level P_GRAND_MASTER = 5; const char * skill_raw_name(Skill s) { switch (s) { case P_DAGGER: return "dagger"; case P_KNIFE: return "knife"; case P_AXE: return "axe"; case P_PICK_AXE: return "pick-axe"; case P_SHORT_SWORD: return "short sword"; case P_BROAD_SWORD: return "broad sword"; case P_LONG_SWORD: return "long sword"; case P_TWO_HANDED_SWORD: return "two-handed sword"; case P_SCIMITAR: return "scimitar"; case P_SABER: return "saber"; case P_CLUB: return "club"; case P_MACE: return "mace"; case P_MORNING_STAR: return "morning star"; case P_FLAIL: return "flail"; case P_HAMMER: return "hammer"; case P_QUARTERSTAFF: return "quarterstaff"; case P_POLEARMS: return "polearms"; case P_SPEAR: return "spear"; case P_JAVELIN: return "javelin"; case P_TRIDENT: return "trident"; case P_LANCE: return "lance"; case P_BOW: return "bow"; case P_SLING: return "sling"; case P_CROSSBOW: return "crossbow"; case P_DART: return "dart"; case P_SHURIKEN: return "shuriken"; case P_BOOMERANG: return "boomerang"; case P_WHIP: return "whip"; case P_UNICORN_HORN: return "unicorn horn"; case P_ATTACK_SPELL: return "attack"; case P_HEALING_SPELL: return "healing"; case P_DIVINATION_SPELL: return "divination"; case P_ENCHANTMENT_SPELL: return "enchantment"; case P_CLERIC_SPELL: return "clerical"; case P_ESCAPE_SPELL: return "escape"; case P_MATTER_SPELL: return "matter"; case P_BARE_HANDED_COMBAT: return "bare hands"; case P_MARTIAL_ARTS: return "martial arts"; case P_TWO_WEAPON_COMBAT: return "two weapon combat"; case P_RIDING: return "riding"; default: return "<STRANGE SKILL>"; } } const string init_cap(const string &c) { string s(c); string::iterator i = s.begin(); if (i) { *i = toupper(*i); } return s; } const string skill_full_name(const Skill &s) { if (P_FIRST_WEAPON <= s && s <= P_LAST_WEAPON) { return skill_raw_name(s) + string(" skill"); } if (P_FIRST_SPELL <= s && s <= P_LAST_SPELL) { return skill_raw_name(s) + string(" spells"); } return string(skill_raw_name(s)); } const char * level_char(const Level &l) { switch (l) { case P_RESTRICTED: return "-"; case P_BASIC: return "b"; case P_SKILLED: return "S"; case P_EXPERT: return "E"; case P_MASTER: return "M"; case P_GRAND_MASTER: return "GM"; default: return "???"; } } const char * level_full(const Level &l) { switch (l) { case P_RESTRICTED: return "(restricted)"; case P_BASIC: return "Basic"; case P_SKILLED: return "Skilled"; case P_EXPERT: return "Expert"; case P_MASTER: return "Master"; case P_GRAND_MASTER: return "Grand Master"; default: return "???"; } } struct def_skill { Skill skill; Level level; }; struct Role { const char *long_name; const char *short_name; const def_skill *skills; }; #define STEED #define TOURIST #include "u_init_snippet.inc" const int NUM_ROLES = 13; const Role ROLES[NUM_ROLES] = { { "Archeologist", "Arc", Skill_A }, { "Barbarian", "Bar", Skill_B }, { "Caveman", "Cav", Skill_C }, { "Healer", "Hea", Skill_H }, { "Knight", "Kni", Skill_K }, { "Monk", "Mon", Skill_Mon }, { "Priest", "Pri", Skill_P }, { "Rogue", "Rog", Skill_R }, { "Ranger", "Ran", Skill_Ran }, { "Samurai", "Sam", Skill_S }, { "Tourist", "Tou", Skill_T }, { "Valkyrie", "Val", Skill_V }, { "Wizard", "Wiz", Skill_W }, }; bool is_restricted(const Role &r, const Skill &s) { for (const def_skill *sp = r.skills; sp->skill != P_NONE; ++sp) { if (sp->skill == s) { return false; } } return true; } void print_header(void) { cout << "! Skill \\ Role"; for (int i = 0; i < NUM_ROLES; i++) { const Role &r = ROLES[i]; cout << " !! [[" << r.long_name << "|" << r.short_name << "]]"; } cout << endl; } void print_role_skill_level(const Role &r, const Skill &s) { for (const def_skill *sp = r.skills; sp->skill != P_NONE; ++sp) { if (sp->skill == s) { cout << level_char(sp->level); return; } } cout << level_char(P_RESTRICTED); } void print_role_skill_level_full(const Role &r, const Skill &s) { for (const def_skill *sp = r.skills; sp->skill != P_NONE; ++sp) { if (sp->skill == s) { cout << level_full(sp->level); return; } } cout << level_full(P_RESTRICTED); } void print_warning(void) { cout << "" << endl; } void print_noinclude(void) { cout << "" << endl; cout << "This page was generated using Wikihack:Skill table generator. " "Instead of editing this page, edit that program, and re-generate " "this page." << "" << endl; } void print_skill_link(const Skill &s) { cout << "[[" << skill_full_name(s) << "|" << skill_raw_name(s) << "]]"; } void print_role_skills(const Role &r, const Skill &first, const Skill &last) { for (Skill s = first; s <= last; ++s) { if (is_restricted(r, s)) { continue; } cout << "|-" << endl; cout << "| "; print_skill_link(s); cout << " || "; print_role_skill_level_full(r, s); cout << endl; } } void do_skill_table(const Skill &first, const Skill &last) { print_warning(); cout << "{| class=\"prettytable\"" << endl; print_header(); for (Skill s = first; s <= last; ++s) { if (s == (P_LAST_WEAPON/2 + 1)) { cout << "|-" << endl; print_header(); } cout << "|-" << endl; cout << "|"; print_skill_link(s); for (int i = 0; i < NUM_ROLES; i++) { const Role &r = ROLES[i]; cout << " || "; print_role_skill_level(r, s); } cout << endl; } cout << "|}"; print_noinclude(); } void do_role_skill_table(const Role &r) { print_warning(); cout << "{| class=\"prettytable\"" << endl; cout << "! colspan=\"2\" style=\"font-size:larger\" | " << r.long_name << " skills" << endl; cout << "|-" << endl; cout << "! Skill !! Maximum level" << endl; cout << "|-" << endl; cout << "| colspan=\"2\" align=\"center\" | Weapon skills" << endl; print_role_skills(r, P_FIRST_WEAPON, P_LAST_WEAPON); cout << "|-" << endl; cout << "| colspan=\"2\" align=\"center\" | Combat skills" << endl; print_role_skills(r, P_FIRST_COMBAT, P_LAST_COMBAT); cout << "|-" << endl; cout << "| colspan=\"2\" align=\"center\" | Spell skills" << endl; print_role_skills(r, P_FIRST_SPELL, P_LAST_SPELL); cout << "|}"; print_noinclude(); } void do_skill_role_table(const Skill &s) { print_warning(); cout << "{| class=\"prettytable\"" << endl; cout << "! colspan=\"2\" style=\"font-size:larger\" | " << init_cap(skill_full_name(s)) << endl; cout << "|-" << endl; cout << "! Role !! Maximum level" << endl; for (int i = 0; i < NUM_ROLES; ++i) { const Role &r = ROLES[i]; if (is_restricted(r, s)) { continue; } cout << "|-" << endl; cout << "| [[" << r.long_name << "]]"; cout << " || "; print_role_skill_level_full(r, s); cout << endl; } cout << "|}"; print_noinclude(); } void print_usage(const char *name) { cout << "Usage:" << endl; cout << " " << name << " weapon|combat|spell" << endl; cout << " " << name << " {Role}|{Rol}" << endl; cout << " " << name << " {Skill}" << endl; } int main(int argc, const char **argv) { if (argc == 2) { const string arg(argv[1]); if (arg == "weapon") { do_skill_table(P_FIRST_WEAPON, P_LAST_WEAPON); } else if (arg == "combat") { do_skill_table(P_FIRST_COMBAT, P_LAST_COMBAT); } else if (arg == "spell") { do_skill_table(P_FIRST_SPELL, P_LAST_SPELL); } else { for (int i = 0; i < NUM_ROLES; ++i) { const Role &r = ROLES[i]; if (arg == r.long_name || arg == r.short_name) { do_role_skill_table(r); exit(0); } } for (Skill s = P_FIRST; s <= P_LAST; ++s) { if (arg == skill_raw_name(s)) { do_skill_role_table(s); exit(0); } } print_usage(argv[0]); } } else { print_usage(argv[0]); } }