Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==================== РЕАЛИЗАЦИЯ СИСТЕМЫ СЦЕН ====================
- // Создание сцены
- stock EventEngine:CreateScene(event_id, const name[], task_min, task_max, flags)
- {
- if (g_EventEngine_SceneCount >= MAX_SCENES)
- {
- printf("[EventEngine] Ошибка: Достигнут лимит сцен (%d)", MAX_SCENES);
- return EVENT_INVALID_VALUE;
- }
- new scene_id = g_EventEngine_SceneCount;
- g_EventEngine_Scenes[scene_id][E_SCENE_ID] = scene_id;
- g_EventEngine_Scenes[scene_id][E_SCENE_EVENT_ID] = event_id;
- format(g_EventEngine_Scenes[scene_id][E_SCENE_NAME], 32, name);
- g_EventEngine_Scenes[scene_id][E_SCENE_TASK_MIN] = task_min;
- g_EventEngine_Scenes[scene_id][E_SCENE_TASK_MAX] = task_max;
- g_EventEngine_Scenes[scene_id][E_SCENE_FLAGS] = flags;
- g_EventEngine_Scenes[scene_id][E_SCENE_ENTITY_COUNT] = 0;
- g_EventEngine_Scenes[scene_id][E_SCENE_ZONE_ID] = EVENT_INVALID_VALUE;
- g_EventEngine_Scenes[scene_id][E_SCENE_ACTIVE] = false;
- g_EventEngine_SceneCount++;
- printf("[EventEngine] Создана сцена '%s' (ID: %d, Задания: %d-%d)", name, scene_id, task_min, task_max);
- return scene_id;
- }
- // Добавление сущности в сцену
- stock EventEngine:AddSceneEntity(scene_id, E_SCENE_ENTITY_TYPE:type, Float:x, Float:y, Float:z, ...)
- {
- if (scene_id < 0 || scene_id >= g_EventEngine_SceneCount)
- return false;
- if (g_EventEngine_Scenes[scene_id][E_SCENE_ENTITY_COUNT] >= MAX_SCENE_ENTITIES)
- {
- printf("[EventEngine] Ошибка: Достигнут лимит сущностей в сцене %d", scene_id);
- return false;
- }
- new entity_index = g_EventEngine_Scenes[scene_id][E_SCENE_ENTITY_COUNT];
- new entity[E_SCENE_ENTITY];
- entity[E_ENTITY_TYPE] = _:type;
- entity[E_ENTITY_ID] = EVENT_INVALID_VALUE; // Будет установлен при активации
- entity[E_ENTITY_X] = x;
- entity[E_ENTITY_Y] = y;
- entity[E_ENTITY_Z] = z;
- // Обработка дополнительных параметров в зависимости от типа
- switch (type)
- {
- case SCENE_ENTITY_OBJECT:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // modelid
- entity[E_ENTITY_RX] = Float:getarg(4);
- entity[E_ENTITY_RY] = Float:getarg(5);
- entity[E_ENTITY_RZ] = Float:getarg(6);
- }
- case SCENE_ENTITY_VEHICLE:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // modelid
- entity[E_ENTITY_RZ] = Float:getarg(4); // rotation
- }
- case SCENE_ENTITY_NPC, SCENE_ENTITY_ACTOR:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // skin/model
- entity[E_ENTITY_RZ] = Float:getarg(4); // rotation
- }
- case SCENE_ENTITY_SOUND:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // sound name (через хэш)
- entity[E_ENTITY_RADIUS] = Float:getarg(4); // радиус звука
- }
- case SCENE_ENTITY_WEATHER:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // weather id
- }
- case SCENE_ENTITY_TIME:
- {
- entity[E_ENTITY_REFERENCE] = getarg(3); // hour
- entity[E_ENTITY_EXTRA_1] = getarg(4); // minute
- }
- case SCENE_ENTITY_ZONE:
- {
- entity[E_ENTITY_RADIUS] = Float:getarg(3); // радиус зоны
- }
- }
- // Копируем сущность в сцену
- g_EventEngine_Scenes[scene_id][E_SCENE_ENTITIES][entity_index] = entity;
- g_EventEngine_Scenes[scene_id][E_SCENE_ENTITY_COUNT]++;
- printf("[EventEngine] Добавлена сущность типа %d в сцену %d", _:type, scene_id);
- return true;
- }
- // Активация сцены для игрока
- stock EventEngine:ActivatePlayerScene(playerid, scene_id)
- {
- if (scene_id < 0 || scene_id >= g_EventEngine_SceneCount)
- return false;
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] >= MAX_PLAYER_SCENES)
- {
- printf("[EventEngine] Ошибка: У игрока %d достигнут лимит активных сцен", playerid);
- return false;
- }
- // Проверяем, не активирована ли уже сцена
- if (EventEngine:IsSceneActiveForPlayer(playerid, scene_id))
- return true;
- new scene[E_SCENE_DATA];
- scene = g_EventEngine_Scenes[scene_id];
- // Сохраняем исходные настройки игрока при первой активации сцены
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] == 0)
- {
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_WEATHER] = GetPlayerWeather(playerid);
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_TIME] = GetPlayerTime(playerid);
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_INTERIOR] = GetPlayerInterior(playerid);
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_WORLD] = GetPlayerVirtualWorld(playerid);
- }
- // Создаем сущности сцены
- for (new i = 0; i < scene[E_SCENE_ENTITY_COUNT]; i++)
- {
- new entity[E_SCENE_ENTITY] = scene[E_SCENE_ENTITIES][i];
- switch (E_SCENE_ENTITY_TYPE:entity[E_ENTITY_TYPE])
- {
- case SCENE_ENTITY_OBJECT:
- {
- new object_id = CreateDynamicObject(
- entity[E_ENTITY_REFERENCE],
- entity[E_ENTITY_X], entity[E_ENTITY_Y], entity[E_ENTITY_Z],
- entity[E_ENTITY_RX], entity[E_ENTITY_RY], entity[E_ENTITY_RZ],
- .worldid = playerid, // Индивидуальный мир для игрока
- .interiorid = GetPlayerInterior(playerid)
- );
- entity[E_ENTITY_ID] = object_id;
- }
- case SCENE_ENTITY_VEHICLE:
- {
- new vehicle_id = CreateVehicle(
- entity[E_ENTITY_REFERENCE],
- entity[E_ENTITY_X], entity[E_ENTITY_Y], entity[E_ENTITY_Z],
- entity[E_ENTITY_RZ],
- -1, -1, -1, 0 // Прозрачные цвета
- );
- SetVehicleVirtualWorld(vehicle_id, playerid + 1000); // Индивидуальный виртуальный мир
- entity[E_ENTITY_ID] = vehicle_id;
- }
- case SCENE_ENTITY_NPC:
- {
- // Создание NPC в индивидуальном мире
- new npc_id = NPC_Create(
- entity[E_ENTITY_REFERENCE],
- entity[E_ENTITY_X], entity[E_ENTITY_Y], entity[E_ENTITY_Z],
- entity[E_ENTITY_RZ],
- .worldid = playerid + 1000
- );
- entity[E_ENTITY_ID] = npc_id;
- }
- case SCENE_ENTITY_SOUND:
- {
- // Воспроизведение 3D звука
- Sound:Play3D(
- entity[E_ENTITY_REFERENCE], // Имя звукового файла
- entity[E_ENTITY_X], entity[E_ENTITY_Y], entity[E_ENTITY_Z],
- .min_distance = 5.0,
- .max_distance = entity[E_ENTITY_RADIUS],
- .initiator_system = SOUND_SYSTEM_EVENT_SCENE
- );
- }
- case SCENE_ENTITY_WEATHER:
- {
- SetPlayerWeather(playerid, entity[E_ENTITY_REFERENCE]);
- }
- case SCENE_ENTITY_TIME:
- {
- SetPlayerTime(playerid, entity[E_ENTITY_REFERENCE], entity[E_ENTITY_EXTRA_1]);
- }
- case SCENE_ENTITY_INTERIOR:
- {
- SetPlayerInterior(playerid, entity[E_ENTITY_REFERENCE]);
- }
- }
- // Сохраняем обновленную сущность
- g_EventEngine_Scenes[scene_id][E_SCENE_ENTITIES][i] = entity;
- }
- // Добавляем сцену в список активных сцен игрока
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]] = scene_id;
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]++;
- g_EventEngine_Scenes[scene_id][E_SCENE_ACTIVE] = true;
- // Вызываем callback активации
- if (funcidx("OnPlayerSceneActivate") != -1)
- {
- CallLocalFunction("OnPlayerSceneActivate", "ii", playerid, scene_id);
- }
- printf("[EventEngine] Активирована сцена %d для игрока %d", scene_id, playerid);
- return true;
- }
- // Деактивация сцены для игрока
- stock EventEngine:DeactivatePlayerScene(playerid, scene_id)
- {
- if (!EventEngine:IsSceneActiveForPlayer(playerid, scene_id))
- return true;
- new scene[E_SCENE_DATA];
- scene = g_EventEngine_Scenes[scene_id];
- // Удаляем сущности сцены
- for (new i = 0; i < scene[E_SCENE_ENTITY_COUNT]; i++)
- {
- new entity[E_SCENE_ENTITY] = scene[E_SCENE_ENTITIES][i];
- switch (E_SCENE_ENTITY_TYPE:entity[E_ENTITY_TYPE])
- {
- case SCENE_ENTITY_OBJECT:
- {
- if (entity[E_ENTITY_ID] != EVENT_INVALID_VALUE)
- {
- DestroyDynamicObject(entity[E_ENTITY_ID]);
- }
- }
- case SCENE_ENTITY_VEHICLE:
- {
- if (entity[E_ENTITY_ID] != EVENT_INVALID_VALUE)
- {
- DestroyVehicle(entity[E_ENTITY_ID]);
- }
- }
- case SCENE_ENTITY_NPC:
- {
- if (entity[E_ENTITY_ID] != EVENT_INVALID_VALUE)
- {
- NPC_Destroy(entity[E_ENTITY_ID]);
- }
- }
- case SCENE_ENTITY_SOUND:
- {
- Sound:Stop3D(entity[E_ENTITY_REFERENCE], entity[E_ENTITY_X], entity[E_ENTITY_Y], entity[E_ENTITY_Z]);
- }
- case SCENE_ENTITY_WEATHER:
- {
- // Восстанавливаем исходную погоду при удалении последней сцены
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] == 1)
- {
- SetPlayerWeather(playerid, g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_WEATHER]);
- }
- }
- case SCENE_ENTITY_TIME:
- {
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] == 1)
- {
- ResetPlayerTime(playerid);
- }
- }
- }
- // Сбрасываем ID сущности
- entity[E_ENTITY_ID] = EVENT_INVALID_VALUE;
- g_EventEngine_Scenes[scene_id][E_SCENE_ENTITIES][i] = entity;
- }
- // Удаляем сцену из списка активных
- for (new i = 0; i < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]; i++)
- {
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][i] == scene_id)
- {
- // Сдвигаем остальные сцены
- for (new j = i; j < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] - 1; j++)
- {
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][j] =
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][j + 1];
- }
- g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]--;
- break;
- }
- }
- g_EventEngine_Scenes[scene_id][E_SCENE_ACTIVE] = false;
- // Вызываем callback деактивации
- if (funcidx("OnPlayerSceneDeactivate") != -1)
- {
- CallLocalFunction("OnPlayerSceneDeactivate", "ii", playerid, scene_id);
- }
- printf("[EventEngine] Деактивирована сцена %d для игрока %d", scene_id, playerid);
- return true;
- }
- // Автоматическое обновление сцен при смене задания
- stock EventEngine:UpdatePlayerScenes(playerid, current_task)
- {
- printf("[EventEngine] Обновление сцен для игрока %d (задание: %d)", playerid, current_task);
- // Деактивируем сцены, которые больше не подходят
- for (new i = 0; i < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]; i++)
- {
- new scene_id = g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][i];
- new scene[E_SCENE_DATA] = g_EventEngine_Scenes[scene_id];
- if (current_task < scene[E_SCENE_TASK_MIN] || current_task > scene[E_SCENE_TASK_MAX])
- {
- if (scene[E_SCENE_FLAGS] & SCENE_FLAG_AUTO_DESTROY)
- {
- EventEngine:DeactivatePlayerScene(playerid, scene_id);
- i--; // Уменьшаем счетчик т.к. массив сдвинулся
- }
- }
- }
- // Активируем подходящие сцены
- for (new scene_id = 0; scene_id < g_EventEngine_SceneCount; scene_id++)
- {
- new scene[E_SCENE_DATA] = g_EventEngine_Scenes[scene_id];
- // Проверяем, подходит ли сцена по заданию и мероприятию
- if (scene[E_SCENE_EVENT_ID] == g_EventEngine_ActiveEvent &&
- current_task >= scene[E_SCENE_TASK_MIN] &&
- current_task <= scene[E_SCENE_TASK_MAX] &&
- !EventEngine:IsSceneActiveForPlayer(playerid, scene_id))
- {
- EventEngine:ActivatePlayerScene(playerid, scene_id);
- }
- }
- }
- // Проверка активности сцены для игрока
- stock EventEngine:IsSceneActiveForPlayer(playerid, scene_id)
- {
- for (new i = 0; i < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]; i++)
- {
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][i] == scene_id)
- return true;
- }
- return false;
- }
- // Уничтожение всех сцен игрока
- stock EventEngine:DestroyPlayerScenes(playerid, bool:keep_persistent = false)
- {
- printf("[EventEngine] Уничтожение сцен для игрока %d (persistent: %d)", playerid, _:keep_persistent);
- for (new i = 0; i < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]; i++)
- {
- new scene_id = g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][i];
- new scene[E_SCENE_DATA] = g_EventEngine_Scenes[scene_id];
- if (keep_persistent && (scene[E_SCENE_FLAGS] & SCENE_FLAG_PERSISTENT))
- continue;
- EventEngine:DeactivatePlayerScene(playerid, scene_id);
- i--; // Уменьшаем счетчик т.к. массив сдвинулся
- }
- // Восстанавливаем исходные настройки
- if (g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT] == 0)
- {
- SetPlayerWeather(playerid, g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_WEATHER]);
- ResetPlayerTime(playerid);
- SetPlayerInterior(playerid, g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_INTERIOR]);
- SetPlayerVirtualWorld(playerid, g_EventEngine_PlayerScenes[playerid][E_PLAYER_CURRENT_WORLD]);
- }
- }
- // Интеграция с системой заданий - обновляем при смене задания
- stock EventEngine:SetPlayerTask(playerid, task_id, bool:is_on_login = false)
- {
- // ... существующий код смены задания ...
- // Обновляем сцены после смены задания
- EventEngine:UpdatePlayerScenes(playerid, task_id);
- // ... остальной код ...
- }
- // Обработка отключения игрока
- public OnPlayerDisconnect(playerid, reason)
- {
- EventEngine:DestroyPlayerScenes(playerid, false);
- // ... остальной код ...
- return 1;
- }
- // Обработка выхода из зоны
- public OnPlayerLeaveDynamicArea(playerid, areaid)
- {
- for (new i = 0; i < g_EventEngine_PlayerScenes[playerid][E_PLAYER_SCENE_COUNT]; i++)
- {
- new scene_id = g_EventEngine_PlayerScenes[playerid][E_PLAYER_ACTIVE_SCENES][i];
- new scene[E_SCENE_DATA] = g_EventEngine_Scenes[scene_id];
- if ((scene[E_SCENE_FLAGS] & SCENE_FLAG_ZONE_BASED) && scene[E_SCENE_ZONE_ID] == areaid)
- {
- EventEngine:DeactivatePlayerScene(playerid, scene_id);
- i--;
- }
- }
- return 1;
- }
- // Пример создания сцены для задания "Поиск реквизита"
- public Circus_OnTaskInit(task_id)
- {
- if (task_id == TASK_FIND_PROPS)
- {
- // Создаем сцену с реквизитом в цирке
- new scene_id = EventEngine:CreateScene(
- EVENT_CIRCUS,
- "Реквизит цирка",
- TASK_FIND_PROPS,
- TASK_FIND_PROPS_FINISH,
- SCENE_FLAG_AUTO_DESTROY
- );
- // Добавляем объекты реквизита
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_OBJECT,
- 35.8412, 1945.6732, 9.8203, 19315, 0.0, 0.0, 0.0); // Ящик с реквизитом
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_OBJECT,
- 33.1289, 1943.4512, 9.8203, 19632, 0.0, 0.0, 90.0); // Костюмы
- // Добавляем NPC охраны
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_NPC,
- 37.2198, 1942.1289, 9.8203, 71, 180.0); // Охранник
- // Добавляем атмосферный звук
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_SOUND,
- 35.0, 1945.0, 10.0, "circus/ambient/storage.mp3", 15.0);
- }
- }
- // Пример сцены с транспортом для задания доставки
- public Circus_OnPlayerStartTask(playerid, sub_task)
- {
- new task_id = EventEngine:GetPlayerTask(playerid);
- if (task_id == TASK_DELIVER_PROPS)
- {
- // Создаем индивидуальный транспорт для доставки
- new scene_id = EventEngine:CreateScene(
- EVENT_CIRCUS,
- "Транспорт доставки",
- TASK_DELIVER_PROPS,
- TASK_DELIVER_PROPS_FINISH,
- SCENE_FLAG_AUTO_DESTROY
- );
- // Добавляем фургон для доставки
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_VEHICLE,
- 45.2198, 1950.1289, 10.1203, 498, 270.0); // Фургон Boxville
- // Устанавливаем погоду для атмосферы
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_WEATHER,
- 0.0, 0.0, 0.0, 8); // Туманная погода
- // Устанавливаем вечернее время
- EventEngine:AddSceneEntity(scene_id, SCENE_ENTITY_TIME,
- 0.0, 0.0, 0.0, 20, 0); // 20:00
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment