- [+] bug: when running, i jumped into deep water!
- [+] instead of evasion skill giving a fixed boost, make it change the evasion bonus due to xp level. * [+] give monsters free moves when you go back onto a level, BEFORE placing the player. - [+] fix dungeon code to eliminate nonlinked rooms - [+] force all vaults to be at least 3 squares away from map edges * [+] implement flood-fill test.
This commit is contained in:
parent
f071b379ca
commit
52f6fd21c3
8
ai.c
8
ai.c
|
@ -528,7 +528,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// reset F_TARGET lifetime to full.
|
||||
if (targetflag) {
|
||||
if (targetflag->id == F_TARGETLF) {
|
||||
targetflag->lifetime = AI_FOLLOWTIME;
|
||||
targetflag->lifetime = DEF_AIFOLLOWTIME;
|
||||
}
|
||||
if (db) dblog(".oO { i can see my target (at %d,%d). might move towards it. }",target->cell->x,target->cell->y);
|
||||
// remember their location
|
||||
|
@ -818,7 +818,7 @@ void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
if (db) dblog(".oO { successfully walked towards f_targetcell. arrived at %d,%d }",lf->cell->x, lf->cell->y);
|
||||
// moved towards it.
|
||||
// reset lifetime
|
||||
f->lifetime = AI_FOLLOWTIME;
|
||||
f->lifetime = DEF_AIFOLLOWTIME;
|
||||
|
||||
// are we there yet?
|
||||
if (lf->cell == c) {
|
||||
|
@ -1382,7 +1382,7 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
if (newtarget) {
|
||||
if (aiattack(lf, newtarget, AI_FOLLOWTIME)) {
|
||||
if (aiattack(lf, newtarget, DEF_AIFOLLOWTIME)) {
|
||||
// failed for some reason. maybe target was feigning
|
||||
// death?
|
||||
} else {
|
||||
|
@ -2030,7 +2030,7 @@ int lookforobs(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
// start walking towards target cell
|
||||
if (aigoto(lf, c, MR_OB, o, AI_FOLLOWTIME)) {
|
||||
if (aigoto(lf, c, MR_OB, o, DEF_AIFOLLOWTIME)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
614
defs.h
614
defs.h
|
@ -8,17 +8,292 @@
|
|||
|
||||
// #define PRACTICETIME 15 // #attempts it takes to learn new weapon skill
|
||||
|
||||
#define WETTIME 10 // how long it takes for things to dry
|
||||
#define DRUNKTIME 10 // how long it takes for alcohol to wear off
|
||||
|
||||
// chances of things happening
|
||||
// Probabilities
|
||||
#define ONEIN_FOUNTAINDRYUP 3
|
||||
#define PCTCH_PILLAR 5
|
||||
|
||||
#define SHOPIDENTPRICE 50 // cost to identify a just-purchased item
|
||||
// Defaults
|
||||
#define DEF_AIFOLLOWTIME (50) // if target lf is out of view
|
||||
// for this many turns, abandon chase
|
||||
#define DEF_ANIMDELAY (1000000 / 50) // 1/100 of a second
|
||||
#define DEF_RESTHEALTIME (3)
|
||||
#define DEF_SCREENW 80
|
||||
#define DEF_SCREENH 24
|
||||
#define DEF_SHOPIDENTPRICE (50) // cost to identify a just-purchased item
|
||||
#define DEF_VAULTMARGIN (3)
|
||||
|
||||
|
||||
// Map building defaults
|
||||
#define DEF_LOOPPCT 95
|
||||
#define DEF_SPARSENESS 20
|
||||
#define DEF_TURNPCT 40
|
||||
#define DEF_WINDOWPCT 5
|
||||
|
||||
// getrandomemptycell() params
|
||||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
#define WE_PORTAL 3
|
||||
#define WE_NOTWALL 4
|
||||
#define WE_NOLF 5
|
||||
|
||||
// Booleans
|
||||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
#define B_VIS (1)
|
||||
#define B_UNKNOWN (0)
|
||||
#define B_NOVIS (-1)
|
||||
#define B_KEEPLOF (-1)
|
||||
#define B_MALE (0)
|
||||
#define B_FEMALE (-1)
|
||||
#define B_MAYCHASE (-1)
|
||||
#define B_NODOORS (0)
|
||||
#define B_DONTKILL (-1)
|
||||
|
||||
//#define B_TEMP (-1)
|
||||
//#define B_PERM (-2)
|
||||
//#define B_NOT (-3)
|
||||
|
||||
#define B_DIEONFAIL (-1)
|
||||
#define B_BLUNTONFAIL (-2)
|
||||
|
||||
#define B_COVETS (-1)
|
||||
#define B_ANY (0)
|
||||
|
||||
#define B_SINGLE (0)
|
||||
#define B_MULTI (-1)
|
||||
#define B_MULTIPLE (-1)
|
||||
|
||||
#define B_NOOBS (0)
|
||||
#define B_WITHOBS (-1)
|
||||
|
||||
#define B_UNKNOWN (0)
|
||||
#define B_KNOWN (-1)
|
||||
#define B_TRIED (1)
|
||||
|
||||
#define B_NOBADMOVES (0)
|
||||
#define B_BADMOVESOK (1)
|
||||
|
||||
#define B_NOSTACK (0)
|
||||
#define B_STACK (-1)
|
||||
#define B_STACKOK (-1)
|
||||
|
||||
#define NOOWNER (NULL)
|
||||
#define NOLOC (NULL)
|
||||
#define NOOB (NULL)
|
||||
|
||||
#define B_NOTSOLID (0)
|
||||
#define B_EMPTY (0)
|
||||
#define B_SOLID (-1)
|
||||
|
||||
#define B_OPAQUE (0)
|
||||
#define B_TRANSPARENT (-1)
|
||||
#define B_TRANS (-1)
|
||||
|
||||
#define B_ALLOWEXPAND (-1)
|
||||
#define B_NOEXPAND (0)
|
||||
|
||||
#define B_IFACTIVATED (-1)
|
||||
|
||||
#define B_BIG (-1)
|
||||
|
||||
// Limits
|
||||
#define MAXCANDIDATES 200
|
||||
#define MAXCHOICES 400
|
||||
#define MAXDEPTH 25 // max dungeon depth
|
||||
#define MAXDIR_ORTH 4
|
||||
#define MAXDIR_COMPASS 8
|
||||
#define MAXFLAGS 500
|
||||
#define MAXHISTORY 20 // max lines of history to keep
|
||||
#define MAX_MAPW 80
|
||||
#define MAX_MAPH 20
|
||||
#define MAXPILEOBS 52
|
||||
#define MAXRANDOMOBCANDIDATES 100
|
||||
#define MAXRANDOMLFCANDIDATES 100
|
||||
#define MAXRETCELLS 80
|
||||
#define MAXSPELLLEV 6
|
||||
#define MAXVISRANGE 10 // max visible range in full light
|
||||
#define MAXVISLIMIT (MAXVISRANGE*8)
|
||||
|
||||
#define MINCLEARINGRADIUS 2
|
||||
#define MAXCLEARINGRADIUS 5
|
||||
|
||||
#define MINROOMS 5
|
||||
#define MAXROOMS 10
|
||||
#define MIN_ROOMH 4
|
||||
#define MIN_ROOMW 4
|
||||
#define MAX_ROOMW (MAX_MAPW / 3)
|
||||
#define MAX_ROOMH (MAX_MAPH / 3)
|
||||
|
||||
// askobject options
|
||||
#define AO_NONE 0
|
||||
#define AO_INCLUDENOTHING 1
|
||||
#define AO_ONLYEQUIPPED 2
|
||||
#define AO_EDIBLE 4
|
||||
#define AO_NOTIDENTIFIED 8
|
||||
#define AO_WEARABLE 16
|
||||
#define AO_OPERABLE 32
|
||||
#define AO_POURABLE 64
|
||||
#define AO_EQUIPPEDNONWEAPON 128
|
||||
#define AO_WEILDABLE 256
|
||||
#define AO_SPECIFIED 512
|
||||
#define AO_READABLE 1024
|
||||
#define AO_ARMOUR 2048
|
||||
#define AO_NOTKNOWN 4096
|
||||
#define AO_DAMAGED 8192
|
||||
#define AO_DRINKABLE 16384
|
||||
|
||||
// askcoords target types
|
||||
#define TT_NONE 0
|
||||
#define TT_MONSTER 1
|
||||
#define TT_OBJECT 2
|
||||
#define TT_DOOR 4
|
||||
#define TT_PLAYER 8
|
||||
#define TT_ALLY 16
|
||||
#define TT_IMPASSABLE 32
|
||||
|
||||
// target requirements
|
||||
#define TR_NONE 0
|
||||
#define TR_NEEDLOS 1
|
||||
#define TR_NEEDLOF 2
|
||||
|
||||
// CONTROLLERS
|
||||
#define C_AI 0
|
||||
#define C_PLAYER 1
|
||||
|
||||
// speeds
|
||||
#define SP_GODLIKE 1
|
||||
#define SP_ULTRAFAST 5
|
||||
#define SP_VERYFAST 10
|
||||
#define SP_FAST 15
|
||||
#define SP_NORMAL 20
|
||||
#define SP_SLOW 25
|
||||
#define SP_VERYSLOW 30
|
||||
#define SP_ULTRASLOW 35
|
||||
#define SP_SLOWEST 40
|
||||
|
||||
#define SPEEDUNIT 5
|
||||
|
||||
// speed settings (lower is faster)
|
||||
#define SPEED_ATTACK SP_NORMAL
|
||||
#define SPEED_DEAD 50
|
||||
#define SPEED_ACTION SP_NORMAL
|
||||
#define SPEED_MOVE SP_NORMAL
|
||||
#define SPEED_DROP SP_FAST
|
||||
#define SPEED_PICKUP SP_FAST
|
||||
#define SPEED_THROW SP_FAST
|
||||
#define SPEED_WAIT SP_NORMAL
|
||||
#define SPEED_READ SP_NORMAL
|
||||
#define SPEED_DRINK SP_FAST
|
||||
|
||||
|
||||
// DIRECTION TYPES
|
||||
#define DT_ORTH 0
|
||||
#define DT_COMPASS 1
|
||||
|
||||
// DIRECTIONS
|
||||
#define D_NONE -1
|
||||
#define D_UNKNOWN -2
|
||||
|
||||
// Orthogonal directions
|
||||
#define D_N 0
|
||||
#define D_E 1
|
||||
#define D_S 2
|
||||
#define D_W 3
|
||||
|
||||
// Compass directions
|
||||
#define DC_N 4
|
||||
#define DC_NE 5
|
||||
#define DC_E 6
|
||||
#define DC_SE 7
|
||||
#define DC_S 8
|
||||
#define DC_SW 9
|
||||
#define DC_W 10
|
||||
#define DC_NW 11
|
||||
|
||||
// altitude directions
|
||||
#define D_UP 12
|
||||
#define D_DOWN 13
|
||||
#define D_IN 14
|
||||
|
||||
#define MAXDIR_MAP 15
|
||||
|
||||
///////////////////////////////////////
|
||||
// STRINGS
|
||||
///////////////////////////////////////
|
||||
// String buffer lengths
|
||||
#define BUFLENTINY 10
|
||||
#define BUFLENSMALL 64
|
||||
#define BUFLEN 128
|
||||
#define BIGBUFLEN 512
|
||||
#define HUGEBUFLEN 1024
|
||||
#define MAXPNAMELEN 12 // max player name length
|
||||
// file i/o
|
||||
#define DATADIR "data"
|
||||
#define MAPDIR "data/maps"
|
||||
#define SAVEDIR "data/save"
|
||||
#define VAULTDIR "vaults"
|
||||
// rank, score, name, job, killer
|
||||
#define HISCOREFORMAT "%-6s%-7s%-14s%-18s%s"
|
||||
|
||||
// game strings
|
||||
#define MORESTRING "--More--"
|
||||
#define MSGMORESTRING "^n--More--"
|
||||
#define SOLDOUTSTRING "--SOLD OUT--"
|
||||
|
||||
// SPECIAL NUMBERS/CONSTANTS
|
||||
#define DUMMYCELLTYPE 0xabcd
|
||||
#define UNLIMITED (-9876)
|
||||
#define ALL (-9875)
|
||||
#define NA (-9874)
|
||||
#define NOBODY (-1)
|
||||
#define ALLCONFERRED (-9873)
|
||||
#define PCT (65432) // must be POSITIVE
|
||||
#define RANDOM (-2610)
|
||||
#define AUTO (-7654)
|
||||
|
||||
// Time periods
|
||||
#define TM_DRUNKTIME (10) // how long it takes for alcohol to wear off
|
||||
#define TM_WETTIME (10) // how long it takes for things to dry
|
||||
#define TM_SCENT (15) // how long scents take to fade
|
||||
#define TM_FOOTPRINT (20) // how long footprints take to fade
|
||||
|
||||
// object conditions for random objects
|
||||
#define RO_NONE 0
|
||||
#define RO_DAMTYPE 1
|
||||
#define RO_OBCLASS 2
|
||||
#define RO_HOLDABLE 3
|
||||
|
||||
// flag lifetimes
|
||||
#define PERMENANT (-9873)
|
||||
#define FROMSPELL (-9863)
|
||||
#define FROMPOISON (-9862)
|
||||
|
||||
// flag lifetimes - external sources (ie. don't kill them)
|
||||
#define FROMEXTERNAL_HIGH (-7000)
|
||||
#define FROMRACE (-7872)
|
||||
#define FROMJOB (-7871)
|
||||
#define FROMOBEQUIP (-7870)
|
||||
#define FROMOBHOLD (-7869)
|
||||
#define FROMOBACTIVATE (-7868)
|
||||
#define FROMMAT (-7867)
|
||||
#define FROMBLESSING (-9866)
|
||||
#define FROMBRAND (-7865)
|
||||
#define FROMOBMOD (-7864)
|
||||
#define FROMSKILL (-7863)
|
||||
#define FROMGODGIFT (-7862)
|
||||
#define FROMEXTERNAL_LOW (-7999)
|
||||
#define LEVABILITYDONE (-8000)
|
||||
|
||||
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known.
|
||||
#define IFACTIVE (-9771) // used by f_prodeuceslight. only does so if object is activated
|
||||
|
||||
// Misc constants
|
||||
#define ANYROOM (-9770)
|
||||
#define FALLTHRU (-8765) // for walkdambp
|
||||
#define TICK_INTERVAL (20)
|
||||
|
||||
|
||||
|
||||
// ncurses colours
|
||||
#define C_NONE (-1)
|
||||
enum COLOUR {
|
||||
|
@ -147,24 +422,6 @@ enum SKILLLEVEL {
|
|||
#define MAXSKILLLEVEL 7
|
||||
|
||||
|
||||
// save/load
|
||||
#define DATADIR "data"
|
||||
#define MAPDIR "data/maps"
|
||||
#define SAVEDIR "data/save"
|
||||
#define VAULTDIR "vaults"
|
||||
#define DUMMYCELLTYPE 0xabcd
|
||||
|
||||
// SPECIAL NUMBERS/CONSTANTS
|
||||
#define UNLIMITED (-9876)
|
||||
#define ALL (-9875)
|
||||
#define NA (-9874)
|
||||
#define NOBODY (-1)
|
||||
#define ALLCONFERRED (-9873)
|
||||
#define PCT (65432) // must be POSITIVE
|
||||
#define RANDOM (-2610)
|
||||
|
||||
#define AUTO (-7654)
|
||||
|
||||
enum GAMEMODE {
|
||||
GM_FIRST,
|
||||
GM_INIT,
|
||||
|
@ -237,76 +494,12 @@ enum SENSE {
|
|||
S_TOUCH,
|
||||
};
|
||||
|
||||
// AI defs
|
||||
|
||||
// if target lf is out of view for this many turns, abandon chase
|
||||
#define AI_FOLLOWTIME (50)
|
||||
|
||||
#define DEFAULTRESTHEALTIME (3)
|
||||
|
||||
|
||||
// object confitions for random objects
|
||||
#define RO_NONE 0
|
||||
#define RO_DAMTYPE 1
|
||||
#define RO_OBCLASS 2
|
||||
#define RO_HOLDABLE 3
|
||||
|
||||
// flag lifetimes
|
||||
#define PERMENANT (-9873)
|
||||
#define FROMSPELL (-9863)
|
||||
#define FROMPOISON (-9862)
|
||||
|
||||
// external sources (ie. don't kill them)
|
||||
#define FROMEXTERNAL_HIGH (-7000)
|
||||
#define FROMRACE (-7872)
|
||||
#define FROMJOB (-7871)
|
||||
#define FROMOBEQUIP (-7870)
|
||||
#define FROMOBHOLD (-7869)
|
||||
#define FROMOBACTIVATE (-7868)
|
||||
#define FROMMAT (-7867)
|
||||
#define FROMBLESSING (-9866)
|
||||
#define FROMBRAND (-7865)
|
||||
#define FROMOBMOD (-7864)
|
||||
#define FROMSKILL (-7863)
|
||||
#define FROMGODGIFT (-7862)
|
||||
#define FROMEXTERNAL_LOW (-7999)
|
||||
|
||||
|
||||
#define LEVABILITYDONE (-8000)
|
||||
|
||||
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known.
|
||||
#define IFACTIVE (-9771) // used by f_prodeuceslight. only does so if object is activated
|
||||
|
||||
enum FLAGCONDITION {
|
||||
FC_NOCONDITION = 0,
|
||||
FC_IFPLAYER,
|
||||
FC_IFMONSTER,
|
||||
};
|
||||
//#define NOCONDITION (0)
|
||||
//#define IFMONSTER (-9769) // used in v2 of f_ifpct job flags
|
||||
//#define IFPLAYER (-9768) // used in v2 of f_ifpct job flags
|
||||
|
||||
#define ANYROOM (-9770)
|
||||
|
||||
#define TICK_INTERVAL (20)
|
||||
|
||||
|
||||
#define SCENTTIME (15)
|
||||
#define FOOTPRINTTIME (20)
|
||||
|
||||
// STRINGS
|
||||
#define BUFLENTINY 10
|
||||
#define BUFLENSMALL 64
|
||||
#define BUFLEN 128
|
||||
#define BIGBUFLEN 512
|
||||
#define HUGEBUFLEN 1024
|
||||
|
||||
#define MAXPNAMELEN 12
|
||||
|
||||
|
||||
#define MORESTRING "--More--"
|
||||
#define MSGMORESTRING "^n--More--"
|
||||
#define SOLDOUTSTRING "--SOLD OUT--"
|
||||
|
||||
enum MSGCHARCOL {
|
||||
CC_VBAD,
|
||||
|
@ -326,100 +519,6 @@ enum MODTYPE {
|
|||
};
|
||||
|
||||
|
||||
// LIMITS
|
||||
|
||||
|
||||
#define DEF_SCREENW 80
|
||||
#define DEF_SCREENH 24
|
||||
|
||||
#define MAXPILEOBS 52
|
||||
|
||||
#define MAXSPELLLEV 6
|
||||
|
||||
#define MAXRETCELLS 80
|
||||
|
||||
#define MAXFLAGS 500
|
||||
|
||||
#define MAXCHOICES 400
|
||||
|
||||
#define MAXDEPTH 25 // max dungeon depth
|
||||
|
||||
#define MAXRANDOMOBCANDIDATES 100
|
||||
#define MAXRANDOMLFCANDIDATES 100
|
||||
#define MAXCANDIDATES 200
|
||||
|
||||
//#define MAX_MAPW 80
|
||||
//#define MAX_MAPH 50
|
||||
#define MAX_MAPW 80
|
||||
#define MAX_MAPH 20
|
||||
|
||||
|
||||
#define MINCLEARINGRADIUS 2
|
||||
#define MAXCLEARINGRADIUS 5
|
||||
|
||||
//#define MAX_MAPROOMS 10
|
||||
|
||||
#define MIN_ROOMH 4
|
||||
#define MIN_ROOMW 4
|
||||
#define MAX_ROOMW (MAX_MAPW / 3)
|
||||
#define MAX_ROOMH (MAX_MAPH / 3)
|
||||
|
||||
#define MAXDIR_ORTH 4
|
||||
#define MAXDIR_COMPASS 8
|
||||
|
||||
#define MAXHISTORY 20 // max lines of history to keep
|
||||
|
||||
// MAP BUILDING
|
||||
#define DEF_TURNPCT 40
|
||||
//#define DEF_SPARSENESS 14
|
||||
#define DEF_SPARSENESS 20
|
||||
//#define DEF_SPARSENESS 0
|
||||
//#define DEF_LOOPPCT 70
|
||||
#define DEF_LOOPPCT 95
|
||||
//#define DEF_LOOPPCT 0
|
||||
#define MINROOMS 5
|
||||
#define MAXROOMS 10
|
||||
#define DEF_WINDOWPCT 5
|
||||
|
||||
//
|
||||
//#define ANIMDELAY (1000000 / 100) // 1/100 of a second
|
||||
#define ANIMDELAY (1000000 / 50) // 1/100 of a second
|
||||
|
||||
#define MAXVISRANGE 10 // max visible range in full light
|
||||
#define MAXVISLIMIT (MAXVISRANGE*8)
|
||||
|
||||
|
||||
// askobject options
|
||||
#define AO_NONE 0
|
||||
#define AO_INCLUDENOTHING 1
|
||||
#define AO_ONLYEQUIPPED 2
|
||||
#define AO_EDIBLE 4
|
||||
#define AO_NOTIDENTIFIED 8
|
||||
#define AO_WEARABLE 16
|
||||
#define AO_OPERABLE 32
|
||||
#define AO_POURABLE 64
|
||||
#define AO_EQUIPPEDNONWEAPON 128
|
||||
#define AO_WEILDABLE 256
|
||||
#define AO_SPECIFIED 512
|
||||
#define AO_READABLE 1024
|
||||
#define AO_ARMOUR 2048
|
||||
#define AO_NOTKNOWN 4096
|
||||
#define AO_DAMAGED 8192
|
||||
#define AO_DRINKABLE 16384
|
||||
|
||||
// askcoords target types
|
||||
#define TT_NONE 0
|
||||
#define TT_MONSTER 1
|
||||
#define TT_OBJECT 2
|
||||
#define TT_DOOR 4
|
||||
#define TT_PLAYER 8
|
||||
#define TT_ALLY 16
|
||||
#define TT_IMPASSABLE 32
|
||||
|
||||
// target requirements
|
||||
#define TR_NONE 0
|
||||
#define TR_NEEDLOS 1
|
||||
#define TR_NEEDLOF 2
|
||||
|
||||
// line of fire args
|
||||
enum LOFTYPE {
|
||||
|
@ -429,74 +528,6 @@ enum LOFTYPE {
|
|||
LOF_NEED = 6, // walls AND lfs block
|
||||
};
|
||||
|
||||
// CONTROLLERS
|
||||
#define C_AI 0
|
||||
#define C_PLAYER 1
|
||||
|
||||
// deafult
|
||||
//#define DEF_HEALTIME 100 // time to heal 1 hp
|
||||
|
||||
// speeds
|
||||
#define SP_GODLIKE 1
|
||||
#define SP_ULTRAFAST 5
|
||||
#define SP_VERYFAST 10
|
||||
#define SP_FAST 15
|
||||
#define SP_NORMAL 20
|
||||
#define SP_SLOW 25
|
||||
#define SP_VERYSLOW 30
|
||||
#define SP_ULTRASLOW 35
|
||||
#define SP_SLOWEST 40
|
||||
|
||||
#define SPEEDUNIT 5
|
||||
|
||||
// speed settings (lower is faster)
|
||||
#define SPEED_ATTACK SP_NORMAL
|
||||
#define SPEED_DEAD 50
|
||||
#define SPEED_ACTION SP_NORMAL
|
||||
#define SPEED_MOVE SP_NORMAL
|
||||
#define SPEED_DROP SP_FAST
|
||||
#define SPEED_PICKUP SP_FAST
|
||||
#define SPEED_THROW SP_FAST
|
||||
#define SPEED_WAIT SP_NORMAL
|
||||
#define SPEED_READ SP_NORMAL
|
||||
#define SPEED_DRINK SP_FAST
|
||||
|
||||
|
||||
// DIRECTION TYPES
|
||||
#define DT_ORTH 0
|
||||
#define DT_COMPASS 1
|
||||
|
||||
// DIRECTIONS
|
||||
|
||||
|
||||
#define D_NONE -1
|
||||
#define D_UNKNOWN -2
|
||||
|
||||
// Orthogonal directions
|
||||
#define D_N 0
|
||||
#define D_E 1
|
||||
#define D_S 2
|
||||
#define D_W 3
|
||||
|
||||
// Compass directions
|
||||
#define DC_N 4
|
||||
#define DC_NE 5
|
||||
#define DC_E 6
|
||||
#define DC_SE 7
|
||||
#define DC_S 8
|
||||
#define DC_SW 9
|
||||
#define DC_W 10
|
||||
#define DC_NW 11
|
||||
|
||||
// altitude directions
|
||||
#define D_UP 12
|
||||
#define D_DOWN 13
|
||||
#define D_IN 14
|
||||
|
||||
#define MAXDIR_MAP 15
|
||||
|
||||
|
||||
|
||||
// Cell types
|
||||
enum CELLTYPE {
|
||||
CT_NONE = 0,
|
||||
|
@ -1486,13 +1517,6 @@ enum DEPTH {
|
|||
DP_NONE = 0,
|
||||
};
|
||||
|
||||
// empty types
|
||||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
#define WE_PORTAL 3
|
||||
#define WE_NOTWALL 4
|
||||
#define WE_NOLF 5
|
||||
|
||||
enum NOISETYPE {
|
||||
N_GETANGRY,
|
||||
N_WALK,
|
||||
|
@ -1608,6 +1632,8 @@ enum FLAG {
|
|||
F_ATTACKABLE, // can attack this with 'A'
|
||||
F_IMPASSABLE, // cannot walk past this if your size is between v0 and v1
|
||||
// (inclusive)
|
||||
F_REALLYIMPASSABLE, // even gaseous form etc won't let you get through
|
||||
// this.
|
||||
F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it
|
||||
F_CAUSESCOUGH, // being in this ob's cell will make you cough unless
|
||||
// immune to gas.
|
||||
|
@ -2354,37 +2380,6 @@ enum PIETYLEV {
|
|||
PL_ECSTATIC = 3,
|
||||
};
|
||||
|
||||
// probabilities
|
||||
//#define CH_DEADENDOB 35
|
||||
//#define CH_EMPTYCELLOB 3
|
||||
#define CH_PILLAR 5
|
||||
|
||||
|
||||
// Booleans
|
||||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
|
||||
#define B_VIS (1)
|
||||
#define B_UNKNOWN (0)
|
||||
#define B_NOVIS (-1)
|
||||
|
||||
#define B_KEEPLOF (-1)
|
||||
|
||||
#define B_MALE (0)
|
||||
#define B_FEMALE (-1)
|
||||
|
||||
#define B_MAYCHASE (-1)
|
||||
|
||||
#define B_NODOORS (0)
|
||||
|
||||
#define B_DONTKILL (-1)
|
||||
|
||||
#define FALLTHRU (-8765)
|
||||
|
||||
//#define B_TEMP (-1)
|
||||
//#define B_PERM (-2)
|
||||
//#define B_NOT (-3)
|
||||
|
||||
enum LIGHTLEV {
|
||||
L_PERMDARK = -1,
|
||||
L_NOTLIT = 0,
|
||||
|
@ -2404,49 +2399,6 @@ enum SPELLTARGET {
|
|||
};
|
||||
|
||||
|
||||
#define B_DIEONFAIL (-1)
|
||||
#define B_BLUNTONFAIL (-2)
|
||||
|
||||
#define B_COVETS (-1)
|
||||
#define B_ANY (0)
|
||||
|
||||
#define B_SINGLE (0)
|
||||
#define B_MULTI (-1)
|
||||
#define B_MULTIPLE (-1)
|
||||
|
||||
#define B_NOOBS (0)
|
||||
#define B_WITHOBS (-1)
|
||||
|
||||
#define B_UNKNOWN (0)
|
||||
#define B_KNOWN (-1)
|
||||
#define B_TRIED (1)
|
||||
|
||||
#define B_NOBADMOVES (0)
|
||||
#define B_BADMOVESOK (1)
|
||||
|
||||
#define B_NOSTACK (0)
|
||||
#define B_STACK (-1)
|
||||
#define B_STACKOK (-1)
|
||||
|
||||
#define NOOWNER (NULL)
|
||||
#define NOLOC (NULL)
|
||||
#define NOOB (NULL)
|
||||
|
||||
#define B_NOTSOLID (0)
|
||||
#define B_EMPTY (0)
|
||||
#define B_SOLID (-1)
|
||||
|
||||
#define B_OPAQUE (0)
|
||||
#define B_TRANSPARENT (-1)
|
||||
#define B_TRANS (-1)
|
||||
|
||||
#define B_ALLOWEXPAND (-1)
|
||||
#define B_NOEXPAND (0)
|
||||
|
||||
#define B_IFACTIVATED (-1)
|
||||
|
||||
#define B_BIG (-1)
|
||||
|
||||
// errors
|
||||
enum ERROR {
|
||||
E_OK = 0,
|
||||
|
@ -2657,6 +2609,7 @@ typedef struct map_s {
|
|||
int nrooms; // how many rooms on this map
|
||||
char *name; // name of this map
|
||||
habitat_t *habitat;
|
||||
long lastplayervisit;
|
||||
unsigned int seed;
|
||||
int w,h; // width/height of this map
|
||||
struct cell_s *cell[MAX_MAPW*MAX_MAPH]; // list of cells in this map
|
||||
|
@ -2747,6 +2700,7 @@ typedef struct cell_s {
|
|||
|
||||
// FOR CONSTRUCTION
|
||||
int visited;
|
||||
int filled;
|
||||
} cell_t;
|
||||
|
||||
typedef struct celltype_s {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
Critical effects:
|
||||
attack.c:
|
||||
update damtypecausescriteffects()
|
||||
update criticalhit()
|
||||
put replacements for similar damage types at the top
|
||||
lf.c:
|
||||
update injure() with special effects for bp_head
|
||||
text.c:
|
||||
update getinjuryname()
|
||||
update getinjurydesc()
|
||||
|
||||
... then implement effects for f_injury bp_xxx dt_xxx
|
2
flag.c
2
flag.c
|
@ -1100,7 +1100,7 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
return;
|
||||
} else {
|
||||
// reset timer
|
||||
f->val[1] = WETTIME;
|
||||
f->val[1] = TM_WETTIME;
|
||||
// TODO: announce
|
||||
}
|
||||
}
|
||||
|
|
56
io.c
56
io.c
|
@ -221,7 +221,7 @@ void anim(cell_t *src, cell_t *dst, char ch, int colour) {
|
|||
//mvwprintw(gamewin, cell->y - viewy, cell->x - viewx, "%c", gl.ch);
|
||||
wmove(gamewin, cell->y - viewy, cell->x - viewx);
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
|
||||
// move to next cell
|
||||
|
@ -279,13 +279,13 @@ void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char c
|
|||
|
||||
if (gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
// show cursor
|
||||
curs_set(1);
|
||||
|
@ -332,13 +332,13 @@ void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colo
|
|||
|
||||
if (gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
// show cursor
|
||||
curs_set(1);
|
||||
|
@ -378,7 +378,7 @@ void animradial(cell_t *src, int radius, char ch, int colour) {
|
|||
|
||||
wrefresh(gamewin);
|
||||
if (drawn) {
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
}
|
||||
// show cursor
|
||||
|
@ -420,7 +420,7 @@ void animradialorth(cell_t *src, int radius, char ch,int colour) {
|
|||
|
||||
wrefresh(gamewin);
|
||||
if (drawn) {
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
}
|
||||
}
|
||||
// show cursor
|
||||
|
@ -453,7 +453,7 @@ void animsky(cell_t *src, char ch, int colour) {
|
|||
drawglyph(&gl, src->x - viewx, y);
|
||||
}
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
usleep(DEF_ANIMDELAY);
|
||||
|
||||
// show cursor
|
||||
curs_set(1);
|
||||
|
@ -4212,7 +4212,7 @@ void docomms(lifeform_t *lf) {
|
|||
} else {
|
||||
// stop attacking all current targets first...
|
||||
killflagsofid(lf->flags, F_TARGETLF);
|
||||
aiattack(lf, lf2, AI_FOLLOWTIME);
|
||||
aiattack(lf, lf2, DEF_AIFOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
|
@ -4220,7 +4220,7 @@ void docomms(lifeform_t *lf) {
|
|||
// find adjacent cell
|
||||
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
aigoto(lf, c, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'd': // donate
|
||||
|
@ -4345,7 +4345,7 @@ void docomms(lifeform_t *lf) {
|
|||
// stop attacking all current targets first...
|
||||
killflagsofid(lf->flags, F_TARGETLF);
|
||||
msg("You say \"Go over there!\" to %s.", lfname);
|
||||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
aigoto(lf, c, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
|
||||
break;
|
||||
case 'j':
|
||||
// charisma check to see if they'll join you.
|
||||
|
@ -4372,19 +4372,19 @@ void docomms(lifeform_t *lf) {
|
|||
msg("You buy %s.", buf);
|
||||
angeramt += 25;
|
||||
// get it identified?
|
||||
if (!isknown(o) && (countmoney(player) >= SHOPIDENTPRICE)) {
|
||||
if (!isknown(o) && (countmoney(player) >= DEF_SHOPIDENTPRICE)) {
|
||||
char buf2[BUFLEN];
|
||||
char ch2;
|
||||
sprintf(buf2, "Pay $%d to identify %s?",(int)SHOPIDENTPRICE, buf);
|
||||
sprintf(buf2, "Pay $%d to identify %s?",(int)DEF_SHOPIDENTPRICE, buf);
|
||||
ch2 = askchar(buf2, "yn","n", B_TRUE);
|
||||
if (ch2 == 'y') {
|
||||
if (givemoney(player, lf, SHOPIDENTPRICE)) {
|
||||
if (givemoney(player, lf, DEF_SHOPIDENTPRICE)) {
|
||||
angeramt += 25;
|
||||
identify(o);
|
||||
real_getobname(o, buf, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness
|
||||
msgnocap("%c - %s",o->letter, buf);
|
||||
} else {
|
||||
msg("You can't afford to pay $%d.", SHOPIDENTPRICE);
|
||||
msg("You can't afford to pay $%d.", DEF_SHOPIDENTPRICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7139,15 +7139,6 @@ void dblog(char *format, ... ) {
|
|||
vsprintf( buf, format, args );
|
||||
va_end(args);
|
||||
|
||||
/*
|
||||
if (gamestarted) {
|
||||
fprintf(logfile, "%s\n", buf);
|
||||
fflush(logfile);
|
||||
} else {
|
||||
printf("%s\n", buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
*/
|
||||
if (logfile) {
|
||||
fprintf(logfile, "%s\n", buf);
|
||||
fflush(logfile);
|
||||
|
@ -7157,6 +7148,23 @@ void dblog(char *format, ... ) {
|
|||
}
|
||||
}
|
||||
|
||||
void dblog_nocr(char *format, ... ) {
|
||||
char buf[HUGEBUFLEN];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf( buf, format, args );
|
||||
va_end(args);
|
||||
|
||||
if (logfile) {
|
||||
fprintf(logfile, "%s", buf);
|
||||
fflush(logfile);
|
||||
} else {
|
||||
fprintf(stdout, "%s", buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// force a '--more--' prompt
|
||||
void more(void) {
|
||||
//msg("^");
|
||||
|
|
1
io.h
1
io.h
|
@ -101,6 +101,7 @@ void msg_real(char *format, ... );
|
|||
int needsbold(enum COLOUR col);
|
||||
void nothinghappens(void);
|
||||
void dblog(char *format, ... );
|
||||
void dblog_nocr(char *format, ... );
|
||||
void redraw(void);
|
||||
void redrawpause(void);
|
||||
void redrawresume(void);
|
||||
|
|
44
lf.c
44
lf.c
|
@ -3199,14 +3199,14 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
|
|||
if (!isplayer(attacker)) return;
|
||||
}
|
||||
|
||||
aiattack(lf, attacker, AI_FOLLOWTIME);
|
||||
aiattack(lf, attacker, DEF_AIFOLLOWTIME);
|
||||
|
||||
// any nearby monsters which will help out?
|
||||
if (getallegiance(lf) != AL_FRIENDLY) {
|
||||
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
||||
if (!isdead(l) && areallies(l,lf)) {
|
||||
if (cansee(l, attacker)) {
|
||||
aiattack(l, attacker, AI_FOLLOWTIME);
|
||||
aiattack(l, attacker, DEF_AIFOLLOWTIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4257,6 +4257,7 @@ int getevasion(lifeform_t *lf) {
|
|||
int ev = 0,i;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags;
|
||||
double level_ev = 0, skillpctmod;
|
||||
|
||||
// no evasion if you can't move!
|
||||
if (isimmobile(lf)) {
|
||||
|
@ -4270,30 +4271,11 @@ int getevasion(lifeform_t *lf) {
|
|||
ev += (f->val[0]);
|
||||
}
|
||||
|
||||
// level based evasion
|
||||
ev += gethitdice(lf);
|
||||
|
||||
// skill based
|
||||
//ev += (getskill(lf, SK_EVASION)*10);
|
||||
ev += (getskill(lf, SK_EVASION)*5);
|
||||
|
||||
// now get object penalties/bonuses
|
||||
/*
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
// armour/weapons must be worn to do anything
|
||||
if (hasflag(o->flags, F_EQUIPPED)) {
|
||||
f = hasflag(o->flags, F_EVASION);
|
||||
if (f) {
|
||||
if (isarmour(o)) {
|
||||
// adjust penalties based on armour skill.
|
||||
ev += adjustarmourpenalty(lf, f->val[0]);
|
||||
} else {
|
||||
ev += (f->val[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// level based evasion (modified by evasion skill)
|
||||
level_ev = gethitdice(lf);
|
||||
skillpctmod = (getskill(lf, SK_EVASION) + 1) * 40;
|
||||
level_ev = pctof(skillpctmod, level_ev);
|
||||
ev += level_ev;
|
||||
|
||||
// adjust for bulky armour/shield
|
||||
getflags(lf->flags, retflag, &nretflags, F_ARMOURPENALTY, F_SHIELDPENALTY, F_NONE);
|
||||
|
@ -4556,7 +4538,7 @@ object_t *getfirearm(lifeform_t *lf) {
|
|||
int getfootprinttime(lifeform_t *lf) {
|
||||
int time;
|
||||
|
||||
time = FOOTPRINTTIME;
|
||||
time = TM_FOOTPRINT;
|
||||
switch (getlfsize(lf)) {
|
||||
case SZ_MINI: time = 1; break;
|
||||
case SZ_TINY: time -= 15; break;
|
||||
|
@ -4842,7 +4824,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
|
|||
f = isdrunk(lf);
|
||||
if (f) {
|
||||
int amt;
|
||||
amt = (f->lifetime/DRUNKTIME)+1;
|
||||
amt = (f->lifetime/TM_DRUNKTIME)+1;
|
||||
if (hasjob(lf, J_PIRATE)) {
|
||||
acc += (10*amt);
|
||||
} else {
|
||||
|
@ -11887,12 +11869,12 @@ void addtrail(lifeform_t *lf, int dir) {
|
|||
scent = hastrailof(lf->cell->obpile, lf, OT_SCENT, &fpflag, NULL);
|
||||
if (scent) {
|
||||
assert(fpflag);
|
||||
fpflag->lifetime = SCENTTIME;
|
||||
fpflag->lifetime = TM_SCENT;
|
||||
} else {
|
||||
char buf[BUFLENTINY];
|
||||
sprintf(buf, "%d", lf->id);
|
||||
scent = addobfast(lf->cell->obpile, OT_SCENT);
|
||||
addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, SCENTTIME);
|
||||
addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, TM_SCENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17602,7 +17584,7 @@ int rest(lifeform_t *lf, int onpurpose) {
|
|||
healtime = ff->val[0];
|
||||
} else {
|
||||
// 3 turns = heal 1 hp
|
||||
healtime = DEFAULTRESTHEALTIME;
|
||||
healtime = DEF_RESTHEALTIME;
|
||||
}
|
||||
|
||||
// modify via restob if resting using 'R'
|
||||
|
|
578
map.c
578
map.c
|
@ -40,6 +40,8 @@ extern enum GAMEMODE gamemode;
|
|||
|
||||
extern int needredraw;
|
||||
|
||||
extern long curtime;
|
||||
|
||||
cell_t *addcell(map_t *m, int x, int y) {
|
||||
cell_t *cell;
|
||||
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
|
||||
|
@ -49,7 +51,6 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell->y = y;
|
||||
cell->habitat = m->habitat;
|
||||
setcelltype(cell, cell->habitat->solidcelltype);
|
||||
cell->visited = B_FALSE;
|
||||
cell->obpile = addobpile(NOOWNER, cell, NOOB);
|
||||
cell->lf = NULL;
|
||||
cell->room = NULL;
|
||||
|
@ -61,6 +62,8 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell->known = B_FALSE;
|
||||
cell->knownglyph.ch = ' ';
|
||||
cell->knownglyph.colour = C_GREY;
|
||||
cell->visited = B_FALSE;
|
||||
cell->filled = B_FALSE;
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
@ -148,6 +151,7 @@ map_t *addmap(void) {
|
|||
a->flags = addflagpile(NULL, NULL);
|
||||
a->beingcreated = B_TRUE;
|
||||
a->habitat = findhabitat(H_DUNGEON); // default!!!
|
||||
a->lastplayervisit = -1;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -1029,6 +1033,67 @@ int dowaterspread(cell_t *c) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void fix_reachability(map_t *m) {
|
||||
int i,keepgoing = B_TRUE, nfixed = 0;
|
||||
int db = B_TRUE;
|
||||
cell_t *c = NULL;
|
||||
if (db) dblog("fix_reachability starting.");
|
||||
// find first non-empty cell
|
||||
for (i = 0; i < m->w * m->h; i++) {
|
||||
if (!m->cell[i]->type->solid) {
|
||||
c = m->cell[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// no empty cells in map?
|
||||
if (!c) return;
|
||||
while (keepgoing) {
|
||||
keepgoing = B_FALSE;
|
||||
// mark all cells as non-filled
|
||||
for (i = 0; i < m->w * m->h; i++) {
|
||||
m->cell[i]->filled = FALSE;
|
||||
}
|
||||
// floodfill
|
||||
floodfill(c);
|
||||
// any remaining non-filled empty cells?
|
||||
for (i = 0; i < m->w * m->h; i++) {
|
||||
if (!m->cell[i]->type->solid && !m->cell[i]->filled) {
|
||||
int nadded = 0;
|
||||
// found an unreachable cell! link it back to a filled cell.
|
||||
if (db) dblog(" found unreachable area at %d,%d. will fix it.",
|
||||
m->cell[i]->x, m->cell[i]->y);
|
||||
|
||||
linkexit(m->cell[i], B_TRUE, &nadded);
|
||||
if (db) dblog(" fixed unreachable area by added %d cells.", nadded);
|
||||
|
||||
|
||||
// now run the test again.
|
||||
// 'c' will be where the next flood will will happen.
|
||||
keepgoing = B_TRUE;
|
||||
c = m->cell[i];
|
||||
nfixed++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db) dblog(" fix_reachability complete. fixed %d unreachable areas.", nfixed);
|
||||
}
|
||||
|
||||
|
||||
void floodfill(cell_t *startcell) {
|
||||
int d;
|
||||
if (startcell && // not off the map
|
||||
!startcell->type->solid && // empty cell
|
||||
!startcell->filled) { // not already filled
|
||||
startcell->filled = B_TRUE;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
floodfill(getcellindir(startcell, d)); // recursive call
|
||||
}
|
||||
}
|
||||
|
||||
cell_t *getcellat(map_t *map, int x, int y) {
|
||||
if (!isonmap(map, x, y)) return NULL;
|
||||
return map->cell[y*map->w + x];
|
||||
|
@ -1310,6 +1375,7 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
cell_t *cell;
|
||||
int sel;
|
||||
int db = B_FALSE;
|
||||
int foundvalid = B_FALSE;
|
||||
|
||||
// init coords list
|
||||
for (y = 1 + ymargin; y < (map->h - ymargin); y++) {
|
||||
|
@ -1377,6 +1443,7 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
if (valid) {
|
||||
if (score < bestscore) {
|
||||
bestscore = score;
|
||||
foundvalid = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
score = 9999;
|
||||
|
@ -1386,12 +1453,16 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
if (db) dblog("cell %d,%d - score %d",x,y,score);
|
||||
}
|
||||
|
||||
// now go through and make a list of all BEST positions
|
||||
nposs = 0;
|
||||
for (i = 0; i < ncoords; i++) {
|
||||
if (coordscore[i] == bestscore) {
|
||||
poss[nposs++] = coord[i];
|
||||
if (foundvalid) {
|
||||
// now go through and make a list of all BEST positions
|
||||
nposs = 0;
|
||||
for (i = 0; i < ncoords; i++) {
|
||||
if (coordscore[i] == bestscore) {
|
||||
poss[nposs++] = coord[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nposs = 0;
|
||||
}
|
||||
|
||||
if (nposs == 0) {
|
||||
|
@ -1652,17 +1723,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
}
|
||||
|
||||
// use sparseness to cut down dead ends
|
||||
for (i = 0; i < sparseness; i++) {
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
cell = getcellat(map, x,y);
|
||||
if (countcellexits(cell) == 1) {
|
||||
// erase this cell
|
||||
setcelltype(cell, CT_WALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
remove_deadends(map, sparseness);
|
||||
|
||||
// introduce loops
|
||||
for (y = 0; y < map->h; y++) {
|
||||
|
@ -1757,6 +1818,8 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
linkexits(map, map->room[i].id);
|
||||
}
|
||||
|
||||
// now clear up dead ends again.
|
||||
remove_deadends(map, sparseness);
|
||||
|
||||
// add staircases.
|
||||
// first dungeon level has 1 up stairs, 3 down.
|
||||
|
@ -1814,7 +1877,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
//dblog("Adding obs to room %d/%d",i+1,numrooms);
|
||||
maxpillars = (roomw[i] / 4) + (roomh[i] / 4);
|
||||
// add pillars first
|
||||
if ((maxpillars > 0) && (rnd(1,100) <= CH_PILLAR)) {
|
||||
if ((maxpillars > 0) && pctchance(PCTCH_PILLAR)) {
|
||||
int n;
|
||||
int numpillars;
|
||||
numpillars = rnd(1,maxpillars);
|
||||
|
@ -1849,7 +1912,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
while (!done) {
|
||||
c = getrandomroomcell(map, i);
|
||||
// if nothing there
|
||||
//if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||
if (c && cellwalkable(NULL, c, NULL)) {
|
||||
|
||||
int obchance;
|
||||
|
@ -1880,9 +1942,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
} // end if !vault
|
||||
} // end foreach room
|
||||
} // end if wantrooms & nrooms>0
|
||||
|
||||
|
||||
if (db) dblog("Finished adding objects.");
|
||||
if (db) dblog("Finished adding stuff to rooms.");
|
||||
|
||||
// now do a border
|
||||
y = 0;
|
||||
|
@ -1906,6 +1966,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
}
|
||||
|
||||
// ensure there are no unreachable areas
|
||||
fix_reachability(map);
|
||||
}
|
||||
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
|
||||
|
@ -2529,7 +2592,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety) {
|
||||
int w,h,x,y;
|
||||
int xmargin = 0,ymargin = 0;
|
||||
int xmargin = DEF_VAULTMARGIN,ymargin = DEF_VAULTMARGIN; // defaults
|
||||
int minx,miny,maxx,maxy;
|
||||
int db = B_FALSE;
|
||||
int rotation = 0;
|
||||
|
@ -2577,7 +2640,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
// forced calcroompos should never fail since it's
|
||||
// allowed to overlap other rooms.
|
||||
dblog("** couldn't make vault room!\n");
|
||||
msg("** ALERT: couldn't make vault room!\n");
|
||||
//msg("** ALERT: couldn't make vault room!\n");
|
||||
return B_TRUE;
|
||||
}
|
||||
maxx = minx + (w-1);
|
||||
|
@ -2633,6 +2696,229 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// link a single cell up to the rest of the map.
|
||||
// make sure it links to an empty cell of a DIFFERENT roomid.
|
||||
// if 'wantfilled' is set, only link to "filled" cells.
|
||||
// return TRUE on failure.
|
||||
int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
||||
int db = B_FALSE;
|
||||
int d, roomid;
|
||||
int poss2[MAXCANDIDATES],nposs2;
|
||||
int dist[MAXDIR_ORTH];
|
||||
int hitsedge[MAXDIR_ORTH];
|
||||
int mindist = 999,maxdist = -1;
|
||||
cell_t *c;
|
||||
|
||||
if (ncellsadded) *ncellsadded = 0;
|
||||
|
||||
if (db) dblog(" calling linkexit() for cell at %d,%d", startcell->x, startcell->y);
|
||||
|
||||
roomid = getroomid(startcell);
|
||||
|
||||
// link it. starting from the door, count the number of cells in
|
||||
// each direction until we hit an empty (walkable) cell which isn't a room.
|
||||
|
||||
// if we hit a cell of this roomid, mark this dir as invalid.
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
dist[d] = 0;
|
||||
hitsedge[d] = B_TRUE;
|
||||
c = getcellindir(startcell, d);
|
||||
while (c) {
|
||||
dist[d]++;
|
||||
if ((roomid >= 0) && getroomid(c) == roomid) { // same room
|
||||
if (wantfilled && c->type->solid) {
|
||||
// EXCEPTION:
|
||||
// if we are calling this function from fix_reachability, then
|
||||
// startcell will actually be a cell _inside_ the room as opposed to
|
||||
// a cell inside the room's walls.
|
||||
// in this case, we ARE allowed to travel through the room's walls.
|
||||
} else {
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
if (db) dblog(" going %s hits same room. invalid.", getdirname(d));
|
||||
break;
|
||||
}
|
||||
} else if (cellwalkable(NULL, c, NULL)) {
|
||||
if (!wantfilled || c->filled) {
|
||||
// walkable and not in this vault. finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
if (db) dblog(" can make %s path (hits empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int perpdir[2],n;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir[0] = d - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = d + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
// is there an adjacent walkable cell in a perpendicular direction
|
||||
// which isn't from the starting room?
|
||||
for (n = 0; n <= 1; n++) {
|
||||
pcell = getcellindir(c, perpdir[n]);
|
||||
if (pcell) {
|
||||
if (((roomid == -1 ) || (getroomid(pcell) != roomid)) &&
|
||||
cellwalkable(NULL, pcell, NULL)) {
|
||||
if (!wantfilled || c->filled) {
|
||||
// finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
if (db) dblog(" can make %s path (hits adjacent empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check next cell
|
||||
c = getcellindir(c, d); // getting the same cell!
|
||||
}
|
||||
if (dist[d] != 999) {
|
||||
if (!hitsedge[d]) {
|
||||
if (dist[d] < mindist) mindist = dist[d];
|
||||
}
|
||||
if (dist[d] > maxdist) maxdist = dist[d];
|
||||
}
|
||||
}
|
||||
|
||||
if (mindist == 999) {
|
||||
cell_t *turncell = NULL,*endcell = NULL;
|
||||
int perpdir[2];
|
||||
int startdir = D_NONE;
|
||||
int turndir = D_NONE;
|
||||
int startdist = 0;
|
||||
// no good directions.
|
||||
if (db) dblog(" No directions lead to valid cells. Trying turns.");
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// find longest distance
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist) {
|
||||
startdir = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(startdir != D_NONE);
|
||||
// figure out perpendicular dirs
|
||||
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
|
||||
if (db) dblog(" Will walk %s (dist %d), checking %s and %s.", getdirname(startdir), maxdist,
|
||||
getdirname(perpdir[0]), getdirname(perpdir[1]));
|
||||
|
||||
// check in startdir
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c && !turncell) {
|
||||
int n;
|
||||
cell_t *c2;
|
||||
startdist++;
|
||||
// check left/right from this door for rooms
|
||||
for (n = 0; n <= 1; n++) {
|
||||
int turndist = 0;
|
||||
c2 = getcellindir(c, perpdir[n]);
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
turndist++;
|
||||
if ((roomid >= 0) && (getroomid(c2) == roomid)) {
|
||||
if (wantfilled && c2->type->solid) {
|
||||
// see EXCEPTION above.
|
||||
} else {
|
||||
// hits same room, not ok.
|
||||
break;
|
||||
}
|
||||
} else if (cellwalkable(NULL, c2, NULL)) {
|
||||
if (!wantfilled || c2->filled) {
|
||||
if (db) dblog(" Got to an empty cell here.");
|
||||
gotsolution = B_TRUE;
|
||||
}
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
|
||||
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
|
||||
for (nn = 0; nn <= 1; nn++) {
|
||||
pcell = getcellindir(c2, perpdir2[nn]);
|
||||
if (pcell) {
|
||||
if ( ((roomid == -1) || (getroomid(pcell) != roomid)) &&
|
||||
cellwalkable(NULL, pcell, NULL)) {
|
||||
if (!wantfilled || pcell->filled) {
|
||||
// finished.
|
||||
if (db) dblog(" Got to an empty cell next to us.");
|
||||
gotsolution = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gotsolution) {
|
||||
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
|
||||
startdist, getdirname(startdir),
|
||||
turndist, getdirname(perpdir[n]));
|
||||
// walkable and not in this roomid. ok!
|
||||
turncell = c;
|
||||
endcell = c2;
|
||||
turndir = perpdir[n];
|
||||
break;
|
||||
}
|
||||
// check next cell
|
||||
c2 = getcellindir(c2, perpdir[n]);
|
||||
}
|
||||
if (turncell) break;
|
||||
}
|
||||
// now keep going in main direction.
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
|
||||
if (turncell) {
|
||||
// make a path up to the turn point.
|
||||
if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir));
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c != turncell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
// clear the corner cell
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir));
|
||||
// now turn and clear up to the next room/empty cell
|
||||
c = getcellindir(c, turndir);
|
||||
while (c != endcell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir);
|
||||
}
|
||||
} else {
|
||||
// give up??
|
||||
if (db) dblog(" Cannot find a way to link up.");
|
||||
return B_TRUE;
|
||||
}
|
||||
} else {
|
||||
int whichway,sel;
|
||||
// now pick the shortest one which doesn't hits the edge
|
||||
// get list of all the minimums and randomly tie-break
|
||||
nposs2 = 0;
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == mindist) {
|
||||
poss2[nposs2++] = d;
|
||||
}
|
||||
}
|
||||
sel = rnd(0,nposs2-1);
|
||||
whichway = poss2[sel];
|
||||
|
||||
// now create a path
|
||||
if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), mindist);
|
||||
c = getcellindir(startcell, whichway);
|
||||
while (c && !cellwalkable(NULL, c, NULL)) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, whichway);
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// make sure exits/doors in a given room link up to the rest of the map.
|
||||
int linkexits(map_t *m, int roomid) {
|
||||
int x,y,i;
|
||||
|
@ -2687,202 +2973,25 @@ int linkexits(map_t *m, int roomid) {
|
|||
// for each door, make sure it links to at least one cell which isn't
|
||||
// part of this room
|
||||
for (i = 0; i < nposs; i++) {
|
||||
int d;
|
||||
int ncorridors = 0;
|
||||
int ncorridors = 0,d;
|
||||
if (db) dblog("linking exit #%d",i);
|
||||
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
c = getcellindir(poss[i], d);
|
||||
if (c && cellwalkable(NULL, c, NULL) && (getroomid(c) != roomid)) {
|
||||
ncorridors++;
|
||||
}
|
||||
}
|
||||
if (db) dblog("Door #%d leads to %d corridors. ",i, ncorridors);
|
||||
if (db) dblog(" This exit leads to %d corridors. ", ncorridors);
|
||||
|
||||
// no corridors?
|
||||
if (ncorridors == 0) {
|
||||
int poss2[MAXCANDIDATES],nposs2;
|
||||
int dist[MAXDIR_ORTH];
|
||||
int hitsedge[MAXDIR_ORTH];
|
||||
int mindist = 999,maxdist = -1;
|
||||
if (db) dblog(" Need to link.");
|
||||
// link it. starting from the door, count the number of cells in
|
||||
// each direction until we hit an empty (walkable) cell which isn't a room.
|
||||
|
||||
// if we hit a cell of this roomid, mark this dir as invalid.
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
dist[d] = 0;
|
||||
hitsedge[d] = B_TRUE;
|
||||
c = getcellindir(poss[i], d);
|
||||
while (c) {
|
||||
dist[d]++;
|
||||
if (getroomid(c) == roomid) {
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
break;
|
||||
} else if (cellwalkable(NULL, c, NULL)) {
|
||||
// walkable and not in this vault. finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
break;
|
||||
} else {
|
||||
int perpdir[2],n;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir[0] = d - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = d + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
// is there an adjacent walkable cell in a perpendicular direction
|
||||
// which isn't from the starting room?
|
||||
for (n = 0; n <= 1; n++) {
|
||||
pcell = getcellindir(c, perpdir[n]);
|
||||
if (pcell) {
|
||||
if ((getroomid(pcell) != roomid) && cellwalkable(NULL, pcell, NULL)) {
|
||||
// finished.
|
||||
hitsedge[d] = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// check next cell
|
||||
c = getcellindir(c, d); // getting the same cell!
|
||||
}
|
||||
if (dist[d] != 999) {
|
||||
if (!hitsedge[d]) {
|
||||
if (dist[d] < mindist) mindist = dist[d];
|
||||
}
|
||||
if (dist[d] > maxdist) maxdist = dist[d];
|
||||
}
|
||||
}
|
||||
|
||||
if (mindist == 999) {
|
||||
cell_t *turncell = NULL,*endcell = NULL;
|
||||
int perpdir[2];
|
||||
int startdir = D_NONE;
|
||||
int turndir = D_NONE;
|
||||
int startdist = 0;
|
||||
// no good directions.
|
||||
if (db) dblog(" No directions lead to rooms. Trying turns.");
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// find longest distance
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist) {
|
||||
startdir = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(startdir != D_NONE);
|
||||
// figure out perpendicular dirs
|
||||
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
|
||||
if (db) dblog(" Will walk %s (dist %d), checking %s and %s.", getdirname(startdir), maxdist,
|
||||
getdirname(perpdir[0]), getdirname(perpdir[1]));
|
||||
|
||||
// check in startdir
|
||||
c = getcellindir(poss[i], startdir);
|
||||
while (c && !turncell) {
|
||||
int n;
|
||||
cell_t *c2;
|
||||
startdist++;
|
||||
// check left/right from this door for rooms
|
||||
for (n = 0; n <= 1; n++) {
|
||||
int turndist = 0;
|
||||
c2 = getcellindir(c, perpdir[n]);
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
turndist++;
|
||||
if (getroomid(c2) == roomid) {
|
||||
// hits same room, not ok.
|
||||
break;
|
||||
} else if (cellwalkable(NULL, c2, NULL)) {
|
||||
if (db) dblog(" Got to an empty cell here.");
|
||||
gotsolution = B_TRUE;
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
|
||||
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
|
||||
for (nn = 0; nn <= 1; nn++) {
|
||||
pcell = getcellindir(c2, perpdir2[nn]);
|
||||
if (pcell) {
|
||||
if ((getroomid(pcell) != roomid) &&
|
||||
cellwalkable(NULL, pcell, NULL)) {
|
||||
// finished.
|
||||
if (db) dblog(" Got to an empty cell next to us.");
|
||||
gotsolution = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gotsolution) {
|
||||
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
|
||||
startdist, getdirname(startdir),
|
||||
turndist, getdirname(perpdir[n]));
|
||||
// walkable and not in this roomid. ok!
|
||||
turncell = c;
|
||||
endcell = c2;
|
||||
turndir = perpdir[n];
|
||||
break;
|
||||
}
|
||||
// check next cell
|
||||
c2 = getcellindir(c2, perpdir[n]);
|
||||
}
|
||||
if (turncell) break;
|
||||
}
|
||||
// now keep going in main direction.
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
|
||||
if (turncell) {
|
||||
// make a path up to the turn point.
|
||||
if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir));
|
||||
nadded++;
|
||||
c = getcellindir(poss[i], startdir);
|
||||
while (c != turncell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
// clear the corner cell
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir));
|
||||
// now turn and clear up to the next room/empty cell
|
||||
c = getcellindir(c, turndir);
|
||||
while (c != endcell) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
c = getcellindir(c, turndir);
|
||||
}
|
||||
} else {
|
||||
// give up??
|
||||
if (db) dblog(" Cannot find a way to link up.");
|
||||
}
|
||||
} else {
|
||||
int whichway,sel;
|
||||
// now pick the shortest one which hits the edge
|
||||
// get list of all the minimums and randomly tie-break
|
||||
nposs2 = 0;
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == mindist) {
|
||||
poss2[nposs2++] = d;
|
||||
}
|
||||
}
|
||||
sel = rnd(0,nposs2-1);
|
||||
whichway = poss2[sel];
|
||||
|
||||
// now create a path
|
||||
if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), mindist);
|
||||
nadded++;
|
||||
c = getcellindir(poss[i], whichway);
|
||||
while (c && !cellwalkable(NULL, c, NULL)) {
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
c = getcellindir(c, whichway);
|
||||
}
|
||||
}
|
||||
} // end if ncorridors = 0
|
||||
nadded += linkexit(poss[i], B_FALSE, NULL);
|
||||
}
|
||||
} // end for each door
|
||||
if (db) dblog("linkexits complete.");
|
||||
|
||||
if (db) dblog("linkexits complete (%d added).", nadded);
|
||||
return nadded;
|
||||
}
|
||||
|
||||
|
@ -3075,13 +3184,27 @@ int dirtoy(int dt, int dir) {
|
|||
void dumpmap(map_t *map) {
|
||||
int x,y;
|
||||
cell_t *cell;
|
||||
char ch;
|
||||
printf("dump of map '%s' (%d x %d):\n",map->name, map->w, map->h);
|
||||
|
||||
// top reference row
|
||||
dblog_nocr(" ");
|
||||
for (x = 0; x < map->w; x++) {
|
||||
dblog_nocr("%d",x % 10);
|
||||
}
|
||||
dblog_nocr("\n");
|
||||
|
||||
for (y = 0; y < map->h; y++) {
|
||||
dblog_nocr("%d",y % 10);
|
||||
for (x = 0; x < map->w; x++) {
|
||||
cell = getcellat(map, x, y);
|
||||
printf("%c",cell->type->glyph.ch);
|
||||
ch = cell->type->glyph.ch;
|
||||
if ((ch == '.') && cell->filled) {
|
||||
ch = 'o';
|
||||
}
|
||||
dblog_nocr("%c",ch);
|
||||
}
|
||||
printf("\n");
|
||||
dblog_nocr("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3258,7 +3381,6 @@ cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
|||
cell_t *selection = NULL;
|
||||
cell_t *bestcell = NULL;
|
||||
int closest = 999;
|
||||
// oooooo TODO handle side being diagonal
|
||||
switch (side) {
|
||||
case D_N:
|
||||
case DC_N:
|
||||
|
@ -4576,6 +4698,16 @@ void mapentereffects(map_t *m) {
|
|||
addflag(lf->flags, F_STAYINROOM, getroomid(c), B_MAYCHASE, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// monsters on the new level now get a bunch of turns to simulate them moving about when the player wasn't there.
|
||||
if (m->lastplayervisit != -1) {
|
||||
int nturns;
|
||||
nturns = (curtime - m->lastplayervisit) / TICK_INTERVAL;
|
||||
//nturns *= countlfs(m);
|
||||
for (i = 0; i < nturns; i++) {
|
||||
donextturn(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob) {
|
||||
|
@ -4624,6 +4756,28 @@ enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob) {
|
|||
return R_NONE;
|
||||
}
|
||||
|
||||
// returns # of dead ends removed.
|
||||
int remove_deadends(map_t *m, int howmuch) {
|
||||
enum CELLTYPE solidcell;
|
||||
int i,n,count = 0;
|
||||
|
||||
solidcell = m->habitat->solidcelltype;
|
||||
|
||||
for (i = 0; i < howmuch; i++) {
|
||||
for (n = 0; n < m->w * m->h; n++) {
|
||||
cell_t *c;
|
||||
c = m->cell[n];
|
||||
if (countcellexits(c) == 1) {
|
||||
// erase this cell
|
||||
setcelltype(c, solidcell);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void setcellknown(cell_t *cell, int forcelev) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
|
|
5
map.h
5
map.h
|
@ -15,6 +15,9 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
void clearcell(cell_t *c);
|
||||
int dowaterspread(cell_t *c);
|
||||
void fix_reachability(map_t *m);
|
||||
int fix_unreachable_cell(cell_t *badcell);
|
||||
void floodfill(cell_t *startcell);
|
||||
cell_t *getcellat(map_t *map, int x, int y);
|
||||
int getcelldist(cell_t *src, cell_t *dst);
|
||||
int getcelldistorth(cell_t *src, cell_t *dst);
|
||||
|
@ -106,6 +109,7 @@ int isonmap(map_t *map, int x, int y);
|
|||
int isoutdoors(map_t *m);
|
||||
int isroom(cell_t *c);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
int linkexit(cell_t *c, int wantfilled, int *ncellsadded);
|
||||
int linkexits(map_t *m, int roomid);
|
||||
int linkholes(map_t *map);
|
||||
int linkstairs(object_t *o, object_t *o2);
|
||||
|
@ -114,6 +118,7 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
|||
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||
void mapentereffects(map_t *m);
|
||||
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob);
|
||||
int remove_deadends(map_t *m, int howmuch);
|
||||
void setcellknown(cell_t *cell, int forcelev);
|
||||
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
|
||||
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
||||
|
|
82
move.c
82
move.c
|
@ -31,6 +31,8 @@ extern void *rdata;
|
|||
extern flag_t *retflag[];
|
||||
extern int nretflags;
|
||||
|
||||
extern long curtime;
|
||||
|
||||
extern WINDOW *gamewin, *msgwin;
|
||||
|
||||
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||
|
@ -148,7 +150,7 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
|
|||
// onlyifknown = true means "check for _known_ dangerous objects"
|
||||
// onlyifknown = false means "check for _any dangerous objects, doesn't matter if we know about them"
|
||||
int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *error) {
|
||||
enum ATTRBRACKET iq;
|
||||
enum ATTRBRACKET wis;
|
||||
int include_nonobvious = B_FALSE;
|
||||
flag_t *f;
|
||||
object_t *o;
|
||||
|
@ -177,7 +179,6 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (onlyifknown && !canseeob(lf, o)) continue;
|
||||
if (hasflag(o->flags, F_TRAP)) {
|
||||
|
@ -239,8 +240,8 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
if (!onlyifknown) {
|
||||
include_nonobvious = B_TRUE;
|
||||
} else {
|
||||
iq = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
if ((iq >= AT_AVERAGE) && haslos(lf, cell)) {
|
||||
wis = getattrbracket(getattr(lf, A_WIS), A_WIS, NULL);
|
||||
if ((wis >= AT_AVERAGE) && haslos(lf, cell)) {
|
||||
if (!lfhasflag(lf, F_UNDEAD)) {
|
||||
include_nonobvious = B_TRUE;
|
||||
}
|
||||
|
@ -311,7 +312,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
if ((mid == MT_GAS) ||
|
||||
(mid == MT_SLIME)) {
|
||||
// ok
|
||||
} else if (lfhasflag(lf, F_NONCORPOREAL)) {
|
||||
} else if (lfhasflag(lf, F_NONCORPOREAL) && !hasflag(o->flags, F_REALLYIMPASSABLE)) {
|
||||
// ok but still set error
|
||||
*error = E_OBINWAY;
|
||||
} else {
|
||||
|
@ -945,9 +946,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
|
||||
if (newcell->map != lf->cell->map) {
|
||||
changedlev = B_TRUE;
|
||||
if (isplayer(lf)) {
|
||||
// remember the time which we exitted this map.
|
||||
lf->cell->map->lastplayervisit = curtime;
|
||||
}
|
||||
}
|
||||
|
||||
// update current cell + room id
|
||||
// remember current cell + room id
|
||||
prespeed = getmovespeed(lf);
|
||||
preroom = getroomid(lf->cell);
|
||||
v = getcellvault(lf->cell);
|
||||
|
@ -960,6 +965,25 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
prewater = B_TRUE;
|
||||
}
|
||||
|
||||
// special effects when the player moves to a new map
|
||||
if (changedlev && isplayer(lf)) {
|
||||
object_t *o;
|
||||
long barrierid = -1;
|
||||
// mapentereffects will give all monster on the new map
|
||||
// a bunch of turns to simulate time passing while the player
|
||||
// was away. to prevent them from blocking off the staircase cell
|
||||
// where the player is about to arrive, place a magic barrier over it.
|
||||
o = addobfast(newcell->obpile, OT_MAGICBARRIER);
|
||||
if (o) barrierid = o->id;
|
||||
|
||||
mapentereffects(newcell->map);
|
||||
|
||||
// now remove the barrier
|
||||
o = hasobid(newcell->obpile, barrierid);
|
||||
if (o) killob(o);
|
||||
}
|
||||
|
||||
|
||||
// move out...
|
||||
lf->cell->lf = NULL;
|
||||
|
||||
|
@ -992,13 +1016,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// update new cell
|
||||
newcell->lf = lf;
|
||||
|
||||
/*
|
||||
// update light
|
||||
if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
|
||||
calclight(lf->cell->map);
|
||||
precalclos(lf);
|
||||
}
|
||||
*/
|
||||
// update light
|
||||
if (lfproduceslight(lf)) {
|
||||
calclight(lf->cell->map);
|
||||
|
@ -1009,11 +1026,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
// special effects when the player moves to a new map
|
||||
if (changedlev && isplayer(lf)) {
|
||||
mapentereffects(newcell->map);
|
||||
}
|
||||
|
||||
didmsg = moveeffects(lf);
|
||||
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
@ -1339,7 +1351,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
if (getlfmaterial(lf) == MT_GAS) {
|
||||
char obname[BUFLEN];
|
||||
for (o = newcell->obpile->first ; o ; o = o->next) {
|
||||
if (isimpassableob(o, lf)) {
|
||||
if (isimpassableob(o, lf) && !hasflag(o->flags, F_REALLYIMPASSABLE)) {
|
||||
getobname(o, obname, o->amt);
|
||||
if (isplayer(lf)) {
|
||||
msg("You seep around %s.", obname);
|
||||
|
@ -2087,7 +2099,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
f = isdrunk(lf);
|
||||
if (f) {
|
||||
if (!hasjob(lf, J_PIRATE)) {
|
||||
if (rnd(1,6) <= ((f->lifetime/DRUNKTIME)+1)) {
|
||||
if (rnd(1,6) <= ((f->lifetime/TM_DRUNKTIME)+1)) {
|
||||
// randomize move
|
||||
dir = rnd(DC_N, DC_NW);
|
||||
drunk = B_TRUE; // ie. you can walk into walls now.
|
||||
|
@ -2099,22 +2111,20 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
|
||||
if (isplayer(lf) && !lfhasflag(lf, F_SNEAK)) {
|
||||
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
|
||||
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) {
|
||||
char ques[BUFLEN];
|
||||
char ch;
|
||||
if ((errcode == E_AVOIDOB) && rdata) {
|
||||
char obname[BUFLEN];
|
||||
object_t *avoidob;
|
||||
avoidob = (object_t *)rdata;
|
||||
getobname(avoidob, obname, avoidob->amt);
|
||||
sprintf(ques, "Really %s into %s?", getmoveverb(lf), obname);
|
||||
} else {
|
||||
sprintf(ques, "Really %s there?", getmoveverb(lf));
|
||||
}
|
||||
ch = askchar(ques, "yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
return B_TRUE;
|
||||
}
|
||||
char ques[BUFLEN];
|
||||
char ch;
|
||||
if ((errcode == E_AVOIDOB) && rdata) {
|
||||
char obname[BUFLEN];
|
||||
object_t *avoidob;
|
||||
avoidob = (object_t *)rdata;
|
||||
getobname(avoidob, obname, avoidob->amt);
|
||||
sprintf(ques, "Really %s into %s?", getmoveverb(lf), obname);
|
||||
} else {
|
||||
sprintf(ques, "Really %s there?", getmoveverb(lf));
|
||||
}
|
||||
ch = askchar(ques, "yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
325
nexus.c
325
nexus.c
|
@ -375,22 +375,17 @@ int main(int argc, char **argv) {
|
|||
needredraw = B_FALSE;
|
||||
numdraws = 0;
|
||||
|
||||
// someone has a turn - this will then call taketime -> timehappens();
|
||||
// someone has a turn - this will then call taketime
|
||||
donextturn(curmap);
|
||||
|
||||
// update lifeform structue to figure out who goes next
|
||||
//timehappens(curmap);
|
||||
|
||||
// show level (if required)
|
||||
//if (haslos(player, curmap->lf->cell)) {
|
||||
drawscreen();
|
||||
|
||||
//dblog("**** END of turn, numdraws = %d", numdraws);
|
||||
|
||||
|
||||
// check end of game
|
||||
checkendgame();
|
||||
|
||||
}
|
||||
|
||||
// identify all objects
|
||||
|
@ -559,143 +554,154 @@ void donextturn(map_t *map) {
|
|||
oldpmap = player->cell->map;
|
||||
|
||||
who = map->lf;
|
||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||
|
||||
if (who) {
|
||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||
|
||||
|
||||
assert(who->timespent == 0);
|
||||
assert(who->timespent == 0);
|
||||
|
||||
turneffectslf(who);
|
||||
turneffectslf(who);
|
||||
|
||||
// calculate light
|
||||
calclight(map);
|
||||
// pre-calculate line of sight for this lifeform
|
||||
precalclos(who);
|
||||
// calculate light
|
||||
calclight(map);
|
||||
// pre-calculate line of sight for this lifeform
|
||||
precalclos(who);
|
||||
|
||||
/*
|
||||
if (isplayer(who) || cansee(player, who)) {
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
}
|
||||
*/
|
||||
// update gun targets
|
||||
autotarget(who);
|
||||
|
||||
// update gun targets
|
||||
autotarget(who);
|
||||
// keep looping until they actually do something or are dead!
|
||||
while (who->timespent == 0) {
|
||||
if (isdead(who)) {
|
||||
// skip turn
|
||||
taketime(who, SPEED_DEAD);
|
||||
} else {
|
||||
// do we need to run away from something?
|
||||
if (!flee(who)) {
|
||||
int donormalmove = B_TRUE;
|
||||
flag_t *f;
|
||||
|
||||
// casting a spell?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_CASTINGSPELL);
|
||||
if (f) {
|
||||
donormalmove = B_FALSE;
|
||||
|
||||
f->val[2]--;
|
||||
if (f->val[2] <= 0) {
|
||||
char *p;
|
||||
char buf[BUFLEN];
|
||||
int lfid,mapid,x,y,power;
|
||||
long obid;
|
||||
lifeform_t *targlf;
|
||||
object_t *targob;
|
||||
cell_t *targcell;
|
||||
map_t *targmap;
|
||||
enum OBTYPE sid;
|
||||
|
||||
sid = f->val[0];
|
||||
power = f->val[1];
|
||||
|
||||
|
||||
// keep looping until they actually do something or are dead!
|
||||
while (who->timespent == 0) {
|
||||
if (isdead(who)) {
|
||||
// skip turn
|
||||
taketime(who, SPEED_DEAD);
|
||||
} else {
|
||||
// do we need to run away from something?
|
||||
if (!flee(who)) {
|
||||
int donormalmove = B_TRUE;
|
||||
flag_t *f;
|
||||
// finished!
|
||||
p = f->text;
|
||||
p = readuntil(buf, p, ';');
|
||||
lfid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
obid = atol(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
mapid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
x = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
y = atoi(p);
|
||||
|
||||
// casting a spell?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_CASTINGSPELL);
|
||||
if (f) {
|
||||
donormalmove = B_FALSE;
|
||||
|
||||
f->val[2]--;
|
||||
if (f->val[2] <= 0) {
|
||||
char *p;
|
||||
char buf[BUFLEN];
|
||||
int lfid,mapid,x,y,power;
|
||||
long obid;
|
||||
lifeform_t *targlf;
|
||||
object_t *targob;
|
||||
cell_t *targcell;
|
||||
map_t *targmap;
|
||||
enum OBTYPE sid;
|
||||
|
||||
sid = f->val[0];
|
||||
power = f->val[1];
|
||||
|
||||
|
||||
// finished!
|
||||
p = f->text;
|
||||
p = readuntil(buf, p, ';');
|
||||
lfid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
obid = atol(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
mapid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
x = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
y = atoi(p);
|
||||
|
||||
if (lfid >= 0) {
|
||||
targlf = findlf(NULL, lfid);
|
||||
} else {
|
||||
targlf = NULL;
|
||||
}
|
||||
if (obid >= 0) {
|
||||
targob = findobidinmap(who->cell->map, obid);
|
||||
} else {
|
||||
targob = NULL;
|
||||
}
|
||||
if (mapid >= 0) {
|
||||
targmap = findmap(mapid);
|
||||
targcell = getcellat(targmap, x, y);
|
||||
}
|
||||
taketime(who, getspellspeed(who));
|
||||
dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE);
|
||||
killflagsofid(who->flags, F_CASTINGSPELL);
|
||||
} else {
|
||||
if (isplayer(who)) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(f->val[0]);
|
||||
msg("You continue casting %s.", sp->name);
|
||||
} else if (cansee(player, who)) {
|
||||
flag_t *f2;
|
||||
char lfname[BUFLEN];
|
||||
// still going...
|
||||
getlfname(who, lfname);
|
||||
f2 = lfhasflag(who,F_SPELLCASTTEXT);
|
||||
if (f2 && strlen(f2->text)) {
|
||||
msg("%s %s.", lfname, f2->text);
|
||||
if (lfid >= 0) {
|
||||
targlf = findlf(NULL, lfid);
|
||||
} else {
|
||||
msg("%s continues casting a spell.", lfname);
|
||||
targlf = NULL;
|
||||
}
|
||||
if (obid >= 0) {
|
||||
targob = findobidinmap(who->cell->map, obid);
|
||||
} else {
|
||||
targob = NULL;
|
||||
}
|
||||
if (mapid >= 0) {
|
||||
targmap = findmap(mapid);
|
||||
targcell = getcellat(targmap, x, y);
|
||||
}
|
||||
taketime(who, getspellspeed(who));
|
||||
dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE);
|
||||
killflagsofid(who->flags, F_CASTINGSPELL);
|
||||
} else {
|
||||
if (isplayer(who)) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(f->val[0]);
|
||||
msg("You continue casting %s.", sp->name);
|
||||
} else if (cansee(player, who)) {
|
||||
flag_t *f2;
|
||||
char lfname[BUFLEN];
|
||||
// still going...
|
||||
getlfname(who, lfname);
|
||||
f2 = lfhasflag(who,F_SPELLCASTTEXT);
|
||||
if (f2 && strlen(f2->text)) {
|
||||
msg("%s %s.", lfname, f2->text);
|
||||
} else {
|
||||
msg("%s continues casting a spell.", lfname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eating?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_EATING);
|
||||
if (f) {
|
||||
object_t *o;
|
||||
o = findobbyid(who->pack, atol(f->text));
|
||||
if (!o) {
|
||||
o = findobidinmap(who->cell->map, atol(f->text));
|
||||
}
|
||||
if (o && caneat(who, o) && (getoblocation(o) == who->cell)) {
|
||||
eat(who,o);
|
||||
donormalmove = B_FALSE;
|
||||
} else {
|
||||
killflag(f);
|
||||
// eating?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_EATING);
|
||||
if (f) {
|
||||
object_t *o;
|
||||
o = findobbyid(who->pack, atol(f->text));
|
||||
if (!o) {
|
||||
o = findobidinmap(who->cell->map, atol(f->text));
|
||||
}
|
||||
if (o && caneat(who, o) && (getoblocation(o) == who->cell)) {
|
||||
eat(who,o);
|
||||
donormalmove = B_FALSE;
|
||||
} else {
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// resting?
|
||||
if (donormalmove) {
|
||||
f = isresting(who);
|
||||
if (!f) {
|
||||
f = lfhasflag(who, F_TRAINING);
|
||||
// resting?
|
||||
if (donormalmove) {
|
||||
f = isresting(who);
|
||||
if (!f) {
|
||||
f = lfhasflag(who, F_TRAINING);
|
||||
}
|
||||
if (f) {
|
||||
// check for interrupt of resting...
|
||||
if (isplayer(who) && checkforkey()) {
|
||||
msg("Stopped %s.",(f->id == F_TRAINING) ? "training" : "resting");
|
||||
killflag(f);
|
||||
} else {
|
||||
if (isplayer(who)) {
|
||||
if (++who->turnsskipped >= 10) {
|
||||
//msg("Time passes...");
|
||||
msg(".");
|
||||
who->turnsskipped = 0;
|
||||
}
|
||||
}
|
||||
rest(who, B_TRUE);
|
||||
donormalmove = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
// check for interrupt of resting...
|
||||
if (isplayer(who) && checkforkey()) {
|
||||
msg("Stopped %s.",(f->id == F_TRAINING) ? "training" : "resting");
|
||||
killflag(f);
|
||||
} else {
|
||||
|
||||
|
||||
if (donormalmove) {
|
||||
// paralyzed etc?
|
||||
if (isimmobile(who)) {
|
||||
if (isplayer(who)) {
|
||||
if (++who->turnsskipped >= 10) {
|
||||
//msg("Time passes...");
|
||||
|
@ -703,54 +709,34 @@ void donextturn(map_t *map) {
|
|||
who->turnsskipped = 0;
|
||||
}
|
||||
}
|
||||
rest(who, B_TRUE);
|
||||
rest(who, B_FALSE);
|
||||
donormalmove = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (donormalmove) {
|
||||
// paralyzed etc?
|
||||
if (isimmobile(who)) {
|
||||
if (isplayer(who)) {
|
||||
if (++who->turnsskipped >= 10) {
|
||||
//msg("Time passes...");
|
||||
msg(".");
|
||||
who->turnsskipped = 0;
|
||||
}
|
||||
}
|
||||
rest(who, B_FALSE);
|
||||
donormalmove = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (donormalmove) {
|
||||
if (isplayer(who)) {
|
||||
drawcursor();
|
||||
// find out what player wants to do
|
||||
handleinput();
|
||||
} else {
|
||||
//char lfname[BUFLEN];
|
||||
//char buf[BUFLEN];
|
||||
// do ai move
|
||||
//real_getlfname(who, lfname, B_FALSE);
|
||||
//sprintf(buf, "aimove %s",lfname);
|
||||
//dbtimestart(buf);
|
||||
aiturn(who);
|
||||
//dbtimeend(buf);
|
||||
if (donormalmove) {
|
||||
if (isplayer(who)) {
|
||||
drawcursor();
|
||||
// find out what player wants to do
|
||||
handleinput();
|
||||
} else {
|
||||
//char lfname[BUFLEN];
|
||||
//char buf[BUFLEN];
|
||||
// do ai move
|
||||
//real_getlfname(who, lfname, B_FALSE);
|
||||
//sprintf(buf, "aimove %s",lfname);
|
||||
//dbtimestart(buf);
|
||||
aiturn(who);
|
||||
//dbtimeend(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasflag(player->flags, F_ASLEEP)) {
|
||||
needredraw = B_FALSE;
|
||||
/*
|
||||
} else if (isdead(who) || cansee(player, who)) {
|
||||
needredraw = B_TRUE;
|
||||
*/
|
||||
if (hasflag(player->flags, F_ASLEEP)) {
|
||||
needredraw = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// check for death etc
|
||||
|
@ -764,7 +750,8 @@ void donextturn(map_t *map) {
|
|||
// note: can't use 'who->' below since 'who' might have died
|
||||
// and been de-alloced during checkdeath() above if they
|
||||
// died.
|
||||
timeeffectsworld(player->cell->map);
|
||||
//timeeffectsworld(player->cell->map);
|
||||
timeeffectsworld(map, B_TRUE);
|
||||
|
||||
// the previous call to timeeffectsworld might cause the player to
|
||||
// change levels (ie. falling down through one or more pits).
|
||||
|
@ -773,7 +760,7 @@ void donextturn(map_t *map) {
|
|||
// values don't get out of whack.
|
||||
while (player->cell->map != oldpmap) {
|
||||
oldpmap = player->cell->map;
|
||||
timeeffectsworld(player->cell->map);
|
||||
timeeffectsworld(player->cell->map, B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1412,7 @@ void sortcommands(void) {
|
|||
|
||||
|
||||
|
||||
void timeeffectsworld(map_t *map) {
|
||||
void timeeffectsworld(map_t *map, int updategametime) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags;
|
||||
lifeform_t *l;
|
||||
|
@ -1544,8 +1531,10 @@ void timeeffectsworld(map_t *map) {
|
|||
//dumplf();
|
||||
} // end if timespent
|
||||
|
||||
// inc game time
|
||||
curtime += firstlftime;
|
||||
if (updategametime) {
|
||||
// inc game time
|
||||
curtime += firstlftime;
|
||||
}
|
||||
|
||||
if (db) dblog("cur time is %ld\n",curtime);
|
||||
}
|
||||
|
|
2
nexus.h
2
nexus.h
|
@ -33,5 +33,5 @@ int rollhitdice(lifeform_t *lf);
|
|||
int rollmpdice(lifeform_t *lf);
|
||||
//void sortlf(map_t *map);
|
||||
void sortcommands(void);
|
||||
void timeeffectsworld(map_t *map);
|
||||
void timeeffectsworld(map_t *map, int updategametime);
|
||||
void usage(char *progname);
|
||||
|
|
17
objects.c
17
objects.c
|
@ -2196,7 +2196,7 @@ int canseeob(lifeform_t *lf, object_t *o) {
|
|||
case PR_INEPT: cutoffpct = 200; break;
|
||||
}
|
||||
|
||||
cutoff = pctof(cutoffpct, FOOTPRINTTIME);
|
||||
cutoff = pctof(cutoffpct, TM_FOOTPRINT);
|
||||
|
||||
if (f->lifetime >= cutoff) {
|
||||
return B_TRUE;
|
||||
|
@ -4129,7 +4129,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
char adjective[BUFLEN];
|
||||
|
||||
lifeform_t *who = NULL;
|
||||
pct = ((float)f->lifetime / (float)SCENTTIME)*100;
|
||||
pct = ((float)f->lifetime / (float)TM_SCENT)*100;
|
||||
if (pct >= 66) {
|
||||
strcpy(adjective, "strong ");
|
||||
} else if (pct >= 33) {
|
||||
|
@ -4161,7 +4161,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
// adept and upwards gets depth
|
||||
if (slev >= PR_BEGINNER) {
|
||||
float pct;
|
||||
pct = ((float)f->lifetime / (float)FOOTPRINTTIME)*100;
|
||||
pct = ((float)f->lifetime / (float)TM_FOOTPRINT)*100;
|
||||
if (pct >= 66) {
|
||||
strcpy(basename, "fresh ");
|
||||
} else if (pct >= 33) {
|
||||
|
@ -8573,6 +8573,7 @@ void initobjects(void) {
|
|||
addot(OT_MAGICBARRIER, "magical barrier", "A glowing, impassable barrier of magical energy.", MT_MAGIC, 0, OC_EFFECT, SZ_LARGE);
|
||||
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "#");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_REALLYIMPASSABLE, NA, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
|
||||
|
@ -10560,10 +10561,10 @@ void makewet(object_t *o, int amt) {
|
|||
}
|
||||
*/
|
||||
f->val[0] += amt;
|
||||
f->val[1] = WETTIME;
|
||||
f->val[1] = TM_WETTIME;
|
||||
} else {
|
||||
// jsut reset wettime
|
||||
f->val[1] = WETTIME;
|
||||
f->val[1] = TM_WETTIME;
|
||||
}
|
||||
} else {
|
||||
|
||||
|
@ -10571,7 +10572,7 @@ void makewet(object_t *o, int amt) {
|
|||
if (haslos(player, loc) && !isdead(player)) {
|
||||
msg("%s get%s wet.",obnamefull, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
f = addflag(o->flags, F_WET, amt, WETTIME, NA, NULL);
|
||||
f = addflag(o->flags, F_WET, amt, TM_WETTIME, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12565,9 +12566,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s looks more tipsy.", lfname);
|
||||
}
|
||||
f->lifetime += DRUNKTIME;
|
||||
f->lifetime += TM_DRUNKTIME;
|
||||
} else {
|
||||
addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, DRUNKTIME);
|
||||
addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, TM_DRUNKTIME);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
2
save.c
2
save.c
|
@ -308,6 +308,7 @@ map_t *loadmap(char *basefile) {
|
|||
fscanf(f, "habitat:%d\n",(int *)&habitatid); // habitat
|
||||
m->habitat = findhabitat(habitatid);
|
||||
fscanf(f, "seed:%d\n",&m->seed); // seed
|
||||
fscanf(f, "lastplayervisit:%ld\n",&m->lastplayervisit);
|
||||
fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons
|
||||
fscanf(f, "nextmaps:\n");
|
||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
|
@ -859,6 +860,7 @@ int savemap(map_t *m) {
|
|||
fprintf(f, "name:%s\n",m->name); // map name
|
||||
fprintf(f, "habitat:%d\n",m->habitat->id); // habitat
|
||||
fprintf(f, "seed:%d\n",m->seed); // seed
|
||||
fprintf(f, "lastplayervisit:%ld\n",m->lastplayervisit);
|
||||
fprintf(f, "dims:%d,%d\n",m->w, m->h); // map dimensons
|
||||
fprintf(f, "nextmaps:\n");
|
||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
|
|
7
spell.c
7
spell.c
|
@ -2926,12 +2926,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("Couldn't create a vault.");
|
||||
} else {
|
||||
char ch;
|
||||
cell_t *c;
|
||||
|
||||
// link the new vault to the rest of the map
|
||||
c = getcellat(caster->cell->map, vx, vy);
|
||||
linkexits(caster->cell->map, getroomid(c));
|
||||
|
||||
msg("BAM! A vault has appeared nearby."); more();
|
||||
needredraw = B_TRUE;
|
||||
ch = askchar("Teleport to the new vault", "yn","y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
// find it
|
||||
for (y = vy; y < vy+vh; y++) {
|
||||
for (x = vy; x < vx + vw; x++) {
|
||||
|
|
Loading…
Reference in New Issue