When selecting job, show recommendations based on race.

This commit is contained in:
Rob Pearce 2016-05-31 14:37:08 +10:00
parent 93257f8b4d
commit cb31db8fff
5 changed files with 194 additions and 18 deletions

4
data.c
View File

@ -451,7 +451,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, PR_SKILLED, NA, NULL);
// abilities // abilities
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
addjob(J_DRUID, "Druid", "Druids use the power of nature to aid themselves or harm others. They start with a pet wolf, and their spells are more powerful when near plants. They are willing to eat other lifeforms when neccessary but prefer a vegetable-based diet. Unlike other spellcasters, Druids gain spells automotically when levelling.", JC_FIGHTERMAGE); addjob(J_DRUID, "Druid", "Druids use the power of nature to aid themselves or harm others. They start with a pet wolf, and their spells are more powerful when near plants. They are willing to eat other lifeforms when neccessary but prefer a vegetable-based diet. Unlike other spellcasters, Druids gain spells automatically when levelling.", JC_FIGHTERMAGE);
// stats // stats
addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, 15, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, 15, NA, NULL);
@ -10793,6 +10793,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_METALWORK, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_METALWORK, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_ENGINEERING, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_ENGINEERING, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SS_ALLOMANCY, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_ALLOMANCY, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_RESISTMAG, 5, NA, NA, NULL);
// penalties // penalties
addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL); addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "1d6"); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "1d6");
@ -10951,6 +10952,7 @@ void initrace(void) {
// bonuses // bonuses
addflag(lastrace->flags, F_SEEINDARK, 6, B_BLINDABLE, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, B_BLINDABLE, NA, NULL);
addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_NECROTIC, NA, NA, NULL);
addflag(lastrace->flags, F_MPMOD, 3, NA, NA, NULL); addflag(lastrace->flags, F_MPMOD, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL);

6
defs.h
View File

@ -1130,6 +1130,12 @@ enum ATTRBRACKET {
AT_EXHIGH = 4, AT_EXHIGH = 4,
}; };
enum RECOMMENDATION {
R_VRECOMMENDED = 2,
R_RECOMMENDED = 1,
R_NOTRECOMMENDED = 0,
};
#define IQ_MINDLESS AT_EXLOW #define IQ_MINDLESS AT_EXLOW
#define IQ_ANIMAL AT_VLOW #define IQ_ANIMAL AT_VLOW

135
lf.c
View File

