- [+] new skill: advanced combat

- [+] each level:  10% increase chance of not using stamina to
          attack
    - [+] nov: improvised weapons
    - [+] beg: nausea, being prone don't affect your accuracy
    - [+] adept:
        - [+]  blind fighting ability.
    - [+] skilled: DISARM skill
    - [+] expert: regain stamina once you kill someone
        - [+] FLIP skill
    - [+] master: attacking uses no stamina
    - [+] assign to jobs
        - [+] Ninja starts with ADEPT level.
        - [+] Warrior too?
- [+] genericise plural code:
    - [+] plural_t
        - [+] singular
        - [+] plural
    - [+] change object.c addobject()
    - [+] chnage text.c makeplural()
- [+] move flak jacket to go over shoudlers.
- [+] fix: don't give player skill in their race
This commit is contained in:
Rob Pearce 2012-07-18 10:12:32 +00:00
parent 023c8a5eaa
commit 8b6f5a13a8
9 changed files with 272 additions and 174 deletions

View File

@ -713,8 +713,14 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
if (isplayer(lf)) { if (isplayer(lf)) {
// lose a bit of stamina enum SKILLLEVEL slev;
modstamina(lf, -getattackstamloss(lf)); slev = getskill(lf, SK_COMBAT);
if (slev != PR_MASTER) {
if (!pctchance(slev * 10)) {
// lose a bit of stamina
modstamina(lf, -getattackstamloss(lf));
}
}
} }
// stop sprinting // stop sprinting

68
data.c
View File

