2018/12/19
■ [変愚蛮怒/開発]変愚蛮怒開発日誌part109…特別編「変愚蛮怒の地形実装例 ~毒沼やら酸の沼やら~(前編)」
今日の枠が埋まりそうになかったのでしつこくやっていきます。今回の地形追加は、以前から少しだけ手を付けてみた内容であったりします。
現状ダメージ地形は溶岩と、浮遊なし&重量オーバー時の溺れ効果しかないので、折角だからもっと属性ダメージフィールドを増やしてみようという魂胆です。
FF_*定義
まずがf_info.txtで用いる地形フラグであるFF_*を新しく定義してみましょう。
例によってdefines.hへの追加と
diff --git a/src/defines.h b/src/defines.h index 1cf2681..21b2982 100644 --- a/src/defines.h +++ b/src/defines.h @@ -988,15 +988,15 @@ #define FF_LAVA 40 #define FF_SHALLOW 41 #define FF_DEEP 42 -/* #define FF_FILLED 43 */ +#define FF_POISON_PUDDLE 43 #define FF_HURT_ROCK 44 /* #define FF_HURT_FIRE 45 */ /* #define FF_HURT_COLD 46 */ /* #define FF_HURT_ACID 47 */ -/* #define FF_ICE 48 */ -/* #define FF_ACID 49 */ -/* #define FF_OIL 50 */ -/* #define FF_XXX04 51 */ +#define FF_COLD_PUDDLE 48 +#define FF_ACID_PUDDLE 49 +/* #define FF_OIL 50 +#define FF_ELEC_PUDDLE 51 /* #define FF_CAN_CLIMB 52 */ #define FF_CAN_FLY 53 #define FF_CAN_SWIM 54
f_info.txtで用いるフラグ文字列の追加です。こうして見てみると結構没になっていたらしい種々の地形フラグの形跡はあるようです。
diff --git a/src/init1.c b/src/init1.c index 4e70c73..c98898f 100644 --- a/src/init1.c +++ b/src/init1.c @@ -189,15 +189,15 @@ static cptr f_info_flags[] = "LAVA", "SHALLOW", "DEEP", - "FILLED", + "POISON_PUDDLE", "HURT_ROCK", "HURT_FIRE", "HURT_COLD", "HURT_ACID", - "ICE", - "ACID", + "COLD_PUDDLE", + "ACID_PUDDLE", "OIL", - "XXX04", + "ELEC_PUDDLE", "CAN_CLIMB", "CAN_FLY", "CAN_SWIM",
地形ダメージ処理実装
dungeon.cの溶岩の熱処理を実装している場所に、そのまま参考にしつつ冷気、電撃、酸、毒ダメージの実装をしてみます。表現や対応する英文はちと苦しいかもしれません。
--- a/src/dungeon.c +++ b/src/dungeon.c @@ -1502,6 +1502,160 @@ static void process_world_aux_hp_and_sp(void) } } + if (have_flag(f_ptr->flags, FF_COLD_PUDDLE) && !IS_INVULN() && !p_ptr->immune_cold) + { + int damage = 0; + + if (have_flag(f_ptr->flags, FF_DEEP)) + { + damage = 6000 + randint0(4000); + } + else if (!p_ptr->levitation) + { + damage = 3000 + randint0(2000); + } + + if (damage) + { + if (p_ptr->resist_cold) damage = damage / 3; + if (IS_OPPOSE_COLD()) damage = damage / 3; + if (p_ptr->levitation) damage = damage / 5; + + damage = damage / 100 + (randint0(100) < (damage % 100)); + + if (p_ptr->levitation) + { + msg_print(_("冷気に覆われた!", "The cold engulfs you!")); + take_hit(DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), + f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name), -1); + } + else + { + cptr name = f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name; + msg_format(_("%sに凍えた!", "The %s frostbites you!"), name); + take_hit(DAMAGE_NOESCAPE, damage, name, -1); + } + + cave_no_regen = TRUE; + } + } + + if (have_flag(f_ptr->flags, FF_ELEC_PUDDLE) && !IS_INVULN() && !p_ptr->immune_elec) + { + int damage = 0; + + if (have_flag(f_ptr->flags, FF_DEEP)) + { + damage = 6000 + randint0(4000); + } + else if (!p_ptr->levitation) + { + damage = 3000 + randint0(2000); + } + + if (damage) + { + if (p_ptr->resist_elec) damage = damage / 3; + if (IS_OPPOSE_ELEC()) damage = damage / 3; + if (p_ptr->levitation) damage = damage / 5; + + damage = damage / 100 + (randint0(100) < (damage % 100)); + + if (p_ptr->levitation) + { + msg_print(_("電撃を受けた!", "The electric shocks you!")); + take_hit(DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), + f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name), -1); + } + else + { + cptr name = f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name; + msg_format(_("%sに感電した!", "The %s shocks you!"), name); + take_hit(DAMAGE_NOESCAPE, damage, name, -1); + } + + cave_no_regen = TRUE; + } + } + + if (have_flag(f_ptr->flags, FF_ACID_PUDDLE) && !IS_INVULN() && !p_ptr->immune_acid) + { + int damage = 0; + + if (have_flag(f_ptr->flags, FF_DEEP)) + { + damage = 6000 + randint0(4000); + } + else if (!p_ptr->levitation) + { + damage = 3000 + randint0(2000); + } + + if (damage) + { + if (p_ptr->resist_acid) damage = damage / 3; + if (IS_OPPOSE_ACID()) damage = damage / 3; + if (p_ptr->levitation) damage = damage / 5; + + damage = damage / 100 + (randint0(100) < (damage % 100)); + + if (p_ptr->levitation) + { + msg_print(_("酸を受けた!", "The acid melt you!")); + take_hit(DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), + f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name), -1); + } + else + { + cptr name = f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name; + msg_format(_("%sに溶かされた!", "The %s melts you!"), name); + take_hit(DAMAGE_NOESCAPE, damage, name, -1); + } + + cave_no_regen = TRUE; + } + } + + if (have_flag(f_ptr->flags, FF_POISON_PUDDLE) && !IS_INVULN()) + { + int damage = 0; + + if (have_flag(f_ptr->flags, FF_DEEP)) + { + damage = 6000 + randint0(4000); + } + else if (!p_ptr->levitation) + { + damage = 3000 + randint0(2000); + } + + if (damage) + { + if (p_ptr->resist_pois) damage = damage / 3; + if (IS_OPPOSE_POIS()) damage = damage / 3; + if (p_ptr->levitation) damage = damage / 5; + + damage = damage / 100 + (randint0(100) < (damage % 100)); + + if (p_ptr->levitation) + { + msg_print(_("毒気を吸い込んだ!", "The gas poisons you!")); + take_hit(DAMAGE_NOESCAPE, damage, format(_("%sの上に浮遊したダメージ", "flying over %s"), + f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name), -1); + if (p_ptr->resist_pois) (void)set_poisoned(p_ptr->poisoned + 1); + } + else + { + cptr name = f_name + f_info[get_feat_mimic(&cave[p_ptr->y][p_ptr->x])].name; + msg_format(_("%sに毒された!", "The %s poisons you!"), name); + take_hit(DAMAGE_NOESCAPE, damage, name, -1); + if (p_ptr->resist_pois) (void)set_poisoned(p_ptr->poisoned + 3); + } + + cave_no_regen = TRUE; + } + } + if (have_flag(f_ptr->flags, FF_WATER) && have_flag(f_ptr->flags, FF_DEEP) && !p_ptr->levitation && !p_ptr->can_swim) {
f_info.txtに各FF_*を当てた新地形を追加。
同じく、これも地形名とかもう少しスマートな表現はあっていい気はします。多少前述のルールの変更も含めて。
--- a/lib/edit/f_info.txt +++ b/lib/edit/f_info.txt @@ -1796,3 +1796,67 @@ W:2 K:DESTROYED:SHALLOW_WATER F:POWER_40 | LOS | REMEMBER | TUNNEL | WALL | HURT_ROCK | CAN_PASS | F:HURT_DISI | GLASS + +N:227:HEAVY_COLD_ZONE +J:極低温帯 +E:heavy cold zone +G:~:W +W:2 +F:LOS | PROJECT | MOVE | PLACE | REMEMBER | GLOW | COLD_PUDDLE | DEEP | CAN_FLY | +F:TELEPORTABLE + +N:228:COLD_ZONE +J:低温帯 +E:cold zone +G:~:w +W:2 +F:LOS | PROJECT | MOVE | PLACE | DROP | REMEMBER | COLD_PUDDLE | SHALLOW | CAN_FLY | +F:TELEPORTABLE + +N:229:HEAVY_ELECTRICAL_ZONE +J:高圧帯電帯 +E:heavy electrical zone +G:~:y +W:2 +F:LOS | PROJECT | MOVE | PLACE | REMEMBER | GLOW | ELEC_PUDDLE | DEEP | CAN_FLY | +F:TELEPORTABLE + +N:230:ELECTRICAL_ZONE +J:帯電帯 +E:electrical zone +G:~:o +W:2 +F:LOS | PROJECT | MOVE | PLACE | DROP | REMEMBER | ELEC_PUDDLE | SHALLOW | CAN_FLY | +F:TELEPORTABLE + +N:231:DEEP_ACID_PUDDLE +J:深い酸の沼 +E:deep acid puddle +G:~:u +W:2 +F:LOS | PROJECT | MOVE | PLACE | REMEMBER | GLOW | ACID_PUDDLE | DEEP | CAN_FLY | +F:TELEPORTABLE + +N:232:SHALLOW_ACID_PUDDLE +J:浅い酸の沼 +E:shallow acid puddle +G:~:U +W:2 +F:LOS | PROJECT | MOVE | PLACE | DROP | REMEMBER | ACID_PUDDLE | SHALLOW | CAN_FLY | +F:TELEPORTABLE + +N:233:DEEP_POISONOUS_PUDDLE +J:深い毒の沼 +E:deep poisonous puddle +G:~:g +W:2 +F:LOS | PROJECT | MOVE | PLACE | REMEMBER | GLOW | POISON_PUDDLE | DEEP | CAN_FLY | +F:TELEPORTABLE + +N:234:SHALLOW_ACID_PUDDLE +J:浅い毒の沼 +E:shallow poisonous puddle +G:~:G +W:2 +F:LOS | PROJECT | MOVE | PLACE | DROP | REMEMBER | POISON_PUDDLE | SHALLOW | CAN_FLY | +F:TELEPORTABLE
そんなこんなで以下の通り追加できました。次回で実際にダンジョンにこれらの地形を生成する手段を追加します。