<ClCompile Include="..\..\src\load\item\item-loader-factory.cpp" />\r
<ClCompile Include="..\..\src\load\monster\monster-loader-factory.cpp" />\r
<ClCompile Include="..\..\src\load\player-class-specific-data-loader.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\object-smith.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\smith-info.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\smith-tables.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\weapon\abstract-weapon-enchanter.cpp" />\r
+ <ClCompile Include="..\..\src\smith\object-smith.cpp" />\r
+ <ClCompile Include="..\..\src\smith\smith-info.cpp" />\r
+ <ClCompile Include="..\..\src\smith\smith-tables.cpp" />\r
<ClCompile Include="..\..\src\object-use\item-use-checker.cpp" />\r
<ClCompile Include="..\..\src\object-use\use-execution.cpp" />\r
<ClCompile Include="..\..\src\object-use\zaprod-execution.cpp" />\r
<ClCompile Include="..\..\src\main-win\main-win-term.cpp" />\r
<ClCompile Include="..\..\src\main-win\wav-reader.cpp" />\r
<ClCompile Include="..\..\src\monster\monster-damage.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-amulet.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\abstract-protector-enchanter.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-boots.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-cloak.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-crown.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-gloves.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-helm.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-ring.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-shield.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-amulet.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\abstract-protector-enchanter.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-boots.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-cloak.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-crown.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-gloves.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-helm.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-ring.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-shield.cpp" />\r
<ClCompile Include="..\..\src\object\object-index-list.cpp" />\r
<ClCompile Include="..\..\src\player-info\alignment.cpp" />\r
<ClCompile Include="..\..\src\player-info\equipment-info.cpp" />\r
<ClCompile Include="..\..\src\load\dungeon-loader.cpp" />\r
<ClCompile Include="..\..\src\load\extra-loader.cpp" />\r
<ClCompile Include="..\..\src\load\inventory-loader.cpp" />\r
- <ClCompile Include="..\..\src\load\old\item-loader-savefile10.cpp" />\r
+ <ClCompile Include="..\..\src\load\old\item-loader-savefile50.cpp" />\r
<ClCompile Include="..\..\src\load\load-util.cpp" />\r
<ClCompile Include="..\..\src\load\old\load-v1-5-0.cpp" />\r
<ClCompile Include="..\..\src\load\old\load-v1-7-0.cpp" />\r
<ClCompile Include="..\..\src\load\load-zangband.cpp" />\r
<ClCompile Include="..\..\src\load\lore-loader.cpp" />\r
- <ClCompile Include="..\..\src\load\old\monster-loader-savefile10.cpp" />\r
+ <ClCompile Include="..\..\src\load\old\monster-loader-savefile50.cpp" />\r
<ClCompile Include="..\..\src\load\option-loader.cpp" />\r
<ClCompile Include="..\..\src\load\player-attack-loader.cpp" />\r
<ClCompile Include="..\..\src\load\player-info-loader.cpp" />\r
<ClCompile Include="..\..\src\monster-attack\monster-attack-switcher.cpp" />\r
<ClCompile Include="..\..\src\monster-attack\monster-attack-types.cpp" />\r
<ClCompile Include="..\..\src\combat\attack-accuracy.cpp" />\r
- <ClCompile Include="..\..\src\monster-attack\monster-attack-util.cpp" />\r
<ClCompile Include="..\..\src\monster-attack\monster-eating.cpp" />\r
<ClCompile Include="..\..\src\player-attack\player-attack.cpp" />\r
<ClCompile Include="..\..\src\combat\slaying.cpp" />\r
<ClCompile Include="..\..\src\mind\mind-samurai.cpp" />\r
<ClCompile Include="..\..\src\mind\mind-warrior.cpp" />\r
<ClCompile Include="..\..\src\racial\racial-vampire.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-armor.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-others.cpp" />\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-weapon.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-armor.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-others.cpp" />\r
+ <ClCompile Include="..\..\src\object-enchant\weapon\apply-magic-weapon.cpp" />\r
<ClCompile Include="..\..\src\object-enchant\apply-magic.cpp" />\r
<ClCompile Include="..\..\src\player\eldritch-horror.cpp" />\r
<ClCompile Include="..\..\src\specific-object\bow.cpp" />\r
<ClInclude Include="..\..\src\load\monster\monster-loader-base.h" />\r
<ClInclude Include="..\..\src\load\monster\monster-loader-factory.h" />\r
<ClInclude Include="..\..\src\load\monster\monster-loader-version-types.h" />\r
- <ClInclude Include="..\..\src\load\old\monster-flag-types-savefile10.h" />\r
+ <ClInclude Include="..\..\src\load\old\monster-flag-types-savefile50.h" />\r
<ClInclude Include="..\..\src\load\player-class-specific-data-loader.h" />\r
<ClInclude Include="..\..\src\load\savedata-old-flag-types.h" />\r
<ClInclude Include="..\..\src\monster-race\monster-aura-types.h" />\r
+ <ClInclude Include="..\..\src\monster-race\race-behavior-flags.h" />\r
+ <ClInclude Include="..\..\src\monster-race\race-visual-flags.h" />\r
<ClInclude Include="..\..\src\mspell\mspell-result.h" />\r
- <ClInclude Include="..\..\src\object-enchant\object-smith.h" />\r
- <ClInclude Include="..\..\src\object-enchant\smith-info.h" />\r
- <ClInclude Include="..\..\src\object-enchant\smith-tables.h" />\r
- <ClInclude Include="..\..\src\object-enchant\smith-types.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\weapon\abstract-weapon-enchanter.h" />\r
+ <ClInclude Include="..\..\src\smith\object-smith.h" />\r
+ <ClInclude Include="..\..\src\smith\smith-info.h" />\r
+ <ClInclude Include="..\..\src\smith\smith-tables.h" />\r
+ <ClInclude Include="..\..\src\smith\smith-types.h" />\r
<ClInclude Include="..\..\src\object-enchant\tr-flags.h" />\r
<ClInclude Include="..\..\src\object-use\item-use-checker.h" />\r
<ClInclude Include="..\..\src\object-use\throw-execution.h" />\r
<ClInclude Include="..\..\src\main-win\main-win-term.h" />\r
<ClInclude Include="..\..\src\main-win\wav-reader.h" />\r
<ClInclude Include="..\..\src\monster\monster-damage.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-amulet.h" />\r
- <ClInclude Include="..\..\src\object-enchant\abstract-protector-enchanter.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-boots.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-cloak.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-crown.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-gloves.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-helm.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-ring.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-shield.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-amulet.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\abstract-protector-enchanter.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-boots.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-cloak.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-crown.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-gloves.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-helm.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-ring.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-shield.h" />\r
<ClInclude Include="..\..\src\object-use\use-execution.h" />\r
<ClInclude Include="..\..\src\object-use\zaprod-execution.h" />\r
<ClInclude Include="..\..\src\object-use\zapwand-execution.h" />\r
<ClInclude Include="..\..\src\load\dungeon-loader.h" />\r
<ClInclude Include="..\..\src\load\extra-loader.h" />\r
<ClInclude Include="..\..\src\load\inventory-loader.h" />\r
- <ClInclude Include="..\..\src\load\old\item-loader-savefile10.h" />\r
+ <ClInclude Include="..\..\src\load\old\item-loader-savefile50.h" />\r
<ClInclude Include="..\..\src\load\load-util.h" />\r
<ClInclude Include="..\..\src\load\old\load-v1-7-0.h" />\r
<ClInclude Include="..\..\src\load\old\load-v1-5-0.h" />\r
<ClInclude Include="..\..\src\load\load-zangband.h" />\r
<ClInclude Include="..\..\src\load\lore-loader.h" />\r
- <ClInclude Include="..\..\src\load\old\monster-loader-savefile10.h" />\r
+ <ClInclude Include="..\..\src\load\old\monster-loader-savefile50.h" />\r
<ClInclude Include="..\..\src\load\old-feature-types.h" />\r
<ClInclude Include="..\..\src\load\option-loader.h" />\r
<ClInclude Include="..\..\src\load\player-attack-loader.h" />\r
<ClInclude Include="..\..\src\load\player-info-loader.h" />\r
- <ClInclude Include="..\..\src\load\old\item-flag-types-savefile10.h" />\r
+ <ClInclude Include="..\..\src\load\old\item-flag-types-savefile50.h" />\r
<ClInclude Include="..\..\src\load\store-loader.h" />\r
<ClInclude Include="..\..\src\load\world-loader.h" />\r
<ClInclude Include="..\..\src\racial\racial-util.h" />\r
<ClInclude Include="..\..\src\monster-attack\monster-attack-switcher.h" />\r
<ClInclude Include="..\..\src\monster-attack\monster-attack-types.h" />\r
<ClInclude Include="..\..\src\combat\attack-accuracy.h" />\r
- <ClInclude Include="..\..\src\monster-attack\monster-attack-util.h" />\r
<ClInclude Include="..\..\src\monster-attack\monster-eating.h" />\r
<ClInclude Include="..\..\src\player-attack\player-attack-util.h" />\r
<ClInclude Include="..\..\src\player-attack\player-attack.h" />\r
<ClInclude Include="..\..\src\mind\mind-warrior.h" />\r
<ClInclude Include="..\..\src\racial\racial-vampire.h" />\r
<ClInclude Include="..\..\src\object-enchant\enchanter-base.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-armor.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-others.h" />\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-weapon.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-armor.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-others.h" />\r
+ <ClInclude Include="..\..\src\object-enchant\weapon\apply-magic-weapon.h" />\r
<ClInclude Include="..\..\src\object-enchant\apply-magic.h" />\r
<ClInclude Include="..\..\src\player\eldritch-horror.h" />\r
<ClInclude Include="..\..\src\realm\realm-types.h" />\r
<ClCompile Include="..\..\src\object-enchant\object-ego.cpp">\r
<Filter>object-enchant</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-weapon.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-armor.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-others.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\object-enchant\apply-magic.cpp">\r
<Filter>object-enchant</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\monster-attack\monster-attack-types.cpp">\r
<Filter>monster-attack</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\monster-attack\monster-attack-util.cpp">\r
- <Filter>monster-attack</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\monster-attack\monster-eating.cpp">\r
<Filter>monster-attack</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\view\display-scores.cpp">\r
<Filter>view</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-ring.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-amulet.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\system\object-type-definition.cpp">\r
<Filter>system</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\main-win\wav-reader.cpp">\r
<Filter>main-win</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\abstract-protector-enchanter.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-shield.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-cloak.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-helm.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-crown.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-boots.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\apply-magic-gloves.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\monster\monster-damage.cpp">\r
<Filter>monster</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\object-use\throw-execution.cpp">\r
<Filter>object-use</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\object-smith.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\smith-tables.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\player-info\race-info.cpp">\r
<Filter>player-info</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\player-base\player-class.cpp">\r
<Filter>player-base</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\object-enchant\smith-info.cpp">\r
- <Filter>object-enchant</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\src\timed-effect\timed-effects.cpp">\r
<Filter>timed-effect</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\load\old\load-v1-7-0.cpp">\r
<Filter>load\old</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\load\old\item-loader-savefile10.cpp">\r
+ <ClCompile Include="..\..\src\load\old\item-loader-savefile50.cpp">\r
<Filter>load\old</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\src\load\old\monster-loader-savefile10.cpp">\r
+ <ClCompile Include="..\..\src\load\old\monster-loader-savefile50.cpp">\r
<Filter>load\old</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\src\load\item\item-loader-base.cpp">\r
<ClCompile Include="..\..\src\load\monster\monster-loader-factory.cpp">\r
<Filter>load\monster</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\abstract-protector-enchanter.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-armor.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-boots.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-cloak.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-crown.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-gloves.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-helm.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\protector\apply-magic-shield.cpp">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\weapon\abstract-weapon-enchanter.cpp">\r
+ <Filter>object-enchant\weapon</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\weapon\apply-magic-weapon.cpp">\r
+ <Filter>object-enchant\weapon</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\smith\object-smith.cpp">\r
+ <Filter>smith</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\smith\smith-info.cpp">\r
+ <Filter>smith</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\smith\smith-tables.cpp">\r
+ <Filter>smith</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-amulet.cpp">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-ring.cpp">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\src\object-enchant\others\apply-magic-others.cpp">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\src\combat\shoot.h">\r
<ClInclude Include="..\..\src\object\tval-types.h">\r
<Filter>object</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-weapon.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-armor.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\object-enchant\enchanter-base.h">\r
<Filter>object-enchant</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-others.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\object-enchant\apply-magic.h">\r
<Filter>object-enchant</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\monster-attack\monster-attack-types.h">\r
<Filter>monster-attack</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\monster-attack\monster-attack-util.h">\r
- <Filter>monster-attack</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\monster-attack\monster-eating.h">\r
<Filter>monster-attack</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\view\display-scores.h">\r
<Filter>view</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-ring.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-amulet.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\dungeon\dungeon-flag-mask.h">\r
<Filter>dungeon</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\main-win\wav-reader.h">\r
<Filter>main-win</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\abstract-protector-enchanter.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-shield.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-cloak.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-helm.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-crown.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-boots.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\apply-magic-gloves.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\system\grid-type-definition.h">\r
<Filter>system</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\object-enchant\tr-flags.h">\r
<Filter>object-enchant</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\object-smith.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\smith-types.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\smith-tables.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\player-info\race-info.h">\r
<Filter>player-info</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\player-base\player-class.h">\r
<Filter>player-base</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\object-enchant\smith-info.h">\r
- <Filter>object-enchant</Filter>\r
- </ClInclude>\r
<ClInclude Include="..\..\src\timed-effect\timed-effects.h">\r
<Filter>timed-effect</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\load\old\load-v1-7-0.h">\r
<Filter>load\old</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\load\old\item-loader-savefile10.h">\r
+ <ClInclude Include="..\..\src\load\old\item-loader-savefile50.h">\r
<Filter>load\old</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\load\old\monster-loader-savefile10.h">\r
+ <ClInclude Include="..\..\src\load\old\monster-loader-savefile50.h">\r
<Filter>load\old</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\load\old\item-flag-types-savefile10.h">\r
+ <ClInclude Include="..\..\src\load\old\item-flag-types-savefile50.h">\r
<Filter>load\old</Filter>\r
</ClInclude>\r
- <ClInclude Include="..\..\src\load\old\monster-flag-types-savefile10.h">\r
+ <ClInclude Include="..\..\src\load\old\monster-flag-types-savefile50.h">\r
<Filter>load\old</Filter>\r
</ClInclude>\r
<ClInclude Include="..\..\src\load\item\item-loader-base.h">\r
<ClInclude Include="..\..\src\effect\attribute-types.h">\r
<Filter>effect</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\src\monster-race\race-behavior-flags.h">\r
+ <Filter>monster-race</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\abstract-weapon-enchanter.h">\r
+ <Filter>object-enchant</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\abstract-protector-enchanter.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-armor.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-boots.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-cloak.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-crown.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-gloves.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-helm.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\protector\apply-magic-shield.h">\r
+ <Filter>object-enchant\protector</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\weapon\abstract-weapon-enchanter.h">\r
+ <Filter>object-enchant\weapon</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\weapon\apply-magic-weapon.h">\r
+ <Filter>object-enchant\weapon</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\smith\object-smith.h">\r
+ <Filter>smith</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\smith\smith-info.h">\r
+ <Filter>smith</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\smith\smith-tables.h">\r
+ <Filter>smith</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\smith\smith-types.h">\r
+ <Filter>smith</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-amulet.h">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-ring.h">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\object-enchant\others\apply-magic-others.h">\r
+ <Filter>object-enchant\others</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\src\monster-race\race-visual-flags.h">\r
+ <Filter>monster-race</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="..\..\src\wall.bmp" />\r
<Filter Include="load\monster">\r
<UniqueIdentifier>{ad11aaea-5034-4df2-9a9b-d63457fdad55}</UniqueIdentifier>\r
</Filter>\r
+ <Filter Include="object-enchant\protector">\r
+ <UniqueIdentifier>{bec9d846-2241-4692-89bf-9ca8988347d8}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="object-enchant\weapon">\r
+ <UniqueIdentifier>{67ae112a-43ae-49a3-96ab-4f60c7c51931}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="smith">\r
+ <UniqueIdentifier>{a69deeae-ad91-4e9e-b811-25f6d4b49aec}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="object-enchant\others">\r
+ <UniqueIdentifier>{8e025e92-a617-4072-9c36-ba6fc3801284}</UniqueIdentifier>\r
+ </Filter>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="..\..\src\angband.rc" />\r
AC_ARG_ENABLE([xft],
AS_HELP_STRING([--enable-xft], [Enable xft support]))
AC_ARG_ENABLE(worldscore,
-[ --disable-worldscore disable worldscore support], worldscore=no, AC_DEFINE(WORLD_SCORE, 1, [Allow the game to send scores to the score server]))
+[ --disable-worldscore disable worldscore support], worldscore=no)
AC_ARG_ENABLE(chuukei,
[ --enable-chuukei enable internet chuukei support], AC_DEFINE(CHUUKEI, 1, [Chuukei mode]))
AC_ARG_ENABLE([pch],
AC_CHECK_LIB(iconv, iconv_open)
+dnl The world score server is currently only available in Japanese.
+if test "$use_japanese" = no; then
+ worldscore=no
+fi
if test "$worldscore" != no; then
PKG_CHECK_MODULES(libcurl, [libcurl])
+ AC_DEFINE(WORLD_SCORE, 1, [Allow the game to send scores to the score server])
fi
dnl Checks for header files.
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 3.0.0Alpha51
+PROJECT_NUMBER = 3.0.0Alpha52
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
E:Chaos vortex
G:v:v
I:140:32d20:100:80:0
-W:55:1:0:4000:0:0
+W:55:2:0:4000:0:0
F:ATTR_MULTI | ATTR_ANY |
F:PREVENT_SUDDEN_MAGIC | NEVER_BLOW |
F:RAND_50 | RAND_25 | CAN_FLY |
F:NO_CONF | NO_SLEEP | NO_STUN | QUANTUM | RAND_25
F:REGENERATE | SELF_DARK_1 | SELF_DARK_2
S:1_IN_5 | BR_NETH | BRAIN_SMASH | SCARE | S_UNDEAD | S_HI_UNDEAD
-S:DRAIN_MANA | HEAL | ANIM_DEAD
+S:DRAIN_MANA | HEAL | ANIM_DEAD | BO_ABYSS | BO_VOID | BR_ABYSS | BR_VOID | BA_VOID | BA_ABYSS
D:$A black hole in the fabric of reality.
D:$ It simply is not there.
D:現実という生地に空いた黒い穴。これは「無」だ。
D:$spells are lethal and his combat blows crushingly hard. He moves at
D:$speed, and commands legions of evil to do his bidding. It is said that he
D:$is fated never to die by the hand of mortal man.
-D:指輪の幽鬼の隊長であり、破壊的な力を持った恐るべき存在だ。その呪文は信じ難
-D:たい威力を持ち、戦闘に際しては全てのものを打ち砕くかのような攻撃力を誇る。
+D:指輪の幽鬼の隊長であり、破壊的な力を持った恐るべき存在だ。その呪文は信じ難い
+D:威力を持ち、戦闘に際しては全てのものを打ち砕くかのような攻撃力を誇る。
D:彼は素早く行動し、邪悪の者どもに命令を発して思い通りに操る。彼は死すべき人
D:間の男の手では決して葬り去ることができないといわれている。
B:BITE:HURT:3d4
F:BASH_DOOR | WILD_GRASS | ANIMAL | PASS_WALL
D:$This terrifying tiger used to escape nightly from the folding screen
-D:$ in a lord's mansion and eat people. So the lord asked a child priest
-D:$ to get rid of the tiger. The priest exorcised the tiger from the
-D:$ screen but did not catch it afterwards. Now it roams as it wills.
+D:$ in a lord's mansion and eat people.
+D:$ So the lord asked a child priest to get rid of the tiger.
+D:$ The priest exorcised the tiger from the
+D:$ screen but did not catch it afterwards.
+D:$ Now it roams as it wills.
+D:$ Now it is settled in the Angband and breeding.
D:この恐るべき虎は、さる殿様の屋敷に飾ってある屏風から毎晩抜け出しては
-D:人を食い殺している。
-D:そこで殿様は坊主に退治を依頼して屏風からこの虎を出したが、
-D:坊主は捕まえ損ねてそのまま逃げ出してしまった。
+D:人を食い殺していた。
+D:そこで殿様は坊主に退治を依頼して屏風からこの虎を出した。
+D:しかし坊主は捕まえ損ね、虎はそのまま逃げ出してしまった。
+D:それから幾星霜、この虎は鉄獄に居着いて繁殖している。
# In Japan, also, taxi in Edo era and bird cage have pronunciation, 'kago'
# Driver and painter have same pronunciation, 'kaki'
S:BO_PLAS
D:$It is a brain-like monster on a machine with four spider-like legs.
D:それは脳みそのような生き物で、蜘蛛のような脚を4つ持つ機械に乗っている。
+
+N:1351:ヴォイド・ボルテックス
+E:Void vortex
+G:v:v
+I:140:32d20:100:80:0
+W:55:2:0:4000:0:0
+F:ATTR_MULTI | ATTR_ANY |
+F:PREVENT_SUDDEN_MAGIC | NEVER_BLOW |
+F:RAND_50 | RAND_25 | CAN_FLY |
+F:EMPTY_MIND | BASH_DOOR | POWERFUL |
+F:RES_GRAV | RES_TELE | NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | NONLIVING
+S:1_IN_6 | BR_VOID
+V:150
+D:$It's a void whirlpool.
+D:空虚な渦巻きだ。
+
+N:1352:アビス・ボルテックス
+E:Abyss vortex
+G:v:v
+I:140:32d20:100:80:0
+W:55:2:0:4000:0:0
+F:ATTR_MULTI | ATTR_ANY |
+F:PREVENT_SUDDEN_MAGIC | NEVER_BLOW |
+F:RAND_50 | RAND_25 | CAN_FLY |
+F:EMPTY_MIND | BASH_DOOR | POWERFUL |
+F:HAS_DARK_1 | HAS_DARK_2 | RES_DARK | NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | NONLIVING
+S:1_IN_6 | BR_ABYSS
+V:150
+D:$It's a abyssal whirlpool.
+D:深淵の渦巻きだ。
+
load/monster/monster-loader-factory.cpp load/monster/monster-loader-factory.h \
load/monster/monster-loader-version-types.h \
\
- load/old/item-flag-types-savefile10.h \
- load/old/item-loader-savefile10.cpp load/old/item-loader-savefile10.h \
+ load/old/item-flag-types-savefile50.h \
+ load/old/item-loader-savefile50.cpp load/old/item-loader-savefile50.h \
load/old/load-v1-5-0.cpp load/old/load-v1-5-0.h \
load/old/load-v1-7-0.cpp load/old/load-v1-7-0.h \
- load/old/monster-flag-types-savefile10.h \
- load/old/monster-loader-savefile10.cpp load/old/monster-loader-savefile10.h \
+ load/old/monster-flag-types-savefile50.h \
+ load/old/monster-loader-savefile50.cpp load/old/monster-loader-savefile50.h \
\
locale/english.cpp locale/english.h \
locale/japanese.cpp locale/japanese.h \
monster-attack/monster-attack-status.cpp monster-attack/monster-attack-status.h \
monster-attack/monster-attack-switcher.cpp monster-attack/monster-attack-switcher.h \
monster-attack/monster-attack-types.cpp monster-attack/monster-attack-types.h \
- monster-attack/monster-attack-util.cpp monster-attack/monster-attack-util.h \
monster-attack/monster-eating.cpp monster-attack/monster-eating.h \
\
monster-floor/monster-death.cpp monster-floor/monster-death.h \
monster-race/monster-race-hook.cpp monster-race/monster-race-hook.h \
monster-race/race-ability-flags.h \
monster-race/race-ability-mask.cpp monster-race/race-ability-mask.h \
+ monster-race/race-behavior-flags.h \
monster-race/race-flags-resistance.h \
monster-race/race-flags1.h monster-race/race-flags2.h \
monster-race/race-flags3.h \
monster-race/race-flags7.h monster-race/race-flags8.h \
monster-race/race-flags9.h \
monster-race/race-indice-types.h \
+ monster-race/race-visual-flags.h \
\
mspell/assign-monster-spell.cpp mspell/assign-monster-spell.h \
mspell/element-resistance-checker.cpp mspell/element-resistance-checker.h \
object-activation/activation-teleport.cpp object-activation/activation-teleport.h \
object-activation/activation-util.cpp object-activation/activation-util.h \
\
- object-enchant/abstract-protector-enchanter.cpp object-enchant/abstract-protector-enchanter.h \
object-enchant/activation-info-table.cpp object-enchant/activation-info-table.h \
object-enchant/apply-magic.cpp object-enchant/apply-magic.h \
- object-enchant/apply-magic-amulet.cpp object-enchant/apply-magic-amulet.h \
- object-enchant/apply-magic-armor.cpp object-enchant/apply-magic-armor.h \
- object-enchant/apply-magic-boots.cpp object-enchant/apply-magic-boots.h \
- object-enchant/apply-magic-cloak.cpp object-enchant/apply-magic-cloak.h \
- object-enchant/apply-magic-crown.cpp object-enchant/apply-magic-crown.h \
- object-enchant/apply-magic-gloves.cpp object-enchant/apply-magic-gloves.h \
- object-enchant/apply-magic-helm.cpp object-enchant/apply-magic-helm.h \
- object-enchant/apply-magic-others.cpp object-enchant/apply-magic-others.h \
- object-enchant/apply-magic-ring.cpp object-enchant/apply-magic-ring.h \
- object-enchant/apply-magic-shield.cpp object-enchant/apply-magic-shield.h \
- object-enchant/apply-magic-weapon.cpp object-enchant/apply-magic-weapon.h \
object-enchant/dragon-breaths-table.cpp object-enchant/dragon-breaths-table.h \
object-enchant/enchanter-base.h \
object-enchant/object-boost.cpp object-enchant/object-boost.h \
object-enchant/object-curse.cpp object-enchant/object-curse.h \
object-enchant/object-ego.cpp object-enchant/object-ego.h \
- object-enchant/object-smith.cpp object-enchant/object-smith.h \
object-enchant/item-apply-magic.h object-enchant/item-feeling.h \
object-enchant/old-ego-extra-values.h object-enchant/special-object-flags.h \
- object-enchant/smith-info.cpp object-enchant/smith-info.h \
- object-enchant/smith-tables.cpp object-enchant/smith-tables.h \
- object-enchant/smith-types.h \
object-enchant/tr-flags.h \
object-enchant/tr-types.h object-enchant/trc-types.h \
object-enchant/trg-types.h \
object-enchant/vorpal-weapon.cpp object-enchant/vorpal-weapon.h \
\
+ object-enchant/others/apply-magic-amulet.cpp object-enchant/others/apply-magic-amulet.h \
+ object-enchant/others/apply-magic-ring.cpp object-enchant/others/apply-magic-ring.h \
+ object-enchant/others/apply-magic-others.cpp object-enchant/others/apply-magic-others.h \
+ \
+ object-enchant/protector/abstract-protector-enchanter.cpp object-enchant/protector/abstract-protector-enchanter.h \
+ object-enchant/protector/apply-magic-armor.cpp object-enchant/protector/apply-magic-armor.h \
+ object-enchant/protector/apply-magic-boots.cpp object-enchant/protector/apply-magic-boots.h \
+ object-enchant/protector/apply-magic-cloak.cpp object-enchant/protector/apply-magic-cloak.h \
+ object-enchant/protector/apply-magic-crown.cpp object-enchant/protector/apply-magic-crown.h \
+ object-enchant/protector/apply-magic-gloves.cpp object-enchant/protector/apply-magic-gloves.h \
+ object-enchant/protector/apply-magic-helm.cpp object-enchant/protector/apply-magic-helm.h \
+ object-enchant/protector/apply-magic-shield.cpp object-enchant/protector/apply-magic-shield.h \
+ \
+ object-enchant/weapon/abstract-weapon-enchanter.cpp object-enchant/weapon/abstract-weapon-enchanter.h \
+ object-enchant/weapon/apply-magic-weapon.cpp object-enchant/weapon/apply-magic-weapon.h \
+ \
object-hook/hook-armor.cpp object-hook/hook-armor.h \
object-hook/hook-expendable.cpp object-hook/hook-expendable.h \
object-hook/hook-magic.cpp object-hook/hook-magic.h \
player/patron.cpp player/patron.h \
player/process-death.cpp player/process-death.h \
player/process-name.cpp player/process-name.h \
- player/race-info-table.cpp player/race-info-table.h\
+ player/race-info-table.cpp player/race-info-table.h \
player/race-resistances.cpp player/race-resistances.h \
player/permanent-resistances.cpp player/permanent-resistances.h \
player/temporary-resistances.cpp player/temporary-resistances.h \
player-info/samurai-data-type.h \
player-info/self-info.cpp player-info/self-info.h \
player-info/self-info-util.cpp player-info/self-info-util.h \
- player-info/smith-data-type.h \
+ player-info/smith-data-type.h \
player-info/sniper-data-type.h \
- player-info/spell-hex-data-type.h \
+ player-info/spell-hex-data-type.h \
player-info/weapon-effect-info.cpp player-info/weapon-effect-info.h \
\
player-status/player-hand-types.h \
save/save.cpp save/save.h \
save/save-util.cpp save/save-util.h \
\
+ smith/object-smith.cpp smith/object-smith.h \
+ smith/smith-info.cpp smith/smith-info.h \
+ smith/smith-tables.cpp smith/smith-tables.h \
+ smith/smith-types.h \
+ \
specific-object/blade-turner.cpp specific-object/blade-turner.h \
specific-object/bloody-moon.cpp specific-object/bloody-moon.h \
specific-object/bow.cpp specific-object/bow.h \
monster_race *riding_r_ptr = &r_info[player_ptr->riding ? riding_m_ptr->r_idx : 0];
PlayerEnergy energy(player_ptr);
if (can_move && player_ptr->riding) {
- if (riding_r_ptr->flags1 & RF1_NEVER_MOVE) {
+ if (riding_r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE)) {
msg_print(_("動けない!", "Can't move!"));
energy.reset_player_turn();
can_move = false;
/* Allow moving */
} else if (f_ptr->flags.has(FloorFeatureType::CAN_SWIM) && (riding_r_ptr->flags7 & RF7_CAN_SWIM)) {
/* Allow moving */
- } else if (f_ptr->flags.has(FloorFeatureType::WATER) && !(riding_r_ptr->flags7 & RF7_AQUATIC)
- && (f_ptr->flags.has(FloorFeatureType::DEEP) || riding_r_ptr->aura_flags.has(MonsterAuraType::FIRE))) {
+ } else if (f_ptr->flags.has(FloorFeatureType::WATER) && !(riding_r_ptr->flags7 & RF7_AQUATIC) && (f_ptr->flags.has(FloorFeatureType::DEEP) || riding_r_ptr->aura_flags.has(MonsterAuraType::FIRE))) {
msg_format(_("%sの上に行けない。", "Can't swim."), f_info[g_ptr->get_feat_mimic()].name.c_str());
energy.reset_player_turn();
can_move = false;
#include "artifact/random-art-effects.h"
#include "object-enchant/activation-info-table.h"
#include "object-enchant/object-ego.h"
-#include "object-enchant/object-smith.h"
#include "object-enchant/tr-types.h"
#include "object/object-kind.h"
+#include "smith/object-smith.h"
#include "system/artifact-type-definition.h"
#include "system/object-type-definition.h"
#include "util/bit-flags-calculator.h"
* @param armour 防具かどうか
* @param power 生成パワー
* @return ファイル名
+ * @detail ss << tmp_grade; と直接呼ぶとC4866警告が出るので、別変数で受けて抑制中.
*/
static std::string get_random_art_filename(const bool armour, const int power)
{
const std::string_view prefix(armour ? "a_" : "w_");
constexpr std::string_view suffix(_("_j.txt", ".txt"));
- std::string_view grade;
+ std::string_view tmp_grade;
switch (power) {
case 0:
- grade = "cursed";
+ tmp_grade = "cursed";
break;
case 1:
- grade = "low";
+ tmp_grade = "low";
break;
case 2:
- grade = "med";
+ tmp_grade = "med";
break;
default:
- grade = "high";
+ tmp_grade = "high";
}
std::stringstream ss;
+ const auto &grade = tmp_grade;
ss << prefix << grade << suffix;
return ss.str();
}
#include "blue-magic/blue-magic-ball-bolt.h"
#include "blue-magic/blue-magic-util.h"
+#include "effect/attribute-types.h"
#include "monster-race/race-ability-flags.h"
#include "mspell/mspell-damage-calculator.h"
#include "spell-kind/spells-launcher.h"
-#include "effect/attribute-types.h"
#include "system/player-type-definition.h"
#include "target/target-getter.h"
#include "view/display-messages.h"
bool cast_blue_ball_acid(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_ACID, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_elec(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_ELEC, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_fire(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_FIRE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_cold(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_COLD, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_pois(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_POIS, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_nuke(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("放射能球を放った。", "You cast a ball of radiation."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_NUKE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_nether(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_NETH, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_chaos(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("純ログルスを放った。", "You invoke a raw Logrus."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_CHAO, bmc_ptr->plev, DAM_ROLL);
*/
bool cast_blue_ball_water(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("流れるような身振りをした。", "You gesture fluidly."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_WATE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_star_burst(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_LITE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_dark_storm(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_DARK, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_ball_mana_storm(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_MANA, bmc_ptr->plev, DAM_ROLL);
return true;
}
+bool cast_blue_ball_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
+ return false;
+ }
+
+ msg_print(_("虚無の嵐の呪文を念じた。", "You invoke a void storm."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_VOID, bmc_ptr->plev, DAM_ROLL);
+ fire_ball(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage, 4);
+ return true;
+}
+
+bool cast_blue_ball_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
+ return false;
+ }
+
+ msg_print(_("深淵の嵐の呪文を念じた。", "You invoke a abyss storm."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_ABYSS, bmc_ptr->plev, DAM_ROLL);
+ fire_ball(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage, 4);
+ return true;
+}
+
bool cast_blue_bolt_acid(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_ACID, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_elec(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_ELEC, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_fire(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_FIRE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_cold(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_COLD, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_nether(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_NETH, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_water(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_WATE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_mana(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_MANA, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_plasma(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_PLAS, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_icee(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_ICEE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_bolt_missile(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::MISSILE, bmc_ptr->plev, DAM_ROLL);
fire_bolt(player_ptr, AttributeType::MISSILE, bmc_ptr->dir, bmc_ptr->damage);
return true;
}
+
+bool cast_blue_bolt_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ return false;
+
+ msg_print(_("アビス・ボルトの呪文を唱えた。", "You cast a abyss bolt."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_ABYSS, bmc_ptr->plev, DAM_ROLL);
+ fire_bolt(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage);
+ return true;
+}
+
+bool cast_blue_bolt_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ return false;
+
+ msg_print(_("ヴォイド・ボルトの呪文を唱えた。", "You cast a void bolt."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_VOID, bmc_ptr->plev, DAM_ROLL);
+ fire_bolt(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage);
+ return true;
+}
bool cast_blue_ball_star_burst(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_ball_dark_storm(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_ball_mana_storm(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_ball_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_ball_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_acid(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_elec(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_mana(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_plasma(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_icee(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_bolt_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_bolt_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_bolt_missile(PlayerType *player_ptr, bmc_type *bmc_ptr);
#include "blue-magic/blue-magic-breath.h"
#include "blue-magic/blue-magic-util.h"
+#include "effect/attribute-types.h"
#include "mind/mind-blue-mage.h"
#include "monster-race/race-ability-flags.h"
#include "mspell/mspell-damage-calculator.h"
#include "spell-kind/spells-launcher.h"
-#include "effect/attribute-types.h"
#include "system/player-type-definition.h"
#include "target/target-getter.h"
#include "view/display-messages.h"
bool cast_blue_breath_acid(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("酸のブレスを吐いた。", "You breathe acid."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_ACID, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_elec(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_ELEC, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_fire(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("火炎のブレスを吐いた。", "You breathe fire."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_FIRE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_cold(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("冷気のブレスを吐いた。", "You breathe frost."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_COLD, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_pois(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("ガスのブレスを吐いた。", "You breathe gas."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_POIS, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_nether(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("地獄のブレスを吐いた。", "You breathe nether."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_NETH, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_lite(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("閃光のブレスを吐いた。", "You breathe light."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_LITE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_dark(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_DARK, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_conf(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("混乱のブレスを吐いた。", "You breathe confusion."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_CONF, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_sound(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("轟音のブレスを吐いた。", "You breathe sound."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_SOUN, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_chaos(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("カオスのブレスを吐いた。", "You breathe chaos."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_CHAO, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_disenchant(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_DISE, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_nexus(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_NEXU, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_time(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("時間逆転のブレスを吐いた。", "You breathe time."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_TIME, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_inertia(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_INER, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_gravity(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("重力のブレスを吐いた。", "You breathe gravity."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_GRAV, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_shards(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("破片のブレスを吐いた。", "You breathe shards."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_SHAR, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_plasma(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_PLAS, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_force(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("フォースのブレスを吐いた。", "You breathe force."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_FORC, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_mana(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("魔力のブレスを吐いた。", "You breathe mana."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_MANA, bmc_ptr->plev, DAM_ROLL);
bool cast_blue_breath_nuke(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_NUKE, bmc_ptr->plev, DAM_ROLL);
*/
bool cast_blue_breath_disintegration(PlayerType *player_ptr, bmc_type *bmc_ptr)
{
- if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
return false;
+ }
msg_print(_("分解のブレスを吐いた。", "You breathe disintegration."));
bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_DISI, bmc_ptr->plev, DAM_ROLL);
fire_breath(player_ptr, AttributeType::DISINTEGRATE, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
return true;
}
+
+/*!
+ * @brief 虚無のブレスの青魔法
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param bmc_ptr 青魔法詠唱への参照ポインタ
+ */
+bool cast_blue_breath_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
+ return false;
+ }
+
+ msg_print(_("虚無のブレスを吐いた。", "You breathe void."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_VOID, bmc_ptr->plev, DAM_ROLL);
+ fire_breath(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
+ return true;
+}
+
+/*!
+ * @brief 深淵のブレスの青魔法
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param bmc_ptr 青魔法詠唱への参照ポインタ
+ */
+bool cast_blue_breath_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+ if (!get_aim_dir(player_ptr, &bmc_ptr->dir)) {
+ return false;
+ }
+
+ msg_print(_("深淵のブレスを吐いた。", "You breathe abyss."));
+ bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_ABYSS, bmc_ptr->plev, DAM_ROLL);
+ fire_breath(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
+ return true;
+}
bool cast_blue_breath_mana(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_breath_nuke(PlayerType *player_ptr, bmc_type *bmc_ptr);
bool cast_blue_breath_disintegration(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_breath_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_breath_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
return cast_blue_breath_nuke(player_ptr, bmc_ptr);
case MonsterAbilityType::BR_DISI:
return cast_blue_breath_disintegration(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BR_VOID:
+ return cast_blue_breath_void(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BR_ABYSS:
+ return cast_blue_breath_abyss(player_ptr, bmc_ptr);
case MonsterAbilityType::BA_ACID:
return cast_blue_ball_acid(player_ptr, bmc_ptr);
case MonsterAbilityType::BA_ELEC:
return cast_blue_ball_dark_storm(player_ptr, bmc_ptr);
case MonsterAbilityType::BA_MANA:
return cast_blue_ball_mana_storm(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BA_VOID:
+ return cast_blue_ball_void(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BA_ABYSS:
+ return cast_blue_ball_abyss(player_ptr, bmc_ptr);
case MonsterAbilityType::DRAIN_MANA:
return cast_blue_drain_mana(player_ptr, bmc_ptr);
case MonsterAbilityType::MIND_BLAST:
return cast_blue_bolt_plasma(player_ptr, bmc_ptr);
case MonsterAbilityType::BO_ICEE:
return cast_blue_bolt_icee(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BO_ABYSS:
+ return cast_blue_bolt_abyss(player_ptr, bmc_ptr);
+ case MonsterAbilityType::BO_VOID:
+ return cast_blue_bolt_void(player_ptr, bmc_ptr);
case MonsterAbilityType::MISSILE:
return cast_blue_bolt_missile(player_ptr, bmc_ptr);
case MonsterAbilityType::SCARE:
case MonsterAbilityType::BR_INER:
case MonsterAbilityType::BR_FORC:
case MonsterAbilityType::BR_DISI:
+ case MonsterAbilityType::BR_VOID:
+ case MonsterAbilityType::BR_ABYSS:
case MonsterAbilityType::BA_NUKE:
case MonsterAbilityType::BA_CHAO:
case MonsterAbilityType::BA_ACID:
case MonsterAbilityType::BA_POIS:
case MonsterAbilityType::BA_NETH:
case MonsterAbilityType::BA_WATE:
+ case MonsterAbilityType::BA_VOID:
+ case MonsterAbilityType::BA_ABYSS:
set_bluemage_damage(player_ptr, power, plev, KWD_DAM, p);
break;
case MonsterAbilityType::DRAIN_MANA:
case MonsterAbilityType::BO_WATE:
case MonsterAbilityType::BO_MANA:
case MonsterAbilityType::BO_PLAS:
+ case MonsterAbilityType::BO_ABYSS:
+ case MonsterAbilityType::BO_VOID:
case MonsterAbilityType::BO_ICEE:
case MonsterAbilityType::MISSILE:
set_bluemage_damage(player_ptr, power, plev, KWD_DAM, p);
const auto power_int = enum2i(power);
- if ((power_int > 2 && power_int < 41) || (power_int > 41 && power_int < 59) || (power == MonsterAbilityType::PSY_SPEAR))
+ if ((power_int > 2 && power_int < 41) || (power_int > 41 && power_int < 59) || (power == MonsterAbilityType::PSY_SPEAR) || (power == MonsterAbilityType::BO_VOID) || (power == MonsterAbilityType::BO_ABYSS) || (power == MonsterAbilityType::BA_VOID) || (power == MonsterAbilityType::BA_ABYSS) || (power == MonsterAbilityType::BR_VOID) || (power == MonsterAbilityType::BR_ABYSS)) {
sprintf(p, " %s%d", KWD_DAM, (int)dam);
- else {
+ } else {
switch (power) {
case MonsterAbilityType::DRAIN_MANA:
sprintf(p, " %sd%d+%d", KWD_HEAL, plev * 3, plev);
choice = always_show_list ? ESCAPE : 1;
while (!flag) {
- if (choice == ESCAPE)
+ if (choice == ESCAPE) {
choice = ' ';
- else if (!get_com(out_val, &choice, true))
+ } else if (!get_com(out_val, &choice, true)) {
break;
+ }
/* Request redraw */
if ((choice == ' ') || (choice == '*') || (choice == '?')) {
chance = spell.manefail;
/* Reduce failure rate by "effective" level adjustment */
- if (plev > spell.level)
+ if (plev > spell.level) {
chance -= 3 * (plev - spell.level);
+ }
/* Reduce failure rate by INT/WIS adjustment */
chance -= 3 * (adj_mag_stat[player_ptr->stat_index[spell.use_stat]] + adj_mag_stat[player_ptr->stat_index[A_DEX]] - 2) / 2;
- if (spell.manedam)
+ if (spell.manedam) {
chance = chance * (baigaesi ? mane.damage * 2 : mane.damage) / spell.manedam;
+ }
chance += player_ptr->to_m_chance;
ask = isupper(choice);
/* Lowercase */
- if (ask)
+ if (ask) {
choice = (char)tolower(choice);
+ }
/* Extract request */
i = (islower(choice) ? A2I(choice) : -1);
(void)strnfmt(tmp_val, 78, _("%sをまねますか?", "Use %s? "), spell.name);
/* Belay that order */
- if (!get_check(tmp_val))
+ if (!get_check(tmp_val)) {
continue;
+ }
}
/* Stop the loop */
flag = true;
}
- if (redraw)
+ if (redraw) {
screen_load();
+ }
player_ptr->window_flags |= (PW_SPELL);
handle_stuff(player_ptr);
/* Abort if needed */
- if (!flag)
+ if (!flag) {
return false;
+ }
/* Save the choice */
(*sn) = i;
BIT_FLAGS mode = (PM_ALLOW_GROUP | PM_FORCE_PET);
BIT_FLAGS u_mode = 0L;
- if (randint1(50 + plev) < plev / 10)
+ if (randint1(50 + plev) < plev / 10) {
u_mode = PM_ALLOW_UNIQUE;
+ }
/* spell code */
switch (spell) {
case MonsterAbilityType::DISPEL: {
MONSTER_IDX m_idx;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
m_idx = player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
- if (!m_idx)
+ if (!m_idx) {
break;
- if (!player_has_los_bold(player_ptr, target_row, target_col))
+ }
+ if (!player_has_los_bold(player_ptr, target_row, target_col)) {
break;
- if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col))
+ }
+ if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col)) {
break;
+ }
dispel_monster_status(player_ptr, m_idx);
break;
}
case MonsterAbilityType::ROCKET:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("ロケットを発射した。", "You fire a rocket."));
+ }
fire_rocket(player_ptr, AttributeType::ROCKET, dir, damage, 2);
break;
case MonsterAbilityType::SHOOT:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("矢を放った。", "You fire an arrow."));
+ }
fire_bolt(player_ptr, AttributeType::MONSTER_SHOOT, dir, damage);
break;
break;
case MonsterAbilityType::BR_ACID:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("酸のブレスを吐いた。", "You breathe acid."));
+ }
fire_breath(player_ptr, AttributeType::ACID, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_ELEC:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning."));
+ }
fire_breath(player_ptr, AttributeType::ELEC, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_FIRE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("火炎のブレスを吐いた。", "You breathe fire."));
+ }
fire_breath(player_ptr, AttributeType::FIRE, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_COLD:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("冷気のブレスを吐いた。", "You breathe frost."));
+ }
fire_breath(player_ptr, AttributeType::COLD, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_POIS:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("ガスのブレスを吐いた。", "You breathe gas."));
+ }
fire_breath(player_ptr, AttributeType::POIS, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_NETH:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("地獄のブレスを吐いた。", "You breathe nether."));
+ }
fire_breath(player_ptr, AttributeType::NETHER, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_LITE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("閃光のブレスを吐いた。", "You breathe light."));
+ }
fire_breath(player_ptr, AttributeType::LITE, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_DARK:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness."));
+ }
fire_breath(player_ptr, AttributeType::DARK, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_CONF:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("混乱のブレスを吐いた。", "You breathe confusion."));
+ }
fire_breath(player_ptr, AttributeType::CONFUSION, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_SOUN:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("轟音のブレスを吐いた。", "You breathe sound."));
+ }
fire_breath(player_ptr, AttributeType::SOUND, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_CHAO:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("カオスのブレスを吐いた。", "You breathe chaos."));
+ }
fire_breath(player_ptr, AttributeType::CHAOS, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_DISE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment."));
+ }
fire_breath(player_ptr, AttributeType::DISENCHANT, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_NEXU:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus."));
+ }
fire_breath(player_ptr, AttributeType::NEXUS, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_TIME:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("時間逆転のブレスを吐いた。", "You breathe time."));
+ }
fire_breath(player_ptr, AttributeType::TIME, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_INER:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia."));
+ }
fire_breath(player_ptr, AttributeType::INERTIAL, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_GRAV:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("重力のブレスを吐いた。", "You breathe gravity."));
+ }
fire_breath(player_ptr, AttributeType::GRAVITY, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_SHAR:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("破片のブレスを吐いた。", "You breathe shards."));
+ }
fire_breath(player_ptr, AttributeType::SHARDS, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_PLAS:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma."));
-
+ }
fire_breath(player_ptr, AttributeType::PLASMA, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_FORC:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("フォースのブレスを吐いた。", "You breathe force."));
-
+ }
fire_breath(player_ptr, AttributeType::FORCE, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BR_MANA:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("魔力のブレスを吐いた。", "You breathe mana."));
-
+ }
fire_breath(player_ptr, AttributeType::MANA, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BA_NUKE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("放射能球を放った。", "You cast a ball of radiation."));
-
+ }
fire_ball(player_ptr, AttributeType::NUKE, dir, damage, 2);
break;
case MonsterAbilityType::BR_NUKE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste."));
+ }
fire_breath(player_ptr, AttributeType::NUKE, dir, damage, (plev > 35 ? 3 : 2));
break;
case MonsterAbilityType::BA_CHAO:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("純ログルスを放った。", "You invoke a raw Logrus."));
+ }
fire_ball(player_ptr, AttributeType::CHAOS, dir, damage, 4);
break;
case MonsterAbilityType::BR_DISI:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("分解のブレスを吐いた。", "You breathe disintegration."));
+ }
fire_breath(player_ptr, AttributeType::DISINTEGRATE, dir, damage, (plev > 35 ? 3 : 2));
break;
+ case MonsterAbilityType::BR_VOID:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("虚無のブレスを吐いた。", "You breathe void."));
+ }
+
+ fire_breath(player_ptr, AttributeType::VOID_MAGIC, dir, damage, (plev > 35 ? 3 : 2));
+ break;
+
+ case MonsterAbilityType::BR_ABYSS:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("深淵のブレスを吐いた。", "You breathe abyss."));
+ }
+
+ fire_breath(player_ptr, AttributeType::ABYSS, dir, damage, (plev > 35 ? 3 : 2));
+ break;
+
case MonsterAbilityType::BA_ACID:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball."));
+ }
fire_ball(player_ptr, AttributeType::ACID, dir, damage, 2);
break;
case MonsterAbilityType::BA_ELEC:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball."));
+ }
fire_ball(player_ptr, AttributeType::ELEC, dir, damage, 2);
break;
case MonsterAbilityType::BA_FIRE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball."));
+ }
fire_ball(player_ptr, AttributeType::FIRE, dir, damage, 2);
break;
case MonsterAbilityType::BA_COLD:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball."));
+ }
fire_ball(player_ptr, AttributeType::COLD, dir, damage, 2);
break;
case MonsterAbilityType::BA_POIS:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud."));
+ }
fire_ball(player_ptr, AttributeType::POIS, dir, damage, 2);
break;
case MonsterAbilityType::BA_NETH:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball."));
+ }
fire_ball(player_ptr, AttributeType::NETHER, dir, damage, 2);
break;
case MonsterAbilityType::BA_WATE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("流れるような身振りをした。", "You gesture fluidly."));
+ }
fire_ball(player_ptr, AttributeType::WATER, dir, damage, 4);
break;
case MonsterAbilityType::BA_MANA:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm."));
+ }
fire_ball(player_ptr, AttributeType::MANA, dir, damage, 4);
break;
case MonsterAbilityType::BA_DARK:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm."));
+ }
fire_ball(player_ptr, AttributeType::DARK, dir, damage, 4);
break;
+ case MonsterAbilityType::BA_VOID:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("虚無の嵐の呪文を念じた。", "You cast a void ball."));
+ }
+
+ fire_ball(player_ptr, AttributeType::VOID_MAGIC, dir, damage, 4);
+ break;
+ case MonsterAbilityType::BA_ABYSS:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("深淵の嵐の呪文を念じた。", "You cast a abyss ball."));
+ }
+
+ fire_ball(player_ptr, AttributeType::ABYSS, dir, damage, 4);
+ break;
case MonsterAbilityType::DRAIN_MANA:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::DRAIN_MANA, dir, randint1(plev * 3) + plev, 0);
break;
case MonsterAbilityType::MIND_BLAST:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::MIND_BLAST, dir, damage, 0);
break;
case MonsterAbilityType::BRAIN_SMASH:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::BRAIN_SMASH, dir, damage, 0);
break;
case MonsterAbilityType::CAUSE_1:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::CAUSE_1, dir, damage, 0);
break;
case MonsterAbilityType::CAUSE_2:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::CAUSE_2, dir, damage, 0);
break;
case MonsterAbilityType::CAUSE_3:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::CAUSE_3, dir, damage, 0);
break;
case MonsterAbilityType::CAUSE_4:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
fire_ball_hide(player_ptr, AttributeType::CAUSE_4, dir, damage, 0);
break;
case MonsterAbilityType::BO_ACID:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt."));
+ }
fire_bolt(player_ptr, AttributeType::ACID, dir, damage);
break;
case MonsterAbilityType::BO_ELEC:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt."));
+ }
fire_bolt(player_ptr, AttributeType::ELEC, dir, damage);
break;
case MonsterAbilityType::BO_FIRE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt."));
+ }
fire_bolt(player_ptr, AttributeType::FIRE, dir, damage);
break;
case MonsterAbilityType::BO_COLD:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt."));
+ }
fire_bolt(player_ptr, AttributeType::COLD, dir, damage);
break;
case MonsterAbilityType::BA_LITE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst."));
+ }
fire_ball(player_ptr, AttributeType::LITE, dir, damage, 4);
break;
case MonsterAbilityType::BO_NETH:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt."));
+ }
fire_bolt(player_ptr, AttributeType::NETHER, dir, damage);
break;
case MonsterAbilityType::BO_WATE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt."));
+ }
fire_bolt(player_ptr, AttributeType::WATER, dir, damage);
break;
case MonsterAbilityType::BO_MANA:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt."));
+ }
fire_bolt(player_ptr, AttributeType::MANA, dir, damage);
break;
case MonsterAbilityType::BO_PLAS:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt."));
+ }
fire_bolt(player_ptr, AttributeType::PLASMA, dir, damage);
break;
case MonsterAbilityType::BO_ICEE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt."));
+ }
fire_bolt(player_ptr, AttributeType::ICE, dir, damage);
break;
+ case MonsterAbilityType::BO_VOID:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("虚無の矢の呪文を唱えた。", "You cast a void bolt."));
+ }
+
+ fire_bolt(player_ptr, AttributeType::VOID_MAGIC, dir, damage);
+ break;
+ case MonsterAbilityType::BO_ABYSS:
+ if (!get_aim_dir(player_ptr, &dir)) {
+ return false;
+ } else {
+ msg_print(_("深淵の矢の呪文を唱えた。", "You cast a abyss bolt."));
+ }
+
+ fire_bolt(player_ptr, AttributeType::ABYSS, dir, damage);
+ break;
case MonsterAbilityType::MISSILE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile."));
+ }
fire_bolt(player_ptr, AttributeType::MISSILE, dir, damage);
break;
case MonsterAbilityType::SCARE:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("恐ろしげな幻覚を作り出した。", "You cast a fearful illusion."));
+ }
fear_monster(player_ptr, dir, plev + 10);
break;
case MonsterAbilityType::BLIND:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
confuse_monster(player_ptr, dir, plev * 2);
break;
case MonsterAbilityType::CONF:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("誘惑的な幻覚をつくり出した。", "You cast a mesmerizing illusion."));
+ }
confuse_monster(player_ptr, dir, plev * 2);
break;
case MonsterAbilityType::SLOW:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
slow_monster(player_ptr, dir, plev);
break;
case MonsterAbilityType::HOLD:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
sleep_monster(player_ptr, dir, plev);
break;
case MonsterAbilityType::HASTE:
(void)set_fast(player_ptr, randint1(20 + plev) + plev, false);
break;
case MonsterAbilityType::HAND_DOOM: {
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("<破滅の手>を放った!", "You invoke the Hand of Doom!"));
+ }
fire_ball_hide(player_ptr, AttributeType::HAND_DOOM, dir, 200, 0);
break;
monster_race *r_ptr;
GAME_TEXT m_name[MAX_NLEN];
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
- if (!player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx)
+ }
+ if (!player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx) {
break;
- if (!player_has_los_bold(player_ptr, target_row, target_col))
+ }
+ if (!player_has_los_bold(player_ptr, target_row, target_col)) {
break;
- if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col))
+ }
+ if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col)) {
break;
+ }
m_ptr = &player_ptr->current_floor_ptr->m_list[player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx];
r_ptr = &r_info[m_ptr->r_idx];
monster_desc(player_ptr, m_name, m_ptr, 0);
if (r_ptr->flagsr & RFR_RES_TELE) {
if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) {
- if (is_original_ap_and_seen(player_ptr, m_ptr))
+ if (is_original_ap_and_seen(player_ptr, m_ptr)) {
r_ptr->r_flagsr |= RFR_RES_TELE;
+ }
msg_format(_("%sには効果がなかった!", "%s is unaffected!"), m_name);
break;
} else if (r_ptr->level > randint1(100)) {
- if (is_original_ap_and_seen(player_ptr, m_ptr))
+ if (is_original_ap_and_seen(player_ptr, m_ptr)) {
r_ptr->r_flagsr |= RFR_RES_TELE;
+ }
msg_format(_("%sには耐性がある!", "%s resists!"), m_name);
break;
break;
}
case MonsterAbilityType::TELE_AWAY:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
+ }
(void)fire_beam(player_ptr, AttributeType::AWAY_ALL, dir, plev);
break;
break;
case MonsterAbilityType::PSY_SPEAR:
- if (!get_aim_dir(player_ptr, &dir))
+ if (!get_aim_dir(player_ptr, &dir)) {
return false;
- else
+ } else {
msg_print(_("光の剣を放った。", "You throw a psycho-spear."));
+ }
(void)fire_beam(player_ptr, AttributeType::PSY_SPEAR, dir, damage);
break;
break;
case MonsterAbilityType::TRAPS:
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("呪文を唱えて邪悪に微笑んだ。", "You cast a spell and cackle evilly."));
trap_creation(player_ptr, target_row, target_col);
break;
break;
case MonsterAbilityType::S_KIN: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("援軍を召喚した。", "You summon minions."));
for (k = 0; k < 4; k++) {
case MonsterAbilityType::S_CYBER: {
int k;
int max_cyber = (player_ptr->current_floor_ptr->dun_level / 50) + randint1(3);
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("サイバーデーモンを召喚した!", "You summon Cyberdemons!"));
- if (max_cyber > 4)
+ if (max_cyber > 4) {
max_cyber = 4;
- for (k = 0; k < max_cyber; k++)
+ }
+ for (k = 0; k < max_cyber; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_CYBER, mode);
+ }
break;
}
case MonsterAbilityType::S_MONSTER: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("仲間を召喚した。", "You summon help."));
- for (k = 0; k < 1; k++)
+ for (k = 0; k < 1; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_NONE, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_MONSTERS: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("モンスターを召喚した!", "You summon monsters!"));
- for (k = 0; k < 6; k++)
+ for (k = 0; k < 6; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_NONE, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_ANT: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("アリを召喚した。", "You summon ants."));
- for (k = 0; k < 6; k++)
+ for (k = 0; k < 6; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_ANT, mode);
+ }
break;
}
case MonsterAbilityType::S_SPIDER: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("蜘蛛を召喚した。", "You summon spiders."));
- for (k = 0; k < 6; k++)
+ for (k = 0; k < 6; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_SPIDER, mode);
+ }
break;
}
case MonsterAbilityType::S_HOUND: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("ハウンドを召喚した。", "You summon hounds."));
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 4; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HOUND, mode);
+ }
break;
}
case MonsterAbilityType::S_HYDRA: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("ヒドラを召喚した。", "You summon hydras."));
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 4; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HYDRA, mode);
+ }
break;
}
case MonsterAbilityType::S_ANGEL: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("天使を召喚した!", "You summon an angel!"));
- for (k = 0; k < 1; k++)
+ for (k = 0; k < 1; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_ANGEL, mode);
+ }
break;
}
case MonsterAbilityType::S_DEMON: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("混沌の宮廷から悪魔を召喚した!", "You summon a demon from the Courts of Chaos!"));
- for (k = 0; k < 1; k++)
+ for (k = 0; k < 1; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_DEMON, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_UNDEAD: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("アンデッドの強敵を召喚した!", "You summon an undead adversary!"));
- for (k = 0; k < 1; k++)
+ for (k = 0; k < 1; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_UNDEAD, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_DRAGON: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("ドラゴンを召喚した!", "You summon a dragon!"));
- for (k = 0; k < 1; k++)
+ for (k = 0; k < 1; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_DRAGON, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_HI_UNDEAD: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("強力なアンデッドを召喚した!", "You summon greater undead!"));
- for (k = 0; k < 6; k++)
+ for (k = 0; k < 6; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_HI_DRAGON: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("古代ドラゴンを召喚した!", "You summon ancient dragons!"));
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 4; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_DRAGON, (mode | u_mode));
+ }
break;
}
case MonsterAbilityType::S_AMBERITES: {
int k;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("アンバーの王族を召喚した!", "You summon Lords of Amber!"));
- for (k = 0; k < 4; k++)
+ for (k = 0; k < 4; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_AMBERITES, (mode | PM_ALLOW_UNIQUE));
+ }
break;
}
case MonsterAbilityType::S_UNIQUE: {
int k, count = 0;
- if (!target_set(player_ptr, TARGET_KILL))
+ if (!target_set(player_ptr, TARGET_KILL)) {
return false;
+ }
msg_print(_("特別な強敵を召喚した!", "You summon special opponents!"));
- for (k = 0; k < 4; k++)
- if (summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE)))
+ for (k = 0; k < 4; k++) {
+ if (summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE))) {
count++;
- for (k = count; k < 4; k++)
+ }
+ }
+ for (k = count; k < 4; k++) {
summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
+ }
break;
}
default:
monster_power spell;
bool cast;
- if (cmd_limit_confused(player_ptr))
+ if (cmd_limit_confused(player_ptr)) {
return false;
+ }
auto mane_data = PlayerClass(player_ptr).get_specific_data<mane_data_type>();
return false;
}
- if (!get_mane_power(player_ptr, &n, baigaesi))
+ if (!get_mane_power(player_ptr, &n, baigaesi)) {
return false;
+ }
spell = monster_powers.at(mane_data->mane_list[n].spell);
chance = spell.manefail;
/* Reduce failure rate by "effective" level adjustment */
- if (plev > spell.level)
+ if (plev > spell.level) {
chance -= 3 * (plev - spell.level);
+ }
/* Reduce failure rate by 1 stat and DEX adjustment */
chance -= 3 * (adj_mag_stat[player_ptr->stat_index[spell.use_stat]] + adj_mag_stat[player_ptr->stat_index[A_DEX]] - 2) / 2;
- if (spell.manedam)
+ if (spell.manedam) {
chance = chance * damage / spell.manedam;
+ }
chance += player_ptr->to_m_chance;
minfail = adj_mag_fail[player_ptr->stat_index[spell.use_stat]];
/* Minimum failure rate */
- if (chance < minfail)
+ if (chance < minfail) {
chance = minfail;
+ }
auto player_stun = player_ptr->effects()->stun();
chance += player_stun->get_magic_chance_penalty();
/* Failed spell */
if (randint0(100) < chance) {
- if (flush_failure)
+ if (flush_failure) {
flush();
+ }
msg_print(_("ものまねに失敗した!", "You failed to concentrate hard enough!"));
sound(SOUND_FAIL);
} else {
sound(SOUND_ZAP);
cast = use_mane(player_ptr, mane_data->mane_list[n].spell);
- if (!cast)
+ if (!cast) {
return false;
+ }
}
mane_data->mane_list.erase(std::next(mane_data->mane_list.begin(), n));
#include "effect/effect-processor.h"
#include "grid/grid.h"
#include "inventory/inventory-slot-types.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags-resistance.h"
#include "monster-race/race-flags3.h"
#include "system/player-type-definition.h"
#include "view/display-messages.h"
-static void aura_fire_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_fire_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!has_sh_fire(player_ptr) || !monap_ptr->alive || player_ptr->is_dead)
return;
}
}
-static void aura_elec_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_elec_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!has_sh_elec(player_ptr) || !monap_ptr->alive || player_ptr->is_dead)
return;
}
}
-static void aura_cold_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_cold_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!has_sh_cold(player_ptr) || !monap_ptr->alive || player_ptr->is_dead)
return;
}
}
-static void aura_shards_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_shards_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!player_ptr->dustrobe || !monap_ptr->alive || player_ptr->is_dead)
return;
teleport_player(player_ptr, 10, TELEPORT_SPONTANEOUS);
}
-static void aura_holy_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_holy_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!player_ptr->tim_sh_holy || !monap_ptr->alive || player_ptr->is_dead)
return;
r_ptr->r_flags3 |= RF3_EVIL;
}
-static void aura_force_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_force_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!player_ptr->tim_sh_touki || !monap_ptr->alive || player_ptr->is_dead)
return;
}
}
-static void aura_shadow_by_monster_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+static void aura_shadow_by_monster_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!SpellHex(player_ptr).is_spelling_specific(HEX_SHADOW_CLOAK) || !monap_ptr->alive || player_ptr->is_dead)
return;
}
}
-void process_aura_counterattack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_aura_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!monap_ptr->touched)
return;
#pragma once
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void process_aura_counterattack(PlayerType *player_ptr, monap_type *monap_ptr);
+void process_aura_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
#include "floor/floor-util.h"
#include "floor/geometry.h"
#include "floor/wild.h"
+#include "game-option/cheat-options.h"
#include "game-option/disturbance-options.h"
#include "game-option/map-screen-options.h"
-#include "game-option/cheat-options.h"
#include "grid/grid.h"
#include "inventory/pack-overflow.h"
#include "io/cursor.h"
get_mon_num_prep(player_ptr, monster_is_fishing_target, nullptr);
r_idx = get_mon_num(player_ptr, 0,
is_in_dungeon(player_ptr) ? player_ptr->current_floor_ptr->dun_level
- : wilderness[player_ptr->wilderness_y][player_ptr->wilderness_x].level,
+ : wilderness[player_ptr->wilderness_y][player_ptr->wilderness_x].level,
0);
msg_print(nullptr);
if (r_idx && one_in_(2)) {
if (!monster_is_valid(m_ptr))
continue;
- m_ptr->mflag2.set({MonsterConstantFlagType::MARK, MonsterConstantFlagType::SHOW});
+ m_ptr->mflag2.set({ MonsterConstantFlagType::MARK, MonsterConstantFlagType::SHOW });
update_monster(player_ptr, m_idx, false);
}
- WorldTurnProcessor(player_ptr).print_time();
+ WorldTurnProcessor(player_ptr).print_time();
} else if (!(load && player_ptr->energy_need <= 0)) {
player_ptr->energy_need -= SPEED_TO_ENERGY(player_ptr->pspeed);
}
auto effects = player_ptr->effects();
auto is_stunned = effects->stun()->is_stunned();
auto is_cut = effects->cut()->is_cut();
- if ((player_ptr->chp == player_ptr->mhp) && (player_ptr->csp >= player_ptr->msp) && !player_ptr->blind && !player_ptr->confused
- && !player_ptr->poisoned && !player_ptr->afraid && !is_stunned && !is_cut && !player_ptr->slow
- && !player_ptr->paralyzed && !player_ptr->hallucinated && !player_ptr->word_recall && !player_ptr->alter_reality) {
+ if ((player_ptr->chp == player_ptr->mhp) && (player_ptr->csp >= player_ptr->msp) && !player_ptr->blind && !player_ptr->confused && !player_ptr->poisoned && !player_ptr->afraid && !is_stunned && !is_cut && !player_ptr->slow && !player_ptr->paralyzed && !player_ptr->hallucinated && !player_ptr->word_recall && !player_ptr->alter_reality) {
set_action(player_ptr, ACTION_NONE);
}
}
r_ptr = &r_info[m_ptr->ap_r_idx];
// モンスターのシンボル/カラーの更新
- if (m_ptr->ml && any_bits(r_ptr->flags1, (RF1_ATTR_MULTI | RF1_SHAPECHANGER))) {
+ if (m_ptr->ml && r_ptr->visual_flags.has_any_of({ MonsterVisualType::MULTI_COLOR, MonsterVisualType::SHAPECHANGER })) {
lite_spot(player_ptr, m_ptr->fy, m_ptr->fx);
}
if (player_ptr->pclass == PlayerClassType::IMITATOR) {
auto mane_data = PlayerClass(player_ptr).get_specific_data<mane_data_type>();
- if (static_cast<int>(mane_data->mane_list.size()) > (player_ptr->lev > 44 ? 3 : player_ptr->lev > 29 ? 2 : 1)) {
+ if (static_cast<int>(mane_data->mane_list.size()) > (player_ptr->lev > 44 ? 3 : player_ptr->lev > 29 ? 2
+ : 1)) {
mane_data->mane_list.pop_front();
}
char buf[32];
/* Save the version */
- sprintf(the_score.what, "%u.%u.%u", FAKE_VER_MAJOR, FAKE_VER_MINOR, FAKE_VER_PATCH);
+ sprintf(the_score.what, "%u.%u.%u", H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH);
/* Calculate and save the points */
sprintf(the_score.pts, "%9ld", (long)calc_score(current_player_ptr));
}
/* Save the version */
- sprintf(the_score.what, "%u.%u.%u", FAKE_VER_MAJOR, FAKE_VER_MINOR, FAKE_VER_PATCH);
+ sprintf(the_score.what, "%u.%u.%u", H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH);
/* Calculate and save the points */
sprintf(the_score.pts, "%9ld", (long)calc_score(current_player_ptr));
continue;
}
- prt(format(_("[変愚蛮怒 %d.%d.%d, %s, %d/%d]", "[Hengband %d.%d.%d, %s, Line %d/%d]"), FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, caption,
+ prt(format(_("[変愚蛮怒 %d.%d.%d, %s, %d/%d]", "[Hengband %d.%d.%d, %s, Line %d/%d]"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH, caption,
line, size),
0, 0);
-#pragma once
+#pragma once
#include <string>
#include <vector>
#include "dungeon/dungeon-flag-types.h"
#include "monster-race/race-ability-flags.h"
+#include "monster-race/race-behavior-flags.h"
+#include "monster-race/race-visual-flags.h"
#include "system/angband.h"
#include "util/flag-group.h"
#define DUNGEON_FEAT_PROB_NUM 3
-#define DUNGEON_ANGBAND 1
-#define DUNGEON_GALGALS 2
-#define DUNGEON_ORC 3
-#define DUNGEON_MAZE 4
-#define DUNGEON_DRAGON 5
-#define DUNGEON_GRAVE 6
-#define DUNGEON_WOOD 7
-#define DUNGEON_VOLCANO 8
-#define DUNGEON_HELL 9
-#define DUNGEON_HEAVEN 10
-#define DUNGEON_OCEAN 11
-#define DUNGEON_CASTLE 12
-#define DUNGEON_CTH 13
+#define DUNGEON_ANGBAND 1
+#define DUNGEON_GALGALS 2
+#define DUNGEON_ORC 3
+#define DUNGEON_MAZE 4
+#define DUNGEON_DRAGON 5
+#define DUNGEON_GRAVE 6
+#define DUNGEON_WOOD 7
+#define DUNGEON_VOLCANO 8
+#define DUNGEON_HELL 9
+#define DUNGEON_HEAVEN 10
+#define DUNGEON_OCEAN 11
+#define DUNGEON_CASTLE 12
+#define DUNGEON_CTH 13
#define DUNGEON_MOUNTAIN 14
-#define DUNGEON_GOLD 15
+#define DUNGEON_GOLD 15
#define DUNGEON_NO_MAGIC 16
#define DUNGEON_NO_MELEE 17
#define DUNGEON_CHAMELEON 18
} feat_prob;
/* A structure for the != dungeon types */
-typedef struct dungeon_type {
+struct dungeon_type {
DUNGEON_IDX idx{};
std::string name; /* Name */
std::string text; /* Description */
- POSITION dy{};
- POSITION dx{};
-
- feat_prob floor[DUNGEON_FEAT_PROB_NUM]{}; /* Floor probability */
- feat_prob fill[DUNGEON_FEAT_PROB_NUM]{}; /* Cave wall probability */
- FEAT_IDX outer_wall{}; /* Outer wall tile */
- FEAT_IDX inner_wall{}; /* Inner wall tile */
- FEAT_IDX stream1{}; /* stream tile */
- FEAT_IDX stream2{}; /* stream tile */
-
- DEPTH mindepth{}; /* Minimal depth */
- DEPTH maxdepth{}; /* Maximal depth */
- PLAYER_LEVEL min_plev{}; /* Minimal plev needed to enter -- it's an anti-cheating mesure */
- BIT_FLAGS16 pit{};
- BIT_FLAGS16 nest{};
- BIT_FLAGS8 mode{}; /* Mode of combinaison of the monster flags */
-
- int min_m_alloc_level{}; /* Minimal number of monsters per level */
- int max_m_alloc_chance{}; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */
-
- EnumClassFlagGroup<DungeonFeatureType> flags{}; /* Dungeon Flags */
-
- BIT_FLAGS mflags1{}; /* The monster flags that are allowed */
- BIT_FLAGS mflags2{};
- BIT_FLAGS mflags3{};
- BIT_FLAGS mflags7{};
- BIT_FLAGS mflags8{};
- BIT_FLAGS mflags9{};
- BIT_FLAGS mflagsr{};
-
- EnumClassFlagGroup<MonsterAbilityType> m_ability_flags;
-
- char r_char[5]{}; /* Monster race allowed */
- KIND_OBJECT_IDX final_object{}; /* The object you'll find at the bottom */
- ARTIFACT_IDX final_artifact{}; /* The artifact you'll find at the bottom */
- MONRACE_IDX final_guardian{}; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */
-
- PROB special_div{}; /* % of monsters affected by the flags/races allowed, to add some variety */
- int tunnel_percent{};
- int obj_great{};
- int obj_good{};
-} dungeon_type;
+ POSITION dy{};
+ POSITION dx{};
+
+ feat_prob floor[DUNGEON_FEAT_PROB_NUM]{}; /* Floor probability */
+ feat_prob fill[DUNGEON_FEAT_PROB_NUM]{}; /* Cave wall probability */
+ FEAT_IDX outer_wall{}; /* Outer wall tile */
+ FEAT_IDX inner_wall{}; /* Inner wall tile */
+ FEAT_IDX stream1{}; /* stream tile */
+ FEAT_IDX stream2{}; /* stream tile */
+
+ DEPTH mindepth{}; /* Minimal depth */
+ DEPTH maxdepth{}; /* Maximal depth */
+ PLAYER_LEVEL min_plev{}; /* Minimal plev needed to enter -- it's an anti-cheating mesure */
+ BIT_FLAGS16 pit{};
+ BIT_FLAGS16 nest{};
+ BIT_FLAGS8 mode{}; /* Mode of combinaison of the monster flags */
+
+ int min_m_alloc_level{}; /* Minimal number of monsters per level */
+ int max_m_alloc_chance{}; /* There is a 1/max_m_alloc_chance chance per round of creating a new monster */
+
+ EnumClassFlagGroup<DungeonFeatureType> flags{}; /* Dungeon Flags */
+
+ BIT_FLAGS mflags1{}; /* The monster flags that are allowed */
+ BIT_FLAGS mflags2{};
+ BIT_FLAGS mflags3{};
+ BIT_FLAGS mflags7{};
+ BIT_FLAGS mflags8{};
+ BIT_FLAGS mflags9{};
+ BIT_FLAGS mflagsr{};
+
+ EnumClassFlagGroup<MonsterAbilityType> mon_ability_flags;
+ EnumClassFlagGroup<MonsterBehaviorType> mon_behavior_flags;
+ EnumClassFlagGroup<MonsterVisualType> mon_visual_flags;
+
+ char r_char[5]{}; /* Monster race allowed */
+ KIND_OBJECT_IDX final_object{}; /* The object you'll find at the bottom */
+ ARTIFACT_IDX final_artifact{}; /* The artifact you'll find at the bottom */
+ MONRACE_IDX final_guardian{}; /* The artifact's guardian. If an artifact is specified, then it's NEEDED */
+
+ PROB special_div{}; /* % of monsters affected by the flags/races allowed, to add some variety */
+ int tunnel_percent{};
+ int obj_great{};
+ int obj_good{};
+};
extern std::vector<DEPTH> max_dlv;
extern std::vector<dungeon_type> d_info;
continue;
if (r_ptr->rarity > 100)
continue;
- if (r_ptr->flags7 & RF7_FRIENDLY)
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY))
continue;
if (r_ptr->flags7 & RF7_AQUATIC)
continue;
if (quest[i].status != QuestStatusType::TAKEN)
continue;
- if ((quest[i].type == QuestKindType::KILL_LEVEL) && !(quest[i].flags & QUEST_FLAG_PRESET) && (quest[i].level == level)
- && (quest[i].dungeon == player_ptr->dungeon_idx))
+ if ((quest[i].type == QuestKindType::KILL_LEVEL) && !(quest[i].flags & QUEST_FLAG_PRESET) && (quest[i].level == level) && (quest[i].dungeon == player_ptr->dungeon_idx))
return i;
}
return 0;
for (QUEST_IDX i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++) {
- if ((quest[i].type == QuestKindType::RANDOM) && (quest[i].status == QuestStatusType::TAKEN) && (quest[i].level == level)
- && (quest[i].dungeon == DUNGEON_ANGBAND)) {
+ if ((quest[i].type == QuestKindType::RANDOM) && (quest[i].status == QuestStatusType::TAKEN) && (quest[i].level == level) && (quest[i].dungeon == DUNGEON_ANGBAND)) {
return i;
}
}
quest[QUEST_TOWER1].comptime = w_ptr->play_time;
}
-/*!
+/*!
* @brief Player enters a new quest
*/
void exe_enter_quest(PlayerType *player_ptr, QUEST_IDX quest_idx)
cave_set_feat(player_ptr, y, x, one_in_(3) ? feat_brake : feat_grass);
/* Observe */
- if (g_ptr->is_mark())
+ if (g_ptr->is_mark()) {
obvious = true;
+ }
}
}
}
}
- if (player_ptr->blind || !player_has_los_bold(player_ptr, y, x))
+ if (player_ptr->blind || !player_has_los_bold(player_ptr, y, x)) {
break;
+ }
g_ptr->info &= ~(CAVE_UNSAFE);
lite_spot(player_ptr, y, x);
cave_alter_feat(player_ptr, y, x, FloorFeatureType::TUNNEL);
}
- if (player_ptr->blind || !player_has_los_bold(player_ptr, y, x))
+ if (player_ptr->blind || !player_has_los_bold(player_ptr, y, x)) {
break;
+ }
g_ptr->info &= ~(CAVE_UNSAFE);
lite_spot(player_ptr, y, x);
break;
}
case AttributeType::JAM_DOOR: {
- if (f_ptr->flags.has_not(FloorFeatureType::SPIKE))
+ if (f_ptr->flags.has_not(FloorFeatureType::SPIKE)) {
break;
+ }
int16_t old_mimic = g_ptr->mimic;
feature_type *mimic_f_ptr = &f_info[g_ptr->get_feat_mimic()];
note_spot(player_ptr, y, x);
lite_spot(player_ptr, y, x);
- if (!known || mimic_f_ptr->flags.has_not(FloorFeatureType::OPEN))
+ if (!known || mimic_f_ptr->flags.has_not(FloorFeatureType::OPEN)) {
break;
+ }
msg_format(_("%sに何かがつっかえて開かなくなった。", "The %s seems stuck."), mimic_f_ptr->name.c_str());
obvious = true;
break;
}
case AttributeType::KILL_WALL: {
- if (f_ptr->flags.has_not(FloorFeatureType::HURT_ROCK))
+ if (f_ptr->flags.has_not(FloorFeatureType::HURT_ROCK)) {
break;
+ }
if (known && g_ptr->is_mark()) {
msg_format(_("%sが溶けて泥になった!", "The %s turns into mud!"), f_info[g_ptr->get_feat_mimic()].name.c_str());
break;
}
case AttributeType::MAKE_DOOR: {
- if (!cave_naked_bold(player_ptr, y, x))
+ if (!cave_naked_bold(player_ptr, y, x)) {
break;
- if (player_bold(player_ptr, y, x))
+ }
+ if (player_bold(player_ptr, y, x)) {
break;
+ }
cave_set_feat(player_ptr, y, x, feat_door[DOOR_DOOR].closed);
- if (g_ptr->is_mark())
+ if (g_ptr->is_mark()) {
obvious = true;
+ }
break;
}
case AttributeType::MAKE_TRAP: {
break;
}
case AttributeType::MAKE_TREE: {
- if (!cave_naked_bold(player_ptr, y, x))
+ if (!cave_naked_bold(player_ptr, y, x)) {
break;
- if (player_bold(player_ptr, y, x))
+ }
+ if (player_bold(player_ptr, y, x)) {
break;
+ }
cave_set_feat(player_ptr, y, x, feat_tree);
- if (g_ptr->is_mark())
+ if (g_ptr->is_mark()) {
obvious = true;
+ }
break;
}
case AttributeType::MAKE_RUNE_PROTECTION: {
- if (!cave_naked_bold(player_ptr, y, x))
+ if (!cave_naked_bold(player_ptr, y, x)) {
break;
+ }
g_ptr->info |= CAVE_OBJECT;
g_ptr->mimic = feat_rune_protection;
note_spot(player_ptr, y, x);
break;
}
case AttributeType::STONE_WALL: {
- if (!cave_naked_bold(player_ptr, y, x))
+ if (!cave_naked_bold(player_ptr, y, x)) {
break;
- if (player_bold(player_ptr, y, x))
+ }
+ if (player_bold(player_ptr, y, x)) {
break;
+ }
cave_set_feat(player_ptr, y, x, feat_granite);
break;
}
case AttributeType::LAVA_FLOW: {
- if (f_ptr->flags.has(FloorFeatureType::PERMANENT))
+ if (f_ptr->flags.has(FloorFeatureType::PERMANENT)) {
break;
+ }
if (dam == 1) {
- if (f_ptr->flags.has_not(FloorFeatureType::FLOOR))
+ if (f_ptr->flags.has_not(FloorFeatureType::FLOOR)) {
break;
+ }
cave_set_feat(player_ptr, y, x, feat_shallow_lava);
} else if (dam) {
cave_set_feat(player_ptr, y, x, feat_deep_lava);
break;
}
case AttributeType::WATER_FLOW: {
- if (f_ptr->flags.has(FloorFeatureType::PERMANENT))
+ if (f_ptr->flags.has(FloorFeatureType::PERMANENT)) {
break;
+ }
if (dam == 1) {
- if (f_ptr->flags.has_not(FloorFeatureType::FLOOR))
+ if (f_ptr->flags.has_not(FloorFeatureType::FLOOR)) {
break;
+ }
cave_set_feat(player_ptr, y, x, feat_shallow_water);
} else if (dam) {
cave_set_feat(player_ptr, y, x, feat_deep_water);
}
case AttributeType::LITE_WEAK:
case AttributeType::LITE: {
- if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::DARKNESS))
+ if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::DARKNESS)) {
break;
+ }
g_ptr->info |= (CAVE_GLOW);
note_spot(player_ptr, y, x);
lite_spot(player_ptr, y, x);
update_local_illumination(player_ptr, y, x);
- if (player_can_see_bold(player_ptr, y, x))
+ if (player_can_see_bold(player_ptr, y, x)) {
obvious = true;
- if (g_ptr->m_idx)
+ }
+ if (g_ptr->m_idx) {
update_monster(player_ptr, g_ptr->m_idx, false);
+ }
if (player_bold(player_ptr, y, x)) {
set_superstealth(player_ptr, false);
case AttributeType::DARK:
case AttributeType::ABYSS: {
bool do_dark = !player_ptr->phase_out && !g_ptr->is_mirror();
- if (!do_dark)
+ if (!do_dark) {
break;
+ }
if ((floor_ptr->dun_level > 0) || !is_daytime()) {
for (int j = 0; j < 9; j++) {
int by = y + ddy_ddd[j];
int bx = x + ddx_ddd[j];
- if (!in_bounds2(floor_ptr, by, bx))
+ if (!in_bounds2(floor_ptr, by, bx)) {
continue;
+ }
grid_type *cc_ptr = &floor_ptr->grid_array[by][bx];
if (f_info[cc_ptr->get_feat_mimic()].flags.has(FloorFeatureType::GLOW)) {
}
}
- if (!do_dark)
+ if (!do_dark) {
break;
+ }
}
g_ptr->info &= ~(CAVE_GLOW);
update_local_illumination(player_ptr, y, x);
- if (player_can_see_bold(player_ptr, y, x))
+ if (player_can_see_bold(player_ptr, y, x)) {
obvious = true;
- if (g_ptr->m_idx)
+ }
+ if (g_ptr->m_idx) {
update_monster(player_ptr, g_ptr->m_idx, false);
+ }
break;
}
(PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI));
}
- if (f_ptr->flags.has_not(FloorFeatureType::GLASS) || f_ptr->flags.has(FloorFeatureType::PERMANENT) || (dam < 50))
+ if (f_ptr->flags.has_not(FloorFeatureType::GLASS) || f_ptr->flags.has(FloorFeatureType::PERMANENT) || (dam < 50)) {
break;
+ }
if (known && (g_ptr->is_mark())) {
msg_format(_("%sが割れた!", "The %s crumbled!"), f_info[g_ptr->get_feat_mimic()].name.c_str());
(PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI));
}
- if (f_ptr->flags.has_not(FloorFeatureType::GLASS) || f_ptr->flags.has(FloorFeatureType::PERMANENT) || (dam < 200))
+ if (f_ptr->flags.has_not(FloorFeatureType::GLASS) || f_ptr->flags.has(FloorFeatureType::PERMANENT) || (dam < 200)) {
break;
+ }
if (known && (g_ptr->is_mark())) {
msg_format(_("%sが割れた!", "The %s crumbled!"), f_info[g_ptr->get_feat_mimic()].name.c_str());
break;
}
case AttributeType::DISINTEGRATE: {
- if (g_ptr->is_mirror() || g_ptr->is_rune_protection() || g_ptr->is_rune_explosion())
+ if (g_ptr->is_mirror() || g_ptr->is_rune_protection() || g_ptr->is_rune_explosion()) {
remove_mirror(player_ptr, y, x);
+ }
- if (f_ptr->flags.has_not(FloorFeatureType::HURT_DISI) || f_ptr->flags.has(FloorFeatureType::PERMANENT))
+ if (f_ptr->flags.has_not(FloorFeatureType::HURT_DISI) || f_ptr->flags.has(FloorFeatureType::PERMANENT)) {
break;
+ }
cave_alter_feat(player_ptr, y, x, FloorFeatureType::HURT_DISI);
player_ptr->update |= (PU_FLOW);
*/
static bool resisted_psi_because_weird_mind_or_powerful(effect_monster_type *em_ptr)
{
- bool has_resistance = any_bits(em_ptr->r_ptr->flags2, RF2_STUPID | RF2_WEIRD_MIND) || any_bits(em_ptr->r_ptr->flags3, RF3_ANIMAL)
- || (em_ptr->r_ptr->level > randint1(3 * em_ptr->dam));
+ bool has_resistance = em_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID) || any_bits(em_ptr->r_ptr->flags2, RF2_WEIRD_MIND) || any_bits(em_ptr->r_ptr->flags3, RF3_ANIMAL) || (em_ptr->r_ptr->level > randint1(3 * em_ptr->dam));
if (!has_resistance)
return false;
*/
process_result effect_monster_nothing(effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_acid(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_IM_ACID) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_IM_ACID) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_ACID);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_elec(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_IM_ELEC) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_IM_ELEC) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_ELEC);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_fire(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (em_ptr->r_ptr->flagsr & RFR_IM_FIRE) {
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_FIRE);
+ }
return PROCESS_CONTINUE;
}
- if ((em_ptr->r_ptr->flags3 & (RF3_HURT_FIRE)) == 0)
+ if ((em_ptr->r_ptr->flags3 & (RF3_HURT_FIRE)) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
em_ptr->dam *= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_HURT_FIRE);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_cold(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (em_ptr->r_ptr->flagsr & RFR_IM_COLD) {
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_COLD);
+ }
return PROCESS_CONTINUE;
}
- if ((em_ptr->r_ptr->flags3 & (RF3_HURT_COLD)) == 0)
+ if ((em_ptr->r_ptr->flags3 & (RF3_HURT_COLD)) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
em_ptr->dam *= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_HURT_COLD);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_pois(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_IM_POIS) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_IM_POIS) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_POIS);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_nuke(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (em_ptr->r_ptr->flagsr & RFR_IM_POIS) {
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_POIS);
+ }
return PROCESS_CONTINUE;
}
- if (one_in_(3))
+ if (one_in_(3)) {
em_ptr->do_polymorph = true;
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_hell_fire(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flags3 & RF3_GOOD) == 0)
+ if ((em_ptr->r_ptr->flags3 & RF3_GOOD) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
em_ptr->dam *= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= RF3_GOOD;
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_holy_fire(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (any_bits(em_ptr->r_ptr->flags3, RF3_GOOD)) {
em_ptr->note = _("には完全な耐性がある!", " is immune.");
em_ptr->dam = 0;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
set_bits(em_ptr->r_ptr->r_flags3, RF3_GOOD);
+ }
return PROCESS_CONTINUE;
}
if (any_bits(em_ptr->r_ptr->flags3, RF3_EVIL)) {
em_ptr->dam *= 2;
em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
set_bits(em_ptr->r_ptr->r_flags3, RF3_EVIL);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_plasma(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_PLAS) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_PLAS) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_PLAS);
+ }
return PROCESS_CONTINUE;
}
static bool effect_monster_nether_resist(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if ((em_ptr->r_ptr->flagsr & RFR_RES_NETH) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_NETH) == 0) {
return false;
+ }
if (em_ptr->r_ptr->flags3 & RF3_UNDEAD) {
em_ptr->note = _("には完全な耐性がある!", " is immune.");
em_ptr->dam = 0;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
+ }
} else {
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
}
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_NETH);
+ }
return true;
}
process_result effect_monster_nether(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if (effect_monster_nether_resist(player_ptr, em_ptr) || ((em_ptr->r_ptr->flags3 & RF3_EVIL) == 0))
+ if (effect_monster_nether_resist(player_ptr, em_ptr) || ((em_ptr->r_ptr->flags3 & RF3_EVIL) == 0)) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
em_ptr->dam /= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_EVIL);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_water(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_WATE) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_WATE) == 0) {
return PROCESS_CONTINUE;
+ }
if ((em_ptr->m_ptr->r_idx == MON_WATER_ELEM) || (em_ptr->m_ptr->r_idx == MON_UNMAKER)) {
em_ptr->note = _("には完全な耐性がある!", " is immune.");
em_ptr->dam /= randint1(6) + 6;
}
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_WATE);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_chaos(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (em_ptr->r_ptr->flagsr & RFR_RES_CHAO) {
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_CHAO);
+ }
} else if ((em_ptr->r_ptr->flags3 & RF3_DEMON) && one_in_(3)) {
em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_DEMON);
+ }
} else {
em_ptr->do_polymorph = true;
em_ptr->do_conf = (5 + randint1(11) + em_ptr->r) / (em_ptr->r + 1);
process_result effect_monster_shards(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_SHAR) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_SHAR) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_SHAR);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_rocket(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_SHAR) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_SHAR) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
em_ptr->dam /= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_SHAR);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_sound(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if ((em_ptr->r_ptr->flagsr & RFR_RES_SOUN) == 0) {
em_ptr->do_stun = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 2;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_SOUN);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_confusion(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if ((em_ptr->r_ptr->flags3 & RF3_NO_CONF) == 0) {
em_ptr->do_conf = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_NO_CONF);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_disenchant(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_DISE) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_DISE) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_DISE);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_nexus(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_NEXU) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_NEXU) == 0) {
return PROCESS_CONTINUE;
+ }
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_NEXU);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_force(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if ((em_ptr->r_ptr->flagsr & RFR_RES_WALL) == 0) {
em_ptr->do_stun = (randint1(15) + em_ptr->r) / (em_ptr->r + 1);
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_WALL);
+ }
return PROCESS_CONTINUE;
}
// Powerful monsters can resists and normal monsters slow down.
process_result effect_monster_inertial(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (em_ptr->r_ptr->flagsr & RFR_RES_INER) {
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_INER);
+ }
return PROCESS_CONTINUE;
}
return PROCESS_CONTINUE;
}
- if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50))
+ if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50)) {
em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_time(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if ((em_ptr->r_ptr->flagsr & RFR_RES_TIME) == 0) {
em_ptr->do_time = (em_ptr->dam + 1) / 2;
em_ptr->note = _("には耐性がある。", " resists.");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_TIME);
+ }
return PROCESS_CONTINUE;
}
static bool effect_monster_gravity_resist_teleport(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flagsr & RFR_RES_TELE) == 0)
+ if ((em_ptr->r_ptr->flagsr & RFR_RES_TELE) == 0) {
return false;
+ }
if (em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) {
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= RFR_RES_TELE;
+ }
em_ptr->note = _("には効果がなかった。", " is unaffected!");
return true;
}
- if (em_ptr->r_ptr->level <= randint1(100))
+ if (em_ptr->r_ptr->level <= randint1(100)) {
return false;
+ }
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= RFR_RES_TELE;
+ }
em_ptr->note = _("には耐性がある!", " resists!");
return true;
static void effect_monster_gravity_slow(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) || (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
+ if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) || (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10)) {
em_ptr->obvious = false;
+ }
- if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50))
+ if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50)) {
em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
+ }
}
static void effect_monster_gravity_stun(effect_monster_type *em_ptr)
process_result effect_monster_gravity(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
em_ptr->do_dist = effect_monster_gravity_resist_teleport(player_ptr, em_ptr) ? 0 : 10;
- if (player_ptr->riding && (em_ptr->g_ptr->m_idx == player_ptr->riding))
+ if (player_ptr->riding && (em_ptr->g_ptr->m_idx == player_ptr->riding)) {
em_ptr->do_dist = 0;
+ }
if (em_ptr->r_ptr->flagsr & RFR_RES_GRAV) {
em_ptr->note = _("には耐性がある!", " resists!");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
em_ptr->do_dist = 0;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_GRAV);
+ }
return PROCESS_CONTINUE;
}
process_result effect_monster_disintegration(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
- if ((em_ptr->r_ptr->flags3 & RF3_HURT_ROCK) == 0)
+ if ((em_ptr->r_ptr->flags3 & RF3_HURT_ROCK) == 0) {
return PROCESS_CONTINUE;
+ }
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_HURT_ROCK);
+ }
em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
em_ptr->note_dies = _("は蒸発した!", " evaporates!");
process_result effect_monster_icee_bolt(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
em_ptr->do_stun = (randint1(15) + 1) / (em_ptr->r + 1);
if (em_ptr->r_ptr->flagsr & RFR_IM_COLD) {
em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
em_ptr->dam /= 9;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_IM_COLD);
+ }
} else if (em_ptr->r_ptr->flags3 & (RF3_HURT_COLD)) {
em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
em_ptr->dam *= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flags3 |= (RF3_HURT_COLD);
+ }
}
return PROCESS_CONTINUE;
* @details
* 量子生物に倍打、壁抜けに1.5倍打、テレポート耐性が耐性
*/
-process_result effect_monster_void(PlayerType* player_ptr, effect_monster_type* em_ptr)
+process_result effect_monster_void(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
if (any_bits(em_ptr->r_ptr->flags2, RF2_QUANTUM)) {
em_ptr->note = _("の存在確率が減少した。", "'s wave function is reduced.");
em_ptr->note_dies = _("は観測されなくなった。", "'s wave function collapses.");
em_ptr->dam *= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
set_bits(em_ptr->r_ptr->r_flags2, RF2_QUANTUM);
+ }
} else if (any_bits(em_ptr->r_ptr->flags2, RF2_PASS_WALL)) {
em_ptr->note = _("の存在が薄れていく。", "is fading out.");
em_ptr->note_dies = _("は消えてしまった。", "has disappeared.");
em_ptr->dam *= 3;
em_ptr->dam /= 2;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
set_bits(em_ptr->r_ptr->r_flags2, RF2_PASS_WALL);
+ }
} else if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_TELE | RFR_RES_WALL | RFR_RES_GRAV)) {
em_ptr->note = _("には耐性がある!", " resists!");
em_ptr->dam *= 3;
em_ptr->dam /= randint1(6) + 6;
if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
- if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_TELE))
+ if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_TELE)) {
set_bits(em_ptr->r_ptr->r_flagsr, RFR_RES_TELE);
- if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_WALL))
+ }
+ if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_WALL)) {
set_bits(em_ptr->r_ptr->r_flagsr, RFR_RES_WALL);
- if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_GRAV))
+ }
+ if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_GRAV)) {
set_bits(em_ptr->r_ptr->r_flagsr, RFR_RES_GRAV);
+ }
}
- } else
+ } else {
em_ptr->note_dies = _("は消滅してしまった。", "has vanished.");
+ }
return PROCESS_CONTINUE;
}
*/
process_result effect_monster_abyss(PlayerType *player_ptr, effect_monster_type *em_ptr)
{
- if (em_ptr->seen)
+ if (em_ptr->seen) {
em_ptr->obvious = true;
+ }
BIT_FLAGS dark = RF7_SELF_DARK_1 | RF7_SELF_DARK_2 | RF7_HAS_DARK_1 | RF7_HAS_DARK_2;
em_ptr->note = _("には耐性がある!", " resists!");
em_ptr->dam *= 3;
em_ptr->dam /= (randint1(4) + 5);
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
em_ptr->r_ptr->r_flagsr |= (RFR_RES_DARK);
+ }
} else if (!any_bits(em_ptr->r_ptr->flags7, RF7_CAN_FLY)) {
if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_TELE)) {
em_ptr->dam *= 5;
em_ptr->dam /= 4;
- if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
+ if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
set_bits(em_ptr->r_ptr->r_flagsr, RFR_RES_TELE);
+ }
}
em_ptr->note = _("は深淵に囚われていく。", " is trapped in the abyss.");
em_ptr->note_dies = _("は深淵に堕ちてしまった。", " has fallen into the abyss.");
- if (one_in_(3) && set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50))
+ if (one_in_(3) && set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50)) {
em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
+ }
}
- if (any_bits(em_ptr->r_ptr->flags2, RF2_ELDRITCH_HORROR) || any_bits(em_ptr->r_ptr->flags2, RF2_EMPTY_MIND))
+ if (any_bits(em_ptr->r_ptr->flags2, RF2_ELDRITCH_HORROR) || any_bits(em_ptr->r_ptr->flags2, RF2_EMPTY_MIND)) {
return PROCESS_CONTINUE;
+ }
if (one_in_(3)) {
- if (one_in_(2))
+ if (one_in_(2)) {
em_ptr->do_conf = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
- else
+ } else {
em_ptr->do_fear = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
+ }
}
return PROCESS_CONTINUE;
if (!player_ptr->levitation || one_in_(13)) {
inventory_damage(player_ptr, BreakerCold(), 2);
}
+ ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
}
void effect_player_abyss(PlayerType *player_ptr, EffectPlayerType *ep_ptr)
if (!has_resist_fear(player_ptr)) {
(void)bss.mod_afraidness(randint1(10));
}
+ ep_ptr->get_damage = take_hit(player_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer);
}
void effect_player_meteor(PlayerType *player_ptr, EffectPlayerType *ep_ptr);
void effect_player_icee(PlayerType *player_ptr, EffectPlayerType *ep_ptr);
void effect_player_hand_doom(PlayerType *player_ptr, EffectPlayerType *ep_ptr);
+void effect_player_void(PlayerType *player_ptr, EffectPlayerType *ep_ptr);
+void effect_player_abyss(PlayerType *player_ptr, EffectPlayerType *ep_ptr);
case AttributeType::HAND_DOOM:
effect_player_hand_doom(player_ptr, ep_ptr);
return;
+ case AttributeType::VOID_MAGIC:
+ effect_player_void(player_ptr, ep_ptr);
+ return;
+ case AttributeType::ABYSS:
+ effect_player_abyss(player_ptr, ep_ptr);
+ return;
default: {
ep_ptr->dam = 0;
return;
#include "mind/mind-sniper.h"
#include "mind/mind-weaponsmith.h"
#include "object-enchant/object-ego.h"
-#include "object-enchant/object-smith.h"
-#include "object-enchant/smith-types.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/tr-types.h"
#include "object-enchant/trg-types.h"
#include "perception/object-perception.h"
#include "player/player-status-table.h"
#include "player/player-status.h"
+#include "smith/object-smith.h"
+#include "smith/smith-types.h"
#include "specific-object/bow.h"
#include "sv-definition/sv-lite-types.h"
#include "sv-definition/sv-weapon-types.h"
return;
}
- if (((flavor_ptr->o_ptr->tval == ItemKindType::RING) || (flavor_ptr->o_ptr->tval == ItemKindType::AMULET) || (flavor_ptr->o_ptr->tval == ItemKindType::LITE)
- || (flavor_ptr->o_ptr->tval == ItemKindType::FIGURINE))
- && flavor_ptr->aware && !flavor_ptr->known && !(flavor_ptr->o_ptr->ident & IDENT_SENSE)) {
+ if (((flavor_ptr->o_ptr->tval == ItemKindType::RING) || (flavor_ptr->o_ptr->tval == ItemKindType::AMULET) || (flavor_ptr->o_ptr->tval == ItemKindType::LITE) || (flavor_ptr->o_ptr->tval == ItemKindType::FIGURINE)) && flavor_ptr->aware && !flavor_ptr->known && !(flavor_ptr->o_ptr->ident & IDENT_SENSE)) {
strcpy(flavor_ptr->fake_insc_buf, _("未鑑定", "unidentified"));
return;
}
m_ptr->mtimed[MTIMED_CSLEEP] = 0;
m_ptr->hold_o_idx_list.clear();
m_ptr->target_y = 0;
- if (((*r_ptr)->flags1 & RF1_PREVENT_SUDDEN_MAGIC) && !ironman_nightmare) {
+ if ((*r_ptr)->behavior_flags.has(MonsterBehaviorType::PREVENT_SUDDEN_MAGIC) && !ironman_nightmare) {
m_ptr->mflag.set(MonsterTemporaryFlagType::PREVENT_MAGIC);
}
}
*/
static bool grab_one_basic_monster_flag(dungeon_type *d_ptr, std::string_view what)
{
- if (info_grab_one_flag(d_ptr->mflags1, r_info_flags1, what))
+ if (info_grab_one_flag(d_ptr->mflags1, r_info_flags1, what)) {
return true;
+ }
+
+ if (info_grab_one_flag(d_ptr->mflags2, r_info_flags2, what)) {
+ return true;
+ }
+
+ if (info_grab_one_flag(d_ptr->mflags3, r_info_flags3, what)) {
+ return true;
+ }
- if (info_grab_one_flag(d_ptr->mflags2, r_info_flags2, what))
+ if (info_grab_one_flag(d_ptr->mflags7, r_info_flags7, what)) {
return true;
+ }
- if (info_grab_one_flag(d_ptr->mflags3, r_info_flags3, what))
+ if (info_grab_one_flag(d_ptr->mflags8, r_info_flags8, what)) {
return true;
+ }
- if (info_grab_one_flag(d_ptr->mflags7, r_info_flags7, what))
+ if (info_grab_one_flag(d_ptr->mflags9, r_info_flags9, what)) {
return true;
+ }
- if (info_grab_one_flag(d_ptr->mflags8, r_info_flags8, what))
+ if (info_grab_one_flag(d_ptr->mflagsr, r_info_flagsr, what)) {
return true;
+ }
- if (info_grab_one_flag(d_ptr->mflags9, r_info_flags9, what))
+ if (EnumClassFlagGroup<MonsterBehaviorType>::grab_one_flag(d_ptr->mon_behavior_flags, r_info_behavior_flags, what)) {
return true;
+ }
- if (info_grab_one_flag(d_ptr->mflagsr, r_info_flagsr, what))
+ if (EnumClassFlagGroup<MonsterVisualType>::grab_one_flag(d_ptr->mon_visual_flags, r_info_visual_flags, what)) {
return true;
+ }
msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what.data());
return false;
*/
static bool grab_one_spell_monster_flag(dungeon_type *d_ptr, std::string_view what)
{
- if (EnumClassFlagGroup<MonsterAbilityType>::grab_one_flag(d_ptr->m_ability_flags, r_info_ability_flags, what))
+ if (EnumClassFlagGroup<MonsterAbilityType>::grab_one_flag(d_ptr->mon_ability_flags, r_info_ability_flags, what))
return true;
msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what.data());
if (!grab_one_spell_monster_flag(d_ptr, f))
return PARSE_ERROR_INVALID_FLAG;
}
- }
- else
+ } else
return PARSE_ERROR_UNDEFINED_DIRECTIVE;
return 0;
case 'C': {
auto pct_max = PLAYER_CLASS_TYPE_MAX;
auto n = tokenize(s + 2, pct_max, zz, 0);
- for (int i = 0; i < pct_max; i++) {
- building[index].member_class.push_back((i < n) ? atoi(zz[i]) : 1);
+ for (auto i = 0; i < pct_max; i++) {
+ building[index].member_class[i] = (i < n) ? atoi(zz[i]) : 1;
}
break;
#include "monster-attack/monster-attack-effect.h"
#include "monster-attack/monster-attack-types.h"
#include "monster-race/race-ability-flags.h"
+#include "monster-race/race-visual-flags.h"
/*!
- * モンスターの打撃手段トークンの定義 /
- * Monster Blow Methods
- */
+ * モンスターの打撃手段トークンの定義 /
+ * Monster Blow Methods
+ */
const std::unordered_map<std::string_view, RaceBlowMethodType> r_info_blow_method = {
- { "HIT", RaceBlowMethodType::HIT },
- { "TOUCH", RaceBlowMethodType::TOUCH },
- { "PUNCH", RaceBlowMethodType::PUNCH },
- { "KICK", RaceBlowMethodType::KICK },
- { "CLAW", RaceBlowMethodType::CLAW },
- { "BITE", RaceBlowMethodType::BITE },
- { "STING", RaceBlowMethodType::STING },
- { "SLASH", RaceBlowMethodType::SLASH },
- { "BUTT", RaceBlowMethodType::BUTT },
- { "CRUSH", RaceBlowMethodType::CRUSH },
- { "ENGULF", RaceBlowMethodType::ENGULF },
- { "CHARGE", RaceBlowMethodType::CHARGE },
- { "CRAWL", RaceBlowMethodType::CRAWL },
- { "DROOL", RaceBlowMethodType::DROOL },
- { "SPIT", RaceBlowMethodType::SPIT },
- { "EXPLODE", RaceBlowMethodType::EXPLODE },
- { "GAZE", RaceBlowMethodType::GAZE },
- { "WAIL", RaceBlowMethodType::WAIL },
- { "SPORE", RaceBlowMethodType::SPORE },
- { "XXX4", RaceBlowMethodType::XXX4 },
- { "BEG", RaceBlowMethodType::BEG },
- { "INSULT", RaceBlowMethodType::INSULT },
- { "MOAN", RaceBlowMethodType::MOAN },
- { "SHOW", RaceBlowMethodType::SHOW },
- { "SHOOT", RaceBlowMethodType::SHOOT },
+ { "HIT", RaceBlowMethodType::HIT },
+ { "TOUCH", RaceBlowMethodType::TOUCH },
+ { "PUNCH", RaceBlowMethodType::PUNCH },
+ { "KICK", RaceBlowMethodType::KICK },
+ { "CLAW", RaceBlowMethodType::CLAW },
+ { "BITE", RaceBlowMethodType::BITE },
+ { "STING", RaceBlowMethodType::STING },
+ { "SLASH", RaceBlowMethodType::SLASH },
+ { "BUTT", RaceBlowMethodType::BUTT },
+ { "CRUSH", RaceBlowMethodType::CRUSH },
+ { "ENGULF", RaceBlowMethodType::ENGULF },
+ { "CHARGE", RaceBlowMethodType::CHARGE },
+ { "CRAWL", RaceBlowMethodType::CRAWL },
+ { "DROOL", RaceBlowMethodType::DROOL },
+ { "SPIT", RaceBlowMethodType::SPIT },
+ { "EXPLODE", RaceBlowMethodType::EXPLODE },
+ { "GAZE", RaceBlowMethodType::GAZE },
+ { "WAIL", RaceBlowMethodType::WAIL },
+ { "SPORE", RaceBlowMethodType::SPORE },
+ { "XXX4", RaceBlowMethodType::XXX4 },
+ { "BEG", RaceBlowMethodType::BEG },
+ { "INSULT", RaceBlowMethodType::INSULT },
+ { "MOAN", RaceBlowMethodType::MOAN },
+ { "SHOW", RaceBlowMethodType::SHOW },
+ { "SHOOT", RaceBlowMethodType::SHOOT },
};
/*!
* Monster Blow Effects
*/
const std::unordered_map<std::string_view, RaceBlowEffectType> r_info_blow_effect = {
- { "HURT", RaceBlowEffectType::HURT },
- { "POISON", RaceBlowEffectType::POISON },
- { "UN_BONUS", RaceBlowEffectType::UN_BONUS },
- { "UN_POWER", RaceBlowEffectType::UN_POWER },
- { "EAT_GOLD", RaceBlowEffectType::EAT_GOLD },
- { "EAT_ITEM", RaceBlowEffectType::EAT_ITEM },
- { "EAT_FOOD", RaceBlowEffectType::EAT_FOOD },
- { "EAT_LITE", RaceBlowEffectType::EAT_LITE },
- { "ACID", RaceBlowEffectType::ACID },
- { "ELEC", RaceBlowEffectType::ELEC },
- { "FIRE", RaceBlowEffectType::FIRE },
- { "COLD", RaceBlowEffectType::COLD },
- { "BLIND", RaceBlowEffectType::BLIND },
- { "CONFUSE", RaceBlowEffectType::CONFUSE },
- { "TERRIFY", RaceBlowEffectType::TERRIFY },
- { "PARALYZE", RaceBlowEffectType::PARALYZE },
- { "LOSE_STR", RaceBlowEffectType::LOSE_STR },
- { "LOSE_INT", RaceBlowEffectType::LOSE_INT },
- { "LOSE_WIS", RaceBlowEffectType::LOSE_WIS },
- { "LOSE_DEX", RaceBlowEffectType::LOSE_DEX },
- { "LOSE_CON", RaceBlowEffectType::LOSE_CON },
- { "LOSE_CHR", RaceBlowEffectType::LOSE_CHR },
- { "LOSE_ALL", RaceBlowEffectType::LOSE_ALL },
- { "SHATTER", RaceBlowEffectType::SHATTER },
- { "EXP_10", RaceBlowEffectType::EXP_10 },
- { "EXP_20", RaceBlowEffectType::EXP_20 },
- { "EXP_40", RaceBlowEffectType::EXP_40 },
- { "EXP_80", RaceBlowEffectType::EXP_80 },
- { "DISEASE", RaceBlowEffectType::DISEASE },
- { "TIME", RaceBlowEffectType::TIME },
- { "EXP_VAMP", RaceBlowEffectType::DR_LIFE },
- { "DR_MANA", RaceBlowEffectType::DR_MANA },
- { "SUPERHURT", RaceBlowEffectType::SUPERHURT },
- { "INERTIA", RaceBlowEffectType::INERTIA },
+ { "HURT", RaceBlowEffectType::HURT },
+ { "POISON", RaceBlowEffectType::POISON },
+ { "UN_BONUS", RaceBlowEffectType::UN_BONUS },
+ { "UN_POWER", RaceBlowEffectType::UN_POWER },
+ { "EAT_GOLD", RaceBlowEffectType::EAT_GOLD },
+ { "EAT_ITEM", RaceBlowEffectType::EAT_ITEM },
+ { "EAT_FOOD", RaceBlowEffectType::EAT_FOOD },
+ { "EAT_LITE", RaceBlowEffectType::EAT_LITE },
+ { "ACID", RaceBlowEffectType::ACID },
+ { "ELEC", RaceBlowEffectType::ELEC },
+ { "FIRE", RaceBlowEffectType::FIRE },
+ { "COLD", RaceBlowEffectType::COLD },
+ { "BLIND", RaceBlowEffectType::BLIND },
+ { "CONFUSE", RaceBlowEffectType::CONFUSE },
+ { "TERRIFY", RaceBlowEffectType::TERRIFY },
+ { "PARALYZE", RaceBlowEffectType::PARALYZE },
+ { "LOSE_STR", RaceBlowEffectType::LOSE_STR },
+ { "LOSE_INT", RaceBlowEffectType::LOSE_INT },
+ { "LOSE_WIS", RaceBlowEffectType::LOSE_WIS },
+ { "LOSE_DEX", RaceBlowEffectType::LOSE_DEX },
+ { "LOSE_CON", RaceBlowEffectType::LOSE_CON },
+ { "LOSE_CHR", RaceBlowEffectType::LOSE_CHR },
+ { "LOSE_ALL", RaceBlowEffectType::LOSE_ALL },
+ { "SHATTER", RaceBlowEffectType::SHATTER },
+ { "EXP_10", RaceBlowEffectType::EXP_10 },
+ { "EXP_20", RaceBlowEffectType::EXP_20 },
+ { "EXP_40", RaceBlowEffectType::EXP_40 },
+ { "EXP_80", RaceBlowEffectType::EXP_80 },
+ { "DISEASE", RaceBlowEffectType::DISEASE },
+ { "TIME", RaceBlowEffectType::TIME },
+ { "EXP_VAMP", RaceBlowEffectType::DR_LIFE },
+ { "DR_MANA", RaceBlowEffectType::DR_MANA },
+ { "SUPERHURT", RaceBlowEffectType::SUPERHURT },
+ { "INERTIA", RaceBlowEffectType::INERTIA },
{ "STUN", RaceBlowEffectType::STUN },
{ "HUNGRY", RaceBlowEffectType::HUNGRY },
{ "FLAVOR", RaceBlowEffectType::FLAVOR },
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags1> r_info_flags1 = {
- { "UNIQUE", RF1_UNIQUE },
- { "QUESTOR", RF1_QUESTOR },
- { "MALE", RF1_MALE },
- { "FEMALE", RF1_FEMALE },
- { "CHAR_CLEAR", RF1_CHAR_CLEAR },
- { "SHAPECHANGER", RF1_SHAPECHANGER },
- { "ATTR_CLEAR", RF1_ATTR_CLEAR },
- { "ATTR_MULTI", RF1_ATTR_MULTI },
- { "FORCE_DEPTH", RF1_FORCE_DEPTH },
- { "FORCE_MAXHP", RF1_FORCE_MAXHP },
- { "PREVENT_SUDDEN_MAGIC", RF1_PREVENT_SUDDEN_MAGIC },
- { "FORCE_EXTRA", RF1_FORCE_EXTRA },
- { "ATTR_SEMIRAND", RF1_ATTR_SEMIRAND },
- { "FRIENDS", RF1_FRIENDS },
- { "ESCORT", RF1_ESCORT },
- { "ESCORTS", RF1_ESCORTS },
- { "NEVER_BLOW", RF1_NEVER_BLOW },
- { "NEVER_MOVE", RF1_NEVER_MOVE },
- { "RAND_25", RF1_RAND_25 },
- { "RAND_50", RF1_RAND_50 },
- { "ONLY_GOLD", RF1_ONLY_GOLD },
- { "ONLY_ITEM", RF1_ONLY_ITEM },
- { "DROP_60", RF1_DROP_60 },
- { "DROP_90", RF1_DROP_90 },
- { "DROP_1D2", RF1_DROP_1D2 },
- { "DROP_2D2", RF1_DROP_2D2 },
- { "DROP_3D2", RF1_DROP_3D2 },
- { "DROP_4D2", RF1_DROP_4D2 },
- { "DROP_GOOD", RF1_DROP_GOOD },
- { "DROP_GREAT", RF1_DROP_GREAT },
+ { "UNIQUE", RF1_UNIQUE },
+ { "QUESTOR", RF1_QUESTOR },
+ { "MALE", RF1_MALE },
+ { "FEMALE", RF1_FEMALE },
+ { "FORCE_DEPTH", RF1_FORCE_DEPTH },
+ { "FORCE_MAXHP", RF1_FORCE_MAXHP },
+ { "FORCE_EXTRA", RF1_FORCE_EXTRA },
+ { "FRIENDS", RF1_FRIENDS },
+ { "ESCORT", RF1_ESCORT },
+ { "ESCORTS", RF1_ESCORTS },
+ { "ONLY_GOLD", RF1_ONLY_GOLD },
+ { "ONLY_ITEM", RF1_ONLY_ITEM },
+ { "DROP_60", RF1_DROP_60 },
+ { "DROP_90", RF1_DROP_90 },
+ { "DROP_1D2", RF1_DROP_1D2 },
+ { "DROP_2D2", RF1_DROP_2D2 },
+ { "DROP_3D2", RF1_DROP_3D2 },
+ { "DROP_4D2", RF1_DROP_4D2 },
+ { "DROP_GOOD", RF1_DROP_GOOD },
+ { "DROP_GREAT", RF1_DROP_GREAT },
};
/*!
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags2> r_info_flags2 = {
- { "STUPID", RF2_STUPID },
- { "SMART", RF2_SMART },
- { "CAN_SPEAK", RF2_CAN_SPEAK },
- { "REFLECTING", RF2_REFLECTING },
- { "INVISIBLE", RF2_INVISIBLE },
- { "COLD_BLOOD", RF2_COLD_BLOOD },
- { "EMPTY_MIND", RF2_EMPTY_MIND },
- { "WEIRD_MIND", RF2_WEIRD_MIND },
- { "MULTIPLY", RF2_MULTIPLY },
- { "REGENERATE", RF2_REGENERATE },
- { "CHAR_MULTI", RF2_CHAR_MULTI },
- { "ATTR_ANY", RF2_ATTR_ANY },
- { "POWERFUL", RF2_POWERFUL },
- { "ELDRITCH_HORROR", RF2_ELDRITCH_HORROR },
- { "FLAGS2_XX14", RF2_XX14 },
- { "FLAGS2_XX15", RF2_XX15 },
- { "OPEN_DOOR", RF2_OPEN_DOOR },
- { "BASH_DOOR", RF2_BASH_DOOR },
- { "PASS_WALL", RF2_PASS_WALL },
- { "KILL_WALL", RF2_KILL_WALL },
- { "MOVE_BODY", RF2_MOVE_BODY },
- { "KILL_BODY", RF2_KILL_BODY },
- { "TAKE_ITEM", RF2_TAKE_ITEM },
- { "KILL_ITEM", RF2_KILL_ITEM },
- { "HUMAN", RF2_HUMAN },
- { "QUANTUM", RF2_QUANTUM }
+ { "CAN_SPEAK", RF2_CAN_SPEAK },
+ { "REFLECTING", RF2_REFLECTING },
+ { "INVISIBLE", RF2_INVISIBLE },
+ { "COLD_BLOOD", RF2_COLD_BLOOD },
+ { "EMPTY_MIND", RF2_EMPTY_MIND },
+ { "WEIRD_MIND", RF2_WEIRD_MIND },
+ { "MULTIPLY", RF2_MULTIPLY },
+ { "REGENERATE", RF2_REGENERATE },
+ { "CHAR_MULTI", RF2_CHAR_MULTI },
+ { "POWERFUL", RF2_POWERFUL },
+ { "ELDRITCH_HORROR", RF2_ELDRITCH_HORROR },
+ { "FLAGS2_XX14", RF2_XX14 },
+ { "FLAGS2_XX15", RF2_XX15 },
+ { "PASS_WALL", RF2_PASS_WALL },
+ { "KILL_WALL", RF2_KILL_WALL },
+ { "HUMAN", RF2_HUMAN },
+ { "QUANTUM", RF2_QUANTUM }
};
/*!
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags3> r_info_flags3 = {
- { "ORC", RF3_ORC },
- { "TROLL", RF3_TROLL },
- { "GIANT", RF3_GIANT },
- { "DRAGON", RF3_DRAGON },
- { "DEMON", RF3_DEMON },
- { "UNDEAD", RF3_UNDEAD },
- { "EVIL", RF3_EVIL },
- { "ANIMAL", RF3_ANIMAL },
- { "AMBERITE", RF3_AMBERITE },
- { "GOOD", RF3_GOOD },
- { "FLAGS3_XX10", RF3_XX10 },
- { "NONLIVING", RF3_NONLIVING },
- { "HURT_LITE", RF3_HURT_LITE },
- { "HURT_ROCK", RF3_HURT_ROCK },
- { "HURT_FIRE", RF3_HURT_FIRE },
- { "HURT_COLD", RF3_HURT_COLD },
- { "ANGEL", RF3_ANGEL },
- { "NO_FEAR", RF3_NO_FEAR },
- { "NO_STUN", RF3_NO_STUN },
- { "NO_CONF", RF3_NO_CONF },
- { "NO_SLEEP", RF3_NO_SLEEP }
+ { "ORC", RF3_ORC },
+ { "TROLL", RF3_TROLL },
+ { "GIANT", RF3_GIANT },
+ { "DRAGON", RF3_DRAGON },
+ { "DEMON", RF3_DEMON },
+ { "UNDEAD", RF3_UNDEAD },
+ { "EVIL", RF3_EVIL },
+ { "ANIMAL", RF3_ANIMAL },
+ { "AMBERITE", RF3_AMBERITE },
+ { "GOOD", RF3_GOOD },
+ { "FLAGS3_XX10", RF3_XX10 },
+ { "NONLIVING", RF3_NONLIVING },
+ { "HURT_LITE", RF3_HURT_LITE },
+ { "HURT_ROCK", RF3_HURT_ROCK },
+ { "HURT_FIRE", RF3_HURT_FIRE },
+ { "HURT_COLD", RF3_HURT_COLD },
+ { "ANGEL", RF3_ANGEL },
+ { "NO_FEAR", RF3_NO_FEAR },
+ { "NO_STUN", RF3_NO_STUN },
+ { "NO_CONF", RF3_NO_CONF },
+ { "NO_SLEEP", RF3_NO_SLEEP }
};
/*!
{"BR_NUKE", MonsterAbilityType::BR_NUKE },
{"BA_CHAO", MonsterAbilityType::BA_CHAO },
{"BR_DISI", MonsterAbilityType::BR_DISI },
+ {"BR_VOID", MonsterAbilityType::BR_VOID },
+ {"BR_ABYSS", MonsterAbilityType::BR_ABYSS },
{"BA_ACID", MonsterAbilityType::BA_ACID },
{"BA_ELEC", MonsterAbilityType::BA_ELEC },
{"BA_WATE", MonsterAbilityType::BA_WATE },
{"BA_MANA", MonsterAbilityType::BA_MANA },
{"BA_DARK", MonsterAbilityType::BA_DARK },
+ {"BA_VOID", MonsterAbilityType::BA_VOID },
+ {"BA_ABYSS", MonsterAbilityType::BA_ABYSS },
{"DRAIN_MANA", MonsterAbilityType::DRAIN_MANA },
{"MIND_BLAST", MonsterAbilityType::MIND_BLAST },
{"BRAIN_SMASH", MonsterAbilityType::BRAIN_SMASH },
{"BO_MANA", MonsterAbilityType::BO_MANA },
{"BO_PLAS", MonsterAbilityType::BO_PLAS },
{"BO_ICEE", MonsterAbilityType::BO_ICEE },
+ {"BO_VOID", MonsterAbilityType::BO_VOID },
+ {"BO_ABYSS", MonsterAbilityType::BO_ABYSS },
{"MISSILE", MonsterAbilityType::MISSILE },
{"SCARE", MonsterAbilityType::SCARE },
{"BLIND", MonsterAbilityType::BLIND },
* "GUARDIAN" ... init.c d_infoの FINAL_GUARDIAN_* にて自動指定
*/
const std::unordered_map<std::string_view, race_flags7> r_info_flags7 = {
- { "AQUATIC", RF7_AQUATIC },
- { "CAN_SWIM", RF7_CAN_SWIM },
- { "CAN_FLY", RF7_CAN_FLY },
- { "FRIENDLY", RF7_FRIENDLY },
- { "NAZGUL", RF7_NAZGUL },
- { "UNIQUE2", RF7_UNIQUE2 },
- { "RIDING", RF7_RIDING },
- { "KAGE", RF7_KAGE },
- { "HAS_LITE_1", RF7_HAS_LITE_1 },
- { "SELF_LITE_1", RF7_SELF_LITE_1 },
- { "HAS_LITE_2", RF7_HAS_LITE_2 },
- { "SELF_LITE_2", RF7_SELF_LITE_2 },
- { "CHAMELEON", RF7_CHAMELEON },
- { "TANUKI", RF7_TANUKI },
- { "HAS_DARK_1", RF7_HAS_DARK_1 },
- { "SELF_DARK_1", RF7_SELF_DARK_1 },
- { "HAS_DARK_2", RF7_HAS_DARK_2 },
- { "SELF_DARK_2", RF7_SELF_DARK_2 },
+ { "AQUATIC", RF7_AQUATIC },
+ { "CAN_SWIM", RF7_CAN_SWIM },
+ { "CAN_FLY", RF7_CAN_FLY },
+ { "NAZGUL", RF7_NAZGUL },
+ { "UNIQUE2", RF7_UNIQUE2 },
+ { "RIDING", RF7_RIDING },
+ { "KAGE", RF7_KAGE },
+ { "HAS_LITE_1", RF7_HAS_LITE_1 },
+ { "SELF_LITE_1", RF7_SELF_LITE_1 },
+ { "HAS_LITE_2", RF7_HAS_LITE_2 },
+ { "SELF_LITE_2", RF7_SELF_LITE_2 },
+ { "CHAMELEON", RF7_CHAMELEON },
+ { "TANUKI", RF7_TANUKI },
+ { "HAS_DARK_1", RF7_HAS_DARK_1 },
+ { "SELF_DARK_1", RF7_SELF_DARK_1 },
+ { "HAS_DARK_2", RF7_HAS_DARK_2 },
+ { "SELF_DARK_2", RF7_SELF_DARK_2 },
};
/*!
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags8> r_info_flags8 = {
- { "WILD_ONLY", RF8_WILD_ONLY },
- { "WILD_TOWN", RF8_WILD_TOWN },
+ { "WILD_ONLY", RF8_WILD_ONLY },
+ { "WILD_TOWN", RF8_WILD_TOWN },
{ "NO_QUEST", RF8_NO_QUEST },
{ "WILD_SHORE", RF8_WILD_SHORE },
- { "WILD_OCEAN", RF8_WILD_OCEAN },
- { "WILD_WASTE", RF8_WILD_WASTE },
- { "WILD_WOOD", RF8_WILD_WOOD },
- { "WILD_VOLCANO", RF8_WILD_VOLCANO },
- { "WILD_MOUNTAIN", RF8_WILD_MOUNTAIN },
- { "WILD_GRASS", RF8_WILD_GRASS },
- { "WILD_SWAMP", RF8_WILD_SWAMP },
- { "WILD_ALL", RF8_WILD_ALL },
+ { "WILD_OCEAN", RF8_WILD_OCEAN },
+ { "WILD_WASTE", RF8_WILD_WASTE },
+ { "WILD_WOOD", RF8_WILD_WOOD },
+ { "WILD_VOLCANO", RF8_WILD_VOLCANO },
+ { "WILD_MOUNTAIN", RF8_WILD_MOUNTAIN },
+ { "WILD_GRASS", RF8_WILD_GRASS },
+ { "WILD_SWAMP", RF8_WILD_SWAMP },
+ { "WILD_ALL", RF8_WILD_ALL },
};
/*!
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags9> r_info_flags9 = {
- { "DROP_CORPSE", RF9_DROP_CORPSE },
- { "DROP_SKELETON", RF9_DROP_SKELETON },
- { "EAT_BLIND", RF9_EAT_BLIND },
- { "EAT_CONF", RF9_EAT_CONF },
- { "EAT_MANA", RF9_EAT_MANA },
- { "EAT_NEXUS", RF9_EAT_NEXUS },
- // { "EAT_BLINK", RF9_EAT_BLINK }, //<! @note フラグ未定義
- { "EAT_SLEEP", RF9_EAT_SLEEP },
- { "EAT_BERSERKER", RF9_EAT_BERSERKER },
- { "EAT_ACIDIC", RF9_EAT_ACIDIC },
- { "EAT_SPEED", RF9_EAT_SPEED },
- { "EAT_CURE", RF9_EAT_CURE },
- { "EAT_FIRE_RES", RF9_EAT_FIRE_RES },
- { "EAT_COLD_RES", RF9_EAT_COLD_RES },
- { "EAT_ACID_RES", RF9_EAT_ACID_RES },
- { "EAT_ELEC_RES", RF9_EAT_ELEC_RES },
- { "EAT_POIS_RES", RF9_EAT_POIS_RES },
- { "EAT_INSANITY", RF9_EAT_INSANITY },
- { "EAT_DRAIN_EXP", RF9_EAT_DRAIN_EXP },
- { "EAT_POISONOUS", RF9_EAT_POISONOUS },
- { "EAT_GIVE_STR", RF9_EAT_GIVE_STR },
- { "EAT_GIVE_INT", RF9_EAT_GIVE_INT },
- { "EAT_GIVE_WIS", RF9_EAT_GIVE_WIS },
- { "EAT_GIVE_DEX", RF9_EAT_GIVE_DEX },
- { "EAT_GIVE_CON", RF9_EAT_GIVE_CON },
- { "EAT_GIVE_CHR", RF9_EAT_GIVE_CHR },
- { "EAT_LOSE_STR", RF9_EAT_LOSE_STR },
- { "EAT_LOSE_INT", RF9_EAT_LOSE_INT },
- { "EAT_LOSE_WIS", RF9_EAT_LOSE_WIS },
- { "EAT_LOSE_DEX", RF9_EAT_LOSE_DEX },
- { "EAT_LOSE_CON", RF9_EAT_LOSE_CON },
- { "EAT_LOSE_CHR", RF9_EAT_LOSE_CHR },
- { "EAT_DRAIN_MANA", RF9_EAT_DRAIN_MANA },
+ { "DROP_CORPSE", RF9_DROP_CORPSE },
+ { "DROP_SKELETON", RF9_DROP_SKELETON },
+ { "EAT_BLIND", RF9_EAT_BLIND },
+ { "EAT_CONF", RF9_EAT_CONF },
+ { "EAT_MANA", RF9_EAT_MANA },
+ { "EAT_NEXUS", RF9_EAT_NEXUS },
+ // { "EAT_BLINK", RF9_EAT_BLINK }, //<! @note フラグ未定義
+ { "EAT_SLEEP", RF9_EAT_SLEEP },
+ { "EAT_BERSERKER", RF9_EAT_BERSERKER },
+ { "EAT_ACIDIC", RF9_EAT_ACIDIC },
+ { "EAT_SPEED", RF9_EAT_SPEED },
+ { "EAT_CURE", RF9_EAT_CURE },
+ { "EAT_FIRE_RES", RF9_EAT_FIRE_RES },
+ { "EAT_COLD_RES", RF9_EAT_COLD_RES },
+ { "EAT_ACID_RES", RF9_EAT_ACID_RES },
+ { "EAT_ELEC_RES", RF9_EAT_ELEC_RES },
+ { "EAT_POIS_RES", RF9_EAT_POIS_RES },
+ { "EAT_INSANITY", RF9_EAT_INSANITY },
+ { "EAT_DRAIN_EXP", RF9_EAT_DRAIN_EXP },
+ { "EAT_POISONOUS", RF9_EAT_POISONOUS },
+ { "EAT_GIVE_STR", RF9_EAT_GIVE_STR },
+ { "EAT_GIVE_INT", RF9_EAT_GIVE_INT },
+ { "EAT_GIVE_WIS", RF9_EAT_GIVE_WIS },
+ { "EAT_GIVE_DEX", RF9_EAT_GIVE_DEX },
+ { "EAT_GIVE_CON", RF9_EAT_GIVE_CON },
+ { "EAT_GIVE_CHR", RF9_EAT_GIVE_CHR },
+ { "EAT_LOSE_STR", RF9_EAT_LOSE_STR },
+ { "EAT_LOSE_INT", RF9_EAT_LOSE_INT },
+ { "EAT_LOSE_WIS", RF9_EAT_LOSE_WIS },
+ { "EAT_LOSE_DEX", RF9_EAT_LOSE_DEX },
+ { "EAT_LOSE_CON", RF9_EAT_LOSE_CON },
+ { "EAT_LOSE_CHR", RF9_EAT_LOSE_CHR },
+ { "EAT_DRAIN_MANA", RF9_EAT_DRAIN_MANA },
};
/*!
* Monster race flags
*/
const std::unordered_map<std::string_view, race_flags_resistance> r_info_flagsr = {
- { "IM_ACID", RFR_IM_ACID },
- { "IM_ELEC", RFR_IM_ELEC },
- { "IM_FIRE", RFR_IM_FIRE },
- { "IM_COLD", RFR_IM_COLD },
- { "IM_POIS", RFR_IM_POIS },
- { "RES_LITE", RFR_RES_LITE },
- { "RES_DARK", RFR_RES_DARK },
- { "RES_NETH", RFR_RES_NETH },
- { "RES_WATE", RFR_RES_WATE },
- { "RES_PLAS", RFR_RES_PLAS },
- { "RES_SHAR", RFR_RES_SHAR },
- { "RES_SOUN", RFR_RES_SOUN },
- { "RES_CHAO", RFR_RES_CHAO },
- { "RES_NEXU", RFR_RES_NEXU },
- { "RES_DISE", RFR_RES_DISE },
- { "RES_WALL", RFR_RES_WALL },
- { "RES_INER", RFR_RES_INER },
- { "RES_TIME", RFR_RES_TIME },
- { "RES_GRAV", RFR_RES_GRAV },
- { "RES_ALL", RFR_RES_ALL },
- { "RES_TELE", RFR_RES_TELE },
+ { "IM_ACID", RFR_IM_ACID },
+ { "IM_ELEC", RFR_IM_ELEC },
+ { "IM_FIRE", RFR_IM_FIRE },
+ { "IM_COLD", RFR_IM_COLD },
+ { "IM_POIS", RFR_IM_POIS },
+ { "RES_LITE", RFR_RES_LITE },
+ { "RES_DARK", RFR_RES_DARK },
+ { "RES_NETH", RFR_RES_NETH },
+ { "RES_WATE", RFR_RES_WATE },
+ { "RES_PLAS", RFR_RES_PLAS },
+ { "RES_SHAR", RFR_RES_SHAR },
+ { "RES_SOUN", RFR_RES_SOUN },
+ { "RES_CHAO", RFR_RES_CHAO },
+ { "RES_NEXU", RFR_RES_NEXU },
+ { "RES_DISE", RFR_RES_DISE },
+ { "RES_WALL", RFR_RES_WALL },
+ { "RES_INER", RFR_RES_INER },
+ { "RES_TIME", RFR_RES_TIME },
+ { "RES_GRAV", RFR_RES_GRAV },
+ { "RES_ALL", RFR_RES_ALL },
+ { "RES_TELE", RFR_RES_TELE },
};
const std::unordered_map<std::string_view, MonsterAuraType> r_info_aura_flags = {
{ "AURA_VOIDS", MonsterAuraType::VOIDS },
{ "AURA_ABYSS", MonsterAuraType::ABYSS },
};
+
+const std::unordered_map<std::string_view, MonsterBehaviorType> r_info_behavior_flags = {
+ { "NEVER_BLOW", MonsterBehaviorType::NEVER_BLOW },
+ { "NEVER_MOVE", MonsterBehaviorType::NEVER_MOVE },
+ { "OPEN_DOOR", MonsterBehaviorType::OPEN_DOOR },
+ { "BASH_DOOR", MonsterBehaviorType::BASH_DOOR },
+ { "MOVE_BODY", MonsterBehaviorType::MOVE_BODY },
+ { "KILL_BODY", MonsterBehaviorType::KILL_BODY },
+ { "TAKE_ITEM", MonsterBehaviorType::TAKE_ITEM },
+ { "KILL_ITEM", MonsterBehaviorType::KILL_ITEM },
+ { "RAND_25", MonsterBehaviorType::RAND_MOVE_25 },
+ { "RAND_50", MonsterBehaviorType::RAND_MOVE_50 },
+ { "STUPID", MonsterBehaviorType::STUPID },
+ { "SMART", MonsterBehaviorType::SMART },
+ { "FRIENDLY", MonsterBehaviorType::FRIENDLY },
+ { "PREVENT_SUDDEN_MAGIC", MonsterBehaviorType::PREVENT_SUDDEN_MAGIC },
+};
+
+const std::unordered_map<std::string_view, MonsterVisualType> r_info_visual_flags = {
+ { "CHAR_CLEAR", MonsterVisualType::CLEAR },
+ { "SHAPECHANGER", MonsterVisualType::SHAPECHANGER },
+ { "ATTR_CLEAR", MonsterVisualType::CLEAR_COLOR },
+ { "ATTR_MULTI", MonsterVisualType::MULTI_COLOR },
+ { "ATTR_SEMIRAND", MonsterVisualType::RANDOM_COLOR },
+ { "ATTR_ANY", MonsterVisualType::ANY_COLOR },
+};
#include "monster-attack/monster-attack-types.h"
#include "monster-race/monster-aura-types.h"
#include "monster-race/race-ability-flags.h"
+#include "monster-race/race-behavior-flags.h"
+#include "monster-race/race-flags-resistance.h"
#include "monster-race/race-flags1.h"
#include "monster-race/race-flags2.h"
#include "monster-race/race-flags3.h"
#include "monster-race/race-flags7.h"
#include "monster-race/race-flags8.h"
#include "monster-race/race-flags9.h"
-#include "monster-race/race-flags-resistance.h"
+#include "monster-race/race-visual-flags.h"
#include "system/angband.h"
#include <string_view>
extern const std::unordered_map<std::string_view, race_flags9> r_info_flags9;
extern const std::unordered_map<std::string_view, race_flags_resistance> r_info_flagsr;
extern const std::unordered_map<std::string_view, MonsterAuraType> r_info_aura_flags;
-
+extern const std::unordered_map<std::string_view, MonsterBehaviorType> r_info_behavior_flags;
+extern const std::unordered_map<std::string_view, MonsterVisualType> r_info_visual_flags;
*/
static bool grab_one_basic_flag(monster_race *r_ptr, std::string_view what)
{
- if (info_grab_one_flag(r_ptr->flags1, r_info_flags1, what))
+ if (info_grab_one_flag(r_ptr->flags1, r_info_flags1, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flags2, r_info_flags2, what))
+ if (info_grab_one_flag(r_ptr->flags2, r_info_flags2, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flags3, r_info_flags3, what))
+ if (info_grab_one_flag(r_ptr->flags3, r_info_flags3, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flags7, r_info_flags7, what))
+ if (info_grab_one_flag(r_ptr->flags7, r_info_flags7, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flags8, r_info_flags8, what))
+ if (info_grab_one_flag(r_ptr->flags8, r_info_flags8, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flags9, r_info_flags9, what))
+ if (info_grab_one_flag(r_ptr->flags9, r_info_flags9, what)) {
return true;
+ }
- if (info_grab_one_flag(r_ptr->flagsr, r_info_flagsr, what))
+ if (info_grab_one_flag(r_ptr->flagsr, r_info_flagsr, what)) {
return true;
+ }
if (EnumClassFlagGroup<MonsterAuraType>::grab_one_flag(r_ptr->aura_flags, r_info_aura_flags, what)) {
return true;
}
+ if (EnumClassFlagGroup<MonsterBehaviorType>::grab_one_flag(r_ptr->behavior_flags, r_info_behavior_flags, what)) {
+ return true;
+ }
+
+ if (EnumClassFlagGroup<MonsterVisualType>::grab_one_flag(r_ptr->visual_flags, r_info_visual_flags, what)) {
+ return true;
+ }
+
msg_format(_("未知のモンスター・フラグ '%s'。", "Unknown monster flag '%s'."), what.data());
return false;
}
static void curse_cowardice(PlayerType *player_ptr)
{
- if (player_ptr->cursed.has_not(CurseTraitType::COWARDICE))
+ if (player_ptr->cursed.has_not(CurseTraitType::COWARDICE)) {
return;
+ }
- object_type *o_ptr;
- o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::COWARDICE);
- int chance = 1500;
- int duration = 13 + randint1(26);
-
+ auto *o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::COWARDICE);
+ auto chance = 1500;
+ short duration = 13 + randint1(26);
if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
chance = 150;
duration *= 2;
}
- if (!one_in_(chance))
- return;
-
- if (has_resist_fear(player_ptr))
+ if (!one_in_(chance) || (has_resist_fear(player_ptr) != 0)) {
return;
+ }
disturb(player_ptr, false, true);
msg_print(_("とても暗い... とても恐い!", "It's so dark... so scary!"));
*/
static void curse_berserk_rage(PlayerType *player_ptr)
{
- if (player_ptr->cursed.has_not(CurseTraitType::BERS_RAGE))
+ if (player_ptr->cursed.has_not(CurseTraitType::BERS_RAGE)) {
return;
+ }
- object_type *o_ptr;
- o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::BERS_RAGE);
- int chance = 1500;
- int duration = 10 + randint1(player_ptr->lev);
+ auto *o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::BERS_RAGE);
+ auto chance = 1500;
+ short duration = 10 + randint1(player_ptr->lev);
if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
chance = 150;
duration *= 2;
}
- if (!one_in_(chance))
+ if (!one_in_(chance)) {
return;
+ }
disturb(player_ptr, false, true);
msg_print(_("ウガァァア!", "RAAAAGHH!"));
#include "mind/mind-blue-mage.h"
#include "monster-race/race-ability-flags.h"
#include "mspell/monster-power-table.h"
-#include "object-enchant/object-smith.h"
#include "object/object-kind-hook.h"
#include "object/object-kind.h"
#include "player-base/player-class.h"
#include "player-info/bluemage-data-type.h"
#include "player-info/magic-eater-data-type.h"
+#include "smith/object-smith.h"
#include "system/player-type-definition.h"
#include "util/enum-converter.h"
#include "util/flag-group.h"
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
char user_agent[64];
- snprintf(user_agent, sizeof(user_agent), "Hengband %d.%d.%d", FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
+ snprintf(user_agent, sizeof(user_agent), "Hengband %d.%d.%d", H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH);
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
#include "system/player-type-definition.h"
/*!
- * @brief ファイルのドロップパーミッションチェック / Hack -- drop permissions
+ * @brief ファイルのドロップパーミッションチェック / Check drop permissions
*/
void safe_setuid_drop(void)
{
-#ifdef SET_UID
-#ifdef SAFE_SETUID
+#if defined(SET_UID) && defined(SAFE_SETUID)
#ifdef SAFE_SETUID_POSIX
-
- if (setuid(getuid()) != 0) {
- quit(_("setuid(): 正しく許可が取れません!", "setuid(): cannot set permissions correctly!"));
+ if (auto ret = setuid(getuid()); ret != 0) {
+ auto msg = _("setuid(): 正しく許可が取れません! エラーコード:%d", "setuid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
- if (setgid(getgid()) != 0) {
- quit(_("setgid(): 正しく許可が取れません!", "setgid(): cannot set permissions correctly!"));
+
+ if (auto ret = setgid(getgid()); ret != 0) {
+ auto msg = _("setgid(): 正しく許可が取れません! エラーコード:%d", "setgid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
#else
- if (setreuid(geteuid(), getuid()) != 0) {
- quit(_("setreuid(): 正しく許可が取れません!", "setreuid(): cannot set permissions correctly!"));
+ if (auto ret = setreuid(geteuid(), getuid()); ret != 0) {
+ auto msg = _("setreuid(): 正しく許可が取れません! エラーコード:%d", "setreuid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
- if (setregid(getegid(), getgid()) != 0) {
- quit(_("setregid(): 正しく許可が取れません!", "setregid(): cannot set permissions correctly!"));
+
+ if (auto ret = setregid(getegid(), getgid()); ret != 0) {
+ auto msg = _("setregid(): 正しく許可が取れません! エラーコード:%d", "setregid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
#endif
#endif
-#endif
}
/*!
- * @brief ファイルのグラブパーミッションチェック / Hack -- grab permissions
+ * @brief ファイルのグラブパーミッションチェック / Check grab permissions
+ * @param プレイヤーへの参照ポインタ
*/
void safe_setuid_grab(PlayerType *player_ptr)
{
-#ifdef SET_UID
-#ifdef SAFE_SETUID
+#if defined(SET_UID) && defined(SAFE_SETUID)
#ifdef SAFE_SETUID_POSIX
-
- if (setuid(player_ptr->player_euid) != 0) {
- quit(_("setuid(): 正しく許可が取れません!", "setuid(): cannot set permissions correctly!"));
+ if (auto ret = setuid(player_ptr->player_euid); ret != 0) {
+ auto msg = _("setuid(): 正しく許可が取れません! エラーコード:%d", "setuid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
- if (setgid(player_ptr->player_egid) != 0) {
- quit(_("setgid(): 正しく許可が取れません!", "setgid(): cannot set permissions correctly!"));
+
+ if (auto ret = setgid(player_ptr->player_egid); ret != 0) {
+ auto msg = _("setgid(): 正しく許可が取れません! エラーコード:%d", "setgid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
#else
(void)player_ptr;
-
- if (setreuid(geteuid(), getuid()) != 0) {
- quit(_("setreuid(): 正しく許可が取れません!", "setreuid(): cannot set permissions correctly!"));
+ if (auto ret = setreuid(geteuid(), getuid()); ret != 0) {
+ auto msg = _("setreuid(): 正しく許可が取れません! エラーコード:%d", "setreuid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
- if (setregid(getegid(), getgid()) != 0) {
- quit(_("setregid(): 正しく許可が取れません!", "setregid(): cannot set permissions correctly!"));
+
+ if (auto ret = setregid(getegid(), getgid()); ret != 0) {
+ auto msg = _("setregid(): 正しく許可が取れません! エラーコード:%d", "setregid(): cannot set permissions correctly! Error code: %d");
+ quit(format(msg, ret));
}
#endif
-#endif
#else
(void)player_ptr;
#endif
#include "load/angband-version-comparer.h"
+#include "system/angband-version.h"
#include "world/world.h"
/*!
*/
bool h_older_than(byte major, byte minor, byte patch, byte extra)
{
- if (w_ptr->h_ver_major < major)
+ if (VARIANT_NAME != ROOT_VARIANT_NAME) {
+ return false;
+ }
+
+ if (w_ptr->h_ver_major < major) {
return true;
- if (w_ptr->h_ver_major > major)
+ }
+ if (w_ptr->h_ver_major > major) {
return false;
+ }
- if (w_ptr->h_ver_minor < minor)
+ if (w_ptr->h_ver_minor < minor) {
return true;
- if (w_ptr->h_ver_minor > minor)
+ }
+ if (w_ptr->h_ver_minor > minor) {
return false;
+ }
- if (w_ptr->h_ver_patch < patch)
+ if (w_ptr->h_ver_patch < patch) {
return true;
- if (w_ptr->h_ver_patch > patch)
+ }
+ if (w_ptr->h_ver_patch > patch) {
return false;
+ }
- if (w_ptr->h_ver_extra < extra)
+ if (w_ptr->h_ver_extra < extra) {
return true;
- if (w_ptr->h_ver_extra > extra)
+ }
+ if (w_ptr->h_ver_extra > extra) {
return false;
+ }
return false;
}
*/
bool h_older_than(byte major, byte minor, byte patch)
{
- if (w_ptr->h_ver_major < major)
+ if (VARIANT_NAME != ROOT_VARIANT_NAME) {
+ return false;
+ }
+
+ if (w_ptr->h_ver_major < major) {
return true;
- if (w_ptr->h_ver_major > major)
+ }
+ if (w_ptr->h_ver_major > major) {
return false;
+ }
- if (w_ptr->h_ver_minor < minor)
+ if (w_ptr->h_ver_minor < minor) {
return true;
- if (w_ptr->h_ver_minor > minor)
+ }
+ if (w_ptr->h_ver_minor > minor) {
return false;
+ }
- if (w_ptr->h_ver_patch < patch)
+ if (w_ptr->h_ver_patch < patch) {
return true;
- if (w_ptr->h_ver_patch > patch)
+ }
+ if (w_ptr->h_ver_patch > patch) {
return false;
+ }
return false;
}
#include "load/angband-version-comparer.h"
#include "load/load-util.h"
#include "load/monster/monster-loader-factory.h"
-#include "load/old/monster-loader-savefile10.h"
+#include "load/old/monster-loader-savefile50.h"
#include "system/floor-type-definition.h"
#include "system/monster-type-definition.h"
#include "system/player-type-definition.h"
#include "load/angband-version-comparer.h"
#include "load/item/item-loader-factory.h"
#include "load/load-util.h"
-#include "load/old-feature-types.h"
#include "load/monster/monster-loader-factory.h"
-#include "load/old/item-loader-savefile10.h"
+#include "load/old-feature-types.h"
+#include "load/old/item-loader-savefile50.h"
#include "load/old/load-v1-5-0.h"
-#include "load/old/monster-loader-savefile10.h"
+#include "load/old/monster-loader-savefile50.h"
#include "monster-race/monster-race.h"
#include "monster/monster-info.h"
#include "monster/monster-list.h"
*/
void rd_version_info(void)
{
- byte fake_major = rd_byte();
+ auto tmp_major = rd_byte();
+ auto is_old_ver = (10 <= tmp_major) && (tmp_major <= 13);
+ auto variant_length = VARIANT_NAME.length();
+ if (tmp_major == variant_length) {
+ strip_bytes(variant_length);
+ load_xor_byte = 0;
+ w_ptr->h_ver_major = rd_byte();
+ w_ptr->h_ver_minor = rd_byte();
+ w_ptr->h_ver_patch = rd_byte();
+ w_ptr->h_ver_extra = rd_byte();
+ strip_bytes(1);
+ } else if (is_old_ver) {
+ strip_bytes(3);
+ } else {
+ throw("Invalid version is detected!");
+ }
- strip_bytes(3);
load_xor_byte = w_ptr->sf_extra;
v_check = 0L;
x_check = 0L;
- /* Old savefile will be version 0.0.0.3 */
- w_ptr->h_ver_extra = rd_byte();
- w_ptr->h_ver_patch = rd_byte();
- w_ptr->h_ver_minor = rd_byte();
- w_ptr->h_ver_major = rd_byte();
+ if (is_old_ver) {
+ /* Old savefile will be version 0.0.0.3 */
+ w_ptr->h_ver_extra = rd_byte();
+ w_ptr->h_ver_patch = rd_byte();
+ w_ptr->h_ver_minor = rd_byte();
+ w_ptr->h_ver_major = rd_byte();
+ }
w_ptr->sf_system = rd_u32b();
w_ptr->sf_when = rd_u32b();
loading_savefile_version = rd_u32b();
/* h_ver_majorがfake_ver_majorと同じだったころへの対策 */
- if (fake_major - w_ptr->h_ver_major < FAKE_VER_PLUS)
- w_ptr->h_ver_major -= FAKE_VER_PLUS;
+ if (loading_savefile_version_is_older_than(10)) {
+ constexpr auto fake_ver_plus = 10;
+ if (tmp_major - w_ptr->h_ver_major < fake_ver_plus) {
+ w_ptr->h_ver_major -= fake_ver_plus;
+ }
+ }
load_note(format(_("バージョン %d.%d.%d のセーブデータ(SAVE%lu形式)をロード中...", "Loading a Verison %d.%d.%d savefile (SAVE%lu format)..."),
w_ptr->h_ver_major, w_ptr->h_ver_minor, w_ptr->h_ver_patch,
#include "inventory/inventory-slot-types.h"
#include "load/item/item-loader-factory.h"
#include "load/load-util.h"
-#include "load/old/item-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
#include "object/object-mark-types.h"
#include "system/object-type-definition.h"
#include "system/player-type-definition.h"
#include "load/item/item-loader-base.h"
#include "load/item/item-loader-version-types.h"
#include "load/load-util.h"
-#include "load/old/item-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
/*!
* @brief アイテム読み込みクラスを返却する.
{
auto version = get_version();
switch (version) {
- case ItemLoaderVersionType::LOAD10:
- return std::make_shared<ItemLoader10>();
- case ItemLoaderVersionType::LOAD11:
+ case ItemLoaderVersionType::LOAD50:
+ return std::make_shared<ItemLoader50>();
+ case ItemLoaderVersionType::LOAD51:
// dummy yet.
default:
throw("Invalid loader version was specified!");
* @brief ItemLoaderのバージョン切り替え.
* @return セーブファイルバージョン群の中で互換性のある最古のバージョン.
* @details (備忘録)例えばバージョン15で更に変更された場合、以下のように書き換えること.
- *
+ *
* if (loading_savefile_version_is_older_than(15)) {
* return ItemLoaderVersionType::LOAD11;
* } else if (loading_savefile_version_is_older_than(11)) {
*/
ItemLoaderVersionType ItemLoaderFactory::get_version()
{
- if (loading_savefile_version_is_older_than(11)) {
- return ItemLoaderVersionType::LOAD10;
+ if (loading_savefile_version_is_older_than(51)) {
+ return ItemLoaderVersionType::LOAD50;
} else {
- return ItemLoaderVersionType::LOAD11;
+ return ItemLoaderVersionType::LOAD51;
}
}
#pragma once
enum class ItemLoaderVersionType {
- LOAD10,
- LOAD11,
+ LOAD50,
+ LOAD51,
};
#include "load/load-util.h"
#include "load/load-zangband.h"
#include "load/lore-loader.h"
-#include "load/old/item-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
#include "load/old/load-v1-5-0.h"
#include "load/old/load-v1-7-0.h"
#include "load/option-loader.h"
#include "util/enum-converter.h"
#include "view/display-messages.h"
#include "world/world.h"
+#include <sstream>
+#include <string>
/*!
* @brief 変愚蛮怒 v2.1.3で追加された街とクエストについて読み込む
*/
static errr load_town_quest(PlayerType *player_ptr)
{
- if (h_older_than(2, 1, 3))
+ if (h_older_than(2, 1, 3)) {
return 0;
+ }
- errr load_town_result = load_town();
- if (load_town_result != 0)
+ auto load_town_result = load_town();
+ if (load_town_result != 0) {
return load_town_result;
+ }
uint16_t max_quests_load;
byte max_rquests_load;
- errr load_quest_result = load_quest_info(&max_quests_load, &max_rquests_load);
- if (load_quest_result != 0)
+ auto load_quest_result = load_quest_info(&max_quests_load, &max_rquests_load);
+ if (load_quest_result != 0) {
return load_quest_result;
+ }
analyze_quests(player_ptr, max_quests_load, max_rquests_load);
*/
static void rd_total_play_time()
{
- if (loading_savefile_version_is_older_than(4))
+ if (loading_savefile_version_is_older_than(4)) {
return;
+ }
w_ptr->sf_play_time = rd_u32b();
}
*/
static void rd_winner_class()
{
- if (loading_savefile_version_is_older_than(4))
+ if (loading_savefile_version_is_older_than(4)) {
return;
+ }
rd_FlagGroup(w_ptr->sf_winner, rd_byte);
rd_FlagGroup(w_ptr->sf_retired, rd_byte);
rd_global_configurations(player_ptr);
rd_extra(player_ptr);
- if (player_ptr->energy_need < -999)
+ if (player_ptr->energy_need < -999) {
player_ptr->timewalk = true;
+ }
load_note(_("特別情報をロードしました", "Loaded extra information"));
}
return 25;
}
- for (int i = 0; i < tmp16u; i++) {
+ for (auto i = 0; i < tmp16u; i++) {
player_ptr->player_hp[i] = rd_s16b();
}
player_ptr->spell_worked2 = rd_u32b();
player_ptr->spell_forgotten1 = rd_u32b();
player_ptr->spell_forgotten2 = rd_u32b();
-
- if (h_older_than(0, 0, 5))
+ if (h_older_than(0, 0, 5)) {
set_zangband_learnt_spells(player_ptr);
- else
+ } else {
player_ptr->learned_spells = rd_s16b();
+ }
- if (h_older_than(0, 0, 6))
+ if (h_older_than(0, 0, 6)) {
player_ptr->add_spells = 0;
- else
+ } else {
player_ptr->add_spells = rd_s16b();
+ }
}
static errr verify_checksum()
{
auto n_v_check = v_check;
- if (rd_u32b() == n_v_check)
+ if (rd_u32b() == n_v_check) {
return 0;
+ }
load_note(_("チェックサムがおかしい", "Invalid checksum"));
return 11;
static errr verify_encoded_checksum()
{
auto n_x_check = x_check;
- if (rd_u32b() == n_x_check)
+ if (rd_u32b() == n_x_check) {
return 0;
+ }
load_note(_("エンコードされたチェックサムがおかしい", "Invalid encoded checksum"));
return 11;
load_lore();
auto item_loader = ItemLoaderFactory::create_loader();
item_loader->load_item();
- errr load_town_quest_result = load_town_quest(player_ptr);
- if (load_town_quest_result != 0)
+ auto load_town_quest_result = load_town_quest(player_ptr);
+ if (load_town_quest_result != 0) {
return load_town_quest_result;
+ }
load_note(_("クエスト情報をロードしました", "Loaded Quests"));
item_loader->load_artifact();
load_player_world(player_ptr);
- errr load_hp_result = load_hp(player_ptr);
- if (load_hp_result != 0)
+ auto load_hp_result = load_hp(player_ptr);
+ if (load_hp_result != 0) {
return load_hp_result;
+ }
auto short_pclass = enum2i(player_ptr->pclass);
sp_ptr = &sex_info[player_ptr->psex];
mp_ptr = &m_info[short_pclass];
load_spells(player_ptr);
- if (player_ptr->pclass == PlayerClassType::MINDCRAFTER)
+ if (player_ptr->pclass == PlayerClassType::MINDCRAFTER) {
player_ptr->add_spells = 0;
+ }
- errr load_inventory_result = load_inventory(player_ptr);
- if (load_inventory_result != 0)
+ auto load_inventory_result = load_inventory(player_ptr);
+ if (load_inventory_result != 0) {
return load_inventory_result;
+ }
load_store(player_ptr);
player_ptr->pet_follow_distance = rd_s16b();
- if (h_older_than(0, 4, 10))
+ if (h_older_than(0, 4, 10)) {
set_zangband_pet(player_ptr);
- else
+ } else {
player_ptr->pet_extra_flags = rd_u16b();
+ }
if (!h_older_than(1, 0, 9)) {
std::vector<char> buf(SCREEN_BUF_MAX_SIZE);
rd_string(buf.data(), SCREEN_BUF_MAX_SIZE);
- if (buf[0])
+ if (buf[0]) {
screen_dump = string_make(buf.data());
+ }
}
- errr restore_dungeon_result = restore_dungeon(player_ptr);
- if (restore_dungeon_result != 0)
+ auto restore_dungeon_result = restore_dungeon(player_ptr);
+ if (restore_dungeon_result != 0) {
return restore_dungeon_result;
+ }
- if (h_older_than(1, 7, 0, 6))
+ if (h_older_than(1, 7, 0, 6)) {
remove_water_cave(player_ptr);
+ }
- errr checksum_result = verify_checksum();
- if (checksum_result != 0)
+ auto checksum_result = verify_checksum();
+ if (checksum_result != 0) {
return checksum_result;
+ }
return verify_encoded_checksum();
}
safe_setuid_grab(player_ptr);
loading_savefile = angband_fopen(savefile, "rb");
safe_setuid_drop();
- if (!loading_savefile)
+ if (!loading_savefile) {
return -1;
+ }
errr err = exe_reading_savefile(player_ptr);
- if (ferror(loading_savefile))
+ if (ferror(loading_savefile)) {
err = -1;
+ }
angband_fclose(loading_savefile);
return err;
*/
bool load_savedata(PlayerType *player_ptr, bool *new_game)
{
- concptr what = "generic";
+ auto what = "generic";
w_ptr->game_turn = 0;
player_ptr->is_dead = false;
- if (!savefile[0])
+ if (!savefile[0]) {
return true;
+ }
#ifndef WINDOWS
if (access(savefile, 0) < 0) {
}
#endif
- bool err = false;
- int fd = -1;
- byte fake_ver[4];
+ auto err = false;
+ auto fd = -1;
+
+ // バリアント名長1バイト+バージョン番号4バイト+セーブファイルエンコードキー1バイト == 6バイト.
+ constexpr auto variant_length = static_cast<char>(VARIANT_NAME.length());
+ constexpr auto version_length = variant_length + 6;
+ char tmp_ver[version_length]{};
if (!err) {
fd = fd_open(savefile, O_RDONLY);
- if (fd < 0)
+ if (fd < 0) {
err = true;
+ }
- if (err)
+ if (err) {
what = _("セーブファイルを開けません", "Cannot open savefile");
+ }
}
if (!err) {
- if (fd_read(fd, (char *)(fake_ver), 4))
+ if (fd_read(fd, tmp_ver, version_length)) {
err = true;
+ }
- if (err)
+ if (err) {
what = _("セーブファイルを読めません", "Cannot read savefile");
-
- (void)fd_close(fd);
+ }
}
if (!err) {
- if (fake_ver[0] < FAKE_VER_PLUS) {
- what = _("セーブデータが古すぎます", "Savefile version is too old");
- err = true;
+ // v0.0.X~v3.0.0 Alpha51までは、セーブデータの第1バイトがFAKE_MAJOR_VERというZangbandと互換性を取ったバージョン番号フィールドだった.
+ // v3.0.0 Alpha52以降は、バリアント名の長さフィールドとして再定義した.
+ // 10~13はその名残。変愚蛮怒から更にバリアントを切ったらこの評価は不要.
+ auto tmp_major = tmp_ver[0];
+ auto is_old_ver = (10 <= tmp_major) && (tmp_major <= 13);
+ if (tmp_major == variant_length) {
+ if (std::string_view(&tmp_ver[1], variant_length) != VARIANT_NAME) {
+ throw(_("セーブデータのバリアントは変愚蛮怒以外です", "The variant of save data is other than Hengband!"));
+ }
+
+ w_ptr->sf_extra = tmp_ver[version_length - 1];
+ (void)fd_close(fd);
+ } else if (is_old_ver) {
+ w_ptr->sf_extra = tmp_ver[3];
+ (void)fd_close(fd);
+ } else {
+ (void)fd_close(fd);
+ throw("Invalid version is detected!");
}
}
return false;
}
- w_ptr->sf_extra = fake_ver[3];
-
if (!err) {
term_clear();
- if (rd_savefile(player_ptr))
+ if (rd_savefile(player_ptr)) {
err = true;
- if (err)
+ }
+
+ if (err) {
what = _("セーブファイルを解析出来ません。", "Cannot parse savefile");
+ }
}
if (!err) {
- if (!w_ptr->game_turn)
+ if (!w_ptr->game_turn) {
err = true;
+ }
- if (err)
+ if (err) {
what = _("セーブファイルが壊れています", "Broken savefile");
+ }
}
if (err) {
msg_format(_("エラー(%s)がバージョン%d.%d.%d.%d 用セーブファイル読み込み中に発生。", "Error (%s) reading %d.%d.%d.% savefile."), what,
w_ptr->h_ver_major, w_ptr->h_ver_minor, w_ptr->h_ver_patch, w_ptr->h_ver_extra);
-
msg_print(nullptr);
return false;
}
msg_print(nullptr);
return false;
}
+
player_ptr->is_dead = true;
player_ptr->wait_report_score = false;
}
}
w_ptr->character_loaded = true;
- uint32_t tmp = counts_read(player_ptr, 2);
+ auto tmp = counts_read(player_ptr, 2);
if (tmp > player_ptr->count)
player_ptr->count = tmp;
- if (counts_read(player_ptr, 0) > w_ptr->play_time || counts_read(player_ptr, 1) == w_ptr->play_time)
+ if (counts_read(player_ptr, 0) > w_ptr->play_time || counts_read(player_ptr, 1) == w_ptr->play_time) {
counts_write(player_ptr, 2, ++player_ptr->count);
+ }
counts_write(player_ptr, 1, w_ptr->play_time);
return true;
#include "load/old/load-v1-5-0.h"
#include "load/savedata-old-flag-types.h"
#include "monster-race/monster-race.h"
+#include "monster-race/race-flags1.h"
+#include "monster-race/race-flags2.h"
+#include "monster-race/race-flags7.h"
#include "system/angband.h"
#include "system/monster-race-definition.h"
#include "util/bit-flags-calculator.h"
rd_FlagGroup(r_ptr->r_aura_flags, rd_byte);
}
+static void rd_r_behavior_flags(monster_race *r_ptr)
+{
+ if (loading_savefile_version_is_older_than(11)) {
+ struct flag_list_ver11 {
+ BIT_FLAGS check_flag;
+ MonsterBehaviorType flag;
+ };
+
+ const std::vector<flag_list_ver11> flag1 = {
+ { RF1_NEVER_BLOW, MonsterBehaviorType::NEVER_BLOW },
+ { RF1_NEVER_MOVE, MonsterBehaviorType::NEVER_MOVE },
+ { RF1_RAND_25, MonsterBehaviorType::RAND_MOVE_25 },
+ { RF1_RAND_50, MonsterBehaviorType::RAND_MOVE_50 },
+ };
+
+ const std::vector<flag_list_ver11> flag2 = {
+ { RF2_OPEN_DOOR, MonsterBehaviorType::OPEN_DOOR },
+ { RF2_BASH_DOOR, MonsterBehaviorType::BASH_DOOR },
+ { RF2_MOVE_BODY, MonsterBehaviorType::MOVE_BODY },
+ { RF2_KILL_BODY, MonsterBehaviorType::KILL_BODY },
+ { RF2_TAKE_ITEM, MonsterBehaviorType::TAKE_ITEM },
+ { RF2_KILL_ITEM, MonsterBehaviorType::KILL_ITEM },
+ { RF2_STUPID, MonsterBehaviorType::STUPID },
+ { RF2_SMART, MonsterBehaviorType::SMART },
+ };
+
+ for (const auto &f : flag1)
+ if (any_bits(r_ptr->r_flags1, f.check_flag))
+ r_ptr->r_behavior_flags.set(f.flag);
+
+ for (const auto &f : flag2)
+ if (any_bits(r_ptr->r_flags2, f.check_flag))
+ r_ptr->r_behavior_flags.set(f.flag);
+
+ return;
+ }
+
+ rd_FlagGroup(r_ptr->r_behavior_flags, rd_byte);
+}
+
/*!
* @brief モンスターの思い出を読み込む / Read the monster lore
* @param r_ptr 読み込み先モンスター種族情報へのポインタ
migrate_old_aura_flags(r_ptr);
rd_r_ability_flags(r_ptr, r_idx);
rd_r_aura_flags(r_ptr);
+ rd_r_behavior_flags(r_ptr);
r_ptr->max_num = rd_byte();
r_ptr->floor_id = rd_s16b();
r_ptr->r_flagsr &= r_ptr->flagsr;
r_ptr->r_ability_flags &= r_ptr->ability_flags;
r_ptr->r_aura_flags &= r_ptr->aura_flags;
+ r_ptr->r_behavior_flags &= r_ptr->r_behavior_flags;
}
void load_lore(void)
* @author Hourier
*/
-#include "load/monster/monster-loader-base.h"
#include "load/monster/monster-loader-factory.h"
-#include "load/monster/monster-loader-version-types.h"
#include "load/load-util.h"
-#include "load/old/monster-loader-savefile10.h"
+#include "load/monster/monster-loader-base.h"
+#include "load/monster/monster-loader-version-types.h"
+#include "load/old/monster-loader-savefile50.h"
/*!
* @brief アイテム読み込みクラスを返却する.
{
auto version = get_version();
switch (version) {
- case MonsterLoaderVersionType::LOAD10:
- return std::make_shared<MonsterLoader10>(player_ptr);
- case MonsterLoaderVersionType::LOAD11:
+ case MonsterLoaderVersionType::LOAD50:
+ return std::make_shared<MonsterLoader50>(player_ptr);
+ case MonsterLoaderVersionType::LOAD51:
// dummy yet.
default:
throw("Invalid loader version was specified!");
* @brief MonsterLoaderのバージョン切り替え.
* @return セーブファイルバージョン群の中で互換性のある最古のバージョン.
* @details (備忘録)例えばバージョン15で更に変更された場合、以下のように書き換えること.
- *
+ *
* if (loading_savefile_version_is_older_than(15)) {
* return MonsterLoaderVersionType::LOAD11;
* } else if (loading_savefile_version_is_older_than(11)) {
*/
MonsterLoaderVersionType MonsterLoaderFactory::get_version()
{
- if (loading_savefile_version_is_older_than(11)) {
- return MonsterLoaderVersionType::LOAD10;
+ if (loading_savefile_version_is_older_than(51)) {
+ return MonsterLoaderVersionType::LOAD50;
} else {
- return MonsterLoaderVersionType::LOAD11;
+ return MonsterLoaderVersionType::LOAD51;
}
}
#pragma once
enum class MonsterLoaderVersionType {
- LOAD10,
- LOAD11,
+ LOAD50,
+ LOAD51,
};
-#include "load/old/item-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
#include "artifact/fixed-art-types.h"
#include "game-option/runtime-arguments.h"
#include "load/angband-version-comparer.h"
#include "load/load-util.h"
+#include "load/old/item-flag-types-savefile50.h"
#include "load/old/load-v1-5-0.h"
-#include "load/old/item-flag-types-savefile10.h"
#include "load/savedata-old-flag-types.h"
#include "object-enchant/object-ego.h"
#include "object-enchant/tr-types.h"
#include "util/quarks.h"
/*!
- * @brief アイテムオブジェクトを読み込む(v3.0.0 Savefile ver10まで)
+ * @brief アイテムオブジェクトを読み込む(v3.0.0 Savefile ver50まで)
* @param o_ptr アイテムオブジェクト保存先ポインタ
*/
-void ItemLoader10::rd_item(object_type *o_ptr)
+void ItemLoader50::rd_item(object_type *o_ptr)
{
if (h_older_than(1, 5, 0, 0)) {
rd_item_old(o_ptr);
#include "load/item/item-loader-base.h"
struct object_type;
-class ItemLoader10 : public ItemLoaderBase {
+class ItemLoader50 : public ItemLoaderBase {
public:
- ItemLoader10() = default;
+ ItemLoader50() = default;
void rd_item(object_type *o_ptr) override;
};
#include "load/load-util.h"
#include "load/monster/monster-loader-factory.h"
#include "load/old-feature-types.h"
-#include "load/old/item-loader-savefile10.h"
-#include "load/old/monster-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
+#include "load/old/monster-loader-savefile50.h"
#include "mind/mind-weaponsmith.h"
#include "monster-floor/monster-move.h"
#include "monster-race/monster-race.h"
-#include "load/old/monster-loader-savefile10.h"
+#include "load/old/monster-loader-savefile50.h"
#include "load/angband-version-comparer.h"
#include "load/load-util.h"
#include "load/old/load-v1-5-0.h"
-#include "load/old/monster-flag-types-savefile10.h"
+#include "load/old/monster-flag-types-savefile50.h"
#include "system/monster-type-definition.h"
#include "system/player-type-definition.h"
#include "util/bit-flags-calculator.h"
#include "util/enum-converter.h"
#include "util/quarks.h"
-MonsterLoader10::MonsterLoader10(PlayerType *player_ptr)
+MonsterLoader50::MonsterLoader50(PlayerType *player_ptr)
: player_ptr(player_ptr)
{
}
/*!
- * @brief モンスターを読み込む(v3.0.0 Savefile ver10まで)
+ * @brief モンスターを読み込む(v3.0.0 Savefile ver50まで)
*/
-void MonsterLoader10::rd_monster(monster_type *m_ptr_)
+void MonsterLoader50::rd_monster(monster_type *m_ptr_)
{
this->m_ptr = m_ptr_;
if (h_older_than(1, 5, 0, 0)) {
struct monster_type;
class PlayerType;
-class MonsterLoader10 : public MonsterLoaderBase {
+class MonsterLoader50 : public MonsterLoaderBase {
public:
- MonsterLoader10(PlayerType *player_ptr);
+ MonsterLoader50(PlayerType *player_ptr);
void rd_monster(monster_type *m_ptr) override;
private:
#include "load/angband-version-comparer.h"
#include "load/item/item-loader-factory.h"
#include "load/load-util.h"
-#include "load/old/item-loader-savefile10.h"
+#include "load/old/item-loader-savefile50.h"
#include "object/object-stack.h"
#include "object/object-value.h"
#include "store/store.h"
if (!lore_ptr->know_everything)
return;
- lore_ptr->drop_gold = lore_ptr->drop_item = (((lore_ptr->r_ptr->flags1 & RF1_DROP_4D2) ? 8 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_3D2) ? 6 : 0)
- + ((lore_ptr->r_ptr->flags1 & RF1_DROP_2D2) ? 4 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_1D2) ? 2 : 0)
- + ((lore_ptr->r_ptr->flags1 & RF1_DROP_90) ? 1 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_60) ? 1 : 0));
+ lore_ptr->drop_gold = lore_ptr->drop_item = (((lore_ptr->r_ptr->flags1 & RF1_DROP_4D2) ? 8 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_3D2) ? 6 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_2D2) ? 4 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_1D2) ? 2 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_90) ? 1 : 0) + ((lore_ptr->r_ptr->flags1 & RF1_DROP_60) ? 1 : 0));
if (lore_ptr->r_ptr->flags1 & RF1_ONLY_GOLD)
lore_ptr->drop_item = 0;
lore_ptr->flags3 = lore_ptr->r_ptr->flags3;
lore_ptr->ability_flags = lore_ptr->r_ptr->ability_flags;
lore_ptr->aura_flags = lore_ptr->r_ptr->aura_flags;
+ lore_ptr->behavior_flags = lore_ptr->r_ptr->behavior_flags;
lore_ptr->flagsr = lore_ptr->r_ptr->flagsr;
}
#include "lore/lore-store.h"
#include "core/window-redrawer.h"
-#include "monster-race/race-flags1.h"
#include "monster-race/monster-race.h"
+#include "monster-race/race-flags1.h"
#include "monster/monster-info.h"
#include "system/floor-type-definition.h"
#include "system/monster-race-definition.h"
}
}
- byte tmp_byte = (((r_ptr->flags1 & RF1_DROP_4D2) ? 8 : 0) + ((r_ptr->flags1 & RF1_DROP_3D2) ? 6 : 0) + ((r_ptr->flags1 & RF1_DROP_2D2) ? 4 : 0)
- + ((r_ptr->flags1 & RF1_DROP_1D2) ? 2 : 0) + ((r_ptr->flags1 & RF1_DROP_90) ? 1 : 0) + ((r_ptr->flags1 & RF1_DROP_60) ? 1 : 0));
+ byte tmp_byte = (((r_ptr->flags1 & RF1_DROP_4D2) ? 8 : 0) + ((r_ptr->flags1 & RF1_DROP_3D2) ? 6 : 0) + ((r_ptr->flags1 & RF1_DROP_2D2) ? 4 : 0) + ((r_ptr->flags1 & RF1_DROP_1D2) ? 2 : 0) + ((r_ptr->flags1 & RF1_DROP_90) ? 1 : 0) + ((r_ptr->flags1 & RF1_DROP_60) ? 1 : 0));
if (!(r_ptr->flags1 & RF1_ONLY_GOLD)) {
if (r_ptr->r_drop_item != tmp_byte)
auto ability_flags = r_ptr->ability_flags;
n += ability_flags.reset(r_ptr->r_ability_flags).count();
+ auto behavior_flags = r_ptr->behavior_flags;
+ n += behavior_flags.reset(r_ptr->r_behavior_flags).count();
+
r_ptr->r_flags1 = r_ptr->flags1;
r_ptr->r_flags2 = r_ptr->flags2;
r_ptr->r_flags3 = r_ptr->flags3;
r_ptr->r_flagsr = r_ptr->flagsr;
r_ptr->r_ability_flags = r_ptr->ability_flags;
+ r_ptr->r_behavior_flags = r_ptr->behavior_flags;
if (!r_ptr->r_can_evolve)
n++;
lore_ptr->flags3 = (lore_ptr->r_ptr->flags3 & lore_ptr->r_ptr->r_flags3);
lore_ptr->ability_flags = (lore_ptr->r_ptr->ability_flags & lore_ptr->r_ptr->r_ability_flags);
lore_ptr->aura_flags = (lore_ptr->r_ptr->aura_flags & lore_ptr->r_ptr->r_aura_flags);
+ lore_ptr->behavior_flags = (lore_ptr->r_ptr->behavior_flags & lore_ptr->r_ptr->r_behavior_flags);
lore_ptr->flags7 = (lore_ptr->r_ptr->flags7 & lore_ptr->r_ptr->flags7);
lore_ptr->flagsr = (lore_ptr->r_ptr->flagsr & lore_ptr->r_ptr->r_flagsr);
lore_ptr->reinforce = false;
* @brief モンスターの思い出メッセージをあらかじめ指定された関数ポインタに基づき出力する
* @param str 出力文字列
*/
-void hooked_roff(concptr str) { hook_c_roff(TERM_WHITE, str); }
+void hooked_roff(concptr str)
+{
+ hook_c_roff(TERM_WHITE, str);
+}
#pragma once
-#include "system/angband.h"
#include "monster-attack/monster-attack-types.h"
#include "monster-race/monster-aura-types.h"
#include "monster-race/race-ability-flags.h"
+#include "monster-race/race-behavior-flags.h"
+#include "monster-race/race-visual-flags.h"
+#include "system/angband.h"
#include "util/flag-group.h"
#include <string>
#include <unordered_map>
};
struct monster_race;
-typedef struct lore_type {
+struct lore_type {
#ifdef JP
char jverb_buf[64];
#else
BIT_FLAGS flags3;
EnumClassFlagGroup<MonsterAbilityType> ability_flags;
EnumClassFlagGroup<MonsterAuraType> aura_flags;
+ EnumClassFlagGroup<MonsterBehaviorType> behavior_flags;
+ EnumClassFlagGroup<MonsterVisualType> visual_flags;
BIT_FLAGS flags7;
BIT_FLAGS flagsr;
int count;
bool shoot = false;
bool rocket = false;
-} lore_type;
+};
enum monster_lore_mode {
MONSTER_LORE_NONE,
lore_type *initialize_lore_type(lore_type *lore_ptr, MONRACE_IDX r_idx, monster_lore_mode mode);
void hooked_roff(concptr str);
-enum WHO_WORD_TYPE { WHO = 0, WHOSE = 1, WHOM = 2 };
+enum WHO_WORD_TYPE { WHO = 0,
+ WHOSE = 1,
+ WHOM = 2 };
using who_word_definition = std::unordered_map<WHO_WORD_TYPE, const std::unordered_map<bool, const std::unordered_map<monster_sex, std::string>>>;
class Who {
lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
}
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BR_VOID)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BR_VOID, _("虚無%s", "void%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BR_ABYSS)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BR_ABYSS, _("深淵%s", "abyss%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
}
void set_ball_types(PlayerType *player_ptr, lore_type *lore_ptr)
lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
}
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BA_VOID)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BA_VOID, _("虚無の嵐%s", "invoke void storms%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BA_ABYSS)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BA_ABYSS, _("深淵の嵐%s", "invoke abyss storms%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
}
void set_particular_types(PlayerType *player_ptr, lore_type *lore_ptr)
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BO_VOID)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BO_VOID, _("ヴォイド・ボルト%s", "produce void bolts%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
+
+ if (lore_ptr->ability_flags.has(MonsterAbilityType::BO_ABYSS)) {
+ set_damage(player_ptr, lore_ptr, MonsterAbilityType::BO_ABYSS, _("アビス・ボルト%s", "produce abyss bolts%s"));
+ lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+ lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+ }
+
if (lore_ptr->ability_flags.has(MonsterAbilityType::MISSILE)) {
set_damage(player_ptr, lore_ptr, MonsterAbilityType::MISSILE, _("マジックミサイル%s", "produce magic missiles%s"));
lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
*/
#include <curses.h>
+/**
+ * Simple rectangle type
+ */
+struct rect_s {
+ int x, y;
+ int cx, cy;
+};
+typedef struct rect_s rect_t, *rect_ptr;
+
+/* Trivial rectangle utility to make code a bit more readable */
+static rect_t rect(int x, int y, int cx, int cy)
+{
+ rect_t r;
+ r.x = x;
+ r.y = y;
+ r.cx = cx;
+ r.cy = cy;
+ return r;
+}
+
+/**
+ * Information about a term
+ */
struct term_data {
term_type t;
-
+ rect_t r;
WINDOW *win;
};
+/* Max number of windows on screen */
#define MAX_TERM_DATA 4
+/* Minimum main term size */
+#define MIN_TERM0_LINES 24
+#define MIN_TERM0_COLS 80
+
+/* Information about our windows */
static term_data data[MAX_TERM_DATA];
/*
* Simple Angband to Curses color conversion table
*/
static int colortable[16];
+
+/**
+ * Background color we should draw with; either BLACK or DEFAULT
+ */
+static int bg_color = COLOR_BLACK;
+
#endif
/*
return (0);
}
+static int scale_color(int i, int j, int scale)
+{
+ return (angband_color_table[i][j] * (scale - 1) + 127) / 255;
+}
+
+static int create_color(int i, int scale)
+{
+ int r = scale_color(i, 1, scale);
+ int g = scale_color(i, 2, scale);
+ int b = scale_color(i, 3, scale);
+ int rgb = 16 + scale * scale * r + scale * g + b;
+ /* In the case of white and black we need to use the ANSI colors */
+ if (r == g && g == b) {
+ if (b == 0)
+ rgb = 0;
+ if (b == scale)
+ rgb = 15;
+ }
+ return rgb;
+}
+
/*
* React to changes
*/
#ifdef A_COLOR
- int i;
-
- /* Cannot handle color redefinition */
- if (!can_fix_color)
- return (0);
-
- /* Set the colors */
- for (i = 0; i < 16; i++) {
- /* Set one color (note scaling) */
- init_color(i, angband_color_table[i][1] * 1000 / 255, angband_color_table[i][2] * 1000 / 255, angband_color_table[i][3] * 1000 / 255);
+ if (!can_change_color()) {
+ if (COLORS == 256 || COLORS == 88) {
+ /* If we have more than 16 colors, find the best matches. These numbers
+ * correspond to xterm/rxvt's builtin color numbers--they do not
+ * correspond to curses' constants OR with curses' color pairs.
+ *
+ * XTerm has 216 (6*6*6) RGB colors, with each RGB setting 0-5.
+ * RXVT has 64 (4*4*4) RGB colors, with each RGB setting 0-3.
+ *
+ * Both also have the basic 16 ANSI colors, plus some extra grayscale
+ * colors which we do not use.
+ */
+ int scale = COLORS == 256 ? 6 : 4;
+ for (int i = 0; i < 16; i++) {
+ int fg = create_color(i, scale);
+ init_pair(i + 1, fg, bg_color);
+ colortable[i] = COLOR_PAIR(i + 1) | A_NORMAL;
+ }
+ }
+ } else {
+ for (int i = 0; i < 16; ++i) {
+ init_color(i,
+ (angband_color_table[i][1] * 1000) / 255,
+ (angband_color_table[i][2] * 1000) / 255,
+ (angband_color_table[i][3] * 1000) / 255);
+ }
}
#endif
(void)wrefresh(td->win);
return (0);
-#ifdef USE_CURS_SET
-
/* Change the cursor visibility */
case TERM_XTRA_SHAPE:
curs_set(v);
return (0);
-#endif
-
/* Suspend/Resume curses */
case TERM_XTRA_ALIVE:
return (Term_xtra_gcu_alive(v));
return (0);
}
-static errr term_data_init(term_data *td, int rows, int cols, int y, int x)
+/**
+ * Create a window for the given "term_data" argument.
+ *
+ * Assumes legal arguments.
+ */
+static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x)
{
term_type *t = &td->t;
return (0);
}
+/**
+ * Simple helper
+ */
+static errr term_data_init(term_data *td)
+{
+ return term_data_init_gcu(td, td->r.cy, td->r.cx, td->r.y, td->r.x);
+}
+
+/* Parse 27,15,*x30 up to the 'x'. * gets converted to a big number
+ Parse 32,* until the end. Return count of numbers parsed */
+static int _parse_size_list(const char *arg, int sizes[], int max)
+{
+ int i = 0;
+ const char *start = arg;
+ const char *stop = arg;
+
+ for (;;) {
+ if (!*stop || !isdigit(*stop)) {
+ if (i >= max)
+ break;
+ if (*start == '*')
+ sizes[i] = 255;
+ else {
+ /* rely on atoi("23,34,*") -> 23
+ otherwise, copy [start, stop) into a new buffer first.*/
+ sizes[i] = atoi(start);
+ }
+ i++;
+ if (!*stop || *stop != ',')
+ break;
+
+ stop++;
+ start = stop;
+ } else
+ stop++;
+ }
+ return i;
+}
+
static void hook_quit(concptr str)
{
/* Unused */
/* Extract the normal keymap */
keymap_norm_prepare();
+ bool nobigscreen = false;
+
+ /* Parse args */
+ for (i = 1; i < argc; i++) {
+ if (prefix(argv[i], "-o")) {
+ nobigscreen = true;
+ }
+ }
+
/* Initialize for others systems */
if (initscr() == (WINDOW *)ERR)
return (-1);
keymap_game_prepare();
/*** Now prepare the term(s) ***/
- for (i = 0; i < num_term; i++) {
- int rows, cols;
- int y, x;
-
- switch (i) {
- /* Upper left */
- case 0:
- rows = 24;
- cols = 80;
- y = x = 0;
- break;
- /* Lower left */
- case 1:
- rows = LINES - 25;
- cols = 80;
- y = 24;
- x = 0;
- break;
- /* Upper right */
- case 2:
- rows = 24;
- cols = COLS - 81;
- y = 0;
- x = 81;
- break;
- /* Lower right */
- case 3:
- rows = LINES - 25;
- cols = COLS - 81;
- y = 24;
- x = 81;
- break;
- /* XXX */
- default:
- rows = cols = 0;
- y = x = 0;
- break;
- }
+ if (nobigscreen) {
+ /* Create several terms */
+ for (i = 0; i < num_term; i++) {
+ int rows, cols, y, x;
+
+ /* Decide on size and position */
+ switch (i) {
+ /* Upper left */
+ case 0: {
+ rows = 24;
+ cols = 80;
+ y = x = 0;
+ break;
+ }
- /* No non-windows */
- if (rows <= 0 || cols <= 0)
- continue;
+ /* Lower left */
+ case 1: {
+ rows = LINES - 25;
+ cols = 80;
+ y = 25;
+ x = 0;
+ break;
+ }
- /* Initialize */
- term_data_init(&data[next_win], rows, cols, y, x);
+ /* Upper right */
+ case 2: {
+ rows = 24;
+ cols = COLS - 81;
+ y = 0;
+ x = 81;
+ break;
+ }
- /* Store */
- angband_term[next_win] = Term;
+ /* Lower right */
+ case 3: {
+ rows = LINES - 25;
+ cols = COLS - 81;
+ y = 25;
+ x = 81;
+ break;
+ }
+
+ /* XXX */
+ default: {
+ rows = cols = y = x = 0;
+ break;
+ }
+ }
- next_win++;
+ /* Skip non-existant windows */
+ if (rows <= 0 || cols <= 0)
+ continue;
+
+ /* Create a term */
+ term_data_init_gcu(&data[next_win], rows, cols, y, x);
+
+ /* Remember the term */
+ angband_term[next_win] = &data[next_win].t;
+
+ /* One more window */
+ next_win++;
+ }
+ } else
+ /* Parse Args and Prepare the Terminals. Rectangles are specified
+ as Width x Height, right? The game will allow you to have two
+ strips of extra terminals, one on the right and one on the bottom.
+ The map terminal will than fit in as big as possible in the remaining
+ space.
+ Examples:
+ angband -mgcu -- -right 30x27,* -bottom *x7 will layout as
+ Term-0: Map (COLS-30)x(LINES-7) | Term-1: 30x27
+ --------------------------------|----------------------
+ <----Term-3: (COLS-30)x7------->| Term-2: 30x(LINES-27)
+ composband -mgcu -- -bottom *x7 -right 30x27,* will layout as
+ Term-0: Map (COLS-30)x(LINES-7) | Term-2: 30x27
+ |------------------------------
+ | Term-3: 30x(LINES-27)
+ ---------------------------------------------------------------
+ <----------Term-1: (COLS)x7----------------------------------->
+ Notice the effect on the bottom terminal by specifying its argument
+ second or first. Notice the sequence numbers for the various terminals
+ as you will have to blindly configure them in the window setup screen.
+ EDIT: Added support for -left and -top.
+ */
+ {
+ rect_t remaining = rect(0, 0, COLS, LINES);
+ int spacer_cx = 1;
+ int spacer_cy = 1;
+ int next_term = 1;
+ int term_ct = 1;
+
+ for (i = 1; i < argc; i++) {
+ if (streq(argv[i], "-spacer")) {
+ i++;
+ if (i >= argc)
+ quit("Missing size specifier for -spacer");
+ sscanf(argv[i], "%dx%d", &spacer_cx, &spacer_cy);
+ } else if (streq(argv[i], "-right") || streq(argv[i], "-left")) {
+ const char *arg, *tmp;
+ bool left = streq(argv[i], "-left");
+ int cx, cys[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
+
+ i++;
+ if (i >= argc)
+ quit(format("Missing size specifier for -%s", left ? "left" : "right"));
+
+ arg = argv[i];
+ tmp = strchr(arg, 'x');
+ if (!tmp)
+ quit(format("Expected something like -%s 60x27,* for two %s hand terminals of 60 columns, the first 27 lines and the second whatever is left.", left ? "left" : "right", left ? "left" : "right"));
+ cx = atoi(arg);
+ remaining.cx -= cx;
+ if (left) {
+ x = remaining.x;
+ y = remaining.y;
+ remaining.x += cx;
+ } else {
+ x = remaining.x + remaining.cx;
+ y = remaining.y;
+ }
+ remaining.cx -= spacer_cx;
+ if (left)
+ remaining.x += spacer_cx;
+
+ tmp++;
+ ct = _parse_size_list(tmp, cys, MAX_TERM_DATA);
+ for (j = 0; j < ct; j++) {
+ int cy = cys[j];
+ if (y + cy > remaining.y + remaining.cy)
+ cy = remaining.y + remaining.cy - y;
+ if (next_term >= MAX_TERM_DATA)
+ quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ if (cy <= 0) {
+ quit(format("Out of bounds in -%s: %d is too large (%d rows max for this strip)",
+ left ? "left" : "right", cys[j], remaining.cy));
+ }
+ data[next_term++].r = rect(x, y, cx, cy);
+ y += cy + spacer_cy;
+ term_ct++;
+ }
+ } else if (streq(argv[i], "-top") || streq(argv[i], "-bottom")) {
+ const char *arg, *tmp;
+ bool top = streq(argv[i], "-top");
+ int cy, cxs[MAX_TERM_DATA] = { 0 }, ct, j, x, y;
+
+ i++;
+ if (i >= argc)
+ quit(format("Missing size specifier for -%s", top ? "top" : "bottom"));
+
+ arg = argv[i];
+ tmp = strchr(arg, 'x');
+ if (!tmp)
+ quit(format("Expected something like -%s *x7 for a single %s terminal of 7 lines using as many columns as are available.", top ? "top" : "bottom", top ? "top" : "bottom"));
+ tmp++;
+ cy = atoi(tmp);
+ ct = _parse_size_list(arg, cxs, MAX_TERM_DATA);
+
+ remaining.cy -= cy;
+ if (top) {
+ x = remaining.x;
+ y = remaining.y;
+ remaining.y += cy;
+ } else {
+ x = remaining.x;
+ y = remaining.y + remaining.cy;
+ }
+ remaining.cy -= spacer_cy;
+ if (top)
+ remaining.y += spacer_cy;
+
+ tmp++;
+ for (j = 0; j < ct; j++) {
+ int cx = cxs[j];
+ if (x + cx > remaining.x + remaining.cx)
+ cx = remaining.x + remaining.cx - x;
+ if (next_term >= MAX_TERM_DATA)
+ quit(format("Too many terminals. Only %d are allowed.", MAX_TERM_DATA));
+ if (cx <= 0) {
+ quit(format("Out of bounds in -%s: %d is too large (%d cols max for this strip)",
+ top ? "top" : "bottom", cxs[j], remaining.cx));
+ }
+ data[next_term++].r = rect(x, y, cx, cy);
+ x += cx + spacer_cx;
+ term_ct++;
+ }
+ }
+ }
+
+ /* Map Terminal */
+ if (remaining.cx < MIN_TERM0_COLS || remaining.cy < MIN_TERM0_LINES)
+ quit(format("Failed: angband needs an %dx%d map screen, not %dx%d", MIN_TERM0_COLS, MIN_TERM0_LINES, remaining.cx, remaining.cy));
+ data[0].r = remaining;
+ term_data_init(&data[0]);
+ angband_term[0] = Term;
+
+ /* Child Terminals */
+ for (next_term = 1; next_term < term_ct; next_term++) {
+ term_data_init(&data[next_term]);
+ angband_term[next_term] = Term;
+ }
}
/* Activate the "Angband" window screen */
* 特定の名前のミューテックスオブジェクトの所有権取得を試みる。
* 取得できない場合は他に変愚蛮怒のプロセスが起動しているとみなす。
* 取得したミューテックスのハンドルは明示的な解放は行わず、プロセス終了時にOSが解放する。
- * @retval true 他に変愚蛮怒のプロセスが起動している
- * @retval false 他に変愚蛮怒のプロセスは起動していない
+ * @return 起動済の変愚蛮怒プロセス有無
*/
bool is_already_running(void)
{
- [[maybe_unused]] HANDLE hMutex = CreateMutexW(NULL, TRUE, L"" VERSION_NAME);
- if (GetLastError() == ERROR_ALREADY_EXISTS) {
- return true;
- }
-
- return false;
+ wchar_t wtext[32];
+ mbstowcs(wtext, VARIANT_NAME.data(), VARIANT_NAME.length());
+ [[maybe_unused]] HANDLE hMutex = CreateMutexW(NULL, TRUE, wtext);
+ return GetLastError() == ERROR_ALREADY_EXISTS;
}
/*!
#include "util/string-processor.h"
#include "view/display-scores.h"
#include "wizard/wizard-spoiler.h"
+#include <string>
/*
* Available graphic modes
mkdir(dirpath, 0700);
/* Build the path to the variant-specific sub-directory */
- path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
+ path_build(subdirpath, sizeof(subdirpath), dirpath, VARIANT_NAME.data());
/* Create the directory */
mkdir(subdirpath, 0700);
#ifdef USE_GCU
puts(" -mgcu To use GCU (GNU Curses)");
+ puts(" -- Sub options");
+ puts(" -- -o old subwindow layout (no bigscreen)");
#endif /* USE_GCU */
#ifdef USE_CAP
#include <dirent.h>
#include "util/string-processor.h"
#endif
+#ifdef PRIVATE_USER_PATH
+#include <string>
+#endif
/*!
* @brief 各データファイルを読み取るためのパスを取得する
path_build(buf, sizeof(buf), ANGBAND_DIR_SAVE, "log");
ANGBAND_DIR_DEBUG_SAVE = string_make(buf);
#ifdef PRIVATE_USER_PATH
- path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VERSION_NAME);
+ path_build(buf, sizeof(buf), PRIVATE_USER_PATH, VARIANT_NAME.data());
ANGBAND_DIR_USER = string_make(buf);
#else
strcpy(vartail, "user");
#include "dungeon/dungeon-flag-types.h"
#include "dungeon/dungeon.h"
#include "effect/effect-characteristics.h"
-#include "floor/line-of-sight.h"
#include "floor/geometry.h"
+#include "floor/line-of-sight.h"
#include "melee/melee-spell-util.h"
#include "monster-floor/monster-move.h"
#include "monster-race/monster-race.h"
ms_ptr->target_idx = dummy;
ms_ptr->t_ptr = &floor_ptr->m_list[ms_ptr->target_idx];
- if (!monster_is_valid(ms_ptr->t_ptr) || (ms_ptr->m_idx == ms_ptr->target_idx) || !are_enemies(player_ptr, ms_ptr->m_ptr, ms_ptr->t_ptr)
- || !projectable(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx))
+ if (!monster_is_valid(ms_ptr->t_ptr) || (ms_ptr->m_idx == ms_ptr->target_idx) || !are_enemies(player_ptr, ms_ptr->m_ptr, ms_ptr->t_ptr) || !projectable(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx))
continue;
return true;
bool vs_ninja = (player_ptr->pclass == PlayerClassType::NINJA) && !is_hostile(ms_ptr->t_ptr);
bool can_use_lite_area = vs_ninja && !(ms_ptr->r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) && !(ms_ptr->r_ptr->flags7 & RF7_DARK_MASK);
- if ((ms_ptr->r_ptr->flags2 & RF2_STUPID) != 0)
+ if (ms_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return;
if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::DARKNESS)) {
static void check_stupid(melee_spell_type *ms_ptr)
{
- if (!ms_ptr->in_no_magic_dungeon || ((ms_ptr->r_ptr->flags2 & RF2_STUPID) != 0))
+ if (!ms_ptr->in_no_magic_dungeon || ms_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return;
ms_ptr->ability_flags &= RF_ABILITY_NOMAGIC_MASK;
POSITION real_y = ms_ptr->y;
POSITION real_x = ms_ptr->x;
get_project_point(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, &real_y, &real_x, 0L);
- if (!projectable(player_ptr, real_y, real_x, player_ptr->y, player_ptr->x) && ms_ptr->ability_flags.has(MonsterAbilityType::BA_LITE)
- && (distance(real_y, real_x, player_ptr->y, player_ptr->x) <= 4) && los(player_ptr, real_y, real_x, player_ptr->y, player_ptr->x)) {
+ if (!projectable(player_ptr, real_y, real_x, player_ptr->y, player_ptr->x) && ms_ptr->ability_flags.has(MonsterAbilityType::BA_LITE) && (distance(real_y, real_x, player_ptr->y, player_ptr->x) <= 4) && los(player_ptr, real_y, real_x, player_ptr->y, player_ptr->x)) {
ms_ptr->ability_flags.reset(MonsterAbilityType::BA_LITE);
return;
static void check_melee_spell_beam(PlayerType *player_ptr, melee_spell_type *ms_ptr)
{
- if (ms_ptr->ability_flags.has_none_of(RF_ABILITY_BEAM_MASK)
- || direct_beam(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, ms_ptr->m_ptr))
+ if (ms_ptr->ability_flags.has_none_of(RF_ABILITY_BEAM_MASK) || direct_beam(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, ms_ptr->m_ptr))
return;
ms_ptr->ability_flags.reset(RF_ABILITY_BEAM_MASK);
return;
}
- if (ms_ptr->ability_flags.has(MonsterAbilityType::BR_LITE) && !breath_direct(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx,
- ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, rad, AttributeType::LITE, true)) {
+ if (ms_ptr->ability_flags.has(MonsterAbilityType::BR_LITE) && !breath_direct(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx,
+ ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, rad, AttributeType::LITE, true)) {
ms_ptr->ability_flags.reset(MonsterAbilityType::BR_LITE);
return;
}
- if (ms_ptr->ability_flags.has(MonsterAbilityType::BR_DISI) && !breath_direct(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx,
- ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, rad, AttributeType::DISINTEGRATE, true)) {
+ if (ms_ptr->ability_flags.has(MonsterAbilityType::BR_DISI) && !breath_direct(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx,
+ ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, rad, AttributeType::DISINTEGRATE, true)) {
ms_ptr->ability_flags.reset(MonsterAbilityType::BR_DISI);
}
}
static void check_non_stupid(PlayerType *player_ptr, melee_spell_type *ms_ptr)
{
- if ((ms_ptr->r_ptr->flags2 & RF2_STUPID) != 0)
+ if (ms_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return;
- if (ms_ptr->ability_flags.has_any_of(RF_ABILITY_BOLT_MASK)
- && !clean_shot(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, ms_ptr->pet)) {
+ if (ms_ptr->ability_flags.has_any_of(RF_ABILITY_BOLT_MASK) && !clean_shot(player_ptr, ms_ptr->m_ptr->fy, ms_ptr->m_ptr->fx, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx, ms_ptr->pet)) {
ms_ptr->ability_flags.reset(RF_ABILITY_BOLT_MASK);
}
if (ms_ptr->ability_flags.has(MonsterAbilityType::RAISE_DEAD) && !raise_possible(player_ptr, ms_ptr->m_ptr))
ms_ptr->ability_flags.reset(MonsterAbilityType::RAISE_DEAD);
- if (ms_ptr->ability_flags.has(MonsterAbilityType::SPECIAL) && (ms_ptr->m_ptr->r_idx == MON_ROLENTO)
- && !summon_possible(player_ptr, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx))
+ if (ms_ptr->ability_flags.has(MonsterAbilityType::SPECIAL) && (ms_ptr->m_ptr->r_idx == MON_ROLENTO) && !summon_possible(player_ptr, ms_ptr->t_ptr->fy, ms_ptr->t_ptr->fx))
ms_ptr->ability_flags.reset(MonsterAbilityType::SPECIAL);
}
static void check_smart(PlayerType *player_ptr, melee_spell_type *ms_ptr)
{
- if ((ms_ptr->r_ptr->flags2 & RF2_SMART) == 0)
+ if (ms_ptr->r_ptr->behavior_flags.has_not(MonsterBehaviorType::SMART))
return;
if ((ms_ptr->m_ptr->hp < ms_ptr->m_ptr->maxhp / 10) && (randint0(100) < 50)) {
ms_ptr->ability_flags &= RF_ABILITY_INT_MASK;
}
- if (ms_ptr->ability_flags.has(MonsterAbilityType::TELE_LEVEL)
- && is_teleport_level_ineffective(player_ptr, (ms_ptr->target_idx == player_ptr->riding) ? 0 : ms_ptr->target_idx))
+ if (ms_ptr->ability_flags.has(MonsterAbilityType::TELE_LEVEL) && is_teleport_level_ineffective(player_ptr, (ms_ptr->target_idx == player_ptr->riding) ? 0 : ms_ptr->target_idx))
ms_ptr->ability_flags.reset(MonsterAbilityType::TELE_LEVEL);
}
#include "core/player-redraw-types.h"
#include "dungeon/dungeon-flag-types.h"
#include "dungeon/dungeon.h"
+#include "effect/attribute-types.h"
#include "effect/effect-characteristics.h"
#include "effect/effect-processor.h"
#include "main/sound-definitions-table.h"
#include "monster/monster-status.h"
#include "spell-kind/spells-teleport.h"
#include "spell-realm/spells-hex.h"
-#include "effect/attribute-types.h"
#include "system/floor-type-definition.h"
#include "system/monster-race-definition.h"
#include "system/monster-type-definition.h"
AttributeType::TURN_ALL, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED);
break;
case BLOW_EFFECT_TYPE_SLEEP:
- project(player_ptr, mam_ptr->m_idx, 0, mam_ptr->t_ptr->fy, mam_ptr->t_ptr->fx, r_ptr->level,
+ project(player_ptr, mam_ptr->m_idx, 0, mam_ptr->t_ptr->fy, mam_ptr->t_ptr->fx, r_ptr->level,
AttributeType::OLD_SLEEP, PROJECT_KILL | PROJECT_STOP | PROJECT_AIMED);
break;
case BLOW_EFFECT_TYPE_HEAL:
return false;
monster_race *r_ptr = &r_info[mam_ptr->m_ptr->r_idx];
- if (r_ptr->flags1 & RF1_NEVER_BLOW)
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW))
return false;
if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE))
#include "inventory/inventory-slot-types.h"
#include "io/input-key-acceptor.h"
#include "mind/stances-table.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-race/monster-race-hook.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags-resistance.h"
* @param player_ptr プレイヤーへの参照ポインタ
* @param pa_ptr 直接攻撃構造体への参照ポインタ
*/
-void musou_counterattack(PlayerType *player_ptr, monap_type *monap_ptr)
+void musou_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if ((!player_ptr->counter && !PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) || !monap_ptr->alive || player_ptr->is_dead || !monap_ptr->m_ptr->ml
|| (player_ptr->csp <= 7))
#include "combat/combat-options-type.h"
#include "object-enchant/tr-flags.h"
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
struct monster_type;
struct player_attack_type;
class PlayerType;
bool choose_samurai_stance(PlayerType* player_ptr);
int calc_attack_quality(PlayerType *player_ptr, player_attack_type *pa_ptr);
void mineuchi(PlayerType *player_ptr, player_attack_type *pa_ptr);
-void musou_counterattack(PlayerType *player_ptr, monap_type *monap_ptr);
+void musou_counterattack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
#include "io/input-key-requester.h"
#include "main/sound-of-music.h"
#include "mind/mind-weaponsmith.h"
-#include "object-enchant/object-smith.h"
-#include "object-enchant/smith-types.h"
#include "object-enchant/tr-types.h"
#include "object/item-tester-hooker.h"
#include "object/item-use-flags.h"
#include "player-status/player-energy.h"
+#include "smith/object-smith.h"
+#include "smith/smith-types.h"
#include "system/object-type-definition.h"
#include "system/player-type-definition.h"
#include "term/screen-processor.h"
#include "util/buffer-shaper.h"
#include "util/int-char-converter.h"
#include "view/display-messages.h"
-
#include <algorithm>
#include <sstream>
}
else if (pa_ptr->ma_ptr->effect == MA_SLOW) {
- if (!((r_ptr->flags1 & RF1_NEVER_MOVE) || angband_strchr("~#{}.UjmeEv$,DdsbBFIJQSXclnw!=?", r_ptr->d_char))) {
+ if (!(r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE) || angband_strchr("~#{}.UjmeEv$,DdsbBFIJQSXclnw!=?", r_ptr->d_char))) {
msg_format(_("%sの足首に関節蹴りをくらわした!", "You kick %s in the ankle."), pa_ptr->m_name);
special_effect = MA_SLOW;
} else
#include "main/sound-definitions-table.h"
#include "main/sound-of-music.h"
#include "monster-attack/insults-moans.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
+#include "monster-attack/monster-attack-types.h"
#include "monster-race/race-indice-types.h"
#include "system/angband.h"
#include "system/monster-type-definition.h"
-static void show_jaian_song(monap_type *monap_ptr)
+static void show_jaian_song(MonsterAttackPlayer *monap_ptr)
{
#ifdef JP
switch (randint1(15)) {
#endif
}
-static void monster_attack_show(monap_type *monap_ptr)
+static void monster_attack_show(MonsterAttackPlayer *monap_ptr)
{
#ifdef JP
monap_ptr->abbreviate = -1;
sound(SOUND_SHOW);
}
-void describe_monster_attack_method(monap_type *monap_ptr)
+void describe_monster_attack_method(MonsterAttackPlayer *monap_ptr)
{
switch (monap_ptr->method) {
case RaceBlowMethodType::HIT: {
#pragma once
-typedef struct monap_type monap_type;
-void describe_monster_attack_method(monap_type *monap_ptr);
+class MonsterAttackPlayer;
+void describe_monster_attack_method(MonsterAttackPlayer *monap_ptr);
#include "monster-attack/monster-attack-lose.h"
#include "mind/mind-mirror-master.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-attack/monster-attack-status.h"
-#include "monster-attack/monster-attack-util.h"
#include "player/player-damage.h"
#include "player/player-status-flags.h"
#include "player/player-status-resist.h"
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @details 10% (毒の一次耐性があれば4%、二重耐性ならば1.6%)の確率で耐久が低下し、更に1/10の確率で永久低下する
*/
-void calc_blow_disease(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_disease(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_pois(player_ptr))
monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_strength(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_strength(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_str(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_intelligence(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_intelligence(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_int(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_wisdom(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_wisdom(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_wis(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_dexterity(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_dexterity(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_dex(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_constitution(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_constitution(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_con(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_charisma(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_charisma(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_sustain_chr(player_ptr))
monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void calc_blow_lose_all(PlayerType *player_ptr, monap_type *monap_ptr)
+void calc_blow_lose_all(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
int damage_ratio = 100;
if (has_sustain_str(player_ptr))
#pragma once
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void calc_blow_disease(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_strength(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_intelligence(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_wisdom(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_dexterity(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_constitution(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_charisma(PlayerType *player_ptr, monap_type *monap_ptr);
-void calc_blow_lose_all(PlayerType *player_ptr, monap_type *monap_ptr);
+void calc_blow_disease(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_strength(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_intelligence(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_wisdom(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_dexterity(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_constitution(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_charisma(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void calc_blow_lose_all(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
#include "monster-attack/monster-attack-describer.h"
#include "monster-attack/monster-attack-effect.h"
#include "monster-attack/monster-attack-switcher.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-types.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags1.h"
#include "monster-race/race-flags3.h"
#include "spell-realm/spells-hex.h"
#include "status/action-setter.h"
#include "status/bad-status-setter.h"
+#include "system/angband.h"
#include "system/floor-type-definition.h"
#include "system/monster-race-definition.h"
#include "system/monster-type-definition.h"
#include "util/bit-flags-calculator.h"
#include "view/display-messages.h"
-static bool check_no_blow(PlayerType *player_ptr, monap_type *monap_ptr)
+/*!
+ * @brief コンストラクタ
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param m_idx 打撃を行うモンスターのID
+ */
+MonsterAttackPlayer::MonsterAttackPlayer(PlayerType *player_ptr, short m_idx)
+ : m_idx(m_idx)
+ , m_ptr(&player_ptr->current_floor_ptr->m_list[m_idx])
+ , method(RaceBlowMethodType::NONE)
+ , effect(RaceBlowEffectType::NONE)
+ , do_silly_attack(one_in_(2) && player_ptr->hallucinated)
+ , player_ptr(player_ptr)
+{
+}
+
+/*!
+ * @brief モンスターからプレイヤーへの打撃処理 / Attack the player via physical attacks.
+ */
+void MonsterAttackPlayer::make_attack_normal()
+{
+ if (!this->check_no_blow()) {
+ return;
+ }
+
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ this->rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
+ monster_desc(this->player_ptr, this->m_name, this->m_ptr, 0);
+ monster_desc(this->player_ptr, this->ddesc, this->m_ptr, MD_WRONGDOER_NAME);
+ if (PlayerClass(this->player_ptr).samurai_stance_is(SamuraiStanceType::IAI)) {
+ msg_format(_("相手が襲いかかる前に素早く武器を振るった。", "You took sen, drew and cut in one motion before %s moved."), this->m_name);
+ if (do_cmd_attack(this->player_ptr, this->m_ptr->fy, this->m_ptr->fx, HISSATSU_IAI)) {
+ return;
+ }
+ }
+
+ auto can_activate_kawarimi = randint0(55) < (this->player_ptr->lev * 3 / 5 + 20);
+ if (can_activate_kawarimi && kawarimi(this->player_ptr, true)) {
+ return;
+ }
+
+ this->blinked = false;
+ if (this->process_monster_blows()) {
+ return;
+ }
+
+ this->postprocess_monster_blows();
+}
+
+/*!
+ * @brief 能力値の実値を求める
+ * @param raw PlayerTypeに格納されている生値
+ * @return 実値
+ * @details AD&Dの記法に則り、19以上の値を取らなくしているので、格納方法が面倒
+ */
+int MonsterAttackPlayer::stat_value(const int raw)
{
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- if (any_bits(r_ptr->flags1, RF1_NEVER_BLOW)) {
+ if (raw <= 18) {
+ return raw;
+ }
+
+ return (raw - 18) / 10 + 18;
+}
+
+bool MonsterAttackPlayer::check_no_blow()
+{
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) {
return false;
}
- if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE)) {
+ if (d_info[this->player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE)) {
return false;
}
- return is_hostile(monap_ptr->m_ptr);
+ return is_hostile(this->m_ptr);
+}
+
+/*!
+ * @brief モンスターからプレイヤーへの打撃処理本体
+ * @return 打撃に反応してプレイヤーがその場から離脱したかどうか
+ */
+bool MonsterAttackPlayer::process_monster_blows()
+{
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ for (auto ap_cnt = 0; ap_cnt < MAX_NUM_BLOWS; ap_cnt++) {
+ this->obvious = false;
+ this->damage = 0;
+ this->act = nullptr;
+ this->effect = r_ptr->blow[ap_cnt].effect;
+ this->method = r_ptr->blow[ap_cnt].method;
+ this->d_dice = r_ptr->blow[ap_cnt].d_dice;
+ this->d_side = r_ptr->blow[ap_cnt].d_side;
+
+ if (!this->check_monster_continuous_attack()) {
+ break;
+ }
+
+ // effect が RaceBlowEffectType::NONE (無効値)になることはあり得ないはずだが、万一そう
+ // なっていたら単に攻撃を打ち切る。
+ // r_info.txt の "B:" トークンに effect 以降を書き忘れた場合が該当する。
+ if (this->effect == RaceBlowEffectType::NONE) {
+ plog("unexpected: MonsterAttackPlayer::effect == RaceBlowEffectType::NONE");
+ break;
+ }
+
+ if (this->method == RaceBlowMethodType::SHOOT) {
+ continue;
+ }
+
+ // フレーバーの打撃は必中扱い。それ以外は通常の命中判定を行う。
+ this->ac = this->player_ptr->ac + this->player_ptr->to_a;
+ bool hit;
+ if (this->effect == RaceBlowEffectType::FLAVOR) {
+ hit = true;
+ } else {
+ const int power = mbe_info[enum2i(this->effect)].power;
+ hit = check_hit_from_monster_to_player(this->player_ptr, power, this->rlev, monster_stunned_remaining(this->m_ptr));
+ }
+
+ if (hit) {
+ // 命中した。命中処理と思い出処理を行う。
+ // 打撃そのものは対邪悪結界で撃退した可能性がある。
+ const bool protect = !this->process_monster_attack_hit();
+ this->increase_blow_type_seen(ap_cnt);
+
+ // 撃退成功時はそのまま次の打撃へ移行。
+ if (protect)
+ continue;
+
+ // 撃退失敗時は落馬処理、変わり身のテレポート処理を行う。
+ check_fall_off_horse(this->player_ptr, this);
+
+ // 変わり身のテレポートが成功したら攻撃を打ち切り、プレイヤーが離脱した旨を返す。
+ if (kawarimi(this->player_ptr, false)) {
+ return true;
+ }
+ } else {
+ // 命中しなかった。回避時の処理、思い出処理を行う。
+ this->process_monster_attack_evasion();
+ this->increase_blow_type_seen(ap_cnt);
+ }
+ }
+
+ // 通常はプレイヤーはその場にとどまる。
+ return false;
}
/*!
* @brief プレイヤー死亡等でモンスターからプレイヤーへの直接攻撃処理を途中で打ち切るかどうかを判定する
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @return 攻撃続行ならばTRUE、打ち切りになったらFALSE
*/
-static bool check_monster_continuous_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+bool MonsterAttackPlayer::check_monster_continuous_attack()
{
- if (!monster_is_valid(monap_ptr->m_ptr) || (monap_ptr->method == RaceBlowMethodType::NONE)) {
+ if (!monster_is_valid(this->m_ptr) || (this->method == RaceBlowMethodType::NONE)) {
return false;
}
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- if (is_pet(monap_ptr->m_ptr) && (r_ptr->flags1 & RF1_UNIQUE) && (monap_ptr->method == RaceBlowMethodType::EXPLODE)) {
- monap_ptr->method = RaceBlowMethodType::HIT;
- monap_ptr->d_dice /= 10;
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ if (is_pet(this->m_ptr) && (r_ptr->flags1 & RF1_UNIQUE) && (this->method == RaceBlowMethodType::EXPLODE)) {
+ this->method = RaceBlowMethodType::HIT;
+ this->d_dice /= 10;
}
- auto is_neighbor = distance(player_ptr->y, player_ptr->x, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx) <= 1;
- return player_ptr->playing && !player_ptr->is_dead && is_neighbor && !player_ptr->leaving;
+ auto is_neighbor = distance(this->player_ptr->y, this->player_ptr->x, this->m_ptr->fy, this->m_ptr->fx) <= 1;
+ return this->player_ptr->playing && !this->player_ptr->is_dead && is_neighbor && !this->player_ptr->leaving;
}
/*!
- * @brief 対邪悪結界が効いている状態で邪悪なモンスターから直接攻撃を受けた時の処理
- * @param player_ptr プレイヤーへの参照ポインタ
+ * @brief モンスターから直接攻撃を1回受けた時の処理
+ * @return 対邪悪結界により攻撃が当たらなかったらFALSE、それ以外はTRUE
+ * @param this->player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
+ * @details 最大4 回/モンスター/ターン、このルーチンを通る
+ */
+bool MonsterAttackPlayer::process_monster_attack_hit()
+{
+ disturb(this->player_ptr, true, true);
+ if (this->effect_protecion_from_evil()) {
+ return false;
+ }
+
+ this->do_cut = 0;
+ this->do_stun = 0;
+ describe_monster_attack_method(this);
+ this->describe_silly_attacks();
+ this->obvious = true;
+ this->damage = damroll(this->d_dice, this->d_side);
+ if (this->explode) {
+ this->damage = 0;
+ }
+
+ switch_monster_blow_to_player(this->player_ptr, this);
+ this->select_cut_stun();
+ this->calc_player_cut();
+ this->process_player_stun();
+ this->monster_explode();
+ process_aura_counterattack(this->player_ptr, this);
+ return true;
+}
+
+/*!
+ * @brief 対邪悪結界が効いている状態で邪悪なモンスターから直接攻撃を受けた時の処理
* @return briefに書いた条件+確率が満たされたらTRUE、それ以外はFALSE
*/
-static bool effect_protecion_from_evil(PlayerType *player_ptr, monap_type *monap_ptr)
+bool MonsterAttackPlayer::effect_protecion_from_evil()
{
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- if ((player_ptr->protevil <= 0) || none_bits(r_ptr->flags3, RF3_EVIL) || (player_ptr->lev < monap_ptr->rlev) || ((randint0(100) + player_ptr->lev) <= 50)) {
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ if ((this->player_ptr->protevil <= 0) || none_bits(r_ptr->flags3, RF3_EVIL) || (this->player_ptr->lev < this->rlev) || ((randint0(100) + this->player_ptr->lev) <= 50)) {
return false;
}
- if (is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr)) {
+ if (is_original_ap_and_seen(this->player_ptr, this->m_ptr)) {
r_ptr->r_flags3 |= RF3_EVIL;
}
#ifdef JP
- monap_ptr->abbreviate ? msg_format("撃退した。") : msg_format("%^sは撃退された。", monap_ptr->m_name);
- monap_ptr->abbreviate = 1; /* 2回目以降は省略 */
+ this->abbreviate ? msg_format("撃退した。") : msg_format("%^sは撃退された。", this->m_name);
+ this->abbreviate = 1; /* 2回目以降は省略 */
#else
- msg_format("%^s is repelled.", monap_ptr->m_name);
+ msg_format("%^s is repelled.", this->m_name);
#endif
return true;
}
-static void describe_silly_attacks(monap_type *monap_ptr)
+void MonsterAttackPlayer::describe_silly_attacks()
{
- if (monap_ptr->act == nullptr) {
+ if (this->act == nullptr) {
return;
}
- if (monap_ptr->do_silly_attack) {
+ if (this->do_silly_attack) {
#ifdef JP
- monap_ptr->abbreviate = -1;
+ this->abbreviate = -1;
#endif
- monap_ptr->act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
+ this->act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
}
#ifdef JP
- if (monap_ptr->abbreviate == 0) {
- msg_format("%^sに%s", monap_ptr->m_name, monap_ptr->act);
- } else if (monap_ptr->abbreviate == 1) {
- msg_format("%s", monap_ptr->act);
+ if (this->abbreviate == 0) {
+ msg_format("%^sに%s", this->m_name, this->act);
+ } else if (this->abbreviate == 1) {
+ msg_format("%s", this->act);
} else {
- /* if (monap_ptr->abbreviate == -1) */
- msg_format("%^s%s", monap_ptr->m_name, monap_ptr->act);
+ /* if (this->abbreviate == -1) */
+ msg_format("%^s%s", this->m_name, this->act);
}
- monap_ptr->abbreviate = 1; /*2回目以降は省略 */
+ this->abbreviate = 1; /*2回目以降は省略 */
#else
- msg_format("%^s %s%s", monap_ptr->m_name, monap_ptr->act, monap_ptr->do_silly_attack ? " you." : "");
+ msg_format("%^s %s%s", this->m_name, this->act, this->do_silly_attack ? " you." : "");
#endif
}
/*!
* @brief 切り傷と朦朧が同時に発生した時、片方を無効にする
- * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void select_cut_stun(monap_type *monap_ptr)
+void MonsterAttackPlayer::select_cut_stun()
{
- if ((monap_ptr->do_cut == 0) || (monap_ptr->do_stun == 0)) {
+ if ((this->do_cut == 0) || (this->do_stun == 0)) {
return;
}
if (randint0(100) < 50) {
- monap_ptr->do_cut = 0;
+ this->do_cut = 0;
} else {
- monap_ptr->do_stun = 0;
+ this->do_stun = 0;
}
}
-static void calc_player_cut(PlayerType *player_ptr, monap_type *monap_ptr)
+void MonsterAttackPlayer::calc_player_cut()
{
- if (monap_ptr->do_cut == 0) {
+ if (this->do_cut == 0) {
return;
}
- auto cut_plus = PlayerCut::get_accumulation(monap_ptr->d_dice * monap_ptr->d_side, monap_ptr->damage);
+ auto cut_plus = PlayerCut::get_accumulation(this->d_dice * this->d_side, this->damage);
if (cut_plus > 0) {
- (void)BadStatusSetter(player_ptr).mod_cut(cut_plus);
+ (void)BadStatusSetter(this->player_ptr).mod_cut(cut_plus);
}
}
/*!
- * @brief 能力値の実値を求める
- * @param raw PlayerTypeに格納されている生値
- * @return 実値
- * @details AD&Dの記法に則り、19以上の値を取らなくしているので、格納方法が面倒
- */
-static int stat_value(const int raw)
-{
- if (raw <= 18) {
- return raw;
- }
-
- return (raw - 18) / 10 + 18;
-}
-
-/*!
* @brief 朦朧を蓄積させる
- * @param player_ptr プレイヤーへの参照ポインタ
+ * @param this->player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスター打撃への参照ポインタ
* @details
* 痛恨の一撃ならば朦朧蓄積ランクを1上げる.
* 2%の確率で朦朧蓄積ランクを1上げる.
* 肉体のパラメータが合計80を超える水準に強化されていたら朦朧蓄積ランクを1下げる.
*/
-static void process_player_stun(PlayerType *player_ptr, monap_type *monap_ptr)
+void MonsterAttackPlayer::process_player_stun()
{
- if (monap_ptr->do_stun == 0) {
+ if (this->do_stun == 0) {
return;
}
- auto total = monap_ptr->d_dice * monap_ptr->d_side;
- auto accumulation_rank = PlayerStun::get_accumulation_rank(total, monap_ptr->damage);
+ auto total = this->d_dice * this->d_side;
+ auto accumulation_rank = PlayerStun::get_accumulation_rank(total, this->damage);
if (accumulation_rank == 0) {
return;
}
- if ((total < monap_ptr->damage) && (accumulation_rank <= 6)) {
+ if ((total < this->damage) && (accumulation_rank <= 6)) {
accumulation_rank++;
}
accumulation_rank++;
}
- auto str = stat_value(player_ptr->stat_cur[A_STR]);
- auto dex = stat_value(player_ptr->stat_cur[A_DEX]);
- auto con = stat_value(player_ptr->stat_cur[A_CON]);
+ auto str = this->stat_value(this->player_ptr->stat_cur[A_STR]);
+ auto dex = this->stat_value(this->player_ptr->stat_cur[A_DEX]);
+ auto con = this->stat_value(this->player_ptr->stat_cur[A_CON]);
auto is_powerful_body = str + dex + con > 80;
if (is_powerful_body) {
accumulation_rank--;
auto stun_plus = PlayerStun::get_accumulation(accumulation_rank);
if (stun_plus > 0) {
- (void)BadStatusSetter(player_ptr).mod_stun(stun_plus);
+ (void)BadStatusSetter(this->player_ptr).mod_stun(stun_plus);
}
}
-static void monster_explode(PlayerType *player_ptr, monap_type *monap_ptr)
+void MonsterAttackPlayer::monster_explode()
{
- if (!monap_ptr->explode) {
+ if (!this->explode) {
return;
}
sound(SOUND_EXPLODE);
- MonsterDamageProcessor mdp(player_ptr, monap_ptr->m_idx, monap_ptr->m_ptr->hp + 1, &monap_ptr->fear, AttributeType::NONE);
+ MonsterDamageProcessor mdp(this->player_ptr, this->m_idx, this->m_ptr->hp + 1, &this->fear, AttributeType::NONE);
if (mdp.mon_take_hit(nullptr)) {
- monap_ptr->blinked = false;
- monap_ptr->alive = false;
+ this->blinked = false;
+ this->alive = false;
}
}
-static void describe_attack_evasion(PlayerType *player_ptr, monap_type *monap_ptr)
+/*!
+ * @brief 一部の打撃種別の場合のみ、避けた旨のメッセージ表示と盾技能スキル向上を行う
+ * @param this->player_ptr プレイヤーへの参照ポインタ
+ * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
+ */
+void MonsterAttackPlayer::process_monster_attack_evasion()
{
- if (!monap_ptr->m_ptr->ml) {
+ switch (this->method) {
+ case RaceBlowMethodType::HIT:
+ case RaceBlowMethodType::TOUCH:
+ case RaceBlowMethodType::PUNCH:
+ case RaceBlowMethodType::KICK:
+ case RaceBlowMethodType::CLAW:
+ case RaceBlowMethodType::BITE:
+ case RaceBlowMethodType::STING:
+ case RaceBlowMethodType::SLASH:
+ case RaceBlowMethodType::BUTT:
+ case RaceBlowMethodType::CRUSH:
+ case RaceBlowMethodType::ENGULF:
+ case RaceBlowMethodType::CHARGE:
+ this->describe_attack_evasion();
+ this->gain_armor_exp();
+ this->damage = 0;
+ return;
+ default:
return;
}
+}
- disturb(player_ptr, true, true);
+void MonsterAttackPlayer::describe_attack_evasion()
+{
+ if (!this->m_ptr->ml) {
+ return;
+ }
+
+ disturb(this->player_ptr, true, true);
#ifdef JP
- auto is_suiken = any_bits(player_ptr->special_attack, ATTACK_SUIKEN);
- if (monap_ptr->abbreviate) {
+ auto is_suiken = any_bits(this->player_ptr->special_attack, ATTACK_SUIKEN);
+ if (this->abbreviate) {
msg_format("%sかわした。", is_suiken ? "奇妙な動きで" : "");
} else {
- msg_format("%s%^sの攻撃をかわした。", is_suiken ? "奇妙な動きで" : "", monap_ptr->m_name);
+ msg_format("%s%^sの攻撃をかわした。", is_suiken ? "奇妙な動きで" : "", this->m_name);
}
- monap_ptr->abbreviate = 1; /* 2回目以降は省略 */
+ this->abbreviate = 1; /* 2回目以降は省略 */
#else
- msg_format("%^s misses you.", monap_ptr->m_name);
+ msg_format("%^s misses you.", this->m_name);
#endif
}
-static void gain_armor_exp(PlayerType *player_ptr, monap_type *monap_ptr)
+void MonsterAttackPlayer::gain_armor_exp()
{
- const auto o_ptr_mh = &player_ptr->inventory_list[INVEN_MAIN_HAND];
- const auto o_ptr_sh = &player_ptr->inventory_list[INVEN_SUB_HAND];
+ const auto o_ptr_mh = &this->player_ptr->inventory_list[INVEN_MAIN_HAND];
+ const auto o_ptr_sh = &this->player_ptr->inventory_list[INVEN_SUB_HAND];
if (!o_ptr_mh->is_armour() && !o_ptr_sh->is_armour()) {
return;
}
- auto cur = player_ptr->skill_exp[PlayerSkillKindType::SHIELD];
- auto max = s_info[enum2i(player_ptr->pclass)].s_max[PlayerSkillKindType::SHIELD];
+ auto cur = this->player_ptr->skill_exp[PlayerSkillKindType::SHIELD];
+ auto max = s_info[enum2i(this->player_ptr->pclass)].s_max[PlayerSkillKindType::SHIELD];
if (cur >= max) {
return;
}
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
auto target_level = r_ptr->level;
short increment = 0;
if ((cur / 100) < target_level) {
increment += 1 + addition;
}
- player_ptr->skill_exp[PlayerSkillKindType::SHIELD] = std::min<short>(max, cur + increment);
- player_ptr->update |= (PU_BONUS);
-}
-
-/*!
- * @brief モンスターから直接攻撃を1回受けた時の処理
- * @return 対邪悪結界により攻撃が当たらなかったらFALSE、それ以外はTRUE
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
- * @details 最大4 回/モンスター/ターン、このルーチンを通る
- */
-static bool process_monster_attack_hit(PlayerType *player_ptr, monap_type *monap_ptr)
-{
- disturb(player_ptr, true, true);
- if (effect_protecion_from_evil(player_ptr, monap_ptr)) {
- return false;
- }
-
- monap_ptr->do_cut = 0;
- monap_ptr->do_stun = 0;
- describe_monster_attack_method(monap_ptr);
- describe_silly_attacks(monap_ptr);
- monap_ptr->obvious = true;
- monap_ptr->damage = damroll(monap_ptr->d_dice, monap_ptr->d_side);
- if (monap_ptr->explode) {
- monap_ptr->damage = 0;
- }
-
- switch_monster_blow_to_player(player_ptr, monap_ptr);
- select_cut_stun(monap_ptr);
- calc_player_cut(player_ptr, monap_ptr);
- process_player_stun(player_ptr, monap_ptr);
- monster_explode(player_ptr, monap_ptr);
- process_aura_counterattack(player_ptr, monap_ptr);
- return true;
-}
-
-/*!
- * @brief 一部の打撃種別の場合のみ、避けた旨のメッセージ表示と盾技能スキル向上を行う
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
- */
-static void process_monster_attack_evasion(PlayerType *player_ptr, monap_type *monap_ptr)
-{
- switch (monap_ptr->method) {
- case RaceBlowMethodType::HIT:
- case RaceBlowMethodType::TOUCH:
- case RaceBlowMethodType::PUNCH:
- case RaceBlowMethodType::KICK:
- case RaceBlowMethodType::CLAW:
- case RaceBlowMethodType::BITE:
- case RaceBlowMethodType::STING:
- case RaceBlowMethodType::SLASH:
- case RaceBlowMethodType::BUTT:
- case RaceBlowMethodType::CRUSH:
- case RaceBlowMethodType::ENGULF:
- case RaceBlowMethodType::CHARGE:
- describe_attack_evasion(player_ptr, monap_ptr);
- gain_armor_exp(player_ptr, monap_ptr);
- monap_ptr->damage = 0;
- return;
- default:
- return;
- }
+ this->player_ptr->skill_exp[PlayerSkillKindType::SHIELD] = std::min<short>(max, cur + increment);
+ this->player_ptr->update |= (PU_BONUS);
}
/*!
* @brief モンスターの打撃情報を蓄積させる
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @param ap_cnt モンスターの打撃 N回目
* @details どの敵が何をしてきたか正しく認識できていなければ情報を蓄積しない.
* 非自明な類の打撃については、そのダメージが 0 ならば基本的に知識が増えない.
* 但し、既に一定以上の知識があれば常に知識が増える(何をされたのか察知できる).
*/
-static void increase_blow_type_seen(PlayerType *player_ptr, monap_type *monap_ptr, const int ap_cnt)
+void MonsterAttackPlayer::increase_blow_type_seen(const int ap_cnt)
{
- if (!is_original_ap_and_seen(player_ptr, monap_ptr->m_ptr) || monap_ptr->do_silly_attack) {
+ if (!is_original_ap_and_seen(this->player_ptr, this->m_ptr) || this->do_silly_attack) {
return;
}
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- if (!monap_ptr->obvious && (monap_ptr->damage == 0) && (r_ptr->r_blows[ap_cnt] <= 10)) {
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ if (!this->obvious && (this->damage == 0) && (r_ptr->r_blows[ap_cnt] <= 10)) {
return;
}
}
}
-/*!
- * @brief モンスターからプレイヤーへの打撃処理本体
- * @return 打撃に反応してプレイヤーがその場から離脱したかどうか
- */
-static bool process_monster_blows(PlayerType *player_ptr, monap_type *monap_ptr)
-{
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- for (auto ap_cnt = 0; ap_cnt < MAX_NUM_BLOWS; ap_cnt++) {
- monap_ptr->obvious = false;
- monap_ptr->damage = 0;
- monap_ptr->act = nullptr;
- monap_ptr->effect = r_ptr->blow[ap_cnt].effect;
- monap_ptr->method = r_ptr->blow[ap_cnt].method;
- monap_ptr->d_dice = r_ptr->blow[ap_cnt].d_dice;
- monap_ptr->d_side = r_ptr->blow[ap_cnt].d_side;
-
- if (!check_monster_continuous_attack(player_ptr, monap_ptr)) {
- break;
- }
-
- // effect が RaceBlowEffectType::NONE (無効値)になることはあり得ないはずだが、万一そう
- // なっていたら単に攻撃を打ち切る。
- // r_info.txt の "B:" トークンに effect 以降を書き忘れた場合が該当する。
- if (monap_ptr->effect == RaceBlowEffectType::NONE) {
- plog("unexpected: monap_ptr->effect == RaceBlowEffectType::NONE");
- break;
- }
-
- if (monap_ptr->method == RaceBlowMethodType::SHOOT) {
- continue;
- }
-
- // フレーバーの打撃は必中扱い。それ以外は通常の命中判定を行う。
- monap_ptr->ac = player_ptr->ac + player_ptr->to_a;
- bool hit;
- if (monap_ptr->effect == RaceBlowEffectType::FLAVOR) {
- hit = true;
- } else {
- const int power = mbe_info[enum2i(monap_ptr->effect)].power;
- hit = check_hit_from_monster_to_player(player_ptr, power, monap_ptr->rlev, monster_stunned_remaining(monap_ptr->m_ptr));
- }
-
- if (hit) {
- // 命中した。命中処理と思い出処理を行う。
- // 打撃そのものは対邪悪結界で撃退した可能性がある。
- const bool protect = !process_monster_attack_hit(player_ptr, monap_ptr);
- increase_blow_type_seen(player_ptr, monap_ptr, ap_cnt);
-
- // 撃退成功時はそのまま次の打撃へ移行。
- if (protect)
- continue;
-
- // 撃退失敗時は落馬処理、変わり身のテレポート処理を行う。
- check_fall_off_horse(player_ptr, monap_ptr);
-
- // 変わり身のテレポートが成功したら攻撃を打ち切り、プレイヤーが離脱した旨を返す。
- if (kawarimi(player_ptr, false)) {
- return true;
- }
- } else {
- // 命中しなかった。回避時の処理、思い出処理を行う。
- process_monster_attack_evasion(player_ptr, monap_ptr);
- increase_blow_type_seen(player_ptr, monap_ptr, ap_cnt);
- }
- }
-
- // 通常はプレイヤーはその場にとどまる。
- return false;
-}
-
-static void postprocess_monster_blows(PlayerType *player_ptr, monap_type *monap_ptr)
+void MonsterAttackPlayer::postprocess_monster_blows()
{
- SpellHex spell_hex(player_ptr, monap_ptr);
- spell_hex.store_vengeful_damage(monap_ptr->get_damage);
+ SpellHex spell_hex(this->player_ptr, this);
+ spell_hex.store_vengeful_damage(this->get_damage);
spell_hex.eyes_on_eyes();
- musou_counterattack(player_ptr, monap_ptr);
+ musou_counterattack(this->player_ptr, this);
spell_hex.thief_teleport();
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- if (player_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !player_ptr->current_floor_ptr->inside_arena) {
+ auto *r_ptr = &r_info[this->m_ptr->r_idx];
+ if (this->player_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !this->player_ptr->current_floor_ptr->inside_arena) {
r_ptr->r_deaths++;
}
- if (monap_ptr->m_ptr->ml && monap_ptr->fear && monap_ptr->alive && !player_ptr->is_dead) {
+ if (this->m_ptr->ml && this->fear && this->alive && !this->player_ptr->is_dead) {
sound(SOUND_FLEE);
- msg_format(_("%^sは恐怖で逃げ出した!", "%^s flees in terror!"), monap_ptr->m_name);
+ msg_format(_("%^sは恐怖で逃げ出した!", "%^s flees in terror!"), this->m_name);
}
- PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::IAI });
-}
-
-/*!
- * @brief モンスターからプレイヤーへの打撃処理 / Attack the player via physical attacks.
- * @param m_idx 打撃を行うモンスターのID
- * @return 実際に攻撃処理を行った場合TRUEを返す
- */
-bool make_attack_normal(PlayerType *player_ptr, MONSTER_IDX m_idx)
-{
- monap_type tmp_monap;
- monap_type *monap_ptr = initialize_monap_type(player_ptr, &tmp_monap, m_idx);
- if (!check_no_blow(player_ptr, monap_ptr)) {
- return false;
- }
-
- auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
- monap_ptr->rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
- monster_desc(player_ptr, monap_ptr->m_name, monap_ptr->m_ptr, 0);
- monster_desc(player_ptr, monap_ptr->ddesc, monap_ptr->m_ptr, MD_WRONGDOER_NAME);
- if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::IAI)) {
- msg_format(_("相手が襲いかかる前に素早く武器を振るった。", "You took sen, drew and cut in one motion before %s moved."), monap_ptr->m_name);
- if (do_cmd_attack(player_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, HISSATSU_IAI)) {
- return true;
- }
- }
-
- auto can_activate_kawarimi = randint0(55) < (player_ptr->lev * 3 / 5 + 20);
- if (can_activate_kawarimi && kawarimi(player_ptr, true)) {
- return true;
- }
-
- monap_ptr->blinked = false;
- if (process_monster_blows(player_ptr, monap_ptr)) {
- return true;
- }
-
- postprocess_monster_blows(player_ptr, monap_ptr);
- return true;
+ PlayerClass(this->player_ptr).break_samurai_stance({ SamuraiStanceType::IAI });
}
#include "system/angband.h"
+enum class RaceBlowEffectType;
+enum class RaceBlowMethodType;
class PlayerType;
-bool make_attack_normal(PlayerType *player_ptr, MONSTER_IDX m_idx);
+struct monster_type;
+struct object_type;
+class MonsterAttackPlayer {
+public:
+ MonsterAttackPlayer(PlayerType *player_ptr, short m_idx);
+#ifdef JP
+ int abbreviate = 0; // 2回目以降の省略表現フラグ.
+#endif
+ short m_idx;
+ monster_type *m_ptr;
+ RaceBlowMethodType method;
+ RaceBlowEffectType effect;
+ bool do_silly_attack;
+ concptr act = nullptr;
+ int do_cut = 0;
+ int do_stun = 0;
+ bool touched = false;
+ bool explode = false;
+ DEPTH rlev = 0;
+ GAME_TEXT m_name[MAX_NLEN]{};
+ int d_dice = 0;
+ int d_side = 0;
+ object_type *o_ptr = nullptr;
+ bool obvious = false;
+ HIT_POINT damage = 0;
+ bool blinked = false;
+ GAME_TEXT o_name[MAX_NLEN]{};
+ HIT_POINT get_damage = 0;
+ GAME_TEXT ddesc[MAX_MONSTER_NAME]{};
+ ARMOUR_CLASS ac = 0;
+ bool alive = true;
+ bool fear = false;
+
+ void make_attack_normal();
+
+private:
+ PlayerType *player_ptr;
+
+ static int stat_value(const int raw);
+ bool check_no_blow();
+ bool process_monster_blows();
+ bool check_monster_continuous_attack();
+ bool process_monster_attack_hit();
+ bool effect_protecion_from_evil();
+ void describe_silly_attacks();
+ void select_cut_stun();
+ void calc_player_cut();
+ void process_player_stun();
+ void monster_explode();
+ void process_monster_attack_evasion();
+ void describe_attack_evasion();
+ void gain_armor_exp();
+ void increase_blow_type_seen(const int ap_cnt);
+ void postprocess_monster_blows();
+};
if (!turn_flags_ptr->do_move || !player_bold(player_ptr, ny, nx))
return;
- if (r_ptr->flags1 & RF1_NEVER_BLOW) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) {
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags1 |= (RF1_NEVER_BLOW);
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::NEVER_BLOW);
turn_flags_ptr->do_move = false;
}
if (turn_flags_ptr->do_move && d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE) && !monster_confused_remaining(m_ptr)) {
- if (!(r_ptr->flags2 & RF2_STUPID))
+ if (r_ptr->behavior_flags.has_not(MonsterBehaviorType::STUPID))
turn_flags_ptr->do_move = false;
else if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags2 |= (RF2_STUPID);
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::STUPID);
}
if (!turn_flags_ptr->do_move)
return;
if (!player_ptr->riding || one_in_(2)) {
- (void)make_attack_normal(player_ptr, m_idx);
+ MonsterAttackPlayer(player_ptr, m_idx).make_attack_normal();
turn_flags_ptr->do_move = false;
turn_flags_ptr->do_turn = true;
}
monster_race *r_ptr = &r_info[m_ptr->r_idx];
monster_type *y_ptr;
y_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
- if ((r_ptr->flags1 & RF1_NEVER_BLOW) != 0)
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW))
return false;
- if (((r_ptr->flags2 & RF2_KILL_BODY) == 0) && is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags2 |= (RF2_KILL_BODY);
+ if ((r_ptr->behavior_flags.has_not(MonsterBehaviorType::KILL_BODY)) && is_original_ap_and_seen(player_ptr, m_ptr))
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::KILL_BODY);
if ((y_ptr->r_idx == 0) || (y_ptr->hp < 0))
return false;
return false;
if (monster_confused_remaining(m_ptr))
return true;
- if ((r_ptr->flags2 & RF2_STUPID) == 0)
+ if (r_ptr->behavior_flags.has_not(MonsterBehaviorType::STUPID))
return false;
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags2 |= (RF2_STUPID);
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::STUPID);
return true;
}
monster_race *z_ptr = &r_info[y_ptr->r_idx];
turn_flags_ptr->do_move = false;
- bool do_kill_body = any_bits(r_ptr->flags2, RF2_KILL_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_BLOW);
+ bool do_kill_body = r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW);
do_kill_body &= (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level);
do_kill_body &= (g_ptr->m_idx != player_ptr->riding);
- if (do_kill_body || are_enemies(player_ptr, m_ptr, y_ptr) || monster_confused_remaining(m_ptr))
- {
+ if (do_kill_body || are_enemies(player_ptr, m_ptr, y_ptr) || monster_confused_remaining(m_ptr)) {
return exe_monster_attack_to_monster(player_ptr, m_idx, g_ptr);
}
- bool do_move_body = any_bits(r_ptr->flags2, RF2_MOVE_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_MOVE);
+ bool do_move_body = r_ptr->behavior_flags.has(MonsterBehaviorType::MOVE_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE);
do_move_body &= (r_ptr->mexp > z_ptr->mexp);
do_move_body &= can_cross;
do_move_body &= (g_ptr->m_idx != player_ptr->riding);
do_move_body &= monster_can_cross_terrain(player_ptr, player_ptr->current_floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].feat, z_ptr, 0);
- if (do_move_body)
- {
+ if (do_move_body) {
turn_flags_ptr->do_move = true;
turn_flags_ptr->did_move_body = true;
(void)set_monster_csleep(player_ptr, g_ptr->m_idx, 0);
#include "monster-attack/monster-attack-status.h"
#include "core/player-update-types.h"
#include "mind/mind-mirror-master.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-indice-types.h"
#include "player/player-status-flags.h"
#include "timed-effect/timed-effects.h"
#include "view/display-messages.h"
-void process_blind_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_blind_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_blind(player_ptr) || check_multishadow(player_ptr)) {
return;
monap_ptr->obvious = true;
}
-void process_terrify_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_terrify_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (check_multishadow(player_ptr)) {
return;
}
}
-void process_paralyze_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_paralyze_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (check_multishadow(player_ptr)) {
return;
}
}
-void process_lose_all_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_lose_all_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (do_dec_stat(player_ptr, A_STR)) {
monap_ptr->obvious = true;
}
}
-void process_stun_attack(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_stun_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_sound(player_ptr) || check_multishadow(player_ptr)) {
return;
* @param player_ptr プレイヤーへの参照ポインタ
* @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
*/
-static void describe_disability(PlayerType *player_ptr, monap_type *monap_ptr)
+static void describe_disability(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
int stat = randint0(6);
switch (stat) {
}
}
-void process_monster_attack_time(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_monster_attack_time(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_time(player_ptr) || check_multishadow(player_ptr)) {
return;
#include "system/angband.h"
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void process_blind_attack(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_terrify_attack(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_paralyze_attack(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_lose_all_attack(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_stun_attack(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_monster_attack_time(PlayerType *player_ptr, monap_type *monap_ptr);
+void process_blind_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_terrify_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_paralyze_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_lose_all_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_stun_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_monster_attack_time(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
#include "mind/drs-types.h"
#include "mind/mind-mirror-master.h"
#include "monster-attack/monster-attack-lose.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-attack/monster-attack-status.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-types.h"
#include "monster-attack/monster-eating.h"
#include "monster/monster-status.h"
#include "monster/monster-update.h"
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @details 減衰の計算式がpoisではなくnukeなのは仕様 (1/3では減衰が強すぎると判断したため)
*/
-static void calc_blow_poison(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_poison(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (monap_ptr->explode)
return;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_disenchant(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_disenchant(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (monap_ptr->explode)
return;
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
* @detals 魔道具使用能力向上フラグがあれば、吸収対象のアイテムをスキャンされる回数が半分で済む
*/
-static void calc_blow_un_power(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_un_power(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
int damage_ratio = 1000;
if (has_dec_mana(player_ptr))
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_blind(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_blind(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_blind(player_ptr))
monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_confusion(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_confusion(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (monap_ptr->explode) {
return;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_fear(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_fear(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_resist_fear(player_ptr))
monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_paralysis(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_paralysis(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (has_free_act(player_ptr))
monap_ptr->damage = monap_ptr->damage * (randint1(4) + 3) / 8;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_drain_exp(PlayerType *player_ptr, monap_type *monap_ptr, const int drain_value, const int hold_exp_prob)
+static void calc_blow_drain_exp(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr, const int drain_value, const int hold_exp_prob)
{
int32_t d = damroll(drain_value, 6) + (player_ptr->exp / 100) * MON_DRAIN_LIFE;
monap_ptr->obvious = true;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_time(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_time(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (monap_ptr->explode)
return;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_drain_life(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_drain_life(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
int32_t d = damroll(60, 6) + (player_ptr->exp / 100) * MON_DRAIN_LIFE;
monap_ptr->obvious = true;
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-static void calc_blow_drain_mana(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_drain_mana(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
monap_ptr->obvious = true;
int damage_ratio = 100;
update_smart_learn(player_ptr, monap_ptr->m_idx, DRS_MANA);
}
-static void calc_blow_inertia(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_inertia(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if ((player_ptr->fast > 0) || (player_ptr->pspeed >= 130))
monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
/*!
* @brief 空腹進行度を計算する (急速回復があれば+100%、遅消化があれば-50%)
*/
-static void calc_blow_hungry(PlayerType *player_ptr, monap_type *monap_ptr)
+static void calc_blow_hungry(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (player_ptr->regenerate)
monap_ptr->damage = monap_ptr->damage * 2;
process_monster_attack_hungry(player_ptr, monap_ptr);
}
-void switch_monster_blow_to_player(PlayerType *player_ptr, monap_type *monap_ptr)
+void switch_monster_blow_to_player(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
switch (monap_ptr->effect) {
case RaceBlowEffectType::NONE:
#pragma once
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void switch_monster_blow_to_player(PlayerType *player_ptr, monap_type *monap_ptr);
+void switch_monster_blow_to_player(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+++ /dev/null
-/*!
- * @brief モンスターがプレイヤーへ攻撃する処理に関するユーティリティ
- * @date 2020/05/30
- * @author Hourier
- */
-
-#include "monster-attack/monster-attack-util.h"
-#include "system/floor-type-definition.h"
-#include "system/monster-type-definition.h"
-#include "system/player-type-definition.h"
-
-monap_type *initialize_monap_type(PlayerType *player_ptr, monap_type *monap_ptr, MONSTER_IDX m_idx)
-{
-#ifdef JP
- monap_ptr->abbreviate = 0;
-#endif
- monap_ptr->m_idx = m_idx;
- floor_type *floor_ptr = player_ptr->current_floor_ptr;
- monap_ptr->m_ptr = &floor_ptr->m_list[m_idx];
- monap_ptr->act = nullptr;
- monap_ptr->touched = false;
- monap_ptr->explode = false;
- monap_ptr->do_silly_attack = one_in_(2) && player_ptr->hallucinated;
- monap_ptr->obvious = false;
- monap_ptr->get_damage = 0;
- monap_ptr->alive = true;
- monap_ptr->fear = false;
- return monap_ptr;
-}
+++ /dev/null
-#pragma once
-
-#include "monster-attack/monster-attack-effect.h"
-#include "monster-attack/monster-attack-types.h"
-#include "system/angband.h"
-
-/* MONster-Attack-Player、地図のMAPと紛らわしいのでmonapとした */
-struct monster_type;
-struct object_type;
-typedef struct monap_type {
-#ifdef JP
- int abbreviate; // 2回目以降の省略表現フラグ.
-#endif
- MONSTER_IDX m_idx;
- monster_type *m_ptr;
- concptr act;
- int do_cut;
- int do_stun;
- bool touched;
- RaceBlowMethodType method;
- bool explode;
- DEPTH rlev;
- GAME_TEXT m_name[MAX_NLEN];
- bool do_silly_attack;
- int d_dice;
- int d_side;
- object_type *o_ptr;
- bool obvious;
- HIT_POINT damage;
- RaceBlowEffectType effect;
- bool blinked;
- GAME_TEXT o_name[MAX_NLEN];
- HIT_POINT get_damage;
- GAME_TEXT ddesc[MAX_MONSTER_NAME];
- ARMOUR_CLASS ac;
- bool alive;
- bool fear;
-} monap_type;
-
-class PlayerType;
-monap_type *initialize_monap_type(PlayerType *player_ptr, monap_type *monap_ptr, MONSTER_IDX m_idx);
#include "inventory/inventory-object.h"
#include "inventory/inventory-slot-types.h"
#include "mind/mind-mirror-master.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster/monster-status.h"
#include "object/object-info.h"
#include "object/object-kind.h"
#include "view/display-messages.h"
#include "world/world-object.h"
-void process_eat_gold(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_eat_gold(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (!player_ptr->paralyzed && (randint0(100) < (adj_dex_safe[player_ptr->stat_index[A_DEX]] + player_ptr->lev))) {
msg_print(_("しかし素早く財布を守った!", "You quickly protect your money pouch!"));
* @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
* @return 盗まれたらTRUE、何も盗まれなかったらFALSE
*/
-bool check_eat_item(PlayerType *player_ptr, monap_type *monap_ptr)
+bool check_eat_item(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (monster_confused_remaining(monap_ptr->m_ptr))
return false;
* @param player_ptr プレイヤーへの参照ポインタ
* @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
*/
-static void move_item_to_monster(PlayerType *player_ptr, monap_type *monap_ptr, const OBJECT_IDX o_idx)
+static void move_item_to_monster(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr, const OBJECT_IDX o_idx)
{
if (o_idx == 0)
return;
* @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
* @details eatとあるがお金や食べ物と違ってなくならない、盗んだモンスターを倒せば取り戻せる
*/
-void process_eat_item(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_eat_item(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
for (int i = 0; i < 10; i++) {
OBJECT_IDX o_idx;
}
}
-void process_eat_food(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_eat_food(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
for (int i = 0; i < 10; i++) {
INVENTORY_IDX i_idx = (INVENTORY_IDX)randint0(INVEN_PACK);
}
}
-void process_eat_lite(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_eat_lite(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if ((monap_ptr->o_ptr->xtra4 <= 0) || monap_ptr->o_ptr->is_fixed_artifact())
return;
* @details 魔道具使用能力向上フラグがあれば、吸収量は全部ではない
* 詳細はOSDN #40911の議論を参照のこと
*/
-bool process_un_power(PlayerType *player_ptr, monap_type *monap_ptr)
+bool process_un_power(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (((monap_ptr->o_ptr->tval != ItemKindType::STAFF) && (monap_ptr->o_ptr->tval != ItemKindType::WAND)) || (monap_ptr->o_ptr->pval == 0))
return false;
}
}
-void process_drain_life(PlayerType *player_ptr, monap_type *monap_ptr, const bool resist_drain)
+void process_drain_life(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr, const bool resist_drain)
{
if ((monap_ptr->damage <= 5) || resist_drain)
return;
msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), monap_ptr->m_name);
}
-void process_drain_mana(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_drain_mana(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if (check_multishadow(player_ptr)) {
msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, but you are unharmed!"));
* @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
* @details 空腹、衰弱の一歩手前で止める優しさは残す。
*/
-void process_monster_attack_hungry(PlayerType *player_ptr, monap_type *monap_ptr)
+void process_monster_attack_hungry(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
msg_format(_("あなたは腹が減った!", "You feel hungry!"));
auto subtracted_food = static_cast<int16_t>(player_ptr->food - monap_ptr->damage);
#include "system/angband.h"
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void process_eat_gold(PlayerType *player_ptr, monap_type *monap_ptr);
-bool check_eat_item(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_eat_item(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_eat_food(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_eat_lite(PlayerType *player_ptr, monap_type *monap_ptr);
+void process_eat_gold(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+bool check_eat_item(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_eat_item(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_eat_food(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_eat_lite(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
-bool process_un_power(PlayerType *player_ptr, monap_type *monap_ptr);
+bool process_un_power(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
bool check_drain_hp(PlayerType *player_ptr, const int32_t d);
-void process_drain_life(PlayerType *player_ptr, monap_type *monap_ptr, const bool resist_drain);
-void process_drain_mana(PlayerType *player_ptr, monap_type *monap_ptr);
-void process_monster_attack_hungry(PlayerType *player_ptr, monap_type *monap_ptr);
+void process_drain_life(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr, const bool resist_drain);
+void process_drain_mana(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
+void process_monster_attack_hungry(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
if (!are_enemies(player_ptr, m_ptr, t_ptr))
continue;
- if (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != player_ptr->riding) || has_pass_wall(player_ptr)))
- || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != player_ptr->riding))) {
+ if (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != player_ptr->riding) || has_pass_wall(player_ptr))) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != player_ptr->riding))) {
if (!in_disintegration_range(floor_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx))
continue;
} else {
static bool random_walk(PlayerType *player_ptr, DIRECTION *mm, monster_type *m_ptr)
{
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (((r_ptr->flags1 & (RF1_RAND_50 | RF1_RAND_25)) == (RF1_RAND_50 | RF1_RAND_25)) && (randint0(100) < 75)) {
+ if (r_ptr->behavior_flags.has_all_of({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 }) && (randint0(100) < 75)) {
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags1 |= (RF1_RAND_50 | RF1_RAND_25);
+ r_ptr->r_behavior_flags.set({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 });
mm[0] = mm[1] = mm[2] = mm[3] = 5;
return true;
}
- if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 50)) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && (randint0(100) < 50)) {
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags1 |= RF1_RAND_50;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::RAND_MOVE_50);
mm[0] = mm[1] = mm[2] = mm[3] = 5;
return true;
}
- if ((r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 25)) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25) && (randint0(100) < 25)) {
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags1 |= RF1_RAND_25;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::RAND_MOVE_25);
mm[0] = mm[1] = mm[2] = mm[3] = 5;
return true;
if (!is_pet(m_ptr)) {
return false;
}
-
+
bool avoid = ((msd->player_ptr->pet_follow_distance < 0) && (m_ptr->cdis <= (0 - msd->player_ptr->pet_follow_distance)));
bool lonely = (!avoid && (m_ptr->cdis > msd->player_ptr->pet_follow_distance));
bool distant = (m_ptr->cdis > PET_SEEK_DIST);
if (!avoid && !lonely && !distant) {
return true;
}
-
+
POSITION dis = msd->player_ptr->pet_follow_distance;
if (msd->player_ptr->pet_follow_distance > PET_SEEK_DIST) {
msd->player_ptr->pet_follow_distance = PET_SEEK_DIST;
if (random_walk(player_ptr, mm, m_ptr)) {
return true;
}
-
- if ((r_ptr->flags1 & RF1_NEVER_MOVE) && (m_ptr->cdis > 1)) {
+
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE) && (m_ptr->cdis > 1)) {
mm[0] = mm[1] = mm[2] = mm[3] = 5;
return true;
}
if (decide_pet_movement_direction(&msd)) {
return true;
}
-
+
if (!is_hostile(m_ptr)) {
mm[0] = mm[1] = mm[2] = mm[3] = 5;
get_enemy_dir(player_ptr, m_idx, mm);
#include "floor/floor-util.h"
#include "floor/geometry.h"
#include "game-option/cheat-options.h"
+#include "game-option/cheat-types.h"
#include "monster-floor/one-monster-placer.h"
#include "monster-floor/place-monster-types.h"
#include "monster-race/monster-race-hook.h"
#include "util/string-processor.h"
#include "view/display-messages.h"
#include "wizard/wizard-messages.h"
-#include "game-option/cheat-types.h"
#define MON_SCAT_MAXD 10 /*!< mon_scatter()関数によるモンスター配置で許される中心からの最大距離 */
return false;
if (clone || m_ptr->mflag2.has(MonsterConstantFlagType::CLONED)) {
- floor_ptr->m_list[hack_m_idx_ii].mflag2.set({MonsterConstantFlagType::CLONED, MonsterConstantFlagType::NOPET});
+ floor_ptr->m_list[hack_m_idx_ii].mflag2.set({ MonsterConstantFlagType::CLONED, MonsterConstantFlagType::NOPET });
}
return true;
if (monster_has_hostile_align(player_ptr, m_ptr, 0, 0, z_ptr))
return false;
- if (r_ptr->flags7 & RF7_FRIENDLY) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY)) {
if (monster_has_hostile_align(player_ptr, nullptr, 1, -1, z_ptr))
return false;
}
if (r_idx == 0)
return false;
- if ((one_in_(5) || (player_ptr->current_floor_ptr->dun_level == 0)) && !(r_info[r_idx].flags1 & RF1_UNIQUE)
- && angband_strchr("hkoptuyAHLOPTUVY", r_info[r_idx].d_char)) {
+ if ((one_in_(5) || (player_ptr->current_floor_ptr->dun_level == 0)) && !(r_info[r_idx].flags1 & RF1_UNIQUE) && angband_strchr("hkoptuyAHLOPTUVY", r_info[r_idx].d_char)) {
mode |= PM_JURAL;
}
#include "core/player-update-types.h"
#include "core/speed-table.h"
#include "core/window-redrawer.h"
+#include "effect/attribute-types.h"
#include "effect/effect-characteristics.h"
#include "effect/effect-processor.h"
#include "floor/cave.h"
#include "monster/monster-update.h"
#include "pet/pet-util.h"
#include "player/player-status-flags.h"
-#include "effect/attribute-types.h"
#include "system/floor-type-definition.h"
#include "system/grid-type-definition.h"
#include "system/monster-race-definition.h"
static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
{
- return f_ptr->flags.has_not(FloorFeatureType::GLASS) || (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) || (m_ptr->hp >= std::max(m_ptr->maxhp / 3, 200));
+ return f_ptr->flags.has_not(FloorFeatureType::GLASS) || r_info[m_ptr->r_idx].behavior_flags.has(MonsterBehaviorType::STUPID) || (m_ptr->hp >= std::max(m_ptr->maxhp / 3, 200));
}
/*!
return true;
}
- if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) && (can_cross ? f_ptr->flags.has_not(FloorFeatureType::LOS) : !turn_flags_ptr->is_riding_mon)
- && f_ptr->flags.has(FloorFeatureType::HURT_DISI) && f_ptr->flags.has_not(FloorFeatureType::PERMANENT) && check_hp_for_feat_destruction(f_ptr, m_ptr)) {
+ if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) && (can_cross ? f_ptr->flags.has_not(FloorFeatureType::LOS) : !turn_flags_ptr->is_riding_mon) && f_ptr->flags.has(FloorFeatureType::HURT_DISI) && f_ptr->flags.has_not(FloorFeatureType::PERMANENT) && check_hp_for_feat_destruction(f_ptr, m_ptr)) {
turn_flags_ptr->do_move = true;
if (!can_cross)
turn_flags_ptr->must_alter_to_move = true;
feature_type *f_ptr;
f_ptr = &f_info[g_ptr->feat];
turn_flags_ptr->do_move = false;
- if (((r_ptr->flags2 & RF2_OPEN_DOOR) == 0) || f_ptr->flags.has_not(FloorFeatureType::OPEN) || (is_pet(m_ptr) && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
+ if ((r_ptr->behavior_flags.has_not(MonsterBehaviorType::OPEN_DOOR)) || f_ptr->flags.has_not(FloorFeatureType::OPEN) || (is_pet(m_ptr) && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
return true;
if (f_ptr->power == 0) {
static void bash_glass_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, feature_type *f_ptr, bool may_bash)
{
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!may_bash || ((r_ptr->flags2 & RF2_BASH_DOOR) == 0) || f_ptr->flags.has_not(FloorFeatureType::BASH)
- || (is_pet(m_ptr) && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
+ if (!may_bash || (r_ptr->behavior_flags.has_not(MonsterBehaviorType::BASH_DOOR)) || f_ptr->flags.has_not(FloorFeatureType::BASH) || (is_pet(m_ptr) && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
return;
if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power))
if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door)
return true;
- if (turn_flags_ptr->did_bash_door
- && ((randint0(100) < 50) || (feat_state(player_ptr->current_floor_ptr, g_ptr->feat, FloorFeatureType::OPEN) == g_ptr->feat) || f_ptr->flags.has(FloorFeatureType::GLASS))) {
+ if (turn_flags_ptr->did_bash_door && ((randint0(100) < 50) || (feat_state(player_ptr->current_floor_ptr, g_ptr->feat, FloorFeatureType::OPEN) == g_ptr->feat) || f_ptr->flags.has(FloorFeatureType::GLASS))) {
cave_alter_feat(player_ptr, ny, nx, FloorFeatureType::BASH);
if (!monster_is_valid(m_ptr)) {
player_ptr->update |= (PU_FLOW);
player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags2 |= (RF2_BASH_DOOR);
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::BASH_DOOR);
return false;
}
grid_type *g_ptr;
g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!turn_flags_ptr->do_move || !g_ptr->is_rune_protection() || (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(player_ptr, ny, nx)))
+ if (!turn_flags_ptr->do_move || !g_ptr->is_rune_protection() || ((r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) && player_bold(player_ptr, ny, nx)))
return false;
turn_flags_ptr->do_move = false;
grid_type *g_ptr;
g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!turn_flags_ptr->do_move || !g_ptr->is_rune_explosion() || (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(player_ptr, ny, nx)))
+ if (!turn_flags_ptr->do_move || !g_ptr->is_rune_explosion() || ((r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) && player_bold(player_ptr, ny, nx)))
return true;
turn_flags_ptr->do_move = false;
if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
turn_flags_ptr->do_move = false;
- if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE)) {
+ if (turn_flags_ptr->do_move && r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE)) {
if (is_original_ap_and_seen(player_ptr, m_ptr))
- r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::NEVER_MOVE);
turn_flags_ptr->do_move = false;
}
break;
monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
- if (m_ptr->ml
- && (disturb_move || (disturb_near && m_ptr->mflag.has(MonsterTemporaryFlagType::VIEW) && projectable(player_ptr, player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx))
- || (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= player_ptr->lev))) {
+ if (m_ptr->ml && (disturb_move || (disturb_near && m_ptr->mflag.has(MonsterTemporaryFlagType::VIEW) && projectable(player_ptr, player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx)) || (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= player_ptr->lev))) {
if (is_hostile(m_ptr))
disturb(player_ptr, false, true);
}
bool is_takable_or_killable = !g_ptr->o_idx_list.empty();
- is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
+ is_takable_or_killable &= r_ptr->behavior_flags.has_any_of({ MonsterBehaviorType::TAKE_ITEM, MonsterBehaviorType::KILL_ITEM });
bool is_pickup_items = (player_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
- is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
+ is_pickup_items &= r_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM);
is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
if (!is_takable_or_killable) {
msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
}
- if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware || !one_in_(SPEAK_CHANCE) || !player_has_los_bold(player_ptr, oy, ox)
- || !projectable(player_ptr, oy, ox, player_ptr->y, player_ptr->x))
+ if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware || !one_in_(SPEAK_CHANCE) || !player_has_los_bold(player_ptr, oy, ox) || !projectable(player_ptr, oy, ox, player_ptr->y, player_ptr->x))
return;
GAME_TEXT m_name[MAX_NLEN];
* @brief モンスターの目標地点をリセットする / Reset the target of counter attack
* @param m_ptr モンスターの参照ポインタ
*/
-void reset_target(monster_type *m_ptr) { set_target(m_ptr, 0, 0); }
+void reset_target(monster_type *m_ptr)
+{
+ set_target(m_ptr, 0, 0);
+}
#include "monster-floor/monster-object.h"
#include "flavor/flavor-describer.h"
-#include "floor/floor-object.h"
#include "floor/cave.h"
+#include "floor/floor-object.h"
#include "floor/geometry.h"
#include "monster-race/monster-race.h"
#include "monster-race/race-flags-resistance.h"
monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
if (is_special_object) {
- if (turn_flags_ptr->do_take && (r_ptr->flags2 & RF2_STUPID)) {
+ if (turn_flags_ptr->do_take && r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID)) {
turn_flags_ptr->did_take_item = true;
if (m_ptr->ml && player_can_see_bold(player_ptr, ny, nx)) {
msg_format(_("%^sは%sを拾おうとしたが、だめだった。", "%^s tries to pick up %s, but fails."), m_name, o_name);
grid_type *g_ptr;
g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
- turn_flags_ptr->do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
+ turn_flags_ptr->do_take = r_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM);
for (auto it = g_ptr->o_idx_list.begin(); it != g_ptr->o_idx_list.end();) {
BIT_FLAGS flg2 = 0L, flg3 = 0L, flgr = 0L;
GAME_TEXT m_name[MAX_NLEN], o_name[MAX_NLEN];
monster_desc(player_ptr, m_name, m_ptr, MD_INDEF_HIDDEN);
update_object_flags(flgs, &flg2, &flg3, &flgr);
- bool is_special_object = o_ptr->is_artifact() || ((r_ptr->flags3 & flg3) != 0) || ((r_ptr->flags2 & flg2) != 0)
- || (((~(r_ptr->flagsr) & flgr) != 0) && !(r_ptr->flagsr & RFR_RES_ALL));
+ bool is_special_object = o_ptr->is_artifact() || ((r_ptr->flags3 & flg3) != 0) || ((r_ptr->flags2 & flg2) != 0) || (((~(r_ptr->flagsr) & flgr) != 0) && !(r_ptr->flagsr & RFR_RES_ALL));
monster_pickup_object(player_ptr, turn_flags_ptr, m_idx, o_ptr, is_special_object, ny, nx, m_name, o_name, this_o_idx);
}
}
this->can_pass_wall = any_bits(r_ptr->flags2, RF2_PASS_WALL) && ((this->m_idx != this->player_ptr->riding) || has_pass_wall(this->player_ptr));
if (!this->will_run && m_ptr->target_y) {
int t_m_idx = floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
- if ((t_m_idx > 0) && are_enemies(this->player_ptr, m_ptr, &floor_ptr->m_list[t_m_idx])
- && los(this->player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x)
- && projectable(this->player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x)) {
+ if ((t_m_idx > 0) && are_enemies(this->player_ptr, m_ptr, &floor_ptr->m_list[t_m_idx]) && los(this->player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x) && projectable(this->player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x)) {
y = m_ptr->fy - m_ptr->target_y;
x = m_ptr->fx - m_ptr->target_x;
this->done = true;
return;
}
- if ((!los(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x)
- || !projectable(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x))) {
+ if ((!los(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x) || !projectable(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x))) {
if (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(r_ptr) >= MAX_SIGHT / 2) {
return;
}
now_cost = 999;
}
- if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR)) {
+ if (r_ptr->behavior_flags.has_any_of({ MonsterBehaviorType::BASH_DOOR, MonsterBehaviorType::OPEN_DOOR })) {
this->can_open_door = true;
}
auto *floor_ptr = this->player_ptr->current_floor_ptr;
auto *r_ptr = &r_info[floor_ptr->m_list[this->m_idx].r_idx];
auto is_riding = this->m_idx == this->player_ptr->riding;
- if ((none_bits(r_ptr->flags2, RF2_PASS_WALL) || (is_riding && !has_pass_wall(this->player_ptr)))
- && (none_bits(r_ptr->flags2, RF2_KILL_WALL) || is_riding)) {
+ if ((none_bits(r_ptr->flags2, RF2_PASS_WALL) || (is_riding && !has_pass_wall(this->player_ptr))) && (none_bits(r_ptr->flags2, RF2_KILL_WALL) || is_riding)) {
if (this->cost == 0) {
return false;
}
this->best = when;
} else {
auto *r_ptr = &r_info[floor_ptr->m_list[this->m_idx].r_idx];
- this->cost = any_bits(r_ptr->flags2, RF2_BASH_DOOR | RF2_OPEN_DOOR) ? g_ptr->get_distance(r_ptr) : g_ptr->get_cost(r_ptr);
+ this->cost = r_ptr->behavior_flags.has_any_of({ MonsterBehaviorType::BASH_DOOR, MonsterBehaviorType::OPEN_DOOR }) ? g_ptr->get_distance(r_ptr) : g_ptr->get_cost(r_ptr);
if ((this->cost == 0) || (this->best < this->cost)) {
continue;
}
#include "core/player-update-types.h"
#include "core/speed-table.h"
#include "dungeon/quest.h"
+#include "effect/attribute-types.h"
#include "effect/effect-characteristics.h"
#include "effect/effect-processor.h"
#include "flavor/flavor-describer.h"
#include "monster/monster-util.h"
#include "object/warning.h"
#include "player/player-status.h"
-#include "effect/attribute-types.h"
#include "system/floor-type-definition.h"
#include "system/grid-type-definition.h"
#include "system/monster-race-definition.h"
monster_race *r_ptr = &r_info[r_idx];
bool unselectable = any_bits(r_ptr->flags1, RF1_UNIQUE);
unselectable |= any_bits(r_ptr->flags2, RF2_MULTIPLY);
- unselectable |= any_bits(r_ptr->flags7, RF7_FRIENDLY | RF7_CHAMELEON);
- unselectable |= any_bits(r_ptr->flags7, RF7_AQUATIC);
+ unselectable |= r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY);
+ unselectable |= any_bits(r_ptr->flags7, RF7_AQUATIC | RF7_CHAMELEON);
if (unselectable)
return false;
return false;
}
- if (any_bits(r_ptr->flags1, RF1_FORCE_DEPTH) && (player_ptr->current_floor_ptr->dun_level < r_ptr->level)
- && (!ironman_nightmare || any_bits(r_ptr->flags1, RF1_QUESTOR))) {
+ if (any_bits(r_ptr->flags1, RF1_FORCE_DEPTH) && (player_ptr->current_floor_ptr->dun_level < r_ptr->level) && (!ironman_nightmare || any_bits(r_ptr->flags1, RF1_QUESTOR))) {
return false;
}
m_ptr->ml = false;
if (any_bits(mode, PM_FORCE_PET)) {
set_pet(player_ptr, m_ptr);
- } else if (((who == 0) && any_bits(r_ptr->flags7, RF7_FRIENDLY)) || is_friendly_idx(player_ptr, who) || any_bits(mode, PM_FORCE_FRIENDLY)) {
+ } else if (((who == 0) && r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY)) || is_friendly_idx(player_ptr, who) || any_bits(mode, PM_FORCE_FRIENDLY)) {
if (!monster_has_hostile_align(player_ptr, nullptr, 0, -1, r_ptr) && !player_ptr->current_floor_ptr->inside_arena)
set_friendly(m_ptr);
}
m_ptr->energy_need = ENERGY_NEED() - (int16_t)randint0(100) * 2;
}
- if (any_bits(r_ptr->flags1, RF1_PREVENT_SUDDEN_MAGIC) && !ironman_nightmare) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::PREVENT_SUDDEN_MAGIC) && !ironman_nightmare) {
m_ptr->mflag.set(MonsterTemporaryFlagType::PREVENT_MAGIC);
}
if (any_bits(r_ptr->flags2, RF2_MULTIPLY))
return false;
- if (any_bits(r_ptr->flags7, RF7_FRIENDLY))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY))
return false;
return true;
return (any_bits(d_ptr->mflags8, RF8_WILD_MOUNTAIN) && any_bits(r_ptr->flags8, RF8_WILD_MOUNTAIN));
bool land = none_bits(r_ptr->flags7, RF7_AQUATIC);
- return none_bits(d_ptr->mflags8, RF8_WILD_MOUNTAIN | RF8_WILD_VOLCANO)
- || (any_bits(d_ptr->mflags8, RF8_WILD_MOUNTAIN) && (land || any_bits(r_ptr->flags8, RF8_WILD_MOUNTAIN)))
- || (any_bits(d_ptr->mflags8, RF8_WILD_VOLCANO) && (land || any_bits(r_ptr->flags8, RF8_WILD_VOLCANO)));
+ return none_bits(d_ptr->mflags8, RF8_WILD_MOUNTAIN | RF8_WILD_VOLCANO) || (any_bits(d_ptr->mflags8, RF8_WILD_MOUNTAIN) && (land || any_bits(r_ptr->flags8, RF8_WILD_MOUNTAIN))) || (any_bits(d_ptr->mflags8, RF8_WILD_VOLCANO) && (land || any_bits(r_ptr->flags8, RF8_WILD_VOLCANO)));
}
/*!
if (!vault_monster_okay(player_ptr, r_idx))
return false;
- if (any_bits(r_ptr->flags2, RF2_KILL_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_BLOW))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW))
return false;
if (any_bits(r_ptr->flags3, RF3_EVIL))
if (!vault_monster_okay(player_ptr, r_idx))
return false;
- if (any_bits(r_ptr->flags2, RF2_KILL_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_BLOW))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW))
return false;
if (any_bits(r_ptr->flags3, RF3_GOOD))
if (!vault_monster_okay(player_ptr, r_idx))
return false;
- if (any_bits(r_ptr->flags2, RF2_KILL_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_BLOW))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW))
return false;
if (any_bits(r_ptr->flags3, RF3_EVIL))
if (!vault_monster_okay(player_ptr, r_idx))
return false;
- if (any_bits(r_ptr->flags2, RF2_KILL_BODY) && none_bits(r_ptr->flags1, RF1_NEVER_BLOW))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW))
return false;
if (none_bits(r_ptr->flags3, RF3_DEMON))
if (!vault_monster_okay(player_ptr, r_idx))
return false;
- if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY) && r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW))
return false;
if (!(r_ptr->flags2 & (RF2_ELDRITCH_HORROR)))
HIT_POINT dam = 0;
monster_race *r_ptr = &r_info[r_idx];
- bool unselectable = any_bits(r_ptr->flags1, RF1_NEVER_MOVE);
+ bool unselectable = r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE);
unselectable |= any_bits(r_ptr->flags2, RF2_MULTIPLY);
unselectable |= any_bits(r_ptr->flags2, RF2_QUANTUM) && none_bits(r_ptr->flags1, RF1_UNIQUE);
unselectable |= any_bits(r_ptr->flags7, RF7_AQUATIC);
*/
bool vault_monster_okay(PlayerType *player_ptr, MONRACE_IDX r_idx)
{
- return (mon_hook_dungeon(player_ptr, r_idx) && none_bits(r_info[r_idx].flags1, RF1_UNIQUE) && none_bits(r_info[r_idx].flags7, RF7_UNIQUE2)
- && none_bits(r_info[r_idx].flagsr, RFR_RES_ALL) && none_bits(r_info[r_idx].flags7, RF7_AQUATIC));
+ return (mon_hook_dungeon(player_ptr, r_idx) && none_bits(r_info[r_idx].flags1, RF1_UNIQUE) && none_bits(r_info[r_idx].flags7, RF7_UNIQUE2) && none_bits(r_info[r_idx].flagsr, RFR_RES_ALL) && none_bits(r_info[r_idx].flags7, RF7_AQUATIC));
}
ret = ret * 4 / 3;
else if (r_ptr->ability_flags.has(MonsterAbilityType::DRAIN_MANA))
ret = ret * 11 / 10;
- if (r_ptr->flags1 & RF1_RAND_25)
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25))
ret = ret * 9 / 10;
- if (r_ptr->flags1 & RF1_RAND_50)
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50))
ret = ret * 9 / 10;
if (r_ptr->flagsr & RFR_RES_ALL)
ret *= 100000;
S_HI_DRAGON = 93, /* Summon Ancient Dragon */
S_AMBERITES = 94, /* Summon Amberites */
S_UNIQUE = 95, /* Summon Unique Monster */
+ BO_VOID = 97, /*!< モンスター能力: ヴォイド・ボルト / Void Bolt */
+ BO_ABYSS = 98, /*!< モンスター能力: アビス・ボルト / Abyss Bolt */
+ BR_VOID = 99, /*!< モンスター能力: 虚無のブレス / Breathe Void */
+ BR_ABYSS = 100, /*!< モンスター能力: 深淵のブレス / Breathe Abyss */
+ BA_VOID = 101, /*!< モンスター能力: 虚無のボール / Void Ball */
+ BA_ABYSS = 102, /*!< モンスター能力: 深淵のボール / Abyss Ball */
MAX,
};
const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BOLT_MASK = {
MonsterAbilityType::ROCKET, MonsterAbilityType::SHOOT, MonsterAbilityType::BO_ACID, MonsterAbilityType::BO_ELEC,
MonsterAbilityType::BO_FIRE, MonsterAbilityType::BO_COLD, MonsterAbilityType::BO_NETH, MonsterAbilityType::BO_WATE,
- MonsterAbilityType::BO_MANA, MonsterAbilityType::BO_PLAS, MonsterAbilityType::BO_ICEE, MonsterAbilityType::MISSILE,
+ MonsterAbilityType::BO_MANA, MonsterAbilityType::BO_PLAS, MonsterAbilityType::BO_ICEE, MonsterAbilityType::BO_VOID,
+ MonsterAbilityType::BO_ABYSS, MonsterAbilityType::MISSILE,
};
/*
*/
const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BIG_BALL_MASK = {
MonsterAbilityType::BA_CHAO, MonsterAbilityType::BA_LITE, MonsterAbilityType::BA_DARK, MonsterAbilityType::BA_WATE,
- MonsterAbilityType::BA_MANA,
+ MonsterAbilityType::BA_MANA, MonsterAbilityType::BA_VOID, MonsterAbilityType::BA_ABYSS,
};
/*
MonsterAbilityType::BR_CONF, MonsterAbilityType::BR_SOUN, MonsterAbilityType::BR_CHAO, MonsterAbilityType::BR_DISE,
MonsterAbilityType::BR_NEXU, MonsterAbilityType::BR_SHAR, MonsterAbilityType::BR_TIME, MonsterAbilityType::BR_INER,
MonsterAbilityType::BR_GRAV, MonsterAbilityType::BR_PLAS, MonsterAbilityType::BR_FORC, MonsterAbilityType::BR_MANA,
- MonsterAbilityType::BR_NUKE, MonsterAbilityType::BR_DISI,
+ MonsterAbilityType::BR_NUKE, MonsterAbilityType::BR_DISI, MonsterAbilityType::BR_VOID, MonsterAbilityType::BR_ABYSS,
};
/*
--- /dev/null
+#pragma once
+
+enum class MonsterBehaviorType {
+ NEVER_BLOW = 0,
+ NEVER_MOVE = 1,
+ OPEN_DOOR = 2,
+ BASH_DOOR = 3,
+ MOVE_BODY = 4,
+ KILL_BODY = 5,
+ TAKE_ITEM = 6,
+ KILL_ITEM = 7,
+ RAND_MOVE_25 = 8,
+ RAND_MOVE_50 = 9,
+ STUPID = 10,
+ SMART = 11,
+ FRIENDLY = 12,
+ PREVENT_SUDDEN_MAGIC = 13,
+ MAX,
+};
--- /dev/null
+#pragma once
+
+enum class MonsterVisualType {
+ CLEAR = 0,
+ SHAPECHANGER = 1,
+ CLEAR_COLOR = 2,
+ MULTI_COLOR = 3,
+ RANDOM_COLOR = 4,
+ ANY_COLOR = 5,
+ MAX,
+};
\ No newline at end of file
* @brief モンスターを友好的にする
* @param m_ptr モンスター情報構造体の参照ポインタ
*/
-void set_friendly(monster_type *m_ptr) { m_ptr->mflag2.set(MonsterConstantFlagType::FRIENDLY); }
+void set_friendly(monster_type *m_ptr)
+{
+ m_ptr->mflag2.set(MonsterConstantFlagType::FRIENDLY);
+}
/*!
* @brief モンスターが地形を踏破できるかどうかを返す
return false;
}
-bool is_original_ap_and_seen(PlayerType *player_ptr, monster_type *m_ptr) { return m_ptr->ml && !player_ptr->hallucinated && (m_ptr->ap_r_idx == m_ptr->r_idx); }
+bool is_original_ap_and_seen(PlayerType *player_ptr, monster_type *m_ptr)
+{
+ return m_ptr->ml && !player_ptr->hallucinated && (m_ptr->ap_r_idx == m_ptr->r_idx);
+}
/* Determine monster race appearance index is same as race index */
-bool is_original_ap(monster_type *m_ptr) { return m_ptr->ap_r_idx == m_ptr->r_idx; }
+bool is_original_ap(monster_type *m_ptr)
+{
+ return m_ptr->ap_r_idx == m_ptr->r_idx;
+}
-bool is_friendly(monster_type *m_ptr) { return m_ptr->mflag2.has(MonsterConstantFlagType::FRIENDLY); }
+bool is_friendly(monster_type *m_ptr)
+{
+ return m_ptr->mflag2.has(MonsterConstantFlagType::FRIENDLY);
+}
-bool is_pet(monster_type *m_ptr) { return m_ptr->mflag2.has(MonsterConstantFlagType::PET); }
+bool is_pet(monster_type *m_ptr)
+{
+ return m_ptr->mflag2.has(MonsterConstantFlagType::PET);
+}
-bool is_hostile(monster_type *m_ptr) { return !is_friendly(m_ptr) && !is_pet(m_ptr); }
+bool is_hostile(monster_type *m_ptr)
+{
+ return !is_friendly(m_ptr) && !is_pet(m_ptr);
+}
/*!
* @brief モンスターがアイテム類に擬態しているかどうかを返す
if (angband_strchr("/|\\()[]=$,.!?&`#%<>+~", r_ptr->d_char) == nullptr)
return false;
- if (none_bits(r_ptr->flags1, RF1_NEVER_MOVE) && !monster_csleep_remaining(m_ptr)) {
+ if (r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE) && !monster_csleep_remaining(m_ptr)) {
return false;
}
* @param m_ptr モンスターの参照ポインタ
* @return 本当のモンスター種族参照ポインタ
*/
-monster_race *real_r_ptr(monster_type *m_ptr) { return &r_info[real_r_idx(m_ptr)]; }
+monster_race *real_r_ptr(monster_type *m_ptr)
+{
+ return &r_info[real_r_idx(m_ptr)];
+}
MONRACE_IDX real_r_idx(monster_type *m_ptr)
{
if (!(r_ptr->flags1 & (RF1_UNIQUE)))
return false;
- if (r_ptr->flags7 & (RF7_FRIENDLY | RF7_CHAMELEON))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY) || (r_ptr->flags7 & RF7_CHAMELEON))
return false;
if (std::abs(r_ptr->level - r_info[MON_CHAMELEON_K].level) > 5)
return false;
- if ((r_ptr->blow[0].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[1].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[2].method == RaceBlowMethodType::EXPLODE)
- || (r_ptr->blow[3].method == RaceBlowMethodType::EXPLODE))
+ if ((r_ptr->blow[0].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[1].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[2].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[3].method == RaceBlowMethodType::EXPLODE))
return false;
if (!monster_can_cross_terrain(player_ptr, floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].feat, r_ptr, 0))
return false;
if (r_ptr->flags2 & RF2_MULTIPLY)
return false;
- if (r_ptr->flags7 & (RF7_FRIENDLY | RF7_CHAMELEON))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::FRIENDLY) && (r_ptr->flags7 & RF7_CHAMELEON))
return false;
- if ((r_ptr->blow[0].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[1].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[2].method == RaceBlowMethodType::EXPLODE)
- || (r_ptr->blow[3].method == RaceBlowMethodType::EXPLODE))
+ if ((r_ptr->blow[0].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[1].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[2].method == RaceBlowMethodType::EXPLODE) || (r_ptr->blow[3].method == RaceBlowMethodType::EXPLODE))
return false;
if (!monster_can_cross_terrain(player_ptr, floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].feat, r_ptr, 0))
#include "system/monster-race-definition.h"
#include "system/monster-type-definition.h"
- /*!
- * @brief ターン経過フラグ構造体の初期化
- * @param riding_idx 乗馬中のモンスターID
- * @param m_idx モンスターID
- * @return 初期化済のターン経過フラグ
- */
+/*!
+ * @brief ターン経過フラグ構造体の初期化
+ * @param riding_idx 乗馬中のモンスターID
+ * @param m_idx モンスターID
+ * @return 初期化済のターン経過フラグ
+ */
turn_flags *init_turn_flags(MONSTER_IDX riding_idx, MONSTER_IDX m_idx, turn_flags *turn_flags_ptr)
{
- turn_flags_ptr->is_riding_mon = (m_idx == riding_idx);
- turn_flags_ptr->do_turn = false;
- turn_flags_ptr->do_move = false;
- turn_flags_ptr->do_view = false;
- turn_flags_ptr->must_alter_to_move = false;
- turn_flags_ptr->did_open_door = false;
- turn_flags_ptr->did_bash_door = false;
- turn_flags_ptr->did_take_item = false;
- turn_flags_ptr->did_kill_item = false;
- turn_flags_ptr->did_move_body = false;
- turn_flags_ptr->did_pass_wall = false;
- turn_flags_ptr->did_kill_wall = false;
- return turn_flags_ptr;
+ turn_flags_ptr->is_riding_mon = (m_idx == riding_idx);
+ turn_flags_ptr->do_turn = false;
+ turn_flags_ptr->do_move = false;
+ turn_flags_ptr->do_view = false;
+ turn_flags_ptr->must_alter_to_move = false;
+ turn_flags_ptr->did_open_door = false;
+ turn_flags_ptr->did_bash_door = false;
+ turn_flags_ptr->did_take_item = false;
+ turn_flags_ptr->did_kill_item = false;
+ turn_flags_ptr->did_move_body = false;
+ turn_flags_ptr->did_pass_wall = false;
+ turn_flags_ptr->did_kill_wall = false;
+ return turn_flags_ptr;
}
-
/*!
* @brief old_race_flags_ptr の初期化
*/
old_race_flags *init_old_race_flags(old_race_flags *old_race_flags_ptr)
{
- old_race_flags_ptr->old_r_flags1 = 0L;
- old_race_flags_ptr->old_r_flags2 = 0L;
- old_race_flags_ptr->old_r_flags3 = 0L;
- old_race_flags_ptr->old_r_flagsr = 0L;
- old_race_flags_ptr->old_r_ability_flags.clear();
-
- old_race_flags_ptr->old_r_blows0 = 0;
- old_race_flags_ptr->old_r_blows1 = 0;
- old_race_flags_ptr->old_r_blows2 = 0;
- old_race_flags_ptr->old_r_blows3 = 0;
-
- old_race_flags_ptr->old_r_cast_spell = 0;
- return old_race_flags_ptr;
+ old_race_flags_ptr->old_r_flags1 = 0L;
+ old_race_flags_ptr->old_r_flags2 = 0L;
+ old_race_flags_ptr->old_r_flags3 = 0L;
+ old_race_flags_ptr->old_r_flagsr = 0L;
+ old_race_flags_ptr->old_r_ability_flags.clear();
+
+ old_race_flags_ptr->old_r_blows0 = 0;
+ old_race_flags_ptr->old_r_blows1 = 0;
+ old_race_flags_ptr->old_r_blows2 = 0;
+ old_race_flags_ptr->old_r_blows3 = 0;
+
+ old_race_flags_ptr->old_r_cast_spell = 0;
+ return old_race_flags_ptr;
}
-
/*!
* @brief coordinate_candidate の初期化
* @param なし
*/
coordinate_candidate init_coordinate_candidate(void)
{
- coordinate_candidate candidate;
- candidate.gy = 0;
- candidate.gx = 0;
- candidate.gdis = 0;
- return candidate;
+ coordinate_candidate candidate;
+ candidate.gy = 0;
+ candidate.gx = 0;
+ candidate.gdis = 0;
+ return candidate;
}
-
/*!
* @brief モンスターの移動方向を保存する
* @param mm 移動方向
*/
void store_enemy_approch_direction(int *mm, POSITION y, POSITION x)
{
- /* North, South, East, West, North-West, North-East, South-West, South-East */
- if ((y < 0) && (x == 0))
- {
- mm[0] = 8;
- mm[1] = 7;
- mm[2] = 9;
- }
- else if ((y > 0) && (x == 0))
- {
- mm[0] = 2;
- mm[1] = 1;
- mm[2] = 3;
- }
- else if ((x > 0) && (y == 0))
- {
- mm[0] = 6;
- mm[1] = 9;
- mm[2] = 3;
- }
- else if ((x < 0) && (y == 0))
- {
- mm[0] = 4;
- mm[1] = 7;
- mm[2] = 1;
- }
- else if ((y < 0) && (x < 0))
- {
- mm[0] = 7;
- mm[1] = 4;
- mm[2] = 8;
- }
- else if ((y < 0) && (x > 0))
- {
- mm[0] = 9;
- mm[1] = 6;
- mm[2] = 8;
- }
- else if ((y > 0) && (x < 0))
- {
- mm[0] = 1;
- mm[1] = 4;
- mm[2] = 2;
- }
- else if ((y > 0) && (x > 0))
- {
- mm[0] = 3;
- mm[1] = 6;
- mm[2] = 2;
- }
+ /* North, South, East, West, North-West, North-East, South-West, South-East */
+ if ((y < 0) && (x == 0)) {
+ mm[0] = 8;
+ mm[1] = 7;
+ mm[2] = 9;
+ } else if ((y > 0) && (x == 0)) {
+ mm[0] = 2;
+ mm[1] = 1;
+ mm[2] = 3;
+ } else if ((x > 0) && (y == 0)) {
+ mm[0] = 6;
+ mm[1] = 9;
+ mm[2] = 3;
+ } else if ((x < 0) && (y == 0)) {
+ mm[0] = 4;
+ mm[1] = 7;
+ mm[2] = 1;
+ } else if ((y < 0) && (x < 0)) {
+ mm[0] = 7;
+ mm[1] = 4;
+ mm[2] = 8;
+ } else if ((y < 0) && (x > 0)) {
+ mm[0] = 9;
+ mm[1] = 6;
+ mm[2] = 8;
+ } else if ((y > 0) && (x < 0)) {
+ mm[0] = 1;
+ mm[1] = 4;
+ mm[2] = 2;
+ } else if ((y > 0) && (x > 0)) {
+ mm[0] = 3;
+ mm[1] = 6;
+ mm[2] = 2;
+ }
}
-
/*!
* @brief get_movable_grid() における移動の方向を保存する
* @param mm 移動方向
*/
void store_moves_val(int *mm, int y, int x)
{
- POSITION ax = std::abs(x);
- POSITION ay = std::abs(y);
-
- int move_val = 0;
- if (y < 0) move_val += 8;
- if (x > 0) move_val += 4;
-
- if (ay > (ax << 1)) move_val += 2;
- else if (ax > (ay << 1)) move_val++;
-
- switch (move_val)
- {
- case 0:
- {
- mm[0] = 9;
- if (ay > ax)
- {
- mm[1] = 8;
- mm[2] = 6;
- mm[3] = 7;
- mm[4] = 3;
- }
- else
- {
- mm[1] = 6;
- mm[2] = 8;
- mm[3] = 3;
- mm[4] = 7;
- }
-
- break;
- }
- case 1:
- case 9:
- {
- mm[0] = 6;
- if (y < 0)
- {
- mm[1] = 3;
- mm[2] = 9;
- mm[3] = 2;
- mm[4] = 8;
- }
- else
- {
- mm[1] = 9;
- mm[2] = 3;
- mm[3] = 8;
- mm[4] = 2;
- }
-
- break;
- }
- case 2:
- case 6:
- {
- mm[0] = 8;
- if (x < 0)
- {
- mm[1] = 9;
- mm[2] = 7;
- mm[3] = 6;
- mm[4] = 4;
- }
- else
- {
- mm[1] = 7;
- mm[2] = 9;
- mm[3] = 4;
- mm[4] = 6;
- }
-
- break;
- }
- case 4:
- {
- mm[0] = 7;
- if (ay > ax)
- {
- mm[1] = 8;
- mm[2] = 4;
- mm[3] = 9;
- mm[4] = 1;
- }
- else
- {
- mm[1] = 4;
- mm[2] = 8;
- mm[3] = 1;
- mm[4] = 9;
- }
-
- break;
- }
- case 5:
- case 13:
- {
- mm[0] = 4;
- if (y < 0)
- {
- mm[1] = 1;
- mm[2] = 7;
- mm[3] = 2;
- mm[4] = 8;
- }
- else
- {
- mm[1] = 7;
- mm[2] = 1;
- mm[3] = 8;
- mm[4] = 2;
- }
-
- break;
- }
- case 8:
- {
- mm[0] = 3;
- if (ay > ax)
- {
- mm[1] = 2;
- mm[2] = 6;
- mm[3] = 1;
- mm[4] = 9;
- }
- else
- {
- mm[1] = 6;
- mm[2] = 2;
- mm[3] = 9;
- mm[4] = 1;
- }
-
- break;
- }
- case 10:
- case 14:
- {
- mm[0] = 2;
- if (x < 0)
- {
- mm[1] = 3;
- mm[2] = 1;
- mm[3] = 6;
- mm[4] = 4;
- }
- else
- {
- mm[1] = 1;
- mm[2] = 3;
- mm[3] = 4;
- mm[4] = 6;
- }
-
- break;
- }
- case 12:
- {
- mm[0] = 1;
- if (ay > ax)
- {
- mm[1] = 2;
- mm[2] = 4;
- mm[3] = 3;
- mm[4] = 7;
- }
- else
- {
- mm[1] = 4;
- mm[2] = 2;
- mm[3] = 7;
- mm[4] = 3;
- }
-
- break;
- }
- }
+ POSITION ax = std::abs(x);
+ POSITION ay = std::abs(y);
+
+ int move_val = 0;
+ if (y < 0)
+ move_val += 8;
+ if (x > 0)
+ move_val += 4;
+
+ if (ay > (ax << 1))
+ move_val += 2;
+ else if (ax > (ay << 1))
+ move_val++;
+
+ switch (move_val) {
+ case 0: {
+ mm[0] = 9;
+ if (ay > ax) {
+ mm[1] = 8;
+ mm[2] = 6;
+ mm[3] = 7;
+ mm[4] = 3;
+ } else {
+ mm[1] = 6;
+ mm[2] = 8;
+ mm[3] = 3;
+ mm[4] = 7;
+ }
+
+ break;
+ }
+ case 1:
+ case 9: {
+ mm[0] = 6;
+ if (y < 0) {
+ mm[1] = 3;
+ mm[2] = 9;
+ mm[3] = 2;
+ mm[4] = 8;
+ } else {
+ mm[1] = 9;
+ mm[2] = 3;
+ mm[3] = 8;
+ mm[4] = 2;
+ }
+
+ break;
+ }
+ case 2:
+ case 6: {
+ mm[0] = 8;
+ if (x < 0) {
+ mm[1] = 9;
+ mm[2] = 7;
+ mm[3] = 6;
+ mm[4] = 4;
+ } else {
+ mm[1] = 7;
+ mm[2] = 9;
+ mm[3] = 4;
+ mm[4] = 6;
+ }
+
+ break;
+ }
+ case 4: {
+ mm[0] = 7;
+ if (ay > ax) {
+ mm[1] = 8;
+ mm[2] = 4;
+ mm[3] = 9;
+ mm[4] = 1;
+ } else {
+ mm[1] = 4;
+ mm[2] = 8;
+ mm[3] = 1;
+ mm[4] = 9;
+ }
+
+ break;
+ }
+ case 5:
+ case 13: {
+ mm[0] = 4;
+ if (y < 0) {
+ mm[1] = 1;
+ mm[2] = 7;
+ mm[3] = 2;
+ mm[4] = 8;
+ } else {
+ mm[1] = 7;
+ mm[2] = 1;
+ mm[3] = 8;
+ mm[4] = 2;
+ }
+
+ break;
+ }
+ case 8: {
+ mm[0] = 3;
+ if (ay > ax) {
+ mm[1] = 2;
+ mm[2] = 6;
+ mm[3] = 1;
+ mm[4] = 9;
+ } else {
+ mm[1] = 6;
+ mm[2] = 2;
+ mm[3] = 9;
+ mm[4] = 1;
+ }
+
+ break;
+ }
+ case 10:
+ case 14: {
+ mm[0] = 2;
+ if (x < 0) {
+ mm[1] = 3;
+ mm[2] = 1;
+ mm[3] = 6;
+ mm[4] = 4;
+ } else {
+ mm[1] = 1;
+ mm[2] = 3;
+ mm[3] = 4;
+ mm[4] = 6;
+ }
+
+ break;
+ }
+ case 12: {
+ mm[0] = 1;
+ if (ay > ax) {
+ mm[1] = 2;
+ mm[2] = 4;
+ mm[3] = 3;
+ mm[4] = 7;
+ } else {
+ mm[1] = 4;
+ mm[2] = 2;
+ mm[3] = 7;
+ mm[4] = 3;
+ }
+
+ break;
+ }
+ }
}
-
/*!
* @brief 古いモンスター情報の保存
* @param monster_race_idx モンスターID
*/
void save_old_race_flags(MONRACE_IDX monster_race_idx, old_race_flags *old_race_flags_ptr)
{
- if (monster_race_idx == 0) return;
+ if (monster_race_idx == 0)
+ return;
- monster_race *r_ptr;
- r_ptr = &r_info[monster_race_idx];
+ monster_race *r_ptr;
+ r_ptr = &r_info[monster_race_idx];
- old_race_flags_ptr->old_r_flags1 = r_ptr->r_flags1;
- old_race_flags_ptr->old_r_flags2 = r_ptr->r_flags2;
- old_race_flags_ptr->old_r_flags3 = r_ptr->r_flags3;
- old_race_flags_ptr->old_r_flagsr = r_ptr->r_flagsr;
- old_race_flags_ptr->old_r_ability_flags = r_ptr->r_ability_flags;
+ old_race_flags_ptr->old_r_flags1 = r_ptr->r_flags1;
+ old_race_flags_ptr->old_r_flags2 = r_ptr->r_flags2;
+ old_race_flags_ptr->old_r_flags3 = r_ptr->r_flags3;
+ old_race_flags_ptr->old_r_flagsr = r_ptr->r_flagsr;
+ old_race_flags_ptr->old_r_ability_flags = r_ptr->r_ability_flags;
- old_race_flags_ptr->old_r_blows0 = r_ptr->r_blows[0];
- old_race_flags_ptr->old_r_blows1 = r_ptr->r_blows[1];
- old_race_flags_ptr->old_r_blows2 = r_ptr->r_blows[2];
- old_race_flags_ptr->old_r_blows3 = r_ptr->r_blows[3];
+ old_race_flags_ptr->old_r_blows0 = r_ptr->r_blows[0];
+ old_race_flags_ptr->old_r_blows1 = r_ptr->r_blows[1];
+ old_race_flags_ptr->old_r_blows2 = r_ptr->r_blows[2];
+ old_race_flags_ptr->old_r_blows3 = r_ptr->r_blows[3];
- old_race_flags_ptr->old_r_cast_spell = r_ptr->r_cast_spell;
+ old_race_flags_ptr->old_r_cast_spell = r_ptr->r_cast_spell;
}
-
/*!
* @brief モンスターの加速値を決定する
* @param m_ptr モンスターへの参照ポインタ
*/
SPEED decide_monster_speed(monster_type *m_ptr)
{
- SPEED speed = m_ptr->mspeed;
- if (ironman_nightmare) speed += 5;
+ SPEED speed = m_ptr->mspeed;
+ if (ironman_nightmare)
+ speed += 5;
- if (monster_fast_remaining(m_ptr)) speed += 10;
- if (monster_slow_remaining(m_ptr)) speed -= 10;
+ if (monster_fast_remaining(m_ptr))
+ speed += 10;
+ if (monster_slow_remaining(m_ptr))
+ speed -= 10;
- return speed;
+ return speed;
}
#pragma once
-#include "system/angband.h"
#include "monster-race/race-ability-flags.h"
+#include "monster-race/race-behavior-flags.h"
+#include "system/angband.h"
#include "util/flag-group.h"
-typedef struct turn_flags {
- bool see_m;
- bool aware;
- bool is_riding_mon;
- bool do_turn;
- bool do_move;
- bool do_view;
- bool do_take;
- bool must_alter_to_move;
-
- bool did_open_door;
- bool did_bash_door;
- bool did_take_item;
- bool did_kill_item;
- bool did_move_body;
- bool did_pass_wall;
- bool did_kill_wall;
-} turn_flags;
-
-typedef struct old_race_flags {
- BIT_FLAGS old_r_flags1;
- BIT_FLAGS old_r_flags2;
- BIT_FLAGS old_r_flags3;
- BIT_FLAGS old_r_flagsr;
- EnumClassFlagGroup<MonsterAbilityType> old_r_ability_flags;
-
- byte old_r_blows0;
- byte old_r_blows1;
- byte old_r_blows2;
- byte old_r_blows3;
-
- byte old_r_cast_spell;
-} old_race_flags;
-
-typedef struct coordinate_candidate {
- POSITION gy;
- POSITION gx;
- POSITION gdis;
-} coordinate_candidate;
+struct turn_flags {
+ bool see_m;
+ bool aware;
+ bool is_riding_mon;
+ bool do_turn;
+ bool do_move;
+ bool do_view;
+ bool do_take;
+ bool must_alter_to_move;
+
+ bool did_open_door;
+ bool did_bash_door;
+ bool did_take_item;
+ bool did_kill_item;
+ bool did_move_body;
+ bool did_pass_wall;
+ bool did_kill_wall;
+};
+
+struct old_race_flags {
+ BIT_FLAGS old_r_flags1;
+ BIT_FLAGS old_r_flags2;
+ BIT_FLAGS old_r_flags3;
+ BIT_FLAGS old_r_flagsr;
+ EnumClassFlagGroup<MonsterAbilityType> old_r_ability_flags;
+ EnumClassFlagGroup<MonsterBehaviorType> old_r_behavior_flags;
+
+ byte old_r_blows0;
+ byte old_r_blows1;
+ byte old_r_blows2;
+ byte old_r_blows3;
+
+ byte old_r_cast_spell;
+};
+
+struct coordinate_candidate {
+ POSITION gy;
+ POSITION gx;
+ POSITION gdis;
+};
struct monster_type;
turn_flags *init_turn_flags(MONSTER_IDX riding_idx, MONSTER_IDX m_idx, turn_flags *turn_flags_ptr);
player_ptr->window_flags |= PW_OVERHEAD | PW_DUNGEON;
}
- if (turn_flags_ptr->do_move
- && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
- || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !player_ptr->phase_out))) {
+ if (turn_flags_ptr->do_move && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2)) || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !player_ptr->phase_out))) {
player_ptr->update |= PU_MON_LITE;
}
}
return;
if (turn_flags_ptr->did_open_door)
- r_ptr->r_flags2 |= RF2_OPEN_DOOR;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::OPEN_DOOR);
if (turn_flags_ptr->did_bash_door)
- r_ptr->r_flags2 |= RF2_BASH_DOOR;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::BASH_DOOR);
if (turn_flags_ptr->did_take_item)
- r_ptr->r_flags2 |= RF2_TAKE_ITEM;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::TAKE_ITEM);
if (turn_flags_ptr->did_kill_item)
- r_ptr->r_flags2 |= RF2_KILL_ITEM;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::KILL_ITEM);
if (turn_flags_ptr->did_move_body)
- r_ptr->r_flags2 |= RF2_MOVE_BODY;
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::MOVE_BODY);
if (turn_flags_ptr->did_pass_wall)
r_ptr->r_flags2 |= RF2_PASS_WALL;
{
monster_race *r_ptr;
r_ptr = &r_info[player_ptr->monster_race_idx];
- if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) || (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2)
- || (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) || (old_race_flags_ptr->old_r_ability_flags != r_ptr->r_ability_flags)
- || (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0])
- || (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2])
- || (old_race_flags_ptr->old_r_blows3 != r_ptr->r_blows[3]) || (old_race_flags_ptr->old_r_cast_spell != r_ptr->r_cast_spell)) {
+ if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) || (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2) ||
+ (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) || (old_race_flags_ptr->old_r_ability_flags != r_ptr->r_ability_flags) ||
+ (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0]) ||
+ (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2]) ||
+ (old_race_flags_ptr->old_r_blows3 != r_ptr->r_blows[3]) || (old_race_flags_ptr->old_r_cast_spell != r_ptr->r_cast_spell)) {
player_ptr->window_flags |= PW_MONSTER;
}
}
static void update_smart_stupid_flags(monster_race *r_ptr)
{
- if (r_ptr->flags2 & RF2_SMART)
- r_ptr->r_flags2 |= RF2_SMART;
+ if (r_ptr->r_behavior_flags.has(MonsterBehaviorType::SMART))
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::SMART);
- if (r_ptr->flags2 & RF2_STUPID)
- r_ptr->r_flags2 |= RF2_STUPID;
+ if (r_ptr->r_behavior_flags.has(MonsterBehaviorType::STUPID))
+ r_ptr->r_behavior_flags.set(MonsterBehaviorType::STUPID);
}
/*!
r_ptr->r_sights++;
}
- if (w_ptr->is_loading_now && w_ptr->character_dungeon && !player_ptr->phase_out
- && r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
+ if (w_ptr->is_loading_now && w_ptr->character_dungeon && !player_ptr->phase_out && r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::SANITY_BLAST);
- if (disturb_near
- && (projectable(player_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, player_ptr->y, player_ptr->x)
- && projectable(player_ptr, player_ptr->y, player_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
+ if (disturb_near && (projectable(player_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, player_ptr->y, player_ptr->x) && projectable(player_ptr, player_ptr->y, player_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
if (disturb_pets || is_hostile(um_ptr->m_ptr))
disturb(player_ptr, true, true);
}
{
monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!smart_learn || ((r_ptr->flags2 & RF2_STUPID) != 0) || (((r_ptr->flags2 & RF2_SMART) == 0) && (randint0(100) < 50)))
+ if (!smart_learn || (r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID)) || ((r_ptr->behavior_flags.has_not(MonsterBehaviorType::SMART)) && (randint0(100) < 50)))
return;
switch (what) {
if (d_ptr->flags.has(DungeonFeatureType::NO_MELEE)) {
if (r_idx == MON_CHAMELEON)
return true;
- if (r_ptr->ability_flags.has_none_of(RF_ABILITY_BOLT_MASK | RF_ABILITY_BEAM_MASK | RF_ABILITY_BALL_MASK)
- && r_ptr->ability_flags.has_none_of(
- { MonsterAbilityType::CAUSE_1, MonsterAbilityType::CAUSE_2, MonsterAbilityType::CAUSE_3, MonsterAbilityType::CAUSE_4, MonsterAbilityType::MIND_BLAST, MonsterAbilityType::BRAIN_SMASH }))
+ if (r_ptr->ability_flags.has_none_of(RF_ABILITY_BOLT_MASK | RF_ABILITY_BEAM_MASK | RF_ABILITY_BALL_MASK) && r_ptr->ability_flags.has_none_of(
+ { MonsterAbilityType::CAUSE_1, MonsterAbilityType::CAUSE_2, MonsterAbilityType::CAUSE_3, MonsterAbilityType::CAUSE_4, MonsterAbilityType::MIND_BLAST, MonsterAbilityType::BRAIN_SMASH }))
return false;
}
return false;
}
- if (d_ptr->m_ability_flags.any()) {
- if (!r_ptr->ability_flags.has_all_of(d_ptr->m_ability_flags))
+ if (d_ptr->mon_ability_flags.any()) {
+ if (!r_ptr->ability_flags.has_all_of(d_ptr->mon_ability_flags))
+ return false;
+ }
+
+ if (d_ptr->mon_behavior_flags.any()) {
+ if (!r_ptr->behavior_flags.has_all_of(d_ptr->mon_behavior_flags))
return false;
}
return true;
}
- if (d_ptr->m_ability_flags.any()) {
- if (!r_ptr->ability_flags.has_all_of(d_ptr->m_ability_flags))
+ if (d_ptr->mon_ability_flags.any()) {
+ if (!r_ptr->ability_flags.has_all_of(d_ptr->mon_ability_flags))
+ return true;
+ }
+
+ if (d_ptr->mon_behavior_flags.any()) {
+ if (!r_ptr->behavior_flags.has_all_of(d_ptr->mon_behavior_flags))
return true;
}
return true;
if (r_ptr->flags3 & d_ptr->mflags3)
return true;
- if (r_ptr->ability_flags.has_any_of(d_ptr->m_ability_flags))
+ if (r_ptr->ability_flags.has_any_of(d_ptr->mon_ability_flags))
+ return true;
+ if (r_ptr->behavior_flags.has_any_of(d_ptr->mon_behavior_flags))
return true;
if (r_ptr->flags7 & d_ptr->mflags7)
return true;
return false;
if (r_ptr->flags3 & d_ptr->mflags3)
return false;
- if (r_ptr->ability_flags.has_any_of(d_ptr->m_ability_flags))
+ if (r_ptr->ability_flags.has_any_of(d_ptr->mon_ability_flags))
+ return false;
+ if (r_ptr->behavior_flags.has_any_of(d_ptr->mon_behavior_flags))
return false;
if (r_ptr->flags7 & d_ptr->mflags7)
return false;
case MonsterAbilityType::BR_NUKE: return spell_RF4_BREATH(player_ptr, AttributeType::NUKE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_NUKE */
case MonsterAbilityType::BA_CHAO: return spell_RF4_BA_CHAO(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BA_CHAO */
case MonsterAbilityType::BR_DISI: return spell_RF4_BREATH(player_ptr, AttributeType::DISINTEGRATE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_DISI */
+ case MonsterAbilityType::BR_VOID: return spell_RF4_BREATH(player_ptr, AttributeType::VOID_MAGIC, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_VOID */
+ case MonsterAbilityType::BR_ABYSS: return spell_RF4_BREATH(player_ptr, AttributeType::ABYSS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ABYSS */
case MonsterAbilityType::BA_ACID: return spell_RF5_BA_ACID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ACID */
case MonsterAbilityType::BA_ELEC: return spell_RF5_BA_ELEC(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ELEC */
case MonsterAbilityType::BA_FIRE: return spell_RF5_BA_FIRE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_FIRE */
case MonsterAbilityType::BA_WATE: return spell_RF5_BA_WATE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_WATE */
case MonsterAbilityType::BA_MANA: return spell_RF5_BA_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_MANA */
case MonsterAbilityType::BA_DARK: return spell_RF5_BA_DARK(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_DARK */
+ case MonsterAbilityType::BA_VOID: return spell_RF5_BA_VOID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_VOID */
+ case MonsterAbilityType::BA_ABYSS: return spell_RF5_BA_ABYSS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ABYSS */
case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_DRAIN_MANA */
case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MIND_BLAST */
case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MIND_BLAST */
case MonsterAbilityType::BO_MANA: return spell_RF5_BO_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_MANA */
case MonsterAbilityType::BO_PLAS: return spell_RF5_BO_PLAS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_PLAS */
case MonsterAbilityType::BO_ICEE: return spell_RF5_BO_ICEE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_ICEE */
+ case MonsterAbilityType::BO_VOID: return spell_RF5_BO_VOID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_VOID */
+ case MonsterAbilityType::BO_ABYSS: return spell_RF5_BO_ABYSS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_ABYSS */
case MonsterAbilityType::MISSILE: return spell_RF5_MISSILE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MISSILE */
case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_SCARE */
case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_BLIND */
case MonsterAbilityType::BR_NUKE: return spell_RF4_BREATH(player_ptr, AttributeType::NUKE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_NUKE */
case MonsterAbilityType::BA_CHAO: return spell_RF4_BA_CHAO(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BA_CHAO */
case MonsterAbilityType::BR_DISI: return spell_RF4_BREATH(player_ptr, AttributeType::DISINTEGRATE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_DISI */
+ case MonsterAbilityType::BR_VOID: return spell_RF4_BREATH(player_ptr, AttributeType::VOID_MAGIC, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_VOID */
+ case MonsterAbilityType::BR_ABYSS: return spell_RF4_BREATH(player_ptr, AttributeType::ABYSS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ABYSS */
case MonsterAbilityType::BA_ACID: return spell_RF5_BA_ACID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ACID */
case MonsterAbilityType::BA_ELEC: return spell_RF5_BA_ELEC(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ELEC */
case MonsterAbilityType::BA_FIRE: return spell_RF5_BA_FIRE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_FIRE */
case MonsterAbilityType::BA_WATE: return spell_RF5_BA_WATE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_WATE */
case MonsterAbilityType::BA_MANA: return spell_RF5_BA_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_MANA */
case MonsterAbilityType::BA_DARK: return spell_RF5_BA_DARK(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_DARK */
+ case MonsterAbilityType::BA_VOID: return spell_RF5_BA_VOID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_VOID */
+ case MonsterAbilityType::BA_ABYSS: return spell_RF5_BA_ABYSS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ABYSS */
case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_DRAIN_MANA */
case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_MIND_BLAST */
case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BRAIN_SMASH */
case MonsterAbilityType::BO_MANA: return spell_RF5_BO_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_MANA */
case MonsterAbilityType::BO_PLAS: return spell_RF5_BO_PLAS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_PLAS */
case MonsterAbilityType::BO_ICEE: return spell_RF5_BO_ICEE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_ICEE */
+ case MonsterAbilityType::BO_VOID: return spell_RF5_BO_VOID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_VOID */
+ case MonsterAbilityType::BO_ABYSS: return spell_RF5_BO_ABYSS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_ABYSS */
case MonsterAbilityType::MISSILE: return spell_RF5_MISSILE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_MISSILE */
case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_SCARE */
case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_BLIND */
void add_cheat_remove_flags_others(PlayerType *player_ptr, msr_type *msr_ptr)
{
- if (has_resist_neth(player_ptr))
+ if (has_resist_neth(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_NETH);
+ }
- if (has_resist_lite(player_ptr))
+ if (has_resist_lite(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_LITE);
+ }
- if (has_resist_dark(player_ptr))
+ if (has_resist_dark(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_DARK);
+ }
- if (has_resist_fear(player_ptr))
+ if (has_resist_fear(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_FEAR);
+ }
- if (has_resist_conf(player_ptr))
+ if (has_resist_conf(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_CONF);
+ }
- if (has_resist_chaos(player_ptr))
+ if (has_resist_chaos(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_CHAOS);
+ }
- if (has_resist_disen(player_ptr))
+ if (has_resist_disen(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_DISEN);
+ }
- if (has_resist_blind(player_ptr))
+ if (has_resist_blind(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_BLIND);
+ }
- if (has_resist_nexus(player_ptr))
+ if (has_resist_nexus(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_NEXUS);
+ }
- if (has_resist_sound(player_ptr))
+ if (has_resist_sound(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_SOUND);
+ }
- if (has_resist_shard(player_ptr))
+ if (has_resist_shard(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::RES_SHARD);
+ }
- if (has_reflect(player_ptr))
+ if (has_reflect(player_ptr)) {
msr_ptr->smart.set(MonsterSmartLearnType::IMM_REFLECT);
+ }
- if (player_ptr->free_act)
+ if (player_ptr->free_act) {
msr_ptr->smart.set(MonsterSmartLearnType::IMM_FREE);
+ }
- if (!player_ptr->msp)
+ if (!player_ptr->msp) {
msr_ptr->smart.set(MonsterSmartLearnType::IMM_MANA);
+ }
}
static void check_nether_resistance(PlayerType *player_ptr, msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_NETH))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_NETH)) {
return;
+ }
if (PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_NETH);
return;
}
- if (int_outof(msr_ptr->r_ptr, 20))
+ if (int_outof(msr_ptr->r_ptr, 20)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_NETH);
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BA_NETH);
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_NETH);
+ }
}
static void check_lite_resistance(msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_LITE))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_LITE)) {
return;
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_LITE);
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BA_LITE);
+ }
}
static void check_dark_resistance(PlayerType *player_ptr, msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_DARK))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_DARK)) {
return;
+ }
if (PlayerRace(player_ptr).tr_flags().has(TR_IM_DARK)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_DARK);
return;
}
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_DARK);
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BA_DARK);
+ }
}
static void check_conf_resistance(msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_CONF))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_CONF)) {
return;
+ }
msr_ptr->ability_flags.reset(MonsterAbilityType::CONF);
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_CONF);
+ }
}
static void check_chaos_resistance(msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_CHAOS))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_CHAOS)) {
return;
+ }
- if (int_outof(msr_ptr->r_ptr, 20))
+ if (int_outof(msr_ptr->r_ptr, 20)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_CHAO);
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BA_CHAO);
+ }
}
static void check_nexus_resistance(msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_NEXUS))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::RES_NEXUS)) {
return;
+ }
- if (int_outof(msr_ptr->r_ptr, 50))
+ if (int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_NEXU);
+ }
msr_ptr->ability_flags.reset(MonsterAbilityType::TELE_LEVEL);
}
static void check_reflection(msr_type *msr_ptr)
{
- if (msr_ptr->smart.has_not(MonsterSmartLearnType::IMM_REFLECT))
+ if (msr_ptr->smart.has_not(MonsterSmartLearnType::IMM_REFLECT)) {
return;
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_COLD);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_FIRE);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ACID);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ELEC);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_NETH);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_WATE);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_MANA);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_PLAS);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ICEE);
+ }
+
+ if (int_outof(msr_ptr->r_ptr, 150)) {
+ msr_ptr->ability_flags.reset(MonsterAbilityType::BO_VOID);
+ }
- if (int_outof(msr_ptr->r_ptr, 150))
+ if (int_outof(msr_ptr->r_ptr, 150)) {
+ msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ABYSS);
+ }
+
+ if (int_outof(msr_ptr->r_ptr, 150)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::MISSILE);
+ }
}
void check_high_resistances(PlayerType *player_ptr, msr_type *msr_ptr)
check_nether_resistance(player_ptr, msr_ptr);
check_lite_resistance(msr_ptr);
check_dark_resistance(player_ptr, msr_ptr);
- if (msr_ptr->smart.has(MonsterSmartLearnType::RES_FEAR))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::RES_FEAR)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::SCARE);
+ }
check_conf_resistance(msr_ptr);
check_chaos_resistance(msr_ptr);
- if (msr_ptr->smart.has(MonsterSmartLearnType::RES_DISEN) && int_outof(msr_ptr->r_ptr, 40))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::RES_DISEN) && int_outof(msr_ptr->r_ptr, 40)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_DISE);
+ }
- if (msr_ptr->smart.has(MonsterSmartLearnType::RES_BLIND))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::RES_BLIND)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BLIND);
+ }
check_nexus_resistance(msr_ptr);
- if (msr_ptr->smart.has(MonsterSmartLearnType::RES_SOUND) && int_outof(msr_ptr->r_ptr, 50))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::RES_SOUND) && int_outof(msr_ptr->r_ptr, 50)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_SOUN);
+ }
- if (msr_ptr->smart.has(MonsterSmartLearnType::RES_SHARD) && int_outof(msr_ptr->r_ptr, 40))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::RES_SHARD) && int_outof(msr_ptr->r_ptr, 40)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::BR_SHAR);
+ }
check_reflection(msr_ptr);
if (msr_ptr->smart.has(MonsterSmartLearnType::IMM_FREE)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::SLOW);
}
- if (msr_ptr->smart.has(MonsterSmartLearnType::IMM_MANA))
+ if (msr_ptr->smart.has(MonsterSmartLearnType::IMM_MANA)) {
msr_ptr->ability_flags.reset(MonsterAbilityType::DRAIN_MANA);
+ }
}
{
msr_type tmp_msr;
msr_type *msr_ptr = initialize_msr_type(player_ptr, &tmp_msr, m_idx, ability_flags);
- if (msr_ptr->r_ptr->flags2 & RF2_STUPID)
+ if (msr_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return;
if (!smart_cheat && !smart_learn)
{ MonsterAbilityType::BR_NUKE, { 25, 15, 70, 800, 95, A_CON, _("放射性廃棄物のブレス", "breathe nuke") } },
{ MonsterAbilityType::BA_CHAO, { 30, 32, 85, 400, 80, A_INT, _("純ログルス", "raw Logrus") } },
{ MonsterAbilityType::BR_DISI, { 35, 40, 95, 150, 95, A_CON, _("分解のブレス", "breathe disintegration") } },
+ { MonsterAbilityType::BR_VOID, { 40, 44, 95, 250, 95, A_CON, _("虚無のブレス", "breathe void") } },
+ { MonsterAbilityType::BR_ABYSS, { 40, 44, 95, 250, 95, A_CON, _("深淵のブレス", "breathe abyss") } },
{ MonsterAbilityType::BA_ACID, { 18, 13, 55, 630, 80, A_INT, _("アシッド・ボール", "acid ball") } },
{ MonsterAbilityType::BA_ELEC, { 14, 10, 45, 316, 60, A_INT, _("サンダー・ボール", "lightning ball") } },
{ MonsterAbilityType::BA_WATE, { 30, 22, 75, 350, 80, A_INT, _("ウォーター・ボール", "water ball") } },
{ MonsterAbilityType::BA_MANA, { 44, 45, 85, 550, 95, A_INT, _("魔力の嵐", "mana storm") } },
{ MonsterAbilityType::BA_DARK, { 40, 42, 90, 550, 95, A_INT, _("暗黒の嵐", "darkness storm") } },
+ { MonsterAbilityType::BA_VOID, { 38, 41, 85, 400, 90, A_INT, _("虚無の嵐", "void ball") } },
+ { MonsterAbilityType::BA_ABYSS, { 39, 42, 85, 400, 90, A_INT, _("深淵の嵐", "abyss ball") } },
{ MonsterAbilityType::DRAIN_MANA, { 10, 5, 50, 0, 25, A_INT, _("魔力吸収", "drain mana") } },
{ MonsterAbilityType::MIND_BLAST, { 25, 10, 60, 0, 30, A_INT, _("精神攻撃", "mind blast") } },
{ MonsterAbilityType::BRAIN_SMASH, { 30, 14, 65, 0, 30, A_INT, _("脳攻撃", "brain smash") } },
{ MonsterAbilityType::BO_MANA, { 25, 24, 90, 400, 80, A_INT, _("魔力の矢", "mana bolt") } },
{ MonsterAbilityType::BO_PLAS, { 25, 20, 80, 216, 60, A_INT, _("プラズマ・ボルト", "plasma bolt") } },
{ MonsterAbilityType::BO_ICEE, { 25, 16, 60, 186, 60, A_INT, _("極寒の矢", "ice bolt") } },
+ { MonsterAbilityType::BO_VOID, { 35, 31, 80, 342, 70, A_INT, _("ヴォイド・ボルト", "void bolt") } },
+ { MonsterAbilityType::BO_ABYSS, { 35, 33, 80, 342, 70, A_INT, _("アビス・ボルト", "abyss bolt") } },
{ MonsterAbilityType::MISSILE, { 3, 1, 25, 12, 20, A_INT, _("マジック・ミサイル", "magic missile") } },
{ MonsterAbilityType::SCARE, { 5, 3, 35, 0, 20, A_INT, _("恐慌", "scare") } },
{ MonsterAbilityType::BLIND, { 10, 5, 40, 0, 20, A_INT, _("盲目", "blind") } },
{ MonsterAbilityType::BR_NUKE, _("放射性廃棄物", "Nuke") },
{ MonsterAbilityType::BA_CHAO, _("純ログルス", "Logrus") },
{ MonsterAbilityType::BR_DISI, _("分解", "Disintegration") },
+ { MonsterAbilityType::BR_VOID, _("虚無", "Void") },
+ { MonsterAbilityType::BR_ABYSS, _("深淵", "Abyss") },
{ MonsterAbilityType::BA_ACID, _("酸", "Acid") },
{ MonsterAbilityType::BA_ELEC, _("電撃", "Lightning") },
{ MonsterAbilityType::BA_WATE, _("ウォーター", "Water") },
{ MonsterAbilityType::BA_MANA, _("魔力の嵐", "Mana storm") },
{ MonsterAbilityType::BA_DARK, _("暗黒の嵐", "Darkness storm") },
+ { MonsterAbilityType::BA_VOID, _("虚無", "Void") },
+ { MonsterAbilityType::BA_ABYSS, _("深淵", "Abyss") },
{ MonsterAbilityType::DRAIN_MANA, _("魔力吸収", "Drain mana") },
{ MonsterAbilityType::MIND_BLAST, _("精神攻撃", "Mind blast") },
{ MonsterAbilityType::BRAIN_SMASH, _("脳攻撃", "Brain smash") },
{ MonsterAbilityType::BO_MANA, _("魔力の矢", "Mana") },
{ MonsterAbilityType::BO_PLAS, _("プラズマ", "Plasma") },
{ MonsterAbilityType::BO_ICEE, _("極寒", "Ice") },
+ { MonsterAbilityType::BO_VOID, _("ヴォイド", "Void") },
+ { MonsterAbilityType::BO_ABYSS, _("アビス", "Abyss") },
{ MonsterAbilityType::MISSILE, _("マジックミサイル", "Magic missile") },
{ MonsterAbilityType::SCARE, _("恐慌", "Scare") },
{ MonsterAbilityType::BLIND, _("盲目", "Blind") },
{
floor_type *floor_ptr = player_ptr->current_floor_ptr;
msa_ptr->in_no_magic_dungeon = d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MAGIC) && floor_ptr->dun_level && (!floor_ptr->inside_quest || quest_type::is_fixed(floor_ptr->inside_quest));
- if (!msa_ptr->in_no_magic_dungeon || ((msa_ptr->r_ptr->flags2 & RF2_STUPID) != 0))
+ if (!msa_ptr->in_no_magic_dungeon || ((msa_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))))
return;
msa_ptr->ability_flags &= RF_ABILITY_NOMAGIC_MASK;
static void check_mspell_smart(PlayerType *player_ptr, msa_type *msa_ptr)
{
- if ((msa_ptr->r_ptr->flags2 & RF2_SMART) == 0)
+ if (msa_ptr->r_ptr->behavior_flags.has_not(MonsterBehaviorType::SMART))
return;
if ((msa_ptr->m_ptr->hp < msa_ptr->m_ptr->maxhp / 10) && (randint0(100) < 50)) {
static bool check_mspell_non_stupid(PlayerType *player_ptr, msa_type *msa_ptr)
{
- if ((msa_ptr->r_ptr->flags2 & RF2_STUPID) != 0)
+ if (msa_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return true;
if (!player_ptr->csp)
static bool check_mspell_unexploded(PlayerType *player_ptr, msa_type *msa_ptr)
{
PERCENTAGE fail_rate = 25 - (msa_ptr->rlev + 3) / 4;
- if (msa_ptr->r_ptr->flags2 & RF2_STUPID)
+ if (msa_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
fail_rate = 0;
if (!spell_is_inate(msa_ptr->thrown_spell) && (msa_ptr->in_no_magic_dungeon || (monster_stunned_remaining(msa_ptr->m_ptr) && one_in_(2)) || (randint0(100) < fail_rate))) {
case MonsterAbilityType::BO_MANA:
case MonsterAbilityType::BO_PLAS:
case MonsterAbilityType::BO_ICEE:
+ case MonsterAbilityType::BO_VOID:
+ case MonsterAbilityType::BO_ABYSS:
case MonsterAbilityType::MISSILE:
case MonsterAbilityType::SCARE:
case MonsterAbilityType::BLIND:
#include "mspell/mspell-ball.h"
+#include "effect/attribute-types.h"
#include "effect/effect-processor.h"
#include "main/sound-of-music.h"
#include "mind/drs-types.h"
#include "mspell/mspell-damage-calculator.h"
#include "mspell/mspell-result.h"
#include "mspell/mspell-util.h"
-#include "mspell/mspell-result.h"
-#include "effect/attribute-types.h"
#include "system/floor-type-definition.h"
#include "system/monster-type-definition.h"
#include "system/player-type-definition.h"
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_NUKE, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::NUKE, dam, 2, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_POIS);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_CHAO, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::CHAOS, dam, 4, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_CHAOS);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ACID, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ACID, dam, rad, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_ACID);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ELEC, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ELEC, dam, rad, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_ELEC);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_FIRE, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::FIRE, dam, rad, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_FIRE);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_COLD, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::COLD, dam, rad, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_COLD);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_POIS, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::POIS, dam, 2, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_POIS);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_NETH, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::NETHER, dam, 2, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_NETH);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_DARK, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::DARK, dam, 4, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_DARK);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_LITE, m_idx, DAM_ROLL);
const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::LITE, dam, 4, false, TARGET_TYPE);
- if (TARGET_TYPE == MONSTER_TO_PLAYER)
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
update_smart_learn(player_ptr, m_idx, DRS_LITE);
+ }
+
+ auto res = MonsterSpellResult::make_valid(dam);
+ res.learnable = proj_res.affected_player;
+
+ return res;
+}
+
+/*!
+ * @brief RF5_BA_VOIDの処理。虚無の嵐。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BA_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+ mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
+ _("%^sが虚無の嵐の呪文を念じた。", "%^s invokes a void storm."),
+ _("%^sが%sに対して虚無の嵐の呪文を念じた。", "%^s invokes a void storm upon %s."));
+
+ monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+ const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_VOID, m_idx, DAM_ROLL);
+ const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::VOID_MAGIC, dam, 4, false, TARGET_TYPE);
+
+ auto res = MonsterSpellResult::make_valid(dam);
+ res.learnable = proj_res.affected_player;
+
+ return res;
+}
+
+/*!
+ * @brief RF5_BA_ABYSSの処理。アビス・ボール。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BA_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+ mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
+ _("%^sが深淵の嵐の呪文を念じた。", "%^s invokes a abyss storm."),
+ _("%^sが%sに対して深淵の嵐の呪文を念じた。", "%^s invokes a void abyss upon %s."));
+
+ monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+ const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ABYSS, m_idx, DAM_ROLL);
+ const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ABYSS, dam, 4, false, TARGET_TYPE);
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
+ update_smart_learn(player_ptr, m_idx, DRS_DARK);
+ }
auto res = MonsterSpellResult::make_valid(dam);
res.learnable = proj_res.affected_player;
MonsterSpellResult spell_RF5_BA_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
MonsterSpellResult spell_RF5_BA_DARK(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
MonsterSpellResult spell_RF5_BA_LITE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BA_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BA_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
}
/*!
+ * @brief RF5_BO_VOIDの処理。ヴォイド・ボルト。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BO_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+ mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
+ _("%^sがヴォイド・ボルトの呪文を唱えた。", "%^s casts a void bolt."),
+ _("%^sが%sに向かってヴォイド・ボルトの呪文を唱えた。", "%^s casts a void bolt at %s."));
+
+ monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+ const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BO_VOID, m_idx, DAM_ROLL);
+ const auto proj_res = bolt(player_ptr, m_idx, y, x, AttributeType::VOID_MAGIC, dam, TARGET_TYPE);
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
+ update_smart_learn(player_ptr, m_idx, DRS_REFLECT);
+ }
+
+ auto res = MonsterSpellResult::make_valid(dam);
+ res.learnable = proj_res.affected_player;
+
+ return res;
+}
+
+/*!
+ * @brief RF5_BO_ABYSSの処理。アビス・ボルト。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BO_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+ mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
+ _("%^sがアビス・ボルトの呪文を唱えた。", "%^s casts a abyss bolt."),
+ _("%^sが%sに向かってアビス・ボルトの呪文を唱えた。", "%^s casts a abyss bolt at %s."));
+
+ monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+ const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BO_ABYSS, m_idx, DAM_ROLL);
+ const auto proj_res = bolt(player_ptr, m_idx, y, x, AttributeType::ABYSS, dam, TARGET_TYPE);
+ if (TARGET_TYPE == MONSTER_TO_PLAYER) {
+ update_smart_learn(player_ptr, m_idx, DRS_REFLECT);
+ }
+
+ auto res = MonsterSpellResult::make_valid(dam);
+ res.learnable = proj_res.affected_player;
+
+ return res;
+}
+
+/*!
* @brief RF5_MISSILEの処理。マジック・ミサイル。 /
* @param player_ptr プレイヤーへの参照ポインタ
* @param y 対象の地点のy座標
MonsterSpellResult spell_RF5_BO_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
MonsterSpellResult spell_RF5_BO_PLAS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
MonsterSpellResult spell_RF5_BO_ICEE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BO_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BO_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
MonsterSpellResult spell_RF5_MISSILE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
type_s = _("分解", "disintegration");
smart_learn_aux = false;
break;
+ case AttributeType::VOID_MAGIC:
+ dam = monspell_damage(player_ptr, MonsterAbilityType::BR_VOID, m_idx, DAM_ROLL);
+ type_s = _("虚無", "void");
+ smart_learn_aux = false;
+ break;
+ case AttributeType::ABYSS:
+ dam = monspell_damage(player_ptr, MonsterAbilityType::BR_ABYSS, m_idx, DAM_ROLL);
+ type_s = _("深淵", "disintegration");
+ smart_learn_aux = false;
+ break;
default:
/* Do not reach here */
dam = 0;
case MonsterAbilityType::BR_DISI:
dam = ((hp / 6) > 150 ? 150 : (hp / 6));
break;
+ case MonsterAbilityType::BR_VOID:
+ dam = ((hp / 3) > 250 ? 250 : (hp / 6));
+ break;
+ case MonsterAbilityType::BR_ABYSS:
+ dam = ((hp / 3) > 250 ? 250 : (hp / 6));
+ break;
case MonsterAbilityType::BA_ACID:
if (powerful) {
dam = (rlev * 4) + 50;
dice_num = 10;
dice_side = 10;
break;
+ case MonsterAbilityType::BA_VOID:
+ dam = (powerful ? (rlev * 3) : (rlev * 2));
+ dice_num = 10;
+ dice_side = 10;
+ break;
+ case MonsterAbilityType::BA_ABYSS:
+ dam = (powerful ? (rlev * 3) : (rlev * 2));
+ dice_num = 10;
+ dice_side = 10;
+ break;
case MonsterAbilityType::DRAIN_MANA:
dam = rlev;
div = 1;
dice_num = 6;
dice_side = 6;
break;
+ case MonsterAbilityType::BO_VOID:
+ dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
+ dice_num = 13;
+ dice_side = 14;
+ break;
+ case MonsterAbilityType::BO_ABYSS:
+ dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
+ dice_num = 13;
+ dice_side = 14;
+ break;
case MonsterAbilityType::MISSILE:
dam = (rlev / 3);
dice_num = 2;
static void check_lite_area_by_mspell(PlayerType *player_ptr, msa_type *msa_ptr)
{
- if (msa_ptr->ability_flags.has(MonsterAbilityType::BR_DISI) && (msa_ptr->m_ptr->cdis < get_max_range(player_ptr) / 2)
- && in_disintegration_range(player_ptr->current_floor_ptr, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx, msa_ptr->y, msa_ptr->x)
- && (one_in_(10) || (projectable(player_ptr, msa_ptr->y, msa_ptr->x, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx) && one_in_(2)))) {
+ if (msa_ptr->ability_flags.has(MonsterAbilityType::BR_DISI) && (msa_ptr->m_ptr->cdis < get_max_range(player_ptr) / 2) && in_disintegration_range(player_ptr->current_floor_ptr, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx, msa_ptr->y, msa_ptr->x) && (one_in_(10) || (projectable(player_ptr, msa_ptr->y, msa_ptr->x, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx) && one_in_(2)))) {
msa_ptr->do_spell = DO_SPELL_BR_DISI;
msa_ptr->success = true;
return;
}
- if (msa_ptr->ability_flags.has(MonsterAbilityType::BR_LITE) && (msa_ptr->m_ptr->cdis < get_max_range(player_ptr) / 2)
- && los(player_ptr, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx, msa_ptr->y, msa_ptr->x) && one_in_(5)) {
+ if (msa_ptr->ability_flags.has(MonsterAbilityType::BR_LITE) && (msa_ptr->m_ptr->cdis < get_max_range(player_ptr) / 2) && los(player_ptr, msa_ptr->m_ptr->fy, msa_ptr->m_ptr->fx, msa_ptr->y, msa_ptr->x) && one_in_(5)) {
msa_ptr->do_spell = DO_SPELL_BR_LITE;
msa_ptr->success = true;
return;
if (msa_ptr->ability_flags.has_not(MonsterAbilityType::DARKNESS))
return;
- bool can_use_lite_area = (player_ptr->pclass == PlayerClassType::NINJA) && ((msa_ptr->r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) == 0)
- && ((msa_ptr->r_ptr->flags7 & RF7_DARK_MASK) == 0);
+ bool can_use_lite_area = (player_ptr->pclass == PlayerClassType::NINJA) && ((msa_ptr->r_ptr->flags3 & (RF3_UNDEAD | RF3_HURT_LITE)) == 0) && ((msa_ptr->r_ptr->flags7 & RF7_DARK_MASK) == 0);
- if ((msa_ptr->r_ptr->flags2 & RF2_STUPID) != 0)
+ if (msa_ptr->r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
return;
if (d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::DARKNESS)) {
#include "mspell/mspell-attack-util.h"
#include "mspell/mspell-judgement.h"
#include "player/player-status.h"
-#include "system/monster-type-definition.h"
#include "system/floor-type-definition.h"
#include "system/monster-race-definition.h"
+#include "system/monster-type-definition.h"
#include "system/player-type-definition.h"
#include "util/enum-converter.h"
#include "world/world.h"
static bool spell_attack(MonsterAbilityType spell)
{
/* All RF4 spells hurt (except for shriek and dispel) */
- if (spell_in_between(spell, MonsterAbilityType::ROCKET, MonsterAbilityType::BR_DISI))
+ if (spell_in_between(spell, MonsterAbilityType::ROCKET, MonsterAbilityType::BR_DISI)) {
+ return true;
+ }
+ if (spell_in_between(spell, MonsterAbilityType::BR_VOID, MonsterAbilityType::BR_ABYSS)) {
return true;
+ }
/* Various "ball" spells */
- if (spell_in_between(spell, MonsterAbilityType::BA_ACID, MonsterAbilityType::BA_DARK))
+ if (spell_in_between(spell, MonsterAbilityType::BA_ACID, MonsterAbilityType::BA_DARK)) {
+ return true;
+ }
+ if (spell_in_between(spell, MonsterAbilityType::BA_VOID, MonsterAbilityType::BA_ABYSS)) {
return true;
+ }
/* "Cause wounds" and "bolt" spells */
- if (spell_in_between(spell, MonsterAbilityType::CAUSE_1, MonsterAbilityType::MISSILE))
+ if (spell_in_between(spell, MonsterAbilityType::CAUSE_1, MonsterAbilityType::MISSILE)) {
+ return true;
+ }
+ if (spell_in_between(spell, MonsterAbilityType::BO_VOID, MonsterAbilityType::BO_ABYSS)) {
return true;
+ }
/* Hand of Doom */
- if (spell == MonsterAbilityType::HAND_DOOM)
+ if (spell == MonsterAbilityType::HAND_DOOM) {
return true;
+ }
/* Psycho-Spear */
- if (spell == MonsterAbilityType::PSY_SPEAR)
+ if (spell == MonsterAbilityType::PSY_SPEAR) {
return true;
+ }
/* Doesn't hurt */
return false;
static bool spell_escape(MonsterAbilityType spell)
{
/* Blink or Teleport */
- if (spell == MonsterAbilityType::BLINK || spell == MonsterAbilityType::TPORT)
+ if (spell == MonsterAbilityType::BLINK || spell == MonsterAbilityType::TPORT) {
return true;
+ }
/* Teleport the player away */
- if (spell == MonsterAbilityType::TELE_AWAY || spell == MonsterAbilityType::TELE_LEVEL)
+ if (spell == MonsterAbilityType::TELE_AWAY || spell == MonsterAbilityType::TELE_LEVEL) {
return true;
+ }
/* Isn't good for escaping */
return false;
static bool spell_annoy(MonsterAbilityType spell)
{
/* Shriek */
- if (spell == MonsterAbilityType::SHRIEK)
+ if (spell == MonsterAbilityType::SHRIEK) {
return true;
+ }
/* Brain smash, et al (added curses) */
- if (spell_in_between(spell, MonsterAbilityType::DRAIN_MANA, MonsterAbilityType::CAUSE_4))
+ if (spell_in_between(spell, MonsterAbilityType::DRAIN_MANA, MonsterAbilityType::CAUSE_4)) {
return true;
+ }
/* Scare, confuse, blind, slow, paralyze */
- if (spell_in_between(spell, MonsterAbilityType::SCARE, MonsterAbilityType::HOLD))
+ if (spell_in_between(spell, MonsterAbilityType::SCARE, MonsterAbilityType::HOLD)) {
return true;
+ }
/* Teleport to */
- if (spell == MonsterAbilityType::TELE_TO)
+ if (spell == MonsterAbilityType::TELE_TO) {
return true;
+ }
/* Teleport level */
- if (spell == MonsterAbilityType::TELE_LEVEL)
+ if (spell == MonsterAbilityType::TELE_LEVEL) {
return true;
+ }
/* Darkness, make traps, cause amnesia */
- if (spell_in_between(spell, MonsterAbilityType::TRAPS, MonsterAbilityType::RAISE_DEAD))
+ if (spell_in_between(spell, MonsterAbilityType::TRAPS, MonsterAbilityType::RAISE_DEAD)) {
return true;
+ }
/* Doesn't annoy */
return false;
*/
static bool spell_special(PlayerType *player_ptr, MonsterAbilityType spell)
{
- if (player_ptr->phase_out)
+ if (player_ptr->phase_out) {
return false;
+ }
return spell == MonsterAbilityType::SPECIAL;
}
monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[msa_ptr->m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (r_ptr->flags2 & RF2_STUPID)
+ if (r_ptr->flags2 & RF2_STUPID) {
return (msa_ptr->mspells[randint0(msa_ptr->mspells.size())]);
+ }
for (size_t i = 0; i < msa_ptr->mspells.size(); i++) {
- if (spell_escape(msa_ptr->mspells[i]))
+ if (spell_escape(msa_ptr->mspells[i])) {
escape.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_attack(msa_ptr->mspells[i]))
+ if (spell_attack(msa_ptr->mspells[i])) {
attack.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_summon(msa_ptr->mspells[i]))
+ if (spell_summon(msa_ptr->mspells[i])) {
summon.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_tactic(msa_ptr->mspells[i]))
+ if (spell_tactic(msa_ptr->mspells[i])) {
tactic.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_annoy(msa_ptr->mspells[i]))
+ if (spell_annoy(msa_ptr->mspells[i])) {
annoy.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_invulner(msa_ptr->mspells[i]))
+ if (spell_invulner(msa_ptr->mspells[i])) {
invul.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_haste(msa_ptr->mspells[i]))
+ if (spell_haste(msa_ptr->mspells[i])) {
haste.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_world(msa_ptr->mspells[i]))
+ if (spell_world(msa_ptr->mspells[i])) {
world.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_special(player_ptr, msa_ptr->mspells[i]))
+ if (spell_special(player_ptr, msa_ptr->mspells[i])) {
special.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_psy_spe(msa_ptr->mspells[i]))
+ if (spell_psy_spe(msa_ptr->mspells[i])) {
psy_spe.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_raise(msa_ptr->mspells[i]))
+ if (spell_raise(msa_ptr->mspells[i])) {
raise.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_heal(msa_ptr->mspells[i]))
+ if (spell_heal(msa_ptr->mspells[i])) {
heal.push_back(msa_ptr->mspells[i]);
+ }
- if (spell_dispel(msa_ptr->mspells[i]))
+ if (spell_dispel(msa_ptr->mspells[i])) {
dispel.push_back(msa_ptr->mspells[i]);
+ }
}
- if (!world.empty() && (randint0(100) < 15) && !w_ptr->timewalk_m_idx)
+ if (!world.empty() && (randint0(100) < 15) && !w_ptr->timewalk_m_idx) {
return (world[randint0(world.size())]);
+ }
if (!special.empty()) {
bool success = false;
switch (m_ptr->r_idx) {
case MON_BANOR:
case MON_LUPART:
- if ((m_ptr->hp < m_ptr->maxhp / 2) && r_info[MON_BANOR].max_num && r_info[MON_LUPART].max_num)
+ if ((m_ptr->hp < m_ptr->maxhp / 2) && r_info[MON_BANOR].max_num && r_info[MON_LUPART].max_num) {
success = true;
+ }
break;
default:
break;
}
- if (success)
+ if (success) {
return (special[randint0(special.size())]);
+ }
}
if (m_ptr->hp < m_ptr->maxhp / 3 && one_in_(2)) {
- if (!heal.empty())
+ if (!heal.empty()) {
return (heal[randint0(heal.size())]);
+ }
}
if (((m_ptr->hp < m_ptr->maxhp / 3) || monster_fear_remaining(m_ptr)) && one_in_(2)) {
- if (!escape.empty())
+ if (!escape.empty()) {
return (escape[randint0(escape.size())]);
+ }
}
if (!special.empty()) {
case MON_LUPART:
break;
case MON_BANORLUPART:
- if (randint0(100) < 70)
+ if (randint0(100) < 70) {
success = true;
+ }
break;
case MON_ROLENTO:
- if (randint0(100) < 40)
+ if (randint0(100) < 40) {
success = true;
+ }
break;
default:
- if (randint0(100) < 50)
+ if (randint0(100) < 50) {
success = true;
+ }
break;
}
- if (success)
+ if (success) {
return (special[randint0(special.size())]);
+ }
}
- if ((distance(player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx) < 4) && (!attack.empty() || r_ptr->ability_flags.has(MonsterAbilityType::TRAPS)) && (randint0(100) < 75)
- && !w_ptr->timewalk_m_idx) {
- if (!tactic.empty())
+ if ((distance(player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx) < 4) && (!attack.empty() || r_ptr->ability_flags.has(MonsterAbilityType::TRAPS)) && (randint0(100) < 75) && !w_ptr->timewalk_m_idx) {
+ if (!tactic.empty()) {
return (tactic[randint0(tactic.size())]);
+ }
}
- if (!summon.empty() && (randint0(100) < 40))
+ if (!summon.empty() && (randint0(100) < 40)) {
return (summon[randint0(summon.size())]);
+ }
if (!dispel.empty() && one_in_(2)) {
if (dispel_check(player_ptr, msa_ptr->m_idx)) {
}
}
- if (!raise.empty() && (randint0(100) < 40))
+ if (!raise.empty() && (randint0(100) < 40)) {
return (raise[randint0(raise.size())]);
+ }
if (is_invuln(player_ptr)) {
if (!psy_spe.empty() && (randint0(100) < 50)) {
return (attack[randint0(attack.size())]);
}
- if (!tactic.empty() && (randint0(100) < 50) && !w_ptr->timewalk_m_idx)
+ if (!tactic.empty() && (randint0(100) < 50) && !w_ptr->timewalk_m_idx) {
return (tactic[randint0(tactic.size())]);
+ }
- if (!invul.empty() && !m_ptr->mtimed[MTIMED_INVULNER] && (randint0(100) < 50))
+ if (!invul.empty() && !m_ptr->mtimed[MTIMED_INVULNER] && (randint0(100) < 50)) {
return (invul[randint0(invul.size())]);
+ }
if ((m_ptr->hp < m_ptr->maxhp * 3 / 4) && (randint0(100) < 25)) {
- if (!heal.empty())
+ if (!heal.empty()) {
return (heal[randint0(heal.size())]);
+ }
}
- if (!haste.empty() && (randint0(100) < 20) && !monster_fast_remaining(m_ptr))
+ if (!haste.empty() && (randint0(100) < 20) && !monster_fast_remaining(m_ptr)) {
return (haste[randint0(haste.size())]);
+ }
- if (!annoy.empty() && (randint0(100) < 80))
+ if (!annoy.empty() && (randint0(100) < 80)) {
return (annoy[randint0(annoy.size())]);
+ }
return MonsterAbilityType::MAX;
}
}
if (player_ptr->blind && count && mon_to_player) {
- msg_print(_("ä¸\8dæ»ã\81®è\80\85ã\81\8cè¿\91ã\81\8fã\81«ç\8f¾ã\82\8cã\82\8bã\81®ã\81\8cè\81\9eã\81\93ã\81\88ã\81\9fã\80\82", "You hear immortal beings appear nearby."));
+ msg_print(_("ä½\95è\80\85ã\81\8bã\81\8c次å\85\83ã\82\92è¶\85ã\81\88ã\81¦ç\8f¾ã\82\8cã\81\9fæ°\97é\85\8dã\81\8cã\81\97ã\81\9fã\80\82", "You feel shadow shifting by immortal beings."));
}
if (monster_near_player(floor_ptr, m_idx, t_idx) && !see_monster(player_ptr, t_idx) && count && mon_to_mon)
*/
bool int_outof(monster_race *r_ptr, PERCENTAGE prob)
{
- if (!(r_ptr->flags2 & RF2_SMART))
+ if (r_ptr->behavior_flags.has_not(MonsterBehaviorType::SMART))
prob = prob / 2;
return (randint0(100) < prob);
+++ /dev/null
-/*!
- * @brief 武器系のアイテムを強化して(恐らく床に)生成する処理
- * @date 2020/06/02
- * @author Hourier
- * @todo ちょっと長い。要分割
- */
-
-#include "object-enchant/apply-magic-weapon.h"
-#include "artifact/random-art-generator.h"
-#include "inventory/inventory-slot-types.h"
-#include "object-enchant/object-boost.h"
-#include "object-enchant/object-ego.h"
-#include "object-enchant/tr-types.h"
-#include "object-enchant/trc-types.h"
-#include "sv-definition/sv-weapon-types.h"
-#include "system/floor-type-definition.h"
-#include "system/object-type-definition.h"
-#include "util/bit-flags-calculator.h"
-#include "view/display-messages.h"
-
-/*!
- * @brief 武器系オブジェクトに生成ランクごとの強化を与えるサブルーチン
- * Apply magic to an item known to be a "weapon"
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
- * @param level 生成基準階
- * @param power 生成ランク
- * @details
- * Hack -- note special base damage dice boosting\n
- * Hack -- note special processing for weapon/digger\n
- */
-void apply_magic_weapon(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power)
-{
- HIT_PROB tohit1 = randint1(5) + (HIT_PROB)m_bonus(5, level);
- HIT_POINT todam1 = randint1(5) + (HIT_POINT)m_bonus(5, level);
-
- HIT_PROB tohit2 = (HIT_PROB)m_bonus(10, level);
- HIT_POINT todam2 = (HIT_POINT)m_bonus(10, level);
-
- if ((o_ptr->tval == ItemKindType::BOLT) || (o_ptr->tval == ItemKindType::ARROW) || (o_ptr->tval == ItemKindType::SHOT)) {
- tohit2 = (tohit2 + 1) / 2;
- todam2 = (todam2 + 1) / 2;
- }
-
- if (power > 0) {
- o_ptr->to_h += tohit1;
- o_ptr->to_d += todam1;
- if (power > 1) {
- o_ptr->to_h += tohit2;
- o_ptr->to_d += todam2;
- }
- } else if (power < 0) {
- o_ptr->to_h -= tohit1;
- o_ptr->to_d -= todam1;
- if (power < -1) {
- o_ptr->to_h -= tohit2;
- o_ptr->to_d -= todam2;
- }
-
- if (o_ptr->to_h + o_ptr->to_d < 0)
- o_ptr->curse_flags.set(CurseTraitType::CURSED);
- }
-
- if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_DIAMOND_EDGE))
- return;
-
- switch (o_ptr->tval) {
- case ItemKindType::DIGGING: {
- if (power > 1) {
- /* power > 2はデバッグ専用. */
- if (one_in_(30) || (power > 2))
- become_random_artifact(player_ptr, o_ptr, false);
- else
- o_ptr->name2 = EGO_DIGGING;
- } else if (power < -1) {
- o_ptr->pval = 0 - (5 + randint1(5));
- } else if (power < 0) {
- o_ptr->pval = 0 - (o_ptr->pval);
- }
-
- break;
- }
- case ItemKindType::HAFTED:
- case ItemKindType::POLEARM:
- case ItemKindType::SWORD: {
- if (power > 1) {
- /* power > 2はデバッグ専用. */
- if (one_in_(40) || (power > 2)) {
- become_random_artifact(player_ptr, o_ptr, false);
- break;
- }
- while (true) {
- o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, true);
- if (o_ptr->name2 == EGO_SHARPNESS && o_ptr->tval != ItemKindType::SWORD)
- continue;
- if (o_ptr->name2 == EGO_EARTHQUAKES && o_ptr->tval != ItemKindType::HAFTED)
- continue;
- break;
- }
-
- switch (o_ptr->name2) {
- case EGO_SHARPNESS:
- o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, level) + 1;
- break;
- case EGO_EARTHQUAKES:
- if (one_in_(3) && (level > 60))
- o_ptr->art_flags.set(TR_BLOWS);
- else
- o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, level);
- break;
- default:
- break;
- }
-
- if (!o_ptr->art_name) {
- while (one_in_(10L * o_ptr->dd * o_ptr->ds))
- o_ptr->dd++;
-
- if (o_ptr->dd > 9)
- o_ptr->dd = 9;
- }
- } else if (power < -1) {
- if (randint0(MAX_DEPTH) < level) {
- int n = 0;
- while (true) {
- o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, false);
- if (o_ptr->name2 == EGO_WEIRD && o_ptr->tval != ItemKindType::SWORD) {
- continue;
- }
-
- ego_item_type *e_ptr = &e_info[o_ptr->name2];
- if (o_ptr->tval == ItemKindType::SWORD && o_ptr->sval == SV_HAYABUSA && e_ptr->max_pval < 0) {
- if (++n > 1000) {
- msg_print(_("エラー:隼の剣に割り当てるエゴ無し", "Error: Cannot find for Hayabusa."));
- return;
- }
- continue;
- }
- break;
- }
- }
- }
-
- break;
- }
- case ItemKindType::BOW: {
- if (power > 1) {
- /* power > 2はデバッグ専用. */
- if (one_in_(20) || (power > 2)) {
- become_random_artifact(player_ptr, o_ptr, false);
- break;
- }
-
- o_ptr->name2 = get_random_ego(INVEN_BOW, true);
- }
-
- break;
- }
- case ItemKindType::BOLT:
- case ItemKindType::ARROW:
- case ItemKindType::SHOT: {
- if (power > 1) {
- /* power > 2はデバッグ専用. */
- if (power > 2) {
- become_random_artifact(player_ptr, o_ptr, false);
- break;
- }
-
- o_ptr->name2 = get_random_ego(INVEN_AMMO, true);
-
- while (one_in_(10L * o_ptr->dd * o_ptr->ds))
- o_ptr->dd++;
-
- if (o_ptr->dd > 9)
- o_ptr->dd = 9;
- } else if (power < -1) {
- if (randint0(MAX_DEPTH) < level) {
- o_ptr->name2 = get_random_ego(INVEN_AMMO, false);
- }
- }
-
- break;
- }
-
- default:
- break;
- }
-}
+++ /dev/null
-#pragma once
-
-#include "system/angband.h"
-
-struct object_type;
-class PlayerType;
-void apply_magic_weapon(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power);
#include "artifact/fixed-art-types.h"
#include "dungeon/dungeon.h"
#include "mutation/mutation-flag-types.h"
-#include "object-enchant/apply-magic-amulet.h"
-#include "object-enchant/apply-magic-armor.h"
-#include "object-enchant/apply-magic-boots.h"
-#include "object-enchant/apply-magic-cloak.h"
-#include "object-enchant/apply-magic-crown.h"
-#include "object-enchant/apply-magic-gloves.h"
-#include "object-enchant/apply-magic-helm.h"
-#include "object-enchant/apply-magic-others.h"
-#include "object-enchant/apply-magic-ring.h"
-#include "object-enchant/apply-magic-shield.h"
-#include "object-enchant/apply-magic-weapon.h"
#include "object-enchant/item-apply-magic.h"
#include "object-enchant/object-curse.h"
#include "object-enchant/object-ego.h"
+#include "object-enchant/others/apply-magic-amulet.h"
+#include "object-enchant/others/apply-magic-others.h"
+#include "object-enchant/others/apply-magic-ring.h"
+#include "object-enchant/protector/apply-magic-armor.h"
+#include "object-enchant/protector/apply-magic-boots.h"
+#include "object-enchant/protector/apply-magic-cloak.h"
+#include "object-enchant/protector/apply-magic-crown.h"
+#include "object-enchant/protector/apply-magic-gloves.h"
+#include "object-enchant/protector/apply-magic-helm.h"
+#include "object-enchant/protector/apply-magic-shield.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/tr-types.h"
#include "object-enchant/trc-types.h"
#include "object-enchant/trg-types.h"
+#include "object-enchant/weapon/apply-magic-weapon.h"
#include "object/object-kind.h"
#include "player/player-status-flags.h"
#include "sv-definition/sv-armor-types.h"
return;
}
+ // @todo ファクトリパターンで抽象化する.
switch (o_ptr->tval) {
case ItemKindType::DIGGING:
case ItemKindType::HAFTED:
case ItemKindType::ARROW:
case ItemKindType::BOLT:
if (power != 0) {
- apply_magic_weapon(player_ptr, o_ptr, lev, power);
+ WeaponEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
}
break;
case ItemKindType::POLEARM:
if ((power != 0) && (o_ptr->sval != SV_DEATH_SCYTHE)) {
- apply_magic_weapon(player_ptr, o_ptr, lev, power);
+ WeaponEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
}
break;
case ItemKindType::SWORD:
if ((power != 0) && (o_ptr->sval != SV_POISON_NEEDLE)) {
- apply_magic_weapon(player_ptr, o_ptr, lev, power);
+ WeaponEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
}
break;
* @details 純粋仮想関数につき、必要なメンバ変数は派生クラスで設定すること
*/
-#include "system/angband.h"
-
struct object_type;
class PlayerType;
class EnchanterBase {
public:
virtual void apply_magic() = 0;
+ virtual ~EnchanterBase() = default;
protected:
EnchanterBase() = default;
- virtual ~EnchanterBase() = default;
virtual void enchant() = 0;
virtual void give_ego_index() = 0;
virtual void give_high_ego_index() = 0;
* @author Hourier
*/
-#include "object-enchant/apply-magic-amulet.h"
+#include "object-enchant/others/apply-magic-amulet.h"
#include "artifact/random-art-generator.h"
#include "object-enchant/object-boost.h"
#include "object-enchant/object-ego.h"
* @todo ちょっと長い。要分割
*/
-#include "object-enchant/apply-magic-others.h"
+#include "object-enchant/others/apply-magic-others.h"
#include "artifact/random-art-generator.h"
#include "game-option/cheat-options.h"
#include "inventory/inventory-slot-types.h"
* @author Hourier
*/
-#include "object-enchant/apply-magic-ring.h"
+#include "object-enchant/others/apply-magic-ring.h"
#include "artifact/random-art-generator.h"
#include "object-enchant/object-boost.h"
#include "object-enchant/object-ego.h"
* @author Hourier
*/
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/object-boost.h"
#include "system/object-type-definition.h"
* @author Hourier
*/
-#include "object-enchant/apply-magic-armor.h"
+#include "object-enchant/protector/apply-magic-armor.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-ego.h"
#pragma once
#include "object-enchant/enchanter-base.h"
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "system/angband.h"
struct object_type;
* @details ドラゴンブーツは必ず付与する. それ以外は確率的に付与する.
*/
-#include "object-enchant/apply-magic-boots.h"
+#include "object-enchant/protector/apply-magic-boots.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-boost.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
* @author Hourier
*/
-#include "object-enchant/apply-magic-cloak.h"
+#include "object-enchant/protector/apply-magic-cloak.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-ego.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
* @author Hourier
*/
-#include "object-enchant/apply-magic-crown.h"
+#include "object-enchant/protector/apply-magic-crown.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-boost.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
* @details ドラゴングローヴは必ず付与する. それ以外は確率的に付与する.
*/
-#include "object-enchant/apply-magic-gloves.h"
+#include "object-enchant/protector/apply-magic-gloves.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-boost.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
* @details ドラゴンヘルムは必ず付与する. それ以外は確率的に付与する.
*/
-#include "object-enchant/apply-magic-helm.h"
+#include "object-enchant/protector/apply-magic-helm.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-boost.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
* @details ドラゴンシールドは必ず付与する. それ以外は確率的に付与する.
*/
-#include "object-enchant/apply-magic-shield.h"
+#include "object-enchant/protector/apply-magic-shield.h"
#include "artifact/random-art-generator.h"
#include "inventory/inventory-slot-types.h"
#include "object-enchant/object-boost.h"
#pragma once
-#include "object-enchant/abstract-protector-enchanter.h"
+#include "object-enchant/protector/abstract-protector-enchanter.h"
#include "object-enchant/enchanter-base.h"
#include "system/angband.h"
--- /dev/null
+#include "object-enchant/weapon/abstract-weapon-enchanter.h"
+#include "object-enchant/object-boost.h"
+#include "system/object-type-definition.h"
+
+AbstractWeaponEnchanter::AbstractWeaponEnchanter(object_type* o_ptr, DEPTH level, int power)
+ : o_ptr(o_ptr)
+ , level(level)
+ , power(power)
+{
+ auto tohit1 = static_cast<short>(randint1(5) + m_bonus(5, this->level));
+ auto todam1 = static_cast<short>(randint1(5) + m_bonus(5, this->level));
+ auto tohit2 = static_cast<short>(m_bonus(10, this->level));
+ auto todam2 = static_cast<short>(m_bonus(10, this->level));
+
+ if ((this->o_ptr->tval == ItemKindType::BOLT) || (this->o_ptr->tval == ItemKindType::ARROW) || (this->o_ptr->tval == ItemKindType::SHOT)) {
+ tohit2 = (tohit2 + 1) / 2;
+ todam2 = (todam2 + 1) / 2;
+ }
+
+ if (this->power > 0) {
+ this->o_ptr->to_h += tohit1;
+ this->o_ptr->to_d += todam1;
+ if (this->power > 1) {
+ this->o_ptr->to_h += tohit2;
+ this->o_ptr->to_d += todam2;
+ }
+
+ return;
+ }
+
+ if (this->power < 0) {
+ this->o_ptr->to_h -= tohit1;
+ this->o_ptr->to_d -= todam1;
+ if (this->power < -1) {
+ this->o_ptr->to_h -= tohit2;
+ this->o_ptr->to_d -= todam2;
+ }
+
+ if (this->o_ptr->to_h + this->o_ptr->to_d < 0) {
+ this->o_ptr->curse_flags.set(CurseTraitType::CURSED);
+ }
+ }
+}
--- /dev/null
+#pragma once
+
+#include "object-enchant/enchanter-base.h"
+#include "system/angband.h"
+
+struct object_type;
+class AbstractWeaponEnchanter : EnchanterBase {
+protected:
+ AbstractWeaponEnchanter(object_type *o_ptr, DEPTH level, int power);
+ object_type *o_ptr;
+ DEPTH level;
+ int power;
+};
--- /dev/null
+/*!
+ * @brief 武器系のアイテムを強化する処理
+ * @date 2022/01/30
+ * @author Hourier
+ */
+
+#include "object-enchant/weapon/apply-magic-weapon.h"
+#include "artifact/random-art-generator.h"
+#include "inventory/inventory-slot-types.h"
+#include "object-enchant/object-boost.h"
+#include "object-enchant/object-ego.h"
+#include "object-enchant/tr-types.h"
+#include "object-enchant/trc-types.h"
+#include "sv-definition/sv-weapon-types.h"
+#include "system/floor-type-definition.h"
+#include "system/object-type-definition.h"
+#include "util/bit-flags-calculator.h"
+#include "view/display-messages.h"
+
+/*!
+ * @brief 武器強化クラスのコンストラクタ
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
+ * @param level 生成基準階
+ * @param power 生成ランク
+ */
+WeaponEnchanter::WeaponEnchanter(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power)
+ : AbstractWeaponEnchanter(o_ptr, level, power)
+ , player_ptr(player_ptr)
+{
+}
+
+/*!
+ * @brief 武器系オブジェクトに生成ランクごとの強化を与えるサブルーチン
+ * Apply magic to an item known to be a "weapon"
+ */
+void WeaponEnchanter::apply_magic()
+{
+ if ((this->o_ptr->tval == ItemKindType::SWORD) && (this->o_ptr->sval == SV_DIAMOND_EDGE))
+ return;
+
+ switch (this->o_ptr->tval) {
+ case ItemKindType::DIGGING: {
+ if (this->power > 1) {
+ /* this->power > 2はデバッグ専用. */
+ if (one_in_(30) || (this->power > 2))
+ become_random_artifact(this->player_ptr, this->o_ptr, false);
+ else
+ this->o_ptr->name2 = EGO_DIGGING;
+ } else if (this->power < -1) {
+ this->o_ptr->pval = 0 - (5 + randint1(5));
+ } else if (this->power < 0) {
+ this->o_ptr->pval = 0 - (this->o_ptr->pval);
+ }
+
+ break;
+ }
+ case ItemKindType::HAFTED:
+ case ItemKindType::POLEARM:
+ case ItemKindType::SWORD: {
+ if (this->power > 1) {
+ /* power > 2はデバッグ専用. */
+ if (one_in_(40) || (this->power > 2)) {
+ become_random_artifact(this->player_ptr, this->o_ptr, false);
+ break;
+ }
+ while (true) {
+ this->o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, true);
+ if (this->o_ptr->name2 == EGO_SHARPNESS && this->o_ptr->tval != ItemKindType::SWORD)
+ continue;
+ if (this->o_ptr->name2 == EGO_EARTHQUAKES && this->o_ptr->tval != ItemKindType::HAFTED)
+ continue;
+ break;
+ }
+
+ switch (this->o_ptr->name2) {
+ case EGO_SHARPNESS:
+ this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, this->level) + 1;
+ break;
+ case EGO_EARTHQUAKES:
+ if (one_in_(3) && (this->level > 60))
+ this->o_ptr->art_flags.set(TR_BLOWS);
+ else
+ this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, this->level);
+ break;
+ default:
+ break;
+ }
+
+ if (!this->o_ptr->art_name) {
+ while (one_in_(10L * this->o_ptr->dd * this->o_ptr->ds))
+ this->o_ptr->dd++;
+
+ if (this->o_ptr->dd > 9)
+ this->o_ptr->dd = 9;
+ }
+ } else if (this->power < -1) {
+ if (randint0(MAX_DEPTH) < this->level) {
+ int n = 0;
+ while (true) {
+ this->o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, false);
+ if (this->o_ptr->name2 == EGO_WEIRD && this->o_ptr->tval != ItemKindType::SWORD) {
+ continue;
+ }
+
+ ego_item_type *e_ptr = &e_info[this->o_ptr->name2];
+ if (this->o_ptr->tval == ItemKindType::SWORD && this->o_ptr->sval == SV_HAYABUSA && e_ptr->max_pval < 0) {
+ if (++n > 1000) {
+ msg_print(_("エラー:隼の剣に割り当てるエゴ無し", "Error: Cannot find for Hayabusa."));
+ return;
+ }
+ continue;
+ }
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ case ItemKindType::BOW: {
+ if (this->power > 1) {
+ /* this->power > 2はデバッグ専用. */
+ if (one_in_(20) || (this->power > 2)) {
+ become_random_artifact(this->player_ptr, this->o_ptr, false);
+ break;
+ }
+
+ this->o_ptr->name2 = get_random_ego(INVEN_BOW, true);
+ }
+
+ break;
+ }
+ case ItemKindType::BOLT:
+ case ItemKindType::ARROW:
+ case ItemKindType::SHOT: {
+ if (this->power > 1) {
+ /* this->power > 2はデバッグ専用. */
+ if (this->power > 2) {
+ become_random_artifact(this->player_ptr, this->o_ptr, false);
+ break;
+ }
+
+ this->o_ptr->name2 = get_random_ego(INVEN_AMMO, true);
+
+ while (one_in_(10L * this->o_ptr->dd * this->o_ptr->ds))
+ this->o_ptr->dd++;
+
+ if (this->o_ptr->dd > 9)
+ this->o_ptr->dd = 9;
+ } else if (this->power < -1) {
+ if (randint0(MAX_DEPTH) < this->level) {
+ this->o_ptr->name2 = get_random_ego(INVEN_AMMO, false);
+ }
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
--- /dev/null
+#pragma once
+
+#include "object-enchant/weapon/abstract-weapon-enchanter.h"
+#include "system/angband.h"
+
+struct object_type;
+class PlayerType;
+class WeaponEnchanter : AbstractWeaponEnchanter {
+public:
+ WeaponEnchanter(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power);
+ void apply_magic() override;
+
+protected:
+ virtual void enchant() override {}
+ virtual void give_ego_index() override {}
+ virtual void give_high_ego_index() override {}
+ virtual void give_cursed() override {}
+
+private:
+ PlayerType *player_ptr;
+};
#include "object/object-flags.h"
#include "mind/mind-weaponsmith.h"
#include "object-enchant/object-ego.h"
-#include "object-enchant/object-smith.h"
#include "object-enchant/tr-types.h"
#include "object/object-kind.h"
#include "perception/object-perception.h"
+#include "smith/object-smith.h"
#include "sv-definition/sv-lite-types.h"
#include "system/artifact-type-definition.h"
#include "system/object-type-definition.h"
#include "object/object-stack.h"
#include "game-option/game-play-options.h"
#include "object-enchant/object-ego.h"
-#include "object-enchant/object-smith.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/trc-types.h"
#include "object/object-kind.h"
#include "object/object-value.h"
#include "perception/object-perception.h"
+#include "smith/object-smith.h"
#include "sv-definition/sv-other-types.h"
#include "system/object-type-definition.h"
int choices[INVEN_TOTAL - INVEN_MAIN_HAND];
/* Paranoia -- Player has no warning ability */
- if (!player_ptr->warning)
+ if (!player_ptr->warning) {
return nullptr;
+ }
/* Search Inventory */
int number = 0;
case AttributeType::DARK:
dam = dam * calc_dark_damage_rate(player_ptr, CALC_MAX) / 100;
- if (has_immune_dark(player_ptr) || player_ptr->wraith_form)
+ if (has_immune_dark(player_ptr) || player_ptr->wraith_form) {
ignore_wraith_form = true;
+ }
break;
case AttributeType::SHARDS:
case AttributeType::DEATH_RAY:
dam = dam * calc_deathray_damage_rate(player_ptr, CALC_MAX) / 100;
- if (dam == 0)
+ if (dam == 0) {
ignore_wraith_form = true;
+ }
break;
case AttributeType::HOLY_FIRE:
dam = dam * calc_hell_fire_damage_rate(player_ptr, CALC_MAX) / 100;
break;
+ case AttributeType::ABYSS:
+ dam = dam * calc_abyss_damage_rate(player_ptr, CALC_MAX) / 100;
+ break;
+
+ case AttributeType::VOID_MAGIC:
+ dam = dam * calc_void_damage_rate(player_ptr, CALC_MAX) / 100;
+ break;
+
case AttributeType::MIND_BLAST:
case AttributeType::BRAIN_SMASH:
if (100 + rlev / 2 <= std::max<short>(5, player_ptr->skill_sav)) {
if (player_ptr->wraith_form && !ignore_wraith_form) {
dam /= 2;
- if (!dam)
+ if (!dam) {
dam = 1;
+ }
}
- if (dam > *max)
+ if (dam > *max) {
*max = dam;
+ }
}
/*!
if (check_wraith_form && player_ptr->wraith_form) {
dam /= 2;
- if (!dam)
+ if (!dam) {
dam = 1;
+ }
}
return dam;
monster_type *m_ptr;
monster_race *r_ptr;
- if (!in_bounds(player_ptr->current_floor_ptr, my, mx) || (distance(my, mx, yy, xx) > WARNING_AWARE_RANGE))
+ if (!in_bounds(player_ptr->current_floor_ptr, my, mx) || (distance(my, mx, yy, xx) > WARNING_AWARE_RANGE)) {
continue;
+ }
g_ptr = &player_ptr->current_floor_ptr->grid_array[my][mx];
- if (!g_ptr->m_idx)
+ if (!g_ptr->m_idx) {
continue;
+ }
m_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
- if (monster_csleep_remaining(m_ptr))
+ if (monster_csleep_remaining(m_ptr)) {
continue;
- if (!is_hostile(m_ptr))
+ }
+ if (!is_hostile(m_ptr)) {
continue;
+ }
r_ptr = &r_info[m_ptr->r_idx];
const auto flags = r_ptr->ability_flags;
if (d_info[player_ptr->dungeon_idx].flags.has_not(DungeonFeatureType::NO_MAGIC)) {
- if (flags.has(MonsterAbilityType::BA_CHAO))
+ if (flags.has(MonsterAbilityType::BA_CHAO)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_CHAO, AttributeType::CHAOS, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BA_MANA))
+ }
+ if (flags.has(MonsterAbilityType::BA_MANA)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_MANA, AttributeType::MANA, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BA_DARK))
+ }
+ if (flags.has(MonsterAbilityType::BA_DARK)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_DARK, AttributeType::DARK, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BA_LITE))
+ }
+ if (flags.has(MonsterAbilityType::BA_LITE)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_LITE, AttributeType::LITE, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::HAND_DOOM))
+ }
+ if (flags.has(MonsterAbilityType::HAND_DOOM)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::HAND_DOOM, AttributeType::HAND_DOOM, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::PSY_SPEAR))
+ }
+ if (flags.has(MonsterAbilityType::PSY_SPEAR)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::PSY_SPEAR, AttributeType::PSY_SPEAR, g_ptr->m_idx, &dam_max0);
+ }
+ if (flags.has(MonsterAbilityType::BA_VOID)) {
+ spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_VOID, AttributeType::VOID_MAGIC, g_ptr->m_idx, &dam_max0);
+ }
+ if (flags.has(MonsterAbilityType::BA_ABYSS)) {
+ spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_ABYSS, AttributeType::ABYSS, g_ptr->m_idx, &dam_max0);
+ }
}
- if (flags.has(MonsterAbilityType::ROCKET))
+ if (flags.has(MonsterAbilityType::ROCKET)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::ROCKET, AttributeType::ROCKET, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_ACID))
+ }
+ if (flags.has(MonsterAbilityType::BR_ACID)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_ACID, AttributeType::ACID, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_ELEC))
+ }
+ if (flags.has(MonsterAbilityType::BR_ELEC)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_ELEC, AttributeType::ELEC, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_FIRE))
+ }
+ if (flags.has(MonsterAbilityType::BR_FIRE)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_FIRE, AttributeType::FIRE, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_COLD))
+ }
+ if (flags.has(MonsterAbilityType::BR_COLD)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_COLD, AttributeType::COLD, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_POIS))
+ }
+ if (flags.has(MonsterAbilityType::BR_POIS)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_POIS, AttributeType::POIS, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_NETH))
+ }
+ if (flags.has(MonsterAbilityType::BR_NETH)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_NETH, AttributeType::NETHER, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_LITE))
+ }
+ if (flags.has(MonsterAbilityType::BR_LITE)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_LITE, AttributeType::LITE, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_DARK))
+ }
+ if (flags.has(MonsterAbilityType::BR_DARK)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_DARK, AttributeType::DARK, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_CONF))
+ }
+ if (flags.has(MonsterAbilityType::BR_CONF)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_CONF, AttributeType::CONFUSION, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_SOUN))
+ }
+ if (flags.has(MonsterAbilityType::BR_SOUN)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_SOUN, AttributeType::SOUND, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_CHAO))
+ }
+ if (flags.has(MonsterAbilityType::BR_CHAO)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_CHAO, AttributeType::CHAOS, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_DISE))
+ }
+ if (flags.has(MonsterAbilityType::BR_DISE)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_DISE, AttributeType::DISENCHANT, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_NEXU))
+ }
+ if (flags.has(MonsterAbilityType::BR_NEXU)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_NEXU, AttributeType::NEXUS, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_TIME))
+ }
+ if (flags.has(MonsterAbilityType::BR_TIME)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_TIME, AttributeType::TIME, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_INER))
+ }
+ if (flags.has(MonsterAbilityType::BR_INER)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_INER, AttributeType::INERTIAL, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_GRAV))
+ }
+ if (flags.has(MonsterAbilityType::BR_GRAV)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_GRAV, AttributeType::GRAVITY, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_SHAR))
+ }
+ if (flags.has(MonsterAbilityType::BR_SHAR)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_SHAR, AttributeType::SHARDS, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_PLAS))
+ }
+ if (flags.has(MonsterAbilityType::BR_PLAS)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_PLAS, AttributeType::PLASMA, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_FORC))
+ }
+ if (flags.has(MonsterAbilityType::BR_FORC)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_FORC, AttributeType::FORCE, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_MANA))
+ }
+ if (flags.has(MonsterAbilityType::BR_MANA)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_MANA, AttributeType::MANA, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_NUKE))
+ }
+ if (flags.has(MonsterAbilityType::BR_NUKE)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_NUKE, AttributeType::NUKE, g_ptr->m_idx, &dam_max0);
- if (flags.has(MonsterAbilityType::BR_DISI))
+ }
+ if (flags.has(MonsterAbilityType::BR_DISI)) {
spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_DISI, AttributeType::DISINTEGRATE, g_ptr->m_idx, &dam_max0);
+ }
+ if (flags.has(MonsterAbilityType::BR_VOID)) {
+ spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_VOID, AttributeType::VOID_MAGIC, g_ptr->m_idx, &dam_max0);
+ }
+ if (flags.has(MonsterAbilityType::BR_ABYSS)) {
+ spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_ABYSS, AttributeType::ABYSS, g_ptr->m_idx, &dam_max0);
+ }
}
-
/* Monster melee attacks */
- if ((r_ptr->flags1 & RF1_NEVER_BLOW) || d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE)) {
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW) || d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_MELEE)) {
dam_max += dam_max0;
continue;
}
int dam_melee = 0;
for (int m = 0; m < 4; m++) {
/* Skip non-attacks */
- if (r_ptr->blow[m].method == RaceBlowMethodType::NONE || (r_ptr->blow[m].method == RaceBlowMethodType::SHOOT))
+ if (r_ptr->blow[m].method == RaceBlowMethodType::NONE || (r_ptr->blow[m].method == RaceBlowMethodType::SHOOT)) {
continue;
+ }
/* Extract the attack info */
dam_melee += blow_damcalc(m_ptr, player_ptr, &r_ptr->blow[m]);
- if (r_ptr->blow[m].method == RaceBlowMethodType::EXPLODE)
+ if (r_ptr->blow[m].method == RaceBlowMethodType::EXPLODE) {
break;
+ }
}
- if (dam_melee > dam_max0)
+ if (dam_melee > dam_max0) {
dam_max0 = dam_melee;
+ }
dam_max += dam_max0;
}
}
if (dam_max > player_ptr->chp / 2) {
object_type *o_ptr = choose_warning_item(player_ptr);
- if (o_ptr)
+ if (o_ptr) {
describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
- else
+ } else {
strcpy(o_name, _("体", "body")); /* Warning ability without item */
+ }
msg_format(_("%sが鋭く震えた!", "Your %s pulsates sharply!"), o_name);
disturb(player_ptr, false, true);
return get_check(_("本当にこのまま進むか?", "Really want to go ahead? "));
}
- } else
+ } else {
old_damage = old_damage / 2;
+ }
g_ptr = &player_ptr->current_floor_ptr->grid_array[yy][xx];
bool is_warning = (!easy_disarm && is_trap(player_ptr, g_ptr->feat)) || (g_ptr->mimic && is_trap(player_ptr, g_ptr->feat));
is_warning &= !one_in_(13);
- if (!is_warning)
+ if (!is_warning) {
return true;
+ }
object_type *o_ptr = choose_warning_item(player_ptr);
- if (o_ptr != nullptr)
+ if (o_ptr != nullptr) {
describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
- else
+ } else {
strcpy(o_name, _("体", "body")); /* Warning ability without item */
+ }
msg_format(_("%sが鋭く震えた!", "Your %s pulsates sharply!"), o_name);
disturb(player_ptr, false, true);
return get_check(_("本当にこのまま進むか?", "Really want to go ahead? "));
#include "floor/geometry.h"
#include "grid/feature.h"
#include "grid/grid.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-race/monster-race.h"
#include "monster/monster-describer.h"
#include "pet/pet-util.h"
* @param player_ptr プレイヤーへの参照ポインタ
* @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
*/
-void check_fall_off_horse(PlayerType *player_ptr, monap_type *monap_ptr)
+void check_fall_off_horse(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
{
if ((player_ptr->riding == 0) || (monap_ptr->damage == 0))
return;
#include "system/angband.h"
-typedef struct monap_type monap_type;
+class MonsterAttackPlayer;
class PlayerType;
-void check_fall_off_horse(PlayerType *player_ptr, monap_type *monap_ptr);
+void check_fall_off_horse(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
bool process_fall_off_horse(PlayerType *player_ptr, HIT_POINT dam, bool force);
result |= FLAG_CAUSE_MAGIC_TIME_EFFECT;
}
-
return result;
}
bool has_two_handed_weapons(PlayerType *player_ptr)
{
if (can_two_hands_wielding(player_ptr)) {
- if (can_attack_with_main_hand(player_ptr) && (empty_hands(player_ptr, false) == EMPTY_HAND_SUB)
- && player_ptr->inventory_list[INVEN_MAIN_HAND].allow_two_hands_wielding()) {
+ if (can_attack_with_main_hand(player_ptr) && (empty_hands(player_ptr, false) == EMPTY_HAND_SUB) && player_ptr->inventory_list[INVEN_MAIN_HAND].allow_two_hands_wielding()) {
return true;
- } else if (can_attack_with_sub_hand(player_ptr) && (empty_hands(player_ptr, false) == EMPTY_HAND_MAIN)
- && player_ptr->inventory_list[INVEN_SUB_HAND].allow_two_hands_wielding()) {
+ } else if (can_attack_with_sub_hand(player_ptr) && (empty_hands(player_ptr, false) == EMPTY_HAND_MAIN) && player_ptr->inventory_list[INVEN_SUB_HAND].allow_two_hands_wielding()) {
return true;
}
}
if (!has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
return false;
}
-
+
auto tval = player_ptr->inventory_list[INVEN_MAIN_HAND + i].tval;
auto sval = player_ptr->inventory_list[INVEN_MAIN_HAND + i].sval;
return ((player_ptr->pclass == PlayerClassType::MONK) || (player_ptr->pclass == PlayerClassType::FORCETRAINER)) && (player_ptr->weapon_exp_max[tval][sval] == PlayerSkill::weapon_exp_at(PlayerSkillRank::UNSKILLED));
{
(void)mode; // unused
PERCENTAGE per = 100;
- if (player_ptr->levitation) {
+ if (has_levitation(player_ptr)) {
per = (per * 2) / 3;
}
return per;
{
(void)mode; // unused
PERCENTAGE per = 100;
- if (player_ptr->tim_pass_wall) {
+ if (has_pass_wall(player_ptr)) {
per = per * 3 / 2;
- } else if (player_ptr->anti_tele) {
+ } else if (has_anti_tele(player_ptr) != 0) {
per *= 400;
per /= randrate(4, 7, mode);
- } else if (player_ptr->levitation) {
+ } else if (has_levitation(player_ptr) != 0) {
per = (per * 2) / 3;
}
return per;
(void)mode; // unused
PERCENTAGE per = 100;
- if (has_resist_dark(player_ptr)) {
+ if (has_resist_dark(player_ptr) != 0) {
per *= 400;
per /= randrate(4, 7, mode);
- } else if (!player_ptr->levitation && player_ptr->anti_tele) {
+ } else if ((has_levitation(player_ptr) == 0) && (has_anti_tele(player_ptr) != 0)) {
per = (per * 5) / 4;
}
return per;
* @note that we restrict the number of "crowded" rooms to reduce the chance of overflowing the monster list during level creation.
* @return 部屋の生成に成功した場合 TRUE を返す。
*/
-static bool room_build(PlayerType *player_ptr, dun_data_type *dd_ptr, room_type typ)
+static bool room_build(PlayerType *player_ptr, dun_data_type *dd_ptr, RoomType typ)
{
switch (typ) {
- case ROOM_T_NORMAL:
+ case RoomType::NORMAL:
return build_type1(player_ptr, dd_ptr);
- case ROOM_T_OVERLAP:
+ case RoomType::OVERLAP:
return build_type2(player_ptr, dd_ptr);
- case ROOM_T_CROSS:
+ case RoomType::CROSS:
return build_type3(player_ptr, dd_ptr);
- case ROOM_T_INNER_FEAT:
+ case RoomType::INNER_FEAT:
return build_type4(player_ptr, dd_ptr);
- case ROOM_T_NEST:
+ case RoomType::NEST:
return build_type5(player_ptr, dd_ptr);
- case ROOM_T_PIT:
+ case RoomType::PIT:
return build_type6(player_ptr, dd_ptr);
- case ROOM_T_LESSER_VAULT:
+ case RoomType::LESSER_VAULT:
return build_type7(player_ptr, dd_ptr);
- case ROOM_T_GREATER_VAULT:
+ case RoomType::GREATER_VAULT:
return build_type8(player_ptr, dd_ptr);
- case ROOM_T_FRACAVE:
+ case RoomType::FRACAVE:
return build_type9(player_ptr, dd_ptr);
- case ROOM_T_RANDOM_VAULT:
+ case RoomType::RANDOM_VAULT:
return build_type10(player_ptr, dd_ptr);
- case ROOM_T_OVAL:
+ case RoomType::OVAL:
return build_type11(player_ptr, dd_ptr);
- case ROOM_T_CRYPT:
+ case RoomType::CRYPT:
return build_type12(player_ptr, dd_ptr);
- case ROOM_T_TRAP_PIT:
+ case RoomType::TRAP_PIT:
return build_type13(player_ptr, dd_ptr);
- case ROOM_T_TRAP:
+ case RoomType::TRAP:
return build_type14(player_ptr, dd_ptr);
- case ROOM_T_GLASS:
+ case RoomType::GLASS:
return build_type15(player_ptr, dd_ptr);
- case ROOM_T_ARCADE:
+ case RoomType::ARCADE:
return build_type16(player_ptr, dd_ptr);
- case ROOM_T_FIXED:
+ case RoomType::FIXED:
return build_type17(player_ptr, dd_ptr);
default:
return false;
* @param dst 確率を移す先の部屋種ID
* @param src 確率を与える元の部屋種ID
*/
-static void move_prob_list(room_type dst, room_type src, int *prob_list)
+static void move_prob_list(RoomType dst, RoomType src, std::map<RoomType, int> &prob_list)
{
prob_list[dst] += prob_list[src];
prob_list[src] = 0;
{
floor_type *floor_ptr = player_ptr->current_floor_ptr;
int crowded = 0;
- int prob_list[ROOM_T_MAX];
+ std::map<RoomType, int> prob_list;
int rooms_built = 0;
int area_size = 100 * (floor_ptr->height * floor_ptr->width) / (MAX_HGT * MAX_WID);
int level_index = std::min(10, div_round(floor_ptr->dun_level, 10));
- int16_t room_num[ROOM_T_MAX];
+ std::map<RoomType, int> room_num;
int dun_rooms = DUN_ROOMS_MAX * area_size / 100;
room_info_type *room_info_ptr = room_info_normal;
- for (int i = 0; i < ROOM_T_MAX; i++) {
- if (floor_ptr->dun_level < room_info_ptr[i].min_level)
- prob_list[i] = 0;
+ for (auto r : ROOM_TYPE_LIST) {
+ if (floor_ptr->dun_level < room_info_ptr[enum2i(r)].min_level)
+ prob_list[r] = 0;
else
- prob_list[i] = room_info_ptr[i].prob[level_index];
+ prob_list[r] = room_info_ptr[enum2i(r)].prob[level_index];
}
/*!
* GRATER_VAULTのみを生成対象とする。 / Ironman sees only Greater Vaults
*/
if (ironman_rooms && d_info[floor_ptr->dungeon_idx].flags.has_none_of( {DungeonFeatureType::BEGINNER, DungeonFeatureType::CHAMELEON, DungeonFeatureType::SMALLEST })) {
- for (int i = 0; i < ROOM_T_MAX; i++) {
- if (i == ROOM_T_GREATER_VAULT)
- prob_list[i] = 1;
+ for (auto r : ROOM_TYPE_LIST) {
+ if (r == RoomType::GREATER_VAULT)
+ prob_list[r] = 1;
else
- prob_list[i] = 0;
+ prob_list[r] = 0;
}
} else if (d_info[floor_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_VAULT)) {
/*! @details ダンジョンにNO_VAULTフラグがあるならば、LESSER_VAULT / GREATER_VAULT/ RANDOM_VAULTを除外 / Forbidden vaults */
- prob_list[ROOM_T_LESSER_VAULT] = 0;
- prob_list[ROOM_T_GREATER_VAULT] = 0;
- prob_list[ROOM_T_RANDOM_VAULT] = 0;
+ prob_list[RoomType::LESSER_VAULT] = 0;
+ prob_list[RoomType::GREATER_VAULT] = 0;
+ prob_list[RoomType::RANDOM_VAULT] = 0;
}
/*! @details ダンジョンにBEGINNERフラグがあるならば、FIXED_ROOMを除外 / Forbidden vaults */
if (d_info[floor_ptr->dungeon_idx].flags.has(DungeonFeatureType::BEGINNER))
- prob_list[ROOM_T_FIXED] = 0;
+ prob_list[RoomType::FIXED] = 0;
/*! @details ダンジョンにNO_CAVEフラグがある場合、FRACAVEの生成枠がNORMALに与えられる。CRIPT、OVALの生成枠がINNER_Fに与えられる。/ NO_CAVE dungeon */
if (d_info[floor_ptr->dungeon_idx].flags.has(DungeonFeatureType::NO_CAVE)) {
- move_prob_list(ROOM_T_NORMAL, ROOM_T_FRACAVE, prob_list);
- move_prob_list(ROOM_T_INNER_FEAT, ROOM_T_CRYPT, prob_list);
- move_prob_list(ROOM_T_INNER_FEAT, ROOM_T_OVAL, prob_list);
+ move_prob_list(RoomType::NORMAL, RoomType::FRACAVE, prob_list);
+ move_prob_list(RoomType::INNER_FEAT, RoomType::CRYPT, prob_list);
+ move_prob_list(RoomType::INNER_FEAT, RoomType::OVAL, prob_list);
} else if (d_info[floor_ptr->dungeon_idx].flags.has(DungeonFeatureType::CAVE)) {
/*! @details ダンジョンにCAVEフラグがある場合、NORMALの生成枠がFRACAVEに与えられる。/ CAVE dungeon (Orc floor_ptr->grid_array etc.) */
- move_prob_list(ROOM_T_FRACAVE, ROOM_T_NORMAL, prob_list);
+ move_prob_list(RoomType::FRACAVE, RoomType::NORMAL, prob_list);
} else if (dd_ptr->cavern || dd_ptr->empty_level) {
/*! @details ダンジョンの基本地形が最初から渓谷かアリーナ型の場合 FRACAVE は生成から除外。 / No caves when a (random) cavern exists: they look bad */
- prob_list[ROOM_T_FRACAVE] = 0;
+ prob_list[RoomType::FRACAVE] = 0;
}
/*! @details ダンジョンに最初からGLASS_ROOMフラグがある場合、GLASS を生成から除外。/ Forbidden glass rooms */
if (d_info[floor_ptr->dungeon_idx].flags.has_not(DungeonFeatureType::GLASS_ROOM))
- prob_list[ROOM_T_GLASS] = 0;
+ prob_list[RoomType::GLASS] = 0;
/*! @details ARCADEは同フラグがダンジョンにないと生成されない。 / Forbidden glass rooms */
if (d_info[floor_ptr->dungeon_idx].flags.has_not(DungeonFeatureType::ARCADE))
- prob_list[ROOM_T_ARCADE] = 0;
+ prob_list[RoomType::ARCADE] = 0;
- ProbabilityTable<int> prob_table;
- for (int i = 0; i < ROOM_T_MAX; i++) {
+ ProbabilityTable<RoomType> prob_table;
+ for (auto i : ROOM_TYPE_LIST) {
room_num[i] = 0;
prob_table.entry_item(i, prob_list[i]);
}
for (int i = dun_rooms; i > 0; i--) {
- int room_type;
- if (prob_table.empty())
- room_type = ROOM_T_NORMAL;
- else
- room_type = prob_table.pick_one_at_random();
-
- room_num[room_type]++;
- switch (room_type) {
- case ROOM_T_NEST:
- case ROOM_T_PIT:
- case ROOM_T_LESSER_VAULT:
- case ROOM_T_TRAP_PIT:
- case ROOM_T_GLASS:
- case ROOM_T_ARCADE:
+ auto r = prob_table.empty() ? RoomType::NORMAL : prob_table.pick_one_at_random();
+
+ room_num[r]++;
+ switch (r) {
+ case RoomType::NEST:
+ case RoomType::PIT:
+ case RoomType::LESSER_VAULT:
+ case RoomType::TRAP_PIT:
+ case RoomType::GLASS:
+ case RoomType::ARCADE:
/* Large room */
i -= 2;
break;
- case ROOM_T_GREATER_VAULT:
- case ROOM_T_RANDOM_VAULT:
+ case RoomType::GREATER_VAULT:
+ case RoomType::RANDOM_VAULT:
/* Largest room */
i -= 3;
break;
+ default:
+ break;
}
}
bool remain;
while (true) {
remain = false;
- for (int i = 0; i < ROOM_T_MAX; i++) {
- room_type room_type = room_build_order[i];
+ for (auto i = 0; i < ROOM_TYPE_MAX; i++) {
+ auto room_type = room_build_order[i];
if (!room_num[room_type])
continue;
rooms_built++;
remain = true;
switch (room_type) {
- case ROOM_T_PIT:
- case ROOM_T_NEST:
- case ROOM_T_TRAP_PIT:
+ case RoomType::PIT:
+ case RoomType::NEST:
+ case RoomType::TRAP_PIT:
if (++crowded >= 2) {
- room_num[ROOM_T_PIT] = 0;
- room_num[ROOM_T_NEST] = 0;
- room_num[ROOM_T_TRAP_PIT] = 0;
+ room_num[RoomType::PIT] = 0;
+ room_num[RoomType::NEST] = 0;
+ room_num[RoomType::TRAP_PIT] = 0;
}
break;
- case ROOM_T_ARCADE:
- room_num[ROOM_T_ARCADE] = 0;
+ case RoomType::ARCADE:
+ room_num[RoomType::ARCADE] = 0;
break;
default:
break;
* appear above their minimum depth. Tiny levels will not have space\n
* for all the rooms you ask for.\n
*/
-room_info_type room_info_normal[ROOM_T_MAX] = {
+room_info_type room_info_normal[ROOM_TYPE_MAX] = {
/* Depth */
/* 0 10 20 30 40 50 60 70 80 90 100 min limit */
{ { 999, 900, 800, 700, 600, 500, 400, 300, 200, 100, 0 }, 0 }, /*NORMAL */
};
/*! 部屋の生成処理順 / Build rooms in descending order of difficulty. */
-room_type room_build_order[ROOM_T_MAX] = {
- ROOM_T_GREATER_VAULT,
- ROOM_T_ARCADE,
- ROOM_T_RANDOM_VAULT,
- ROOM_T_LESSER_VAULT,
- ROOM_T_TRAP_PIT,
- ROOM_T_PIT,
- ROOM_T_NEST,
- ROOM_T_TRAP,
- ROOM_T_GLASS,
- ROOM_T_INNER_FEAT,
- ROOM_T_FIXED,
- ROOM_T_OVAL,
- ROOM_T_CRYPT,
- ROOM_T_OVERLAP,
- ROOM_T_CROSS,
- ROOM_T_FRACAVE,
- ROOM_T_NORMAL,
+RoomType room_build_order[ROOM_TYPE_MAX] = {
+ RoomType::GREATER_VAULT,
+ RoomType::ARCADE,
+ RoomType::RANDOM_VAULT,
+ RoomType::LESSER_VAULT,
+ RoomType::TRAP_PIT,
+ RoomType::PIT,
+ RoomType::NEST,
+ RoomType::TRAP,
+ RoomType::GLASS,
+ RoomType::INNER_FEAT,
+ RoomType::FIXED,
+ RoomType::OVAL,
+ RoomType::CRYPT,
+ RoomType::OVERLAP,
+ RoomType::CROSS,
+ RoomType::FRACAVE,
+ RoomType::NORMAL,
};
/* Room type information */
typedef struct room_info_type {
- int16_t prob[ROOM_T_MAX]; /* Allocation information. */
+ int16_t prob[ROOM_TYPE_MAX]; /* Allocation information. */
byte min_level; /* Minimum level on which room can appear. */
} room_info_type;
-extern room_info_type room_info_normal[ROOM_T_MAX];
-extern room_type room_build_order[ROOM_T_MAX];
+extern room_info_type room_info_normal[ROOM_TYPE_MAX];
+extern RoomType room_build_order[ROOM_TYPE_MAX];
#pragma once
+#include "util/enum-converter.h"
+#include "util/enum-range.h"
+
/* 部屋型ID / Room types for room_build() */
-enum room_type {
- ROOM_T_NORMAL = 0, /*!<部屋型ID:基本長方形 / Simple (33x11) */
- ROOM_T_OVERLAP = 1, /*!<部屋型ID:長方形二つ重ね / Overlapping (33x11) */
- ROOM_T_CROSS = 2, /*!<部屋型ID:十字 / Crossed (33x11) */
- ROOM_T_INNER_FEAT = 3, /*!<部屋型ID:二重壁 / Large (33x11) */
- ROOM_T_NEST = 4, /*!<部屋型ID:モンスターNEST / Monster nest (33x11) */
- ROOM_T_PIT = 5, /*!<部屋型ID:モンスターPIT / Monster pit (33x11) */
- ROOM_T_LESSER_VAULT = 6, /*!<部屋型ID:小型VAULT / Lesser vault (33x22) */
- ROOM_T_GREATER_VAULT = 7, /*!<部屋型ID:大型VAULT / Greater vault (66x44) */
- ROOM_T_FRACAVE = 8, /*!<部屋型ID:フラクタル地形 / Fractal room (42x24) */
- ROOM_T_RANDOM_VAULT = 9, /*!<部屋型ID:ランダムVAULT / Random vault (44x22) */
- ROOM_T_OVAL = 10, /*!<部屋型ID:円形部屋 / Circular rooms (22x22) */
- ROOM_T_CRYPT = 11, /*!<部屋型ID:聖堂 / Crypts (22x22) */
- ROOM_T_TRAP_PIT = 12, /*!<部屋型ID:トラップつきモンスターPIT / Trapped monster pit */
- ROOM_T_TRAP = 13, /*!<部屋型ID:トラップ部屋 / Piranha/Armageddon trap room */
- ROOM_T_GLASS = 14, /*!<部屋型ID:ガラス部屋 / Glass room */
- ROOM_T_ARCADE = 15, /*!<部屋型ID:商店 / Arcade */
- ROOM_T_FIXED = 16, /*!<部屋型ID:固定部屋 / Fixed room */
- ROOM_T_MAX = 17, /*!<部屋型ID最大数 */
+enum class RoomType {
+ NORMAL = 0, /*!<部屋型ID:基本長方形 / Simple (33x11) */
+ OVERLAP = 1, /*!<部屋型ID:長方形二つ重ね / Overlapping (33x11) */
+ CROSS = 2, /*!<部屋型ID:十字 / Crossed (33x11) */
+ INNER_FEAT = 3, /*!<部屋型ID:二重壁 / Large (33x11) */
+ NEST = 4, /*!<部屋型ID:モンスターNEST / Monster nest (33x11) */
+ PIT = 5, /*!<部屋型ID:モンスターPIT / Monster pit (33x11) */
+ LESSER_VAULT = 6, /*!<部屋型ID:小型VAULT / Lesser vault (33x22) */
+ GREATER_VAULT = 7, /*!<部屋型ID:大型VAULT / Greater vault (66x44) */
+ FRACAVE = 8, /*!<部屋型ID:フラクタル地形 / Fractal room (42x24) */
+ RANDOM_VAULT = 9, /*!<部屋型ID:ランダムVAULT / Random vault (44x22) */
+ OVAL = 10, /*!<部屋型ID:円形部屋 / Circular rooms (22x22) */
+ CRYPT = 11, /*!<部屋型ID:聖堂 / Crypts (22x22) */
+ TRAP_PIT = 12, /*!<部屋型ID:トラップつきモンスターPIT / Trapped monster pit */
+ TRAP = 13, /*!<部屋型ID:トラップ部屋 / Piranha/Armageddon trap room */
+ GLASS = 14, /*!<部屋型ID:ガラス部屋 / Glass room */
+ ARCADE = 15, /*!<部屋型ID:商店 / Arcade */
+ FIXED = 16, /*!<部屋型ID:固定部屋 / Fixed room */
+ MAX = 17, /*!<部屋型ID最大数 */
};
+
+constexpr int ROOM_TYPE_MAX = enum2i(RoomType::MAX);
+
+constexpr auto ROOM_TYPE_LIST = EnumRange(RoomType::NORMAL, RoomType::FIXED);
* @param allow_flag_mask 生成が許されるpit/nestのビット配列
* @return 選択されたpit/nestのID、選択失敗した場合-1を返す。
*/
-static int pick_vault_type(floor_type *floor_ptr, std::vector<nest_pit_type>& l_ptr, BIT_FLAGS16 allow_flag_mask)
+static int pick_vault_type(floor_type *floor_ptr, std::vector<nest_pit_type> &l_ptr, BIT_FLAGS16 allow_flag_mask)
{
ProbabilityTable<int> table;
for (size_t i = 0; i < l_ptr.size(); i++) {
strcpy(inner_buf, _("(万色)", "(multi-hued)"));
} else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_ACID)) {
strcpy(inner_buf, _("(酸)", "(acid)"));
- }else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_ELEC)) {
+ } else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_ELEC)) {
strcpy(inner_buf, _("(稲妻)", "(lightning)"));
- }else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_FIRE)) {
+ } else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_FIRE)) {
strcpy(inner_buf, _("(火炎)", "(fire)"));
- }else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_COLD)) {
+ } else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_COLD)) {
strcpy(inner_buf, _("(冷気)", "(frost)"));
- }else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_POIS)) {
+ } else if (vault_aux_dragon_mask4.has(MonsterAbilityType::BR_POIS)) {
strcpy(inner_buf, _("(毒)", "(poison)"));
} else {
strcpy(inner_buf, _("(未定義)", "(undefined)"));
#include "save/item-writer.h"
#include "artifact/random-art-effects.h"
-#include "load/old/item-flag-types-savefile10.h"
+#include "load/old/item-flag-types-savefile50.h"
#include "object/object-kind.h"
#include "save/save-util.h"
#include "system/object-type-definition.h"
#include "save/monster-writer.h"
-#include "load/old/monster-flag-types-savefile10.h"
+#include "load/old/monster-flag-types-savefile50.h"
#include "monster-race/monster-race.h"
#include "monster/monster-info.h"
#include "monster/monster-status.h"
wr_u32b(r_ptr->r_flagsr);
wr_FlagGroup(r_ptr->r_ability_flags, wr_byte);
wr_FlagGroup(r_ptr->r_aura_flags, wr_byte);
+ wr_FlagGroup(r_ptr->r_behavior_flags, wr_byte);
wr_byte((byte)r_ptr->max_num);
wr_s16b(r_ptr->floor_id);
w_ptr->sf_system = 0L;
w_ptr->sf_when = now;
w_ptr->sf_saves++;
+
save_xor_byte = 0;
- wr_byte(FAKE_VER_MAJOR);
- save_xor_byte = 0;
- wr_byte(FAKE_VER_MINOR);
- save_xor_byte = 0;
- wr_byte(FAKE_VER_PATCH);
+ auto variant_length = VARIANT_NAME.length();
+ wr_byte(static_cast<byte>(variant_length));
+ for (auto i = 0U; i < variant_length; i++) {
+ save_xor_byte = 0;
+ wr_byte(VARIANT_NAME[i]);
+ }
+
save_xor_byte = 0;
+ wr_byte(H_VER_MAJOR);
+ wr_byte(H_VER_MINOR);
+ wr_byte(H_VER_PATCH);
+ wr_byte(H_VER_EXTRA);
byte tmp8u = (byte)Rand_external(256);
wr_byte(tmp8u);
v_stamp = 0L;
x_stamp = 0L;
-
- wr_byte(H_VER_EXTRA);
- wr_byte(H_VER_PATCH);
- wr_byte(H_VER_MINOR);
- wr_byte(H_VER_MAJOR);
+
wr_u32b(w_ptr->sf_system);
wr_u32b(w_ptr->sf_when);
wr_u16b(w_ptr->sf_lives);
-#include "object-enchant/object-smith.h"
-#include "object-enchant/smith-info.h"
-#include "object-enchant/smith-tables.h"
-#include "object-enchant/smith-types.h"
+#include "smith/object-smith.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/tr-flags.h"
#include "object-enchant/tr-types.h"
#include "perception/object-perception.h"
#include "player-base/player-class.h"
#include "player-info/smith-data-type.h"
+#include "smith/smith-info.h"
+#include "smith/smith-tables.h"
+#include "smith/smith-types.h"
#include "system/object-type-definition.h"
#include "system/player-type-definition.h"
-#include "object-enchant/smith-info.h"
-#include "object-enchant/smith-types.h"
+#include "smith/smith-info.h"
#include "object-enchant/tr-types.h"
#include "object/object-flags.h"
+#include "smith/smith-types.h"
#include "sv-definition/sv-weapon-types.h"
#include "system/object-type-definition.h"
#include "system/player-type-definition.h"
bool ActivationSmithInfo::can_give_smith_effect(const object_type *o_ptr) const
{
- if (o_ptr->is_artifact() || o_ptr->smith_act_idx.has_value())
- {
+ if (o_ptr->is_artifact() || o_ptr->smith_act_idx.has_value()) {
return false;
}
-#include "object-enchant/smith-tables.h"
+#include "smith/smith-tables.h"
#include "artifact/random-art-effects.h"
-#include "object-enchant/object-smith.h"
-#include "object-enchant/smith-info.h"
-#include "object-enchant/smith-types.h"
#include "object-enchant/tr-flags.h"
#include "object-enchant/tr-types.h"
+#include "smith/object-smith.h"
+#include "smith/smith-info.h"
+#include "smith/smith-types.h"
#include <memory>
#include <unordered_map>
GAME_TEXT m_name[MAX_NLEN];
sn = 0;
- if (none_bits(r_ptr->flags1, RF1_NEVER_MOVE)) {
+ if (r_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE)) {
for (DIRECTION i = 0; i < 8; i++) {
POSITION y = yy + ddy_ddd[i];
POSITION x = xx + ddx_ddd[i];
-#include "dungeon/dungeon-flag-types.h"
+#include "spell-kind/spells-lite.h"
+#include "dungeon/dungeon-flag-types.h"
#include "dungeon/dungeon.h"
+#include "effect/attribute-types.h"
#include "effect/effect-characteristics.h"
#include "effect/effect-processor.h"
#include "floor/cave.h"
-#include "floor/geometry.h"
#include "floor/floor-util.h"
+#include "floor/geometry.h"
#include "game-option/map-screen-options.h"
#include "grid/feature.h"
#include "grid/grid.h"
#include "monster/monster-update.h"
#include "player/special-defense-types.h"
#include "spell-kind/spells-launcher.h"
-#include "spell-kind/spells-lite.h"
-#include "effect/attribute-types.h"
#include "system/floor-type-definition.h"
#include "system/grid-type-definition.h"
#include "system/monster-race-definition.h"
monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
update_monster(player_ptr, g_ptr->m_idx, false);
- if (r_ptr->flags2 & (RF2_STUPID))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::STUPID))
chance = 10;
- if (r_ptr->flags2 & (RF2_SMART))
+ if (r_ptr->behavior_flags.has(MonsterBehaviorType::SMART))
chance = 100;
if (monster_csleep_remaining(m_ptr) && (randint0(100) < chance)) {
* properly.
* This leaves only a check for 6 bounding walls!
*/
- if (in_bounds(floor_ptr, y, x) && pass_bold(floor_ptr, y, x) && (next_to_walls_adj(floor_ptr, y, x, pass_bold) == 6)
- && (next_to_open(floor_ptr, y, x, pass_bold) <= 1))
+ if (in_bounds(floor_ptr, y, x) && pass_bold(floor_ptr, y, x) && (next_to_walls_adj(floor_ptr, y, x, pass_bold) == 6) && (next_to_open(floor_ptr, y, x, pass_bold) <= 1))
return;
}
* @param x 指定X座標
* @return 射線を通すならばtrueを返す。
*/
-static bool cave_pass_dark_bold(floor_type *floor_ptr, POSITION y, POSITION x) { return cave_has_flag_bold(floor_ptr, y, x, FloorFeatureType::PROJECT); }
+static bool cave_pass_dark_bold(floor_type *floor_ptr, POSITION y, POSITION x)
+{
+ return cave_has_flag_bold(floor_ptr, y, x, FloorFeatureType::PROJECT);
+}
/*!
* @brief (y,x) が暗くすべきマスなら points に加える
#include "core/window-redrawer.h"
#include "effect/effect-characteristics.h"
#include "effect/effect-processor.h"
-#include "monster-attack/monster-attack-util.h"
+#include "monster-attack/monster-attack-player.h"
#include "monster-race/monster-race.h"
#include "player-base/player-class.h"
#include "player-info/spell-hex-data-type.h"
}
}
-SpellHex::SpellHex(PlayerType *player_ptr, monap_type *monap_ptr)
+SpellHex::SpellHex(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
: player_ptr(player_ptr)
, monap_ptr(monap_ptr)
{
REVENGE = 2,
};
-struct monap_type;
+class MonsterAttackPlayer;
class PlayerType;
struct spell_hex_data_type;
class SpellHex {
public:
SpellHex(PlayerType *player_ptr);
- SpellHex(PlayerType *player_ptr, monap_type *monap_ptr);
+ SpellHex(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr);
virtual ~SpellHex() = default;
bool stop_spells_with_selection();
private:
PlayerType *player_ptr;
std::vector<int> casting_spells;
- monap_type *monap_ptr = nullptr;
+ MonsterAttackPlayer *monap_ptr = nullptr;
std::shared_ptr<spell_hex_data_type> spell_hex_data;
std::tuple<bool, bool, char> select_spell_stopping(char *out_val);
void put_version(char *buf)
{
- if (IS_ALPHA_VERSION) {
- sprintf(buf, _("変愚蛮怒 %d.%d.%dAlpha%d", "Hengband %d.%d.%dAlpha%d"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH, H_VER_EXTRA);
+ std::string_view expr;
+ switch (VERSION_STATUS) {
+ case VersionStatusType::ALPHA:
+ expr = "Alpha";
+ break;
+ case VersionStatusType::BETA:
+ expr = "Beta";
+ break;
+ case VersionStatusType::RELEASE_CANDIDATE:
+ expr = "RC";
+ break;
+ case VersionStatusType::RELEASE:
+ expr = "";
+ break;
+ default:
+ throw("Invalid version status was specified!");
+ }
+
+ if (VERSION_STATUS != VersionStatusType::RELEASE) {
+ sprintf(buf, _("変愚蛮怒 %d.%d.%d%s%d", "Hengband %d.%d.%d%s%d"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH, expr.data(), H_VER_EXTRA);
} else {
concptr mode = IS_STABLE_VERSION ? _("安定版", "Stable") : _("開発版", "Developing");
sprintf(buf, _("変愚蛮怒 %d.%d.%d.%d(%s)", "Hengband %d.%d.%d.%d(%s)"), H_VER_MAJOR, H_VER_MINOR, H_VER_PATCH, H_VER_EXTRA, mode);
#pragma once
#include <stdint.h>
+#include <string>
-#define VERSION_NAME "Hengband" /*!< バリアント名称 / Name of the version/variant */
+constexpr std::string_view VARIANT_NAME("Hengband");
+
+constexpr std::string_view ROOT_VARIANT_NAME("Hengband");
/*!
- * @brief セーブファイル上のバージョン定義(メジャー番号) / "Savefile Version Number" for Hengband 1.1.1 and later
- * @details
- * 当面FAKE_VER_*を参照しておく。
- * <pre>
- * Program Version of Hengband version is
- * "(H_VER_MAJOR).(H_VER_MINOR).(H_VER_PATCH).(H_VER_EXTRA)".
- * Upper compatibility is always guaranteed when it is more than 1.0.0 .
- * </pre>
+ * @brief セーブファイル上のバージョン定義 / "Savefile Version Number" for Hengband
+ * @details v1.1.1以上にのみ適用
*/
-#define H_VER_MAJOR 3 //!< ゲームのバージョン定義(メジャー番号)
-#define H_VER_MINOR 0 //!< ゲームのバージョン定義(マイナー番号)
-#define H_VER_PATCH 0 //!< ゲームのバージョン定義(パッチ番号)
-#define H_VER_EXTRA 51 //!< ゲームのバージョン定義(エクストラ番号)
+#define H_VER_MAJOR 3 //!< ゲームのバージョン定義(メジャー番号)
+#define H_VER_MINOR 0 //!< ゲームのバージョン定義(マイナー番号)
+#define H_VER_PATCH 0 //!< ゲームのバージョン定義(パッチ番号)
+#define H_VER_EXTRA 52 //!< ゲームのバージョン定義(エクストラ番号)
/*!
* @brief セーブファイルのバージョン(3.0.0から導入)
*/
-constexpr uint32_t SAVEFILE_VERSION = 10;
+constexpr uint32_t SAVEFILE_VERSION = 11;
/*!
* @brief バージョンが開発版が安定版かを返す(廃止予定)
*/
-#define IS_STABLE_VERSION (H_VER_MINOR % 2 == 0 && H_VER_EXTRA == 0)
+constexpr bool IS_STABLE_VERSION = (H_VER_MINOR % 2 == 0 && H_VER_EXTRA == 0);
-/*!
- * @brief 状態がアルファ版かどうかを返す
- * @note アルファ版はエクストラ番号一定値までをアルファとし、一定まで進めて安定次第ベータ版、さらにそれも解除して無印版とする。
- */
-#define IS_ALPHA_VERSION 1
+enum class VersionStatusType {
+ ALPHA,
+ BETA,
+ RELEASE_CANDIDATE,
+ RELEASE,
+};
/*!
- * @brief ゲームのバージョン番号定義 / "Program Version Number" of the game
- * @details
- * 本FAKE_VERSIONそのものは未使用である。Zangと整合性を合わせるための疑似的処理のためFAKE_VER_MAJORは実値-10が該当のバージョン番号となる。
- * <pre>
- * FAKE_VER_MAJOR=1,2 were reserved for ZAngband version 1.x.x/2.x.x .
- * </pre>
+ * @brief バージョンの立ち位置
*/
-#define FAKE_VER_PLUS 10 //!< 偽バージョン番号としていくつ足すか
-#define FAKE_VER_MAJOR (H_VER_MAJOR + FAKE_VER_PLUS) //!< 偽バージョン番号定義(メジャー番号) */
-#define FAKE_VER_MINOR H_VER_MINOR //!< 偽バージョン番号定義(マイナー番号) */
-#define FAKE_VER_PATCH H_VER_PATCH //!< 偽バージョン番号定義(パッチ番号) */
-#define FAKE_VER_EXTRA H_VER_EXTRA //!< 偽バージョン番号定義(エクストラ番号) */
+constexpr VersionStatusType VERSION_STATUS = VersionStatusType::ALPHA;
void put_version(char *buf);
#include "monster-attack/monster-attack-types.h"
#include "monster-race/monster-aura-types.h"
#include "monster-race/race-ability-flags.h"
-#include "util/flag-group.h"
+#include "monster-race/race-behavior-flags.h"
+#include "monster-race/race-visual-flags.h"
#include "system/angband.h"
+#include "util/flag-group.h"
#include <string>
/*! モンスターが1ターンに攻撃する最大回数 (射撃を含む) / The maximum number of times a monster can attack in a turn (including SHOOT) */
BIT_FLAGS flagsr{}; //!< 耐性フラグ / Flags R (resistances info)
EnumClassFlagGroup<MonsterAbilityType> ability_flags; //!< 能力フラグ(魔法/ブレス) / Ability Flags
EnumClassFlagGroup<MonsterAuraType> aura_flags; //!< オーラフラグ / Aura Flags
+ EnumClassFlagGroup<MonsterBehaviorType> behavior_flags; //!< 能力フラグ(習性)
+ EnumClassFlagGroup<MonsterVisualType> visual_flags; //!< 能力フラグ(シンボル) / Symbol Flags
monster_blow blow[MAX_NUM_BLOWS]{}; //!< 打撃能力定義 / Up to four blows per round
MONRACE_IDX reinforce_id[6]{}; //!< 指定護衛モンスター種族ID(6種まで)
DICE_NUMBER reinforce_dd[6]{}; //!< 指定護衛数ダイス数
uint32_t r_flagsr{}; //!< 見た耐性フラグ / Observed racial resistance flags
EnumClassFlagGroup<MonsterAbilityType> r_ability_flags; //!< 見た能力フラグ(魔法/ブレス) / Observed racial ability flags
EnumClassFlagGroup<MonsterAuraType> r_aura_flags; //!< 見た能力フラグ(オーラ) / Observed aura flags
+ EnumClassFlagGroup<MonsterBehaviorType> r_behavior_flags; //!< 見た能力フラグ(習性) / Observed racial attr flags
PLAYER_LEVEL defeat_level{}; //!< 倒したレベル(ユニーク用) / player level at which defeated this race
REAL_TIME defeat_time{}; //!< 倒した時間(ユニーク用) / time at which defeated this race
PERCENTAGE cur_hp_per{}; //!< 生成時現在HP率(%)
#include "artifact/random-art-effects.h"
#include "monster-race/monster-race.h"
#include "object-enchant/object-curse.h"
-#include "object-enchant/object-smith.h"
#include "object-enchant/special-object-flags.h"
#include "object-enchant/tr-types.h"
#include "object-enchant/trc-types.h"
#include "object-enchant/trg-types.h"
#include "object/object-flags.h"
#include "object/object-kind.h"
+#include "smith/object-smith.h"
#include "sv-definition/sv-armor-types.h"
#include "sv-definition/sv-lite-types.h"
#include "sv-definition/sv-other-types.h"
if (monster_confused_remaining(m_ptr)) {
if (randint0(100) < 75)
dir = ddd[randint0(8)];
- } else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
+ } else if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25) && (randint0(100) < 50))
dir = ddd[randint0(8)];
- else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
+ else if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && (randint0(100) < 25))
dir = ddd[randint0(8)];
}
dir = (DIRECTION)code;
*dp = (DIRECTION)code;
- concptr prompt
- = under ? _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ") : _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
+ concptr prompt = under ? _("方向 ('.'足元, ESCで中断)? ", "Direction ('.' at feet, Escape to cancel)? ") : _("方向 (ESCで中断)? ", "Direction (Escape to cancel)? ");
while (!dir) {
char ch;
if (!get_com(prompt, &ch, true))
if (monster_confused_remaining(m_ptr)) {
if (randint0(100) < 75)
dir = ddd[randint0(8)];
- } else if ((r_ptr->flags1 & RF1_RAND_50) && (r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 50))
+ } else if (r_ptr->behavior_flags.has_all_of({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 }) && (randint0(100) < 50))
dir = ddd[randint0(8)];
- else if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 25))
+ else if (r_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && (randint0(100) < 25))
dir = ddd[randint0(8)];
}
*/
int16_t randnor(int mean, int stand)
{
+ if (stand <= 0) {
+ return static_cast<int16_t>(mean);
+ }
std::normal_distribution<> d(mean, stand);
auto result = std::round(d(w_ptr->rng));
return static_cast<int16_t>(result);
}
}
- /* Cursor Update -- Erase old Cursor */
+ /* Hide the hardware cursor while drawing */
else {
/* Cursor will be invisible */
- if (scr->cu || !scr->cv) {
- /* Make the cursor invisible */
- term_xtra(TERM_XTRA_SHAPE, 0);
- }
+ term_xtra(TERM_XTRA_SHAPE, 0);
}
/* Something to update */
/* Cursor Update -- Show new Cursor */
else {
- /* The cursor is useless, hide it */
if (scr->cu) {
/* Paranoia -- Put the cursor NEAR where it belongs */
(void)((*Term->curs_hook)(w - 1, scr->cy));
-
- /* Make the cursor invisible */
- /* term_xtra(TERM_XTRA_SHAPE, 0); */
- }
-
- /* The cursor is invisible, hide it */
- else if (!scr->cv) {
- /* Paranoia -- Put the cursor where it belongs */
- (void)((*Term->curs_hook)(scr->cx, scr->cy));
-
- /* Make the cursor invisible */
- /* term_xtra(TERM_XTRA_SHAPE, 0); */
- }
-
- /* The cursor is visible, display it correctly */
- else {
+ } else {
/* Put the cursor where it belongs */
(void)((*Term->curs_hook)(scr->cx, scr->cy));
-
- /* Make the cursor visible */
- term_xtra(TERM_XTRA_SHAPE, 1);
}
}
/* Actually flush the output */
term_xtra(TERM_XTRA_FRESH, 0);
+
+ if (!Term->soft_cursor && !scr->cu && scr->cv) {
+ /* The cursor is visible, display it correctly */
+ term_xtra(TERM_XTRA_SHAPE, 1);
+ }
+
return 0;
}
if (attack_numbers > 0) {
hooked_roff(_("。", ". "));
- } else if (lore_ptr->flags1 & RF1_NEVER_BLOW) {
+ } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) {
hooked_roff(format(_("%^sは物理的な攻撃方法を持たない。", "%^s has no physical attacks. "), Who::who(lore_ptr->msex)));
} else {
hooked_roff(format(_("%s攻撃については何も知らない。", "Nothing is known about %s attack. "), Who::whose(lore_ptr->msex)));
}
#ifdef JP
- if (lore_ptr->flags2 & (RF2_SMART))
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::SMART))
hook_c_roff(TERM_YELLOW, "的確に");
hooked_roff("魔法を使うことができ、");
#else
hooked_roff(" magical, casting spells");
- if (lore_ptr->flags2 & RF2_SMART)
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::SMART))
hook_c_roff(TERM_YELLOW, " intelligently");
#endif
lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
}
- if (lore_ptr->flags2 & RF2_OPEN_DOOR) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::OPEN_DOOR)) {
lore_ptr->vp[lore_ptr->vn] = _("ドアを開ける", "open doors");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
- if (lore_ptr->flags2 & RF2_BASH_DOOR) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::BASH_DOOR)) {
lore_ptr->vp[lore_ptr->vn] = _("ドアを打ち破る", "bash down doors");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
- if (lore_ptr->flags2 & RF2_MOVE_BODY) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::MOVE_BODY)) {
lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを押しのける", "push past weaker monsters");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
- if (lore_ptr->flags2 & RF2_KILL_BODY) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_BODY)) {
lore_ptr->vp[lore_ptr->vn] = _("弱いモンスターを倒す", "destroy weaker monsters");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
- if (lore_ptr->flags2 & RF2_TAKE_ITEM) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM)) {
lore_ptr->vp[lore_ptr->vn] = _("アイテムを拾う", "pick up objects");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
- if (lore_ptr->flags2 & RF2_KILL_ITEM) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::KILL_ITEM)) {
lore_ptr->vp[lore_ptr->vn] = _("アイテムを壊す", "destroy objects");
lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
}
void display_random_move(lore_type *lore_ptr)
{
- if (((lore_ptr->flags1 & RF1_RAND_50) == 0) && ((lore_ptr->flags1 & RF1_RAND_25) == 0))
+ if (lore_ptr->behavior_flags.has_none_of({ MonsterBehaviorType::RAND_MOVE_50, MonsterBehaviorType::RAND_MOVE_25 }))
return;
- if ((lore_ptr->flags1 & RF1_RAND_50) && (lore_ptr->flags1 & RF1_RAND_25)) {
+ if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50) && lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
hooked_roff(_("かなり", " extremely"));
- } else if (lore_ptr->flags1 & RF1_RAND_50) {
+ } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_50)) {
hooked_roff(_("幾分", " somewhat"));
- } else if (lore_ptr->flags1 & RF1_RAND_25) {
+ } else if (lore_ptr->behavior_flags.has(MonsterBehaviorType::RAND_MOVE_25)) {
hooked_roff(_("少々", " a bit"));
}
void display_monster_never_move(lore_type *lore_ptr)
{
- if ((lore_ptr->flags1 & RF1_NEVER_MOVE) == 0)
+ if (lore_ptr->behavior_flags.has_not(MonsterBehaviorType::NEVER_MOVE))
return;
if (lore_ptr->old) {
c = f_ptr->x_char[F_LIT_DARK];
}
} else if (darkened_grid(player_ptr, g_ptr) && !player_ptr->blind) {
- if (f_ptr->flags.has_all_of({FloorFeatureType::LOS, FloorFeatureType::PROJECT})) {
+ if (f_ptr->flags.has_all_of({ FloorFeatureType::LOS, FloorFeatureType::PROJECT })) {
feat = (view_unsafe_grids && (g_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
f_ptr = &f_info[feat];
a = f_ptr->x_attr[F_LIT_STANDARD];
monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
feat_priority = 30;
if (player_ptr->hallucinated) {
- if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
+ if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
/* Do nothing */
} else {
image_monster(ap, cp);
a = r_ptr->x_attr;
c = r_ptr->x_char;
- if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_SHAPECHANGER | RF1_ATTR_CLEAR | RF1_ATTR_MULTI | RF1_ATTR_SEMIRAND))) {
+ if (r_ptr->visual_flags.has_none_of({ MonsterVisualType::CLEAR, MonsterVisualType::SHAPECHANGER, MonsterVisualType::CLEAR_COLOR, MonsterVisualType::MULTI_COLOR, MonsterVisualType::RANDOM_COLOR })) {
*ap = a;
*cp = c;
set_term_color(player_ptr, y, x, ap, cp);
return;
}
- if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) {
+ if (r_ptr->visual_flags.has_all_of({ MonsterVisualType::CLEAR, MonsterVisualType::CLEAR_COLOR })) {
set_term_color(player_ptr, y, x, ap, cp);
return;
}
- if ((r_ptr->flags1 & RF1_ATTR_CLEAR) && (*ap != TERM_DARK) && !use_graphics) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR_COLOR) && (*ap != TERM_DARK) && !use_graphics) {
/* Do nothing */
- } else if ((r_ptr->flags1 & RF1_ATTR_MULTI) && !use_graphics) {
- if (r_ptr->flags2 & RF2_ATTR_ANY)
+ } else if (r_ptr->visual_flags.has(MonsterVisualType::MULTI_COLOR) && !use_graphics) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::ANY_COLOR))
*ap = randint1(15);
else
switch (randint1(7)) {
*ap = TERM_GREEN;
break;
}
- } else if ((r_ptr->flags1 & RF1_ATTR_SEMIRAND) && !use_graphics) {
+ } else if (r_ptr->visual_flags.has(MonsterVisualType::RANDOM_COLOR) && !use_graphics) {
*ap = g_ptr->m_idx % 15 + 1;
} else {
*ap = a;
}
- if ((r_ptr->flags1 & RF1_CHAR_CLEAR) && (*cp != ' ') && !use_graphics) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR) && (*cp != ' ') && !use_graphics) {
set_term_color(player_ptr, y, x, ap, cp);
return;
}
- if (r_ptr->flags1 & RF1_SHAPECHANGER) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::SHAPECHANGER)) {
if (use_graphics) {
monster_race *tmp_r_ptr = &r_info[randint1(r_info.size() - 1)];
*cp = tmp_r_ptr->x_char;
*/
static concptr attr_to_text(monster_race *r_ptr)
{
- if (any_bits(r_ptr->flags1, RF1_ATTR_CLEAR)) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::CLEAR_COLOR)) {
return _("透明な", "Clear");
}
- if (any_bits(r_ptr->flags1, RF1_ATTR_MULTI)) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::MULTI_COLOR)) {
return _("万色の", "Multi");
}
- if (any_bits(r_ptr->flags1, RF1_ATTR_SEMIRAND)) {
+ if (r_ptr->visual_flags.has(MonsterVisualType::RANDOM_COLOR)) {
return _("準ランダムな", "S.Rand");
}
*/
void wiz_create_feature(PlayerType *player_ptr)
{
+ int f_val1, f_val2;
POSITION y, x;
if (!tgt_pt(player_ptr, &x, &y))
return;
grid_type *g_ptr;
g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
- static int prev_feat = 0;
- char tmp_val[160];
- sprintf(tmp_val, "%d", prev_feat);
- if (!get_string(_("地形: ", "Feature: "), tmp_val, 3))
+ f_val1 = g_ptr->feat;
+ if (!get_value(_("実地形ID", "FeatureID"), 0, f_info.size() - 1, &f_val1)) {
return;
+ }
- FEAT_IDX tmp_feat = (FEAT_IDX)atoi(tmp_val);
- if (tmp_feat < 0)
- tmp_feat = 0;
- else if (tmp_feat >= static_cast<FEAT_IDX>(f_info.size()))
- tmp_feat = static_cast<FEAT_IDX>(f_info.size()) - 1;
-
- static int prev_mimic = 0;
- sprintf(tmp_val, "%d", prev_mimic);
-
- if (!get_string(_("地形 (mimic): ", "Feature (mimic): "), tmp_val, 3))
+ f_val2 = f_val1;
+ if (!get_value(_("偽装地形ID", "FeatureID"), 0, f_info.size() - 1, &f_val2)) {
return;
+ }
- FEAT_IDX tmp_mimic = (FEAT_IDX)atoi(tmp_val);
- if (tmp_mimic < 0)
- tmp_mimic = 0;
- else if (tmp_mimic >= static_cast<FEAT_IDX>(f_info.size()))
- tmp_mimic = static_cast<FEAT_IDX>(f_info.size()) - 1;
- cave_set_feat(player_ptr, y, x, tmp_feat);
- g_ptr->mimic = (int16_t)tmp_mimic;
+ cave_set_feat(player_ptr, y, x, f_val1);
+ g_ptr->mimic = (int16_t)f_val2;
feature_type *f_ptr;
f_ptr = &f_info[g_ptr->get_feat_mimic()];
note_spot(player_ptr, y, x);
lite_spot(player_ptr, y, x);
player_ptr->update |= PU_FLOW;
- prev_feat = tmp_feat;
- prev_mimic = tmp_mimic;
+
}
/*
#include "monster-floor/monster-generator.h"
#include "monster-floor/monster-summon.h"
#include "monster-floor/place-monster-types.h"
-#include "monster-race/race-ability-flags.h"
#include "monster-race/monster-race.h"
+#include "monster-race/race-ability-flags.h"
#include "mutation/mutation-processor.h"
-#include "object-enchant/object-smith.h"
#include "player-base/player-class.h"
#include "player-info/bluemage-data-type.h"
#include "player-info/smith-data-type.h"
+#include "smith/object-smith.h"
#include "spell-kind/spells-launcher.h"
#include "spell-kind/spells-random.h"
#include "spell-kind/spells-teleport.h"
#include "spell/spells-status.h"
#include "spell/summon-types.h"
#include "system/floor-type-definition.h"
-#include "system/player-type-definition.h"
#include "system/monster-race-definition.h"
+#include "system/player-type-definition.h"
#include "target/grid-selector.h"
#include "target/target-checker.h"
#include "target/target-getter.h"
{
if (r_idx <= 0) {
int val = 1;
- if(!get_value("MonsterID", 1, r_info.size() - 1, &val)) {
+ if (!get_value("MonsterID", 1, r_info.size() - 1, &val)) {
return;
}
r_idx = static_cast<MONRACE_IDX>(val);