From d80d064e7bb7eb8f542d43616f51274f1f9e54e6 Mon Sep 17 00:00:00 2001 From: Oxotnak <107066254+Oxotnak@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:46:23 +0300 Subject: [PATCH 1/6] GAS carry build late game (#4957) * agro-grab * noslip + tackle resist * movespeed raise * eyes slot + offset * agrograb's qol spans * faster scythes + remove comment * no glasses actually + exceptions * exceptions + icon name fix * [Drish] fix huds nabber * scythes_stop_standing * aaa * aaa2 * lategaming * aaa2.1 * aaa1.1 * stash valid * tabulation missed * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/_nabbers.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/nabber_bolaimmunity.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/nabber_language.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * Update tff_modular/modules/nabbers/code/nabber_language.dm Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> * eyes fix * qol, fix, blacklist update * language fix --------- Co-authored-by: SuperDrish <59139863+Microvolnovka19@users.noreply.github.com> --- code/modules/clothing/glasses/hud.dm | 14 ++ code/modules/mob/living/living_say.dm | 12 ++ .../research/techweb/nodes/cyborg_nodes.dm | 1 + .../modules/huds/code/glasses/HUD_Glasses.dm | 4 + .../meson_scouter/code/meson_scouter.dm | 10 +- tff_modular/modules/nabbers/code/_nabbers.dm | 178 +++++++++++++++++- .../modules/nabbers/code/abilites/agrograb.dm | 25 +++ .../code/abilites/nabber_combat_effect.dm | 2 +- .../code/abilites/nabber_welding_eyes.dm | 2 +- .../nabbers/code/abilites/toggle_arms.dm | 55 ++++-- .../modules/nabbers/code/nabber_bodyparts.dm | 6 + .../nabbers/code/nabber_bolaimmunity.dm | 57 ++++++ .../modules/nabbers/code/nabber_huds.dm | 90 +++++++++ .../modules/nabbers/code/nabber_language.dm | 122 ++++++++++++ .../modules/nabbers/code/nabber_organs.dm | 21 ++- tgstation.dme | 4 + 16 files changed, 571 insertions(+), 32 deletions(-) create mode 100644 tff_modular/modules/nabbers/code/abilites/agrograb.dm create mode 100644 tff_modular/modules/nabbers/code/nabber_bolaimmunity.dm create mode 100644 tff_modular/modules/nabbers/code/nabber_huds.dm create mode 100644 tff_modular/modules/nabbers/code/nabber_language.dm diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 332aba8a719..97ed81c630e 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -38,6 +38,7 @@ icon_state = "healthhud" clothing_traits = list(TRAIT_MEDICAL_HUD) glass_colour_type = /datum/client_colour/glass_colour/lightblue + species_exception = list(/datum/species/nabber) // FF ADDITION /obj/item/clothing/glasses/hud/medsechud name = "health scanner security HUD" @@ -57,6 +58,7 @@ glass_colour_type = /datum/client_colour/glass_colour/lightgreen actions_types = list(/datum/action/item_action/toggle_nv) forced_glass_color = TRUE + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/health/night/update_icon_state() . = ..() @@ -82,6 +84,7 @@ flags_cover = GLASSESCOVERSEYES tint = 1 glass_colour_type = /datum/client_colour/glass_colour/blue + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/health/sunglasses/Initialize(mapload) . = ..() @@ -98,6 +101,7 @@ icon_state = "diagnostichud" clothing_traits = list(TRAIT_DIAGNOSTIC_HUD) glass_colour_type = /datum/client_colour/glass_colour/lightorange + species_exception = list(/datum/species/nabber) // FF ADDITION /obj/item/clothing/glasses/hud/diagnostic/night name = "night vision diagnostic HUD" @@ -111,6 +115,7 @@ glass_colour_type = /datum/client_colour/glass_colour/lightyellow actions_types = list(/datum/action/item_action/toggle_nv) forced_glass_color = TRUE + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/diagnostic/night/update_icon_state() . = ..() @@ -124,6 +129,7 @@ flash_protect = FLASH_PROTECTION_FLASH flags_cover = GLASSESCOVERSEYES tint = 1 + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/diagnostic/sunglasses/Initialize(mapload) . = ..() @@ -140,12 +146,14 @@ icon_state = "securityhud" clothing_traits = list(TRAIT_SECURITY_HUD) glass_colour_type = /datum/client_colour/glass_colour/red + species_exception = list(/datum/species/nabber) // FF ADDITION /obj/item/clothing/glasses/hud/security/chameleon name = "chameleon security HUD" desc = "A stolen security HUD integrated with Syndicate chameleon technology. Provides flash protection." flash_protect = FLASH_PROTECTION_FLASH actions_types = list(/datum/action/item_action/chameleon/change/glasses/no_preset) + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch name = "eyepatch HUD" @@ -153,6 +161,7 @@ icon_state = "hudpatch" base_icon_state = "hudpatch" actions_types = list(/datum/action/item_action/flip) + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch/attack_self(mob/user, modifiers) . = ..() @@ -167,6 +176,7 @@ flags_cover = GLASSESCOVERSEYES tint = 1 glass_colour_type = /datum/client_colour/glass_colour/darkred + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/sunglasses/Initialize(mapload) . = ..() @@ -188,6 +198,7 @@ glass_colour_type = /datum/client_colour/glass_colour/lightred actions_types = list(/datum/action/item_action/toggle_nv) forced_glass_color = TRUE + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/night/update_icon_state() . = ..() @@ -206,6 +217,7 @@ attack_verb_simple = list("slice") hitsound = 'sound/items/weapons/bladeslice.ogg' sharpness = SHARP_EDGED + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/sunglasses/gars/giga name = "giga HUD gar glasses" @@ -213,6 +225,7 @@ icon_state = "gigagar_sec" force = 12 throwforce = 12 + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/toggle name = "Toggle HUD" @@ -251,6 +264,7 @@ color_cutoffs = list(25, 8, 5) glass_colour_type = /datum/client_colour/glass_colour/red clothing_traits = list(TRAIT_SECURITY_HUD) + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user) ..() diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index c935989a580..e72899d482d 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -278,6 +278,18 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( if((SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_HEAR, args) & COMSIG_MOVABLE_CANCEL_HEARING) || !GET_CLIENT(src)) return FALSE +// FLUFFY EDIT START Converts scrambled nabber's msg into emote for people + if(ispath(message_language, /datum/language/nabber) && speaker != src) + var/gbs_translation_check = translate_language(speaker, message_language, raw_message, spans, message_mods) + if(raw_message != gbs_translation_check) + message_mods[MODE_CUSTOM_SAY_EMOTE] = gbs_translation_check + message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] = TRUE + + if(ispath(message_language, /datum/language/nabber) && isnabber(src)) + message_mods[MODE_CUSTOM_SAY_EMOTE] = null + message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] = FALSE + // FLUFFY EDIT END + var/deaf_message var/deaf_type diff --git a/code/modules/research/techweb/nodes/cyborg_nodes.dm b/code/modules/research/techweb/nodes/cyborg_nodes.dm index fad15b6f019..bc5b7efc0be 100644 --- a/code/modules/research/techweb/nodes/cyborg_nodes.dm +++ b/code/modules/research/techweb/nodes/cyborg_nodes.dm @@ -149,6 +149,7 @@ "implanter", "locator", "c38_trac", + "implant_gasspeech", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_1_POINTS) announce_channels = list(RADIO_CHANNEL_SECURITY, RADIO_CHANNEL_MEDICAL) diff --git a/modular_nova/modules/huds/code/glasses/HUD_Glasses.dm b/modular_nova/modules/huds/code/glasses/HUD_Glasses.dm index 13d25055eb8..3945298af98 100644 --- a/modular_nova/modules/huds/code/glasses/HUD_Glasses.dm +++ b/modular_nova/modules/huds/code/glasses/HUD_Glasses.dm @@ -4,6 +4,7 @@ icon = 'modular_nova/modules/huds/icons/huds.dmi' icon_state = "glasses_healthhud" worn_icon = 'modular_nova/modules/huds/icons/hudeyes.dmi' + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/health/prescription/Initialize(mapload) clothing_traits += list(TRAIT_NEARSIGHTED_CORRECTED) @@ -15,6 +16,7 @@ icon = 'modular_nova/modules/huds/icons/huds.dmi' icon_state = "glasses_diagnostichud" worn_icon = 'modular_nova/modules/huds/icons/hudeyes.dmi' + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/diagnostic/prescription/Initialize(mapload) clothing_traits += list(TRAIT_NEARSIGHTED_CORRECTED) @@ -26,6 +28,7 @@ icon = 'modular_nova/modules/huds/icons/huds.dmi' icon_state = "glasses_securityhud" worn_icon = 'modular_nova/modules/huds/icons/hudeyes.dmi' + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/hud/security/prescription/Initialize(mapload) clothing_traits += list(TRAIT_NEARSIGHTED_CORRECTED) @@ -51,6 +54,7 @@ /obj/item/clothing/glasses/meson/prescription name = "prescription optical meson scanner" desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions. This one has prescription lens fitted in." + species_exception = list() // FF ADDITION /obj/item/clothing/glasses/meson/prescription/Initialize(mapload) clothing_traits += list(TRAIT_NEARSIGHTED_CORRECTED) diff --git a/modular_nova/modules/meson_scouter/code/meson_scouter.dm b/modular_nova/modules/meson_scouter/code/meson_scouter.dm index 08931499aa3..3c6fd5792eb 100644 --- a/modular_nova/modules/meson_scouter/code/meson_scouter.dm +++ b/modular_nova/modules/meson_scouter/code/meson_scouter.dm @@ -1,4 +1,5 @@ /obj/item/clothing/glasses/meson + species_exception = list(/datum/species/nabber) // FF ADDITION uses_advanced_reskins = TRUE unique_reskin = list( "Meson Glasses" = list( @@ -11,12 +12,12 @@ RESKIN_ICON = 'modular_nova/modules/meson_scouter/icons/meson_scouter.dmi', RESKIN_ICON_STATE = "meson_scouter", RESKIN_WORN_ICON = 'modular_nova/modules/meson_scouter/icons/meson-scouter_mob.dmi', - RESKIN_WORN_ICON_STATE = "meson_scouter" ), ) /obj/item/clothing/glasses/meson/night/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Meson Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -34,6 +35,7 @@ /obj/item/clothing/glasses/meson/gar/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Meson Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -51,6 +53,7 @@ /obj/item/clothing/glasses/meson/prescription/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Meson Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -67,6 +70,7 @@ ) /obj/item/clothing/glasses/meson/engine + species_exception = list(/datum/species/nabber) // FF ADDITION uses_advanced_reskins = TRUE unique_reskin = list( "Engine Glasses" = list( @@ -83,6 +87,7 @@ /obj/item/clothing/glasses/meson/engine/tray/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Engine Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -98,6 +103,7 @@ /obj/item/clothing/glasses/meson/engine/shuttle/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Engine Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -113,6 +119,7 @@ /obj/item/clothing/glasses/meson/engine/atmos_imaging/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Engine Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', @@ -128,6 +135,7 @@ /obj/item/clothing/glasses/meson/engine/prescription/Initialize(mapload) . = ..() + species_exception = list() // FF ADDITION unique_reskin -= list( "Engine Glasses" = list( RESKIN_ICON = 'icons/obj/clothing/glasses.dmi', diff --git a/tff_modular/modules/nabbers/code/_nabbers.dm b/tff_modular/modules/nabbers/code/_nabbers.dm index cd906b2be98..a41e631eaac 100644 --- a/tff_modular/modules/nabbers/code/_nabbers.dm +++ b/tff_modular/modules/nabbers/code/_nabbers.dm @@ -16,21 +16,25 @@ TRAIT_MUTANT_COLORS, TRAIT_NO_UNDERWEAR, TRAIT_HARD_SOLES, - TRAIT_NO_BLOOD_OVERLAY + TRAIT_NO_BLOOD_OVERLAY, + TRAIT_NO_SLIP_WATER, + TRAIT_BRAWLING_KNOCKDOWN_BLOCKED, + TRAIT_PERSONALSPACE, // Нет жопы :с ) body_size_restricted = TRUE digitigrade_customization = DIGITIGRADE_NEVER - no_equip_flags = ITEM_SLOT_FEET | ITEM_SLOT_OCLOTHING | ITEM_SLOT_SUITSTORE | ITEM_SLOT_EYES + no_equip_flags = ITEM_SLOT_FEET | ITEM_SLOT_OCLOTHING | ITEM_SLOT_SUITSTORE | ITEM_SLOT_EYES | ITEM_SLOT_LEGCUFFED inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutanttongue = /obj/item/organ/internal/tongue/nabber - always_customizable = FALSE + always_customizable = TRUE hair_alpha = 0 facial_hair_alpha = 0 payday_modifier = 0.75 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT + species_cookie = /obj/item/food/grown/cabbage bodytemp_heat_damage_limit = (BODYTEMP_HEAT_DAMAGE_LIMIT - 10) mutantbrain = /obj/item/organ/internal/brain/nabber - mutanteyes = /obj/item/organ/internal/eyes/robotic/nabber + mutanteyes = /obj/item/organ/internal/eyes/nabber mutantlungs = /obj/item/organ/internal/lungs/nabber mutantheart = /obj/item/organ/internal/heart/nabber mutantliver = /obj/item/organ/internal/liver/nabber @@ -56,6 +60,11 @@ var/datum/action/cooldown/toggle_arms/arms var/datum/action/cooldown/optical_camouflage/camouflage var/datum/action/cooldown/nabber_threat/threat_mod + placeholder_description = "Giant armoured serpentids (GAS), also known as Nabbers, or snake-bugs, are a massive predatory species who are trained by a company to work with humans. Physically, although they look intimidating, they're unlikely to harm a human except in times of great stress. If you see them getting their large attack arms ready, it's telling you to back off." + placeholder_lore = "https://fluffy-frontier.ru/osobye-rasy" + + species_language_holder = /datum/language_holder/nabber + language_prefs_whitelist = list(/datum/language/nabber) /datum/species/nabber/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load) . = ..() @@ -66,9 +75,16 @@ threat_mod = new(C) threat_mod.Grant(C) - // Предохраняемся от получения проклятого квирка. Ломающего ГБС - if(C.has_quirk(/datum/quirk/oversized)) - C.remove_quirk(/datum/quirk/oversized) + var/is_dummy = istype(C, /mob/living/carbon/human/dummy) + + if(!is_dummy) + C.uncuff() + if(!C.legcuffed) + var/obj/item/restraints/legcuffs/gas_placeholder/anti_cuffs = new() + C.equip_to_slot(anti_cuffs, ITEM_SLOT_LEGCUFFED, initial = TRUE) + + var/obj/item/implant/gas_sol_speaker/imp_in = new() + imp_in.implant(C) /datum/species/nabber/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) . = ..() @@ -77,6 +93,10 @@ threat_mod.Destroy() /datum/species/nabber/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) + // Вызываем это перед проверкой на смерть, чтобы даже у мёртвых ГБСов была заглушка + if(H.num_legs >= 2 && !H.legcuffed && !QDELETED(H)) + var/obj/item/restraints/legcuffs/gas_placeholder/anti_cuffs = new() + H.equip_to_slot(anti_cuffs, ITEM_SLOT_LEGCUFFED, initial = TRUE) . = ..() if(isdead(H)) return @@ -125,7 +145,7 @@ )) perk_descriptions += list(list( - SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, SPECIES_PERK_ICON = "dna", SPECIES_PERK_NAME = "Robust chitin", SPECIES_PERK_DESC = "GAS possess durable chitinous exoskeletons and can withstand a lot of brute damage." @@ -169,3 +189,145 @@ /mob/living/carbon/human/species/nabber race = /datum/species/nabber + +/mob/living/carbon/human/Destroy() + if(isnabber(src) && !QDELETED(legcuffed)) + QDEL_NULL(legcuffed) + . = ..() + +// Отображение для других наличия повреждений у голосового импланта +/mob/living/carbon/human/examine(mob/user) + . = ..() + + if(isnabber(src)) + var/is_really_borked = FALSE + for(var/obj/item/implant/gas_sol_speaker/imp in implants) + var/is_borked = imp.emp_damage + if (is_borked > 0) + is_really_borked = TRUE + if(is_really_borked) + . += span_notice("[user.p_Their()] speech synthesizer emits constant silent white noise.") + "\n" + +// Не заковывается при наличии кос +/mob/living/carbon/human/canBeHandcuffed() + if(isnabber(src)) + var/obj/item/held = get_active_held_item() + var/obj/item/inactive = get_inactive_held_item() + if(istype((inactive || held), /obj/item/melee/nabber_blade)) + return FALSE + . = ..() + +// В режиме кос агро грабы не будут замедлять +/mob/living/carbon/human/add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE) + if(isnabber(src) && type_or_datum == /datum/movespeed_modifier/grab_slowdown/aggressive) + var/datum/species/nabber/our_nabber = src.dna.species + var/datum/action/cooldown/toggle_arms/arms = our_nabber.arms + if(arms.button_icon_state == "arms_on") + return FALSE + return ..() + +// ЧС квирков +/mob/living/carbon/human/add_quirk(datum/quirk/quirktype, client/override_client) + var/bad_nabber_quirks = list( + // негативные + /datum/quirk/oversized, + /datum/quirk/prosthetic_limb, + /datum/quirk/quadruple_amputee, + /datum/quirk/item_quirk/addict/junkie, + /datum/quirk/item_quirk/addict/smoker, + /datum/quirk/item_quirk/addict/alcoholic, + /datum/quirk/all_nighter, + /datum/quirk/item_quirk/allergic, // До введения системы дыхания + /datum/quirk/badback, + /datum/quirk/bighands, + /datum/quirk/item_quirk/blindness, + /datum/quirk/blooddeficiency, + /datum/quirk/body_purist, + /datum/quirk/item_quirk/brainproblems, + /datum/quirk/item_quirk/chronic_illness, + /datum/quirk/clumsy, + /datum/quirk/item_quirk/deafness, + /datum/quirk/item_quirk/family_heirloom, + /datum/quirk/item_quirk/food_allergic, + /datum/quirk/frail, + /datum/quirk/glass_jaw, + /datum/quirk/hemiplegic, + /datum/quirk/indebted, + /datum/quirk/insanity, + /datum/quirk/light_drinker, + /datum/quirk/mute, + /datum/quirk/item_quirk/nearsighted, + /datum/quirk/nonviolent, + /datum/quirk/numb, + /datum/quirk/nyctophobia, + /datum/quirk/paraplegic, + /datum/quirk/photophobia, + /datum/quirk/prosopagnosia, + /datum/quirk/pushover, + /datum/quirk/social_anxiety, + /datum/quirk/softspoken, + /datum/quirk/tin_man, + /datum/quirk/touchy, + /datum/quirk/narcolepsy, + /datum/quirk/fragile, + /datum/quirk/alexithymia, + // Нейтральные + /datum/quirk/item_quirk/bald, + /datum/quirk/item_quirk/borg_ready, + /datum/quirk/deviant_tastes, + /datum/quirk/foreigner, + /datum/quirk/gamer, + /datum/quirk/no_taste, + /datum/quirk/item_quirk/photographer, + /datum/quirk/pineapple_hater, + /datum/quirk/pineapple_liker, + /datum/quirk/snob, + /datum/quirk/transhumanist, + /datum/quirk/vegetarian, + /datum/quirk/canine_aspect, + /datum/quirk/feline_aspect, + /datum/quirk/avian_aspect, + /datum/quirk/water_aspect, + /datum/quirk/webbing_aspect, + /datum/quirk/floral_aspect, + /datum/quirk/ash_aspect, + /datum/quirk/sparkle_aspect, + /datum/quirk/excitable, + /datum/quirk/personalspace, // Встроен + /datum/quirk/item_quirk/joker, + /datum/quirk/overweight, + /datum/quirk/echolocation, + /datum/quirk/equipping/entombed, + /datum/quirk/hydra, + /datum/quirk/possessive, + /datum/quirk/kleptomaniac, + /datum/quirk/masochism, + /datum/quirk/sadism, + /datum/quirk/ropebunny, + /datum/quirk/rigger, + /datum/quirk/telepathic, + /datum/quirk/burr, + /datum/quirk/item_quirk/underworld_connections, + /datum/quirk/unsteady, + // Позитивные + /datum/quirk/alcohol_tolerance, + /datum/quirk/bilingual, + /datum/quirk/drunkhealing, + /datum/quirk/light_step, // Встроен + /datum/quirk/item_quirk/musician, + /datum/quirk/item_quirk/settler, + /datum/quirk/item_quirk/signer, + /datum/quirk/item_quirk/pet_owner, + /datum/quirk/skittish, + /datum/quirk/spacer_born, + /datum/quirk/item_quirk/spiritual, + /datum/quirk/hard_soles, // Встроен + /datum/quirk/linguist, + /datum/quirk/sharpclaws, + /datum/quirk/water_breathing, + /datum/quirk/no_appendix, // Нет аппендикса + /datum/quirk/shapeshifter, + ) + if(isnabber(src) && (quirktype in bad_nabber_quirks)) + return FALSE + . = ..() diff --git a/tff_modular/modules/nabbers/code/abilites/agrograb.dm b/tff_modular/modules/nabbers/code/abilites/agrograb.dm new file mode 100644 index 00000000000..8f043043e17 --- /dev/null +++ b/tff_modular/modules/nabbers/code/abilites/agrograb.dm @@ -0,0 +1,25 @@ +#define MARTIALART_NABBER "scythes grab" + +/datum/martial_art/nabber_grab + name = "scythes grab" + id = MARTIALART_NABBER + +/datum/martial_art/nabber_grab/grab_act(mob/living/attacker, mob/living/defender) + if(attacker == defender) + return MARTIAL_ATTACK_INVALID + + var/old_grab_state = attacker.grab_state + defender.grabbedby(attacker, TRUE) + if(old_grab_state == GRAB_PASSIVE) + defender.drop_all_held_items() + attacker.setGrabState(GRAB_AGGRESSIVE) //Instant aggressive grab if on grab intent + log_combat(attacker, defender, "grabbed", addition="aggressively") + defender.visible_message( + span_warning("[attacker] grabs [defender] in his scythes!"), + span_userdanger("You're grabbed in scythes by [attacker]!"), + span_hear("You hear sounds of aggressive fondling!"), + COMBAT_MESSAGE_RANGE, + attacker, + ) + to_chat(attacker, span_danger("You grab [defender] in your scythes!")) + return MARTIAL_ATTACK_SUCCESS diff --git a/tff_modular/modules/nabbers/code/abilites/nabber_combat_effect.dm b/tff_modular/modules/nabbers/code/abilites/nabber_combat_effect.dm index 8b64d239d3d..92f116940f6 100644 --- a/tff_modular/modules/nabbers/code/abilites/nabber_combat_effect.dm +++ b/tff_modular/modules/nabbers/code/abilites/nabber_combat_effect.dm @@ -51,7 +51,7 @@ /datum/movespeed_modifier/nabber_combat blacklisted_movetypes = FLYING - multiplicative_slowdown = -0.25 + multiplicative_slowdown = -0.40 #undef NABBER_THREAT_ICON #undef NABBER_THREAT_ICON_STATE diff --git a/tff_modular/modules/nabbers/code/abilites/nabber_welding_eyes.dm b/tff_modular/modules/nabbers/code/abilites/nabber_welding_eyes.dm index 1f6253a79e1..60a8dd241d3 100644 --- a/tff_modular/modules/nabbers/code/abilites/nabber_welding_eyes.dm +++ b/tff_modular/modules/nabbers/code/abilites/nabber_welding_eyes.dm @@ -2,7 +2,7 @@ name = "Toggle welding shield" desc = "Toggle your eyes welding shield" - var/obj/item/organ/internal/eyes/robotic/nabber/eyes + var/obj/item/organ/internal/eyes/nabber/eyes /datum/action/toggle_welding/Trigger(trigger_flags) . = ..() diff --git a/tff_modular/modules/nabbers/code/abilites/toggle_arms.dm b/tff_modular/modules/nabbers/code/abilites/toggle_arms.dm index f83866ad337..9d28e0bf5b1 100644 --- a/tff_modular/modules/nabbers/code/abilites/toggle_arms.dm +++ b/tff_modular/modules/nabbers/code/abilites/toggle_arms.dm @@ -1,3 +1,5 @@ +var/datum/martial_art/martial_to_learn = new /datum/martial_art/nabber_grab() + /obj/item/melee/nabber_blade name = "Mantis arm" desc = "A grotesque matn made out of bone and flesh that cleaves through people as a hot knife through butter." @@ -46,12 +48,18 @@ desc = "Pump blood from manipulating arms into mantis arms, becoming a menace in close combat but loosing ability to interact." cooldown_time = 5 SECONDS + var/obj/item/restraints/handcuffs/stored_handcuffs = null //Переменная для сохранения наручников + button_icon = 'tff_modular/modules/nabbers/icons/actions.dmi' /datum/action/cooldown/toggle_arms/New(Target, original) . = ..() button_icon_state = "arms_off" +/datum/action/cooldown/toggle_arms/Destroy() + stored_handcuffs = null + . = ..() + /datum/action/cooldown/toggle_arms/Activate(atom/target) var/mob/living/carbon/human/nabber = owner @@ -59,8 +67,9 @@ return FALSE if(isdead(nabber) || nabber.incapacitated) - nabber.balloon_alert(nabber, "Incapacitated!") - return FALSE + if(!nabber.handcuffed) + nabber.balloon_alert(nabber, "Incapacitated!") + return FALSE if(nabber.num_hands < 2) nabber.balloon_alert(nabber, "Need both hands!") @@ -89,11 +98,19 @@ nabber.visible_message(span_warning("[nabber] starts to pump blood into their mantis arms!"), span_warning("You start pumping blood into your mantis arms and emmitting defensive screech! Stay still!"), span_hear("You hear ramping up screech!")) playsound(nabber, 'tff_modular/modules/nabbers/sounds/nabberscream.ogg', 70) - if(!do_after(nabber, 5 SECONDS, nabber)) + if(!do_after(nabber, 2 SECONDS, nabber, IGNORE_USER_LOC_CHANGE)) StartCooldown() - nabber.balloon_alert(nabber, "Stand still!") return FALSE + //"Сохраняет" наручники надетые на ГБСа в ЕГО ТЕЛО и позволяет пользоваться косами + открепляет его от стула и подобного + if(nabber.handcuffed) + stored_handcuffs = nabber.handcuffed + nabber.handcuffed.forceMove(nabber) + nabber.set_handcuffed(null) + if(nabber.buckled?.buckle_requires_restraints) + nabber.buckled.unbuckle_mob(nabber) + nabber.update_handcuffed() + nabber.balloon_alert(nabber, "Arms rised!") nabber.visible_message(span_warning("[nabber] raised their mantis arms ready for combat!"), span_warning("You raise your mantis arms, ready for combat."), span_hear("You hear terrible a screech!")) playsound(nabber, 'tff_modular/modules/nabbers/sounds/nabberscream.ogg', 70) @@ -107,8 +124,9 @@ nabber.put_in_active_hand(active_hand) nabber.put_in_inactive_hand(inactive_hand) + martial_to_learn.teach(nabber) - RegisterSignal(owner, COMSIG_CARBON_REMOVE_LIMB, PROC_REF(on_lose_hand)) + RegisterSignal(owner, COMSIG_CARBON_POST_REMOVE_LIMB, PROC_REF(on_lose_hand)) button_icon_state = "arms_on" nabber.update_action_buttons() @@ -117,7 +135,10 @@ nabber.visible_message(span_notice("[nabber] starts to pump blood out their mantis arms!"), span_notice("You start pumping blood out your mantis arms. Stay still!"), span_hear("You hear ramping up screech!")) - if(force) + if(force) //Типикал бьонд код + if(stored_handcuffs) + stored_handcuffs.forceMove(stored_handcuffs.drop_location()) + stored_handcuffs = null nabber.Stun(5 SECONDS) for(var/obj/item/held in nabber.held_items) if(istype(held, /obj/item/melee/nabber_blade)) @@ -128,8 +149,7 @@ nabber.balloon_alert(nabber, "Starting pumping blood out!") - if(!do_after(nabber, 5 SECONDS, nabber)) - nabber.balloon_alert(nabber, "Stand still!") + if(!do_after(nabber, 2 SECONDS, nabber, IGNORE_USER_LOC_CHANGE)) return FALSE playsound(nabber, 'tff_modular/modules/nabbers/sounds/nabberscream.ogg', 70) @@ -137,17 +157,23 @@ if(istype(held, /obj/item/melee/nabber_blade)) qdel(held) - UnregisterSignal(owner, COMSIG_CARBON_REMOVE_LIMB) + UnregisterSignal(owner, COMSIG_CARBON_POST_REMOVE_LIMB) + martial_to_learn.remove(nabber) nabber.balloon_alert(nabber, "Arms down!") button_icon_state = "arms_off" nabber.update_action_buttons() + // Надевает наручники обратно если они были до перехода в косы + if(stored_handcuffs) + nabber.equip_to_slot(stored_handcuffs, ITEM_SLOT_HANDCUFFED) + stored_handcuffs = null + /datum/action/cooldown/toggle_arms/proc/on_lose_hand() SIGNAL_HANDLER var/mob/living/carbon/human/nabber = owner - if(!(nabber.num_hands < 2)) - return FALSE + if(nabber.num_hands >= 2) + return FALSE nabber.visible_message(span_notice("[nabber] starts to pump blood out their mantis arms!"), span_notice("You start pumping blood out your mantis arms. Stay still!"), span_hear("You hear ramping up screech!")) playsound(nabber, 'tff_modular/modules/nabbers/sounds/nabberscream.ogg', 70) @@ -157,5 +183,12 @@ if(istype(held, /obj/item/melee/nabber_blade)) qdel(held) + martial_to_learn.remove(nabber) button_icon_state = "arms_off" nabber.update_action_buttons() + + if(stored_handcuffs) + stored_handcuffs.forceMove(stored_handcuffs.drop_location()) + stored_handcuffs = null + + UnregisterSignal(owner, COMSIG_CARBON_POST_REMOVE_LIMB) diff --git a/tff_modular/modules/nabbers/code/nabber_bodyparts.dm b/tff_modular/modules/nabbers/code/nabber_bodyparts.dm index 04587b7ae9b..65c059e9f10 100644 --- a/tff_modular/modules/nabbers/code/nabber_bodyparts.dm +++ b/tff_modular/modules/nabbers/code/nabber_bodyparts.dm @@ -30,6 +30,12 @@ feature_key = OFFSET_FACEMASK, offset_y = list("north" = 7, "south" = 7, "east" = 7, "west" = 7), ) + worn_glasses_offset = new( + attached_part = src, + feature_key = OFFSET_GLASSES, + offset_y = list("north" = 10, "south" = 10, "east" = 10, "west" = 10), + offset_x = list("north" = 1, "south" = 1, "east" = 1, "west" = -1) + ) return ..() diff --git a/tff_modular/modules/nabbers/code/nabber_bolaimmunity.dm b/tff_modular/modules/nabbers/code/nabber_bolaimmunity.dm new file mode 100644 index 00000000000..ec6f41597b8 --- /dev/null +++ b/tff_modular/modules/nabbers/code/nabber_bolaimmunity.dm @@ -0,0 +1,57 @@ +/// Special type of legcuffs that do not affect movement or doesnt show up, but block other legcuffs +/obj/item/restraints/legcuffs/gas_placeholder + name = "serpentid thick tail" + desc = "You should not see this." + gender = PLURAL + icon_state = NONE + inhand_icon_state = "nabber_r_leg" + lefthand_file = 'tff_modular/modules/nabbers/icons/bodyparts/nabber_parts_greyscale.dmi' + righthand_file = 'tff_modular/modules/nabbers/icons/bodyparts/nabber_parts_greyscale.dmi' + w_class = WEIGHT_CLASS_TINY + slowdown = 0 + item_flags = DROPDEL | ABSTRACT + +/obj/item/restraints/legcuffs/gas_placeholder/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + +/obj/item/restraints/legcuffs/gas_placeholder/update_icon_state() + icon_state = NONE + return ..() + +/mob/living/carbon/human/cuff_resist(obj/item/cuffs, breakouttime = 1 MINUTES, cuff_break = 0) + if(isnabber(src)) + if(istype(cuffs, /obj/item/restraints/legcuffs/gas_placeholder)) + return FALSE + return ..() + +/mob/living/carbon/human/doUnEquip(obj/item/unequip_item, force, newloc, no_move, invdrop, silent) + if(isnabber(src)) + if(istype(unequip_item, /obj/item/restraints/legcuffs/gas_placeholder)) + return FALSE + return ..() + +/// У ГБСов этот слот всегда должен быть занять заглушкой, которую нельзя снять +/mob/living/carbon/human/update_worn_legcuffs(update_obscured = TRUE) + if(isnabber(src)) + return FALSE + else + return ..() + +/datum/species/nabber/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self, ignore_equipped, indirect_action) + if(slot == ITEM_SLOT_LEGCUFFED) + return FALSE + . = ..() + +// Это ужас +/obj/item/restraints/legcuffs/gas_placeholder/canStrip(mob/stripper, mob/owner) + INVOKE_ASYNC(src, PROC_REF(touch_ze_bug), stripper, owner) + return ..() + +/obj/item/restraints/legcuffs/gas_placeholder/proc/touch_ze_bug(mob/stripper, mob/owner) + owner.visible_message( + span_purple("[stripper] лапает хвост ГБСа. Кажется зря."), + span_purple("[stripper] лапает мой хвост! Кажется зря."), + blind_message = span_hear("You hear lewd bug noises."), + ) + playsound(get_turf(owner), 'modular_nova/modules/modular_items/lewd_items/sounds/vax2.ogg', 50, TRUE) diff --git a/tff_modular/modules/nabbers/code/nabber_huds.dm b/tff_modular/modules/nabbers/code/nabber_huds.dm new file mode 100644 index 00000000000..af7e5a9bd2c --- /dev/null +++ b/tff_modular/modules/nabbers/code/nabber_huds.dm @@ -0,0 +1,90 @@ +#define NABBER_HUD_Y_SHIFT 12 + +/mob/living/carbon/human/species/nabber/med_hud_set_status() + . = ..() + var/image/holder = hud_list?[STATUS_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/species/nabber/med_hud_set_health() + . = ..() + var/image/holder = hud_list?[HEALTH_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/species/nabber/sec_hud_set_ID() + . = ..() + var/image/holder = hud_list[ID_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + var/image/permit_holder = hud_list[PERMIT_HUD] + if (isnull(permit_holder)) + return + permit_holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/species/nabber/sec_hud_set_security_status() + . = ..() + var/image/holder = hud_list[WANTED_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/species/nabber/sec_hud_set_implants() + . = ..() + var/image/holder + for(var/i in (list(IMPSEC_FIRST_HUD, IMPLOYAL_HUD, IMPSEC_SECOND_HUD) & hud_list)) + holder = hud_list[i] + if(isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/med_hud_set_status() + . = ..() + if(isnabber(src)) + var/image/holder = hud_list?[STATUS_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/med_hud_set_health() + . = ..() + if(isnabber(src)) + var/image/holder = hud_list?[HEALTH_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/sec_hud_set_ID() + . = ..() + if(isnabber(src)) + var/image/holder = hud_list[ID_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + var/image/permit_holder = hud_list[PERMIT_HUD] + if (isnull(permit_holder)) + return + permit_holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/sec_hud_set_security_status() + . = ..() + if(isnabber(src)) + var/image/holder = hud_list[WANTED_HUD] + if (isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +/mob/living/carbon/human/sec_hud_set_implants() + . = ..() + if(isnabber(src)) + var/image/holder + for(var/i in (list(IMPSEC_FIRST_HUD, IMPLOYAL_HUD, IMPSEC_SECOND_HUD) & hud_list)) + holder = hud_list[i] + if(isnull(holder)) + return + holder.pixel_y += NABBER_HUD_Y_SHIFT + +#undef NABBER_HUD_Y_SHIFT diff --git a/tff_modular/modules/nabbers/code/nabber_language.dm b/tff_modular/modules/nabbers/code/nabber_language.dm new file mode 100644 index 00000000000..4f1dc00564c --- /dev/null +++ b/tff_modular/modules/nabbers/code/nabber_language.dm @@ -0,0 +1,122 @@ +/datum/language/nabber + name = "Giant Armored Serpentid" + desc = "A complex language that contains various sounds and movements, spoken only by Serpentids." + key = "N" + syllables = null + special_characters = null + default_priority = 70 + + flags = NO_STUTTER | TONGUELESS_SPEECH + always_use_default_namelist = TRUE + icon_state = "animal" + secret = TRUE + +/datum/language/nabber/scramble(input) + + var/scrambled_text = "[pick("ритмично", "коротко", "быстро", "громко", "мелодично", "монотонно", "резко", "характерно")] \ + [pick("жужжит", "щёлкает", "верещит", "стрекочет")] \ + [pick("пару раз" , "несколько раз", "три раза")]." + + add_to_cache(input, scrambled_text) + + return scrambled_text + +/datum/language_holder/nabber + understood_languages = list( + /datum/language/common = list(LANGUAGE_MIND), + /datum/language/nabber = list(LANGUAGE_MIND), + ) + spoken_languages = list( + /datum/language/common = list(LANGUAGE_ATOM), + /datum/language/nabber = list(LANGUAGE_SPECIES), + ) + selected_language = /datum/language/common + +/obj/item/implant/gas_sol_speaker + name = "sol speech synthesizer implant" + actions_types = null + // Implant gets damaged evevy emp_act(). If 0 - its fine. 1 - it stops working. Any more damage will give burn damage + // TODO: add more stages + var/emp_damage = 0 + +/obj/item/implant/gas_sol_speaker/get_data() + return "Implant Specifications:
\ + Name: Sol Government Giant Armored Serpentid Speech Synthesizer Beta v0.3
\ + Life: Activates upon speech attempt.
\ + Important Notes: Does not work on other species.
\ +
\ + Implant Details:
\ + Function: Contains a small electonic speech syntesizer, similar to the borg ones and AI-processing unit, which detects GASs attempt to speak and, \ + if enabled, will translate its neuron signals into comprehensible human language.
\ + Changelog: No longer causes infinite scream loop once GAS is angered.
\ + Known bugs: EMP tends to damage the implant power source. Will isolate it later.
" + +/obj/item/implant/gas_sol_speaker/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE) + . = ..() + if(isnabber(target) && !QDELING(target)) + var/mob/living/carbon/human/species/nabber/our_gas = target + our_gas.grant_language(/datum/language/common, language_flags = SPOKEN_LANGUAGE, source = LANGUAGE_ATOM) + +/obj/item/implant/gas_sol_speaker/removed(mob/target, silent = FALSE, special = FALSE) + . = ..() + if(isnabber(target) && !QDELING(target)) + var/mob/living/carbon/human/species/nabber/our_gas = target + our_gas.remove_language(/datum/language/common, language_flags = SPOKEN_LANGUAGE) + if(our_gas.has_status_effect(/datum/status_effect/speech/stutter/nabber)) + our_gas.remove_status_effect(/datum/status_effect/speech/stutter/nabber) + +/obj/item/implant/gas_sol_speaker/emp_act(severity) + . = ..() + switch(emp_damage) + if(0) + emp_damage += 1 + if(imp_in && isnabber(imp_in)) + var/mob/living/carbon/human/species/nabber/our_gas = imp_in + our_gas.apply_status_effect(/datum/status_effect/speech/stutter/nabber, -1) + to_chat(imp_in, span_hear("You hear something inside of you zap silently.")) + if (1) + emp_damage += 1 + if(imp_in && isnabber(imp_in)) + var/mob/living/carbon/human/species/nabber/our_gas = imp_in + our_gas.remove_language(/datum/language/common, language_flags = SPOKEN_LANGUAGE) + if(our_gas.has_status_effect(/datum/status_effect/speech/stutter/nabber)) + our_gas.remove_status_effect(/datum/status_effect/speech/stutter/nabber) + to_chat(imp_in, span_hear("You hear something inside of you zap silently.")) + if (2) + if (imp_in) + imp_in.apply_damage(5, BURN) + to_chat(imp_in, span_warning("You feel something burning inside you!")) + +/// Special type of stutter, only affecting non nabber languages +/datum/status_effect/speech/stutter/nabber + id = "gas_stutter" + alert_type = null + duration = -1 + +/datum/status_effect/speech/stutter/nabber/handle_message(datum/source, list/message_args) + if(isnabber(owner) && ispath(owner.get_selected_language(), /datum/language/nabber)) + stutter_prob = 0 + else + stutter_prob = 80 + return ..() + +/obj/item/implanter/gas_sol_speaker + name = "implanter (GAS Sol speaker)" + imp_type = /obj/item/implant/gas_sol_speaker + +/obj/item/implantcase/gas_sol_speaker + name = "implant case - 'GAS Sol speaker'" + desc = "A glass case containing a sol speaker, designed for GAS." + imp_type = /obj/item/implant/gas_sol_speaker + +/datum/design/implant_gassolspeaker + name = "GAS Sol speaker Implant Case" + desc = "Makes GAS able to speak normally." + id = "implant_gasspeech" + build_type = PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/glass =SMALL_MATERIAL_AMOUNT*5, /datum/material/silver =SMALL_MATERIAL_AMOUNT*5) + build_path = /obj/item/implantcase/gas_sol_speaker + category = list( + RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_HEALTH + ) + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE diff --git a/tff_modular/modules/nabbers/code/nabber_organs.dm b/tff_modular/modules/nabbers/code/nabber_organs.dm index 7bb98527030..083f1c56439 100644 --- a/tff_modular/modules/nabbers/code/nabber_organs.dm +++ b/tff_modular/modules/nabbers/code/nabber_organs.dm @@ -13,6 +13,14 @@ liked_foodtypes = RAW | GORE | GRAIN disliked_foodtypes = CLOTH | FRIED | TOXIC toxic_foodtypes = DAIRY + var/static/list/languages_possible_gas = typecacheof(list( + /datum/language/common, + /datum/language/nabber, + )) + +/obj/item/organ/internal/tongue/nabber/get_possible_languages() + RETURN_TYPE(/list) + return languages_possible_gas /obj/item/organ/internal/ears/nabber name = "nabber ears" @@ -30,13 +38,6 @@ icon_state = "brain" /obj/item/organ/internal/eyes/nabber - name = "nabber eyes" - desc = "Small orange orbs." - icon = ORGGAN_ICON_NABBER - icon_state = "eyes" - flash_protect = FLASH_PROTECTION_SENSITIVE - -/obj/item/organ/internal/eyes/robotic/nabber name = "nabber eyes" desc = "Small orange orbs. With pair welding shield linses." icon = ORGGAN_ICON_NABBER @@ -45,7 +46,7 @@ var/datum/action/toggle_welding/shield var/active = FALSE -/obj/item/organ/internal/eyes/robotic/nabber/Insert(mob/living/carbon/eye_recipient, special, movement_flags) +/obj/item/organ/internal/eyes/nabber/Insert(mob/living/carbon/eye_recipient, special, movement_flags) . = ..() shield = new(eye_recipient) shield.button_icon = ORGGAN_ICON_NABBER @@ -53,7 +54,7 @@ shield.Grant(eye_recipient) shield.eyes = src -/obj/item/organ/internal/eyes/robotic/nabber/proc/toggle_shielding() +/obj/item/organ/internal/eyes/nabber/proc/toggle_shielding() if(!owner) return @@ -72,7 +73,7 @@ owner.update_tint() owner.balloon_alert(owner, "Welder eyelids open!") -/obj/item/organ/internal/eyes/robotic/nabber/Remove(mob/living/carbon/eye_owner, special) +/obj/item/organ/internal/eyes/nabber/Remove(mob/living/carbon/eye_owner, special) . = ..() shield.Destroy() active = FALSE diff --git a/tgstation.dme b/tgstation.dme index 3a7331b8b9b..8841314acef 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -8871,8 +8871,12 @@ #include "tff_modular\modules\modular_automapper\replacer.dm" #include "tff_modular\modules\nabbers\code\_nabbers.dm" #include "tff_modular\modules\nabbers\code\nabber_bodyparts.dm" +#include "tff_modular\modules\nabbers\code\nabber_bolaimmunity.dm" #include "tff_modular\modules\nabbers\code\nabber_emotes.dm" +#include "tff_modular\modules\nabbers\code\nabber_huds.dm" +#include "tff_modular\modules\nabbers\code\nabber_language.dm" #include "tff_modular\modules\nabbers\code\nabber_organs.dm" +#include "tff_modular\modules\nabbers\code\abilites\agrograb.dm" #include "tff_modular\modules\nabbers\code\abilites\camouflage.dm" #include "tff_modular\modules\nabbers\code\abilites\nabber_combat_effect.dm" #include "tff_modular\modules\nabbers\code\abilites\nabber_threat.dm" From 82294c076a97ca435f5933dc4848168854281aa5 Mon Sep 17 00:00:00 2001 From: Yaroslav Nurkov <78199449+AnywayFarus@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:46:51 +0300 Subject: [PATCH 2/6] Automatic changelog for PR #4957 [ci skip] --- html/changelogs/AutoChangeLog-pr-4957.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4957.yml diff --git a/html/changelogs/AutoChangeLog-pr-4957.yml b/html/changelogs/AutoChangeLog-pr-4957.yml new file mode 100644 index 00000000000..900b7d4e96e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4957.yml @@ -0,0 +1,17 @@ +author: "Oxotnak" +delete-after: True +changes: + - rscadd: "GAS now have basic noslip" + - rscadd: "GAS now able to grab in scythes" + - rscadd: "GAS now faster in threat form" + - rscadd: "GAS now raises scythes faster and can move at same time" + - rscadd: "GAS now able to wear scouter-huds" + - rscadd: "GAS now more resistant to tackle" + - rscadd: "GAS now have own language" + - rscadd: "GAS now have sol implant. Damages by emp. Fixable via replacing implant" + - rscadd: "GAS now immune to bolas and beartrap" + - rscadd: "GAS now can raise scythes in cuffs. Can't be cuffed with raised scythes" + - rscadd: "GAS now moves fast while grabbing in scythes" + - rscadd: "GAS now have special cookie" + - bugfix: "GAS now can't pick languages" + - qol: "GAS now have quirks blacklist" \ No newline at end of file From 2a63441a1d3dea52a91772d516bc40173774bb1e Mon Sep 17 00:00:00 2001 From: Axidy <76065506+Axidyuwu@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:09:46 +0200 Subject: [PATCH 3/6] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC=D0=B0?= =?UTF-8?q?=D0=B5=D0=BC=20=D1=83=D1=80=D0=BE=D0=BD=20=D0=A2=D0=93=20=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D0=B3=D0=BE=D0=B2=20(=D0=B2=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=B0=D1=85=20=D0=B8=D0=B4=D0=B5=D0=B0=D0=BB?= =?UTF-8?q?=D0=B0=20=D0=B2=20=D0=B1=D0=B0=D0=BB=D0=B0=D0=B4=D0=B5=20=D0=BE?= =?UTF-8?q?=20=D0=BA=D1=80=D1=8B=D1=81=D0=BE=D0=BF=D1=83=D1=88=D0=BA=D0=B0?= =?UTF-8?q?=D1=85)=20(#5159)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sir buffs a lot * funny descriptions * 30 to 85 --- code/modules/antagonists/heretic/items/heretic_blades.dm | 4 ++-- code/modules/antagonists/heretic/knowledge/lock_lore.dm | 2 +- code/modules/antagonists/heretic/magic/blood_cleave.dm | 2 +- code/modules/antagonists/heretic/magic/blood_siphon.dm | 4 ++-- code/modules/antagonists/heretic/magic/furious_steel.dm | 2 +- code/modules/antagonists/heretic/magic/mind_gate.dm | 2 +- code/modules/antagonists/heretic/magic/void_phase.dm | 2 +- code/modules/antagonists/heretic/magic/void_pull.dm | 2 +- .../antagonists/heretic/status_effects/mark_effects.dm | 2 +- code/modules/antagonists/nightmare/nightmare_equipment.dm | 2 +- code/modules/antagonists/voidwalker/voidwalker_void_eater.dm | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/modules/antagonists/heretic/items/heretic_blades.dm b/code/modules/antagonists/heretic/items/heretic_blades.dm index 6e0d3d7d186..be8b59a23e7 100644 --- a/code/modules/antagonists/heretic/items/heretic_blades.dm +++ b/code/modules/antagonists/heretic/items/heretic_blades.dm @@ -13,7 +13,7 @@ slot_flags = ITEM_SLOT_BELT sharpness = SHARP_EDGED w_class = WEIGHT_CLASS_NORMAL - force = 20 + force = 28 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 20 throwforce = 10 wound_bonus = 5 bare_wound_bonus = 15 @@ -219,7 +219,7 @@ name = "\improper cursed blade" desc = "A dark blade, cursed to bleed forever. In constant struggle between the eldritch and the dark, it is forced to accept any wielder as its master. \ Its eye's cornea drips blood endlessly into the ground, yet its piercing gaze remains on you." - force = 25 + force = 32 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 25 throwforce = 15 block_chance = 35 wound_bonus = 25 diff --git a/code/modules/antagonists/heretic/knowledge/lock_lore.dm b/code/modules/antagonists/heretic/knowledge/lock_lore.dm index 28e02112fd7..a618a0fcba1 100644 --- a/code/modules/antagonists/heretic/knowledge/lock_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/lock_lore.dm @@ -146,7 +146,7 @@ wound_type = /datum/wound/slash/flesh/critical research_tree_icon_path = 'icons/ui_icons/antags/heretic/knowledge.dmi' research_tree_icon_state = "blade_upgrade_lock" - var/chance = 35 + var/chance = 55 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 35 /datum/heretic_knowledge/blade_upgrade/flesh/lock/do_melee_effects(mob/living/source, mob/living/target, obj/item/melee/sickly_blade/blade) if(prob(chance)) diff --git a/code/modules/antagonists/heretic/magic/blood_cleave.dm b/code/modules/antagonists/heretic/magic/blood_cleave.dm index d5317f23e34..431a08fa7b2 100644 --- a/code/modules/antagonists/heretic/magic/blood_cleave.dm +++ b/code/modules/antagonists/heretic/magic/blood_cleave.dm @@ -47,7 +47,7 @@ var/obj/item/bodypart/bodypart = pick(victim.bodyparts) var/datum/wound/slash/flesh/crit_wound = new wound_type() crit_wound.apply_wound(bodypart) - victim.apply_damage(20, BURN, wound_bonus = CANT_WOUND) + victim.apply_damage(30, BURN, wound_bonus = CANT_WOUND) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 20 new /obj/effect/temp_visual/cleave(get_turf(victim)) diff --git a/code/modules/antagonists/heretic/magic/blood_siphon.dm b/code/modules/antagonists/heretic/magic/blood_siphon.dm index 1801b6d9dbc..98f9a10130c 100644 --- a/code/modules/antagonists/heretic/magic/blood_siphon.dm +++ b/code/modules/antagonists/heretic/magic/blood_siphon.dm @@ -40,8 +40,8 @@ ) var/mob/living/living_owner = owner - cast_on.adjustBruteLoss(20) - living_owner.adjustBruteLoss(-20) + cast_on.adjustBruteLoss(25) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 20 + living_owner.adjustBruteLoss(-25) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 20 if(!cast_on.blood_volume || !living_owner.blood_volume) return TRUE diff --git a/code/modules/antagonists/heretic/magic/furious_steel.dm b/code/modules/antagonists/heretic/magic/furious_steel.dm index 9414ca9d711..d71659b5af4 100644 --- a/code/modules/antagonists/heretic/magic/furious_steel.dm +++ b/code/modules/antagonists/heretic/magic/furious_steel.dm @@ -101,7 +101,7 @@ icon = 'icons/effects/eldritch.dmi' icon_state = "dio_knife" speed = 2 - damage = 25 + damage = 35 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 25 armour_penetration = 100 sharpness = SHARP_EDGED wound_bonus = 15 diff --git a/code/modules/antagonists/heretic/magic/mind_gate.dm b/code/modules/antagonists/heretic/magic/mind_gate.dm index 7963c4d6c02..7c95a4878c5 100644 --- a/code/modules/antagonists/heretic/magic/mind_gate.dm +++ b/code/modules/antagonists/heretic/magic/mind_gate.dm @@ -32,7 +32,7 @@ return FALSE cast_on.adjust_confusion(10 SECONDS) - cast_on.adjustOxyLoss(30) + cast_on.adjustOxyLoss(40) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 30 cast_on.cause_hallucination(get_random_valid_hallucination_subtype(/datum/hallucination/body), "Mind gate, cast by [owner]") cast_on.cause_hallucination(/datum/hallucination/delusion/preset/heretic/gate, "Caused by mindgate") cast_on.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30) diff --git a/code/modules/antagonists/heretic/magic/void_phase.dm b/code/modules/antagonists/heretic/magic/void_phase.dm index 473fa057cf5..17188ba86ac 100644 --- a/code/modules/antagonists/heretic/magic/void_phase.dm +++ b/code/modules/antagonists/heretic/magic/void_phase.dm @@ -56,7 +56,7 @@ continue if(living_mob.can_block_magic(antimagic_flags)) continue - living_mob.apply_damage(40, BRUTE, wound_bonus = CANT_WOUND) + living_mob.apply_damage(60, BRUTE, wound_bonus = CANT_WOUND) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 40 living_mob.apply_status_effect(/datum/status_effect/void_chill, 1) /obj/effect/temp_visual/voidin diff --git a/code/modules/antagonists/heretic/magic/void_pull.dm b/code/modules/antagonists/heretic/magic/void_pull.dm index 4e73ff6f49b..5473990f51c 100644 --- a/code/modules/antagonists/heretic/magic/void_pull.dm +++ b/code/modules/antagonists/heretic/magic/void_pull.dm @@ -31,7 +31,7 @@ // Before we cast the actual effects, deal AOE damage to anyone adjacent to us for(var/mob/living/nearby_living as anything in get_things_to_cast_on(cast_on, damage_radius)) - nearby_living.apply_damage(30, BRUTE, wound_bonus = CANT_WOUND) + nearby_living.apply_damage(40, BRUTE, wound_bonus = CANT_WOUND) // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 30 nearby_living.apply_status_effect(/datum/status_effect/void_chill, 1) /datum/action/cooldown/spell/aoe/void_pull/get_things_to_cast_on(atom/center, radius_override = 1) diff --git a/code/modules/antagonists/heretic/status_effects/mark_effects.dm b/code/modules/antagonists/heretic/status_effects/mark_effects.dm index de895d33caa..c4ef6e4ee49 100644 --- a/code/modules/antagonists/heretic/status_effects/mark_effects.dm +++ b/code/modules/antagonists/heretic/status_effects/mark_effects.dm @@ -79,7 +79,7 @@ /datum/status_effect/eldritch/ash/on_effect() if(iscarbon(owner)) var/mob/living/carbon/carbon_owner = owner - carbon_owner.adjustStaminaLoss(6 * repetitions) // first one = 30 stam + carbon_owner.adjustStaminaLoss(17 * repetitions) // first one = 85 stam; FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 6 carbon_owner.adjustFireLoss(3 * repetitions) // first one = 15 burn for(var/mob/living/carbon/victim in shuffle(range(1, carbon_owner))) if(IS_HERETIC(victim) || victim == carbon_owner) diff --git a/code/modules/antagonists/nightmare/nightmare_equipment.dm b/code/modules/antagonists/nightmare/nightmare_equipment.dm index 52a687f9ac7..d22595c0808 100644 --- a/code/modules/antagonists/nightmare/nightmare_equipment.dm +++ b/code/modules/antagonists/nightmare/nightmare_equipment.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/weapons/changeling_items.dmi' icon_state = "arm_blade" inhand_icon_state = "arm_blade" - force = 25 + force = 30 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 25 armour_penetration = 35 lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' diff --git a/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm b/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm index 9bf5b3c2664..7bc369f8993 100644 --- a/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm +++ b/code/modules/antagonists/voidwalker/voidwalker_void_eater.dm @@ -7,7 +7,7 @@ icon = 'icons/obj/weapons/voidwalker_items.dmi' icon_state = "tentacle" inhand_icon_state = "tentacle" - force = 25 + force = 35 // FLUFFY FRONTIER EDIT: ANTAG BUFF #5159; original: 25 armour_penetration = 35 lefthand_file = 'icons/mob/inhands/antag/voidwalker_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/voidwalker_righthand.dmi' From 7a456b6104aab72ac895c8383d1037d7928c3a19 Mon Sep 17 00:00:00 2001 From: Yaroslav Nurkov <78199449+AnywayFarus@users.noreply.github.com> Date: Thu, 19 Dec 2024 19:10:12 +0300 Subject: [PATCH 4/6] Automatic changelog for PR #5159 [ci skip] --- html/changelogs/AutoChangeLog-pr-5159.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5159.yml diff --git a/html/changelogs/AutoChangeLog-pr-5159.yml b/html/changelogs/AutoChangeLog-pr-5159.yml new file mode 100644 index 00000000000..dd718c2744d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5159.yml @@ -0,0 +1,4 @@ +author: "Axidyuwu" +delete-after: True +changes: + - balance: "Damage buffs for herethic, void walker and nightmare items or spells" \ No newline at end of file From e3d6e73b51493806ecffb1b5400950f6f5481e0f Mon Sep 17 00:00:00 2001 From: Yaroslav Nurkov <78199449+AnywayFarus@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:37:54 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=90=D0=BF=D0=B3=D1=80=D0=B5=D0=B9=D0=B4?= =?UTF-8?q?=20=D0=B8=D0=B2=D0=B5=D0=BD=D1=82=D0=BE=D0=B4=D0=B5=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=20(#4973)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * base * todos * forgeted * is_eventmaker fix * client in client method * another fix with eventmaker check * refactor * hehe * dme * Apply suggestions from code review * add verbs to eventers --------- Co-authored-by: Iajret Co-authored-by: Iajret <8430839+Iajret@users.noreply.github.com> --- SQL/optimisations_2017-02-19.sql | 2 +- SQL/tgstation_schema.sql | 2 +- SQL/tgstation_schema_prefixed.sql | 2 +- code/__DEFINES/speech_channels.dm | 1 + .../_globalvars/lists/hidden_verbs.dm | 15 +++++ .../~ff_defines/_globalvars/logging.dm | 1 + code/__DEFINES/~ff_defines/span.dm | 1 + code/__HELPERS/hearted.dm | 2 +- code/controllers/subsystem/admin_verbs.dm | 1 - code/controllers/subsystem/stickyban.dm | 2 +- code/datums/brain_damage/imaginary_friend.dm | 7 +- code/modules/admin/admin.dm | 11 +++- code/modules/admin/known_alts.dm | 4 +- code/modules/admin/sql_ban_system.dm | 8 +-- code/modules/admin/sql_message_system.dm | 65 ++++++++++++++----- code/modules/admin/stickyban.dm | 18 ++--- code/modules/admin/topic.dm | 7 ++ code/modules/admin/verbs/admingame.dm | 39 +++++------ code/modules/admin/verbs/adminsay.dm | 9 ++- code/modules/admin/verbs/maprotation.dm | 2 +- code/modules/admin/verbs/secrets.dm | 4 ++ code/modules/admin/verbs/server.dm | 6 +- code/modules/admin/view_variables/topic.dm | 2 +- code/modules/client/client_procs.dm | 28 ++++---- .../modules/mob/dead/observer/observer_say.dm | 7 +- code/modules/mob/living/living_say.dm | 7 +- code/modules/tgui_input/say_modal/modal.dm | 2 +- code/modules/tgui_input/say_modal/speech.dm | 5 ++ config/nova/config_nova.txt | 1 + config/nova/eventmakers.txt | 0 .../logging/categories/log_category_game.dm | 5 ++ .../code/subsystem/player_ranks.dm | 1 - tff_modular/modules/eventers/eventmaker.dm | 34 ++++++++++ .../modules/eventers/eventmaker_verbs.dm | 13 ++++ .../modules/eventers/random_stuff_ban.dm | 14 ++++ tgstation.dme | 6 ++ tgui/packages/tgui-panel/chat/constants.ts | 9 +++ .../tgui-panel/styles/tgchat/chat-dark.scss | 8 +++ .../tgui-panel/styles/tgchat/chat-light.scss | 8 +++ tgui/packages/tgui-say/ChannelIterator.ts | 8 ++- tgui/packages/tgui-say/constants/index.tsx | 1 + tgui/packages/tgui-say/styles/colors.scss | 2 + tgui/packages/tgui/interfaces/Secrets.jsx | 32 ++++----- 43 files changed, 302 insertions(+), 100 deletions(-) create mode 100644 code/__DEFINES/~ff_defines/_globalvars/lists/hidden_verbs.dm create mode 100644 code/__DEFINES/~ff_defines/_globalvars/logging.dm create mode 100644 code/__DEFINES/~ff_defines/span.dm create mode 100644 config/nova/eventmakers.txt create mode 100644 tff_modular/modules/eventers/eventmaker.dm create mode 100644 tff_modular/modules/eventers/eventmaker_verbs.dm create mode 100644 tff_modular/modules/eventers/random_stuff_ban.dm diff --git a/SQL/optimisations_2017-02-19.sql b/SQL/optimisations_2017-02-19.sql index 1bb19cc6677..a98386186f2 100644 --- a/SQL/optimisations_2017-02-19.sql +++ b/SQL/optimisations_2017-02-19.sql @@ -124,7 +124,7 @@ ALTER TABLE `library` , CHANGE COLUMN `deleted` `deleted` TINYINT(1) UNSIGNED NULL DEFAULT NULL; ALTER TABLE `messages` - CHANGE COLUMN `type` `type` ENUM('memo', 'message', 'message sent', 'note', 'watchlist entry') NOT NULL + CHANGE COLUMN `type` `type` ENUM('memo', 'message', 'message sent', 'note', 'watchlist entry', 'eventmaker note') NOT NULL , CHANGE COLUMN `text` `text` VARCHAR(2048) NOT NULL , CHANGE COLUMN `secret` `secret` TINYINT(1) UNSIGNED NOT NULL; diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 01d04af965f..877ce168b11 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -307,7 +307,7 @@ DROP TABLE IF EXISTS `messages`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `messages` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `type` enum('memo','message','message sent','note','watchlist entry') NOT NULL, + `type` enum('memo','message','message sent','note','watchlist entry', 'eventmaker note') NOT NULL, `targetckey` varchar(32) NOT NULL, `adminckey` varchar(32) NOT NULL, `text` varchar(2048) NOT NULL, diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 99a4191172c..7c918b144db 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -305,7 +305,7 @@ DROP TABLE IF EXISTS `SS13_messages`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `SS13_messages` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `type` enum('memo','message','message sent','note','watchlist entry') NOT NULL, + `type` enum('memo','message','message sent','note','watchlist entry', 'eventmaker note') NOT NULL, `targetckey` varchar(32) NOT NULL, `adminckey` varchar(32) NOT NULL, `text` varchar(2048) NOT NULL, diff --git a/code/__DEFINES/speech_channels.dm b/code/__DEFINES/speech_channels.dm index 9f1526ebd56..4e628dad0d5 100644 --- a/code/__DEFINES/speech_channels.dm +++ b/code/__DEFINES/speech_channels.dm @@ -4,3 +4,4 @@ #define ME_CHANNEL "Me" #define OOC_CHANNEL "OOC" #define ADMIN_CHANNEL "Admin" +#define EVENT_CHANNEL "Event" // TFF ADDITION - Eventmaker diff --git a/code/__DEFINES/~ff_defines/_globalvars/lists/hidden_verbs.dm b/code/__DEFINES/~ff_defines/_globalvars/lists/hidden_verbs.dm new file mode 100644 index 00000000000..9e4b6fa181d --- /dev/null +++ b/code/__DEFINES/~ff_defines/_globalvars/lists/hidden_verbs.dm @@ -0,0 +1,15 @@ +GLOBAL_LIST_INIT(eventmakers_blacklist_verbs, list( + //Admin + "Add PB Bypass" = TRUE, "ASay" = TRUE, "Cross-server Help Request" = TRUE, + "Get Current Logs" = TRUE, "Get Server Logs" = TRUE, "Known Alts Panel" = TRUE, + "loudAsay" = TRUE, "Paintings manager" = TRUE, "Player Playtime" = TRUE, "Player Ticket History" = TRUE, + "Reload Admins" = TRUE, "Revoke PB Bypass" = TRUE, "Trophy Manager" = TRUE, "View Round Logs" = TRUE, + "Load Away Mission" = TRUE, "Mass Zombie Cure" = TRUE, "Mass Zombie Infection" = TRUE, + "Polymorph All" = TRUE, "Title Screen: Change" = TRUE, "Title Screen: Set HTML" = TRUE, "Title Screen: Set Notice" = TRUE, + "Show Lag Switches" = TRUE, + //Server + "Reestablish DB Connection" = TRUE, "Reset Player OOC Color" = TRUE, "Set Player OOC Color" = TRUE, + "Toggle Antag OOC" = TRUE, "Toggle CDN" = TRUE, "Toggle OOC" = TRUE, "Toggle Security OOC" = TRUE, + //Debug + "Debug Stat Panel" = TRUE, "Migrate Player Ranks" = TRUE, "Open LUA Editor" = TRUE, "Re-establish Connection To TTS" = TRUE, "Reload Configuration" = TRUE, "Run Empty Query" = TRUE, "View Runtime" = TRUE +)) diff --git a/code/__DEFINES/~ff_defines/_globalvars/logging.dm b/code/__DEFINES/~ff_defines/_globalvars/logging.dm new file mode 100644 index 00000000000..3dddcc20c13 --- /dev/null +++ b/code/__DEFINES/~ff_defines/_globalvars/logging.dm @@ -0,0 +1 @@ +#define LOG_CATEGORY_GAME_EVENTMAKER "game-eventmaker" diff --git a/code/__DEFINES/~ff_defines/span.dm b/code/__DEFINES/~ff_defines/span.dm new file mode 100644 index 00000000000..170453b8d49 --- /dev/null +++ b/code/__DEFINES/~ff_defines/span.dm @@ -0,0 +1 @@ +#define span_eventmaker(str) ("" + str + "") diff --git a/code/__HELPERS/hearted.dm b/code/__HELPERS/hearted.dm index d8f7832cbc0..5594a0f63f8 100644 --- a/code/__HELPERS/hearted.dm +++ b/code/__HELPERS/hearted.dm @@ -33,7 +33,7 @@ continue hearted_mob.client.adjust_heart() message += "[hearted_ckey][i == hearts.len ? "" : ", "]" - message_admins(message.Join()) + message_admins(message.Join(), TRUE) /// Ask someone if they'd like to award a commendation for the round, 3 tries to get the name they want before we give up /mob/proc/query_heart(attempt=1) diff --git a/code/controllers/subsystem/admin_verbs.dm b/code/controllers/subsystem/admin_verbs.dm index 9496b95d998..f977c17dd6e 100644 --- a/code/controllers/subsystem/admin_verbs.dm +++ b/code/controllers/subsystem/admin_verbs.dm @@ -109,7 +109,6 @@ SUBSYSTEM_DEF(admin_verbs) if(!admin.holder.check_for_rights(verb_singleton.permissions)) to_chat(admin, span_adminnotice("You lack the permissions to do this.")) return - var/old_usr = usr usr = admin.mob // THE MACRO ENSURES THIS EXISTS. IF IT EVER DOESNT EXIST SOMEONE DIDNT USE THE DAMN MACRO! diff --git a/code/controllers/subsystem/stickyban.dm b/code/controllers/subsystem/stickyban.dm index 757df6a2266..aecf0ca7c13 100644 --- a/code/controllers/subsystem/stickyban.dm +++ b/code/controllers/subsystem/stickyban.dm @@ -46,7 +46,7 @@ SUBSYSTEM_DEF(stickyban) //get_stickyban_from_ckey returned null, aka something broke. Notify admins about it if (!ban) - message_admins("Failed to apply stickyban for [bannedkey]. Check the DB for corrupt stickyban entries.") + message_admins("Failed to apply stickyban for [bannedkey]. Check the DB for corrupt stickyban entries.", TRUE) log_admin_private ("Failed to apply stickyban for [bannedkey]. Check the DB for corrupt stickyban entries.") continue diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 6945648a734..750362f5880 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -227,7 +227,12 @@ message = capitalize(message) if(message_mods[RADIO_EXTENSION] == MODE_ADMIN) - SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) + // TFF ADDITION START - Eventmaker + if(client.is_eventmaker()) + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_eventmaker_say, message) + else + // TFF ADDITION END + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) return if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5f40de037f4..963e85f1450 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1,7 +1,14 @@ //////////////////////////////// -/proc/message_admins(msg) +/proc/message_admins(msg, not_to_eventmaker) // TFF EDIT. ORIGINAL /proc/message_admins(msg) msg = "ADMIN LOG: [msg]" - to_chat(GLOB.admins, +// TFF CHANGE START - EVENTMAKERS + var/list/addressee = GLOB.admins.Copy() + if(not_to_eventmaker) + for(var/client/admin in GLOB.admins) + if(admin.is_eventmaker()) + addressee -= admin +// TFF CHANGE END + to_chat(addressee, // TFF EDIT. ORIGINAL GLOB.admins, type = MESSAGE_TYPE_ADMINLOG, html = msg, confidential = TRUE) diff --git a/code/modules/admin/known_alts.dm b/code/modules/admin/known_alts.dm index 4105c7f4edc..268e72f727b 100644 --- a/code/modules/admin/known_alts.dm +++ b/code/modules/admin/known_alts.dm @@ -65,7 +65,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new) if (query_add_known_alt.warn_execute()) var/message = "[key_name(usr)] has added a new known alt connection between [ckey1] and [ckey2]." - message_admins(message) + message_admins(message, TRUE) log_admin_private(message) cached_known_alts = null @@ -115,7 +115,7 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new) if (query_delete_known_alt.warn_execute()) var/message = "[key_name(usr)] has deleted the known alt connection between [result[1]] and [result[2]]." - message_admins(message) + message_admins(message, TRUE) log_admin_private(message) cached_known_alts = null diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 270907cb1ab..ef446f7c817 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -685,7 +685,7 @@ var/target = ban_target_string(player_key, player_ip, player_cid) var/msg = "has created a [global_ban ? "global" : "local"] [isnull(duration) ? "permanent" : "temporary [time_message]"] [applies_to_admins ? "admin " : ""][is_server_ban ? "server ban" : "role ban from [roles_to_ban.len] roles"] for [target]." // NOVA EDIT CHANGE - MULTISERVER log_admin_private("[kn] [msg][is_server_ban ? "" : " Roles: [roles_to_ban.Join(", ")]"] Reason: [reason]") - message_admins("[kna] [msg][is_server_ban ? "" : " Roles: [roles_to_ban.Join("\n")]"]\nReason: [reason]") + message_admins("[kna] [msg][is_server_ban ? "" : " Roles: [roles_to_ban.Join("\n")]"]\nReason: [reason]", TRUE) if(applies_to_admins) send2adminchat("BAN ALERT","[kn] [msg]") if(player_ckey) @@ -885,7 +885,7 @@ return qdel(query_unban) log_admin_private("[kn] has unbanned [target] from [role].") - message_admins("[kna] has unbanned [target] from [role].") + message_admins("[kna] has unbanned [target] from [role].", TRUE) var/client/C = GLOB.directory[player_key] if(C) build_ban_cache(C) @@ -930,7 +930,7 @@ return qdel(query_reban) log_admin_private("[kn] has rebanned [target] from [role].") - message_admins("[kna] has rebanned [target] from [role].") + message_admins("[kna] has rebanned [target] from [role].", TRUE) var/banned_player_message = span_boldannounce("[usr.client.key] has re-activated a removed ban from [role] for your key.") var/banned_other_message = span_boldannounce("[usr.client.key] has re-activated a removed ban from [role] for your IP or CID.") @@ -1041,7 +1041,7 @@ var/kn = key_name(usr) var/kna = key_name_admin(usr) log_admin_private("[kn] has edited the [changes_keys_text] of a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"].") //if a ban doesn't have a key it must have an ip and/or a cid to have reached this point normally - message_admins("[kna] has edited the [changes_keys_text] of a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"].") + message_admins("[kna] has edited the [changes_keys_text] of a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"].", TRUE) if(changes["Applies to admins"]) send2adminchat("BAN ALERT","[kn] has edited a ban for [old_key ? "[old_key]" : "[old_ip]-[old_cid]"] to [applies_to_admins ? "" : "not"]affect admins") diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index c44853646e3..52bebfd72d7 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -5,7 +5,7 @@ if(!type) return var/target_ckey = ckey(target_key) - if(!target_key && (type == "note" || type == "message" || type == "watchlist entry")) + if(!target_key && (type == "note" || type == "message" || type == "watchlist entry" || type == "eventmaker note")) // TFF EDIT - Eventmaker var/new_key = input(usr,"Who would you like to create a [type] for?","Enter a key or ckey",null) as null|text if(!new_key) return @@ -102,7 +102,7 @@ qdel(query_create_message) if(logged) log_admin_private(pm) - message_admins("[header]:
[text]") + message_admins("[header]:
[text]", TRUE) admin_ticket_log(target_ckey, "[header]
[text]") if(browse) browse_messages("[type]") @@ -146,7 +146,7 @@ var/m1 = "[user_key_name] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_key]: [text]" var/m2 = "[user_name_admin] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_key]:
[text]" log_admin_private(m1) - message_admins(m2) + message_admins(m2, TRUE) if(browse) browse_messages("[type]") else @@ -195,7 +195,7 @@ return qdel(query_edit_message) log_admin_private("[kn] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_text] to [new_text]") - message_admins("[kna] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from
[old_text]
to
[new_text]") + message_admins("[kna] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from
[old_text]
to
[new_text]", TRUE) if(browse) browse_messages("[type]") else @@ -266,7 +266,7 @@ return qdel(query_edit_message_expiry) log_admin_private("[kn] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [(old_expiry ? old_expiry : "no expiration date")] to [new_expiry]") - message_admins("[kna] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [(old_expiry ? old_expiry : "no expiration date")] to [new_expiry]") + message_admins("[kna] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [(old_expiry ? old_expiry : "no expiration date")] to [new_expiry]", TRUE) if(browse) browse_messages("[type]") else @@ -320,7 +320,7 @@ return qdel(query_edit_note_severity) log_admin_private("[kn] has edited the severity of a [type] for [target_key] made by [admin_key] from [old_severity] to [new_severity]") - message_admins("[kna] has edited the severity time of a [type] for [target_key] made by [admin_key] from [old_severity] to [new_severity]") + message_admins("[kna] has edited the severity time of a [type] for [target_key] made by [admin_key] from [old_severity] to [new_severity]", TRUE) browse_messages(target_ckey = ckey(target_key), agegate = TRUE) qdel(query_find_edit_note_severity) @@ -364,7 +364,7 @@ return qdel(query_message_secret) log_admin_private("[kn] has toggled [target_key]'s [type] made by [admin_key] to [secret ? "not secret" : "secret"]") - message_admins("[kna] has toggled [target_key]'s [type] made by [admin_key] to [secret ? "not secret" : "secret"]") + message_admins("[kna] has toggled [target_key]'s [type] made by [admin_key] to [secret ? "not secret" : "secret"]", TRUE) browse_messages(target_ckey = ckey(target_key), agegate = TRUE) qdel(query_find_message_secret) @@ -381,7 +381,8 @@ var/list/navbar = list("All#") for(var/letter in GLOB.alphabet) navbar += "[letter]" - navbar += "MemosWatchlist" + if(!usr?.client.is_eventmaker()) // TFF ADDITION - Eventmaker + navbar += "MemosWatchlist" navbar += "
\ \ [HrefTokenFormField()]\ @@ -438,6 +439,10 @@ var/playtime = query_get_type_messages.item[11] var/round_id = query_get_type_messages.item[12] // NOVA EDIT CHANGE END - MULTISERVER output += "" + // TFF ADDITION START - Eventmaker + if(type != "eventmaker note" && usr?.client.is_eventmaker()) + continue + // TFF ADDITION END if(type == "watchlist entry") output += "[t_key] | " output += "[timestamp] | [server] | Round [round_id] | [admin_key]" @@ -482,6 +487,10 @@ var/list/messagedata = list() var/list/watchdata = list() var/list/notedata = list() + // TFF ADDITION START - Eventmaker + var/list/rating = 5 // Изначальный рейтинг пользователя, далее его.. понижают нотесы с тяжестью. + var/list/eventnotedata = list() // Храним в себе нотесы ивентеров + // TFF ADDITION END var/skipped = 0 while(query_get_messages.NextRow()) if(QDELETED(usr)) @@ -519,6 +528,15 @@ alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];" var/list/data = list("

