135 lines
6.5 KiB
Markdown
135 lines
6.5 KiB
Markdown
Эта функция представляет собой **систему управления игровыми объектами или характеристиками персонажа** в игре на PS1. Вот детальный анализ:
|
||
|
||
### 🔍 Основное назначение
|
||
Функция выполняет:
|
||
1. **Обновление параметров объекта** (персонажа, предмета или системы)
|
||
2. **Расчет характеристик** на основе базовых значений и модификаторов
|
||
3. **Обработку двух режимов работы** (нормальный и специальный через флаг 0x8000)
|
||
|
||
### 📌 Полная реконструкция на C
|
||
```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
|
||
|
||
### 📊 Структура данных
|
||
```c
|
||
// Пример структуры объекта (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: Рассчитанные значения
|
||
// ... другие поля ...
|
||
};
|
||
```
|
||
|
||
Эта функция — критически важная часть игровой логики, отвечающая за корректное обновление всех динамических параметров объектов в игре. |