diff --git a/code/__HELPERS/admin.dm b/code/__HELPERS/admin.dm new file mode 100644 index 0000000000..63df20ce46 --- /dev/null +++ b/code/__HELPERS/admin.dm @@ -0,0 +1,9 @@ +/// Returns if the given client is an admin, REGARDLESS of if they're deadminned or not. +/proc/is_admin(client/client) + return !isnull(GLOB.admin_datums[client.ckey]) || !isnull(GLOB.deadmins[client.ckey]) + +/// Sends a message in the event that someone attempts to elevate their permissions through invoking a certain proc. +/proc/alert_to_permissions_elevation_attempt(mob/user) + var/message = " has tried to elevate permissions!" + message_admins(key_name_admin(user) + message) + log_admin(key_name(user) + message) diff --git a/code/datums/action.dm b/code/datums/action.dm index 77d6b78917..a4bd371c1e 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -93,7 +93,7 @@ if(!hud.mymob) continue HideFrom(hud.mymob) - LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared + LAZYREMOVE(remove_from?.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared viewers = list() if(isnull(owner)) diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm index 8eb37eabdf..043e2f8f18 100644 --- a/code/datums/components/rotation.dm +++ b/code/datums/components/rotation.dm @@ -13,7 +13,7 @@ var/rotation_flags = NONE var/default_rotation_direction = ROTATION_CLOCKWISE -/datum/component/simple_rotation/Initialize(rotation_flags = NONE ,can_user_rotate,can_be_rotated,after_rotation) +/datum/component/simple_rotation/Initialize(rotation_flags = NONE, can_user_rotate, can_be_rotated, after_rotation) if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 0eaba60ba8..6c1b085e0c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -702,7 +702,8 @@ /atom/proc/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) SEND_SIGNAL(src, COMSIG_ATOM_HITBY, hitting_atom, skipcatch, hitpush, blocked, throwingdatum) if(density && !has_gravity(hitting_atom)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). - addtimer(CALLBACK(src, PROC_REF(hitby_react), hitting_atom), 2) + addtimer(CALLBACK(src, PROC_REF(hitby_react), hitting_atom), 0.2 SECONDS) + return FALSE /** * We have have actually hit the passed in atom diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index df751a114a..7d1bda4340 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -389,7 +389,7 @@ /atom/movable/hitby(atom/movable/hitting_atom, skipcatch, hitpush = TRUE, blocked, datum/thrownthing/throwingdatum) if(!anchored && hitpush && (!throwingdatum || (throwingdatum.force >= (move_resist * MOVE_FORCE_PUSH_RATIO)))) step(src, hitting_atom.dir) - ..() + return ..() /atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE) if((force < (move_resist * MOVE_FORCE_THROW_RATIO)) || (move_resist == INFINITY)) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 831041db91..a14d207423 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -47,14 +47,14 @@ if(BURN) playsound(src.loc, 'sound/items/welder.ogg', 100, 1) -/obj/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) +/obj/hitby(atom/movable/hit_by, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) ..() - var/throwdamage = AM.throwforce - if(isobj(AM)) - var/obj/O = AM - if(O.damtype == STAMINA) + var/throwdamage = hit_by.throwforce + if(isobj(hit_by)) + var/obj/as_obj = hit_by + if(as_obj.damtype == STAMINA) throwdamage = 0 - take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, AM)) + take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, hit_by)) /obj/ex_act(severity, target, origin) if(resistance_flags & INDESTRUCTIBLE) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index ba854e7ec2..f0cb2c22d0 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -17,9 +17,9 @@ /obj/structure/chair/examine(mob/user) . = ..() - . += "It's held together by a couple of bolts." + . += span_notice("It's held together by a couple of bolts.") if(!has_buckled_mobs()) - . += "Drag your sprite to sit in it." + . += span_notice("Drag your sprite to sit in it.") /obj/structure/chair/Initialize(mapload) . = ..() @@ -28,7 +28,7 @@ /obj/structure/chair/ComponentInitialize() . = ..() - AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, PROC_REF(can_user_rotate),CALLBACK(src), PROC_REF(can_be_rotated)),null) + AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, PROC_REF(can_user_rotate)), CALLBACK(src, PROC_REF(can_be_rotated)), null) /obj/structure/chair/proc/can_be_rotated(mob/user) return TRUE diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 79ba4abae7..08cfbe3218 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -13,9 +13,7 @@ GLOBAL_PROTECT(protected_ranks) /datum/admin_rank/New(init_name, init_rights, init_exclude_rights, init_edit_rights) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) if (name == "NoRank") //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins QDEL_IN(src, 0) CRASH("Admin proc call creation of admin datum") @@ -35,9 +33,7 @@ GLOBAL_PROTECT(protected_ranks) /datum/admin_rank/Destroy() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return QDEL_HINT_LETMELIVE . = ..() @@ -93,9 +89,7 @@ GLOBAL_PROTECT(protected_ranks) // Adds/removes rights to this admin_rank /datum/admin_rank/proc/process_keyword(word, previous_rights=0) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return var/flag = admin_keyword_to_flag(word, previous_rights) if(flag) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index ea16283070..2bd6dc9236 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -40,9 +40,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) if (!target) //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins QDEL_IN(src, 0) CRASH("Admin proc call creation of admin datum") @@ -70,17 +68,13 @@ GLOBAL_PROTECT(href_token) /datum/admins/Destroy() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return QDEL_HINT_LETMELIVE . = ..() /datum/admins/proc/activate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return GLOB.deadmins -= target GLOB.admin_datums[target] = src @@ -91,9 +85,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/deactivate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return GLOB.deadmins[target] = src GLOB.admin_datums -= target @@ -105,9 +97,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/associate(client/C) if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return if(istype(C)) @@ -127,9 +117,7 @@ GLOBAL_PROTECT(href_token) /datum/admins/proc/disassociate() if(IsAdminAdvancedProcCall()) - var/msg = " has tried to elevate permissions!" - message_admins("[key_name_admin(usr)][msg]") - log_admin("[key_name(usr)][msg]") + alert_to_permissions_elevation_attempt(usr) return if(owner) GLOB.admins -= owner diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 2e586228af..22b1c8fd6d 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -130,10 +130,10 @@ return FALSE -/obj/item/assembly/mousetrap/hitby(atom/hit_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) +/obj/item/assembly/mousetrap/hitby(atom/movable/hit_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(!armed) return ..() - visible_message("[src] is triggered by [hit_atom].") + visible_message(span_warning("[src] is triggered by [hit_atom].")) triggered(null) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index f38721671c..7e505d2861 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1139,11 +1139,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(user.client) if(unlock_content) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" - if(unlock_content || check_rights_for(user.client, R_ADMIN)) + if(unlock_content || is_admin(user.client)) dat += "OOC Color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour] Change
" dat += "Antag OOC Color: [aooccolor ? aooccolor : GLOB.normal_aooc_colour] Change
" - if(user.client.holder) + if(is_admin(user.client)) dat += "