") if(severity) + // TFF ADDITION START - Eventmaker + switch(severity) + if("high") + rating -= 0.4 + if("medium") + rating -= 0.2 + if("minor") + rating -= 0.1 + // TFF ADDITION END data += " " data += "[timestamp] | [server] | Round [round_id] | [admin_key][secret ? " | - Secret" : ""] | [get_exp_format(text2num(playtime))] Living Playtime" if(expire_timestamp) @@ -553,6 +571,10 @@ watchdata += data if("note") notedata += data + // TFF ADDITION START - Eventmaker + if("eventmaker note") + eventnotedata += data + // TFF ADDITION END qdel(query_get_messages) if(!target_key) var/datum/db_query/query_get_message_key = SSdbcore.NewQuery({" @@ -565,21 +587,24 @@ target_key = query_get_message_key.item[1] qdel(query_get_message_key) output += "

[target_key]

" + output += "

Player Rating: [rating > -1 ? rating : 0]

" // TFF ADDITION - Eventmaker if(!linkless) - output += "Add note" - output += " Add message" - output += " Add to watchlist" + if(!usr?.client.is_eventmaker()) // TFF ADDITION - Eventmaker + output += "Add note" + output += " Add message" + output += " Add to watchlist" + output += " Add event note" // TFF ADDITION - Eventmaker output += " Refresh page
" else output += " Refresh page" output += ruler - if(messagedata) + if(messagedata && !usr?.client.is_eventmaker())// TFF ADDITION - Eventmaker output += "

