增加dog和eat的注释

chenguanyu_branch
陈冠宇 1 year ago
parent d83233d22b
commit 6824d6dec2

@ -19,7 +19,7 @@ enum arrival {
}; };
void void
newedog(struct monst *mtmp) newedog(struct monst *mtmp) /*Create a new dog*/
{ {
if (!mtmp->mextra) if (!mtmp->mextra)
mtmp->mextra = newmextra(); mtmp->mextra = newmextra();
@ -30,26 +30,26 @@ newedog(struct monst *mtmp)
} }
void void
free_edog(struct monst *mtmp) free_edog(struct monst *mtmp) /*This code is about releasing a struct resource called "edog"*/
{ {
if (mtmp->mextra && EDOG(mtmp)) { if (mtmp->mextra && EDOG(mtmp)) { /*This line of code first checks if the mextra member of mtmp is non-empty, and calls the EDOG(mtmp) macro to get the edog struct associated with mtmp. If both conditions are met, the code in curly braces is executed.*/
free((genericptr_t) EDOG(mtmp)); free((genericptr_t) EDOG(mtmp)); /*This line of code uses the free function to free up the memory space occupied by the EDOG struct obtained through the EDOG(mtmp) macro. (genericptr_t) EDOG(mtmp) converts Pointers to the edog structure to a generic pointer type to ensure proper memory release.*/
EDOG(mtmp) = (struct edog *) 0; EDOG(mtmp) = (struct edog *) 0; /*This line sets the pointer to the EDOG struct fetched by the EDOG(mtmp) macro to NULL to indicate that the struct has been released.*/
} }
mtmp->mtame = 0; mtmp->mtame = 0;
} }
void void
initedog(struct monst *mtmp) initedog(struct monst *mtmp) /*Initialize the dog*/
{ {
mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5; mtmp->mtame = is_domestic(mtmp->data) ? 10 : 5; /*This line of code determines whether the dog is a domestic dog, and sets its taming to 10 if it is, or 5 if it is not. is_domestic might be a function that checks whether mtmp->data represents a domestic dog.*/
mtmp->mpeaceful = 1; mtmp->mpeaceful = 1;
mtmp->mavenge = 0; mtmp->mavenge = 0;
set_malign(mtmp); /* recalc alignment now that it's tamed */ set_malign(mtmp); /* recalc alignment now that it's tamed */
mtmp->mleashed = 0; mtmp->mleashed = 0;
mtmp->meating = 0; mtmp->meating = 0;
EDOG(mtmp)->droptime = 0; EDOG(mtmp)->droptime = 0;
EDOG(mtmp)->dropdist = 10000; EDOG(mtmp)->dropdist = 10000; /*These two lines of code set the dog's item drop time and distance.*/
EDOG(mtmp)->apport = ACURR(A_CHA); EDOG(mtmp)->apport = ACURR(A_CHA);
EDOG(mtmp)->whistletime = 0; EDOG(mtmp)->whistletime = 0;
EDOG(mtmp)->hungrytime = 1000 + gm.moves; EDOG(mtmp)->hungrytime = 1000 + gm.moves;
@ -61,18 +61,18 @@ initedog(struct monst *mtmp)
EDOG(mtmp)->killed_by_u = 0; EDOG(mtmp)->killed_by_u = 0;
u.uconduct.pets++; u.uconduct.pets++;
} }
/*In general, this code initializes a dog's status, including its tame, flatness, marital status, evil, whether it is tied, whether it is eating, the related Settings for item drop, charisma, hunger time, target location, whether it has been abused, whether it has been resurrected, maximum health penalty, and whether it has been killed by the player. At the same time, this code also reflects that in the game, the player can have pets, and the number of pets has been increased during the initialization process.*/
static int static int
pet_type(void) pet_type(void)
{ {
if (gu.urole.petnum != NON_PM) if (gu.urole.petnum != NON_PM) /*The number of pets of a user character (possibly a player character in the game) is checked here*/
return gu.urole.petnum; return gu.urole.petnum;
else if (gp.preferred_pet == 'c') else if (gp.preferred_pet == 'c')
return PM_KITTEN; return PM_KITTEN;
else if (gp.preferred_pet == 'd') else if (gp.preferred_pet == 'd')
return PM_LITTLE_DOG; return PM_LITTLE_DOG;
else else
return rn2(2) ? PM_KITTEN : PM_LITTLE_DOG; return rn2(2) ? PM_KITTEN : PM_LITTLE_DOG; /*A ternary operator is used here. It first calls the function rn2(2) (probably a random number generating function, but the argument 2 May represent some kind of distribution or range) and then decides which pet class to return based on the result of this random number*/
} }
struct monst * struct monst *
@ -178,7 +178,7 @@ make_familiar(struct obj *otmp, coordxy x, coordxy y, boolean quietly)
struct monst * struct monst *
makedog(void) makedog(void)
{ { /*When the pet type is 'n', the function returns an empty struct pointer; When the pet type is PM_LITTLE_DOG, set the pet name to gd.dogname. When the pet type is PM_PONY, set the pet name to gh.horsename; Otherwise, set pet name to gc.catname.*/
register struct monst *mtmp; register struct monst *mtmp;
register struct obj *otmp; register struct obj *otmp;
const char *petname; const char *petname;
@ -434,7 +434,19 @@ mon_arrive(struct monst *mtmp, int when)
wander = (xint16) min(nmv, 8L); wander = (xint16) min(nmv, 8L);
} else } else
wander = 0; wander = 0;
/*If the value of xyloc is MIGR_APPROX_XY, the code doesn't do anything, because xlocale and ylocale are already set above.
If xyloc has a value of MIGR_EXACT_XY, set wander's value to 0.
If the value of xyloc is MIGR_WITH_HERO, assign the values U.U.X and U.U.Y to xlocale and ylocale, respectively.
If the value of xyloc is MIGR_STAIRS_UP or MIGR_STAIRS_DOWN, look for stairs starting from the given floor, and if found, assign the x and y coordinates of the stairs to xlocale and ylocale, respectively.
If the value of xyloc is MIGR_LADDER_UP or MIGR_LADDER_DOWN, look for the stairs starting from the given floor, and if found, assign the x and y coordinates of the stairs to xlocale and ylocale, respectively.
If the value of xyloc is MIGR_SSTAIRS, find the stairs for the given floor, and if found, assign the x and y coordinates of the stairs to xlocale and ylocale, respectively.
If the value of xyloc is MIGR_PORTAL, check whether you are in the final game level. If it is, it randomly generates an internal coordinate in the target region and assigns it to xlocale and ylocale.*/
switch (xyloc) { switch (xyloc) {
case MIGR_APPROX_XY: /* {x,y}locale set above */ case MIGR_APPROX_XY: /* {x,y}locale set above */
break; break;
@ -1246,18 +1258,18 @@ wary_dog(struct monst *mtmp, boolean was_dead)
void void
abuse_dog(struct monst *mtmp) abuse_dog(struct monst *mtmp)
{ {
if (!mtmp->mtame) if (!mtmp->mtame) /*If the monster is not tamed (mtame is 0), the function returns directly.*/
return; return;
if (Aggravate_monster || Conflict) if (Aggravate_monster || Conflict) /*If Aggravate_monster or Conflict variables in the game are true, then the monster's tame level (mtame) will be halved. Otherwise, the monster's taming level will be reduced by 1.*/
mtmp->mtame /= 2; mtmp->mtame /= 2;
else else
mtmp->mtame--; mtmp->mtame--;
if (mtmp->mtame && !mtmp->isminion) if (mtmp->mtame && !mtmp->isminion) /*If the monster is not a pawn (isminion is 0) and the monster's taming level is greater than 0, the monster's abuse count is increased by 1*/
EDOG(mtmp)->abuse++; EDOG(mtmp)->abuse++;
if (!mtmp->mtame && mtmp->mleashed) if (!mtmp->mtame && mtmp->mleashed) /*If the monster has been tamed (mtame greater than or equal to 0) and is tethered (mleashed is true), the monster will be untethered.*/
m_unleash(mtmp, TRUE); m_unleash(mtmp, TRUE);
/* don't make a sound if pet is in the middle of leaving the level */ /* don't make a sound if pet is in the middle of leaving the level */

@ -4,7 +4,7 @@
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
#include "hack.h" #include "hack.h"
/*Define the required structure*/
static int eatmdone(void); static int eatmdone(void);
static int eatfood(void); static int eatfood(void);
static struct obj *costly_tin(int); static struct obj *costly_tin(int);
@ -392,7 +392,7 @@ food_disappears(struct obj *obj)
resume eating/opening would restart from scratch */ resume eating/opening would restart from scratch */
void void
food_substitution(struct obj *old_obj, struct obj *new_obj) food_substitution(struct obj *old_obj, struct obj *new_obj)
{ { /*A declaration of a function, which defines a function named food_substitution and takes two arguments: old_obj and new_obj. Both of these parameters are Pointers to the obj structure.*/
if (old_obj == gc.context.victual.piece) { if (old_obj == gc.context.victual.piece) {
gc.context.victual.piece = new_obj; gc.context.victual.piece = new_obj;
gc.context.victual.o_id = new_obj->o_id; gc.context.victual.o_id = new_obj->o_id;
@ -406,7 +406,7 @@ food_substitution(struct obj *old_obj, struct obj *new_obj)
static void static void
do_reset_eat(void) do_reset_eat(void)
{ {
debugpline0("do_reset_eat..."); debugpline0("do_reset_eat..."); /*代码检查gc.context.victual.piece是否为真。gc.context.victual.piece可能代表当前正在被吃的食物或者对象。*/
if (gc.context.victual.piece) { if (gc.context.victual.piece) {
gc.context.victual.o_id = 0; gc.context.victual.o_id = 0;
gc.context.victual.piece = touchfood(gc.context.victual.piece); gc.context.victual.piece = touchfood(gc.context.victual.piece);
@ -513,24 +513,24 @@ eatfood(void)
static void static void
done_eating(boolean message) done_eating(boolean message)
{ {// 从gc结构体中获取到正在被吃的食物或对象并将其地址赋给piece指针
struct obj *piece = gc.context.victual.piece; struct obj *piece = gc.context.victual.piece;
// 将该食物或对象标记为正在使用,表示已经被角色选中
piece->in_use = TRUE; piece->in_use = TRUE;
go.occupation = 0; /* do this early, so newuhs() knows we're done */ go.occupation = 0; /* do this early, so newuhs() knows we're done */
newuhs(FALSE); newuhs(FALSE);// 调用newuhs函数将FALSE作为参数传入可能表示角色已经完成了一个周期的活动或状态
if (gn.nomovemsg) { if (gn.nomovemsg) {// 检查gn结构体中的nomovemsg字段如果存在并且message为真则打印一条消息
if (message) if (message)
pline1(gn.nomovemsg); pline1(gn.nomovemsg);
gn.nomovemsg = 0; gn.nomovemsg = 0;
} else if (message) { } else if (message) {
You("finish %s %s.", You("finish %s %s.", // 如果nomovemsg字段不存在并且message为真则打印一条消息表示角色已经完成了一个动作这里可能表示角色已经吃完了一个食物或者对象
(gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming" (gy.youmonst.data == &mons[PM_FIRE_ELEMENTAL]) ? "consuming"
: "eating", : "eating",
food_xname(piece, TRUE)); food_xname(piece, TRUE));
} }
if (piece->otyp == CORPSE || piece->globby) if (piece->otyp == CORPSE || piece->globby)// 如果食物或对象是一个尸体或者是一个普通的对象调用cpostfx函数处理它的后效否则调用fpostfx函数处理它的后效
cpostfx(piece->corpsenm); cpostfx(piece->corpsenm);
else else
fpostfx(piece); fpostfx(piece);
@ -539,14 +539,14 @@ done_eating(boolean message)
useup(piece); useup(piece);
else else
useupf(piece, 1L); useupf(piece, 1L);
//将gc结构体中的victual字段重置为零表示角色已经完成了一个进食周期并将食物或对象的指针设置为0以及将其o_id字段也设置为0
gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ gc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */
} }
void void
eating_conducts(struct permonst *pd) eating_conducts(struct permonst *pd)
{ {
int ll_conduct = 0; int ll_conduct = 0;// 定义一个整型变量ll_conduct并将其初始化为0。这个变量可能用来计数某种行为或条件被满足的次数
if (!u.uconduct.food++) { if (!u.uconduct.food++) {
livelog_printf(LL_CONDUCT, "ate for the first time - %s", livelog_printf(LL_CONDUCT, "ate for the first time - %s",
@ -554,18 +554,20 @@ eating_conducts(struct permonst *pd)
ll_conduct++; ll_conduct++;
} }
if (!vegan(pd)) { if (!vegan(pd)) {
if (!u.uconduct.unvegan++ && !ll_conduct) { if (!u.uconduct.unvegan++
livelog_printf(LL_CONDUCT, && !ll_conduct) { // 检查u.uconduct.food的值。如果它为真那么执行下面的代码。否则跳过。在这个情况下由于food的值被递增了所以它始终为真这可能是代码的一个错误。
livelog_printf(
LL_CONDUCT, // 打印一条消息到日志,说明这个生物第一次进食。消息的内容是这个生物的中性名称
"consumed animal products (%s) for the first time", "consumed animal products (%s) for the first time",
pd->pmnames[NEUTRAL]); pd->pmnames[NEUTRAL]);
ll_conduct++; ll_conduct++; // 由于food的值已经被递增所以ll_conduct的值增加1
} }
} }
if (!vegetarian(pd)) { if (!vegetarian(pd)) {// 检查pd是否是素食的。如果不是执行下面的代码。否则跳过。
if (!u.uconduct.unvegetarian && !ll_conduct) if (!u.uconduct.unvegetarian && !ll_conduct)// 如果这个生物第一次消费非素食且之前没有违反任何条件ll_conduct为0那么执行下面的代码。
livelog_printf(LL_CONDUCT, "tasted meat (%s) for the first time", livelog_printf(LL_CONDUCT, "tasted meat (%s) for the first time",// 打印一条消息到日志,说明这个生物第一次消费动物产品。消息的内容是这个生物的中性名称。
pd->pmnames[NEUTRAL]); pd->pmnames[NEUTRAL]);
violated_vegetarian(); violated_vegetarian();// 调用violated_vegetarian函数可能是处理违反素食规定的情况。
} }
} }
@ -575,6 +577,7 @@ eat_brains(
struct monst *magr, struct monst *magr,
struct monst *mdef, struct monst *mdef,
boolean visflag, boolean visflag,
int *dmg_p) /* for dishing out extra damage in lieu of Int loss */ int *dmg_p) /* for dishing out extra damage in lieu of Int loss */
{ {
struct permonst *pd = mdef->data; struct permonst *pd = mdef->data;
@ -755,18 +758,25 @@ maybe_cannibal(int pm, boolean allowmsg)
static void static void
cprefx(register int pm) cprefx(register int pm)
{ {
(void) maybe_cannibal(pm, TRUE); (void) maybe_cannibal(
if (flesh_petrifies(&mons[pm])) { pm,
if (!Stone_resistance TRUE); // 调用maybe_cannibal函数将pm和TRUE作为参数传入。maybe_cannibal函数可能处理关于食人的特定情况
&& !(poly_when_stoned(gy.youmonst.data) if (flesh_petrifies(&mons[pm])) {// 调用flesh_petrifies函数将mons[pm]的地址作为参数传入。如果该函数返回真,则执行下面的代码块
if (!Stone_resistance// 检查角色是否对石头有抵抗力
&& !(
poly_when_stoned(
gy.youmonst
.data) // 检查角色是否在变成石头时具有多态性(可以变成其他的怪物)
&& polymon(PM_STONE_GOLEM))) { && polymon(PM_STONE_GOLEM))) {
Sprintf(gk.killer.name, "tasting %s meat", Sprintf(gk.killer.name, "tasting %s meat",// 格式化字符串将怪物mons[pm]的中性名称添加到字符串中并存储在gk.killer.name中。这可能表示杀手的名称或者某种杀人行为的描述
mons[pm].pmnames[NEUTRAL]); mons[pm].pmnames[NEUTRAL]);
gk.killer.format = KILLED_BY; gk.killer.format =
KILLED_BY; // 设置gk.killer.format为KILLED_BY。这可能是一个标志表示某种死亡方式例如被xx杀死
You("turn to stone."); You("turn to stone.");
done(STONING); done(STONING);// 调用done函数将STONING作为参数传入。这可能表示完成了变成石头的动画或者状态
if (gc.context.victual.piece) if (gc.context.victual.piece)// 检查gc.context.victual.piece是否为真。如果为真执行下面的代码块
gc.context.victual.eating = 0; gc.context.victual.eating =
0; // 将gc.context.victual.eating设置为0。可能表示停止进食的行为或者重置某种状态
return; /* lifesaved */ return; /* lifesaved */
} }
} }
@ -960,7 +970,7 @@ temp_givit(int type, struct permonst *ptr)
* and what type of intrinsic it is trying to give you. * and what type of intrinsic it is trying to give you.
*/ */
static void static void
givit(int type, register struct permonst *ptr) givit(int type, register struct permonst *ptr)//Analysis for different situations
{ {
debugpline1("Attempting to give intrinsic %d", type); debugpline1("Attempting to give intrinsic %d", type);
@ -1384,8 +1394,10 @@ tin_details(struct obj *obj, int mnum, char *buf)
Strcat(buf, " of spinach"); Strcat(buf, " of spinach");
else if (mnum == NON_PM) else if (mnum == NON_PM)
Strcpy(buf, "empty tin"); Strcpy(buf, "empty tin");
else { else {//// 如果 obj->cknown 为真或者 iflags.override_ID 为真,并且 obj->spe < 0那么执行以下代码块。
// 这可能意味着这是一个已知的、被重定向的、并且其特殊属性小于0的物体。
if ((obj->cknown || iflags.override_ID) && obj->spe < 0) { if ((obj->cknown || iflags.override_ID) && obj->spe < 0) {
if (r == ROTTEN_TIN || r == HOMEMADE_TIN) {//// 如果 r 的值为 ROTTEN_TIN 或者 HOMEMADE_TIN那么将字符串 " of " 和 tintxts[r].txt 追加到 buf2 中,然后将 buf2 复制到 buf 中。
if (r == ROTTEN_TIN || r == HOMEMADE_TIN) { if (r == ROTTEN_TIN || r == HOMEMADE_TIN) {
/* put these before the word tin */ /* put these before the word tin */
Sprintf(buf2, "%s %s of ", tintxts[r].txt, buf); Sprintf(buf2, "%s %s of ", tintxts[r].txt, buf);
@ -1396,7 +1408,12 @@ tin_details(struct obj *obj, int mnum, char *buf)
} else { } else {
Strcpy(eos(buf), " of "); Strcpy(eos(buf), " of ");
} }
if (vegetarian(&mons[mnum])) if (vegetarian(
&mons[mnum])) // 检查 mons[mnum]
// 是否为素食。如果是素食,那么将
// mons[mnum].pmnames[NEUTRAL] 追加到 buf
// 的末尾。否则,将字符串 "meat" 和
// mons[mnum].pmnames[NEUTRAL] 追加到 buf 的末尾
Sprintf(eos(buf), "%s", mons[mnum].pmnames[NEUTRAL]); Sprintf(eos(buf), "%s", mons[mnum].pmnames[NEUTRAL]);
else else
Sprintf(eos(buf), "%s meat", mons[mnum].pmnames[NEUTRAL]); Sprintf(eos(buf), "%s meat", mons[mnum].pmnames[NEUTRAL]);

Loading…
Cancel
Save