- [+] move pctchance for individual spells from F_AICASTTOxxx to
F_AISPELLTARGETOVERRIDE v2. - [+] change code: - [+] F_AISPELLTARGETOVERRIDE v0=spellid, v1=F_AICASTTOxxx v2=TT_xxx text=pctchance or NULL. - [+] aispellok(xx, purpose) : check this _before_ checking spell->f_aicasttoxxx - [+] add spelltargetoverride for vampire - [+] add spelltargetoverride for werewolf - [+] retain F_FLEEFROM on polymorph. - [+] lycanthropes - [+] show up as "human" unless your animal/magic lore is high enough - [+] vulnerable to silver weapons - [+] Wererat (3hd, weapon damage) - [+] uses short blades - [+] stench - [+] want alcohol? - [+] transform into fast version of rat. plague rat? - [+] summon small animals. summon # override? "count:" - [+] Werewolf (4hd, 6 dam) - [+] summon wolves ? - [+] shapeshift to dire wolf - [+] regenerates - [+] firstaid skill (fast healing when resting) - [+] Werebear - [+] 6 hd - [+] shapeshift to grizzly bear - [+] summon 2-3 black bears - [+] firstaid skill (fast healing) - [+] shapeshifting monsters sometimes start as animal form - [+] if you are good/evil different alignments, mosnters should flat out refuse to join you. - [+] more different sayphrases for recruitment. - [+] when placing homelevobs, try to stick to rooms, not corridors - [+] getrandomroomcell() needs WE_xxx argument. - [+] implement cellmatchescondition(c, cond) - [+] real_getrandomadjcell() should use this too - [+] swoop ability should only work with claw attacks - [+] F_FORCEATTACKOB - [+] getweapons() needs to honour this. - [+] spell.c: check if you have the right attack type - [+] aispellok: only if you have the right attack yype - [+] horse - 2hd, brown u - [+] Hippogriff (3hd , horse/eagle, 'u') - yellow - [+] centaur (4hd, u) - grey - [+] make pegasus be cyan - [+] CATs - [+] Griffon (7hd, tr4-5, u, hates horses) - lion/eagle - yellow 'f'
This commit is contained in:
parent
192afcec2b
commit
5d61533c15
38
ai.c
38
ai.c
|
@ -895,7 +895,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
} else {
|
||||
getflags(lf->flags, retflag, &nretflags, F_HATESRACEWITHFLAG, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (lfhasflag(who, retflag[i]->id) &&
|
||||
if (lfhasflagval(who, retflag[i]->val[0], retflag[i]->val[1], retflag[i]->val[2], NA, NULL) &&
|
||||
!areallies(lf, who)) {
|
||||
|
||||
if (db) dblog(".oO { found a target with hated flags - lfid %d (%s) ! }",who->id, who->race->name);
|
||||
|
@ -2096,6 +2096,9 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
int needlos = B_TRUE;
|
||||
enum LOFTYPE needlof = LOF_NEED;
|
||||
|
||||
int castchance = 0;
|
||||
enum SPELLTARGET targettype = TT_NONE;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
|
@ -2177,11 +2180,31 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
}
|
||||
|
||||
f = hasflag(ot->flags, purpose);
|
||||
f = lfhasflagval(lf, F_AISPELLTARGETOVERRIDE, ot->id, purpose, NA, NULL);
|
||||
if (f) {
|
||||
if ((f->val[1] == NA) || pctchance(f->val[1])) {
|
||||
if (strlen(f->text)) {
|
||||
castchance = atoi(f->text);
|
||||
} else {
|
||||
castchance = 100;
|
||||
}
|
||||
targettype = f->val[2];
|
||||
} else {
|
||||
f = hasflag(ot->flags, purpose);
|
||||
if (f) {
|
||||
if (f->val[1] == NA) {
|
||||
castchance = 100;
|
||||
} else {
|
||||
castchance = f->val[1];
|
||||
}
|
||||
targettype = f->val[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (f) {
|
||||
if (pctchance(castchance)) {
|
||||
int range;
|
||||
switch (f->val[0]) {
|
||||
switch (targettype) {
|
||||
case ST_VICTIM:
|
||||
range = getspellrange(lf, spellid, getspellpower(lf, spellid));
|
||||
if ((range == UNLIMITED) || (getcelldist(lf->cell, victim->cell) <= range)) {
|
||||
|
@ -2229,10 +2252,13 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
case ST_SPECIAL:
|
||||
specialcase = B_TRUE;
|
||||
break;
|
||||
case ST_NONE:
|
||||
ok = B_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
// now check for line of sight / fire
|
||||
switch (f->val[0]) {
|
||||
switch (targettype) {
|
||||
case ST_VICTIM:
|
||||
case ST_ADJVICTIM:
|
||||
if (needlos && (!victim || !cansee(lf, victim)) ) {
|
||||
|
@ -2533,6 +2559,8 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
specificcheckok = B_FALSE;
|
||||
} else if ((ot->id == OT_A_SWOOP) && !lfhasflag(lf, F_FLYING)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if ((ot->id == OT_A_SWOOP) && !lfhasflagval(lf, F_HASATTACK, OT_CLAWS, NA, NA, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (getcelldist(lf->cell, victim->cell) > srange) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (getcelldist(lf->cell, victim->cell) == 1) { // ie already adjacent
|
||||
|
|
293
data.c
293
data.c
|
@ -3984,7 +3984,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how powerful a creature you can become.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
oooooooo
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
// l5
|
||||
|
@ -7816,7 +7815,7 @@ void initrace(void) {
|
|||
|
||||
// races / monsters
|
||||
// playable races
|
||||
addrace(R_HUMAN, "human", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID, "Your average example of the Homo Sapiens species.");
|
||||
addrace(R_HUMAN, "human", 75, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Your average example of the Homo Sapiens species.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
|
@ -8917,6 +8916,42 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior");
|
||||
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||
|
||||
addrace(R_CENTAUR, "centaur", 500, 'u', C_GREY, MT_FLESH, RC_ANIMAL, "Centaurs look like horses with their neck upwards replaced by a human torso and arms.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_RANDOM, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_HOOF, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_HOOF, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
|
||||
// 50% chance of a shortbow.
|
||||
// if not, then 50% chance of a longbow
|
||||
f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "short bow");
|
||||
addcondition(f, FC_NOCONDITION, 50);
|
||||
addaltval(f, F_STARTOB, 50, NA, NA, "longbow");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10-30 arrows");
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield");
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "lance");
|
||||
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-20 gold coins");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain");
|
||||
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_RANGED, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_SHIELDS, PR_ADEPT, NA, NULL);
|
||||
|
||||
addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_DRAGON, "A small two-legged wyrm with a rooster's head. Its touch is said to petrify the flesh of living creatures.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_WINGS, NULL);
|
||||
|
@ -9324,7 +9359,7 @@ void initrace(void) {
|
|||
// TODO: storm giant
|
||||
// TODO: storm titan
|
||||
|
||||
addrace(R_GNOLL, "gnoll", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Gnolls are doglike warriors - the gladiators of the kobold race. They are highly organised and often travel in packs.");
|
||||
addrace(R_GNOLL, "gnoll", 130, 'k', C_YELLOW, MT_FLESH, RC_HUMANOID, "Gnolls are doglike warriors - the gladiators of the kobold race. They are highly organised and often travel in packs.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
setbodypartname(lastrace, BP_HANDS, "claws");
|
||||
setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw");
|
||||
|
@ -9650,6 +9685,74 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANCAST, OT_S_GASEOUSFORM, NA, NA, "pw:1;");
|
||||
// gremlins also cause tech to fail around them.
|
||||
|
||||
addrace(R_GRIFFON, "griffon", 220, 'f', C_YELLOW, MT_FLESH, RC_ANIMAL, "Griffons have a lion's body and the head, torso and forelegs of an eagle.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, 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, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EVASION, 20, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
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_MAXATTACKS, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 14, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screeches");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain");
|
||||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 8, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SWOOPRANGE, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EQUINE, B_COVETS, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_EQUINE, NA, NA, NULL);
|
||||
|
||||
addrace(R_HIPPOGRIFF, "hippogriff", 500, 'u', C_YELLOW, MT_FLESH, RC_ANIMAL, "Hippogriffs are fierce hybrids of a horse and an eagle. Their head, wings and claws take the form of the latter.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
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_HITDICE, 3, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 10, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
|
||||
addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_YELLOW, MT_FLESH, RC_HUMANOID, "A larger, stronger, smarter and more menacing form of a goblin.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
|
@ -9934,7 +10037,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
|
@ -10281,9 +10384,10 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "80");
|
||||
|
||||
addrace(R_PEGASUS, "pegasus", 130, 'Q', C_WHITE, MT_FLESH, RC_MAGIC, "A legendary white, winged horse.");
|
||||
addrace(R_PEGASUS, "pegasus", 500, 'u', C_CYAN, MT_FLESH, RC_ANIMAL, "A legendary white, winged horse.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANTALK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 57, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, 57, NA, NULL);
|
||||
|
@ -10304,13 +10408,15 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SMITEEVIL, NA, NA, "pw:8;");
|
||||
addflag(lastrace->flags, F_SWOOPRANGE, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SMITEEVIL, NA, NA, "pw:8;");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain");
|
||||
addflag(lastrace->flags, F_RESISTMAG, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 25, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||
addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_PIXIE, "pixie", 5, 'n', C_GREEN, MT_FLESH, RC_MAGIC, "A small magical woodland creature, flying around on moth-like wings.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
|
@ -11762,7 +11868,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_S_WATERJET, NA, NA, "pw:4;");
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_FLOOD, ST_SELF, NA, NULL);
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_FLOOD, F_AICASTTOATTACK, ST_SELF, "100");
|
||||
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "hop");
|
||||
addflag(lastrace->flags, F_EATCONFER, F_BREATHWATER, B_TRUE, NA, "50");
|
||||
|
||||
|
@ -11906,7 +12012,30 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_TAMABLE, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
|
||||
|
||||
|
||||
addrace(R_HORSE, "horse", 500, 'u', C_BROWN, MT_FLESH, RC_ANIMAL, "Large quadrapeds with many purposes: transport, moving goods, pulling ploughs to name but a few.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_HOOF, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_HOOF, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 80, NA, NA, "");
|
||||
addflag(lastrace->flags, F_MORALE, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_FROG, "impaler frog", 10, ';', C_BOLDGREEN, MT_FLESH, RC_ANIMAL, "As their name implies, impaler frogs are dangerous frogs whose tongues end in a very sharp point. They use this to spear their enemies from afar, often while hiding underwater.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
|
@ -12212,7 +12341,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp spines");
|
||||
addflag(lastrace->flags, F_CORPSEFLAG, F_SHARP, 1, 4, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
|
||||
addrace(R_RAT, "dire rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL, "A rodent of unusual size.");
|
||||
|
||||
addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL, "An aggressive rodent, approximately the size of a cat.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -12237,6 +12367,58 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_RATDIRE, "dire rat", 3, 'r', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Dire rats are massive rats, larger than most dogs. Unlike dogs, dire rats are equipped with razor sharp shark-like teeth and their bite is very much worse than their bark.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 8, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 7, NA, NA, NULL);
|
||||
|
||||
addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, "");
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_FREQUENT, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 10, "2-4");
|
||||
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian
|
||||
setbodytype(lastrace, BT_BIRD);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
|
||||
|
@ -12687,6 +12869,7 @@ void initrace(void) {
|
|||
addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Highly intelligent members of the canine family.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
|
@ -12721,6 +12904,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, "");
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
|
||||
|
@ -13963,7 +14147,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_DEAF, B_TRUE, 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_GREY, 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);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
|
||||
|
@ -14181,6 +14365,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:3;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_STUN, 5, 5, "pw:1;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:vampire bat;");
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOATTACK, ST_SELF, "100");
|
||||
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DETECTOBS, 10, OT_COFFIN, NA, NULL);
|
||||
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pile of ash");
|
||||
|
@ -14191,6 +14376,86 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
addrace(R_WEREBEAR, "werebear", 90, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Stout, well-muscled humans with large, thick beards.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MATVULN, MT_SILVER, 200, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLSPEED, SP_SLOW, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d8;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:grizzly bear;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSLG, 10, 10, "pw:5;race:black bear;count:2;");
|
||||
addflag(lastrace->flags, F_CASTCHANCE, 20, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "bares its teeth");
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOATTACK, ST_SELF, "100");
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_UNARMED, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "hatchet");
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HATESRACE, R_WERERAT, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HATESRACE, R_WEREWOLF, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_WERERAT, "wererat", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Weedy humans with shifty eyes and whiskers, wererats are known for their extreme cunning.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MATVULN, MT_SILVER, 200, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 7, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLSPEED, SP_ULTRAFAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:plague rat;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSSM, 10, 10, "pw:5;race:giant rat;count:5;");
|
||||
addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_SHORTBLADES, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTOB, 10, NA, NA, "potion of rum");
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOFLEE, ST_SELF, "100");
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_THIEVERY, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTS, OT_POT_RUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "twitches its nose");
|
||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||
|
||||
addrace(R_WEREWOLF, "werewolf", 100, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Shaggy humans with the uncanny ability to shapeshift into a ferocious wolf.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
|
@ -14200,10 +14465,10 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "3d6");
|
||||
addflag(lastrace->flags, F_MATVULN, MT_SILVER, 200, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
|
@ -14214,11 +14479,17 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SHAPESHIFT, 3, 3, "pw:1;race:dire wolf;");
|
||||
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSMD, 10, 10, "pw:5;race:young wolf;");
|
||||
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_SHAPESHIFT, F_AICASTTOATTACK, ST_SELF, "100");
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "howls");
|
||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_LYCANTHROPE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); // ie. cats will know!
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||
|
||||
// special monsters
|
||||
|
|
42
defs.h
42
defs.h
|
@ -62,6 +62,7 @@
|
|||
//#define UNI_SOLID '#'
|
||||
|
||||
// getrandomemptycell() params
|
||||
#define WE_NONE 0
|
||||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
#define WE_PORTAL 3
|
||||
|
@ -982,6 +983,7 @@ enum RACE {
|
|||
// monsters
|
||||
R_BEHOLDER,
|
||||
R_BUGBEAR,
|
||||
R_CENTAUR,
|
||||
R_COCKATRICE,
|
||||
R_CREEPINGCLAW,
|
||||
R_CRYMIDIA,
|
||||
|
@ -1003,6 +1005,8 @@ enum RACE {
|
|||
R_GOBLINWAR,
|
||||
R_GOBLINSHOOTER,
|
||||
R_GREMLIN,
|
||||
R_GRIFFON,
|
||||
R_HIPPOGRIFF,
|
||||
R_HOBGOBLIN,
|
||||
R_HOBGOBLINWAR,
|
||||
R_KOBOLD,
|
||||
|
@ -1046,6 +1050,8 @@ enum RACE {
|
|||
R_TROLLSNOW,
|
||||
R_TROLLSWAMP,
|
||||
R_VAMPIRE,
|
||||
R_WEREBEAR,
|
||||
R_WERERAT,
|
||||
R_WEREWOLF,
|
||||
R_XAT,
|
||||
// fish
|
||||
|
@ -1094,12 +1100,15 @@ enum RACE {
|
|||
R_HAWKYOUNG,
|
||||
R_HAWKBLOOD,
|
||||
R_HAWKFROST,
|
||||
R_HORSE,
|
||||
R_FROG,
|
||||
R_LEECH,
|
||||
R_MAMMOTH,
|
||||
R_NEWT,
|
||||
R_PORCUPINE,
|
||||
R_RAT,
|
||||
R_RATDIRE,
|
||||
R_RATPLAGUE,
|
||||
R_ROC,
|
||||
R_SLUG,
|
||||
R_SNAIL,
|
||||
|
@ -2243,6 +2252,14 @@ enum SLEEPTYPE {
|
|||
ST_KO,
|
||||
};
|
||||
|
||||
|
||||
enum ANIMALTYPE {
|
||||
AT_AVIAN,
|
||||
AT_CANINE,
|
||||
AT_EQUINE,
|
||||
AT_FELINE,
|
||||
};
|
||||
|
||||
enum FLAG {
|
||||
F_NONE = 0, // dummy flag
|
||||
// map flags
|
||||
|
@ -2326,8 +2343,10 @@ enum FLAG {
|
|||
F_THROWMISSILE, // weapon would make a good thrown missle - used by AI
|
||||
F_CANHOME, // this object can have the 'homing' flag
|
||||
F_UNIQUE, // only one may appear
|
||||
F_GLYPH, // override the glyph with the first char of text.
|
||||
F_GLYPH, // override the glyph with f->val[1]
|
||||
// v0 is either NA (white) or colourid (C_xxx).
|
||||
// OPTIONAL v2: if you lorelev for this race is less
|
||||
// then v2,
|
||||
F_NOGLYPH, // this object doesn't appear normally
|
||||
F_COSMETIC, // this object is mostly cosmetic, don't say 'you see xx'
|
||||
// also don't stop the player running past it.
|
||||
|
@ -3003,6 +3022,8 @@ enum FLAG {
|
|||
// sight
|
||||
F_HATESRACECLASS, // lf will attack lfs with raceclass->id=v0
|
||||
F_HATESRACEWITHFLAG, // lf will attack lfs with flag v0 on sight
|
||||
// will also check flag v0=this v1 and
|
||||
// flag v1 = this v2
|
||||
F_TERRITORIAL, // lf will attack ALL other visible lfs within range v0
|
||||
F_HARMLESS, // it is safe to rest around this lf
|
||||
F_RNDHOSTILE, // v0% chance of being hostile.
|
||||
|
@ -3010,8 +3031,8 @@ enum FLAG {
|
|||
F_FRIENDLY, // lf will attack all non-players if in sight
|
||||
F_FATALFOOD, // if lf eats food with id = v0, they die.
|
||||
F_NATURALFLIGHT, // lf can fly natural using wings or similar
|
||||
F_WANTS, // lf will try to pick up object type val0. if
|
||||
// val1 = B_COVETS, will even abandon attacks
|
||||
F_WANTS, // lf will try to pick up object type val0.
|
||||
// if val1 = B_COVETS, will even abandon attacks
|
||||
// for it!
|
||||
F_WANTSOBFLAG, // lf will look for obs with this flag. val1=covets
|
||||
F_WANTSBETTERWEP, // lf will look for better weapons, val1=covets
|
||||
|
@ -3062,9 +3083,13 @@ enum FLAG {
|
|||
// for spellid v0
|
||||
F_SPELLCASTTIME, // override F_CASTINGTIME to v0 when this lf
|
||||
// casts spellid v1.
|
||||
F_AISPELLTARGETOVERRIDE, // when casting spellid v0, this lf will
|
||||
// use v1 (ST_xxx) instead of what the AICASTTOxxx
|
||||
// flag specifies.
|
||||
F_AISPELLTARGETOVERRIDE, // when casting spellid v0,
|
||||
// use AICASTTOxxx=v1 instead of the one
|
||||
// from the spell.
|
||||
// use targettype = v2, intsead of the one
|
||||
// from the spell.
|
||||
// OPTIONAL: text = pctchance to cast for
|
||||
// thispurpose. if not given, chance is 100.
|
||||
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
||||
F_NODEATHSPEECH, // lf doesn't talk when dying
|
||||
F_BEHEADED, // use special corpse drop code
|
||||
|
@ -3142,12 +3167,16 @@ enum FLAG {
|
|||
F_AQUATIC, // this race can attack normally in water and suffers no
|
||||
// movement penalties. they can also swim at master
|
||||
// level.
|
||||
|
||||
F_AVIAN, // this race is an avian
|
||||
F_CANINE, // this race is a canine
|
||||
F_EQUINE, // this race is an equine
|
||||
F_FELINE, // this race is a feline
|
||||
|
||||
F_HUMANOID, // this race is a humanoid
|
||||
// (can wear armour / use weapons)
|
||||
F_INSECT, // this race is classed as an insect
|
||||
F_LYCANTHROPE, // this race is a lycanthrope
|
||||
F_UNDEAD, // this race is classed as undead
|
||||
F_COLDBLOOD, // this race is coldblooded
|
||||
F_NOBODYPART, // this race doesn't have bodypart val0
|
||||
|
@ -3349,6 +3378,7 @@ enum FLAG {
|
|||
F_HASATTACK, // v0 = obid to use when attacking unarmed
|
||||
// if v1 is set, it overrides DR(damagerating)
|
||||
// if text is set, it overrides the damage
|
||||
F_FORCEATTACK, // this lf may only attack using F_HASATTACK v0
|
||||
F_EVASION, // % chance of evading an attack
|
||||
|
||||
// healing/resting/training
|
||||
|
|
|
@ -11,7 +11,7 @@ A = avian / bird
|
|||
b = small roBot
|
||||
B = bat
|
||||
c = cockatrice / chicken / small bird
|
||||
C = celestial / divine ?
|
||||
C = ? celestial/divine?
|
||||
d = canine/dog
|
||||
D = ?
|
||||
e = eye or floating thing
|
||||
|
@ -25,9 +25,11 @@ H = large humanoid
|
|||
i = insect
|
||||
I = large insect
|
||||
j = jelly/ooze/leech
|
||||
k = kobold
|
||||
J = ?
|
||||
k = dog-like humanoid (kobold, gnoll)
|
||||
K = ?
|
||||
L = lich, or other powerful undead ?
|
||||
m = mutant / magic creature
|
||||
m = mutant / hybrid creature
|
||||
M = mummy
|
||||
n = small humanoid / nymph / sprite
|
||||
N = ling / alieN creature
|
||||
|
@ -35,7 +37,7 @@ o = orc
|
|||
O = monstrous humanoid (ie. ogre)
|
||||
P = gastropod
|
||||
p = sPirit
|
||||
q = quadraped
|
||||
q = medium quadraped
|
||||
Q = large quadraped
|
||||
r = rodent
|
||||
R = robot
|
||||
|
@ -43,7 +45,7 @@ s = snake
|
|||
S = spider
|
||||
t = troll
|
||||
T = walkingtree-like monster (dryad, treant)
|
||||
u = ? make this be horse? if so, change pegasus.
|
||||
u = horse.
|
||||
U = unearthly/horrific creature
|
||||
v = ?
|
||||
V = vampire
|
||||
|
|
18
io.c
18
io.c
|
@ -11771,14 +11771,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
// non-intrinsic effecst like polymorph, eye shading
|
||||
f = lfhasknownflag(lf, F_POLYMORPHED);
|
||||
if (f && (f->known)) {
|
||||
snprintf(buf, BUFLEN, "%s have been polymorphed into a %s.",you(lf), lf->race->name);
|
||||
//if (lfhasflag(lf, F_OMNIPOTENT) || lfhasflag(lf, F_EXTRAINFO)) {
|
||||
snprintf(buf2, BUFLEN, " [%d left]", f->lifetime);
|
||||
strcat(buf, buf2);
|
||||
// }
|
||||
wrapprint(mainwin, &y, &x, 0, "%s ", buf);
|
||||
if (isplayer(lf)) {
|
||||
f = lfhasknownflag(lf, F_POLYMORPHED);
|
||||
if (f && (f->known)) {
|
||||
snprintf(buf, BUFLEN, "%s have been polymorphed into a %s.",you(lf), lf->race->name);
|
||||
//if (lfhasflag(lf, F_OMNIPOTENT) || lfhasflag(lf, F_EXTRAINFO)) {
|
||||
snprintf(buf2, BUFLEN, " [%d left]", f->lifetime);
|
||||
strcat(buf, buf2);
|
||||
// }
|
||||
wrapprint(mainwin, &y, &x, 0, "%s ", buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (!canuseweapons(lf)) {
|
||||
|
|
181
lf.c
181
lf.c
|
@ -2856,7 +2856,7 @@ void die(lifeform_t *lf) {
|
|||
if (premaxhp < lf->maxhp) {
|
||||
float ratio;
|
||||
ratio = (float)premaxhp / (float) lf->maxhp;
|
||||
lf->maxhp = ratio * lf->maxhp;
|
||||
lf->hp = ratio * lf->maxhp;
|
||||
limit(&(lf->hp), 1, lf->maxhp);
|
||||
}
|
||||
if (thisisplayer) statdirty = B_TRUE;
|
||||
|
@ -3135,7 +3135,12 @@ void die(lifeform_t *lf) {
|
|||
copyflag(corpse->flags, lf->flags, F_CANCAST);
|
||||
copyflag(corpse->flags, lf->flags, F_CANWILL);
|
||||
copyflag(corpse->flags, lf->flags, F_JOB);
|
||||
|
||||
// race subspecies flags, so that we can have mosnters which eat
|
||||
// only certain kinds of corpses
|
||||
copyflag(corpse->flags, lf->flags, F_AVIAN);
|
||||
copyflag(corpse->flags, lf->flags, F_CANINE);
|
||||
copyflag(corpse->flags, lf->flags, F_EQUINE);
|
||||
copyflag(corpse->flags, lf->flags, F_FELINE);
|
||||
|
||||
f = hasflag(corpse->flags, F_CORPSEOF);
|
||||
if (f) {
|
||||
|
@ -8356,10 +8361,28 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
char jobstring[BUFLEN];
|
||||
char the[6];
|
||||
char lname[BUFLEN];
|
||||
race_t *lfrace;
|
||||
flag_t *f;
|
||||
enum LFSIZE size,racesize;
|
||||
int dobehaviour = B_TRUE;
|
||||
enum SKILLLEVEL lorelev;
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
lorelev = getlorelevel(player, lf->race->raceclass->id);
|
||||
} else {
|
||||
lorelev = PR_MASTER;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_LYCANTHROPE)) {
|
||||
// lycanthropes appear as human unless you know better
|
||||
if (lorelev >= PR_ADEPT) {
|
||||
lfrace = lf->race;
|
||||
} else {
|
||||
lfrace = findrace(R_HUMAN);
|
||||
}
|
||||
} else {
|
||||
lfrace = lf->race;
|
||||
}
|
||||
|
||||
// 'the' or 'your' ?
|
||||
f = lfhasflag(lf, F_NAME);
|
||||
|
@ -8368,7 +8391,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
strcpy(lname, f->text);
|
||||
} else if (lfhasflag(lf, F_UNIQUE)) {
|
||||
strcpy(the, "");
|
||||
strcpy(lname, lf->race->name);
|
||||
strcpy(lname, lfrace->name);
|
||||
} else {
|
||||
if (ispetof(lf, player)) {
|
||||
strcpy(the, "your ");
|
||||
|
@ -8377,33 +8400,35 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
}
|
||||
f = lfhasflag(lf, F_NAMED);
|
||||
if (f) { // ie. "the xat named blah"
|
||||
strcpy(lname, lf->race->name);
|
||||
strcpy(lname, lfrace->name);
|
||||
strcat(lname, " named ");
|
||||
strcat(lname, f->text);
|
||||
} else { // ie. "the xat"
|
||||
strcpy(lname, lf->race->name);
|
||||
strcpy(lname, lfrace->name);
|
||||
}
|
||||
}
|
||||
|
||||
// construct description string
|
||||
strcpy(descstring, "");
|
||||
|
||||
// has their size changed?
|
||||
f = hasflag(lf->race->flags, F_SIZE);
|
||||
if (f) {
|
||||
racesize = f->val[0];
|
||||
} else {
|
||||
racesize = SZ_HUMAN; // default
|
||||
// if you lorelev is high enough, you can tell when the race is larger or smaller than
|
||||
// they should be.
|
||||
if (lorelev >= PR_BEGINNER) {
|
||||
f = hasflag(lfrace->flags, F_SIZE);
|
||||
if (f) {
|
||||
racesize = f->val[0];
|
||||
} else {
|
||||
racesize = SZ_HUMAN; // default
|
||||
}
|
||||
size = getlfsize(lf);
|
||||
if (size != racesize) {
|
||||
strcat(descstring, getsizetext(size));
|
||||
strcat(descstring, " ");
|
||||
}
|
||||
}
|
||||
size = getlfsize(lf);
|
||||
if (size != racesize) {
|
||||
strcat(descstring, getsizetext(size));
|
||||
strcat(descstring, " ");
|
||||
}
|
||||
|
||||
|
||||
// need a certain amount of race knowledge to recognise ai traits
|
||||
if (getlorelevel(player, lf->race->raceclass->id) < PR_SKILLED) {
|
||||
if (lorelev < PR_SKILLED) {
|
||||
dobehaviour = B_FALSE;
|
||||
}
|
||||
// frozen/headless trump behavioural descriptions like "insane"
|
||||
|
@ -8426,7 +8451,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
|
||||
// construct job string
|
||||
strcpy(jobstring, "");
|
||||
if (showall || isplayer(lf) || (getlorelevel(player, lf->race->raceclass->id) >= PR_BEGINNER)) {
|
||||
if (showall || isplayer(lf) || (lorelev >= PR_BEGINNER)) {
|
||||
if (!lfhasflag(lf, F_NOJOBTEXT) && !lfhasflag(lf, F_NAME) && !lfhasflag(lf, F_UNIQUE)) {
|
||||
if (getjob(lf)) {
|
||||
snprintf(jobstring, BUFLEN, " %s", getjobname(lf));
|
||||
|
@ -8483,6 +8508,29 @@ char *getlfnamea(lifeform_t *lf, char *buf) {
|
|||
}
|
||||
|
||||
char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) {
|
||||
race_t *lfrace;
|
||||
enum SKILLLEVEL lorelev;
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
lorelev = getlorelevel(player, lf->race->raceclass->id);
|
||||
} else {
|
||||
lorelev = PR_MASTER;
|
||||
}
|
||||
|
||||
switch (lf->race->id) {
|
||||
case R_WERERAT:
|
||||
case R_WEREWOLF:
|
||||
if (lorelev >= PR_ADEPT) {
|
||||
lfrace = lf->race;
|
||||
} else {
|
||||
lfrace = findrace(R_HUMAN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lfrace = lf->race;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
snprintf(buf, BUFLEN, "you");
|
||||
} else {
|
||||
|
@ -8497,7 +8545,7 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
if (ispetof(lf, player)) {
|
||||
strcpy(the, "your ");
|
||||
} else {
|
||||
if (isvowel(lf->race->name[0])) {
|
||||
if (isvowel(lfrace->name[0])) {
|
||||
strcpy(the, "an ");
|
||||
} else {
|
||||
strcpy(the, "a ");
|
||||
|
@ -9513,39 +9561,44 @@ object_t *getweapon(lifeform_t *lf) {
|
|||
// this function MIGHT allocat op!
|
||||
int getweapons(lifeform_t *lf, object_t **wep, flag_t **damflag, int *lastweaponidx, obpile_t **op, int *nweps) {
|
||||
int gotweapon = B_FALSE;
|
||||
flag_t *retflag[MAXCANDIDATES],*f;
|
||||
flag_t *retflag[MAXCANDIDATES],*f,*forcewep;
|
||||
int nretflags,i;
|
||||
// first use our weapon...
|
||||
*nweps = 0;
|
||||
wep[*nweps] = getweapon(lf);
|
||||
if (wep[*nweps]) {
|
||||
if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM);
|
||||
if (lastweaponidx) *lastweaponidx = 0;
|
||||
(*nweps)++;
|
||||
gotweapon = B_TRUE;
|
||||
}
|
||||
|
||||
// if we are skilled at twoweaponing, we can attack with our second weapon
|
||||
// as well, with a possible accuracy penalty depending on our skill level.
|
||||
if (getskill(lf, SK_TWOWEAPON)) {
|
||||
wep[*nweps] = getsecmeleeweapon(lf);
|
||||
*nweps = 0;
|
||||
|
||||
forcewep = lfhasflag(lf, F_FORCEATTACK);
|
||||
if (!forcewep) {
|
||||
wep[*nweps] = getweapon(lf);
|
||||
if (wep[*nweps]) {
|
||||
if ((*nweps >= 1) && (wep[*nweps] == wep[(*nweps)-1])) {
|
||||
// can't be the same as first one
|
||||
} else {
|
||||
if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM);
|
||||
if (lastweaponidx) *lastweaponidx = *nweps;
|
||||
(*nweps)++;
|
||||
gotweapon = B_TRUE;
|
||||
if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM);
|
||||
if (lastweaponidx) *lastweaponidx = 0;
|
||||
(*nweps)++;
|
||||
gotweapon = B_TRUE;
|
||||
}
|
||||
|
||||
// if we are skilled at twoweaponing, we can attack with our second weapon
|
||||
// as well, with a possible accuracy penalty depending on our skill level.
|
||||
if (getskill(lf, SK_TWOWEAPON)) {
|
||||
wep[*nweps] = getsecmeleeweapon(lf);
|
||||
if (wep[*nweps]) {
|
||||
if ((*nweps >= 1) && (wep[*nweps] == wep[(*nweps)-1])) {
|
||||
// can't be the same as first one
|
||||
} else {
|
||||
if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM);
|
||||
if (lastweaponidx) *lastweaponidx = *nweps;
|
||||
(*nweps)++;
|
||||
gotweapon = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end if !forcewep
|
||||
|
||||
// then use all our innate attacks..
|
||||
getflags(lf->flags, retflag, &nretflags, F_HASATTACK, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->id == F_HASATTACK) {
|
||||
if (!forcewep || (f->val[0] == forcewep->val[0])) {
|
||||
objecttype_t *ot;
|
||||
|
||||
if (!(*op)) {
|
||||
|
@ -16235,11 +16288,20 @@ int readytotrain(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
int recruit(lifeform_t *lf) {
|
||||
enum ALIGNMENT pa,lfa;
|
||||
// alignments must match, otherwire VERY hard to make them join!
|
||||
pa = getalignment(player);
|
||||
lfa = getalignment(lf);
|
||||
int rv = B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_NOHIRE)) {
|
||||
// refusing to join at all.
|
||||
sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL);
|
||||
rv = B_TRUE;
|
||||
} else if ( ((pa == AL_GOOD) && (lfa == AL_EVIL)) ||
|
||||
((pa == AL_EVIL) && (lfa == AL_GOOD)) ) {
|
||||
sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL);
|
||||
rv = B_TRUE;
|
||||
} else {
|
||||
int dohire = B_FALSE;
|
||||
int askingprice = -1;
|
||||
|
@ -16259,6 +16321,7 @@ int recruit(lifeform_t *lf) {
|
|||
// since you have to be at least speech=4(skilled) to ask someone to
|
||||
// join, add +8 to difficulty (pr_skilled * 2)
|
||||
difficulty = 25 + 8 + ((gettr(player) - gettr(lf))*2);
|
||||
|
||||
if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) {
|
||||
minmult = 10;
|
||||
maxmult = 20;
|
||||
|
@ -16970,11 +17033,30 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
|||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_RECRUIT_ASKPRICE:
|
||||
snprintf(buf, BUFLEN, "My services will cost you $%d.",val0);
|
||||
switch (rnd(1,8)) {
|
||||
case 1: snprintf(buf, BUFLEN, "My services will cost you $%d.", val0); break;
|
||||
case 2: snprintf(buf, BUFLEN, "$%d and you have yourself a deal.", val0); break;
|
||||
case 3: snprintf(buf, BUFLEN, "Okay. How does $%d sound?", val0); break;
|
||||
case 4: snprintf(buf, BUFLEN, "I'll do it for $%d.", val0); break;
|
||||
case 5: snprintf(buf, BUFLEN, "Let's see... $%d should do it.", val0); break;
|
||||
case 6: snprintf(buf, BUFLEN, "My fee is $%d. Still interested?", val0); break;
|
||||
case 7: snprintf(buf, BUFLEN, "I don't work for free. $%d.", val0); break;
|
||||
case 8: snprintf(buf, BUFLEN, "$%d and your cause is mine.", val0); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_RECRUIT_DECLINE:
|
||||
rv = say(lf, "No, I regretfully decline your offer.", volume);
|
||||
switch (rnd(1,8)) {
|
||||
case 1: snprintf(buf, BUFLEN, "No, I regretfully decline your offer."); break;
|
||||
case 2: snprintf(buf, BUFLEN, "You dare ask me for help?"); break;
|
||||
case 3: snprintf(buf, BUFLEN, "I will never help you."); break;
|
||||
case 4: snprintf(buf, BUFLEN, "No."); break;
|
||||
case 5: snprintf(buf, BUFLEN, "Me? Help you?."); break;
|
||||
case 6: snprintf(buf, BUFLEN, "Ahem. I think not."); break;
|
||||
case 7: snprintf(buf, BUFLEN, "I don't think that would be a good idea."); break;
|
||||
case 8: snprintf(buf, BUFLEN, "Sorry, but no."); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_RECRUIT_DECLINE_CANTPAY:
|
||||
rv = say(lf, "...which I see you cannot afford.", volume);
|
||||
|
@ -17417,8 +17499,15 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
killflag(f);
|
||||
nkilled++;
|
||||
} else if ((f->lifetime > 0) && (f->id != F_POLYMORPHED)) {
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
// kill most temporary flags, with exceptions
|
||||
switch (f->id) {
|
||||
case F_FLEEFROM:
|
||||
break;
|
||||
default:
|
||||
killflag(f);
|
||||
nkilled++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
119
map.c
119
map.c
|
@ -142,12 +142,18 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
|
|||
amt = rnd(f->val[0],f->val[1]);
|
||||
for (i = 0; i < amt; i++) {
|
||||
cell_t *c;
|
||||
// pick new EMPTY random spot
|
||||
c = getrandomcell(lf->cell->map);
|
||||
while (!cellwalkable(NULL, c, NULL)) {
|
||||
// pick new EMPTY random spot. try rooms first.
|
||||
c = getrandomroomcell(lf->cell->map, ANYROOM, WE_WALKABLE);
|
||||
if (!c) {
|
||||
// if no rooms, get any walkable cell.
|
||||
c = getrandomcell(lf->cell->map);
|
||||
while (!cellwalkable(NULL, c, NULL)) {
|
||||
c = getrandomcell(lf->cell->map);
|
||||
}
|
||||
}
|
||||
if (c) {
|
||||
o = addob(c->obpile, f->text);
|
||||
}
|
||||
o = addob(c->obpile, f->text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1236,6 +1242,39 @@ int adjcellokforreachability(cell_t *c, int srcroomid, int dir, int wantfilled)
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int cellmatchescondition(cell_t *c, int wecond) {
|
||||
int ok = B_FALSE;
|
||||
if (wecond == WE_EMPTY) {
|
||||
// make sure it's empty
|
||||
if (isempty(c)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wecond == WE_WALKABLE) {
|
||||
if (cellwalkable(NULL, c, NULL)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wecond == WE_PORTAL) {
|
||||
if (cellwalkable(NULL, c, NULL) && !hasenterableobject(c) ) {
|
||||
if (!hasobwithflag(c->obpile, F_DOOR)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (wecond == WE_NOTWALL) {
|
||||
if ((!c->type->solid) && !hasobwithflag(c->obpile, F_IMPASSABLE)) {
|
||||
//if (!c->type->solid) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wecond == WE_NOLF) {
|
||||
if (!c->lf) ok = B_TRUE;
|
||||
} else if (wecond == WE_SOLID) {
|
||||
if (c->type->solid) ok = B_TRUE;
|
||||
} else {
|
||||
// always ok
|
||||
ok = B_TRUE;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// returns B_TRUE, B_FALSE or B_MAYBE
|
||||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom) {
|
||||
int db = B_FALSE;
|
||||
|
@ -2873,9 +2912,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
if (db) dblog("--> Will add %d pillars",numpillars);
|
||||
for (n = 0; n < numpillars;n++ ) {
|
||||
//dblog("----> Adding pillar %d/%d",n+1,numpillars);
|
||||
c = getrandomroomcell(map, i);
|
||||
c = getrandomroomcell(map, i, WE_EMPTY);
|
||||
|
||||
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||
if (c && !countobs(c->obpile, B_TRUE)) {
|
||||
setcelltype(c, solidcell);
|
||||
}
|
||||
}
|
||||
|
@ -2897,10 +2936,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
int nmonsters = 0;
|
||||
done = B_FALSE;
|
||||
while (!done) {
|
||||
c = getrandomroomcell(map, i);
|
||||
c = getrandomroomcell(map, i, WE_WALKABLE);
|
||||
// if nothing there
|
||||
if (c && cellwalkable(NULL, c, NULL)) {
|
||||
|
||||
if (c) {
|
||||
int obchance;
|
||||
int nadded = 0;
|
||||
|
||||
|
@ -3418,7 +3456,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
break;
|
||||
case RT_OBJECT:
|
||||
if (db) dblog(" adding forced regionthing object: %s", thing[i]->what);
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
|
||||
if (!c) c = getrandomcell(map);
|
||||
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL);
|
||||
addob(c->obpile, thing[i]->what);
|
||||
|
@ -3967,7 +4005,7 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
|
|||
// also ensure it's not over water.
|
||||
c = NULL;
|
||||
while (!c || (countadjwalls(c) == 0) || getcellwaterdepth(c, NULL)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
c = getrandomroomcell(map, ANYROOM, WE_NONE);
|
||||
assert(c);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_GRATINGROOF);
|
||||
|
@ -4659,13 +4697,13 @@ int linkexits(map_t *m, int roomid) {
|
|||
assert(roomidx != -1);
|
||||
|
||||
// does this roomid actually exist??
|
||||
c = getrandomroomcell(m, roomid);
|
||||
c = getrandomroomcell(m, roomid, WE_NONE);
|
||||
if (!c) return B_FALSE;
|
||||
|
||||
if (db) {
|
||||
char buf[BUFLEN];
|
||||
vault_t *v;
|
||||
c = getrandomroomcell(m, roomid);
|
||||
c = getrandomroomcell(m, roomid, WE_NONE);
|
||||
v = getcellvault(c);
|
||||
snprintf(buf, BUFLEN, "*** linkexits for roomid %d (%s) [%d,%d-%d,%d]", roomid,
|
||||
v ? v->id : "novault",
|
||||
|
@ -5195,8 +5233,8 @@ void finalisemap(map_t *map, object_t *entryob) {
|
|||
flag_t *f;
|
||||
// first dungeon level. just one exit stairs
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
while (!c || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM, WE_EMPTY);
|
||||
}
|
||||
o = addobfast(c->obpile, upstairtype);
|
||||
if (entryob) {
|
||||
|
@ -5223,8 +5261,8 @@ void finalisemap(map_t *map, object_t *entryob) {
|
|||
// up stairs on all other levels
|
||||
for (i = 0; i < nupstairsneeded; i++) {
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
while (!c || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM, WE_EMPTY);
|
||||
if (!c) {
|
||||
// ANY cell at all, doesn't have to be a room.
|
||||
c = getrandomcell(map);
|
||||
|
@ -5248,8 +5286,8 @@ void finalisemap(map_t *map, object_t *entryob) {
|
|||
if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) {
|
||||
for (i = 0; i < ndownstairsneeded; i++) {
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
while (!c || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM, WE_EMPTY);
|
||||
if (!c) {
|
||||
// ANY cell at all, doesn't have to be a room.
|
||||
c = getrandomcell(map);
|
||||
|
@ -5329,7 +5367,7 @@ void finalisemap(map_t *map, object_t *entryob) {
|
|||
if (roomlightchance) {
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
if (pctchance(roomlightchance)) {
|
||||
c = getrandomroomcell(map, i);
|
||||
c = getrandomroomcell(map, i, WE_WALKABLE);
|
||||
addob(c->obpile, roomlightob);
|
||||
}
|
||||
}
|
||||
|
@ -5474,6 +5512,13 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags,
|
|||
|
||||
addhomeobs(lf, B_TRUE);
|
||||
|
||||
// if monster can shapeshift, it will sometimes start in its alternate form.
|
||||
if (cancast(lf, OT_S_SHAPESHIFT, NULL)) {
|
||||
if (onein(4)) {
|
||||
castspell(lf, OT_S_SHAPESHIFT, lf, NULL, lf->cell, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
getflags(lf->flags, retflag, &nretflags, F_LIFEOB, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
|
@ -6018,34 +6063,8 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
|
|||
enum OBTYPE *badoid;
|
||||
int ok = B_FALSE;
|
||||
numwithlof++;
|
||||
if (wantempty == WE_EMPTY) {
|
||||
// make sure it's empty
|
||||
if (isempty(new)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wantempty == WE_WALKABLE) {
|
||||
if (cellwalkable(NULL, new, NULL)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wantempty == WE_PORTAL) {
|
||||
if (cellwalkable(NULL, new, NULL) && !hasenterableobject(new) ) {
|
||||
if (!hasobwithflag(new->obpile, F_DOOR)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (wantempty == WE_NOTWALL) {
|
||||
if ((!new->type->solid) && !hasobwithflag(new->obpile, F_IMPASSABLE)) {
|
||||
//if (!new->type->solid) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (wantempty == WE_NOLF) {
|
||||
if (!new->lf) ok = B_TRUE;
|
||||
} else if (wantempty == WE_SOLID) {
|
||||
if (new->type->solid) ok = B_TRUE;
|
||||
} else {
|
||||
// always ok
|
||||
ok = B_TRUE;
|
||||
}
|
||||
|
||||
ok = cellmatchescondition(new, wantempty);
|
||||
|
||||
// obs we dont want?
|
||||
if (dontwantob) {
|
||||
|
@ -6149,7 +6168,7 @@ int getrandomdirexcept(int dirtype, int exception) {
|
|||
return dir;
|
||||
}
|
||||
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid) {
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid, int wantempty) {
|
||||
int npossible = 0;
|
||||
int selidx;
|
||||
int x,y;
|
||||
|
@ -6175,7 +6194,7 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
if (ok && cellmatchescondition(c, wantempty)) {
|
||||
poss[npossible] = c;
|
||||
npossible++;
|
||||
}
|
||||
|
|
3
map.h
3
map.h
|
@ -16,6 +16,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
void breakwall(cell_t *c);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
int cellisfixedvaultwall(cell_t *c);
|
||||
int cellmatchescondition(cell_t *c, int wecond);
|
||||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom);
|
||||
void clearcell(cell_t *c);
|
||||
void clearcell_exceptflags(cell_t *c, ...);
|
||||
|
@ -120,7 +121,7 @@ cell_t *getrandomcell(map_t *map);
|
|||
cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id);
|
||||
int getrandomdir(int dirtype);
|
||||
int getrandomdirexcept(int dirtype, int exception);
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid);
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid, int wantempty);
|
||||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
||||
int getslipperyness(cell_t *c, object_t **slipob);
|
||||
cell_t *getstairdestination(object_t *o, int *madenewmap);
|
||||
|
|
|
@ -942,7 +942,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
targetmap = addmap();
|
||||
createmap(targetmap, dlev, c->map->region, NULL, D_NONE, NULL);
|
||||
}
|
||||
targetcell = getrandomroomcell(targetmap, ANYROOM);
|
||||
targetcell = getrandomroomcell(targetmap, ANYROOM, WE_WALKABLE);
|
||||
if (!targetcell) targetcell = getrandomcell(targetmap);
|
||||
while (!cellwalkable(NULL, targetcell, NULL)) {
|
||||
targetcell = getrandomadjcell(targetcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
|
@ -1634,6 +1634,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
cf->val[1] = sizetonutrition(rf->val[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// fill in animal subspecies
|
||||
copyflag(o->flags, corpserace->flags, F_AVIAN);
|
||||
copyflag(o->flags, corpserace->flags, F_CANINE);
|
||||
copyflag(o->flags, corpserace->flags, F_EQUINE);
|
||||
copyflag(o->flags, corpserace->flags, F_FELINE);
|
||||
} else if (o->type->id == OT_MAP) {
|
||||
region_t *srcregion;
|
||||
regiontype_t *dstrt = NULL;
|
||||
|
|
30
spell.c
30
spell.c
|
@ -2067,9 +2067,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
// find a random empty cell here
|
||||
entry = getrandomroomcell(newmap, ANYROOM);
|
||||
entry = getrandomroomcell(newmap, ANYROOM, WE_WALKABLE);
|
||||
while (!cellwalkable(target, entry, NULL)) {
|
||||
entry = getrandomroomcell(newmap, ANYROOM);
|
||||
entry = getrandomroomcell(newmap, ANYROOM, WE_WALKABLE);
|
||||
}
|
||||
|
||||
// link the map to this lf
|
||||
|
@ -2121,6 +2121,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (!lfhasflag(user, F_FLYING)) {
|
||||
if (isplayer(user)) msg("You are not flying, therefore cannot swoop.");
|
||||
return B_TRUE;
|
||||
} else if (!lfhasflagval(user, F_HASATTACK, OT_CLAWS, NA, NA, NULL)) {
|
||||
if (isplayer(user)) msg("You need claws to perform a swoop attack.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!targcell) {
|
||||
|
@ -2189,7 +2192,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
// attack
|
||||
addflag(user->flags, F_FORCEATTACK, OT_CLAWS, NA, NA, "fromuseability");
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
f = lfhasflagval(user, F_FORCEATTACK, OT_CLAWS, NA, NA, "fromuseability");
|
||||
if (f) killflag(f);
|
||||
|
||||
// teleport back to initial pos
|
||||
movelf(user, origcell);
|
||||
|
@ -4891,7 +4897,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
// determine type of mosnter
|
||||
if (getforcedspellrace(caster, spellid, buf)) {
|
||||
if (getforcedspellrace(caster, spellid, buf, NULL)) {
|
||||
} else if ((power >= 7) && isplayer(caster)) {
|
||||
// ask what kind of monster
|
||||
askstring("Create what kind of monster", '?', buf, BUFLEN, NULL);
|
||||
|
@ -4952,13 +4958,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
ch = askchar("Teleport to the new vault", "yn","y", B_TRUE, B_FALSE);
|
||||
if (ch == 'y') {
|
||||
int ntries = 0;
|
||||
c = getrandomroomcell(caster->cell->map, caster->cell->map->nrooms-1);
|
||||
c = getrandomroomcell(caster->cell->map, caster->cell->map->nrooms-1, WE_WALKABLE);
|
||||
if (!c || !cellwalkable(caster, c, NULL)) {
|
||||
if (++ntries >= 10) {
|
||||
msg("Oops, couldn't find a free space.");
|
||||
return B_FALSE;
|
||||
}
|
||||
c = getrandomroomcell(caster->cell->map, caster->cell->map->nrooms-1);
|
||||
c = getrandomroomcell(caster->cell->map, caster->cell->map->nrooms-1, WE_WALKABLE);
|
||||
}
|
||||
teleportto(caster, c, B_TRUE);
|
||||
return B_FALSE;
|
||||
|
@ -8980,7 +8986,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
} else if ((spellid == OT_S_POLYMORPH) || (spellid == OT_S_SHAPESHIFT)) {
|
||||
race_t *r = NULL;
|
||||
|
||||
if (caster && (frompot || (spellid == OT_S_SHAPESHIFT))) {
|
||||
target = caster;
|
||||
} else {
|
||||
|
@ -9007,7 +9012,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
//if ((caster == target) && getforcedspellrace(caster, spellid, buf)) {
|
||||
if (getforcedspellrace(target, spellid, buf)) {
|
||||
if (getforcedspellrace(target, spellid, buf, NULL)) {
|
||||
r = findracebyname(buf);
|
||||
} else {
|
||||
if (spellid == OT_S_POLYMORPH) {
|
||||
|
@ -10812,6 +10817,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
(spellid == OT_S_HECTASSERVANT) ||
|
||||
(spellid == OT_S_SUMMONDEMON)) {
|
||||
int lifetime, nwant,ngot,successrate;
|
||||
int tempcount = 0;
|
||||
enum LFSIZE wantsize;
|
||||
enum RACECLASS wantrc;
|
||||
enum RACE wantrace = R_NONE;
|
||||
|
@ -10887,7 +10893,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
// override with forced race?
|
||||
if (caster && getforcedspellrace(caster, spellid, racename)) {
|
||||
if (caster && getforcedspellrace(caster, spellid, racename, &tempcount)) {
|
||||
race_t *r;
|
||||
r = findracebyname(racename);
|
||||
if (r) {
|
||||
|
@ -10896,6 +10902,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
wantsize = SZ_ANY;
|
||||
}
|
||||
}
|
||||
// override count
|
||||
if (tempcount > 0) {
|
||||
nwant = tempcount;
|
||||
}
|
||||
|
||||
if (!pctchance(successrate)) {
|
||||
fizzle(caster);
|
||||
|
@ -11842,7 +11852,7 @@ enum OBTYPE getfirstwizspell(enum SPELLSCHOOL school) {
|
|||
return firstspell;
|
||||
}
|
||||
|
||||
char *getforcedspellrace(lifeform_t *lf, enum OBTYPE spellid, char *racestr) {
|
||||
char *getforcedspellrace(lifeform_t *lf, enum OBTYPE spellid, char *racestr, int *count) {
|
||||
flag_t *f;
|
||||
// forced?
|
||||
f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
|
||||
|
@ -11850,7 +11860,7 @@ char *getforcedspellrace(lifeform_t *lf, enum OBTYPE spellid, char *racestr) {
|
|||
f = lfhasflagval(lf, F_CANCAST, spellid, NA, NA, NULL);
|
||||
}
|
||||
if (f) {
|
||||
texttospellopts(f->text, "race:", racestr, NULL);
|
||||
texttospellopts(f->text, "race:", racestr, "count:", count, NULL);
|
||||
if (strlen(racestr)) {
|
||||
return racestr;
|
||||
}
|
||||
|
|
2
spell.h
2
spell.h
|
@ -9,7 +9,7 @@ enum SPELLSCHOOL findspellschoolbyname(char *buf);
|
|||
void fizzle(lifeform_t *caster);
|
||||
//int getiqreq(enum OBTYPE oid);
|
||||
enum OBTYPE getfirstwizspell(enum SPELLSCHOOL school);
|
||||
char *getforcedspellrace(lifeform_t *lf, enum OBTYPE spellid, char *racestr);
|
||||
char *getforcedspellrace(lifeform_t *lf, enum OBTYPE spellid, char *racestr, int *count);
|
||||
int getmpcost(lifeform_t *lf, enum OBTYPE oid);
|
||||
int getmrdiff(enum OBTYPE spellid, int power);
|
||||
enum OBTYPE getrandomspell(int maxlev);
|
||||
|
|
74
text.c
74
text.c
|
@ -2304,6 +2304,7 @@ int texttospellopts(char *text, ... ) {
|
|||
int nfilled = 0;
|
||||
char *validname[] = {
|
||||
"pw:",
|
||||
"count:",
|
||||
"dam:",
|
||||
"needgrab:",
|
||||
"range:",
|
||||
|
@ -2313,6 +2314,7 @@ int texttospellopts(char *text, ... ) {
|
|||
};
|
||||
int argdefault[] = {
|
||||
0,
|
||||
1,
|
||||
-1, // string
|
||||
B_FALSE,
|
||||
0,
|
||||
|
@ -2321,6 +2323,7 @@ int texttospellopts(char *text, ... ) {
|
|||
-99, // last
|
||||
};
|
||||
char argtype[] = {
|
||||
'i',
|
||||
'i',
|
||||
's',
|
||||
'b',
|
||||
|
@ -2336,50 +2339,51 @@ int texttospellopts(char *text, ... ) {
|
|||
wantname = va_arg(args, char *);
|
||||
if (wantname) writeto = va_arg(args, void *);
|
||||
while (wantname) { // process this one
|
||||
int foundidx = -1,i;
|
||||
if (writeto) {
|
||||
int foundidx = -1,i;
|
||||
|
||||
// validate 'wantname' - must match one of 'validname[]'
|
||||
for (i = 0; validname[i]; i++) {
|
||||
if (streq(validname[i], wantname)) {
|
||||
foundidx = i;
|
||||
break;
|
||||
// validate 'wantname' - must match one of 'validname[]'
|
||||
for (i = 0; validname[i]; i++) {
|
||||
if (streq(validname[i], wantname)) {
|
||||
foundidx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(foundidx != -1);
|
||||
assert(foundidx != -1);
|
||||
|
||||
// blank our dest buffer
|
||||
if (argtype[foundidx] == 'i') {
|
||||
*((int *)writeto) = argdefault[foundidx];
|
||||
} else if (argtype[foundidx] == 'b') {
|
||||
*((int *)writeto) = argdefault[foundidx];
|
||||
} else if (argtype[foundidx] == 's') {
|
||||
strcpy((char *)writeto, "");
|
||||
}
|
||||
// blank our dest buffer
|
||||
if (argtype[foundidx] == 'i') {
|
||||
*((int *)writeto) = argdefault[foundidx];
|
||||
} else if (argtype[foundidx] == 'b') {
|
||||
*((int *)writeto) = argdefault[foundidx];
|
||||
} else if (argtype[foundidx] == 's') {
|
||||
strcpy((char *)writeto, "");
|
||||
}
|
||||
|
||||
// look for 'wantname' within 'text'
|
||||
for (p = text ; *p ; p++) {
|
||||
if (!strncmp(p, wantname, strlen(wantname)) ) { // found it!
|
||||
char localval[BUFLEN];
|
||||
char *valfull;
|
||||
// look for 'wantname' within 'text'
|
||||
for (p = text ; *p ; p++) {
|
||||
if (!strncmp(p, wantname, strlen(wantname)) ) { // found it!
|
||||
char localval[BUFLEN];
|
||||
char *valfull;
|
||||
|
||||
// extract value from text
|
||||
// p will point to "pw:xxx;"
|
||||
strcpy(localval, p + strlen(wantname)); // localval is "xxx;"
|
||||
valfull = strtok(localval, ";"); // valfull is "xxx"
|
||||
if (valfull) {
|
||||
// if it's there, write the value into 'writeto'
|
||||
if (argtype[foundidx] == 'i') {
|
||||
*((int *)writeto) = atoi(valfull);
|
||||
} else if (argtype[foundidx] == 'b') {
|
||||
*((int *)writeto) = atoi(valfull) ? B_TRUE : B_FALSE;
|
||||
} else if (argtype[foundidx] == 's') {
|
||||
strcpy((char *)writeto, valfull);
|
||||
// extract value from text
|
||||
// p will point to "pw:xxx;"
|
||||
strcpy(localval, p + strlen(wantname)); // localval is "xxx;"
|
||||
valfull = strtok(localval, ";"); // valfull is "xxx"
|
||||
if (valfull) {
|
||||
// if it's there, write the value into 'writeto'
|
||||
if (argtype[foundidx] == 'i') {
|
||||
*((int *)writeto) = atoi(valfull);
|
||||
} else if (argtype[foundidx] == 'b') {
|
||||
*((int *)writeto) = atoi(valfull) ? B_TRUE : B_FALSE;
|
||||
} else if (argtype[foundidx] == 's') {
|
||||
strcpy((char *)writeto, valfull);
|
||||
}
|
||||
nfilled++;
|
||||
}
|
||||
nfilled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get next one
|
||||
wantname = va_arg(args, char *);
|
||||
if (wantname) writeto = va_arg(args, void *);
|
||||
|
|
Loading…
Reference in New Issue