Messages

" output += messagedata - if(watchdata) + if(watchdata && !usr?.client.is_eventmaker())// TFF ADDITION - Eventmaker output += "

Watchlist

" output += watchdata - if(notedata) + if(notedata && !usr?.client.is_eventmaker())// TFF ADDITION - Eventmaker output += "

Notes

" output += notedata if(!linkless) @@ -590,9 +615,15 @@ output += "
Show All
" else output += "
Hide Old
" + // TFF ADDITION START - Eventmaker + if(eventnotedata) + output += "

Event Notes

" + output += eventnotedata + // TFF ADDITION END if(index) var/search - output += "
Add messageAdd watchlist entryAdd note
" + if(!usr?.client.is_eventmaker()) // TFF ADDITION - Eventmaker + output += "
Add messageAdd watchlist entryAdd note
" output += ruler switch(index) if(1) @@ -624,7 +655,7 @@ index_key = index_ckey output += "[index_key]
" qdel(query_list_messages) - else if(!type && !target_ckey && !index) + else if(!type && !target_ckey && !index && !usr?.client.is_eventmaker()) // TFF EDIT - Eventmaker output += "
Add messageAdd watchlist entryAdd note
" output += ruler var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500) @@ -717,7 +748,7 @@ /proc/scream_about_watchlists(client/read_from) for(var/datum/admin_message/message in get_message_output("watchlist entry", read_from.ckey)) - message_admins("Notice: [key_name_admin(read_from.ckey)] has been on the watchlist since [message.timestamp] and has just connected - Reason: [message.text]") + message_admins("Notice: [key_name_admin(read_from.ckey)] has been on the watchlist since [message.timestamp] and has just connected - Reason: [message.text]", TRUE) send2tgs_adminless_only("Watchlist", "[key_name(read_from.ckey)] is on the watchlist and has just connected - Reason: [message.text]") #define NOTESFILE "data/player_notes.sav" diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm index fede9724ab1..af6a477e2af 100644 --- a/code/modules/admin/stickyban.dm +++ b/code/modules/admin/stickyban.dm @@ -50,7 +50,7 @@ SSstickyban.cache[ckey] = ban log_admin_private("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]") - message_admins(span_adminnotice("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]")) + message_admins(span_adminnotice("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]"), TRUE) if ("remove") if (!data["ckey"]) @@ -79,7 +79,7 @@ log_admin_private("[key_name(usr)] removed [ckey]'s stickyban") - message_admins(span_adminnotice("[key_name_admin(usr)] removed [ckey]'s stickyban")) + message_admins(span_adminnotice("[key_name_admin(usr)] removed [ckey]'s stickyban"), TRUE) if ("remove_alt") if (!data["ckey"]) @@ -127,7 +127,7 @@ qdel(query_remove_stickyban_alt) log_admin_private("[key_name(usr)] has disassociated [alt] from [ckey]'s sticky ban") - message_admins(span_adminnotice("[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban")) + message_admins(span_adminnotice("[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban"), TRUE) if ("edit") if (!data["ckey"]) @@ -161,7 +161,7 @@ qdel(query_edit_stickyban) log_admin_private("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]") - message_admins(span_adminnotice("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")) + message_admins(span_adminnotice("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]"), TRUE) if ("exempt") if (!data["ckey"]) @@ -211,7 +211,7 @@ qdel(query_exempt_stickyban_alt) log_admin_private("[key_name(usr)] has exempted [alt] from [ckey]'s sticky ban") - message_admins(span_adminnotice("[key_name_admin(usr)] has exempted [alt] from [ckey]'s sticky ban")) + message_admins(span_adminnotice("[key_name_admin(usr)] has exempted [alt] from [ckey]'s sticky ban"), TRUE) if ("unexempt") if (!data["ckey"]) @@ -261,7 +261,7 @@ qdel(query_unexempt_stickyban_alt) log_admin_private("[key_name(usr)] has unexempted [alt] from [ckey]'s sticky ban") - message_admins(span_adminnotice("[key_name_admin(usr)] has unexempted [alt] from [ckey]'s sticky ban")) + message_admins(span_adminnotice("[key_name_admin(usr)] has unexempted [alt] from [ckey]'s sticky ban"), TRUE) if ("timeout") if (!data["ckey"]) @@ -288,7 +288,7 @@ cachedban["timeout"] = TRUE log_admin_private("[key_name(usr)] has put [ckey]'s sticky ban on timeout.") - message_admins(span_adminnotice("[key_name_admin(usr)] has put [ckey]'s sticky ban on timeout.")) + message_admins(span_adminnotice("[key_name_admin(usr)] has put [ckey]'s sticky ban on timeout."), TRUE) if ("untimeout") if (!data["ckey"]) @@ -316,7 +316,7 @@ world.SetConfig("ban",ckey,list2stickyban(ban)) log_admin_private("[key_name(usr)] has taken [ckey]'s sticky ban off of timeout.") - message_admins(span_adminnotice("[key_name_admin(usr)] has taken [ckey]'s sticky ban off of timeout.")) + message_admins(span_adminnotice("[key_name_admin(usr)] has taken [ckey]'s sticky ban off of timeout."), TRUE) if ("revert") @@ -335,7 +335,7 @@ world.SetConfig("ban",ckey,null) log_admin_private("[key_name(usr)] has reverted [ckey]'s sticky ban to its state at round start.") - message_admins(span_adminnotice("[key_name_admin(usr)] has reverted [ckey]'s sticky ban to its state at round start.")) + message_admins(span_adminnotice("[key_name_admin(usr)] has reverted [ckey]'s sticky ban to its state at round start."), TRUE) //revert is mostly used when shit goes rouge, so we have to set it to null // and wait a byond tick before assigning it to ensure byond clears its shit. sleep(world.tick_lag) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 4cca6441d9c..fa8e9fead62 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -282,6 +282,13 @@ return var/target_key = href_list["addwatch"] create_message("watchlist entry", target_key, secret = 1) + // TFF ADDITION START - Eventmaker + else if(href_list["addeventnote"]) + if(!check_rights(R_ADMIN)) + return + var/target_key = href_list["addeventnote"] + create_message("eventmaker note", target_key, secret = 1) + // TFF ADDITION END else if(href_list["addmemo"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 76d814e8ee0..97957ec1adc 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -24,7 +24,7 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo if(player.ckey) body += "
\[Find Updated Panel\]" - if(player.client) + if(player.client && !user.is_eventmaker()) // TFF EDIT - Eventmaker body += "
\[First Seen: [player.client.player_join_date]\]\[Byond account registered on: [player.client.account_join_date]\]" // NOVA EDIT ADDITION START - Player Ranks var/list/player_ranks = list() @@ -84,30 +84,31 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo else body += "None?!" body += "

