- [+] bug: notime being set in timeeffectslf() but NOT being UNSET!!!
- [+] air spells: - [+] create whirlwind - make a single whirlwind - [+] implement - [+] ethereal steed - move very fast and levitate - [+] f_autocreateob whirlwind behind you - [+] whirlwind object throws any lfs/objects around randomly - [+] tornado - creates a single tornado at a given location (more powerful). it moves around randomly, kills adjacent walls. - [+] F_OBMOVESRANDOMLY - [+] find an adjacent cell (walls ok) - [+] kill any walls there - [+] move there - [+] hurricane - creates a cross cloud of whirlwinds (very powerful!). these move around randomly and kills adjacent walls. - [+] implement - [+] make them all move TOGETHER. - [+] djinni / genie - [+] invisibility - [+] gaseous form - [+] illusion? mirror image ? - [+] permenant ethereal steed effects - [+] airblast - [+] gust of wind - [+] efreeti - [+] wall of fire (new spell) - [+] gas form - [+] enlarge - [+] flame pillar - [+] when summoning a monster with a lifeob, place it under them? - [+] druid should learn canwill plantwalk at some point... level 7 - [+] allow f_cancast to have a timer too, like canwill. (so that monsters only cast certain spells sometimes) - [+] is ai plantwalk working? - [+] seems to... - [+] but then i get "something casts a spell at you!" - [+] aigetspelltarget is setting targlf to player. FIXED. - [+] ai keeps on casting plantwalk after doing it once. - [+] ai needs to sto fleeing after casting plantwalk successfully! - [+] this is because after stealing, we are fleeing for a time limit, rather than PERMENANT - [+] once this is fixed, add spellcasttext plantwalk = null for dryad. - [+] NEw code: if you teleport, and you were fleeing, and you can no longer have LOF to the one uou're fleeing from, STOP. - [+] The dryad vanishes! A dryad moves out of view.--More-- - [+] don't say both! - [+] change CHARMEDBY code for player: - [+] walk towards charmer, then give them your stuff! - [+] dryad brown 'T' (tree creature) - [+] knife - [+] must stay near oak tree - [+] can "plantwalk" between oak trees (or other plants). - [+] cast spell at cell with plant, warps you to a random one - [+] for player: reveal all cells with trees, then ask you which one. - [+] range 1 - [+] maxpower 1 - [+] ai casting: must be a plant in range. - [+] emergency code: if not within lifeob range, move back! - [+] can cast sleep - [+] wants gold/gems/weapons - [+] home oak tree contains gems - [+] steal - [+] stayinroom - [+] charm - [+] AI shouldn't ever walk away from life ob! - [+] ai homeob gems aren't appearing
This commit is contained in:
parent
899c185870
commit
ea5d012876
66
ai.c
66
ai.c
|
@ -562,6 +562,26 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
|
||||||
|
|
||||||
// aim at an adjacent wall cell
|
// aim at an adjacent wall cell
|
||||||
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
|
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
|
||||||
|
} else if (spelltype->id == OT_S_PLANTWALK) {
|
||||||
|
cell_t *cell[MAXCANDIDATES];
|
||||||
|
int ncells,i;
|
||||||
|
cell_t *poss[MAX_MAPW*MAX_MAPH];
|
||||||
|
int nposs = 0;
|
||||||
|
|
||||||
|
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_TRUE, cell, &ncells, 0);
|
||||||
|
// any plants within range 1?
|
||||||
|
for (i = 0; i < ncells; i++) {
|
||||||
|
if (hasobofclass(cell[i]->obpile, OC_FLORA)) {
|
||||||
|
poss[nposs++] = cell[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// should always be true since we check this in aispellok
|
||||||
|
if (nposs > 0) {
|
||||||
|
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
|
||||||
|
if (spelllf) *spelllf = NULL;
|
||||||
|
if (spellob) *spellob = NULL;
|
||||||
|
}
|
||||||
} else if (spelltype->id == OT_S_TELEKINESIS) {
|
} else if (spelltype->id == OT_S_TELEKINESIS) {
|
||||||
float maxweight;
|
float maxweight;
|
||||||
object_t *poss[MAXPILEOBS];
|
object_t *poss[MAXPILEOBS];
|
||||||
|
@ -596,6 +616,7 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
|
||||||
// cast spell at the victim
|
// cast spell at the victim
|
||||||
if (spelllf) *spelllf = victim;
|
if (spelllf) *spelllf = victim;
|
||||||
if (spellcell) *spellcell = victim->cell;
|
if (spellcell) *spellcell = victim->cell;
|
||||||
|
/*
|
||||||
} else if (spelltype->id == OT_S_CHARM) {
|
} else if (spelltype->id == OT_S_CHARM) {
|
||||||
lifeform_t *l;
|
lifeform_t *l;
|
||||||
l = getnearbypeaceful(lf);
|
l = getnearbypeaceful(lf);
|
||||||
|
@ -604,6 +625,7 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
|
||||||
if (spellcell) *spellcell = l->cell;
|
if (spellcell) *spellcell = l->cell;
|
||||||
if (spellob) *spellob = NULL;
|
if (spellob) *spellob = NULL;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else if (spelltype->id == OT_S_SUPERHEAT) {
|
} else if (spelltype->id == OT_S_SUPERHEAT) {
|
||||||
// get all potions
|
// get all potions
|
||||||
object_t *poss[MAXPILEOBS],*o;
|
object_t *poss[MAXPILEOBS],*o;
|
||||||
|
@ -963,10 +985,39 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
||||||
int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
|
int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
|
||||||
int db = B_FALSE;
|
int db = B_FALSE;
|
||||||
int moveawayfromcell = B_FALSE;
|
int moveawayfromcell = B_FALSE;
|
||||||
|
flag_t *f;
|
||||||
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
||||||
|
|
||||||
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
|
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
|
||||||
|
|
||||||
|
// if we are not near our life ob, move towards it!
|
||||||
|
f = lfhasflag(lf, F_LIFEOB);
|
||||||
|
if (f) {
|
||||||
|
if (!findnearbylifeob(lf->cell, f, NULL)) {
|
||||||
|
cell_t *poss[8];
|
||||||
|
int nposs = 0;
|
||||||
|
int dir;
|
||||||
|
if (db) dblog(".oO { not near my lifeob! }");
|
||||||
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||||
|
cell_t *c;
|
||||||
|
c = getcellindir(lf->cell, dir);
|
||||||
|
if (c && findnearbylifeob(c, f, NULL)) {
|
||||||
|
poss[nposs++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nposs) {
|
||||||
|
if (aigoto(lf, poss[rnd(0,nposs-1)], MR_OTHER, NULL, PERMENANT)) {
|
||||||
|
if (db) dblog(".oO { moving close to lifeob }");
|
||||||
|
// success
|
||||||
|
return B_TRUE;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { couldnt find an adjacent cell near lifeob }");
|
||||||
|
// TODO: search all in los
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if our cell is dangerous, move away!
|
// if our cell is dangerous, move away!
|
||||||
if (iqb >= AT_AVERAGE) {
|
if (iqb >= AT_AVERAGE) {
|
||||||
if (celldangerous(lf, lf->cell, B_TRUE, NULL)) {
|
if (celldangerous(lf, lf->cell, B_TRUE, NULL)) {
|
||||||
|
@ -1565,7 +1616,6 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
||||||
// spell failed. we will keep going through aiturn.
|
// spell failed. we will keep going through aiturn.
|
||||||
} else {
|
} else {
|
||||||
// spell succesful
|
// spell succesful
|
||||||
|
|
||||||
if ((spell == OT_A_STEAL) && !lfhasflag(lf, F_NOFLEE)) {
|
if ((spell == OT_A_STEAL) && !lfhasflag(lf, F_NOFLEE)) {
|
||||||
if (!isgod(lf)) {
|
if (!isgod(lf)) {
|
||||||
// run away for a while
|
// run away for a while
|
||||||
|
@ -2235,6 +2285,16 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ot->id == OT_S_PLANTWALK) {
|
||||||
|
cell_t *cell[MAXCANDIDATES];
|
||||||
|
int ncells,i;
|
||||||
|
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_TRUE, cell, &ncells, 0);
|
||||||
|
// any plants within range 1?
|
||||||
|
for (i = 0; i < ncells; i++) {
|
||||||
|
if (hasobofclass(cell[i]->obpile, OC_FLORA)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (ot->id == OT_S_PYROMANIA) {
|
} else if (ot->id == OT_S_PYROMANIA) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < lf->nlos; i++) {
|
for (i = 0; i < lf->nlos; i++) {
|
||||||
|
@ -2262,10 +2322,6 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ot->id == OT_S_CHARM) {
|
|
||||||
if (getnearbypeaceful(lf)) {
|
|
||||||
ok = B_TRUE;
|
|
||||||
}
|
|
||||||
} else if (ot->id == OT_S_SUPERHEAT) {
|
} else if (ot->id == OT_S_SUPERHEAT) {
|
||||||
// got a potion?
|
// got a potion?
|
||||||
if (victim && hasobwithflag(lf->pack, F_DRINKABLE) && haslof(lf->cell, victim->cell, LOF_NEED, NULL)) {
|
if (victim && hasobwithflag(lf->pack, F_DRINKABLE) && haslof(lf->cell, victim->cell, LOF_NEED, NULL)) {
|
||||||
|
|
219
data.c
219
data.c
|
@ -445,6 +445,7 @@ void initjobs(void) {
|
||||||
addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
|
addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
|
||||||
addflag(lastjob->flags, F_PARTVEGETARIAN, B_TRUE, NA, NA, NULL);
|
addflag(lastjob->flags, F_PARTVEGETARIAN, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastjob->flags, F_LEVSKILL, 5, SK_LORE_NATURE, NA, NULL);
|
addflag(lastjob->flags, F_LEVSKILL, 5, SK_LORE_NATURE, NA, NULL);
|
||||||
|
addflag(lastjob->flags, F_LEVSPELL, 7, OT_S_PLANTWALK, NA, NULL);
|
||||||
addflag(lastjob->flags, F_LEVSKILL, 10, SK_LORE_NATURE, NA, NULL);
|
addflag(lastjob->flags, F_LEVSKILL, 10, SK_LORE_NATURE, NA, NULL);
|
||||||
addflag(lastjob->flags, F_LEVSKILL, 15, SK_LORE_NATURE, NA, NULL);
|
addflag(lastjob->flags, F_LEVSKILL, 15, SK_LORE_NATURE, NA, NULL);
|
||||||
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -3109,6 +3110,13 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_ADJSELF, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_ADJSELF, NA, NA, NULL);
|
||||||
|
addot(OT_S_WHIRLWIND, "conjure whirlwind", "Creates a spinning whirlwind at a specified location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the whirlwind will last.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_OBJECT, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
// l4
|
// l4
|
||||||
addot(OT_S_CLOUDKILL, "cloudkill", "Creates a cloud of poisonous gas. The cloud's size is 1-3 cells, depending on the spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_CLOUDKILL, "cloudkill", "Creates a cloud of poisonous gas. The cloud's size is 1-3 cells, depending on the spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
@ -3135,12 +3143,6 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// l5
|
// l5
|
||||||
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 3d6 damage, the next deals 3d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 3d6 damage, the next deals 3d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power.");
|
||||||
|
@ -3149,6 +3151,12 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||||
|
addot(OT_S_ETHEREALSTEED, "ethereal steed", "Raises the caster onto a spinning whirlwind, granting them levitation and speed. Smaller whirlwinds are left in a trail behind the caster, deterring pursuit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||||
addot(OT_S_HASTE, "haste", "Increases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_HASTE, "haste", "Increases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last.");
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
@ -3156,12 +3164,26 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||||
|
addot(OT_S_TORNADO, "conjure tornado", "Creates a lethal tornado at a specified location. The tornado will move about, causing damage to everything in its path.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the tornado will last.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_OBJECT, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
// l6
|
// l6
|
||||||
addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||||
|
addot(OT_S_HURRICANE, "conjure hurricane", "Creates a devastating hurricane at a specified location. The hurricane will move about, obliterating all in its path.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the hurricane will last.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_OBJECT, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// elemental - fire magic
|
// elemental - fire magic
|
||||||
|
@ -3264,6 +3286,15 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
||||||
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 5, NA, NULL);
|
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 5, NA, NULL);
|
||||||
|
addot(OT_S_WALLOFFIRE, "wall of fire", "Creates an roaring wall of flames.", MT_ICE, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the flames.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 5, NA, NULL);
|
||||||
// l6
|
// l6
|
||||||
addot(OT_S_METEOR, "meteor", "Launches a white-hot meteorite towards the target location, dealing up to ^bpower^nd6+30 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_METEOR, "meteor", "Launches a white-hot meteorite towards the target location, dealing up to ^bpower^nd6+30 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
|
||||||
|
@ -3596,6 +3627,16 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||||
|
addot(OT_S_PLANTWALK, "plantwalk", "Instantly travel through a plant to another nearby plant.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level I, caster may only travel to plants of the same type.");
|
||||||
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level II, caster may travel to any other plant.");
|
||||||
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAXPOWER, 2, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SPECIAL, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||||
// l6
|
// l6
|
||||||
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how many bolts will appear.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how many bolts will appear.");
|
||||||
|
@ -3821,7 +3862,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||||
///////////////////
|
///////////////////
|
||||||
// modification
|
// modification
|
||||||
|
@ -3859,16 +3900,18 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||||
// l2
|
// l2
|
||||||
addot(OT_S_SIZEUP, "unnatural growth", "Causes the target's body to grow in size. They will become easier to hit, but deal less damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_SIZEUP, "unnatural growth", "Causes the target's body to grow in size. They will become easier to hit, but deal more damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||||
addot(OT_S_SIZEDOWN, "unnatural shrinkage", "Causes the target's body to shrink in size. They will deal less damage, but become harder to hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_SIZEDOWN, "unnatural shrinkage", "Causes the target's body to shrink in size. They will deal less damage, but become harder to hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||||
addot(OT_S_MIRRORIMAGE, "mirror image", "Creates ^bpower^n illusionary clones of the caster to distract enemies. These clones cannot deal damage, and vanish when hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_MIRRORIMAGE, "mirror image", "Creates ^bpower^n illusionary clones of the caster to distract enemies. These clones cannot deal damage, and vanish when hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many clones are created, and how many hits they can sustain.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many clones are created, and how many hits they can sustain.");
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||||
|
@ -3933,6 +3976,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||||
addot(OT_S_QUICKENSTONE, "quicken stone", "Crafts nearby stone into powerful stone primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_QUICKENSTONE, "quicken stone", "Crafts nearby stone into powerful stone primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created.");
|
||||||
|
@ -5673,6 +5717,17 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2");
|
addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2");
|
||||||
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2");
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2");
|
||||||
|
|
||||||
|
addot(OT_HURRICANE, "hurricane", "A massive column of devestating air currents.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SPIRAL, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHP, 12, 12, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_KNOCKAWAY, 4, 40, 12, "4d6");
|
||||||
|
addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||||
|
|
||||||
addot(OT_ICEWALL, "wall of ice", "A wall made of solid ice.", MT_ICE, 0, OC_EFFECT, SZ_LARGE);
|
addot(OT_ICEWALL, "wall of ice", "A wall made of solid ice.", MT_ICE, 0, OC_EFFECT, SZ_LARGE);
|
||||||
addflag(lastot->flags, F_GLYPH, C_CYAN, '#', NA, NULL);
|
addflag(lastot->flags, F_GLYPH, C_CYAN, '#', NA, NULL);
|
||||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||||
|
@ -5691,6 +5746,17 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
|
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
|
||||||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
||||||
|
|
||||||
|
addot(OT_TORNADO, "tornado", "A large column of incredibly fast spinning air.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SPIRAL, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHP, 8, 8, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_KNOCKAWAY, 2, 35, 10, "3d6");
|
||||||
|
addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||||
|
|
||||||
addot(OT_VIBCLOUD, "vibrating cloud", "A cloud of unstable molecules.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
|
addot(OT_VIBCLOUD, "vibrating cloud", "A cloud of unstable molecules.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
|
||||||
addflag(lastot->flags, F_GLYPH, C_ORANGE, UNI_SHADEMED, NA, NULL);
|
addflag(lastot->flags, F_GLYPH, C_ORANGE, UNI_SHADEMED, NA, NULL);
|
||||||
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
|
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
|
||||||
|
@ -5731,6 +5797,16 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_DTVULN, DT_ACID, NA, NA, NULL);
|
addflag(lastot->flags, F_DTVULN, DT_ACID, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||||
|
|
||||||
|
addot(OT_WHIRLWIND, "whirlwind", "A large column of very rapidly spinning air.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SPIRAL, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_KNOCKAWAY, 1, 30, 8, "2d6");
|
||||||
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||||
|
|
||||||
// armour objects
|
// armour objects
|
||||||
// armour - multipart
|
// armour - multipart
|
||||||
addot(OT_WETSUIT, "wetsuit", "Full-body rubber suit which provides good insulation from cold.", MT_RUBBER, 6, OC_ARMOUR, SZ_MEDIUM);
|
addot(OT_WETSUIT, "wetsuit", "Full-body rubber suit which provides good insulation from cold.", MT_RUBBER, 6, OC_ARMOUR, SZ_MEDIUM);
|
||||||
|
@ -8767,6 +8843,113 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_EATCONFER, F_NIGHTVISRANGEMOD, 1, NA, "75");
|
addflag(lastrace->flags, F_EATCONFER, F_NIGHTVISRANGEMOD, 1, NA, "75");
|
||||||
|
|
||||||
|
addrace(R_DRYAD, "dryad", 65, 'n', C_BROWN, MT_WOOD, RC_MAGIC, "Dryads are gentle forest spirits. These peaceful creatures prefer the tranquility of nature, and will avoid fighting if possible.");
|
||||||
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
|
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, RR_RARE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4");
|
||||||
|
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_LIFEOB, OT_TREE, 2, 3, NULL);
|
||||||
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "tree");
|
||||||
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "random gem");
|
||||||
|
addflag(lastrace->flags, F_HOMEOB, 66, NA, NA, "random gem");
|
||||||
|
addflag(lastrace->flags, F_HOMEOB, 33, NA, NA, "random gem");
|
||||||
|
addflag(lastrace->flags, F_HOMEOB, 50, NA, NA, "10-50 gold");
|
||||||
|
addflag(lastrace->flags, F_HOMELEVOB, 2, 4, NA, "tree");
|
||||||
|
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "knife");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_PLANTWALK, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, "pw:1;");
|
||||||
|
//addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL);
|
||||||
|
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PLANTWALK, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||||
|
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_SS_NATURE, PR_EXPERT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_THIEVERY, PR_SKILLED, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL); // stay in our starting room
|
||||||
|
addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL);
|
||||||
|
|
||||||
|
addrace(R_DJINNI, "genie", 65, 'Y', C_YELLOW, MT_FLESH, RC_MAGIC, "Genies are powerful air spirits. They resemble richly dressed humans floating on a cone of whirling air.");
|
||||||
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
|
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, RR_RARE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "7d4+3");
|
||||||
|
addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_DTIMMUNE, DT_PROJECTILE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 7, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "2 scimitars");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "silk shirt");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "riding trousers");
|
||||||
|
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "whirlwind");
|
||||||
|
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_AIRBLAST, NA, NA, "pw:3;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_GUSTOFWIND, NA, NA, "pw:8;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_INVISIBILITY, 20, 20, "pw:1;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_GASEOUSFORM, NA, NA, "pw:1;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_MIRRORIMAGE, 10, 10, "pw:2;");
|
||||||
|
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_TWOWEAPON, PR_ADEPT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_SS_AIR, PR_EXPERT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||||
|
|
||||||
|
addrace(R_EFREETI, "efreeti", 65, 'Y', C_RED, MT_FLESH, RC_MAGIC, "Efreeti are evil, fire-based cousins of genies. They resemble richly dressed humans surrounded by crackling flames.");
|
||||||
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
|
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, RR_RARE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+3");
|
||||||
|
addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 5, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming scimitar");
|
||||||
|
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "medium fire");
|
||||||
|
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_WALLOFFIRE, 10, 10, "pw:5;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEPILLAR, NA, NA, "pw:7;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_GASEOUSFORM, NA, NA, "pw:1;");
|
||||||
|
addflag(lastrace->flags, F_CANCAST, OT_S_SIZEUP, 20, 20, "pw:1;");
|
||||||
|
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_TWOWEAPON, PR_ADEPT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_EXPERT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||||
|
|
||||||
addrace(R_EYEBAT, "eyebat", 5, 'e', C_BLUE, MT_FLESH, RC_MAGIC, "A smaller cousin to the beholder, an eyebat is a single oversized eyeball suspended between bat-like wings.");
|
addrace(R_EYEBAT, "eyebat", 5, 'e', C_BLUE, MT_FLESH, RC_MAGIC, "A smaller cousin to the beholder, an eyebat is a single oversized eyeball suspended between bat-like wings.");
|
||||||
addbodypart(lastrace, BP_BODY, NULL);
|
addbodypart(lastrace, BP_BODY, NULL);
|
||||||
addbodypart(lastrace, BP_WINGS, NULL);
|
addbodypart(lastrace, BP_WINGS, NULL);
|
||||||
|
@ -9304,7 +9487,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_CANCAST, OT_S_GASEOUSFORM, NA, NA, "pw:3;");
|
addflag(lastrace->flags, F_CANCAST, OT_S_GASEOUSFORM, NA, NA, "pw:1;");
|
||||||
// gremlins also cause tech to fail around them.
|
// gremlins also cause tech to fail around them.
|
||||||
|
|
||||||
addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_YELLOW, MT_FLESH, RC_HUMANOID, "A larger, stronger, smarter and more menacing form of a goblin.");
|
addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_YELLOW, MT_FLESH, RC_HUMANOID, "A larger, stronger, smarter and more menacing form of a goblin.");
|
||||||
|
@ -9930,7 +10113,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
|
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||||
|
|
||||||
addrace(R_POLTERGEIST, "poltergeist", 50, 'p', C_GREEN, MT_FLESH, RC_UNDEAD, "An evil ghostly spirit who telekinetically throws objects at its enemies."); // sPirit
|
addrace(R_POLTERGEIST, "poltergeist", 50, 'P', C_GREEN, MT_FLESH, RC_UNDEAD, "An evil ghostly spirit who telekinetically throws objects at its enemies."); // sPirit
|
||||||
addbodypart(lastrace, BP_BODY, NULL);
|
addbodypart(lastrace, BP_BODY, NULL);
|
||||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -11415,7 +11598,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||||
addrace(R_SLUG, "acid slug", 150, 'P', C_GREY, MT_FLESH, RC_ANIMAL, "While acid slugs lack the protective shell of their snail cousings, their rubbery flesh is extremely resilient. Their acid-based attacks also make them much more dangerous.");
|
addrace(R_SLUG, "acid slug", 150, 'p', C_GREY, MT_FLESH, RC_ANIMAL, "While acid slugs lack the protective shell of their snail cousings, their rubbery flesh is extremely resilient. Their acid-based attacks also make them much more dangerous.");
|
||||||
addbodypart(lastrace, BP_BODY, NULL);
|
addbodypart(lastrace, BP_BODY, NULL);
|
||||||
addbodypart(lastrace, BP_HEAD, NULL);
|
addbodypart(lastrace, BP_HEAD, NULL);
|
||||||
addbodypart(lastrace, BP_EYES, NULL);
|
addbodypart(lastrace, BP_EYES, NULL);
|
||||||
|
@ -11445,7 +11628,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||||
addrace(R_SNAIL, "mottled snail", 150, 'P', C_BROWN, MT_FLESH, RC_ANIMAL, "An enormous snail, protected by a hard, scaled shell and gifted with long, sharp fangs.");
|
addrace(R_SNAIL, "mottled snail", 150, 'p', C_BROWN, MT_FLESH, RC_ANIMAL, "An enormous snail, protected by a hard, scaled shell and gifted with long, sharp fangs.");
|
||||||
addbodypart(lastrace, BP_BODY, NULL);
|
addbodypart(lastrace, BP_BODY, NULL);
|
||||||
addbodypart(lastrace, BP_HEAD, NULL);
|
addbodypart(lastrace, BP_HEAD, NULL);
|
||||||
addbodypart(lastrace, BP_EYES, NULL);
|
addbodypart(lastrace, BP_EYES, NULL);
|
||||||
|
@ -11680,7 +11863,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "web");
|
||||||
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
|
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
||||||
|
@ -11710,7 +11893,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "web");
|
||||||
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "20-30 webs");
|
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "20-30 webs");
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
||||||
|
@ -11741,7 +11924,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "web");
|
||||||
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "10-20 webs");
|
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "10-20 webs");
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
||||||
|
@ -11771,7 +11954,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "web");
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "web");
|
||||||
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
|
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
|
||||||
|
@ -12972,7 +13155,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||||
|
|
||||||
addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit
|
addrace(R_GHOST, "ghost", 50, 'P', C_BLUE, MT_MAGIC, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit
|
||||||
setbodytype(lastrace, BT_HUMANOID);
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
|
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
|
||||||
|
@ -13148,7 +13331,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_TR, 9, NA, NA, NULL);
|
addflag(lastrace->flags, F_TR, 9, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
|
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOMEOB, NA, NA, NA, "coffin");
|
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "coffin");
|
||||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 10, NA, NULL);
|
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 10, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 7, NA, NULL);
|
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 7, NA, NULL);
|
||||||
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
|
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
|
||||||
|
|
33
defs.h
33
defs.h
|
@ -58,6 +58,7 @@
|
||||||
#define UNI_SHADELIGHT 0x2591
|
#define UNI_SHADELIGHT 0x2591
|
||||||
#define UNI_SHADEMED 0x2592
|
#define UNI_SHADEMED 0x2592
|
||||||
#define UNI_SHADEDARK 0x2593
|
#define UNI_SHADEDARK 0x2593
|
||||||
|
#define UNI_SPIRAL 0x2202
|
||||||
//#define UNI_SOLID '#'
|
//#define UNI_SOLID '#'
|
||||||
|
|
||||||
// getrandomemptycell() params
|
// getrandomemptycell() params
|
||||||
|
@ -228,6 +229,7 @@
|
||||||
#define AO_DRINKABLE 16384
|
#define AO_DRINKABLE 16384
|
||||||
|
|
||||||
// askcoords target types
|
// askcoords target types
|
||||||
|
#define TT_SPECIFIED -1
|
||||||
#define TT_NONE 0
|
#define TT_NONE 0
|
||||||
#define TT_MONSTER 1
|
#define TT_MONSTER 1
|
||||||
#define TT_OBJECT 2
|
#define TT_OBJECT 2
|
||||||
|
@ -979,6 +981,9 @@ enum RACE {
|
||||||
R_CREEPINGCLAW,
|
R_CREEPINGCLAW,
|
||||||
R_CRYMIDIA,
|
R_CRYMIDIA,
|
||||||
R_DARKMANTLE,
|
R_DARKMANTLE,
|
||||||
|
R_DJINNI,
|
||||||
|
R_DRYAD,
|
||||||
|
R_EFREETI,
|
||||||
R_EYEBAT,
|
R_EYEBAT,
|
||||||
R_GIANTHILL,
|
R_GIANTHILL,
|
||||||
R_GIANTFIRE,
|
R_GIANTFIRE,
|
||||||
|
@ -1470,10 +1475,14 @@ enum OBTYPE {
|
||||||
OT_S_AIRBLAST,
|
OT_S_AIRBLAST,
|
||||||
OT_S_CHAINLIGHTNING,
|
OT_S_CHAINLIGHTNING,
|
||||||
OT_S_CLOUDKILL,
|
OT_S_CLOUDKILL,
|
||||||
|
OT_S_ETHEREALSTEED,
|
||||||
OT_S_GUSTOFWIND,
|
OT_S_GUSTOFWIND,
|
||||||
|
OT_S_HURRICANE,
|
||||||
OT_S_MIST,
|
OT_S_MIST,
|
||||||
OT_S_SHATTER,
|
OT_S_SHATTER,
|
||||||
OT_S_TAILWIND,
|
OT_S_TAILWIND,
|
||||||
|
OT_S_TORNADO,
|
||||||
|
OT_S_WHIRLWIND,
|
||||||
OT_S_WINDSHIELD,
|
OT_S_WINDSHIELD,
|
||||||
// -- elemental - fire
|
// -- elemental - fire
|
||||||
OT_S_BLADEBURN,
|
OT_S_BLADEBURN,
|
||||||
|
@ -1488,6 +1497,7 @@ enum OBTYPE {
|
||||||
OT_S_PYROMANIA,
|
OT_S_PYROMANIA,
|
||||||
OT_S_SPARK,
|
OT_S_SPARK,
|
||||||
OT_S_SUPERHEAT,
|
OT_S_SUPERHEAT,
|
||||||
|
OT_S_WALLOFFIRE,
|
||||||
// -- elemental - ice
|
// -- elemental - ice
|
||||||
OT_S_ABSOLUTEZERO,
|
OT_S_ABSOLUTEZERO,
|
||||||
OT_S_CHILL,
|
OT_S_CHILL,
|
||||||
|
@ -1586,6 +1596,7 @@ enum OBTYPE {
|
||||||
OT_S_HAILSTORM,
|
OT_S_HAILSTORM,
|
||||||
OT_S_LIGHTNINGBOLT,
|
OT_S_LIGHTNINGBOLT,
|
||||||
OT_S_LIGHTNINGSTORM,
|
OT_S_LIGHTNINGSTORM,
|
||||||
|
OT_S_PLANTWALK,
|
||||||
OT_S_PURIFYFOOD,
|
OT_S_PURIFYFOOD,
|
||||||
OT_S_QUENCH,
|
OT_S_QUENCH,
|
||||||
OT_S_LESSENPOISON,
|
OT_S_LESSENPOISON,
|
||||||
|
@ -1817,6 +1828,7 @@ enum OBTYPE {
|
||||||
OT_FIREMED,
|
OT_FIREMED,
|
||||||
OT_FIRESMALL,
|
OT_FIRESMALL,
|
||||||
OT_HAILSTORM,
|
OT_HAILSTORM,
|
||||||
|
OT_HURRICANE,
|
||||||
OT_ICEWALL,
|
OT_ICEWALL,
|
||||||
OT_MAGICBARRIER,
|
OT_MAGICBARRIER,
|
||||||
OT_STEAMCLOUD,
|
OT_STEAMCLOUD,
|
||||||
|
@ -1828,9 +1840,11 @@ enum OBTYPE {
|
||||||
OT_METHANEPUFF,
|
OT_METHANEPUFF,
|
||||||
OT_POISONCLOUD,
|
OT_POISONCLOUD,
|
||||||
OT_POISONPUFF,
|
OT_POISONPUFF,
|
||||||
|
OT_TORNADO,
|
||||||
OT_VIBCLOUD,
|
OT_VIBCLOUD,
|
||||||
OT_VINE,
|
OT_VINE,
|
||||||
OT_WEB,
|
OT_WEB,
|
||||||
|
OT_WHIRLWIND,
|
||||||
// armour - multipart
|
// armour - multipart
|
||||||
OT_WETSUIT,
|
OT_WETSUIT,
|
||||||
// armour - body
|
// armour - body
|
||||||
|
@ -2230,6 +2244,13 @@ enum FLAG {
|
||||||
F_REPELBLESSED, // v0 = b_blessed or b_cursed. repels other obejcts
|
F_REPELBLESSED, // v0 = b_blessed or b_cursed. repels other obejcts
|
||||||
// of this blesstype.
|
// of this blesstype.
|
||||||
// if v1 == b_blessed or b_cursed, will ID these blessings/curses
|
// if v1 == b_blessed or b_cursed, will ID these blessings/curses
|
||||||
|
F_KNOCKAWAY, // this obejct will cause a knockback() effect on
|
||||||
|
// other objects of lifeforms in its space.
|
||||||
|
// v0 is the distance to knock lfs.
|
||||||
|
// v1 = skillcheck difficulty to avoid falling
|
||||||
|
// v2 = speed to fire objects
|
||||||
|
// text = "xdx" (damage to deal)
|
||||||
|
|
||||||
F_TRAIL, // this object denotes the trail left by a lf.
|
F_TRAIL, // this object denotes the trail left by a lf.
|
||||||
// v0 = raceid of lf who left it
|
// v0 = raceid of lf who left it
|
||||||
// v1 = direction the lf moved out of this cell
|
// v1 = direction the lf moved out of this cell
|
||||||
|
@ -2285,6 +2306,9 @@ enum FLAG {
|
||||||
F_THEREISHERE, // announce "there is xx here!", not "you see xx here"
|
F_THEREISHERE, // announce "there is xx here!", not "you see xx here"
|
||||||
// text[0] is punctuation to use.
|
// text[0] is punctuation to use.
|
||||||
F_OBDIETEXT, // text when the object dies
|
F_OBDIETEXT, // text when the object dies
|
||||||
|
F_OBMOVESRANDOMLY, // object will randomly move around
|
||||||
|
// if v0 is true, it can destroy
|
||||||
|
// walls
|
||||||
F_DIECONVERTTEXT, // text when the object converts. eg. "melts"
|
F_DIECONVERTTEXT, // text when the object converts. eg. "melts"
|
||||||
F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt"
|
F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt"
|
||||||
F_DIECONVERT, // text = what this turns into when dying
|
F_DIECONVERT, // text = what this turns into when dying
|
||||||
|
@ -2821,8 +2845,13 @@ enum FLAG {
|
||||||
F_EXTRACORPSE, // text field specifies what additional corpse
|
F_EXTRACORPSE, // text field specifies what additional corpse
|
||||||
// obtype to leave
|
// obtype to leave
|
||||||
// v0 = pct change for this to happen. NA = 100.
|
// v0 = pct change for this to happen. NA = 100.
|
||||||
F_MYCORPSE, // text field contains obid of my corpse.
|
F_LIFEOB, // v0 = obtype of life object
|
||||||
// (for ghosts)
|
// OR
|
||||||
|
// text field contains obid of life object
|
||||||
|
// (text overrise v0)
|
||||||
|
// if lf is not witihn v1 dist of this object(s),
|
||||||
|
// they lose v2 hp
|
||||||
|
// (used by ghosts)
|
||||||
F_NOCORPSE, // monster's body crumbles to dust after death
|
F_NOCORPSE, // monster's body crumbles to dust after death
|
||||||
F_NOCTURNAL, // monster sleeps during the day
|
F_NOCTURNAL, // monster sleeps during the day
|
||||||
F_DIURNAL, // monster sleeps at night
|
F_DIURNAL, // monster sleeps at night
|
||||||
|
|
|
@ -31,8 +31,8 @@ n = small humanoid / nymph / sprite
|
||||||
N = necron
|
N = necron
|
||||||
o = orc
|
o = orc
|
||||||
O = monstrous humanoid (ie. ogre)
|
O = monstrous humanoid (ie. ogre)
|
||||||
p = sPirit
|
p = gastropod
|
||||||
P = gastroPod
|
P = sPirit
|
||||||
q = quadraped
|
q = quadraped
|
||||||
Q = large quadraped
|
Q = large quadraped
|
||||||
r = rodent
|
r = rodent
|
||||||
|
@ -41,6 +41,7 @@ s = snake
|
||||||
S = spider
|
S = spider
|
||||||
T = walkingtree-like monster (dryad, treant)
|
T = walkingtree-like monster (dryad, treant)
|
||||||
U = unearthly/horrific creature
|
U = unearthly/horrific creature
|
||||||
|
v = ?
|
||||||
V = vampire
|
V = vampire
|
||||||
w = small wyrm
|
w = small wyrm
|
||||||
W = large wyrm
|
W = large wyrm
|
||||||
|
|
1
flag.c
1
flag.c
|
@ -562,6 +562,7 @@ int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol ) {
|
||||||
break;
|
break;
|
||||||
case F_BEINGSTONED:
|
case F_BEINGSTONED:
|
||||||
case F_CONFUSED:
|
case F_CONFUSED:
|
||||||
|
case F_CHARMEDBY:
|
||||||
case F_FEIGNINGDEATH:
|
case F_FEIGNINGDEATH:
|
||||||
case F_FLYING:
|
case F_FLYING:
|
||||||
case F_LEVITATING:
|
case F_LEVITATING:
|
||||||
|
|
2
god.c
2
god.c
|
@ -619,7 +619,7 @@ void dooffer(void) {
|
||||||
pleasegod(god->race->id, pietyplus);
|
pleasegod(god->race->id, pietyplus);
|
||||||
if (strlen(splatterob)) {
|
if (strlen(splatterob)) {
|
||||||
addob(player->cell->obpile, splatterob);
|
addob(player->cell->obpile, splatterob);
|
||||||
addobsinradius(player->cell, 1, DT_COMPASS, splatterob, B_TRUE);
|
addobsinradius(player->cell, 1, DT_COMPASS, splatterob, B_TRUE, NULL);
|
||||||
}
|
}
|
||||||
if (god->race->id == R_GODFIRE) {
|
if (god->race->id == R_GODFIRE) {
|
||||||
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
|
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
|
||||||
|
|
75
io.c
75
io.c
|
@ -541,8 +541,11 @@ char askchar(char *prompt, char *validchars, char *def, int showchars, int mayca
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "func" is a pointer to a function which returns an added description for a highlighted cell
|
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail) {
|
||||||
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE LOFTYPE, int wanttrail) {
|
return real_askcoords(prompt, subprompt, targettype, srclf, maxrange, loftype, wanttrail, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs) {
|
||||||
static int startlf = -1;
|
static int startlf = -1;
|
||||||
int finished = B_FALSE;
|
int finished = B_FALSE;
|
||||||
int moved = B_FALSE;
|
int moved = B_FALSE;
|
||||||
|
@ -570,7 +573,13 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
}
|
}
|
||||||
|
|
||||||
// build list of targets if required
|
// build list of targets if required
|
||||||
if (targettype != TT_NONE) {
|
if (targettype == TT_SPECIFIED) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nspectargs; i++) {
|
||||||
|
target[i] = spectarg[i];
|
||||||
|
}
|
||||||
|
ntargets = nspectargs;
|
||||||
|
} else if (targettype != TT_NONE) {
|
||||||
for (y = 0; y < player->cell->map->h; y++) {
|
for (y = 0; y < player->cell->map->h; y++) {
|
||||||
for (x = 0; x < player->cell->map->w; x++) {
|
for (x = 0; x < player->cell->map->w; x++) {
|
||||||
c = getcellat(player->cell->map, x, y);
|
c = getcellat(player->cell->map, x, y);
|
||||||
|
@ -607,7 +616,6 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
target[ntargets] = c;
|
target[ntargets] = c;
|
||||||
if (curtarget == -1) curtarget = ntargets;
|
|
||||||
ntargets++;
|
ntargets++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,6 +623,10 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((curtarget == -1) && ntargets) {
|
||||||
|
//curtarget = ntargets;
|
||||||
|
curtarget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// start prompting
|
// start prompting
|
||||||
if (curtarget == -1) {
|
if (curtarget == -1) {
|
||||||
|
@ -855,16 +867,32 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
if (wep && (c->lf->race->id != R_DANCINGWEAPON)) {
|
if (wep && (c->lf->race->id != R_DANCINGWEAPON)) {
|
||||||
object_t *secwep;
|
object_t *secwep;
|
||||||
char obname[BUFLEN];
|
char obname[BUFLEN];
|
||||||
|
char obname2[BUFLEN];
|
||||||
char buf2[BUFLEN];
|
char buf2[BUFLEN];
|
||||||
|
int donesec = B_FALSE;
|
||||||
getobname(wep, obname, wep->amt);
|
getobname(wep, obname, wep->amt);
|
||||||
snprintf(buf2, BUFLEN, "weilding %s",obname);
|
secwep = getequippedob(c->lf->pack, BP_SECWEAPON);
|
||||||
|
if (secwep) {
|
||||||
|
getobname(secwep, obname2, secwep->amt);
|
||||||
|
} else {
|
||||||
|
strcpy(obname2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// two different weapons with the same name?
|
||||||
|
if (secwep && (secwep != wep) && streq(obname, obname2)) {
|
||||||
|
char *plur;
|
||||||
|
plur = makeplural(noprefix(obname));
|
||||||
|
snprintf(buf2, BUFLEN, "weilding two %s",plur);
|
||||||
|
free(plur);
|
||||||
|
donesec = B_TRUE;
|
||||||
|
} else {
|
||||||
|
snprintf(buf2, BUFLEN, "weilding %s",obname);
|
||||||
|
}
|
||||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||||
|
|
||||||
secwep = getequippedob(c->lf->pack, BP_SECWEAPON);
|
if (!donesec && secwep && (secwep != wep) ) {
|
||||||
if (secwep && (secwep != wep)) {
|
|
||||||
getobname(secwep, obname, secwep->amt);
|
|
||||||
strcat(buf2, " and ");
|
strcat(buf2, " and ");
|
||||||
strcat(buf2, obname);
|
strcat(buf2, obname2);
|
||||||
}
|
}
|
||||||
strcat(extrainfo, buf2);
|
strcat(extrainfo, buf2);
|
||||||
} else {
|
} else {
|
||||||
|
@ -958,15 +986,15 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
}
|
}
|
||||||
|
|
||||||
trailtarg = c;
|
trailtarg = c;
|
||||||
if (LOFTYPE != LOF_DONTNEED) {
|
if (loftype != LOF_DONTNEED) {
|
||||||
cell_t *newcell;
|
cell_t *newcell;
|
||||||
int bad = B_FALSE;
|
int bad = B_FALSE;
|
||||||
if (srclf) {
|
if (srclf) {
|
||||||
if (!haslof_real(srclf->cell, c, LOFTYPE, &newcell, srclf, B_TRUE)) {
|
if (!haslof_real(srclf->cell, c, loftype, &newcell, srclf, B_TRUE)) {
|
||||||
bad = B_TRUE;
|
bad = B_TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!haslof(srclf->cell, c, LOFTYPE, &newcell)) {
|
if (!haslof(srclf->cell, c, loftype, &newcell)) {
|
||||||
bad = B_TRUE;
|
bad = B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1418,7 +1446,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
||||||
lf2 = findlf(NULL, f->val[0]);
|
lf2 = findlf(NULL, f->val[0]);
|
||||||
if (lf2) {
|
if (lf2) {
|
||||||
getlfname(lf2, buf);
|
getlfname(lf2, buf);
|
||||||
msg("%s %s now under %s%s power!",lfname, is(lf), buf,getpossessive(buf));
|
msg("^%c%s %s now under %s%s power!^n",getlfcol(lf, CC_BAD), lfname, is(lf), buf,getpossessive(buf));
|
||||||
donesomething = B_TRUE;
|
donesomething = B_TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2099,7 +2127,8 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
||||||
if (lf2) {
|
if (lf2) {
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
getlfname(lf2, buf);
|
getlfname(lf2, buf);
|
||||||
msg("%s break%s free of %s%s control!",lfname, isplayer(lf) ? "" : "s", buf,getpossessive(buf));
|
msg("^%c%s break%s free of %s%s control!^n",getlfcol(lf, CC_GOOD),
|
||||||
|
lfname, isplayer(lf) ? "" : "s", buf,getpossessive(buf));
|
||||||
if (isplayer(lf2)) {
|
if (isplayer(lf2)) {
|
||||||
more();
|
more();
|
||||||
}
|
}
|
||||||
|
@ -7455,6 +7484,8 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
||||||
mpcost[nposs] = cost;
|
mpcost[nposs] = cost;
|
||||||
deactspell[nposs] = B_FALSE; // default
|
deactspell[nposs] = B_FALSE; // default
|
||||||
power = getspellpower(lf, ot->id);
|
power = getspellpower(lf, ot->id);
|
||||||
|
|
||||||
|
|
||||||
if (power > 0) {
|
if (power > 0) {
|
||||||
if (hasactivespell(lf, ot->id)) {
|
if (hasactivespell(lf, ot->id)) {
|
||||||
cost = 0;
|
cost = 0;
|
||||||
|
@ -7465,8 +7496,20 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
|
||||||
getspellcosttext(lf, ot->id, power, mpdesc[nposs]);
|
getspellcosttext(lf, ot->id, power, mpdesc[nposs]);
|
||||||
}
|
}
|
||||||
if (mpcost[nposs] <= mpcutoff) {
|
if (mpcost[nposs] <= mpcutoff) {
|
||||||
validspell[nposs] = B_TRUE;
|
if (f->val[2] == NA) {
|
||||||
err[nposs] = E_OK;
|
validspell[nposs] = B_TRUE;
|
||||||
|
err[nposs] = E_OK;
|
||||||
|
} else {
|
||||||
|
if (f->val[1] == f->val[2]) {
|
||||||
|
snprintf(mpdesc[nposs], BUFLEN, "(ready)");
|
||||||
|
validspell[nposs] = B_TRUE;
|
||||||
|
err[nposs] = E_OK;
|
||||||
|
} else {
|
||||||
|
snprintf(mpdesc[nposs], BUFLEN, "(%d/%d)",f->val[1],f->val[2]);
|
||||||
|
validspell[nposs] = B_FALSE;
|
||||||
|
err[nposs] = E_NOTREADY;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
validspell[nposs] = B_FALSE;
|
validspell[nposs] = B_FALSE;
|
||||||
err[nposs] = E_NOMP;
|
err[nposs] = E_NOMP;
|
||||||
|
|
1
io.h
1
io.h
|
@ -25,6 +25,7 @@ object_t *doaskobject(obpile_t *op, char *title, int *count, int showlong, int f
|
||||||
int askobjectmulti(obpile_t *op, char *prompt, long opts);
|
int askobjectmulti(obpile_t *op, char *prompt, long opts);
|
||||||
char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel);
|
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 *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 maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs);
|
||||||
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||||
vault_t *askvault(char *prompttext);
|
vault_t *askvault(char *prompttext);
|
||||||
void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );
|
void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );
|
||||||
|
|
220
lf.c
220
lf.c
|
@ -100,10 +100,12 @@ void autoweild(lifeform_t *lf) {
|
||||||
weild(lf, bestfirearm);
|
weild(lf, bestfirearm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// weild armour if required,
|
// weild armour/2nd weapons if required,
|
||||||
// and mark other weapons as secondary
|
// and mark other weapons as secondary
|
||||||
for (o = lf->pack->first ; o ; o = o->next) {
|
for (o = lf->pack->first ; o ; o = o->next) {
|
||||||
if (!donesecondary && isweapon(o) && !isequipped(o)) {
|
if (isweapon(o) && !isequipped(o) && getskill(lf, SK_TWOWEAPON) && !getequippedob(lf->pack, BP_SECWEAPON) && canweild(lf, o)) {
|
||||||
|
weild(lf, o);
|
||||||
|
} else if (!donesecondary && isweapon(o) && !isequipped(o)) {
|
||||||
addflag(o->flags, F_SECONDARY, B_TRUE, NA, NA, NULL);
|
addflag(o->flags, F_SECONDARY, B_TRUE, NA, NA, NULL);
|
||||||
donesecondary = B_TRUE;
|
donesecondary = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -211,7 +213,7 @@ void bleed(lifeform_t *lf, int splatter) {
|
||||||
|
|
||||||
if (strlen(obname) > 0) {
|
if (strlen(obname) > 0) {
|
||||||
addob(lf->cell->obpile, obname);
|
addob(lf->cell->obpile, obname);
|
||||||
if (splatter) addobsinradius(lf->cell, 1, DT_COMPASS, obname, B_TRUE);
|
if (splatter) addobsinradius(lf->cell, 1, DT_COMPASS, obname, B_TRUE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +624,7 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (lfhasflagval(lf, F_CANCAST, oid, NA, NA, NULL)) {
|
} else if ((f = lfhasflagval(lf, F_CANCAST, oid, NA, NA, NULL)) != NULL) {
|
||||||
int cost,power;
|
int cost,power;
|
||||||
|
|
||||||
// override!
|
// override!
|
||||||
|
@ -639,6 +641,14 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for mosnters: spell ready?
|
||||||
|
if (f->val[1] == f->val[2]) {
|
||||||
|
castable = B_TRUE;
|
||||||
|
} else {
|
||||||
|
reason = E_NOTREADY;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// how powerful is this spell?
|
// how powerful is this spell?
|
||||||
power = getspellpower(lf, oid);
|
power = getspellpower(lf, oid);
|
||||||
if (power <= 0) {
|
if (power <= 0) {
|
||||||
|
@ -2050,6 +2060,75 @@ int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int charmedaction(lifeform_t *lf, flag_t *charmflag) {
|
||||||
|
lifeform_t *charmer;
|
||||||
|
char charmername[BUFLEN];
|
||||||
|
charmer = findlf(lf->cell->map, charmflag->val[0]);
|
||||||
|
if (!charmer) {
|
||||||
|
killflag(charmflag);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
getlfname(charmer, charmername);
|
||||||
|
|
||||||
|
if (isadjacent(lf->cell, charmer->cell)) {
|
||||||
|
object_t *o;
|
||||||
|
enum OBTYPE oid[MAXPILEOBS];
|
||||||
|
int oidcovet[MAXPILEOBS];
|
||||||
|
int noids = 0;
|
||||||
|
enum FLAG wantflag[MAXPILEOBS];
|
||||||
|
int wantflagcovet[MAXPILEOBS];
|
||||||
|
int nwantflags = 0;
|
||||||
|
int ndone = 0;
|
||||||
|
// hands over wantob/weapon/armour
|
||||||
|
makewantedoblist(charmer, &noids, oid, oidcovet, &nwantflags, wantflag, wantflagcovet);
|
||||||
|
for (o = lf->pack->first ; o ; o = o->next) {
|
||||||
|
if (iscursed(o)) continue;
|
||||||
|
if (isweapon(o) || aiwants_real(charmer, o, NULL, &noids, oid, oidcovet, &nwantflags, wantflag, wantflagcovet)) {
|
||||||
|
if (isequipped(o)) {
|
||||||
|
takeoff(lf, o);
|
||||||
|
} else {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
getobname(o, obname, o->amt);
|
||||||
|
msg("You hand over your %s to %s.", obname,
|
||||||
|
cansee(lf, charmer) ? charmername : "your new master");
|
||||||
|
moveob(o, charmer->pack, o->amt);
|
||||||
|
}
|
||||||
|
ndone++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// nothing they want? just remove armour/weapons.
|
||||||
|
if (!ndone) {
|
||||||
|
for (o = lf->pack->first ; o ; o = o->next) {
|
||||||
|
if (isequipped(o)) {
|
||||||
|
takeoff(lf, o);
|
||||||
|
ndone++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ndone) {
|
||||||
|
msg("You bask in the glory of %s!", cansee(lf, charmer) ? charmername : "your new master");
|
||||||
|
taketime(lf, getactspeed(lf));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int dir;
|
||||||
|
// walks towards charmer, regardless of anything in the way
|
||||||
|
turntoface(lf, charmer->cell);
|
||||||
|
dir = getdirtowards(lf->cell, charmer->cell, lf, B_FALSE, DT_ORTH);
|
||||||
|
if (dir == D_NONE) {
|
||||||
|
msg("You try to %s towards %s, but fail.", getmoveverb(lf),
|
||||||
|
cansee(lf, charmer) ? charmername : "your new master");
|
||||||
|
} else {
|
||||||
|
msg("You mindlessly %s towards %s.", getmoveverb(lf),
|
||||||
|
cansee(lf, charmer) ? charmername : "your new master");
|
||||||
|
trymove(lf, dir, B_FALSE, B_TRUE);
|
||||||
|
}
|
||||||
|
taketime(lf, getactspeed(lf));
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int checkburdened(lifeform_t *lf, int preburdened) {
|
int checkburdened(lifeform_t *lf, int preburdened) {
|
||||||
int postburdened;
|
int postburdened;
|
||||||
|
|
||||||
|
@ -3101,7 +3180,7 @@ void die(lifeform_t *lf) {
|
||||||
if (corpse) {
|
if (corpse) {
|
||||||
char cid[BUFLEN];
|
char cid[BUFLEN];
|
||||||
snprintf(cid, BUFLEN, "%ld",corpse->id);
|
snprintf(cid, BUFLEN, "%ld",corpse->id);
|
||||||
addflag(lf->flags, F_MYCORPSE, NA, NA, NA, cid);
|
addflag(lf->flags, F_LIFEOB, NA, 5, 2, cid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Will the dead lf get reanimated up as a monster ?
|
// Will the dead lf get reanimated up as a monster ?
|
||||||
|
@ -3265,14 +3344,22 @@ void dumplf(void) {
|
||||||
void dumpmonsters(void) {
|
void dumpmonsters(void) {
|
||||||
race_t *r;
|
race_t *r;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
int count = 0,wanthd;
|
int wanthd;
|
||||||
|
int totcount = 0;
|
||||||
|
|
||||||
dblog("START MONSTER DUMP:");
|
dblog("START MONSTER DUMP:");
|
||||||
for (wanthd = 0; wanthd <= maxmonhitdice ; wanthd++) {
|
for (wanthd = 0; wanthd <= maxmonhitdice ; wanthd++) {
|
||||||
dblog("MONSTERS WITH THREAT RATING %d:",wanthd);
|
int count = 0;
|
||||||
|
// count them
|
||||||
|
for (r = firstrace ; r ; r = r->next) {
|
||||||
|
if (gettrrace(r) == wanthd) {
|
||||||
|
count++;
|
||||||
|
totcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dblog("MONSTERS WITH THREAT RATING %d (%d found):",wanthd, count);
|
||||||
for (r = firstrace ; r ; r = r->next) {
|
for (r = firstrace ; r ; r = r->next) {
|
||||||
int thishd;
|
int thishd;
|
||||||
|
|
||||||
thishd = gettrrace(r);
|
thishd = gettrrace(r);
|
||||||
if (thishd == wanthd) {
|
if (thishd == wanthd) {
|
||||||
int ndice,nsides,bonus,min,max;
|
int ndice,nsides,bonus,min,max;
|
||||||
|
@ -3282,11 +3369,10 @@ void dumpmonsters(void) {
|
||||||
min = ndice + bonus;
|
min = ndice + bonus;
|
||||||
max = (ndice*nsides) + bonus;
|
max = (ndice*nsides) + bonus;
|
||||||
dblog("\t%s (%d hp)",r->name, max);
|
dblog("\t%s (%d hp)",r->name, max);
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dblog("END MONSTER DUMP (%d found)",count);
|
dblog("END MONSTER DUMP (%d found)",totcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void genareaknowledge(flagpile_t *fp, int chancemod) {
|
void genareaknowledge(flagpile_t *fp, int chancemod) {
|
||||||
|
@ -5151,6 +5237,57 @@ lifeform_t *findlfunique(enum RACE rid) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell_t *findnearbylifeob(cell_t *src, flag_t *lifeobflag, object_t **retlifeob) {
|
||||||
|
object_t *corpse = NULL;
|
||||||
|
int maxdist;
|
||||||
|
maxdist = lifeobflag->val[1];
|
||||||
|
|
||||||
|
if (retlifeob) {
|
||||||
|
*retlifeob = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(lifeobflag->text)) {
|
||||||
|
long corpseid;
|
||||||
|
// find the corpse
|
||||||
|
corpseid = atol(lifeobflag->text);
|
||||||
|
corpse = findobidinmap(src->map, corpseid);
|
||||||
|
if (getcelldist(src, corpse->pile->where) > maxdist) {
|
||||||
|
corpse = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// find closest location with corpse...
|
||||||
|
cell_t *retcell[MAXCANDIDATES];
|
||||||
|
int nretcells,i;
|
||||||
|
enum OBTYPE oid;
|
||||||
|
int mindist = 9999;
|
||||||
|
|
||||||
|
oid = lifeobflag->val[0];
|
||||||
|
getradiuscells(src, maxdist, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_FALSE, retcell, &nretcells, 0);
|
||||||
|
for (i = 0; i < nretcells; i++) {
|
||||||
|
object_t *o;
|
||||||
|
cell_t *c;
|
||||||
|
int thisdist;
|
||||||
|
c = retcell[i];
|
||||||
|
o = hasob(c->obpile, oid);
|
||||||
|
if (o) {
|
||||||
|
thisdist = getcelldist(src, c);
|
||||||
|
if (thisdist < mindist) {
|
||||||
|
mindist = thisdist;
|
||||||
|
corpse = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (corpse) {
|
||||||
|
if (retlifeob) {
|
||||||
|
*retlifeob = corpse;
|
||||||
|
}
|
||||||
|
return corpse->pile->where;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
poisontype_t *findpoisontype(enum POISONTYPE id) {
|
poisontype_t *findpoisontype(enum POISONTYPE id) {
|
||||||
poisontype_t *pt;
|
poisontype_t *pt;
|
||||||
for (pt = firstpoisontype; pt ; pt = pt->next) {
|
for (pt = firstpoisontype; pt ; pt = pt->next) {
|
||||||
|
@ -11803,6 +11940,10 @@ int ischarmable(lifeform_t *lf) {
|
||||||
reason = E_DRUNK;
|
reason = E_DRUNK;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
if (lfhasflag(lf, F_CHARMEDBY)) {
|
||||||
|
reason = E_ALREADYUSING;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
if (hasflag(lf->flags, F_UNIQUE)) {
|
if (hasflag(lf->flags, F_UNIQUE)) {
|
||||||
reason = E_NOEFFECT; // generic error
|
reason = E_NOEFFECT; // generic error
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
|
@ -14287,10 +14428,10 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
|
||||||
if (postlowhp && !prelowhp) {
|
if (postlowhp && !prelowhp) {
|
||||||
f = lfhasflag(lf, F_LOWHPABIL);
|
f = lfhasflag(lf, F_LOWHPABIL);
|
||||||
if (f) {
|
if (f) {
|
||||||
flag_t *notime;
|
flag_t *ntm;
|
||||||
notime = addflag(lf->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
ntm = addflag(lf->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
|
||||||
abilityeffects(lf, f->val[0], lf->cell, lf, NULL);
|
abilityeffects(lf, f->val[0], lf->cell, lf, NULL);
|
||||||
killflag(notime);
|
killflag(ntm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18370,25 +18511,25 @@ void startlfturn(lifeform_t *lf) {
|
||||||
if (f) {
|
if (f) {
|
||||||
int radius;
|
int radius;
|
||||||
radius = f->val[0];
|
radius = f->val[0];
|
||||||
addobsinradius(lf->cell, f->val[0], DT_COMPASS, f->text, B_FALSE);
|
addobsinradius(lf->cell, f->val[0], DT_COMPASS, f->text, B_FALSE, lf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle ghosts
|
// handle life objects
|
||||||
if (lf->race->id == R_GHOST) {
|
f = lfhasflag(lf, F_LIFEOB);
|
||||||
f = lfhasflag(lf, F_MYCORPSE);
|
if (f) {
|
||||||
if (f) {
|
cell_t *corpseloc = NULL;
|
||||||
long corpseid;
|
object_t *corpse;
|
||||||
cell_t *corpseloc = NULL;
|
char corpsename[BUFLEN];
|
||||||
object_t *corpse;
|
|
||||||
|
|
||||||
corpseid = atol(f->text);
|
corpseloc = findnearbylifeob(lf->cell, f, &corpse);
|
||||||
|
if (corpse) {
|
||||||
corpse = findobidinmap(lf->cell->map, corpseid);
|
// did we find a corpse in range ?
|
||||||
if (corpse) {
|
if (corpse->type->id == OT_CORPSE) {
|
||||||
corpseloc = corpse->pile->where;
|
strcpy(corpsename, "corpse");
|
||||||
|
} else {
|
||||||
|
strcpy(corpsename, corpse->type->name);
|
||||||
}
|
}
|
||||||
// can we see our corpse?
|
if (lf->race->id == R_GHOST) {
|
||||||
if (corpseloc && haslos(lf, corpseloc)) {
|
|
||||||
// give possession ability
|
// give possession ability
|
||||||
if (!lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) {
|
if (!lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) {
|
||||||
char pwbuf[BUFLEN];
|
char pwbuf[BUFLEN];
|
||||||
|
@ -18400,14 +18541,22 @@ void startlfturn(lifeform_t *lf) {
|
||||||
f = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf);
|
f = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf);
|
||||||
f->lifetime = FROMRACE;
|
f->lifetime = FROMRACE;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// can't see corpse
|
} else {
|
||||||
|
// can't see corpse
|
||||||
|
if (lf->race->id == R_GHOST) {
|
||||||
f = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL);
|
f = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL);
|
||||||
if (f) killflag(f);
|
if (f) killflag(f);
|
||||||
// drain life
|
|
||||||
if (isplayer(lf)) msg("^BWithout your corpse, you feel yourself fading into nothingness.");
|
|
||||||
losehp(lf, 2, DT_DIRECT, NULL, "fading into nothingness");
|
|
||||||
}
|
}
|
||||||
|
// drain life
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("^BWithout your %s, you feel yourself fading into nothingness.", corpsename);
|
||||||
|
} else if (cansee(player, lf)) {
|
||||||
|
char lfname[BUFLEN];
|
||||||
|
getlfname(lf, lfname);
|
||||||
|
msg("%s seems to be fading from view!", lfname);
|
||||||
|
}
|
||||||
|
losehp(lf, f->val[2], DT_DIRECT, NULL, "fading into nothingness");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18843,7 +18992,7 @@ void startlfturn(lifeform_t *lf) {
|
||||||
if (isdead(lf)) return;
|
if (isdead(lf)) return;
|
||||||
|
|
||||||
// effects for/on your own flags
|
// effects for/on your own flags
|
||||||
getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
|
getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
|
||||||
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY,
|
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY,
|
||||||
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
|
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||||
for (i = 0; i < nretflags; i++) {
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
@ -18990,7 +19139,7 @@ void startlfturn(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// recharge abilities
|
// recharge abilities
|
||||||
if (f->id == F_CANWILL) {
|
if ((f->id == F_CANWILL) || (f->id == F_CANCAST)) {
|
||||||
if (f->val[2] != NA) {
|
if (f->val[2] != NA) {
|
||||||
if (f->val[1] < f->val[2]) {
|
if (f->val[1] < f->val[2]) {
|
||||||
f->val[1]++;
|
f->val[1]++;
|
||||||
|
@ -19538,6 +19687,7 @@ void timeeffectslf(lifeform_t *lf) {
|
||||||
|
|
||||||
if (isdead(lf)) {
|
if (isdead(lf)) {
|
||||||
killflagsofid(lf->flags, F_NOTIME);
|
killflagsofid(lf->flags, F_NOTIME);
|
||||||
|
notime = B_FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
lf.h
2
lf.h
|
@ -67,6 +67,7 @@ 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 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 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);
|
||||||
|
int charmedaction(lifeform_t *lf, flag_t *charmflag);
|
||||||
int checkburdened(lifeform_t *lf, int preburdened);
|
int checkburdened(lifeform_t *lf, int preburdened);
|
||||||
int checkfordrowning(lifeform_t *lf, object_t *o);
|
int checkfordrowning(lifeform_t *lf, object_t *o);
|
||||||
int check_rest_ok(lifeform_t *lf);
|
int check_rest_ok(lifeform_t *lf);
|
||||||
|
@ -107,6 +108,7 @@ job_t *findjob(enum JOB jobid);
|
||||||
job_t *findjobbyname(char *name);
|
job_t *findjobbyname(char *name);
|
||||||
lifeform_t *findlf(map_t *m, int lfid);
|
lifeform_t *findlf(map_t *m, int lfid);
|
||||||
lifeform_t *findlfunique(enum RACE rid);
|
lifeform_t *findlfunique(enum RACE rid);
|
||||||
|
cell_t *findnearbylifeob(cell_t *src, flag_t *lifeobflag, object_t **retlifeob);
|
||||||
poisontype_t *findpoisontype(enum POISONTYPE id);
|
poisontype_t *findpoisontype(enum POISONTYPE id);
|
||||||
race_t *findrace(enum RACE id);
|
race_t *findrace(enum RACE id);
|
||||||
race_t *findracebyname(char *name);
|
race_t *findracebyname(char *name);
|
||||||
|
|
39
map.c
39
map.c
|
@ -119,12 +119,23 @@ habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addhomeobs(lifeform_t *lf) {
|
void addhomeobs(lifeform_t *lf, int dolevelobs) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
cell_t *homeobloc;
|
||||||
|
homeobloc = lf->cell;
|
||||||
for (f = lf->flags->first ; f ; f = f->next) {
|
for (f = lf->flags->first ; f ; f = f->next) {
|
||||||
if (f->id == F_HOMEOB) {
|
if ((f->id == F_HOMEOB) && pctchance(f->val[0])) {
|
||||||
addob(lf->cell->obpile, f->text);
|
cell_t *c;
|
||||||
} else if (f->id == F_HOMELEVOB) {
|
object_t *o;
|
||||||
|
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);
|
||||||
|
if (c) {
|
||||||
|
homeobloc = c; // future obs will go here too.
|
||||||
|
moveob(o, homeobloc->obpile, o->amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((f->id == F_HOMELEVOB) && dolevelobs) {
|
||||||
int i,amt;
|
int i,amt;
|
||||||
amt = rnd(f->val[0],f->val[1]);
|
amt = rnd(f->val[0],f->val[1]);
|
||||||
for (i = 0; i < amt; i++) {
|
for (i = 0; i < amt; i++) {
|
||||||
|
@ -3369,7 +3380,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
||||||
// add home objects
|
// add home objects
|
||||||
if (db) dblog(" adding home objects.");
|
if (db) dblog(" adding home objects.");
|
||||||
for (lf = map->lf ; lf ; lf = lf->next) {
|
for (lf = map->lf ; lf ; lf = lf->next) {
|
||||||
addhomeobs(lf);
|
addhomeobs(lf, B_TRUE);
|
||||||
}
|
}
|
||||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||||
|
|
||||||
|
@ -4355,7 +4366,12 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((startdir >= D_N) && (startdir <= D_W));
|
//assert((startdir >= D_N) && (startdir <= D_W));
|
||||||
|
if ((startdir < D_N) || (startdir > D_W)) {
|
||||||
|
// couldn't find any valid start dirs!
|
||||||
|
if (db) dblog(" Cannot find a valid startdir.");
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// figure out perpendicular dirs
|
// figure out perpendicular dirs
|
||||||
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||||
|
@ -5445,6 +5461,17 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags,
|
||||||
if (f) {
|
if (f) {
|
||||||
autospells(lf, f->val[0]);
|
autospells(lf, f->val[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addhomeobs(lf, B_TRUE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
getflags(lf->flags, retflag, &nretflags, F_LIFEOB, F_NONE);
|
||||||
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
if (retflag[i]->val[0] != NA) {
|
||||||
|
addobfast(lf->cell->obpile, retflag[i]->val[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
celltype_t *findcelltype(enum CELLTYPE cid) {
|
celltype_t *findcelltype(enum CELLTYPE cid) {
|
||||||
|
|
2
map.h
2
map.h
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
cell_t *addcell(map_t *map, int x, int y);
|
cell_t *addcell(map_t *map, int x, int y);
|
||||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype);
|
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype);
|
||||||
void addhomeobs(lifeform_t *lf);
|
void addhomeobs(lifeform_t *lf, int dolevelobs);
|
||||||
map_t *addmap(void);
|
map_t *addmap(void);
|
||||||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded);
|
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded);
|
||||||
object_t *addrandomob(cell_t *c);
|
object_t *addrandomob(cell_t *c);
|
||||||
|
|
43
move.c
43
move.c
|
@ -909,13 +909,15 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
||||||
}
|
}
|
||||||
if (seen) msg("^%c%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing);
|
if (seen) msg("^%c%s slam%s into %s!^n",getlfcol(lf, CC_BAD), lfname,isplayer(lf) ? "" : "s", thing);
|
||||||
snprintf(buf, BUFLEN, "slamming into %s", thing);
|
snprintf(buf, BUFLEN, "slamming into %s", thing);
|
||||||
dam = roll("1d6");
|
// 1d6 dam per cell pushed
|
||||||
|
dam = rolldie(howfar, 6);
|
||||||
losehp(lf, dam, DT_BASH, pusher, buf);
|
losehp(lf, dam, DT_BASH, pusher, buf);
|
||||||
// stop moving
|
// stop moving
|
||||||
i = howfar;
|
i = howfar;
|
||||||
// don't fall
|
// don't fall
|
||||||
mightfall = B_FALSE;
|
mightfall = B_FALSE;
|
||||||
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf, NULL), dam, DT_BASH);
|
// 20% chance per cell pushed
|
||||||
|
if (pctchance(howfar*20)) criticalhit(NULL, lf, getrandomcorebp(lf, NULL), dam, DT_BASH);
|
||||||
break;
|
break;
|
||||||
case E_SWIMMING:
|
case E_SWIMMING:
|
||||||
case E_LFINWAY:
|
case E_LFINWAY:
|
||||||
|
@ -1131,6 +1133,7 @@ int moveeffects(lifeform_t *lf, int moved) {
|
||||||
// returns TRUE if something happened
|
// returns TRUE if something happened
|
||||||
int movelf(lifeform_t *lf, cell_t *newcell) {
|
int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
object_t *o,*nexto;
|
object_t *o,*nexto;
|
||||||
|
cell_t *precell;
|
||||||
char obname[BUFLEN],lfname[BUFLEN],buf[BUFLEN];
|
char obname[BUFLEN],lfname[BUFLEN],buf[BUFLEN];
|
||||||
lifeform_t *l;
|
lifeform_t *l;
|
||||||
int didmsg = B_FALSE;
|
int didmsg = B_FALSE;
|
||||||
|
@ -1215,6 +1218,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
precell = lf->cell;
|
||||||
|
|
||||||
// move out...
|
// move out...
|
||||||
lf->cell->lf = NULL;
|
lf->cell->lf = NULL;
|
||||||
|
|
||||||
|
@ -1560,9 +1565,11 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (preseenbyplayer && !cansee(player, lf) && !changedlev) {
|
if (preseenbyplayer && !cansee(player, lf) && !changedlev) {
|
||||||
if (areenemies(player, lf)) {
|
if (isadjacent(lf->cell, precell)) { // ie don't say this if we teleported/jumped
|
||||||
real_getlfnamea(lf, lfname, B_FALSE, B_FALSE);
|
if (areenemies(player, lf)) {
|
||||||
msg("%s moves out of view.", lfname);
|
real_getlfnamea(lf, lfname, B_FALSE, B_FALSE);
|
||||||
|
msg("%s %ss out of view.", lfname, getmoveverb(lf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,6 +2678,21 @@ int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
|
||||||
if (isplayer(lf) && countnoncosmeticobs(lf->cell->obpile, B_TRUE, B_TRUE)) {
|
if (isplayer(lf) && countnoncosmeticobs(lf->cell->obpile, B_TRUE, B_TRUE)) {
|
||||||
dolook(lf->cell, B_FALSE);
|
dolook(lf->cell, B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for enemies, if we teleported and now can't see the person(s) we were fleeing
|
||||||
|
// from, stop fleeing.
|
||||||
|
if (!isplayer(lf)) {
|
||||||
|
flag_t *retflag[MAXCANDIDATES];
|
||||||
|
int nretflags,i;
|
||||||
|
getflags(lf->flags, retflag, &nretflags, F_FLEEFROM, F_NONE);
|
||||||
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
lifeform_t *thisone;
|
||||||
|
thisone = findlf(lf->cell->map, retflag[i]->val[0]);
|
||||||
|
if (thisone && !haslof(lf->cell, thisone->cell, LOF_WALLSTOP, NULL)) {
|
||||||
|
killflag(retflag[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3370,6 +3392,17 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dont move out of range of lifeobs, but attacking out of range lfs is ok
|
||||||
|
if (!cell->lf) {
|
||||||
|
f = lfhasflag(lf, F_LIFEOB);
|
||||||
|
if (f) {
|
||||||
|
if (!findnearbylifeob(cell, f, NULL)) {
|
||||||
|
if (error) *error = E_WONT;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// glyph of warding?
|
// glyph of warding?
|
||||||
if (cell->writing && strstr(cell->writing, "*WARD")) {
|
if (cell->writing && strstr(cell->writing, "*WARD")) {
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
|
|
11
nexus.c
11
nexus.c
|
@ -724,11 +724,22 @@ void donextturn(map_t *map) {
|
||||||
// skip turn
|
// skip turn
|
||||||
taketime(who, SPEED_DEAD);
|
taketime(who, SPEED_DEAD);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// do we need to run away from something?
|
// do we need to run away from something?
|
||||||
if (!flee(who)) {
|
if (!flee(who)) {
|
||||||
int donormalmove = B_TRUE;
|
int donormalmove = B_TRUE;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
|
||||||
|
// charmed ?
|
||||||
|
if (donormalmove) {
|
||||||
|
f = lfhasflag(who, F_CHARMEDBY);
|
||||||
|
if (f) {
|
||||||
|
if (!charmedaction(who, f)) {
|
||||||
|
donormalmove = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// casting a spell?
|
// casting a spell?
|
||||||
if (donormalmove) {
|
if (donormalmove) {
|
||||||
f = lfhasflag(who, F_CASTINGSPELL);
|
f = lfhasflag(who, F_CASTINGSPELL);
|
||||||
|
|
157
objects.c
157
objects.c
|
@ -1026,6 +1026,23 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
||||||
}
|
}
|
||||||
if (found) break;
|
if (found) break;
|
||||||
}
|
}
|
||||||
|
// cope with "random gem"
|
||||||
|
if (!found) {
|
||||||
|
if (strstarts(p, "random gem")) {
|
||||||
|
int minrarity,maxrarity;
|
||||||
|
// want a specific rarity?
|
||||||
|
rrtorarity(wantrarity, &minrarity, &maxrarity);
|
||||||
|
|
||||||
|
ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL);
|
||||||
|
if (ot) {
|
||||||
|
// make sure it's not just a rock.
|
||||||
|
while (!hasflag(ot->flags, F_GEM)) {
|
||||||
|
ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL);
|
||||||
|
}
|
||||||
|
found = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// look up the object name
|
// look up the object name
|
||||||
|
@ -2112,10 +2129,11 @@ void addomprefix(enum OBMOD id, char *altprefix) {
|
||||||
om->naltprefix++;
|
om->naltprefix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes) {
|
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes, lifeform_t *creator) {
|
||||||
cell_t *cell[MAXCANDIDATES],*c;
|
cell_t *cell[MAXCANDIDATES],*c;
|
||||||
int ncells,i;
|
int ncells,i;
|
||||||
objecttype_t *ot;
|
objecttype_t *ot;
|
||||||
|
object_t *o;
|
||||||
|
|
||||||
ot = findotn(name);
|
ot = findotn(name);
|
||||||
if (!ot) return;
|
if (!ot) return;
|
||||||
|
@ -2125,7 +2143,10 @@ void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int all
|
||||||
c = cell[i];
|
c = cell[i];
|
||||||
if (!c->type->solid) {
|
if (!c->type->solid) {
|
||||||
if (allowdupes || !hasob(c->obpile, ot->id)) {
|
if (allowdupes || !hasob(c->obpile, ot->id)) {
|
||||||
addob(c->obpile, name);
|
o = addob(c->obpile, name);
|
||||||
|
if (o && creator) {
|
||||||
|
setobcreatedby(o, creator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6961,6 +6982,7 @@ int isidentified(object_t *o) {
|
||||||
|
|
||||||
int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) {
|
int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
|
||||||
f = hasflag(o->flags, F_IMPASSABLE);
|
f = hasflag(o->flags, F_IMPASSABLE);
|
||||||
if (f) {
|
if (f) {
|
||||||
enum LFSIZE lfsize;
|
enum LFSIZE lfsize;
|
||||||
|
@ -6986,6 +7008,7 @@ int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11785,7 +11808,6 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
|
||||||
|
|
||||||
// initial effects based on damage type
|
// initial effects based on damage type
|
||||||
if (damtype == DT_FIRE) {
|
if (damtype == DT_FIRE) {
|
||||||
|
|
||||||
if ( ((o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH) || (o->type->id == OT_CANDELABRUM)) &&
|
if ( ((o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH) || (o->type->id == OT_CANDELABRUM)) &&
|
||||||
!isactivated(o)) {
|
!isactivated(o)) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
|
@ -12301,7 +12323,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
||||||
}
|
}
|
||||||
radius = o->amt * 2;
|
radius = o->amt * 2;
|
||||||
if (radius > 10) radius = 10;
|
if (radius > 10) radius = 10;
|
||||||
addobsinradius(thrower->cell, radius, DT_COMPASS, "cloud of smoke", B_FALSE);
|
addobsinradius(thrower->cell, radius, DT_COMPASS, "cloud of smoke", B_FALSE, thrower);
|
||||||
} else if (o->type->id == OT_ASHEXPLODE) {
|
} else if (o->type->id == OT_ASHEXPLODE) {
|
||||||
char diebuf[BUFLEN];
|
char diebuf[BUFLEN];
|
||||||
// explosion!
|
// explosion!
|
||||||
|
@ -13097,9 +13119,8 @@ void timeeffectsob(object_t *o) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// check each flag for this object...
|
// check each flag for this object...
|
||||||
getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_EXPLODEONDEATH, F_MATCONVERT, F_HOT, F_OBHPDRAIN, F_ONFIRE,
|
getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_EXPLODEONDEATH, F_MATCONVERT, F_HOT, F_KNOCKAWAY, F_OBHPDRAIN, F_ONFIRE,
|
||||||
F_RECHARGE, F_REVIVETIMER, F_WALKDAM, F_WET, F_NONE);
|
F_RECHARGE, F_REVIVETIMER, F_WALKDAM, F_WET, F_NONE);
|
||||||
for (i = 0; i < nretflags; i++) {
|
for (i = 0; i < nretflags; i++) {
|
||||||
object_t *oo,*nextoo;
|
object_t *oo,*nextoo;
|
||||||
|
@ -13204,6 +13225,52 @@ void timeeffectsob(object_t *o) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((f->id == F_KNOCKAWAY) && (o->pile->where)) {
|
||||||
|
lifeform_t *lf,*creator;
|
||||||
|
object_t *oo;
|
||||||
|
lf = o->pile->where->lf;
|
||||||
|
creator = getobcreatedby(o);
|
||||||
|
if (lf && (lf != creator) ) {
|
||||||
|
char damstring[BUFLEN];
|
||||||
|
if (cansee(player, lf)) {
|
||||||
|
char lfname[BUFLEN];
|
||||||
|
getlfname(lf, lfname);
|
||||||
|
msg("^%dPowerful winds pummel %s!^n", getlfcol(lf, CC_BAD), lfname);
|
||||||
|
}
|
||||||
|
// lfs here take damage
|
||||||
|
if (creator) {
|
||||||
|
char cname[BUFLEN];
|
||||||
|
getlfname(creator, cname);
|
||||||
|
// ie. "the djinn's whirlwind"
|
||||||
|
sprintf(damstring, "%s%s %s", cname, getpossessive(cname), noprefix(obname));
|
||||||
|
} else {
|
||||||
|
// ie. "a whirlwind"
|
||||||
|
sprintf(damstring, "%s", obname);
|
||||||
|
}
|
||||||
|
losehp(lf, roll(f->text), DT_PROJECTILE, creator, damstring);
|
||||||
|
// lfs then get knocked away (and might take further damage from hitting something)
|
||||||
|
knockback(lf, getrandomdir(DT_COMPASS), f->val[0], creator, f->val[1], B_TRUE);
|
||||||
|
}
|
||||||
|
// objects get knocked away
|
||||||
|
for (oo = o->pile->where->obpile->first ; oo ; oo = oo->next) {
|
||||||
|
if (oo == o) continue;
|
||||||
|
// note: f_nopickup obs will still get moved!
|
||||||
|
if (hasflag(oo->flags, F_COSMETIC) || hasflag(oo->flags, F_CLIMBABLE) ||
|
||||||
|
(hasflag(oo->flags, F_TRAIL)) ||
|
||||||
|
(hasflag(oo->flags, F_KNOCKAWAY)) || // don't affect other wind knockaway objects
|
||||||
|
(oo->type->obclass->id == OC_BUILDING)) {
|
||||||
|
} else {
|
||||||
|
cell_t *retcell[MAXRETCELLS],*c;
|
||||||
|
int nretcells;
|
||||||
|
getradiuscells(oo->pile->where, f->val[0], DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, retcell, &nretcells, 0);
|
||||||
|
if (nretcells) {
|
||||||
|
c = retcell[rnd(0,nretcells-1)];
|
||||||
|
fireat(NULL, oo, oo->amt, c, f->val[2], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (f->id == F_OBHPDRAIN) {
|
if (f->id == F_OBHPDRAIN) {
|
||||||
enum DAMTYPE damtype;
|
enum DAMTYPE damtype;
|
||||||
int doit = B_TRUE;
|
int doit = B_TRUE;
|
||||||
|
@ -13426,6 +13493,71 @@ void timeeffectsob(object_t *o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end for each object flag
|
} // end for each object flag
|
||||||
|
|
||||||
|
|
||||||
|
// do this one after others.
|
||||||
|
if (o->pile->where) {
|
||||||
|
f = hasflag(o->flags, F_OBMOVESRANDOMLY);
|
||||||
|
if (f) {
|
||||||
|
cell_t *newcell,*c;
|
||||||
|
object_t *adjob[MAXPILEOBS*8];
|
||||||
|
int nadjobs = 0;
|
||||||
|
int possdir[8];
|
||||||
|
int npossdir = 0;
|
||||||
|
int dir;
|
||||||
|
|
||||||
|
// before moving, get a list of other adjacent objects of the same type
|
||||||
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||||
|
c = getcellindir(o->pile->where, dir);
|
||||||
|
if (c) {
|
||||||
|
object_t *oo;
|
||||||
|
for (oo = c->obpile->first ; oo ; oo = oo->next) {
|
||||||
|
if (oo->type->id == o->type->id) {
|
||||||
|
adjob[nadjobs++] = oo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now pick a direction to move.
|
||||||
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||||
|
c = getcellindir(o->pile->where, dir);
|
||||||
|
if (c) {
|
||||||
|
int ok = B_TRUE;
|
||||||
|
if (c->type->solid && (f->val[0] != B_TRUE)) {
|
||||||
|
ok = B_FALSE;
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
possdir[npossdir++] = dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (npossdir) {
|
||||||
|
int i;
|
||||||
|
dir = possdir[rnd(0,npossdir-1)];
|
||||||
|
newcell = getcellindir(o->pile->where, dir);
|
||||||
|
if (newcell->type->solid) {
|
||||||
|
// this should always kill it!
|
||||||
|
damagecell(newcell, newcell->hp, DT_DIRECT);
|
||||||
|
}
|
||||||
|
moveob(o, newcell->obpile, o->amt);
|
||||||
|
|
||||||
|
// now move other adjacent objects in the same direction (if we can).
|
||||||
|
for (i = 0; i < nadjobs; i++) {
|
||||||
|
c = getcellindir(adjob[i]->pile->where, dir);
|
||||||
|
if (c) {
|
||||||
|
if (c->type->solid) {
|
||||||
|
// this should always kill it!
|
||||||
|
damagecell(c, c->hp, DT_DIRECT);
|
||||||
|
}
|
||||||
|
moveob(adjob[i], c->obpile, adjob[i]->amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
checkflagpile(o->flags);
|
checkflagpile(o->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13983,6 +14115,19 @@ int validateobs(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
f = hasflag(ot->flags, F_HOMEOB);
|
||||||
|
if (f && (f->val[0] == NA)) {
|
||||||
|
printf("ERROR in object '%s' - has F_HOMEOB but missing pctchance in v0.\n", ot->name);
|
||||||
|
goterror = B_TRUE;
|
||||||
|
}
|
||||||
|
f = hasflag(ot->flags, F_HOMELEVOB);
|
||||||
|
if (f) {
|
||||||
|
if ((f->val[0] == NA) || (f->val[1] == NA)) {
|
||||||
|
printf("ERROR in object '%s' - has F_HOMELEVOB but missing count in v0/v1.\n", ot->name);
|
||||||
|
goterror = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f = hasflag(ot->flags, F_TECHLEVEL);
|
f = hasflag(ot->flags, F_TECHLEVEL);
|
||||||
if (f && (f->val[0] != PR_INEPT)) {
|
if (f && (f->val[0] != PR_INEPT)) {
|
||||||
if (!hasflag(ot->flags, F_HASHIDDENNAME)) {
|
if (!hasflag(ot->flags, F_HASHIDDENNAME)) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fr
|
||||||
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
||||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where, object_t *parentob);
|
obpile_t *addobpile(lifeform_t *owner, cell_t *where, object_t *parentob);
|
||||||
void addomprefix(enum OBMOD id, char *altprefix);
|
void addomprefix(enum OBMOD id, char *altprefix);
|
||||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
|
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes, lifeform_t *creator);
|
||||||
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size);
|
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size);
|
||||||
recipe_t *addrecipe(enum OBTYPE result, ...);
|
recipe_t *addrecipe(enum OBTYPE result, ...);
|
||||||
void adjustdamhardness(int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
void adjustdamhardness(int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||||
|
|
345
spell.c
345
spell.c
|
@ -4525,12 +4525,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
}
|
}
|
||||||
getlfname(target, targetname);
|
getlfname(target, targetname);
|
||||||
|
|
||||||
// only animals/humanoids
|
// if the target is of a different raceclass, you usually
|
||||||
|
// can't charm them.
|
||||||
if (getraceclass(target) != getraceclass(caster)) {
|
if (getraceclass(target) != getraceclass(caster)) {
|
||||||
if (isplayer(caster)) {
|
int willfail = B_FALSE;
|
||||||
msg("%s%s mind is too alien for you to charm.",targetname,getpossessive(targetname));
|
switch (getraceclass(target)) {
|
||||||
|
case RC_DEMON:
|
||||||
|
case RC_DRAGON:
|
||||||
|
case RC_GOD:
|
||||||
|
case RC_SLIME:
|
||||||
|
case RC_MAGIC:
|
||||||
|
case RC_PLANT:
|
||||||
|
willfail = B_TRUE;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (willfail) {
|
||||||
|
if (isplayer(caster)) {
|
||||||
|
msg("%s%s mind is too alien for you to charm.",targetname,getpossessive(targetname));
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
return B_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ischarmable(target)) {
|
if (!ischarmable(target)) {
|
||||||
|
@ -4545,6 +4560,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
case E_UNDEAD:
|
case E_UNDEAD:
|
||||||
msg("The undead are immune to charming.");
|
msg("The undead are immune to charming.");
|
||||||
break;
|
break;
|
||||||
|
case E_ALREADYUSING:
|
||||||
|
msg("%s is already charmed by another!", targetname);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
msg("You cannot charm %s.", targetname);
|
msg("You cannot charm %s.", targetname);
|
||||||
break;
|
break;
|
||||||
|
@ -4575,11 +4593,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
howlong = getspellduration(20,30,blessed) + (power*10);
|
howlong = getspellduration(2,5,blessed) + power;
|
||||||
|
|
||||||
//
|
if (isplayer(target)) {
|
||||||
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
|
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
|
||||||
addtempflag(target->flags, F_PETOF, caster->id, NA, NA, NULL, howlong);
|
} else {
|
||||||
|
// becaomes allied to caster
|
||||||
|
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
|
||||||
|
addtempflag(target->flags, F_PETOF, caster->id, NA, NA, NULL, howlong);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (spellid == OT_S_CHARMANIMAL) {
|
} else if (spellid == OT_S_CHARMANIMAL) {
|
||||||
char targetname[BUFLEN];
|
char targetname[BUFLEN];
|
||||||
|
@ -5244,10 +5266,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addobsinradius(c, 1, DT_COMPASS, "5-10 stones", B_TRUE);
|
addobsinradius(c, 1, DT_COMPASS, "5-10 stones", B_TRUE, NULL);
|
||||||
addob(c->obpile, "5-10 stones");
|
addob(c->obpile, "5-10 stones");
|
||||||
} else if (c->type->material->id == MT_BLOOD) {
|
} else if (c->type->material->id == MT_BLOOD) {
|
||||||
addobsinradius(c, 1, DT_COMPASS, "pool of blood", B_TRUE);
|
addobsinradius(c, 1, DT_COMPASS, "pool of blood", B_TRUE, NULL);
|
||||||
addob(c->obpile, "pool of blood");
|
addob(c->obpile, "pool of blood");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5453,6 +5475,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
f = addtempflag(caster->flags, F_REFLECTION, B_TRUE, NA, NA, NULL, FROMSPELL);
|
f = addtempflag(caster->flags, F_REFLECTION, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||||
f->obfrom = spellid;
|
f->obfrom = spellid;
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
} else if (spellid == OT_S_ETHEREALSTEED) {
|
||||||
|
int howlong;
|
||||||
|
howlong = power*5;
|
||||||
|
addtempflag(caster->flags, F_AUTOCREATEOB, 0, NA, NA, "whirlwind", howlong);
|
||||||
|
if (isplayer(caster)) {
|
||||||
|
msg("A spinning whirlwind lifts you off the ground!");
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
} else if (cansee(player, caster)) {
|
||||||
|
msg("A spinning whirlwind lifts %s off the ground!", castername);
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
}
|
||||||
|
addtempflag(caster->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, howlong);
|
||||||
|
addtempflag(caster->flags, F_DTIMMUNE, DT_PROJECTILE, NA, NA, NULL, howlong);
|
||||||
|
|
||||||
} else if (spellid == OT_S_EVAPORATE) {
|
} else if (spellid == OT_S_EVAPORATE) {
|
||||||
cell_t *cell[MAXCANDIDATES];
|
cell_t *cell[MAXCANDIDATES];
|
||||||
int i,ncells;
|
int i,ncells;
|
||||||
|
@ -5729,7 +5765,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
}
|
}
|
||||||
losehp(target, roll("2d6"), DT_DIRECT, caster, "terrifying nightmares");
|
losehp(target, roll("2d6"), DT_DIRECT, caster, "terrifying nightmares");
|
||||||
} else {
|
} else {
|
||||||
scare(target, caster, 5+rnd(1,power), 5+power);
|
scare(target, caster, 5+rnd(1,power), 6+power);
|
||||||
}
|
}
|
||||||
} else if (spellid == OT_S_FEEBLEMIND) {
|
} else if (spellid == OT_S_FEEBLEMIND) {
|
||||||
target = targcell->lf;
|
target = targcell->lf;
|
||||||
|
@ -6548,7 +6584,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
radius = power / 2;
|
radius = power / 2;
|
||||||
if (radius < 1) radius = 1;
|
if (radius < 1) radius = 1;
|
||||||
addobsinradius(targcell, radius, DT_ORTH, "hail storm", B_FALSE);
|
addobsinradius(targcell, radius, DT_ORTH, "hail storm", B_FALSE, caster);
|
||||||
|
|
||||||
// replace damage per sec with power d4
|
// replace damage per sec with power d4
|
||||||
asprintf(&dambuf, "%dd4", power);
|
asprintf(&dambuf, "%dd4", power);
|
||||||
|
@ -7656,6 +7692,85 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
fizzle(caster);
|
fizzle(caster);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
} else if (spellid == OT_S_PLANTWALK) {
|
||||||
|
int x,y;
|
||||||
|
cell_t *poss[MAX_MAPW*MAX_MAPH];
|
||||||
|
object_t *srcob;
|
||||||
|
int nposs = 0;
|
||||||
|
srcob = hasobofclass(targcell->obpile, OC_FLORA);
|
||||||
|
if (!srcob) {
|
||||||
|
fizzle(caster);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// after this point the spell always counts as successful
|
||||||
|
// (ie. costs mana)
|
||||||
|
if (isplayer(caster)) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
getobname(srcob, obname, 1);
|
||||||
|
msg("You touch %s.", obname);
|
||||||
|
} else if (cansee(player, caster)) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
getobname(srcob, obname, 1);
|
||||||
|
msg("%s touches %s.", castername, obname);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = 0; y < caster->cell->map->h; y++) {
|
||||||
|
for (x = 0; x < caster->cell->map->w; x++) {
|
||||||
|
cell_t *c;
|
||||||
|
c = getcellat(caster->cell->map, x, y);
|
||||||
|
if (c && (c != targcell)) {
|
||||||
|
if ((power == 1) && hasob(c->obpile, srcob->type->id)) {
|
||||||
|
poss[nposs++] = c;
|
||||||
|
} else if ((power == 2) && hasobofclass(c->obpile, OC_FLORA)) {
|
||||||
|
poss[nposs++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no possible destinations?
|
||||||
|
if (!nposs) {
|
||||||
|
if (isplayer(caster) || cansee(player, caster)) {
|
||||||
|
nothinghappens();
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isplayer(caster)) {
|
||||||
|
int i;
|
||||||
|
// reveal all potential locations
|
||||||
|
for (i = 0; i < nposs; i++) {
|
||||||
|
setcellknown(poss[i], PR_EXPERT);
|
||||||
|
}
|
||||||
|
// then ask to select one
|
||||||
|
targcell = real_askcoords("Travel where?", "Plantwalk->", TT_SPECIFIED, player, UNLIMITED, LOF_DONTNEED, B_FALSE, poss, nposs);
|
||||||
|
if (!hasobofclass(targcell->obpile, OC_FLORA)) {
|
||||||
|
targcell = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
targcell = poss[rnd(0,nposs-1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targcell) {
|
||||||
|
fizzle(caster);
|
||||||
|
// purposely returning false here, since we've already revealed
|
||||||
|
// some information to the caster.
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cellwalkable(caster, targcell, NULL)) {
|
||||||
|
targcell = real_getrandomadjcell(targcell, WE_WALKABLE, B_NOEXPAND, LOF_DONTNEED, NULL, NULL);
|
||||||
|
if (!targcell) {
|
||||||
|
fizzle(caster);
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// teleport to destination.
|
||||||
|
msg("orig cell: %d,%d.", caster->cell->x, caster->cell->y);
|
||||||
|
teleportto(caster, targcell, B_FALSE);
|
||||||
|
msg("new cell: %d,%d.", caster->cell->x, caster->cell->y);
|
||||||
} else if (spellid == OT_S_PARALYZE) {
|
} else if (spellid == OT_S_PARALYZE) {
|
||||||
int howlong;
|
int howlong;
|
||||||
int saved = B_FALSE;
|
int saved = B_FALSE;
|
||||||
|
@ -8649,7 +8764,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
for (o = op->first ; o ; o = nexto) {
|
for (o = op->first ; o ; o = nexto) {
|
||||||
nexto = o->next;
|
nexto = o->next;
|
||||||
if (!hasflag(o->flags, F_NOSTEAL)) {
|
if (!hasflag(o->flags, F_NOSTEAL) && !hasflag(o->flags, F_NOPICKUP) && !hasflag(o->flags, F_COSMETIC)) {
|
||||||
if ((getobunitweight(o) <= 5) ||
|
if ((getobunitweight(o) <= 5) ||
|
||||||
((isweapon(o)) && (isequipped(o))) ) {
|
((isweapon(o)) && (isequipped(o))) ) {
|
||||||
poss[nposs++] = o;
|
poss[nposs++] = o;
|
||||||
|
@ -9702,7 +9817,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
radius = power / 2;
|
radius = power / 2;
|
||||||
if (radius < 1) radius = 1;
|
if (radius < 1) radius = 1;
|
||||||
addobsinradius(targcell, radius, DT_ORTH, "storm of sleet", B_FALSE);
|
addobsinradius(targcell, radius, DT_ORTH, "storm of sleet", B_FALSE, caster);
|
||||||
} else {
|
} else {
|
||||||
failed = B_TRUE;
|
failed = B_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -10846,29 +10961,144 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
stopspell(caster, spellid);
|
stopspell(caster, spellid);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
} else if (spellid == OT_S_WALLOFFIRE) {
|
||||||
|
object_t *o;
|
||||||
|
cell_t *c;
|
||||||
|
int vdist = 0,hdist = 0;
|
||||||
|
int vbad = B_FALSE, hbad = B_FALSE;
|
||||||
|
int walldir;
|
||||||
|
int seen = B_FALSE;
|
||||||
|
char firename[BUFLEN];
|
||||||
|
|
||||||
|
if (power < 5) {
|
||||||
|
sprintf(firename, "small fire");
|
||||||
|
} else if (power < 8) {
|
||||||
|
sprintf(firename, "medium fire");
|
||||||
|
} else {
|
||||||
|
sprintf(firename, "large fire");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get vert distance
|
||||||
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_N)) {
|
||||||
|
vdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
vbad = B_TRUE; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_S)) {
|
||||||
|
vdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
vbad = B_TRUE; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// get horz dist
|
||||||
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_E)) {
|
||||||
|
hdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
hbad = B_TRUE; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_W)) {
|
||||||
|
hdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
hbad = B_TRUE; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vbad) vdist = 0;
|
||||||
|
if (hbad) hdist = 0;
|
||||||
|
|
||||||
|
if ((vdist == 0) && (hdist == 0)) {
|
||||||
|
fizzle(caster);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// select direction
|
||||||
|
if (vdist < hdist) {
|
||||||
|
walldir = D_N;
|
||||||
|
} else if (hdist < vdist) {
|
||||||
|
walldir = D_E;
|
||||||
|
} else {
|
||||||
|
if (onein(2)) {
|
||||||
|
walldir = D_N;
|
||||||
|
} else {
|
||||||
|
walldir = D_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walldir == D_N) {
|
||||||
|
// vert wall
|
||||||
|
for (c = targcell ; (c == targcell) || c->lf || cellwalkable(NULL, c, NULL); c = getcellindir(c, D_N)) {
|
||||||
|
if (!seen && haslos(player, c)) seen = B_TRUE;
|
||||||
|
o = addob(c->obpile, firename);
|
||||||
|
}
|
||||||
|
for (c = getcellindir(targcell, D_S) ;
|
||||||
|
(c == targcell) || c->lf || cellwalkable(NULL, c, NULL);
|
||||||
|
c = getcellindir(c, D_S)) {
|
||||||
|
if (!seen && haslos(player, c)) seen = B_TRUE;
|
||||||
|
o = addob(c->obpile, firename);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// horz wall
|
||||||
|
for (c = targcell ; (c == targcell) || c->lf || cellwalkable(NULL, c, NULL); c = getcellindir(c, D_E)) {
|
||||||
|
if (!seen && haslos(player, c)) seen = B_TRUE;
|
||||||
|
o = addob(c->obpile, firename);
|
||||||
|
}
|
||||||
|
for (c = getcellindir(targcell, D_W) ;
|
||||||
|
(c == targcell) || c->lf || cellwalkable(NULL, c, NULL);
|
||||||
|
c = getcellindir(c, D_W)) {
|
||||||
|
if (!seen && haslos(player, c)) seen = B_TRUE;
|
||||||
|
o = addob(c->obpile, firename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seen) {
|
||||||
|
drawscreen();
|
||||||
|
msg("A wall of fire appears!");
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
}
|
||||||
|
if (isplayer(caster)) {
|
||||||
|
angergodmaybe(R_GODNATURE, 25, GA_HERESY);
|
||||||
|
}
|
||||||
} else if (spellid == OT_S_WALLOFICE) {
|
} else if (spellid == OT_S_WALLOFICE) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
int donesomething = B_FALSE;
|
int donesomething = B_FALSE;
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
int vdist = 0,hdist = 0;
|
int vdist = 0,hdist = 0;
|
||||||
|
int vbad = B_FALSE, hbad = B_FALSE;
|
||||||
int walldir;
|
int walldir;
|
||||||
int seen = B_FALSE;
|
int seen = B_FALSE;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
// get vert distance
|
// get vert distance
|
||||||
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_N)) {
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_N)) {
|
||||||
vdist++;
|
vdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
vbad = B_TRUE; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_S)) {
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_S)) {
|
||||||
vdist++;
|
vdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
vbad = B_TRUE; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// get horz dist
|
// get horz dist
|
||||||
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_E)) {
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_E)) {
|
||||||
hdist++;
|
hdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
hbad = B_TRUE; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_W)) {
|
for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_W)) {
|
||||||
hdist++;
|
hdist++;
|
||||||
|
if (c->lf && (c->lf == caster)) {
|
||||||
|
hbad = B_TRUE; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vbad) vdist = 0;
|
||||||
|
if (hbad) hdist = 0;
|
||||||
|
|
||||||
if ((vdist == 0) && (hdist == 0)) {
|
if ((vdist == 0) && (hdist == 0)) {
|
||||||
fizzle(caster);
|
fizzle(caster);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
@ -11161,6 +11391,93 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
msg("A positive gravity field forms around %s!", castername);
|
msg("A positive gravity field forms around %s!", castername);
|
||||||
}
|
}
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
} else if ((spellid == OT_S_WHIRLWIND) || (spellid == OT_S_TORNADO) || (spellid == OT_S_HURRICANE)) {
|
||||||
|
int failed = B_FALSE;
|
||||||
|
char obname[BUFLEN],obdesc[BUFLEN];
|
||||||
|
switch (spellid) {
|
||||||
|
case OT_S_HURRICANE:
|
||||||
|
strcpy(obname, "hurricane");
|
||||||
|
strcpy(obdesc, "raging hurricane");
|
||||||
|
break;
|
||||||
|
case OT_S_TORNADO:
|
||||||
|
strcpy(obname, "tornado");
|
||||||
|
strcpy(obdesc, "towering tornado");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case OT_S_WHIRLWIND:
|
||||||
|
strcpy(obname, "whirlwind");
|
||||||
|
strcpy(obdesc, "spinning whirlwind");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (targcell) {
|
||||||
|
cell_t *c[5];
|
||||||
|
int ncells = 0,i,ndone = 0,doneannounce = B_FALSE;
|
||||||
|
if (spellid == OT_S_HURRICANE) {
|
||||||
|
c[0] = targcell;
|
||||||
|
c[1] = getcellindir(targcell, DC_N);
|
||||||
|
c[2] = getcellindir(targcell, DC_E);
|
||||||
|
c[3] = getcellindir(targcell, DC_S);
|
||||||
|
c[4] = getcellindir(targcell, DC_W);
|
||||||
|
ncells = 5;
|
||||||
|
} else {
|
||||||
|
c[0] = targcell;
|
||||||
|
ncells = 1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ncells; i++) {
|
||||||
|
if (c[i]) {
|
||||||
|
int ok = B_TRUE;
|
||||||
|
if (c[i]->type->solid) {
|
||||||
|
if (spellid == OT_S_HURRICANE) {
|
||||||
|
// this should always kill it!
|
||||||
|
damagecell(c[i], c[i]->hp, DT_DIRECT);
|
||||||
|
} else {
|
||||||
|
ok = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
flag_t *f;
|
||||||
|
object_t *o;
|
||||||
|
// create flame there
|
||||||
|
if (haslos(player, c[i])) {
|
||||||
|
if (!doneannounce) {
|
||||||
|
msg("A %s appears!", obdesc);
|
||||||
|
doneannounce = B_TRUE;
|
||||||
|
}
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
}
|
||||||
|
o = addob(c[i]->obpile, obname);
|
||||||
|
// magically boost hp based on power
|
||||||
|
f = hasflag(o->flags, F_OBHP);
|
||||||
|
if (f) {
|
||||||
|
f->val[0] += (power*6);
|
||||||
|
// centre hurricane lasts a bit longer
|
||||||
|
if (i == 0) {
|
||||||
|
f->val[0] += 5;
|
||||||
|
}
|
||||||
|
f->val[1] = f->val[0];
|
||||||
|
}
|
||||||
|
setobcreatedby(o, caster);
|
||||||
|
// for non-centre hurricanes, remove randommove flag
|
||||||
|
// (they will move with the original)
|
||||||
|
if (i != 0) {
|
||||||
|
killflagsofid(o->flags, F_OBMOVESRANDOMLY);
|
||||||
|
}
|
||||||
|
ndone++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ndone) {
|
||||||
|
failed = B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
failed = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
fizzle(caster);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
} else if (spellid == OT_S_WINDSHIELD) {
|
} else if (spellid == OT_S_WINDSHIELD) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
// always targetted at caster
|
// always targetted at caster
|
||||||
|
|
Loading…
Reference in New Issue