- [+] intelligent (ie. more than animal) ai shouldn't move if it will
cause damage - [+] move_will_hurt() - [+] ie. if in PAIN, or appropriate injury. - [+] if you're deaf, use "the xx says something" rather than "the xx says yy" - [+] STILL reachability errors in dlev 6 (jimbos' lair not linked) - [+] new forest habitat mechanism - clusters of trees - [+] bashing injury if you are slammed into a wall? - [+] jimbo didn't have a weapon! "+2 halberd" not working - [+] if you don't have knowledge about a creature, still show items (but only equipped ones) - [+] listen skill should take longer to train - [+] candle should last longer - [+] carrot grants temp darkvision - [+] shouldn't be able to eat stuff from floor while levitating - [+] CHANGE f_hitdice to use text - [+] fear spell from dretch always failing even on l1 player. why? * [+] summondemon spell - [+] adjust spell damage - 1d6 per level. ice spells: - [+] l4 - ice armour (higher power means more pieces of ice armour) - [+] (power/3)+1 pieces of armour. ie. 1 - 4 - [+] order: body,helmet, gloves, feet - [+] 4AC each. * [+] l5 - shardshot (higher level ray damage, does less damage the further away it goes) - [+] l5 - snap freeze ? turn one lf to ice? - [+] more things which use light attacks (ie. make glasses useful) - [+] replace bp_righthand with bp_rightfinger - [+] bug in blink spell: "Nothing seems to happen." - [+] make metal resist bite/slash/chop, not be immune. - [+] fix shatter spell on glass wall * [+] bug: in jimbos vault and plaeyrstart2, exits are being added in in appropriate places. * [+] make player's starting point be a "prison_cell" vault. - [+] earplugs - stop all sound. - [+] make f_deaf an intrinsic (ie. announcements) - [+] add the object critical hits: - [+] "you hit xxx" "xxx turns to flee" "xxx's leg is bruised" - [+] need losehp to NOT trigger fightback in this case - we will trigger it ourself after crithit. - [+] pass this as a param? - [+] critical eye hits - [+] scraped eyelid (slash, lower accuracy) - [+] black eye (bash, lower vision range and charisma) - [+] destroyed eye (pierce, permenant lower vision range!) - [+] injuries heal heaps faster when asleep - [+] redo f_injured flag to use an "enum INJURY" IJ_xxx - [+] change how it is applied - [+] change how it is announced (io.c) - [+] change how effects work (search for F_INJURY) - [+] pierce - [+] pierced artery: v.high bleed - [+] stabbed heart (instant death, very unlikely) - [+] slash: - [+] cut flexor tendon (cannot weild ANY weapon) - [+] slashed hamstring (fall. skillcehck every time you move, vslow movement) - [+] severed finger - [+] finger drops to the ground - [+] ring drops to the ground - [+] (get nobodypart bp_rightfinger or bp_leftfinger) - [+] bash: - [+] dislocated arm (cannot weild anything heavy in that hand) - [+] broken rib (reduced carrying capacity) - [+] swelled ankle (cannot remove or put on boots)
This commit is contained in:
parent
c181893ae4
commit
1f6429e305
2
ai.c
2
ai.c
|
@ -1183,7 +1183,7 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// do we have better armour?
|
||||
for (bp = BP_RIGHTHAND ; bp < MAXBODYPARTS; bp++) {
|
||||
for (bp = BP_RIGHTFINGER ; bp < MAXBODYPARTS; bp++) {
|
||||
object_t *curarm;
|
||||
curarm = getarmour(lf, bp);
|
||||
// do we have a better one?
|
||||
|
|
63
attack.c
63
attack.c
|
@ -425,7 +425,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
}
|
||||
|
||||
if (lfhasflagval(lf, F_INJURY, NA, BP_HANDS, DT_SLASH, NULL)) {
|
||||
bleed(lf);
|
||||
bleed(lf, B_FALSE);
|
||||
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
|
||||
}
|
||||
|
||||
|
@ -762,6 +762,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
//dblog("reduced by armour to dam[%d] = %d",i,dam[i]);
|
||||
}
|
||||
|
||||
// if damage has dropped to zero, it's not a critical hit anymore.
|
||||
if (dam[i] <= 0) {
|
||||
critical = B_FALSE;
|
||||
critpos = BP_NONE;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_QUIVERINGPALM)) {
|
||||
// make sure damage isn't fatal
|
||||
if (dam[i] >= victim->hp) {
|
||||
|
@ -898,7 +904,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
} else if (lfhasflag(lf, F_QUIVERINGPALM)) {
|
||||
// victim explodes!
|
||||
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL);
|
||||
losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE, NULL, B_FALSE);
|
||||
} else {
|
||||
char attackername2[BUFLEN];
|
||||
real_getlfname(lf, attackername2, B_FALSE);
|
||||
|
@ -923,7 +929,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
} else {
|
||||
strcpy(buf, attackername2);
|
||||
}
|
||||
losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL);
|
||||
losehp_real(victim, dam[i], damtype[i], lf, buf, B_FALSE, NULL, B_FALSE);
|
||||
|
||||
// victim's armour loses hp
|
||||
if (reduceamt && !critical) {
|
||||
|
@ -968,7 +974,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
char lfname[BUFLEN];
|
||||
dam = rolldie(f->val[0], f->val[1]) + f->val[2];
|
||||
real_getlfname(lf, lfname, B_FALSE);
|
||||
losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL);
|
||||
losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE, NULL, B_FALSE);
|
||||
if (isplayer(victim) || cansee(player, victim)) {
|
||||
msg("^%c%s bites %s!", isplayer(victim) ? 'b' : 'n', lfname, victimname);
|
||||
}
|
||||
|
@ -994,7 +1000,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (nmatched >= f->val[2]) {
|
||||
char damstring[BUFLEN];
|
||||
snprintf(damstring, BUFLEN, "%s pack", lfname);
|
||||
losehp(victim, f->val[0], f->val[1], lf, damstring);
|
||||
losehp_real(victim, f->val[0], f->val[1], lf, damstring, B_TRUE, NULL, B_FALSE);
|
||||
if (isplayer(victim) || cansee(player, victim)) {
|
||||
msg("%c%s pack attacks %s!", isplayer(victim) ? 'b' : 'c', lfname, victimname);
|
||||
}
|
||||
|
@ -1004,7 +1010,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// critical hit effects
|
||||
if (critical && damtypecausescriteffects(damtype[0])) {
|
||||
criticalhit(lf, victim, critpos, damtype[0]);
|
||||
|
||||
}
|
||||
|
||||
// confer flags from attacker?
|
||||
|
@ -1036,6 +1041,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fightback(victim, lf);
|
||||
}
|
||||
|
||||
// retaliation happens even if victim died
|
||||
|
@ -1053,7 +1060,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
attackername);
|
||||
}
|
||||
snprintf(damstring, BUFLEN, "%s%s %s", victimname, getpossessive(victimname), noprefix(f->text));
|
||||
losehp(lf, rdam, f->val[2], victim, damstring);
|
||||
losehp_real(lf, rdam, f->val[2], victim, damstring, B_TRUE, NULL, B_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1111,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
}
|
||||
}
|
||||
fightback(victim, lf);
|
||||
}
|
||||
|
||||
// practice?
|
||||
|
@ -1345,14 +1351,14 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
// chance of your helmet falling off
|
||||
o = getarmour(victim, BP_HEAD);
|
||||
if (o) {
|
||||
if (isplayer(lf)) {
|
||||
if (isplayer(victim)) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
msg("Your %s falls off!", noprefix(buf));
|
||||
} else if (cansee(player, lf)) {
|
||||
} else if (cansee(player, victim)) {
|
||||
char buf[BUFLEN], lfname[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
getlfname(lf, lfname);
|
||||
getlfname(victim, lfname);
|
||||
msg("%s%s %s falls off!", lfname, getpossessive(lfname), noprefix(buf));
|
||||
}
|
||||
moveob(o, victim->cell->obpile, o->amt);
|
||||
|
@ -1375,8 +1381,10 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (!getarmour(victim, hitpos)) injure(victim, hitpos, damtype);
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_CRITKNOCKDOWN) && !isprone(victim)) {
|
||||
fall(victim, lf, B_TRUE);
|
||||
if (lf) {
|
||||
if (lfhasflag(lf, F_CRITKNOCKDOWN) && !isprone(victim)) {
|
||||
fall(victim, lf, B_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2033,7 +2041,6 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
int acc,ev;
|
||||
int gothit = B_FALSE;
|
||||
enum SKILLLEVEL lorelev = PR_INEPT;
|
||||
int myroll;
|
||||
flag_t *f;
|
||||
|
||||
// remember lore about victim...
|
||||
|
@ -2088,37 +2095,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
|
||||
acc -= ev;
|
||||
|
||||
|
||||
// modify if we can't see the victim
|
||||
if (!cansee(lf, victim)) {
|
||||
acc -= 50;
|
||||
}
|
||||
|
||||
if (!cansee(lf, victim)) acc -= 50;
|
||||
// metal weapon versus magnetic shield?
|
||||
if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) {
|
||||
acc -= 45;
|
||||
}
|
||||
|
||||
if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) acc -= 45;
|
||||
// victim immobile or asleep?
|
||||
if (isimmobile(victim) || lfhasflag(victim, F_EATING)) {
|
||||
acc += 50;
|
||||
}
|
||||
|
||||
if (isimmobile(victim) || lfhasflag(victim, F_EATING)) acc += 50;
|
||||
// modify for lore level
|
||||
if (lorelev != PR_INEPT) {
|
||||
lorelev += (lorelev*10);
|
||||
}
|
||||
if (lorelev != PR_INEPT) lorelev += (lorelev*10);
|
||||
|
||||
limit(&acc, 0, 100);
|
||||
|
||||
//if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc);
|
||||
|
||||
myroll = rnd(1,100);
|
||||
|
||||
// modify for lore
|
||||
if (myroll <= acc) {
|
||||
gothit = B_TRUE;
|
||||
}
|
||||
if (pctchance(acc)) gothit = B_TRUE;
|
||||
}
|
||||
|
||||
return gothit;
|
||||
|
|
48
defs.h
48
defs.h
|
@ -49,6 +49,7 @@
|
|||
#define B_NODOORS (0)
|
||||
#define B_DONTKILL (-1)
|
||||
#define B_APPENDYOU (-1)
|
||||
#define B_SPLATTER (-1)
|
||||
|
||||
//#define B_TEMP (-1)
|
||||
//#define B_PERM (-2)
|
||||
|
@ -256,6 +257,14 @@
|
|||
#define AUTO (-7654)
|
||||
#define HEAVYWEPKG (5)
|
||||
|
||||
// how quickly the game clock increments
|
||||
// 1 = roughly 30 secs per turn
|
||||
#define TIMECONST (3)
|
||||
// hunger constant - this is how many turns
|
||||
// it will take to go from 'normal' to 'peckish' etc
|
||||
// ... try to make this roughly 4 hours (check TIMECONST.
|
||||
#define HUNGERCONST 500
|
||||
|
||||
// Time periods
|
||||
#define TM_DRUNKTIME (10) // how long it takes for alcohol to wear off
|
||||
#define TM_WETTIME (10) // how long it takes for things to dry
|
||||
|
@ -520,9 +529,6 @@ enum MSGCHARCOL {
|
|||
CC_VGOOD,
|
||||
};
|
||||
|
||||
// hunger constant - this is how many turns
|
||||
// it will take to go from 'normal' to 'hungry' etc
|
||||
#define HUNGERCONST 200
|
||||
|
||||
enum MODTYPE {
|
||||
M_PCT,
|
||||
|
@ -747,7 +753,6 @@ enum RACE {
|
|||
R_HOBGOBLINWAR,
|
||||
R_KOBOLD,
|
||||
R_LIZARDMAN,
|
||||
R_LURKINGHORROR,
|
||||
R_MINOTAUR,
|
||||
R_OGRE,
|
||||
R_OGRESAVAGE,
|
||||
|
@ -817,6 +822,10 @@ enum RACE {
|
|||
R_GIANTFLY,
|
||||
R_GIANTBLOWFLY,
|
||||
R_STIRGE,
|
||||
// demons
|
||||
R_DRETCH,
|
||||
R_LURKINGHORROR,
|
||||
R_QUASIT,
|
||||
// undead
|
||||
R_GHAST,
|
||||
R_GHOST,
|
||||
|
@ -960,6 +969,7 @@ enum OBTYPE {
|
|||
OT_CLOVER,
|
||||
// corpses
|
||||
OT_CORPSE,
|
||||
OT_FINGER,
|
||||
OT_HEAD,
|
||||
// potions
|
||||
OT_POT_ACID,
|
||||
|
@ -1073,6 +1083,7 @@ enum OBTYPE {
|
|||
OT_S_CHILL,
|
||||
OT_S_COLDBURST,
|
||||
OT_S_COLDRAY,
|
||||
OT_S_CRYSTALARM,
|
||||
OT_S_CRYSTALSHIELD,
|
||||
OT_S_FREEZEOB,
|
||||
OT_S_FROSTBITE,
|
||||
|
@ -1080,6 +1091,8 @@ enum OBTYPE {
|
|||
OT_S_ICEEDGE,
|
||||
OT_S_ICICLE,
|
||||
OT_S_SLIDE,
|
||||
OT_S_SHARDSHOT,
|
||||
OT_S_SNAPFREEZE,
|
||||
OT_S_SNOWBALL,
|
||||
OT_S_WALLOFICE,
|
||||
// -- gravity
|
||||
|
@ -1152,6 +1165,7 @@ enum OBTYPE {
|
|||
OT_S_SUMMONANIMALSSM,
|
||||
OT_S_SUMMONANIMALSMD,
|
||||
OT_S_SUMMONANIMALSLG,
|
||||
OT_S_SUMMONDEMON,
|
||||
OT_S_THORNS,
|
||||
OT_S_WARPWOOD,
|
||||
OT_S_WATERJET,
|
||||
|
@ -1373,6 +1387,8 @@ enum OBTYPE {
|
|||
OT_GOLDCROWN,
|
||||
OT_HELMBONE,
|
||||
OT_HELMFOOTBALL,
|
||||
// armour - ears
|
||||
OT_EARPLUGS,
|
||||
// armour - eyes
|
||||
OT_SUNGLASSES,
|
||||
OT_EYEPATCH,
|
||||
|
@ -1485,7 +1501,13 @@ enum OBTYPE {
|
|||
// special weapons
|
||||
OT_ENERGYBLADE,
|
||||
OT_HANDOFGOD,
|
||||
OT_ICEARMOUR,
|
||||
OT_ICEBOOTS,
|
||||
OT_ICEGLOVES,
|
||||
OT_ICEHELMET,
|
||||
OT_ICESHIELD,
|
||||
// special obs
|
||||
OT_PLAYERSTART,
|
||||
|
||||
|
||||
};
|
||||
|
@ -1495,6 +1517,7 @@ enum OBTYPE {
|
|||
enum BODYPART {
|
||||
BP_WEAPON = 0,
|
||||
BP_SECWEAPON,
|
||||
BP_EARS,
|
||||
BP_EYES,
|
||||
BP_HEAD,
|
||||
BP_SHOULDERS,
|
||||
|
@ -1503,10 +1526,10 @@ enum BODYPART {
|
|||
BP_WAIST,
|
||||
BP_LEGS,
|
||||
BP_FEET,
|
||||
BP_RIGHTHAND,
|
||||
BP_LEFTHAND,
|
||||
BP_RIGHTFINGER,
|
||||
BP_LEFTFINGER,
|
||||
};
|
||||
#define MAXBODYPARTS (12)
|
||||
#define MAXBODYPARTS (13)
|
||||
|
||||
// depth on a human
|
||||
|
||||
|
@ -1607,6 +1630,7 @@ enum FLAG {
|
|||
F_DEAD, // object will be removed
|
||||
F_ONEPERCELL, // only one of these objects can exist per cell
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
F_CREATEDBYSPELL, // object was made by spell id v0
|
||||
F_ENCHANTABLE, // object can get +1/-1 ect
|
||||
F_GODGIFT, // this was a gift form god with race v0.
|
||||
F_NOSHATTER, // object will not shatter, even if it's material should.
|
||||
|
@ -2118,7 +2142,7 @@ enum FLAG {
|
|||
|
||||
F_NUMAPPEAR, // when randomly appearing, can have > 1. val[0] = min, val[1] = max
|
||||
F_MINIONS, // val0 % chance of appearing with v1-v2 lf of type text
|
||||
F_HITDICE, // val0: # d4 to roll for maxhp per level. val1: +xx
|
||||
F_HITDICE, // text = xdy+z to roll for maxhp per level.
|
||||
F_MPDICE, // val0: # d4 to roll for maxmp per level. val1: +xx
|
||||
F_JOB, // val0 = player's class/job
|
||||
F_GODOF, // text = what this lf is the god of. use capitals.
|
||||
|
@ -2363,6 +2387,7 @@ enum FLAG {
|
|||
F_VAULTGOESIN, // this vault randomly appears in habitat type v0.
|
||||
// can be repeated multiple times
|
||||
// if a vault doesnt have this flag, it can go anywhere
|
||||
F_VAULTISPLAYERSTART, // player can start in this vault
|
||||
F_VAULTISSHOP, // this vault is a shop, so add f_shopitem to objects
|
||||
// here.
|
||||
F_VAULTISSHRINE, // this vault is a godstone shrine
|
||||
|
@ -2403,9 +2428,15 @@ enum HUNGER {
|
|||
// injuries
|
||||
enum INJURY {
|
||||
IJ_NONE,
|
||||
IJ_ANKLESWOLLEN,
|
||||
IJ_ARTERYPIERCE,
|
||||
IJ_BLACKEYE,
|
||||
IJ_CHESTBLEED,
|
||||
IJ_EYELIDSCRAPED,
|
||||
IJ_EYEDESTROYED,
|
||||
IJ_FINGERBROKEN,
|
||||
IJ_FINGERMISSING,
|
||||
IJ_HAMSTRUNG,
|
||||
IJ_HANDBLEED,
|
||||
IJ_LEGBLEED,
|
||||
IJ_LEGBROKEN,
|
||||
|
@ -2651,6 +2682,7 @@ typedef struct room_s {
|
|||
int id;
|
||||
int x1,y1,x2,y2;
|
||||
struct vault_s *vault;
|
||||
int exitslinked; // don't need to save this.
|
||||
} room_t;
|
||||
|
||||
typedef struct map_s {
|
||||
|
|
3
flag.c
3
flag.c
|
@ -921,7 +921,10 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
if (multiplier > 0) {
|
||||
howlong *= multiplier;
|
||||
}
|
||||
} else if ((f->id == F_INJURY) && hasflag(f->pile, F_ASLEEP)) {
|
||||
howlong *= 3;
|
||||
}
|
||||
|
||||
|
||||
f->lifetime -= howlong;
|
||||
|
||||
|
|
4
god.c
4
god.c
|
@ -175,7 +175,7 @@ void angergod(enum RACE rid, int amt) {
|
|||
case 2:
|
||||
// summon undead
|
||||
msg("\"Destroy him, my pets!\"");
|
||||
summonlfs(god, player->cell, RC_UNDEAD, SZ_ANY, AL_EVIL, 3, PERMENANT);
|
||||
summonlfs(god, player->cell, RC_UNDEAD, SZ_ANY, AL_EVIL, 3, PERMENANT, B_FALSE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -227,7 +227,7 @@ void angergod(enum RACE rid, int amt) {
|
|||
case 2:
|
||||
// summon holy creautes
|
||||
msg("\"Destroy him, my pets!\"");
|
||||
summonlfs(god, player->cell, RC_ANY, SZ_ANY, AL_GOOD, 3, PERMENANT);
|
||||
summonlfs(god, player->cell, RC_ANY, SZ_ANY, AL_GOOD, 3, PERMENANT, B_FALSE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
97
io.c
97
io.c
|
@ -1240,6 +1240,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DEAF:
|
||||
if (isplayer(lf)) {
|
||||
msg("^WYou cannot hear anything!");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("^gYou feel immune to %s!", getdamnamenoun(f->val[0]));
|
||||
|
@ -1780,6 +1786,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DEAF:
|
||||
if (isplayer(lf)) {
|
||||
msg("Your hearing returns.");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You are no longer immune to %s.", getdamnamenoun(f->val[0]));
|
||||
|
@ -3426,7 +3438,6 @@ void describeob(object_t *o) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// skip line
|
||||
y++;
|
||||
|
||||
|
@ -3615,7 +3626,7 @@ void describeob(object_t *o) {
|
|||
mvwprintw(mainwin, y, 0, "%s modifies your %s.", buf, getattrname(f->val[1])); y++;
|
||||
break;
|
||||
case F_BLIND:
|
||||
mvwprintw(mainwin, y, 0, "%s prevents you from seeing.", buf); y++;
|
||||
mvwprintw(mainwin, y, 0, "%s prevents you from seeing anything.", buf); y++;
|
||||
break;
|
||||
case F_BREATHWATER:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to breath normally while underwater.", buf); y++;
|
||||
|
@ -3623,6 +3634,9 @@ void describeob(object_t *o) {
|
|||
case F_CONTROL:
|
||||
mvwprintw(mainwin, y, 0, "%s lets you control teleportation and polymorphic effects.", buf); y++;
|
||||
break;
|
||||
case F_DEAF:
|
||||
mvwprintw(mainwin, y, 0, "%s prevents you from hearing anything.", buf); y++;
|
||||
break;
|
||||
case F_DETECTLIFE:
|
||||
mvwprintw(mainwin, y, 0, "%s will detect nearby lifeforms.", buf); y++;
|
||||
break;
|
||||
|
@ -4611,7 +4625,7 @@ void doeat(obpile_t *op) {
|
|||
|
||||
// edible objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
if (caneat(player, o)) {
|
||||
if (caneat(player, o) && canpickup(player, o, 1)) {
|
||||
getobname(o, obname, o->amt);
|
||||
snprintf(buf, BUFLEN, "There %s %s here. Eat %s",
|
||||
(o->amt == 1) ? "is" : "are",
|
||||
|
@ -5211,7 +5225,7 @@ void dooperate(obpile_t *op) {
|
|||
|
||||
// operable objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
if (isoperable(o)) {
|
||||
if (isoperable(o) && canpickup(player, o, 1)) {
|
||||
char obname[BUFLEN],buf[BUFLEN];
|
||||
char verb[BUFLEN];
|
||||
int ch;
|
||||
|
@ -5503,7 +5517,7 @@ void doquaff(obpile_t *op) {
|
|||
|
||||
// quaffable objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
if (isdrinkable(o) && canquaff(player, o)) {
|
||||
if (isdrinkable(o) && canquaff(player, o) && canpickup(player, o, 1)) {
|
||||
char obname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
char ch;
|
||||
|
@ -7865,7 +7879,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
job_t *j;
|
||||
flag_t *f;
|
||||
char *ftext= "%12s: ";
|
||||
char *ftext= "%13s: ";
|
||||
long xpneeded;
|
||||
object_t *o;
|
||||
object_t *w[2];
|
||||
|
@ -7881,7 +7895,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
obpile_t *op = NULL;
|
||||
char ch;
|
||||
char mode = '@';
|
||||
char prompt[BUFLEN];
|
||||
char promptstr[BUFLEN];
|
||||
char cmdchars[BUFLEN];
|
||||
int done = B_FALSE;
|
||||
enum SKILLLEVEL lorelev;
|
||||
|
@ -7912,12 +7926,12 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
if (showall) {
|
||||
snprintf(prompt, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects ^WG^nods %s^W?^n=help ^WESC^n=quit^h]",
|
||||
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects ^WG^nods %s^W?^n=help ^WESC^n=quit^h]",
|
||||
isplayer(lf) ? "" : "^WI^ntems " );
|
||||
snprintf(cmdchars, BUFLEN, "@asmeg%s",isplayer(lf) ? "" : "i");
|
||||
} else {
|
||||
snprintf(prompt, BUFLEN, "%s", "[ESC=quit]");
|
||||
snprintf(cmdchars, BUFLEN, "%s", "@");
|
||||
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats %s ESC=quit]", isplayer(lf) ? "" : "^WI^ntems ");
|
||||
snprintf(cmdchars, BUFLEN, "@i");
|
||||
}
|
||||
|
||||
while (!done) {
|
||||
|
@ -8393,7 +8407,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
rating = comparelfs(player, lf);
|
||||
setcol(mainwin, lorecol);
|
||||
if (rating >= 4) {
|
||||
snprintf(buf, BUFLEN, "It is not a threat.");
|
||||
snprintf(buf, BUFLEN, "It should pose no threat to you.");
|
||||
} else if (rating >= 3) {
|
||||
snprintf(buf, BUFLEN, "You could defeat it very easily.");
|
||||
} else if (rating >= 2) {
|
||||
|
@ -8549,12 +8563,12 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
nmissingbp = 0;
|
||||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
||||
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
||||
if (bp == BP_RIGHTHAND) {
|
||||
if (bp == BP_RIGHTFINGER) {
|
||||
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
||||
missingbp[nmissingbp] = bp;
|
||||
nmissingbp++;
|
||||
}
|
||||
} else if (bp == BP_LEFTHAND) {
|
||||
} else if (bp == BP_LEFTFINGER) {
|
||||
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL) &&
|
||||
!lfhasflagval(lf, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL)
|
||||
) {
|
||||
|
@ -8762,7 +8776,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
snprintf(buf, BUFLEN, "%s%s", ot->desc, eb2);
|
||||
wprintw(mainwin, buf);
|
||||
|
||||
if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) {
|
||||
if (downline(&y, h, "ABILITIES", NULL, promptstr, cmdchars, &ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8817,7 +8831,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
(known[n]->lifetime == FROMSPELL) ? "[spell]" : "");
|
||||
unsetcol(mainwin, getskilllevelcolour(known[n]->val[1]));
|
||||
}
|
||||
if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) {
|
||||
if (downline(&y, h, "SKILLS", skilltitle, promptstr, cmdchars, &ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -8898,7 +8912,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (castable) unsetcol(mainwin, C_GREEN);
|
||||
else unsetcol(mainwin, C_RED);
|
||||
anyfound = B_TRUE;
|
||||
if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) {
|
||||
if (downline(&y, h, "MAGIC", subheading, promptstr, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -8944,7 +8958,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
isplayer(lf) ? "have" : "has");
|
||||
y++;
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, " - %s", sp->name);
|
||||
mvwprintw(mainwin, y, 0, " - %s %s (consuming %d MP)", sp->name, roman(f->val[2]), f->val[1]);
|
||||
y++;
|
||||
nfound++;
|
||||
}
|
||||
|
@ -9052,6 +9066,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s can control teleportation and polymorphic effects.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_DEAF);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s deaf.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_DETECTAURAS);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s automatically detect blessings or curses.", you(lf));
|
||||
|
@ -9410,27 +9429,39 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
} else if (mode == 'i') {
|
||||
object_t *o;
|
||||
cls();
|
||||
centre(mainwin, C_WHITE, 0, "INVENTORY");
|
||||
if (lf == player) { // mindscanning it
|
||||
centre(mainwin, C_WHITE, 0, "INVENTORY");
|
||||
} else { // not mindscanning
|
||||
centre(mainwin, C_WHITE, 0, "INVENTORY (equipped items only)");
|
||||
}
|
||||
|
||||
y = 2;
|
||||
if (lfhasflag(lf, F_NOPACK)) {
|
||||
if ((lf == player) && lfhasflag(lf, F_NOPACK)) {
|
||||
mvwprintw(mainwin, y, 0, "It cannot carry anything.");
|
||||
} else if (countobs(lf->pack, B_FALSE)) {
|
||||
char invtitle[BUFLEN];
|
||||
float packweight,maxweight,pct;
|
||||
packweight = getobpileweight(lf->pack);
|
||||
maxweight = getmaxcarryweight(lf);
|
||||
pct = (packweight / maxweight) * 100;
|
||||
snprintf(invtitle, BUFLEN, "It is carrying: (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct);
|
||||
if (lf == player) {
|
||||
float packweight,maxweight,pct;
|
||||
packweight = getobpileweight(lf->pack);
|
||||
maxweight = getmaxcarryweight(lf);
|
||||
pct = (packweight / maxweight) * 100;
|
||||
snprintf(invtitle, BUFLEN, "It is carrying: (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct);
|
||||
} else {
|
||||
snprintf(invtitle, BUFLEN, "It is using:");
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "%s", invtitle);
|
||||
y += 2;
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
getobname(o, buf,o->amt);
|
||||
getobextrainfo(o, buf2);
|
||||
|
||||
mvwprintw(mainwin, y, 0, "%s%s", buf,buf2);
|
||||
|
||||
if (o->next && downline(&y, h, "INVENTORY", NULL, prompt, cmdchars, &ch)) {
|
||||
break;
|
||||
if ((lf == player) || isequipped(o)) {
|
||||
getobname(o, buf,o->amt);
|
||||
getobequipinfo(o, buf2); strcat(buf, buf2);
|
||||
getobextrainfo(o, buf2); strcat(buf, buf2);
|
||||
|
||||
mvwprintw(mainwin, y, 0, "%s", buf);
|
||||
|
||||
if (o->next && downline(&y, h, "INVENTORY", NULL, promptstr, cmdchars, &ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -9515,7 +9546,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
// wait for key
|
||||
centre(mainwin, C_WHITE, h-1, prompt);
|
||||
centre(mainwin, C_WHITE, h-1, promptstr);
|
||||
if (ch == '\0') {
|
||||
ch = getch();
|
||||
}
|
||||
|
@ -9534,7 +9565,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (showall) mode = ch;
|
||||
break;
|
||||
case 'i':
|
||||
if (showall && !isplayer(lf)) mode = ch;
|
||||
if (!isplayer(lf)) mode = ch;
|
||||
break;
|
||||
case '?':
|
||||
if (mode == 'g') { // help on gods
|
||||
|
|
4
lf.h
4
lf.h
|
@ -21,7 +21,7 @@ void autotarget(lifeform_t *lf);
|
|||
void autoweild(lifeform_t *lf);
|
||||
int appearsrandomly(enum RACE rid);
|
||||
void awardxpfor(lifeform_t *killed, float pct);
|
||||
void bleed(lifeform_t *lf);
|
||||
void bleed(lifeform_t *lf, int splatter);
|
||||
void breakgrabs(lifeform_t *lf, int fromme, int tome);
|
||||
long calcscore(lifeform_t *lf);
|
||||
int calcxp(lifeform_t *lf);
|
||||
|
@ -272,7 +272,7 @@ int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo);
|
|||
int loadfirearmfast(lifeform_t *lf);
|
||||
void loseconcentration(lifeform_t *lf);
|
||||
int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate);
|
||||
void losemp(lifeform_t *lf, int amt);
|
||||
void makefriendly(lifeform_t *lf, int howlong);
|
||||
int makenauseated(lifeform_t *lf, int amt, int howlong);
|
||||
|
|
355
map.c
355
map.c
|
@ -1038,7 +1038,19 @@ void fix_reachability(map_t *m) {
|
|||
int i,keepgoing = B_TRUE, nfixed = 0;
|
||||
int db = B_TRUE;
|
||||
cell_t *c = NULL;
|
||||
|
||||
if (db) dblog("fix_reachability starting.");
|
||||
|
||||
switch (m->habitat->id) {
|
||||
case H_FOREST:
|
||||
case H_HEAVEN:
|
||||
case H_PIT:
|
||||
case H_VILLAGE:
|
||||
if (db) dblog("fix_reachability not required for this habitat.");
|
||||
return;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// find first non-empty cell
|
||||
for (i = 0; i < m->w * m->h; i++) {
|
||||
if (!m->cell[i]->type->solid) {
|
||||
|
@ -1065,8 +1077,8 @@ void fix_reachability(map_t *m) {
|
|||
m->cell[i]->x, m->cell[i]->y);
|
||||
|
||||
linkexit(m->cell[i], B_TRUE, &nadded);
|
||||
if (db) dblog(" fixed unreachable area by added %d cells.", nadded);
|
||||
|
||||
if (db) dblog(" fixed unreachable area by adding %d cells.", nadded);
|
||||
assert(nadded);
|
||||
|
||||
// now run the test again.
|
||||
// 'c' will be where the next flood will will happen.
|
||||
|
@ -1821,14 +1833,16 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
}
|
||||
}
|
||||
|
||||
// link up room exits
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
linkexits(map, map->room[i].id);
|
||||
}
|
||||
|
||||
// now clear up dead ends again.
|
||||
remove_deadends(map, sparseness);
|
||||
|
||||
// link up room exits
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
if (!map->room[i].exitslinked) {
|
||||
linkexits(map, map->room[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
// add staircases.
|
||||
// first dungeon level has 1 up stairs, 3 down.
|
||||
// subsequent levels always have 3 up and down stairs
|
||||
|
@ -1868,6 +1882,8 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
// make sure we have at least one up stairs
|
||||
assert(findobinmap(map, OT_STAIRSUP));
|
||||
|
||||
// DOWN STAIRS
|
||||
if (map->depth < map->region->rtype->maxdepth) {
|
||||
|
@ -1980,9 +1996,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
}
|
||||
|
||||
// ensure there are no unreachable areas
|
||||
fix_reachability(map);
|
||||
}
|
||||
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
|
||||
|
@ -1995,9 +2008,8 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
|
|||
char buf[BUFLEN];
|
||||
//object_t *o;
|
||||
|
||||
// what kind of cells will 'empty' ones be?
|
||||
// fill entire maze with emptiness
|
||||
emptycell = map->habitat->emptycelltype;
|
||||
// fill entire maze with walls
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
c = addcell(map, x, y);
|
||||
|
@ -2005,55 +2017,84 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
|
|||
}
|
||||
}
|
||||
|
||||
// determine density
|
||||
density = rnd(40,70);
|
||||
// add a plant to density percent of cells
|
||||
ntrees = (int)(((float)density/100.0) * (float)(map->w*map->h));
|
||||
for (i = 0; i < ntrees; i++) {
|
||||
c = getrandomcell(map);
|
||||
while (c->lf) {
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
switch (rnd(0,1)) {
|
||||
default: case 0: strcpy(buf, "tree"); break;
|
||||
case 1: strcpy(buf, "shrub"); break;
|
||||
}
|
||||
addob(c->obpile, buf);
|
||||
}
|
||||
|
||||
// clearings
|
||||
for (i = 0; i < nclearings; i++) {
|
||||
int w;
|
||||
c = getrandomcell(map);
|
||||
w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS);
|
||||
for (y = c->y - w; y <= c->y + w; y++) {
|
||||
for (x = c->x - w; x <= c->x + w; x++) {
|
||||
cell_t *newc;
|
||||
int dist = 999;
|
||||
newc = getcellat(map, x, y);
|
||||
|
||||
|
||||
if (newc) {
|
||||
dist = getcelldistorth(newc, c);
|
||||
if (dist <= w) {
|
||||
int dirtchance;
|
||||
// kill all obs here
|
||||
while (newc->obpile->first) killob(newc->obpile->first);
|
||||
|
||||
// change it into dirt.
|
||||
// ie. at centre (dist=0) dirt chance is 100%
|
||||
// ie. at max distance, dirt chance is 30%
|
||||
dirtchance = 100 - (((float)dist / (float)w) * 70);
|
||||
if (rnd(1,100) <= dirtchance) {
|
||||
setcelltype(newc, CT_DIRT);
|
||||
|
||||
switch (rnd(1,2)) {
|
||||
case 1: // forest type 1: add trees in x% of cells, then add some clearings
|
||||
// determine density
|
||||
density = rnd(40,70);
|
||||
// add a plant to density percent of cells
|
||||
ntrees = (int)(((float)density/100.0) * (float)(map->w*map->h));
|
||||
for (i = 0; i < ntrees; i++) {
|
||||
c = getrandomcell(map);
|
||||
while (c->lf) c = getrandomcell(map);
|
||||
switch (rnd(0,1)) {
|
||||
default: case 0: strcpy(buf, "tree"); break;
|
||||
case 1: strcpy(buf, "shrub"); break;
|
||||
}
|
||||
addob(c->obpile, buf);
|
||||
}
|
||||
// clearings
|
||||
for (i = 0; i < nclearings; i++) {
|
||||
int w;
|
||||
c = getrandomcell(map);
|
||||
w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS);
|
||||
for (y = c->y - w; y <= c->y + w; y++) {
|
||||
for (x = c->x - w; x <= c->x + w; x++) {
|
||||
cell_t *newc;
|
||||
int dist = 999;
|
||||
newc = getcellat(map, x, y);
|
||||
if (newc) {
|
||||
dist = getcelldistorth(newc, c);
|
||||
if (dist <= w) {
|
||||
int dirtchance;
|
||||
// kill all obs here
|
||||
while (newc->obpile->first) killob(newc->obpile->first);
|
||||
|
||||
// change it into dirt.
|
||||
// ie. at centre (dist=0) dirt chance is 100%
|
||||
// ie. at max distance, dirt chance is 30%
|
||||
dirtchance = 100 - (((float)dist / (float)w) * 70);
|
||||
if (rnd(1,100) <= dirtchance) {
|
||||
setcelltype(newc, CT_DIRT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: // add clusters of trees
|
||||
nclearings = rnd(5,10);
|
||||
for (i = 0; i < nclearings; i++) {
|
||||
int w;
|
||||
c = getrandomcell(map);
|
||||
while (c->lf) c = getrandomcell(map);
|
||||
|
||||
// add monsters
|
||||
w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS);
|
||||
for (y = c->y - w; y <= c->y + w; y++) {
|
||||
for (x = c->x - w; x <= c->x + w; x++) {
|
||||
cell_t *newc;
|
||||
int dist = 999;
|
||||
newc = getcellat(map, x, y);
|
||||
if (newc) {
|
||||
dist = getcelldistorth(newc, c);
|
||||
if (dist <= w) {
|
||||
int treechance;
|
||||
treechance = 100 - (((float)dist / (float)w) * 70);
|
||||
if (rnd(1,100) <= treechance) {
|
||||
switch (rnd(0,1)) {
|
||||
default: case 0: strcpy(buf, "tree"); break;
|
||||
case 1: strcpy(buf, "shrub"); break;
|
||||
}
|
||||
addob(c->obpile, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2391,6 +2432,9 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
}
|
||||
|
||||
// ensure there are no unreachable areas
|
||||
fix_reachability(map);
|
||||
|
||||
// special cases
|
||||
// village - add town walls and clear it out
|
||||
if (db) dblog(" finalising village creation...");
|
||||
|
@ -2677,6 +2721,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
map->room[map->nrooms].x2 = maxx;
|
||||
map->room[map->nrooms].y2 = maxy;
|
||||
map->room[map->nrooms].vault = v;
|
||||
map->room[map->nrooms].exitslinked = B_FALSE;
|
||||
thisroom = &(map->room[map->nrooms]);
|
||||
map->nrooms++;
|
||||
|
||||
|
@ -2718,6 +2763,9 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
autodoors(map, roomid, minx, miny, maxx, maxy, f->val[0], B_NODOORS);
|
||||
}
|
||||
|
||||
// link up exits from this vault
|
||||
linkexits(map, roomid);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2726,11 +2774,11 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
// if 'wantfilled' is set, only link to "filled" cells.
|
||||
// return TRUE on failure.
|
||||
int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
||||
int db = B_FALSE;
|
||||
int db = B_TRUE;
|
||||
int d, roomid;
|
||||
int poss2[MAXCANDIDATES],nposs2;
|
||||
int dist[MAXDIR_ORTH];
|
||||
int hitsedge[MAXDIR_ORTH];
|
||||
int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH];
|
||||
cell_t *directendcell[MAXDIR_ORTH];
|
||||
int mindist = 999,maxdist = -1;
|
||||
cell_t *c;
|
||||
|
||||
|
@ -2739,6 +2787,10 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
if (db) dblog(" calling linkexit() for cell at %d,%d", startcell->x, startcell->y);
|
||||
|
||||
roomid = getroomid(startcell);
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
hitsedge[d] = B_TRUE;
|
||||
directendcell[d] = NULL;
|
||||
}
|
||||
|
||||
// link it. starting from the door, count the number of cells in
|
||||
// each direction until we hit an empty (walkable) cell which isn't a room.
|
||||
|
@ -2747,6 +2799,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
for (d = D_N; d <= D_W; d++) {
|
||||
dist[d] = 0;
|
||||
hitsedge[d] = B_TRUE;
|
||||
sameroom[d] = B_FALSE;
|
||||
c = getcellindir(startcell, d);
|
||||
while (c) {
|
||||
dist[d]++;
|
||||
|
@ -2760,6 +2813,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
} else {
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
sameroom[d] = B_TRUE;
|
||||
if (db) dblog(" going %s hits same room. invalid.", getdirname(d));
|
||||
break;
|
||||
}
|
||||
|
@ -2767,6 +2821,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
if (!wantfilled || c->filled) {
|
||||
// walkable and not in this vault. finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
directendcell[d] = c;
|
||||
if (db) dblog(" can make %s path (hits empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
break;
|
||||
}
|
||||
|
@ -2785,7 +2840,8 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
if (!wantfilled || c->filled) {
|
||||
// finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
if (db) dblog(" can make %s path (hits adjacent empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
directendcell[d] = c;
|
||||
if (db) dblog(" can make %s path (hits adjacent empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2796,32 +2852,47 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
c = getcellindir(c, d); // getting the same cell!
|
||||
}
|
||||
if (dist[d] != 999) {
|
||||
if (!hitsedge[d]) {
|
||||
if (dist[d] < mindist) mindist = dist[d];
|
||||
}
|
||||
if (dist[d] < mindist) mindist = dist[d];
|
||||
if (dist[d] > maxdist) maxdist = dist[d];
|
||||
}
|
||||
}
|
||||
|
||||
if (mindist == 999) {
|
||||
cell_t *turncell = NULL,*endcell = NULL;
|
||||
cell_t *perpcell[MAX_MAPW*MAX_MAPH];
|
||||
cell_t *perpturncell1[MAX_MAPW*MAX_MAPH];
|
||||
int perpturndir1[MAX_MAPW*MAX_MAPH];
|
||||
int nperpcells = 0;
|
||||
int perpdir[2];
|
||||
int startdir = D_NONE;
|
||||
int turndir = D_NONE;
|
||||
int startdist = 0;
|
||||
int maxdist2 = -1;
|
||||
int startposs[MAXDIR_ORTH];
|
||||
int nstartposs = 0;
|
||||
// no good directions.
|
||||
if (db) dblog(" No directions lead to valid cells. Trying turns.");
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// find longest distance
|
||||
// find longest distance that doesn't go through same room
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist) {
|
||||
startdir = d;
|
||||
break;
|
||||
if (!sameroom[d] && (dist[d] > maxdist2)) {
|
||||
maxdist2 = dist[d];
|
||||
}
|
||||
}
|
||||
// pick one randomly
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist2) {
|
||||
startposs[nstartposs++] = d;
|
||||
}
|
||||
}
|
||||
if (nstartposs) {
|
||||
startdir = startposs[rnd(0,nstartposs-1)];
|
||||
}
|
||||
|
||||
assert(startdir != D_NONE);
|
||||
|
||||
// figure out perpendicular dirs
|
||||
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
|
@ -2839,6 +2910,12 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
for (n = 0; n <= 1; n++) {
|
||||
int turndist = 0;
|
||||
c2 = getcellindir(c, perpdir[n]);
|
||||
|
||||
perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns
|
||||
perpturncell1[nperpcells] = c;
|
||||
perpturndir1[nperpcells] = perpdir[n];
|
||||
nperpcells++;
|
||||
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
turndist++;
|
||||
|
@ -2875,7 +2952,6 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gotsolution) {
|
||||
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
|
||||
startdist, getdirname(startdir),
|
||||
|
@ -2915,17 +2991,126 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
c = getcellindir(c, turndir);
|
||||
}
|
||||
} else {
|
||||
// give up??
|
||||
if (db) dblog(" Cannot find a way to link up.");
|
||||
// We need to make 3 turns.
|
||||
// for each perpcell[], look in startdir + diropposite(startdir)
|
||||
int dir3[2],i,n;
|
||||
cell_t *turncell2 = NULL;
|
||||
int turndir2;
|
||||
dir3[0] = startdir;
|
||||
dir3[1] = diropposite(startdir);
|
||||
for (i = 0; i < nperpcells; i++) {
|
||||
for (n = 0; n < 1; n++) {
|
||||
cell_t *c2;
|
||||
int turndist = 0;
|
||||
c2 = getcellindir(perpcell[i], dir3[n]);
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
turndist++;
|
||||
if ((roomid >= 0) && (getroomid(c2) == roomid)) {
|
||||
if (wantfilled && c2->type->solid) {
|
||||
// see EXCEPTION above.
|
||||
} else {
|
||||
// hits same room, not ok.
|
||||
break;
|
||||
}
|
||||
} else if (cellwalkable(NULL, c2, NULL)) {
|
||||
if (!wantfilled || c2->filled) {
|
||||
if (db) dblog(" Got to an empty cell here.");
|
||||
gotsolution = B_TRUE;
|
||||
}
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
|
||||
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
|
||||
for (nn = 0; nn <= 1; nn++) {
|
||||
pcell = getcellindir(c2, perpdir2[nn]);
|
||||
if (pcell) {
|
||||
if ( ((roomid == -1) || (getroomid(pcell) != roomid)) &&
|
||||
cellwalkable(NULL, pcell, NULL)) {
|
||||
if (!wantfilled || pcell->filled) {
|
||||
// finished.
|
||||
if (db) dblog(" Got to an empty cell next to us.");
|
||||
gotsolution = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotsolution) {
|
||||
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
|
||||
startdist, getdirname(startdir),
|
||||
turndist, getdirname(perpdir[n]));
|
||||
|
||||
turncell = perpturncell1[i];
|
||||
turndir = perpturndir1[i];
|
||||
turncell2 = perpcell[i];
|
||||
turndir2 = dir3[n];
|
||||
|
||||
endcell = c2;
|
||||
break;
|
||||
}
|
||||
// check next cell
|
||||
c2 = getcellindir(c2, perpdir[n]);
|
||||
} // end while c2
|
||||
if (turncell2) break;
|
||||
} // end for n=1-2
|
||||
if (turncell2) break;
|
||||
} // end foreach perpcell
|
||||
|
||||
// TODO: if we find a solution, fill in turncell2 and make path.
|
||||
if (turncell2) {
|
||||
if (db) dblog(" 2turn Solution found: Walk %s, then %s, then %s.",
|
||||
getdirname(startdir), getdirname(turndir), getdirname(turndir2));
|
||||
|
||||
// make a path up to the turn point.
|
||||
if (db) dblog(" Making path from vault to first corner, initdir=%s", getdirname(startdir));
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c != turncell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
// clear the corner cell
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
// now turn and clear up to the next turn
|
||||
if (db) dblog(" Making path from 1st corner to 2nd corner, turndir=%s", getdirname(turndir));
|
||||
c = getcellindir(c, turndir);
|
||||
while (c != turncell2) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir);
|
||||
}
|
||||
|
||||
// now turn and clear up to the next room/empty cell
|
||||
if (db) dblog(" Making path from 2nd corner to rest of map, turndir=%s", getdirname(turndir2));
|
||||
c = getcellindir(c, turndir2);
|
||||
while (c != endcell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir2);
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(" Cannot find a way to link up.");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
} else {
|
||||
} else { // we found a way to go without needing to turn.
|
||||
int whichway,sel;
|
||||
// now pick the shortest one which doesn't hits the edge
|
||||
int mindist2 = 999;
|
||||
// now pick the shortest one which doesn't hit the edge
|
||||
// get list of all the minimums and randomly tie-break
|
||||
nposs2 = 0;
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == mindist) {
|
||||
if (!hitsedge[d] && (dist[d] < mindist2)) {
|
||||
mindist2 = dist[d];
|
||||
}
|
||||
}
|
||||
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == mindist2) {
|
||||
poss2[nposs2++] = d;
|
||||
}
|
||||
}
|
||||
|
@ -2933,9 +3118,10 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
whichway = poss2[sel];
|
||||
|
||||
// now create a path
|
||||
if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), mindist);
|
||||
if (db) dblog(" Linking directly %s (distance %d).", getdirname(whichway), mindist);
|
||||
c = getcellindir(startcell, whichway);
|
||||
while (c && !cellwalkable(NULL, c, NULL)) {
|
||||
//while (c && !cellwalkable(NULL, c, NULL)) {
|
||||
while (c && c != directendcell[whichway]) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, whichway);
|
||||
|
@ -2949,9 +3135,10 @@ int linkexits(map_t *m, int roomid) {
|
|||
int x,y,i;
|
||||
cell_t *poss[MAXCANDIDATES],*c;
|
||||
int nposs = 0;
|
||||
int db = B_FALSE;
|
||||
int db = B_TRUE;
|
||||
int nadded = 0;
|
||||
int minx = -1, miny = -1, maxx = -1, maxy = -1;
|
||||
int roomidx = -1;
|
||||
|
||||
// figure out room coords
|
||||
for (i = 0; i < m->nrooms; i++) {
|
||||
|
@ -2960,10 +3147,11 @@ int linkexits(map_t *m, int roomid) {
|
|||
miny = m->room[i].y1;
|
||||
maxx = m->room[i].x2;
|
||||
maxy = m->room[i].y2;
|
||||
roomidx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(minx != -1);
|
||||
assert(roomidx != -1);
|
||||
|
||||
|
||||
if (db) {
|
||||
|
@ -2984,8 +3172,10 @@ int linkexits(map_t *m, int roomid) {
|
|||
if (!c) continue;
|
||||
|
||||
if (hasobwithflag(c->obpile, F_DOOR)) {
|
||||
if (db) dblog("found door at %d,%d",x,y);
|
||||
poss[nposs++] = c;
|
||||
if ((x == minx) || (x == maxx) || (y == miny) || (y == maxy) ) {
|
||||
if (db) dblog("found wall door at %d,%d",x,y);
|
||||
poss[nposs++] = c;
|
||||
}
|
||||
} else if (hasflagval(m->flags, F_ROOMEXIT, roomid, x, y, NULL)) {
|
||||
if (db) dblog("found roomexit at %d,%d",x,y);
|
||||
poss[nposs++] = c;
|
||||
|
@ -3016,6 +3206,8 @@ int linkexits(map_t *m, int roomid) {
|
|||
}
|
||||
} // end for each door
|
||||
|
||||
m->room[roomidx].exitslinked = B_TRUE;
|
||||
|
||||
if (db) dblog("linkexits complete (%d added).", nadded);
|
||||
return nadded;
|
||||
}
|
||||
|
@ -3116,6 +3308,7 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
|
|||
map->room[map->nrooms].x2 = maxx;
|
||||
map->room[map->nrooms].y2 = maxy;
|
||||
map->room[map->nrooms].vault = NULL;
|
||||
map->room[map->nrooms].exitslinked = B_FALSE;
|
||||
thisroom = &(map->room[map->nrooms]);
|
||||
map->nrooms++;
|
||||
|
||||
|
@ -4184,6 +4377,7 @@ void initmap(void) {
|
|||
}
|
||||
//vx = 0; vy = -1;
|
||||
addregionoutline(RG_FIRSTDUNGEON);
|
||||
addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL);
|
||||
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");
|
||||
addregionthing(lastregionoutline, 10, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISSHRINE, NULL); // godstone on last floor
|
||||
}
|
||||
|
@ -4904,6 +5098,9 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
|
|||
losehp(target, rnd(1,100), DT_SLASH, fromlf, damstring); // BIG damage
|
||||
}
|
||||
|
||||
// change cell type
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
|
||||
// place shards
|
||||
if (c->type->material->id == MT_GLASS) {
|
||||
int numshards;
|
||||
|
|
40
move.c
40
move.c
|
@ -28,9 +28,6 @@ extern void (*precalclos)(lifeform_t *);
|
|||
extern enum ERROR reason;
|
||||
extern void *rdata;
|
||||
|
||||
extern flag_t *retflag[];
|
||||
extern int nretflags;
|
||||
|
||||
extern long curtime;
|
||||
|
||||
extern WINDOW *gamewin, *msgwin;
|
||||
|
@ -739,6 +736,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
i = howfar;
|
||||
// don't fall
|
||||
mightfall = B_FALSE;
|
||||
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf), DT_BASH);
|
||||
break;
|
||||
case E_SWIMMING:
|
||||
case E_LFINWAY:
|
||||
|
@ -874,21 +872,25 @@ int moveclear(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
|
||||
// effects which happen after player moves.
|
||||
// IMPORTANT: don't modify lf's flagpile during this code!
|
||||
// particularly don't remove flags...
|
||||
|
||||
// returns TRUE if we displayed a message
|
||||
int moveeffects(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
int didmsg = B_FALSE;
|
||||
|
||||
if (lfhasflagval(lf, F_INJURY, IJ_HAMSTRUNG, NA, NA, NULL)) {
|
||||
if (!skillcheck(lf, SC_FALL, 20, 0)) fall(lf, NULL, B_TRUE);
|
||||
}
|
||||
|
||||
if (isbleeding(lf)) {
|
||||
if (lfhasflagval(lf, F_INJURY, NA, BP_LEGS, DT_SLASH, NULL)) {
|
||||
bleed(lf);
|
||||
bleed(lf, B_FALSE);
|
||||
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
|
||||
} else {
|
||||
if (rnd(1,2) == 1) {
|
||||
bleed(lf);
|
||||
bleed(lf, B_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1455,6 +1457,30 @@ int movetowards(lifeform_t *lf, cell_t *dst, int dirtype) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
int move_will_hurt(lifeform_t *lf) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
|
||||
if (lfhasflag(lf, F_PAIN)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_PAIN, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
flag_t *f;
|
||||
f = retflag[i];
|
||||
if (f->id == F_PAIN) return B_TRUE;
|
||||
if (f->id == F_INJURY) {
|
||||
switch (f->val[0]) {
|
||||
case IJ_LEGBLEED:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int opendoorat(lifeform_t *lf, cell_t *c) {
|
||||
object_t *o;
|
||||
int rv;
|
||||
|
@ -2649,7 +2675,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
// for at least average iq things...
|
||||
if (iq >= AT_AVERAGE) {
|
||||
// don't move if in pain
|
||||
if (lfhasflag(lf, F_PAIN)) {
|
||||
if (move_will_hurt(lf)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
1
move.h
1
move.h
|
@ -19,6 +19,7 @@ int moveeffects(lifeform_t *lf);
|
|||
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg);
|
||||
int movetowards(lifeform_t *lf, cell_t *dst, int dirtype);
|
||||
int move_will_hurt(lifeform_t *lf);
|
||||
int opendoorat(lifeform_t *lf, cell_t *c);
|
||||
int opendoor(lifeform_t *lf, object_t *o);
|
||||
int pullnextto(lifeform_t *lf, cell_t *c);
|
||||
|
|
64
nexus.c
64
nexus.c
|
@ -151,11 +151,10 @@ int main(int argc, char **argv) {
|
|||
|
||||
// if no player (ie. didn't load a game), add them
|
||||
if (!player) {
|
||||
char *user;
|
||||
char pname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
char *user,pname[BUFLEN],buf[BUFLEN];
|
||||
job_t *j = NULL;
|
||||
char ch;
|
||||
object_t *o;
|
||||
cell_t *where;
|
||||
int dir;
|
||||
flag_t *f;
|
||||
|
@ -222,13 +221,20 @@ int main(int argc, char **argv) {
|
|||
killlf(where->lf);
|
||||
}
|
||||
|
||||
// add player nearby
|
||||
where = real_getrandomadjcell(where, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL);
|
||||
// add player in the starting position
|
||||
//where = real_getrandomadjcell(where, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL);
|
||||
where = findobinmap(dmap, OT_PLAYERSTART);
|
||||
if (!where) {
|
||||
dblog("fatal error: couldn't find player start position!");
|
||||
msg("fatal error: couldn't find player start position!");
|
||||
more();
|
||||
exit(1);
|
||||
}
|
||||
real_addlf(where, R_HUMAN, 1, C_PLAYER); // this will assign 'player'
|
||||
|
||||
// add abilities which the player always has
|
||||
addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL);
|
||||
addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL);
|
||||
o = hasob(where->obpile, OT_PLAYERSTART);
|
||||
killob(o);
|
||||
|
||||
user = getenv("USER");
|
||||
if (user) {
|
||||
|
@ -1199,50 +1205,32 @@ int rolldie(int ndice, int sides) {
|
|||
|
||||
int rollhitdice(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
int ndice, plus;
|
||||
int roll = 0;
|
||||
int i;
|
||||
int ndice, nsides = 4, plus = 0;
|
||||
int myroll = 0;
|
||||
float mod;
|
||||
int db = B_FALSE;
|
||||
|
||||
f = hasflag(lf->flags, F_HITDICE);
|
||||
if (f) {
|
||||
ndice = f->val[0];
|
||||
if (f->val[1] == NA) plus = 0;
|
||||
else plus = f->val[1];
|
||||
myroll = roll(f->text);
|
||||
} else {
|
||||
ndice = 1;
|
||||
nsides = 4;
|
||||
plus = 0;
|
||||
myroll = roll("1d4");
|
||||
}
|
||||
if (db) dblog("rollhitdice() for %s - rolling %dd4 + %d",lf->race->name,ndice,plus);
|
||||
|
||||
mod = 100 + getstatmod(lf, A_CON);
|
||||
if (db) dblog("rollhitdice() - mod is +%0.0f%%",mod);
|
||||
|
||||
if (ndice == 0) {
|
||||
int thisroll;
|
||||
// just the bonus
|
||||
thisroll = plus;
|
||||
|
||||
if (thisroll < 1) thisroll = 1;
|
||||
|
||||
roll += thisroll;
|
||||
} else {
|
||||
for (i = 0; i < ndice; i++) {
|
||||
int thisroll;
|
||||
thisroll = rolldie(1, 4) + plus;
|
||||
if (thisroll < 1) thisroll = 1;
|
||||
if (db) dblog("rollhitdice() ---- die %d/%d == %d",i+1,ndice,thisroll);
|
||||
|
||||
roll += thisroll;
|
||||
}
|
||||
}
|
||||
if (db) dblog("TOTAL: %d",roll);
|
||||
|
||||
if (db) dblog("TOTAL: %d",myroll);
|
||||
|
||||
// modify for fitness/con
|
||||
roll = pctof(mod, roll);
|
||||
limit(&roll, 1, NA);
|
||||
if (db) dblog(" -> modified to: %d",roll);
|
||||
return roll;
|
||||
myroll = pctof(mod, myroll);
|
||||
limit(&myroll, 1, NA);
|
||||
if (db) dblog(" -> modified to: %d",myroll);
|
||||
return myroll;
|
||||
}
|
||||
|
||||
int rollmpdice(lifeform_t *lf) {
|
||||
|
@ -1533,7 +1521,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
|
|||
|
||||
if (updategametime) {
|
||||
// inc game time
|
||||
curtime += firstlftime;
|
||||
curtime += (firstlftime*(TIMECONST));
|
||||
// don't let it get higher than 23:59
|
||||
while (curtime >= DAYSECS) {
|
||||
curtime -= DAYSECS;
|
||||
|
|
184
objects.c
184
objects.c
|
@ -455,6 +455,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
nadded = 0;
|
||||
nretobs = 0;
|
||||
|
||||
if (where->where) {
|
||||
assert(!where->where->type->solid);
|
||||
}
|
||||
|
||||
if (where->owner && hasflag(where->owner->flags, F_NOPACK)) {
|
||||
if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name);
|
||||
nretobs = 0;
|
||||
|
@ -468,7 +472,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
dblog("DB: called addobject() for forceoid %s, canstack = %d",ot->name, canstack);
|
||||
}
|
||||
} else {
|
||||
char *p2;
|
||||
char *bonusstart,*p2;
|
||||
int bonussign = 1;
|
||||
localname = strdup(name);
|
||||
|
||||
if (db) {
|
||||
|
@ -532,36 +537,34 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
}
|
||||
|
||||
bonus = 0;
|
||||
|
||||
// handle for bonuses. eg. "+1"
|
||||
p2 = strchr(p, '+');
|
||||
if (p2) {
|
||||
char *p3;
|
||||
bonusstart = strchr(p, '+');
|
||||
if (!bonusstart) {
|
||||
bonussign = -1;
|
||||
bonusstart = strchr(p, '-');
|
||||
}
|
||||
if (bonusstart) {
|
||||
char *p3,*bonusend;
|
||||
char numbuf[BUFLENSMALL];
|
||||
|
||||
p3 = numbuf;
|
||||
p++;
|
||||
while (isdigit(*p2)) {
|
||||
*p3 = *p2;
|
||||
p2++;
|
||||
bonusend = bonusstart+1; // go past the + or -
|
||||
while (isdigit(*bonusend)) { // grab the full number
|
||||
*p3 = *bonusend;
|
||||
bonusend++;
|
||||
p3++;
|
||||
}
|
||||
*p3 = '\0';
|
||||
bonus += atoi(numbuf);
|
||||
}
|
||||
// check for penalties. eg. "-1"
|
||||
p2 = strchr(p, '-');
|
||||
if (p2) {
|
||||
char *p3;
|
||||
char numbuf[BUFLENSMALL];
|
||||
p3 = numbuf;
|
||||
p2++;
|
||||
while (isdigit(*p2)) {
|
||||
*p3 = *p2;
|
||||
p2++;
|
||||
p3++;
|
||||
bonus += (atoi(numbuf) * bonussign);
|
||||
// strip off the "+xxx" / "-xxx", as long as xxx was a number.
|
||||
// might not be the case if it was part of the object name
|
||||
// eg. "waist-deep water"
|
||||
if (bonus) {
|
||||
while (*bonusend == ' ') bonusend++; // go past spaces
|
||||
strcpy(bonusstart, bonusend);
|
||||
}
|
||||
*p3 = '\0';
|
||||
bonus -= atoi(numbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// handle prefixes. strip them off as we go.
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1269,7 +1272,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
rf = hasflag(corpserace->flags, F_HITDICE);
|
||||
if (rf) {
|
||||
int maxhp;
|
||||
maxhp = (rf->val[0] * 4) + rf->val[1];
|
||||
maxhp = roll(rf->text);
|
||||
f->val[0] = maxhp;
|
||||
f->val[1] = maxhp;
|
||||
}
|
||||
|
@ -4576,7 +4579,9 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
strcpy(triedbuf, "");
|
||||
|
||||
if (hasflag(o->flags, F_BEINGUSED)) {
|
||||
strcat(triedbuf, " [currently being read]");
|
||||
if (strlen(triedbuf)) strcat(triedbuf, ", ");
|
||||
else strcpy(triedbuf, " [");
|
||||
strcat(triedbuf, "currently being read");
|
||||
}
|
||||
|
||||
if (istried(o)) {
|
||||
|
@ -5734,9 +5739,8 @@ void initobjects(void) {
|
|||
addmaterial(MT_METAL, "metal", 13);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BITE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_BITE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
|
||||
addmaterial(MT_GLASS, "glass", 13);
|
||||
|
@ -5784,8 +5788,8 @@ void initobjects(void) {
|
|||
addoc(OC_RING, "Rings", "A circular band, worn on the finger.", '=', C_GREY);
|
||||
addocnoun(lastobjectclass, "ring");
|
||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_GOESON, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTFINGER, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_GOESON, BP_LEFTFINGER, NA, NA, NULL);
|
||||
addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY);
|
||||
addocnoun(lastobjectclass, "weapon");
|
||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6041,7 +6045,7 @@ void initobjects(void) {
|
|||
|
||||
|
||||
addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE);
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "&");
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "^");
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6101,7 +6105,7 @@ void initobjects(void) {
|
|||
addot(OT_TRAPSUMMON, "summoning trap", "A magical trap which causes a monster to appear.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
|
||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "^");
|
||||
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||
|
@ -6400,12 +6404,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
|
||||
// corpses
|
||||
addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden
|
||||
addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_SMALL);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden
|
||||
addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD, SZ_SMALL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL);
|
||||
addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
|
||||
|
||||
|
||||
// potions (sorted by rarity)
|
||||
|
@ -6589,8 +6595,8 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, 4, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL);
|
||||
|
@ -6681,7 +6687,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
|
@ -6837,7 +6843,7 @@ void initobjects(void) {
|
|||
addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity, dealing 1-^bpower^n damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
|
@ -6854,6 +6860,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||
addot(OT_S_SHATTER, "shatter", "Instantly shatters all glass in the target location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
|
@ -6880,8 +6887,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 2d6 damage, the next deals 2d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 3d6 damage, the next deals 3d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
|
@ -6933,14 +6941,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
||||
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd4 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
///////////////////
|
||||
// elemental - ice
|
||||
// elemental - cold
|
||||
///////////////////
|
||||
// l1
|
||||
addot(OT_S_CHILL, "chill", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
|
@ -6981,7 +6989,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 2-10 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 3d6 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how difficult the ray is to dodge.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
|
@ -7020,6 +7028,27 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_CRYSTALARM, "crystalline armour", "Summons ice crystal armour to protect you from damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 1-3: one piece of armour is created.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 4-6: two pieces of armour are created.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 7-9: three pieces of armour are created.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power 10: four pieces of armour are created.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_SHARDSHOT, "shard shot", "Fires a scattered burst of small, fast moving ice shards. The shot will pass through multiple creatures, but damage is reduced with range.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is determined by its power.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_WALLSTOP, NA, NULL);
|
||||
addot(OT_S_SNAPFREEZE, "snap freeze", "Instantly freezes the target creature. Cold-resistant creatures will take minor damage instead.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
///////////////////
|
||||
// nature
|
||||
///////////////////
|
||||
|
@ -7076,6 +7105,7 @@ void initobjects(void) {
|
|||
addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
@ -7166,6 +7196,7 @@ void initobjects(void) {
|
|||
addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
@ -7187,7 +7218,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l6
|
||||
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how many bolts will appear.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
|
@ -7196,6 +7227,7 @@ void initobjects(void) {
|
|||
addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
@ -7486,6 +7518,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_SUMMONDEMON, "summon demon", "Summons a random demonic entity.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its chances of success, and how long the demon will remain.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
///////////////////
|
||||
// translocation
|
||||
///////////////////
|
||||
|
@ -7551,7 +7589,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addot(OT_S_ALARM, "alarm", "Creates a passive alarm which goes off when an enemy is nearby.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
||||
|
@ -7559,7 +7597,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster, causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster, causing 2d6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the radius of the blast.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
|
@ -7815,7 +7853,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit");
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
||||
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
|
||||
|
@ -7837,7 +7875,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 100, 200, NA, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 200, 400, NA, NULL);
|
||||
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
||||
|
@ -7849,7 +7887,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 200, 300, NA, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 300, 500, NA, NULL);
|
||||
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
||||
|
@ -7875,7 +7913,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_HELPSCLIMB, 3, NA, NA, NULL);
|
||||
|
||||
addot(OT_SACK, "sack", "A small cloth sack.", MT_CLOTH, 0.5, OC_TOOLS, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "(");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7982,7 +8020,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit");
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 100, 200, NA, NULL);
|
||||
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_FIRE, NA, NA, "1d4");
|
||||
|
@ -8174,7 +8212,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_CHEST, "chest", "A small wooden treasure chest.", MT_METAL, 40, OC_FURNITURE, SZ_MEDIUM);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "(");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -9007,6 +9045,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
||||
addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL);
|
||||
|
||||
// armour - ears
|
||||
addot(OT_EARPLUGS, "set of earplugs", "A pair of cloth plugs designed to give the wearer a peaceful night's sleep. ", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_EARS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_DEAF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// armour - eyes
|
||||
addot(OT_SUNGLASSES, "pair of sunglasses", "Tinted eyewear to protect against sunlight.", MT_GLASS, 0.01, OC_ARMOUR, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
|
@ -9796,6 +9842,26 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); // will be replaced when summoned
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
|
||||
|
||||
addot(OT_ICEARMOUR, "ice crystal armour", "Summoned body armour made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_HUMAN);
|
||||
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
|
||||
addot(OT_ICEBOOTS, "pair of ice crystal boots", "Summoned boots made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL);
|
||||
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
|
||||
addot(OT_ICEGLOVES, "pair of ice crystal gauntlets", "Summoned gauntlets made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL);
|
||||
addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
|
||||
addot(OT_ICEHELMET, "ice crystal helmet", "A summoned helmet made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL);
|
||||
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
|
||||
|
||||
// special obs
|
||||
addot(OT_PLAYERSTART, "playerstart", "starting pos for player", MT_NOTHING, 0, OC_MISC, SZ_MINI);
|
||||
}
|
||||
|
||||
// returns the 'armourrating' flag
|
||||
|
@ -13217,9 +13283,10 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
// let player select ANY object (even if it won't
|
||||
// work).
|
||||
if (needsob && isplayer(lf) && !isknown(o)) {
|
||||
f = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL);
|
||||
flag_t *f2;
|
||||
f2 = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL);
|
||||
targob = askobject(lf->pack, "Target which object", NULL, AO_NONE);
|
||||
killflag(f);
|
||||
killflag(f2);
|
||||
}
|
||||
|
||||
dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE);
|
||||
|
@ -14101,7 +14168,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
|
||||
// now use the REAL name
|
||||
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
|
||||
losehp_real(owner, howmuch , damtype, NULL, obname, B_TRUE, o);
|
||||
losehp_real(owner, howmuch , damtype, NULL, obname, B_TRUE, o, B_FALSE);
|
||||
if (isdead(owner)) {
|
||||
return howmuch;
|
||||
}
|
||||
|
@ -15929,11 +15996,6 @@ int getcritchance(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
// oooooo
|
||||
chance = 100;
|
||||
}
|
||||
|
||||
return chance;
|
||||
}
|
||||
|
||||
|
|
340
spell.c
340
spell.c
|
@ -794,8 +794,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
howlong = 10;
|
||||
addtempflag(user->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong);
|
||||
needredraw = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
if (isplayer(user)) {
|
||||
needredraw = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
drawscreen();
|
||||
}
|
||||
} else if (abilid == OT_A_REPAIR) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
|
@ -1983,7 +1986,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char castername[BUFLEN];
|
||||
int rv = B_FALSE;
|
||||
objecttype_t *sp;
|
||||
flag_t *casttype;
|
||||
flag_t *casttype = NULL;
|
||||
|
||||
sp = findot(spellid);
|
||||
|
||||
|
@ -2042,18 +2045,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
power += powerinc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// special: spit attacks need an animation
|
||||
casttype = lfhasflag(caster, F_CASTTYPE);
|
||||
if (casttype && (casttype->val[0] == CT_EYESPIT)) {
|
||||
enum COLOUR col;
|
||||
if (casttype->val[1] == NA) {
|
||||
col = C_GREEN;
|
||||
} else {
|
||||
col = casttype->val[1];
|
||||
// special: spit attacks need an animation
|
||||
casttype = lfhasflag(caster, F_CASTTYPE);
|
||||
if (casttype && (casttype->val[0] == CT_EYESPIT)) {
|
||||
enum COLOUR col;
|
||||
if (casttype->val[1] == NA) {
|
||||
col = C_GREEN;
|
||||
} else {
|
||||
col = casttype->val[1];
|
||||
}
|
||||
anim(caster->cell, targcell, '}', col);
|
||||
}
|
||||
anim(caster->cell, targcell, '}', col);
|
||||
}
|
||||
|
||||
// switch based on spell effects...
|
||||
|
@ -2337,49 +2340,44 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_BLINK) {
|
||||
if (!caster->nlos) {
|
||||
// can't see anywhere
|
||||
fizzle(caster);
|
||||
} else {
|
||||
if (lfhasflag(caster, F_CONTROL) && (power < 6)) {
|
||||
power = 6;
|
||||
if (lfhasflag(caster, F_CONTROL) && (power < 6)) {
|
||||
power = 6;
|
||||
}
|
||||
if (power >= 6) {
|
||||
// controlled
|
||||
// must be within line of sight.
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
if (!targcell || !cellwalkable(caster, targcell, NULL)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
if (power >= 6) {
|
||||
// controlled
|
||||
// must be within line of sight.
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
if (!targcell || !cellwalkable(caster, targcell, NULL)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else {
|
||||
cell_t *poss[MAXCANDIDATES];
|
||||
int nposs = 0,x,y;
|
||||
// pick a random location
|
||||
// only needs to be in line-of-FIRE, not neccesarily sight.
|
||||
for (y = 0 ; y <= caster->cell->map->h; y++) {
|
||||
for (x = 0 ; x <= caster->cell->map->w; x++) {
|
||||
cell_t *c;
|
||||
c = getcellat(caster->cell->map, x, y);
|
||||
if (c && haslof(caster->cell, c, LOF_WALLSTOP, NULL)) {
|
||||
if (cellwalkable(caster, targcell, NULL) &&
|
||||
!celldangerous(caster, targcell, B_FALSE, NULL)) {
|
||||
poss[nposs++] = c;
|
||||
}
|
||||
} else {
|
||||
cell_t *poss[MAXCANDIDATES];
|
||||
int nposs = 0,x,y;
|
||||
// pick a random location
|
||||
// only needs to be in line-of-FIRE, not neccesarily sight.
|
||||
for (y = 0 ; y <= caster->cell->map->h; y++) {
|
||||
for (x = 0 ; x <= caster->cell->map->w; x++) {
|
||||
cell_t *c;
|
||||
c = getcellat(caster->cell->map, x, y);
|
||||
if (c && haslof(caster->cell, c, LOF_WALLSTOP, NULL)) {
|
||||
if (cellwalkable(caster, c, NULL) &&
|
||||
!celldangerous(caster, c, B_FALSE, NULL)) {
|
||||
poss[nposs++] = c;
|
||||
}
|
||||
if (nposs >= MAXCANDIDATES) break;
|
||||
}
|
||||
if (nposs >= MAXCANDIDATES) break;
|
||||
}
|
||||
|
||||
if (!nposs) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
targcell = poss[rnd(0,nposs-1)];
|
||||
if (nposs >= MAXCANDIDATES) break;
|
||||
}
|
||||
teleportto(caster, targcell, B_TRUE);
|
||||
|
||||
if (!nposs) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
targcell = poss[rnd(0,nposs-1)];
|
||||
}
|
||||
teleportto(caster, targcell, B_TRUE);
|
||||
} else if (spellid == OT_S_LOWERMETAB) {
|
||||
flag_t *f;
|
||||
// ie. 2 - 4
|
||||
|
@ -2669,7 +2667,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int stillseen = B_FALSE;
|
||||
// everyone takes damage, and mark cells as hit
|
||||
for (i = 0; i < narccells; i++) {
|
||||
losehp(arccell[i]->lf, rolldie(2,nsides), DT_ELECTRIC, caster, "an electricity bolt");
|
||||
losehp(arccell[i]->lf, rolldie(3,nsides), DT_ELECTRIC, caster, "an electricity bolt");
|
||||
hitcell[nhitcells++] = arccell[i];
|
||||
|
||||
if (haslos(player, arccell[i])) {
|
||||
|
@ -2731,8 +2729,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
radius = power/3;
|
||||
if (radius < 1) radius = 1;
|
||||
radius = (power/4)+1;
|
||||
|
||||
addobburst(targcell, radius, DT_COMPASS, "cloud of poison gas", caster, LOF_WALLSTOP);
|
||||
|
||||
|
@ -2988,7 +2985,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (cansee(player, target)) {
|
||||
msg("A ray of coldness ray hits %s.",lfname);
|
||||
}
|
||||
losehp(target, rnd(2,5), DT_COLD, caster, "a blast of coldness");
|
||||
losehp(target, roll("3d6"), DT_COLD, caster, "a blast of coldness");
|
||||
// ray stops here.
|
||||
break;
|
||||
}
|
||||
|
@ -3130,6 +3127,63 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
|
||||
} else if (spellid == OT_S_CRYSTALARM) {
|
||||
object_t *o;
|
||||
enum BODYPART bp[4];
|
||||
int nbp, donesomething = B_FALSE,i;
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
nbp = (power/3)+1;
|
||||
bp[0] = BP_BODY;
|
||||
bp[1] = BP_HEAD;
|
||||
bp[2] = BP_HANDS;
|
||||
bp[3] = BP_FEET;
|
||||
for (i = 0; (i < 4) && (i < nbp); i++) {
|
||||
if (hasbp(target, bp[i]) && !getequippedob(target->pack, bp[i])) {
|
||||
switch (bp[i]) {
|
||||
case BP_BODY: default:
|
||||
o = addob(target->pack, "ice crystal armour"); break;
|
||||
case BP_HEAD:
|
||||
o = addob(target->pack, "ice crystal helmet"); break;
|
||||
case BP_HANDS:
|
||||
o = addob(target->pack, "ice crystal gauntlets"); break;
|
||||
case BP_FEET:
|
||||
o = addob(target->pack, "ice crystal boots"); break;
|
||||
}
|
||||
if (o) {
|
||||
if (canwear(target, o, BP_NONE)) {
|
||||
char obname[BUFLEN];
|
||||
flag_t *f;
|
||||
// announce
|
||||
getobname(o, obname, 1);
|
||||
if (isplayer(target)) {
|
||||
msg("%s forms %s your %s!", obname, getbodypartequipname(bp[i]), getbodypartname(bp[i]));
|
||||
} else if (cansee(player, target)) {
|
||||
msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]),
|
||||
castername, getpossessive(castername), getbodypartname(bp[i]));
|
||||
}
|
||||
wear(target, o);
|
||||
// set its values
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (f) {
|
||||
f->val[0] = power*5;
|
||||
f->val[1] = power*5;
|
||||
}
|
||||
addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL);
|
||||
donesomething = B_TRUE;
|
||||
} else {
|
||||
killob(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!donesomething) {
|
||||
fizzle(caster);
|
||||
stopspell(caster, spellid);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
} else if (spellid == OT_S_CRYSTALSHIELD) {
|
||||
object_t *o;
|
||||
targcell = caster->cell;
|
||||
|
@ -3167,6 +3221,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
f->val[0] = power*5;
|
||||
f->val[1] = power*5;
|
||||
}
|
||||
addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL);
|
||||
} else {
|
||||
killob(o);
|
||||
fizzle(caster);
|
||||
|
@ -3654,7 +3709,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(c->lf, lfname);
|
||||
msg("A blast of energy hits %s.",lfname);
|
||||
}
|
||||
losehp(c->lf, rnd(2,6), DT_MAGIC, caster, "an energy blast");
|
||||
losehp(c->lf, roll("2d6"), DT_MAGIC, caster, "an energy blast");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3876,7 +3931,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
setobcreatedby(o, caster);
|
||||
}
|
||||
if (c->lf) {
|
||||
losehp(c->lf, rolldie(power,4), DT_FIRE, caster, "a fireball");
|
||||
losehp(c->lf, rolldie(power,3), DT_FIRE, caster, "a fireball");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3891,7 +3946,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (c->lf) {
|
||||
int ndice;
|
||||
ndice = power / 2; if (ndice < 1) ndice = 1;
|
||||
losehp(c->lf, rolldie(ndice,4), DT_FIRE, caster, "a fireball");
|
||||
losehp(c->lf, rolldie(ndice,3), DT_FIRE, caster, "a fireball");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4115,8 +4170,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
o = targob;
|
||||
} else {
|
||||
// rings?
|
||||
o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTHAND, NA, NA, NULL);
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTHAND, NA, NA, NULL);
|
||||
o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTFINGER, NA, NA, NULL);
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTFINGER, NA, NA, NULL);
|
||||
// gloves?
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_HANDS, NA, NA, NULL);
|
||||
// weapon?
|
||||
|
@ -4737,7 +4792,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
f = isequipped(o);
|
||||
if (f) {
|
||||
if ((f->val[0] == BP_WEAPON) || (f->val[0] == BP_SECWEAPON)) {
|
||||
} else if ((f->val[0] == BP_RIGHTHAND) || (f->val[0] == BP_LEFTHAND)) {
|
||||
} else if ((f->val[0] == BP_RIGHTFINGER) || (f->val[0] == BP_LEFTFINGER)) {
|
||||
if (isplayer(caster)) {
|
||||
getobname(o, buf, 1);
|
||||
msg("Your %s slides off your %s!", buf, getbodypartname(f->val[0]));
|
||||
|
@ -5027,7 +5082,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
} else {
|
||||
int howlong = 7;
|
||||
howlong = getspellduration(3,5,blessed) + (power/2);
|
||||
howlong = getspellduration(3,5,blessed) + (power/4);
|
||||
addtempflag(target->flags, F_PAIN, DT_MAGIC, NA, NA, "1d3", howlong);
|
||||
}
|
||||
} else {
|
||||
|
@ -5083,7 +5138,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("A glob of venom hits %s.",lfname);
|
||||
}
|
||||
if (!isimmuneto(target->flags, DT_POISON)) {
|
||||
poison(target, power*3, P_VENOM, power, "a glob of venom");
|
||||
poison(target, power*3, P_VENOM, (power/4)+1, "a glob of venom");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -6449,6 +6504,34 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_SHARDSHOT) {
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcells;
|
||||
int i;
|
||||
int nhits = power;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
|
||||
// create a line of fire towards the target cell
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcells);
|
||||
animcells(caster->cell, &retcell[1], nretcells-1, B_FALSE, '*', '\0', C_WHITE);
|
||||
if (cansee(player, caster)) {
|
||||
msg("%s fire%s a burst of ice shards!",castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
// don't hit the caster cell on fire!
|
||||
for (i = 1; (i < nretcells) && (nhits > 0); i++) {
|
||||
cell_t *c;
|
||||
c = retcell[i];
|
||||
if (c->lf) {
|
||||
// hit with ice
|
||||
losehp(c->lf, rolldie(nhits, 6), DT_COLD, caster, "a burst of ice shards");
|
||||
nhits--;
|
||||
}
|
||||
if (haslos(player, c)) {
|
||||
needredraw = B_TRUE;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_SHATTER) {
|
||||
char buf[BUFLEN];
|
||||
if (!validatespellcell(caster, &targcell,TT_NONE, spellid, power, frompot)) return B_TRUE;
|
||||
|
@ -6573,6 +6656,28 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// use direct damage rather than holy, because otherwise it might be increased
|
||||
// due to vulnerabilities
|
||||
losehp(target, rnd(1,power*2), DT_DIRECT, caster, "a smiting");
|
||||
} else if (spellid == OT_S_SNAPFREEZE) {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
target = haslf(targcell);
|
||||
if (target) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
char tname[BUFLEN];
|
||||
getlfname(target, tname);
|
||||
msg("%s resists.",tname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// they get angry!
|
||||
if (!isplayer(target) && cansee(target, caster)) {
|
||||
fightback(target, caster);
|
||||
}
|
||||
} else {
|
||||
if (seenbyplayer && (isplayer(caster) || cansee(player, target))) *seenbyplayer = B_TRUE;
|
||||
freezelf(target, caster, rnd(20,40));
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_SNOWBALL) {
|
||||
int failed = B_FALSE;
|
||||
// ask for a target cell
|
||||
|
@ -6790,12 +6895,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (strstr(r->name, " snake")) {
|
||||
flag_t *f;
|
||||
f = hasflag(r->flags, F_HITDICE);
|
||||
// ie. 1hd needs power 2
|
||||
// ie. 2hd needs power 4
|
||||
// ie. 3hd needs power 6
|
||||
// ie. 4hd needs power 8
|
||||
if (f && (power >= (f->val[0] * 2))) {
|
||||
raceposs[nraceposs++] = r;
|
||||
if (f) {
|
||||
int ndice,nsides,bonus,maxroll;
|
||||
texttodice(f->text, &ndice,&nsides,&bonus);
|
||||
maxroll = ndice * nsides + bonus;
|
||||
// ie. 1hd needs power 2
|
||||
// ie. 2hd needs power 4
|
||||
// ie. 3hd needs power 6
|
||||
// ie. 4hd needs power 8
|
||||
if (power >= (maxroll/4)) {
|
||||
raceposs[nraceposs++] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7302,30 +7412,62 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
swapplaces(caster, target, B_FALSE);
|
||||
} else if ((spellid == OT_S_SUMMONANIMALSSM) ||
|
||||
(spellid == OT_S_SUMMONANIMALSMD) ||
|
||||
(spellid == OT_S_SUMMONANIMALSLG)) {
|
||||
int lifetime, nwant,ngot;
|
||||
(spellid == OT_S_SUMMONANIMALSLG) ||
|
||||
(spellid == OT_S_SUMMONDEMON)) {
|
||||
int lifetime, nwant,ngot,successrate;
|
||||
enum LFSIZE wantsize;
|
||||
enum RACECLASS wantrc;
|
||||
int friendly;
|
||||
lifetime = (power * 9) + rnd(1,power*2);
|
||||
nwant = rnd(2,3);
|
||||
|
||||
|
||||
switch (spellid) {
|
||||
case OT_S_SUMMONDEMON:
|
||||
wantrc = RC_DEMON;
|
||||
wantsize = SZ_ANY;
|
||||
nwant = 1;
|
||||
successrate = power*10;
|
||||
if (caster->race->raceclass->id == RC_DEMON) {
|
||||
friendly = B_TRUE;
|
||||
} else if (onein(4)) {
|
||||
friendly = B_FALSE;
|
||||
} else {
|
||||
friendly = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case OT_S_SUMMONANIMALSSM:
|
||||
wantrc = RC_ANIMAL;
|
||||
wantsize = SZ_SMALL;
|
||||
nwant = rnd(2,3);
|
||||
successrate = 100;
|
||||
friendly = B_TRUE;
|
||||
break;
|
||||
case OT_S_SUMMONANIMALSMD:
|
||||
wantrc = RC_ANIMAL;
|
||||
wantsize = SZ_MEDIUM;
|
||||
nwant = rnd(2,3);
|
||||
successrate = 100;
|
||||
friendly = B_TRUE;
|
||||
break;
|
||||
case OT_S_SUMMONANIMALSLG:
|
||||
wantrc = RC_ANIMAL;
|
||||
wantsize = SZ_LARGE;
|
||||
nwant = rnd(2,3);
|
||||
successrate = 100;
|
||||
friendly = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
wantsize = SZ_ANY;
|
||||
successrate = 100;
|
||||
break;
|
||||
}
|
||||
ngot = summonlfs(caster, caster->cell, wantrc, wantsize, AL_NONE, nwant, lifetime);
|
||||
|
||||
if (!pctchance(successrate)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
ngot = summonlfs(caster, caster->cell, wantrc, wantsize, AL_NONE, nwant, lifetime, friendly);
|
||||
if (!ngot) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
|
@ -7334,7 +7476,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
raceclass_t *rc;
|
||||
rc = findraceclass(wantrc);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
msg("%s appear around %s!", makeplural(rc->name), castername);
|
||||
if (ngot == 1) {
|
||||
msg("%s %s appears near %s!", needan(rc->name) ? "An" : "A", rc->name, castername);
|
||||
} else {
|
||||
msg("%s appear around %s!", makeplural(rc->name), castername);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_SUMMONWEAPON) {
|
||||
|
@ -7365,6 +7511,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
snprintf(buf, BUFLEN, "2d%d",power);
|
||||
changeflagtext(f, buf);
|
||||
}
|
||||
addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL);
|
||||
} else {
|
||||
killob(o);
|
||||
fizzle(caster);
|
||||
|
@ -7977,12 +8124,11 @@ void fizzle(lifeform_t *caster) {
|
|||
} else {
|
||||
nothinghappens();
|
||||
}
|
||||
/*
|
||||
} else if (cansee(player, caster)) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(caster, buf);
|
||||
capitalise(buf);
|
||||
msg("%s's spell fizzles.", buf);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8383,12 +8529,13 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
|
|||
// If we can _will_ this to occur then we might have a set
|
||||
// range
|
||||
if (lf) {
|
||||
int newrange;
|
||||
flag_t *f;
|
||||
f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
|
||||
if (f && strlen(f->text)) {
|
||||
texttospellopts(f->text, NULL, NULL, NULL, &range);
|
||||
if (range > 0) {
|
||||
return range;
|
||||
texttospellopts(f->text, NULL, NULL, NULL, &newrange);
|
||||
if (newrange > 0) {
|
||||
return newrange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8419,6 +8566,9 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
|
|||
case OT_S_CHAINLIGHTNING:
|
||||
range = (power*3);
|
||||
break;
|
||||
case OT_S_SHARDSHOT:
|
||||
range = power;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -8587,6 +8737,10 @@ void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYP
|
|||
void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
||||
flag_t *f,*nextf;
|
||||
object_t *o, *nexto;
|
||||
objecttype_t *sp;
|
||||
|
||||
sp = findot(spellid);
|
||||
if (!sp) return;
|
||||
|
||||
for (f = caster->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
|
@ -8596,28 +8750,22 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
|||
killflag(f);
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(caster)) {
|
||||
msg("Your %s spell disappates.",sp->name);
|
||||
}
|
||||
|
||||
// remove any other specific effects based on spell type.
|
||||
for (o = caster->pack->first; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if ((o->type->id == OT_ENERGYBLADE) && (spellid == OT_S_SUMMONWEAPON)) {
|
||||
if (hasflagval(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL)) {
|
||||
if (cansee(player, caster)) {
|
||||
char obname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
getobname(o, obname, 1);
|
||||
getlfname(caster, lfname);
|
||||
msg("%s%s %s vanishes.", lfname, getpossessive(lfname),
|
||||
obname);
|
||||
}
|
||||
killob(o);
|
||||
}
|
||||
if ((o->type->id == OT_ICESHIELD) && (spellid == OT_S_CRYSTALSHIELD)) {
|
||||
if (cansee(player, caster)) {
|
||||
char obname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
getobname(o, obname, 1);
|
||||
getlfname(caster, lfname);
|
||||
msg("%s%s %s vanishes.", lfname, getpossessive(lfname),
|
||||
obname);
|
||||
noprefix(obname));
|
||||
}
|
||||
killob(o);
|
||||
}
|
||||
|
@ -8642,7 +8790,7 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
|||
|
||||
|
||||
// returns # created
|
||||
int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime) {
|
||||
int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly) {
|
||||
lifeform_t *newlf;
|
||||
race_t *r = NULL;
|
||||
enum RACE poss[MAXCANDIDATES];
|
||||
|
@ -8699,10 +8847,12 @@ int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFS
|
|||
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
// summoned
|
||||
addflag(newlf->flags, F_SUMMONEDBY, caster->id, lifetime, NA, NULL);
|
||||
addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL);
|
||||
if (areallies(player, caster)) {
|
||||
makefriendly(newlf, PERMENANT);
|
||||
}
|
||||
if (friendly) {
|
||||
addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL);
|
||||
if (areallies(player, caster)) {
|
||||
makefriendly(newlf, PERMENANT);
|
||||
}
|
||||
}
|
||||
ncreated++;
|
||||
}
|
||||
}
|
||||
|
|
2
spell.h
2
spell.h
|
@ -27,7 +27,7 @@ void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYP
|
|||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
void stopallspellsexcept(lifeform_t *lf, ...);
|
||||
int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime);
|
||||
int summonlfs(lifeform_t *caster, cell_t *where, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly);
|
||||
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target);
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, enum OBTYPE spellid, int power, int frompot);
|
||||
//lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
@id:playerstart_1
|
||||
@map
|
||||
##########
|
||||
#...c..|,#
|
||||
#...-/-###
|
||||
+......|,#
|
||||
#.-/-..###
|
||||
#...c..|,#
|
||||
##########
|
||||
@end
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
|:ob:iron gate
|
||||
,:ob:1-4 bones:50
|
||||
+:ob:wooden door
|
||||
+:exit
|
||||
/:ob:wooden table
|
||||
-:ob:wooden footstool
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
playerstart
|
||||
norandom
|
||||
atoneof(8,1)(8,3)(8,5) ob:playerstart
|
||||
scatter(1,1,-2,-2) ob:wooden footstool:0-3
|
||||
scatter(1,1,-2,-2) ob:random food:0-2
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@id:playerstart_2
|
||||
@map
|
||||
###x###
|
||||
#.|.|.#
|
||||
###.###
|
||||
#.|.|.#
|
||||
###.###
|
||||
#.|.|.#
|
||||
###.###
|
||||
#.|.|.#
|
||||
###x###
|
||||
@end
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
|:ob:iron gate
|
||||
x:exit
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
playerstart
|
||||
norandom
|
||||
atoneof(1,1)(1,3)(1,5)(1,7)(5,1)(5,3)(5,5)(5,7) ob:playerstart
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
@id:playerstart_3
|
||||
@map
|
||||
#########
|
||||
#.......#
|
||||
#.IIIII.#
|
||||
#.II.I..#
|
||||
#.I.p.,.#
|
||||
#.II.II.#
|
||||
#.IIIII.#
|
||||
#.......#
|
||||
#########
|
||||
@end
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
I:cell:glass wall
|
||||
,:ob:4-8 pieces of broken glass
|
||||
p:ob:playerstart
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
playerstart
|
||||
norandom
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@id:playerstart_4
|
||||
@map
|
||||
#######
|
||||
#wwwww#
|
||||
#ww.ww#
|
||||
#w.p._x
|
||||
#ww.ww#
|
||||
#wwwww#
|
||||
#######
|
||||
@end
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
w:cell:low rock floor
|
||||
w:ob:very deep water
|
||||
_:cell:wood floor
|
||||
p:ob:playerstart
|
||||
x:exit
|
||||
@end
|
||||
@flags
|
||||
goesin:dungeon
|
||||
playerstart
|
||||
norandom
|
||||
mayrotate
|
||||
@end
|
||||
|
Loading…
Reference in New Issue