" - - body += "Kick | " - if(player.client) - body += "Ban | " - else - body += "Ban | " + if(!user.is_eventmaker()) // TFF ADDITION - Eventmaker + body += "Kick | " + if(player.client) + body += "Ban | " + else + body += "Ban | " body += "Notes | Messages | Watchlist | " if(player.client) body += "| Prison | " body += "\ Send back to Lobby | " var/muted = player.client.prefs.muted - body += "
Mute: " - body += "\[IC | " - body += "OOC | " - body += "PRAY | " - body += "ADMINHELP | " - //Nova Edit Addition Begin - LOOC muting again. - body += "DEADCHAT | " - body += "LOOC\]" - //Nova Edit Addition End - LOOC muting again. - body += "WEBREQ | " - body += "DEADCHAT\]" - body += "(toggle all)" + if(!user.is_eventmaker()) // TFF ADDITION - Eventmaker + body += "
Mute: " + body += "\[IC | " + body += "OOC | " + body += "PRAY | " + body += "ADMINHELP | " + //Nova Edit Addition Begin - LOOC muting again. + body += "DEADCHAT | " + body += "LOOC\]" + //Nova Edit Addition End - LOOC muting again. + body += "WEBREQ | " + body += "DEADCHAT\]" + body += "(toggle all)" body += "