@ -3062,6 +3062,15 @@ int countlegs(lifeform_t *lf) {
return legs; return legs;
} }
int countmonsters(void) {
int count = 0;
race_t *r;
for (r = firstrace ; r ; r = r->next) {
count++;
}
return count;
}
int countnearbyallies(lifeform_t *lf) { int countnearbyallies(lifeform_t *lf) {
lifeform_t *l; lifeform_t *l;
int count = 0; int count = 0;
@ -8780,6 +8789,132 @@ char *getjobname(lifeform_t *lf) {
return ""; return "";
} }
int getjobrecommendation(race_t *r, job_t *j) {
int rec = 0;
flag_t *retflag[MAXCANDIDATES],*jobflag,*f;
int nretflags,i;
getflags(r->flags, retflag, &nretflags, F_STARTATT, F_STARTSKILL, F_NOSPELLS, F_NOSKILL, F_MPMOD, F_DTIMMUNE, F_DTRESIST, F_RESISTMAG, F_MPDICE, F_ARMOURRATING, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if ((f->id == F_STARTATT) && (f->val[1] != AT_RANDOM)) {
flag_t *jobflag;
jobflag = hasflagval(j->flags, F_JOBATTRMOD, f->val[0], NA, NA, NULL);
if (jobflag && (jobflag->val[1] != AT_RANDOM)) {
if ((f->val[1] >= AT_HIGH) && (jobflag->val[1] <= -10)) { // race high, job low = --
rec -= 1;
} else if ((f->val[1] >= AT_GTAVERAGE) && (jobflag->val[1] > 0)) { // race high, job high = ++
rec += 2;
} else if ((f->val[1] <= AT_LTAVERAGE) && (jobflag->val[1] > 0)) { // race low, job high = --
rec -= 2;
//} else if ((f->val[1] < 0) && (jobflag->val[1] < 0)) { // race low, job low = ----
// rec -= 2;
}
}
} else if (f->id == F_STARTSKILL) {
if (!isloreskill(f->val[0])) {
jobflag = hasflagval(j->flags, f->id, f->val[0], NA, NA, NULL);
if (jobflag) { // both race and job start with the same skill
rec++;
}
jobflag = hasflagval(j->flags, F_NOSKILL, f->val[0], NA, NA, NULL);
if (jobflag) { // race has a skill, job can't have that skill
rec -= 4;
}
// magic skill, and job has nomagic?
if (isspellskill(f->val[0]) && hasflag(j->flags, F_NOSPELLS)) {
rec -= 6;
}
}
} else if (f->id == F_ARMOURRATING) {
for (jobflag = j->flags->first ; jobflag ; jobflag = jobflag->next) {
if ((jobflag->id == F_STARTSKILL) && isweaponskill(jobflag->val[0])) {
rec += 1;
}
}
} else if ((f->id == F_DTIMMUNE) || (f->id == F_DTRESIST)) {
if (hasflag(j->flags, f->id)) {
rec += 2;
}
if ((f->val[0] == DT_FIRE) || (f->val[0] == DT_HEAT)) {
if (hasflagval(j->flags, F_STARTSKILL, SK_SS_FIRE, NA, NA, NULL)) {
rec += 4;
}
} else if (f->val[0] == DT_COLD) {
if (hasflagval(j->flags, F_STARTSKILL, SK_SS_COLD, NA, NA, NULL)) {
rec += 4;
}
} else if (f->val[0] == DT_NECROTIC) {
if (hasflagval(j->flags, F_STARTSKILL, SK_SS_DEATH, NA, NA, NULL)) {
rec += 4;
}
}
} else if (f->id == F_NOSPELLS) {
// both race and job can't us spells
if (hasflag(j->flags, f->id)) {
rec += 4;
}
// race can't have spells, and job has a magic skill?
// (SLOW search)
for (jobflag = j->flags->first ; jobflag ; jobflag = jobflag->next) {
if ((jobflag->id == F_STARTSKILL) && isspellskill(jobflag->val[0])) {
rec -= 2;
}
}
// job uses mp?
if (hasflag(j->flags, F_MPDICE)) {
rec -= 4;
}
} else if (f->id == F_MPMOD) {
jobflag = hasflag(j->flags, f->id);
if (f->val[0] < 0) { // mp penalty
if (jobflag && (jobflag->val[0] < 0)) {
rec += 4;
}
if (hasflag(j->flags, F_NOSPELLS)) {
rec += 6;
} else if (hasflag(j->flags, F_MPDICE)) {
rec -= 2;
}
} else if (f->val[0] > 0) { // mp bonus
if (jobflag && (jobflag->val[0] > 0)) {
rec += 4;
} else if (jobflag && (jobflag->val[0] < 0)) {
rec -= 4;
}
if (hasflag(j->flags, F_NOSPELLS)) {
rec -= 6;
} else if (hasflag(j->flags, F_MPDICE)) {
rec += 4;
}
}
} else if (f->id == F_RESISTMAG) {
if (hasflag(j->flags, f->id)) {
rec += 6;
}
} else if (f->id == F_MPDICE) {
if (hasflag(j->flags, F_NOSPELLS)) {
rec -= 4;
}
} else if (f->id == F_NOSKILL) {
jobflag = hasflagval(j->flags, F_STARTSKILL, f->val[0], NA, NA, NULL);
if (jobflag) { // race can't have a skill, job starts with it
rec -= 4;
}
jobflag = hasflagval(j->flags, F_CANLEARN, f->val[0], NA, NA, NULL);
if (jobflag) { // race can't have a skill, job can learn it
rec--;
}
jobflag = hasflagval(j->flags, F_NOSKILL, f->val[0], NA, NA, NULL);
if (jobflag) { // race can't have a skill, job can't have that skill
rec += 2;
}
}
}
return rec;
}
int getlastdir(lifeform_t *lf) { int getlastdir(lifeform_t *lf) {
flag_t *f; flag_t *f;
f = lfhasflag(lf, F_LASTDIR); f = lfhasflag(lf, F_LASTDIR);

2
lf.h
View File

@ -94,6 +94,7 @@ int continuedigging(lifeform_t *lf);
int continuerepairing(lifeform_t *lf, flag_t *repairflag); int continuerepairing(lifeform_t *lf, flag_t *repairflag);
int countinnateattacks(lifeform_t *lf); int countinnateattacks(lifeform_t *lf);
int countlegs(lifeform_t *lf); int countlegs(lifeform_t *lf);
int countmonsters(void);
int countnearbyallies(lifeform_t *lf); int countnearbyallies(lifeform_t *lf);
int countnearbyhurtallies(lifeform_t *lf); int countnearbyhurtallies(lifeform_t *lf);
int countplantsinsight(lifeform_t *lf); int countplantsinsight(lifeform_t *lf);
@ -208,6 +209,7 @@ job_t *getjob(lifeform_t *lf);
enum JOBCATEGORY getjobcat(lifeform_t *lf); enum JOBCATEGORY getjobcat(lifeform_t *lf);
//enum SUBJOB getsubjob(lifeform_t *lf); //enum SUBJOB getsubjob(lifeform_t *lf);
char *getjobname(lifeform_t *lf); char *getjobname(lifeform_t *lf);
int getjobrecommendation(race_t *r, job_t *j);
int getlastdir(lifeform_t *lf); int getlastdir(lifeform_t *lf);
int getleftrightwalls(lifeform_t *lf); int getleftrightwalls(lifeform_t *lf);
int getlfaccuracy(lifeform_t *lf, object_t *wep); int getlfaccuracy(lifeform_t *lf, object_t *wep);

33
nexus.c
View File

@ -269,12 +269,42 @@ int main(int argc, char **argv) {
if (!j) { if (!j) {
enum JOBCATEGORY jcid; enum JOBCATEGORY jcid;
int recommended;
// ask for job // ask for job
initprompt(&prompt, "Select your base job:"); initprompt(&prompt, "Select your base job:");
ch = 'a'; ch = 'a';
// sort by recommendaion, then by category
for (recommended = R_VRECOMMENDED ; recommended >= R_NOTRECOMMENDED; recommended--) {
switch (recommended) {
case R_VRECOMMENDED:
addheading(&prompt, "Highly Recommended");
break;
case R_RECOMMENDED:
addheading(&prompt, "Recommended");
break;
case R_NOTRECOMMENDED:
addheading(&prompt, "Not Recommended");
break;
default:
break;
}
for (jcid = JC_FIRST ; jcid <= JC_LAST; jcid++) { for (jcid = JC_FIRST ; jcid <= JC_LAST; jcid++) {
for (j = firstjob ; j ; j = j->next) { for (j = firstjob ; j ; j = j->next) {
if ((j->category == jcid) && jobpossible(startrace->flags, j->id)) { int rec,recok = B_FALSE;
if (j->id == J_GOD) {
rec = -50;
} else {
rec = getjobrecommendation(startrace, j);
}
if ((recommended == R_VRECOMMENDED) && (rec >= 3)) {
recok = B_TRUE;
} else if ((recommended == R_RECOMMENDED) && (rec >= 0) && (rec < 3)) {
recok = B_TRUE;
} else if ((recommended == R_NOTRECOMMENDED) && (rec < 0)) {
recok = B_TRUE;
}
if ((j->category == jcid) && recok && jobpossible(startrace->flags, j->id)) {
char *longdesc,buf[BUFLEN]; char *longdesc,buf[BUFLEN];
longdesc = malloc(HUGEBUFLEN * sizeof(char)); longdesc = malloc(HUGEBUFLEN * sizeof(char));
makedesc_job(j, longdesc); makedesc_job(j, longdesc);
@ -290,6 +320,7 @@ int main(int argc, char **argv) {
free(longdesc); free(longdesc);
} }
} }
} // end for jobcat
} }
j = NULL; j = NULL;
while (!j) { while (!j) {