AM_CONFIG_HEADER(src/autoconf.h)
-AM_INIT_AUTOMAKE(hengband, 1.3.2)
+AM_INIT_AUTOMAKE(hengband, 1.5.0)
AC_ARG_WITH(setgid,
[ --with-setgid=NAME install hengband as group NAME],
****************************************
- ** Hengband 1.3.2 **
+ ** Hengband 1.5.0 **
****************************************
Based on Moria: Copyright (c) 1985 Robert Alan Koeneke
***************************************
- ** ÊѶòÈÚÅÜ 1.3.2 **
+ ** ÊѶòÈÚÅÜ 1.5.0 **
***************************************
Based on Moria: Copyright (c) 1985 Robert Alan Koeneke
¤³¤È¤¬¤ï¤«¤Ã¤Æ¤¤¤ë¥¢¥¤¥Æ¥à¤òÁõÈ÷¤·¤è¤¦¤È¤¹¤ë¤È¡¢³Îǧ¤·¤Æ¤¯¤ë¤è¤¦¤Ë
¤Ê¤ë¤Î¤Ç¤¹¡£
-***** <confirm_stairs>
-Ê̤γ¬¤Ë¹Ô¤¯»þ³Îǧ¤¹¤ë [confirm_stairs]
- Ãæ¤Ë¤Ï¶öÁ³'<'¥¡¼¤ò²¡¤·¤ÆÆÃÊ̤ÊÊ·°Ïµ¤¤ò´¶¤¸¼è¤Ã¤¿³¬¤«¤éÈ´¤±¤Æ¤·¤Þ
- ¤¦¿Í¤â¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òON¤Ë¤¹¤ì¤Ð¡¢³¬¤ò°ÜÆ°¤·¤è
- ¤¦¤È¤¹¤ëÅ٤˳Îǧ¤¬µá¤á¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+***** <confirm_quest>
+¥¯¥¨¥¹¥È¤òÄü¤á¤Æ³¬ÃʤÇƨ¤²¤ëÁ°¤Ë³Îǧ¤¹¤ë [confirm_quest]
+ ¥À¥ó¥¸¥ç¥ó¤ÎÃæ¤ÎÄ̾ï¤Î³¬Ãʤϼ«Í³¤ËÅФê¹ß¤ê¤·¤Æ¸µ¤Î¾ì½ê¤ËÌá¤ì¤Þ¤¹¤¬¡£
+ ¥¯¥¨¥¹¥È¤Î¥Õ¥í¥¢Æâ¤Ç¤Ï³¬ÃʤòÅФ俽ִ֤˥¯¥¨¥¹¥È¼ºÇԤˤʤêÆóÅÙ¤ÈÌá
+ ¤ì¤Ê¤¤»ö¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òON¤Ë¤¹¤ì¤Ð¡¢¸µ¤Î¾ì½ê¤ËÌá¤ì¤Ê¤¤
+ »ö¤ò·Ù¹ð¤µ¤ì¡¢³Îǧ¤¬µá¤á¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
***** <target_pet>
¥Ú¥Ã¥È¤ò¥¿¡¼¥²¥Ã¥È¤Ë¤¹¤ë [target_pet]
¤¹¡£¥È¥é¥Ã¥×¤ò´¶ÃκѤߤ¬¤É¤¦¤«¤¬¤ï¤«¤ê¤ä¤¹¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢ËâË¡¤ÎÃÏ¿Þ
Åù¤ÇÃÏ·Á¤ò´¶ÃκѤߤλþ¤Ï¶èÊ̤Ǥ¤Þ¤»¤ó¡£
-***** <dungeon_stair>
-³¬Ãʤò¤Ä¤Ê¤²¤Æ¥À¥ó¥¸¥ç¥ó¤òÀ¸À®¤¹¤ë [dungeon_stair]
- ³Æ³¬¤Î³¬ÃʤòʪÍýŪ¤Ë·Ò¤¬¤Ã¤¿°ÌÃÖ¤ËÇÛÃÖ¤·¤Þ¤¹¡£²¼¤ê³¬ÃʤDz¼¤ê¤¿Àè¤Ë
- ¤Ï¾å¤ê³¬Ãʤ¬¡¢¾å¤ê³¬ÃʤǾå¤Ã¤¿Àè¤Ë¤Ï²¼¤ê³¬Ãʤ¬É¬¤ºÂ¸ºß¤¹¤ë¤ï¤±¤Ç
- ¤¹¡£¤³¤ì¤Ï¤è¤ê¸½¼ÂŪ¤Ç¡¢°ÂÁ´¤Ç¤¹¤¬¡¢¤Ê¤«¤Ë¤ÏÄ©À魯¤ë³Ú¤·¤ß¤¬ºï¤¬¤ì
- ¤ë¡¢¤È¹Í¤¨¤ë¿Í¤â¤¤¤Þ¤¹¡£
-
***** <small_levels>
Èó¾ï¤Ë¾®¤µ¤¤¥Õ¥í¥¢¤ÎÀ¸À®¤ò²Äǽ¤Ë¤¹¤ë [small_levels]
Á´ÂΤΥµ¥¤¥º¤¬°ã¤¦³¬¤¬¤Ç¤¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤É¤Î°Ì¾®¤µ¤¯¤Ê¤ë¤«¤Ï¥é
***** <disturb_near>
»ë³¦Æâ¤Î¥â¥ó¥¹¥¿¡¼¤¬Æ°¤¤¤¿¤é¹ÔÆ°¤òÃæ»ß¤¹¤ë [disturb_near]
¸«¤¨¤Æ¤¤¤ë²øʪ¤¬Æ°¤¤¤¿¤ê¡¢²øʪ¤¬»ë³¦¤Ë½é¤á¤ÆÆþ¤Ã¤Æ¤¤¿¤ê¡¢»ë³¦Æâ¤Î
- ²øʪ¤¬»ë³¦³°¤Ë½Ð¤¿¤È¤¤Ë¹ÔÆ°¤ò¥¥ã¥ó¥»¥ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç
- ¤Ï¡¢¥Æ¥ì¥Ñ¥·¡¼¤Ç¸«¤¨¤Æ¤¤¤ë²øʪ¤Î¸ºß¤Ï̵»ë¤µ¤ì¤Þ
- ¤¹¡£'view_reduce_view'¥ª¥×¥·¥ç¥ó¤â»²¹Í¤Ë¤·¤Æ²¼¤µ¤¤¡£
+ ²øʪ¤¬»ë³¦³°¤Ë½Ð¤¿¤È¤¤Ë¹ÔÆ°¤ò¥¥ã¥ó¥»¥ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç¤Ï¡¢
+ ¥Æ¥ì¥Ñ¥·¡¼¤Ç¸«¤¨¤Æ¤¤¤ë²øʪ¤Î¸ºß¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£'view_reduce_view'
+ ¥ª¥×¥·¥ç¥ó¤â»²¹Í¤Ë¤·¤Æ²¼¤µ¤¤¡£
***** <disturb_pets>
»ë³¦Æâ¤Î¥Ú¥Ã¥È¤¬Æ°¤¤¤¿¤é¹ÔÆ°¤òÃæ»ß¤¹¤ë [disturb_pets]
will be prompted if you attempt to wear or wield an item if your
character knows it is cursed.
-***** <confirm_stairs>
-Prompt before exiting a dungeon level [confirm_stairs]
- Some players (such as myself) often accidentally press the '<' key
- and exit a Special feeling level. If this option is set, the
- program asks for confirmation before you go up or down the stairs.
- Others may find the prompt annoying, they should of course not set
- this option. :-)
+***** <confirm_quest>
+Prompt before exiting a quest level [confirm_quest]
+ In the dungeon, you can freely climb up/down stairs and can return
+ to former floors normally. But in some quest level, including the
+ random quest, you can not return once you escaped from the level.
+ If this option is set, the program asks for confirmation before
+ you go up the stairs from such quest levels.
***** <target_pet>
Allow targetting pets [target_pet]
are trap free. This option has no effect on surface grids, but
outdoor locations cannot be trapped.
-***** <dungeon_stair>
-Generate dungeons with connected stairs [dungeon_stair]
- Always generate a staircase back to the level you came from, if you
- used a staircase to get to the level. This is more "realistic", and
- "safer", but less of a "challenge" for some people.
-
***** <small_levels>
Allow unusually small dungeon levels [small_levels]
This option enables the creation of levels of varying sizes. Levels
Y:always_repeat
X:confirm_destroy
Y:confirm_wear
-X:confirm_stairs
+Y:confirm_quest
X:target_pet
Y:easy_open
Y:easy_disarm
Y:view_perma_grids
X:view_torch_grids
X:view_unsafe_grids
-Y:dungeon_stair
Y:small_levels
X:always_small_levels
Y:empty_levels
variable.c tables.c util.c cave.c \
kajitips.h object1.c object2.c monster1.c monster2.c \
xtra1.c xtra2.c spells1.c spells2.c \
- melee1.c melee2.c save.c files.c \
+ melee1.c melee2.c save.c files.c floors.c\
cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c \
store.c birth.c load.c \
wizard1.c wizard2.c grid.c streams.c rooms.c \
mspells1.c mspells2.c scores.c mind.c mane.c hissatsu.c \
bldg.c obj_kind.c wild.c avatar.c japanese.c mspells3.c \
main-cap.c main-gcu.c main-x11.c main-xaw.c main.c chuukei.c \
- angband.h defines.h event.h externs.h generate.h grid.h \
+ angband.h defines.h externs.h generate.h grid.h \
h-basic.h h-config.h h-define.h h-system.h h-type.h \
mindtips.h readdib.h rooms.h spellstips.h streams.h init.h \
types.h z-config.h z-form.h z-rand.h z-term.h z-util.h z-virt.h
angband.ico angband.rc ang_eng.rc maid-x11.c main-mac.c main-win.c \
main-dos.c main-ibm.c main-mac-carbon.c \
makefile.bcc makefile.std makefile.dos makefile.ibm \
- readdib.c script.c wall.bmp
+ readdib.c wall.bmp
install-exec-hook:
if SET_GID
case FEAT_MAGMA_K:
case FEAT_QUARTZ_K:
- feat_priority = 3;
+ /* Now a days treasere grid is too many */
+ feat_priority = 2;
break;
case FEAT_MOUNTAIN:
do_cmd_save_game(TRUE);
#ifdef JP
- do_cmd_write_nikki(NIKKI_STAIR, 1, "Í¸Í¤ËÍî¤Á¤¿");
+ do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "Í¸Í¤ËÍî¤Á¤¿");
#else
- do_cmd_write_nikki(NIKKI_STAIR, 1, "You have fallen through a trap door!");
+ do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "You have fallen through a trap door!");
#endif
- dun_level++;
+ prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
/* Leaving */
p_ptr->leaving = TRUE;
{
/* Success */
#ifdef JP
- if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
- msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
- else
- msg_print("¾å¤Î³¬¤ËÅФä¿¡£");
+ if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+ msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
+ else
+ msg_print("¾å¤Î³¬¤ËÅФä¿¡£");
#else
msg_print("You enter the up staircase.");
#endif
}
else
{
- if (confirm_stairs)
+ quest_type *q_ptr = &quest[p_ptr->inside_quest];
+
+ /* Confirm leaving from once only quest */
+ if (confirm_quest && p_ptr->inside_quest &&
+ (q_ptr->type == QUEST_TYPE_RANDOM ||
+ (q_ptr->flags & QUEST_FLAG_ONCE &&
+ q_ptr->status != QUEST_STATUS_COMPLETED)))
{
#ifdef JP
-if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©"))
+ msg_print("¤³¤Î³¬¤ò°ìÅÙµî¤ë¤ÈÆóÅÙ¤ÈÌá¤Ã¤ÆÍè¤é¤ì¤Þ¤»¤ó¡£");
+ if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©")) go_up = TRUE;
#else
- if (get_check("Really leave the level? "))
+ msg_print("You can't come back here once you leave this floor.");
+ if (get_check("Really leave this floor? ")) go_up = TRUE;
#endif
-
- go_up = TRUE;
}
else
{
if (p_ptr->inside_quest)
{
- if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM) dun_level = 1;
-
leave_quest_check();
- p_ptr->inside_quest = c_ptr->special;
+ if (quest[leaving_quest].type != QUEST_TYPE_RANDOM)
+ {
+ p_ptr->inside_quest = c_ptr->special;
+ dun_level = 0;
+ }
+ else
+ {
+ p_ptr->inside_quest = 0;
+ }
}
/* New depth */
if (c_ptr->feat == FEAT_LESS_LESS)
{
/* Create a way back */
- create_down_stair = 2;
+ prepare_change_floor_mode(CFM_UP | CFM_SHAFT);
up_num += 2;
}
else
{
/* Create a way back */
- create_down_stair = 1;
+ prepare_change_floor_mode(CFM_UP);
up_num += 1;
}
+#if 0
if (!c_ptr->special && dungeon_type && ((dun_level - up_num + 1) > d_info[dungeon_type].mindepth) && one_in_(13))
{
up_num++;
#endif
msg_print(NULL);
}
+#endif /* 0 */
+
if (dun_level-up_num+1 == d_info[dungeon_type].mindepth) up_num = dun_level;
#ifdef JP
if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "³¬Ãʤò¾å¤Ã¤¿");
#else
if (record_stair) do_cmd_write_nikki(NIKKI_STAIR, 0-up_num, "go up the stairs to");
#endif
- dun_level -= up_num;
/* Success */
#ifdef JP
msg_print("You enter a maze of up staircases.");
#endif
-
- /* Leaving the dungeon to town */
- if (!dun_level && dungeon_type)
- {
- p_ptr->leaving_dungeon = TRUE;
- if (!vanilla_town && !lite_town)
- {
- p_ptr->wilderness_y = d_info[dungeon_type].dy;
- p_ptr->wilderness_x = d_info[dungeon_type].dx;
- }
- p_ptr->recall_dungeon = dungeon_type;
- }
-
- if (!dun_level) dungeon_type = 0;
-
/* Leaving */
p_ptr->leaving = TRUE;
}
void do_cmd_go_down(void)
{
cave_type *c_ptr;
- bool go_down = FALSE;
bool fall_trap = FALSE;
int down_num = 0;
if (!get_check("Do you really get in this dungeon? ")) return;
#endif
}
- go_down = TRUE;
/* Save old player position */
p_ptr->oldpx = px;
p_ptr->oldpy = py;
dungeon_type = (byte)c_ptr->special;
}
- else
- {
- if (confirm_stairs)
- {
-#ifdef JP
-if (get_check("ËÜÅö¤Ë¤³¤Î³¬¤òµî¤ê¤Þ¤¹¤«¡©"))
-#else
- if (get_check("Really leave the level? "))
-#endif
- go_down = TRUE;
- }
- else
- {
- go_down = TRUE;
- }
- }
+ /* Hack -- take a turn */
+ energy_use = 100;
- if (go_down)
- {
+ if (autosave_l) do_cmd_save_game(TRUE);
- /* Hack -- take a turn */
- energy_use = 100;
+ /* Go down */
+ if (c_ptr->feat == FEAT_MORE_MORE) down_num += 2;
+ else down_num += 1;
- if (autosave_l) do_cmd_save_game(TRUE);
- /* Go down */
- if (c_ptr->feat == FEAT_MORE_MORE) down_num += 2;
- else down_num += 1;
- if (!quest_number(dun_level+down_num) && (dun_level < d_info[dungeon_type].maxdepth - 1 - down_num) && one_in_(13) && !fall_trap && dun_level && !ironman_downward)
- {
- down_num++;
+ if (!dun_level)
+ {
+ /* Enter the dungeon just now */
+ p_ptr->enter_dungeon = TRUE;
+ down_num = d_info[c_ptr->special].mindepth;
+ }
+
+ if (record_stair)
+ {
#ifdef JP
- if (c_ptr->feat == FEAT_MORE_MORE) msg_print("Ť¤¹£Æ»¤ò²¼¤ê¤¿¡£");
- else msg_print("Ť¤³¬Ãʤò²¼¤ê¤¿¡£");
+ if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "Í¸Í¤ËÍî¤Á¤¿");
+ else do_cmd_write_nikki(NIKKI_STAIR, down_num, "³¬Ãʤò²¼¤ê¤¿");
#else
- msg_print("These were very long stairs.");
+ if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "fall from trap door");
+ else do_cmd_write_nikki(NIKKI_STAIR, down_num, "go down the stairs to");
#endif
- msg_print(NULL);
- }
- else if (!dun_level) down_num = d_info[c_ptr->special].mindepth;
- if (record_stair)
- {
+ }
+
+ if (fall_trap)
+ {
#ifdef JP
- if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "Í¸Í¤ËÍî¤Á¤¿");
- else do_cmd_write_nikki(NIKKI_STAIR, down_num, "³¬Ãʤò²¼¤ê¤¿");
+ msg_print("¤ï¤¶¤ÈÍ¸Í¤ËÍî¤Á¤¿¡£");
#else
- if (fall_trap) do_cmd_write_nikki(NIKKI_STAIR, down_num, "fall from trap door");
- else do_cmd_write_nikki(NIKKI_STAIR, down_num, "go down the stairs to");
+ msg_print("You deliberately jump through the trap door.");
#endif
- }
-
- if (fall_trap)
+ }
+ else
+ {
+ /* Success */
+ if(c_ptr->feat == FEAT_ENTRANCE)
{
- dun_level += down_num;
#ifdef JP
- msg_print("¤ï¤¶¤ÈÍ¸Í¤ËÍî¤Á¤¿¡£");
+ msg_format("%s¤ØÆþ¤Ã¤¿¡£", d_text + d_info[dungeon_type].text);
#else
- msg_print("You deliberately jump through the trap door.");
+ msg_format("You entered %s.", d_text + d_info[dungeon_type].text);
#endif
}
else
{
- /* Success */
- if(c_ptr->feat == FEAT_ENTRANCE)
- {
- dun_level = d_info[c_ptr->special].mindepth;
#ifdef JP
- msg_format("%s¤ØÆþ¤Ã¤¿¡£", d_text + d_info[dungeon_type].text);
-#else
- msg_format("You entered %s.", d_text + d_info[dungeon_type].text);
-#endif
- }
+ if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
+ msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
else
- {
- dun_level += down_num;
-#ifdef JP
- if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
- msg_print("¤Ê¤ó¤À¤³¤Î³¬Ãʤϡª");
- else
- msg_print("³¬Ãʤò²¼¤ê¤Æ¿·¤¿¤Ê¤ë̵ܤؤȤòƧ¤ßÆþ¤ì¤¿¡£");
+ msg_print("³¬Ãʤò²¼¤ê¤Æ¿·¤¿¤Ê¤ë̵ܤؤȤòƧ¤ßÆþ¤ì¤¿¡£");
#else
- msg_print("You enter a maze of down staircases.");
+ msg_print("You enter a maze of down staircases.");
#endif
- }
}
+ }
- /* Leaving */
- p_ptr->leaving = TRUE;
+ /* Leaving */
+ p_ptr->leaving = TRUE;
- if (!fall_trap)
+ if (fall_trap)
+ {
+ prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
+ }
+ else
+ {
+ if (c_ptr->feat == FEAT_MORE_MORE)
{
- if (c_ptr->feat == FEAT_MORE_MORE)
- {
- /* Create a way back */
- create_up_stair = 2;
- }
- else
- {
- /* Create a way back */
- create_up_stair = 1;
- }
+ /* Create a way back */
+ prepare_change_floor_mode(CFM_DOWN | CFM_SHAFT);
+ }
+ else
+ {
+ /* Create a way back */
+ prepare_change_floor_mode(CFM_DOWN);
}
}
}
/* Why are you sleeping when there's no need? WAKE UP!*/
if ((p_ptr->chp == p_ptr->mhp) &&
- (p_ptr->csp == p_ptr->msp) &&
- !p_ptr->blind && !p_ptr->confused &&
- !p_ptr->poisoned && !p_ptr->afraid &&
- !p_ptr->stun && !p_ptr->cut &&
- !p_ptr->slow && !p_ptr->paralyzed &&
- !p_ptr->image && !p_ptr->word_recall)
+ (p_ptr->csp == p_ptr->msp) &&
+ !p_ptr->blind && !p_ptr->confused &&
+ !p_ptr->poisoned && !p_ptr->afraid &&
+ !p_ptr->stun && !p_ptr->cut &&
+ !p_ptr->slow && !p_ptr->paralyzed &&
+ !p_ptr->image && !p_ptr->word_recall &&
+ !p_ptr->alter_reality)
chg_virtue(V_DILIGENCE, -1);
/* Save the rest code */
}
case NIKKI_TELE_LEV:
{
- cptr to;
- if (!dun_level)
- {
-#ifdef JP
- to = "1³¬";
-#else
- to = "level 1";
-#endif
- }
- else if (quest_number(dun_level) && ((quest_number(dun_level) < MIN_RANDOM_QUEST) && !(quest_number(dun_level) == QUEST_OBERON || quest_number(dun_level) == QUEST_SERPENT)))
- {
-#ifdef JP
- to = "ÃϾå";
-#else
- to = "the surface";
-#endif
- }
- else
- {
-#ifdef JP
- if (!(dun_level+num)) to = "ÃϾå";
- else to = format("%d³¬", dun_level+num);
-#else
- if (!(dun_level+num)) to = "surface";
- else to = format("level %d", dun_level+num);
-#endif
- }
-
#ifdef JP
- fprintf(fff, " %2d:%02d %20s %s¤Ø¤È¥Æ¥ì¥Ý¡¼¥È¤Ç°ÜÆ°¤·¤¿¡£\n", hour, min, note_level, to);
+ fprintf(fff, " %2d:%02d %20s ¥ì¥Ù¥ë¡¦¥Æ¥ì¥Ý¡¼¥È¤Çæ½Ð¤·¤¿¡£\n", hour, min, note_level);
#else
- fprintf(fff, " %2d:%02d %20s teleport level to %s.\n", hour, min, note_level, to);
+ fprintf(fff, " %2d:%02d %20s Get out using teleport level.\n", hour, min, note_level);
#endif
break;
}
/* Savefile version for Hengband 1.1.1 and later */
#define H_VER_MAJOR 1
-#define H_VER_MINOR 3
-#define H_VER_PATCH 2
+#define H_VER_MINOR 5
+#define H_VER_PATCH 0
#define H_VER_EXTRA 0
/* Added for ZAngband */
#define FAKE_VERSION 0
#define FAKE_VER_MAJOR 11
-#define FAKE_VER_MINOR 3
-#define FAKE_VER_PATCH 1
+#define FAKE_VER_MINOR 5
+#define FAKE_VER_PATCH 0
#define ANGBAND_2_8_1
#define ZANGBAND
/*
+ * Maximum number of saved floors.
+ */
+#define MAX_SAVED_FLOORS 20
+
+
+/*
* Maximum size of the "lite" array (see "cave.c")
* Note that the "lite radius" will NEVER exceed 14, and we would
* never require more than 581 entries in the array for circular "lite".
#define DUNGEON_DARKNESS 19
+/*
+ * Flags for change floor mode
+ */
+#define CFM_UP 0x0001 /* Move up */
+#define CFM_DOWN 0x0002 /* Move down */
+#define CFM_LONG_STAIRS 0x0004 /* Randomly occurred long stairs/shaft */
+#define CFM_XXX 0x0008 /* XXX */
+#define CFM_SHAFT 0x0010 /* Shaft */
+#define CFM_RAND_PLACE 0x0020 /* Arrive at random grid */
+#define CFM_RAND_CONNECT 0x0040 /* Connect with random stairs */
+#define CFM_CLEAR_ALL 0x0080 /* Reach to the surface/Recall/Alter reality */
+#define CFM_NO_RETURN 0x0100 /* Flee from random quest etc... */
+
+
+/*
+ * Flags for save/load temporal saved floor file
+ */
+#define SLF_SECOND 0x0001 /* Called from another save/load function */
+#define SLF_NO_KILL 0x0002 /* Don't kill temporal files */
+
+
+/*
+ * Flags for wr_item()/rd_item()
+ */
+#define SAVE_ITEM_PVAL 0x00000001
+#define SAVE_ITEM_DISCOUNT 0x00000002
+#define SAVE_ITEM_NUMBER 0x00000004
+#define SAVE_ITEM_NAME1 0x00000008
+#define SAVE_ITEM_NAME2 0x00000010
+#define SAVE_ITEM_TIMEOUT 0x00000020
+#define SAVE_ITEM_TO_H 0x00000040
+#define SAVE_ITEM_TO_D 0x00000080
+#define SAVE_ITEM_TO_A 0x00000100
+#define SAVE_ITEM_AC 0x00000200
+#define SAVE_ITEM_DD 0x00000400
+#define SAVE_ITEM_DS 0x00000800
+#define SAVE_ITEM_IDENT 0x00001000
+#define SAVE_ITEM_MARKED 0x00002000
+#define SAVE_ITEM_ART_FLAGS0 0x00004000
+#define SAVE_ITEM_ART_FLAGS1 0x00008000
+#define SAVE_ITEM_ART_FLAGS2 0x00010000
+#define SAVE_ITEM_ART_FLAGS3 0x00020000
+#define SAVE_ITEM_CURSE_FLAGS 0x00040000
+#define SAVE_ITEM_HELD_M_IDX 0x00080000
+#define SAVE_ITEM_XTRA1 0x00100000
+#define SAVE_ITEM_XTRA2 0x00200000
+#define SAVE_ITEM_XTRA3 0x00400000
+#define SAVE_ITEM_XTRA4 0x00800000
+#define SAVE_ITEM_XTRA5 0x01000000
+#define SAVE_ITEM_FEELING 0x02000000
+#define SAVE_ITEM_INSCRIPTION 0x04000000
+#define SAVE_ITEM_ART_NAME 0x08000000
+
+
+/*
+ * Flags for wr_monster()/rd_monster()
+ */
+#define SAVE_MON_AP_R_IDX 0x00000001
+#define SAVE_MON_SUB_ALIGN 0x00000002
+#define SAVE_MON_CSLEEP 0x00000004
+#define SAVE_MON_FAST 0x00000008
+#define SAVE_MON_SLOW 0x00000010
+#define SAVE_MON_STUNNED 0x00000020
+#define SAVE_MON_CONFUSED 0x00000040
+#define SAVE_MON_MONFEAR 0x00000080
+#define SAVE_MON_TARGET_Y 0x00000100
+#define SAVE_MON_TARGET_X 0x00000200
+#define SAVE_MON_INVULNER 0x00000400
+#define SAVE_MON_SMART 0x00000800
+#define SAVE_MON_EXP 0x00001000
+#define SAVE_MON_MFLAG2 0x00002000
+#define SAVE_MON_NICKNAME 0x00004000
+
+
+/*
+ * Constant for kinds of mimic
+ */
#define MIMIC_NONE 0
#define MIMIC_DEMON 1
#define MIMIC_DEMON_LORD 2
/* Change level */
dun_level = command_arg;
+ prepare_change_floor_mode(CFM_CLEAR_ALL);
leave_quest_check();
r_info[quest[leaving_quest].r_idx].flags1 &= ~(RF1_QUESTOR);
if (record_rand_quest)
do_cmd_write_nikki(NIKKI_RAND_QUEST_F, leaving_quest, NULL);
+
+ /* Floor of random quest will be blocked */
+ prepare_change_floor_mode(CFM_NO_RETURN);
}
else if (record_fix_quest)
do_cmd_write_nikki(NIKKI_FIX_QUEST_F, leaving_quest, NULL);
dun_level = 0;
dungeon_type = 0;
+ prepare_change_floor_mode(CFM_CLEAR_ALL);
leave_quest_check();
}
p_ptr->wild_mode = FALSE;
+ prepare_change_floor_mode(CFM_CLEAR_ALL);
+
/* Leaving */
p_ptr->leaving = TRUE;
sound(SOUND_TPLEVEL);
}
}
+
+
+ /* Delayed Alter reality */
+ if (p_ptr->alter_reality)
+ {
+ if (autosave_l && (p_ptr->alter_reality == 1) && !p_ptr->inside_battle)
+ do_cmd_save_game(TRUE);
+
+ /* Count down towards alter */
+ p_ptr->alter_reality--;
+
+ p_ptr->redraw |= (PR_STATUS);
+
+ /* Activate the alter reality */
+ if (!p_ptr->alter_reality)
+ {
+ /* Disturbing! */
+ disturb(0, 0);
+
+ /* Determine the level */
+ if (!quest_number(dun_level) && dun_level)
+ {
+#ifdef JP
+ msg_print("À¤³¦¤¬ÊѤï¤Ã¤¿¡ª");
+#else
+ msg_print("The world changes!");
+#endif
+
+ prepare_change_floor_mode(CFM_CLEAR_ALL);
+
+ /* Leaving */
+ p_ptr->leaving = TRUE;
+ }
+ else
+ {
+#ifdef JP
+ msg_print("À¤³¦¤¬¾¯¤·¤Î´ÖÊѲ½¤·¤¿¤è¤¦¤À¡£");
+#else
+ msg_print("The world seems to change for a moment!");
+#endif
+ }
+
+ /* Sound */
+ sound(SOUND_TPLEVEL);
+ }
+ }
}
!p_ptr->poisoned && !p_ptr->afraid &&
!p_ptr->stun && !p_ptr->cut &&
!p_ptr->slow && !p_ptr->paralyzed &&
- !p_ptr->image && !p_ptr->word_recall)
+ !p_ptr->image && !p_ptr->word_recall &&
+ !p_ptr->alter_reality)
{
set_action(ACTION_NONE);
}
*/
static void dungeon(bool load_game)
{
- int quest_num = 0, i, num;
+ int quest_num = 0, i;
/* Set the base level */
base_level = dun_level;
if (record_maxdeapth) do_cmd_write_nikki(NIKKI_MAXDEAPTH, dun_level, NULL);
}
- /* No stairs down from Quest */
- if (quest_number(dun_level))
- {
- create_down_stair = 0;
- }
-
- /* Paranoia -- no stairs from town or wilderness */
- if (!dun_level) create_down_stair = create_up_stair = 0;
-
- /* Option -- no connected stairs */
- if (!dungeon_stair) create_down_stair = create_up_stair = 0;
-
- /* Option -- no up stairs */
- if (ironman_downward) create_down_stair = create_up_stair = 0;
-
- /* Make a stairway. */
- if (create_up_stair || create_down_stair)
- {
- /* Place a stairway */
- if (cave_valid_bold(py, px))
- {
- /* XXX XXX XXX */
- delete_object(py, px);
-
- /* Make stairs */
- if (create_down_stair)
- {
- if (create_down_stair == 2) cave_set_feat(py, px, FEAT_MORE_MORE);
- else cave_set_feat(py, px, FEAT_MORE);
- }
- else
- {
- if (create_up_stair == 2) cave_set_feat(py, px, FEAT_LESS_LESS);
- else cave_set_feat(py, px, FEAT_LESS);
- }
- }
-
- /* Cancel the stair request */
- create_down_stair = create_up_stair = 0;
- }
-
/* Validate the panel */
panel_bounds_center();
/* Not save-and-quit and not dead? */
if (p_ptr->playing && !p_ptr->is_dead)
{
- for(num = 0; num < 21; num++)
- {
- party_mon[num].r_idx = 0;
- }
-
- if (p_ptr->riding)
- {
- COPY(&party_mon[0], &m_list[p_ptr->riding], monster_type);
- }
-
- for(i = m_max - 1, num = 1; (i >= 1 && num < 21); i--)
- {
- monster_type *m_ptr = &m_list[i];
-
- if (!m_ptr->r_idx) continue;
- if (!is_pet(m_ptr)) continue;
- if (i == p_ptr->riding) continue;
-
- if (reinit_wilderness)
- {
- /* Don't lose sight of pets when getting a Quest */
- }
- else
- {
- int dis = distance(py, px, m_ptr->fy, m_ptr->fx);
-
- /*
- * Pets with nickname will follow even from 3 blocks away
- * when you or the pet can see the other.
- */
- if (m_ptr->nickname &&
- (player_has_los_bold(m_ptr->fy, m_ptr->fx) ||
- los(m_ptr->fy, m_ptr->fx, py, px)))
- {
- if (dis > 3) continue;
- }
- else
- {
- if (dis > 1) continue;
- }
- if (m_ptr->confused || m_ptr->stunned || m_ptr->csleep) continue;
- }
-
- COPY(&party_mon[num], &m_list[i], monster_type);
- num++;
-
- /* Mark as followed */
- delete_monster_idx(i);
- }
+ /*
+ * Maintain Unique monsters and artifact, save current
+ * floor, then prepare next floor
+ */
+ leave_floor();
/* Forget the flag */
reinit_wilderness = FALSE;
-
- if (record_named_pet)
- {
- for (i = m_max - 1; i >=1; i--)
- {
- monster_type *m_ptr = &m_list[i];
- char m_name[80];
-
- if (!m_ptr->r_idx) continue;
- if (!is_pet(m_ptr)) continue;
- if (!m_ptr->nickname) continue;
- if (p_ptr->riding == i) continue;
-
- monster_desc(m_name, m_ptr, 0x88);
- do_cmd_write_nikki(NIKKI_NAMED_PET, 4, m_name);
- }
- }
}
+ /* Write about current level on the play record once per level */
write_level = TRUE;
}
/* Prepare to init the RNG */
Rand_quick = TRUE;
+
+ /* Initialize the saved floors data */
+ init_saved_floors();
+ }
+
+ /* Old game is loaded. But new game is requested. */
+ else if (new_game)
+ {
+ /* Delete expanded temporal files */
+ clear_saved_floor_files();
}
/* Process old character */
#endif
/* Generate a dungeon level if needed */
- if (!character_dungeon) generate_cave();
+ if (!character_dungeon) change_floor();
/* Character is now "complete" */
p_ptr->redraw |= (PR_STATUS);
}
+ /* Hack -- cancel alter */
+ if (p_ptr->alter_reality)
+ {
+ /* Hack -- Prevent alter */
+ p_ptr->alter_reality = 0;
+ p_ptr->redraw |= (PR_STATUS);
+ }
+
/* Note cause of death XXX XXX XXX */
#ifdef JP
(void)strcpy(p_ptr->died_from, "»à¤Îµ½¤");
if (p_ptr->is_dead) break;
/* Make a new level */
- generate_cave();
+ change_floor();
}
/* Close stuff */
p_ptr->oppose_pois = 0; /* Timed -- oppose poison */
p_ptr->word_recall = FALSE;
+ p_ptr->alter_reality = FALSE;
p_ptr->sutemi = FALSE;
p_ptr->counter = FALSE;
p_ptr->ele_attack = 0;
+++ /dev/null
-#include "angband.h"
-#include "Python.h"
-
-extern void eat_callback(int sval);
-extern void kill_monster_callback(int m_idx);
-extern bool player_move_callback(int y, int x);
-extern bool cmd_open_callback(int y, int x);
-extern bool cmd_search_callback(int y, int x);
-extern bool cmd_feeling_callback(int feeling);
-extern bool cmd_go_up_callback(void);
-extern bool building_command_callback(int number, int action);
-extern void callbacks_load_callback(char *data);
-extern cptr callbacks_save_callback(void);
-
-/* Dungeon grids */
-extern bool player_enter_grid_callback(int y, int x);
-extern bool player_search_grid_callback(int y, int x);
-
-/* Dungeon levels */
-extern bool generate_level_callback(int level);
-extern void leave_level_callback(int level);
-extern void enter_level_callback(int level);
-
-/* Wilderness */
-extern bool wilderness_init_callback(void);
-extern bool generate_wilderness_callback(int y, int x);
-extern bool enter_wilderness_callback(int y, int x);
-extern bool leave_wilderness_callback(int y, int x);
-
-extern void store_examine_callback(object_type *o_ptr);
-extern bool monster_move_callback(int *mm, int m_idx);
-extern void create_monster_callback(int m_idx);
-extern void delete_monster_callback(int m_idx);
-extern void copy_monster_callback(int i1, int i2);
-extern char inkey_borg_callback(bool inkey_base, bool inkey_xtra,
- bool inkey_flag, bool inkey_scan);
-extern char inkey_callback(char key);
-
-/* Birth */
-extern long get_world_callback(void);
-extern long get_player_class_callback(void);
-extern long get_player_realms_callback(void);
-extern long get_player_race_callback(void);
-extern long get_player_seikaku_callback(void);
-
-extern bool get_player_flags_callback(void);
-extern bool player_outfit_callback(void);
-
-extern long sense_inventory_callback(void);
-extern bool destroy_object_callback(object_type *o_ptr, int number);
-
-/* Object callbacks - global */
-extern PyObject* object_create_callback(object_type *o_ptr);
-extern PyObject* object_load_callback(char *code);
-
-/* Object callbacks - object specific */
-extern bool object_eat_callback(object_type *o_ptr);
-extern bool object_browse_callback(object_type *o_ptr);
-extern bool object_cast_callback(object_type *o_ptr);
-extern cptr object_save_callback(object_type *o_ptr);
-extern void object_delete_callback(object_type *o_ptr);
-extern PyObject* object_copy_callback(object_type *o_ptr, object_type *j_ptr);
-extern long get_object_level_callback(object_type *o_ptr);
-extern long get_object_cost_callback(object_type *o_ptr);
-extern cptr get_object_name_callback(object_type *o_ptr);
-extern char get_object_d_char_callback(object_type *o_ptr);
-extern char get_object_x_char_callback(object_type *o_ptr);
-extern byte get_object_d_attr_callback(object_type *o_ptr);
-extern byte get_object_x_attr_callback(object_type *o_ptr);
-extern bool get_object_aware_callback(object_type *o_ptr);
-extern bool get_object_tried_callback(object_type *o_ptr);
-
-/* Object_kind callbacks */
-extern bool free_object_kind_list_callback(void);
-extern bool init_object_kind_list_callback(void);
-
-extern bool use_skill_callback(void);
-
-
-#define CMD_EAT_EVENT 1
-#define PLAYER_MOVE_EVENT 2
-#define CMD_OPEN_EVENT 3
-#define CMD_SEARCH_EVENT 4
-#define PLAYER_SEARCH_GRID_EVENT 5
-#define CMD_FEELING_EVENT 6
-#define CMD_GO_UP_EVENT 7
-#define CALLBACKS_LOAD_EVENT 8
-#define CALLBACKS_SAVE_EVENT 9
-#define KILL_MONSTER_EVENT 10
-#define BUILDING_COMMAND_EVENT 11
-#define LEAVE_LEVEL_EVENT 12
-#define PLAYER_ENTER_GRID_EVENT 13
-#define ENTER_LEVEL_EVENT 14
-#define GENERATE_LEVEL_EVENT 15
-#define GENERATE_WILDERNESS_EVENT 16
-#define ENTER_WILDERNESS_EVENT 17
-#define LEAVE_WILDERNESS_EVENT 18
-#define STORE_EXAMINE_EVENT 19
-#define MONSTER_MOVE_EVENT 20
-#define CREATE_MONSTER_EVENT 21
-#define DELETE_MONSTER_EVENT 22
-#define INKEY_BORG_EVENT 23
-#define INKEY_EVENT 24
-#define GET_PLAYER_CLASS_EVENT 25
-#define GET_PLAYER_FLAGS_EVENT 26
-#define SENSE_INVENTORY_EVENT 27
-#define DESTROY_OBJECT_EVENT 28
-#define GET_PLAYER_RACE_EVENT 29
-#define OBJECT_CREATE_EVENT 30
-#define OBJECT_LOAD_EVENT 31
-#define PLAYER_OUTFIT_EVENT 32
-#define WILDERNESS_INIT_EVENT 33
-#define FREE_OBJECT_KIND_LIST_EVENT 34
-#define INIT_OBJECT_KIND_LIST_EVENT 35
-#define GET_PLAYER_REALMS_EVENT 36
-#define GET_WORLD_EVENT 37
-#define COPY_MONSTER_EVENT 38
-#define USE_SKILL_EVENT 39
-
-#define MAX_EVENT 40
extern s16b command_wrk;
extern s16b command_new;
extern s16b energy_use;
-extern byte create_up_stair;
-extern byte create_down_stair;
extern bool msg_flag;
extern s16b running;
extern s16b resting;
extern bool plain_descriptions;
extern bool confirm_destroy;
extern bool confirm_wear;
-extern bool confirm_stairs;
+extern bool confirm_quest;
extern bool disturb_pets;
extern bool view_perma_grids;
extern bool view_torch_grids;
extern bool auto_scum;
extern bool expand_look;
extern bool expand_list;
-extern bool dungeon_stair;
extern bool smart_learn;
extern bool smart_cheat;
extern bool show_labels;
extern byte angband_color_table[256][4];
extern char angband_sound_name[SOUND_MAX][16];
extern cave_type *cave[MAX_HGT];
+extern saved_floor_type saved_floors[MAX_SAVED_FLOORS];
+extern s16b max_floor_id;
+extern u32b saved_floor_file_sign;
extern object_type *o_list;
extern monster_type *m_list;
extern u16b max_towns;
extern char *object_desc_kosuu(char *t, object_type *o_ptr);
extern void object_desc(char *buf, object_type *o_ptr, int pref, int mode);
+/* floors.c */
+extern void init_saved_floors(void);
+extern void clear_saved_floor_files(void);
+extern saved_floor_type *get_sf_ptr(s16b floor_id);
+extern s16b get_new_floor_id(void);
+extern void prepare_change_floor_mode(u32b mode);
+extern void leave_floor(void);
+extern void change_floor(void);
+extern void stair_creation(void);
+
/* generate.c */
extern void place_closed_door(int y, int x);
+extern void place_quest_monsters(void);
+extern void clear_cave(void);
extern void generate_cave(void);
/* init1.c */
/* load.c */
extern errr rd_savefile_new(void);
+extern bool load_floor(saved_floor_type *sf_ptr, u32b mode);
/* melee1.c */
/* melee2.c */
extern bool save_player(void);
extern bool load_player(void);
extern void remove_loc(void);
+extern bool save_floor(saved_floor_type *sf_ptr, u32b mode);
/* spells1.c */
extern bool in_disintegration_range(int y1, int x1, int y2, int x2);
extern bool remove_curse(void);
extern bool remove_all_curse(void);
extern bool alchemy(void);
-extern void stair_creation(void);
extern bool item_tester_hook_weapon(object_type *o_ptr);
extern bool item_tester_hook_armour(object_type *o_ptr);
extern bool item_tester_hook_weapon_armour(object_type *o_ptr);
/* Forget the high score fd */
highscore_fd = -1;
+ /* Kill all temporal files */
+ clear_saved_floor_files();
/* Allow suspending now */
signals_handle_tstp();
/* Require "naked" floor grid */
if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;
+ /* Avoid player location */
+ if (py == y && px == x) continue;
+
/* Check for "room" */
room = (cave[y][x].info & CAVE_ROOM) ? TRUE : FALSE;
}
+/*
+ * Fill the arrays of floors and walls in the good proportions
+ */
+static void set_basic_floor_and_wall(byte type)
+{
+ int i;
+
+ for (i = 0; i < 100; i++)
+ {
+ int lim1, lim2, lim3;
+
+ lim1 = d_info[type].floor_percent1;
+ lim2 = lim1 + d_info[type].floor_percent2;
+ lim3 = lim2 + d_info[type].floor_percent3;
+
+ if (i < lim1)
+ floor_type[i] = d_info[type].floor1;
+ else if (i < lim2)
+ floor_type[i] = d_info[type].floor2;
+ else if (i < lim3)
+ floor_type[i] = d_info[type].floor3;
+
+ lim1 = d_info[type].fill_percent1;
+ lim2 = lim1 + d_info[type].fill_percent2;
+ lim3 = lim2 + d_info[type].fill_percent3;
+ if (i < lim1)
+ fill_type[i] = d_info[type].fill_type1;
+ else if (i < lim2)
+ fill_type[i] = d_info[type].fill_type2;
+ else if (i < lim3)
+ fill_type[i] = d_info[type].fill_type3;
+ }
+}
+
+
+/* Place quest monsters */
+void place_quest_monsters(void)
+{
+ int i;
+
+ /* Handle the quest monster placements */
+ for (i = 0; i < max_quests; i++)
+ {
+ monster_race *r_ptr;
+ u32b mode;
+ int j;
+
+ if (quest[i].status != QUEST_STATUS_TAKEN ||
+ (quest[i].type != QUEST_TYPE_KILL_LEVEL &&
+ quest[i].type != QUEST_TYPE_RANDOM) ||
+ quest[i].level != dun_level ||
+ dungeon_type != quest[i].dungeon ||
+ (quest[i].flags & QUEST_FLAG_PRESET))
+ {
+ /* Ignore it */
+ continue;
+ }
+
+ r_ptr = &r_info[quest[i].r_idx];
+
+ /* Hack -- "unique" monsters must be "unique" */
+ if ((r_ptr->flags1 & RF1_UNIQUE) &&
+ (r_ptr->cur_num >= r_ptr->max_num)) continue;
+
+ mode = (PM_NO_KAGE | PM_NO_PET);
+
+ if (!(r_ptr->flags1 & RF1_FRIENDS))
+ mode |= PM_ALLOW_GROUP;
+
+ for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++)
+ {
+ int k;
+
+ for (k = 0; k < SAFE_MAX_ATTEMPTS; k++)
+ {
+ int x, y;
+ int l;
+
+ /* Find an empty grid */
+ for (l = SAFE_MAX_ATTEMPTS; l > 0; l--)
+ {
+ cave_type *c_ptr;
+
+ y = randint0(cur_hgt);
+ x = randint0(cur_wid);
+ c_ptr = &cave[y][x];
+
+ if (!cave_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;
+ if (distance(y, x, py, px) < 10) continue;
+ else break;
+ }
+
+ /* Failed to place */
+ if (!l) break;
+
+ /* Try to place the monster */
+ if (place_monster_aux(0, y, x, quest[i].r_idx, mode))
+ {
+ /* Success */
+ break;
+ }
+ else
+ {
+ /* Failure - Try again */
+ continue;
+ }
+ }
+ }
+ }
+}
+
/*
* Generate a new dungeon level
dun_data dun_body;
/* Fill the arrays of floors and walls in the good proportions */
- for (i = 0; i < 100; i++)
- {
- int lim1, lim2, lim3;
-
- lim1 = d_info[dungeon_type].floor_percent1;
- lim2 = lim1 + d_info[dungeon_type].floor_percent2;
- lim3 = lim2 + d_info[dungeon_type].floor_percent3;
+ set_basic_floor_and_wall(dungeon_type);
- if (i < lim1)
- floor_type[i] = d_info[dungeon_type].floor1;
- else if (i < lim2)
- floor_type[i] = d_info[dungeon_type].floor2;
- else if (i < lim3)
- floor_type[i] = d_info[dungeon_type].floor3;
-
- lim1 = d_info[dungeon_type].fill_percent1;
- lim2 = lim1 + d_info[dungeon_type].fill_percent2;
- lim3 = lim2 + d_info[dungeon_type].fill_percent3;
- if (i < lim1)
- fill_type[i] = d_info[dungeon_type].fill_type1;
- else if (i < lim2)
- fill_type[i] = d_info[dungeon_type].fill_type2;
- else if (i < lim3)
- fill_type[i] = d_info[dungeon_type].fill_type3;
- }
/* Prepare allocation table */
get_mon_num_prep(get_monster_hook(), NULL);
if (!laketype)
{
- if (d_info[dungeon_type].stream1)
- {
- /* Hack -- Add some magma streamers */
- for (i = 0; i < DUN_STR_MAG; i++)
- {
- build_streamer(d_info[dungeon_type].stream1, DUN_STR_MC);
- }
- }
-
if (d_info[dungeon_type].stream2)
{
/* Hack -- Add some quartz streamers */
build_streamer(d_info[dungeon_type].stream2, DUN_STR_QC);
}
}
- }
- /* Handle the quest monster placements */
- for (i = 0; i < max_quests; i++)
- {
- if ((quest[i].status == QUEST_STATUS_TAKEN) &&
- ((quest[i].type == QUEST_TYPE_KILL_LEVEL) ||
- (quest[i].type == QUEST_TYPE_RANDOM)) &&
- (quest[i].level == dun_level) && (dungeon_type == quest[i].dungeon) &&
- !(quest[i].flags & QUEST_FLAG_PRESET))
+ if (d_info[dungeon_type].stream1)
{
- monster_race *r_ptr = &r_info[quest[i].r_idx];
-
- /* Hack -- "unique" monsters must be "unique" */
- if ((r_ptr->flags1 & RF1_UNIQUE) &&
- (r_ptr->cur_num >= r_ptr->max_num))
- {
- /* The unique is already dead */
- }
- else
+ /* Hack -- Add some magma streamers */
+ for (i = 0; i < DUN_STR_MAG; i++)
{
- u32b mode = (PM_NO_KAGE | PM_NO_PET);
-
- for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++)
- {
- for (k = 0; k < SAFE_MAX_ATTEMPTS; k++)
- {
- /* Find an empty grid */
- while (TRUE)
- {
- y = randint0(cur_hgt);
- x = randint0(cur_wid);
-
- /* Access the grid */
- c_ptr = &cave[y][x];
-
- if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;
- if (distance(y, x, py, px) < 10) continue;
- else break;
- }
-
- if (!(r_ptr->flags1 & RF1_FRIENDS))
- mode |= PM_ALLOW_GROUP;
-
- /* Try to place the monster */
- if (place_monster_aux(0, y, x, quest[i].r_idx, mode))
- {
- /* Success */
- break;
- }
- else
- {
- /* Failure - Try again */
- continue;
- }
- }
- }
+ build_streamer(d_info[dungeon_type].stream1, DUN_STR_MC);
}
}
}
+ /* Determine the character location */
+ if (!new_player_spot()) return FALSE;
+
+ place_quest_monsters();
/* Basic "amount" */
k = (dun_level / 3);
/* Put some rubble in corridors */
alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k));
- /* Put some objects in rooms */
- alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
+ /* Mega Hack -- No object at first level of deeper dungeon */
+ if (p_ptr->enter_dungeon && dun_level > 1)
+ {
+ /* No stair scum! */
+ }
+ else
+ {
+ /* Put some objects in rooms */
+ alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
- /* Put some objects/gold in the dungeon */
- alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
- alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
+ /* Put some objects/gold in the dungeon */
+ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
+ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
+ }
/* Put an Artifact and Artifact Guardian is requested */
if(d_info[dungeon_type].final_guardian && (d_info[dungeon_type].maxdepth == dun_level))
}
}
- /* Determine the character location */
- if (!new_player_spot())
- return FALSE;
-
return TRUE;
}
}
-static void place_pet(void)
-{
- int i, max_num;
-
- if (p_ptr->wild_mode)
- max_num = 1;
- else
- max_num = 21;
-
- for (i = 0; i < max_num; i++)
- {
- int cy, cx, m_idx;
-
- if (!(party_mon[i].r_idx)) continue;
-
-
- if (i == 0)
- {
- m_idx = m_pop();
- p_ptr->riding = m_idx;
- if (m_idx)
- {
- cy = py;
- cx = px;
- }
- }
- else
- {
- int j, d;
-
- for(d = 1; d < 6; d++)
- {
- for(j = 1000; j > 0; j--)
- {
- scatter(&cy, &cx, py, px, d, 0);
- if ((cave_floor_bold(cy, cx) || (cave[cy][cx].feat == FEAT_TREES)) && !cave[cy][cx].m_idx && !((cy == py) && (cx == px))) break;
- }
- if (j) break;
- }
- if (d == 6 || p_ptr->inside_arena || p_ptr->inside_battle)
- m_idx = 0;
- else
- m_idx = m_pop();
- }
-
- if (m_idx)
- {
- monster_type *m_ptr = &m_list[m_idx];
- monster_race *r_ptr;
-
- cave[cy][cx].m_idx = m_idx;
-
- m_ptr->r_idx = party_mon[i].r_idx;
- r_ptr = &r_info[m_ptr->r_idx];
-
- m_ptr->ap_r_idx = party_mon[i].ap_r_idx;
- m_ptr->sub_align = party_mon[i].sub_align;
- m_ptr->fy = cy;
- m_ptr->fx = cx;
- m_ptr->cdis = party_mon[i].cdis;
- m_ptr->mflag = party_mon[i].mflag;
- m_ptr->mflag2 = party_mon[i].mflag2;
- m_ptr->ml = TRUE;
- m_ptr->hp = party_mon[i].hp;
- m_ptr->maxhp = party_mon[i].maxhp;
- m_ptr->max_maxhp = party_mon[i].max_maxhp;
- m_ptr->mspeed = party_mon[i].mspeed;
- m_ptr->fast = party_mon[i].fast;
- m_ptr->slow = party_mon[i].slow;
- m_ptr->stunned = party_mon[i].stunned;
- m_ptr->confused = party_mon[i].confused;
- m_ptr->monfear = party_mon[i].monfear;
- m_ptr->invulner = party_mon[i].invulner;
- m_ptr->smart = party_mon[i].smart;
- m_ptr->csleep = 0;
- m_ptr->nickname = party_mon[i].nickname;
- m_ptr->energy_need = party_mon[i].energy_need;
- m_ptr->exp = party_mon[i].exp;
- set_pet(m_ptr);
-
- if ((r_ptr->flags1 & RF1_FORCE_SLEEP) && !ironman_nightmare)
- {
- /* Monster is still being nice */
- m_ptr->mflag |= (MFLAG_NICE);
-
- /* Must repair monsters */
- repair_monsters = TRUE;
- }
-
- /* Update the monster */
- update_mon(m_idx, TRUE);
- lite_spot(cy, cx);
-
- r_ptr->cur_num++;
-
- /* Hack -- Count the number of "reproducers" */
- if (r_ptr->flags2 & RF2_MULTIPLY) num_repro++;
-
- /* Hack -- Notice new multi-hued monsters */
- if (r_ptr->flags1 & RF1_ATTR_MULTI) shimmer_monsters = TRUE;
- }
- else
- {
- char m_name[80];
-
- monster_desc(m_name, &party_mon[i], 0);
-#ifdef JP
- msg_format("%s¤È¤Ï¤°¤ì¤Æ¤·¤Þ¤Ã¤¿¡£", m_name);
-#else
- msg_format("You have lost sight of %s.", m_name);
-#endif
- if (record_named_pet && party_mon[i].nickname)
- {
- monster_desc(m_name, &party_mon[i], 0x08);
- do_cmd_write_nikki(NIKKI_NAMED_PET, 5, m_name);
- }
- }
- }
-}
-
/*
* Wipe all unnecessary flags after cave generation
*/
}
}
+
/*
- * Generates a random dungeon level -RAK-
- *
- * Hack -- regenerate any "overflow" levels
- *
- * Hack -- allow auto-scumming via a gameplay option.
+ * Clear and empty the cave
*/
-void generate_cave(void)
+void clear_cave(void)
{
- int y, x, num;
- int i;
+ int x, y, i;
- /* The dungeon is not ready */
- character_dungeon = FALSE;
+ /* Very simplified version of wipe_o_list() */
+ for (i = 0; i < o_max; i++)
+ o_list[i].k_idx = 0;
+ o_max = 1;
+ o_cnt = 0;
- /* No longer in the trap detecteded region */
- p_ptr->dtrap = FALSE;
+ /* Very simplified version of wipe_m_list() */
+ for (i = 0; i < m_max; i++)
+ m_list[i].r_idx = 0;
+ for (i = 1; i < max_r_idx; i++)
+ r_info[i].cur_num = 0;
+ m_max = 1;
+ m_cnt = 0;
- /* Generate */
- for (num = 0; TRUE; num++)
+
+ /* Start with a blank cave */
+ for (y = 0; y < MAX_HGT; y++)
{
- bool okay = TRUE;
+ for (x = 0; x < MAX_WID; x++)
+ {
+ cave_type *c_ptr = &cave[y][x];
- cptr why = NULL;
+ /* No flags */
+ c_ptr->info = 0;
+ /* No features */
+ c_ptr->feat = 0;
- /* XXX XXX XXX XXX */
- o_max = 1;
- m_max = 1;
+ /* No objects */
+ c_ptr->o_idx = 0;
- /* Start with a blank cave */
- for (y = 0; y < MAX_HGT; y++)
- {
- for (x = 0; x < MAX_WID; x++)
- {
- /* No flags */
- cave[y][x].info = 0;
+ /* No monsters */
+ c_ptr->m_idx = 0;
- /* No features */
- cave[y][x].feat = 0;
+ /* No special */
+ c_ptr->special = 0;
- /* No objects */
- cave[y][x].o_idx = 0;
+ /* No mimic */
+ c_ptr->mimic = 0;
- /* No monsters */
- cave[y][x].m_idx = 0;
+ /* No flow */
+ c_ptr->cost = 0;
+ c_ptr->dist = 0;
+ c_ptr->when = 0;
+ }
+ }
- /* No mimic */
- cave[y][x].mimic = 0;
+ /* Mega-Hack -- no player yet */
+ px = py = 0;
- /* No flow */
- cave[y][x].cost = 0;
- cave[y][x].dist = 0;
- cave[y][x].when = 0;
- }
- }
+ /* Set the base level */
+ base_level = dun_level;
+
+ /* Reset the monster generation level */
+ monster_level = base_level;
- /* Mega-Hack -- no player yet */
- px = py = 0;
+ /* Reset the object generation level */
+ object_level = base_level;
- /* Mega-Hack -- no panel yet */
- panel_row_min = 0;
- panel_row_max = 0;
- panel_col_min = 0;
- panel_col_max = 0;
+ /* Nothing special here yet */
+ good_item_flag = FALSE;
- /* Set the base level */
- base_level = dun_level;
+ /* Nothing good here yet */
+ rating = 0;
- /* Reset the monster generation level */
- monster_level = base_level;
+ /* Fill the arrays of floors and walls in the good proportions */
+ set_basic_floor_and_wall(0);
+}
- /* Reset the object generation level */
- object_level = base_level;
- /* Nothing special here yet */
- good_item_flag = FALSE;
+/*
+ * Generates a random dungeon level -RAK-
+ *
+ * Hack -- regenerate any "overflow" levels
+ *
+ * Hack -- allow auto-scumming via a gameplay option.
+ */
+void generate_cave(void)
+{
+ int y, x, num;
+ int i;
- /* Nothing good here yet */
- rating = 0;
+ /* Generate */
+ for (num = 0; TRUE; num++)
+ {
+ bool okay = TRUE;
- if ((d_info[dungeon_type].fill_type1 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type2 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type3 == FEAT_MAGMA_K)) rating += 40;
+ cptr why = NULL;
- ambush_flag = FALSE;
+ /* Clear and empty the cave */
+ clear_cave();
- /* Fill the arrays of floors and walls in the good proportions */
- for (i = 0; i < 100; i++)
- {
- int lim1, lim2, lim3;
-
- lim1 = d_info[0].floor_percent1;
- lim2 = lim1 + d_info[0].floor_percent2;
- lim3 = lim2 + d_info[0].floor_percent3;
-
- if (i < lim1)
- floor_type[i] = d_info[0].floor1;
- else if (i < lim2)
- floor_type[i] = d_info[0].floor2;
- else if (i < lim3)
- floor_type[i] = d_info[0].floor3;
-
- lim1 = d_info[0].fill_percent1;
- lim2 = lim1 + d_info[0].fill_percent2;
- lim3 = lim2 + d_info[0].fill_percent3;
- if (i < lim1)
- fill_type[i] = d_info[0].fill_type1;
- else if (i < lim2)
- fill_type[i] = d_info[0].fill_type2;
- else if (i < lim3)
- fill_type[i] = d_info[0].fill_type3;
- }
+ if ((d_info[dungeon_type].fill_type1 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type2 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type3 == FEAT_MAGMA_K)) rating += 40;
/* Build the arena -KMW- */
if (p_ptr->inside_arena)
/* Mega-Hack -- "auto-scum" */
else if ((auto_scum || ironman_autoscum) && (num < 100) &&
- !p_ptr->inside_quest && !(d_info[dungeon_type].flags1 & DF1_BEGINNER))
+ !p_ptr->inside_quest &&
+ !(d_info[dungeon_type].flags1 & DF1_BEGINNER) &&
+ !p_ptr->enter_dungeon)
{
/* Require "goodness" */
if ((feeling > 9) ||
}
}
- wipe_generate_cave_flags();
-
- place_pet();
+ /* Reset flag */
+ p_ptr->enter_dungeon = FALSE;
- /* The dungeon is ready */
- character_dungeon = TRUE;
-
- if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN) wiz_lite(TRUE, (bool)(p_ptr->pclass == CLASS_NINJA));
-
- /* Remember when this level was "created" */
- old_turn = turn;
+ wipe_generate_cave_flags();
}
* Dungeon streamer generation values
*/
#define DUN_STR_DEN 5 /* Density of streamers */
-#define DUN_STR_RNG 2 /* Width of streamers */
-#define DUN_STR_MAG 3 /* Number of magma streamers */
-#define DUN_STR_MC 90 /* 1/chance of treasure per magma */
-#define DUN_STR_QUA 2 /* Number of quartz streamers */
-#define DUN_STR_QC 40 /* 1/chance of treasure per quartz */
+#define DUN_STR_RNG 5 /* Width of streamers */
+#define DUN_STR_MAG 6 /* Number of magma streamers */
+#define DUN_STR_MC 30 /* 1/chance of treasure per magma */
+#define DUN_STR_QUA 4 /* Number of quartz streamers */
+#define DUN_STR_QC 15 /* 1/chance of treasure per quartz */
#define DUN_STR_WLW 1 /* Width of lava & water streamers -KMW- */
#define DUN_STR_DWLW 8 /* Density of water & lava streams -KMW- */
#define OLD_MAX_MANE 22
/*
- * Read an object
+ * Read an object (Old method)
*
* This function attempts to "repair" old savefiles, and to extract
* the most up to date values for various object fields.
* a complete hack, items which are inscribed with "uncursed" will be
* "uncursed" when imported from pre-2.7.9 savefiles.
*/
-static void rd_item(object_type *o_ptr)
+static void rd_item_old(object_type *o_ptr)
{
char buf[128];
}
+/*
+ * Read an object (New method)
+ */
+static void rd_item(object_type *o_ptr)
+{
+ object_kind *k_ptr;
+ u32b flags;
+ char buf[128];
+
+ if (h_older_than(1, 3, 2, 1))
+ {
+ rd_item_old(o_ptr);
+ return;
+ }
+
+ /*** Item save flags ***/
+ rd_u32b(&flags);
+
+ /*** Read un-obvious elements ***/
+ /* Kind */
+ rd_s16b(&o_ptr->k_idx);
+
+ /* Location */
+ rd_byte(&o_ptr->iy);
+ rd_byte(&o_ptr->ix);
+
+ /* Type/Subtype */
+ k_ptr = &k_info[o_ptr->k_idx];
+ o_ptr->tval = k_ptr->tval;
+ o_ptr->sval = k_ptr->sval;
+
+ /* Special pval */
+ if (flags & SAVE_ITEM_PVAL) rd_s16b(&o_ptr->pval);
+ else o_ptr->pval = 0;
+
+ if (flags & SAVE_ITEM_DISCOUNT) rd_byte(&o_ptr->discount);
+ else o_ptr->discount = 0;
+ if (flags & SAVE_ITEM_NUMBER) rd_byte(&o_ptr->number);
+ else o_ptr->number = 1;
+
+ rd_s16b(&o_ptr->weight);
+
+ if (flags & SAVE_ITEM_NAME1) rd_byte(&o_ptr->name1);
+ else o_ptr->name1 = 0;
+ if (flags & SAVE_ITEM_NAME2) rd_byte(&o_ptr->name2);
+ else o_ptr->name2 = 0;
+ if (flags & SAVE_ITEM_TIMEOUT) rd_s16b(&o_ptr->timeout);
+ else o_ptr->timeout = 0;
+
+ if (flags & SAVE_ITEM_TO_H) rd_s16b(&o_ptr->to_h);
+ else o_ptr->to_h = 0;
+ if (flags & SAVE_ITEM_TO_D) rd_s16b(&o_ptr->to_d);
+ else o_ptr->to_d = 0;
+ if (flags & SAVE_ITEM_TO_A) rd_s16b(&o_ptr->to_a);
+ else o_ptr->to_a = 0;
+
+ if (flags & SAVE_ITEM_AC) rd_s16b(&o_ptr->ac);
+ else o_ptr->ac = 0;
+
+ if (flags & SAVE_ITEM_DD) rd_byte(&o_ptr->dd);
+ else o_ptr->dd = 0;
+ if (flags & SAVE_ITEM_DS) rd_byte(&o_ptr->ds);
+ else o_ptr->ds = 0;
+
+ if (flags & SAVE_ITEM_IDENT) rd_byte(&o_ptr->ident);
+ else o_ptr->ident = 0;
+
+ if (flags & SAVE_ITEM_MARKED) rd_byte(&o_ptr->marked);
+ else o_ptr->marked = 0;
+
+ /* Object flags */
+ if (flags & SAVE_ITEM_ART_FLAGS0) rd_u32b(&o_ptr->art_flags[0]);
+ else o_ptr->art_flags[0] = 0;
+ if (flags & SAVE_ITEM_ART_FLAGS1) rd_u32b(&o_ptr->art_flags[1]);
+ else o_ptr->art_flags[1] = 0;
+ if (flags & SAVE_ITEM_ART_FLAGS2) rd_u32b(&o_ptr->art_flags[2]);
+ else o_ptr->art_flags[2] = 0;
+ if (flags & SAVE_ITEM_ART_FLAGS3) rd_u32b(&o_ptr->art_flags[3]);
+ else o_ptr->art_flags[3] = 0;
+
+ if (flags & SAVE_ITEM_CURSE_FLAGS) rd_u32b(&o_ptr->curse_flags);
+ else o_ptr->curse_flags = 0;
+
+ /* Monster holding object */
+ if (flags & SAVE_ITEM_HELD_M_IDX) rd_s16b(&o_ptr->held_m_idx);
+ else o_ptr->held_m_idx = 0;
+
+ /* Special powers */
+ if (flags & SAVE_ITEM_XTRA1) rd_byte(&o_ptr->xtra1);
+ else o_ptr->xtra1 = 0;
+ if (flags & SAVE_ITEM_XTRA2) rd_byte(&o_ptr->xtra2);
+ else o_ptr->xtra2 = 0;
+
+ if (flags & SAVE_ITEM_XTRA3) rd_byte(&o_ptr->xtra3);
+ else o_ptr->xtra3 = 0;
+
+ if (flags & SAVE_ITEM_XTRA4) rd_s16b(&o_ptr->xtra4);
+ else o_ptr->xtra4 = 0;
+ if (flags & SAVE_ITEM_XTRA5) rd_s16b(&o_ptr->xtra5);
+ else o_ptr->xtra5 = 0;
+
+ if (flags & SAVE_ITEM_FEELING) rd_byte(&o_ptr->feeling);
+ else o_ptr->feeling = 0;
+
+ if (flags & SAVE_ITEM_INSCRIPTION)
+ {
+ rd_string(buf, sizeof(buf));
+ if (buf[0]) o_ptr->inscription = quark_add(buf);
+ else o_ptr->inscription = 0;
+ }
+ else o_ptr->inscription = 0;
+
+ if (flags & SAVE_ITEM_ART_NAME)
+ {
+ rd_string(buf, sizeof(buf));
+ if (buf[0]) o_ptr->art_name = quark_add(buf);
+ else o_ptr->art_name = 0;
+ }
+ else o_ptr->art_name = 0;
+}
/*
- * Read a monster
+ * Read a monster (Old method)
*/
-static void rd_monster(monster_type *m_ptr)
+static void rd_monster_old(monster_type *m_ptr)
{
byte tmp8u;
char buf[128];
}
+/*
+ * Read a monster (New method)
+ */
+static void rd_monster(monster_type *m_ptr)
+{
+ u32b flags;
+ byte tmp8u;
+ char buf[128];
+
+ if (h_older_than(1, 3, 2, 1))
+ {
+ rd_monster_old(m_ptr);
+ return;
+ }
+
+ /*** Monster save flags ***/
+ rd_u32b(&flags);
+
+ /*** Read un-obvious elements ***/
+
+ /* Read the monster race */
+ rd_s16b(&m_ptr->r_idx);
+
+ /* Read the other information */
+ rd_byte(&m_ptr->fy);
+ rd_byte(&m_ptr->fx);
+ rd_s16b(&m_ptr->hp);
+ rd_s16b(&m_ptr->maxhp);
+ rd_s16b(&m_ptr->max_maxhp);
+
+ /* Monster race index of its appearance */
+ if (flags & SAVE_MON_AP_R_IDX) rd_s16b(&m_ptr->ap_r_idx);
+ else m_ptr->ap_r_idx = m_ptr->r_idx;
+
+ if (flags & SAVE_MON_SUB_ALIGN) rd_byte(&m_ptr->sub_align);
+ else m_ptr->sub_align = 0;
+
+ if (flags & SAVE_MON_CSLEEP) rd_s16b(&m_ptr->csleep);
+ else m_ptr->csleep = 0;
+
+ rd_byte(&m_ptr->mspeed);
+
+ rd_s16b(&m_ptr->energy_need);
+
+ if (flags & SAVE_MON_FAST) rd_byte(&m_ptr->fast);
+ else m_ptr->fast = 0;
+ if (flags & SAVE_MON_SLOW) rd_byte(&m_ptr->slow);
+ else m_ptr->slow = 0;
+ if (flags & SAVE_MON_STUNNED) rd_byte(&m_ptr->stunned);
+ else m_ptr->stunned = 0;
+ if (flags & SAVE_MON_CONFUSED) rd_byte(&m_ptr->confused);
+ else m_ptr->confused = 0;
+ if (flags & SAVE_MON_MONFEAR) rd_byte(&m_ptr->monfear);
+ else m_ptr->monfear = 0;
+
+ if (flags & SAVE_MON_TARGET_Y) rd_s16b(&m_ptr->target_y);
+ else m_ptr->target_y = 0;
+ if (flags & SAVE_MON_TARGET_X) rd_s16b(&m_ptr->target_x);
+ else m_ptr->target_x = 0;
+
+ if (flags & SAVE_MON_INVULNER) rd_byte(&m_ptr->invulner);
+ else m_ptr->invulner = 0;
+
+ if (flags & SAVE_MON_SMART) rd_u32b(&m_ptr->smart);
+ else m_ptr->smart = 0;
+
+ if (flags & SAVE_MON_EXP) rd_u32b(&m_ptr->exp);
+ else m_ptr->exp = 0;
+
+ m_ptr->mflag = 0; /* Not saved */
+
+ if (flags & SAVE_MON_MFLAG2) rd_byte(&m_ptr->mflag2);
+ else m_ptr->mflag2 = 0;
+
+ if (flags & SAVE_MON_NICKNAME)
+ {
+ rd_string(buf, sizeof(buf));
+ if (buf[0]) m_ptr->nickname = quark_add(buf);
+ else m_ptr->nickname = 0;
+ }
+ else m_ptr->nickname = 0;
+}
/* Read the "Racial" monster limit per level */
rd_byte(&r_ptr->max_num);
+ /* Location in saved floor */
+ rd_s16b(&r_ptr->floor_id);
+
/* Later (?) */
rd_byte(&tmp8u);
- rd_byte(&tmp8u);
- rd_byte(&tmp8u);
/* Repair the lore flags */
r_ptr->r_flags1 &= r_ptr->flags1;
rd_s16b(&tmp16s);
p_ptr->recall_dungeon = (byte)tmp16s;
}
+
+ if (h_older_than(1, 3, 2, 1))
+ p_ptr->alter_reality = 0;
+ else
+ rd_s16b(&p_ptr->alter_reality);
+
rd_s16b(&p_ptr->see_infra);
rd_s16b(&p_ptr->tim_infra);
rd_s16b(&p_ptr->oppose_fire);
rd_s16b(&p_ptr->riding);
}
+ /* Current floor_id */
+ if (h_older_than(1, 3, 2, 1))
+ {
+ p_ptr->floor_id = 0;
+ }
+ else
+ {
+ rd_s16b(&p_ptr->floor_id);
+ }
+
if (z_older_than(10,1,2))
{
playtime = 0;
#define CAVE_TRAP 0x8000
/*
- * Read the dungeon
+ * Read the dungeon (old method)
*
* The monsters/objects must be loaded in the same order
* that they were stored, since the actual indexes matter.
*/
-static errr rd_dungeon(void)
+static errr rd_dungeon_old(void)
{
int i, y, x;
int ymax, xmax;
/*
+ * Read the saved floor
+ *
+ * The monsters/objects must be loaded in the same order
+ * that they were stored, since the actual indexes matter.
+ */
+static errr rd_saved_floor(saved_floor_type *sf_ptr)
+{
+ int ymax, xmax;
+ int i, y, x;
+ byte count;
+ byte tmp8u;
+ s16b tmp16s;
+ u16b tmp16u;
+ s32b tmp32s;
+ u32b tmp32u;
+ u16b limit;
+
+ cave_template_type *template;
+ u16b num_temp;
+
+
+ /*** Basic info ***/
+
+ /* Dungeon floor specific info follows */
+
+ if (!sf_ptr)
+ {
+ /*** Not a saved floor ***/
+
+ rd_s16b(&dun_level);
+ base_level = dun_level;
+ }
+ else
+ {
+ /*** The saved floor ***/
+
+ rd_s16b(&tmp16s);
+ if (tmp16s != sf_ptr->floor_id) return 171;
+
+ rd_byte(&tmp8u);
+ if (tmp8u != sf_ptr->savefile_id) return 171;
+
+ rd_s16b(&tmp16s);
+ if (tmp16s != sf_ptr->dun_level) return 171;
+ dun_level = sf_ptr->dun_level;
+
+ rd_s32b(&tmp32s);
+ if (tmp32s != sf_ptr->last_visit) return 171;
+
+ rd_u32b(&tmp32u);
+ if (tmp32u != sf_ptr->visit_mark) return 171;
+
+ rd_s16b(&tmp16s);
+ if (tmp16s != sf_ptr->upper_floor_id) return 171;
+
+ rd_s16b(&tmp16s);
+ if (tmp16s != sf_ptr->lower_floor_id) return 171;
+ }
+
+ rd_s16b(&base_level);
+ rd_s16b(&num_repro);
+
+ rd_u16b(&tmp16u);
+ py = (int)tmp16u;
+
+ rd_u16b(&tmp16u);
+ px = (int)tmp16u;
+
+ rd_s16b(&cur_hgt);
+ rd_s16b(&cur_wid);
+
+ rd_byte(&feeling);
+
+
+
+ /*** Read template for cave_type ***/
+
+ /* Read the template count */
+ rd_u16b(&limit);
+
+ /* Allocate the "template" array */
+ C_MAKE(template, limit, cave_template_type);
+
+ /* Read the templates */
+ for (i = 0; i < limit; i++)
+ {
+ cave_template_type *ct_ptr = &template[i];
+
+ /* Read it */
+ rd_u16b(&ct_ptr->info);
+ rd_byte(&ct_ptr->feat);
+ rd_byte(&ct_ptr->mimic);
+ rd_s16b(&ct_ptr->special);
+ }
+
+ /* Maximal size */
+ ymax = cur_hgt;
+ xmax = cur_wid;
+
+
+ /*** Run length decoding ***/
+
+ /* Load the dungeon data */
+ for (x = y = 0; y < ymax; )
+ {
+ u16b id;
+
+ /* Grab RLE info */
+ rd_byte(&count);
+
+ id = 0;
+ do
+ {
+ rd_byte(&tmp8u);
+ id += tmp8u;
+ } while (tmp8u == MAX_UCHAR);
+
+ /* Apply the RLE info */
+ for (i = count; i > 0; i--)
+ {
+ /* Access the cave */
+ cave_type *c_ptr = &cave[y][x];
+
+ /* Extract cave data */
+ c_ptr->info = template[id].info;
+ c_ptr->feat = template[id].feat;
+ c_ptr->mimic = template[id].mimic;
+ c_ptr->special = template[id].special;
+
+ /* Advance/Wrap */
+ if (++x >= xmax)
+ {
+ /* Wrap */
+ x = 0;
+
+ /* Advance/Wrap */
+ if (++y >= ymax) break;
+ }
+ }
+ }
+
+ /* Free the "template" array */
+ C_FREE(template, limit, cave_template_type);
+
+
+ /*** Objects ***/
+
+ /* Read the item count */
+ rd_u16b(&limit);
+
+ /* Verify maximum */
+ if (limit >= max_o_idx) return 151;
+
+
+ /* Read the dungeon items */
+ for (i = 1; i < limit; i++)
+ {
+ int o_idx;
+ object_type *o_ptr;
+
+
+ /* Get a new record */
+ o_idx = o_pop();
+
+ /* Oops */
+ if (i != o_idx) return 152;
+
+ /* Acquire place */
+ o_ptr = &o_list[o_idx];
+
+ /* Read the item */
+ rd_item(o_ptr);
+
+
+ /* Monster */
+ if (o_ptr->held_m_idx)
+ {
+ monster_type *m_ptr;
+
+ /* Monster */
+ m_ptr = &m_list[o_ptr->held_m_idx];
+
+ /* Build a stack */
+ o_ptr->next_o_idx = m_ptr->hold_o_idx;
+
+ /* Place the object */
+ m_ptr->hold_o_idx = o_idx;
+ }
+
+ /* Dungeon */
+ else
+ {
+ /* Access the item location */
+ cave_type *c_ptr = &cave[o_ptr->iy][o_ptr->ix];
+
+ /* Build a stack */
+ o_ptr->next_o_idx = c_ptr->o_idx;
+
+ /* Place the object */
+ c_ptr->o_idx = o_idx;
+ }
+ }
+
+
+ /*** Monsters ***/
+
+ /* Read the monster count */
+ rd_u16b(&limit);
+
+ /* Hack -- verify */
+ if (limit >= max_m_idx) return 161;
+
+ /* Read the monsters */
+ for (i = 1; i < limit; i++)
+ {
+ cave_type *c_ptr;
+ int m_idx;
+ monster_type *m_ptr;
+ monster_race *r_ptr;
+
+
+ /* Get a new record */
+ m_idx = m_pop();
+
+ /* Oops */
+ if (i != m_idx) return 162;
+
+
+ /* Acquire monster */
+ m_ptr = &m_list[m_idx];
+
+ /* Read the monster */
+ rd_monster(m_ptr);
+
+
+ /* Access grid */
+ c_ptr = &cave[m_ptr->fy][m_ptr->fx];
+
+ /* Mark the location */
+ c_ptr->m_idx = m_idx;
+
+
+ /* Access race */
+ r_ptr = &r_info[m_ptr->r_idx];
+
+ /* Count XXX XXX XXX */
+ r_ptr->cur_num++;
+ }
+
+ /* Success */
+ return 0;
+}
+
+
+/*
+ * Read the dungeon (new method)
+ *
+ * The monsters/objects must be loaded in the same order
+ * that they were stored, since the actual indexes matter.
+ */
+static errr rd_dungeon(void)
+{
+ errr err = 0;
+ byte num;
+ int i;
+
+ /* Initialize saved_floors array and temporal files */
+ init_saved_floors();
+
+ /* Older method */
+ if (h_older_than(1, 3, 2, 1))
+ {
+ err = rd_dungeon_old();
+
+ /* Prepare floor_id of current floor */
+ if (dungeon_type)
+ {
+ p_ptr->floor_id = get_new_floor_id();
+ get_sf_ptr(p_ptr->floor_id)->dun_level = dun_level;
+ }
+
+ return err;
+ }
+
+
+ /*** Meta info ***/
+
+ /* Number of floor_id used from birth */
+ rd_s16b(&max_floor_id);
+
+ /* Current dungeon type */
+ rd_byte(&dungeon_type);
+
+
+ /*** On the surface ***/
+ if (!p_ptr->floor_id)
+ {
+ /* Number of array elements?? */
+ rd_byte(&num);
+
+ /* It should be 0 */
+ if (num) err = 181;
+
+ /* Read the current floor data */
+ err = rd_saved_floor(NULL);
+ }
+
+ /*** In the dungeon ***/
+ else
+ {
+ /* Number of array elements */
+ rd_byte(&num);
+
+ /* Read the saved_floors array */
+ for (i = 0; i < num; i++)
+ {
+ saved_floor_type *sf_ptr = &saved_floors[i];
+
+ rd_s16b(&sf_ptr->floor_id);
+ rd_byte(&sf_ptr->savefile_id);
+ rd_s16b(&sf_ptr->dun_level);
+ rd_s32b(&sf_ptr->last_visit);
+ rd_u32b(&sf_ptr->visit_mark);
+ rd_s16b(&sf_ptr->upper_floor_id);
+ rd_s16b(&sf_ptr->lower_floor_id);
+ }
+
+
+ /* Move saved floors data to temporal files */
+ for (i = 0; i < num; i++)
+ {
+ saved_floor_type *sf_ptr = &saved_floors[i];
+ byte tmp8u;
+
+ /* Unused element */
+ if (!sf_ptr->floor_id) continue;
+
+ /* Read the failure mark */
+ rd_byte(&tmp8u);
+ if (tmp8u) continue;
+
+ /* Wipe all cave */
+ clear_cave();
+
+ /* Read from the save file */
+ err = rd_saved_floor(sf_ptr);
+
+ /* Error? */
+ if (err) break;
+
+ /* Re-save as temporal saved floor file */
+ if (!save_floor(sf_ptr, SLF_SECOND)) err = 182;
+
+ /* Error? */
+ if (err) break;
+ }
+
+ /* Finally load current floor data from temporal file */
+ if (!err)
+ {
+ /* Wipe all cave */
+ clear_cave();
+
+ if (!load_floor(get_sf_ptr(p_ptr->floor_id), SLF_SECOND)) err = 183;
+ }
+ }
+
+
+ /*** Error messages ***/
+ switch (err)
+ {
+ case 151:
+#ifdef JP
+ note("¥¢¥¤¥Æ¥à¤ÎÇÛÎó¤¬Â礤¹¤®¤ë¡ª");
+#else
+ note("Too many object entries!");
+#endif
+ break;
+
+ case 152:
+#ifdef JP
+ note("¥¢¥¤¥Æ¥àÇÛÃÖ¥¨¥é¡¼");
+#else
+ note("Object allocation error");
+#endif
+ break;
+
+ case 161:
+#ifdef JP
+ note("¥â¥ó¥¹¥¿¡¼¤ÎÇÛÎó¤¬Â礤¹¤®¤ë¡ª");
+#else
+ note("Too many monster entries!");
+#endif
+ break;
+
+ case 162:
+#ifdef JP
+ note("¥â¥ó¥¹¥¿¡¼ÇÛÃÖ¥¨¥é¡¼");
+#else
+ note("Monster allocation error");
+#endif
+ break;
+
+ case 171:
+#ifdef JP
+ note("Êݸ¤µ¤ì¤¿¥Õ¥í¥¢¤Î¥À¥ó¥¸¥ç¥ó¥Ç¡¼¥¿¤¬²õ¤ì¤Æ¤¤¤Þ¤¹¡ª");
+#else
+ note("Dungeon data of saved floors are broken!");
+#endif
+ break;
+
+ case 181:
+#ifdef JP
+ note("Error 181");
+#else
+ note("Error 181");
+#endif
+ break;
+
+ case 182:
+#ifdef JP
+ note("¥Æ¥ó¥Ý¥é¥ê¡¦¥Õ¥¡¥¤¥ë¤òºîÀ®¤Ç¤¤Þ¤»¤ó¡ª");
+#else
+ note("Failed to make temporal files!");
+#endif
+ break;
+
+ case 183:
+#ifdef JP
+ note("Error 183");
+#else
+ note("Error 183");
+#endif
+ break;
+ }
+
+ /* The dungeon is ready */
+ character_dungeon = TRUE;
+
+ /* Success or Error */
+ return err;
+}
+
+
+/*
* Actually read the savefile
*/
static errr rd_savefile_new_aux(void)
/* Read the artifact flags */
for (i = 0; i < tmp16u; i++)
{
+ artifact_type *a_ptr = &a_info[i];
+
rd_byte(&tmp8u);
- a_info[i].cur_num = tmp8u;
- rd_byte(&tmp8u);
- rd_byte(&tmp8u);
- rd_byte(&tmp8u);
+ a_ptr->cur_num = tmp8u;
+
+ if (h_older_than(1, 3, 2, 1))
+ {
+ a_ptr->floor_id = 0;
+
+ rd_byte(&tmp8u);
+ rd_byte(&tmp8u);
+ rd_byte(&tmp8u);
+ }
+ else
+ {
+ rd_s16b(&a_ptr->floor_id);
+ }
}
#ifdef JP
if (arg_fiddle) note("ÅÁÀâ¤Î¥¢¥¤¥Æ¥à¤ò¥í¡¼¥É¤·¤Þ¤·¤¿");
}
+/*
+ * Actually load and verify a floor save data
+ */
+static bool load_floor_aux(saved_floor_type *sf_ptr)
+{
+ byte tmp8u;
+ u16b tmp16u;
+ u32b tmp32u;
+
+#ifdef VERIFY_CHECKSUMS
+ u32b n_x_check, n_v_check;
+ u32b o_x_check, o_v_check;
+#endif
+
+ /* Hack -- decrypt (read xor_byte) */
+ xor_byte = 0;
+ rd_byte(&tmp8u);
+
+ /* Clear the checksums */
+ v_check = 0L;
+ x_check = 0L;
+
+ /* Set the version number to current version */
+ /* Never load old temporal files */
+ h_ver_extra = H_VER_EXTRA;
+ h_ver_patch = H_VER_PATCH;
+ h_ver_minor = H_VER_MINOR;
+ h_ver_major = H_VER_MAJOR;
+
+ /* Verify the sign */
+ rd_u32b(&tmp32u);
+ if (saved_floor_file_sign != tmp32u) return FALSE;
+
+ /* Read -- have error? */
+ if (rd_saved_floor(sf_ptr)) return FALSE;
+
+
+#ifdef VERIFY_CHECKSUMS
+ /* Save the checksum */
+ n_v_check = v_check;
+
+ /* Read the old checksum */
+ rd_u32b(&o_v_check);
+
+ /* Verify */
+ if (o_v_check != n_v_check) return FALSE;
+
+ /* Save the encoded checksum */
+ n_x_check = x_check;
+
+ /* Read the checksum */
+ rd_u32b(&o_x_check);
+
+ /* Verify */
+ if (o_x_check != n_x_check) return FALSE;
+#endif
+
+ /* Success */
+ return TRUE;
+}
+
+
+/*
+ * Attempt to load the temporally saved-floor data
+ */
+bool load_floor(saved_floor_type *sf_ptr, u32b mode)
+{
+ FILE *old_fff = NULL;
+ byte old_xor_byte = 0;
+ u32b old_v_check = 0;
+ u32b old_x_check = 0;
+ byte old_h_ver_major = 0;
+ byte old_h_ver_minor = 0;
+ byte old_h_ver_patch = 0;
+ byte old_h_ver_extra = 0;
+
+ bool ok = TRUE;
+ char floor_savefile[1024];
+
+ /* We have one file already opened */
+ if (mode & SLF_SECOND)
+ {
+ /* Backup original values */
+ old_fff = fff;
+ old_xor_byte = xor_byte;
+ old_v_check = v_check;
+ old_x_check = x_check;
+ old_h_ver_major = h_ver_major;
+ old_h_ver_minor = h_ver_minor;
+ old_h_ver_patch = h_ver_patch;
+ old_h_ver_extra = h_ver_extra;
+ }
+
+ /* floor savefile */
+ sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);
+
+ /* The savefile is a binary file */
+ fff = my_fopen(floor_savefile, "rb");
+
+ /* Couldn't read */
+ if (!fff) ok = FALSE;
+
+ /* Attempt to load */
+ if (ok)
+ {
+ /* Load saved floor data from file */
+ ok = load_floor_aux(sf_ptr);
+
+ /* Check for errors */
+ if (ferror(fff)) ok = FALSE;
+
+ /* Close the file */
+ my_fclose(fff);
+
+ /* Delete the file */
+ if (!(mode & SLF_NO_KILL)) (void)fd_kill(floor_savefile);
+ }
+
+ /* We have one file already opened */
+ if (mode & SLF_SECOND)
+ {
+ /* Restore original values */
+ fff = old_fff;
+ xor_byte = old_xor_byte;
+ v_check = old_v_check;
+ x_check = old_x_check;
+ h_ver_major = old_h_ver_major;
+ h_ver_minor = old_h_ver_minor;
+ h_ver_patch = old_h_ver_patch;
+ h_ver_extra = old_h_ver_extra;
+ }
+
+ /* Result */
+ return ok;
+}
OBJ = \
artifact.obj autopick.obj avatar.obj birth.obj bldg.obj cave.obj \
cmd1.obj cmd2.obj cmd3.obj cmd4.obj cmd5.obj cmd6.obj \
- dungeon.obj effects.obj files.obj flavor.obj generate.obj \
+ dungeon.obj effects.obj files.obj floors.obj flavor.obj generate.obj \
grid.obj hissatsu.obj inet.obj init1.obj init2.obj japanese.obj \
load.obj main-win.obj mane.obj melee1.obj melee2.obj mind.obj \
monster1.obj monster2.obj mspells1.obj mspells2.obj mspells3.obj \
variable.o tables.o util.o cave.o \
object1.o object2.o monster1.o monster2.o \
xtra1.o xtra2.o spells1.o spells2.o \
- melee1.o melee2.o save.o files.o \
+ melee1.o melee2.o save.o files.o floors.o \
cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \
store.o birth.o load.o \
wizard1.o wizard2.o grid.o streams.o rooms.o \
variable.o tables.o util.o cave.o \
object1.o object2.o monster1.o monster2.o \
xtra1.o xtra2.o spells1.o spells2.o \
- melee1.o melee2.o save.o files.o \
+ melee1.o melee2.o save.o files.o floors.o \
cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \
store.o birth.o load.o \
wizard1.o wizard2.o grid.o streams.o rooms.o \
variable.c tables.c util.c cave.c \
object1.c object2.c monster1.c monster2.c \
xtra1.c xtra2.c spells1.c spells2.c \
- melee1.c melee2.c save.c files.c \
+ melee1.c melee2.c save.c files.c floors.c \
cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c \
store.c birth.c load.c \
wizard1.c wizard2.c grid.c streams.c rooms.c \
variable.o tables.o util.o cave.o \
object1.o object2.o monster1.o monster2.o \
xtra1.o xtra2.o spells1.o spells2.o \
- melee1.o melee2.o save.o files.o \
+ melee1.o melee2.o save.o files.o floors.o \
cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \
store.o birth.o load.o \
wizard1.o wizard2.o grid.o streams.o rooms.o \
if (racial_aux(25, 0, A_INT, 10))
{
int gain_sp;
- if ((gain_sp = take_hit(DAMAGE_USELIFE, p_ptr->lev,
#ifdef JP
-"£È£Ð¤«¤é£Í£Ð¤Ø¤Î̵ËŤÊÊÑ´¹", -1)))
+ if ((gain_sp = take_hit(DAMAGE_USELIFE, p_ptr->lev, "£È£Ð¤«¤é£Í£Ð¤Ø¤Î̵ËŤÊÊÑ´¹", -1)))
#else
-"thoughtless convertion from HP to SP", -1)))
+ if ((gain_sp = take_hit(DAMAGE_USELIFE, p_ptr->lev, "thoughtless convertion from HP to SP", -1)))
#endif
{
p_ptr->csp += gain_sp / 5;
{
if (racial_aux(30, 50, A_INT, 50))
{
- /* No effect in arena or quest */
- if (p_ptr->inside_arena || p_ptr->inside_quest)
- {
-#ifdef JP
-msg_print("¸ú²Ì¤¬¤Ê¤«¤Ã¤¿¡£");
-#else
- msg_print("There is no effect.");
-#endif
-
- }
- else
- {
#ifdef JP
-msg_print("¤¢¤Ê¤¿¤ÏÊ⤼þ¤ê»Ï¤á¤¿¡£¼þ°Ï¤¬ÊѲ½¤·¤Æ¤¤¤ë¡£");
+ msg_print("¤¢¤Ê¤¿¤ÏÊ⤼þ¤ê»Ï¤á¤¿¡£");
#else
- msg_print("You start walking around. Your surroundings change.");
+ msg_print("You start walking around. ");
#endif
-
-
- if (autosave_l) do_cmd_save_game(TRUE);
-
- /* Leaving */
- p_ptr->leaving = TRUE;
- }
+ alter_reality();
}
}
break;
*/
static void wr_item(object_type *o_ptr)
{
+ u32b flags = 0x00000000;
+
+ if (o_ptr->pval) flags |= SAVE_ITEM_PVAL;
+ if (o_ptr->discount) flags |= SAVE_ITEM_DISCOUNT;
+ if (o_ptr->number != 1) flags |= SAVE_ITEM_NUMBER;
+ if (o_ptr->name1) flags |= SAVE_ITEM_NAME1;
+ if (o_ptr->name2) flags |= SAVE_ITEM_NAME2;
+ if (o_ptr->timeout) flags |= SAVE_ITEM_TIMEOUT;
+ if (o_ptr->to_h) flags |= SAVE_ITEM_TO_H;
+ if (o_ptr->to_d) flags |= SAVE_ITEM_TO_D;
+ if (o_ptr->to_a) flags |= SAVE_ITEM_TO_A;
+ if (o_ptr->ac) flags |= SAVE_ITEM_AC;
+ if (o_ptr->dd) flags |= SAVE_ITEM_DD;
+ if (o_ptr->ds) flags |= SAVE_ITEM_DS;
+ if (o_ptr->ident) flags |= SAVE_ITEM_IDENT;
+ if (o_ptr->marked) flags |= SAVE_ITEM_MARKED;
+ if (o_ptr->art_flags[0]) flags |= SAVE_ITEM_ART_FLAGS0;
+ if (o_ptr->art_flags[1]) flags |= SAVE_ITEM_ART_FLAGS1;
+ if (o_ptr->art_flags[2]) flags |= SAVE_ITEM_ART_FLAGS2;
+ if (o_ptr->art_flags[3]) flags |= SAVE_ITEM_ART_FLAGS3;
+ if (o_ptr->curse_flags) flags |= SAVE_ITEM_CURSE_FLAGS;
+ if (o_ptr->held_m_idx) flags |= SAVE_ITEM_HELD_M_IDX;
+ if (o_ptr->xtra1) flags |= SAVE_ITEM_XTRA1;
+ if (o_ptr->xtra2) flags |= SAVE_ITEM_XTRA2;
+ if (o_ptr->xtra3) flags |= SAVE_ITEM_XTRA3;
+ if (o_ptr->xtra4) flags |= SAVE_ITEM_XTRA4;
+ if (o_ptr->xtra5) flags |= SAVE_ITEM_XTRA5;
+ if (o_ptr->feeling) flags |= SAVE_ITEM_FEELING;
+ if (o_ptr->inscription) flags |= SAVE_ITEM_INSCRIPTION;
+ if (o_ptr->art_name) flags |= SAVE_ITEM_ART_NAME;
+
+ /*** Item save flags ***/
+ wr_u32b(flags);
+
+ /*** Write only un-obvious elements ***/
wr_s16b(o_ptr->k_idx);
/* Location */
wr_byte(o_ptr->iy);
wr_byte(o_ptr->ix);
- wr_byte(o_ptr->tval);
- wr_byte(o_ptr->sval);
- wr_s16b(o_ptr->pval);
+ if (flags & SAVE_ITEM_PVAL) wr_s16b(o_ptr->pval);
+
+ if (flags & SAVE_ITEM_DISCOUNT) wr_byte(o_ptr->discount);
+ if (flags & SAVE_ITEM_NUMBER) wr_byte(o_ptr->number);
- wr_byte(o_ptr->discount);
- wr_byte(o_ptr->number);
wr_s16b(o_ptr->weight);
- wr_byte(o_ptr->name1);
- wr_byte(o_ptr->name2);
- wr_s16b(o_ptr->timeout);
+ if (flags & SAVE_ITEM_NAME1) wr_byte(o_ptr->name1);
+ if (flags & SAVE_ITEM_NAME2) wr_byte(o_ptr->name2);
+ if (flags & SAVE_ITEM_TIMEOUT) wr_s16b(o_ptr->timeout);
- wr_s16b(o_ptr->to_h);
- wr_s16b(o_ptr->to_d);
- wr_s16b(o_ptr->to_a);
- wr_s16b(o_ptr->ac);
- wr_byte(o_ptr->dd);
- wr_byte(o_ptr->ds);
+ if (flags & SAVE_ITEM_TO_H) wr_s16b(o_ptr->to_h);
+ if (flags & SAVE_ITEM_TO_D) wr_s16b(o_ptr->to_d);
+ if (flags & SAVE_ITEM_TO_A) wr_s16b(o_ptr->to_a);
+ if (flags & SAVE_ITEM_AC) wr_s16b(o_ptr->ac);
+ if (flags & SAVE_ITEM_DD) wr_byte(o_ptr->dd);
+ if (flags & SAVE_ITEM_DS) wr_byte(o_ptr->ds);
- wr_byte(o_ptr->ident);
+ if (flags & SAVE_ITEM_IDENT) wr_byte(o_ptr->ident);
- wr_byte(o_ptr->marked);
+ if (flags & SAVE_ITEM_MARKED) wr_byte(o_ptr->marked);
- wr_u32b(o_ptr->art_flags[0]);
- wr_u32b(o_ptr->art_flags[1]);
- wr_u32b(o_ptr->art_flags[2]);
- wr_u32b(o_ptr->art_flags[3]);
+ if (flags & SAVE_ITEM_ART_FLAGS0) wr_u32b(o_ptr->art_flags[0]);
+ if (flags & SAVE_ITEM_ART_FLAGS1) wr_u32b(o_ptr->art_flags[1]);
+ if (flags & SAVE_ITEM_ART_FLAGS2) wr_u32b(o_ptr->art_flags[2]);
+ if (flags & SAVE_ITEM_ART_FLAGS3) wr_u32b(o_ptr->art_flags[3]);
- wr_u32b(o_ptr->curse_flags);
+ if (flags & SAVE_ITEM_CURSE_FLAGS) wr_u32b(o_ptr->curse_flags);
/* Held by monster index */
- wr_s16b(o_ptr->held_m_idx);
+ if (flags & SAVE_ITEM_HELD_M_IDX) wr_s16b(o_ptr->held_m_idx);
/* Extra information */
- wr_byte(o_ptr->xtra1);
- wr_byte(o_ptr->xtra2);
- wr_byte(o_ptr->xtra3);
- wr_s16b(o_ptr->xtra4);
- wr_s16b(o_ptr->xtra5);
+ if (flags & SAVE_ITEM_XTRA1) wr_byte(o_ptr->xtra1);
+ if (flags & SAVE_ITEM_XTRA2) wr_byte(o_ptr->xtra2);
+ if (flags & SAVE_ITEM_XTRA3) wr_byte(o_ptr->xtra3);
+ if (flags & SAVE_ITEM_XTRA4) wr_s16b(o_ptr->xtra4);
+ if (flags & SAVE_ITEM_XTRA5) wr_s16b(o_ptr->xtra5);
/* Feelings */
- wr_byte(o_ptr->feeling);
-
- /* Save the inscription (if any) */
- if (o_ptr->inscription)
- {
- wr_string(quark_str(o_ptr->inscription));
- }
- else
- {
- wr_string("");
- }
+ if (flags & SAVE_ITEM_FEELING) wr_byte(o_ptr->feeling);
- /* If it is a "new" named artifact, save the name */
- if (o_ptr->art_name)
- {
- wr_string(quark_str(o_ptr->art_name));
- }
- else
- {
- wr_string("");
- }
-
- /* No Python object */
- wr_s32b(0);
+ if (flags & SAVE_ITEM_INSCRIPTION) wr_string(quark_str(o_ptr->inscription));
+ if (flags & SAVE_ITEM_ART_NAME) wr_string(quark_str(o_ptr->art_name));
}
*/
static void wr_monster(monster_type *m_ptr)
{
+ u32b flags = 0x00000000;
+
+ if (m_ptr->ap_r_idx != m_ptr->r_idx) flags |= SAVE_MON_AP_R_IDX;
+ if (m_ptr->sub_align) flags |= SAVE_MON_SUB_ALIGN;
+ if (m_ptr->csleep) flags |= SAVE_MON_CSLEEP;
+ if (m_ptr->fast) flags |= SAVE_MON_FAST;
+ if (m_ptr->slow) flags |= SAVE_MON_SLOW;
+ if (m_ptr->stunned) flags |= SAVE_MON_STUNNED;
+ if (m_ptr->confused) flags |= SAVE_MON_CONFUSED;
+ if (m_ptr->monfear) flags |= SAVE_MON_MONFEAR;
+ if (m_ptr->target_y) flags |= SAVE_MON_TARGET_Y;
+ if (m_ptr->target_x) flags |= SAVE_MON_TARGET_X;
+ if (m_ptr->invulner) flags |= SAVE_MON_INVULNER;
+ if (m_ptr->smart) flags |= SAVE_MON_SMART;
+ if (m_ptr->exp) flags |= SAVE_MON_EXP;
+ if (m_ptr->mflag2) flags |= SAVE_MON_MFLAG2;
+ if (m_ptr->nickname) flags |= SAVE_MON_NICKNAME;
+
+ /*** Monster save flags ***/
+ wr_u32b(flags);
+
+ /*** Write only un-obvious elements ***/
wr_s16b(m_ptr->r_idx);
- wr_s16b(m_ptr->ap_r_idx);
- wr_byte(m_ptr->sub_align);
wr_byte(m_ptr->fy);
wr_byte(m_ptr->fx);
wr_s16b(m_ptr->hp);
wr_s16b(m_ptr->maxhp);
wr_s16b(m_ptr->max_maxhp);
- wr_s16b(m_ptr->csleep);
+
+ /* Monster race index of its appearance */
+ if (flags & SAVE_MON_AP_R_IDX) wr_s16b(m_ptr->ap_r_idx);
+ else m_ptr->ap_r_idx = m_ptr->r_idx;
+
+ if (flags & SAVE_MON_SUB_ALIGN) wr_byte(m_ptr->sub_align);
+ if (flags & SAVE_MON_CSLEEP) wr_s16b(m_ptr->csleep);
+
wr_byte(m_ptr->mspeed);
wr_s16b(m_ptr->energy_need);
- wr_byte(m_ptr->fast);
- wr_byte(m_ptr->slow);
- wr_byte(m_ptr->stunned);
- wr_byte(m_ptr->confused);
- wr_byte(m_ptr->monfear);
- wr_s16b(m_ptr->target_y);
- wr_s16b(m_ptr->target_x);
- wr_byte(m_ptr->invulner);
- wr_u32b(m_ptr->smart);
- wr_u32b(m_ptr->exp);
- wr_byte(m_ptr->mflag2);
- if (m_ptr->nickname)
- {
- wr_string(quark_str(m_ptr->nickname));
- }
- else
- {
- wr_string("");
- }
- wr_byte(0);
+
+ if (flags & SAVE_MON_FAST) wr_byte(m_ptr->fast);
+ if (flags & SAVE_MON_SLOW) wr_byte(m_ptr->slow);
+ if (flags & SAVE_MON_STUNNED) wr_byte(m_ptr->stunned);
+ if (flags & SAVE_MON_CONFUSED) wr_byte(m_ptr->confused);
+ if (flags & SAVE_MON_MONFEAR) wr_byte(m_ptr->monfear);
+ if (flags & SAVE_MON_TARGET_Y) wr_s16b(m_ptr->target_y);
+ if (flags & SAVE_MON_TARGET_X) wr_s16b(m_ptr->target_x);
+ if (flags & SAVE_MON_INVULNER) wr_byte(m_ptr->invulner);
+ if (flags & SAVE_MON_SMART) wr_u32b(m_ptr->smart);
+ if (flags & SAVE_MON_EXP) wr_u32b(m_ptr->exp);
+ if (flags & SAVE_MON_MFLAG2) wr_byte(m_ptr->mflag2);
+ if (flags & SAVE_MON_NICKNAME) wr_string(quark_str(m_ptr->nickname));
}
/* Monster limit per level */
wr_byte(r_ptr->max_num);
+ /* Location in saved floor */
+ wr_s16b(r_ptr->floor_id);
+
/* Later (?) */
wr_byte(0);
- wr_byte(0);
- wr_byte(0);
}
wr_s16b(p_ptr->tim_invis);
wr_s16b(p_ptr->word_recall);
wr_s16b(p_ptr->recall_dungeon);
+ wr_s16b(p_ptr->alter_reality);
wr_s16b(p_ptr->see_infra);
wr_s16b(p_ptr->tim_infra);
wr_s16b(p_ptr->oppose_fire);
wr_s16b(p_ptr->today_mon);
wr_s16b(p_ptr->riding);
+ /* Current floor_id */
+ wr_s16b(p_ptr->floor_id);
+
wr_u32b(playtime);
wr_s32b(p_ptr->visit);
/*
- * Write the current dungeon
+ * hook function to sort monsters by level
*/
-static void wr_dungeon(void)
+static bool ang_sort_comp_cave_temp(vptr u, vptr v, int a, int b)
+{
+ cave_template_type *who = (cave_template_type *)(u);
+
+ u16b o1 = who[a].occurrence;
+ u16b o2 = who[b].occurrence;
+
+ return o2 <= o1;
+}
+
+
+/*
+ * Sorting hook -- Swap function
+ */
+static void ang_sort_swap_cave_temp(vptr u, vptr v, int a, int b)
+{
+ cave_template_type *who = (cave_template_type *)(u);
+
+ cave_template_type holder;
+
+ /* Swap */
+ holder = who[a];
+ who[a] = who[b];
+ who[b] = holder;
+}
+
+
+/*
+ * Actually write a saved floor data
+ * using effectively compressed format.
+ */
+static void wr_saved_floor(saved_floor_type *sf_ptr)
{
+ cave_template_type *template;
+ u16b max_num_temp;
+ u16b num_temp = 0;
+ int dummy_why;
+
int i, y, x;
byte tmp8u;
byte count;
byte prev_char;
- s16b prev_s16b;
+ u16b prev_u16b;
cave_type *c_ptr;
/*** Basic info ***/
- /* Dungeon specific info follows */
- wr_u16b(dun_level);
- wr_byte(dungeon_type);
+ /* Dungeon floor specific info follows */
+
+ if (!sf_ptr)
+ {
+ /*** Not a saved floor ***/
+
+ wr_s16b(dun_level);
+ }
+ else
+ {
+ /*** The saved floor ***/
+
+ wr_s16b(sf_ptr->floor_id);
+ wr_byte(sf_ptr->savefile_id);
+ wr_s16b(sf_ptr->dun_level);
+ wr_s32b(sf_ptr->last_visit);
+ wr_u32b(sf_ptr->visit_mark);
+ wr_s16b(sf_ptr->upper_floor_id);
+ wr_s16b(sf_ptr->lower_floor_id);
+ }
+
wr_u16b(base_level);
wr_u16b(num_repro);
wr_u16b((u16b)py);
wr_u16b((u16b)px);
wr_u16b(cur_hgt);
wr_u16b(cur_wid);
- wr_u16b(0); /* max_panel_rows */
- wr_u16b(0); /* max_panel_cols */
+ wr_byte(feeling);
- /*** Simple "Run-Length-Encoding" of cave ***/
- /* Note that this will induce two wasted bytes */
- count = 0;
- prev_s16b = 0;
+ /*********** Make template for cave_type **********/
- /* Dump the cave */
+ /*
+ * Usually number of templates are fewer than 255. Even if
+ * more than 254 are exist, the occurrence of each template
+ * with larger ID is very small when we sort templates by
+ * occurrence. So we will use two (or more) bytes for
+ * templete ID larger than 254.
+ *
+ * Ex: 256 will be "0xff" "0x01".
+ * 515 will be "0xff" "0xff" "0x03"
+ */
+
+ /* Fake max number */
+ max_num_temp = 255;
+
+ /* Allocate the "template" array */
+ C_MAKE(template, max_num_temp, cave_template_type);
+
+ /* Extract template array */
for (y = 0; y < cur_hgt; y++)
{
for (x = 0; x < cur_wid; x++)
{
- /* Get the cave */
- c_ptr = &cave[y][x];
-
- /* Extract a byte */
- tmp16u = c_ptr->info;
+ cave_type *c_ptr = &cave[y][x];
- /* If the run is broken, or too full, flush it */
- if ((tmp16u != prev_s16b) || (count == MAX_UCHAR))
+ for (i = 0; i < num_temp; i++)
{
- wr_byte((byte)count);
- wr_u16b((u16b)prev_s16b);
- prev_s16b = tmp16u;
- count = 1;
+ if (template[i].info == c_ptr->info &&
+ template[i].feat == c_ptr->feat &&
+ template[i].mimic == c_ptr->mimic &&
+ template[i].special == c_ptr->special)
+ {
+ /* Same terrain is exist */
+ template[i].occurrence++;
+ break;
+ }
}
- /* Continue the run */
- else
+ /* Are there same one? */
+ if (i < num_temp) continue;
+
+ /* If the max_num_temp is too small, increase it. */
+ if (num_temp >= max_num_temp)
{
- count++;
+ cave_template_type *old_template = template;
+
+ /* Re-allocate the "template" array */
+ C_MAKE(template, max_num_temp + 255, cave_template_type);
+ C_COPY(template, old_template, max_num_temp, cave_template_type);
+ C_FREE(old_template, max_num_temp, cave_template_type);
+ max_num_temp += 255;
}
- }
- }
- /* Flush the data (if any) */
- if (count)
- {
- wr_byte((byte)count);
- wr_u16b((byte)prev_s16b);
+ /* Add new template */
+ template[num_temp].info = c_ptr->info;
+ template[num_temp].feat = c_ptr->feat;
+ template[num_temp].mimic = c_ptr->mimic;
+ template[num_temp].special = c_ptr->special;
+ template[num_temp].occurrence = 1;
+
+ /* Increase number of template */
+ num_temp++;
+ }
}
+ /* Select the sort method */
+ ang_sort_comp = ang_sort_comp_cave_temp;
+ ang_sort_swap = ang_sort_swap_cave_temp;
- /*** Simple "Run-Length-Encoding" of cave ***/
+ /* Sort by occurrence */
+ ang_sort(template, &dummy_why, num_temp);
- /* Note that this will induce two wasted bytes */
- count = 0;
- prev_char = 0;
- /* Dump the cave */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
- {
- /* Get the cave */
- c_ptr = &cave[y][x];
+ /*** Dump templates ***/
- /* Extract a byte */
- tmp8u = c_ptr->feat;
+ /* Total templates */
+ wr_u16b(num_temp);
- /* If the run is broken, or too full, flush it */
- if ((tmp8u != prev_char) || (count == MAX_UCHAR))
- {
- wr_byte((byte)count);
- wr_byte((byte)prev_char);
- prev_char = tmp8u;
- count = 1;
- }
+ /* Dump the templates */
+ for (i = 0; i < num_temp; i++)
+ {
+ cave_template_type *ct_ptr = &template[i];
- /* Continue the run */
- else
- {
- count++;
- }
- }
+ /* Dump it */
+ wr_u16b(ct_ptr->info);
+ wr_byte(ct_ptr->feat);
+ wr_byte(ct_ptr->mimic);
+ wr_s16b(ct_ptr->special);
}
- /* Flush the data (if any) */
- if (count)
- {
- wr_byte((byte)count);
- wr_byte((byte)prev_char);
- }
- /*** Simple "Run-Length-Encoding" of cave ***/
+ /*** "Run-Length-Encoding" of cave ***/
/* Note that this will induce two wasted bytes */
count = 0;
- prev_char = 0;
+ prev_u16b = 0;
/* Dump the cave */
for (y = 0; y < cur_hgt; y++)
{
for (x = 0; x < cur_wid; x++)
{
- /* Get the cave */
- c_ptr = &cave[y][x];
+ cave_type *c_ptr = &cave[y][x];
- /* Extract a byte */
- tmp8u = c_ptr->mimic;
+ for (i = 0; i < num_temp; i++)
+ {
+ if (template[i].info == c_ptr->info &&
+ template[i].feat == c_ptr->feat &&
+ template[i].mimic == c_ptr->mimic &&
+ template[i].special == c_ptr->special)
+ break;
+ }
+
+ /* Extract an ID */
+ tmp16u = i;
/* If the run is broken, or too full, flush it */
- if ((tmp8u != prev_char) || (count == MAX_UCHAR))
+ if ((tmp16u != prev_u16b) || (count == MAX_UCHAR))
{
wr_byte((byte)count);
- wr_byte((byte)prev_char);
- prev_char = tmp8u;
+
+ while (prev_u16b >= MAX_UCHAR)
+ {
+ /* Mark as actual data is larger than 254 */
+ wr_byte(MAX_UCHAR);
+ prev_u16b -= MAX_UCHAR;
+ }
+
+ wr_byte((byte)prev_u16b);
+ prev_u16b = tmp16u;
count = 1;
}
if (count)
{
wr_byte((byte)count);
- wr_byte((byte)prev_char);
- }
-
-
- /*** Simple "Run-Length-Encoding" of cave ***/
- /* Note that this will induce two wasted bytes */
- count = 0;
- prev_s16b = 0;
-
- /* Dump the cave */
- for (y = 0; y < cur_hgt; y++)
- {
- for (x = 0; x < cur_wid; x++)
+ while (prev_u16b >= MAX_UCHAR)
{
- /* Get the cave */
- c_ptr = &cave[y][x];
-
- /* Extract a byte */
- tmp16u = c_ptr->special;
-
- /* If the run is broken, or too full, flush it */
- if ((tmp16u != prev_s16b) || (count == MAX_UCHAR))
- {
- wr_byte((byte)count);
- wr_u16b(prev_s16b);
- prev_s16b = tmp16u;
- count = 1;
- }
-
- /* Continue the run */
- else
- {
- count++;
- }
+ /* Mark as actual data is larger than 254 */
+ wr_byte(MAX_UCHAR);
+ prev_u16b -= MAX_UCHAR;
}
+ wr_byte((byte)prev_u16b);
}
- /* Flush the data (if any) */
- if (count)
- {
- wr_byte((byte)count);
- wr_u16b(prev_s16b);
- }
+
+ /* Free the "template" array */
+ C_FREE(template, max_num_temp, cave_template_type);
/*** Dump objects ***/
/*** Dump the monsters ***/
-
/* Total monsters */
wr_u16b(m_max);
}
+/*
+ * Write the current dungeon (new method)
+ */
+static void wr_dungeon(void)
+{
+ saved_floor_type *cur_sf_ptr;
+ int i;
+
+ /*** Meta info ***/
+
+ /* Number of floor_id used from birth */
+ wr_s16b(max_floor_id);
+
+ /* Current dungeon type */
+ wr_byte(dungeon_type);
+
+
+ /*** On the surface ***/
+ if (!p_ptr->floor_id)
+ {
+ /* No array elements */
+ wr_byte(0);
+
+ /* Write the current floor data */
+ wr_saved_floor(NULL);
+
+ return;
+ }
+
+
+ /*** In the dungeon ***/
+
+ /* Number of array elements */
+ wr_byte(MAX_SAVED_FLOORS);
+
+ /* Write the saved_floors array */
+ for (i = 0; i < MAX_SAVED_FLOORS; i++)
+ {
+ saved_floor_type *sf_ptr = &saved_floors[i];
+
+ wr_s16b(sf_ptr->floor_id);
+ wr_byte(sf_ptr->savefile_id);
+ wr_s16b(sf_ptr->dun_level);
+ wr_s32b(sf_ptr->last_visit);
+ wr_u32b(sf_ptr->visit_mark);
+ wr_s16b(sf_ptr->upper_floor_id);
+ wr_s16b(sf_ptr->lower_floor_id);
+ }
+
+ /* Extract pointer to current floor */
+ cur_sf_ptr = get_sf_ptr(p_ptr->floor_id);
+
+
+ /* Save current floor to temporal file */
+ if (!save_floor(cur_sf_ptr, (SLF_SECOND)))
+ {
+ /* Error */
+ /* Hack -- fflush(fff) will notice this error */
+ fclose(fff);
+
+ return;
+ }
+
+ /* Move data in temporal files to the savefile */
+ for (i = 0; i < MAX_SAVED_FLOORS; i++)
+ {
+ saved_floor_type *sf_ptr = &saved_floors[i];
+
+ /* Unused element */
+ if (!sf_ptr->floor_id) continue;
+
+ /* Wipe all cave */
+ clear_cave();
+
+ /* Load temporal saved floor file */
+ if (load_floor(sf_ptr, (SLF_SECOND | SLF_NO_KILL)))
+ {
+ /* Mark success */
+ wr_byte(0);
+
+ /* Write saved floor data to the save file */
+ wr_saved_floor(sf_ptr);
+ }
+ else
+ {
+ /* Mark failure */
+ wr_byte(1);
+ }
+ }
+
+ /* Wipe all cave */
+ clear_cave();
+
+ /* Restore current floor */
+ if (!load_floor(cur_sf_ptr, (SLF_SECOND)))
+ {
+ /* Error */
+ /* Hack -- fflush(fff) will notice this error */
+ fclose(fff);
+
+ return;
+ }
+}
+
+
/*
* Actually write a save-file
{
artifact_type *a_ptr = &a_info[i];
wr_byte(a_ptr->cur_num);
- wr_byte(0);
- wr_byte(0);
- wr_byte(0);
+ wr_s16b(a_ptr->floor_id);
}
#endif
-
/* Return the result */
return (result);
}
/* Message */
#ifdef JP
msg_format("¥Ð¡¼¥¸¥ç¥ó %d.%d.%d ÍѤΥ»¡¼¥Ö¡¦¥Õ¥¡¥¤¥ë¤òÊÑ´¹¤·¤Þ¤·¤¿¡£",
+ (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
#else
msg_format("Converted a %d.%d.%d savefile.",
-#endif
-
(z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
+#endif
}
msg_print(NULL);
}
/* Message */
#ifdef JP
msg_format("¥¨¥é¡¼(%s)¤¬¥Ð¡¼¥¸¥ç¥ó%d.%d.%d ÍÑ¥»¡¼¥Ö¥Õ¥¡¥¤¥ëÆɤ߹þÃæ¤ËȯÀ¸¡£",
+ what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
#else
msg_format("Error (%s) reading %d.%d.%d savefile.",
-#endif
-
what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
+#endif
msg_print(NULL);
/* Oops */
#endif /* SET_UID */
}
+
+
+/*
+ * Actually write a temporal saved floor file
+ */
+static bool save_floor_aux(saved_floor_type *sf_ptr)
+{
+ byte tmp8u;
+
+ /* Compact the objects */
+ compact_objects(0);
+ /* Compact the monsters */
+ compact_monsters(0);
+
+
+ /*** Actually write the file ***/
+
+ /* Initial value of xor_byte */
+ tmp8u = (byte)randint0(256);
+ xor_byte = 0;
+ wr_byte(tmp8u);
+
+
+ /* Reset the checksum */
+ v_stamp = 0L;
+ x_stamp = 0L;
+
+ /* Write the sign of this process */
+ wr_u32b(saved_floor_file_sign);
+
+ /* Dump the dungeon floor */
+ wr_saved_floor(sf_ptr);
+
+
+ /* Write the "value check-sum" */
+ wr_u32b(v_stamp);
+
+ /* Write the "encoded checksum" */
+ wr_u32b(x_stamp);
+
+
+ /* Error in save */
+ if (ferror(fff) || (fflush(fff) == EOF)) return FALSE;
+
+ /* Successful save */
+ return TRUE;
+}
+
+
+/*
+ * Attempt to save the temporally saved-floor data
+ */
+bool save_floor(saved_floor_type *sf_ptr, u32b mode)
+{
+ FILE *old_fff = NULL;
+ byte old_xor_byte = 0;
+ u32b old_v_stamp = 0;
+ u32b old_x_stamp = 0;
+
+ char floor_savefile[1024];
+ int fd = -1;
+ bool ok = FALSE;
+
+ if (!(mode & SLF_SECOND))
+ {
+#ifdef SET_UID
+# ifdef SECURE
+ /* Get "games" permissions */
+ beGames();
+# endif
+#endif
+ }
+
+ /* We have one file already opened */
+ else
+ {
+ /* Backup original values */
+ old_fff = fff;
+ old_xor_byte = xor_byte;
+ old_v_stamp = v_stamp;
+ old_x_stamp = x_stamp;
+ }
+
+ /* New savefile */
+ sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);
+
+ /* Attempt to save the player */
+
+ /* No file yet */
+ fff = NULL;
+
+ /* File type is "SAVE" */
+ FILE_TYPE(FILE_TYPE_SAVE);
+
+ /* Create the savefile */
+ fd = fd_make(floor_savefile, 0644);
+
+ /* File is okay */
+ if (fd >= 0)
+ {
+ /* Close the "fd" */
+ (void)fd_close(fd);
+
+ /* Open the savefile */
+ fff = my_fopen(floor_savefile, "wb");
+
+ /* Successful open */
+ if (fff)
+ {
+ /* Write the savefile */
+ if (save_floor_aux(sf_ptr)) ok = TRUE;
+
+ /* Attempt to close it */
+ if (my_fclose(fff)) ok = FALSE;
+ }
+
+ /* Remove "broken" files */
+ if (!ok) (void)fd_kill(floor_savefile);
+ }
+
+ if (!(mode & SLF_SECOND))
+ {
+#ifdef SET_UID
+# ifdef SECURE
+ /* Drop "games" permissions */
+ bePlayer();
+# endif
+#endif
+ }
+
+ /* We have one file already opened */
+ else
+ {
+ /* Restore original values */
+ fff = old_fff;
+ xor_byte = old_xor_byte;
+ v_stamp = old_v_stamp;
+ x_stamp = old_x_stamp;
+ }
+
+ /* Return the result */
+ return ok;
+}
+++ /dev/null
-/* File: script.c */
-
-/* Purpose: Script interface */
-
-#include "angband.h"
-
-#ifdef USE_SCRIPT
-
-#include "Python.h"
-
-/*
- * Execute a Python script
- */
-errr script_execute(char *name)
-{
- char buf[1024];
-
- if (!name || !*name)
- {
- msg_print("Oops! No script given.");
- return (1);
- }
-
- /* Load a script file */
- if (name[0] == '@')
- {
- FILE *fff;
- int result;
-
- /* Skip the '@' */
- name++;
-
- /* Either run the specified file or try to start "idle" */
- if (name[0] != '\0')
- {
- /* Build the filename */
- path_build(buf, sizeof(buf), ANGBAND_DIR_SCRIPT, name);
- }
- else
- {
- /* Build the filename */
- path_build(buf, sizeof(buf), ANGBAND_DIR_SCRIPT, "idle.py");
- }
-
- fff = my_fopen(buf, "rw");
-
- result = PyRun_SimpleFile(fff, buf);
-
- my_fclose(fff);
-
- return result;
- }
- else
- {
- return PyRun_SimpleString(name);
- }
-
- return (0);
-}
-
-
-#ifdef STATIC_PYTHON
-extern void initeventc(void);
-extern void initplayerc(void);
-extern void initioc(void);
-extern void initobjectsc(void);
-extern void initcavec(void);
-extern void initmonsterc(void);
-extern void initpclassc(void);
-extern void initpracec(void);
-extern void initterrainc(void);
-extern void initcommandsc(void);
-extern void initrealmsc(void);
-extern void initrandomc(void);
-extern void initspellsc(void);
-extern void initstorec(void);
-extern void initsystemc(void);
-#endif /* STATIC_PYTHON */
-
-
-/*
- * Initialize the script support
- */
-errr init_script(void)
-{
- char buf[1024];
- char path[1024];
- char path1[1024];
- cptr *program_name = &argv0;
-
- Py_SetProgramName((char*)argv0);
-
-#ifdef __djgpp__
- /* Set the enviroment variables */
- setenv("PYTHONPATH", ANGBAND_DIR_SCRIPT, 1);
- setenv("PYTHONHOME", ANGBAND_DIR_SCRIPT, 1);
-#endif /* __djgpp__ */
-
- /* Initialize the Python interpreter */
- Py_Initialize();
-
- /* Define sys.argv. It is up to the application if you
- want this; you can also let it undefined (since the Python
- code is generally not a main program it has no business
- touching sys.argv...) */
- PySys_SetArgv(1, (char **)program_name);
-
-
- /* Convert the script path to a nice string */
- ascii_to_text(path, ANGBAND_DIR_SCRIPT);
-
- /* Build the path to the Python modules */
- path_build(buf, sizeof(buf), ANGBAND_DIR_SCRIPT, "python");
-
- /* Convert the script path to a nice string */
- ascii_to_text(path1, buf);
-
- /* Add the "script" directory to the module search path */
- sprintf(buf, "import sys; sys.path.insert(0, '%s'); sys.path.insert(0, '%s')", path1, path);
-
- if (PyRun_SimpleString(buf) == 0)
- {
-#ifdef STATIC_PYTHON
- initeventc();
- initplayerc();
- initioc();
- initobjectsc();
- initcavec();
- initmonsterc();
- initpclassc();
- initpracec();
- initterrainc();
- initcommandsc();
- initrealmsc();
- initrandomc();
- initspellsc();
- initstorec();
- initsystemc();
-#endif /* STATIC_PYTHON */
-
- if (PyRun_SimpleString("import init") == 0) return 0;
- }
-
- return -1;
-}
-
-#endif /* USE_SCRIPT */
#endif
}
+ if (p_ptr->alter_reality)
+ {
+#ifdef JP
+ info[i++] = "¤¢¤Ê¤¿¤Ï¤¹¤°¤Ë¤³¤ÎÀ¤³¦¤òÎ¥¤ì¤ë¤À¤í¤¦¡£";
+#else
+ info[i++] = "You will soon be altered.";
+#endif
+
+ }
if (p_ptr->see_infra)
{
#ifdef JP
{
info2[i] = report_magics_aux(p_ptr->word_recall);
#ifdef JP
-info[i++] = "¤³¤Î¸åµ¢´Ô¤Î¾Û¤òȯư¤¹¤ë¡£";
+ info[i++] = "¤³¤Î¸åµ¢´Ô¤Î¾Û¤òȯư¤¹¤ë¡£";
#else
info[i++] = "You are waiting to be recalled";
#endif
}
+ if (p_ptr->alter_reality)
+ {
+ info2[i] = report_magics_aux(p_ptr->alter_reality);
+#ifdef JP
+ info[i++] = "¤³¤Î¸å¸½¼ÂÊÑÍƤ¬È¯Æ°¤¹¤ë¡£";
+#else
+ info[i++] = "You waiting to be altered";
+#endif
+
+ }
if (p_ptr->oppose_acid)
{
info2[i] = report_magics_aux(p_ptr->oppose_acid);
if (detect_traps(range, TRUE)) detect = TRUE;
if (detect_doors(range)) detect = TRUE;
if (detect_stairs(range)) detect = TRUE;
- if (detect_treasure(range)) detect = TRUE;
+
+ /* There are too many hidden treasure. So... */
+ /* if (detect_treasure(range)) detect = TRUE; */
+
if (detect_objects_gold(range)) detect = TRUE;
if (detect_objects_normal(range)) detect = TRUE;
if (detect_monsters_invis(range)) detect = TRUE;
*/
void teleport_player_level(void)
{
+ bool go_up;
+
/* No effect in arena or quest */
if (p_ptr->inside_arena || (p_ptr->inside_quest && !random_quest_number(dun_level)) ||
(quest_number(dun_level) && (dun_level > 1) && ironman_downward))
return;
}
+ /* Choose up or down */
+ if (randint0(100) < 50) go_up = TRUE;
+ else go_up = FALSE;
+
+ if (p_ptr->wizard)
+ {
+ if (get_check("Force to go up? ")) go_up = TRUE;
+ else if (get_check("Force to go down? ")) go_up = FALSE;
+ }
+
+ /* Down only */
if (ironman_downward || (dun_level <= d_info[dungeon_type].mindepth))
{
#ifdef JP
if (!dun_level)
{
dun_level = d_info[dungeon_type].mindepth;
+ prepare_change_floor_mode(CFM_RAND_PLACE | CFM_CLEAR_ALL);
}
else
{
- dun_level++;
+ prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
}
/* Leaving */
p_ptr->leaving = TRUE;
}
+
+ /* Up only */
else if (quest_number(dun_level) || (dun_level >= d_info[dungeon_type].maxdepth))
{
#ifdef JP
if (autosave_l) do_cmd_save_game(TRUE);
- dun_level--;
-
- if (!dun_level) dungeon_type = 0;
+ prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
leave_quest_check();
p_ptr->inside_quest = 0;
p_ptr->leaving = TRUE;
}
- else if (randint0(100) < 50)
+ else if (go_up)
{
#ifdef JP
msg_print("¤¢¤Ê¤¿¤ÏÅ·°æ¤òÆͤÇˤäÆÃè¤ØÉ⤤¤Æ¤¤¤¯¡£");
if (autosave_l) do_cmd_save_game(TRUE);
- dun_level--;
-
- if (!dun_level) dungeon_type = 0;
+ prepare_change_floor_mode(CFM_UP | CFM_RAND_PLACE | CFM_RAND_CONNECT);
/* Leaving */
p_ptr->leaving = TRUE;
msg_print("You sink through the floor.");
#endif
- if (!dun_level) dungeon_type = p_ptr->recall_dungeon;
+ /* Never reach this code on the surface */
+ /* if (!dun_level) dungeon_type = p_ptr->recall_dungeon; */
if (record_stair) do_cmd_write_nikki(NIKKI_TELE_LEV, 1, NULL);
if (autosave_l) do_cmd_save_game(TRUE);
- dun_level++;
+ prepare_change_floor_mode(CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
/* Leaving */
p_ptr->leaving = TRUE;
}
- if (!dun_level && dungeon_type)
- {
- p_ptr->leaving_dungeon = TRUE;
- p_ptr->wilderness_y = d_info[dungeon_type].dy;
- p_ptr->wilderness_x = d_info[dungeon_type].dx;
- p_ptr->recall_dungeon = dungeon_type;
- }
-
- if (!dun_level) dungeon_type = 0;
-
/* Sound */
sound(SOUND_TPLEVEL);
}
void alter_reality(void)
{
- if (!quest_number(dun_level) && dun_level)
+ /* Ironman option */
+ if (p_ptr->inside_arena || ironman_downward)
{
#ifdef JP
-msg_print("À¤³¦¤¬ÊѤï¤Ã¤¿¡ª");
+ msg_print("²¿¤âµ¯¤³¤é¤Ê¤«¤Ã¤¿¡£");
#else
- msg_print("The world changes!");
+ msg_print("Nothing happens.");
#endif
+ return;
+ }
+ if (!p_ptr->alter_reality)
+ {
+ int turns = randint0(21) + 15;
- if (autosave_l) do_cmd_save_game(TRUE);
+ p_ptr->alter_reality = turns;
+#ifdef JP
+ msg_print("²ó¤ê¤Î·Ê¿§¤¬ÊѤï¤ê»Ï¤á¤¿...");
+#else
+ msg_print("The view around you begins to change...");
+#endif
- /* Leaving */
- p_ptr->leaving = TRUE;
+ p_ptr->redraw |= (PR_STATUS);
}
else
{
+ p_ptr->alter_reality = 0;
#ifdef JP
-msg_print("À¤³¦¤¬¾¯¤·¤Î´ÖÊѲ½¤·¤¿¤è¤¦¤À¡£");
+ msg_print("·Ê¿§¤¬¸µ¤ËÌá¤Ã¤¿...");
#else
- msg_print("The world seems to change for a moment!");
+ msg_print("The view around you got back...");
#endif
+ p_ptr->redraw |= (PR_STATUS);
}
+ return;
}
}
-/*
- * Create stairs at the player location
- */
-void stair_creation(void)
-{
- /* XXX XXX XXX */
- if (!cave_valid_bold(py, px))
- {
-#ifdef JP
-msg_print("¾²¾å¤Î¥¢¥¤¥Æ¥à¤¬¼öʸ¤òÄ·¤ÍÊÖ¤·¤¿¡£");
-#else
- msg_print("The object resists the spell.");
-#endif
-
- return;
- }
-
- /* XXX XXX XXX */
- delete_object(py, px);
-
- /* Create a staircase */
- if (p_ptr->inside_arena || (p_ptr->inside_quest && (p_ptr->inside_quest < MIN_RANDOM_QUEST)) || p_ptr->inside_battle || !dun_level)
- {
- /* arena or quest */
-#ifdef JP
-msg_print("¸ú²Ì¤¬¤¢¤ê¤Þ¤»¤ó¡ª");
-#else
- msg_print("There is no effect!");
-#endif
-
- }
- else if (ironman_downward)
- {
- /* Town/wilderness or Ironman */
- cave_set_feat(py, px, FEAT_MORE);
- }
- else if (quest_number(dun_level) || (dun_level >= d_info[dungeon_type].maxdepth))
- {
- /* Quest level */
- cave_set_feat(py, px, FEAT_LESS);
- }
- else if (randint0(100) < 50)
- {
- cave_set_feat(py, px, FEAT_MORE);
- }
- else
- {
- cave_set_feat(py, px, FEAT_LESS);
- }
-}
-
/*
* Hook to specify "weapon"
cave_type *c_ptr;
/* Hack -- Choose starting point */
- y = rand_spread(cur_hgt / 2, 10);
- x = rand_spread(cur_wid / 2, 15);
+ y = rand_spread(cur_hgt / 2, cur_hgt / 6);
+ x = rand_spread(cur_wid / 2, cur_wid / 6);
/* Choose a random compass direction */
dir = ddd[randint0(8)];
/* Paranoia: Clear mimic field */
c_ptr->mimic = 0;
- /* Hack -- Add some (known) treasure */
- if (treasure && one_in_(chance)) c_ptr->feat += 0x04;
+ /* Hack -- Add some known treasure */
+ if (treasure && one_in_(chance))
+ c_ptr->feat += (FEAT_MAGMA_K - FEAT_MAGMA);
+
+ /* Hack -- Add some hidden treasure */
+ else if (treasure && one_in_(chance/4))
+ c_ptr->feat += (FEAT_MAGMA_H - FEAT_MAGMA);
}
if (dummy >= SAFE_MAX_ATTEMPTS)
#ifdef JP
- { &confirm_stairs, FALSE, 1, 5, 5,
- "confirm_stairs", "Ê̤γ¬¤Ë¹Ô¤¯»þ³Îǧ¤¹¤ë" },
+ { &confirm_quest, TRUE, 1, 1, 9,
+ "confirm_quest", "¥¯¥¨¥¹¥È¤òÄü¤á¤Æ³¬ÃʤÇƨ¤²¤ëÁ°¤Ë³Îǧ¤¹¤ë" },
#else
- { &confirm_stairs, FALSE, 1, 5, 5,
- "confirm_stairs", "Prompt before exiting a dungeon level" },
+ { &confirm_quest, TRUE, 1, 1, 9,
+ "confirm_quest", "Prompt before exiting a quest level" },
#endif
#ifdef JP
- { &dungeon_stair, TRUE, 3, 1, 9,
- "dungeon_stair", "³¬Ãʤò¤Ä¤Ê¤²¤Æ¥À¥ó¥¸¥ç¥ó¤òÀ¸À®¤¹¤ë" },
-#else
- { &dungeon_stair, TRUE, 3, 1, 9,
- "dungeon_stair", "Generate dungeons with connected stairs" },
-#endif
-
-
-#ifdef JP
{ &small_levels, TRUE, 3, 0, 30,
"small_levels", "Èó¾ï¤Ë¾®¤µ¤¤¥Õ¥í¥¢¤ÎÀ¸À®¤ò²Äǽ¤Ë¤¹¤ë" },
#else
byte cur_num; /* Number created (0 or 1) */
byte max_num; /* Unused (should be "1") */
+
+ s16b floor_id; /* Leaved on this location last time */
};
byte cur_num; /* Monster population on current level */
+ s16b floor_id; /* Location of unique monster */
+
s16b r_sights; /* Count sightings of this monster */
s16b r_deaths; /* Count deaths from this monster */
s16b vir_types[8];
s16b word_recall; /* Word of recall counter */
+ s16b alter_reality; /* Alter reality counter */
byte recall_dungeon; /* Dungeon set to be recalled */
s16b energy_need; /* Energy needed for next move */
s16b today_mon; /* Wanted monster */
bool dtrap; /* Whether you are on trap-safe grids */
-
+ s16b floor_id; /* Current floor location */
/*** Temporary fields ***/
bool leaving_dungeon; /* True if player is leaving the dungeon */
bool teleport_town;
+ bool enter_dungeon; /* Just enter the dungeon */
s16b health_who; /* Health bar trackee */
byte bonus; /* Items which have more than 'bonus' magical bonus match */
} autopick_type;
+
+/*
+ * A structure type for the saved floor
+ */
+typedef struct
+{
+ s16b floor_id; /* No recycle until 65536 IDs are all used */
+ byte savefile_id; /* ID for savefile (from 0 to MAX_SAVED_FLOOR) */
+ s16b dun_level;
+ s32b last_visit; /* Time count of last visit. 0 for new floor. */
+ u32b visit_mark; /* Older has always smaller mark. */
+ s16b upper_floor_id; /* a floor connected with level teleportation */
+ s16b lower_floor_id; /* a floor connected with level tel. and trap door */
+} saved_floor_type;
+
+
+/*
+ * A structure type for terrain template of saving dungeon floor
+ */
+typedef struct
+{
+ u16b info;
+ byte feat;
+ byte mimic;
+ s16b special;
+ u16b occurrence;
+} cave_template_type;
+
s16b energy_use; /* Energy use this turn */
-byte create_up_stair; /* Auto-create "up stairs" */
-byte create_down_stair; /* Auto-create "down stairs" */
-
bool msg_flag; /* Used in msg_print() for "buffering" */
s16b running; /* Current counter for running, if any */
bool display_mutations; /* Skip mutations screen even if we have it */
bool plain_descriptions; /* Plain object descriptions */
bool confirm_destroy; /* Known worthless items are destroyed without confirmation */
-bool confirm_stairs; /* Prompt before staircases... */
+bool confirm_quest; /* Prompt before staircases... */
bool confirm_wear; /* Confirm before putting on known cursed items */
bool disturb_pets; /* Pets moving nearby disturb us */
bool view_unsafe_grids; /* Map marked by detect traps */
bool dungeon_align; /* Generate dungeons with aligned rooms */
-bool dungeon_stair; /* Generate dungeons with connected stairs */
bool track_follow; /* Monsters follow the player */
bool track_target; /* Monsters target the player */
*/
cave_type *cave[MAX_HGT];
+
+/*
+ * The array of saved floors
+ */
+saved_floor_type saved_floors[MAX_SAVED_FLOORS];
+
+
+/*
+ * Number of floor_id used from birth
+ */
+s16b max_floor_id;
+
+
+/*
+ * Sign for current process used in temporal files.
+ * Actually it is the start time of current process.
+ */
+u32b saved_floor_file_sign;
+
+
/*
* The array of dungeon items [max_o_idx]
*/
/* Change level */
dun_level = command_arg;
+ prepare_change_floor_mode(CFM_RAND_PLACE | CFM_CLEAR_ALL);
+
if (!dun_level) dungeon_type = 0;
p_ptr->inside_arena = FALSE;
+ p_ptr->wild_mode = FALSE;
leave_quest_check();
/*
+ * hook function to sort monsters by level
+ */
+static bool ang_sort_comp_cave_temp(vptr u, vptr v, int a, int b)
+{
+ cave_template_type *who = (cave_template_type *)(u);
+
+ int o1 = who[a].occurrence;
+ int o2 = who[b].occurrence;
+
+ return o2 <= o1;
+}
+
+
+/*
+ * Sorting hook -- Swap function
+ */
+static void ang_sort_swap_cave_temp(vptr u, vptr v, int a, int b)
+{
+ cave_template_type *who = (cave_template_type *)(u);
+
+ cave_template_type holder;
+
+ /* Swap */
+ holder = who[a];
+ who[a] = who[b];
+ who[b] = holder;
+}
+
+
+/*
* Summon a creature of the specified type
*
* XXX XXX XXX This function is rather dangerous
#define BAR_STEALTH 49
#define BAR_SUPERSTEALTH 50
#define BAR_RECALL 51
+#define BAR_ALTER 52
static struct {
{TERM_UMBER, "±£", "±£Ì©"},
{TERM_YELLOW, "±£", "Ķ±£Ì©"},
{TERM_WHITE, "µ¢", "µ¢´Ô"},
+ {TERM_WHITE, "¸½", "¸½¼ÂÊÑÍÆ"},
{0, NULL, NULL}
};
#else
{TERM_UMBER, "Sl", "Stealth"},
{TERM_YELLOW, "Stlt", "Stealth"},
{TERM_WHITE, "Rc", "Recall"},
+ {TERM_WHITE, "Al", "Alter"},
{0, NULL, NULL}
};
#endif
/* Word of Recall */
if (p_ptr->word_recall) ADD_FLG(BAR_RECALL);
+ /* Alter realiry */
+ if (p_ptr->alter_reality) ADD_FLG(BAR_ALTER);
+
/* Afraid */
if (p_ptr->afraid) ADD_FLG(BAR_AFRAID);
if ((feat >= FEAT_DOOR_HEAD) &&
(feat <= FEAT_DOOR_TAIL)) return (TRUE);
+#if 0
/* Notice rubble */
/* I think FEAT_RUBBLEs should not be "interesting" */
-#if 0
if (feat == FEAT_RUBBLE) return (TRUE);
-#endif
+
/* Notice veins with treasure */
+ /* Now veins with treasure are too many */
if (feat == FEAT_MAGMA_K) return (TRUE);
if (feat == FEAT_QUARTZ_K) return (TRUE);
+#endif
/* Notice quest features */
if (feat == FEAT_QUEST_ENTER) return (TRUE);