Admin Settings

" dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
" dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
" diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 73e55487bf..48bacef977 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -122,10 +122,10 @@ if (isitem(AM) && !istype(AM,/obj/item/projectile)) if(prob(50)) AM.forceMove(get_turf(src)) - visible_message("Swish! [AM] lands in [src].") + visible_message(span_warning("Swish! [AM] lands in [src].")) return else - visible_message("[AM] bounces off of [src]'s rim!") + visible_message(span_danger("[AM] bounces off of [src]'s rim!")) return ..() else return ..() diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 8976a0cc6d..6af29ca689 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -397,7 +397,7 @@ return ..() /mob/living/carbon/monkey/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 7e4497f5cd..e1427302c2 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -107,37 +107,42 @@ return FALSE /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) + var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest if(!isitem(AM)) // Filled with made up numbers for non-items. - if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list())) + if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum.thrower, zone, list()) & BLOCK_SUCCESS) hitpush = FALSE skipcatch = TRUE blocked = TRUE + return TRUE else playsound(loc, 'sound/weapons/genhit.ogg', 50, TRUE, -1) //Item sounds are handled in the item itself + log_combat(AM, src, "hit ") return ..() var/obj/item/thrown_item = AM if(thrown_item.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions return ..() - if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_THROWN, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list())) + if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_THROWN, 0, throwingdatum.thrower, zone, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE - var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest + // zone moved up because things need it early while checking it from the thrower is unnecessary var/nosell_hit = SEND_SIGNAL(thrown_item, COMSIG_MOVABLE_IMPACT_ZONE, src, zone, throwingdatum, blocked, FALSE) if(nosell_hit) skipcatch = TRUE hitpush = FALSE if(blocked) - return TRUE + return BLOCK_SUCCESS var/mob/thrown_by = thrown_item.thrownby?.resolve() if(thrown_by) log_combat(thrown_by, src, "threw and hit", thrown_item) + else + log_combat(thrown_item, src, "hit ") if(nosell_hit) return ..() visible_message(span_danger("[src] is hit by [thrown_item]!"), \ diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index a5b2655a09..c6af5ff770 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -139,7 +139,7 @@ /mob/living/simple_animal/bot/honkbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) playsound(src, honksound, 50, TRUE, -1) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 4a228e29a1..464e430bfd 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -352,7 +352,7 @@ /mob/living/simple_animal/bot/secbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(istype(hitting_atom, /obj/item)) + if(isitem(hitting_atom)) var/obj/item/item_hitby = hitting_atom var/mob/thrown_by = item_hitby.thrownby?.resolve() if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by)) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index 2463431ad3..9494f2de78 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -44,13 +44,13 @@ visible_message("[P] has a reduced effect on [src]!") return ..() -/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy - if(istype(AM, /obj/item)) - var/obj/item/T = AM +/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy + if(isitem(hitting_atom)) + var/obj/item/item_hitby = hitting_atom if(!stat) Aggro() - if(T.throwforce <= 20) - visible_message(span_notice("The [T.name] [throw_message] [src.name]!")) + if(item_hitby.throwforce <= 20) + visible_message(span_notice("\The [item_hitby] [throw_message] [src]!")) return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index ecac9591a4..9a6fbd0cd0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -180,11 +180,11 @@ if(M.a_intent == INTENT_HARM) Bruise() -/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) +/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) ..() - if(istype(AM, /obj/item)) - var/obj/item/T = AM - if(T.throwforce) + if(isitem(hitting_atom)) + var/obj/item/item_hitby = hitting_atom + if(item_hitby.throwforce) Bruise() /mob/living/simple_animal/hostile/mushroom/bullet_act(obj/item/projectile/P) diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 977d210bc6..ab4f5dc76b 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -552,7 +552,7 @@ if(S.amount < S.max_amount) sheets += S - if(sheets.len > 0) + if(length(sheets)) var/obj/item/stack/sheet/S = pick(sheets) S.add(1) // Dare var edit directly again and i'll strangle you. to_chat(owner, "[linked_extract] adds a layer of slime to [S], which metamorphosizes into another sheet of material!") @@ -587,6 +587,7 @@ /obj/item/hothands name = "burning fingertips" desc = "You shouldn't see this." + item_flags = ABSTRACT /obj/item/hothands/get_temperature() return 290 //Below what's required to ignite plasma. @@ -595,11 +596,11 @@ id = "stabilizeddarkpurple" colour = "dark purple" var/obj/item/hothands/fire - examine_text = "Their fingertips burn brightly!" + examine_text = span_notice("Their fingertips burn brightly!") /datum/status_effect/stabilized/darkpurple/on_apply() ADD_TRAIT(owner, TRAIT_RESISTHEATHANDS, "slimestatus") - fire = new(owner) + fire = new() return ..() /datum/status_effect/stabilized/darkpurple/tick() @@ -607,7 +608,7 @@ if(item) var/obj/item/reagent_containers/food/snacks/F = item if(istype(F) && F.cooked_type) - to_chat(owner, "[linked_extract] flares up brightly, and your hands alone are enough cook [F]!") + to_chat(owner, span_warning("[linked_extract] flares up brightly, and your hands alone are enough cook [F]!")) F.microwave_act() else item.attackby(fire, owner) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 7af2aca81b..618308b509 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1027,13 +1027,13 @@ GLOBAL_LIST_EMPTY(vending_products) /obj/machinery/vending/proc/canLoadItem(obj/item/I, mob/user) return FALSE -/obj/machinery/vending/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) +/obj/machinery/vending/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) . = ..() - var/mob/living/L = AM - if(tilted || !istype(L) || !prob(20 * (throwingdatum.speed - L.throw_speed))) // hulk throw = +20%, neckgrab throw = +20% + var/mob/living/living_mob = hitting_atom + if(tilted || !istype(living_mob) || !prob(20 * (throwingdatum.speed - living_mob.throw_speed))) // hulk throw = +20%, neckgrab throw = +20% return - tilt(L) + tilt(living_mob) /obj/machinery/vending/attack_tk_grab(mob/user) to_chat(user, span_warning("[src] seems to resist your mental grasp!")) diff --git a/tgstation.dme b/tgstation.dme index 6adf6658d6..14b128e4c8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -196,6 +196,7 @@ #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" +#include "code\__HELPERS\admin.dm" #include "code\__HELPERS\angles.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\chat.dm"