The functions in the new ng-restr.cc are "pure": They don't access global state; data is passed in via the new and incomplete newgame_def.
Eventually, new_game should be split into something like newgame_def choose_game(); that doesn't access "you", and void setup_game(newgame_def); that sets up the player.
Also get rid of player_size in favour of player::body_size. Rename player_size_type to size_part_type since it's not really player-specific (used in actor::body_size). Move parts of player_genus, player::has_claws, body_size out into species.cc.
77KQMSMPKSU2HXCP5UDQJOM6ETXFCF2IYFM2EU566D5A7XE7AHKQC Q2DRRRBRUB5YD6RC7J73CIIA4566TTGOWDHKPRALBVWFYEZKEUSQC 75JWS3AAH2VYNUJO3HM54T3XUBQQX75RI5NARFF6AYTABOPXUPHAC VCCUMZF3AVNPDNGZZUBOPVY4EUYGE4BM3CS7MUSMMEUZ5CIMPJ6AC ZZPIS557ACG3GKJORIG4ITIH7EYAJJECFWERKEGA7Q4M7OIRKXCAC OLS6D34F57OHGMA25CFXWZ3KEIA47M3XBTBSY4RWMTVNEYKX6X7AC IJXKGFW3SSADXDWHBFA4TOW74RLVJAWKBHZ245KG64LHHJFCC6XAC NEQMKAUYFAGS3M44REOZXBBGSLM5KJBY4PSXIKUBM7J5BRD2AMDAC HHEXCJDIFUD4LO2TJWRW6UAXK3XMKCIGMFOFJZFB3YAYSFUAMPQAC P7DI6TRDWFXMNCBFI5WKPFXVB7PLW7JAJSL2HWC25I6YEWBUC4OAC 6ZDCG4JTGE6VQO755P4COB2BW2STIBVL2LX7EPBGP4JE54AIJKYQC IL4WCJVROF4HKGUQLIRWIMXL2SCULU43PAE5D7U5V6EXLB52DO6QC ASXBSZVXJCWVX5VQSRWXL5BWQ4NA7JLYXP6LWQTRGYW6DC2DZZPQC M7THNJTZZ2MRBFR7XZWIR7WZLL6PFXBDQNYKTRWNUNIFQSSVZOPQC SNH6UWOYVWP4A6B4NC6YZ6KRYPYCGGNYCW5TILTALPH552H2EUFQC DIAGORS5MPTNYDMPDOBXCIGCVDH7THTHYFOQUKMET57QH2J6WF5AC WRDCASRSGOBY5RLVORAMRBSYKEWLLO7VZ4V5NQG2TKBWYNU4OZKAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC CLIEHAE2PP7ZIGLLIMYCWM4FC54KBOAN5AILOLAZJ5S26GTJM4RQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC DKRSOHZXL6EPSLKOKHF7GJXSZEJVY7CXGACSHWLM5B5FTRETWWCAC 5WKKONCYM73GBJ6GDYK3OLZ2PB7KJHFDYGEMHQQMPQMFJJHTLWCQC LDFSITXKT52MLJJYOKDEFNLOEYIIV4ZOZHFH3U7PYSUNKF2KBIVQC QIHESOUNY5H7T56DAVXJMZRBUJPDMLHGTM34WIMPCWSUM72Z6QPQC M5ZDZJBTOJ7SWQPZZQPC24JYZKP26MWSRDHXBWQE2MPPL6WCXOIQC VJZ4D26E4L4E22SO6UYB44DNUTLG72LA4GTAEZ2DKKEMAICHOXBQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC YN7KNAJU72XINIQ3GP7RJLKW3STMN5VWJV2K66ICPZXR2VMYLZPAC S6ADNAPM545WP3FRHCU6UWKX5VEMY5TPSIZYSZ3XE76VCBTVIN5QC 3GJTOMYXXJLY7QZNJLIONXAOHMU64PDYRXUYYQATIB7WPRHSNN6AC 3BYA46OYLVN6ZPGAZD5OGIMMH5PRWGNSU3ITJRCVBE6P5HYYYAYQC ADIVVYTV2MJ3XVRYDNBLPTAEACCNF27XZDCRVZFQEHRHPMZGNITQC A3O24OMWTAW7EHB4T7HYAMW6MXINAWHEHV6LWZI6XS3GGFWSWZQAC FKQ4AQKB2XXAQQFMNPUQCT6FD54NM5JVWABBPT26HKKQPPWB7XUAC VXSORUQOM2VZA4CAZDC6KPAY373NQIN3UT7CXQXTRCYXO2WM62DAC KKJUHD576DZVDDQ7JFBAO7S35DAPIMZNOYVLAUBDOTTUGR4Q53JQC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC ILO5P5FRDUY4SEQEXMTUDKOPXAUBJRSORHHUVTLLCYOYSXBXOVRAC 3V52MSSK7QX7FWLLUW63DTWCBAJEK674EFZLKP45FLZ5KZKVARHAC 5LDEEBB7DT4CORJZOAYLQFXNI7FOURUJGAKVDVX7YL745NNRW63AC DIL5CIV3FGFPRSMRAGDDOHBJ2MBIOEZNMDDTJ4MYI7CU6BYAFVUAC UVJBHQ5KGUIEFRHKTYQPKSXYDUDKTRAXINUXGJJJ6QGNCR6JO7ZAC 5WOIUTOWIGPY64XLGDFHYJZUJCHUBHKDBYY3ZHMD4JDAJ7KHPMDAC MXXDHHK4X5OHJ24JK6LSWZOSN7GMKOERH2LR27Z6LLLG2QECLYPAC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC JDM5R3HYGXKQKZWY35QZ2KOB24TFZ3FW2PCNXCRCMWG72AZC5ZXQC WN3ZHNL4T7QMQC6JF5DJR6NHLZVOGQVO4OJNEKEM5FZKQ7AVOP4AC S34LKQDIQJLIWVIPASOJBBZ6ZCXDHP5KPS7TRBZJSCDRVNCLK6UAC C2PRXJYHDRF2642VDAUY76HJKCPQFGWDI6AM3SMCMYCHGWYDQXQQC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC PNRMCHHEBCAUD2XBSSH6JOEQ6A6CFEZBCIX436DVD26DA52OCYTQC LY2CUJ262FHANYCRHMGFEUBVPBHMA5FJHAUALAU6WVZGJSJ6YELQC RGWUYJO74FDGTH22CYSHBKFDGJ4S76WTLIULKPXA4QT5ZCNOB4LQC LABXKXWWQY2V4FUDLGVTDYHXINAP6KRHZDHBQ2FE22FFOEIZPL6QC JJULXW764V5C2HJKZNWQAEWB6QM5YZADD7ZCE35LYTBFEM6PMYCAC S4BRP4VHB23F2FCC6BXNAN2MZRVUGW7QMXUEOAVZVGFXKXJPVLLQC 5LVPHV2K57SCC7S4PECZOHPPQOIY5S7N6QBPAHK7IZLYV6NQQC7QC 33MBISZXMRGZMQ37PVINHKNWAXHYPHURMRG6ST7O2SKIRGGBHI2AC YPL32ZYVNBA2OSLEUGSAGSDJ5U2NKYMUHOL7GYSE2F4FCFZI2PTAC WAO43LWOVQKOXAKIML5ZA6UKSORMPXAMGYFPRVK2DNMQSPLC5JGQC XYQFJLTMLSU7LC7VODUJVN5F2P47STH2KVSP7Q3BSCUUDRHROW7QC QY5XETDODOIIOMYH4AKVORUYMMYG5WSDFUIDZI6NRFEEQWXI55UAC OHOFJZ6S5AJUO5EFVGG7HJHRPSXJSTJD2DDXAERT4LNVWDK23K6AC WMFU65IAJ3LX2YSFXXRS7ZFNDCZYQC3ZQ3QDHHK3DU3UMLJMAP4QC QWIGHBYDCRD4VSUAY4GAPS66VM2JGMYMLPHWK6A6BCVPUXU7W5WQC WUCXHWMF2FL5KCC6E6KNKMYL2NBXXC3WVRY2AUPWSBAPWJFGS34QC GUXTGUEMZYBRGV5QUAQSJHG3AOIQDWWCDIMOX4LASFJAZVGL2WQAC 3FRPKD2JSN7RA2HKWAO3XV7MMKCIAMWIMU6JNJ452VZEUSXM6PWQC ORZ37JMK7WY6FLTYZGC75D3POVCAZMZ7RCZIY4ZL2EGPXBMBCKJQC RWSXCNYUGDSMP2GKN22HROC5Q2GHSAVJJUDRT3Z53WU2DAI4IZOQC VGKONTCFVUJKMGHHKIUBSMTYHWH7776H5HUJ74XV7NLK3TCGIZPAC PO3IATZV4JX3I3522UAGF53ZLZ4FW7C2J32Z23PEWQVHGGEUO7SAC ES6J64POV7ONJRA4GVMPMVS7JKZZEXHE64BQAOOASMJDUPM7OKWAC JPGW2YFZDRPAWPG4VAKOOB5SCJA2QSSLR5JJP7ULRBX3LLGI7PUAC Z5QBJXLFUTXIHT4ADRMK7M33GX2DCDN323QQKYHWGYJ7GQKWW3TAC B5OK4FEITJ6MUT7J76OJJH2TOPTZGG7J7UPIJ6Z6WA5FC526FLTAC MCQZ4HEOF65FEVWUEAMO2765JYMJPKXQ454HCCWWK3JUYEUSUXTAC G5CA5STLILMQZO2ICHZTVTW76V6RMC7KWP4ELU7ANZBNXYSTWV7AC Y35JUXHENHI4INSFP2UO4ZJLJJFC7WDDC7LR4HZZHR73FKQB4DXQC FS732HH3GBQCSQRKU5ZYBYVLDBGOAGBWDNKHQV5HETPT634CFLDAC M6IHSU5JWCTOTUSPCVVHMAQ4XJDGQJOLZTTN5BGKEOS4B6Z7IOWAC 2VI52BHBTTER5YTZVPZNAOKVNXFJAJ6XLYXTFWCBWEBDFNJ7PWDAC HCQBAKIE4MXJ3XID6CECTZGNWYC33C3642KOKNKO37VVRDMJ2T4QC 2DZ57LMGON6GPOAGZAWNXQPFMPGGZOMZJO62GQBDECNM5KIOC6OQC BTDIRPAGSX5DWEEV62VGTYALWM6G5LKFKHT7HYJXVH7XBA4BPHLQC 3RY3A4K3ZCAJ235ID3ZDKFWYSYFD42AZOVAKL6767D5GH2QJTCPQC UKYGZDI6PYZPXDACCQGVPHANUP5ADCSNROOZIE7LYIZQWSNFHJZAC LCDAVMTTCXQW6AOXG4IHXGRGVNMA47ZKHXW3NDYK2YFJFBMCFFQAC YXWZYOBUFR4EHBSKXCFGZNK7NIM7IPE2GMZYIXEJTUPDDC3BIEDAC QHABWX5UYQAREZC4B6JGSRXSUH6DQLRD7WB4YGV4HHUHMTXY3ERAC 3U54KX4JPCEBGC3USUQJVX35HBEWV6DX6ZZ4RV7GT3HBX7LMLKPAC C67GX7W5HBCDPQJRSHWMLM4DUJ3ELFSHH42SVICFJVCJW25T5Z3AC MQ62OAMLGJVRW2QIL4PAZRAU6PC52ZVGY2FCOBIY6IWGQIHMU5CAC K4ZO7CVDWUJRLGMBQDDLHOVT45DWZQWINRQGWPWP4DLYKVD3672AC 3UUTHUKEJVRCYSOE3S3W423SADYD22L3DUXFB6CAFDVM66EPIF7AC YJ4Q65CCPG2R3O2CFICU6WS27ISYEHQGWIHNOOYPN2TIPKNXVX7QC 4FQAKUKUO6PCAZ3N4HUR5XL6E4VA5UQUZ3AEDGRBLVY7W2LMWI7QC R4KOJ7NY3HSBUCXYLNGBA7REIEKBIQBYQE5HTPFCMVWLMNBYYPWAC 26ACPNDHIMNMT5RV3GML6RTSVILQHVURAFL2JZR4O6AC5OXE7JHAC GAYW6ZERQLVVVZ6ZT7QUHA3MUETUBWNRSEE22DO4T7MWL7NBIPAAC 3EUPIYJNWOMOQBP2Z5SGSMWK453BXJD6KL2WFTR3NM565MEBYASAC SUWIERONPDATHPDMZRYO6GYIXSW6XIS5V5MK5IV23DWQH2LL7VIAC MBTH7A4NYIRD3T64ASJI2HOMUQ42BGOVTQXTKM5DLHMUQMM7H5FAC PI5BATR2SER3RFE76IUGHM2AGXVFOUM3PLU7WC2K2Q2BA5K2E73QC SHFSQYLN7WPQC35V3XYYEIZ4CQMREASUNR474CIKFG3C2FYI4SHQC 7BBEAPSUBQMBK4XC2Q6YJ2JPSVSPCSBJUYXM6EWXHNTQG4AEJX3QC M2FQTQ5MGAOKGIN4RSMF6RYT7WB4PVLMWFIY7S5IU5LB6DIWZSBQC }int species_has_claws(species_type species){if (species == SP_TROLL)return (3);if (species == SP_GHOUL)return (1);return (0);}genus_type species_genus(species_type species){switch (species){case SP_RED_DRACONIAN:case SP_WHITE_DRACONIAN:case SP_GREEN_DRACONIAN:case SP_YELLOW_DRACONIAN:case SP_GREY_DRACONIAN:case SP_BLACK_DRACONIAN:case SP_PURPLE_DRACONIAN:case SP_MOTTLED_DRACONIAN:case SP_PALE_DRACONIAN:case SP_BASE_DRACONIAN:return (GENPC_DRACONIAN);case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:return (GENPC_ELVEN);case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:return (GENPC_DWARVEN);case SP_OGRE:return (GENPC_OGRE);default:return (GENPC_NONE);}}size_type species_size(species_type species, size_part_type psize){switch (species){case SP_OGRE:case SP_TROLL:return (SIZE_LARGE);case SP_NAGA:// Most of their body is on the ground giving them a low profile.if (psize == PSIZE_TORSO || psize == PSIZE_PROFILE)return (SIZE_MEDIUM);elsereturn (SIZE_LARGE);case SP_CENTAUR:return ((psize == PSIZE_TORSO) ? SIZE_MEDIUM : SIZE_LARGE);case SP_SPRIGGAN:return (SIZE_LITTLE);case SP_HALFLING:case SP_KOBOLD:return (SIZE_SMALL);default:return(SIZE_MEDIUM);}
bool is_valid_species(species_type species){return (species >= 0 && species < NUM_SPECIES);}
switch (species){case SP_RED_DRACONIAN:case SP_WHITE_DRACONIAN:case SP_GREEN_DRACONIAN:case SP_YELLOW_DRACONIAN:case SP_GREY_DRACONIAN:case SP_BLACK_DRACONIAN:case SP_PURPLE_DRACONIAN:case SP_MOTTLED_DRACONIAN:case SP_PALE_DRACONIAN:case SP_BASE_DRACONIAN:return (which_genus == GENPC_DRACONIAN);case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:return (which_genus == GENPC_ELVEN);case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:return (which_genus == GENPC_DWARVEN);case SP_OGRE:return (which_genus == GENPC_OGRE);
// psize defaults to PSIZE_TORSO, which checks the part of the body// that wears armour and wields weapons (which is different for some hybrids).// base defaults to "false", meaning consider our current size, not our// natural one.size_type player_size(int psize, bool base){return you.body_size(psize, base);}
// XXX: player_size() implementations are incomplete, fix.const size_type size = player_size(PSIZE_BODY);const size_type torso = player_size(PSIZE_TORSO);
// XXX: you.body_size() implementations are incomplete, fix.const size_type size = you.body_size(PSIZE_BODY);const size_type torso = you.body_size(PSIZE_TORSO);
// Transformation has size of character's species.switch (species){case SP_OGRE:case SP_TROLL:ret = SIZE_LARGE;break;case SP_NAGA:// Most of their body is on the ground giving them a low profile.if (psize == PSIZE_TORSO || psize == PSIZE_PROFILE)ret = SIZE_MEDIUM;elseret = SIZE_LARGE;break;case SP_CENTAUR:ret = (psize == PSIZE_TORSO) ? SIZE_MEDIUM : SIZE_LARGE;break;case SP_SPRIGGAN:ret = SIZE_LITTLE;break;case SP_HALFLING:case SP_KOBOLD:ret = SIZE_SMALL;break;default:ret = SIZE_MEDIUM;break;}
size_type tf_size = transform_size(psize);return (tf_size == SIZE_CHARACTER ? species_size(species, psize): tf_size);
// these are the only other sources for clawsif (species == SP_TROLL)return (3);if (species == SP_GHOUL)return (1);
// XXX: Some assumptions about mutations and species in here.int sp_claws = species_has_claws(species);if (sp_claws > 0)return (sp_claws);
#ifndef NG_RESTR_H#define NG_RESTR_H#include "newgame.h"enum char_choice_restriction{CC_BANNED = 0,CC_RESTRICTED,CC_UNRESTRICTED};char_choice_restriction class_allowed(species_type speci,job_type char_class);bool is_good_combination(species_type spc, job_type cls,bool good = false);char_choice_restriction book_restriction(startup_book_type booktype,const newgame_def &ng);char_choice_restriction weapon_restriction(weapon_type wpn,const newgame_def &ng);char_choice_restriction religion_restriction(god_type god,const newgame_def &ng);#endif
/** File: ng-restr.cc* Summary: Character choice restrictions.** The functions in this file are "pure": They don't* access any global data.*/#include "AppHdr.h"#include "ng-restr.h"#include "newgame.h"#include "species.h"#include "jobs.h"char_choice_restriction class_allowed(species_type speci,job_type char_class){switch (char_class){case JOB_FIGHTER:switch (speci){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_GLADIATOR:switch (speci){case SP_DEEP_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_TROLL:case SP_RED_DRACONIAN:case SP_GHOUL:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_MONK:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_RED_DRACONIAN:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_BERSERKER:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_PALADIN:switch (speci){case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_TROLL:case SP_KENKU:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_PRIEST:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_DEEP_ELF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_TROLL:case SP_KENKU:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CHAOS_KNIGHT:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_DEEP_ELF:case SP_SPRIGGAN:case SP_NAGA:case SP_KENKU:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_DEATH_KNIGHT:switch (speci){case SP_SPRIGGAN:case SP_NAGA:case SP_KENKU:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_HEALER:switch (speci){case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_DEEP_ELF:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CRUSADER:switch (speci){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_REAVER:switch (speci){case SP_HUMAN:case SP_SLUDGE_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WIZARD:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_OGRE:case SP_MINOTAUR:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CONJURER:switch (speci){case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ENCHANTER:switch (speci){case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_GHOUL:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_SUMMONER:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_NECROMANCER:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WARPER:switch (speci){case SP_HUMAN:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_TRANSMUTER:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_FIRE_ELEMENTALIST:switch (speci){case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ICE_ELEMENTALIST:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_AIR_ELEMENTALIST:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_EARTH_ELEMENTALIST:switch (speci){case SP_HIGH_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_VENOM_MAGE:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_STALKER:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_THIEF:return (CC_RESTRICTED);case JOB_ASSASSIN:switch (speci){case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_HUNTER:switch (speci){case SP_DEEP_DWARF:case SP_KOBOLD:case SP_NAGA:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ARTIFICER:switch (speci){case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_OGRE:case SP_MUMMY:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WANDERER:return (CC_RESTRICTED);default:return (CC_BANNED);}}bool is_good_combination(species_type spc, job_type cls, bool good){const char_choice_restriction restrict = class_allowed(spc, cls);if (good)return (restrict == CC_UNRESTRICTED);return (restrict != CC_BANNED);}// Is the given book restricted for the character defined by ng?// Only uses ng.species.char_choice_restriction book_restriction(startup_book_type booktype,const newgame_def &ng){ASSERT(is_valid_species(ng.species));switch (booktype){case SBT_FIRE: // Fireswitch (ng.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}break;case SBT_COLD: // Iceswitch (ng.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_HILL_ORC:case SP_MERFOLK:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}break;case SBT_SUMM: // Summoningswitch (ng.species){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_MUMMY:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}break;default:return (CC_RESTRICTED);}}// Is the given god restricted for the character defined by ng?// Only uses ng.species and ng.job.char_choice_restriction weapon_restriction(weapon_type wpn,const newgame_def &ng){ASSERT(is_valid_species(ng.species));ASSERT(is_valid_job(ng.job));switch (wpn){case WPN_UNARMED:if (species_has_claws(ng.species))return (CC_UNRESTRICTED);return (CC_BANNED);case WPN_SHORT_SWORD:switch (ng.species){case SP_NAGA:case SP_VAMPIRE:// The fighter's heavy armour hinders stabbing.if (ng.job == JOB_FIGHTER)return (CC_RESTRICTED);// else fall throughcase SP_HIGH_ELF:case SP_DEEP_ELF:// Sludge elves have bad aptitudes with short swords (110) but are// still better with them than any other starting weapon.case SP_SLUDGE_ELF:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}// Maces and hand axes usually share the same restrictions.case WPN_MACE:if (ng.species == SP_TROLL)return (CC_UNRESTRICTED);if (ng.species == SP_VAMPIRE)return (CC_RESTRICTED);// else fall-throughcase WPN_HAND_AXE:switch (ng.species){case SP_HUMAN:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MUMMY:case SP_CENTAUR:case SP_NAGA:case SP_MINOTAUR:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:return (species_genus(ng.species) == GENPC_DRACONIAN ? CC_UNRESTRICTED: CC_RESTRICTED);}case WPN_SPEAR:switch (ng.species){case SP_HUMAN:case SP_HILL_ORC:case SP_MERFOLK:case SP_NAGA:case SP_CENTAUR:case SP_MINOTAUR:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:return (species_genus(ng.species) == GENPC_DRACONIAN ? CC_UNRESTRICTED: CC_RESTRICTED);}case WPN_TRIDENT:if (ng.species != SP_MERFOLK&& (ng.job != JOB_GLADIATOR|| species_size(ng.species, PSIZE_BODY) < SIZE_MEDIUM)){return (CC_BANNED);}// Tridents are strictly better than spears, so unrestrict them// for some species whose Polearm aptitudes are not too bad.switch (ng.species){case SP_MOUNTAIN_DWARF:case SP_OGRE:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:break;}// Both are polearms, right?return (weapon_restriction(WPN_SPEAR, ng));case WPN_ANKUS:if (species_genus(ng.species) == GENPC_OGRE)return (CC_UNRESTRICTED);// intentional fall-throughdefault:return (CC_BANNED);}}// Is the given god restricted for the character defined by ng?// Only uses ng.species and ng.job.char_choice_restriction religion_restriction(god_type god,const newgame_def &ng){ASSERT(is_valid_species(ng.species));ASSERT(is_valid_job(ng.job));// Sanity check.if (ng.species == SP_DEMIGOD)return (CC_BANNED);switch (god){case GOD_BEOGH:if (ng.species == SP_HILL_ORC)return (CC_UNRESTRICTED);return (CC_BANNED);case GOD_ZIN:switch (ng.species){case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_SPRIGGAN:case SP_CENTAUR:case SP_MINOTAUR:case SP_OGRE:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}case GOD_YREDELEMNUL:switch (ng.species){case SP_HILL_ORC:// Restrict in favour of Beogh, else unrestricted.if (ng.job == JOB_PRIEST)return (CC_RESTRICTED);return (CC_UNRESTRICTED);case SP_DEEP_ELF:case SP_KENKU:// Unrestrict these only for Priests as Zin is worse, but// Necromancy (DK) the better choice.if (ng.job == JOB_PRIEST)return (CC_UNRESTRICTED);return (CC_RESTRICTED);case SP_HUMAN:case SP_HIGH_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_XOM:switch (ng.species){case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_DEMONSPAWN:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_MAKHLEB:switch (ng.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_LUGONU:switch (ng.species){case SP_HUMAN:case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_SPRIGGAN:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (species_genus(ng.species) == GENPC_DRACONIAN)return (CC_UNRESTRICTED);return (CC_RESTRICTED);}default:return (CC_RESTRICTED);}}
static char_choice_restriction _class_allowed(species_type speci,job_type char_class){switch (char_class){case JOB_FIGHTER:switch (speci){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_GLADIATOR:switch (speci){case SP_DEEP_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_TROLL:case SP_RED_DRACONIAN:case SP_GHOUL:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_MONK:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_RED_DRACONIAN:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_BERSERKER:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_PALADIN:switch (speci){case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_TROLL:case SP_KENKU:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_PRIEST:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_DEEP_ELF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:case SP_OGRE:case SP_TROLL:case SP_KENKU:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CHAOS_KNIGHT:switch (speci){case SP_DEMIGOD:return (CC_BANNED);case SP_DEEP_ELF:case SP_SPRIGGAN:case SP_NAGA:case SP_KENKU:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_DEATH_KNIGHT:switch (speci){case SP_SPRIGGAN:case SP_NAGA:case SP_KENKU:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_HEALER:switch (speci){case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_DEEP_ELF:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CRUSADER:switch (speci){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_REAVER:switch (speci){case SP_HUMAN:case SP_SLUDGE_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WIZARD:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_OGRE:case SP_MINOTAUR:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_CONJURER:switch (speci){case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ENCHANTER:switch (speci){case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_GHOUL:case SP_MUMMY:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_SUMMONER:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_NECROMANCER:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WARPER:switch (speci){case SP_HUMAN:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_TRANSMUTER:switch (speci){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}
case JOB_FIRE_ELEMENTALIST:switch (speci){case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ICE_ELEMENTALIST:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_SPRIGGAN:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_AIR_ELEMENTALIST:switch (speci){case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_EARTH_ELEMENTALIST:switch (speci){case SP_HIGH_ELF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_SPRIGGAN:case SP_NAGA:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_RED_DRACONIAN:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_VENOM_MAGE:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_HALFLING:case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_STALKER:switch (speci){case SP_HIGH_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_THIEF:return (CC_RESTRICTED);case JOB_ASSASSIN:switch (speci){case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_RED_DRACONIAN:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_HUNTER:switch (speci){case SP_DEEP_DWARF:case SP_KOBOLD:case SP_NAGA:case SP_RED_DRACONIAN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_ARTIFICER:switch (speci){case SP_CENTAUR:case SP_TROLL:case SP_MINOTAUR:case SP_OGRE:case SP_MUMMY:case SP_GHOUL:return (CC_RESTRICTED);default:return (CC_UNRESTRICTED);}case JOB_WANDERER:return (CC_RESTRICTED);default:return (CC_BANNED);}}static bool _is_good_combination( species_type spc, job_type cls, bool good){const char_choice_restriction restrict = _class_allowed(spc, cls);if (good)return (restrict == CC_UNRESTRICTED);return (restrict != CC_BANNED);}
}}static char_choice_restriction _book_restriction(startup_book_type booktype){switch (booktype){case SBT_FIRE: // Fireswitch (you.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}break;case SBT_COLD: // Iceswitch (you.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_HILL_ORC:case SP_MERFOLK:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}break;case SBT_SUMM: // Summoningswitch (you.species){case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_KOBOLD:case SP_NAGA:case SP_OGRE:case SP_KENKU:case SP_MUMMY:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}break;default:return (CC_RESTRICTED);
static char_choice_restriction _weapon_restriction(weapon_type wpn){switch (wpn){case WPN_UNARMED:if (you.has_claws())return (CC_UNRESTRICTED);return (CC_BANNED);case WPN_SHORT_SWORD:switch (you.species){case SP_NAGA:case SP_VAMPIRE:// The fighter's heavy armour hinders stabbing.if (you.char_class == JOB_FIGHTER)return (CC_RESTRICTED);// else fall throughcase SP_HIGH_ELF:case SP_DEEP_ELF:// Sludge elves have bad aptitudes with short swords (110) but are// still better with them than any other starting weapon.case SP_SLUDGE_ELF:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}// Maces and hand axes usually share the same restrictions.case WPN_MACE:if (you.species == SP_TROLL)return (CC_UNRESTRICTED);if (you.species == SP_VAMPIRE)return (CC_RESTRICTED);// else fall-throughcase WPN_HAND_AXE:switch (you.species){case SP_HUMAN:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MUMMY:case SP_CENTAUR:case SP_NAGA:case SP_MINOTAUR:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:return (player_genus(GENPC_DRACONIAN) ? CC_UNRESTRICTED: CC_RESTRICTED);}case WPN_SPEAR:switch (you.species){case SP_HUMAN:case SP_HILL_ORC:case SP_MERFOLK:case SP_NAGA:case SP_CENTAUR:case SP_MINOTAUR:case SP_KENKU:case SP_DEMIGOD:case SP_DEMONSPAWN:case SP_MUMMY:return (CC_UNRESTRICTED);default:return (player_genus(GENPC_DRACONIAN) ? CC_UNRESTRICTED: CC_RESTRICTED);}case WPN_TRIDENT:if (you.species != SP_MERFOLK&& (you.char_class != JOB_GLADIATOR|| player_size(PSIZE_BODY) < SIZE_MEDIUM)){return (CC_BANNED);}// Tridents are strictly better than spears, so unrestrict them// for some species whose Polearm aptitudes are not too bad.switch (you.species){case SP_MOUNTAIN_DWARF:case SP_OGRE:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:break;}// Both are polearms, right?return (_weapon_restriction(WPN_SPEAR));case WPN_ANKUS:if (player_genus(GENPC_OGRE))return (CC_UNRESTRICTED);// intentional fall-throughdefault:return (CC_BANNED);}}
// Gods are not restricted but there are some choices that are banned (false).// Everything else will be unrestricted.static char_choice_restriction _religion_restriction(god_type god){// Sanity check.if (you.species == SP_DEMIGOD)return (CC_BANNED);switch (god){case GOD_BEOGH:if (you.species == SP_HILL_ORC)return (CC_UNRESTRICTED);return (CC_BANNED);case GOD_ZIN:switch (you.species){case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_BANNED);case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_SPRIGGAN:case SP_CENTAUR:case SP_MINOTAUR:case SP_OGRE:return (CC_UNRESTRICTED);default:return (CC_RESTRICTED);}case GOD_YREDELEMNUL:switch (you.species){case SP_HILL_ORC:// Restrict in favour of Beogh, else unrestricted.if (you.char_class == JOB_PRIEST)return (CC_RESTRICTED);return (CC_UNRESTRICTED);case SP_DEEP_ELF:case SP_KENKU:// Unrestrict these only for Priests as Zin is worse, but// Necromancy (DK) the better choice.if (you.char_class == JOB_PRIEST)return (CC_UNRESTRICTED);return (CC_RESTRICTED);case SP_HUMAN:case SP_HIGH_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_SPRIGGAN:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_XOM:switch (you.species){case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_KENKU:case SP_DEMONSPAWN:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_MAKHLEB:switch (you.species){case SP_HUMAN:case SP_HIGH_ELF:case SP_DEEP_ELF:case SP_SLUDGE_ELF:case SP_MOUNTAIN_DWARF:case SP_DEEP_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_HALFLING:case SP_KOBOLD:case SP_NAGA:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_MUMMY:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}case GOD_LUGONU:switch (you.species){case SP_HUMAN:case SP_MOUNTAIN_DWARF:case SP_HILL_ORC:case SP_MERFOLK:case SP_SPRIGGAN:case SP_CENTAUR:case SP_OGRE:case SP_TROLL:case SP_MINOTAUR:case SP_DEMONSPAWN:case SP_GHOUL:case SP_VAMPIRE:return (CC_UNRESTRICTED);default:if (player_genus(GENPC_DRACONIAN))return (CC_UNRESTRICTED);return (CC_RESTRICTED);}default:return (CC_RESTRICTED);}}
bool is_valid_job(job_type job){return (job >= 0 && job < NUM_JOBS);}
if (player_size(PSIZE_BODY) < SIZE_MEDIUM&& !check_weapon_wieldable_size(*weapon, player_size(PSIZE_BODY)))
if (you.body_size(PSIZE_BODY) < SIZE_MEDIUM&& !check_weapon_wieldable_size(*weapon, you.body_size(PSIZE_BODY)))