" body += "Jump to | " diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index b988104dd23..60a6fd0f6bc 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -1,6 +1,6 @@ ADMIN_VERB(cmd_admin_say, R_NONE, "ASay", "Send a message to other admins", ADMIN_CATEGORY_MAIN, message as text) message = emoji_parse(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) - if(!message) + if(!message || user.is_eventmaker()) // TFF EDIT - Eventmaker return if(findtext(message, "@") || findtext(message, "#")) @@ -22,7 +22,12 @@ ADMIN_VERB(cmd_admin_say, R_NONE, "ASay", "Send a message to other admins", ADMI var/asay_color = user.prefs.read_preference(/datum/preference/color/asay_color) var/custom_asay_color = (CONFIG_GET(flag/allow_admin_asaycolor) && asay_color) ? "" : "" message = "[span_adminsay("[span_prefix("ADMIN:")] [key_name_admin(user)] [ADMIN_FLW(user.mob)]: [custom_asay_color][message]")][custom_asay_color ? "":null]" - to_chat(GLOB.admins, + var/addressee = GLOB.admins.Copy() + for(var/client/admin in addressee) + if(admin.is_eventmaker()) + addressee -= admin + + to_chat(addressee, type = MESSAGE_TYPE_ADMINCHAT, html = message, confidential = TRUE) diff --git a/code/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index 38d7535758f..e251c034176 100644 --- a/code/modules/admin/verbs/maprotation.dm +++ b/code/modules/admin/verbs/maprotation.dm @@ -1,4 +1,4 @@ -ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_CATEGORY_SERVER) +ADMIN_VERB(admin_change_map, R_DEBUG, "Change Map", "Set the next map.", ADMIN_CATEGORY_SERVER) // TFF EDIT. ORIGINAL - ADMIN_VERB(admin_change_map, R_SERVER, "Change Map", "Set the next map.", ADMIN_CATEGORY_SERVER) var/list/maprotatechoices = list() for (var/map in config.maplist) var/datum/map_config/virtual_map = config.maplist[map] diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index 368f6f4d6f4..c9779652fd1 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -9,6 +9,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w var/client/holder //client of whoever is using this datum var/is_debugger = FALSE var/is_funmin = FALSE + var/is_eventmaker_admin = FALSE // TFF EDIT - Eventmaker /datum/secrets_menu/New(user)//user can either be a client or a mob due to byondcode(tm) if (istype(user, /client)) @@ -20,6 +21,8 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w is_debugger = check_rights(R_DEBUG) is_funmin = check_rights(R_FUN) + is_eventmaker_admin = holder.is_eventmaker() // TFF EDIT - Eventmaker + world.log << is_eventmaker_admin // TFF EDIT - Eventmaker /datum/secrets_menu/ui_state(mob/user) return GLOB.admin_state @@ -37,6 +40,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w var/list/data = list() data["is_debugger"] = is_debugger data["is_funmin"] = is_funmin + data["is_eventmaker"] = is_eventmaker_admin // TFF EDIT - Eventmaker return data #define THUNDERDOME_TEMPLATE_FILE "admin_thunderdome.dmm" diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index b5891686119..04cdffd5dea 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -66,7 +66,7 @@ ADMIN_VERB(restart, R_SERVER, "Reboot World", "Restarts the world immediately.", #undef HARDEST_RESTART #undef TGS_RESTART -ADMIN_VERB(end_round, R_SERVER, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) +ADMIN_VERB(end_round, R_DEBUG, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) // TFF CHANGE. OROGINAL - ADMIN_VERB(end_round, R_DEBUG, "End Round", "Forcibly ends the round and allows the server to restart normally.", ADMIN_CATEGORY_SERVER) var/confirm = tgui_alert(user, "End the round and restart the game world?", "End Round", list("Yes", "Cancel")) if(confirm != "Yes") return @@ -88,7 +88,7 @@ ADMIN_VERB(toggle_ooc_dead, R_ADMIN, "Toggle Dead OOC", "Toggle the OOC channel ADMIN_VERB(toggle_vote_dead, R_ADMIN, "Toggle Dead Vote", "Toggle the vote for dead players on or off.", ADMIN_CATEGORY_SERVER) SSvote.toggle_dead_voting(user) -ADMIN_VERB(start_now, R_SERVER, "Start Now", "Start the round RIGHT NOW.", ADMIN_CATEGORY_SERVER) +ADMIN_VERB(start_now, R_DEBUG, "Start Now", "Start the round RIGHT NOW.", ADMIN_CATEGORY_SERVER) // TFF CHANGE. ORGINAL - ADMIN_VERB(start_now, R_SERVER, "Start Now", "Start the round RIGHT NOW.", ADMIN_CATEGORY_SERVER) var/static/list/waiting_states = list(GAME_STATE_PREGAME, GAME_STATE_STARTUP) if(!(SSticker.current_state in waiting_states)) to_chat(user, span_warning(span_red("The game has already started!"))) @@ -192,7 +192,7 @@ ADMIN_VERB(toggle_respawn, R_SERVER, "Toggle Respawn", "Toggle the ability to re world.update_status() SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[new_state_text]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! -ADMIN_VERB(delay, R_SERVER, "Delay Pre-Game", "Delay the game start.", ADMIN_CATEGORY_SERVER) +ADMIN_VERB(delay, R_DEBUG, "Delay Pre-Game", "Delay the game start.", ADMIN_CATEGORY_SERVER) // TFF CHANGE. ORIGINAL - ADMIN_VERB(delay, R_SERVER, "Delay Pre-Game", "Delay the game start.", ADMIN_CATEGORY_SERVER) var/newtime = input(user, "Set a new time in seconds. Set -1 for indefinite delay.", "Set Delay", round(SSticker.GetTimeLeft()/10)) as num|null if(!newtime) return diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 4fde1e30d1a..443e08d05d8 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -1,7 +1,7 @@ //DO NOT ADD MORE TO THIS FILE. //Use vv_do_topic() for datums! /client/proc/view_var_Topic(href, href_list, hsrc) - if( (usr.client != src) || !src.holder || !holder.CheckAdminHref(href, href_list)) + if( (usr.client != src) || !src.holder || (!holder.CheckAdminHref(href, href_list) && !is_eventmaker())) // TFF EDIT - Eventmaker return var/target = GET_VV_TARGET vv_do_basic(target, href_list, href) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 08e98bb2af3..af30bbd2771 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -65,7 +65,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( topiclimiter[ADMINSWARNED_AT] = minute msg += " Administrators have been informed." log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") - message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") + message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute", TRUE) to_chat(src, span_danger("[msg]")) return @@ -324,10 +324,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(matches) if(C) - message_admins(span_danger("[message_type]: Connecting player [key_name_admin(src)] has the same [matches] as [key_name_admin(C)][in_round].")) + message_admins(span_danger("[message_type]: Connecting player [key_name_admin(src)] has the same [matches] as [key_name_admin(C)][in_round]."), TRUE) log_admin_private("[message_type]: Connecting player [key_name(src)] has the same [matches] as [key_name(C)][in_round].") else - message_admins(span_danger("[message_type]: Connecting player [key_name_admin(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round]. ")) + message_admins(span_danger("[message_type]: Connecting player [key_name_admin(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round]. "), TRUE) log_admin_private("[message_type]: Connecting player [key_name(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round].") var/reconnecting = FALSE if(GLOB.player_details[ckey]) @@ -422,7 +422,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( var/dupe_login_message = "Your ComputerID has already logged in with another key this round, please log out of this one NOW or risk being banned!" if (alert_admin_multikey) dupe_login_message += "\nAdmins have been informed." - message_admins(span_danger("MULTIKEYING: [key_name_admin(src)] has a matching CID+IP with another player and is clearly multikeying. They have been warned to leave the server or risk getting banned.")) + message_admins(span_danger("MULTIKEYING: [key_name_admin(src)] has a matching CID+IP with another player and is clearly multikeying. They have been warned to leave the server or risk getting banned."), TRUE) log_admin_private("MULTIKEYING: [key_name(src)] has a matching CID+IP with another player and is clearly multikeying. They have been warned to leave the server or risk getting banned.") spawn(0.5 SECONDS) //needs to run during world init, do not convert to add timer alert(mob, dupe_login_message) //players get banned if they don't see this message, do not convert to tgui_alert (or even tg_alert) please. @@ -507,7 +507,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (isnum(cached_player_age) && cached_player_age == -1) //first connection if (nnpa >= 0) log_admin_private("New login: [key_name(key, FALSE, TRUE)] (IP: [address], ID: [computer_id]) logged onto the servers for the first time.") - message_admins("New user: [key_name_admin(src)] is connecting here for the first time.") + message_admins("New user: [key_name_admin(src)] is connecting here for the first time.", TRUE) if (CONFIG_GET(flag/irc_first_connection_alert)) var/new_player_alert_role = CONFIG_GET(string/new_player_alert_role_id) send2tgs_adminless_only( @@ -515,11 +515,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( "[key_name(src)] is connecting for the first time![new_player_alert_role ? " <@&[new_player_alert_role]>" : ""]" ) else if (isnum(cached_player_age) && cached_player_age < nnpa) - message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age == 1?"":"s")]") + message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age == 1?"":"s")]", TRUE) if(CONFIG_GET(flag/use_account_age_for_jobs) && account_age >= 0) player_age = account_age if(account_age >= 0 && account_age < nnpa) - message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age == 1?"":"s")] old, created on [account_join_date].") + message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age == 1?"":"s")] old, created on [account_join_date].", TRUE) if (CONFIG_GET(flag/irc_first_connection_alert)) var/new_player_alert_role = CONFIG_GET(string/new_player_alert_role_id) send2tgs_adminless_only( @@ -703,7 +703,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( //NOVA EDIT ADDITION BEGIN - PANICBUNKER if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough)) log_access("Failed Login: [key] - [address] - New account attempting to connect during panic bunker") - message_admins(span_adminnotice("Failed Login: [key] - [address] - New account attempting to connect during panic bunker")) + message_admins(span_adminnotice("Failed Login: [key] - [address] - New account attempting to connect during panic bunker"), TRUE) to_chat_immediate(src, span_notice("Hi! We have temporarily enabled safety measures that prevents new players from joining currently.
Please try again later, or contact a staff on Discord if you have any questions.

