- [+] walking on glowing moss sohuld damage it.
- [+] make dagger stronger than combat knife (but combat knife is faster) - [+] optimise makefile. - [+] swapplaces message not appearing. - [+] fix exploit for dizziness with 'A' - [+] every time we ask for a direction, use askdirection(prompt). make this do dizziness check. - [+] no shieldblocking or dodging if you have no stamina. - [+] object rarity bugs - [+] i'm finding way too many books! might be fixed now... ? - [+] never finding wands - [+] added debugging to see if there is a problem with wands.... - [+] adjust footstep sound based on material - [+] carpet = soft - [+] stone = normal - [+] tiles = loud - [+] in @e, "you ar etipsy" should also talk about damage resistance. - [+] don't show starting abilities if you are a diety. - [+] don't say 'xx walks out of view' if they didn't move on purpose - [+] CRASH - summon weapon then drop the energy blade. * [+] CRASH when fumbling attack using energy blade. - [+] fighter with wisdom 31. novice perception skill. noticied teleport trap right in front of me. chances? - [+] maybe make it you can never detect anything further away than your perception skill. - [+] fix bug in geteffecttime() - [+] announce starting spells at beginning of game - [+] in skill help, highlight your current level. Maybe: "At Novice level>>> Unskilled weapons etc..." - [+] inept level lore shouldn't show "Adept Stealth" as a strength - [+] when you / then move over a cell with footprints short "Dirt (with human footprints)" - [+] or "Dirt (with xxx foorprints leading east) - [+] typo in killer text - an vs a - [+] get over here! should give you enough time to attack ? - [+] felix prayer should remove impassable objects. - [+] robots shoudl have big penalties to getting up checks. slip, fall, etc. - [+] fix bug when falling off a fence. - [+] BUG: no los when i climb on top of a wooden fence. why? - [+] F_BLOCKSVIEW needs new option: v1 = true means dont block if you are standing on it * [+] engineering / construction skill - replaces 'traps' - [+] fixed bug where you couldn't rest when you pet was visible. - [+] bug: aigetlastknownpos populating lastx & lasty with different info from the the cell returned. - [+] this has happening when following the direction of a scent. - [+] remove display of "xx throws xxx towards you" if you can't see the source and something is in the way. - [+] druid should alway sbe able to swap with plants. - [+] peaceful check should do this - [+] try agian... * [+] problem- create water can be used instead of soften earth ??? - [+] detect life should help with checking stairs. - [+] pentagrams should heal the undead. - [+] ekrub - don't et you sacrifice the flower that appears. * [+] when doing check for piety on eating animals - [+] don't auto give druid short blade skill due to sickle - [+] soften earth on boulder... turn it to mud - [+] adept psychology - receive change for gems. - [+] BUG: announceflagloss is never happening. - [+] new nature spell - absorb wood - [+] clank - robot, chomp to steal health, self destruct - [+] new tech - [+] l0 - [+] chewing gum (jam doors with it) - this should be food though. - [+] plants shoudl HELP druid from level 4 onwards - [+] clean up skill ability code - [+] automate skill descriptions based on skillwills "you gain the 'xxx' ability" - [+] auto-learn spells from initial spellbook, rather than having to read it manually - [+] finding rings of unholiness everywhere. - [+] because it's the only rare ring! - [+] fixed by making ALL rings be uncommon - [+] first time you slip on something, suggest using 's' - [+] sewing / metalwork: get resize and enhance earlier. - [+] bug with engineering seeing through one wall!s - [+] rogue/knifedancer / blademaster - throwing, extra skill with small blades. starts with extra knives. - [+] replace all SUBJOBS with plain regular JOBs - [+] fix "needobforstaff" for wizards! - [+] sewer should have mossy rock floor. slippery. - [+] new specialist classes: - [+] rogue/assassin (no stealing, no traps, lockpicking, better stealth+backstab, poison knives) - [+] minor healing spell is too powerful. should do 5-10hp max. - [+] reveal hidden is not powerful enough for l4. move to l2. - [+] reduce effects of stench as TR gets higher - [+] lumara should accept sacrifice of anything magic. - [+] oil lamp not making my viison longer! (on dlev11) - [+] just describe f_produceslight in io.c - [+] with no evasion skill, agi does way less for EV. - [+] fungus clouds should be in 1 radius, non orthogonal - [+] try putting monster zoo back in? - [+] STILL bugs detecting trapped doors ages away! - [+] detected one 8 away, perception novice! - [+] when a monster necromancer is made, i'm prompted for spell school!!! - [+] new mushroom: greycap. looks like a miniature snowy mountain. grants cold resistance - [+] shop opening hours - [+] F_OPENHOURS - [+] v0 = start (inclusive) - [+] v1 = end (inclusive) - [+] v2 = sayphrase - [+] SP_CLOSEDTILMORN (come back in the morning) - [+] SP_CLOSEDTILNIGHT (come back tonight) - [+] SP_CLOSEDTILHOUR (come back after x oclock!) - [+] make shops only be open during the day. - [+] make some temples only be open at night (eg. hecta)
This commit is contained in:
parent
db83aadaac
commit
68e5435fdf
65
Makefile
65
Makefile
|
@ -1,6 +1,65 @@
|
|||
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h shops.c shops.h spell.c spell.h vault.c vault.h
|
||||
gcc -Wall -g -o nexus nexus.c ai.c attack.c data.c flag.c god.c io.c lf.c map.c move.c objects.c text.c save.c spell.c shops.c vault.c -lncurses -lsqlite3
|
||||
#gcc -Wall -g -o nexus nexus.c ai.c attack.c data.c flag.c god.c io.c lf.c map.c move.c objects.c text.c save.c spell.c shops.c vault.c findleak.c -lncurses -lsqlite3
|
||||
#all: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h shops.c shops.h spell.c spell.h vault.c vault.h
|
||||
# gcc -Wall -g -o nexus nexus.c ai.c attack.c data.c flag.c god.c io.c lf.c map.c move.c objects.c text.c save.c spell.c shops.c vault.c -lncurses -lsqlite3
|
||||
|
||||
all: ai.o attack.o data.o findleak.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -g -Wall -o nexus ai.o attack.o data.o findleak.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o -lncurses -lsqlite3
|
||||
|
||||
ai.o: ai.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h ai.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o ai.o ai.c
|
||||
|
||||
attack.o: attack.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h attack.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o attack.o attack.c
|
||||
|
||||
data.o: data.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h data.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o data.o data.c
|
||||
|
||||
findleak.o: findleak.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h findleak.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o findleak.o findleak.c
|
||||
|
||||
flag.o: flag.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h flag.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o flag.o flag.c
|
||||
|
||||
god.o: god.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h god.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o god.o god.c
|
||||
|
||||
io.o: io.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h io.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o io.o io.c
|
||||
|
||||
lf.o: lf.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h lf.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o lf.o lf.c
|
||||
|
||||
map.o: map.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h map.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o map.o map.c
|
||||
|
||||
move.o: move.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h move.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o move.o move.c
|
||||
|
||||
nexus.o: nexus.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o nexus.o nexus.c
|
||||
|
||||
objects.o: objects.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h objects.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o objects.o objects.c
|
||||
|
||||
save.o: save.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h save.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o save.o save.c
|
||||
|
||||
shops.o: shops.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h shops.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o shops.o shops.c
|
||||
|
||||
spell.o: spell.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h spell.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o spell.o spell.c
|
||||
|
||||
text.o: text.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h text.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o text.o text.c
|
||||
|
||||
vault.o: vault.c ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h vault.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -o vault.o vault.c
|
||||
|
||||
|
||||
######################
|
||||
|
||||
clean:
|
||||
rm nexus *.o
|
||||
|
||||
check: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h shops.c shops.h spell.c spell.h vault.c vault.h
|
||||
splint -onlytrans -nullret -nullstate -branchstate -usedef -type -retvalint -retvalother +posixlib -unrecog -boolops -mustfreefresh -predboolint -unqualifiedtrans -compdef *.c
|
||||
|
|
36
ai.c
36
ai.c
|
@ -167,8 +167,8 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
|
||||
|
||||
f = lfhasflag(lf, F_NEEDOBFORSPELLS);
|
||||
if (f && !hasob(lf->pack, f->val[0])) {
|
||||
|
||||
if (missingspellcastob(lf)) {
|
||||
if (db) dblog(".oO { Cannot cast spell, I don't have my spellcast object }");
|
||||
return OT_NONE;
|
||||
}
|
||||
|
@ -308,14 +308,16 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
|
|||
f = ispetortarget(lf, target);
|
||||
if (f) {
|
||||
c = getcellat(lf->cell->map, f->val[1], f->val[2]);
|
||||
if (c) {
|
||||
if (c && cellwalkable(lf, c, NULL)) {
|
||||
if (lastx) *lastx = c->x;
|
||||
if (lasty) *lasty = c->y;
|
||||
if (strlen(f->text)) {
|
||||
locallastdir = atoi(f->text);
|
||||
}
|
||||
trailcell = c;
|
||||
if (lastx) *lastx = c->x;
|
||||
if (lasty) *lasty = c->y;
|
||||
}
|
||||
trailcell = c;
|
||||
}
|
||||
|
||||
// if not, check for the most recent scent/footprints first
|
||||
|
@ -350,13 +352,18 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
|
|||
|
||||
// if we found somewhere, follow any trails out of there
|
||||
if (trailcell) {
|
||||
finalcell = trailcell;
|
||||
if (locallastdir != D_NONE) {
|
||||
cell_t *c;
|
||||
// follow the trail
|
||||
finalcell = getcellindir(trailcell, locallastdir);
|
||||
locallastdir = D_NONE;
|
||||
} else {
|
||||
finalcell = trailcell;
|
||||
c = getcellindir(trailcell, locallastdir);
|
||||
if (getcelldist(c, target->cell) < getcelldist(trailcell, target->cell)) {
|
||||
locallastdir = D_NONE;
|
||||
finalcell = c;
|
||||
}
|
||||
}
|
||||
if (lastx) *lastx = finalcell->x;
|
||||
if (lasty) *lasty = finalcell->y;
|
||||
}
|
||||
|
||||
// return last movement direction
|
||||
|
@ -364,6 +371,13 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
|
|||
*lastdir = locallastdir;
|
||||
}
|
||||
|
||||
// just in case...
|
||||
if (!finalcell) {
|
||||
if ((*lastx != NA) && (*lasty != NA)) {
|
||||
finalcell = getcellat(lf->cell->map, *lastx, *lasty);
|
||||
}
|
||||
}
|
||||
|
||||
return finalcell;
|
||||
}
|
||||
|
||||
|
@ -1489,7 +1503,7 @@ int ai_premovement(lifeform_t *lf) {
|
|||
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
|
||||
|
||||
// need light?
|
||||
if (!lfhasflag(lf, F_PRODUCESLIGHT) && (lf->cell->map->illumination != IL_FULLLIT)) {
|
||||
if (lfproduceslight(lf, NULL) && (lf->cell->map->illumination != IL_FULLLIT)) {
|
||||
object_t *lamp;
|
||||
lamp = hasobwithflagval(lf->pack, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL);
|
||||
if (lamp && !isactivated(lamp)) {
|
||||
|
@ -1912,6 +1926,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
} else {
|
||||
// not already at their last known cell. try to go there.
|
||||
if (db) dblog(".oO { i cannot see my target. moving to last known loc %d/%d }",lastx,lasty);
|
||||
assert(targcell->x == lastx);
|
||||
assert(targcell->y == lasty);
|
||||
if (aigoto(lf, targcell, MR_LF, target, PERMENANT)) {
|
||||
if (db) dblog(".oO { set target cell for LKL. }");
|
||||
// success
|
||||
|
@ -2627,7 +2643,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
specificcheckok = B_FALSE;
|
||||
} else if (!safetorest(lf)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (lfhasflag(lf, F_PRODUCESLIGHT)) {
|
||||
} else if (lfproduceslight(lf, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
25
attack.c
25
attack.c
|
@ -1649,7 +1649,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
rdam = roll(dicetext);
|
||||
if (cansee(player, victim)) {
|
||||
msg("^%c%s%s %s %s %s!", isplayer(lf) ? 'b' : 'n', victimname, getpossessive(victimname),
|
||||
msg("^%c%s%s %s %s %s!", getlfcol(lf, CC_BAD), victimname, getpossessive(victimname),
|
||||
noprefix(obname),
|
||||
getattackverb(victim, NULL, f->val[0], rdam, lf->maxhp),
|
||||
attackername);
|
||||
|
@ -1718,10 +1718,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
// high chance that ai will give up if we can't reach the victim
|
||||
if (!isplayer(lf) && !canreach(lf, victim, NULL)) {
|
||||
if (pctchance(90)) {
|
||||
if (pctchance(80)) {
|
||||
loseaitargets(lf);
|
||||
if (isplayer(victim) && cansee(player, lf)) {
|
||||
msg("%s seems to have lost interest in you.", attackername);
|
||||
//msg("%s seems to have lost interest in you.", attackername);
|
||||
msg("%s can't reach you!", attackername);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1849,6 +1850,11 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
|
||||
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
|
||||
|
||||
if (isdoor(o, NULL)) {
|
||||
// extra damage for engineering skill
|
||||
dam[0] += getengineeringwallmod(lf);
|
||||
}
|
||||
|
||||
for (i = 0; i < ndam; i++) {
|
||||
// announce the hit
|
||||
construct_hit_string(lf, NULL, attackername, obname, NULL, wep, damtype[i], dam[i], maxhp, i, B_FALSE, B_FALSE, B_FALSE, isunarmed, buf);
|
||||
|
@ -2026,6 +2032,8 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
|
|||
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
|
||||
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
|
||||
|
||||
// extra damage for engineering skill
|
||||
dam[0] += getengineeringwallmod(lf);
|
||||
|
||||
for (i = 0; i < ndam; i++) {
|
||||
char cellname[BUFLEN];
|
||||
|
@ -2141,6 +2149,9 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
|
|||
|
||||
if (lf && !cansee(victim, lf)) return B_FALSE;
|
||||
|
||||
// need stamina to block
|
||||
if (!getstamina(victim)) return B_FALSE;
|
||||
|
||||
// get all usable shields for this damtype
|
||||
getallshields(victim, damtype, shield, checkmod, &nshields);
|
||||
for (i = 0; i < nshields; i++) {
|
||||
|
@ -3059,6 +3070,8 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
if (!where) return;
|
||||
|
||||
wep = fp->ob;
|
||||
if (wep && isdeadob(wep)) wep = NULL;
|
||||
|
||||
if (wep) {
|
||||
cell_t *c;
|
||||
c = getoblocation(wep);
|
||||
|
@ -3274,7 +3287,11 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
|
||||
if (wep && owner && victim) {
|
||||
enum DRAINTYPE draintype = DR_NONE;
|
||||
if ((wep->type->id == OT_TEETH) && lfhasflag(owner, F_VAMPIRIC) && islowhp(victim)) {
|
||||
flag_t *vampflag;
|
||||
vampflag = lfhasflag(owner, F_VAMPIRIC);
|
||||
if ((wep->type->id == OT_TEETH) && vampflag &&
|
||||
((vampflag->val[0] == B_TRUE) || islowhp(victim))
|
||||
) {
|
||||
draintype = DR_FROMBITE;
|
||||
} else if (hasflag(wep->flags, F_VAMPIRIC)) {
|
||||
draintype = DR_FROMWEP;
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
|
@ -17,5 +17,7 @@ scatter(1,1,-2,-2) ob:random:100%
|
|||
scatter(1,1,-2,-2) ob:random:100%:50
|
||||
scatter(1,1,-2,-2) ob:random:100%:50
|
||||
rarity:rare
|
||||
mayrotate
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
99
defs.h
99
defs.h
|
@ -16,6 +16,9 @@
|
|||
#define ONEIN_FOUNTAINDRYUP 3
|
||||
#define PCTCH_PILLAR 5
|
||||
|
||||
// skill check difficulty
|
||||
#define D_ALWAYSFAIL -99
|
||||
|
||||
// Text
|
||||
#define TEXT_WARN_ATTACK_NOXP "You will not gain experience until you train. Really attack?"
|
||||
#define TEXT_WARN_CLIMB "Really attempt to climb without Climbing skill?"
|
||||
|
@ -324,6 +327,7 @@
|
|||
#define D_NONE -1
|
||||
#define D_UNKNOWN -2
|
||||
#define D_ALL -3
|
||||
#define D_MYSELF -4
|
||||
|
||||
// Orthogonal directions
|
||||
#define D_N 0
|
||||
|
@ -491,6 +495,7 @@ enum SHOPACTION {
|
|||
#define FROMSPELL (-9863)
|
||||
#define FROMPOISON (-9862)
|
||||
#define FROMLYCANTHROPY (-9861)
|
||||
#define FROMGAMESTART (-9860)
|
||||
|
||||
// flag lifetimes - external sources (ie. don't kill them)
|
||||
#define FROMEXTERNAL_HIGH (-7000)
|
||||
|
@ -611,6 +616,9 @@ enum SAYPHRASE {
|
|||
SP_BEG,
|
||||
SP_BEGATTACK,
|
||||
SP_BEGTHANKS,
|
||||
SP_CLOSEDTILMORN,
|
||||
SP_CLOSEDTILNIGHT,
|
||||
SP_CLOSEDTILTIME,
|
||||
SP_DIE,
|
||||
SP_DRUNK,
|
||||
SP_LIFEOB_DESTROYED,
|
||||
|
@ -647,6 +655,8 @@ enum SPEECHVOL {
|
|||
SV_TRUCK = 5,
|
||||
SV_PLANE = 6,
|
||||
};
|
||||
#define MINVOL SV_SILENT
|
||||
#define MAXVOL SV_PLANE
|
||||
|
||||
enum SKILL {
|
||||
SK_NONE = 0,
|
||||
|
@ -673,7 +683,7 @@ enum SKILL {
|
|||
SK_TECHUSAGE,
|
||||
SK_THIEVERY,
|
||||
SK_THROWING,
|
||||
SK_TRAPS,
|
||||
SK_ENGINEERING,
|
||||
SK_TWOWEAPON,
|
||||
// knowledge
|
||||
SK_LORE_ARCANA,
|
||||
|
@ -719,6 +729,7 @@ enum SKILLLEVEL {
|
|||
PR_MASTER = 6,
|
||||
};
|
||||
#define MAXSKILLLEVEL 7
|
||||
#define MAXSKILLWILLS (MAXSKILLLEVEL*5)
|
||||
|
||||
|
||||
enum GAMEMODE {
|
||||
|
@ -861,6 +872,7 @@ enum CELLTYPE {
|
|||
CT_WALLDURANITE,
|
||||
// empty
|
||||
CT_CORRIDOR,
|
||||
CT_MOSSROCK,
|
||||
CT_DIRT,
|
||||
CT_VILLAGEGROUND,
|
||||
CT_FAKE,
|
||||
|
@ -1031,6 +1043,7 @@ enum RACE {
|
|||
R_NONE = 0,
|
||||
R_RANDOM, R_SPECIFIED,
|
||||
// unique monstesr
|
||||
R_CLANK,
|
||||
R_BABAYAGAHUT,
|
||||
R_BABAYAGA,
|
||||
R_JAILER,
|
||||
|
@ -1305,6 +1318,9 @@ enum JOB {
|
|||
J_ADVENTURER,
|
||||
J_ALLOMANCER,
|
||||
J_WARRIOR,
|
||||
J_BATTLEMAGE,
|
||||
J_PALADIN,
|
||||
J_SCOURGE,
|
||||
J_CHEF,
|
||||
J_COMMANDO,
|
||||
J_DRUID,
|
||||
|
@ -1315,8 +1331,15 @@ enum JOB {
|
|||
J_PIRATE,
|
||||
J_PRINCE,
|
||||
J_ROGUE,
|
||||
J_ASSASSIN,
|
||||
J_KNIFEDANCER,
|
||||
//J_SHOPKEEPER,
|
||||
J_WIZARD,
|
||||
//J_WIZARD,
|
||||
J_AIRMAGE,
|
||||
J_ICEMAGE,
|
||||
J_FIREMAGE,
|
||||
J_NECROMANCER,
|
||||
J_WILDMAGE,
|
||||
// monster-only jobs
|
||||
J_BERZERKER,
|
||||
J_DEMONOLOGIST,
|
||||
|
@ -1325,6 +1348,20 @@ enum JOB {
|
|||
};
|
||||
#define J_RANDOM J_NONE
|
||||
|
||||
enum JOBCATEGORY {
|
||||
JC_NONE,
|
||||
JC_FIGHTER,
|
||||
JC_FIGHTERRANGED,
|
||||
JC_MAGE,
|
||||
JC_THIEF,
|
||||
JC_FIGHTERMAGE,
|
||||
JC_FIGHTERTHIEF,
|
||||
JC_GENERAL,
|
||||
};
|
||||
#define JC_FIRST JC_NONE
|
||||
#define JC_LAST JC_GENERAL
|
||||
|
||||
/*
|
||||
enum SUBJOB {
|
||||
SJ_NONE,
|
||||
SJ_RANDOM,
|
||||
|
@ -1338,8 +1375,10 @@ enum SUBJOB {
|
|||
SJ_BATTLEMAGE,
|
||||
SJ_PALADIN,
|
||||
SJ_SCOURGE,
|
||||
|
||||
// rogue
|
||||
SJ_KNIFEDANCER,
|
||||
};
|
||||
*/
|
||||
|
||||
enum MATSTATE {
|
||||
MS_SOLID,
|
||||
|
@ -1515,6 +1554,7 @@ enum OBTYPE {
|
|||
OT_GARLIC,
|
||||
OT_HOTDOG,
|
||||
OT_JERKY,
|
||||
OT_MUSHROOMGREY,
|
||||
OT_MUSHROOMSHI,
|
||||
OT_MUSHROOMTOAD,
|
||||
OT_MUSHROOMSTUFFED,
|
||||
|
@ -1754,6 +1794,7 @@ enum OBTYPE {
|
|||
OT_S_STUNMASS,
|
||||
OT_S_TELEKINESIS,
|
||||
// nature / enviromancy
|
||||
OT_S_ABSORBWOOD,
|
||||
OT_S_ANIMATETREE,
|
||||
OT_S_BARKSKIN,
|
||||
OT_S_CALLLIGHTNING,
|
||||
|
@ -1861,12 +1902,14 @@ enum OBTYPE {
|
|||
// abilities
|
||||
OT_A_AIMEDSTRIKE,
|
||||
OT_A_ALTERATTACK,
|
||||
OT_A_BUILD,
|
||||
OT_A_CHECKSTAIRS,
|
||||
OT_A_CLIMB,
|
||||
OT_A_COOK,
|
||||
OT_A_DARKWALK,
|
||||
OT_A_DISARM, // disarm a trap
|
||||
OT_A_DISARMLF, // disarm an opponent
|
||||
OT_A_DISMANTLE,
|
||||
OT_A_DRAGUNDERGROUND,
|
||||
OT_A_ENHANCEOB,
|
||||
OT_A_EXPLODESELF,
|
||||
|
@ -1960,6 +2003,7 @@ enum OBTYPE {
|
|||
OT_TOWEL,
|
||||
OT_UNICORNHORN,
|
||||
// tech l0
|
||||
OT_CHEWINGGUM,
|
||||
OT_COMPUTER,
|
||||
OT_CREDITCARD,
|
||||
OT_PAPERCLIP,
|
||||
|
@ -2317,6 +2361,9 @@ enum OBTYPE {
|
|||
OT_SHILLELAGH,
|
||||
OT_SPANNER,
|
||||
OT_STICK,
|
||||
// hammers
|
||||
OT_WARHAMMER,
|
||||
OT_SLEDGEHAMMER,
|
||||
// projectile weapons
|
||||
OT_BLOWGUN,
|
||||
OT_BOW,
|
||||
|
@ -2535,6 +2582,7 @@ enum FLAG {
|
|||
// f->text (if given), or obtype v1.
|
||||
F_STACKABLE, // can stack multiple objects togethr
|
||||
F_THE, // say "the xxx", not "a xxx"
|
||||
F_WIZSTAFF, // this object counts as a wizard staff
|
||||
F_NO_PLURAL, // this obname doesn't need an 's' for plurals (eg. gold, money)
|
||||
F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold)
|
||||
F_CONTAINSOB, // for vending machiens. v0 is ob letter
|
||||
|
@ -2548,6 +2596,7 @@ enum FLAG {
|
|||
// where the amulet was put on. v1/v2 is x/y coords.
|
||||
F_NEWMAP, // for amulet of the traveller - v0 = target map id
|
||||
// where amulet takes us. v1/v2 is x/y coords.
|
||||
F_NOSACRIFICE, // cannot be sacrificed.
|
||||
F_SIGNTEXT, // for 'sign' objects. f->text is what is says.
|
||||
F_IMPORTANT, // don't destroy this object
|
||||
F_IMMUTABLE, // this object cannot be damaged OR repaired.
|
||||
|
@ -2619,8 +2668,14 @@ enum FLAG {
|
|||
F_CAUSESCOUGH, // being in this ob's cell will make you cough unless
|
||||
// immune to gas.
|
||||
// v0 = con skillcheck difficulty.
|
||||
F_DIMONWALK, // when a lf walks on this ob, its f_produceslight
|
||||
// flag v0 reduces by one.
|
||||
// if it gets to 0 (or doesnt have produceslight),
|
||||
// the object will vanish.
|
||||
F_BLOCKSVIEW, // if v0 = true, cannot see past this
|
||||
// if v0 > 0, reduces your vision by v0.
|
||||
// if v1 = true then don't block sight if you are
|
||||
// standing on it.
|
||||
F_BLOCKSLOF, // this object interrupts line of fire
|
||||
F_THEREISHERE, // announce "there is xx here!", not "you see xx here"
|
||||
// text[0] is punctuation to use.
|
||||
|
@ -2701,7 +2756,7 @@ enum FLAG {
|
|||
// val2 = ifactivated, only explodes if activated.
|
||||
F_FLASHONDEATH, // produce a bright flash when it dies,v0=range
|
||||
F_FLASHONDAM, // produces a bright flash when it is damaged,v0=range,v2=ifacctivated
|
||||
F_SPELLCLOUDONDEATH, // cast spell v0 in radius v1 upon death.
|
||||
F_SPELLCLOUDONDEATH, // cast spell v0 in radius v1 (orth) upon death.
|
||||
// v2 = ifactivated
|
||||
// text = "seebuf^noseebuf^spell_power"
|
||||
F_SPELLCLOUDONDAM, // cast spell v0 in radius v1 upon damage.
|
||||
|
@ -2819,8 +2874,9 @@ enum FLAG {
|
|||
// v1 = enum MENUACTION
|
||||
// v2 = value for action (optional)
|
||||
// text = "x:whatever" (x is letter to press)
|
||||
|
||||
|
||||
F_OPENHOURS, // v0 = shop open time (inclusive)
|
||||
// v1 = shop close time (inclusive)
|
||||
// v2 = enuim sayphrase SP_xxx when closed
|
||||
// doors
|
||||
F_DOOR, // this object is a door - ie. can open it
|
||||
// v0 and v1 are like F_IMPASSABLE
|
||||
|
@ -3118,6 +3174,7 @@ enum FLAG {
|
|||
// can pick what alignment they want to be.
|
||||
// text shows the choices ("g", "n" or "e")
|
||||
F_PIETY, // for god lifeforms - tracks player's piety with them
|
||||
F_PLANTFRIEND, // for player druids - makes plants friendly.
|
||||
F_HOMEMAP, // which map did this lf get created on?
|
||||
F_TOOKACTION, // lf purposely took action in their last turn.
|
||||
F_JUSTENTERED, // lf just entered a new map.
|
||||
|
@ -3161,6 +3218,8 @@ enum FLAG {
|
|||
// successful bite attacks from this lf will heal it
|
||||
// when on an object
|
||||
// successful attacks with this weapon will heal lf
|
||||
// v0 = TRUE means always drain, otherwise only drain
|
||||
// if victim has low hp.
|
||||
F_VEGETARIAN, // this lf will not eat meat.
|
||||
F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry'
|
||||
F_CARNIVORE, // this lf will only eat meat.
|
||||
|
@ -3235,7 +3294,7 @@ enum FLAG {
|
|||
// to take stuff out or put it in.
|
||||
F_HOLDING, // this container is a xxx of holding and makes objects
|
||||
// inside become weightless
|
||||
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid, v2=subjobid
|
||||
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
|
||||
F_STARTSKILL, // val0 = skill id
|
||||
F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS)
|
||||
// if text is set, it overrides val0.
|
||||
|
@ -3466,7 +3525,6 @@ enum FLAG {
|
|||
F_GENDER, // v0 = G_MALE or G_FEMALE. default if G_NONE if this
|
||||
// flag isn't set.
|
||||
F_JOB, // val0 = player's job
|
||||
// val1 = player's subjob or NA
|
||||
F_GODOF, // text = what this lf is the god of. use capitals.
|
||||
F_GODLIKES, // text = something this god likes (ie. incs piety)
|
||||
F_GODDISLIKES, // text = something this god likes (ie. decs piety)
|
||||
|
@ -3486,6 +3544,8 @@ enum FLAG {
|
|||
// corpse of something with raceclass v1.
|
||||
F_SACRIFICEOBCLASS, // v0 = can sacrifice obclass v0 to this god
|
||||
F_SACRIFICEOBBLESSED, // v0 = can sacrifice obs with ->blessed=v0 and blessknown!
|
||||
F_SACRIFICEOBMAGIC, // can sacrifice obs which are magical.
|
||||
// v2 = piety per ob
|
||||
|
||||
F_NAME, // text = lf's name. ie. lfname = "Fred"
|
||||
// also used for names of OT_GRIMOIRE objects
|
||||
|
@ -3596,7 +3656,12 @@ enum FLAG {
|
|||
F_BLIND, // cannot see anything
|
||||
F_CONFUSED, // move randomly about
|
||||
F_DEAF, // cannot hear
|
||||
F_NEEDOBFORSPELLS, // lf can only cast spells if it has object v0
|
||||
F_NEEDOBFORSPELLS, // if v0 != NA, lf can only cast spells if
|
||||
// it has object v0
|
||||
// if v1 != NA, lf can only cast spells if they
|
||||
// have an object with flag v1.
|
||||
// text = name of object you need, only used for
|
||||
// messages.
|
||||
F_CASTTYPE, // lf uses enum CASTTYPE v1 for spellid v0. (ot_none=all)
|
||||
// optional v2 is colour for casttype-based animations
|
||||
// (ie. spit spells)
|
||||
|
@ -3811,7 +3876,7 @@ enum FLAG {
|
|||
F_NOSELECTWEAPON, // override F_SELECTWEAPON from job
|
||||
F_NOPLAYER, // players can't pick this job
|
||||
F_HASPET, // this job starts with a pet of race f->text
|
||||
F_CANHAVESUBJOB, // this job can have subjob = v0
|
||||
//F_CANHAVESUBJOB, // this job can have subjob = v0
|
||||
//F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0.
|
||||
//F_ELSE,
|
||||
//F_IFPLAYER,
|
||||
|
@ -4331,6 +4396,7 @@ typedef struct poisontype_s {
|
|||
struct poisontype_s *next, *prev;
|
||||
} poisontype_t;
|
||||
|
||||
/*
|
||||
typedef struct subjob_s {
|
||||
enum SUBJOB id;
|
||||
char *name;
|
||||
|
@ -4338,6 +4404,7 @@ typedef struct subjob_s {
|
|||
char letter;
|
||||
struct subjob_s *next, *prev;
|
||||
} subjob_t;
|
||||
*/
|
||||
|
||||
typedef struct room_s {
|
||||
int id;
|
||||
|
@ -4512,6 +4579,7 @@ typedef struct celltype_s {
|
|||
int transparent; // can you see through it?
|
||||
int floorheight; // 0 is default. <0 is low.
|
||||
int hp; // hit points left. <0 = invulnerable
|
||||
int volumemod; // modifer to footstep volume
|
||||
struct material_s *material;
|
||||
|
||||
struct flagpile_s *flags;
|
||||
|
@ -4670,6 +4738,7 @@ typedef struct flag_s {
|
|||
enum FLAGCONDITION condition;
|
||||
int chance;
|
||||
|
||||
struct skill_s *skillfrom; // only used if ->lifetime is FROMSKILL.
|
||||
long obfrom; // for conferred flags, link to object->id. -1 if not conferred.
|
||||
// also used for godgifts, in which case it is thr race->id of
|
||||
// the god who gifted you this flag.
|
||||
|
@ -4701,6 +4770,15 @@ typedef struct skill_s {
|
|||
char *skilldesctext[MAXSKILLLEVEL*2];
|
||||
int skilldescmsg[MAXSKILLLEVEL*2];
|
||||
int nskilldesc;
|
||||
|
||||
struct skillwill_s {
|
||||
enum SKILLLEVEL lev;
|
||||
enum OBTYPE abilid;
|
||||
int timeout;
|
||||
char *text;
|
||||
} skillwill[MAXSKILLWILLS];
|
||||
int nskillwills;
|
||||
|
||||
int traintime;
|
||||
struct skill_s *next, *prev;
|
||||
} skill_t;
|
||||
|
@ -4733,6 +4811,7 @@ typedef struct knowledge_s {
|
|||
|
||||
typedef struct job_s {
|
||||
enum JOB id;
|
||||
enum JOBCATEGORY category;
|
||||
char *name;
|
||||
char *desc;
|
||||
flagpile_t *flags;
|
||||
|
|
19
flag.c
19
flag.c
|
@ -208,6 +208,8 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
f->known = known;
|
||||
f->obfrom = obfromid;
|
||||
|
||||
f->skillfrom = NULL;
|
||||
|
||||
f->altval = NULL;
|
||||
f->condition = FC_NOCONDITION;
|
||||
f->chance = 100;
|
||||
|
@ -1464,6 +1466,23 @@ int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... ) {
|
|||
return *nretflags;
|
||||
}
|
||||
|
||||
void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2) {
|
||||
flag_t *f;
|
||||
if (max0) *max0 = 0;
|
||||
if (max1) *max1 = 0;
|
||||
if (max2) *max2 = 0;
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
|
||||
if (f->id == id) {
|
||||
if (max0 && (f->val[0] > *max0)) *max0 = f->val[0];
|
||||
if (max1 && (f->val[1] > *max1)) *max1 = f->val[1];
|
||||
if (max2 && (f->val[2] > *max2)) *max2 = f->val[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flag_t *getrandomflag(flagpile_t *fp, enum FLAG fid) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0;
|
||||
|
|
1
flag.h
1
flag.h
|
@ -27,6 +27,7 @@ int flagstacks(enum FLAG fid);
|
|||
int flagtomaxhp(flag_t *f);
|
||||
cell_t *getflagpilelocation(flagpile_t *fp);
|
||||
int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... );
|
||||
void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2);
|
||||
flag_t *getrandomflag(flagpile_t *fp, enum FLAG fid);
|
||||
flag_t *hasflag(flagpile_t *fp, int id);
|
||||
flag_t *hasflagknown(flagpile_t *fp, int id);
|
||||
|
|
38
god.c
38
god.c
|
@ -520,6 +520,7 @@ void dooffer(void) {
|
|||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,pietyplus = 0;
|
||||
int dowoodsangry = B_FALSE;
|
||||
int success = B_FALSE;
|
||||
char splatterob[BUFLEN];
|
||||
strcpy(splatterob, "");
|
||||
|
||||
|
@ -534,7 +535,7 @@ void dooffer(void) {
|
|||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_NONE);
|
||||
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_SACRIFICEOBMAGIC, F_NONE);
|
||||
if (nretflags == 0) {
|
||||
msg("%s does not accept sacrifices.", god->race->name);
|
||||
return;
|
||||
|
@ -543,8 +544,9 @@ void dooffer(void) {
|
|||
for (o = player->cell->obpile->first ; o ; o = nexto) {
|
||||
int i;
|
||||
nexto = o->next;
|
||||
if (hasflag(o->flags, F_NOSACRIFICE)) continue;
|
||||
// does the god want this?
|
||||
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_NONE);
|
||||
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_SACRIFICEOBMAGIC, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
int ok = B_FALSE;
|
||||
int thispiety = 0;
|
||||
|
@ -589,6 +591,9 @@ void dooffer(void) {
|
|||
} else if ((f->id == F_SACRIFICEOBBLESSED) && (f->val[0] == o->blessed) && (o->blessknown == B_TRUE)) {
|
||||
ok = B_TRUE;
|
||||
thispiety = f->val[2];
|
||||
} else if ((f->id == F_SACRIFICEOBMAGIC) && ismagical(o)) {
|
||||
ok = B_TRUE;
|
||||
thispiety = f->val[2];
|
||||
}
|
||||
if (ok) {
|
||||
char *p;
|
||||
|
@ -670,7 +675,7 @@ void dooffer(void) {
|
|||
if (god->race->id == R_GODFIRE) {
|
||||
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
|
||||
}
|
||||
} else {
|
||||
} else if (!success) {
|
||||
nothinghappens();
|
||||
}
|
||||
taketime(player, getactspeed(player));
|
||||
|
@ -843,7 +848,7 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) {
|
|||
strcpy(killedname, "");
|
||||
if (!where) {
|
||||
// somewhere next to the player.
|
||||
where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player);
|
||||
where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player, MT_NOTHING);
|
||||
if (!where) {
|
||||
where = getrandomadjcell(player->cell, B_FALSE, B_NOEXPAND);
|
||||
}
|
||||
|
@ -964,6 +969,7 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
more();
|
||||
strcpy(obtogive, "");
|
||||
switch (god->race->id) {
|
||||
case R_GODBATTLE:
|
||||
|
@ -2222,19 +2228,27 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
|
|||
object_t *possob[MAXPILEOBS];
|
||||
int npossob,i,first;
|
||||
object_t *o;
|
||||
// unlock doors
|
||||
// unlock doors and remove impassable objects
|
||||
first = B_TRUE;
|
||||
for (i = 0; i < player->nlos; i++) {
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
object_t *o,*nexto;
|
||||
c = player->los[i];
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (killflagsofid(o->flags, F_LOCKED) || killflagsofid(o->flags, F_SECRET)) {
|
||||
if (first) {
|
||||
msg("\"Access granted!\"");
|
||||
first = B_FALSE;
|
||||
}
|
||||
noise(c, NULL, NC_OTHER, SV_TALK, "the click of a lock.", NULL);
|
||||
} else if (isimpassableob(o, lf, SZ_ANY)) {
|
||||
if (first) {
|
||||
msg("\"Access granted!\"");
|
||||
first = B_FALSE;
|
||||
}
|
||||
removeob(o, ALL);
|
||||
noise(c, NULL, NC_OTHER, SV_TALK, "the sucking of air.", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2524,9 +2538,13 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
|
|||
|
||||
|
||||
if (god->race->id == R_GODNATURE) {
|
||||
addob(lf->cell->obpile, "flower");
|
||||
if (haslos(player, lf->cell)) {
|
||||
msg("A beautiful flower grows from the ground.");
|
||||
object_t *oo;
|
||||
oo = addob(lf->cell->obpile, "flower");
|
||||
if (oo) {
|
||||
if (haslos(player, lf->cell)) {
|
||||
msg("A beautiful flower grows from the ground.");
|
||||
}
|
||||
addflag(oo->flags, F_NOSACRIFICE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
224
io.c
224
io.c
|
@ -700,12 +700,16 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
while (!finished) {
|
||||
int dir;
|
||||
char ch;
|
||||
char groundbuf[BUFLEN],fullbuf[BUFLEN];
|
||||
int valid = B_TRUE;
|
||||
|
||||
drawstatus();
|
||||
updateviewfor(c);
|
||||
drawlevelfor(player);
|
||||
|
||||
strcpy(groundbuf, c->type->name);
|
||||
addengineeringinfo(player, groundbuf, c);
|
||||
|
||||
if (moved) {
|
||||
flag_t *f;
|
||||
int inlof = B_TRUE, inrange = B_TRUE;
|
||||
|
@ -1026,11 +1030,16 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
}
|
||||
}
|
||||
// dont use msg() to avoid 'more's
|
||||
capitalise(buf);
|
||||
if (streq(groundbuf, buf)) {
|
||||
strcpy(fullbuf, buf);
|
||||
} else {
|
||||
sprintf(fullbuf, "%s, %s", groundbuf, buf);
|
||||
}
|
||||
capitalise(fullbuf);
|
||||
if (srclf && (maxrange != UNLIMITED)) {
|
||||
if (getcelldist(srclf->cell, c) > maxrange) {
|
||||
inrange = B_FALSE;
|
||||
strcat(buf, " ^R[too-far]^n");
|
||||
strcat(fullbuf, " ^R[too-far]^n");
|
||||
valid = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1050,7 +1059,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
}
|
||||
if (bad) {
|
||||
inlof = B_FALSE;
|
||||
strcat(buf, " ^B[no-lof]^n");
|
||||
strcat(fullbuf, " ^B[no-lof]^n");
|
||||
valid = B_FALSE;
|
||||
if (newcell) trailtarg = newcell;
|
||||
}
|
||||
|
@ -1062,7 +1071,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
char throwbuf[BUFLEN];
|
||||
makethrowaccstring(player, c, f, throwbuf);
|
||||
if (strlen(throwbuf)) {
|
||||
strcat(buf, throwbuf);
|
||||
strcat(fullbuf, throwbuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1071,11 +1080,11 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
if (subprompt) {
|
||||
char fullline[BUFLEN];
|
||||
wmove(msgwin, 0, 0);
|
||||
sprintf(fullline, "%s%s", subprompt, buf);
|
||||
sprintf(fullline, "%s%s", subprompt, fullbuf);
|
||||
textwithcol(msgwin, fullline);
|
||||
} else {
|
||||
wmove(msgwin, 0, 0);
|
||||
textwithcol(msgwin, buf);
|
||||
textwithcol(msgwin, fullbuf);
|
||||
}
|
||||
wrefresh(msgwin);
|
||||
|
||||
|
@ -1168,6 +1177,25 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char askdir(char *prompt, int maycancel, int usedrunk) {
|
||||
int dirch,dir = D_NONE;
|
||||
dirch = askchar(prompt, "yuhjklbn.-","-", B_FALSE, maycancel);
|
||||
if (dirch == '.') return D_MYSELF;
|
||||
|
||||
dir = chartodir(dirch);
|
||||
|
||||
// tipsy...
|
||||
if (usedrunk && movesrandomly(player)) {
|
||||
int dir;
|
||||
dir = rnd(DC_N, DC_NW+1);
|
||||
if (dir == (DC_NW + 1)) {
|
||||
dir = D_MYSELF;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
// retbuf must already be allocated
|
||||
// "def" is optional
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def) {
|
||||
|
@ -1293,7 +1321,8 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (notime) return B_FALSE;
|
||||
/// note: notime = maybe means we can still announce flag loss
|
||||
if (notime == B_TRUE) return B_FALSE;
|
||||
|
||||
if (!lf->born && !isplayer(lf)) {
|
||||
return B_FALSE;
|
||||
|
@ -1688,8 +1717,11 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
break;
|
||||
case F_INVULNERABLE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel invulnerable!");
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou feel invulnerable!", getlfcol(lf, CC_VGOOD));
|
||||
donesomething = B_TRUE;
|
||||
} else {
|
||||
msg("^%c%s looks invulnerable!", lfname, getlfcol(lf, CC_VGOOD));
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -1725,7 +1757,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("^%cYou %s %s.", getlfcol(lf, CC_VBAD), pt->contracttext, pt->name);
|
||||
more();
|
||||
} else {
|
||||
msg("^%c%s looks very sick.", getlfcol(lf, CC_VBAD), lfname);
|
||||
msg("^%c%s looks sick.", getlfcol(lf, CC_VBAD), lfname);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
|
@ -1886,6 +1918,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_PLANTFRIEND:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("^gYou feel a sudden affinity towards plantlife!");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_PRODUCESLIGHT:
|
||||
msg("%s start%s producing light!", lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -2102,7 +2140,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
if (isdead(player)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if (notime) return B_FALSE;
|
||||
|
||||
/// note: notime = maybe means we can still announce flag loss
|
||||
if (notime == B_TRUE) return B_FALSE;
|
||||
|
||||
if (!lf->born) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -2472,9 +2513,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
break;
|
||||
case F_INVULNERABLE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
if (isplayer(lf)) {
|
||||
msg("You no longer feel invulnerable.");
|
||||
donesomething = B_TRUE;
|
||||
} else {
|
||||
msg("%s no longer looks invulnerable.", lfname);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_DETECTAURAS:
|
||||
|
@ -2598,6 +2642,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_PLANTFRIEND:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You no longer feel an affinity towards plantlife.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_PRODUCESLIGHT:
|
||||
msg("%s %s no longer producing light.", lfname, is(lf));
|
||||
donesomething = B_TRUE;
|
||||
|
@ -4144,17 +4194,12 @@ void doattackcell(char dirch) {
|
|||
cell_t *c;
|
||||
|
||||
if (dirch == '\0') {
|
||||
dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
|
||||
dir = askdir("Attack in which direction (- to cancel)", B_TRUE, B_TRUE);
|
||||
}
|
||||
|
||||
|
||||
if (dirch == '.') {
|
||||
// yourself!
|
||||
if (dir == D_MYSELF) {
|
||||
c = player->cell;
|
||||
}
|
||||
|
||||
dir = chartodir(dirch);
|
||||
if (dir == D_NONE) {
|
||||
} else if (dir == D_NONE) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
} else {
|
||||
|
@ -4181,7 +4226,6 @@ void doattackcell(char dirch) {
|
|||
}
|
||||
|
||||
void doclose(void) {
|
||||
char ch;
|
||||
int failed = B_TRUE; // default is to fail
|
||||
int dir;
|
||||
int adjdoors;
|
||||
|
@ -4217,12 +4261,11 @@ void doclose(void) {
|
|||
} else if (adjdoors == 1) {
|
||||
dir = forcedir;
|
||||
} else {
|
||||
ch = askchar("Close door in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
|
||||
dir = chartodir(ch);
|
||||
dir = askdir("Close door in which direction (- to cancel)", B_TRUE, B_FALSE);
|
||||
}
|
||||
|
||||
if (dir == D_NONE) {
|
||||
clearmsg();
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
} else {
|
||||
cell_t *c;
|
||||
|
@ -5084,7 +5127,6 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
|
|||
object_t *toob = NULL;
|
||||
char toname[BUFLEN];
|
||||
|
||||
|
||||
// where is destination?
|
||||
if (dst->owner) {
|
||||
tolf = dst->owner;
|
||||
|
@ -5126,6 +5168,8 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
|
|||
//pickup(player, retobs[i],retobscount[i]);
|
||||
|
||||
o = retobs[i];
|
||||
if (isdeadob(o)) continue;
|
||||
|
||||
count = retobscount[i];
|
||||
|
||||
getobname(o, buf, count);
|
||||
|
@ -5664,8 +5708,6 @@ char *makedesc_god(lifeform_t *god, char *retbuf) {
|
|||
|
||||
char *makedesc_job(job_t *j, char *retbuf) {
|
||||
char thisline[BUFLEN];
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
skill_t *sk;
|
||||
enum ATTRIB a;
|
||||
int count = 0;
|
||||
|
@ -5744,9 +5786,6 @@ char *makedesc_job(job_t *j, char *retbuf) {
|
|||
count = 0;
|
||||
strcpy(thisline, "");
|
||||
|
||||
if (j->id == J_PIRATE) {
|
||||
dblog("xxx");
|
||||
}
|
||||
for (sk = firstskill ; sk ; sk = sk->next) {
|
||||
char lev[BUFLEN];
|
||||
enum SKILLLEVEL slev = PR_INEPT;
|
||||
|
@ -5798,32 +5837,6 @@ char *makedesc_job(job_t *j, char *retbuf) {
|
|||
strcpy(thisline, "");
|
||||
}
|
||||
|
||||
// specialisations
|
||||
getflags(j->flags, retflag, &nretflags, F_CANHAVESUBJOB, F_NONE);
|
||||
strcpy(thisline, "");
|
||||
if (nretflags > 0) {
|
||||
int first = B_TRUE;
|
||||
strcat(retbuf, "SPECIALISATIONS\n");
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
subjob_t *sj;
|
||||
sj = findsubjob(retflag[i]->val[0]);
|
||||
if (sj) {
|
||||
char buf[BUFLEN];
|
||||
if (first) {
|
||||
sprintf(buf, "- %s",sj->name);
|
||||
first = B_FALSE;
|
||||
} else {
|
||||
sprintf(buf, ", %s",sj->name);
|
||||
}
|
||||
strncat(thisline, buf, HUGEBUFLEN);
|
||||
}
|
||||
}
|
||||
if (strlen(thisline)) {
|
||||
strcat(thisline, "\n");
|
||||
strncat(retbuf, thisline, HUGEBUFLEN);
|
||||
}
|
||||
}
|
||||
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
|
@ -6639,8 +6652,9 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
|
||||
if (obproduceslight(o)) {
|
||||
sprintf(buf, "It is producing light.\n");
|
||||
i = obproduceslight(o);
|
||||
if (i > 0) {
|
||||
sprintf(buf, "It is producing light (%d metre%s).\n", i, (i == 1) ? "" : "s");
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
f = hasflag(o->flags, F_RUSTED);
|
||||
|
@ -6970,6 +6984,13 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
}
|
||||
break;
|
||||
case F_DAYBOOST:
|
||||
if (f->val[0] > 0) {
|
||||
sprintf(buf2, "%s grants a +%d accuracy bonus during daytime.\n", buf,getaccuracymodnum(f->val[0]));
|
||||
} else {
|
||||
sprintf(buf2, "%s imposes a -%d accuracy penalty during daytime.\n", buf, getaccuracymodnum(abs(f->val[0])));
|
||||
}
|
||||
break;
|
||||
case F_DETECTAURAS:
|
||||
sprintf(buf2, "%s allows you to detect blessings or curses.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
|
@ -7014,6 +7035,13 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
sprintf(buf2, "%s causes you to feel nauseated.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
break;
|
||||
case F_NIGHTBOOST:
|
||||
if (f->val[0] > 0) {
|
||||
sprintf(buf2, "%s grants a +%d accuracy bonus at night.\n", buf,getaccuracymodnum(f->val[0]));
|
||||
} else {
|
||||
sprintf(buf2, "%s imposes a -%d accuracy penalty at night.\n", buf, getaccuracymodnum(abs(f->val[0])));
|
||||
}
|
||||
break;
|
||||
case F_NONCORPOREAL:
|
||||
sprintf(buf2, "%s makes you non-corporeal.\n", buf);
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
|
@ -7043,7 +7071,8 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
break;
|
||||
case F_PRODUCESLIGHT:
|
||||
sprintf(buf2, "%s produces light.\n", buf);
|
||||
sprintf(buf2, "%s produces light out to %d metre%s.\n", buf,
|
||||
f->val[0], (f->val[0] == 1) ? "" : "s");
|
||||
strncat(retbuf, buf2, HUGEBUFLEN);
|
||||
break;
|
||||
case F_RETALIATE:
|
||||
|
@ -7331,6 +7360,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
// NOVICE:
|
||||
// common knowledge
|
||||
// eg: whether it breathes water, can fly, etc.
|
||||
// skills
|
||||
// BEGINNER:
|
||||
// spells/powers
|
||||
// knowledge known by studying this creature a little.
|
||||
|
@ -7428,7 +7458,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
ot = findot(f->val[0]);
|
||||
if (ot && (ot->obclass->id == spellorabil[n])) {
|
||||
if (i == 0) {
|
||||
sprintf(buf, "%s: %s", (spellorabil[n] == OC_ABILITY) ? "Ability" : "Spell",
|
||||
sprintf(buf, "Innate %s: %s", (spellorabil[n] == OC_ABILITY) ? "Ability" : "Spell",
|
||||
ot->name);
|
||||
} else {
|
||||
sprintf(buf, ", %s", ot->name);
|
||||
|
@ -7451,23 +7481,25 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
}
|
||||
|
||||
// skills?
|
||||
getflags(r->flags, retflag, &nretflags, F_STARTSKILL, F_NONE);
|
||||
strcpy(buf, "");
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
char nextbit[BUFLEN];
|
||||
f = retflag[i];
|
||||
if (i == 0) {
|
||||
sprintf(nextbit, "%s %s", getskilllevelname(f->val[1]), getskillname(f->val[0]));
|
||||
} else {
|
||||
sprintf(nextbit, ", %s %s", getskilllevelname(f->val[1]), getskillname(f->val[0]));
|
||||
if (lorelev >= PR_NOVICE) {
|
||||
getflags(r->flags, retflag, &nretflags, F_STARTSKILL, F_NONE);
|
||||
strcpy(buf, "");
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
char nextbit[BUFLEN];
|
||||
f = retflag[i];
|
||||
if (i == 0) {
|
||||
sprintf(nextbit, "%s %s", getskilllevelname(f->val[1]), getskillname(f->val[0]));
|
||||
} else {
|
||||
sprintf(nextbit, ", %s %s", getskilllevelname(f->val[1]), getskillname(f->val[0]));
|
||||
}
|
||||
strcat(buf, nextbit);
|
||||
}
|
||||
if (strlen(buf)) {
|
||||
strncat(retbuf, "@- ", HUGEBUFLEN);
|
||||
strcat(buf, "\n");
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
curidx++;
|
||||
}
|
||||
strcat(buf, nextbit);
|
||||
}
|
||||
if (strlen(buf)) {
|
||||
strncat(retbuf, "@- ", HUGEBUFLEN);
|
||||
strcat(buf, "\n");
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
curidx++;
|
||||
}
|
||||
|
||||
// auto bonuses from flags
|
||||
|
@ -7554,9 +7586,13 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
case F_HITCONFER:
|
||||
if (lorelev >= PR_BEGINNER) {
|
||||
if (f->val[0] == F_POISONED) {
|
||||
poisontype_t *pt;
|
||||
pt = findpoisontype(f->val[1]);
|
||||
sprintf(buf, "Attacks inflict %s.", pt->name);
|
||||
flag_t *f2;
|
||||
f2 = hasflag(r->flags, F_HITCONFERVALS);
|
||||
if (f2) {
|
||||
poisontype_t *pt;
|
||||
pt = findpoisontype(f2->val[0]);
|
||||
sprintf(buf, "Attacks inflict %s.", pt->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -8685,7 +8721,7 @@ void dohelp(char helpmode) {
|
|||
done = B_TRUE;
|
||||
} else {
|
||||
sk = (skill_t *)prompt.result;
|
||||
if (sk) describeskill(sk->id, PR_INEPT);
|
||||
if (sk) describeskill(sk->id, getskill(player, sk->id));
|
||||
else done = B_TRUE;
|
||||
}
|
||||
} else if (helpmode == 'g') {
|
||||
|
@ -9312,6 +9348,16 @@ int haschoice(prompt_t *p, char ch) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
choice_t *haschoicedata(prompt_t *p, void *data) {
|
||||
int i;
|
||||
for (i = 0; i < p->nchoices; i++) {
|
||||
if (p->choice[i].data == data) {
|
||||
return &(p->choice[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void doheading(WINDOW *win, int *y, int x, char *what) {
|
||||
int len,i;
|
||||
char *underline;
|
||||
|
@ -9477,6 +9523,8 @@ int drop(object_t *o, int count) {
|
|||
obpile_t *op;
|
||||
char obname[BUFLEN];
|
||||
enum OBTYPE origid;
|
||||
|
||||
if (isdeadob(o)) return B_TRUE;
|
||||
|
||||
op = o->pile;
|
||||
assert(op->owner);
|
||||
|
@ -11145,6 +11193,7 @@ void drawstatus(void) {
|
|||
char dstring[BUFLEN];
|
||||
strcpy(dstring, getdrunktext(f));
|
||||
capitalise(dstring);
|
||||
|
||||
setcol(statwin, C_BROWN);
|
||||
//wprintw(statwin, " %s(%d)", dstring,f->lifetime);
|
||||
wprintw(statwin, " %s", dstring);
|
||||
|
@ -12450,7 +12499,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
f = lfhasflag(lf, F_PRODUCESLIGHT);
|
||||
if (f && (f->known)) {
|
||||
wrapprint(mainwin, &y, &x, 0, "%s produce%s light. ", you(lf), isplayer(lf) ? "" : "s");
|
||||
int amt;
|
||||
getmaxflags(lf->flags, F_PRODUCESLIGHT, &amt, NULL, NULL);
|
||||
wrapprint(mainwin, &y, &x, 0, "%s produce%s light (minimum vision range: %d). ", you(lf),
|
||||
isplayer(lf) ? "" : "s",
|
||||
amt);
|
||||
}
|
||||
f = lfhasknownflag(lf, F_SLOWMETAB);
|
||||
if (f && (f->known)) {
|
||||
|
@ -13531,8 +13584,10 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
f = lfhasknownflag(lf, F_DRUNK);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s %s.", you(lf), is(lf), getdrunktext(f));
|
||||
if (f) {
|
||||
char ddesc[BUFLEN];
|
||||
getdrunkdesc(lf, f, ddesc);
|
||||
mvwprintw(mainwin, y, 0, "%s %s %s (%s).", you(lf), is(lf), getdrunktext(f), ddesc);
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -14520,9 +14575,6 @@ char wrapprint(WINDOW *win, int *y, int *x, int newlineindent, char *format, ...
|
|||
} else if ((*x != newlineindent) && strlen(word)) {
|
||||
textwithcol_real(win, " ", B_FALSE);
|
||||
}
|
||||
/* if (strlen(repword) < 2) {
|
||||
dblog("xxx");
|
||||
} */
|
||||
textwithcol_real(win, repword, B_FALSE);
|
||||
//(*x) += strlen(buf);
|
||||
getyx(win, *y, *x);
|
||||
|
|
2
io.h
2
io.h
|
@ -28,6 +28,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts);
|
|||
char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel);
|
||||
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
|
||||
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int minrange, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs);
|
||||
char askdir(char *prompt, int maycancel, int usedrunk);
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||
vault_t *askvault(char *prompttext);
|
||||
void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );
|
||||
|
@ -105,6 +106,7 @@ enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev);
|
|||
void handle_ctrl_y(int arg);
|
||||
void handleinput(void);
|
||||
int haschoice(prompt_t *p, char ch);
|
||||
choice_t *haschoicedata(prompt_t *p, void *data);
|
||||
void doheading(WINDOW *win, int *y, int x, char *what);
|
||||
void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading);
|
||||
void initgfx(void);
|
||||
|
|
35
lf.h
35
lf.h
|
@ -1,16 +1,17 @@
|
|||
#include "defs.h"
|
||||
|
||||
void add_subjob_alignment_restrictions(flagpile_t *fp, enum SUBJOB sj);
|
||||
//void add_subjob_alignment_restrictions(flagpile_t *fp, enum SUBJOB sj);
|
||||
void addbodypart(race_t *r, enum BODYPART bp, char *name);
|
||||
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
|
||||
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
|
||||
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *contracttext, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime);
|
||||
job_t *addjob(enum JOB id, char *name, char *desc);
|
||||
job_t *addjob(enum JOB id, char *name, char *desc, enum JOBCATEGORY category);
|
||||
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc);
|
||||
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime);
|
||||
void addskillabil(enum SKILL id, enum SKILLLEVEL lev, enum OBTYPE abilid, int timeout, char *text, int announce);
|
||||
void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg);
|
||||
subjob_t *addsubjob(enum SUBJOB id, char *name, char *desc, char letter);
|
||||
//subjob_t *addsubjob(enum SUBJOB id, char *name, char *desc, char letter);
|
||||
object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int doscents);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
||||
|
@ -25,6 +26,7 @@ int askforinfo(lifeform_t *lf, int diffmod);
|
|||
//int askforpayment(lifeform_t *shk, lifeform_t *lf);
|
||||
char *assignnpcname(flagpile_t *fp);
|
||||
int attrincreasable(enum ATTRIB a);
|
||||
void autolearnspellsfrombook(lifeform_t *lf, object_t *book);
|
||||
void autoshortcut(lifeform_t *lf, enum OBTYPE spellid);
|
||||
void autoskill(lifeform_t *lf);
|
||||
void autospells(lifeform_t *lf, int howmany);
|
||||
|
@ -42,6 +44,7 @@ int calcxp(lifeform_t *lf);
|
|||
int calcxprace(enum RACE rid);
|
||||
void callguards(lifeform_t *caller, lifeform_t *victim);
|
||||
int canattack(lifeform_t *lf);
|
||||
int canbuild(lifeform_t *lf, objecttype_t *ot, char *needtext, enum OBTYPE *needob, int *numneed);
|
||||
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost);
|
||||
int cancook(lifeform_t *lf, recipe_t *rec, enum ERROR *reason);
|
||||
int canclimb(lifeform_t *lf, enum ERROR *reason);
|
||||
|
@ -69,7 +72,7 @@ int cantakeoff(lifeform_t *lf, object_t *o);
|
|||
int cantalk(lifeform_t *lf);
|
||||
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell, object_t *fromob, int *seen);
|
||||
int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange);
|
||||
int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod);
|
||||
int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod, cell_t *nextcell);
|
||||
int charmedaction(lifeform_t *lf, flag_t *charmflag);
|
||||
int checkburdened(lifeform_t *lf, int preburdened);
|
||||
int checkfordrowning(lifeform_t *lf, object_t *o);
|
||||
|
@ -124,8 +127,8 @@ raceclass_t *findraceclass(enum RACECLASS id);
|
|||
skill_t *findskill(enum SKILL id);
|
||||
skill_t *findskillbyname(char *name);
|
||||
enum SKILLLEVEL findskilllevbyname(char *name);
|
||||
subjob_t *findsubjob(enum SUBJOB sjid);
|
||||
subjob_t *findsubjobbyletter(char letter);
|
||||
//subjob_t *findsubjob(enum SUBJOB sjid);
|
||||
//subjob_t *findsubjobbyletter(char letter);
|
||||
int fixcurses(lifeform_t *lf);
|
||||
int flee(lifeform_t *lf);
|
||||
void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose);
|
||||
|
@ -160,6 +163,8 @@ enum ATTRBRACKET getattrbracket(int attrval, enum ATTRIB whichatt, /*@null@*/cha
|
|||
int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
|
||||
int getavgdam(lifeform_t *lf, int forxp);
|
||||
enum CASTTYPE getcasttype(lifeform_t *lf, enum OBTYPE sid);
|
||||
int getdrunkattrmod(lifeform_t *lf, enum ATTRIB att, int drunkamt);
|
||||
int getengineeringwallmod(lifeform_t *lf);
|
||||
float getequippedweight(lifeform_t *lf);
|
||||
int getevasion(lifeform_t *lf);
|
||||
object_t *getbestthrowmissile(lifeform_t *lf, lifeform_t *target);
|
||||
|
@ -186,7 +191,8 @@ enum HUNGER gethungerlevel(int hunger);
|
|||
char *gethungername(lifeform_t *lf, enum HUNGER hunger, char *buf);
|
||||
int gethungerval(lifeform_t *lf);
|
||||
job_t *getjob(lifeform_t *lf);
|
||||
enum SUBJOB getsubjob(lifeform_t *lf);
|
||||
enum JOBCATEGORY getjobcat(lifeform_t *lf);
|
||||
//enum SUBJOB getsubjob(lifeform_t *lf);
|
||||
char *getjobname(lifeform_t *lf);
|
||||
int getlastdir(lifeform_t *lf);
|
||||
int getleftrightwalls(lifeform_t *lf);
|
||||
|
@ -288,8 +294,8 @@ int getweapons(lifeform_t *lf, int meleeonly, object_t **wep, flag_t **damflag,
|
|||
enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o);
|
||||
long getxpforlev(int level);
|
||||
void givebehaviour(lifeform_t *lf, enum BEHAVIOUR bid);
|
||||
void givejob(lifeform_t *lf, enum JOB jobid, enum SUBJOB sj);
|
||||
void givesubjob(lifeform_t *lf, enum SUBJOB sj);
|
||||
void givejob(lifeform_t *lf, enum JOB jobid);
|
||||
//void givesubjob(lifeform_t *lf, enum SUBJOB sj);
|
||||
int givemoney(lifeform_t *from, lifeform_t *to, int amt);
|
||||
void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype);
|
||||
int giverandomobs(lifeform_t *lf, int amt);
|
||||
|
@ -306,7 +312,8 @@ int hasfreeaction(lifeform_t *lf);
|
|||
int real_hasfreeaction(lifeform_t *lf, enum FLAG exception);
|
||||
int hashealableinjuries(lifeform_t *lf);
|
||||
job_t *hasjob(lifeform_t *lf, enum JOB job);
|
||||
int hassubjob(lifeform_t *lf, enum SUBJOB id);
|
||||
int hasjobcat(lifeform_t *lf, enum JOBCATEGORY jcid);
|
||||
//int hassubjob(lifeform_t *lf, enum SUBJOB id);
|
||||
int hassoul(lifeform_t *lf);
|
||||
void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch);
|
||||
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJURY forcetype);
|
||||
|
@ -382,12 +389,12 @@ flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp);
|
|||
int isweaponbp(enum BODYPART bp);
|
||||
int isweaponskill(enum SKILL skid);
|
||||
enum FLAG iswoozy(lifeform_t *lf);
|
||||
int jobpossible(flagpile_t *basefp, enum JOB jid, enum SUBJOB sjid);
|
||||
int jobpossible(flagpile_t *basefp, enum JOB jid);
|
||||
void killjob(job_t *job);
|
||||
void killlf(lifeform_t *lf);
|
||||
void killpoisontype(poisontype_t *pt);
|
||||
void killrace(race_t *race);
|
||||
void killsubjob(subjob_t *sj);
|
||||
//void killsubjob(subjob_t *sj);
|
||||
flag_t *levelabilityready(lifeform_t *lf);
|
||||
int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo);
|
||||
int loadfirearmfast(lifeform_t *lf, int onpurpose);
|
||||
|
@ -398,6 +405,7 @@ int losehp_bp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf,
|
|||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart);
|
||||
void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart);
|
||||
void losemp(lifeform_t *lf, int amt);
|
||||
void loseskill(lifeform_t *lf, enum SKILL skid);
|
||||
void magicwoods_angry(lifeform_t *who);
|
||||
void magicwoods_warn(lifeform_t *who);
|
||||
void makefriendly(lifeform_t *lf, int howlong);
|
||||
|
@ -411,6 +419,7 @@ void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how, int o
|
|||
int meetsallattreqs(lifeform_t *lf, object_t *o);
|
||||
int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *modpct);
|
||||
int mightflee(lifeform_t *lf);
|
||||
flag_t *missingspellcastob(lifeform_t *lf);
|
||||
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
||||
void modhunger(lifeform_t *lf, int amt);
|
||||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
|
@ -418,6 +427,7 @@ void modmorale(lifeform_t *lf, int howmuch);
|
|||
int modskillcheckroll(lifeform_t *lf, enum CHECKTYPE ct, int *roll);
|
||||
void modstamina(lifeform_t *lf, float howmuch);
|
||||
int movecausesnoise(lifeform_t *lf);
|
||||
int movesrandomly(lifeform_t *lf);
|
||||
int needstobreath(lifeform_t *lf);
|
||||
int needstorest(lifeform_t *lf, char *validchars);
|
||||
void noarmouron(race_t *r, enum BODYPART bp);
|
||||
|
@ -509,6 +519,7 @@ int validateraces(void);
|
|||
void wakeup(lifeform_t *lf, int howmuch);
|
||||
int wear(lifeform_t *lf, object_t *o);
|
||||
int weild(lifeform_t *lf, object_t *o);
|
||||
enum SKILLLEVEL whichlevforabil(enum SKILL skid, enum OBTYPE oid);
|
||||
int willbackstab(lifeform_t *lf, lifeform_t *victim, object_t *wep);
|
||||
int willbleedfrom(lifeform_t *lf, enum BODYPART bp);
|
||||
int willburden(lifeform_t *lf, object_t *o, int howmany);
|
||||
|
|
272
map.c
272
map.c
|
@ -133,7 +133,7 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
|
|||
cell_t *c;
|
||||
o = addob(homeobloc->obpile, f->text);
|
||||
if (o && (homeobloc == lf->cell) && isimpassableob(o, lf, SZ_ANY)) {
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL, MT_NOTHING);
|
||||
if (c) {
|
||||
homeobloc = c; // future obs will go here too.
|
||||
moveob(o, homeobloc->obpile, o->amt);
|
||||
|
@ -246,7 +246,6 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
int db = B_FALSE;
|
||||
flagpile_t *wantflags = NULL;
|
||||
enum JOB wantjob = J_NONE;
|
||||
enum SUBJOB wantsubjob = SJ_NONE;
|
||||
enum BEHAVIOUR wantbehaviour = BH_NONE;
|
||||
|
||||
if (nadded) *nadded = 0;
|
||||
|
@ -274,7 +273,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
} else {
|
||||
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
rid = parserace(racename, wantflags, &wantjob, &wantsubjob, &wantbehaviour);
|
||||
rid = parserace(racename, wantflags, &wantjob, &wantbehaviour);
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
if (rid == R_RANDOM) {
|
||||
|
@ -340,8 +339,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
f = retflag[i];
|
||||
// has a job?
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
job_t *j;
|
||||
enum SUBJOB wantsubjob;
|
||||
//job_t *j;
|
||||
if (f->val[1] == J_RANDOM) {
|
||||
job_t *j;
|
||||
j = getrandomjob(B_TRUE);
|
||||
|
@ -349,40 +347,13 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
} else {
|
||||
wantjob = f->val[1];
|
||||
}
|
||||
// special case: wizards MUST have a subjob.
|
||||
if (wantjob == J_WIZARD) {
|
||||
wantsubjob = SJ_RANDOM;
|
||||
} else {
|
||||
wantsubjob = f->val[2];
|
||||
}
|
||||
givejob(lf, wantjob, SJ_NONE);
|
||||
|
||||
j = findjob(wantjob);
|
||||
// subjob ?
|
||||
if (j && (wantsubjob != NA)) {
|
||||
// cope with random
|
||||
if (wantsubjob == SJ_RANDOM) {
|
||||
// find a subjob which applies
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags;
|
||||
|
||||
getflags(j->flags, retflag, &nretflags, F_CANHAVESUBJOB, F_NONE);
|
||||
if (nretflags) {
|
||||
givesubjob(lf, retflag[rnd(0,nretflags-1)]->val[0]);
|
||||
}
|
||||
} else {
|
||||
givesubjob(lf, wantsubjob);
|
||||
}
|
||||
}
|
||||
givejob(lf, wantjob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
givejob(lf, wantjob, SJ_NONE);
|
||||
}
|
||||
if (wantsubjob != SJ_NONE) {
|
||||
givesubjob(lf, wantsubjob);
|
||||
givejob(lf, wantjob);
|
||||
}
|
||||
|
||||
generatealignment(lf);
|
||||
|
@ -483,7 +454,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
lifeform_t *newlf;
|
||||
// find an adjacent cell to one of the newly added monsters,
|
||||
// starting with the first one
|
||||
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL);
|
||||
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL, MT_NOTHING);
|
||||
// did we find one?
|
||||
if (!adjcell) break;
|
||||
|
||||
|
@ -533,10 +504,10 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
enum RACE newrid;
|
||||
race_t *newr;
|
||||
|
||||
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL);
|
||||
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL, MT_NOTHING);
|
||||
if (!adjcell) break;
|
||||
|
||||
newrid = parserace(f->text, NULL, NULL, NULL, NULL);
|
||||
newrid = parserace(f->text, NULL, NULL, NULL);
|
||||
newr = findrace(newrid);
|
||||
if (!newr) break;
|
||||
|
||||
|
@ -1244,6 +1215,7 @@ int cellhaslos(cell_t *c1, cell_t *dest) {
|
|||
|
||||
// you can always see your own cell
|
||||
if (i != 0) {
|
||||
object_t *oo;
|
||||
// solid cells stop los - but if you are standing on a solid
|
||||
// cell you can still see out.
|
||||
cell = getcellat(map, x, y);
|
||||
|
@ -1263,8 +1235,19 @@ int cellhaslos(cell_t *c1, cell_t *dest) {
|
|||
*/
|
||||
|
||||
// check for objects which block view
|
||||
if (hasobwithflag(cell->obpile, F_BLOCKSVIEW)) {
|
||||
return B_FALSE;
|
||||
oo = hasobwithflag(cell->obpile, F_BLOCKSVIEW);
|
||||
if (oo) {
|
||||
if (cell == c1) {
|
||||
flag_t *f;
|
||||
f = hasflag(oo->flags, F_BLOCKSVIEW);
|
||||
if (f && (f->val[1] == B_TRUE)) {
|
||||
// ok.
|
||||
} else {
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1879,11 +1862,7 @@ int damagecell(cell_t *c, int amt, enum DAMTYPE damtype, lifeform_t *fromlf) {
|
|||
|
||||
// returns true if something happened
|
||||
int doelementspread(cell_t *c) {
|
||||
float thisdepth;
|
||||
int i;
|
||||
int nsurround = 0;
|
||||
int db = B_FALSE;
|
||||
cell_t *surroundcell[8];
|
||||
//int db = B_FALSE;
|
||||
object_t *fireob = NULL;
|
||||
|
||||
if (!c || c->type->solid) {
|
||||
|
@ -1891,7 +1870,13 @@ int doelementspread(cell_t *c) {
|
|||
}
|
||||
|
||||
// calculate depth of this cell
|
||||
/* DISABLED FOR NOW.
|
||||
if (!hascloseddoor(c)) {
|
||||
float thisdepth;
|
||||
int i;
|
||||
int nsurround = 0;
|
||||
cell_t *surroundcell[8];
|
||||
|
||||
thisdepth = getcellwaterdepth(c, NULL);
|
||||
|
||||
if (thisdepth) {
|
||||
|
@ -1904,20 +1889,18 @@ int doelementspread(cell_t *c) {
|
|||
float newcdepth;
|
||||
int ok = B_FALSE;
|
||||
|
||||
/*
|
||||
FIX THIS CODE LATER
|
||||
if (newc->type->floorheight == c->type->floorheight) {
|
||||
// same height - don't include these???
|
||||
ok = B_FALSE;
|
||||
//ok = B_TRUE;
|
||||
} else if (newc->type->floorheight < c->type->floorheight) {
|
||||
// ie. downhill. don't include these
|
||||
ok = B_FALSE;
|
||||
} else if (newc->type->floorheight > c->type->floorheight) {
|
||||
// ie. uphill.
|
||||
ok = B_TRUE;
|
||||
}
|
||||
*/
|
||||
//FIX THIS CODE LATER
|
||||
//if (newc->type->floorheight == c->type->floorheight) {
|
||||
// // same height - don't include these???
|
||||
// ok = B_FALSE;
|
||||
// //ok = B_TRUE;
|
||||
//} else if (newc->type->floorheight < c->type->floorheight) {
|
||||
// // ie. downhill. don't include these
|
||||
// ok = B_FALSE;
|
||||
//} else if (newc->type->floorheight > c->type->floorheight) {
|
||||
// // ie. uphill.
|
||||
// ok = B_TRUE;
|
||||
//}
|
||||
if (newc->type->floorheight == c->type->floorheight) {
|
||||
ok = B_TRUE;
|
||||
} else {
|
||||
|
@ -1971,6 +1954,7 @@ int doelementspread(cell_t *c) {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// fire
|
||||
fireob = hasobofmaterial(c->obpile, MT_FIRE);
|
||||
if (fireob && (fireob->birthtime != curtime) && !isdeadob(fireob)) {
|
||||
|
@ -3311,7 +3295,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
// randomise dungeon parameters
|
||||
turnpct += (rnd(0,40)-20); // (-20 to +20)%
|
||||
sparseness += (rnd(0,20)-10); // -10 to +10
|
||||
looppct -= (rnd(0,10)); // subtrace 0 - 10
|
||||
looppct -= (rnd(0,10)); // subtract 0 - 10
|
||||
|
||||
if (shape == MS_NORMAL) {
|
||||
if (onein(2)) {
|
||||
|
@ -3443,7 +3427,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
c = getcellat(map, x, y);
|
||||
if (!c->type->solid && countcellexits(c, DT_ORTH) == 1) {
|
||||
// dead end - maybe make loop from here
|
||||
if (rnd(1,100) <= looppct) {
|
||||
if (pctchance(looppct)) {
|
||||
int connected = B_FALSE;
|
||||
int loopok = B_TRUE;
|
||||
int dir;
|
||||
|
@ -4216,14 +4200,14 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (db) dblog(" adding forced regionthing object: %s", thing[i]->what);
|
||||
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
|
||||
if (!c) c = getrandomcell(map);
|
||||
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
|
||||
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL, MT_NOTHING);
|
||||
addob(c->obpile, thing[i]->what);
|
||||
break;
|
||||
case RT_LF:
|
||||
if (db) dblog(" adding forced regionthing lifeform: %s", thing[i]->what);
|
||||
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
|
||||
if (!c) c = getrandomcell(map);
|
||||
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
|
||||
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL, MT_NOTHING);
|
||||
addmonster(c, R_SPECIFIED, thing[i]->what, B_FALSE, thing[i]->value, B_TRUE, NULL);
|
||||
break;
|
||||
case RT_BRANCHLINK:
|
||||
|
@ -4240,6 +4224,16 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
// ensure that starting level has a player start position
|
||||
if ((gamemode == GM_CHARGEN) && (region->rtype->id == BH_MAINDUNGEON)) {
|
||||
cell_t *startpos;
|
||||
startpos = findobinmap(map, OT_PLAYERSTART);
|
||||
if (!startpos) {
|
||||
dblog("ERROR - first level of main dungeon missing player start position.");
|
||||
failed = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure there are no unreachable areas
|
||||
if (!failed) {
|
||||
if (fix_reachability(map)) {
|
||||
|
@ -4402,6 +4396,21 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
*/
|
||||
|
||||
// link up holes - this will create NEW holes in THIS map connecting to
|
||||
// EXISTING unlinked holes in adjacent maps
|
||||
//
|
||||
// do this BEFORE linkind stairs, in case the act of linking holes generates the next map.
|
||||
// if this happens then we want to also join up unlinked stairs.
|
||||
// if we don't do this then when the player tries to use stairs, we will find
|
||||
// that an existing map below/above exists but has no stairs linked,
|
||||
// which isn't meant to happen.
|
||||
i = linkholes(map);
|
||||
if (db) {
|
||||
if (db) dblog(" autolinked to %d holes in adjacent maps.",i);
|
||||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
// try to join up any unlinked staircases in this map.
|
||||
if (db) dblog(" joining unlinked stairs...");
|
||||
|
@ -4435,13 +4444,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
// link up holes - this will create NEW holes in THIS map connecting to
|
||||
// EXISTING unlinked holes in adjacent maps
|
||||
i = linkholes(map);
|
||||
if (db) {
|
||||
if (db) dblog(" autolinked to %d holes in adjacent maps.",i);
|
||||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
|
||||
// add random objects and monsters , and remove
|
||||
// bad objects
|
||||
|
@ -6838,6 +6841,8 @@ cell_t *getcellindir(cell_t *cell, int dir) {
|
|||
case DC_NW:
|
||||
dt = DT_COMPASS;
|
||||
break;
|
||||
case D_MYSELF:
|
||||
return cell;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -6977,10 +6982,10 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
|
|||
|
||||
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) {
|
||||
return real_getrandomadjcell(c, wantempty, allowexpand, LOF_NEED, NULL, NULL, NULL);
|
||||
return real_getrandomadjcell(c, wantempty, allowexpand, LOF_NEED, NULL, NULL, NULL, MT_NOTHING);
|
||||
}
|
||||
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos) {
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos, enum MATERIAL wantmat) {
|
||||
int radius = 1;
|
||||
int x,y;
|
||||
cell_t *poss[MAXCANDIDATES];
|
||||
|
@ -7014,6 +7019,11 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
|
|||
}
|
||||
}
|
||||
}
|
||||
if (wantmat != MT_NOTHING) {
|
||||
if (new->type->material->id != wantmat) {
|
||||
ok = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (preferlos && haslos(preferlos, new)) {
|
||||
|
@ -7176,6 +7186,10 @@ int getslipperyness(cell_t *c, object_t **slipob) {
|
|||
if (slipob) *slipob = NULL;
|
||||
|
||||
switch (c->type->id) {
|
||||
case CT_MOSSROCK:
|
||||
addition = 15;
|
||||
pctmod += 50;
|
||||
break;
|
||||
case CT_FLOORTILE:
|
||||
addition = 10;
|
||||
pctmod += 50;
|
||||
|
@ -7199,12 +7213,13 @@ int getslipperyness(cell_t *c, object_t **slipob) {
|
|||
bestob = o;
|
||||
bestslip = thisslip;
|
||||
}
|
||||
thisslip += pctof(pctmod, addition);
|
||||
thisslip = pctof(pctmod, thisslip);
|
||||
thisslip *= o->amt;
|
||||
totalslip += thisslip;
|
||||
}
|
||||
}
|
||||
|
||||
totalslip += addition;
|
||||
//totalslip *= 2;
|
||||
|
||||
if (slipob) {
|
||||
|
@ -7301,6 +7316,16 @@ cell_t *getstairdestination(object_t *o, int *madenewmap) {
|
|||
return newcell;
|
||||
}
|
||||
|
||||
object_t *hasdoor(cell_t *c) {
|
||||
object_t *o;
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (isdoor(o, NULL)) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object_t *hasenterableobject(cell_t *c) {
|
||||
return hasobwithflag(c->obpile, F_CLIMBABLE);
|
||||
}
|
||||
|
@ -7398,7 +7423,7 @@ void initmap(void) {
|
|||
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE);
|
||||
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE);
|
||||
addhabitat(H_SEWER, "sewer", CT_MOSSROCK, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE);
|
||||
addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN);
|
||||
addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE);
|
||||
|
@ -7406,32 +7431,33 @@ void initmap(void) {
|
|||
addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 5, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN);
|
||||
|
||||
// cell types - solid
|
||||
// floorheight, hp
|
||||
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50);
|
||||
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40);
|
||||
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20);
|
||||
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30);
|
||||
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100);
|
||||
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20);
|
||||
// floorheight, hp, volmod
|
||||
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50, 0);
|
||||
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40, 0);
|
||||
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0);
|
||||
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0);
|
||||
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100, 0);
|
||||
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25, 0);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20, 0);
|
||||
//addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
|
||||
addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
|
||||
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75);
|
||||
addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100, 0);
|
||||
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75, 0);
|
||||
// cell types - non-solid
|
||||
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, C_ORANGE, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1);
|
||||
addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, NA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1);
|
||||
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
|
||||
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, NA, B_EMPTY, B_TRANS, MT_FLESH, 0, -1);
|
||||
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
|
||||
addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1);
|
||||
addcelltype(CT_GRASS, "grass", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_PLANT, 0, -1);
|
||||
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, C_YELLOW, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -1, -1);
|
||||
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -2, -1);
|
||||
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0);
|
||||
addcelltype(CT_MOSSROCK, "mossy rock floor", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0);
|
||||
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0);
|
||||
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0);
|
||||
addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, C_ORANGE, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1, -1);
|
||||
addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, NA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1, 1);
|
||||
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 1);
|
||||
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, NA, B_EMPTY, B_TRANS, MT_FLESH, 0, -1, -2);
|
||||
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 0);
|
||||
addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1, 2);
|
||||
addcelltype(CT_GRASS, "grass", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_PLANT, 0, -1, -1);
|
||||
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, C_YELLOW, B_EMPTY, B_TRANS, MT_STONE, 0, -1, -1);
|
||||
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -1, -1, 0);
|
||||
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -2, -1, 0);
|
||||
|
||||
// region types
|
||||
// name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth?
|
||||
|
@ -7813,7 +7839,7 @@ int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph) {
|
|||
int islit(cell_t *c) {
|
||||
int amt = 0;
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
//flag_t *f;
|
||||
/*
|
||||
switch (c->lit) {
|
||||
case L_TEMP:
|
||||
|
@ -7828,18 +7854,24 @@ int islit(cell_t *c) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
amt += obproduceslight(o);
|
||||
/*
|
||||
f = hasflag(o->flags, F_PRODUCESLIGHT);
|
||||
if (f) {
|
||||
amt += f->val[0];
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (c->lf) {
|
||||
amt += lfproduceslight(c->lf, NULL);
|
||||
/*
|
||||
for (o = c->lf->pack->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_PRODUCESLIGHT);
|
||||
if (f) {
|
||||
amt += f->val[0];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
@ -8018,7 +8050,7 @@ int linkholes(map_t *map) {
|
|||
// this will automatically avoid lifeforms since we're using
|
||||
// we_walkable rather than we_notwall. this saves problems
|
||||
// with someine coming up underneath you!
|
||||
c2 = real_getrandomadjcell(c2, WE_NOLF, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id, NULL, NULL);
|
||||
c2 = real_getrandomadjcell(c2, WE_NOLF, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id, NULL, NULL, MT_NOTHING);
|
||||
}
|
||||
// clear out the cell if required
|
||||
if (c2->type->solid) {
|
||||
|
@ -8395,7 +8427,7 @@ void mapentereffects(map_t *m) {
|
|||
// find the closest cell of my lair
|
||||
where = getclosestroomcell(c->lf, roomid);
|
||||
if (where) {
|
||||
movelf(c->lf, where);
|
||||
movelf(c->lf, where, B_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8498,7 +8530,7 @@ int orthdir(int compassdir) {
|
|||
return D_NONE;
|
||||
}
|
||||
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum SUBJOB *wantsubjob, enum BEHAVIOUR *wantbehaviour) {
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum BEHAVIOUR *wantbehaviour) {
|
||||
int donesomething;
|
||||
char *p,*suff;
|
||||
job_t *j;
|
||||
|
@ -8566,42 +8598,6 @@ enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum S
|
|||
}
|
||||
}
|
||||
|
||||
if (!j) {
|
||||
int foundsubjob = B_FALSE;
|
||||
// search for subjob names
|
||||
char *ep;
|
||||
ep = strends(localname, "Skymage");
|
||||
if (ep && !foundsubjob) {
|
||||
if (wantjob) *wantjob = J_WIZARD;
|
||||
if (wantsubjob) *wantsubjob = SJ_AIRMAGE;
|
||||
*ep = '\0';
|
||||
foundsubjob = B_TRUE;
|
||||
}
|
||||
ep = strends(localname, "Icemage");
|
||||
if (ep && !foundsubjob) {
|
||||
if (wantjob) *wantjob = J_WIZARD;
|
||||
if (wantsubjob) *wantsubjob = SJ_ICEMAGE;
|
||||
*ep = '\0';
|
||||
foundsubjob = B_TRUE;
|
||||
}
|
||||
ep = strends(localname, "Firemage");
|
||||
if (ep && !foundsubjob) {
|
||||
if (wantjob) *wantjob = J_WIZARD;
|
||||
if (wantsubjob) *wantsubjob = SJ_FIREMAGE;
|
||||
*ep = '\0';
|
||||
foundsubjob = B_TRUE;
|
||||
}
|
||||
ep = strends(localname, "Necromancer");
|
||||
if (ep && !foundsubjob) {
|
||||
if (wantjob) *wantjob = J_WIZARD;
|
||||
if (wantsubjob) *wantsubjob = SJ_NECROMANCER;
|
||||
*ep = '\0';
|
||||
foundsubjob = B_TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// try removing suffixes for "named xxx"
|
||||
strcpy(named, "");
|
||||
suff = strstr(localname, " named ");
|
||||
|
@ -9095,7 +9091,7 @@ int validateregionthing(regionthing_t *thing) {
|
|||
}
|
||||
break;
|
||||
case RT_LF:
|
||||
rid = parserace(thing->what, NULL, NULL, NULL, NULL);
|
||||
rid = parserace(thing->what, NULL, NULL, NULL);
|
||||
if (rid == R_NONE) {
|
||||
dblog("Invalid lifeform '%s' specified in regionthing.", thing->what);
|
||||
goterrors = B_TRUE;
|
||||
|
|
5
map.h
5
map.h
|
@ -132,7 +132,7 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
|||
int getobchance(int habitat);
|
||||
int getthingchance(int habitat);
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos, enum MATERIAL wantmat);
|
||||
cell_t *getrandomcell(map_t *map);
|
||||
cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id);
|
||||
int getrandomdir(int dirtype);
|
||||
|
@ -141,6 +141,7 @@ cell_t *getrandomroomcell(map_t *map, int roomid, int wantempty);
|
|||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
||||
int getslipperyness(cell_t *c, object_t **slipob);
|
||||
cell_t *getstairdestination(object_t *o, int *madenewmap);
|
||||
object_t *hasdoor(cell_t *c);
|
||||
object_t *hasenterableobject(cell_t *c);
|
||||
object_t *hascloseddoor(cell_t *c);
|
||||
int hascrushableob(cell_t *c, lifeform_t *lf);
|
||||
|
@ -185,7 +186,7 @@ void mapentereffects(map_t *m);
|
|||
void modillumination(map_t *m, int dir);
|
||||
void moveobtoclearcell(object_t *o);
|
||||
int orthdir(int compassdir);
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum SUBJOB *wantsubjob, enum BEHAVIOUR *wantbehaviour);
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum BEHAVIOUR *wantbehaviour);
|
||||
int remove_deadends(map_t *m, int howmuch);
|
||||
void selectcelltypes(map_t *map);
|
||||
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph);
|
||||
|
|
172
move.c
172
move.c
|
@ -143,9 +143,10 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
|
|||
if (isknownpeaceful(lf2)) {
|
||||
// player can swap with peaceful lfs
|
||||
// if they are a lot smaller
|
||||
if (getlfsize(lf) - getlfsize(lf2) >= 2) {
|
||||
return B_TRUE;
|
||||
}
|
||||
//if (getlfsize(lf) - getlfsize(lf2) >= 2) {
|
||||
// return B_TRUE;
|
||||
//}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
|
@ -1194,7 +1195,7 @@ int moveeffects(lifeform_t *lf, int moved) {
|
|||
|
||||
|
||||
// returns TRUE if something happened
|
||||
int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||
int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
||||
object_t *o,*nexto;
|
||||
cell_t *precell;
|
||||
char obname[BUFLEN],lfname[BUFLEN],buf[BUFLEN];
|
||||
|
@ -1222,9 +1223,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (newcell->map != lf->cell->map) {
|
||||
changedlev = B_TRUE;
|
||||
lf->changinglev = B_TRUE;
|
||||
|
@ -1341,6 +1339,9 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
*/
|
||||
//precalclos(lf);
|
||||
|
||||
// refresh name of lf, in case it came into view.
|
||||
getlfname(lf, lfname);
|
||||
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
@ -1453,36 +1454,58 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!lfhasflag(lf, F_CAREFULMOVE) && cancrush(lf, o)) {
|
||||
// crush it
|
||||
getobname(o, obname, 1);
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_BROKENGLASS) {
|
||||
if (o->amt > 1) {
|
||||
char *newname;
|
||||
// we want 'xx steps on some pieces of broken glass'
|
||||
// not 'xx steps on 5 pieces of broken glass'
|
||||
newname = makeplural(obname);
|
||||
newname = strrep(newname, "a ", "some ", NULL);
|
||||
strcpy(obname, newname);
|
||||
free(newname);
|
||||
if (!lfhasflag(lf, F_CAREFULMOVE)) {
|
||||
if (cancrush(lf, o)) {
|
||||
// crush it
|
||||
getobname(o, obname, 1);
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_BROKENGLASS) {
|
||||
if (o->amt > 1) {
|
||||
char *newname;
|
||||
// we want 'xx steps on some pieces of broken glass'
|
||||
// not 'xx steps on 5 pieces of broken glass'
|
||||
newname = makeplural(obname);
|
||||
newname = strrep(newname, "a ", "some ", NULL);
|
||||
strcpy(obname, newname);
|
||||
free(newname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You crush %s underfoot.",obname);
|
||||
didmsg = B_TRUE;
|
||||
} else if (haslos(player, newcell)) {
|
||||
msg("%s crushes %s.",lfname, obname);
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
// kill object which is being crushed.
|
||||
removeob(o, o->amt);
|
||||
if (isplayer(lf)) {
|
||||
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
|
||||
}
|
||||
continue;
|
||||
if (isplayer(lf)) {
|
||||
msg("You crush %s underfoot.",obname);
|
||||
didmsg = B_TRUE;
|
||||
} else if (haslos(player, newcell)) {
|
||||
msg("%s crushes %s.",lfname, obname);
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
// kill object which is being crushed.
|
||||
removeob(o, o->amt);
|
||||
if (isplayer(lf)) {
|
||||
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (hasflag(o->flags, F_DIMONWALK)) {
|
||||
f = hasflag(o->flags, F_PRODUCESLIGHT);
|
||||
getobname(o, obname, o->amt);
|
||||
if (f) f->val[0]--;
|
||||
if (!f || (f->val[0] <= 0)) {
|
||||
if (haslos(player, newcell)) {
|
||||
msg("%s dim%s and crumbles.",obname,
|
||||
(o->amt == 1) ? "s" : "");
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
removeob(o, ALL);
|
||||
continue;
|
||||
} else {
|
||||
if (haslos(player, newcell)) {
|
||||
msg("%s dim%s slightly.",obname,
|
||||
(o->amt == 1) ? "s" : "");
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
}
|
||||
} // end if dimonwalk
|
||||
} // end if crushable
|
||||
|
||||
if ((o->type->id == OT_VINE) && !hasjob(lf, J_DRUID)) {
|
||||
|
@ -1664,7 +1687,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
}
|
||||
*/
|
||||
if (preseenbyplayer && !cansee(player, lf) && !changedlev) {
|
||||
if (onpurpose && preseenbyplayer && !cansee(player, lf) && !changedlev) {
|
||||
if (isadjacent(lf->cell, precell)) { // ie don't say this if we teleported/jumped
|
||||
if (areenemies(player, lf)) {
|
||||
char buf[BUFLEN];
|
||||
|
@ -1703,7 +1726,7 @@ int movelfsoutofway(cell_t *newcell) {
|
|||
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
// move them there
|
||||
movelf(newcell->lf, c);
|
||||
movelf(newcell->lf, c, B_FALSE);
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1748,7 +1771,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
// actually do the move
|
||||
didmsg = movelf(lf, newcell);
|
||||
didmsg = movelf(lf, newcell, onpurpose);
|
||||
|
||||
if (isplayer(lf)) {
|
||||
// is new cell dark?
|
||||
|
@ -2085,11 +2108,20 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
// known - try to force it
|
||||
int amt = 0;
|
||||
amt = getattr(lf, A_STR) - 10;
|
||||
if (amt < 0) amt = 0;
|
||||
limit(&amt, 0, NA);
|
||||
|
||||
// loosen a bit
|
||||
if (amt > 0) {
|
||||
f->val[0] -= amt;
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
if (amt > 0) {
|
||||
msg("The %s moves slightly but remains jammed.", noprefix(obname));
|
||||
if (f->val[0] > 0) {
|
||||
msg("The %s moves slightly but remains jammed.", noprefix(obname));
|
||||
}
|
||||
// ... otherwise we'll announce later that we forced the door
|
||||
// successfully
|
||||
} else {
|
||||
msg("You cannot budge the jammed %s.", noprefix(obname));
|
||||
}
|
||||
|
@ -2113,12 +2145,9 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// loosen a bit
|
||||
if (amt) {
|
||||
f->val[0] -= amt;
|
||||
}
|
||||
if (f->val[0] <= 0) {
|
||||
killflag(f);
|
||||
killflag(f);
|
||||
f = NULL;
|
||||
openit = B_TRUE;
|
||||
} else {
|
||||
openit = B_FALSE; // don't open the door
|
||||
|
@ -2374,7 +2403,7 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
|
|||
isairborne(lf) ? "through the air" :
|
||||
"along the ground");
|
||||
}
|
||||
movelf(lf, dst);
|
||||
movelf(lf, dst, B_FALSE);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2404,7 +2433,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
|
|||
} else {
|
||||
// must pass a skill check to keep climbing!
|
||||
if (!skillcheck(lf, SC_CLIMB, getcellclimbdifficulty(cell), 0)) {
|
||||
msg("You lose your footing!");
|
||||
msg("^bYou lose your footing!");
|
||||
stopclimbing(lf, B_FALSE);
|
||||
reason = E_OK;
|
||||
return B_TRUE;
|
||||
|
@ -2771,7 +2800,7 @@ int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
|
|||
if (wantsmoke) {
|
||||
addob(lf->cell->obpile, "cloud of smoke");
|
||||
}
|
||||
movelf(lf, c);
|
||||
movelf(lf, c, B_FALSE);
|
||||
|
||||
if (cansee(player, lf)) {
|
||||
redraw(); // redraw screen
|
||||
|
@ -2858,7 +2887,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
int srcmoney = 0;
|
||||
int prebattle = B_FALSE;
|
||||
int prebattlearmed = B_FALSE;
|
||||
flag_t *f,*fleeing = NULL;
|
||||
flag_t *fleeing = NULL;
|
||||
// are we next to an enemy who we can see?
|
||||
prebattle = isinbattle(lf, B_NODISTANT, B_FALSE);
|
||||
if (isplayer(lf)) {
|
||||
|
@ -2911,21 +2940,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
}
|
||||
|
||||
|
||||
f = lfhasflag(lf, F_DRUNK);
|
||||
if (f) {
|
||||
if (!hasjob(lf, J_PIRATE)) {
|
||||
if (rnd(1,6) <= ((f->lifetime/TM_DRUNKTIME)+1)) {
|
||||
// randomize move
|
||||
rndmove = B_TRUE; // ie. you can walk into walls now.
|
||||
}
|
||||
}
|
||||
} else if (iswoozy(lf)) {
|
||||
rndmove = B_TRUE;
|
||||
} else if (lfhasflagval(lf, F_INJURY, IJ_TAILBRUISED, NA, NA, NULL) && onein(6)) {
|
||||
rndmove = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
rndmove = movesrandomly(lf);
|
||||
if (rndmove) {
|
||||
dir = rnd(DC_N, DC_NW);
|
||||
strafe = B_TRUE;
|
||||
|
@ -3105,7 +3120,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
getlfname(alf, alfname);
|
||||
msg("%s drags %s along.", lfname, alfname);
|
||||
}
|
||||
movelf(alf, nc);
|
||||
movelf(alf, nc, B_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3358,18 +3373,32 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
} else {
|
||||
if (canswapwith(lf, cell->lf)) {
|
||||
lifeform_t *lfinway;
|
||||
char lfname[BUFLEN];
|
||||
strcpy(lfname, "__not used yet__");
|
||||
// otherwise swap locations.
|
||||
lfinway = cell->lf;
|
||||
|
||||
// need to get the name of whoever you swapped with
|
||||
// BEFORE moving, as afterwards we may no longer be
|
||||
// able to see it.
|
||||
if (isplayer(lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lfinway, lfname);
|
||||
msg("You swap places with %s.", lfname);
|
||||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
|
||||
swapplaces(lf, lfinway, B_NOCHANGEDIR, B_NOCHANGEDIR, onpurpose);
|
||||
|
||||
// need to print this AFTER moving, because otherwise the
|
||||
// act of moving will clear the message line and we'll never
|
||||
// see it.
|
||||
if (isplayer(lf)) {
|
||||
msg("You swap places with %s.", lfname);
|
||||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
|
||||
//if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
taketime(lf, getmovespeed(lf));
|
||||
} else {
|
||||
|
@ -3536,7 +3565,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
c = getrandomadjcell(dst, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
if (!initiatemove(adjally[n], NULL, B_TRUE, NULL)) {
|
||||
movelf(adjally[n], c);
|
||||
movelf(adjally[n], c, B_FALSE);
|
||||
taketime(adjally[n], getmovespeed(adjally[n]));
|
||||
}
|
||||
}
|
||||
|
@ -3719,8 +3748,9 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
if (isundead(lf)) {
|
||||
f = hasflag(o->flags, F_PRODUCESLIGHT);
|
||||
if (f && (f->val[0] >= gettr(lf))) {
|
||||
int amt;
|
||||
amt = obproduceslight(o);
|
||||
if (amt && (amt >= gettr(lf))) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
2
move.h
2
move.h
|
@ -18,7 +18,7 @@ int makeorthogonal(int dir);
|
|||
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype, int keepinlof, int strafe, int onpurpose);
|
||||
int moveclear(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
int moveeffects(lifeform_t *lf, int moved);
|
||||
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||
int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose);
|
||||
int movelfsoutofway(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 strafe);
|
||||
|
|
179
nexus.c
179
nexus.c
|
@ -35,7 +35,6 @@ raceclass_t *firstraceclass = NULL,*lastraceclass = NULL;
|
|||
recipe_t *firstrecipe = NULL,*lastrecipe = NULL;
|
||||
job_t *firstjob = NULL,*lastjob = NULL;
|
||||
poisontype_t *firstpoisontype = NULL,*lastpoisontype = NULL;
|
||||
subjob_t *firstsubjob = NULL,*lastsubjob = NULL;
|
||||
skill_t *firstskill = NULL,*lastskill = NULL;
|
||||
habitat_t *firsthabitat = NULL,*lasthabitat = NULL;
|
||||
map_t *firstmap = NULL,*lastmap = NULL;
|
||||
|
@ -51,6 +50,9 @@ int numnpcnames;
|
|||
extern lifeform_t *godlf[];
|
||||
extern int ngodlfs;
|
||||
|
||||
|
||||
extern WINDOW *mainwin;
|
||||
|
||||
int nextregionthingid = 0;
|
||||
|
||||
int playerorigalignment = AL_NONE;
|
||||
|
@ -207,7 +209,6 @@ int main(int argc, char **argv) {
|
|||
if (!foundsavegame) {
|
||||
char *user,pname[BUFLEN],buf[BUFLEN];
|
||||
job_t *j = NULL;
|
||||
enum SUBJOB wantsubjob = SJ_NONE;
|
||||
race_t *startrace = NULL;
|
||||
char ch;
|
||||
//object_t *o;
|
||||
|
@ -262,48 +263,33 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (!j) {
|
||||
enum JOBCATEGORY jcid;
|
||||
// ask for job
|
||||
initprompt(&prompt, "Select your base job:");
|
||||
ch = 'a';
|
||||
for (j = firstjob ; j ; j = j->next) {
|
||||
if (jobpossible(startrace->flags, j->id, SJ_NONE)) {
|
||||
subjob_t *sub;
|
||||
char *longdesc;
|
||||
// wizards must have a subjob
|
||||
if (j->id != J_WIZARD) {
|
||||
for (jcid = JC_FIRST ; jcid <= JC_LAST; jcid++) {
|
||||
for (j = firstjob ; j ; j = j->next) {
|
||||
if ((j->category == jcid) && jobpossible(startrace->flags, j->id)) {
|
||||
char *longdesc,buf[BUFLEN];
|
||||
longdesc = malloc(HUGEBUFLEN * sizeof(char));
|
||||
makedesc_job(j, longdesc);
|
||||
if (!hasflag(j->flags, F_NOPLAYER)) {
|
||||
// letter isn't used
|
||||
addchoice(&prompt, '-', (j->id == J_GOD) ? "Diety (for debugging)" : j->name, NULL, j, longdesc);
|
||||
if (j->id == J_GOD) {
|
||||
sprintf(buf, "%-20s(%s)", "Diety", "for debugging");
|
||||
} else {
|
||||
sprintf(buf, "%-20s(%s)", j->name, getjobcatname(j->category));
|
||||
}
|
||||
addchoice(&prompt, '-', buf, NULL, j, longdesc);
|
||||
}
|
||||
free(longdesc);
|
||||
}
|
||||
// show subjobs of this one too...
|
||||
for (sub = firstsubjob ; sub ; sub = sub->next) {
|
||||
if (hasflagval(j->flags, F_CANHAVESUBJOB, sub->id, NA, NA, NULL)) {
|
||||
if (jobpossible(startrace->flags, J_NONE, sub->id)) {
|
||||
char thisname[BUFLEN];
|
||||
sprintf(thisname, "%s:%s", j->name, sub->name);
|
||||
addchoice(&prompt, sub->letter, thisname, NULL, j, sub->desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j = NULL;
|
||||
while (!j) {
|
||||
getchoicestr(&prompt, B_FALSE, B_TRUE);
|
||||
j = prompt.result;
|
||||
if (prompt.selection != '-') {
|
||||
subjob_t *sj;
|
||||
// ie. selected a subjob
|
||||
// find the subjob with this letter....
|
||||
sj = findsubjobbyletter(prompt.choice[prompt.selection].ch);
|
||||
if (sj) {
|
||||
wantsubjob = sj->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,10 +299,10 @@ int main(int argc, char **argv) {
|
|||
createfakes(&fakemap, &fakecell);
|
||||
real_addlf(&fakecell, startrace->id, 1, C_PLAYER); // this will assign 'player'
|
||||
// give them basic abilities
|
||||
addflag(player->flags, F_CANWILL, OT_A_CHECKSTAIRS, NA, NA, NULL);
|
||||
addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL);
|
||||
addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL);
|
||||
addflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL); /////////
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_CHECKSTAIRS, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL, FROMGAMESTART); /////////
|
||||
|
||||
// make the initial level
|
||||
|
||||
|
@ -353,7 +339,7 @@ int main(int argc, char **argv) {
|
|||
exit(1);
|
||||
}
|
||||
if (where->lf) killlf(where->lf);
|
||||
movelf(player, where);
|
||||
movelf(player, where, B_FALSE);
|
||||
// new remove fakes
|
||||
killfakes(&fakemap, &fakecell);
|
||||
|
||||
|
@ -394,7 +380,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// give the player their job
|
||||
givejob(player, j->id, wantsubjob);
|
||||
givejob(player, j->id);
|
||||
//////////////////////
|
||||
|
||||
// read cheat info from player file
|
||||
|
@ -431,7 +417,7 @@ int main(int argc, char **argv) {
|
|||
assert(r);
|
||||
|
||||
// create pet, in view of player if possible.
|
||||
c = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, &avoidob, NULL, player);
|
||||
c = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, &avoidob, NULL, player, MT_NOTHING);
|
||||
assert(c);
|
||||
pet = addlf(c, r->id, 1);
|
||||
// mark us as its master
|
||||
|
@ -531,9 +517,127 @@ int main(int argc, char **argv) {
|
|||
// show level
|
||||
drawscreen();
|
||||
|
||||
if (!hasjob(player, J_GOD) && (lfhasflag(player, F_CANCAST) || lfhasflag(player, F_CANWILL))) {
|
||||
int order[3] = { FROMRACE, FROMJOB, FROMSKILL }, norder = 3;
|
||||
int first = B_TRUE,i,nspells = 0, nabils = 0, n;
|
||||
char buf[BUFLEN];
|
||||
cls();
|
||||
wmove(mainwin, 0, 0);
|
||||
textwithcol(mainwin, welcomemsg);
|
||||
textwithcol(mainwin, "\n\n");
|
||||
|
||||
// show spells
|
||||
getflags(player->flags, retflag, &nspells, F_CANCAST, F_NONE);
|
||||
for (n = 0; n < norder; n++) {
|
||||
for (i = 0; i < nspells; i++) {
|
||||
objecttype_t *sp;
|
||||
if (retflag[i]->lifetime != order[n]) continue;
|
||||
|
||||
sp = findot(retflag[i]->val[0]);
|
||||
if (sp) {
|
||||
if (first) {
|
||||
textwithcol(mainwin, "Your starting spells are:\n");
|
||||
first = B_FALSE;
|
||||
}
|
||||
sprintf(buf, " - %-20s (%s", sp->name, getschoolname(getspellschoolknown(player, sp->id)) );
|
||||
if (order[n] == FROMRACE) {
|
||||
char rname[BUFLEN];
|
||||
strcat(buf, ", ^g");
|
||||
sprintf(rname, "%s", player->race->name);
|
||||
capitalise(rname);
|
||||
strcat(buf, rname);
|
||||
strcat(buf, " perk^n");
|
||||
} else if (order[n] == FROMJOB) {
|
||||
strcat(buf, ", ^G");
|
||||
strcat(buf, getjobname(player));
|
||||
strcat(buf, " perk^n");
|
||||
} else if (order[n] == FROMSKILL) {
|
||||
skill_t *sk;
|
||||
enum SKILLLEVEL whichlev;
|
||||
sk = retflag[i]->skillfrom;
|
||||
assert(sk);
|
||||
|
||||
whichlev = whichlevforabil(sk->id, sp->id);
|
||||
assert(whichlev != PR_INEPT);
|
||||
|
||||
strcat(buf, ", ^w");
|
||||
strcat(buf, getskilllevelname(whichlev));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, sk->name);
|
||||
strcat(buf, " perk^n");
|
||||
}
|
||||
strcat(buf, ")\n");
|
||||
textwithcol(mainwin, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nspells) {
|
||||
textwithcol(mainwin, "\n");
|
||||
}
|
||||
|
||||
// show racial and job abilities
|
||||
first = B_TRUE;
|
||||
getflags(player->flags, retflag, &nabils, F_CANWILL, F_NONE);
|
||||
for (n = 0; n < norder; n++) {
|
||||
for (i = 0; i < nabils; i++) {
|
||||
objecttype_t *sp;
|
||||
// don't list abilities which everyone has.
|
||||
if (retflag[i]->lifetime == FROMGAMESTART) continue;
|
||||
if (retflag[i]->lifetime != order[n]) continue;
|
||||
|
||||
sp = findot(retflag[i]->val[0]);
|
||||
if (sp) {
|
||||
if (first) {
|
||||
textwithcol(mainwin, "Your unique starting abilities are:\n");
|
||||
first = B_FALSE;
|
||||
}
|
||||
sprintf(buf, " - %-20s", sp->name);
|
||||
if (order[n] == FROMRACE) {
|
||||
char rname[BUFLEN];
|
||||
strcat(buf, " (^g");
|
||||
|
||||
sprintf(rname, "%s", player->race->name);
|
||||
capitalise(rname);
|
||||
strcat(buf, rname);
|
||||
|
||||
strcat(buf, " perk^n)");
|
||||
} else if (order[n] == FROMJOB) {
|
||||
strcat(buf, " (^G");
|
||||
strcat(buf, getjobname(player));
|
||||
strcat(buf, " perk^n)");
|
||||
} else if (order[n] == FROMSKILL) {
|
||||
skill_t *sk;
|
||||
enum SKILLLEVEL whichlev;
|
||||
sk = retflag[i]->skillfrom;
|
||||
assert(sk);
|
||||
|
||||
whichlev = whichlevforabil(sk->id, sp->id);
|
||||
assert(whichlev != PR_INEPT);
|
||||
|
||||
strcat(buf, " (^w");
|
||||
strcat(buf, getskilllevelname(whichlev));
|
||||
strcat(buf, " ");
|
||||
strcat(buf, sk->name);
|
||||
strcat(buf, " perk^n)");
|
||||
}
|
||||
strcat(buf, "\n");
|
||||
textwithcol(mainwin, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nabils) {
|
||||
textwithcol(mainwin, "\n");
|
||||
}
|
||||
wprintw(mainwin, "\n[Press any key to begin]");
|
||||
getch();
|
||||
|
||||
restoregamewindows();
|
||||
}
|
||||
|
||||
clearmsg();
|
||||
msg("%s",welcomemsg);
|
||||
more();
|
||||
//more();
|
||||
|
||||
playerorigalignment = getalignment(player);
|
||||
|
||||
// MAIN LOOP
|
||||
|
@ -587,7 +691,7 @@ int main(int argc, char **argv) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp) {
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod) {
|
||||
celltype_t *a;
|
||||
|
||||
// add to the end of the list
|
||||
|
@ -620,6 +724,7 @@ celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, i
|
|||
a->material = findmaterial(mat);
|
||||
a->floorheight = floorheight;
|
||||
a->hp = hp;
|
||||
a->volumemod = volumemod;
|
||||
|
||||
a->flags = addflagpile(NULL, NULL);
|
||||
|
||||
|
|
2
nexus.h
2
nexus.h
|
@ -1,6 +1,6 @@
|
|||
#include "defs.h"
|
||||
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp);
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod);
|
||||
warning_t *addwarning(char *text, int lifetime);
|
||||
void checkdeath(void);
|
||||
void checkendgame(void);
|
||||
|
|
193
objects.c
193
objects.c
|
@ -1464,12 +1464,23 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
addflag(o->flags, F_MAPLINK, targetmap->id, tx, ty, NULL);
|
||||
}
|
||||
|
||||
// assign gods to temples
|
||||
// assign gods to temples, and set opening hours.
|
||||
if (o->type->id == OT_TEMPLE) {
|
||||
lifeform_t *god;
|
||||
god = getrandomgod();
|
||||
if (god) {
|
||||
addflag(o->flags, F_LINKGOD, god->race->id, NA, NA, NULL);
|
||||
switch (god->race->id) {
|
||||
case R_GODDEATH:
|
||||
case R_GODTHIEVES
|
||||
|
||||
oooooo
|
||||
// open at night only
|
||||
addflag(lastot->flags, F_OPENHOURS, 9, 17, SP_CLOSEDTILNIGHT, NULL);
|
||||
break;
|
||||
default: // always open
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// this should only ever happen when creating the
|
||||
// surface map - because the realm of gods (and hence the
|
||||
|
@ -1631,7 +1642,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
// add contents to the book
|
||||
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
|
||||
// giving to player at start of game
|
||||
if (hasjob(where->owner, J_WIZARD)) {
|
||||
if (hasjobcat(where->owner, JC_MAGE)) {
|
||||
enum OBTYPE firstspell;
|
||||
nspells = 5;
|
||||
firstlev = 2;
|
||||
|
@ -1654,7 +1665,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (lev > MAXSPELLLEV) break;
|
||||
oid = getrandomspellfromschool(bookcontents,lev);
|
||||
// special case - paladin's always have this spell
|
||||
if ((lev == 3) && (where->owner) && hassubjob(where->owner, SJ_PALADIN) &&
|
||||
if ((lev == 3) && (where->owner) && hasjob(where->owner, J_PALADIN) &&
|
||||
(bookcontents == SS_LIFE)) {
|
||||
while (oid == OT_S_DISRUPTUNDEAD) {
|
||||
oid = getrandomspellfromschool(bookcontents,lev);
|
||||
|
@ -1671,10 +1682,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
enum SPELLSCHOOL school[MAXCANDIDATES];
|
||||
|
||||
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
|
||||
if (hassubjob(where->owner, SJ_BATTLEMAGE)) {
|
||||
if (hasjob(where->owner, J_BATTLEMAGE)) {
|
||||
nschools = 3;
|
||||
} else if (hasjob(where->owner, J_WIZARD)) {
|
||||
nschools = 6;
|
||||
} else if (hasjobcat(where->owner, JC_MAGE)) {
|
||||
nschools = 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1691,7 +1702,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
} else {
|
||||
// select actual random schools to use.
|
||||
for (i = 0; i < nschools; i++) {
|
||||
if (where->owner && hassubjob(where->owner, SJ_BATTLEMAGE)) {
|
||||
if (where->owner && hasjob(where->owner, J_BATTLEMAGE)) {
|
||||
switch (rnd(1,5)) {
|
||||
case 1: school[i] = SS_FIRE; break;
|
||||
case 2: school[i] = SS_COLD; break;
|
||||
|
@ -1699,8 +1710,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
case 4: school[i] = SS_TRANSLOCATION; break;
|
||||
case 5: school[i] = SS_WILD; break;
|
||||
}
|
||||
} else if (where->owner && hasjob(where->owner, J_WIZARD)) {
|
||||
school[i] = getrandomspellschool(where->owner, B_TRUE);
|
||||
} else if (where->owner && hasjobcat(where->owner, JC_MAGE)) {
|
||||
school[i] = getrandomspellschool(where->owner, B_TRUE);
|
||||
} else {
|
||||
// should never happen?
|
||||
school[i] = getrandomspellschool(NULL, B_FALSE);
|
||||
|
@ -1718,7 +1729,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
// giving to player at start of game? limit levels to
|
||||
// 1-3.
|
||||
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
|
||||
if (hasjob(where->owner, J_WIZARD)) {
|
||||
if (hasjobcat(where->owner, JC_MAGE)) {
|
||||
switch (rnd(1,10)) {
|
||||
case 1: case 2: case 3:
|
||||
case 4: case 5: case 6:
|
||||
|
@ -1731,7 +1742,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
wantlev = 3;
|
||||
break;
|
||||
}
|
||||
} else if (hassubjob(where->owner, SJ_BATTLEMAGE)) {
|
||||
} else if (hasjob(where->owner, J_BATTLEMAGE)) {
|
||||
wantlev = 1;
|
||||
} else {
|
||||
wantlev = getrandomgrimoirelev();
|
||||
|
@ -2946,6 +2957,15 @@ int canseeob(lifeform_t *lf, object_t *o) {
|
|||
object_t *blockob;
|
||||
blockob = hasobwithflag(o->pile, F_BLOCKSVIEW);
|
||||
if (blockob && (blockob != o)) {
|
||||
if (o->pile->where == lf->cell) {
|
||||
flag_t *f;
|
||||
f = hasflag(blockob->flags, F_BLOCKSVIEW);
|
||||
if (f && (f->val[1] == B_TRUE)) {
|
||||
// ok
|
||||
} else {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -5874,6 +5894,21 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
strcat(localbuf, "}");
|
||||
}
|
||||
|
||||
// trap type known?
|
||||
f = hasflagval(o->flags, F_TRAPPED, NA, NA, B_TRUE, NULL);
|
||||
if (f) {
|
||||
if (getskill(player, SK_ENGINEERING) >= PR_BEGINNER) {
|
||||
objecttype_t *traptype;
|
||||
traptype = findot(f->val[0]);
|
||||
if (traptype) {
|
||||
strcat(localbuf, " (");
|
||||
strcat(localbuf, traptype->name);
|
||||
strcat(localbuf, ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// show if we've tried this
|
||||
//if (!shopitem && (gamemode == GM_GAMESTARTED)) {
|
||||
if ((gamemode == GM_GAMESTARTED) && wanttried) {
|
||||
|
@ -6296,6 +6331,10 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh
|
|||
} else if (!nwantflag) {
|
||||
wantclass[0] = getrandomobclass(hab->id);
|
||||
nwantclass = 1;
|
||||
if (wantclass[0] == OC_WAND) {
|
||||
dblog("random WAND picked!");
|
||||
partdb = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6384,7 +6423,12 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh
|
|||
}*/
|
||||
|
||||
if (rarflag) {
|
||||
if ((rarflag->val[1] >= raritymin) && (rarflag->val[1] <= raritymax)) {
|
||||
int rarnum;
|
||||
rarnum = rarflag->val[1];
|
||||
if (rarnum == NA) rarnum = 100;
|
||||
|
||||
if ((rarnum >= raritymin) && (rarnum <= raritymax)) {
|
||||
// now check common, rare, etc
|
||||
enum RARITY thisrr;
|
||||
thisrr = rarflag->val[2];
|
||||
if (thisrr == NA) thisrr = RR_FREQUENT;
|
||||
|
@ -6868,6 +6912,7 @@ char *gettopobname(cell_t *c, char *retbuf) {
|
|||
} else {
|
||||
// just print the cell's name
|
||||
strcat(retbuf, c->type->name);
|
||||
addengineeringinfo(player, retbuf, c);
|
||||
}
|
||||
if (c->writing) {
|
||||
strcat(retbuf, ", writing:");
|
||||
|
@ -8426,6 +8471,11 @@ void makewet(object_t *o, int amt) {
|
|||
}
|
||||
f = addflag(o->flags, F_WET, amt, TM_WETTIME, NA, NULL);
|
||||
}
|
||||
// water washes off bloodstain and stench
|
||||
if (hasobmod(o, findobmod(OM_BLOODSTAINED)) ){
|
||||
killflagsofid(o->flags, F_SCARY);
|
||||
}
|
||||
killflagsofid(o->flags, F_STENCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8885,13 +8935,13 @@ void obdie(object_t *o) {
|
|||
|
||||
if (f->val[2] == B_IFACTIVATED) {
|
||||
if (isactivated(o)) {
|
||||
spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
spellcloud(where, f->val[1], DT_ORTH, cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
|
||||
removeob(o, o->amt);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
spellcloud(where, f->val[1], DT_ORTH, cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
|
||||
removeob(o, o->amt);
|
||||
return;
|
||||
|
@ -10027,7 +10077,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
r = poss[rnd(0,nposs-1)];
|
||||
sprintf(wname, "%s warrior", r->name);
|
||||
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, lf);
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, lf, MT_NOTHING);
|
||||
if (c) {
|
||||
summonmonster(lf, c, R_SPECIFIED, wname, rnd(50,90), B_TRUE);
|
||||
}
|
||||
|
@ -10169,7 +10219,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
}
|
||||
// summon treant
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, lf);
|
||||
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, lf, MT_NOTHING);
|
||||
if (c) {
|
||||
summonmonster(lf, c, R_TREANT, NULL, rnd(50,90), B_TRUE);
|
||||
}
|
||||
|
@ -10433,11 +10483,9 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
msg("%s looks at %s.",buf, obname);
|
||||
}
|
||||
} else if (o->type->id == OT_LOCKHACKER) {
|
||||
char ch;
|
||||
int dir;
|
||||
// ask direction
|
||||
ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
|
||||
dir = chartodir(ch);
|
||||
dir = askdir("Manipulate lock in which direction (- to cancel)", B_TRUE, B_TRUE);
|
||||
if (dir == D_NONE) {
|
||||
clearmsg();
|
||||
return B_TRUE;
|
||||
|
@ -10514,6 +10562,33 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
return B_TRUE;
|
||||
}
|
||||
} // end if ch is a direction
|
||||
} else if (o->type->id == OT_CHEWINGGUM) {
|
||||
int donesomething = B_FALSE;
|
||||
if (!where) {
|
||||
if (isplayer(lf)) msg("There is nothing to use your gum on there!");
|
||||
} else if (where->lf) {
|
||||
if (isplayer(lf)) msg("There is someone in your way!");
|
||||
} else {
|
||||
object_t *o;
|
||||
for (o = where->obpile->first ; o ; o = o->next) {
|
||||
int isopen = B_FALSE;
|
||||
// jammed doors
|
||||
if (isdoor(o, &isopen) && !isopen) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, 1);
|
||||
msg("You stick your gum into the hinges of %s.", obname);
|
||||
addflag(o->flags, F_JAMMED, rnd(5,10), B_TRUE, NA, NULL);
|
||||
taketime(lf, getactspeed(lf));
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (donesomething) {
|
||||
removeob(o, 1);
|
||||
} else {
|
||||
taketime(lf, getactspeed(lf));
|
||||
if (isplayer(lf)) msg("There is nothing to use your gum on there!");
|
||||
}
|
||||
} else if (o->type->id == OT_SPANNER) {
|
||||
int donesomething = B_FALSE;
|
||||
if (!where) {
|
||||
|
@ -10668,7 +10743,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
|
||||
enum RARITY pickrr(int whatfor) {
|
||||
enum RARITY wantrr = RR_FREQUENT;
|
||||
int chance = 2;
|
||||
int chance = 3;
|
||||
int mod = 0;
|
||||
|
||||
if ((gamemode == GM_GAMESTARTED) && hasflag(player->flags, F_EXTRALUCK)) {
|
||||
|
@ -10885,12 +10960,8 @@ int pour(lifeform_t *lf, object_t *o) {
|
|||
} else if (isdoor(dst, NULL)) {
|
||||
msg("Your pour %s all over %s.", obname, dstname);
|
||||
if (o->type->id == OT_POT_OIL) {
|
||||
flag_t *f;
|
||||
// unjam doors
|
||||
f = hasflag(dst->flags, F_JAMMED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
}
|
||||
killflagsofid(dst->flags, F_JAMMED);
|
||||
}
|
||||
} else { // default
|
||||
if (isplayer(lf)) {
|
||||
|
@ -11347,8 +11418,15 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
}
|
||||
i = geteffecttime(20,40,potblessed);
|
||||
|
||||
if (!lfhasflagval(lf, F_INVULNERABLE, B_TRUE, NA, NA, NULL)) {
|
||||
addtempflag(lf->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL, i);
|
||||
if (potblessed == B_CURSED) {
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou feel invulnerable!", getlfcol(lf, CC_VGOOD));
|
||||
// but you don't actually become invulnerable!
|
||||
}
|
||||
} else {
|
||||
if (!lfhasflagval(lf, F_INVULNERABLE, B_TRUE, NA, NA, NULL)) {
|
||||
addtempflag(lf->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OT_POT_LEVITATION:
|
||||
|
@ -13106,14 +13184,14 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif
|
|||
if (f->val[2] == B_IFACTIVATED) {
|
||||
if (isactivated(o)) {
|
||||
if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) {
|
||||
spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
spellcloud(where, f->val[1], DT_ORTH, cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
|
||||
}
|
||||
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
} else {
|
||||
if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) {
|
||||
spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
spellcloud(where, f->val[1], DT_ORTH, cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
|
||||
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
|
||||
}
|
||||
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
|
@ -13443,6 +13521,11 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
}
|
||||
}
|
||||
|
||||
// adjust destination location in case something is in the way.
|
||||
// but DONT modify 'where' yet, as we still want to say (for example)
|
||||
// "the orc throws a knife at you", even if something is in the way.
|
||||
haslof(srcloc, where, LOF_NEED, &newloc);
|
||||
|
||||
// announce it ("xx throws xx" "at yy")
|
||||
if (announcethrow) {
|
||||
if (thrower && isplayer(thrower)) {
|
||||
|
@ -13469,24 +13552,39 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
msg("%s", throwstring);
|
||||
} else if (seen) {
|
||||
char throwstring[BUFLEN];
|
||||
// an object is moving on its own
|
||||
if (o->pile->owner && cansee(player, o->pile->owner)) {
|
||||
char ownername[BUFLEN];
|
||||
getlfname(o->pile->owner, ownername);
|
||||
snprintf(throwstring, BUFLEN, "%s%s %s %s through the air", ownername, getpossessive(ownername),
|
||||
noprefix(obname), (amt == 1) ? "flies" : "fly");
|
||||
} else {
|
||||
// an object is moving on its own
|
||||
snprintf(throwstring, BUFLEN, "%s %s through the air", obname, (amt == 1) ? "flies" : "fly");
|
||||
}
|
||||
if (target && haslos(player, where)) {
|
||||
strcat(throwstring, " toward ");
|
||||
strcat(throwstring, targetname);
|
||||
if (target) {
|
||||
int showtoward = B_FALSE;
|
||||
if (!newloc && haslos(player, where)) {
|
||||
// player can see the destination?.
|
||||
showtoward = B_TRUE;
|
||||
} else if (haslos(player, srcloc)) {
|
||||
// player can see the source..
|
||||
showtoward = B_TRUE;
|
||||
}
|
||||
if (showtoward) {
|
||||
strcat(throwstring, " toward ");
|
||||
strcat(throwstring, targetname);
|
||||
}
|
||||
}
|
||||
strcat(throwstring, ".");
|
||||
msg("%s", throwstring);
|
||||
}
|
||||
}
|
||||
|
||||
// now that announcement is done, adjust the destination if anyone
|
||||
// is in the way.
|
||||
if (newloc) {
|
||||
where = newloc;
|
||||
}
|
||||
//taketime(thrower, SPEED_THROW);
|
||||
|
||||
// special case
|
||||
|
@ -13569,7 +13667,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
radius = o->amt * 2;
|
||||
if (radius > 10) radius = 10;
|
||||
|
||||
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL, B_INCLUDECENTRE);
|
||||
spellcloud(srcloc, radius, DT_ORTH, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL, B_INCLUDECENTRE);
|
||||
} else if (o->type->id == OT_ASHSLEEP) {
|
||||
int radius;
|
||||
char buf[BUFLEN];
|
||||
|
@ -13582,7 +13680,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
radius = o->amt * 2;
|
||||
if (radius > 10) radius = 10;
|
||||
|
||||
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL, B_INCLUDECENTRE);
|
||||
spellcloud(srcloc, radius, DT_ORTH, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL, B_INCLUDECENTRE);
|
||||
} else if (o->type->id == OT_SALT) {
|
||||
int dist;
|
||||
dist = getcelldist(srcloc, where);
|
||||
|
@ -13688,12 +13786,6 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
|
||||
}
|
||||
|
||||
// adjust destination location in case something is in the way.
|
||||
haslof(srcloc, where, LOF_NEED, &newloc);
|
||||
if (newloc) {
|
||||
where = newloc;
|
||||
}
|
||||
|
||||
// ... in case the target cell changed...
|
||||
target = where->lf;
|
||||
if (target && isdead(target)) {
|
||||
|
@ -14964,8 +15056,6 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
|
|||
if (lf) getlfname(lf, lfname);
|
||||
|
||||
temp = findot(oid);
|
||||
|
||||
|
||||
// saving throw?
|
||||
if (temp && lf) {
|
||||
flag_t *f;
|
||||
|
@ -14983,7 +15073,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
|
|||
}
|
||||
// easier to avoid if you're sneaking
|
||||
if (lfhasflag(lf, F_CAREFULMOVE)) mod += 5;
|
||||
mod += getskill(lf, SK_TRAPS);
|
||||
mod += getskill(lf, SK_ENGINEERING);
|
||||
avoided = skillcheck(lf, ct, f->val[2], mod);
|
||||
}
|
||||
}
|
||||
|
@ -14995,6 +15085,11 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
|
|||
f = hasflag(trapob->flags, F_TRAP);
|
||||
if (f) f->val[1] = curtime;
|
||||
}
|
||||
|
||||
if (lf && (getskill(lf, SK_ENGINEERING) == PR_MASTER)) {
|
||||
avoided = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (oid == OT_TRAPWIND) {
|
||||
// can't be dodged
|
||||
|
@ -15111,7 +15206,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s leaps away from a pit!", lfname);
|
||||
}
|
||||
movelf(lf, escapeto);
|
||||
movelf(lf, escapeto, B_TRUE);
|
||||
}
|
||||
}
|
||||
} else if (oid == OT_TRAPALARM) {
|
||||
|
@ -15183,7 +15278,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s leaps out of the way!", lfname);
|
||||
}
|
||||
movelf(lf, escapeto);
|
||||
movelf(lf, escapeto, B_TRUE);
|
||||
}
|
||||
}
|
||||
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
|
||||
|
@ -15823,13 +15918,13 @@ int geteffecttime(int min, int max, enum BLESSTYPE isblessed) {
|
|||
// how long for?
|
||||
switch (isblessed) {
|
||||
case B_BLESSED:
|
||||
howlong = 15;
|
||||
howlong = max;
|
||||
break;
|
||||
case B_CURSED:
|
||||
howlong = 5;
|
||||
howlong = min;
|
||||
break;
|
||||
default: // ie. B_UNCURSED
|
||||
howlong = rnd(5,15);
|
||||
howlong = rnd(min,max);
|
||||
break;
|
||||
}
|
||||
return howlong;
|
||||
|
|
2
save.c
2
save.c
|
@ -518,7 +518,7 @@ map_t *loadmap(FILE *f) {
|
|||
l->x, l->y, l->id);
|
||||
exit(1);
|
||||
}
|
||||
movelf(l, c);
|
||||
movelf(l, c, B_FALSE);
|
||||
//dblog("Moving lf %d to %d,%d\n",l->id, l->x, l->y);
|
||||
}
|
||||
|
||||
|
|
38
shops.c
38
shops.c
|
@ -154,10 +154,11 @@ void shop(lifeform_t *lf, object_t *vm) {
|
|||
int ngiven = 0;
|
||||
flag_t *f;
|
||||
object_t *o;
|
||||
|
||||
strcpy(toptext, "");
|
||||
|
||||
|
||||
taketime(lf, getactspeed(lf));
|
||||
|
||||
if (!isplayer(lf)) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
|
@ -168,6 +169,16 @@ void shop(lifeform_t *lf, object_t *vm) {
|
|||
return;
|
||||
}
|
||||
|
||||
// closed?
|
||||
f = hasflag(vm->flags, F_OPENHOURS);
|
||||
if (f) {
|
||||
int h = -1,m = -1,s = -1;
|
||||
splittime(&h, &m, &s);
|
||||
if (!timeisbetween(h, f->val[0], f->val[1])) {
|
||||
sayphrase(NULL, f->val[2], SV_TALK, hoursto12(f->val[0]), NULL, player);
|
||||
}
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_STENCH)) {
|
||||
msg("\"Pheeew! You're not coming in smelling like that.\"");
|
||||
return;
|
||||
|
@ -990,17 +1001,36 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
|
|||
if (hasflag(money->flags, F_GEM)) {
|
||||
int gemsneeded;
|
||||
char gemname[BUFLEN];
|
||||
int valpergem;
|
||||
int valpergem,amtpaid = 0, change = 0;
|
||||
valpergem = applyshoppricemod(real_getobvalue(money, 1), player, vm, SA_SELL);
|
||||
gemsneeded = value / valpergem;
|
||||
limit(&gemsneeded, 1, NA); // (in case gem is worth more than object)
|
||||
getobname(money, gemname, gemsneeded);
|
||||
// remove enough to pay...
|
||||
// calculate how much change to give...
|
||||
amtpaid = gemsneeded * valpergem;
|
||||
change = amtpaid - value;
|
||||
|
||||
// remove enough gems to pay...
|
||||
removeob(money, gemsneeded);
|
||||
purchasemethod = PM_GEM;
|
||||
|
||||
// announce that we're using a gem
|
||||
msg("You hand over %s.", gemname); more();
|
||||
// also determine whether the player get change
|
||||
if (slev >= PR_ADEPT) {
|
||||
msg("You hand over %s%s.", gemname,
|
||||
(change > 0) ? " and ask for change." : "");
|
||||
more();
|
||||
if (change > 0) {
|
||||
char changebuf[BUFLEN];
|
||||
|
||||
sprintf(changebuf, "%d gold dollars", change);
|
||||
addob(player->pack, changebuf);
|
||||
msg("You receive $%d change.", change); more();
|
||||
}
|
||||
|
||||
} else {
|
||||
msg("You hand over %s.", gemname); more();
|
||||
}
|
||||
} else {
|
||||
givemoney(player, NULL, value);
|
||||
purchasemethod = PM_GOLD;
|
||||
|
|
2
spell.h
2
spell.h
|
@ -36,7 +36,7 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair
|
|||
object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat);
|
||||
void pullobto(object_t *o, lifeform_t *lf);
|
||||
int schoolappearsinbooks(enum SPELLSCHOOL ss);
|
||||
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob, int includecentre);
|
||||
void spellcloud(cell_t *srcloc, int radius, int dirtype, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob, int includecentre);
|
||||
int spellisfromschool(int spellid, enum SPELLSCHOOL school);
|
||||
int spellokformonsters(int spellid);
|
||||
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce);
|
||||
|
|
131
text.c
131
text.c
|
@ -54,6 +54,66 @@ plural_t *addplural(char *singulartext, char *pluraltext, int stopafter) {
|
|||
return a;
|
||||
}
|
||||
|
||||
void addengineeringinfo(lifeform_t *lf, char *buf, cell_t *c) {
|
||||
enum SKILLLEVEL slev;
|
||||
char newbuf[BUFLEN];
|
||||
strcpy(newbuf, "");
|
||||
slev = getskill(lf, SK_ENGINEERING);
|
||||
if (slev >= PR_NOVICE) {
|
||||
int cdiff = NA;
|
||||
int slip = 0;
|
||||
slip = getslipperyness(c, NULL);
|
||||
if (slip > 0) {
|
||||
char tempbuf[BUFLEN];
|
||||
if (strlen(newbuf)) strcat(newbuf, ",");
|
||||
sprintf(tempbuf, "slippery:%d%%",slip);
|
||||
strcat(newbuf, tempbuf);
|
||||
} else if (slip < 0) {
|
||||
if (strlen(newbuf)) strcat(newbuf, ",");
|
||||
char tempbuf[BUFLEN];
|
||||
sprintf(tempbuf, "stable:%d%%",abs(slip));
|
||||
strcat(newbuf, tempbuf);
|
||||
}
|
||||
|
||||
if (c->type->solid) {
|
||||
cdiff = getcellclimbdifficulty(c);
|
||||
}
|
||||
if (cdiff == NA) {
|
||||
object_t *o;
|
||||
o = hasobwithflag(c->obpile, F_CLIMBOBSTACLE);
|
||||
if (o) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_CLIMBOBSTACLE);
|
||||
if (f) { // should always be true
|
||||
cdiff = f->val[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cdiff != NA) {
|
||||
char tempbuf[BUFLEN];
|
||||
if (strlen(newbuf)) strcat(newbuf, ",");
|
||||
sprintf(tempbuf, "climb diff:%d%%",cdiff);
|
||||
strcat(newbuf, tempbuf);
|
||||
}
|
||||
|
||||
}
|
||||
if (slev >= PR_BEGINNER) {
|
||||
if (c->hp != -1) {
|
||||
char tempbuf[BUFLEN];
|
||||
if (strlen(newbuf)) strcat(newbuf, ",");
|
||||
sprintf(tempbuf, "hp:%d",c->hp);
|
||||
strcat(newbuf, tempbuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(newbuf)) {
|
||||
strcat(buf, "(");
|
||||
strcat(buf, newbuf);
|
||||
strcat(buf, ")");
|
||||
}
|
||||
}
|
||||
|
||||
int needan(char *text) {
|
||||
if (isvowel(tolower(text[0]))) {
|
||||
return B_TRUE;
|
||||
|
@ -1145,6 +1205,28 @@ int gethitconferlifetime(char *text, int *min, int *max) {
|
|||
return howlong;
|
||||
}
|
||||
|
||||
char *getjobcatname(enum JOBCATEGORY jc) {
|
||||
switch (jc) {
|
||||
case JC_GENERAL:
|
||||
return "Generalist";
|
||||
case JC_FIGHTER:
|
||||
return "Fighter";
|
||||
case JC_FIGHTERMAGE:
|
||||
return "Fighter/Mage";
|
||||
case JC_FIGHTERTHIEF:
|
||||
return "Fighter/Thief";
|
||||
case JC_FIGHTERRANGED:
|
||||
return "Ranged Fighter";
|
||||
case JC_MAGE:
|
||||
return "Mage";
|
||||
case JC_THIEF:
|
||||
return "Thief";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "None";
|
||||
}
|
||||
|
||||
char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp) {
|
||||
float pct;
|
||||
pct = (int)(((float) dam / (float) maxhp) * 100.0);
|
||||
|
@ -1276,6 +1358,30 @@ char *getpossessive(char *text) {
|
|||
return "'s";
|
||||
}
|
||||
|
||||
char *getdrunkdesc(lifeform_t *lf, flag_t *drunkflag, char *buf) {
|
||||
int agimod, wismod;
|
||||
char agibuf[BUFLEN], wisbuf[BUFLEN], dambuf[BUFLEN];
|
||||
|
||||
strcpy(buf, "");
|
||||
// agi / wis mod
|
||||
agimod = getdrunkattrmod(lf, A_AGI, drunkflag->val[0]);
|
||||
wismod = getdrunkattrmod(lf, A_WIS, drunkflag->val[0]);
|
||||
sprintf(agibuf, "%s%d Agi", (agimod >= 0) ? "+" : "", agimod);
|
||||
sprintf(wisbuf, "%s%d Wis", (wismod >= 0) ? "+" : "", wismod);
|
||||
|
||||
// damage mod
|
||||
if (drunkflag->val[0] == 1) {
|
||||
sprintf(dambuf, "1 damage reduction");
|
||||
} else {
|
||||
sprintf(dambuf, "1-%d damage reduction", drunkflag->val[0]);
|
||||
}
|
||||
|
||||
// full
|
||||
sprintf(buf, "%s, %s, %s, mental immunity", dambuf, agibuf, wisbuf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *getdrunktext(flag_t *drunkflag) {
|
||||
int bracket;
|
||||
bracket = (drunkflag->lifetime / TM_DRUNKTIME) + 1;
|
||||
|
@ -1879,6 +1985,17 @@ char *getweighttext(float weight, char *buf, int shortfmt) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
int hoursto12(int h) {
|
||||
int twelveh;
|
||||
if (h > 12) {
|
||||
twelveh = h - 12;
|
||||
} else {
|
||||
twelveh = h;
|
||||
}
|
||||
if (twelveh == 0) twelveh = 12;
|
||||
return twelveh;
|
||||
}
|
||||
|
||||
char *is(lifeform_t *lf) {
|
||||
if (isplayer(lf)) return "are";
|
||||
else return "is";
|
||||
|
@ -2758,6 +2875,20 @@ int texttospellopts(char *text, ... ) {
|
|||
return nfilled;
|
||||
}
|
||||
|
||||
int timeisbetween(int h, int start, int end) {
|
||||
int hh = start;
|
||||
if (h == hh) return B_TRUE;
|
||||
while (hh != end) {
|
||||
// increment hour being checked
|
||||
if (++hh >= 24) {
|
||||
hh = 0;
|
||||
}
|
||||
// check...
|
||||
if (h == hh) return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
char *you(lifeform_t *lf) {
|
||||
if (isplayer(lf)) {
|
||||
return "You";
|
||||
|
|
5
text.h
5
text.h
|
@ -1,6 +1,7 @@
|
|||
#include "defs.h"
|
||||
|
||||
plural_t *addplural(char *singulartext, char *pluraltext, int stopafter);
|
||||
void addengineeringinfo(lifeform_t *lf, char *buf, cell_t *c);
|
||||
int needan(char *text);
|
||||
char *capitalise(char *text);
|
||||
char *capitaliseall(char *text);
|
||||
|
@ -25,12 +26,14 @@ void getdisttext(cell_t *src, cell_t *dst,char *distbuf, char *distbufapprox, ch
|
|||
char *getfillingname(int nutrition);
|
||||
char *getflagsourcetext(flag_t *f);
|
||||
int gethitconferlifetime(char *text, int *min, int *max);
|
||||
char *getjobcatname(enum JOBCATEGORY jc);
|
||||
char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
|
||||
char *getpctname(int pct);
|
||||
char *getpoisondamverb(enum POISONTYPE ptype);
|
||||
//char *getpoisondesc(enum POISONTYPE ptype);
|
||||
//char *getpoisonname(enum POISONTYPE ptype);
|
||||
char *getpossessive(char *text);
|
||||
char *getdrunkdesc(lifeform_t *lf, flag_t *drunkflag, char *buf);
|
||||
char *getdrunktext(flag_t *drunkflag);
|
||||
char *getilluminationdesc(enum ILLUMINATION il);
|
||||
char *getinjuredbpname(enum BODYPART bp);
|
||||
|
@ -49,6 +52,7 @@ char *gettimetext(char *retbuf);
|
|||
char *gettimetextfuzzy(char *retbuf, int wantpm);
|
||||
char *getwaterdepthname(enum DEPTH d);
|
||||
char *getweighttext(float weight, char *buf, int shortfmt);
|
||||
int hoursto12(int h);
|
||||
char *is(lifeform_t *lf);
|
||||
char *it(lifeform_t *lf);
|
||||
int isvowel(char c);
|
||||
|
@ -82,6 +86,7 @@ int strpixmatch(char *haystack, char *needle);
|
|||
enum VAULTTHING strtovt(char *text);
|
||||
int texttodice(char *text, int *ndice, int *nsides, int *bonus);
|
||||
int texttospellopts(char *text, ... );
|
||||
int timeisbetween(int h, int start, int end);
|
||||
//void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range, char *racestr);
|
||||
char *you(lifeform_t *lf);
|
||||
char *you_l(lifeform_t *lf);
|
||||
|
|
Loading…
Reference in New Issue