@ -9,6 +9,7 @@
#include "nexus.h" #include "nexus.h"
#include "objects.h" #include "objects.h"
#include "spell.h" #include "spell.h"
#include "text.h"
extern behaviour_t *firstbehaviour,*lastbehaviour; extern behaviour_t *firstbehaviour,*lastbehaviour;
extern command_t *firstcommand,*lastcommand; extern command_t *firstcommand,*lastcommand;
@ -26,6 +27,7 @@ extern brand_t *firstbrand,*lastbrand;
extern obmod_t *firstobmod,*lastobmod; extern obmod_t *firstobmod,*lastobmod;
extern material_t *material,*lastmaterial; extern material_t *material,*lastmaterial;
extern lifeform_t *player; extern lifeform_t *player;
extern plural_t *firstplural,*lastplural;
extern hiddennamewithcol_t colour[]; extern hiddennamewithcol_t colour[];
extern char *bookadjective[]; extern char *bookadjective[];
@ -405,6 +407,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat knife"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat knife");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "revolver"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "revolver");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "flak jacket"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "flak jacket");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat pants"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat pants");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots");
@ -416,6 +419,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 bullets"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 bullets");
// initial skills // initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COMBAT, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_FIRSTAID, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_FIRSTAID, PR_NOVICE, NA, NULL);
@ -460,6 +464,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_NATURE, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_NATURE, PR_NOVICE, NA, NULL);
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_COMBAT, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_EXOTICWEPS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL);
@ -501,6 +506,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COMBAT, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
@ -664,7 +670,8 @@ void initjobs(void) {
// initial skills // initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); // limit addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); // limited
addflag(lastjob->flags, F_STARTSKILL, SK_COMBAT, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_BEGINNER, NA, NULL);
@ -694,7 +701,6 @@ void initjobs(void) {
// abilities // abilities
addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL);
// gained abilities // gained abilities
addflag(lastjob->flags, F_LEVABIL, 2, OT_A_DISARMLF, NA, NULL);
addflag(lastjob->flags, F_LEVABIL, 4, OT_A_TRIPLF, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 4, OT_A_TRIPLF, NA, NULL);
addflag(lastjob->flags, F_LEVABIL, 6, OT_A_FLIP, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 6, OT_A_FLIP, NA, NULL);
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
@ -730,6 +736,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COMBAT, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, PR_EXPERT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, PR_EXPERT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL);
@ -771,6 +778,7 @@ void initjobs(void) {
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, PR_EXPERT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, PR_EXPERT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COMBAT, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, PR_EXPERT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, PR_EXPERT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL);
@ -823,6 +831,7 @@ void initjobs(void) {
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_ARMOUR, PR_NOVICE, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_ARMOUR, PR_NOVICE, NA, NULL); // limit
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COMBAT, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_SKILLED, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); // addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); //
@ -857,6 +866,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10-20 gold dollars"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10-20 gold dollars");
// initial skills // initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COMBAT, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CLUBS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CLUBS, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL);
@ -6746,10 +6756,10 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 120, 120, NA, NULL); addflag(lastot->flags, F_OBHP, 120, 120, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addot(OT_FLAKJACKET, "flak jacket", "Heavy metal body armour. Designed to stop a bullet, but ineffective against melee attacks.", MT_METAL, 30, OC_ARMOUR, SZ_MEDIUM); addot(OT_FLAKJACKET, "flak jacket", "Heavy metal vest, worn over the shoulders. Designed to stop a bullet, but ineffective against melee attacks.", MT_METAL, 30, OC_ARMOUR, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SHOULDERS, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 50, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 50, NA, NULL);
@ -17723,6 +17733,7 @@ void initskills(void) {
addskill(SK_ARMOUR, "Armour", "Reduces evasion and stealth penalties from wearing armour.", 100); addskill(SK_ARMOUR, "Armour", "Reduces evasion and stealth penalties from wearing armour.", 100);
addskilldesc(SK_ARMOUR, PR_INEPT, "- Reduces the noise you make when wearing metal armour.", B_FALSE); addskilldesc(SK_ARMOUR, PR_INEPT, "- Reduces the noise you make when wearing metal armour.", B_FALSE);
addskilldesc(SK_ARMOUR, PR_NOVICE, "^gReduces armour penalties by 10%.^n", B_FALSE); addskilldesc(SK_ARMOUR, PR_NOVICE, "^gReduces armour penalties by 10%.^n", B_FALSE);
addskilldesc(SK_ARMOUR, PR_NOVICE, "^gYou can now recognise the quality of armour.^n", B_FALSE);
addskilldesc(SK_ARMOUR, PR_BEGINNER, "^gReduces armour penalties by 20%.^n", B_FALSE); addskilldesc(SK_ARMOUR, PR_BEGINNER, "^gReduces armour penalties by 20%.^n", B_FALSE);
addskilldesc(SK_ARMOUR, PR_ADEPT, "^gReduces armour penalties by 30%.^n", B_FALSE); addskilldesc(SK_ARMOUR, PR_ADEPT, "^gReduces armour penalties by 30%.^n", B_FALSE);
addskilldesc(SK_ARMOUR, PR_SKILLED, "^gReduces armour penalties by 40%.^n", B_FALSE); addskilldesc(SK_ARMOUR, PR_SKILLED, "^gReduces armour penalties by 40%.^n", B_FALSE);
@ -17768,6 +17779,15 @@ void initskills(void) {
addskilldesc(SK_CLIMBING, PR_SKILLED, "-5 accuracy penalty while climbing.", B_FALSE); addskilldesc(SK_CLIMBING, PR_SKILLED, "-5 accuracy penalty while climbing.", B_FALSE);
addskilldesc(SK_CLIMBING, PR_EXPERT, "-2 accuracy penalty while climbing.", B_FALSE); addskilldesc(SK_CLIMBING, PR_EXPERT, "-2 accuracy penalty while climbing.", B_FALSE);
addskilldesc(SK_CLIMBING, PR_MASTER, "No accuracy penalty or stamina cost to remain climbing.", B_FALSE); addskilldesc(SK_CLIMBING, PR_MASTER, "No accuracy penalty or stamina cost to remain climbing.", B_FALSE);
addskill(SK_COMBAT, "Advanced Combat", "Affects your ability to fight in adverse situations or unorthodox styles.", 0);
addskilldesc(SK_COMBAT, PR_INEPT, " - Each skill level grants a 10% chance to bypass stamina drain when attacking.", B_FALSE);
addskilldesc(SK_COMBAT, PR_NOVICE, "Unskilled weapon penalties are greatly reduced.", B_FALSE);
addskilldesc(SK_COMBAT, PR_BEGINNER, "Eliminates penalties for being prone or nauseated.", B_FALSE);
addskilldesc(SK_COMBAT, PR_ADEPT, "Eliminates penalties when fighting unseen enemies.", B_FALSE);
addskilldesc(SK_COMBAT, PR_ADEPT, "You gain the 'disarm' ability.", B_FALSE);
addskilldesc(SK_COMBAT, PR_SKILLED, "You gain the 'trip' ability.", B_FALSE);
addskilldesc(SK_COMBAT, PR_EXPERT, "^gSecond wind restores stamina after defeating enemies.^n", B_TRUE);
addskilldesc(SK_COMBAT, PR_MASTER, "^gAttacking will no longer drain your stamina.^n", B_TRUE);
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50); addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50);
addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE); addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE);
addskilldesc(SK_COOKING, PR_NOVICE, "^gYou can now cook corpses before consumption.", B_TRUE); addskilldesc(SK_COOKING, PR_NOVICE, "^gYou can now cook corpses before consumption.", B_TRUE);
@ -17841,6 +17861,7 @@ void initskills(void) {
addskill(SK_SHIELDS, "Shields", "Reduces shield accuracy penalty, and raises chance to block attacks.", 50); addskill(SK_SHIELDS, "Shields", "Reduces shield accuracy penalty, and raises chance to block attacks.", 50);
addskilldesc(SK_SHIELDS, PR_INEPT, "- Without this skill, shield accuracy penalties are tripled.", B_FALSE); addskilldesc(SK_SHIELDS, PR_INEPT, "- Without this skill, shield accuracy penalties are tripled.", B_FALSE);
addskilldesc(SK_SHIELDS, PR_NOVICE, "^gShield accuracy penalties are reduced by 1.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_NOVICE, "^gShield accuracy penalties are reduced by 1.^n", B_FALSE);
addskilldesc(SK_SHIELDS, PR_NOVICE, "^gYou can now recognise the quality of shields.^n", B_FALSE);
addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gShield accuracy penalties are reduced by 2.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gShield accuracy penalties are reduced by 2.^n", B_FALSE);
addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gYou gain the 'shield bash' ability.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gYou gain the 'shield bash' ability.^n", B_FALSE);
addskilldesc(SK_SHIELDS, PR_ADEPT, "^gShield accuracy penalties are reduced by 3.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_ADEPT, "^gShield accuracy penalties are reduced by 3.^n", B_FALSE);
@ -18070,6 +18091,8 @@ void initskills(void) {
if (isweaponskill(sk->id) || (sk->id == SK_UNARMED)) { if (isweaponskill(sk->id) || (sk->id == SK_UNARMED)) {
addskilldesc(sk->id, PR_INEPT, "This skill increases your accuracy and damage when using matching weapons.", B_FALSE); addskilldesc(sk->id, PR_INEPT, "This skill increases your accuracy and damage when using matching weapons.", B_FALSE);
if (sk->id == SK_CLUBS) addskilldesc(sk->id, PR_NOVICE, "^gYou gain the 'merciful fighting' ability.^n", B_FALSE); if (sk->id == SK_CLUBS) addskilldesc(sk->id, PR_NOVICE, "^gYou gain the 'merciful fighting' ability.^n", B_FALSE);
addskilldesc(sk->id, PR_NOVICE, "^gYou can now recognise the quality of matching weapons.^n", B_FALSE);
addskilldesc(sk->id, PR_NOVICE, "^gYou no longer suffer accuracy penalties with matching weapons.^n", B_FALSE);
addskilldesc(sk->id, PR_BEGINNER, "^g+1 accuracy.^n", B_FALSE); addskilldesc(sk->id, PR_BEGINNER, "^g+1 accuracy.^n", B_FALSE);
addskilldesc(sk->id, PR_BEGINNER, "^gYou gain the 'wild strike' ability.^n", B_FALSE); addskilldesc(sk->id, PR_BEGINNER, "^gYou gain the 'wild strike' ability.^n", B_FALSE);
addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE);
@ -18083,6 +18106,43 @@ void initskills(void) {
} }
} }
void inittext(void) {
// scrolls
addplural("bag","bags", B_TRUE);
addplural("berry","berries", B_TRUE);
addplural("block","blocks", B_TRUE);
addplural("can","cans", B_TRUE);
addplural("chunk","chunks", B_TRUE);
addplural("cloud","clouds", B_TRUE);
addplural("clove","cloves", B_TRUE);
addplural("flask","flasks", B_TRUE);
addplural("gem","gems", B_TRUE);
addplural("knife","knives", B_TRUE);
addplural("leaf","leaves", B_TRUE);
addplural("loaf","loaves", B_TRUE);
addplural("lump","lumps", B_TRUE);
addplural("piece","pieces", B_TRUE);
addplural("pile","piles", B_TRUE);
addplural("pinch","pinches", B_TRUE);
addplural("plank","planks", B_TRUE);
addplural("pool","pools", B_TRUE);
addplural("potion","potions", B_TRUE);
addplural("puddle","puddles", B_TRUE);
addplural("puff","puffs", B_TRUE);
addplural("ring","rings", B_TRUE);
addplural("ruby","rubies", B_TRUE);
addplural("scroll","scrolls", B_TRUE);
addplural("splash","splashes", B_TRUE);
addplural("set","sets", B_TRUE);
addplural("sheet","sheets", B_TRUE);
addplural("sprig","sprigs", B_TRUE);
addplural("suit","suits", B_TRUE);
addplural("vial","vials", B_TRUE);
// don't return after finding this one
addplural("pair", "pairs", B_FALSE);
}
void killoption(option_t *w) { void killoption(option_t *w) {
option_t *nextone, *lastone; option_t *nextone, *lastone;

1
data.h
View File

@ -11,6 +11,7 @@ void initoptions(void);
void initrace(void); void initrace(void);
void initraceclasses(void); void initraceclasses(void);
void initskills(void); void initskills(void);
void inittext(void);
void killbehaviour(behaviour_t *b); void killbehaviour(behaviour_t *b);
void killcommand(command_t *cmd); void killcommand(command_t *cmd);
void killoption(option_t *o); void killoption(option_t *o);

10
defs.h
View File

@ -652,6 +652,7 @@ enum SKILL {
SK_CARTOGRAPHY, SK_CARTOGRAPHY,
SK_CHANNELING, SK_CHANNELING,
SK_CLIMBING, SK_CLIMBING,
SK_COMBAT,
SK_COOKING, SK_COOKING,
SK_EVASION, SK_EVASION,
SK_FIRSTAID, SK_FIRSTAID,
@ -702,7 +703,7 @@ enum SKILL {
SK_SS_TRANSLOCATION, SK_SS_TRANSLOCATION,
SK_SS_WILD, SK_SS_WILD,
}; };
#define MAXSKILLS 53 #define MAXSKILLS 54
// proficiency levels // proficiency levels
enum SKILLLEVEL { enum SKILLLEVEL {
@ -4161,6 +4162,13 @@ typedef struct option_s {
struct option_s *next, *prev; struct option_s *next, *prev;
} option_t; } option_t;
typedef struct plural_s {
char *singular;
char *plural;
int stopafter; // stop parsing strings after finding this?
struct plural_s *next, *prev;
} plural_t;
enum BRANCH { enum BRANCH {
BH_CAVE, BH_CAVE,
BH_WORLDMAP, BH_WORLDMAP,

43
lf.c
View File

@ -3284,6 +3284,13 @@ void die(lifeform_t *lf) {
} }
} }
} }
// player might get stamina back...
if (isplayer(killer)) {
if (getskill(player, SK_COMBAT) >= PR_EXPERT) {
modstamina(lf, rnd(1,getmaxstamina(lf)));
}
}
} }
// determine where to drop objects // determine where to drop objects
@ -8019,11 +8026,15 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
// modify for blindness // modify for blindness
if (isblind(lf)) { if (isblind(lf)) {
acc -= 50; if (getskill(lf, SK_COMBAT) < PR_ADEPT) {
acc -= 50;
}
} }
// modify for being on the ground // modify for being on the ground
if (isprone(lf)) { if (isprone(lf)) {
acc -= 40; if (getskill(lf, SK_COMBAT) < PR_BEGINNER) {
acc -= 40;
}
} }
// day/night boosts // day/night boosts
@ -8080,7 +8091,9 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
// modify for nausea // modify for nausea
if (lfhasflag(lf, F_NAUSEATED)) { if (lfhasflag(lf, F_NAUSEATED)) {
acc -= 25; if (getskill(lf, SK_COMBAT) < PR_BEGINNER) {
acc -= 25;
}
} }
// modify for stickiness // modify for stickiness
@ -8700,7 +8713,7 @@ enum MATERIAL getlfmaterial(lifeform_t *lf) {
enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid) { enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid) {
enum SKILLLEVEL slev = PR_INEPT; enum SKILLLEVEL slev = PR_INEPT;
raceclass_t *rc; raceclass_t *rc;
if (gamemode < GM_GAMESTARTED) { if (gamemode <= GM_LOADING) {
return PR_INEPT; return PR_INEPT;
} }
rc = findraceclass(rcid); rc = findraceclass(rcid);
@ -10650,7 +10663,7 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
} }
// now give start obs/skills from it // now give start obs/skills from the job
givestartskills(lf, lf->flags); givestartskills(lf, lf->flags);
if (!lfhasflag(lf, F_PHANTASM)) { if (!lfhasflag(lf, F_PHANTASM)) {
givestartobs(lf, NULL, lf->flags); givestartobs(lf, NULL, lf->flags);
@ -10965,6 +10978,9 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
case SJ_SCOURGE: case SJ_SCOURGE:
// remove warrior's level abilities // remove warrior's level abilities
killflagsofid(lf->flags, F_LEVABIL); killflagsofid(lf->flags, F_LEVABIL);
// scourges don't get advanced combat
f = lfhasflagval(lf, F_HASSKILL, SK_COMBAT, NA, NA, NULL);
if (f) killflag(f);
// magic resistance at level 5 // magic resistance at level 5
addtempflag(lf->flags, F_RESISTMAG, 5, NA, NA, NULL, FROMJOB); addtempflag(lf->flags, F_RESISTMAG, 5, NA, NA, NULL, FROMJOB);
// no mp or other magic. // no mp or other magic.
@ -11352,6 +11368,16 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
newf = addtempflag(lf->flags, F_CANWILL, OT_S_MAPPING, 50, 50, "pw:1;", FROMSKILL); newf = addtempflag(lf->flags, F_CANWILL, OT_S_MAPPING, 50, 50, "pw:1;", FROMSKILL);
} }
} }
} else if (id == SK_COMBAT) {
if (f->val[1] == PR_SKILLED) {
if (!hasflagval(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL)) {
newf = addtempflag(lf->flags, F_CANWILL, OT_A_DISARMLF, NA, NA, NULL, FROMSKILL);
}
} else if (f->val[1] == PR_EXPERT) {
if (!hasflagval(lf->flags, F_CANWILL, OT_A_FLIP, NA, NA, NULL)) {
newf = addtempflag(lf->flags, F_CANWILL, OT_A_FLIP, NA, NA, NULL, FROMSKILL);
}
}
} else if (id == SK_COOKING) { } else if (id == SK_COOKING) {
if (f->val[1] == PR_ADEPT) { if (f->val[1] == PR_ADEPT) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -11860,9 +11886,12 @@ void givestartskills(lifeform_t *lf, flagpile_t *fp) {
killflagsofid(fp, F_STARTSKILL); killflagsofid(fp, F_STARTSKILL);
// all races know about their own race // all races know about their own race
if (getlorelevel(lf, lf->race->raceclass->id) < PR_NOVICE) { if (!isplayer(lf)) {
giveskilllev(lf, lf->race->raceclass->skill, PR_NOVICE); if (getlorelevel(lf, lf->race->raceclass->id) < PR_NOVICE) {
giveskilllev(lf, lf->race->raceclass->skill, PR_NOVICE);
}
} }
} }
int gotosleep(lifeform_t *lf, int onpurpose) { int gotosleep(lifeform_t *lf, int onpurpose) {

View File

@ -60,6 +60,7 @@ int nbuildingusage = 0;
warning_t *firstwarning = NULL,*lastwarning = NULL; warning_t *firstwarning = NULL,*lastwarning = NULL;
option_t *firstoption = NULL,*lastoption = NULL; option_t *firstoption = NULL,*lastoption = NULL;
plural_t *firstplural = NULL,*lastplural = NULL;
int maxmonhitdice = 0; // highest number of hitdice for any monster int maxmonhitdice = 0; // highest number of hitdice for any monster
@ -1261,6 +1262,7 @@ int init(void) {
// load npc names // load npc names
loadnpcnames(); loadnpcnames();
inittext();
initoptions(); initoptions();
initcommands(); initcommands();
initobjects(); initobjects();

View File

@ -31,6 +31,7 @@ extern race_t *firstrace, *lastrace;
extern recipe_t *firstrecipe,*lastrecipe; extern recipe_t *firstrecipe,*lastrecipe;
extern skill_t *firstskill, *lastskill; extern skill_t *firstskill, *lastskill;
extern region_t *firstregion; extern region_t *firstregion;
extern plural_t *firstplural;
extern buildingusage_t buildingusage[]; extern buildingusage_t buildingusage[];
extern int nbuildingusage; extern int nbuildingusage;
@ -3614,6 +3615,7 @@ objecttype_t *findot(enum OBTYPE id) {
objecttype_t *findotn(char *name) { objecttype_t *findotn(char *name) {
objecttype_t *ot; objecttype_t *ot;
plural_t *pl;
knowledge_t *k; knowledge_t *k;
char *modname; char *modname;
char *p; char *p;
@ -3628,36 +3630,9 @@ objecttype_t *findotn(char *name) {
// make some replacements // make some replacements
//replace scrolls with scroll etc //replace scrolls with scroll etc
modname = strrep(modname, "bags ", "bag ", NULL); for (pl = firstplural ; pl ; pl = pl->next) {
modname = strrep(modname, "berries ", "berry ", NULL); modname = strrep(modname, pl->plural, pl->singular, NULL);
modname = strrep(modname, "blocks ", "block ", NULL); }
modname = strrep(modname, "cans ", "can ", NULL);
modname = strrep(modname, "chunks ", "chunk ", NULL);
modname = strrep(modname, "clouds ", "cloud ", NULL);
modname = strrep(modname, "cloves ", "clove ", NULL);
modname = strrep(modname, "flasks ", "flask ", NULL);
modname = strrep(modname, "gems ", "gem ", NULL);
modname = strrep(modname, "knives", "knife", NULL);
modname = strrep(modname, "leaves", "leaf", NULL);
modname = strrep(modname, "loaves ", "loaf ", NULL);
modname = strrep(modname, "lumps ", "lump ", NULL);
modname = strrep(modname, "pieces ", "piece ", NULL);
modname = strrep(modname, "piles ", "pile ", NULL);
modname = strrep(modname, "pinches ", "pinch ", NULL);
modname = strrep(modname, "planks ", "plank ", NULL);
modname = strrep(modname, "pools ", "pool ", NULL);
modname = strrep(modname, "potions ", "potion ", NULL);
modname = strrep(modname, "puddles ", "puddle ", NULL);
modname = strrep(modname, "puffs ", "puff ", NULL);
modname = strrep(modname, "rings ", "ring ", NULL);
modname = strrep(modname, "rubies", "ruby", NULL);
modname = strrep(modname, "scrolls ", "scroll ", NULL);
modname = strrep(modname, "sets ", "set ", NULL);
modname = strrep(modname, "sheets ", "sheet ", NULL);
modname = strrep(modname, "splashes ", "splash ", NULL);
modname = strrep(modname, "sprigs ", "sprig ", NULL);
modname = strrep(modname, "suits ", "suit ", NULL);
modname = strrep(modname, "vials ", "vial ", NULL);
// only at start... // only at start...
if (strstr(modname, "the ") == modname) modname = strrep(modname, "the ", "", NULL); if (strstr(modname, "the ") == modname) modname = strrep(modname, "the ", "", NULL);
@ -4096,6 +4071,13 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow) {
// adjust for weapon skill // adjust for weapon skill
weplev = getweaponskill(weilder, wep); weplev = getweaponskill(weilder, wep);
switch (weplev) { switch (weplev) {
case PR_INEPT:
if (getskill(weilder, SK_COMBAT)) {
acc -= 5; break;
} else {
acc -= 15; break;
}
case PR_NOVICE: break; // no change
case PR_BEGINNER: acc += 5; break; case PR_BEGINNER: acc += 5; break;
case PR_ADEPT: acc += 10; break; case PR_ADEPT: acc += 10; break;
case PR_SKILLED: acc += 15; break; case PR_SKILLED: acc += 15; break;

268
text.c
View File

@ -23,6 +23,36 @@ extern enum GAMEMODE gamemode;
extern enum WINGAMETYPE wintype; extern enum WINGAMETYPE wintype;
extern material_t *material,*lastmaterial; extern material_t *material,*lastmaterial;
extern plural_t *firstplural,*lastplural;
plural_t *addplural(char *singulartext, char *pluraltext, int stopafter) {
plural_t *a;
char buf[BUFLEN];
// add to the end of the list
if (firstplural == NULL) {
firstplural = malloc(sizeof(celltype_t));
a = firstplural;
a->prev = NULL;
} else {
// go to end of list
a = lastplural;
a->next = malloc(sizeof(plural_t));
a->next->prev = a;
a = a->next;
}
lastplural = a;
a->next = NULL;
// set props - add spaces at the end of words
sprintf(buf, "%s ",singulartext);
a->singular = strdup(buf);
sprintf(buf, "%s ",pluraltext);
a->plural = strdup(buf);
a->stopafter = stopafter;
return a;
}
int needan(char *text) { int needan(char *text) {
if (isvowel(tolower(text[0]))) { if (isvowel(tolower(text[0]))) {
@ -1300,22 +1330,30 @@ char *getinjurydesc(enum BODYPART where, enum DAMTYPE dt) {
// all strings returned here must also be defined as an obmod altprefix! // all strings returned here must also be defined as an obmod altprefix!
// //
char *getobmodprefix(object_t *o, obmod_t *om) { char *getobmodprefix(object_t *o, obmod_t *om) {
int enoughperception = B_TRUE;
int enoughwepskill = B_TRUE;
if (gamemode == GM_GAMESTARTED) {
if ( (getskill(player, SK_PERCEPTION) < PR_BEGINNER)) {
enoughperception = B_FALSE;
}
if (!getweaponskill(player, o)) {
enoughwepskill = B_FALSE;
}
}
// masterwork/shoddy doors have names based on material. // masterwork/shoddy doors have names based on material.
if (isdoor(o, NULL)) { if (isdoor(o, NULL)) {
// player perceptive enough to notice? // player perceptive enough to notice?
if (om->id == OM_MASTERWORK) { if (om->id == OM_MASTERWORK) {
if ((gamemode == GM_GAMESTARTED) && (getskill(player, SK_PERCEPTION) < PR_BEGINNER)) { if (!enoughperception) return NULL;
return NULL;
}
switch (o->material->id) { switch (o->material->id) {
case MT_STONE: return "reinforced "; case MT_STONE: return "reinforced ";
case MT_METAL: return "reinforced "; case MT_METAL: return "reinforced ";
default: return "sturdy "; default: return "sturdy ";
} }
} else if (om->id == OM_SHODDY) { } else if (om->id == OM_SHODDY) {
if ((gamemode == GM_GAMESTARTED) && (getskill(player, SK_PERCEPTION) < PR_BEGINNER)) { if (!enoughperception) return NULL;
return NULL;
}
switch (o->material->id) { switch (o->material->id) {
case MT_STONE: return "crumbling "; case MT_STONE: return "crumbling ";
case MT_METAL: return "rusted "; case MT_METAL: return "rusted ";
@ -1326,7 +1364,7 @@ char *getobmodprefix(object_t *o, obmod_t *om) {
skill_t *sk; skill_t *sk;
sk = getobskill(o->flags); sk = getobskill(o->flags);
if (sk) { if (sk) {
if (!player || (getskill(player, sk->id) >= PR_BEGINNER) || (getskill(player, SK_PERCEPTION) >= PR_BEGINNER)) { if (!player || enoughwepskill || enoughperception) {
if (om->id == OM_MASTERWORK) { if (om->id == OM_MASTERWORK) {
switch (sk->id) { switch (sk->id) {
case SK_CLUBS: case SK_CLUBS:
@ -1352,66 +1390,70 @@ char *getobmodprefix(object_t *o, obmod_t *om) {
} }
} }
} else if (isshield(o)) { } else if (isshield(o)) {
if (om->id == OM_MASTERWORK) { if (!player || enoughperception || getskill(player, SK_SHIELDS)) {
switch (o->material->id) { if (om->id == OM_MASTERWORK) {
case MT_LEATHER: switch (o->material->id) {
return "studded "; case MT_LEATHER:
case MT_METAL: return "studded ";
case MT_WOOD: case MT_METAL:
case MT_DRAGONWOOD: case MT_WOOD:
return "reinforced "; case MT_DRAGONWOOD:
default: break; return "reinforced ";
} default: break;
} else if (om->id == OM_SHODDY) { }
switch (o->material->id) { } else if (om->id == OM_SHODDY) {
case MT_LEATHER: switch (o->material->id) {
case MT_RUBBER: case MT_LEATHER:
case MT_PAPER: case MT_RUBBER:
return "torn "; case MT_PAPER:
case MT_CLOTH: return "torn ";
case MT_SILK: case MT_CLOTH:
return "frayed "; case MT_SILK:
case MT_GLASS: return "frayed ";
case MT_STONE: case MT_GLASS:
case MT_BONE: case MT_STONE:
return "chipped "; case MT_BONE:
case MT_METAL: return "chipped ";
return "dented "; case MT_METAL:
case MT_WOOD: return "dented ";
case MT_DRAGONWOOD: case MT_WOOD:
return "splintered "; case MT_DRAGONWOOD:
default: break; return "splintered ";
default: break;
}
} }
} }
} else if (isarmour(o)) { } else if (isarmour(o)) {
if (om->id == OM_MASTERWORK) { if (!player || enoughperception || getskill(player, SK_ARMOUR)) {
switch (o->material->id) { if (om->id == OM_MASTERWORK) {
case MT_LEATHER: switch (o->material->id) {
return "studded "; case MT_LEATHER:
case MT_CLOTH: return "studded ";
case MT_SILK: case MT_CLOTH:
return "tailored "; case MT_SILK:
default: break; return "tailored ";
} default: break;
} else if (om->id == OM_SHODDY) { }
switch (o->material->id) { } else if (om->id == OM_SHODDY) {
case MT_LEATHER: switch (o->material->id) {
case MT_RUBBER: case MT_LEATHER:
case MT_PAPER: case MT_RUBBER:
return "torn "; case MT_PAPER:
case MT_CLOTH: return "torn ";
case MT_SILK: case MT_CLOTH:
return "frayed "; case MT_SILK:
case MT_GLASS: return "frayed ";
case MT_STONE: case MT_GLASS:
case MT_BONE: case MT_STONE:
return "chipped "; case MT_BONE:
case MT_METAL: return "chipped ";
return "dented "; case MT_METAL:
case MT_WOOD: return "dented ";
case MT_DRAGONWOOD: case MT_WOOD:
return "splintered "; case MT_DRAGONWOOD:
default: break; return "splintered ";
default: break;
}
} }
} }
} }
@ -1849,6 +1891,33 @@ int isvowel (char c) {
return B_FALSE; return B_FALSE;
} }
void killplural(plural_t *w) {
plural_t *nextone, *lastone;
// free mem
if (w->singular) free(w->singular);
if (w->plural) free(w->plural);
// remove from list
nextone = w->next;
if (nextone != NULL) {
nextone->prev = w->prev;
} else { /* last */
lastplural = w->prev;
}
if (w->prev == NULL) {
/* first */
nextone = w->next;
free(firstplural);
firstplural = nextone;
} else {
lastone = w->prev;
free (lastone->next );
lastone->next = nextone;
}
}
// return text for player's F_GUNTARGET flag eg. "goblin [acc:50%]" // return text for player's F_GUNTARGET flag eg. "goblin [acc:50%]"
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf) { void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf) {
char accbuf[BUFLEN]; char accbuf[BUFLEN];
@ -1932,75 +2001,14 @@ char *makeplural(char *text) {
char lastlet; char lastlet;
char *newtext; char *newtext;
int rv; int rv;
plural_t *pl;
newtext = strdup(text); newtext = strdup(text);
// scrolls for (pl = firstplural ; pl ; pl = pl->next) {
newtext = strrep(newtext, "bag ", "bags ", &rv); newtext = strrep(newtext, pl->singular, pl->plural, &rv);
if (rv) return newtext; if (rv && pl->stopafter) return newtext;
newtext = strrep(newtext, "berry ", "berries ", &rv); }
if (rv) return newtext;
newtext = strrep(newtext, "block ", "blocks ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "can ", "cans ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "chunk ", "chunks ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "cloud ", "clouds ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "clove ", "cloves ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "flask ", "flasks ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "gem ", "gems ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "knife", "knives", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "leaf", "leaves", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "loaf ", "loaves ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "lump ", "lumps ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "piece ", "pieces ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "pile ", "piles ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "pinch ", "pinches ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "plank ", "planks ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "pool ", "pools ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "potion ", "potions ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "puddle ", "puddles ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "puff ", "puffs ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "ring ", "rings ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "ruby", "rubies", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "scroll ", "scrolls ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "splash ", "splashes ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "set ", "sets ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "sheet ", "sheets ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "sprig ", "sprigs ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "suit ", "suits ", &rv);
if (rv) return newtext;
newtext = strrep(newtext, "vial ", "vials ", &rv);
if (rv) return newtext;
//
newtext = strrep(newtext, "pair ", "pairs ", &rv);
// don't return
// default // default
lastlet = text[strlen(text)-1]; lastlet = text[strlen(text)-1];

2
text.h
View File

@ -1,5 +1,6 @@
#include "defs.h" #include "defs.h"
plural_t *addplural(char *singulartext, char *pluraltext, int stopafter);
int needan(char *text); int needan(char *text);
char *capitalise(char *text); char *capitalise(char *text);
char *capitaliseall(char *text); char *capitaliseall(char *text);
@ -49,6 +50,7 @@ char *getweighttext(float weight, char *buf, int shortfmt);
char *is(lifeform_t *lf); char *is(lifeform_t *lf);
char *it(lifeform_t *lf); char *it(lifeform_t *lf);
int isvowel(char c); int isvowel(char c);
void killplural(plural_t *w);
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf); void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf);
char *makekillertext(char *retbuf, char *killverb, char *lastdam, map_t *where, int wantextra, int wantlocation); char *makekillertext(char *retbuf, char *killverb, char *lastdam, map_t *where, int wantextra, int wantlocation);
char *makelowercase(char *text); char *makelowercase(char *text);