This commit is contained in:
parent
907ed43e40
commit
16fb58c3cf
6
ai.c
6
ai.c
|
@ -88,9 +88,9 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// become hostile?
|
// become hostile?
|
||||||
if (!hasflag(lf->flags, F_HOSTILE)) {
|
if (isplayer(victim) && !hasflag(lf->flags, F_HOSTILE) ) {
|
||||||
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
innocentattack = 1;
|
//innocentattack = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// change allegience ?
|
// change allegience ?
|
||||||
|
@ -104,7 +104,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
||||||
// no longer a pet
|
// no longer a pet
|
||||||
f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL);
|
f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL);
|
||||||
if (f) {
|
if (f) {
|
||||||
innocentattack = 3;
|
if (isplayer(victim)) innocentattack = 3;
|
||||||
killflag(f);
|
killflag(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
attack.c
20
attack.c
|
@ -111,10 +111,26 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
|
||||||
|
|
||||||
// figure out reduced damage value
|
// figure out reduced damage value
|
||||||
if (dam) {
|
if (dam) {
|
||||||
|
int ar;
|
||||||
|
|
||||||
newdam = *dam;
|
newdam = *dam;
|
||||||
|
ar = getarmourrating(lf, NULL, NULL, NULL);
|
||||||
|
// if you did at least one damage...
|
||||||
if ((*dam >= 1) && (reduceamt >= 0)) {
|
if ((*dam >= 1) && (reduceamt >= 0)) {
|
||||||
|
int lowerlimit = 0,divideby;
|
||||||
|
// reduce it.
|
||||||
newdam -= reduceamt;
|
newdam -= reduceamt;
|
||||||
limit(&newdam, 1, NA); // don't reduce to <1 damage
|
|
||||||
|
// you will always take at least 1 hp of damage for every (ar/2) damage.
|
||||||
|
// ie. if you took ar/2 damage, you take at least 1.
|
||||||
|
// ie. if you took ar damage, you take at least 2.
|
||||||
|
// ie. if you took ar*2 damage, you take at least 3.
|
||||||
|
// stop at 3.
|
||||||
|
divideby = ar/2;
|
||||||
|
if (divideby <= 0) divideby = 1;
|
||||||
|
lowerlimit = (*dam / divideby);
|
||||||
|
limit(&lowerlimit, 0, 3);
|
||||||
|
limit(&newdam, lowerlimit, NA); // don't reduce too far.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db) {
|
if (db) {
|
||||||
|
@ -811,7 +827,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
||||||
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
|
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
|
||||||
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
|
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
|
||||||
nodam = B_TRUE;
|
nodam = B_TRUE;
|
||||||
strcpy(nodamstr, " but does no damage");
|
strcpy(nodamstr, " ineffectually");
|
||||||
} else {
|
} else {
|
||||||
strcpy(nodamstr, "");
|
strcpy(nodamstr, "");
|
||||||
}
|
}
|
||||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
7
defs.h
7
defs.h
|
@ -2352,6 +2352,10 @@ enum PIETYLEV {
|
||||||
#define B_FALSE (0)
|
#define B_FALSE (0)
|
||||||
#define B_TRUE (-1)
|
#define B_TRUE (-1)
|
||||||
|
|
||||||
|
#define B_VIS (1)
|
||||||
|
#define B_UNKNOWN (0)
|
||||||
|
#define B_NOVIS (-1)
|
||||||
|
|
||||||
#define B_KEEPLOF (-1)
|
#define B_KEEPLOF (-1)
|
||||||
|
|
||||||
#define B_MALE (0)
|
#define B_MALE (0)
|
||||||
|
@ -2807,6 +2811,9 @@ typedef struct lifeform_s {
|
||||||
|
|
||||||
int nlos;
|
int nlos;
|
||||||
cell_t **los;
|
cell_t **los;
|
||||||
|
int *viscell;
|
||||||
|
int visw;
|
||||||
|
int visrange;
|
||||||
|
|
||||||
// set to TRUE after lf has being created
|
// set to TRUE after lf has being created
|
||||||
int born;
|
int born;
|
||||||
|
|
24
flag.c
24
flag.c
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "flag.h"
|
#include "flag.h"
|
||||||
|
#include "god.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
@ -17,6 +18,9 @@ extern enum GAMEMODE gamemode;
|
||||||
extern int needredraw;
|
extern int needredraw;
|
||||||
extern int statdirty;
|
extern int statdirty;
|
||||||
|
|
||||||
|
extern lifeform_t *godlf[];
|
||||||
|
extern int ngodlfs;
|
||||||
|
|
||||||
extern lifeform_t *player;
|
extern lifeform_t *player;
|
||||||
|
|
||||||
int flagdb = B_FALSE;
|
int flagdb = B_FALSE;
|
||||||
|
@ -684,6 +688,11 @@ void killflag(flag_t *f) {
|
||||||
map_t *redolight = NULL;
|
map_t *redolight = NULL;
|
||||||
int redostat = B_FALSE;
|
int redostat = B_FALSE;
|
||||||
int redoscreen = B_FALSE;
|
int redoscreen = B_FALSE;
|
||||||
|
int i,dopleasegod[MAXGODS];
|
||||||
|
|
||||||
|
for (i = 0; i < ngodlfs; i++) {
|
||||||
|
dopleasegod[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
lf = f->pile->owner;
|
lf = f->pile->owner;
|
||||||
|
|
||||||
|
@ -705,6 +714,16 @@ void killflag(flag_t *f) {
|
||||||
if (lf && (isplayer(lf) || cansee(player, lf))) {
|
if (lf && (isplayer(lf) || cansee(player, lf))) {
|
||||||
redolight = lf->cell->map;
|
redolight = lf->cell->map;
|
||||||
}
|
}
|
||||||
|
} else if (f->id == F_FLEEFROM) {
|
||||||
|
if (lf && lf->cell) {
|
||||||
|
lifeform_t *fleefrom;
|
||||||
|
fleefrom = findlf(lf->cell->map, f->val[0]);
|
||||||
|
// ie. this lf was fleeing from the player, and
|
||||||
|
// got away.
|
||||||
|
if (isplayer(fleefrom) && !cansee(lf, fleefrom)) {
|
||||||
|
dopleasegod[R_GODMERCY] += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,6 +811,11 @@ void killflag(flag_t *f) {
|
||||||
updatefpindex(f->pile);
|
updatefpindex(f->pile);
|
||||||
|
|
||||||
if (gamemode == GM_GAMESTARTED) {
|
if (gamemode == GM_GAMESTARTED) {
|
||||||
|
for (i = 0; i < ngodlfs; i++) {
|
||||||
|
if (dopleasegod[i]) {
|
||||||
|
pleasegodmaybe(godlf[i]->race->id, dopleasegod[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (redolight) {
|
if (redolight) {
|
||||||
calclight(redolight);
|
calclight(redolight);
|
||||||
precalclos(player);
|
precalclos(player);
|
||||||
|
|
18
god.c
18
god.c
|
@ -97,11 +97,20 @@ void angergod(enum RACE rid, int amt) {
|
||||||
// then...
|
// then...
|
||||||
if (piety > -100) {
|
if (piety > -100) {
|
||||||
int i,n;
|
int i,n;
|
||||||
|
lifeform_t *l;
|
||||||
// minor bad stuff
|
// minor bad stuff
|
||||||
switch (rid) {
|
switch (rid) {
|
||||||
case R_GODDEATH:
|
case R_GODDEATH:
|
||||||
castspell(god, OT_S_PAIN, player, NULL, player->cell);
|
castspell(god, OT_S_PAIN, player, NULL, player->cell);
|
||||||
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
|
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
|
||||||
|
// all undead in sight become hostile
|
||||||
|
for (l = player->cell->map->lf ; l ; l = l->next) {
|
||||||
|
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
|
||||||
|
if (getallegiance(l) != AL_HOSTILE) {
|
||||||
|
aiattack(l, player, PERMENANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case R_GODTHIEVES:
|
case R_GODTHIEVES:
|
||||||
// take a random object
|
// take a random object
|
||||||
|
@ -139,12 +148,21 @@ void angergod(enum RACE rid, int amt) {
|
||||||
}
|
}
|
||||||
} else if (piety > -200) {
|
} else if (piety > -200) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
|
lifeform_t *l;
|
||||||
int n,i;
|
int n,i;
|
||||||
// major bad stuff
|
// major bad stuff
|
||||||
switch (god->race->id) {
|
switch (god->race->id) {
|
||||||
case R_GODDEATH:
|
case R_GODDEATH:
|
||||||
castspell(god, OT_S_PAIN, player, NULL, player->cell);
|
castspell(god, OT_S_PAIN, player, NULL, player->cell);
|
||||||
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
|
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
|
||||||
|
// all undead in sight become hostile
|
||||||
|
for (l = player->cell->map->lf ; l ; l = l->next) {
|
||||||
|
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
|
||||||
|
if (getallegiance(l) != AL_HOSTILE) {
|
||||||
|
aiattack(l, player, PERMENANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (rnd(1,2)) {
|
switch (rnd(1,2)) {
|
||||||
case 1:
|
case 1:
|
||||||
msg("\"This will teach you some humility, mortal!\"");
|
msg("\"This will teach you some humility, mortal!\"");
|
||||||
|
|
1
io.c
1
io.c
|
@ -6037,6 +6037,7 @@ void drawlevelfor(lifeform_t *lf) {
|
||||||
if (db) dblog("ending DRAWLEVEL");
|
if (db) dblog("ending DRAWLEVEL");
|
||||||
|
|
||||||
sprintf(buf, "end. ndrawn was %d",ndrawn);
|
sprintf(buf, "end. ndrawn was %d",ndrawn);
|
||||||
|
if (db) dblog("%s",buf);
|
||||||
//dbtimeend(buf);
|
//dbtimeend(buf);
|
||||||
// move cursor to the player's position and blit
|
// move cursor to the player's position and blit
|
||||||
if (ndrawn) {
|
if (ndrawn) {
|
||||||
|
|
308
lf.c
308
lf.c
|
@ -195,9 +195,10 @@ void bleed(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void breakallgrabs(lifeform_t *lf) {
|
void breakgrabs(lifeform_t *lf, int fromme, int tome) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
lifeform_t *alf;
|
lifeform_t *alf;
|
||||||
|
if (fromme) {
|
||||||
f = lfhasflag(lf, F_GRABBING);
|
f = lfhasflag(lf, F_GRABBING);
|
||||||
if (f) {
|
if (f) {
|
||||||
lifeform_t *grabee;
|
lifeform_t *grabee;
|
||||||
|
@ -206,6 +207,12 @@ void breakallgrabs(lifeform_t *lf) {
|
||||||
killflagsofid(grabee->flags, F_GRABBEDBY);
|
killflagsofid(grabee->flags, F_GRABBEDBY);
|
||||||
killflagsofid(lf->flags, F_GRABBING);
|
killflagsofid(lf->flags, F_GRABBING);
|
||||||
}
|
}
|
||||||
|
f = lfhasflag(lf, F_ATTACHEDTO);
|
||||||
|
if (f) {
|
||||||
|
killflag(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tome) {
|
||||||
f = lfhasflag(lf, F_GRABBEDBY);
|
f = lfhasflag(lf, F_GRABBEDBY);
|
||||||
if (f) {
|
if (f) {
|
||||||
lifeform_t *graber;
|
lifeform_t *graber;
|
||||||
|
@ -221,6 +228,7 @@ void breakallgrabs(lifeform_t *lf) {
|
||||||
killflag(f);
|
killflag(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long calcscore(lifeform_t *lf) {
|
long calcscore(lifeform_t *lf) {
|
||||||
|
@ -3281,6 +3289,13 @@ int flee(lifeform_t *lf) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
lifeform_t *fleefrom = NULL;
|
lifeform_t *fleefrom = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
int db = B_FALSE;
|
||||||
|
char lfname[BUFLEN];
|
||||||
|
|
||||||
|
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
||||||
|
|
||||||
|
real_getlfname(lf, lfname, B_FALSE);
|
||||||
|
|
||||||
|
|
||||||
// mindless?
|
// mindless?
|
||||||
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) {
|
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) {
|
||||||
|
@ -3304,16 +3319,16 @@ int flee(lifeform_t *lf) {
|
||||||
// if we can't see the person we're running from, and it's not enforced for
|
// if we can't see the person we're running from, and it's not enforced for
|
||||||
// a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing.
|
// a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing.
|
||||||
if (f->lifetime == PERMENANT) {
|
if (f->lifetime == PERMENANT) {
|
||||||
killflag(f);
|
|
||||||
} else {
|
|
||||||
// if the flag is temporary, keep fleeing and wait for it to time out normally
|
|
||||||
fleefrom = thisone;
|
|
||||||
}
|
|
||||||
// player let something flee?
|
// player let something flee?
|
||||||
if (isplayer(thisone)) {
|
if (isplayer(thisone)) {
|
||||||
pleasegodmaybe(R_GODMERCY, 5);
|
pleasegodmaybe(R_GODMERCY, 5);
|
||||||
angergodmaybe(R_GODDEATH, 25);
|
angergodmaybe(R_GODDEATH, 25);
|
||||||
}
|
}
|
||||||
|
killflag(f);
|
||||||
|
} else {
|
||||||
|
// if the flag is temporary, keep fleeing and wait for it to time out normally
|
||||||
|
fleefrom = thisone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3323,7 +3338,9 @@ int flee(lifeform_t *lf) {
|
||||||
if (fleefrom) {
|
if (fleefrom) {
|
||||||
object_t *stairs;
|
object_t *stairs;
|
||||||
|
|
||||||
breakallgrabs(lf);
|
if (db) dblog("%s - fleeing from %s", lfname, fleefrom->race->name);
|
||||||
|
|
||||||
|
breakgrabs(lf, B_TRUE, B_FALSE); // stop grabbing anyone
|
||||||
|
|
||||||
// ways of fleeing other than movement?
|
// ways of fleeing other than movement?
|
||||||
if (!isplayer(lf)) {
|
if (!isplayer(lf)) {
|
||||||
|
@ -3339,14 +3356,23 @@ int flee(lifeform_t *lf) {
|
||||||
aigetspelltarget(lf, findot(spell), fleefrom, &targlf, &targcell, &targob, F_AICASTTOFLEE);
|
aigetspelltarget(lf, findot(spell), fleefrom, &targlf, &targcell, &targob, F_AICASTTOFLEE);
|
||||||
|
|
||||||
if (getschool(spell) == SS_ABILITY) {
|
if (getschool(spell) == SS_ABILITY) {
|
||||||
return useability(lf, spell, targlf, targcell);
|
if (db) dblog("%s - using ability %s to flee", sp->name);
|
||||||
|
if (!useability(lf, spell, targlf, targcell)) {
|
||||||
|
if (db) dblog("%s - success.", lfname);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return castspell(lf, spell, targlf, targob, targcell);
|
if (db) dblog("%s - casting %s to flee", sp->name);
|
||||||
|
if (!castspell(lf, spell, targlf, targob, targcell)) {
|
||||||
|
if (db) dblog("%s - success.", lfname);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if AI, use helpful fleeing items
|
// if AI, use helpful fleeing items
|
||||||
if (!useitemwithflag(lf, F_AIFLEEITEM)) {
|
if (!useitemwithflag(lf, F_AIFLEEITEM)) {
|
||||||
return B_FALSE;
|
if (db) dblog("%s - used an item to flee", lfname);
|
||||||
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3362,13 +3388,16 @@ int flee(lifeform_t *lf) {
|
||||||
stairs = hasobwithflag(lf->cell->obpile, F_CLIMBABLE);
|
stairs = hasobwithflag(lf->cell->obpile, F_CLIMBABLE);
|
||||||
if (stairs) {
|
if (stairs) {
|
||||||
if (!usestairs(lf, stairs, B_TRUE)) {
|
if (!usestairs(lf, stairs, B_TRUE)) {
|
||||||
|
if (db) dblog("%s - fleeing via %s", stairs->type->name);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// move away from them
|
// move away from them
|
||||||
if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE)) {
|
if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE)) {
|
||||||
|
if (db) dblog("%s - fleeing by moving away", lfname);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
if (db) dblog("%s - failed to flee!", lfname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we get here, it means we didn't need to or couldn't flee
|
// if we get here, it means we didn't need to or couldn't flee
|
||||||
|
@ -3404,7 +3433,7 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) {
|
||||||
// already fleeing?
|
// already fleeing?
|
||||||
f = hasflagval(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL);
|
f = hasflagval(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL);
|
||||||
if (f) {
|
if (f) {
|
||||||
// update time
|
// just update time
|
||||||
if (f->lifetime != PERMENANT) {
|
if (f->lifetime != PERMENANT) {
|
||||||
if (f->lifetime < howlong) {
|
if (f->lifetime < howlong) {
|
||||||
f->lifetime = howlong;
|
f->lifetime = howlong;
|
||||||
|
@ -3413,6 +3442,10 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) {
|
||||||
} else {
|
} else {
|
||||||
addtempflag(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL, howlong);
|
addtempflag(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL, howlong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop targetting anyone or going anywhere
|
||||||
|
killflagsofid(lf->flags, F_TARGETLF);
|
||||||
|
killflagsofid(lf->flags, F_TARGETCELL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) {
|
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) {
|
||||||
|
@ -7434,6 +7467,231 @@ int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void idxtoxy(lifeform_t *lf, int idx, int *x, int *y) {
|
||||||
|
int xoffset,yoffset;
|
||||||
|
// get the offset form the lf's position.
|
||||||
|
xoffset = (idx % lf->visw) - lf->visrange;
|
||||||
|
yoffset = (idx / lf->visw) - lf->visrange;
|
||||||
|
// return the actual cell there
|
||||||
|
*x = lf->cell->x + xoffset;
|
||||||
|
*y = lf->cell->y + yoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// confirmed good!
|
||||||
|
int xytoidx(lifeform_t *lf, int x, int y) {
|
||||||
|
int idx;
|
||||||
|
int xd,yd;
|
||||||
|
|
||||||
|
if (abs(x - lf->cell->x) > lf->visrange) return -1;
|
||||||
|
if (abs(y - lf->cell->y) > lf->visrange) return -1;
|
||||||
|
|
||||||
|
xd = lf->cell->x - lf->visrange;
|
||||||
|
yd = lf->cell->y - lf->visrange;
|
||||||
|
|
||||||
|
idx = (y - yd) * lf->visw + (x - xd);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setviscell(lifeform_t *lf, cell_t *cell, int how) {
|
||||||
|
int idx;
|
||||||
|
int x,y;
|
||||||
|
cell_t *c;
|
||||||
|
idx = xytoidx(lf, cell->x, cell->y);
|
||||||
|
assert(idx >= 0);
|
||||||
|
assert(idx < (lf->visw * lf->visw));
|
||||||
|
lf->viscell[idx] = how;
|
||||||
|
|
||||||
|
|
||||||
|
// checks
|
||||||
|
if (how == B_VIS) {
|
||||||
|
assert (abs(lf->cell->x - cell->x) <= 10);
|
||||||
|
assert (abs(lf->cell->y - cell->y) <= 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
idxtoxy(lf, idx, &x, &y);
|
||||||
|
c = getcellat(lf->cell->map, x, y);
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int getviscell(lifeform_t *lf, cell_t *cell) {
|
||||||
|
int idx;
|
||||||
|
idx = xytoidx(lf, cell->x, cell->y);
|
||||||
|
if ((idx < 0) || (idx >= (lf->visw * lf->visw)) ) {
|
||||||
|
return B_NOVIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lf->viscell[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
// find los, remembering cells on the way
|
||||||
|
void calclos(lifeform_t *viewer, cell_t *dest) {
|
||||||
|
int numpixels;
|
||||||
|
int i,n;
|
||||||
|
int x1,y1;
|
||||||
|
int maxvisrange;
|
||||||
|
int nightvisrange;
|
||||||
|
int xray = 0;
|
||||||
|
flag_t *f;
|
||||||
|
int x2,y2;
|
||||||
|
map_t *map;
|
||||||
|
object_t *o;
|
||||||
|
int currange;
|
||||||
|
cell_t *retcell[MAXRETCELLS];
|
||||||
|
int allbad = B_FALSE;
|
||||||
|
|
||||||
|
if (!viewer) return ;
|
||||||
|
if (!dest) return ;
|
||||||
|
if (!viewer->cell) return ;
|
||||||
|
if (viewer->cell->map != dest->map) return ;
|
||||||
|
|
||||||
|
map = dest->map;
|
||||||
|
|
||||||
|
x1 = viewer->cell->x;
|
||||||
|
y1 = viewer->cell->y;
|
||||||
|
x2 = dest->x;
|
||||||
|
y2 = dest->y;
|
||||||
|
|
||||||
|
// find the path of cells
|
||||||
|
calcbresnham(map, x1, y1, x2, y2, retcell, &numpixels);
|
||||||
|
|
||||||
|
// can't see if you're blind
|
||||||
|
if (isblind(viewer)) {
|
||||||
|
allbad = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxvisrange = getvisrange(viewer);
|
||||||
|
nightvisrange = getnightvisrange(viewer);
|
||||||
|
|
||||||
|
//origheight = getheight(x1,y1,z);
|
||||||
|
|
||||||
|
if (allbad) {
|
||||||
|
// mark all as bad
|
||||||
|
for (i = 0; i < numpixels; i++ ){
|
||||||
|
setviscell(viewer, retcell[i], B_VIS);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
f = hasflag(viewer->flags, F_XRAYVIS);
|
||||||
|
if (f) {
|
||||||
|
xray = f->val[0];
|
||||||
|
} else {
|
||||||
|
xray = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//shopwall = B_FALSE;
|
||||||
|
currange = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < numpixels ; i++) {
|
||||||
|
cell_t *cell;
|
||||||
|
int cellopaque = B_FALSE;
|
||||||
|
int celldark = B_FALSE;
|
||||||
|
|
||||||
|
cell = retcell[i];
|
||||||
|
|
||||||
|
//already can't see this one?
|
||||||
|
if (getviscell(viewer, cell) == B_NOVIS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cell->x == x2) && (cell->y == y2)) {
|
||||||
|
// made it to the last cell
|
||||||
|
setviscell(viewer, cell, B_VIS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
// you can always see your own cell
|
||||||
|
setviscell(viewer, cell, B_VIS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
currange++;
|
||||||
|
if (currange > maxvisrange) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check cell type
|
||||||
|
if (!cell->type->transparent) {
|
||||||
|
cellopaque = -1; // fullblock
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check lighting
|
||||||
|
if (!cellopaque) {
|
||||||
|
// outside the range of our light, and not lit
|
||||||
|
if (getcelldist(viewer->cell, cell) > nightvisrange) {
|
||||||
|
if (!islit(cell)) {
|
||||||
|
celldark = B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// inside our nightvis range and magically dark
|
||||||
|
if (cell->lit == L_PERMDARK) {
|
||||||
|
celldark = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for objects which block view
|
||||||
|
if (!cellopaque && !celldark) {
|
||||||
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
|
f = hasflag(o->flags, F_BLOCKSVIEW);
|
||||||
|
if (f) {
|
||||||
|
if (!lfhasflagval(viewer, F_CANSEETHROUGHMAT, o->material->id, NA, NA, NULL)) {
|
||||||
|
if (f->val[0] == B_TRUE) {
|
||||||
|
cellopaque = -1; // fullblock
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
cellopaque += f->val[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cellopaque) {
|
||||||
|
if (xray) {
|
||||||
|
xray--;
|
||||||
|
} else {
|
||||||
|
if (cellopaque == -1) {
|
||||||
|
// can see this one but not the rest.
|
||||||
|
setviscell(viewer, cell, B_VIS);
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
currange += cellopaque;
|
||||||
|
if (currange > maxvisrange) {
|
||||||
|
// can see this one but not the rest.
|
||||||
|
setviscell(viewer, cell, B_VIS);
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// xray vision decreases by one
|
||||||
|
if (xray) xray--;
|
||||||
|
|
||||||
|
// this cell is visible (unless it's dark)
|
||||||
|
if (celldark) {
|
||||||
|
setviscell(viewer, cell, B_NOVIS);
|
||||||
|
} else {
|
||||||
|
setviscell(viewer, cell, B_VIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// rest of cells are not visible.
|
||||||
|
for (n = i; n < numpixels; n++) {
|
||||||
|
setviscell(viewer, retcell[n], B_NOVIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int haslos(lifeform_t *viewer, cell_t *dest) {
|
int haslos(lifeform_t *viewer, cell_t *dest) {
|
||||||
int numpixels;
|
int numpixels;
|
||||||
int i;
|
int i;
|
||||||
|
@ -7463,6 +7721,7 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
|
||||||
|
|
||||||
// can we use pre-calced los?
|
// can we use pre-calced los?
|
||||||
//
|
//
|
||||||
|
|
||||||
if ((viewer->cell->map->lf == viewer) && viewer->los) {
|
if ((viewer->cell->map->lf == viewer) && viewer->los) {
|
||||||
for (i = 0;i < viewer->nlos; i++) {
|
for (i = 0;i < viewer->nlos; i++) {
|
||||||
if (viewer->los[i] == dest) {
|
if (viewer->los[i] == dest) {
|
||||||
|
@ -7626,7 +7885,7 @@ void initjobs(void) {
|
||||||
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL);
|
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL);
|
||||||
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL);
|
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL);
|
||||||
addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL);
|
addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL);
|
||||||
addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
|
//addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
|
||||||
for (i = 1; i < MAXSKILLS; i++) {
|
for (i = 1; i < MAXSKILLS; i++) {
|
||||||
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
|
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
|
||||||
}
|
}
|
||||||
|
@ -11378,7 +11637,10 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
||||||
|
|
||||||
// for precalcing line of sight
|
// for precalcing line of sight
|
||||||
a->nlos = 0;
|
a->nlos = 0;
|
||||||
a->los = NULL;
|
//a->los = malloc(sizeof(cell_t *) * MAXVISRANGE);
|
||||||
|
a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
|
||||||
|
//a->viscell = NULL;
|
||||||
|
a->viscell = malloc( sizeof(int) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
|
||||||
|
|
||||||
// for ai
|
// for ai
|
||||||
|
|
||||||
|
@ -12990,20 +13252,15 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
|
||||||
// if anything nearby hears it, it might respond
|
// if anything nearby hears it, it might respond
|
||||||
for (l = c->map->lf; l ; l = l->next) {
|
for (l = c->map->lf; l ; l = l->next) {
|
||||||
int dist;
|
int dist;
|
||||||
|
int difficulty;
|
||||||
|
int lbonus;
|
||||||
|
|
||||||
|
if (l == noisemaker) continue;
|
||||||
// ie. if this lf is in the process of swapping places
|
// ie. if this lf is in the process of swapping places
|
||||||
if (!l->cell) continue;
|
if (!l->cell) continue;
|
||||||
|
|
||||||
// if you make a noise while swapping position with
|
|
||||||
// something, its ->cell will be null here!
|
|
||||||
dist = getcelldist(l->cell, c);
|
dist = getcelldist(l->cell, c);
|
||||||
|
|
||||||
if (l != noisemaker) {
|
|
||||||
int difficulty;
|
|
||||||
int lbonus;
|
|
||||||
//if (canhear(l, c) && haslos(l, c)) {
|
|
||||||
|
|
||||||
|
|
||||||
// listen check difficulty is based on sound distance vs max hearing distance
|
// listen check difficulty is based on sound distance vs max hearing distance
|
||||||
if (nt == NC_SPEECH) {
|
if (nt == NC_SPEECH) {
|
||||||
// you always hear it, as long as you're in range
|
// you always hear it, as long as you're in range
|
||||||
|
@ -13021,8 +13278,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
|
||||||
}
|
}
|
||||||
|
|
||||||
// skillcheck to hear this
|
// skillcheck to hear this
|
||||||
if ( (haslos(l, c) ||
|
if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing"
|
||||||
(canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)))) {
|
(canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
// announce?
|
// announce?
|
||||||
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
|
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
|
||||||
|
@ -13110,6 +13367,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wake up a little
|
// wake up a little
|
||||||
f = lfhasflag(l, F_ASLEEP);
|
f = lfhasflag(l, F_ASLEEP);
|
||||||
if (f) {
|
if (f) {
|
||||||
|
@ -13155,7 +13413,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14877,7 +15134,8 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
||||||
roll = rolldie(1, 20);
|
roll = rolldie(1, 20);
|
||||||
|
|
||||||
if (db) {
|
if (db) {
|
||||||
sprintf(mbuf, "%s skillcheck - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name, diff, roll, attrib,levmod, othermod,mod);
|
sprintf(mbuf, "%s skillcheck (%d) - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name,
|
||||||
|
ct, diff, roll, attrib,levmod, othermod,mod);
|
||||||
}
|
}
|
||||||
modroll = roll;
|
modroll = roll;
|
||||||
modroll += attrib;
|
modroll += attrib;
|
||||||
|
|
6
lf.h
6
lf.h
|
@ -22,7 +22,7 @@ void autoweild(lifeform_t *lf);
|
||||||
int appearsrandomly(enum RACE rid);
|
int appearsrandomly(enum RACE rid);
|
||||||
void awardxpfor(lifeform_t *killed, float pct);
|
void awardxpfor(lifeform_t *killed, float pct);
|
||||||
void bleed(lifeform_t *lf);
|
void bleed(lifeform_t *lf);
|
||||||
void breakallgrabs(lifeform_t *lf);
|
void breakgrabs(lifeform_t *lf, int fromme, int tome);
|
||||||
long calcscore(lifeform_t *lf);
|
long calcscore(lifeform_t *lf);
|
||||||
int calcxp(lifeform_t *lf);
|
int calcxp(lifeform_t *lf);
|
||||||
int calcxprace(enum RACE rid);
|
int calcxprace(enum RACE rid);
|
||||||
|
@ -145,6 +145,10 @@ int getmaxmp(lifeform_t *lf);
|
||||||
float getmaxpushweight(lifeform_t *lf);
|
float getmaxpushweight(lifeform_t *lf);
|
||||||
int getmr(lifeform_t *lf);
|
int getmr(lifeform_t *lf);
|
||||||
int getvisrange(lifeform_t *lf);
|
int getvisrange(lifeform_t *lf);
|
||||||
|
void idxtoxy(lifeform_t *lf, int idx, int *x, int *y);
|
||||||
|
void setviscell(lifeform_t *lf, cell_t *cell, int how);
|
||||||
|
int getviscell(lifeform_t *lf, cell_t *cell);
|
||||||
|
int xytoidx(lifeform_t *lf, int x, int y);
|
||||||
int getmovespeed(lifeform_t *lf);
|
int getmovespeed(lifeform_t *lf);
|
||||||
char *getmoveverb(lifeform_t *lf);
|
char *getmoveverb(lifeform_t *lf);
|
||||||
char *getmoveverbother(lifeform_t *lf);
|
char *getmoveverbother(lifeform_t *lf);
|
||||||
|
|
4
map.c
4
map.c
|
@ -2033,7 +2033,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
||||||
enum HABITAT habitat;
|
enum HABITAT habitat;
|
||||||
regionthing_t *thing[MAXOUTLINETHINGS];
|
regionthing_t *thing[MAXOUTLINETHINGS];
|
||||||
int nthings = 0;
|
int nthings = 0;
|
||||||
int db = B_TRUE;
|
int db = B_FALSE;
|
||||||
|
|
||||||
// determine habitat based on region
|
// determine habitat based on region
|
||||||
// note: we might override this later based on our region outline
|
// note: we might override this later based on our region outline
|
||||||
|
@ -2505,7 +2505,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
||||||
int w,h,x,y;
|
int w,h,x,y;
|
||||||
int xmargin = 0,ymargin = 0;
|
int xmargin = 0,ymargin = 0;
|
||||||
int minx,miny,maxx,maxy;
|
int minx,miny,maxx,maxy;
|
||||||
int db = B_TRUE;
|
int db = B_FALSE;
|
||||||
int rotation = 0;
|
int rotation = 0;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
|
||||||
|
|
11
move.c
11
move.c
|
@ -695,7 +695,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
||||||
howfar *= 2;
|
howfar *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
breakallgrabs(lf);
|
breakgrabs(lf, B_TRUE, B_TRUE);
|
||||||
|
|
||||||
for (i = 0; i < howfar; i++) {
|
for (i = 0; i < howfar; i++) {
|
||||||
if (moveclear(lf, dir, &reason)) {
|
if (moveclear(lf, dir, &reason)) {
|
||||||
|
@ -983,11 +983,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
// update new cell
|
// update new cell
|
||||||
newcell->lf = lf;
|
newcell->lf = lf;
|
||||||
|
|
||||||
|
/*
|
||||||
// update light
|
// update light
|
||||||
if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
|
if (lfproduceslight(lf) || (changedlev && isplayer(lf))) {
|
||||||
calclight(lf->cell->map);
|
calclight(lf->cell->map);
|
||||||
precalclos(lf);
|
precalclos(lf);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// update light
|
||||||
|
if (lfproduceslight(lf)) {
|
||||||
|
calclight(lf->cell->map);
|
||||||
|
}
|
||||||
|
precalclos(lf);
|
||||||
|
|
||||||
if (isplayer(lf) || cansee(player, lf)) {
|
if (isplayer(lf) || cansee(player, lf)) {
|
||||||
needredraw = B_TRUE;
|
needredraw = B_TRUE;
|
||||||
|
@ -1150,6 +1157,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
// ISNT a vault, reveal it.
|
// ISNT a vault, reveal it.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) {
|
if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) {
|
||||||
if ((postroom > 0) && (postroom != preroom)) {
|
if ((postroom > 0) && (postroom != preroom)) {
|
||||||
cell_t *c[MAX_MAPW*MAX_MAPH];
|
cell_t *c[MAX_MAPW*MAX_MAPH];
|
||||||
|
@ -1176,6 +1184,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// does anyone else see you?
|
// does anyone else see you?
|
||||||
|
|
1
nexus.c
1
nexus.c
|
@ -379,6 +379,7 @@ int main(int argc, char **argv) {
|
||||||
// show level (if required)
|
// show level (if required)
|
||||||
//if (haslos(player, curmap->lf->cell)) {
|
//if (haslos(player, curmap->lf->cell)) {
|
||||||
drawscreen();
|
drawscreen();
|
||||||
|
|
||||||
//dblog("**** END of turn, numdraws = %d", numdraws);
|
//dblog("**** END of turn, numdraws = %d", numdraws);
|
||||||
|
|
||||||
|
|
||||||
|
|
5
spell.c
5
spell.c
|
@ -4028,7 +4028,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
}
|
}
|
||||||
} else if (spellid == OT_S_GASEOUSFORM) {
|
} else if (spellid == OT_S_GASEOUSFORM) {
|
||||||
if (!target) target = caster;
|
if (!target) target = caster;
|
||||||
if (hasmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
if (getmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||||
if (isplayer(target)) {
|
if (isplayer(target)) {
|
||||||
msg("You feel momentarily insubstantial.");
|
msg("You feel momentarily insubstantial.");
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
@ -5822,7 +5822,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
f = addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong);
|
f = addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong);
|
||||||
f->obfrom = OT_S_PASSWALL;
|
f->obfrom = OT_S_PASSWALL;
|
||||||
|
|
||||||
breakallgrabs(caster);
|
breakgrabs(target, B_TRUE, B_TRUE);
|
||||||
} else if (spellid == OT_S_POLYMORPH) {
|
} else if (spellid == OT_S_POLYMORPH) {
|
||||||
race_t *r = NULL;
|
race_t *r = NULL;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
@ -5930,6 +5930,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
if (haslos(player, target->cell)) {
|
if (haslos(player, target->cell)) {
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
}
|
}
|
||||||
|
breakgrabs(target, B_TRUE, B_TRUE);
|
||||||
} else {
|
} else {
|
||||||
fizzle(caster);
|
fizzle(caster);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! filled with random monsters
|
! filled with random monsters
|
||||||
@id:monsterzoo
|
@id:monsterzoo
|
||||||
@map
|
@map
|
||||||
random(4,4)
|
random(3,3,5,5)
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@legend
|
@legend
|
||||||
|
|
Loading…
Reference in New Issue