mextra tweaks (trunk only)

Add new_mname/free_mname functions to make monster name handling be
more like the other extended data and to hide mextra details a bit more.
Add some casts where int and unsigned are being intermixed.  Simplify
christen_monst(); it ought to be changed to have type `void' but I wanted
to avoid modifying another ten or so files.
This commit is contained in:
nethack.rankin
2006-01-08 06:19:42 +00:00
parent 0bdb1fba28
commit 039e051323
6 changed files with 80 additions and 74 deletions

View File

@@ -348,6 +348,8 @@ E void NDECL(heal_legs);
/* ### do_name.c ### */
E int FDECL(getpos, (coord *,BOOLEAN_P,const char *));
E void FDECL(new_mname, (struct monst *,int));
E void FDECL(free_mname, (struct monst *));
E struct monst *FDECL(christen_monst, (struct monst *,const char *));
E int NDECL(do_mname);
E struct obj *FDECL(oname, (struct obj *,const char *));

View File

@@ -1853,14 +1853,15 @@ STATIC_OVL int
size_monst(mtmp)
struct monst *mtmp;
{
int sz = sizeof(struct monst);
int sz = (int)sizeof (struct monst);
if (mtmp->mextra) {
if (MNAME(mtmp)) sz += strlen(MNAME(mtmp))+1;
if (EGD(mtmp)) sz += sizeof(struct egd);
if (EPRI(mtmp)) sz += sizeof(struct epri);
if (ESHK(mtmp)) sz += sizeof(struct eshk);
if (EMIN(mtmp)) sz += sizeof(struct emin);
if (EDOG(mtmp)) sz += sizeof(struct edog);
if (MNAME(mtmp)) sz += (int)strlen(MNAME(mtmp)) + 1;
if (EGD(mtmp)) sz += (int)sizeof (struct egd);
if (EPRI(mtmp)) sz += (int)sizeof (struct epri);
if (ESHK(mtmp)) sz += (int)sizeof (struct eshk);
if (EMIN(mtmp)) sz += (int)sizeof (struct emin);
if (EDOG(mtmp)) sz += (int)sizeof (struct edog);
}
return sz;
}
@@ -1964,6 +1965,7 @@ wiz_migrate_mons()
struct permonst *ptr;
struct monst *mtmp;
d_level tolevel;
getlin("How many random monsters to migrate? [0]", inbuf);
if (*inbuf == '\033') return 0;
mcount = atoi(inbuf);

View File

@@ -212,6 +212,36 @@ const char *goal;
return result;
}
/* allocate space for a monster's name; removes old name if there is one */
void
new_mname(mon, lth)
struct monst *mon;
int lth; /* desired length (caller handles adding 1 for terminator) */
{
if (lth) {
/* allocate mextra if necessary; otherwise get rid of old name */
if (!mon->mextra) mon->mextra = newmextra();
else free_mname(mon); /* already has mextra, might also have name */
MNAME(mon) = (char *) alloc((unsigned) lth);
} else {
/* zero length: the new name is empty; get rid of the old name */
if (has_name(mon)) free_mname(mon);
}
}
/* release a monster's name; retains mextra even if all fields are now null */
void
free_mname(mon)
struct monst *mon;
{
if (has_name(mon)) {
free((genericptr_t)MNAME(mon));
MNAME(mon) = (char *)0;
}
}
/* historical note: this returns a monster pointer because it used to
allocate a new bigger block of memory to hold the monster and its name */
struct monst *
christen_monst(mtmp, name)
struct monst *mtmp;
@@ -221,23 +251,15 @@ const char *name;
char buf[PL_PSIZ];
/* dogname & catname are PL_PSIZ arrays; object names have same limit */
lth = *name ? (int)(strlen(name) + 1) : 0;
if(lth > PL_PSIZ){
lth = (name && *name) ? ((int)strlen(name) + 1) : 0;
if (lth > PL_PSIZ) {
lth = PL_PSIZ;
name = strncpy(buf, name, PL_PSIZ - 1);
buf[PL_PSIZ - 1] = '\0';
}
if (has_name(mtmp) && lth == (int)(strlen(MNAME(mtmp)) + 1)) {
/* don't need to allocate a new mname */
if (lth) Strcpy(MNAME(mtmp), name);
return mtmp;
}
if (has_name(mtmp)) free((genericptr_t)MNAME(mtmp));
if (!mtmp->mextra) mtmp->mextra = newmextra();
MNAME(mtmp) = (char *)alloc(lth);
new_mname(mtmp, lth); /* removes old name if one is present */
if (lth) Strcpy(MNAME(mtmp), name);
return(mtmp);
return mtmp;
}
int
@@ -287,8 +309,8 @@ do_mname()
return(0);
}
/* special case similar to the one in lookat() */
(void) distant_monnam(mtmp, ARTICLE_THE, monnambuf);
Sprintf(qbuf, "What do you want to call %s?", monnambuf);
Sprintf(qbuf, "What do you want to call %s?",
distant_monnam(mtmp, ARTICLE_THE, monnambuf));
getlin(qbuf,buf);
if(!*buf || *buf == '\033') return(0);
/* strip leading and trailing spaces; unnames monster if all spaces */

View File

@@ -232,28 +232,19 @@ unsigned corpseflags;
num = d(2,6);
while (num--)
obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp); /* don't christen obj */
break;
case PM_GLASS_GOLEM:
num = d(2,4); /* very low chance of creating all glass gems */
while (num--)
obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
case PM_CLAY_GOLEM:
obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
obj->quan = (long)(rn2(20) + 50);
obj->owt = weight(obj);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
case PM_STONE_GOLEM:
corpstatflags &= ~CORPSTAT_INIT;
@@ -265,36 +256,24 @@ unsigned corpseflags;
while(num--) {
obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
}
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
case PM_LEATHER_GOLEM:
num = d(2,4);
while(num--)
obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
case PM_GOLD_GOLEM:
/* Good luck gives more coins */
obj = mkgold((long)(200 - rnl(101)), x, y);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
case PM_PAPER_GOLEM:
num = rnd(4);
while (num--)
obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
if (has_name(mtmp)) {
free((genericptr_t)MNAME(mtmp));
MNAME(mtmp) = (char *)0;
}
free_mname(mtmp);
break;
default_1:
default:
@@ -1379,8 +1358,8 @@ struct mextra *x;
if (x->eshk) free((genericptr_t)x->eshk);
if (x->emin) free((genericptr_t)x->emin);
if (x->edog) free((genericptr_t)x->edog);
free((genericptr_t)x);
}
free((genericptr_t)x);
}
void
@@ -2622,8 +2601,12 @@ boolean msg; /* "The oldmon turns into a newmon!" */
newsym(mtmp->mx,mtmp->my);
if (msg) {
char *save_mname = (has_name(mtmp)) ? MNAME(mtmp) : (char *)0;
if (mtmp->mextra) MNAME(mtmp) = (char *)0;
char *save_mname = 0;
if (has_name(mtmp)) {
save_mname = MNAME(mtmp);
MNAME(mtmp) = (char *)0;
}
Strcpy(newname,
(mdat == &mons[PM_GREEN_SLIME]) ? "slime" :
x_monnam(mtmp, ARTICLE_A, (char *)0,SUPPRESS_SADDLE, FALSE));
@@ -2631,7 +2614,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
(void) usmellmon(mdat);
else
pline("%s turns into %s!", oldname, newname);
if(mtmp->mextra) MNAME(mtmp) = save_mname;
if (save_mname) MNAME(mtmp) = save_mname;
}
possibly_unwield(mtmp, polyspot); /* might lose use of weapon */

View File

@@ -297,13 +297,12 @@ genericptr_t buffer;
(void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
spot += sizeof(int);
if (lth) {
if (!mtmp->mextra) mtmp->mextra = newmextra();
MNAME(mtmp) = (char *)alloc(lth);
new_mname(mtmp, lth);
(void) memcpy((genericptr_t)MNAME(mtmp),
(genericptr_t)spot, lth);
spot += lth;
}
/* obtain the length of the egd (guard) structure */
/* obtain the length of the egd (vault guard) structure */
(void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
spot += sizeof(int);
if (lth) {
@@ -371,8 +370,7 @@ boolean ghostly;
/* read the length of the name and the name */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
if (!mtmp->mextra) mtmp->mextra = newmextra();
MNAME(mtmp) = (char *)alloc(buflen);
new_mname(mtmp, buflen);
mread(fd, (genericptr_t) MNAME(mtmp), buflen);
}

View File

@@ -1019,47 +1019,46 @@ int *isize;
genericptr_t buffer, xptr[6];
struct monst *mbuf;
lth = sizeof(struct monst);
/* assert((sizeof (*mbuf->mextra) / sizeof (char *)) == 6); */
lth = (int)sizeof (struct monst);
/* there is always one sizeof(int) for the name
and one for each of the 5 potential mextra fields */
for (k = 0; k < 6; ++k) {
/* there is always one sizeof(int) for each mextra field */
for (k = 0; k < SIZE(xlth); ++k) {
xlth[k] = 0;
xptr[k] = (genericptr_t)0;
}
if (mtmp->mextra) {
if (MNAME(mtmp)) {
xlth[0] = strlen(MNAME(mtmp)) + 1;
xlth[0] = (int)strlen(MNAME(mtmp)) + 1;
xptr[0] = (genericptr_t)MNAME(mtmp);
}
if (EGD(mtmp)) {
xlth[1] = sizeof(struct egd);
xlth[1] = (int)sizeof (struct egd);
xptr[1] = (genericptr_t)EGD(mtmp);
}
if (EPRI(mtmp)) {
xlth[2] = sizeof(struct epri);
xlth[2] = (int)sizeof (struct epri);
xptr[2] = (genericptr_t)EPRI(mtmp);
}
if (ESHK(mtmp)) {
xlth[3] = sizeof(struct eshk);
xlth[3] = (int)sizeof (struct eshk);
xptr[3] = (genericptr_t)ESHK(mtmp);
}
if (EMIN(mtmp)) {
xlth[4] = sizeof(struct emin);
xlth[4] = (int)sizeof (struct emin);
xptr[4] = (genericptr_t)EMIN(mtmp);
}
if (EDOG(mtmp)) {
xlth[5] = sizeof(struct edog);
xlth[5] = (int)sizeof (struct edog);
xptr[5] = (genericptr_t)EDOG(mtmp);
}
}
for (k = 0; k < 6; ++k) {
lth += sizeof(int);
lth += xlth[k];
for (k = 0; k < SIZE(xlth); ++k) {
lth += (int)sizeof (int) + xlth[k];
}
if (isize) *isize = lth;
buffer = alloc(lth);
buffer = alloc((unsigned) lth);
spot = (char *)buffer;
(void) memcpy((genericptr_t)spot, (genericptr_t)mtmp,
@@ -1069,10 +1068,10 @@ int *isize;
mbuf = (struct monst *)buffer;
mbuf->mextra = (struct mextra *)0;
for (k = 0; k < 6; ++k) {
for (k = 0; k < SIZE(xlth); ++k) {
lth = xlth[k];
(void) memcpy((genericptr_t)spot,
(genericptr_t)&lth, sizeof(lth));
(genericptr_t)&lth, sizeof(lth));
spot += sizeof(lth);
if (lth > 0 && xptr[k] != 0) {
(void) memcpy((genericptr_t)spot, xptr[k], lth);