NetHackWiki:Skill table generator

From NetHackWiki
Revision as of 04:36, 4 November 2006 by Killian (talk | contribs) (here's my table-generating program)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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>

using std::string;
using std::cout;
using std::endl;

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_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
skill_full_name(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(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 "???";
    }
}

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 },
};

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
do_skill_table(const Skill &first, const Skill &last) {
    cout << "" << endl;

    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 << "|";
        
        cout << "[[" << skill_full_name(s) 
             << "|" << skill_raw_name(s) << "]]";
             
        for (int i = 0; i < NUM_ROLES; i++) {
            const Role &r = ROLES[i];
            
            cout << " || ";
            print_role_skill_level(r, s);
        }
        
        cout << endl;

    }
    
    cout << "|}" << endl;
}

   
void
print_usage(const char *name) {
    cout << "Usage:" << endl;
    cout << "  " << name << " weapon" << endl;
    cout << "  " << name << " combat" << endl;
    cout << "  " << name << " spell" << 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 {
            print_usage(argv[0]);
        }
    } else {
        print_usage(argv[0]);
    }
}