Files
SergObsidian/PERSONAL PROJECTS/P2EP/pseudoCode/FUN_80015674 Update Entity Stats.md
2025-04-20 00:15:46 +05:00

6.5 KiB
Raw Blame History

Эта функция представляет собой систему управления игровыми объектами или характеристиками персонажа в игре на PS1. Вот детальный анализ:

🔍 Основное назначение

Функция выполняет:

  1. Обновление параметров объекта (персонажа, предмета или системы)
  2. Расчет характеристик на основе базовых значений и модификаторов
  3. Обработку двух режимов работы (нормальный и специальный через флаг 0x8000)

📌 Полная реконструкция на C

// Структура объекта игры (реконструкция)
typedef struct {
    uint32_t id;            // ID объекта + флаги (param_1)
    uint16_t type;          // Тип объекта
    uint16_t subtype;       // Подтип
    uint8_t base_stats[10]; // Базовые характеристики
    uint8_t modifiers[10];  // Модификаторы
    uint16_t calculated[8]; // Рассчитанные значения
    // ... другие поля ...
} GameEntity;

// Глобальные данные (реконструкция)
extern uint16_t DWORD_8006eb8c[]; // Таблицы характеристик
extern uint16_t DWORD_800830d0[]; // Базовая статистика

void UpdateEntityStats(GameEntity* target, GameEntity* source, int offset, bool apply_modifiers) 
{
    // Проверка специального флага
    if ((source->id & 0x8000) == 0) {
        // Нормальный режим -------------------------------------------------
        
        // 1. Поиск нужного объекта в массиве
        int entity_index = 0;
        GameEntity* current = source;
        while(entity_index < 7) {
            if (current->type == (source->id & 0x7FFF)) break;
            entity_index++;
            current = (GameEntity*)((char*)current + 0x54); // Следующий объект
        }

        // 2. Копирование базовых параметров
        if (!apply_modifiers) {
            memcpy(target, current, sizeof(GameEntity)); // Частичное копирование
        }

        // 3. Расчет комбинированных характеристик
        for (int i = 0; i < 5; i++) {
            // Среднее значение между базой и модификатором
            uint8_t combined = (current->base_stats[i] + 
                              (current->modifiers[i] + source->modifiers[i]) / 2) / 2;
            
            // Ограничение значений (макс 99)
            target->modifiers[i] = (combined > 99) ? 99 : combined;
        }

        // 4. Сложные расчеты характеристик
        int calculated_value = 
            (current->base_stats[9] * DWORD_8006eb8c[(current->type-1)*4] +
             current->modifiers[9] * DWORD_8006eb8c[(current->type-1)*4+1]) / 1000;
        
        // 5. Применение ограничений
        calculated_value += DWORD_800830d0[entity_index*0x54 + 2];
        target->calculated[0] = (calculated_value > 999) ? 999 : calculated_value;

        // 6. Обновление связанных объектов
        if (!apply_modifiers) {
            current->calculated[0] = target->calculated[0];
        }

        // ... аналогичные расчеты для других характеристик ...

    } else {
        // Специальный режим (по ID) ---------------------------------------
        
        uint16_t special_id = source->id & 0xFFF;
        
        // 1. Загрузка данных из специальной таблицы
        uint8_t* special_data = (uint8_t*)(0x80062b04 + special_id * 0x20);
        
        // 2. Инициализация объекта
        target->id = 9; // Специальный тип
        target->type = source->id | 0x8000; // Сохраняем флаг
        
        // 3. Копирование характеристик
        memcpy(target->modifiers, special_data + 1, 5);
        
        // 4. Расчет производных значений
        target->calculated[0] = *(uint16_t*)(0x80062b00 + special_id * 0x20 + 2);
        target->calculated[4] = special_data[0] + special_data[1] * 3;
        
        // ... дополнительные расчеты ...
    }
}

🔧 Технические особенности

  1. Два режима работы:

    • Нормальный (поиск по типу объекта)
    • Специальный (прямой доступ по ID с флагом 0x8000)
  2. Система характеристик:

    • Базовые значения
    • Модификаторы
    • Рассчитанные итоговые значения с ограничениями (например, макс. 999)
  3. Оптимизации PS1:

    • Фиксированные смещения (0x54, 0x20)
    • Работа с префиксом 0x80000000 (адресация KSEG0)

🌟 Что делает на практике?

  1. Для персонажей:

    • Пересчитывает HP/MP/статы на основе уровня и экипировки
    • Применяет временные модификаторы (баффы/дебаффы)
  2. Для предметов:

    • Обновляет параметры при экипировке
    • Рассчитывает комбинированные эффекты
  3. Для системных объектов:

    • Управляет специальными объектами через ID

📊 Структура данных

// Пример структуры объекта (0x54 байта)
struct {
    uint32_t id_flags;    // 0x00: ID + флаги
    uint16_t type;        // 0x04: Тип объекта
    uint16_t subtype;     // 0x06: Подтип
    uint8_t stats[10];    // 0x08: Основные характеристики
    uint16_t calculated[8]; // 0x12: Рассчитанные значения
    // ... другие поля ...
};

Эта функция — критически важная часть игровой логики, отвечающая за корректное обновление всех динамических параметров объектов в игре.