Skip to content

Commit

Permalink
Merge branch 'develop' into macos-develop
Browse files Browse the repository at this point in the history
  • Loading branch information
backwardsEric committed Dec 3, 2024
2 parents 83c73bf + 2568900 commit dd5972b
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 105 deletions.
12 changes: 6 additions & 6 deletions src/floor/floor-object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,18 @@ bool make_object(PlayerType *player_ptr, ItemEntity *j_ptr, BIT_FLAGS mode, std:
}
}

if (any_bits(mode, AM_GOOD) && !get_obj_index_hook) {
get_obj_index_hook = kind_is_good;
if (any_bits(mode, AM_GOOD) && !select_baseitem_id_hook) {
select_baseitem_id_hook = kind_is_good;
}

auto &table = BaseitemAllocationTable::get_instance();
if (get_obj_index_hook) {
if (select_baseitem_id_hook) {
table.prepare_allocation();
}

const auto bi_id = get_obj_index(&floor, base, mode);
if (get_obj_index_hook) {
get_obj_index_hook = nullptr;
const auto bi_id = floor.select_baseitem_id(base, mode);
if (select_baseitem_id_hook) {
select_baseitem_id_hook = nullptr;
table.prepare_allocation();
}

Expand Down
14 changes: 7 additions & 7 deletions src/monster-floor/special-death-switcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ static void on_dead_raal(PlayerType *player_ptr, MonsterDeath *md_ptr)
auto *q_ptr = &forge;
q_ptr->wipe();
if ((floor_ptr->dun_level > 49) && one_in_(5)) {
get_obj_index_hook = kind_is_good_book;
select_baseitem_id_hook = kind_is_good_book;
} else {
get_obj_index_hook = kind_is_book;
select_baseitem_id_hook = kind_is_book;
}

(void)make_object(player_ptr, q_ptr, md_ptr->mo_mode);
Expand Down Expand Up @@ -312,22 +312,22 @@ static bool make_equipment(PlayerType *player_ptr, ItemEntity *q_ptr, const BIT_
* @brief 死亡時ドロップとしてランダムアーティファクトのみを生成する
* @param player_ptr プレイヤーへの参照ポインタ
* @param md_ptr モンスター撃破構造体への参照ポインタ
* @param object_hook_pf アイテム種別指定、特になければnullptrで良い
* @param hook_pf アイテム種別指定、特になければnullptrで良い
* @return なし
* @details
* 最初のアイテム生成でいきなり☆が生成された場合を除き、中途半端な☆ (例:呪われている)は生成しない.
* このルーチンで★は生成されないので、★生成フラグのキャンセルも不要
*/
static void on_dead_random_artifact(PlayerType *player_ptr, MonsterDeath *md_ptr, bool (*object_hook_pf)(short bi_id))
static void on_dead_random_artifact(PlayerType *player_ptr, MonsterDeath *md_ptr, bool (*hook_pf)(short bi_id))
{
ItemEntity forge;
auto *q_ptr = &forge;
auto is_object_hook_null = object_hook_pf == nullptr;
auto is_object_hook_null = hook_pf == nullptr;
auto drop_mode = md_ptr->mo_mode | AM_NO_FIXED_ART;
while (true) {
// make_object() の中でアイテム種別をキャンセルしている
// よってこのwhileループ中へ入れないと、引数で指定していない種別のアイテムが選ばれる可能性がある
get_obj_index_hook = object_hook_pf;
select_baseitem_id_hook = hook_pf;
if (!make_equipment(player_ptr, q_ptr, drop_mode, is_object_hook_null)) {
continue;
}
Expand Down Expand Up @@ -372,7 +372,7 @@ static void drop_specific_item_on_dead(PlayerType *player_ptr, MonsterDeath *md_
ItemEntity forge;
auto *q_ptr = &forge;
q_ptr->wipe();
get_obj_index_hook = object_hook_pf;
select_baseitem_id_hook = object_hook_pf;
(void)make_object(player_ptr, q_ptr, md_ptr->mo_mode);
(void)drop_near(player_ptr, q_ptr, -1, md_ptr->md_y, md_ptr->md_x);
}
Expand Down
10 changes: 5 additions & 5 deletions src/room/rooms-special.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ bool build_type15(PlayerType *player_ptr, DungeonData *dd_ptr)
}

/* Place a potion */
get_obj_index_hook = kind_is_potion;
select_baseitem_id_hook = kind_is_potion;
place_object(player_ptr, yval, xval, AM_NO_FIXED_ART);
floor.get_grid({ yval, xval }).info |= CAVE_ICKY;
} break;
Expand Down Expand Up @@ -208,14 +208,14 @@ bool build_type15(PlayerType *player_ptr, DungeonData *dd_ptr)

/* Place two potions */
if (one_in_(2)) {
get_obj_index_hook = kind_is_potion;
select_baseitem_id_hook = kind_is_potion;
place_object(player_ptr, yval, xval - 1, AM_NO_FIXED_ART);
get_obj_index_hook = kind_is_potion;
select_baseitem_id_hook = kind_is_potion;
place_object(player_ptr, yval, xval + 1, AM_NO_FIXED_ART);
} else {
get_obj_index_hook = kind_is_potion;
select_baseitem_id_hook = kind_is_potion;
place_object(player_ptr, yval - 1, xval, AM_NO_FIXED_ART);
get_obj_index_hook = kind_is_potion;
select_baseitem_id_hook = kind_is_potion;
place_object(player_ptr, yval + 1, xval, AM_NO_FIXED_ART);
}

Expand Down
2 changes: 1 addition & 1 deletion src/store/store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ static void store_create(PlayerType *player_ptr, short fix_k_idx, StoreSaleType
DEPTH level;
if (store_num == StoreSaleType::BLACK) {
level = 25 + randint0(25);
bi_id = get_obj_index(player_ptr->current_floor_ptr, level, 0x00000000);
bi_id = player_ptr->current_floor_ptr->select_baseitem_id(level, 0x00000000);
if (bi_id == 0) {
continue;
}
Expand Down
45 changes: 43 additions & 2 deletions src/system/alloc-entries.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "system/alloc-entries.h"
#include "floor/floor-base-definitions.h"
#include "object-enchant/item-apply-magic.h"
#include "system/baseitem/baseitem-definition.h"
#include "system/baseitem/baseitem-list.h"
#include "system/monster-race-info.h"
Expand Down Expand Up @@ -236,6 +237,19 @@ BaseitemAllocationEntry &BaseitemAllocationTable::get_entry(int index)
return this->entries.at(index);
}

short BaseitemAllocationTable::draw_lottery(int level, uint32_t mode, int count) const
{
const auto prob_table = this->make_table(level, mode);
if (prob_table.empty()) {
return 0;
}

std::vector<int> result;
ProbabilityTable<int>::lottery(std::back_inserter(result), prob_table, count);
const auto it = std::max_element(result.begin(), result.end(), [this](int a, int b) { return this->order_level(a, b); });
return this->get_entry(*it).index;
}

bool BaseitemAllocationTable::order_level(int index1, int index2) const
{
const auto &entry1 = this->entries.at(index1);
Expand All @@ -245,15 +259,42 @@ bool BaseitemAllocationTable::order_level(int index1, int index2) const

/*!
* @brief オブジェクト生成テーブルに生成制約を加える
* @todo get_obj_index_hook グローバル関数ポインタは引数化して除去する
* @todo select_baseitem_id_hook グローバル関数ポインタは引数化して除去する
*/
void BaseitemAllocationTable::prepare_allocation()
{
for (auto &entry : this->entries) {
if (!get_obj_index_hook || (*get_obj_index_hook)(entry.index)) {
if (!select_baseitem_id_hook || (*select_baseitem_id_hook)(entry.index)) {
entry.prob2 = entry.prob1;
} else {
entry.prob2 = 0;
}
}
}

ProbabilityTable<int> BaseitemAllocationTable::make_table(int level, uint32_t mode) const
{
ProbabilityTable<int> prob_table;
for (size_t i = 0; i < this->size(); i++) {
const auto &entry = this->get_entry(i);
if (entry.level > level) {
break;
}

if (any_bits(mode, AM_FORBID_CHEST) && entry.is_chest()) {
continue;
}

if (any_bits(mode, AM_GOLD) && !entry.is_gold()) {
continue;
}

if (none_bits(mode, AM_GOLD) && entry.is_gold()) {
continue;
}

prob_table.entry_item(i, entry.prob2);
}

return prob_table;
}
4 changes: 4 additions & 0 deletions src/system/alloc-entries.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include "util/probability-table.h"
#include <vector>

enum class MonraceId : short;
Expand Down Expand Up @@ -93,6 +94,7 @@ class BaseitemAllocationTable {
size_t size() const;
const BaseitemAllocationEntry &get_entry(int index) const;
BaseitemAllocationEntry &get_entry(int index);
short draw_lottery(int level, uint32_t mode, int count) const;
bool order_level(int index1, int index2) const;

void prepare_allocation();
Expand All @@ -101,4 +103,6 @@ class BaseitemAllocationTable {
static BaseitemAllocationTable instance;
BaseitemAllocationTable() = default;
std::vector<BaseitemAllocationEntry> entries;

ProbabilityTable<int> make_table(int level, uint32_t mode) const;
};
49 changes: 47 additions & 2 deletions src/system/floor-type-definition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "game-option/birth-options.h"
#include "monster/monster-timed-effects.h"
#include "object-enchant/item-apply-magic.h"
#include "system/alloc-entries.h"
#include "system/angband-system.h"
#include "system/artifact-type-definition.h"
#include "system/baseitem/baseitem-definition.h"
Expand Down Expand Up @@ -287,7 +288,7 @@ ItemEntity FloorType::make_gold(std::optional<BaseitemKey> bi_key) const
item = ItemEntity(*bi_key);
} else {
const auto level = this->object_level <= 0 ? 1 : this->object_level;
item = ItemEntity(get_obj_index(this, level, AM_GOLD));
item = ItemEntity(this->select_baseitem_id(level, AM_GOLD));
}

const auto base = item.get_baseitem_cost();
Expand All @@ -303,13 +304,36 @@ ItemEntity FloorType::make_gold(std::optional<BaseitemKey> bi_key) const
*/
std::optional<ItemEntity> FloorType::try_make_instant_artifact() const
{
if (!this->is_in_underground() || (get_obj_index_hook != nullptr)) {
if (!this->is_in_underground() || (select_baseitem_id_hook != nullptr)) {
return std::nullopt;
}

return ArtifactList::get_instance().try_make_instant_artifact(this->object_level);
}

/*!
* @brief アイテム生成テーブルからベースアイテムIDを取得する
* @param level_initial 生成基準階層 (天界や地獄の階層もそのまま渡ってくる)
* @param mode 生成モード
* @return 選ばれたベースアイテムID
*/
short FloorType::select_baseitem_id(int level_initial, uint32_t mode) const
{
auto level = level_initial;
if (level > MAX_DEPTH - 1) {
level = MAX_DEPTH - 1;
}

if ((level > 0) && this->get_dungeon_definition().flags.has_not(DungeonFeatureType::BEGINNER)) {
if (one_in_(CHANCE_BASEITEM_LEVEL_BOOST)) {
level = 1 + (level * MAX_DEPTH / randint1(MAX_DEPTH));
}
}

const auto &table = BaseitemAllocationTable::get_instance();
return table.draw_lottery(level, mode, decide_selection_count());
}

/*!
* @brief モンスターの時限ステータスリストを初期化する
* @details リストは逆順に走査し、死んでいるモンスターは初期化対象外とする
Expand Down Expand Up @@ -380,3 +404,24 @@ void FloorType::remove_mproc(short m_idx, MonsterTimedEffect mte)
this->mproc_list[mte][*mproc_idx] = this->mproc_list[mte][--this->mproc_max[mte]];
}
}

/*!
* @brief アイテムの抽選回数をランダムに決定する
* @return 抽選回数
* @details 40 % で1回、50 % で2回、10 % で3回.
* モンスターも同一ルーチンだが将来に亘って同一である保証はないので、アイテムはアイテムで定義する
*/
int FloorType::decide_selection_count()
{
auto count = 1;
const auto p = randint0(100);
if (p < 60) {
count++;
}

if (p < 10) {
count++;
}

return count;
}
4 changes: 4 additions & 0 deletions src/system/floor-type-definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,14 @@ class FloorType {

ItemEntity make_gold(std::optional<BaseitemKey> bi_key = std::nullopt) const;
std::optional<ItemEntity> try_make_instant_artifact() const;
short select_baseitem_id(int level_initial, uint32_t mode) const;

void reset_mproc();
void reset_mproc_max();
std::optional<int> get_mproc_index(short m_idx, MonsterTimedEffect mte);
void add_mproc(short m_idx, MonsterTimedEffect mte);
void remove_mproc(short m_idx, MonsterTimedEffect mte);

private:
static int decide_selection_count();
};
2 changes: 1 addition & 1 deletion src/system/system-variables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ init_flags_type init_flags; //!< @todo このグローバル変数何とかし
/*!
* Function hook to restrict "get_obj_index_prep()" function
*/
bool (*get_obj_index_hook)(short bi_id);
bool (*select_baseitem_id_hook)(short bi_id);
2 changes: 1 addition & 1 deletion src/system/system-variables.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ extern concptr ANGBAND_SYS;
extern concptr ANGBAND_KEYBOARD;
extern concptr ANGBAND_GRAF;

extern bool (*get_obj_index_hook)(short bi_id);
extern bool (*select_baseitem_id_hook)(short bi_id);
Loading

0 comments on commit dd5972b

Please sign in to comment.