- [+] auto swap places with peaceful lfs only if they are a lot smaller
- [+] prevent autoswap if there is somethign dangerous to the other lf in your cell - [+] sometime give monsters random loot (if they dont have f_nopack) - [+] stop sprinting and spellcasting if you slip. - [+] impement "C"ommunicate command - [+] ' with who'? * [+] list of options: - [+] can throw items TO allies - [+] improvements to getbestweapon() * [+] give xp for using can of insecticide - [+] fix monser spell casting - [+] in describeob, include BONUS for armour
This commit is contained in:
parent
290d91677e
commit
e9f752dd2f
91
ai.c
91
ai.c
|
@ -19,6 +19,45 @@ extern enum ERROR reason;
|
|||
|
||||
int wantdb = B_TRUE;
|
||||
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||
int db = B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
|
||||
if (db) {
|
||||
char lfname[BUFLEN],vicname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
getlfname(victim, vicname);
|
||||
dblog(".oO { %s settings new target: %s }", lfname, vicname);
|
||||
}
|
||||
|
||||
killflagsofid(lf->flags, F_TARGET);
|
||||
killflagsofid(lf->flags, F_TARGETCELL);
|
||||
|
||||
|
||||
if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) {
|
||||
addflag(lf->flags, F_TARGET, victim->id, victim->cell->x, victim->cell->y, NULL);
|
||||
} else {
|
||||
addtempflag(lf->flags, F_TARGET, victim->id , victim->cell->x , victim->cell->y, NULL,timelimit);
|
||||
}
|
||||
// tell the player
|
||||
if (cansee(player, lf)) {
|
||||
makenoise(lf, N_GETANGRY);
|
||||
}
|
||||
|
||||
|
||||
// change allegience ?
|
||||
if (!areenemies(lf, victim)) {
|
||||
if (getallegiance(victim) == AL_FRIENDLY) {
|
||||
if (!hasflag(lf->flags, F_HOSTILE)) {
|
||||
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
|
||||
flag_t *f;
|
||||
|
@ -199,6 +238,30 @@ object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void aigoto(lifeform_t *lf, cell_t *c, int timelimit) {
|
||||
int db = B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
|
||||
if (db) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
dblog(".oO { %s going to targecell: %d, %d }", lfname, c->x, c->y);
|
||||
}
|
||||
|
||||
killflagsofid(lf->flags, F_TARGET);
|
||||
killflagsofid(lf->flags, F_TARGETCELL);
|
||||
|
||||
|
||||
if ((timelimit == PERMENANT) || (timelimit == UNLIMITED)) {
|
||||
addflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL);
|
||||
} else {
|
||||
addtempflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL,timelimit);
|
||||
}
|
||||
}
|
||||
|
||||
void aimove(lifeform_t *lf) {
|
||||
int db = B_FALSE;
|
||||
object_t *curwep,*bestwep, *o;
|
||||
|
@ -231,7 +294,7 @@ void aimove(lifeform_t *lf) {
|
|||
|
||||
if (db) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
real_getlfname(lf, lfname, B_FALSE);
|
||||
dblog("AIMOVE: %s", lfname);
|
||||
}
|
||||
|
||||
|
@ -408,7 +471,7 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
if (spellfailed) {
|
||||
if (db) dblog(".oO { cast spell/ability tried but failed (2)! }");
|
||||
if (db) dblog(".oO { cast spell/ability tried but failed (2)! reason = %d }", reason);
|
||||
} else {
|
||||
// spell succesful
|
||||
return;
|
||||
|
@ -503,13 +566,17 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
cell_t *targcell;
|
||||
if (db) dblog(".oO { i cannot see my target. moving to last known loc %d/%d }",lastx,lasty);
|
||||
|
||||
// can't see target.
|
||||
// move towards their last known location instead
|
||||
addflag(lf->flags, F_TARGETCELL, lastx, lasty, NA, NULL);
|
||||
// remove f_target
|
||||
killflag(f);
|
||||
targcell = getcellat(lf->cell->map, lastx, lasty);
|
||||
if (targcell) {
|
||||
aigoto(lf, targcell, PERMENANT);
|
||||
} else {
|
||||
if (db) dblog(".oO { go to target's last known loc failed! }");
|
||||
}
|
||||
|
||||
/*
|
||||
// just try to move in a random direction
|
||||
|
@ -540,7 +607,7 @@ void aimove(lifeform_t *lf) {
|
|||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
} else {
|
||||
if (db) dblog(".oO { successfully walked towards f_targetcell. }");
|
||||
if (db) dblog(".oO { successfully walked towards f_targetcell. arrived at %d,%d }",lf->cell->x, lf->cell->y);
|
||||
// moved towards it.
|
||||
// reset lifetime
|
||||
f->lifetime = AI_FOLLOWTIME;
|
||||
|
@ -586,12 +653,8 @@ void aimove(lifeform_t *lf) {
|
|||
if (c->lf && cansee(lf, c->lf)) {
|
||||
if (isplayer(c->lf)) { // TODO: change to if isenemy ?
|
||||
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||
// target them!
|
||||
addtempflag(lf->flags, F_TARGET, c->lf->id, c->x, c->y, NULL, AI_FOLLOWTIME);
|
||||
// tell the player
|
||||
if (cansee(player, lf)) {
|
||||
makenoise(lf, N_GETANGRY);
|
||||
}
|
||||
|
||||
aiattack(lf, c->lf, AI_FOLLOWTIME);
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target }");
|
||||
|
||||
|
@ -1064,9 +1127,7 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
|
|||
|
||||
if (gothere) {
|
||||
// start walking towards target cell
|
||||
addtempflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL, AI_FOLLOWTIME);
|
||||
// forget about people we are attacking
|
||||
killflagsofid(lf->flags, F_TARGET);
|
||||
aigoto(lf, c, AI_FOLLOWTIME);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
2
ai.h
2
ai.h
|
@ -1,9 +1,11 @@
|
|||
#include "defs.h"
|
||||
|
||||
void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
|
||||
enum OBTYPE aigetfleespell(lifeform_t *lf);
|
||||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
||||
object_t * aigetwand(lifeform_t *lf, enum FLAG purpose);
|
||||
void aigoto(lifeform_t *lf, cell_t *c, int timelimit);
|
||||
void aimove(lifeform_t *lf);
|
||||
int aipickup(lifeform_t *lf, object_t *o);
|
||||
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target);
|
||||
|
|
4
defs.h
4
defs.h
|
@ -24,6 +24,7 @@ enum GAMEMODE {
|
|||
GM_LOADING,
|
||||
GM_LOADED,
|
||||
GM_GAMESTARTED,
|
||||
GM_GAMEOVER,
|
||||
};
|
||||
|
||||
enum ATTRIB {
|
||||
|
@ -1075,6 +1076,7 @@ enum FLAG {
|
|||
F_NONE, // dummy flag
|
||||
// object flags
|
||||
F_DEAD, // object will be removed
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
F_ENCHANTABLE, // object can get +1/-1 ect
|
||||
F_STACKABLE, // can stack multiple objects togethr
|
||||
F_NO_PLURAL, // this obname doesn't need an 's' for plurals (eg. gold, money)
|
||||
|
@ -1573,6 +1575,7 @@ enum ERROR {
|
|||
enum COMMAND {
|
||||
CMD_AIM,
|
||||
CMD_CLOSE,
|
||||
CMD_COMMS,
|
||||
CMD_DOWN,
|
||||
CMD_DROP,
|
||||
CMD_DROPMULTI,
|
||||
|
@ -1601,6 +1604,7 @@ enum COMMAND {
|
|||
CMD_RESTFULL,
|
||||
CMD_SAVEQUIT,
|
||||
CMD_TAKEOFF,
|
||||
CMD_THROW,
|
||||
CMD_UP,
|
||||
CMD_WEAR,
|
||||
CMD_WEILD,
|
||||
|
|
11
flag.c
11
flag.c
|
@ -307,7 +307,16 @@ void killflag(flag_t *f) {
|
|||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (f->pile->owner) {
|
||||
if (announceflagloss(f->pile->owner, f)) {
|
||||
interrupt(f->pile->owner);
|
||||
// don't include flags which interrupt will kill!
|
||||
switch (f->id) {
|
||||
case F_RESTING:
|
||||
case F_RUNNING:
|
||||
case F_AUTOCMD:
|
||||
break;
|
||||
default:
|
||||
interrupt(f->pile->owner);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (f->pile->ob) {
|
||||
announceobflagloss(f->pile->ob, f);
|
||||
|
|
204
io.c
204
io.c
|
@ -5,6 +5,7 @@
|
|||
#include <string.h>
|
||||
#include <ncurses.h>
|
||||
#include <unistd.h>
|
||||
#include "ai.h"
|
||||
#include "attack.h"
|
||||
#include "defs.h"
|
||||
#include "flag.h"
|
||||
|
@ -2227,7 +2228,9 @@ void describeob(object_t *o) {
|
|||
|
||||
f = hasflag(o->flags, F_ACCURACY);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It has %s accuracy.",getaccuracyname(f->val[0]));
|
||||
int acc;
|
||||
acc = getobaccuracy(o, NULL);
|
||||
mvwprintw(mainwin, y, 0, "It has %s accuracy.",getaccuracyname(acc));
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -2236,7 +2239,7 @@ void describeob(object_t *o) {
|
|||
if (isarmour(o)) {
|
||||
f = hasflag(o->flags, F_ARMOURRATING);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It has an Armour Rating of %d.",f->val[0]);
|
||||
mvwprintw(mainwin, y, 0, "It has an Armour Rating of %d.",f->val[0] + getobbonus(o));
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_GOESON);
|
||||
|
@ -2690,15 +2693,134 @@ void doclose(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void dodrop(obpile_t *op, int wantmulti) {
|
||||
void docomms(void) {
|
||||
lifeform_t *lf = NULL;
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
char ch;
|
||||
|
||||
where = askcoords("Talk to who?", TT_MONSTER);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
if (!lf) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
getlfname(lf, lfname);
|
||||
|
||||
sprintf(buf, "What will you say to %s?",lfname);
|
||||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
// are they friendly?
|
||||
if (areallies(player, lf)) {
|
||||
addchoice(&prompt, 'a', "Attack something", NULL, NULL);
|
||||
if (!isadjacent(lf->cell, player->cell)) {
|
||||
addchoice(&prompt, 'c', "Come here", NULL, NULL);
|
||||
}
|
||||
if (isadjacent(lf->cell, player->cell)) {
|
||||
addchoice(&prompt, 't', "Trade items with me", NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL);
|
||||
}
|
||||
addchoice(&prompt, 'n', "(nothing)", NULL, NULL);
|
||||
|
||||
ch = getchoice(&prompt);
|
||||
switch (ch) {
|
||||
cell_t *c;
|
||||
lifeform_t *lf2 = NULL;
|
||||
char lfname2[BUFLEN];
|
||||
case 'a':
|
||||
sprintf(buf, "Tell %s to attack who?",lfname);
|
||||
c = askcoords(buf, TT_MONSTER);
|
||||
if (c && c->lf && cansee(player, c->lf)) {
|
||||
lf2 = c->lf;
|
||||
|
||||
}
|
||||
if (!lf2) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
getlfname(lf2, lfname2);
|
||||
msg("You say \"Attack %s!\" to %s.",lfname2, lfname);
|
||||
aiattack(lf, lf2, AI_FOLLOWTIME);
|
||||
break;
|
||||
case 'c':
|
||||
msg("You say \"Come here!\" to %s.",lfname);
|
||||
// find adjacent cell
|
||||
c = getrandomadjcell(player->cell, WE_NOTSOLID);
|
||||
if (c) {
|
||||
aigoto(lf, c, AI_FOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
case 't':
|
||||
// ask whtehr to give/take
|
||||
initprompt(&prompt, "How will you trade?");
|
||||
sprintf(buf, "Give items to %s",lfname);
|
||||
addchoice(&prompt, 'i', buf, NULL, NULL);
|
||||
sprintf(buf, "Take items from %s",lfname);
|
||||
addchoice(&prompt, 'o', buf, NULL, NULL);
|
||||
sprintf(buf, "Both");
|
||||
addchoice(&prompt, 'b', buf, NULL, NULL);
|
||||
sprintf(buf, "Neither");
|
||||
addchoice(&prompt, 'n', buf, NULL, NULL);
|
||||
ch = getchoice(&prompt);
|
||||
switch (ch) {
|
||||
case 'i':
|
||||
dodrop(player->pack, B_MULTIPLE, lf->pack);
|
||||
break;
|
||||
case 'o':
|
||||
dopickup(lf->pack);
|
||||
break;
|
||||
case 'b':
|
||||
dodrop(player->pack, B_MULTIPLE, lf->pack);
|
||||
dopickup(lf->pack);
|
||||
break;
|
||||
case 'n':
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'y':
|
||||
msg("You shout at %s!", lfname);
|
||||
noise(where, player, "someone shouting!", NULL);
|
||||
break;
|
||||
}
|
||||
taketime(player, getactspeed(player));
|
||||
}
|
||||
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
|
||||
object_t *o;
|
||||
char buf[BUFLEN];
|
||||
int count = ALL;
|
||||
int i;
|
||||
if (wantmulti) {
|
||||
askobjectmulti(op, "Drop what", AO_NONE);
|
||||
lifeform_t *tolf = NULL;
|
||||
char lfname[BUFLEN];
|
||||
|
||||
|
||||
// where is destination?
|
||||
if (dst->owner) {
|
||||
tolf = dst->owner;
|
||||
getlfname(tolf, lfname);
|
||||
} else {
|
||||
o = askobject(op, "Drop what", &count, AO_NONE);
|
||||
// on ground
|
||||
}
|
||||
|
||||
if (tolf) {
|
||||
sprintf(buf, "Give what to %s",lfname);
|
||||
} else {
|
||||
strcpy(buf, "Drop what");
|
||||
}
|
||||
|
||||
if (wantmulti) {
|
||||
askobjectmulti(op, buf, AO_NONE);
|
||||
} else {
|
||||
o = askobject(op, buf, &count, AO_NONE);
|
||||
if (o) {
|
||||
retobs[0] = o;
|
||||
retobscount[0] = count;
|
||||
|
@ -2726,7 +2848,13 @@ void dodrop(obpile_t *op, int wantmulti) {
|
|||
if (f->val[0] == BP_WEAPON) {
|
||||
// first try to unweild it
|
||||
if (unweild(player, o)) {
|
||||
if (nretobs > 1) msg("Not dropping %s.",buf); more();
|
||||
if (nretobs > 1) {
|
||||
if (tolf) {
|
||||
msg("Not giving %s to %s.",buf, lfname); more();
|
||||
} else {
|
||||
msg("Not dropping %s.",buf); more();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else { // armour
|
||||
|
@ -2738,12 +2866,24 @@ void dodrop(obpile_t *op, int wantmulti) {
|
|||
if (ch == 'y') {
|
||||
if (takeoff(player, o)) {
|
||||
// failed to take it off - can't drop it.
|
||||
if (nretobs > 1) msg("Not dropping %s.",buf); more();
|
||||
if (nretobs > 1) {
|
||||
if (tolf) {
|
||||
msg("Not giving %s to %s.",buf, lfname); more();
|
||||
} else {
|
||||
msg("Not dropping %s.",buf); more();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
}
|
||||
} else {
|
||||
if (nretobs > 1) msg("Not dropping %s.",buf); more();
|
||||
if (nretobs > 1) {
|
||||
if (tolf) {
|
||||
msg("Not giving %s to %s.",buf, lfname); more();
|
||||
} else {
|
||||
msg("Not dropping %s.",buf); more();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2751,7 +2891,17 @@ void dodrop(obpile_t *op, int wantmulti) {
|
|||
|
||||
if (count == ALL) count = o->amt;
|
||||
|
||||
drop(o, count);
|
||||
if (tolf) {
|
||||
o = moveob(o, dst, count);
|
||||
if (o) {
|
||||
getobname(o, buf, o->amt);
|
||||
msg("%s takes %s from you.",lfname, buf);
|
||||
} else {
|
||||
msg("%s can't carry that.",lfname);
|
||||
}
|
||||
} else {
|
||||
drop(o, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3364,21 +3514,39 @@ int dopickup(obpile_t *op) {
|
|||
//object_t *o = NULL;
|
||||
int howmany = ALL;
|
||||
int i;
|
||||
lifeform_t *fromlf = NULL;
|
||||
char lfname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
|
||||
if (op->owner) {
|
||||
fromlf = op->owner;
|
||||
getlfname(fromlf, lfname);
|
||||
}
|
||||
|
||||
|
||||
obcount = countobs(op);
|
||||
// anything here?
|
||||
if (obcount == 0) {
|
||||
msg("There is nothing here to pick up!");
|
||||
if (fromlf) {
|
||||
msg("%s is not carrying anything!", lfname);
|
||||
} else {
|
||||
msg("There is nothing here to pick up!");
|
||||
}
|
||||
return B_TRUE;
|
||||
} else if ((obcount == 1) && (op->first->amt == 1)) {
|
||||
} else if (!fromlf && (obcount == 1) && (op->first->amt == 1)) {
|
||||
// just get it
|
||||
howmany = ALL;
|
||||
retobs[0] = op->first;
|
||||
retobscount[0] = op->first->amt;
|
||||
nretobs = 1;
|
||||
} else {
|
||||
if (fromlf) {
|
||||
sprintf(buf, "Take what from %s",lfname);
|
||||
} else {
|
||||
strcpy(buf, "Pick up what");
|
||||
}
|
||||
// prompt which one to pick up
|
||||
askobjectmulti(op, "Pick up what", AO_NONE);
|
||||
askobjectmulti(op, buf, AO_NONE);
|
||||
}
|
||||
|
||||
if (nretobs <= 0) {
|
||||
|
@ -4771,14 +4939,17 @@ void handleinput(void) {
|
|||
addflag(player->flags, F_LASTCMD, NA, NA, NA, temp);
|
||||
doclose();
|
||||
break;
|
||||
case 'C': // communicate
|
||||
docomms();
|
||||
break;
|
||||
case 'e': // eat
|
||||
doeat(player->pack);
|
||||
break;
|
||||
case 'd': // drop
|
||||
dodrop(player->pack, B_SINGLE);
|
||||
dodrop(player->pack, B_SINGLE, player->cell->obpile);
|
||||
break;
|
||||
case 'D': // drop multiple things
|
||||
dodrop(player->pack, B_MULTIPLE);
|
||||
dodrop(player->pack, B_MULTIPLE, player->cell->obpile);
|
||||
break;
|
||||
case 'W': // wear
|
||||
dowear(player->pack);
|
||||
|
@ -6403,6 +6574,9 @@ void tombstone(lifeform_t *lf) {
|
|||
int y;
|
||||
char *p, *dummy;
|
||||
|
||||
|
||||
gamemode = GM_GAMEOVER;
|
||||
|
||||
getplayernamefull(pname);
|
||||
|
||||
// clear screen
|
||||
|
|
3
io.h
3
io.h
|
@ -31,7 +31,8 @@ int contains(enum OBCLASS *array, int nargs, enum OBCLASS want);
|
|||
void describeob(object_t *o);
|
||||
void doattackcell(char dirch);
|
||||
void doclose(void);
|
||||
void dodrop(obpile_t *op, int wantmulti);
|
||||
void docomms(void);
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst);
|
||||
void doeat(obpile_t *op);
|
||||
void doenter(lifeform_t *lf);
|
||||
void doexplain(void);
|
||||
|
|
112
lf.c
112
lf.c
|
@ -394,24 +394,33 @@ int areallies(lifeform_t *lf1, lifeform_t *lf2) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// make sure player has at least novice skill in their start weapon
|
||||
// make sure player has at least novice skill in all their start weapons
|
||||
void autoskill(lifeform_t *lf) {
|
||||
object_t *wep;
|
||||
skill_t *sk;
|
||||
wep = getweapon(lf);
|
||||
if (wep) {
|
||||
sk = getobskill(wep);
|
||||
object_t *o;
|
||||
enum SKILLLEVEL slev;
|
||||
int nweps = 0;
|
||||
|
||||
if (isplayer(lf)) {
|
||||
slev = PR_NOVICE;
|
||||
} else {
|
||||
sk = findskill(SK_UNARMED);
|
||||
slev = PR_ADEPT;
|
||||
}
|
||||
|
||||
if (sk) {
|
||||
if (isplayer(lf)) {
|
||||
giveskilllev(lf, sk->id, PR_NOVICE);
|
||||
} else {
|
||||
giveskilllev(lf, sk->id, PR_ADEPT);
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (isweapon(o) && canweild(lf, o)) {
|
||||
sk = getobskill(o);
|
||||
if (sk) {
|
||||
giveskilllev(lf, sk->id, slev);
|
||||
}
|
||||
nweps++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nweps) {
|
||||
giveskilllev(lf, SK_UNARMED, slev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void autotarget(lifeform_t *lf) {
|
||||
|
@ -523,9 +532,6 @@ void autoweild(lifeform_t *lf) {
|
|||
|
||||
// make sure it doesn't take any time
|
||||
lf->timespent = pretimespent;
|
||||
|
||||
// make sure we are skilled in this.
|
||||
autoskill(lf);
|
||||
}
|
||||
|
||||
int appearsrandomly(enum RACE rid) {
|
||||
|
@ -1750,7 +1756,7 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
|
|||
} else {
|
||||
lifeform_t *l;
|
||||
|
||||
setlftarget(lf, attacker);
|
||||
aiattack(lf, attacker, AI_FOLLOWTIME);
|
||||
|
||||
// any nearby monsters which will help out?
|
||||
if (getallegiance(lf) != AL_FRIENDLY) {
|
||||
|
@ -1758,7 +1764,7 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
|
|||
if (l->race->baseid == lf->race->baseid) {
|
||||
if (!isdead(l) && areallies(l,lf)) {
|
||||
if (cansee(l, attacker)) {
|
||||
setlftarget(l, attacker);
|
||||
aiattack(l, attacker, AI_FOLLOWTIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2589,52 +2595,26 @@ int getlfaccuracy(lifeform_t *lf) {
|
|||
// get weapon
|
||||
wep = getweapon(lf);
|
||||
if (wep) {
|
||||
acc = getobaccuracy(wep);
|
||||
acc = getobaccuracy(wep, lf);
|
||||
} else {
|
||||
// ie. unarmed
|
||||
op = getunarmedweapon(lf, NULL);
|
||||
|
||||
if (op->first) {
|
||||
wep = op->first;
|
||||
acc = getobaccuracy(wep);
|
||||
acc = getobaccuracy(wep, lf);
|
||||
} else {
|
||||
// cannot attack
|
||||
acc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// modify for skill level
|
||||
if (wep) {
|
||||
skill_t *sk;
|
||||
sk = getobskill(wep);
|
||||
if (sk) {
|
||||
switch (getskill(lf, sk->id)) {
|
||||
case PR_INEPT:
|
||||
acc -= 75;
|
||||
break;
|
||||
case PR_NOVICE:
|
||||
acc -= 25;
|
||||
break;
|
||||
case PR_BEGINNER:
|
||||
acc -= 5;
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
break;
|
||||
case PR_SKILLED:
|
||||
acc += 25;
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
acc += 50;
|
||||
break;
|
||||
case PR_MASTER:
|
||||
acc += 75;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op) killobpile(op);
|
||||
|
||||
// modify for weilder's level
|
||||
acc += (lf->level * 2);
|
||||
|
||||
|
||||
// modify with dexterity
|
||||
acc += getstatmod(lf, A_DEX);
|
||||
|
||||
|
@ -3014,11 +2994,15 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) {
|
|||
}
|
||||
|
||||
char *getlfnamea(lifeform_t *lf, char *buf) {
|
||||
return real_getlfnamea(lf, buf, B_TRUE);
|
||||
}
|
||||
|
||||
char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis) {
|
||||
if (lf == player) {
|
||||
sprintf(buf, "you");
|
||||
} else {
|
||||
char buf2[BUFLEN];
|
||||
getlfname(lf, buf2);
|
||||
real_getlfname(lf, buf2, usevis);
|
||||
sprintf(buf, "%s %s",
|
||||
isvowel(lf->race->name[0]) ? "an" : "a",
|
||||
noprefix(buf2));
|
||||
|
@ -3662,6 +3646,7 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
|
|||
// now give start obs/skills from it
|
||||
givestartobs(lf, lf->flags);
|
||||
givestartskills(lf, lf->flags);
|
||||
autoskill(lf);
|
||||
|
||||
|
||||
// override hp/mp from race
|
||||
|
@ -4255,6 +4240,7 @@ int haslof(lifeform_t *viewer, cell_t *dest, enum LOFTYPE loftype, cell_t **newd
|
|||
cell_t *retcell[MAXRETCELLS];
|
||||
|
||||
reason = E_OK;
|
||||
if (newdest) *newdest = viewer->cell;
|
||||
|
||||
if (!viewer) return B_FALSE;
|
||||
if (!viewer->cell) return B_FALSE;
|
||||
|
@ -4279,8 +4265,6 @@ int haslof(lifeform_t *viewer, cell_t *dest, enum LOFTYPE loftype, cell_t **newd
|
|||
calcbresnham(map, x1, y1, x2, y2, retcell, &numpixels);
|
||||
|
||||
|
||||
if (newdest) *newdest = viewer->cell;
|
||||
|
||||
for (i = 0; i < numpixels ; i++) {
|
||||
cell_t *cell;
|
||||
object_t *blockob;
|
||||
|
@ -4512,6 +4496,9 @@ void initjobs(void) {
|
|||
}
|
||||
}
|
||||
addjob(J_ADVENTURER, "Adventurer");
|
||||
addflag(lastjob->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "short sword");
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas");
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
|
||||
|
@ -6548,6 +6535,7 @@ void noise(cell_t *c, lifeform_t *noisemaker, char *text, char *seetext) {
|
|||
void outfitlf(lifeform_t *lf) {
|
||||
givestartobs(lf, lf->flags);
|
||||
givestartskills(lf, lf->flags);
|
||||
autoskill(lf);
|
||||
|
||||
// weild/wear stuff
|
||||
autoweild(lf);
|
||||
|
@ -7346,6 +7334,8 @@ void interrupt(lifeform_t *lf) {
|
|||
stoprunning(lf);
|
||||
killflagsofid(lf->flags, F_AUTOCMD);
|
||||
}
|
||||
|
||||
/*j
|
||||
void setlftarget(lifeform_t *lf, lifeform_t *victim) {
|
||||
// first remove existing targets
|
||||
killflagsofid(lf->flags, F_TARGET);
|
||||
|
@ -7362,6 +7352,7 @@ void setlftarget(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int shoot(lifeform_t *lf) {
|
||||
object_t *gun,*ammo;
|
||||
|
@ -7562,6 +7553,10 @@ int slipon(lifeform_t *lf, object_t *o) {
|
|||
moveob(o, new->obpile, 1);
|
||||
}
|
||||
}
|
||||
// stop sprinting
|
||||
killflagsofid(lf->flags, F_SPRINTING);
|
||||
// boost spells end
|
||||
stopallspells(lf);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -8061,9 +8056,22 @@ void turneffectslf(lifeform_t *lf) {
|
|||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
int dam;
|
||||
flag_t *fromlfflag;
|
||||
lifeform_t *fromlf = NULL;
|
||||
char damstring[BUFLEN];
|
||||
|
||||
dam = roll(f->text);
|
||||
getobname(o, buf, o->amt);
|
||||
dam = losehp(lf, dam, f->val[0], NULL, buf);
|
||||
|
||||
fromlfflag = hasflag(o->flags, F_CREATEDBY);
|
||||
if (fromlfflag) {
|
||||
sprintf(damstring, "%s^created by %s",buf, fromlfflag->text);
|
||||
} else {
|
||||
strcpy(damstring, buf);
|
||||
}
|
||||
|
||||
|
||||
dam = losehp(lf, dam, f->val[0], fromlf, damstring);
|
||||
if (dam > 0) {
|
||||
if (f->val[0] == DT_POISONGAS) {
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
|
|
3
lf.h
3
lf.h
|
@ -94,6 +94,7 @@ lifeform_t *getnearbypeaceful(lifeform_t *lf);
|
|||
char *getlfname(lifeform_t *lf, char *buf);
|
||||
char *real_getlfname(lifeform_t *lf, char *buf, int usevis);
|
||||
char *getlfnamea(lifeform_t *lf, char *buf);
|
||||
char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis);
|
||||
enum LFSIZE getlfsize(lifeform_t *lf);
|
||||
float getlfweight(lifeform_t *lf, int withobs);
|
||||
int getspellspeed(lifeform_t *lf);
|
||||
|
@ -188,7 +189,7 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
|||
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
||||
void setrace(lifeform_t *lf, enum RACE rid);
|
||||
void setlastdam(lifeform_t *lf, char *buf);
|
||||
void setlftarget(lifeform_t *lf, lifeform_t *victim);
|
||||
//void setlftarget(lifeform_t *lf, lifeform_t *victim);
|
||||
int shoot(lifeform_t *lf);
|
||||
int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod);
|
||||
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result);
|
||||
|
|
181
log.txt
181
log.txt
|
@ -7,7 +7,6 @@ xxx
|
|||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
|
@ -116,3 +115,183 @@ finding random lf with rarity val 85-100
|
|||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
finding random lf with rarity val 85-100
|
||||
|
||||
-> possibility: goblin, rarity=85
|
||||
-> possibility: xat, rarity=90
|
||||
-> possibility: giant bat, rarity=90
|
||||
-> possibility: giant worker ant, rarity=85
|
||||
-> possibility: giant newt, rarity=100
|
||||
-> possibility: giant rat, rarity=90
|
||||
-> possibility: brown snake, rarity=85
|
||||
-> possibility: giant fly, rarity=85
|
||||
-> possibility: glowbug, rarity=85
|
||||
got 9 possibilities.
|
||||
rollhitdice() - rolling 2d4 + 2
|
||||
rollhitdice() - mod is +-5%
|
||||
rollhitdice() ---- die 1/2 == 5
|
||||
rollhitdice() ---- die 2/2 == 6
|
||||
TOTAL: 11
|
||||
-> modified to: 11
|
||||
givejob() starting.
|
||||
|
||||
processing normal flag: 186
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 145
|
||||
processing normal flag: 146
|
||||
processing normal flag: 146
|
||||
processing normal flag: 146
|
||||
processing normal flag: 146
|
||||
processing normal flag: 146
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 213
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
processing normal flag: 212
|
||||
fireat(): dam = throwdam(2) * speed(2) = 4
|
||||
AIMOVE: something
|
||||
.oO { looking for covetted objects... }
|
||||
.oO { no targetcell, so looking for remote objects }
|
||||
.oO { didn't find any obs i want }
|
||||
.oO { i have a target... }
|
||||
.oO { my target is lfid 31 (human). }
|
||||
.oO { i cannot see my target. moving to last known loc 12/15 }
|
||||
.oO { something going to targecell: 12, 15 }
|
||||
.oO { walking from 12,17 towards f_targetcell (12,15) ... }
|
||||
.oO { successfully walked towards f_targetcell. }
|
||||
AIMOVE: something
|
||||
.oO { looking for covetted objects... }
|
||||
.oO { didn't find any obs i want }
|
||||
.oO { walking from 11,18 towards f_targetcell (12,15) ... }
|
||||
.oO { successfully walked towards f_targetcell. }
|
||||
|
|
13
map.c
13
map.c
|
@ -167,6 +167,19 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt) {
|
|||
}
|
||||
free(moncell);
|
||||
}
|
||||
|
||||
// sometimes give the lf random objects (extra monsters through
|
||||
// 'numappears' don't get them.
|
||||
if (!lfhasflag(lf, F_NOPACK)) {
|
||||
if (rnd(1,3) == 1) {
|
||||
int nobs = rnd(1,3);
|
||||
char buf[BUFLEN];
|
||||
int i;
|
||||
for (i = 0; i < nobs; i++) {
|
||||
if (getrandomob(c->map, buf)) addob(lf->pack, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
lf->born = B_TRUE;
|
||||
} // end if lf
|
||||
}
|
||||
|
|
113
move.c
113
move.c
|
@ -81,24 +81,53 @@ int canmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
|
||||
// lf is the one moving, lf2 is the one who is being forced to swap
|
||||
int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
|
||||
// player can never be forced to swap
|
||||
if (isplayer(lf2)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
// cannot swap if lf's cell is dangerous to lf2
|
||||
if (celldangerous(lf2, lf->cell, B_FALSE, NULL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// allies can always swap
|
||||
if (areallies(lf, lf2)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isplayer(lf) && !areenemies(lf, lf2)) {
|
||||
// player can swap with peaceful lgs
|
||||
// if they are a lot smaller
|
||||
if (getlfsize(lf) - getlfsize(lf2) >= 2) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// will populate rdata
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
||||
// onlyifknown = true means "check for _known_ dangerous objects"
|
||||
// onlyifknown = false means "check for _any dangerous objects, doesn't matter if we know about them"
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *error) {
|
||||
enum IQBRACKET iq;
|
||||
int include_nonobvious = B_FALSE;
|
||||
flag_t *f;
|
||||
object_t *o;
|
||||
|
||||
// default
|
||||
if (error) {
|
||||
*error = E_OK;
|
||||
rdata = NULL;
|
||||
}
|
||||
|
||||
// check for _known_ dangerous objects
|
||||
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||
if ((iq >= IQ_AVERAGE) && !isblind(lf)) {
|
||||
flag_t *f;
|
||||
object_t *o;
|
||||
// obvious things that you can see
|
||||
if (!onlyifknown || haslos(lf, cell)) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
// don't walk on sharp objects without boots
|
||||
if (hasflag(o->flags, F_SHARP)) {
|
||||
if (!getequippedob(lf->pack, BP_FEET)) {
|
||||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
// are we immune to this?
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[0], NA, NA, NULL)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
|
@ -106,10 +135,23 @@ int celldangerous(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
// are we immune to this?
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[0], NA, NA, NULL)) {
|
||||
}
|
||||
}
|
||||
|
||||
// non-obvious things - only include these if we are smart enough
|
||||
if (!onlyifknown) {
|
||||
include_nonobvious = B_TRUE;
|
||||
} else {
|
||||
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||
if ((iq >= IQ_AVERAGE) && haslos(lf, cell)) {
|
||||
include_nonobvious = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (include_nonobvious) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
// don't walk on sharp objects without boots
|
||||
if (hasflag(o->flags, F_SHARP)) {
|
||||
if (!getequippedob(lf->pack, BP_FEET)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
|
@ -616,7 +658,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
if (haslos(l, newcell)) {
|
||||
int dointerrupt = B_FALSE;
|
||||
|
||||
|
||||
if (isplayer(l)) {
|
||||
if (areenemies(lf, l)) {
|
||||
if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_RESTING)) {
|
||||
|
@ -1213,31 +1254,31 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
break;
|
||||
case E_LFINWAY:
|
||||
if (areallies(lf, cell->lf)) {
|
||||
// if it's the player in the way...
|
||||
if (isplayer(cell->lf)) {
|
||||
return attacklf(lf, cell->lf);
|
||||
} else {
|
||||
lifeform_t *lfinway;
|
||||
cell_t *oldcell;
|
||||
// otherwise swap locations.
|
||||
if (canswapwith(lf, cell->lf)) {
|
||||
lifeform_t *lfinway;
|
||||
cell_t *oldcell;
|
||||
// otherwise swap locations.
|
||||
|
||||
// make lf who is there vanish temporarily...
|
||||
lfinway = cell->lf;
|
||||
cell->lf = NULL;
|
||||
lfinway->cell = NULL;
|
||||
// make lf who is there vanish temporarily...
|
||||
lfinway = cell->lf;
|
||||
cell->lf = NULL;
|
||||
lfinway->cell = NULL;
|
||||
|
||||
// remember your cell
|
||||
oldcell = lf->cell;
|
||||
// remember your cell
|
||||
oldcell = lf->cell;
|
||||
|
||||
// move you..
|
||||
moveto(lf, cell, onpurpose);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
// move you..
|
||||
moveto(lf, cell, onpurpose);
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// move them...
|
||||
lfinway->cell = oldcell;
|
||||
oldcell->lf = lfinway;
|
||||
reason = E_OK;
|
||||
// move them...
|
||||
lfinway->cell = oldcell;
|
||||
oldcell->lf = lfinway;
|
||||
reason = E_OK;
|
||||
if (isplayer(lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lfinway, lfname);
|
||||
msg("You swap places with %s.", lfname);
|
||||
}
|
||||
} else {
|
||||
// attack!
|
||||
|
@ -1315,7 +1356,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
if (celldangerous(lf, cell, error)) {
|
||||
if (celldangerous(lf, cell, B_TRUE, error)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
|
3
move.h
3
move.h
|
@ -2,7 +2,8 @@
|
|||
|
||||
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
int canmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, enum ERROR *error);
|
||||
int canswapwith(lifeform_t *lf, lifeform_t *lf2);
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *error);
|
||||
int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error);
|
||||
int closedoorat(lifeform_t *lf, cell_t *c);
|
||||
int closedoor(lifeform_t *lf, object_t *o);
|
||||
|
|
2
nexus.c
2
nexus.c
|
@ -631,6 +631,7 @@ void initcommands(void) {
|
|||
addcommand(CMD_REST, '.', "Rest once.");
|
||||
addcommand(CMD_PICKUP, ',', "Pick up something from the ground.");
|
||||
addcommand(CMD_CLOSE, 'c', "Close a door.");
|
||||
addcommand(CMD_COMMS, 'C', "Communicate with an ally.");
|
||||
addcommand(CMD_DROP, 'd', "Drop an item.");
|
||||
addcommand(CMD_DROPMULTI, 'D', "Drop multiple items.");
|
||||
addcommand(CMD_EAT, 'e', "Eat something.");
|
||||
|
@ -643,6 +644,7 @@ void initcommands(void) {
|
|||
addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion.");
|
||||
addcommand(CMD_READ, 'r', "Read a scroll/book.");
|
||||
addcommand(CMD_RESTFULL, 'R', "Rest until healed, or train your skills.");
|
||||
addcommand(CMD_THROW, 't', "Throw an object.");
|
||||
addcommand(CMD_TAKEOFF, 'T', "Take off an item of clothing/jewelery.");
|
||||
addcommand(CMD_WEILD, 'w', "Weild a weapon.");
|
||||
addcommand(CMD_WEAR, 'W', "Wear an item of clothing/jewelery.");
|
||||
|
|
263
objects.c
263
objects.c
|
@ -975,7 +975,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
|
||||
// add objects in a circle
|
||||
// returns # added.
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name) {
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf) {
|
||||
int (*distfunc)(cell_t *, cell_t *);
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
|
@ -994,7 +994,12 @@ int addobburst(cell_t *where, int range, int dirtype, char *name) {
|
|||
c = getcellat(where->map, x,y);
|
||||
if (distfunc(where, c) <= range) {
|
||||
if (!c->type->solid) {
|
||||
if (addob(c->obpile, name)) nadded++;
|
||||
object_t *o;
|
||||
o = addob(c->obpile, name);
|
||||
if (o) {
|
||||
if (fromlf) setobcreatedby(o, fromlf);
|
||||
nadded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1245,6 +1250,7 @@ void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype) {
|
|||
}
|
||||
o->blessknown = B_TRUE;
|
||||
}
|
||||
*dam = 0;
|
||||
return;
|
||||
}
|
||||
} else if (o->blessed == B_CURSED) {
|
||||
|
@ -2044,7 +2050,7 @@ int getcharges(object_t *o) {
|
|||
return amt;
|
||||
}
|
||||
|
||||
int getobaccuracy(object_t *wep) {
|
||||
int getobaccuracy(object_t *wep, lifeform_t *weilder) {
|
||||
int acc;
|
||||
flag_t *f;
|
||||
|
||||
|
@ -2063,6 +2069,36 @@ int getobaccuracy(object_t *wep) {
|
|||
acc = f->val[0];
|
||||
}
|
||||
|
||||
if (weilder) {
|
||||
skill_t *sk;
|
||||
// modify for weilder's skill
|
||||
sk = getobskill(wep);
|
||||
if (sk) {
|
||||
switch (getskill(weilder, sk->id)) {
|
||||
case PR_INEPT:
|
||||
acc -= 75;
|
||||
break;
|
||||
case PR_NOVICE:
|
||||
acc -= 25;
|
||||
break;
|
||||
case PR_BEGINNER:
|
||||
acc -= 5;
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
break;
|
||||
case PR_SKILLED:
|
||||
acc += 25;
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
acc += 50;
|
||||
break;
|
||||
case PR_MASTER:
|
||||
acc += 75;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// modify for attacker's level
|
||||
if (wep->pile->owner) {
|
||||
acc += (wep->pile->owner->level * 2);
|
||||
|
@ -4400,7 +4436,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_SCR_REMOVECURSE, "scroll of remove curse", "Removes curses from all weilded equipment.", MT_PAPER, 0.5, OC_SCROLL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
|
||||
addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL);
|
||||
|
@ -4583,7 +4619,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
// l6
|
||||
addot(OT_S_FLIGHT, "flight", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4844,7 +4880,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_SS_GRAVITY, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_LIFE, "manual of life magic", "Teaches you the skill 'life magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_LIFE, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_MODIFICATION, "manual of modification", "Teaches you the skill 'modification'.", MT_PAPER, 3, OC_BOOK);
|
||||
addot(OT_MAN_SS_MODIFICATION, "manual of modification magic", "Teaches you the skill 'modification magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_MODIFICATION, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_MENTAL, "manual of psionics", "Teaches you the skill 'psionics'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_MENTAL, NA, NA, NULL);
|
||||
|
@ -4901,7 +4937,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKSPELL, OT_S_GRAVLOWER, NA, NA, NULL);
|
||||
addot(OT_SB_GRAVBOOST, "spellbook of boost gravity", "Teaches the spell 'boost gravity'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_GRAVBOOST, NA, NA, NULL);
|
||||
addot(OT_SB_FLIGHT, "spellbook of flight", "Teaches the spell 'flight'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addot(OT_SB_FLIGHT, "spellbook of fly", "Teaches the spell 'fly'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_FLIGHT, NA, NA, NULL);
|
||||
addot(OT_SB_HASTE, "spellbook of haste", "Teaches the spell 'haste'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_HASTE, NA, NA, NULL);
|
||||
|
@ -6348,33 +6384,63 @@ int isbetterarmourthan(object_t *a, object_t *b) {
|
|||
|
||||
// compare weapons using max damage
|
||||
int isbetterwepthan(object_t *a, object_t *b) {
|
||||
flag_t *f;
|
||||
//flag_t *f;
|
||||
int dama,damb;
|
||||
float acca,accb;
|
||||
int db = B_FALSE;
|
||||
char namea[BUFLEN];
|
||||
char nameb[BUFLEN];
|
||||
|
||||
if (!a) return B_FALSE;
|
||||
if (!b) return B_TRUE;
|
||||
|
||||
f = hasflag(a->flags, F_DAM);
|
||||
if (f) {
|
||||
dama = (f->val[0] * f->val[1]) + f->val[2];
|
||||
} else {
|
||||
dama = 0;
|
||||
/* if (a->pile->owner && lfhasflag(a->pile->owner, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
if (b->pile->owner && lfhasflag(b->pile->owner, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
} */
|
||||
|
||||
|
||||
if (db) {
|
||||
getobname(a, namea, a->amt);
|
||||
getobname(b, nameb, b->amt);
|
||||
}
|
||||
|
||||
f = hasflag(b->flags, F_DAM);
|
||||
if (f) {
|
||||
damb = (f->val[0] * f->val[1]) + f->val[2];
|
||||
} else {
|
||||
damb = 0;
|
||||
}
|
||||
getdamrange(a->flags, NULL, &dama);
|
||||
getdamrange(b->flags, NULL, &damb);
|
||||
|
||||
// modify based on extra props
|
||||
if (hasflag(a->flags, F_HASBRAND)) {
|
||||
dama *= 3;
|
||||
}
|
||||
if (hasflag(a->flags, F_ONFIRE)) {
|
||||
dama += 8;
|
||||
}
|
||||
|
||||
|
||||
if (hasflag(b->flags, F_HASBRAND)) {
|
||||
damb *= 3;
|
||||
}
|
||||
if (hasflag(b->flags, F_ONFIRE)) {
|
||||
damb += 8;
|
||||
}
|
||||
|
||||
// modify with accuracy
|
||||
acca = getobaccuracy(a, a->pile->owner);
|
||||
accb = getobaccuracy(b, b->pile->owner);
|
||||
|
||||
|
||||
if (db) {
|
||||
msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
|
||||
}
|
||||
|
||||
dama = (int)((float)dama * (acca/100));
|
||||
damb = (int)((float)damb * (accb/100));
|
||||
|
||||
if (db) {
|
||||
msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
|
||||
}
|
||||
|
||||
if (dama > damb) return B_TRUE;
|
||||
return B_FALSE;
|
||||
|
@ -8972,6 +9038,15 @@ void setinscription(object_t *o, char *text) {
|
|||
o->inscription = strdup(text);
|
||||
}
|
||||
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf) {
|
||||
char lfname[BUFLEN];
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
real_getlfnamea(lf, lfname, B_FALSE);
|
||||
addflag(o->flags, F_CREATEDBY, lf->id, NA, NA, lfname);
|
||||
}
|
||||
|
||||
// randomizes hidden names
|
||||
void shufflehiddennames(void) {
|
||||
int i,n;
|
||||
|
@ -9240,6 +9315,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
object_t *newob;
|
||||
cell_t *newloc;
|
||||
int db = B_TRUE;
|
||||
int willcatch = B_FALSE;
|
||||
|
||||
reason = E_OK;
|
||||
|
||||
|
@ -9333,6 +9409,9 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
if (target) {
|
||||
getlfname(target, targetname);
|
||||
if (areallies(thrower, target) && !firearm) {
|
||||
willcatch = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// touch effects
|
||||
|
@ -9346,7 +9425,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (thrower && isplayer(thrower)) {
|
||||
// player is throwing something
|
||||
if (target) {
|
||||
msg("You %s %s at %s.", throwverbpres, obname, targetname);
|
||||
msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname);
|
||||
} else {
|
||||
msg("You %s %s.",throwverbpres, obname);
|
||||
}
|
||||
|
@ -9358,7 +9437,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
obname);
|
||||
|
||||
if (target && haslos(player, where)) {
|
||||
strcat(throwstring, " at ");
|
||||
strcat(throwstring, willcatch ? " to " : " at ");
|
||||
strcat(throwstring, targetname);
|
||||
}
|
||||
strcat(throwstring, ".");
|
||||
|
@ -9430,7 +9509,11 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
// find out your chances of hitting
|
||||
if (target) {
|
||||
if (thrower) {
|
||||
acc = getmissileaccuracy(thrower, where, o, firearm, A_DEX);
|
||||
if (willcatch) {
|
||||
acc = 100;
|
||||
} else {
|
||||
acc = getmissileaccuracy(thrower, where, o, firearm, A_DEX);
|
||||
}
|
||||
} else {
|
||||
// purely based on saving throw...
|
||||
acc = 100;
|
||||
|
@ -9450,7 +9533,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
|
||||
// saving throw
|
||||
if (youhit) {
|
||||
if (youhit && !willcatch) {
|
||||
if (skillcheck(target, SC_DODGE, 20, 0)) {
|
||||
youhit = B_FALSE;
|
||||
}
|
||||
|
@ -9462,76 +9545,86 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
msg("%s recoils in fear!", targetname);
|
||||
}
|
||||
o->blessknown = B_TRUE;
|
||||
// ... but undead won't catch blessed things
|
||||
willcatch = B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// if someone is there, they take damage and the object might die
|
||||
// this should be "if target && youhit"
|
||||
if (youhit) {
|
||||
int dam = 0,shatterdam = 0;
|
||||
char damstring[BUFLEN];
|
||||
int reduceamt = 0;
|
||||
int throwdam;
|
||||
|
||||
throwdam = getthrowdam(o);
|
||||
dam = throwdam * speed;
|
||||
if (db) dblog("fireat(): dam = throwdam(%d) * speed(%d) = %d",throwdam, speed, dam);
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_RUBBERBULLET) {
|
||||
dam = 1;
|
||||
}
|
||||
|
||||
// deal extra cutting damage afterwards?
|
||||
shatterdam = getshatterdam(o);
|
||||
if (shatterdam > 0) {
|
||||
shattered = B_TRUE;
|
||||
}
|
||||
|
||||
// announce
|
||||
if (seen) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, "%s hit%s %s%s",obname,(amt == 1) ? "s" : "", targetname,
|
||||
(willshatter(o->material->id)) ? " and shatters!" : "."
|
||||
);
|
||||
if (lfhasflag(player, F_EXTRAINFO)) {
|
||||
char damstring[BUFLEN];
|
||||
sprintf(damstring, " [%d dmg]",dam);
|
||||
strcat(buf2, damstring);
|
||||
}
|
||||
msg("%s", buf2);
|
||||
} else {
|
||||
if (willshatter(o->material->id)) {
|
||||
noise(where, NULL, "shattering glass.", NULL);
|
||||
}
|
||||
}
|
||||
sprintf(damstring, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
|
||||
reduceamt = getarmourdamreduction(target, o, dam, DT_PROJECTILE);
|
||||
|
||||
applyarmourdamreduction(target, o, reduceamt, &dam, DT_PROJECTILE);
|
||||
|
||||
if (dam > 0) {
|
||||
lifeform_t *whogetsxp = NULL;
|
||||
// TODO: at the moment you won't get experience if you telekenetically
|
||||
// throw an object at something. is this okay?
|
||||
if (thrower && (thrower->cell == srcloc)) {
|
||||
whogetsxp = thrower;
|
||||
}
|
||||
losehp(target, dam, DT_PROJECTILE, whogetsxp, damstring);
|
||||
}
|
||||
|
||||
if (reduceamt && (speed >= 3)) {
|
||||
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE);
|
||||
}
|
||||
|
||||
if (shatterdam && !isdead(target)) {
|
||||
// extra glass damage
|
||||
if (willcatch) {
|
||||
if (seen) {
|
||||
msg("%s %s showered in glass shards!", targetname, isplayer(target) ? "are" : "is");
|
||||
msg("%s catches %s.", targetname, obname);
|
||||
}
|
||||
moveob(o, target->pack, amt);
|
||||
return B_FALSE;
|
||||
} else {
|
||||
int dam = 0,shatterdam = 0;
|
||||
char damstring[BUFLEN];
|
||||
int reduceamt = 0;
|
||||
int throwdam;
|
||||
|
||||
throwdam = getthrowdam(o);
|
||||
dam = throwdam * speed;
|
||||
if (db) dblog("fireat(): dam = throwdam(%d) * speed(%d) = %d",throwdam, speed, dam);
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_RUBBERBULLET) {
|
||||
dam = 1;
|
||||
}
|
||||
|
||||
// deal extra cutting damage afterwards?
|
||||
shatterdam = getshatterdam(o);
|
||||
if (shatterdam > 0) {
|
||||
shattered = B_TRUE;
|
||||
}
|
||||
|
||||
// announce
|
||||
if (seen) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, "%s hit%s %s%s",obname,(amt == 1) ? "s" : "", targetname,
|
||||
(willshatter(o->material->id)) ? " and shatters!" : "."
|
||||
);
|
||||
if (lfhasflag(player, F_EXTRAINFO)) {
|
||||
char damstring[BUFLEN];
|
||||
sprintf(damstring, " [%d dmg]",dam);
|
||||
strcat(buf2, damstring);
|
||||
}
|
||||
msg("%s", buf2);
|
||||
} else {
|
||||
if (willshatter(o->material->id)) {
|
||||
noise(where, NULL, "shattering glass.", NULL);
|
||||
}
|
||||
}
|
||||
sprintf(damstring, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
losehp(target, shatterdam, DT_SLASH, thrower, damstring);
|
||||
|
||||
reduceamt = getarmourdamreduction(target, o, dam, DT_PROJECTILE);
|
||||
|
||||
applyarmourdamreduction(target, o, reduceamt, &dam, DT_PROJECTILE);
|
||||
|
||||
if (dam > 0) {
|
||||
lifeform_t *whogetsxp = NULL;
|
||||
// TODO: at the moment you won't get experience if you telekenetically
|
||||
// throw an object at something. is this okay?
|
||||
if (thrower && (thrower->cell == srcloc)) {
|
||||
whogetsxp = thrower;
|
||||
}
|
||||
losehp(target, dam, DT_PROJECTILE, whogetsxp, damstring);
|
||||
}
|
||||
|
||||
if (reduceamt && (speed >= 3)) {
|
||||
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE);
|
||||
}
|
||||
|
||||
if (shatterdam && !isdead(target)) {
|
||||
// extra glass damage
|
||||
if (seen) {
|
||||
msg("%s %s showered in glass shards!", targetname, isplayer(target) ? "are" : "is");
|
||||
}
|
||||
sprintf(damstring, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
losehp(target, shatterdam, DT_SLASH, thrower, damstring);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isplayer(thrower)) {
|
||||
|
@ -10298,7 +10391,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
|
||||
// base accuracy
|
||||
if (firearm) {
|
||||
acc = getobaccuracy(firearm);
|
||||
acc = getobaccuracy(firearm, thrower);
|
||||
} else {
|
||||
acc = 50;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
|||
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph);
|
||||
object_t *addob(obpile_t *where, char *name);
|
||||
object_t *addobject(obpile_t *where, char *name, int canstack);
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name);
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf);
|
||||
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid);
|
||||
|
@ -49,7 +49,7 @@ int geteffecttime(int min, int max, enum BLESSTYPE isblessed);
|
|||
objecttype_t *getlinkspell(object_t *o);
|
||||
enum MATSTATE getmaterialstate(enum MATERIAL mat);
|
||||
int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, enum ATTRIB whichatt);
|
||||
int getobaccuracy(object_t *wep);
|
||||
int getobaccuracy(object_t *wep, lifeform_t *weilder);
|
||||
int getobbonus(object_t *o);
|
||||
skill_t *getobskill(object_t *o);
|
||||
int getobvalue(object_t *o);
|
||||
|
@ -170,6 +170,7 @@ int removeob(object_t *o, int howmany);
|
|||
object_t *relinkob(object_t *src, obpile_t *dst);
|
||||
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
||||
void setinscription(object_t *o, char *text);
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||
void shufflehiddennames(void);
|
||||
object_t *splitob(object_t *o);
|
||||
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||
|
|
61
spell.c
61
spell.c
|
@ -19,6 +19,8 @@
|
|||
extern lifeform_t *player;
|
||||
extern skill_t *firstskill, *lastskill;
|
||||
|
||||
extern int needredraw;
|
||||
|
||||
extern prompt_t prompt;
|
||||
|
||||
extern WINDOW *msgwin;
|
||||
|
@ -830,7 +832,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int tries = 0,maxtries = 10;
|
||||
// pick a random location
|
||||
targcell = NULL;
|
||||
while (!targcell || !cellwalkable(caster, targcell, NULL) || celldangerous(caster, targcell, NULL)) {
|
||||
while (!targcell || !cellwalkable(caster, targcell, NULL) || celldangerous(caster, targcell, B_FALSE, NULL)) {
|
||||
int i;
|
||||
i = rnd(0,caster->nlos-1);
|
||||
targcell = caster->los[i];
|
||||
|
@ -858,19 +860,31 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// don't set caster's cell on fire!
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
c = retcell[i];
|
||||
|
||||
// set on fire
|
||||
addob(c->obpile, "medium fire");
|
||||
if (c->lf) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(c->lf,buf);
|
||||
if (!isimmuneto(c->lf->flags, DT_FIRE)) {
|
||||
msg("%s burn%s!",buf,isplayer(c->lf) ? "" : "s");
|
||||
o = addob(c->obpile, "medium fire");
|
||||
|
||||
if (o) {
|
||||
setobcreatedby(o, caster);
|
||||
if (c->lf) {
|
||||
char buf[BUFLEN];
|
||||
char damstring[BUFLEN];
|
||||
char realcname[BUFLEN];
|
||||
getlfname(c->lf,buf);
|
||||
if (!isimmuneto(c->lf->flags, DT_FIRE)) {
|
||||
msg("%s burn%s!",buf,isplayer(c->lf) ? "" : "s");
|
||||
}
|
||||
real_getlfname(caster, realcname, B_FALSE);
|
||||
sprintf(damstring, "%s%s wave of fire", realcname, getpossessive(realcname));
|
||||
losehp(c->lf, rolldie(2,10), DT_FIRE, caster, damstring);
|
||||
}
|
||||
losehp(c->lf, rolldie(2,10), DT_FIRE, caster, "a wave of fire");
|
||||
}
|
||||
}
|
||||
if (cansee(player, caster)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
} else if (spellid == OT_S_CLOUDKILL) {
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_FALSE, LOF_NEED, spellid, power)) return B_TRUE;
|
||||
|
@ -880,7 +894,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
addobburst(targcell, (power/3), DT_COMPASS, "cloud of gas");
|
||||
addobburst(targcell, (power/3), DT_COMPASS, "cloud of gas", caster);
|
||||
|
||||
if (haslos(player, targcell)) {
|
||||
msg("A cloud of poison gas appears!");
|
||||
|
@ -1331,6 +1345,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) {
|
||||
int dir;
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
// centre fireball here...
|
||||
if (isplayer(caster)) {
|
||||
msg("You launch an enormous ball of fire!");
|
||||
|
@ -1356,14 +1371,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
c = getcellindir(targcell, dir);
|
||||
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
|
||||
addob(c->obpile, "large fire");
|
||||
o = addob(c->obpile, "large fire");
|
||||
if (o) {
|
||||
setobcreatedby(o, caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (dir = DC_NE; dir <= DC_NW; dir += 2) {
|
||||
cell_t *c;
|
||||
c = getcellindir(targcell, dir);
|
||||
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
|
||||
addob(c->obpile, "medium fire");
|
||||
o = addob(c->obpile, "medium fire");
|
||||
if (o) {
|
||||
setobcreatedby(o, caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
|
@ -1372,7 +1393,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (c) {
|
||||
c = getcellindir(c, dir);
|
||||
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
|
||||
addob(c->obpile, "small fire");
|
||||
o = addob(c->obpile, "small fire");
|
||||
if (o) {
|
||||
setobcreatedby(o, caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1476,6 +1500,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
f->val[0] += power;
|
||||
f->val[1] += power;
|
||||
}
|
||||
setobcreatedby(o, caster);
|
||||
} else {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
@ -1659,7 +1684,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (getmr(target) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s blur%s for a moment.",buf, isplayer(target) ? "" : "s");
|
||||
|
@ -1819,7 +1844,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
losehp(l, 9999, DT_DIRECT, NULL, "an infinite death spell");
|
||||
char dambuf[BUFLEN];
|
||||
char cname[BUFLEN];
|
||||
real_getlfname(caster, cname, B_FALSE);
|
||||
sprintf(dambuf, "%s%s infinite death spell", cname, getpossessive(cname));
|
||||
losehp(l, 9999, DT_DIRECT, NULL, dambuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2303,6 +2332,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// create the source portal
|
||||
srcportal = addob(srccell->obpile, "magic portal");
|
||||
setobcreatedby(srcportal, caster);
|
||||
|
||||
// announce, because we might have a delay creating the level...
|
||||
if (isplayer(caster)) {
|
||||
|
@ -2327,6 +2357,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// add the dst portal
|
||||
dstportal = addob(newcell->obpile, "magic portal");
|
||||
setobcreatedby(dstportal, caster);
|
||||
// link the dst portal
|
||||
addflag_real(dstportal->flags, F_MAPLINK, caster->cell->map->id, srccell->x, srccell->y, NULL, PERMENANT, B_FALSE, -1);
|
||||
|
||||
|
@ -3367,6 +3398,8 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, i
|
|||
|
||||
maxrange = getspellrange(spellid, power);
|
||||
|
||||
if (*targcell) where = *targcell;
|
||||
|
||||
while (!done) {
|
||||
if (where) {
|
||||
cell_t *newwhere = NULL;
|
||||
|
|
Loading…
Reference in New Issue