- [+] bug: mammoan warrior with spear not agile enough to use starting

weapon!
- [+] new option when chatting:
    - [+] "care to trade knowledge?"
        - [+] works if:
            - [+] you have a skill which they don't know (or a spell
                  which they don't know)
                - [+] otherwise "there is nothing you can teach me."
            - [+] AND ONE OF
            - [+] works if they know a spell which you don't know (but
                  are able to learn)
            - [+] works if they have the same skills as you, but better,
            - [+] works if they have the a skill which you don't, AND
                  they are >= adept
                - [+] otherwise "i fear there is nothing useful i can
                      teach you"
        - [+] TEST
        - [+] can only do this once per person ("i have nothign more i
              can teach you")
        - [+] if high speech, you can pick what to learn. otherwise
              it's random.
        - [+] bug: human rogue asking to learn 'summon weapon' but not
              skilled in summoning!!!
        - [+] TEST AGAIN!
- [+] speech skill determines what you can ask people about!
    - [+] nov:any dangers?
    - [+] beg:any useful items around?
    - [+] ad:trade knowledge? 
    - [+] sk:join me?
    - [+] (but make skillchecks harder otherwise by the time you get
          the rigth speech skill level, you'll always pass!)
This commit is contained in:
Rob Pearce 2012-01-21 00:35:04 +00:00
parent 499ef0c0e1
commit fa9071ab69
6 changed files with 286 additions and 21 deletions

12
data.c
View File

@ -11549,12 +11549,12 @@ void initskills(void) {
addskilldesc(SK_SHIELDS, PR_EXPERT, "^gShield accuracy penalties are reduced by 5.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_EXPERT, "^gShield accuracy penalties are reduced by 5.^n", B_FALSE);
addskilldesc(SK_SHIELDS, PR_MASTER, "^gShield accuracy penalties are reduced by 6.^n", B_FALSE); addskilldesc(SK_SHIELDS, PR_MASTER, "^gShield accuracy penalties are reduced by 6.^n", B_FALSE);
addskill(SK_SPEECH, "Negotiation", "Your skill at haggling prices, or swaying others through speech.", 50); addskill(SK_SPEECH, "Negotiation", "Your skill at haggling prices, or swaying others through speech.", 50);
addskilldesc(SK_SPEECH, PR_NOVICE, "^gShop item prices are reduced by 5%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_INEPT, "- Each skill level reduces shop prices by 5%.", B_TRUE);
addskilldesc(SK_SPEECH, PR_BEGINNER, "^gShop item prices are reduced by 10%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_NOVICE, "^gYou can now question people about items on the current level.", B_TRUE);
addskilldesc(SK_SPEECH, PR_ADEPT, "^gShop item prices are reduced by 15%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_BEGINNER, "^gYou can now question people about nearby traps or monsters.", B_TRUE);
addskilldesc(SK_SPEECH, PR_SKILLED, "^gShop item prices are reduced by 20%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_ADEPT, "^gYou can now trade knowledge and spells with other people.", B_TRUE);
addskilldesc(SK_SPEECH, PR_EXPERT, "^gShop item prices are reduced by 25%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_SKILLED, "^gYou can now persuade people to join to as followers.", B_TRUE);
addskilldesc(SK_SPEECH, PR_MASTER, "^gShop item prices are reduced by 30%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_EXPERT, "^gYou can now choose which skills to learn from people.", B_TRUE);
addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50); addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50);
addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE); addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE);
addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE);

12
defs.h
View File

@ -281,6 +281,11 @@ enum RELATIVEDIR {
RD_SIDEWAYS, RD_SIDEWAYS,
}; };
enum TRADEINFOTYPE {
TI_SKILL,
TI_SPELL,
};
/////////////////////////////////////// ///////////////////////////////////////
// STRINGS // STRINGS
/////////////////////////////////////// ///////////////////////////////////////
@ -482,6 +487,11 @@ enum SAYPHRASE {
SP_RECRUIT_DECLINE_WONTPAY, SP_RECRUIT_DECLINE_WONTPAY,
SP_SORRY, SP_SORRY,
SP_THANKS, SP_THANKS,
SP_TRADEINFO_ACCEPT,
SP_TRADEINFO_CANCEL,
SP_TRADEINFO_DECLINE_ALREADYDONE,
SP_TRADEINFO_DECLINE_OTHERBAD,
SP_TRADEINFO_DECLINE_PLAYERBAD,
}; };
enum SPEECHVOL { enum SPEECHVOL {
@ -2437,6 +2447,8 @@ enum FLAG {
F_DONEDARKMSG, // tells the game not to say 'it is very dark here' F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
F_DONELISTEN, // supress further 'you hear xx' messages this turn. F_DONELISTEN, // supress further 'you hear xx' messages this turn.
// lifeform flags / lf flags / monster flags // lifeform flags / lf flags / monster flags
F_DONEKNOWLEDGETRADE, // you've already traded knowledge with this
// person.
F_FOLLOWTIME, // v0 = how long will ai chase you for? defaults to F_FOLLOWTIME, // v0 = how long will ai chase you for? defaults to
// DEF_AIFOLLOWTIME. // DEF_AIFOLLOWTIME.
F_BEHAVIOUR, // textual field describing special behaviour for this F_BEHAVIOUR, // textual field describing special behaviour for this

24
io.c
View File

@ -3725,17 +3725,25 @@ void docomms(lifeform_t *lf) {
} else if (ishirable(lf) ) { } else if (ishirable(lf) ) {
if (lfhasflag(lf, F_ISPRISONER)) { if (lfhasflag(lf, F_ISPRISONER)) {
addchoice(&prompt, 'j', "Join me, and I will help you escape.", NULL, NULL, NULL); addchoice(&prompt, 'j', "Join me, and I will help you escape.", NULL, NULL, NULL);
} else { } else if (getskill(player, SK_SPEECH) >= PR_SKILLED) {
addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL, NULL); addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL, NULL);
} }
} }
// TODO: allow you to ask this of allies, but only on the level they started on. if (!isgod(lf) && ispeaceful(lf) && cantalk(lf)) {
if (!areallies(player, lf) && !isgod(lf)) { enum SKILLLEVEL slev;
if (ispeaceful(lf) && cantalk(lf)) { slev = getskill(player, SK_SPEECH);
if (slev >= PR_NOVICE) {
addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL); addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL);
}
if (slev >= PR_BEGINNER) {
addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL); addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
} }
if (!areallies(player, lf)) {
if (slev >= PR_ADEPT) {
addchoice(&prompt, 'k', "Care to trade knowledge?", NULL, NULL, NULL);
}
}
} }
if (areenemies(player, lf)) { if (areenemies(player, lf)) {
@ -3973,7 +3981,7 @@ void docomms(lifeform_t *lf) {
break; break;
case 'i': case 'i':
msg("You say \"What can you tell me about this area?\" to %s.", lfname); msg("You say \"What can you tell me about this area?\" to %s.", lfname);
if (askforinfo(lf)) { if (askforinfo(lf, 2)) {
genareaknowledge(lf->flags, 0); genareaknowledge(lf->flags, 0);
docomms_areainfo(lfname, lf->flags, lf); docomms_areainfo(lfname, lf->flags, lf);
} }
@ -3987,6 +3995,10 @@ void docomms(lifeform_t *lf) {
} }
recruit(lf); recruit(lf);
break; break;
case 'k': // trade Knowledge
msg("You say \"Care to trade knowledge?\" to %s.", lfname);
tradeknowledge(lf);
break;
case 'm': // mercy case 'm': // mercy
msg("You say \"Have mercy!\" to %s.", lfname); msg("You say \"Have mercy!\" to %s.", lfname);
if (islowhp(player) && if (islowhp(player) &&
@ -4104,7 +4116,7 @@ void docomms(lifeform_t *lf) {
break; break;
case 'x': case 'x':
msg("You say \"Any dangers nearby that I should look out for?\" to %s.", lfname); msg("You say \"Any dangers nearby that I should look out for?\" to %s.", lfname);
if (askforinfo(lf)) { if (askforinfo(lf, 4)) {
genareaknowledge(lf->flags, 0); genareaknowledge(lf->flags, 0);
docomms_areadangers(lfname, lf->flags, lf); docomms_areadangers(lfname, lf->flags, lf);
} }

250
lf.c
View File

@ -8264,6 +8264,93 @@ char *getskilllevelname(enum SKILLLEVEL sl) {
} }
// get a list of of skills which teacher could teach student.
// returns # of potential skills found.
int getteachableskills(lifeform_t *teacher, lifeform_t *student, int *info, enum TRADEINFOTYPE *tradetype, int *ninfo ) {
flag_t *retflag[MAXCANDIDATES], *f;
int nretflags, i;
*ninfo = 0;
// 'teacher' can teach a skill to 'student' if:
// - teacher and student both know the skill, and teacher's skill level is higher.
// OR
// - only teacher has the skill, and teacher's skill level is >= adept.
getflags(teacher->flags, retflag, &nretflags, F_HASSKILL, F_NONE);
for (i = 0; i < nretflags; i++) {
enum SKILLLEVEL studentlev,teacherlev;
enum SKILL sid;
int teachable = B_FALSE;
f = retflag[i];
sid = f->val[0];
teacherlev = f->val[1];
studentlev = getskill(student, sid);
if (studentlev && (teacherlev > studentlev) && !ismaxedskill(student, sid)) {
teachable = B_TRUE;
} else if (!studentlev && (teacherlev >= PR_ADEPT)) {
teachable = B_TRUE;
}
if (teachable) {
info[*ninfo] = sid;
tradetype[*ninfo] = TI_SKILL;
(*ninfo)++;
}
}
// 'teacher' can teach a magic spell (oc_spell) to 'student' if:
// - teacher can will/cast the spell.
// AND
// - student can't already will/cast the spell
// AND
// - student is skilled in at least one of the spell's schools.
// AND
// - student is a high enough level to cast the spell.
// (use existing code from spellbooks!)
getflags(teacher->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE);
for (i = 0; i < nretflags; i++) {
objecttype_t *spell;
enum OBTYPE spellid;
enum SPELLSCHOOL knownschool;
int teachable = B_FALSE;
f = retflag[i];
spellid = f->val[0];
spell = findot(spellid);
if (spell->obclass->id != OC_SPELL) continue;
// student skilled in one of the spell's schools?
knownschool = getspellschoolknown(student, spellid);
if (getskill(student, getschoolskill(knownschool))) {
int mpneeded;
if (!cancast(student, spellid, &mpneeded) && (getspellpower(student, spellid) > 0)) {
if (getmaxmp(student) >= mpneeded) {
teachable = B_TRUE;
}
}
}
if (teachable) {
info[*ninfo] = spellid;
tradetype[*ninfo] = TI_SPELL;
(*ninfo)++;
}
}
return *ninfo;
}
char *gettradeinfoname(int what, enum TRADEINFOTYPE tradetype, char *buf) {
if (tradetype == TI_SKILL) {
skill_t *sk;
sk = findskill(what);
strcpy(buf, sk->name);
} else { // ie. spell
objecttype_t *ot;
ot = findot(what);
sprintf(buf, "the spell '%s'", ot->name);
}
return buf;
}
// get throw speed (ie. damage multiplier) // get throw speed (ie. damage multiplier)
// based on strength. // based on strength.
// //
@ -11801,7 +11888,7 @@ int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason) {
} }
// returns TRUE if 'lf' agrees to share knowledge with the player // returns TRUE if 'lf' agrees to share knowledge with the player
int askforinfo(lifeform_t *lf) { int askforinfo(lifeform_t *lf, int diffmod) {
if (lfhasflag(lf, F_NOINFO)) { if (lfhasflag(lf, F_NOINFO)) {
// refusing to give info // refusing to give info
sayphrase(lf, SP_INFO_REFUSE_AGAIN, SV_TALK, NA, NULL); sayphrase(lf, SP_INFO_REFUSE_AGAIN, SV_TALK, NA, NULL);
@ -11826,7 +11913,7 @@ int askforinfo(lifeform_t *lf) {
int result; int result;
int difficulty; int difficulty;
difficulty = 20 + ((gethitdice(player) - gethitdice(lf))*2); difficulty = 20 + diffmod + ((gethitdice(player) - gethitdice(lf))*2);
if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) { if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) {
askingprice = 0; askingprice = 0;
// passed - free! // passed - free!
@ -11962,7 +12049,8 @@ void autoskill(lifeform_t *lf) {
} }
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
if (isweapon(o) && canweild(lf, o)) { //if (isweapon(o) && canweild(lf, o)) {
if (isweapon(o)) {
sk = getobskill(o); sk = getobskill(o);
if (sk && !getskill(lf, sk->id)) { if (sk && !getskill(lf, sk->id)) {
giveskilllev(lf, sk->id, slev); giveskilllev(lf, sk->id, slev);
@ -11970,7 +12058,7 @@ void autoskill(lifeform_t *lf) {
// monsters:increase stats to match attribn requirements for starting // monsters:increase stats to match attribn requirements for starting
// weapon. // weapon.
if (!isplayer(lf)) { //if (!isplayer(lf)) {
getflags(o->flags, retflag, &nretflags, F_ATTREQ, F_NONE); getflags(o->flags, retflag, &nretflags, F_ATTREQ, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -11978,7 +12066,7 @@ void autoskill(lifeform_t *lf) {
setattr(lf, f->val[0], f->val[1]); setattr(lf, f->val[0], f->val[1]);
} }
} }
} //}
nweps++; nweps++;
} }
if (isfirearm(o) && canweild(lf, o)) { if (isfirearm(o) && canweild(lf, o)) {
@ -14177,7 +14265,9 @@ int recruit(lifeform_t *lf) {
int result; int result;
int difficulty; int difficulty;
int minmult,maxmult; int minmult,maxmult;
difficulty = 25 + ((gethitdice(player) - gethitdice(lf))*2); // since you have to be at least speech=4(skilled) to ask someone to
// join, add +8 to difficulty (pr_skilled * 2)
difficulty = 25 + 8 + ((gethitdice(player) - gethitdice(lf))*2);
if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) { if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) {
minmult = 10; minmult = 10;
maxmult = 20; maxmult = 20;
@ -14613,7 +14703,8 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
int i,rv = B_FALSE; int i,rv = B_FALSE;
char buf[BUFLEN]; char buf[BUFLEN];
char buf2[BUFLEN]; char buf2[BUFLEN];
char *p; char buf3[BUFLEN];
char *p,*p2;
race_t *r; race_t *r;
switch (what) { switch (what) {
case SP_ALLY_ATTACK: case SP_ALLY_ATTACK:
@ -14863,6 +14954,61 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
} }
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
case SP_TRADEINFO_ACCEPT:
p = text;
p2 = buf2;
while (*p != '^') {
*p2 = *p;
p++; p2++;
}
*p2 = '\0';
p++;
// next one...
p2 = buf3;
while (*p != '\0') {
*p2 = *p;
p++; p2++;
}
*p2 = '\0';
switch (rnd(1,2)) {
case 1: snprintf(buf, BUFLEN, "I'll train you in %s...", buf3); break;
case 2: snprintf(buf, BUFLEN, "I can teach you %s...", buf3); break;
}
strcat(buf, "if you teach me ");
strcat(buf, buf2);
rv = say(lf, buf, volume);
break;
case SP_TRADEINFO_CANCEL:
switch (rnd(1,2)) {
case 1: snprintf(buf, BUFLEN, "Maybe another time, then."); break;
case 2: snprintf(buf, BUFLEN, "Fair enough."); break;
}
rv = say(lf, buf, volume);
break;
case SP_TRADEINFO_DECLINE_ALREADYDONE:
switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "Thank you, but I have enough knowledge for now."); break;
case 2: snprintf(buf, BUFLEN, "I'm done with teaching for the moment."); break;
case 3: snprintf(buf, BUFLEN, "I'm sick of learning at the moment."); break;
}
rv = say(lf, buf, volume);
break;
case SP_TRADEINFO_DECLINE_OTHERBAD:
switch (rnd(1,2)) {
case 1: snprintf(buf, BUFLEN, "Thank you, but there is nothing I could teach you."); break;
case 2: snprintf(buf, BUFLEN, "I fear there is nothing you could learn from me."); break;
}
rv = say(lf, buf, volume);
break;
case SP_TRADEINFO_DECLINE_PLAYERBAD:
switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "You teach ME something? I think not."); break;
case 2: snprintf(buf, BUFLEN, "Sorry, I don't believe there is anything you could teach me."); break;
case 3: snprintf(buf, BUFLEN, "No thank you, there's nothing I need from you."); break;
}
rv = say(lf, buf, volume);
break;
default: default:
break; break;
} }
@ -17413,6 +17559,96 @@ void timeeffectslf(lifeform_t *lf) {
notime = B_FALSE; notime = B_FALSE;
} }
// returns TRUE if lf declines to teach.
int tradeknowledge(lifeform_t *lf) {
int poss[MAXCANDIDATES], fromplayer, toplayer;
enum TRADEINFOTYPE tradetype[MAXCANDIDATES],fromplayertype, toplayertype;
int nposs = 0,sel;
char buf[BUFLEN],tradetext[BUFLEN],lfname[BUFLEN],ch;
char fromplayertext[BUFLEN],toplayertext[BUFLEN];
getlfname(lf, lfname);
// already traded?
if (lfhasflag(lf, F_DONEKNOWLEDGETRADE)) {
sayphrase(lf, SP_TRADEINFO_DECLINE_ALREADYDONE, SV_TALK, NA, NULL);
return B_TRUE;
}
// does the player have a skill which lf needs?
getteachableskills(player, lf, poss, tradetype, &nposs);
if (nposs) {
sel = rnd(0,nposs-1);
fromplayer = poss[sel];
fromplayertype = tradetype[sel];
} else {
sayphrase(lf, SP_TRADEINFO_DECLINE_PLAYERBAD, SV_TALK, NA, NULL);
return B_TRUE;
}
// does lf have a skill which the player needs?
getteachableskills(lf, player, poss, tradetype, &nposs);
if (nposs) {
if (getskill(player, SK_SPEECH) >= PR_EXPERT) {
int i;
// you can pick which one to learn.
snprintf(buf, BUFLEN, "What would you like to learn from %s?",lfname);
initprompt(&prompt, buf);
ch = 'a';
for (i = 0; i < nposs; i++) {
gettradeinfoname(poss[i], tradetype[i], buf);
addchoice(&prompt, ch++, buf, NULL, NULL, NULL);
}
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
ch = getchoice(&prompt);
if (ch == '-') {
sayphrase(lf, SP_TRADEINFO_CANCEL, SV_TALK, NA, NULL);
return B_TRUE;
} else {
sel = ch - 'a';
}
} else {
sel = rnd(0,nposs-1);
}
toplayer = poss[sel];
toplayertype = tradetype[sel];
} else {
sayphrase(lf, SP_TRADEINFO_DECLINE_OTHERBAD, SV_TALK, NA, NULL);
return B_TRUE;
}
// at this point we can do a valid trade. make the offer.
// encode skill/spell names into a single string of the form:
// fromplayer^toplayer
gettradeinfoname(fromplayer, fromplayertype, fromplayertext);
gettradeinfoname(toplayer, toplayertype, toplayertext);
sprintf(tradetext, "%s^%s",fromplayertext,toplayertext);
sayphrase(lf, SP_TRADEINFO_ACCEPT, SV_TALK, NA, tradetext);
more();
// confirm.
sprintf(buf, "Learn %s from %s", toplayertext, lfname);
ch = askchar(buf, "yn","y", B_TRUE, B_FALSE);
if (ch == 'y') {
// lf learns skill
if (fromplayertype == TI_SKILL) {
giveskill(lf, fromplayer);
} else { // ie. spell
sprintf(buf, "pw:%d;", getspellpower(lf, fromplayer));
addflag(lf->flags, F_CANCAST, fromplayer, NA, NA, buf);
}
// player learns skill
if (toplayertype == TI_SKILL) {
giveskill(player, toplayer);
} else { // ie. spell
addflag(player->flags, F_CANCAST, toplayer, NA, NA, NULL);
}
// can't trade knowledge anymore
addflag(lf->flags, F_DONEKNOWLEDGETRADE, B_TRUE, NA, NA, NULL);
}
return B_FALSE;
}
// return B_TRUE on failure. // return B_TRUE on failure.
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat) { int tryclimb(lifeform_t *lf, cell_t *where, char *towhat) {
// if you have a rope or there's an adjacent wall, you can try // if you have a rope or there's an adjacent wall, you can try

5
lf.h
View File

@ -18,7 +18,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o);
int areallies(lifeform_t *lf1, lifeform_t *lf2); int areallies(lifeform_t *lf1, lifeform_t *lf2);
int areenemies(lifeform_t *lf1, lifeform_t *lf2); int areenemies(lifeform_t *lf1, lifeform_t *lf2);
int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason); int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason);
int askforinfo(lifeform_t *lf); int askforinfo(lifeform_t *lf, int diffmod);
int askforpayment(lifeform_t *shk, lifeform_t *lf); int askforpayment(lifeform_t *shk, lifeform_t *lf);
char *assignnpcname(lifeform_t *lf); char *assignnpcname(lifeform_t *lf);
void autoskill(lifeform_t *lf); void autoskill(lifeform_t *lf);
@ -241,6 +241,8 @@ float getstatmod(lifeform_t *lf, enum ATTRIB att);
char *getskilldesc(enum SKILL id ); char *getskilldesc(enum SKILL id );
char *getskillname(enum SKILL id ); char *getskillname(enum SKILL id );
char *getskilllevelname(enum SKILLLEVEL sl); char *getskilllevelname(enum SKILLLEVEL sl);
int getteachableskills(lifeform_t *teacher, lifeform_t *student, int *info, enum TRADEINFOTYPE *tradetype, int *ninfo );
char *gettradeinfoname(int what, enum TRADEINFOTYPE tradetype, char *buf);
int getthrowspeed(lifeform_t *lf); int getthrowspeed(lifeform_t *lf);
int getturnspeed(lifeform_t *lf); int getturnspeed(lifeform_t *lf);
void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking); void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking);
@ -418,6 +420,7 @@ int takeoff(lifeform_t *lf, object_t *o);
void taketime(lifeform_t *lf, long howlong); void taketime(lifeform_t *lf, long howlong);
int throwat(lifeform_t *thrower, object_t *o, cell_t *where); int throwat(lifeform_t *thrower, object_t *o, cell_t *where);
void timeeffectslf(lifeform_t *lf); void timeeffectslf(lifeform_t *lf);
int tradeknowledge(lifeform_t *lf);
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat); int tryclimb(lifeform_t *lf, cell_t *where, char *towhat);
int touch(lifeform_t *lf, object_t *o); int touch(lifeform_t *lf, object_t *o);
void turntoface(lifeform_t *lf, cell_t *dstcell); void turntoface(lifeform_t *lf, cell_t *dstcell);

View File

@ -10887,6 +10887,9 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) {
return buf; return buf;
} }
// at what power level COULD lf cast 'spellid' ?
// note: doesn't matter if the lf doesn't actually have f_cancast / f_canwill,
// in this case the function will return the POTENTIAL power.
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
int power = 0; int power = 0;
int spelllev; int spelllev;
@ -10896,7 +10899,6 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
int boost; int boost;
flag_t *f; flag_t *f;
if (db) { if (db) {
objecttype_t *ot; objecttype_t *ot;
ot = findot(spellid); ot = findot(spellid);