To join our community, check out our Discord! To gain full access to our Discord, read the rules and post a request in the #access-requests channel under the \"Landing Zone\" category in the Discord server linked here: https://discord.gg/novasector")) var/list/connectiontopic_a = params2list(connectiontopic) var/list/panic_addr = CONFIG_GET(string/panic_server_address) @@ -901,10 +901,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( msg += " Administrators have been informed." if (ab) log_game("[key_name(src)] is using the middle click aimbot exploit") - message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit
") + message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] is using the middle click aimbot exploit", TRUE) add_system_note("aimbot", "Is using the middle click aimbot exploit") log_game("[key_name(src)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") - message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute") + message_admins("[ADMIN_LOOKUPFLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute click limit of [mcl] clicks in a given game minute", TRUE) to_chat(src, span_danger("[msg]")) return @@ -1044,7 +1044,13 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( movement_keys[key] = SOUTH if(ADMIN_CHANNEL) if(holder) - var/asay = tgui_say_create_open_command(ADMIN_CHANNEL) + // TFF EDIT START - Eventmaker + var/asay + if(is_eventmaker()) + asay = tgui_say_create_open_command(EVENT_CHANNEL) + else + asay = tgui_say_create_open_command(ADMIN_CHANNEL) + // TFF EDIT END winset(src, "default-[REF(key)]", "parent=default;name=[key];command=[asay]") else winset(src, "default-[REF(key)]", "parent=default;name=[key];command=") diff --git a/code/modules/mob/dead/observer/observer_say.dm b/code/modules/mob/dead/observer/observer_say.dm index a8fd0094934..fcf288ec783 100644 --- a/code/modules/mob/dead/observer/observer_say.dm +++ b/code/modules/mob/dead/observer/observer_say.dm @@ -44,7 +44,12 @@ message = trim_left(copytext_char(message, length(message_mods[RADIO_KEY]) + 2)) switch(message_mods[RADIO_EXTENSION]) if(MODE_ADMIN) - SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) + // TFF ADDITION START - Eventmaker + if(client.is_eventmaker()) + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_eventmaker_say, message) + else + // TFF ADDITION END + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) if(MODE_DEADMIN) SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/dsay, message) if(MODE_PUPPET) diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index e72899d482d..290b4cd807b 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -130,7 +130,12 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( return if(message_mods[RADIO_EXTENSION] == MODE_ADMIN) - SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) + // TFF ADDITION START - Eventmaker + if(client.is_eventmaker()) + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_eventmaker_say, message) + else + // TFF ADDITION END + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_admin_say, message) return if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN) diff --git a/code/modules/tgui_input/say_modal/modal.dm b/code/modules/tgui_input/say_modal/modal.dm index f700a6cdbea..4401df88f77 100644 --- a/code/modules/tgui_input/say_modal/modal.dm +++ b/code/modules/tgui_input/say_modal/modal.dm @@ -86,7 +86,7 @@ if(!payload?["channel"]) CRASH("No channel provided to an open TGUI-Say") window_open = TRUE - if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != LOOC_CHANNEL) // NOVA EDIT CHANGE (Add LOOC_CHANNEL) + if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != LOOC_CHANNEL && payload["channel"] != EVENT_CHANNEL) // NOVA EDIT CHANGE (Add LOOC_CHANNEL) // TFF EDIT - Eventmaker start_thinking() if(!client.typing_indicators) log_speech_indicators("[key_name(client)] started typing at [loc_name(client.mob)], indicators DISABLED.") diff --git a/code/modules/tgui_input/say_modal/speech.dm b/code/modules/tgui_input/say_modal/speech.dm index 9ed87be111a..ac1169e84ec 100644 --- a/code/modules/tgui_input/say_modal/speech.dm +++ b/code/modules/tgui_input/say_modal/speech.dm @@ -57,6 +57,11 @@ if(DO_CHANNEL) client.mob.do_verb(entry) // NOVA EDIT ADDITION END + // TFF ADDITION START - Eventmaker + if(EVENT_CHANNEL) + SSadmin_verbs.dynamic_invoke_verb(client, /datum/admin_verb/cmd_eventmaker_say, entry) + return TRUE + // TFF ADDITION END return FALSE /** diff --git a/config/nova/config_nova.txt b/config/nova/config_nova.txt index af44fea6ed8..f5522769253 100644 --- a/config/nova/config_nova.txt +++ b/config/nova/config_nova.txt @@ -152,6 +152,7 @@ SIZE_COLLAR_MINIMUM 15 DONATOR_LEGACY_SYSTEM MENTOR_LEGACY_SYSTEM VETERAN_LEGACY_SYSTEM +EVENTMAKER_LEGACY_SYSTEM ## How much time arrivals shuttle should stay at station after its engines recharged before returning to interlink. In deciseconds. 150 - 15 seconds. 0 - disables autoreturn. ARRIVALS_WAIT 150 diff --git a/config/nova/eventmakers.txt b/config/nova/eventmakers.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/modular_nova/master_files/code/modules/logging/categories/log_category_game.dm b/modular_nova/master_files/code/modules/logging/categories/log_category_game.dm index f665a603a10..f373634061f 100644 --- a/modular_nova/master_files/code/modules/logging/categories/log_category_game.dm +++ b/modular_nova/master_files/code/modules/logging/categories/log_category_game.dm @@ -2,6 +2,11 @@ category = LOG_CATEGORY_GAME_MENTOR master_category = /datum/log_category/game +//TODO: ПЕРЕНЕСТИ ОТСЮДАВОЙ +/datum/log_category/game_eventmaker + category = LOG_CATEGORY_GAME_EVENTMAKER + master_category = /datum/log_category/game + /datum/log_category/game_subtle category = LOG_CATEGORY_GAME_SUBTLE master_category = /datum/log_category/game diff --git a/modular_nova/modules/player_ranks/code/subsystem/player_ranks.dm b/modular_nova/modules/player_ranks/code/subsystem/player_ranks.dm index 6dd15874973..041e5bc0429 100644 --- a/modular_nova/modules/player_ranks/code/subsystem/player_ranks.dm +++ b/modular_nova/modules/player_ranks/code/subsystem/player_ranks.dm @@ -203,7 +203,6 @@ SUBSYSTEM_DEF(player_ranks) load_player_rank_sql(veteran_controller) - /** * Handles populating the player rank from the database. * diff --git a/tff_modular/modules/eventers/eventmaker.dm b/tff_modular/modules/eventers/eventmaker.dm new file mode 100644 index 00000000000..a985a3126f9 --- /dev/null +++ b/tff_modular/modules/eventers/eventmaker.dm @@ -0,0 +1,34 @@ +/** + * Returns whether or not the user is qualified as a eventmaker. + */ +/client/proc/is_eventmaker() + return holder?.ranks && holder.ranks[1].name == "Eventmaker" + + +/datum/controller/subsystem/admin_verbs/get_valid_verbs_for_admin(client/admin) + if(isnull(admin.holder)) + CRASH("Why are we checking a non-admin for their valid... ahem... admin verbs?") + + var/list/has_permission = list() + for(var/permission_flag in GLOB.bitflags) + if(admin.holder.check_for_rights(permission_flag)) + has_permission["[permission_flag]"] = TRUE + + var/list/valid_verbs = list() + for(var/datum/admin_verb/verb_type as anything in admin_verbs_by_type) + var/datum/admin_verb/verb_singleton = admin_verbs_by_type[verb_type] + if(!verify_visibility(admin, verb_singleton)) + continue + + if(admin.is_eventmaker() && GLOB.eventmakers_blacklist_verbs["[verb_singleton.name]"]) + continue + + var/verb_permissions = verb_singleton.permissions + if(verb_permissions == R_NONE) + valid_verbs |= list(verb_singleton) + else for(var/permission_flag in bitfield_to_list(verb_permissions)) + if(!has_permission["[permission_flag]"]) + continue + valid_verbs |= list(verb_singleton) + + return valid_verbs diff --git a/tff_modular/modules/eventers/eventmaker_verbs.dm b/tff_modular/modules/eventers/eventmaker_verbs.dm new file mode 100644 index 00000000000..ae4aaae36bc --- /dev/null +++ b/tff_modular/modules/eventers/eventmaker_verbs.dm @@ -0,0 +1,13 @@ +ADMIN_VERB(cmd_eventmaker_say, R_NONE, "ESay", "Send a message to eventmakes", ADMIN_CATEGORY_MAIN, message as text) + message = emoji_parse(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + if(!message) + return + + user.mob.log_talk(message, LOG_ASAY) + message = keywords_lookup(message) + message = "[span_eventmaker("[span_prefix("EVENTCHAT:")] [key_name_admin(user)] [ADMIN_FLW(user.mob)]: [message]")]
" + to_chat(GLOB.admins, + type = MESSAGE_TYPE_ADMINCHAT, + html = message, + confidential = TRUE) + BLACKBOX_LOG_ADMIN_VERB("Esay") diff --git a/tff_modular/modules/eventers/random_stuff_ban.dm b/tff_modular/modules/eventers/random_stuff_ban.dm new file mode 100644 index 00000000000..10e61655ee6 --- /dev/null +++ b/tff_modular/modules/eventers/random_stuff_ban.dm @@ -0,0 +1,14 @@ +/client/CanProcCall(procname) + if(usr.client.is_eventmaker()) + return FALSE + . = ..() + +/client/can_vv_get(var_name) + if(usr?.client.is_eventmaker()) + return FALSE + . = ..() + +/datum/admins/can_vv_get(var_name) + if(usr?.client.is_eventmaker()) + return FALSE + . = ..() diff --git a/tgstation.dme b/tgstation.dme index 8841314acef..def8c55eca7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -400,11 +400,14 @@ #include "code\__DEFINES\~ff_defines\flavor_misc.dm" #include "code\__DEFINES\~ff_defines\nabber_clothes_pathes.dm" #include "code\__DEFINES\~ff_defines\say.dm" +#include "code\__DEFINES\~ff_defines\span.dm" #include "code\__DEFINES\~ff_defines\text.dm" #include "code\__DEFINES\~ff_defines\vv.dm" #include "code\__DEFINES\~ff_defines\__HELPERS\global_lists.dm" #include "code\__DEFINES\~ff_defines\__HELPERS\ishelpers.dm" #include "code\__DEFINES\~ff_defines\__HELPERS\names.dm" +#include "code\__DEFINES\~ff_defines\_globalvars\logging.dm" +#include "code\__DEFINES\~ff_defines\_globalvars\lists\hidden_verbs.dm" #include "code\__DEFINES\~nova_defines\_organ_defines.dm" #include "code\__DEFINES\~nova_defines\access.dm" #include "code\__DEFINES\~nova_defines\actionspeed_modification.dm" @@ -8858,6 +8861,9 @@ #include "tff_modular\modules\drinks\skrelluq\reaction.dm" #include "tff_modular\modules\drinks\skrelluq\reagent.dm" #include "tff_modular\modules\drone\code\droneDispenser.dm" +#include "tff_modular\modules\eventers\eventmaker.dm" +#include "tff_modular\modules\eventers\eventmaker_verbs.dm" +#include "tff_modular\modules\eventers\random_stuff_ban.dm" #include "tff_modular\modules\extra_vv\extra_carbon_vv.dm" #include "tff_modular\modules\holidays_decor\halloween\halloween-craft.dm" #include "tff_modular\modules\holidays_decor\halloween\halloween-decor.dm" diff --git a/tgui/packages/tgui-panel/chat/constants.ts b/tgui/packages/tgui-panel/chat/constants.ts index 0e1a79bc1d6..46a3ab8ffda 100644 --- a/tgui/packages/tgui-panel/chat/constants.ts +++ b/tgui/packages/tgui-panel/chat/constants.ts @@ -38,6 +38,7 @@ export const MESSAGE_TYPE_ADMINLOG = 'adminlog'; export const MESSAGE_TYPE_ATTACKLOG = 'attacklog'; export const MESSAGE_TYPE_DEBUG = 'debug'; export const MESSAGE_TYPE_MENTOR = 'mentor'; // NOVA EDIT ADDITION +export const MESSAGE_TYPE_EVENTMAKER = 'eventmaker'; // TFF EDIT - Eventmaker // Metadata for each message type export const MESSAGE_TYPES = [ @@ -152,4 +153,12 @@ export const MESSAGE_TYPES = [ description: 'Mentor PMs and other mentor things.', selector: '.mentor, .mentornotice', }, + // TFF ADDITION START - Eventmaker + { + type: MESSAGE_TYPE_EVENTMAKER, + name: 'Eventmaker Log', + description: 'Eventmaker PMs and other eventmaker things.', + selector: '.eventmaker', + }, + // TFF ADDITION END ]; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index 09cdd23495a..710f9ba1ae9 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -1438,3 +1438,11 @@ $border-width-px: $border-width * 1px; font-style: italic; } // NOVA EDIT ADDITION END + +/* TFF ADDITION START - Eventmaker */ + +.eventmaker { + color: #009c22; +} + +// TFF EDIT ADDITION END diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index 8f606cbdd6f..ec4d83762f8 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -1383,3 +1383,11 @@ $border-width-px: $border-width * 1px; } } // NOVA EDIT ADDITION END + +/* TFF ADDITION START - Eventmaker */ + +.eventmaker { + color: #006616; +} + +// TFF EDIT ADDITION END diff --git a/tgui/packages/tgui-say/ChannelIterator.ts b/tgui/packages/tgui-say/ChannelIterator.ts index 57866808609..cddac3571e1 100644 --- a/tgui/packages/tgui-say/ChannelIterator.ts +++ b/tgui/packages/tgui-say/ChannelIterator.ts @@ -8,7 +8,8 @@ export type Channel = | 'Do' // NOVA EDIT ADDITION END | 'OOC' - | 'Admin'; + | 'Admin' + | 'Event'; // TFF EDIT - Eventmaker /** * ### ChannelIterator @@ -29,9 +30,10 @@ export class ChannelIterator { // NOVA EDIT ADDITION 'OOC', 'Admin', + 'Event', // TFF EDIT - Eventmaker ]; - private readonly blacklist: Channel[] = ['Admin']; - private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin']; // NOVA EDIT CHANGE (Add LOOC) + private readonly blacklist: Channel[] = ['Admin', 'Event']; // TFF EDIT - Eventmaker + private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin', 'Event']; // NOVA EDIT CHANGE (Add LOOC) // TFF EDIT - Eventmaker public next(): Channel { if (this.blacklist.includes(this.channels[this.index])) { diff --git a/tgui/packages/tgui-say/constants/index.tsx b/tgui/packages/tgui-say/constants/index.tsx index 8095aa98583..c9a11592d90 100644 --- a/tgui/packages/tgui-say/constants/index.tsx +++ b/tgui/packages/tgui-say/constants/index.tsx @@ -8,6 +8,7 @@ export const CHANNELS = [ 'Do', // NOVA EDIT ADDITION - Do roleplay addition 'OOC', 'Admin', + 'Event', // TFF EDIT - Eventmaker ] as const; /** Window sizes in pixels */ diff --git a/tgui/packages/tgui-say/styles/colors.scss b/tgui/packages/tgui-say/styles/colors.scss index 337887e358f..34cfec4e11b 100644 --- a/tgui/packages/tgui-say/styles/colors.scss +++ b/tgui/packages/tgui-say/styles/colors.scss @@ -36,6 +36,8 @@ $_channel_map: ( 'Whis': hsl(238, 55%, 67%), 'Do': hsl(137, 64%, 60%), // NOVA EDIT ADDITION END + // TFF EDIT - Eventmaker + 'Event': hsl(92, 80%, 37%), ); $channel_keys: map.keys($_channel_map) !default; diff --git a/tgui/packages/tgui/interfaces/Secrets.jsx b/tgui/packages/tgui/interfaces/Secrets.jsx index 3e3ccd70cc0..09d3d93e274 100644 --- a/tgui/packages/tgui/interfaces/Secrets.jsx +++ b/tgui/packages/tgui/interfaces/Secrets.jsx @@ -632,7 +632,7 @@ const FunForYouTab = (props) => { export const Secrets = (props) => { const { act, data } = useBackend(); - const { is_debugger, is_funmin } = data; + const { is_debugger, is_funmin, is_eventmaker } = data; const [tabIndex, setTabIndex] = useState(2); const TabComponent = TAB2NAME[tabIndex - 1].component(); @@ -644,20 +644,22 @@ export const Secrets = (props) => {
-