[ONLY TM] [EVENT] Escape From Tau-Kita - BETA ITERATION#2549
[ONLY TM] [EVENT] Escape From Tau-Kita - BETA ITERATION#2549Voyaker-coder wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the voyaker_events modpack, adding event-related systems such as deployable barricades, auto-cleanup for casings, supply drop pods, loot spawners, trader vending machines with a custom TGUI interface, quest systems, and wooden fences. The review identified several critical issues, including a syntax error in the TGUI interface's disabled check, incorrect TypeScript type definitions, unsupported named arguments in BYOND's image() function, a missing null check for radial menu choices, and list modification during iteration in the cleanup controller. Additionally, recommendations were made to address a memory leak in quest instantiation, fix swapped rotation directions, prevent accidental attacks after repairing barricades, avoid using usr and hardcoded coordinates, add missing mapload arguments, and remove leftover debug logs.
| const disabled = | ||
| loyaltyLocked || | ||
| remaining === 0; | ||
| (!all_products_free && !user) || | ||
| (!free && (discount ? redPrice : product.price) > user?.cash); |
There was a problem hiding this comment.
🔴 Критично
Обнаружена критическая ошибка: на строке 383 установлена точка с запятой ; вместо оператора ||. Из-за этого выражение для переменной disabled завершается досрочно, а последующие проверки баланса игрока и наличия ID-карты полностью игнорируются. Это позволяет покупать товары в обход проверок на клиенте.
Пожалуйста, замените ; на ||.
| const disabled = | |
| loyaltyLocked || | |
| remaining === 0; | |
| (!all_products_free && !user) || | |
| (!free && (discount ? redPrice : product.price) > user?.cash); | |
| const disabled = | |
| loyaltyLocked || | |
| remaining === 0 || | |
| (!all_products_free && !user) || | |
| (!free && (discount ? redPrice : product.price) > user?.cash); |
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| to_chat(user, span_warning("Вам нужно хотя бы <b>[BARRICADE_UPGRADE_REQUIRED_SHEETS]</b> для улучшения [src]!")) | ||
| return FALSE | ||
|
|
||
| var/static/list/cade_types = list(BARRICADE_TYPE_BOMB = image(icon = 'modular_bandastation/voyaker_events/icons/barricade.dmi', icon_state = "explosive_obj"), BARRICADE_TYPE_MELEE = image(icon = 'modular_bandastation/voyaker_events/icons/barricade.dmi', icon_state = "brute_obj"), BARRICADE_TYPE_ACID = image(icon = 'modular_bandastation/voyaker_events/icons/barricade.dmi', icon_state = "burn_obj")) |
There was a problem hiding this comment.
🔴 Критично
Встроенная функция image() в BYOND не поддерживает именованные аргументы (такие как icon = ... или icon_state = ...). Использование такого синтаксиса приведет к ошибке компиляции.
Пожалуйста, используйте позиционные аргументы.
var/static/list/cade_types = list(BARRICADE_TYPE_BOMB = image('modular_bandastation/voyaker_events/icons/barricade.dmi', "explosive_obj"), BARRICADE_TYPE_MELEE = image('modular_bandastation/voyaker_events/icons/barricade.dmi', "brute_obj"), BARRICADE_TYPE_ACID = image('modular_bandastation/voyaker_events/icons/barricade.dmi', "burn_obj"))
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| loyalty?: Record<string, { | ||
| locked: boolean; | ||
| required: number; | ||
| vendor_name?: string; | ||
| vendor_desc?: string; | ||
| vendor_portrait?: string; | ||
| vendor_message?: string; | ||
| }>; |
There was a problem hiding this comment.
🟡 Рекомендация
Поля vendor_name, vendor_desc, vendor_portrait и vendor_message ошибочно описаны внутри типа значения для loyalty, хотя на самом деле они приходят с бэкенда как свойства верхнего уровня и деструктурируются непосредственно из data. Также в типе VendingData отсутствуют поля отношений (trader_level, trader_rep и др.), что вызовет ошибки компиляции TypeScript.
Рекомендуется исправить структуру типа VendingData.
loyalty?: Record<string, {
locked: boolean;
required: number;
}>;
vendor_name?: string;
vendor_desc?: string;
vendor_portrait?: string;
vendor_message?: string;
trader_level: number;
trader_rep: number;
trader_next_rep: number;
trader_sales_progress: number;
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| var/choice = show_radial_menu(user, src, cade_types, require_near = TRUE, tooltips = TRUE) | ||
|
|
There was a problem hiding this comment.
🔴 Критично
Отсутствует проверка на null для переменной choice. Если игрок закроет радиальное меню или отойдет, choice будет равен null. В этом случае код продолжит выполнение, спишет материалы и выведет некорректное сообщение в чат.
Необходимо добавить проверку сразу после вызова меню.
var/choice = show_radial_menu(user, src, cade_types, require_near = TRUE, tooltips = TRUE)
if(!choice)
return FALSE
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| for(var/obj/item/ammo_casing/C in GLOB.shell_casings) | ||
| if(QDELETED(C)) | ||
| continue | ||
| if(world.time - C.spawn_time < 15 MINUTES) | ||
| continue | ||
| removed++ | ||
| qdel(C) |
There was a problem hiding this comment.
🔴 Критично
Вы модифицируете список GLOB.shell_casings во время итерации по нему (вызов qdel(C) приводит к удалению гильзы из списка в её Destroy()). В BYOND изменение списка во время цикла for приводит к пропуску элементов или непредсказуемому поведению итератора.
Рекомендуется сначала собрать список элементов для удаления, а затем удалить их.
var/list/to_delete = list()
for(var/obj/item/ammo_casing/C in GLOB.shell_casings)
if(QDELETED(C))
continue
if(world.time - C.spawn_time < 15 MINUTES)
continue
to_delete += C
for(var/obj/item/ammo_casing/C in to_delete)
removed++
qdel(C)
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| ) | ||
|
|
||
| new /obj/effect/decal/cleanable/ash(death_turf) | ||
| forceMove(locate(100, 50, 3)) |
There was a problem hiding this comment.
🟡 Рекомендация
Использование жестко закодированных координат locate(100, 50, 3) делает код зависимым от конкретной карты и Z-уровня. При смене карты или структуры Z-уровней игроки могут телепортироваться в космос или внутрь стен.
Рекомендуется использовать ориентиры (landmarks) или хотя бы именованные константы/переменные для определения точки спавна.
// TODO: Избегайте хардкода координат, используйте landmarks
forceMove(locate(100, 50, 3))
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| Initialize() | ||
| . = ..() |
There was a problem hiding this comment.
🟡 Рекомендация
Процедура Initialize должна принимать аргумент mapload. Переопределение без аргументов ломает цепочку вызовов ..() и может привести к потере флага mapload в родительских инициализаторах.
Пожалуйста, добавьте аргумент mapload.
Initialize(mapload)
. = ..()
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| for(var/obj/item/I in H.get_all_contents()) | ||
| if(I.loc == H) // защита от продажи предметов в руках/надетых | ||
| continue |
There was a problem hiding this comment.
🟡 Рекомендация
В цикле sell_all_items отсутствует проверка на QDELETED(I). Если один из контейнеров (например, пояс чемпиона) будет продан и удален вместе со своим содержимым, последующие итерации цикла попытаются обработать уже удаленные предметы из списка get_all_contents(), что может привести к багам или начислению лишних кредитов.
Рекомендуется добавить проверку QDELETED.
for(var/obj/item/I in H.get_all_contents())
if(QDELETED(I) || I.loc == H) // защита от продажи предметов в руках/надетых и удаленных
continue
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| reagent_note = "REAGENTS: [pretty_string_from_reagent_list(reagents.reagent_list)]" | ||
|
|
||
| if(ismob(firer) && !do_not_log) | ||
| world.log << "PROJECTILE HIT: [firer] -> [living_target]" |
There was a problem hiding this comment.
💡 Предложение
В коде оставлен отладочный вывод world.log << .... Он будет спамить в консоль сервера при каждом попадании снаряда, что может негативно сказаться на производительности. Для логирования выстрелов ниже уже вызывается log_combat().
Рекомендуется удалить эту строку.
if(isliving(living_target))
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
| world.log << "PUNPUN DIED" | ||
|
|
||
| if(quest_killer) | ||
| world.log << "QUEST KILLER = [quest_killer]" | ||
| else | ||
| world.log << "QUEST KILLER IS NULL" |
There was a problem hiding this comment.
💡 Предложение
В коде оставлены отладочные выводы world.log << .... Рекомендуется удалить их перед слиянием PR.
/mob/living/carbon/human/species/monkey/punpun/death(gibbed)
if(quest_killer && ishuman(quest_killer))
check_trader_kill_quests(quest_killer, src)
. = ..()
References
- Использование визуальных маркеров (Emoji) для классификации замечаний, вежливое обращение на «Вы» и нейтрально-деловой тон бортового ИИ. (link)
Что этот PR делает
Вносит всё необходимое для проведения бета-теста глобального ивента-режима - "Escape From Tau-Kita"
Почему это хорошо для игры
Принципиально новый ивентовый режим PvP-направленности с механиками лутинга, экстракции с локаций, торговой репутации и т.д
Изображения изменений
Тестирование
Всё на локалке
Changelog
🆑
add: Добавление кода для проведения глобального ивента-режима.
image: Добавлено/изменено изображение в игре.
map: Добавлено/изменено/удалено что-то на карте.
/:cl: