mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-27 07:08:55 +01:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ sudo: false
|
||||
env:
|
||||
global:
|
||||
- BYOND_MAJOR="512"
|
||||
- BYOND_MINOR="1412"
|
||||
- BYOND_MINOR="1453"
|
||||
- MACRO_COUNT=4
|
||||
matrix:
|
||||
- TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0"
|
||||
|
||||
@@ -45,3 +45,27 @@
|
||||
#define SMITE_BLUESPACEARTILLERY "Bluespace Artillery"
|
||||
#define SMITE_SPONTANEOUSCOMBUSTION "Spontaneous Combustion"
|
||||
#define SMITE_LIGHTNINGBOLT "Lightning Bolt"
|
||||
|
||||
#define ADMIN_QUE(user) "(<a href='?_src_=holder;adminmoreinfo=\ref[user]'>?</a>)"
|
||||
#define ADMIN_FLW(user) "(<a href='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</a>)"
|
||||
#define ADMIN_PP(user) "(<a href='?_src_=holder;adminplayeropts=\ref[user]'>PP</a>)"
|
||||
#define ADMIN_VV(atom) "(<a href='?_src_=vars;Vars=\ref[atom]'>VV</a>)"
|
||||
#define ADMIN_SM(user) "(<a href='?_src_=holder;subtlemessage=\ref[user]'>SM</a>)"
|
||||
#define ADMIN_TP(user) "(<a href='?_src_=holder;traitor=\ref[user]'>TP</a>)"
|
||||
#define ADMIN_BSA(user) "(<a href='?_src_=holder;BlueSpaceArtillery=\ref[user]'>BSA</a>)"
|
||||
#define ADMIN_KICK(user) "(<a href='?_src_=holder;boot2=\ref[user]'>KICK</a>)"
|
||||
#define ADMIN_CENTCOM_REPLY(user) "(<a href='?_src_=holder;CentcommReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SYNDICATE_REPLY(user) "(<a href='?_src_=holder;SyndicateReply=\ref[user]'>RPLY</a>)"
|
||||
#define ADMIN_SC(user) "(<a href='?_src_=holder;adminspawncookie=\ref[user]'>SC</a>)"
|
||||
#define ADMIN_SMITE(user) "(<a href='?_src_=holder;adminsmite=\ref[user]'>SMITE</a>)"
|
||||
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)]"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
@@ -149,6 +149,7 @@
|
||||
#define MAT_GLASS "glass"
|
||||
#define MAT_SILVER "silver"
|
||||
#define MAT_GOLD "gold"
|
||||
#define MAT_URANIUM "uranium" //Did it
|
||||
#define MAT_TITANIUM "titanium"
|
||||
#define MAT_PHORON "phoron"
|
||||
#define MAT_DIAMOND "diamond"
|
||||
|
||||
@@ -20,4 +20,11 @@
|
||||
|
||||
#define QDELING(X) (X.gc_destroyed)
|
||||
#define QDELETED(X) (!X || X.gc_destroyed)
|
||||
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
|
||||
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
|
||||
#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); }
|
||||
#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); }
|
||||
|
||||
/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly.
|
||||
QDEL_LIST(L)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//Byond type ids
|
||||
#define TYPEID_NULL "0"
|
||||
#define TYPEID_NORMAL_LIST "f"
|
||||
//helper macros
|
||||
#define GET_TYPEID(ref) ( ( (lentext(ref) <= 10) ? "TYPEID_NULL" : copytext(ref, 4, lentext(ref)-6) ) )
|
||||
#define IS_NORMAL_LIST(L) (GET_TYPEID("\ref[L]") == TYPEID_NORMAL_LIST)
|
||||
@@ -1 +1,5 @@
|
||||
GLOBAL_LIST_EMPTY(all_observable_events)
|
||||
GLOBAL_LIST_EMPTY(all_observable_events)
|
||||
|
||||
GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks.
|
||||
|
||||
GLOBAL_VAR_INIT(TAB, " ")
|
||||
@@ -1,2 +1,5 @@
|
||||
GLOBAL_LIST_EMPTY(admins) //all clients whom are admins
|
||||
GLOBAL_PROTECT(admins)
|
||||
GLOBAL_PROTECT(admins)
|
||||
GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb.
|
||||
GLOBAL_LIST_EMPTY(stealthminID)
|
||||
GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
||||
+15
-10
@@ -26,17 +26,17 @@
|
||||
max_z = max(z, max_z)
|
||||
return max_z
|
||||
|
||||
/proc/get_area(O)
|
||||
var/turf/loc = get_turf(O)
|
||||
if(loc)
|
||||
var/area/res = loc.loc
|
||||
.= res
|
||||
/proc/get_area(atom/A)
|
||||
if(isarea(A))
|
||||
return A
|
||||
var/turf/T = get_turf(A)
|
||||
return T ? T.loc : null
|
||||
|
||||
/proc/get_area_name(N) //get area by its name
|
||||
for(var/area/A in all_areas)
|
||||
if(A.name == N)
|
||||
return A
|
||||
return 0
|
||||
/proc/get_area_name(atom/X, format_text = FALSE)
|
||||
var/area/A = isarea(X) ? X : get_area(X)
|
||||
if(!A)
|
||||
return null
|
||||
return format_text ? format_text(A.name) : A.name
|
||||
|
||||
/proc/get_area_master(const/O)
|
||||
var/area/A = get_area(O)
|
||||
@@ -605,3 +605,8 @@ datum/projectile_data
|
||||
|
||||
/proc/SecondsToTicks(var/seconds)
|
||||
return seconds * 10
|
||||
|
||||
/proc/window_flash(var/client_or_usr)
|
||||
if (!client_or_usr)
|
||||
return
|
||||
winset(client_or_usr, "mainwindow", "flash=5")
|
||||
@@ -106,11 +106,12 @@ var/global/list/global_egg_types = list(
|
||||
"Tajaran" = TAJARAN_EGG,
|
||||
"Akula" = AKULA_EGG,
|
||||
"Skrell" = SKRELL_EGG,
|
||||
"Nevrean" = NEVREAN_EGG,
|
||||
"Sergal" = SERGAL_EGG,
|
||||
"Human" = HUMAN_EGG,
|
||||
"Slime" = SLIME_EGG,
|
||||
"Egg" = EGG_EGG,
|
||||
"Xenochimera" = XENOCHIMERA_EGG,
|
||||
"Xenochimera" = XENOCHIMERA_EGG,
|
||||
"Xenomorph" = XENOMORPH_EGG)
|
||||
|
||||
var/global/list/tf_egg_types = list(
|
||||
@@ -119,10 +120,11 @@ var/global/list/tf_egg_types = list(
|
||||
"Akula" = /obj/structure/closet/secure_closet/egg/shark,
|
||||
"Skrell" = /obj/structure/closet/secure_closet/egg/skrell,
|
||||
"Sergal" = /obj/structure/closet/secure_closet/egg/sergal,
|
||||
"Nevrean" = /obj/structure/closet/secure_closet/egg/nevrean,
|
||||
"Human" = /obj/structure/closet/secure_closet/egg/human,
|
||||
"Slime" = /obj/structure/closet/secure_closet/egg/slime,
|
||||
"Egg" = /obj/structure/closet/secure_closet/egg,
|
||||
"Xenochimera" = /obj/structure/closet/secure_closet/egg/scree,
|
||||
"Xenochimera" = /obj/structure/closet/secure_closet/egg/scree,
|
||||
"Xenomorph" = /obj/structure/closet/secure_closet/egg/xenomorph)
|
||||
|
||||
var/global/list/edible_trash = list(/obj/item/trash,
|
||||
|
||||
@@ -240,6 +240,17 @@ proc/listclearnulls(list/list)
|
||||
for(var/i in L)
|
||||
. |= i
|
||||
|
||||
//same, but returns nothing and acts on list in place (also handles associated values properly)
|
||||
/proc/uniqueList_inplace(list/L)
|
||||
var/temp = L.Copy()
|
||||
L.len = 0
|
||||
for(var/key in temp)
|
||||
if (isnum(key))
|
||||
L |= key
|
||||
else
|
||||
L[key] = temp[key]
|
||||
|
||||
|
||||
//Mergesort: divides up the list into halves to begin the sort
|
||||
/proc/sortKey(var/list/client/L, var/order = 1)
|
||||
if(isnull(L) || L.len < 2)
|
||||
|
||||
+103
-1
@@ -64,6 +64,11 @@ var/next_station_date_change = 1 DAY
|
||||
var/time_portion = time2text(world.timeofday, "hh:mm:ss")
|
||||
return "[date_portion]T[time_portion]"
|
||||
|
||||
/proc/gameTimestamp(format = "hh:mm:ss", wtime=null)
|
||||
if(!wtime)
|
||||
wtime = world.time
|
||||
return time2text(wtime - GLOB.timezoneOffset, format)
|
||||
|
||||
/* Returns 1 if it is the selected month and day */
|
||||
proc/isDay(var/month, var/day)
|
||||
if(isnum(month) && isnum(day))
|
||||
@@ -137,4 +142,101 @@ var/round_start_time = 0
|
||||
i *= 2
|
||||
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, GLOB.CURRENT_TICKLIMIT))
|
||||
|
||||
#undef DELTA_CALC
|
||||
#undef DELTA_CALC
|
||||
|
||||
|
||||
//Takes a value of time in deciseconds.
|
||||
//Returns a text value of that number in hours, minutes, or seconds.
|
||||
/proc/DisplayTimeText(time_value, truncate = FALSE)
|
||||
var/second = (time_value)*0.1
|
||||
var/second_adjusted = null
|
||||
var/second_rounded = FALSE
|
||||
var/minute = null
|
||||
var/hour = null
|
||||
var/day = null
|
||||
|
||||
if(!second)
|
||||
return "0 seconds"
|
||||
if(second >= 60)
|
||||
minute = FLOOR(second/60, 1)
|
||||
second = round(second - (minute*60), 0.1)
|
||||
second_rounded = TRUE
|
||||
if(second) //check if we still have seconds remaining to format, or if everything went into minute.
|
||||
second_adjusted = round(second) //used to prevent '1 seconds' being shown
|
||||
if(day || hour || minute)
|
||||
if(second_adjusted == 1 && second >= 1)
|
||||
second = " and 1 second"
|
||||
else if(second > 1)
|
||||
second = " and [second_adjusted] seconds"
|
||||
else //shows a fraction if seconds is < 1
|
||||
if(second_rounded) //no sense rounding again if it's already done
|
||||
second = " and [second] seconds"
|
||||
else
|
||||
second = " and [round(second, 0.1)] seconds"
|
||||
else
|
||||
if(second_adjusted == 1 && second >= 1)
|
||||
second = "[truncate ? "second" : "1 second"]"
|
||||
else if(second > 1)
|
||||
second = "[second_adjusted] seconds"
|
||||
else
|
||||
if(second_rounded)
|
||||
second = "[second] seconds"
|
||||
else
|
||||
second = "[round(second, 0.1)] seconds"
|
||||
else
|
||||
second = null
|
||||
|
||||
if(!minute)
|
||||
return "[second]"
|
||||
if(minute >= 60)
|
||||
hour = FLOOR(minute/60, 1)
|
||||
minute = (minute - (hour*60))
|
||||
if(minute) //alot simpler from here since you don't have to worry about fractions
|
||||
if(minute != 1)
|
||||
if((day || hour) && second)
|
||||
minute = ", [minute] minutes"
|
||||
else if((day || hour) && !second)
|
||||
minute = " and [minute] minutes"
|
||||
else
|
||||
minute = "[minute] minutes"
|
||||
else
|
||||
if((day || hour) && second)
|
||||
minute = ", 1 minute"
|
||||
else if((day || hour) && !second)
|
||||
minute = " and 1 minute"
|
||||
else
|
||||
minute = "[truncate ? "minute" : "1 minute"]"
|
||||
else
|
||||
minute = null
|
||||
|
||||
if(!hour)
|
||||
return "[minute][second]"
|
||||
if(hour >= 24)
|
||||
day = FLOOR(hour/24, 1)
|
||||
hour = (hour - (day*24))
|
||||
if(hour)
|
||||
if(hour != 1)
|
||||
if(day && (minute || second))
|
||||
hour = ", [hour] hours"
|
||||
else if(day && (!minute || !second))
|
||||
hour = " and [hour] hours"
|
||||
else
|
||||
hour = "[hour] hours"
|
||||
else
|
||||
if(day && (minute || second))
|
||||
hour = ", 1 hour"
|
||||
else if(day && (!minute || !second))
|
||||
hour = " and 1 hour"
|
||||
else
|
||||
hour = "[truncate ? "hour" : "1 hour"]"
|
||||
else
|
||||
hour = null
|
||||
|
||||
if(!day)
|
||||
return "[hour][minute][second]"
|
||||
if(day > 1)
|
||||
day = "[day] days"
|
||||
else
|
||||
day = "[truncate ? "day" : "1 day"]"
|
||||
|
||||
return "[day][hour][minute][second]"
|
||||
@@ -522,6 +522,14 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return "[round((powerused * 0.000001),0.001)] MW"
|
||||
return "[round((powerused * 0.000000001),0.0001)] GW"
|
||||
|
||||
/proc/get_mob_by_ckey(key)
|
||||
if(!key)
|
||||
return
|
||||
var/list/mobs = sortmobs()
|
||||
for(var/mob/M in mobs)
|
||||
if(M.ckey == key)
|
||||
return M
|
||||
|
||||
//Forces a variable to be posative
|
||||
/proc/modulus(var/M)
|
||||
if(M >= 0)
|
||||
|
||||
@@ -60,13 +60,13 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
|
||||
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
|
||||
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
|
||||
access_hop, access_RC_announce, access_keycard_auth, access_gateway)
|
||||
access_hop, access_RC_announce, access_keycard_auth) //, access_gateway) //VOREStation Edit
|
||||
minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
|
||||
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
|
||||
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
|
||||
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
|
||||
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
|
||||
access_hop, access_RC_announce, access_keycard_auth, access_gateway)
|
||||
access_hop, access_RC_announce, access_keycard_auth) //, access_gateway) //VOREStation Edit
|
||||
|
||||
/datum/job/secretary
|
||||
title = "Command Secretary"
|
||||
|
||||
@@ -434,6 +434,7 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
H.job = rank
|
||||
log_game("JOINED [key_name(H)] as \"[rank]\"")
|
||||
log_game("SPECIES [key_name(H)] is a: \"[H.species.name]\"") //VOREStation Add
|
||||
|
||||
// If they're head, give them the account info for their department
|
||||
if(H.mind && job.head_position)
|
||||
|
||||
@@ -395,7 +395,7 @@
|
||||
return 0
|
||||
|
||||
// Do after stuff here
|
||||
user << "<span class='notice'>You start to weld the [src]..</span>"
|
||||
user << "<span class='notice'>You start to weld [src]..</span>"
|
||||
playsound(src.loc, WT.usesound, 50, 1)
|
||||
WT.eyecheck(user)
|
||||
busy = 1
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
/obj/machinery/computer/atmoscontrol/laptop
|
||||
name = "Atmospherics Laptop"
|
||||
desc = "A cheap laptop."
|
||||
icon_screen = "atmoslaptop"
|
||||
icon_state = "laptop"
|
||||
icon_keyboard = "laptop_key"
|
||||
density = 0
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
desc = "Used to view, edit and maintain medical records."
|
||||
icon_keyboard = "med_key"
|
||||
icon_screen = "medcomp"
|
||||
density = 0 //Why does a laptop blocks peoples.
|
||||
light_color = "#315ab4"
|
||||
req_one_access = list(access_medical, access_forensics_lockers, access_robotics)
|
||||
circuit = /obj/item/weapon/circuitboard/med_data
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(breather.internals)
|
||||
breather.internals.icon_state = "internal0"
|
||||
breather.remove_from_mob(contained)
|
||||
visible_message("<span class='notice'>The mask rapidly retracts just before /the [src] is destroyed!</span>")
|
||||
visible_message("<span class='notice'>\The [contained] rapidly retracts just before /the [src] is destroyed!</span>")
|
||||
breather = null
|
||||
|
||||
QDEL_NULL(tank)
|
||||
@@ -45,11 +45,11 @@
|
||||
if(istype(target) && CanMouseDrop(target))
|
||||
if(!can_apply_to_target(target, usr)) // There is no point in attempting to apply a mask if it's impossible.
|
||||
return
|
||||
usr.visible_message("\The [usr] begins placing the mask onto [target]..")
|
||||
usr.visible_message("\The [usr] begins placing \the [contained] onto [target].")
|
||||
if(!do_mob(usr, target, 25) || !can_apply_to_target(target, usr))
|
||||
return
|
||||
// place mask and add fingerprints
|
||||
usr.visible_message("\The [usr] has placed \the mask on [target]'s mouth.")
|
||||
usr.visible_message("\The [usr] has placed \the [contained] on [target]'s mouth.")
|
||||
attach_mask(target)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
tank.forceMove(src)
|
||||
breather.remove_from_mob(contained)
|
||||
contained.forceMove(src)
|
||||
src.visible_message("<span class='notice'>\The [user] makes \The [contained] rapidly retracts back into \the [src]!</span>")
|
||||
src.visible_message("<span class='notice'>\The [user] makes \the [contained] rapidly retract back into \the [src]!</span>")
|
||||
if(breather.internals)
|
||||
breather.internals.icon_state = "internal0"
|
||||
breather = null
|
||||
@@ -112,7 +112,7 @@
|
||||
to_chat(user, "<span class='warning'>There is no tank in \the [src].</span>")
|
||||
return
|
||||
if(stat & MAINT)
|
||||
to_chat(user, "<span class='warning'>Please close \the maintenance hatch first.</span>")
|
||||
to_chat(user, "<span class='warning'>Please close the maintenance hatch first.</span>")
|
||||
return
|
||||
if(!Adjacent(target))
|
||||
to_chat(user, "<span class='warning'>Please stay close to \the [src].</span>")
|
||||
@@ -123,18 +123,15 @@
|
||||
return
|
||||
//Checking if breather is still valid
|
||||
if(target == breather && target.wear_mask != contained)
|
||||
to_chat(user, "<span class='warning'>\The [target] is not using the supplied mask.</span>")
|
||||
to_chat(user, "<span class='warning'>\The [target] is not using the supplied [contained].</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/machinery/oxygen_pump/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_screwdriver())
|
||||
stat ^= MAINT
|
||||
user.visible_message("<span class='notice'>\The [user] [stat & MAINT ? "opens" : "closes"] \the [src].</span>", "<span class='notice'>You [stat & MAINT ? "open" : "close"] \the [src].</span>")
|
||||
if(stat & MAINT)
|
||||
icon_state = icon_state_open
|
||||
if(!stat)
|
||||
icon_state = icon_state_closed
|
||||
user.visible_message("<span class='notice'>\The [user] [(stat & MAINT) ? "opens" : "closes"] \the [src].</span>", "<span class='notice'>You [(stat & MAINT) ? "open" : "close"] \the [src].</span>")
|
||||
icon_state = (stat & MAINT) ? icon_state_open : icon_state_closed
|
||||
//TO-DO: Open icon
|
||||
if(istype(W, /obj/item/weapon/tank) && (stat & MAINT))
|
||||
if(tank)
|
||||
@@ -151,7 +148,7 @@
|
||||
/obj/machinery/oxygen_pump/examine(var/mob/user)
|
||||
. = ..()
|
||||
if(tank)
|
||||
to_chat(user, "The meter shows [round(tank.air_contents.return_pressure())]")
|
||||
to_chat(user, "The meter shows [round(tank.air_contents.return_pressure())] kPa.")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It is missing a tank!</span>")
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ var/global/list/ashtray_cache = list()
|
||||
if(!material)
|
||||
qdel(src)
|
||||
return
|
||||
max_butts = round(material.hardness/10) //This is arbitrary but whatever.
|
||||
max_butts = round(material.hardness/5) //This is arbitrary but whatever.
|
||||
src.pixel_y = rand(-5, 5)
|
||||
src.pixel_x = rand(-6, 6)
|
||||
update_icon()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Welding Tool
|
||||
*/
|
||||
/obj/item/weapon/weldingtool
|
||||
name = "welding tool"
|
||||
name = "\improper welding tool"
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "welder"
|
||||
item_state = "welder"
|
||||
|
||||
@@ -9,18 +9,26 @@
|
||||
var/icon_closed = "closed"
|
||||
var/icon_opened = "open"
|
||||
var/opened = 0
|
||||
var/welded = 0
|
||||
var/sealed = 0
|
||||
var/seal_tool = /obj/item/weapon/weldingtool //Tool used to seal the closet, defaults to welder
|
||||
var/wall_mounted = 0 //never solid (You can always pass over it)
|
||||
var/health = 100
|
||||
|
||||
var/breakout = 0 //if someone is currently breaking out. mutex
|
||||
var/breakout_time = 2 //2 minutes by default
|
||||
var/breakout_sound = 'sound/effects/grillehit.ogg' //Sound that plays while breaking out
|
||||
|
||||
var/storage_capacity = 2 * MOB_MEDIUM //This is so that someone can't pack hundreds of items in a locker/crate
|
||||
//then open it in a populated area to crash clients.
|
||||
var/storage_cost = 40 //How much space this closet takes up if it's stuffed in another closet
|
||||
|
||||
var/open_sound = 'sound/machines/click.ogg'
|
||||
var/close_sound = 'sound/machines/click.ogg'
|
||||
|
||||
var/store_misc = 1
|
||||
var/store_items = 1
|
||||
var/store_mobs = 1
|
||||
var/store_misc = 1 //Chameleon item check
|
||||
var/store_items = 1 //Will the closet store items?
|
||||
var/store_mobs = 1 //Will the closet store mobs?
|
||||
var/max_closets = 0 //Number of other closets allowed on tile before it won't close.
|
||||
|
||||
var/list/starts_with
|
||||
|
||||
@@ -42,7 +50,7 @@
|
||||
content_size += Ceiling(I.w_class/2)
|
||||
if(content_size > storage_capacity-5)
|
||||
storage_capacity = content_size + 5
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/closet/examine(mob/user)
|
||||
if(..(user, 1) && !opened)
|
||||
@@ -51,29 +59,33 @@
|
||||
if(!I.anchored)
|
||||
content_size += Ceiling(I.w_class/2)
|
||||
if(!content_size)
|
||||
user << "It is empty."
|
||||
to_chat(user, "It is empty.")
|
||||
else if(storage_capacity > content_size*4)
|
||||
user << "It is barely filled."
|
||||
to_chat(user, "It is barely filled.")
|
||||
else if(storage_capacity > content_size*2)
|
||||
user << "It is less than half full."
|
||||
to_chat(user, "It is less than half full.")
|
||||
else if(storage_capacity > content_size)
|
||||
user << "There is still some free space."
|
||||
to_chat(user, "There is still some free space.")
|
||||
else
|
||||
user << "It is full."
|
||||
to_chat(user, "It is full.")
|
||||
|
||||
/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0 || wall_mounted)) return 1
|
||||
return (!density)
|
||||
|
||||
/obj/structure/closet/proc/can_open()
|
||||
if(src.welded)
|
||||
if(src.sealed)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/can_close()
|
||||
var/closet_count = 0
|
||||
for(var/obj/structure/closet/closet in get_turf(src))
|
||||
if(closet != src)
|
||||
return 0
|
||||
if(!closet.anchored)
|
||||
closet_count ++
|
||||
if(closet_count > max_closets)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/dump_contents()
|
||||
@@ -102,7 +114,7 @@
|
||||
src.icon_state = src.icon_opened
|
||||
src.opened = 1
|
||||
playsound(src.loc, open_sound, 15, 1, -3)
|
||||
density = 0
|
||||
density = !density
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/close()
|
||||
@@ -119,12 +131,14 @@
|
||||
stored_units += store_items(stored_units)
|
||||
if(store_mobs)
|
||||
stored_units += store_mobs(stored_units)
|
||||
if(max_closets)
|
||||
stored_units += store_closets(stored_units)
|
||||
|
||||
src.icon_state = src.icon_closed
|
||||
src.opened = 0
|
||||
|
||||
playsound(src.loc, close_sound, 15, 1, -3)
|
||||
density = 1
|
||||
density = !density
|
||||
return 1
|
||||
|
||||
//Cham Projector Exception
|
||||
@@ -162,9 +176,25 @@
|
||||
added_units += M.mob_size
|
||||
return added_units
|
||||
|
||||
/obj/structure/closet/proc/store_closets(var/stored_units)
|
||||
var/added_units = 0
|
||||
for(var/obj/structure/closet/C in src.loc)
|
||||
if(C == src) //Don't store ourself
|
||||
continue
|
||||
if(C.anchored) //Don't worry about anchored things on the same tile
|
||||
continue
|
||||
if(C.max_closets) //Prevents recursive storage
|
||||
continue
|
||||
if(stored_units + added_units + storage_cost > storage_capacity)
|
||||
break
|
||||
C.forceMove(src)
|
||||
added_units += storage_cost
|
||||
return added_units
|
||||
|
||||
|
||||
/obj/structure/closet/proc/toggle(mob/user as mob)
|
||||
if(!(src.opened ? src.close() : src.open()))
|
||||
user << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
return
|
||||
update_icon()
|
||||
|
||||
@@ -222,7 +252,7 @@
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
playsound(src, WT.usesound, 50)
|
||||
new /obj/item/stack/material/steel(src.loc)
|
||||
@@ -248,21 +278,25 @@
|
||||
W.forceMove(src.loc)
|
||||
else if(istype(W, /obj/item/weapon/packageWrap))
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(!WT.remove_fuel(0,user))
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
||||
return
|
||||
playsound(src, WT.usesound, 50)
|
||||
src.welded = !src.welded
|
||||
src.update_icon()
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("<span class='warning'>[src] has been [welded?"welded shut":"unwelded"] by [user.name].</span>", 3, "You hear welding.", 2)
|
||||
else if(seal_tool)
|
||||
if(istype(W, seal_tool))
|
||||
var/obj/item/weapon/S = W
|
||||
if(istype(S, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = S
|
||||
if(!WT.remove_fuel(0,user))
|
||||
if(!WT.isOn())
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
if(do_after(user, 20 * S.toolspeed))
|
||||
playsound(src, S.usesound, 50)
|
||||
src.sealed = !src.sealed
|
||||
src.update_icon()
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("<span class='warning'>[src] has been [sealed?"sealed":"unsealed"] by [user.name].</span>", 3)
|
||||
else if(W.is_wrench())
|
||||
if(welded)
|
||||
if(sealed)
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
|
||||
else
|
||||
@@ -270,7 +304,7 @@
|
||||
playsound(src, W.usesound, 50)
|
||||
if(do_after(user, 20 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>"
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
else
|
||||
src.attack_hand(user)
|
||||
@@ -306,7 +340,7 @@
|
||||
return
|
||||
|
||||
if(!src.open())
|
||||
user << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
|
||||
/obj/structure/closet/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
@@ -316,7 +350,7 @@
|
||||
/obj/structure/closet/attack_self_tk(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(!src.toggle())
|
||||
usr << "<span class='notice'>It won't budge!</span>"
|
||||
to_chat(usr, "<span class='notice'>It won't budge!</span>")
|
||||
|
||||
/obj/structure/closet/attack_ghost(mob/ghost)
|
||||
if(ghost.client && ghost.client.inquisitive_ghost)
|
||||
@@ -336,14 +370,14 @@
|
||||
src.add_fingerprint(usr)
|
||||
src.toggle(usr)
|
||||
else
|
||||
usr << "<span class='warning'>This mob type can't use this verb.</span>"
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
/obj/structure/closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
/obj/structure/closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
overlays.Cut()
|
||||
if(!opened)
|
||||
icon_state = icon_closed
|
||||
if(welded)
|
||||
overlays += "welded"
|
||||
if(sealed)
|
||||
overlays += "sealed"
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
@@ -359,20 +393,19 @@
|
||||
/obj/structure/closet/proc/req_breakout()
|
||||
if(opened)
|
||||
return 0 //Door's open... wait, why are you in it's contents then?
|
||||
if(!welded)
|
||||
return 0 //closed but not welded...
|
||||
if(!sealed)
|
||||
return 0 //closed but not sealed...
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/proc/mob_breakout(var/mob/living/escapee)
|
||||
var/breakout_time = 2 //2 minutes by default
|
||||
|
||||
if(breakout || !req_breakout())
|
||||
return
|
||||
|
||||
escapee.setClickCooldown(100)
|
||||
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
escapee << "<span class='warning'>You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)</span>"
|
||||
//okay, so the closet is either sealed or locked... resist!!!
|
||||
to_chat(escapee, "<span class='warning'>You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)</span>")
|
||||
|
||||
visible_message("<span class='danger'>\The [src] begins to shake violently!</span>")
|
||||
|
||||
@@ -389,20 +422,20 @@
|
||||
breakout = 0
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
|
||||
playsound(src.loc, breakout_sound, 100, 1)
|
||||
animate_shake()
|
||||
add_fingerprint(escapee)
|
||||
|
||||
//Well then break it!
|
||||
breakout = 0
|
||||
escapee << "<span class='warning'>You successfully break out!</span>"
|
||||
to_chat(escapee, "<span class='warning'>You successfully break out!</span>")
|
||||
visible_message("<span class='danger'>\The [escapee] successfully broke out of \the [src]!</span>")
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
|
||||
playsound(src.loc, breakout_sound, 100, 1)
|
||||
break_open()
|
||||
animate_shake()
|
||||
|
||||
/obj/structure/closet/proc/break_open()
|
||||
welded = 0
|
||||
sealed = 0
|
||||
update_icon()
|
||||
//Do this to prevent contents from being opened into nullspace (read: bluespace)
|
||||
if(istype(loc, /obj/structure/bigDelivery))
|
||||
@@ -421,3 +454,9 @@
|
||||
|
||||
/obj/structure/closet/AllowDrop()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/closet/return_air_for_internal_lifeform(var/mob/living/L)
|
||||
if(src.loc)
|
||||
if(istype(src.loc, /obj/structure/closet))
|
||||
return (loc.return_air_for_internal_lifeform(L))
|
||||
return return_air()
|
||||
@@ -4,9 +4,161 @@
|
||||
icon_state = "coffin"
|
||||
icon_closed = "coffin"
|
||||
icon_opened = "coffin_open"
|
||||
seal_tool = /obj/item/weapon/tool/screwdriver
|
||||
breakout_sound = 'sound/weapons/tablehit1.ogg'
|
||||
|
||||
/obj/structure/closet/coffin/update_icon()
|
||||
if(!opened)
|
||||
icon_state = icon_closed
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
/* Graves */
|
||||
/obj/structure/closet/grave
|
||||
name = "grave"
|
||||
desc = "Dirt."
|
||||
icon_state = "grave"
|
||||
icon_closed = "grave"
|
||||
icon_opened = "grave_open"
|
||||
seal_tool = null
|
||||
breakout_sound = 'sound/weapons/thudswoosh.ogg'
|
||||
anchored = 1
|
||||
max_closets = 1
|
||||
opened = 1
|
||||
|
||||
/obj/structure/closet/grave/attack_hand(mob/user as mob)
|
||||
if(opened)
|
||||
visible_message("<span class='notice'>[user] starts to climb into \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to lower yourself into \the [src.name].</span>")
|
||||
if(do_after(user, 50))
|
||||
user.forceMove(src.loc)
|
||||
visible_message("<span class='notice'>[user] climbs into \the [src.name].</span>", \
|
||||
"<span class='notice'>You climb into \the [src.name].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[user] decides not to climb into \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop climbing into \the [src.name].</span>")
|
||||
return
|
||||
|
||||
/obj/structure/closet/grave/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(opened && ismob(mover))
|
||||
var/mob/M = mover
|
||||
add_fingerprint(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.m_intent == "walk")
|
||||
to_chat(H, "<span class='warning'>You stop at the edge of \the [src.name].</span>")
|
||||
return FALSE
|
||||
else
|
||||
to_chat(H, "<span class='warning'>You fall into \the [src.name]!</span>")
|
||||
fall_in(H)
|
||||
return TRUE
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(R.a_intent == I_HELP)
|
||||
to_chat(R, "<span class='warning'>You stop at the edge of \the [src.name].</span>")
|
||||
return FALSE
|
||||
else
|
||||
to_chat(R, "<span class='warning'>You enter \the [src.name].</span>")
|
||||
return TRUE
|
||||
return TRUE //Everything else can move over the graves
|
||||
|
||||
/obj/structure/closet/grave/proc/fall_in(mob/living/L) //Only called on humans for now, but still
|
||||
L.Weaken(5)
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
var/limb_damage = rand(5,25)
|
||||
H.adjustBruteLoss(limb_damage)
|
||||
|
||||
/obj/structure/closet/grave/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(src.opened)
|
||||
if(istype(W, /obj/item/weapon/shovel))
|
||||
user.visible_message("<span class='notice'>[user] piles dirt into \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to pile dirt into \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] pats down the dirt on top of \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish filling in \the [src.name].</span>")
|
||||
close()
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops filling in \the [src.name].</span>", \
|
||||
"<span class='notice'>You change your mind and stop filling in \the [src.name].</span>")
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = W
|
||||
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
|
||||
return 0
|
||||
if(istype(W,/obj/item/tk_grab))
|
||||
return 0
|
||||
if(istype(W, /obj/item/weapon/storage/laundry_basket) && W.contents.len)
|
||||
var/obj/item/weapon/storage/laundry_basket/LB = W
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/obj/item/I in LB.contents)
|
||||
LB.remove_from_storage(I, T)
|
||||
user.visible_message("<span class='notice'>[user] empties \the [LB] into \the [src].</span>", \
|
||||
"<span class='notice'>You empty \the [LB] into \the [src].</span>", \
|
||||
"<span class='notice'>You hear rustling of clothes.</span>")
|
||||
return
|
||||
if(isrobot(user))
|
||||
return
|
||||
if(W.loc != user) // This should stop mounted modules ending up outside the module.
|
||||
return
|
||||
usr.drop_item()
|
||||
if(W)
|
||||
W.forceMove(src.loc)
|
||||
else
|
||||
if(istype(W, /obj/item/weapon/shovel))
|
||||
if(user.a_intent == I_HURT) // Hurt intent means you're trying to kill someone, or just get rid of the grave
|
||||
user.visible_message("<span class='notice'>[user] begins to smoothe out the dirt of \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to smoothe out the dirt of \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] finishes smoothing out \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish smoothing out \the [src.name].</span>")
|
||||
if(LAZYLEN(contents))
|
||||
alpha = 40 // If we've got stuff inside, like maybe a person, just make it hard to see us
|
||||
else
|
||||
qdel(src) // Else, go away
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops concealing \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop concealing \the [src.name].</span>")
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] begins to unearth \the [src.name].</span>", \
|
||||
"<span class='notice'>You start to unearth \the [src.name].</span>", \
|
||||
"<span class='notice'>You hear dirt being moved.</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
user.visible_message("<span class='notice'>[user] reaches the bottom of \the [src.name].</span>", \
|
||||
"<span class='notice'>You finish digging out \the [src.name].</span>")
|
||||
break_open()
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] stops digging out \the [src.name].</span>", \
|
||||
"<span class='notice'>You stop digging out \the [src.name].</span>")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/structure/closet/grave/close()
|
||||
..()
|
||||
if(!opened)
|
||||
sealed = TRUE
|
||||
|
||||
/obj/structure/closet/grave/open()
|
||||
.=..()
|
||||
alpha = 255 // Needed because of grave hiding
|
||||
|
||||
/obj/structure/closet/grave/bullet_act(var/obj/item/projectile/P)
|
||||
return PROJECTILE_CONTINUE // It's a hole in the ground, doesn't usually stop or even care about bullets
|
||||
|
||||
/obj/structure/closet/grave/return_air_for_internal_lifeform(var/mob/living/L)
|
||||
var/gasid = "carbon_dioxide"
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.species && H.species.exhale_type)
|
||||
gasid = H.species.exhale_type
|
||||
var/datum/gas_mixture/grave_breath = new()
|
||||
var/datum/gas_mixture/above_air = return_air()
|
||||
grave_breath.adjust_gas(gasid, BREATH_MOLES)
|
||||
grave_breath.temperature = (above_air.temperature) - 30 //Underground
|
||||
return grave_breath
|
||||
@@ -10,7 +10,7 @@
|
||||
open_sound = 'sound/vore/schlorp.ogg'
|
||||
close_sound = 'sound/vore/schlorp.ogg'
|
||||
opened = 0
|
||||
welded = 0 //Don't touch this.
|
||||
sealed = 0 //Don't touch this.
|
||||
health = 100
|
||||
|
||||
/obj/structure/closet/secure_closet/egg/attackby(obj/item/weapon/W, mob/user as mob) //This also prevents crew from welding the eggs and making them unable to be opened.
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
|
||||
overlays += icon(src.icon, "door")
|
||||
|
||||
if(welded)
|
||||
overlays += icon(src.icon,"welded")
|
||||
if(sealed)
|
||||
overlays += icon(src.icon,"sealed")
|
||||
|
||||
if(broken)
|
||||
overlays += icon(src.icon,"broken")
|
||||
|
||||
@@ -46,23 +46,23 @@
|
||||
|
||||
/obj/structure/closet/secure_closet/proc/togglelock(mob/user as mob)
|
||||
if(src.opened)
|
||||
user << "<span class='notice'>Close the locker first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the locker first.</span>")
|
||||
return
|
||||
if(src.broken)
|
||||
user << "<span class='warning'>The locker appears to be broken.</span>"
|
||||
to_chat(user, "<span class='warning'>The locker appears to be broken.</span>")
|
||||
return
|
||||
if(user.loc == src)
|
||||
user << "<span class='notice'>You can't reach the lock from inside.</span>"
|
||||
to_chat(user, "<span class='notice'>You can't reach the lock from inside.</span>")
|
||||
return
|
||||
if(src.allowed(user))
|
||||
src.locked = !src.locked
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
for(var/mob/O in viewers(user, 3))
|
||||
if((O.client && !( O.blinded )))
|
||||
O << "<span class='notice'>The locker has been [locked ? null : "un"]locked by [user].</span>"
|
||||
to_chat(O, "<span class='notice'>The locker has been [locked ? null : "un"]locked by [user].</span>")
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='notice'>Access Denied</span>"
|
||||
to_chat(user, "<span class='notice'>Access Denied</span>")
|
||||
|
||||
/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(src.opened)
|
||||
@@ -73,7 +73,7 @@
|
||||
if(src.large)
|
||||
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
|
||||
else
|
||||
user << "<span class='notice'>The locker is too small to stuff [G.affecting] into!</span>"
|
||||
to_chat(user, "<span class='notice'>The locker is too small to stuff [G.affecting] into!</span>")
|
||||
if(isrobot(user))
|
||||
return
|
||||
if(W.loc != user) // This should stop mounted modules ending up outside the module.
|
||||
@@ -89,14 +89,14 @@
|
||||
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
playsound(src.loc, "sparks", 50, 1)
|
||||
else if(W.is_wrench())
|
||||
if(welded)
|
||||
if(sealed)
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
|
||||
else
|
||||
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
|
||||
if(do_after(user, 20 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>"
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
return
|
||||
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
|
||||
@@ -143,9 +143,9 @@
|
||||
src.add_fingerprint(usr)
|
||||
src.togglelock(usr)
|
||||
else
|
||||
usr << "<span class='warning'>This mob type can't use this verb.</span>"
|
||||
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
|
||||
|
||||
/obj/structure/closet/secure_closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
/obj/structure/closet/secure_closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
|
||||
overlays.Cut()
|
||||
|
||||
if(!opened)
|
||||
@@ -155,8 +155,8 @@
|
||||
icon_state = icon_locked
|
||||
else
|
||||
icon_state = icon_closed
|
||||
if(welded)
|
||||
overlays += "welded"
|
||||
if(sealed)
|
||||
overlays += "sealed"
|
||||
else
|
||||
icon_state = icon_opened
|
||||
|
||||
|
||||
@@ -593,6 +593,25 @@ var/list/admin_verbs_event_manager = list(
|
||||
feedback_add_details("admin_verb","OC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/client/proc/findStealthKey(txt)
|
||||
if(txt)
|
||||
for(var/P in GLOB.stealthminID)
|
||||
if(GLOB.stealthminID[P] == txt)
|
||||
return P
|
||||
txt = GLOB.stealthminID[ckey]
|
||||
return txt
|
||||
|
||||
/client/proc/createStealthKey()
|
||||
var/num = (rand(0,1000))
|
||||
var/i = 0
|
||||
while(i == 0)
|
||||
i = 1
|
||||
for(var/P in GLOB.stealthminID)
|
||||
if(num == GLOB.stealthminID[P])
|
||||
num++
|
||||
i = 0
|
||||
GLOB.stealthminID["[ckey]"] = "@[num2text(num)]"
|
||||
|
||||
/client/proc/stealth()
|
||||
set category = "Admin"
|
||||
set name = "Stealth Mode"
|
||||
@@ -603,10 +622,12 @@ var/list/admin_verbs_event_manager = list(
|
||||
mob.name = capitalize(ckey)
|
||||
else
|
||||
var/new_key = ckeyEx(input("Enter your desired display name.", "Fake Key", key) as text|null)
|
||||
if(!new_key) return
|
||||
if(!new_key)
|
||||
return
|
||||
if(length(new_key) >= 26)
|
||||
new_key = copytext(new_key, 1, 26)
|
||||
holder.fakekey = new_key
|
||||
createStealthKey()
|
||||
if(istype(mob, /mob/new_player))
|
||||
mob.name = new_key
|
||||
log_admin("[key_name(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]")
|
||||
|
||||
@@ -10,6 +10,20 @@
|
||||
check_antagonists()
|
||||
return
|
||||
|
||||
if(href_list["ahelp"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/ahelp_ref = href_list["ahelp"]
|
||||
var/datum/admin_help/AH = locate(ahelp_ref)
|
||||
if(AH)
|
||||
AH.Action(href_list["ahelp_action"])
|
||||
else
|
||||
to_chat(usr, "Ticket [ahelp_ref] has been deleted!")
|
||||
|
||||
else if(href_list["ahelp_tickets"])
|
||||
GLOB.ahelp_tickets.BrowseTickets(text2num(href_list["ahelp_tickets"]))
|
||||
|
||||
if(href_list["dbsearchckey"] || href_list["dbsearchadmin"])
|
||||
|
||||
var/adminckey = href_list["dbsearchadmin"]
|
||||
@@ -841,7 +855,9 @@
|
||||
M << "<font color='red'>No ban appeals URL has been set.</font>"
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
|
||||
message_admins("<font color='blue'>[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.</font>")
|
||||
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
qdel(M.client)
|
||||
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
|
||||
if("No")
|
||||
@@ -867,7 +883,9 @@
|
||||
message_admins("<font color='blue'>[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.</font>")
|
||||
feedback_inc("ban_perma",1)
|
||||
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
|
||||
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
qdel(M.client)
|
||||
//qdel(M)
|
||||
if("Cancel")
|
||||
|
||||
@@ -1,32 +1,599 @@
|
||||
/client/var/datum/admin_help/current_ticket //the current ticket the (usually) not-admin client is dealing with
|
||||
|
||||
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
|
||||
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as")
|
||||
//
|
||||
//TICKET MANAGER
|
||||
//
|
||||
|
||||
GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
/datum/admin_help_tickets
|
||||
var/list/active_tickets = list()
|
||||
var/list/closed_tickets = list()
|
||||
var/list/resolved_tickets = list()
|
||||
|
||||
var/obj/effect/statclick/ticket_list/astatclick = new(null, null, AHELP_ACTIVE)
|
||||
var/obj/effect/statclick/ticket_list/cstatclick = new(null, null, AHELP_CLOSED)
|
||||
var/obj/effect/statclick/ticket_list/rstatclick = new(null, null, AHELP_RESOLVED)
|
||||
|
||||
/datum/admin_help_tickets/Destroy()
|
||||
QDEL_LIST(active_tickets)
|
||||
QDEL_LIST(closed_tickets)
|
||||
QDEL_LIST(resolved_tickets)
|
||||
QDEL_NULL(astatclick)
|
||||
QDEL_NULL(cstatclick)
|
||||
QDEL_NULL(rstatclick)
|
||||
return ..()
|
||||
|
||||
//private
|
||||
/datum/admin_help_tickets/proc/ListInsert(datum/admin_help/new_ticket)
|
||||
var/list/ticket_list
|
||||
switch(new_ticket.state)
|
||||
if(AHELP_ACTIVE)
|
||||
ticket_list = active_tickets
|
||||
if(AHELP_CLOSED)
|
||||
ticket_list = closed_tickets
|
||||
if(AHELP_RESOLVED)
|
||||
ticket_list = resolved_tickets
|
||||
else
|
||||
CRASH("Invalid ticket state: [new_ticket.state]")
|
||||
var/num_closed = ticket_list.len
|
||||
if(num_closed)
|
||||
for(var/I in 1 to num_closed)
|
||||
var/datum/admin_help/AH = ticket_list[I]
|
||||
if(AH.id > new_ticket.id)
|
||||
ticket_list.Insert(I, new_ticket)
|
||||
return
|
||||
ticket_list += new_ticket
|
||||
|
||||
//opens the ticket listings for one of the 3 states
|
||||
/datum/admin_help_tickets/proc/BrowseTickets(state)
|
||||
var/list/l2b
|
||||
var/title
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
l2b = active_tickets
|
||||
title = "Active Tickets"
|
||||
if(AHELP_CLOSED)
|
||||
l2b = closed_tickets
|
||||
title = "Closed Tickets"
|
||||
if(AHELP_RESOLVED)
|
||||
l2b = resolved_tickets
|
||||
title = "Resolved Tickets"
|
||||
if(!l2b)
|
||||
return
|
||||
var/list/dat = list("<html><head><title>[title]</title></head>")
|
||||
dat += "<A HREF='?_src_=holder;ahelp_tickets=[state]'>Refresh</A><br><br>"
|
||||
for(var/I in l2b)
|
||||
var/datum/admin_help/AH = I
|
||||
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[AH.id]</span>: <A HREF='?_src_=holder;ahelp=\ref[AH];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A></span><br>"
|
||||
|
||||
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/admin_help_tickets/proc/stat_entry()
|
||||
var/num_disconnected = 0
|
||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||
for(var/I in active_tickets)
|
||||
var/datum/admin_help/AH = I
|
||||
if(AH.initiator)
|
||||
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
|
||||
else
|
||||
++num_disconnected
|
||||
if(num_disconnected)
|
||||
stat("Disconnected:", astatclick.update("[num_disconnected]"))
|
||||
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
|
||||
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
|
||||
|
||||
//Reassociate still open ticket if one exists
|
||||
/datum/admin_help_tickets/proc/ClientLogin(client/C)
|
||||
C.current_ticket = CKey2ActiveTicket(C.ckey)
|
||||
if(C.current_ticket)
|
||||
C.current_ticket.AddInteraction("Client reconnected.")
|
||||
C.current_ticket.initiator = C
|
||||
|
||||
//Dissasociate ticket
|
||||
/datum/admin_help_tickets/proc/ClientLogout(client/C)
|
||||
if(C.current_ticket)
|
||||
C.current_ticket.AddInteraction("Client disconnected.")
|
||||
C.current_ticket.initiator = null
|
||||
C.current_ticket = null
|
||||
|
||||
//Get a ticket given a ckey
|
||||
/datum/admin_help_tickets/proc/CKey2ActiveTicket(ckey)
|
||||
for(var/I in active_tickets)
|
||||
var/datum/admin_help/AH = I
|
||||
if(AH.initiator_ckey == ckey)
|
||||
return AH
|
||||
|
||||
//
|
||||
//TICKET LIST STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ticket_list
|
||||
var/current_state
|
||||
|
||||
/obj/effect/statclick/ticket_list/New(loc, name, state)
|
||||
current_state = state
|
||||
..()
|
||||
|
||||
/obj/effect/statclick/ticket_list/Click()
|
||||
GLOB.ahelp_tickets.BrowseTickets(current_state)
|
||||
|
||||
//
|
||||
//TICKET DATUM
|
||||
//
|
||||
|
||||
/datum/admin_help
|
||||
var/id
|
||||
var/name
|
||||
var/state = AHELP_ACTIVE
|
||||
|
||||
var/opened_at
|
||||
var/closed_at
|
||||
|
||||
var/client/initiator //semi-misnomer, it's the person who ahelped/was bwoinked
|
||||
var/initiator_ckey
|
||||
var/initiator_key_name
|
||||
|
||||
var/list/_interactions //use AddInteraction() or, preferably, admin_ticket_log()
|
||||
|
||||
var/obj/effect/statclick/ahelp/statclick
|
||||
|
||||
var/static/ticket_counter = 0
|
||||
|
||||
//call this on its own to create a ticket, don't manually assign current_ticket
|
||||
//msg is the title of the ticket: usually the ahelp text
|
||||
//is_bwoink is TRUE if this ticket was started by an admin PM
|
||||
/datum/admin_help/New(msg, client/C, is_bwoink)
|
||||
//clean the input msg
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg || !C || !C.mob)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
id = ++ticket_counter
|
||||
opened_at = world.time
|
||||
|
||||
name = msg
|
||||
|
||||
initiator = C
|
||||
initiator_ckey = initiator.ckey
|
||||
initiator_key_name = key_name(initiator, FALSE, TRUE)
|
||||
if(initiator.current_ticket) //This is a bug
|
||||
log_debug("Multiple ahelp current_tickets")
|
||||
initiator.current_ticket.AddInteraction("Ticket erroneously left open by code")
|
||||
initiator.current_ticket.Close()
|
||||
initiator.current_ticket = src
|
||||
|
||||
var/parsed_message = keywords_lookup(msg)
|
||||
|
||||
statclick = new(null, src)
|
||||
_interactions = list()
|
||||
|
||||
if(is_bwoink)
|
||||
AddInteraction("<font color='blue'>[key_name_admin(usr)] PM'd [LinkedReplyName()]</font>")
|
||||
message_admins("<font color='blue'>Ticket [TicketHref("#[id]")] created</font>")
|
||||
else
|
||||
MessageNoRecipient(parsed_message)
|
||||
|
||||
//show it to the person adminhelping too
|
||||
to_chat(C, "<span class='adminnotice'>PM to-<b>Admins</b>: [name]</span>")
|
||||
|
||||
//send it to irc if nobody is on and tell us how many were on
|
||||
var/admin_number_present = send2irc_adminless_only(initiator_ckey, name)
|
||||
log_admin("Ticket #[id]: [key_name(initiator)]: [name] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
if(admin_number_present <= 0)
|
||||
to_chat(C, "<span class='notice'>No active admins are online, your adminhelp was sent to the admin irc.</span>")
|
||||
send2adminchat() //VOREStation Add
|
||||
GLOB.ahelp_tickets.active_tickets += src
|
||||
|
||||
/datum/admin_help/Destroy()
|
||||
RemoveActive()
|
||||
GLOB.ahelp_tickets.closed_tickets -= src
|
||||
GLOB.ahelp_tickets.resolved_tickets -= src
|
||||
return ..()
|
||||
|
||||
/datum/admin_help/proc/AddInteraction(formatted_message)
|
||||
_interactions += "[gameTimestamp()]: [formatted_message]"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/FullMonty(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = ADMIN_FULLMONTY_NONAME(initiator.mob)
|
||||
if(state == AHELP_ACTIVE)
|
||||
. += ClosureLinks(ref_src)
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/ClosureLinks(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=reject'>REJT</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=icissue'>IC</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=close'>CLOSE</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=resolve'>RSLVE</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=handleissue'>HANDLE</A>)"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/LinkedReplyName(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=reply'>[initiator_key_name]</A>"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket")
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=[action]'>[msg]</A>"
|
||||
|
||||
//message from the initiator without a target, all admins will see this
|
||||
//won't bug irc
|
||||
/datum/admin_help/proc/MessageNoRecipient(msg)
|
||||
var/ref_src = "\ref[src]"
|
||||
var/chat_msg = "<span class='adminnotice'><span class='adminhelp'>Ticket [TicketHref("#[id]", ref_src)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> [msg]</span>"
|
||||
|
||||
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in admins)
|
||||
if(X.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
window_flash(X)
|
||||
to_chat(X, chat_msg)
|
||||
|
||||
//Reopen a closed ticket
|
||||
/datum/admin_help/proc/Reopen()
|
||||
if(state == AHELP_ACTIVE)
|
||||
to_chat(usr, "<span class='warning'>This ticket is already open.</span>")
|
||||
return
|
||||
|
||||
if(GLOB.ahelp_tickets.CKey2ActiveTicket(initiator_ckey))
|
||||
to_chat(usr, "<span class='warning'>This user already has an active ticket, cannot reopen this one.</span>")
|
||||
return
|
||||
|
||||
statclick = new(null, src)
|
||||
GLOB.ahelp_tickets.active_tickets += src
|
||||
GLOB.ahelp_tickets.closed_tickets -= src
|
||||
GLOB.ahelp_tickets.resolved_tickets -= src
|
||||
switch(state)
|
||||
if(AHELP_CLOSED)
|
||||
feedback_dec("ahelp_close")
|
||||
if(AHELP_RESOLVED)
|
||||
feedback_dec("ahelp_resolve")
|
||||
state = AHELP_ACTIVE
|
||||
closed_at = null
|
||||
if(initiator)
|
||||
initiator.current_ticket = src
|
||||
|
||||
AddInteraction("<font color='purple'>Reopened by [key_name_admin(usr)]</font>")
|
||||
if(initiator)
|
||||
to_chat(initiator, "<font color='purple'>Ticket [TicketHref("#[id]")] was reopened by [key_name(usr)].</font>")
|
||||
var/msg = "<span class='adminhelp'>Ticket [TicketHref("#[id]")] reopened by [key_name_admin(usr)].</span>"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
feedback_inc("ahelp_reopen")
|
||||
TicketPanel() //can only be done from here, so refresh it
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/RemoveActive()
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
closed_at = world.time
|
||||
QDEL_NULL(statclick)
|
||||
GLOB.ahelp_tickets.active_tickets -= src
|
||||
if(initiator && initiator.current_ticket == src)
|
||||
initiator.current_ticket = null
|
||||
|
||||
//Mark open ticket as closed/meme
|
||||
/datum/admin_help/proc/Close(silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_CLOSED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
AddInteraction("<font color='red'>Closed by [key_name_admin(usr)].</font>")
|
||||
if(initiator)
|
||||
to_chat(initiator, "<font color='red'>Ticket [TicketHref("#[id]")] was closed by [key_name(usr)].</font>")
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_close")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] closed by [key_name_admin(usr)]."
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
|
||||
//Mark open ticket as resolved/legitimate, returns ahelp verb
|
||||
/datum/admin_help/proc/Resolve(silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_RESOLVED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
|
||||
AddInteraction("<font color='green'>Resolved by [key_name_admin(usr)].</font>")
|
||||
if(initiator)
|
||||
to_chat(initiator, "<font color='green'>Ticket [TicketHref("#[id]")] was marked resolved by [key_name(usr)].</font>")
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_resolve")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] resolved by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
|
||||
//Close and return ahelp verb, use if ticket is incoherent
|
||||
/datum/admin_help/proc/Reject(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
if(initiator)
|
||||
initiator << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
to_chat(initiator, "<font color='red' size='4'><b>- AdminHelp Rejected! -</b></font>")
|
||||
to_chat(initiator, "<font color='red'><b>Your admin help was rejected.</b></font>")
|
||||
to_chat(initiator, "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting.")
|
||||
|
||||
feedback_inc("ahelp_reject")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] rejected by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("Rejected by [key_name_admin(usr)].")
|
||||
Close(silent = TRUE)
|
||||
|
||||
//Resolve ticket with IC Issue message
|
||||
/datum/admin_help/proc/ICIssue(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
var/msg = "<font color='red' size='4'><b>- AdminHelp marked as IC issue! -</b></font><br>"
|
||||
msg += "<font color='red'><b>Losing is part of the game!</b></font><br>"
|
||||
msg += "<font color='red'>Your AdminHelp may also be unabled to be answered due to ongoing events.</font>"
|
||||
|
||||
if(initiator)
|
||||
to_chat(initiator, msg)
|
||||
|
||||
feedback_inc("ahelp_icissue")
|
||||
msg = "Ticket [TicketHref("#[id]")] marked as IC by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("Marked as IC issue by [key_name_admin(usr)]")
|
||||
Resolve(silent = TRUE)
|
||||
|
||||
//Resolve ticket with IC Issue message
|
||||
/datum/admin_help/proc/HandleIssue()
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
var/msg = "<font color='red'>Your AdminHelp is being handled by [key_name(usr)] please be patient.</font>"
|
||||
|
||||
if(initiator)
|
||||
to_chat(initiator, msg)
|
||||
|
||||
feedback_inc("ahelp_icissue")
|
||||
msg = "Ticket [TicketHref("#[id]")] being handled by [key_name(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("[key_name_admin(usr)] is now handling this ticket.")
|
||||
|
||||
//Show the ticket panel
|
||||
/datum/admin_help/proc/TicketPanel()
|
||||
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
|
||||
var/ref_src = "\ref[src]"
|
||||
dat += "<h4>Admin Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
|
||||
dat += "<b>State: "
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
dat += "<font color='red'>OPEN</font>"
|
||||
if(AHELP_RESOLVED)
|
||||
dat += "<font color='green'>RESOLVED</font>"
|
||||
if(AHELP_CLOSED)
|
||||
dat += "CLOSED"
|
||||
else
|
||||
dat += "UNKNOWN"
|
||||
dat += "</b>[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
|
||||
if(state != AHELP_ACTIVE)
|
||||
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
|
||||
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [(world.time - opened_at) / 600] minutes ago)"
|
||||
if(closed_at)
|
||||
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [(world.time - closed_at) / 600] minutes ago)"
|
||||
dat += "<br><br>"
|
||||
if(initiator)
|
||||
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
|
||||
else
|
||||
dat += "<b>DISCONNECTED</b>[GLOB.TAB][ClosureLinks(ref_src)]<br>"
|
||||
dat += "<br><b>Log:</b><br><br>"
|
||||
for(var/I in _interactions)
|
||||
dat += "[I]<br>"
|
||||
|
||||
usr << browse(dat.Join(), "window=ahelp[id];size=620x480")
|
||||
|
||||
/datum/admin_help/proc/Retitle()
|
||||
var/new_title = input(usr, "Enter a title for the ticket", "Rename Ticket", name) as text|null
|
||||
if(new_title)
|
||||
name = new_title
|
||||
//not saying the original name cause it could be a long ass message
|
||||
var/msg = "Ticket [TicketHref("#[id]")] titled [name] by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
TicketPanel() //we have to be here to do this
|
||||
|
||||
//Forwarded action from admin/Topic
|
||||
/datum/admin_help/proc/Action(action)
|
||||
testing("Ahelp action: [action]")
|
||||
switch(action)
|
||||
if("ticket")
|
||||
TicketPanel()
|
||||
if("retitle")
|
||||
Retitle()
|
||||
if("reject")
|
||||
Reject()
|
||||
if("reply")
|
||||
usr.client.cmd_ahelp_reply(initiator)
|
||||
if("icissue")
|
||||
ICIssue()
|
||||
if("close")
|
||||
Close()
|
||||
if("resolve")
|
||||
Resolve()
|
||||
if("handleissue")
|
||||
HandleIssue()
|
||||
if("reopen")
|
||||
Reopen()
|
||||
|
||||
//
|
||||
// TICKET STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ahelp
|
||||
var/datum/admin_help/ahelp_datum
|
||||
|
||||
/obj/effect/statclick/ahelp/New(loc, datum/admin_help/AH)
|
||||
ahelp_datum = AH
|
||||
..(loc)
|
||||
|
||||
/obj/effect/statclick/ahelp/update()
|
||||
return ..(ahelp_datum.name)
|
||||
|
||||
/obj/effect/statclick/ahelp/Click()
|
||||
ahelp_datum.TicketPanel()
|
||||
|
||||
/obj/effect/statclick/ahelp/Destroy()
|
||||
ahelp_datum = null
|
||||
return ..()
|
||||
|
||||
//
|
||||
// CLIENT PROCS
|
||||
//
|
||||
|
||||
/client/verb/adminhelp(msg as text)
|
||||
set category = "Admin"
|
||||
set name = "Adminhelp"
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
usr << "<font color='red'>Speech is currently admin-disabled.</font>"
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
src << "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>"
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: You cannot send adminhelps (Muted).</span>")
|
||||
return
|
||||
if(handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
adminhelped = 1 //Determines if they get the message to reply by clicking the name.
|
||||
|
||||
if(msg)
|
||||
handle_spam_prevention(MUTE_ADMINHELP)
|
||||
|
||||
//clean the input msg
|
||||
if(!msg)
|
||||
return
|
||||
msg = sanitize(msg)
|
||||
if(!msg)
|
||||
|
||||
//remove out adminhelp verb temporarily to prevent spamming of admins.
|
||||
src.verbs -= /client/verb/adminhelp
|
||||
spawn(1200)
|
||||
src.verbs += /client/verb/adminhelp // 2 minute cool-down for adminhelps
|
||||
|
||||
feedback_add_details("admin_verb","Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
if(current_ticket)
|
||||
if(alert(usr, "You already have a ticket open. Is this for the same issue?",,"Yes","No") != "No")
|
||||
if(current_ticket)
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Ticket not found, creating new one...</span>")
|
||||
else
|
||||
current_ticket.AddInteraction("[key_name_admin(usr)] opened a new ticket.")
|
||||
current_ticket.Close()
|
||||
|
||||
new /datum/admin_help(msg, src, FALSE)
|
||||
|
||||
//admin proc
|
||||
/client/proc/cmd_admin_ticket_panel()
|
||||
set name = "Show Ticket List"
|
||||
set category = "Admin"
|
||||
|
||||
if(!check_rights(R_ADMIN, TRUE))
|
||||
return
|
||||
var/original_msg = msg
|
||||
|
||||
var/browse_to
|
||||
|
||||
switch(input("Display which ticket list?") as null|anything in list("Active Tickets", "Closed Tickets", "Resolved Tickets"))
|
||||
if("Active Tickets")
|
||||
browse_to = AHELP_ACTIVE
|
||||
if("Closed Tickets")
|
||||
browse_to = AHELP_CLOSED
|
||||
if("Resolved Tickets")
|
||||
browse_to = AHELP_RESOLVED
|
||||
else
|
||||
return
|
||||
|
||||
GLOB.ahelp_tickets.BrowseTickets(browse_to)
|
||||
|
||||
//
|
||||
// LOGGING
|
||||
//
|
||||
|
||||
//Use this proc when an admin takes action that may be related to an open ticket on what
|
||||
//what can be a client, ckey, or mob
|
||||
/proc/admin_ticket_log(what, message)
|
||||
var/client/C
|
||||
var/mob/Mob = what
|
||||
if(istype(Mob))
|
||||
C = Mob.client
|
||||
else
|
||||
C = what
|
||||
if(istype(C) && C.current_ticket)
|
||||
C.current_ticket.AddInteraction(message)
|
||||
return C.current_ticket
|
||||
if(istext(what)) //ckey
|
||||
var/datum/admin_help/AH = GLOB.ahelp_tickets.CKey2ActiveTicket(what)
|
||||
if(AH)
|
||||
AH.AddInteraction(message)
|
||||
return AH
|
||||
|
||||
//
|
||||
// HELPER PROCS
|
||||
//
|
||||
|
||||
/proc/get_admin_counts(requiredflags = R_BAN)
|
||||
. = list("total" = list(), "noflags" = list(), "afk" = list(), "stealth" = list(), "present" = list())
|
||||
for(var/client/X in admins)
|
||||
.["total"] += X
|
||||
if(requiredflags != 0 && !check_rights(rights_required = requiredflags, show_msg = FALSE, C = X)) //VOREStation Edit
|
||||
.["noflags"] += X
|
||||
else if(X.is_afk())
|
||||
.["afk"] += X
|
||||
else if(X.holder.fakekey)
|
||||
.["stealth"] += X
|
||||
else
|
||||
.["present"] += X
|
||||
|
||||
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/activemins = adm["present"]
|
||||
. = activemins.len
|
||||
if(. <= 0)
|
||||
var/final = ""
|
||||
var/list/afkmins = adm["afk"]
|
||||
var/list/stealthmins = adm["stealth"]
|
||||
var/list/powerlessmins = adm["noflags"]
|
||||
var/list/allmins = adm["total"]
|
||||
if(!afkmins.len && !stealthmins.len && !powerlessmins.len)
|
||||
final = "[msg] - No admins online"
|
||||
else
|
||||
final = "[msg] - All admins stealthed\[[english_list(stealthmins)]\], AFK\[[english_list(afkmins)]\], or lacks +BAN\[[english_list(powerlessmins)]\]! Total: [allmins.len] "
|
||||
send2irc(source,final)
|
||||
|
||||
/proc/ircadminwho()
|
||||
var/list/message = list("Admins: ")
|
||||
var/list/admin_keys = list()
|
||||
for(var/adm in admins)
|
||||
var/client/C = adm
|
||||
admin_keys += "[C][C.holder.fakekey ? "(Stealth)" : ""][C.is_afk() ? "(AFK)" : ""]"
|
||||
|
||||
for(var/admin in admin_keys)
|
||||
if(LAZYLEN(admin_keys) > 1)
|
||||
message += ", [admin]"
|
||||
else
|
||||
message += "[admin]"
|
||||
|
||||
return jointext(message, "")
|
||||
|
||||
/proc/keywords_lookup(msg,irc)
|
||||
|
||||
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
|
||||
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as", "i")
|
||||
|
||||
//explode the input msg into a list
|
||||
var/list/msglist = splittext(msg, " ")
|
||||
@@ -35,9 +602,11 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
var/list/surnames = list()
|
||||
var/list/forenames = list()
|
||||
var/list/ckeys = list()
|
||||
var/founds = ""
|
||||
for(var/mob/M in mob_list)
|
||||
var/list/indexing = list(M.real_name, M.name)
|
||||
if(M.mind) indexing += M.mind.name
|
||||
if(M.mind)
|
||||
indexing += M.mind.name
|
||||
|
||||
for(var/string in indexing)
|
||||
var/list/L = splittext(string, " ")
|
||||
@@ -77,55 +646,17 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
|
||||
mobs_found += found
|
||||
if(!ai_found && isAI(found))
|
||||
ai_found = 1
|
||||
msg += "<b><font color='black'>[original_word] (<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>)</font></b> "
|
||||
var/is_antag = 0
|
||||
if(found.mind && found.mind.special_role)
|
||||
is_antag = 1
|
||||
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
|
||||
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
|
||||
continue
|
||||
msg += "[original_word] "
|
||||
|
||||
if(!mob) //this doesn't happen
|
||||
return
|
||||
|
||||
var/ai_cl
|
||||
if(ai_found)
|
||||
ai_cl = " (<A HREF='?_src_=holder;adminchecklaws=\ref[mob]'>CL</A>)"
|
||||
|
||||
//Options bar: mob, details ( admin = 2, dev = 3, event manager = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so),
|
||||
// highlight special roles (0 = everyone has same looking name, 1 = antags / special roles get a golden name)
|
||||
|
||||
msg = "<b><font color=red>Request for Help: </font></b><font color='blue'><b>[get_options_bar(mob, 2, 1, 1)][ai_cl]</b> [msg]</font>"
|
||||
|
||||
var/admin_number_afk = 0
|
||||
|
||||
for(var/client/X in admins)
|
||||
if((R_ADMIN|R_MOD|R_EVENT|R_SERVER) & X.holder.rights)
|
||||
if(X.is_afk())
|
||||
admin_number_afk++
|
||||
X << msg
|
||||
if(X.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
//show it to the person adminhelping too
|
||||
src << "<font color='blue'>PM to-<b>Staff </b>: [original_msg]</font>"
|
||||
|
||||
var/admin_number_present = admins.len - admin_number_afk
|
||||
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
|
||||
if(admin_number_present <= 0)
|
||||
send2adminirc("Request for Help from [key_name(src)]: [html_decode(original_msg)] - !![admin_number_afk ? "All admins AFK ([admin_number_afk])" : "No admins online"]!!")
|
||||
else
|
||||
send2adminirc("Request for Help from [key_name(src)]: [html_decode(original_msg)]")
|
||||
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
// VoreStation Edit Start
|
||||
if (config.chat_webhook_url)
|
||||
spawn(0)
|
||||
var/query_string = "type=adminhelp"
|
||||
query_string += "&key=[url_encode(config.chat_webhook_key)]"
|
||||
query_string += "&from=[url_encode(key_name(src))]"
|
||||
query_string += "&msg=[url_encode(html_decode(original_msg))]"
|
||||
query_string += "&admin_number=[admins.len]"
|
||||
query_string += "&admin_number_afk=[admin_number_afk]"
|
||||
world.Export("[config.chat_webhook_url]?[query_string]")
|
||||
// VoreStation Edit End
|
||||
//YW EDIT START
|
||||
SERVER_TOOLS_RELAY_BROADCAST("ADMINHELP: FROM: [key_name(src)] - MSG: **[strip_html_properly(original_msg)]** - Heard by [admins.len-admin_number_afk] NON-AFK staff members.")
|
||||
//YW EDIT END
|
||||
return
|
||||
msg += "[original_word] "
|
||||
if(irc)
|
||||
if(founds == "")
|
||||
return "Search Failed"
|
||||
else
|
||||
return founds
|
||||
|
||||
return msg
|
||||
@@ -0,0 +1,16 @@
|
||||
/datum/admin_help/proc/send2adminchat()
|
||||
if(!config.chat_webhook_url)
|
||||
return
|
||||
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/afkmins = adm["afk"]
|
||||
var/list/allmins = adm["total"]
|
||||
|
||||
spawn(0) //Unreliable world.Exports()
|
||||
var/query_string = "type=adminhelp"
|
||||
query_string += "&key=[url_encode(config.chat_webhook_key)]"
|
||||
query_string += "&from=[url_encode(key_name(initiator))]"
|
||||
query_string += "&msg=[url_encode(html_decode(name))]"
|
||||
query_string += "&admin_number=[allmins.len]"
|
||||
query_string += "&admin_number_afk=[afkmins.len]"
|
||||
world.Export("[config.chat_webhook_url]?[query_string]")
|
||||
@@ -109,8 +109,10 @@
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG))
|
||||
return
|
||||
if(config.allow_admin_jump)
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]", 1)
|
||||
log_admin("[key_name(usr)] jumped to [key_name(M)]")
|
||||
var/msg = "[key_name_admin(usr)] jumped to [key_name_admin(M)]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
feedback_add_details("admin_verb","GM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -137,7 +139,9 @@
|
||||
if(!M)
|
||||
return
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name(M)]", 1)
|
||||
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
if(M)
|
||||
M.on_mob_jump()
|
||||
M.loc = get_turf(usr)
|
||||
@@ -157,7 +161,9 @@
|
||||
M.loc = pick(get_area_turfs(A))
|
||||
feedback_add_details("admin_verb","SMOB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]", 1)
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
else
|
||||
alert("Admin jumping disabled")
|
||||
alert("Admin jumping disabled")
|
||||
@@ -1,148 +1,286 @@
|
||||
#define IRCREPLYCOUNT 2
|
||||
|
||||
|
||||
//allows right clicking mobs to send an admin PM to their client, forwards the selected mob's client to cmd_admin_pm
|
||||
/client/proc/cmd_admin_pm_context(mob/M as mob in mob_list)
|
||||
/client/proc/cmd_admin_pm_context(mob/M in mob_list)
|
||||
set category = null
|
||||
set name = "Admin PM Mob"
|
||||
if(!holder)
|
||||
src << "<font color='red'>Error: Admin-PM-Context: Only administrators may use this command.</font>"
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM-Context: Only administrators may use this command.</font>")
|
||||
return
|
||||
if( !ismob(M) || !M.client )
|
||||
return
|
||||
if( !ismob(M) || !M.client ) return
|
||||
cmd_admin_pm(M.client,null)
|
||||
feedback_add_details("admin_verb","APMM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
feedback_add_details("admin_verb","Admin PM Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
//shows a list of clients we could send PMs to, then forwards our choice to cmd_admin_pm
|
||||
/client/proc/cmd_admin_pm_panel()
|
||||
set category = "Admin"
|
||||
set name = "Admin PM"
|
||||
if(!holder)
|
||||
src << "<font color='red'>Error: Admin-PM-Panel: Only administrators may use this command.</font>"
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM-Panel: Only administrators may use this command.</font>")
|
||||
return
|
||||
var/list/client/targets[0]
|
||||
for(var/client/T)
|
||||
if(T.mob)
|
||||
if(istype(T.mob, /mob/new_player))
|
||||
if(isnewplayer(T.mob))
|
||||
targets["(New Player) - [T]"] = T
|
||||
else if(istype(T.mob, /mob/observer/dead))
|
||||
else if(isobserver(T.mob))
|
||||
targets["[T.mob.name](Ghost) - [T]"] = T
|
||||
else
|
||||
targets["[T.mob.real_name](as [T.mob.name]) - [T]"] = T
|
||||
else
|
||||
targets["(No Mob) - [T]"] = T
|
||||
var/list/sorted = sortList(targets)
|
||||
var/target = input(src,"To whom shall we send a message?","Admin PM",null) in sorted|null
|
||||
var/target = input(src,"To whom shall we send a message?","Admin PM",null) as null|anything in sortList(targets)
|
||||
cmd_admin_pm(targets[target],null)
|
||||
feedback_add_details("admin_verb","APM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
feedback_add_details("admin_verb","Admin PM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_ahelp_reply(whom)
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>")
|
||||
return
|
||||
var/client/C
|
||||
if(istext(whom))
|
||||
if(cmptext(copytext(whom,1,2),"@"))
|
||||
whom = findStealthKey(whom)
|
||||
C = GLOB.directory[whom]
|
||||
else if(istype(whom,/client))
|
||||
C = whom
|
||||
if(!C)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
return
|
||||
|
||||
var/datum/admin_help/AH = C.current_ticket
|
||||
|
||||
if(AH)
|
||||
message_admins("[key_name_admin(src)] has started replying to [key_name(C, 0, 0)]'s admin help.")
|
||||
var/msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
|
||||
if (!msg)
|
||||
message_admins("[key_name_admin(src)] has cancelled their reply to [key_name(C, 0, 0)]'s admin help.")
|
||||
return
|
||||
cmd_admin_pm(whom, msg, AH)
|
||||
|
||||
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
|
||||
//Fetching a message if needed. src is the sender and C is the target client
|
||||
|
||||
/client/proc/cmd_admin_pm(var/client/C, var/msg = null)
|
||||
/client/proc/cmd_admin_pm(whom, msg, datum/admin_help/AH)
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
src << "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>"
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>")
|
||||
return
|
||||
|
||||
if(!istype(C,/client))
|
||||
if(holder) src << "<font color='red'>Error: Private-Message: Client not found.</font>"
|
||||
else src << "<font color='red'>Error: Private-Message: Client not found. They may have lost connection, so try using an adminhelp!</font>"
|
||||
if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo
|
||||
to_chat(src, "<font color='red'>You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.</font>")
|
||||
to_chat(src, "<font color='blue'>Message: [msg]</font>")
|
||||
return
|
||||
|
||||
//get message text, limit it's length.and clean/escape html
|
||||
if(!msg)
|
||||
msg = input(src,"Message:", "Private message to [key_name(C, 0, holder ? 1 : 0)]") as text|null
|
||||
var/client/recipient
|
||||
var/irc = 0
|
||||
if(istext(whom))
|
||||
if(cmptext(copytext(whom,1,2),"@"))
|
||||
whom = findStealthKey(whom)
|
||||
if(whom == "IRCKEY")
|
||||
irc = 1
|
||||
else
|
||||
recipient = GLOB.directory[whom]
|
||||
else if(istype(whom,/client))
|
||||
recipient = whom
|
||||
|
||||
if(!msg) return
|
||||
if(!C)
|
||||
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
|
||||
else src << "<font color='red'>Error: Private-Message: Client not found. They may have lost connection, so try using an adminhelp!</font>"
|
||||
|
||||
if(irc)
|
||||
if(!ircreplyamount) //to prevent people from spamming irc
|
||||
return
|
||||
if(!msg)
|
||||
msg = input(src,"Message:", "Private message to Administrator") as text|null
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Use the admin IRC channel, nerd.</font>")
|
||||
return
|
||||
|
||||
|
||||
else
|
||||
if(!recipient)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
to_chat(src, msg)
|
||||
else
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
//get message text, limit it's length.and clean/escape html
|
||||
if(!msg)
|
||||
msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as text|null
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>")
|
||||
return
|
||||
|
||||
if(!recipient)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
else
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
//clean the message if it's not sent by a high-rank admin
|
||||
//todo: sanitize for all???
|
||||
if(!check_rights(R_SERVER|R_DEBUG,0))
|
||||
msg = sanitize(msg)
|
||||
if(!msg) return
|
||||
if(!check_rights(R_SERVER|R_DEBUG,0)||irc)//no sending html to the poor bots
|
||||
msg = trim(sanitize(copytext(msg,1,MAX_MESSAGE_LEN)))
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
var/recieve_pm_type = "Player"
|
||||
if(holder)
|
||||
//mod PMs are maroon
|
||||
//PMs sent from admins and mods display their rank
|
||||
if(holder)
|
||||
if(!C.holder && holder && holder.fakekey)
|
||||
recieve_pm_type = "Admin"
|
||||
else
|
||||
recieve_pm_type = holder.rank
|
||||
var/rawmsg = msg
|
||||
|
||||
else if(!C.holder)
|
||||
src << "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>"
|
||||
return
|
||||
var/keywordparsedmsg = keywords_lookup(msg)
|
||||
|
||||
var/recieve_message
|
||||
if(irc)
|
||||
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [rawmsg]</font>")
|
||||
admin_ticket_log(src, "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, TRUE)]</b> to <i>IRC</i>: [keywordparsedmsg]</font>")
|
||||
ircreplyamount--
|
||||
send2irc("Reply: [ckey]",rawmsg)
|
||||
else
|
||||
if(recipient.holder)
|
||||
if(holder) //both are admins
|
||||
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
|
||||
if(holder && !C.holder)
|
||||
recieve_message = "<span class='pm'><span class='howto'><b>-- Click the [recieve_pm_type]'s name to reply --</b></span></span>\n"
|
||||
if(C.adminhelped)
|
||||
C << recieve_message
|
||||
C.adminhelped = 0
|
||||
//omg this is dumb, just fill in both their tickets
|
||||
var/interaction_message = "<font color='purple'>PM from-<b>[key_name(src, recipient, 1)]</b> to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>"
|
||||
admin_ticket_log(src, interaction_message)
|
||||
if(recipient != src) //reeee
|
||||
admin_ticket_log(recipient, interaction_message)
|
||||
|
||||
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
|
||||
if(config.popup_admin_pm)
|
||||
spawn(0) //so we don't hold the caller proc up
|
||||
var/sender = src
|
||||
var/sendername = key
|
||||
var/reply = sanitize(input(C, msg,"[recieve_pm_type] PM from [sendername]", "") as text|null) //show message and await a reply
|
||||
if(C && reply)
|
||||
if(sender)
|
||||
C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
|
||||
else
|
||||
adminhelp(reply) //sender has left, adminhelp instead
|
||||
else //recipient is an admin but sender is not
|
||||
var/replymsg = "<font color='red'>Reply PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>"
|
||||
admin_ticket_log(src, replymsg)
|
||||
to_chat(recipient, replymsg)
|
||||
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [msg]</font>")
|
||||
|
||||
//play the recieving admin the adminhelp sound (if they have them enabled)
|
||||
if(recipient.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||
recipient << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
else
|
||||
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
|
||||
if(!recipient.current_ticket)
|
||||
new /datum/admin_help(msg, recipient, TRUE)
|
||||
|
||||
to_chat(recipient, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
|
||||
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 0)]</b>: [msg]</font>")
|
||||
to_chat(recipient, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [msg]</font>")
|
||||
|
||||
admin_ticket_log(recipient, "<font color='blue'>PM From [key_name_admin(src)]: [keywordparsedmsg]</font>")
|
||||
|
||||
//always play non-admin recipients the adminhelp sound
|
||||
recipient << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
|
||||
if(config.popup_admin_pm)
|
||||
spawn() //so we don't hold the caller proc up
|
||||
var/sender = src
|
||||
var/sendername = key
|
||||
var/reply = input(recipient, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
|
||||
if(recipient && reply)
|
||||
if(sender)
|
||||
recipient.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
|
||||
else
|
||||
adminhelp(reply) //sender has left, adminhelp instead
|
||||
return
|
||||
|
||||
else //neither are admins
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>")
|
||||
return
|
||||
src << "<span class='pm'><span class='out'>" + create_text_tag("pm_out_alt", "PM", src) + " to <span class='name'>[get_options_bar(C, holder ? 1 : 0, holder ? 1 : 0, 1)]</span>: <span class='message'>[msg]</span></span></span>"
|
||||
C << "<span class='pm'><span class='in'>" + create_text_tag("pm_in", "", C) + " <b>\[[recieve_pm_type] PM\]</b> <span class='name'>[get_options_bar(src, C.holder ? 1 : 0, C.holder ? 1 : 0, 1)]</span>: <span class='message'>[msg]</span></span></span>"
|
||||
|
||||
//play the recieving admin the adminhelp sound (if they have them enabled)
|
||||
//non-admins shouldn't be able to disable this
|
||||
if(C.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
if(irc)
|
||||
log_admin("PM: [key_name(src)]->IRC: [rawmsg]")
|
||||
for(var/client/X in admins)
|
||||
to_chat(X, "<font color='blue'><B>PM: [key_name(src, X, 0)]->IRC:</B> [keywordparsedmsg]</font>")
|
||||
else
|
||||
log_admin("PM: [key_name(src)]->[key_name(recipient)]: [rawmsg]")
|
||||
//we don't use message_admins here because the sender/receiver might get it too
|
||||
for(var/client/X in admins)
|
||||
if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipient
|
||||
to_chat(X, "<font color='blue'><B>PM: [key_name(src, X, 0)]->[key_name(recipient, X, 0)]:</B> [keywordparsedmsg]</font>" )
|
||||
|
||||
log_adminpm(msg,src,C)
|
||||
send2adminirc("Reply: [key_name(src)]->[key_name(C)]: [html_decode(msg)]")
|
||||
/proc/IrcPm(target,msg,sender)
|
||||
var/client/C = GLOB.directory[target]
|
||||
|
||||
//we don't use message_admins here because the sender/receiver might get it too
|
||||
for(var/client/X in admins)
|
||||
//check client/X is an admin and isn't the sender or recipient
|
||||
if(X == C || X == src)
|
||||
continue
|
||||
if(X.key != key && X.key != C.key && (X.holder.rights & R_ADMIN|R_MOD|R_EVENT))
|
||||
X << "<span class='pm'><span class='other'>" + create_text_tag("pm_other", "PM:", X) + " <span class='name'>[key_name(src, X, 0)]</span> to <span class='name'>[key_name(C, X, 0)]</span>: <span class='message'>[msg]</span></span></span>"
|
||||
var/datum/admin_help/ticket = C ? C.current_ticket : GLOB.ahelp_tickets.CKey2ActiveTicket(target)
|
||||
var/compliant_msg = trim(lowertext(msg))
|
||||
var/irc_tagged = "[sender](IRC)"
|
||||
var/list/splits = splittext(compliant_msg, " ")
|
||||
if(splits.len && splits[1] == "ticket")
|
||||
if(splits.len < 2)
|
||||
return "Usage: ticket <close|resolve|icissue|reject>"
|
||||
switch(splits[2])
|
||||
if("close")
|
||||
if(ticket)
|
||||
ticket.Close(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully closed"
|
||||
if("resolve")
|
||||
if(ticket)
|
||||
ticket.Resolve(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully resolved"
|
||||
if("icissue")
|
||||
if(ticket)
|
||||
ticket.ICIssue(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully marked as IC issue"
|
||||
if("reject")
|
||||
if(ticket)
|
||||
ticket.Reject(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully rejected"
|
||||
else
|
||||
return "Usage: ticket <close|resolve|icissue|reject>"
|
||||
return "Error: Ticket could not be found"
|
||||
|
||||
/client/proc/cmd_admin_irc_pm(sender)
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
src << "<font color='red'>Error: Private-Message: You are unable to use PM-s (muted).</font>"
|
||||
return
|
||||
var/static/stealthkey
|
||||
var/adminname = "Administrator"
|
||||
|
||||
var/msg = input(src,"Message:", "Reply private message to [sender] on IRC / 400 character limit") as text|null
|
||||
if(!C)
|
||||
return "Error: No client"
|
||||
|
||||
if(!stealthkey)
|
||||
stealthkey = GenIrcStealthKey()
|
||||
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg)
|
||||
return
|
||||
return "Error: No message"
|
||||
|
||||
sanitize(msg)
|
||||
message_admins("IRC message from [sender] to [key_name_admin(C)] : [msg]")
|
||||
log_admin("IRC PM: [sender] -> [key_name(C)] : [msg]")
|
||||
|
||||
// Handled on Bot32's end, unsure about other bots
|
||||
// if(length(msg) > 400) // TODO: if message length is over 400, divide it up into seperate messages, the message length restriction is based on IRC limitations. Probably easier to do this on the bots ends.
|
||||
// src << "<span class='warning'>Your message was not sent because it was more then 400 characters find your message below for ease of copy/pasting</span>"
|
||||
// src << "<span class='notice'>[msg]</span>"
|
||||
// return
|
||||
to_chat(C, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
|
||||
to_chat(C, "<font color='red'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</font>")
|
||||
to_chat(C, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
|
||||
|
||||
send2adminirc("PlayerPM to [sender] from [key_name(src)]: [html_decode(msg)]")
|
||||
admin_ticket_log(C, "<font color='blue'>PM From [irc_tagged]: [msg]</font>")
|
||||
|
||||
src << "<span class='pm'><span class='out'>" + create_text_tag("pm_out_alt", "", src) + " to <span class='name'>IRC-[sender]</span>: <span class='message'>[msg]</span></span></span>"
|
||||
window_flash(C, ignorepref = TRUE)
|
||||
//always play non-admin recipients the adminhelp sound
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
log_admin("PM: [key_name(src)]->IRC-[sender]: [msg]")
|
||||
for(var/client/X in admins)
|
||||
if(X == src)
|
||||
continue
|
||||
if(X.holder.rights & R_ADMIN|R_MOD)
|
||||
X << "<span class='pm'><span class='other'>" + create_text_tag("pm_other", "PM:", X) + " <span class='name'>[key_name(src, X, 0)]</span> to <span class='name'>IRC-[sender]</span>: <span class='message'>[msg]</span></span></span>"
|
||||
C.ircreplyamount = IRCREPLYCOUNT
|
||||
|
||||
return "Message Successful"
|
||||
|
||||
/proc/GenIrcStealthKey()
|
||||
var/num = (rand(0,1000))
|
||||
var/i = 0
|
||||
while(i == 0)
|
||||
i = 1
|
||||
for(var/P in GLOB.stealthminID)
|
||||
if(num == GLOB.stealthminID[P])
|
||||
num++
|
||||
i = 0
|
||||
var/stealth = "@[num2text(num)]"
|
||||
GLOB.stealthminID["IRCKEY"] = stealth
|
||||
return stealth
|
||||
|
||||
#undef IRCREPLYCOUNT
|
||||
@@ -96,7 +96,9 @@
|
||||
M << "<B>You hear a voice in your head...</B> <i>[msg]</i>"
|
||||
|
||||
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
|
||||
message_admins("<font color='blue'><B>SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]</B></font>", 1)
|
||||
msg = "<span class='adminnotice'><b> SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] :</b> [msg]</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE
|
||||
@@ -135,9 +137,11 @@
|
||||
if( !msg )
|
||||
return
|
||||
|
||||
M << msg
|
||||
to_chat(M, msg)
|
||||
log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
|
||||
message_admins("<font color='blue'><B> DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]<BR></B></font>", 1)
|
||||
msg = "<span class='adminnotice'><b> DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]):</b> [msg]<BR></span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","DIRN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_godmode(mob/M as mob in mob_list)
|
||||
@@ -150,7 +154,9 @@
|
||||
usr << "<font color='blue'> Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]</font>"
|
||||
|
||||
log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
|
||||
message_admins("[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]", 1)
|
||||
var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","GOD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -550,7 +556,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
M.revive()
|
||||
|
||||
log_admin("[key_name(usr)] healed / revived [key_name(M)]")
|
||||
message_admins("<font color='red'>Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!</font>", 1)
|
||||
var/msg = "<span class='danger'>Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(M)]!</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
else
|
||||
alert("Admin revive disabled")
|
||||
feedback_add_details("admin_verb","REJU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
wait = world.time + config.gateway_delay //+ thirty minutes default
|
||||
awaygate = locate(/obj/machinery/gateway/centeraway)
|
||||
. = ..()
|
||||
density = 1 //VOREStation Add
|
||||
|
||||
/obj/machinery/gateway/centerstation/update_icon()
|
||||
if(active)
|
||||
icon_state = "oncenter"
|
||||
return
|
||||
icon_state = "offcenter"
|
||||
|
||||
/* VOREStation Removal - Doesn't do anything
|
||||
/obj/machinery/gateway/centerstation/New()
|
||||
density = 1
|
||||
|
||||
|
||||
*/ //VOREStation Removal End
|
||||
|
||||
obj/machinery/gateway/centerstation/process()
|
||||
if(stat & (NOPOWER))
|
||||
@@ -90,7 +90,7 @@ obj/machinery/gateway/centerstation/process()
|
||||
if(world.time < wait)
|
||||
user << "<span class='notice'>Error: Warpspace triangulation in progress. Estimated time to completion: [round(((wait - world.time) / 10) / 60)] minutes.</span>"
|
||||
return
|
||||
if(!awaygate.calibrated && LAZYLEN(awaydestinations))
|
||||
if(!awaygate.calibrated && !LAZYLEN(awaydestinations)) //VOREStation Edit
|
||||
user << "<span class='notice'>Error: Destination gate uncalibrated. Gateway unsafe to use without far-end calibration update.</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
|
||||
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
|
||||
var/ircreplyamount = 0
|
||||
|
||||
/////////
|
||||
//OTHER//
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
if(mute_irc)
|
||||
usr << "<span class='warning'You cannot use this as your client has been muted from sending messages to the admins on IRC</span>"
|
||||
return
|
||||
cmd_admin_irc_pm(href_list["irc_msg"])
|
||||
send2adminirc(href_list["irc_msg"])
|
||||
return
|
||||
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
clients += src
|
||||
directory[ckey] = src
|
||||
|
||||
GLOB.ahelp_tickets.ClientLogin(src)
|
||||
|
||||
//Admin Authorisation
|
||||
holder = admin_datums[ckey]
|
||||
if(holder)
|
||||
@@ -179,6 +181,7 @@
|
||||
if(holder)
|
||||
holder.owner = null
|
||||
admins -= src
|
||||
GLOB.ahelp_tickets.ClientLogout(src)
|
||||
directory -= ckey
|
||||
clients -= src
|
||||
return ..()
|
||||
|
||||
@@ -353,25 +353,17 @@
|
||||
sols[initial(sol.name)] = sol
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(sols))*/ // Vorestation removal.
|
||||
|
||||
/datum/gear/head/surgical/black
|
||||
display_name = "surgical cap, black"
|
||||
path = /obj/item/clothing/head/surgery/black
|
||||
/datum/gear/head/surgical
|
||||
display_name = "surgical cap selection"
|
||||
path = /obj/item/clothing/head/surgery
|
||||
|
||||
/datum/gear/head/surgical/blue
|
||||
display_name = "surgical cap, blue"
|
||||
path = /obj/item/clothing/head/surgery/blue
|
||||
|
||||
/datum/gear/head/surgical/green
|
||||
display_name = "surgical cap, green"
|
||||
path = /obj/item/clothing/head/surgery/green
|
||||
|
||||
/datum/gear/head/surgical/navyblue
|
||||
display_name = "surgical cap, navy blue"
|
||||
path = /obj/item/clothing/head/surgery/navyblue
|
||||
|
||||
/datum/gear/head/surgical/purple
|
||||
display_name = "surgical cap, purple"
|
||||
path = /obj/item/clothing/head/surgery/purple
|
||||
/datum/gear/head/surgical/New()
|
||||
..()
|
||||
var/list/caps = list()
|
||||
for(var/surgery in typesof(/obj/item/clothing/head/surgery))
|
||||
var/obj/item/clothing/head/surgery/cap_type = caps
|
||||
caps[initial(cap_type.name)] = cap_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(caps))
|
||||
|
||||
/datum/gear/head/circuitry
|
||||
display_name = "headwear, circuitry (empty)"
|
||||
|
||||
@@ -4,6 +4,7 @@ var/AKULA_EGG = "Akula"
|
||||
var/SKRELL_EGG = "Skrell"
|
||||
var/SERGAL_EGG = "Sergal"
|
||||
var/HUMAN_EGG = "Human"
|
||||
var/NEVREAN_EGG = "nevrean"
|
||||
var/SLIME_EGG = "Slime"
|
||||
var/EGG_EGG = "Egg"
|
||||
var/XENOCHIMERA_EGG = "Xenochimera"
|
||||
|
||||
@@ -87,6 +87,10 @@
|
||||
var/S = pref.custom_base ? pref.custom_base : "Human"
|
||||
var/datum/species/custom/new_CS = CS.produceCopy(S, pref.pos_traits + pref.neu_traits + pref.neg_traits, character)
|
||||
|
||||
//Statistics for this would be nice
|
||||
var/english_traits = english_list(new_CS.traits, and_text = ";", comma_text = ";")
|
||||
log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet
|
||||
|
||||
//Any additional non-trait settings can be applied here
|
||||
new_CS.blood_color = pref.blood_color
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
qdel(H)
|
||||
spawn(50)
|
||||
new /obj/item/honey_frame(loc)
|
||||
new /obj/item/stack/wax(loc)
|
||||
new /obj/item/stack/material/wax(loc)
|
||||
honey += processing
|
||||
processing = 0
|
||||
icon_state = "centrifuge"
|
||||
@@ -234,14 +234,14 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/stack/wax
|
||||
/obj/item/stack/material/wax
|
||||
name = "wax"
|
||||
singular_name = "wax piece"
|
||||
desc = "Soft substance produced by bees. Used to make candles."
|
||||
icon = 'icons/obj/beekeeping.dmi'
|
||||
icon_state = "wax"
|
||||
|
||||
/obj/item/stack/wax/New()
|
||||
/obj/item/stack/material/wax/New()
|
||||
..()
|
||||
recipes = wax_recipes
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ var/global/use_preloader = FALSE
|
||||
++turfsSkipped
|
||||
#endif
|
||||
CHECK_TICK
|
||||
maxx = max(maxx, ++xcrd)
|
||||
maxx = max(maxx, xcrd++)
|
||||
key_list[++key_list.len] = line_keys
|
||||
|
||||
// Rotate the list according to orientation
|
||||
|
||||
@@ -30,11 +30,6 @@
|
||||
|
||||
var/excavation_amount = 200
|
||||
|
||||
/obj/item/weapon/pickaxe/hammer
|
||||
name = "sledgehammer"
|
||||
//icon_state = "sledgehammer" Waiting on sprite
|
||||
desc = "A mining hammer made of reinforced metal. You feel like smashing your boss in the face with this."
|
||||
|
||||
/obj/item/weapon/pickaxe/silver
|
||||
name = "silver pickaxe"
|
||||
icon_state = "spickaxe"
|
||||
|
||||
@@ -729,7 +729,7 @@
|
||||
src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
|
||||
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \
|
||||
raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch, \
|
||||
twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping"
|
||||
twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yess, no, rcough, rsneeze, ping"
|
||||
|
||||
else
|
||||
src << "<font color='blue'>Unusable emote '[act]'. Say *help for a list.</font>"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
/mob/living/proc/flying_toggle,
|
||||
/mob/living/proc/start_wings_hovering) //Xenochimera get all the special verbs since they can't select traits.
|
||||
|
||||
virus_immune = 1 // They practically ARE one.
|
||||
min_age = 18
|
||||
max_age = 80
|
||||
|
||||
@@ -51,6 +52,16 @@
|
||||
flags = NO_SCAN | NO_INFECT //Dying as a chimera is, quite literally, a death sentence. Well, if it wasn't for their revive, that is.
|
||||
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
|
||||
|
||||
has_organ = list( //Same organ list as tajarans.
|
||||
O_HEART = /obj/item/organ/internal/heart,
|
||||
O_LUNGS = /obj/item/organ/internal/lungs,
|
||||
O_VOICE = /obj/item/organ/internal/voicebox,
|
||||
O_LIVER = /obj/item/organ/internal/liver,
|
||||
O_KIDNEYS = /obj/item/organ/internal/kidneys,
|
||||
O_BRAIN = /obj/item/organ/internal/brain,
|
||||
O_EYES = /obj/item/organ/internal/eyes
|
||||
)
|
||||
|
||||
flesh_color = "#AFA59E"
|
||||
base_color = "#333333"
|
||||
blood_color = "#14AD8B"
|
||||
|
||||
@@ -122,8 +122,8 @@
|
||||
|
||||
/datum/trait/winged_flight
|
||||
name = "Winged Flight"
|
||||
desc = "Allows you to fly by using your wings."
|
||||
cost = 2 //Some in game value.
|
||||
desc = "Allows you to fly by using your wings. Don't forget to bring them!"
|
||||
cost = 1
|
||||
|
||||
/datum/trait/winged_flight/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
||||
..(S,H)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
//kobold
|
||||
/mob/living/simple_animal/kobold
|
||||
name = "kobold"
|
||||
desc = "A small, rat-like creature."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "kobold_idle"
|
||||
icon_living = "kobold_idle"
|
||||
icon_dead = "kobold_dead"
|
||||
intelligence_level = SA_HUMANOID
|
||||
|
||||
run_at_them = 0
|
||||
cooperative = 1
|
||||
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
min_oxy = 16 //Require atleast 16kPA oxygen
|
||||
minbodytemp = 223 //Below -50 Degrees Celcius
|
||||
maxbodytemp = 323 //Above 50 Degrees Celcius
|
||||
|
||||
speak_chance = 5
|
||||
speak = list("You no take candle!","Ooh, pretty shiny.","Me take?","Where gold here...","Me likey.")
|
||||
speak_emote = list("mutters","hisses","grumbles")
|
||||
emote_hear = list("mutters under it's breath.","grumbles.", "yips!")
|
||||
emote_see = list("looks around suspiciously.", "scratches it's arm.","putters around a bit.")
|
||||
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey
|
||||
|
||||
/mob/living/simple_animal/kobold/Life()
|
||||
. = ..()
|
||||
if(!.) return
|
||||
|
||||
if(prob(5))
|
||||
flick("kobold_act",src)
|
||||
|
||||
/mob/living/simple_animal/kobold/Move(var/dir)
|
||||
..()
|
||||
if(!stat)
|
||||
flick("kobold_walk",src)
|
||||
@@ -393,7 +393,7 @@
|
||||
//Resisting out of closets
|
||||
if(istype(loc,/obj/structure/closet))
|
||||
var/obj/structure/closet/C = loc
|
||||
if(C.welded)
|
||||
if(C.sealed)
|
||||
handle_resist()
|
||||
else
|
||||
C.open()
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
var/vore_bump_chance = 0 // Chance of trying to eat anyone that bumps into them, regardless of hostility
|
||||
var/vore_bump_emote = "grabs hold of" // Allow messages for bumpnom mobs to have a flavorful bumpnom
|
||||
var/vore_pounce_chance = 5 // Chance of this mob knocking down an opponent
|
||||
var/vore_pounce_cooldown = 0 // Cooldown timer - if it fails a pounce it won't pounce again for a while
|
||||
var/vore_pounce_successrate = 100 // Chance of a pounce succeeding against a theoretical 0-health opponent
|
||||
var/vore_pounce_falloff = 1 // Success rate falloff per %health of target mob.
|
||||
var/vore_pounce_maxhealth = 80 // Mob will not attempt to pounce targets above this %health
|
||||
var/vore_standing_too = 0 // Can also eat non-stunned mobs
|
||||
var/vore_ignores_undigestable = 1 // Refuse to eat mobs who are undigestable by the prefs toggle.
|
||||
var/swallowsound = null // What noise plays when you succeed in eating the mob.
|
||||
@@ -92,21 +96,49 @@
|
||||
/mob/living/simple_animal/PunchTarget()
|
||||
ai_log("vr/PunchTarget() [target_mob]", 3)
|
||||
|
||||
// For things we don't want to eat, call the sideways "parent" to do normal punching
|
||||
if(!vore_active || !will_eat(target_mob))
|
||||
// If we're not hungry, call the sideways "parent" to do normal punching
|
||||
if(!vore_active)
|
||||
return ..()
|
||||
|
||||
// If target is standing we might pounce and eat them
|
||||
if(target_mob.canmove && prob(vore_pounce_chance))
|
||||
target_mob.Weaken(5)
|
||||
target_mob.visible_message("<span class='danger'>\the [src] pounces on \the [target_mob]!</span>!")
|
||||
// If target is standing we might pounce and knock them down instead of attacking
|
||||
var/pouncechance = CanPounceTarget()
|
||||
if(pouncechance)
|
||||
return PounceTarget(pouncechance)
|
||||
|
||||
// If they're down or we can eat standing, do it
|
||||
if(!target_mob.canmove || vore_standing_too)
|
||||
// We're not attempting a pounce, if they're down or we can eat standing, do it as long as they're edible. Otherwise, hit normally.
|
||||
if(will_eat(target_mob) && (!target_mob.canmove || vore_standing_too))
|
||||
return EatTarget()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/proc/CanPounceTarget() //returns either FALSE or a %chance of success
|
||||
if(!target_mob.canmove || issilicon(target_mob) || world.time < vore_pounce_cooldown) //eliminate situations where pouncing CANNOT happen
|
||||
return FALSE
|
||||
if(!prob(vore_pounce_chance)) //mob doesn't want to pounce
|
||||
return FALSE
|
||||
if(will_eat(target_mob) && vore_standing_too) //100% chance of hitting people we can eat on the spot
|
||||
return 100
|
||||
var/TargetHealthPercent = (target_mob.health/target_mob.getMaxHealth())*100 //now we start looking at the target itself
|
||||
if (TargetHealthPercent > vore_pounce_maxhealth) //target is too healthy to pounce
|
||||
return FALSE
|
||||
else
|
||||
return max(0,(vore_pounce_successrate - (vore_pounce_falloff * TargetHealthPercent)))
|
||||
|
||||
|
||||
/mob/living/simple_animal/proc/PounceTarget(var/successrate = 100)
|
||||
vore_pounce_cooldown = world.time + 20 SECONDS // don't attempt another pounce for a while
|
||||
if(prob(successrate)) // pounce success!
|
||||
target_mob.Weaken(5)
|
||||
target_mob.visible_message("<span class='danger'>\the [src] pounces on \the [target_mob]!</span>!")
|
||||
else // pounce misses!
|
||||
target_mob.visible_message("<span class='danger'>\the [src] attempts to pounce \the [target_mob] but misses!</span>!")
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
|
||||
if(will_eat(target_mob) && (!target_mob.canmove || vore_standing_too)) //if they're edible then eat them too
|
||||
return EatTarget()
|
||||
else
|
||||
return //just leave them
|
||||
|
||||
// Attempt to eat target
|
||||
// TODO - Review this. Could be some issues here
|
||||
/mob/living/simple_animal/proc/EatTarget()
|
||||
@@ -117,7 +149,7 @@
|
||||
. = animal_nom(target_mob)
|
||||
playsound(src, swallowsound, 50, 1)
|
||||
update_icon()
|
||||
|
||||
|
||||
if(.)
|
||||
// If we succesfully ate them, lose the target
|
||||
LoseTarget()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
var/random_skin = 1
|
||||
var/list/skins = list(
|
||||
"catgirl",
|
||||
"catgirlnude",
|
||||
"catgirlbikini",
|
||||
"catgirlrednude",
|
||||
|
||||
@@ -241,7 +241,7 @@
|
||||
if(specific_targets && isliving(A)) //Healing!
|
||||
var/mob/living/L = A
|
||||
var/health_percent = (L.health/L.maxHealth)*100
|
||||
if(health_percent <= 50)
|
||||
if(health_percent <= 50 && will_eat(A))
|
||||
return A
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
eye_desc = "red eyes"
|
||||
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||
slippery gullet of the creature. It's warm, and the air is thick. You can hear \
|
||||
its body squelch and shift around you as you settle into its stomach! Thick digestive \
|
||||
enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \
|
||||
@@ -64,11 +64,11 @@
|
||||
eye_desc = "blue eyes"
|
||||
shy_approach = TRUE
|
||||
stalker = TRUE
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||
slippery gullet of the creature. It's warm, and the air is thick. You can hear its body \
|
||||
squelch and shift around you as you settle into its stomach! It's oddly calm, and very dark. \
|
||||
The doughy flesh rolls across your form in gentle waves. The aches and pains across your form slowly begin to \
|
||||
diminish, your body is healing much faster than normal! You’re also soon soaked in harmless slime."
|
||||
diminish, your body is healing much faster than normal! You're also soon soaked in harmless slime."
|
||||
|
||||
player_msg = "You've chosen to generate your own energy rather than taking \
|
||||
it from others. Most of the time, anyway. You don't have a need to steal energy from others, and gather it up \
|
||||
@@ -106,10 +106,10 @@
|
||||
eye_desc = "purple eyes"
|
||||
shy_approach = TRUE
|
||||
stalker = TRUE
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, slippery gullet of the creature. \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet of the creature. \
|
||||
It's warm, and the air is thick. You can hear its body squelch and shift around you as you settle into its stomach! \
|
||||
It’s relatively calm inside the dark organ. Wet and almost molten for how gooey your surroundings feel. \
|
||||
You can feel the doughy walls cling to you posessively... It’s almost like you could sink into them. \
|
||||
It's relatively calm inside the dark organ. Wet and almost molten for how gooey your surroundings feel. \
|
||||
You can feel the doughy walls cling to you posessively... It's almost like you could sink into them. \
|
||||
There is also an ominous gurgling from somewhere nearby..."
|
||||
|
||||
player_msg = "You're familiar with generating your own energy, but occasionally \
|
||||
@@ -147,10 +147,10 @@
|
||||
|
||||
eye_desc = "yellow eyes"
|
||||
stalker = FALSE
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, slippery gullet \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \
|
||||
of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \
|
||||
as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \
|
||||
you out!! There doesn’t appear to be any actual danger here, harmless slime clings to you, but it’s getting \
|
||||
you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \
|
||||
harder and harder to move as those walls press in on you insistently!"
|
||||
|
||||
player_msg = "Your kind rarely ventures into realspace. Being in any well-lit \
|
||||
@@ -187,10 +187,10 @@
|
||||
|
||||
eye_desc = "green eyes"
|
||||
stalker = TRUE
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, slippery gullet \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, slippery gullet \
|
||||
of the creature. It's warm, and the air is thick. You can hear its body squelch and shift around you \
|
||||
as you settle into its stomach! The doughy walls within cling to you heavily, churning down on you, wearing \
|
||||
you out!! There doesn’t appear to be any actual danger here, harmless slime clings to you, but it’s getting \
|
||||
you out!! There doesn't appear to be any actual danger here, harmless slime clings to you, but it's getting \
|
||||
harder and harder to move as those walls press in on you insistently!"
|
||||
|
||||
player_msg = "Your kind rarely ventures into realspace. Being in any well-lit area is very taxing on you, but you \
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
eye_desc = "orange eyes"
|
||||
|
||||
vore_stomach_flavor = "You slip passed pointy triangle teeth and down the slick, \
|
||||
vore_stomach_flavor = "You slip past pointy triangle teeth and down the slick, \
|
||||
slippery gullet of the creature. It's warm, and the air is thick. You can hear \
|
||||
its body squelch and shift around you as you settle into its stomach! Thick digestive \
|
||||
enzymes cling to you within that dark space, tingling and stinging immediately! The weight of \
|
||||
@@ -248,8 +248,8 @@
|
||||
desc = "She appears to be a fluffer of some sort. Deep blue eyes and curious attitude."
|
||||
icon_state = "rivyr"
|
||||
eye_desc = ""
|
||||
vore_stomach_flavor = "Blue flesh gleams in the fading light as you slip down the little mar’s gullet! \
|
||||
Gooey flesh and heat surrounds your form as you’re tucked away into the darkness of her stomach! Thick slimes cling \
|
||||
vore_stomach_flavor = "Blue flesh gleams in the fading light as you slip down the little mar's gullet! \
|
||||
Gooey flesh and heat surrounds your form as you're tucked away into the darkness of her stomach! Thick slimes cling \
|
||||
to you, but they seem to be harmless. The organ gently churns around you, clinging to your shape and forcing \
|
||||
you to curl up a bit. You can feel her rub at you some through the layers of flesh and fluff, while aches \
|
||||
and pains begin to fade away across your body."
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
vore_pounce_chance = 100
|
||||
vore_digest_chance = 0 // just use the toggle
|
||||
vore_default_mode = DM_HOLD //can use the toggle if you wanna be catfood
|
||||
vore_standing_too = TRUE //gonna get pounced
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/EatTarget()
|
||||
var/mob/living/TM = target_mob
|
||||
@@ -201,6 +202,7 @@
|
||||
vore_pounce_chance = 100
|
||||
vore_digest_chance = 0 // just use the toggle
|
||||
vore_default_mode = DM_HOLD //can use the toggle if you wanna be foxfood
|
||||
vore_standing_too = TRUE // gonna get pounced
|
||||
|
||||
/mob/living/simple_animal/fox/fluff/EatTarget()
|
||||
var/mob/living/TM = target_mob
|
||||
|
||||
@@ -703,7 +703,10 @@
|
||||
stat(null)
|
||||
for(var/datum/controller/subsystem/SS in Master.subsystems)
|
||||
SS.stat_entry()
|
||||
|
||||
|
||||
if(statpanel("Tickets"))
|
||||
GLOB.ahelp_tickets.stat_entry()
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
listed_turf = null
|
||||
|
||||
@@ -988,7 +988,7 @@
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
body_parts = list(BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO)
|
||||
|
||||
spirit_panels_head
|
||||
spirit_lights_head
|
||||
name = "Ward - Spirit FBP Lights (head)"
|
||||
icon_state = "lights"
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
@@ -148,6 +148,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
|
||||
can_assist = FALSE
|
||||
|
||||
/obj/item/organ/internal/brain/slime
|
||||
icon = 'icons/obj/surgery_vr.dmi' // Vorestation edit
|
||||
name = "slime core"
|
||||
desc = "A complex, organic knot of jelly and crystalline particles."
|
||||
icon_state = "core"
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
if(istype(W, /obj/item/stack/cable_coil) && !terminal && !building_terminal)
|
||||
building_terminal = 1
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if (CC.get_amount() <= 10)
|
||||
if (CC.get_amount() < 10)
|
||||
to_chat(user, "<span class='warning'>You need more cables.</span>")
|
||||
building_terminal = 0
|
||||
return 0
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
/obj/machinery/chem_master/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(120)
|
||||
reagents = R
|
||||
var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents.
|
||||
reagents = R //There should be a nano ui thingy to warn of this.
|
||||
R.my_atom = src
|
||||
|
||||
/obj/machinery/chem_master/ex_act(severity)
|
||||
@@ -55,7 +55,7 @@
|
||||
src.beaker = B
|
||||
user.drop_item()
|
||||
B.loc = src
|
||||
to_chat(user, "You add \the [B] to the machine!")
|
||||
to_chat(user, "You add \the [B] to the machine.")
|
||||
icon_state = "mixer1"
|
||||
|
||||
else if(istype(B, /obj/item/weapon/storage/pill_bottle))
|
||||
@@ -67,7 +67,7 @@
|
||||
src.loaded_pill_bottle = B
|
||||
user.drop_item()
|
||||
B.loc = src
|
||||
to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot!")
|
||||
to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.")
|
||||
|
||||
else if(default_unfasten_wrench(user, B, 20))
|
||||
return
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
if (src.amount > 3 && !O.opened)
|
||||
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
|
||||
P.wrapped = O
|
||||
O.welded = 1
|
||||
O.sealed = 1
|
||||
O.loc = P
|
||||
src.amount -= 3
|
||||
user.visible_message("\The [user] wraps \a [target] with \a [src].",\
|
||||
@@ -311,7 +311,7 @@
|
||||
wrapped.forceMove(get_turf(src))
|
||||
if(istype(wrapped, /obj/structure/closet))
|
||||
var/obj/structure/closet/O = wrapped
|
||||
O.welded = 0
|
||||
O.sealed = 0
|
||||
wrapped = null
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/atom/movable/AM in contents)
|
||||
|
||||
Regular → Executable
+14
-10
@@ -121,7 +121,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
//Loading a disk into it.
|
||||
if(istype(D, /obj/item/weapon/disk))
|
||||
if(t_disk || d_disk)
|
||||
user << "A disk is already loaded into the machine."
|
||||
to_chat(user, "A disk is already loaded into the machine.")
|
||||
return
|
||||
|
||||
if(istype(D, /obj/item/weapon/disk/tech_disk))
|
||||
@@ -129,11 +129,11 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
else if (istype(D, /obj/item/weapon/disk/design_disk))
|
||||
d_disk = D
|
||||
else
|
||||
user << "<span class='notice'>Machine cannot accept disks in that format.</span>"
|
||||
to_chat(user, "<span class='notice'>Machine cannot accept disks in that format.</span>")
|
||||
return
|
||||
user.drop_item()
|
||||
D.loc = src
|
||||
user << "<span class='notice'>You add \the [D] to the machine.</span>"
|
||||
to_chat(user, "<span class='notice'>You add \the [D] to the machine.</span>")
|
||||
else
|
||||
//The construction/deconstruction of the console code.
|
||||
..()
|
||||
@@ -145,7 +145,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(!emagged)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
user << "<span class='notice'>You you disable the security protocols.</span>"
|
||||
to_chat(user, "<span class='notice'>You you disable the security protocols.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/rdconsole/Topic(href, href_list)
|
||||
@@ -155,12 +155,16 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
add_fingerprint(usr)
|
||||
|
||||
usr.set_machine(src)
|
||||
if((screen < 1 || (screen == 1.6 && href_list["menu"] != "1.0")) && (!allowed(usr) && !emagged)) //Stops people from HREF exploiting out of the lock screen, but allow it if they have the access.
|
||||
to_chat(usr, "Unauthorized Access")
|
||||
return
|
||||
|
||||
if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code.
|
||||
var/temp_screen = text2num(href_list["menu"])
|
||||
if(temp_screen <= 1.1 || (3 <= temp_screen && 4.9 >= temp_screen) || allowed(usr) || emagged) //Unless you are making something, you need access.
|
||||
screen = temp_screen
|
||||
else
|
||||
usr << "Unauthorized Access."
|
||||
to_chat(usr, "Unauthorized Access.")
|
||||
|
||||
else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk.
|
||||
screen = 0.0
|
||||
@@ -211,7 +215,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
usr << "<span class='notice'>The destructive analyzer is busy at the moment.</span>"
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
|
||||
else if(linked_destroy.loaded_item)
|
||||
linked_destroy.loaded_item.loc = linked_destroy.loc
|
||||
@@ -222,7 +226,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder.
|
||||
if(linked_destroy)
|
||||
if(linked_destroy.busy)
|
||||
usr << "<span class='notice'>The destructive analyzer is busy at the moment.</span>"
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer is busy at the moment.</span>")
|
||||
else
|
||||
if(alert("Proceeding will destroy loaded item. Continue?", "Destructive analyzer confirmation", "Yes", "No") == "No" || !linked_destroy)
|
||||
return
|
||||
@@ -234,7 +238,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(linked_destroy)
|
||||
linked_destroy.busy = 0
|
||||
if(!linked_destroy.loaded_item)
|
||||
usr <<"<span class='notice'>The destructive analyzer appears to be empty.</span>"
|
||||
to_chat(usr, "<span class='notice'>The destructive analyzer appears to be empty.</span>")
|
||||
screen = 1.0
|
||||
return
|
||||
|
||||
@@ -270,12 +274,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(allowed(usr))
|
||||
screen = text2num(href_list["lock"])
|
||||
else
|
||||
usr << "Unauthorized Access."
|
||||
to_chat(usr, "Unauthorized Access.")
|
||||
|
||||
else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected.
|
||||
screen = 0.0
|
||||
if(!sync)
|
||||
usr << "<span class='notice'>You must connect to the network first.</span>"
|
||||
to_chat(usr, "<span class='notice'>You must connect to the network first.</span>")
|
||||
else
|
||||
griefProtection() //Putting this here because I dont trust the sync process
|
||||
spawn(30)
|
||||
|
||||
@@ -1229,3 +1229,259 @@
|
||||
icon_state = "zenghu_taj"
|
||||
|
||||
//Taurs moved to a separate file due to extra code around them
|
||||
|
||||
//Buggo Abdomens!
|
||||
|
||||
/datum/sprite_accessory/tail/buggo
|
||||
name = "Bug abdomen, colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggobee
|
||||
name = "Bug abdomen, bee top, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobee_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggobeefull
|
||||
name = "Bug abdomen, bee full, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobeefull_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggounder
|
||||
name = "Bug abdomen, underside, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggounder_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofirefly
|
||||
name = "Bug abdomen, firefly, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofirefly_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofat
|
||||
name = "Fat bug abdomen, colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggofatbee
|
||||
name = "Fat bug abdomen, bee top, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatbee_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofatbeefull
|
||||
name = "Fat bug abdomen, bee full, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatbeefull_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofatunder
|
||||
name = "Fat bug abdomen, underside, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatunder_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofatfirefly
|
||||
name = "Fat bug abdomen, firefly, dual-colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatfirefly_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggowag
|
||||
name = "Bug abdomen, colorable, vwag change"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
ani_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggobeewag
|
||||
name = "Bug abdomen, bee top, dual color, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
ani_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobee_markings"
|
||||
extra_overlay_w = "buggofatbee_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggobeefullwag
|
||||
name = "Bug abdomen, bee full, dual color, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
ani_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobeefull_markings"
|
||||
extra_overlay_w = "buggofatbeefull_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggounderwag
|
||||
name = "Bug abdomen, underside, dual color, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
ani_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggounder_markings"
|
||||
extra_overlay_w = "buggofatunder_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggofireflywag
|
||||
name = "Bug abdomen, firefly, dual color, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_s"
|
||||
ani_state = "buggofat_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofirefly_markings"
|
||||
extra_overlay_w = "buggofatfirefly_markings"
|
||||
|
||||
//Vass buggo variants!
|
||||
|
||||
/datum/sprite_accessory/tail/buggovass
|
||||
name = "Bug abdomen, vass, colorable"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassbee
|
||||
name = "Bug abdomen, bee top, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobee_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassbeefull
|
||||
name = "Bug abdomen, bee full, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobeefull_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassunder
|
||||
name = "Bug abdomen, underside, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggounder_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfirefly
|
||||
name = "Bug abdomen, firefly, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofirefly_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfat
|
||||
name = "Fat bug abdomen, vass, colorable"
|
||||
desc = ""
|
||||
icon_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfatbee
|
||||
name = "Fat bug abdomen, bee top, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatbee_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfatbeefull
|
||||
name = "Fat bug abdomen, bee full, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatbeefull_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfatunder
|
||||
name = "Fat bug abdomen, underside, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatunder_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfatfirefly
|
||||
name = "Fat bug abdomen, firefly, dc, vass"
|
||||
desc = ""
|
||||
icon_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofatfirefly_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovasswag
|
||||
name = "Bug abdomen, vass, colorable, vwag change"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
ani_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassbeewag
|
||||
name = "Bug abdomen, bee top, dc, vass, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
ani_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobee_vass_markings"
|
||||
extra_overlay_w = "buggofatbee_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassbeefullwag
|
||||
name = "Bug abdomen, bee full, dc, vass, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
ani_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggobeefull_vass_markings"
|
||||
extra_overlay_w = "buggofatbeefull_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassunderwag
|
||||
name = "Bug abdomen, underside, dc, vass, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
ani_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggounder_vass_markings"
|
||||
extra_overlay_w = "buggofatunder_vass_markings"
|
||||
|
||||
/datum/sprite_accessory/tail/buggovassfireflywag
|
||||
name = "Bug abdomen, firefly, dc, vass, vwag"
|
||||
desc = ""
|
||||
icon_state = "buggo_vass_s"
|
||||
ani_state = "buggofat_vass_s"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "buggofirefly_vass_markings"
|
||||
extra_overlay_w = "buggofatfirefly_vass_markings"
|
||||
|
||||
@@ -910,7 +910,7 @@
|
||||
icon_state = "khi_uniform_cmd_i"
|
||||
item_state = "khi_uniform_cmd"
|
||||
worn_state = "khi_uniform_cmd"
|
||||
armor = list(melee = 5, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/under/rank/khi/sec //Security version
|
||||
name = "KHI security suit"
|
||||
@@ -926,7 +926,7 @@
|
||||
icon_state = "khi_uniform_med_i"
|
||||
item_state = "khi_uniform_med"
|
||||
worn_state = "khi_uniform_med"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 5)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0)
|
||||
|
||||
/obj/item/clothing/under/rank/khi/eng //Engineering version
|
||||
name = "KHI engineering suit"
|
||||
@@ -942,7 +942,7 @@
|
||||
icon_state = "khi_uniform_sci_i"
|
||||
item_state = "khi_uniform_sci"
|
||||
worn_state = "khi_uniform_sci"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 5, bio = 0, rad = 5)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 0, rad = 0)
|
||||
|
||||
/obj/item/clothing/under/rank/khi/fluff/aronai //Aro fluff version
|
||||
name = "KHI meditech suit"
|
||||
@@ -950,7 +950,7 @@
|
||||
icon_state = "khi_uniform_aro_i"
|
||||
item_state = "khi_uniform_aro"
|
||||
worn_state = "khi_uniform_aro"
|
||||
armor = list(melee = 5, bullet = 5, laser = 5, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0)
|
||||
|
||||
//jacobdragon:Earthen Breath
|
||||
/obj/item/clothing/under/fluff/earthenbreath
|
||||
@@ -1192,14 +1192,14 @@ Departamental Swimsuits, for general use
|
||||
desc = "The uniform worn by command officers in the mid 2260s."
|
||||
icon_state = "trek_command"
|
||||
item_state = "trek_command"
|
||||
armor = list(melee = 10, bullet = 10, laser = 10,energy = 0, bomb = 0, bio = 10, rad = 10, fire = 0, acid = 0) // Considering only staff heads get to pick it
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) // Considering only staff heads get to pick it
|
||||
|
||||
/obj/item/clothing/under/rank/trek/engsec
|
||||
name = "Operations Uniform"
|
||||
desc = "The uniform worn by operations officers of the mid 2260s. You feel strangely vulnerable just seeing this..."
|
||||
icon_state = "trek_engsec"
|
||||
item_state = "trek_engsec"
|
||||
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 10, fire = 0, acid = 0) // since they're shared between jobs and kinda moot.
|
||||
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) // since they're shared between jobs and kinda moot.
|
||||
|
||||
/obj/item/clothing/under/rank/trek/medsci
|
||||
name = "MedSci Uniform"
|
||||
@@ -1207,7 +1207,7 @@ Departamental Swimsuits, for general use
|
||||
icon_state = "trek_medsci"
|
||||
item_state = "trek_medsci"
|
||||
permeability_coefficient = 0.50
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0, fire = 0, acid = 0) // basically a copy of vanilla sci/med
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0) // basically a copy of vanilla sci/med
|
||||
|
||||
//TNG
|
||||
/obj/item/clothing/under/rank/trek/command/next
|
||||
|
||||
+6
-1
@@ -63,6 +63,8 @@ var/global/datum/global_init/init = new ()
|
||||
// if(config && config.log_runtime)
|
||||
// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
callHook("startup")
|
||||
//Emergency Fix
|
||||
load_mods()
|
||||
@@ -171,7 +173,10 @@ var/world_topic_spam_protect_time = world.timeofday
|
||||
|
||||
s["players"] = players.len
|
||||
s["playerlist"] = list2params(players)
|
||||
s["admins"] = admins.len
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/presentmins = adm["present"]
|
||||
var/list/afkmins = adm["afk"]
|
||||
s["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
|
||||
s["adminlist"] = list2params(admins)
|
||||
else
|
||||
var/n = 0
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# wip (For works in progress)
|
||||
# tweak
|
||||
# soundadd
|
||||
# sounddel
|
||||
# rscadd (general adding of nice things)
|
||||
# rscdel (general deleting of nice things)
|
||||
# imageadd
|
||||
# imagedel
|
||||
# maptweak
|
||||
# spellcheck (typo fixes)
|
||||
# experiment
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: Anewbe
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- rscadd: "Graves are now a thing in the code, will need some testing and probably more work before they get more common."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 699 B |
@@ -6,7 +6,7 @@
|
||||
if(config.wikiurl)
|
||||
if(query)
|
||||
if(config.wikisearchurl)
|
||||
var/output = replacetext(config.wikisearchurl, "%s", url_encode(query))
|
||||
var/output = replacetext(config.wikisearchurl, "%s", url_encode(query))
|
||||
src << link(output)
|
||||
else
|
||||
src << "<span class='warning'> The wiki search URL is not set in the server configuration.</span>"
|
||||
|
||||
@@ -1587,7 +1587,7 @@
|
||||
"EA" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva)
|
||||
"EB" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor/tiled,/area/outpost/mining_main/eva)
|
||||
"EC" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/obj/machinery/light,/turf/simulated/floor/tiled/dark,/area/outpost/mining_main/storage)
|
||||
"ED" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe/hammer,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/turf/simulated/floor/tiled/dark,/area/outpost/mining_main/storage)
|
||||
"ED" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/turf/simulated/floor/tiled/dark,/area/outpost/mining_main/storage)
|
||||
"EE" = (/turf/simulated/wall,/area/outpost/mining_main/storage)
|
||||
"EF" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/camera/network/mining{c_tag = "OPM - Mining Hallway Aft"; dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled,/area/outpost/mining_main/south_hall)
|
||||
"EG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/tiled,/area/outpost/mining_main/south_hall)
|
||||
@@ -1912,7 +1912,7 @@
|
||||
"KN" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space)
|
||||
"KO" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space)
|
||||
"KP" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow,/turf/simulated/floor/airless{icon_state = "asteroidplating2"},/area/outpost/engineering/solarsoutside/aft)
|
||||
|
||||
|
||||
(1,1,1) = {"
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
|
||||
@@ -98,8 +98,8 @@
|
||||
"bT" = (/obj/structure/ore_box,/obj/effect/floor_decal/corner/brown{dir = 10},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bU" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/floor_decal/corner/brown{dir = 10},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bV" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/floor_decal/corner/brown{dir = 10},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bW" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe/hammer,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/obj/effect/floor_decal/corner/brown{dir = 10},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bX" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe/hammer,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/obj/effect/floor_decal/corner/brown{dir = 10},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bW" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/obj/effect/floor_decal/corner/brown{dir = 10},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bX" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/obj/item/weapon/tool/wrench,/obj/item/weapon/tool/crowbar,/obj/item/weapon/shovel,/obj/effect/floor_decal/corner/brown{dir = 10},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main/storage)
|
||||
"bY" = (/obj/effect/floor_decal/corner/brown{dir = 8},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main)
|
||||
"bZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/surface/outpost/mining_main)
|
||||
"ca" = (/obj/effect/floor_decal/industrial/warning/corner,/turf/simulated/floor/tiled,/area/surface/outpost/mining_main)
|
||||
@@ -1818,4 +1818,3 @@ aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafDADADADADA
|
||||
aaafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafagafafafafafafafafDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDVDMDWDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDJDJDKDKDJDJDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDQDVDMDWDQDQDQDQDQDQDQDQDQDQDQDQDQDQafafafafafafafafafafafafagafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafaa
|
||||
aaaaaaaaaaaaaaaaabababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDQDYDYDYDQDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDQDZDZDZDZDZDZDQDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDXDQDYDYDYDQDXDXDXDXDXDXDXDXDXDXDXDXDXababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababab
|
||||
"}
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ var/const/PATHFINDER =(1<<13) //VOREStation Edit - Added Pathfinder
|
||||
idtype = /obj/item/weapon/card/id/science/head/pathfinder
|
||||
economic_modifier = 7
|
||||
|
||||
access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_research)
|
||||
minimal_access = list(access_eva, access_pilot, access_explorer, access_research)
|
||||
access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_research, access_gateway)
|
||||
minimal_access = list(access_eva, access_pilot, access_explorer, access_research, access_gateway)
|
||||
outfit_type = /decl/hierarchy/outfit/job/pathfinder
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
/datum/map_z_level/tether_lateload/underdark
|
||||
name = "Underdark"
|
||||
flags = MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER
|
||||
base_turf = /turf/simulated/mineral/floor/virgo3b
|
||||
|
||||
/datum/map_template/tether_lateload/tether_underdark/on_map_loaded(z)
|
||||
. = ..()
|
||||
|
||||
@@ -14,12 +14,19 @@
|
||||
name = "\improper Unknown Area AU" //Nobody will know what this means if they see it, anyway.
|
||||
requires_power = 1
|
||||
dynamic_lighting = 1
|
||||
power_equip = FALSE
|
||||
power_environ = FALSE
|
||||
power_light = FALSE
|
||||
/area/submap/admin_upload/pow
|
||||
name = "\improper Unknown Area AU+P"
|
||||
requires_power = 0
|
||||
/area/submap/admin_upload/lit
|
||||
name = "\improper Unknown Area AU+L"
|
||||
requires_power = 1
|
||||
dynamic_lighting = 0
|
||||
power_equip = FALSE
|
||||
power_environ = FALSE
|
||||
power_light = FALSE
|
||||
/area/submap/admin_upload/powlit
|
||||
name = "\improper Unknown Area AU+PL"
|
||||
requires_power = 0
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
/area/tether_away/cave
|
||||
flags = RAD_SHIELDED
|
||||
ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg')
|
||||
base_turf = /turf/simulated/mineral/floor/ignore_mapgen/cave
|
||||
|
||||
/area/tether_away/cave/explored/normal
|
||||
name = "\improper Away Mission - Virgo 4 Cave (E)"
|
||||
|
||||
@@ -1802,7 +1802,7 @@
|
||||
/area/tether/surfacebase/mining_main/storage)
|
||||
"adU" = (
|
||||
/obj/structure/table/rack,
|
||||
/obj/item/weapon/pickaxe/hammer,
|
||||
/obj/item/weapon/pickaxe,
|
||||
/obj/item/weapon/tool/wrench,
|
||||
/obj/item/weapon/tool/crowbar,
|
||||
/obj/item/weapon/shovel,
|
||||
|
||||
@@ -8455,13 +8455,11 @@
|
||||
opacity = 0
|
||||
},
|
||||
/obj/structure/grille,
|
||||
/obj/structure/window/reinforced/full,
|
||||
/turf/simulated/floor,
|
||||
/area/security/security_processing)
|
||||
"oh" = (
|
||||
/obj/machinery/door/firedoor/glass,
|
||||
/obj/structure/grille,
|
||||
/obj/structure/window/reinforced/full,
|
||||
/obj/structure/window/reinforced/polarized{
|
||||
dir = 10;
|
||||
icon_state = "fwindow";
|
||||
id = "sec_processing"
|
||||
},
|
||||
/turf/simulated/floor,
|
||||
/area/security/security_processing)
|
||||
"oi" = (
|
||||
@@ -13671,9 +13669,6 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/quartermaster/office)
|
||||
"wb" = (
|
||||
/obj/machinery/computer/supplycomp{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/cable/green{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
@@ -13685,6 +13680,9 @@
|
||||
/obj/effect/floor_decal/corner/brown/border{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/computer/supplycomp/control{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/tiled,
|
||||
/area/quartermaster/office)
|
||||
"wc" = (
|
||||
@@ -35028,7 +35026,7 @@ cS
|
||||
jk
|
||||
jk
|
||||
jk
|
||||
oh
|
||||
qQ
|
||||
oE
|
||||
po
|
||||
pO
|
||||
@@ -35170,7 +35168,7 @@ cT
|
||||
jy
|
||||
jk
|
||||
jk
|
||||
oh
|
||||
qQ
|
||||
oF
|
||||
pp
|
||||
pP
|
||||
@@ -35313,9 +35311,9 @@ mH
|
||||
lD
|
||||
lD
|
||||
of
|
||||
oh
|
||||
oh
|
||||
oh
|
||||
qQ
|
||||
qQ
|
||||
qQ
|
||||
qk
|
||||
qQ
|
||||
qQ
|
||||
|
||||
@@ -122,8 +122,10 @@
|
||||
// Mining Underdark
|
||||
/area/mine/unexplored/underdark
|
||||
name = "\improper Mining Underdark"
|
||||
base_turf = /turf/simulated/mineral/floor/virgo3b
|
||||
/area/mine/explored/underdark
|
||||
name = "\improper Mining Underdark"
|
||||
base_turf = /turf/simulated/mineral/floor/virgo3b
|
||||
|
||||
// Mining outpost areas
|
||||
/area/outpost/mining_main/passage
|
||||
|
||||
@@ -72,6 +72,11 @@
|
||||
{{:helper.link('', 'pill pill' + data.pillSprite, {'tab_select' : 'pill'}, null, 'link32')}}
|
||||
{{:helper.link('', 'pill bottle' + data.bottleSprite, {'tab_select' : 'bottle'}, null, 'link32')}}
|
||||
</div>
|
||||
{{else}}
|
||||
<hr>
|
||||
<div class='item'>
|
||||
{{:helper.link('Create bottle (50 units max)', null, {'createbottle' : 1})}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ automatically by GUI tools like TortoiseGit and GitHub for Windows, but
|
||||
## Current Hooks
|
||||
|
||||
* **Pre-commit**: Runs [mapmerge2] on changed maps, if any.
|
||||
* **DMI merger**: Attempts to [fix icon conflicts] when performing a git merge.
|
||||
If it succeeds, the file is marked merged. If it fails, it logs what states
|
||||
are still in conflict and adds them to the .dmi file, where the desired
|
||||
resolution can be chosen.
|
||||
|
||||
## Adding New Hooks
|
||||
|
||||
@@ -34,3 +38,4 @@ version of Python is found.
|
||||
[merge drivers]: https://git-scm.com/docs/gitattributes#_performing_a_three_way_merge
|
||||
[Git for Windows]: https://gitforwindows.org/
|
||||
[mapmerge2]: ../mapmerge2/README.md
|
||||
[fix icon conflicts]: ../mapmerge2/merge_driver_dmi.py
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
exec tools/hooks/python.sh -m merge_driver_dmi "$@"
|
||||
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
cd %~dp0
|
||||
for %%f in (*.hook) do (
|
||||
echo Installing hook: %%~nf
|
||||
copy %%f ..\..\.git\hooks\%%~nf >nul
|
||||
)
|
||||
for %%f in (*.merge) do (
|
||||
echo Installing merge driver: %%~nf
|
||||
echo [merge "%%~nf"]^
|
||||
|
||||
driver = tools/hooks/%%f %%P %%O %%A %%B %%L >> ..\..\.git\config
|
||||
)
|
||||
echo Installing Python dependencies
|
||||
python -m pip install -r ..\mapmerge2\requirements.txt
|
||||
echo Done
|
||||
pause
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
shopt -s nullglob
|
||||
cd "$(dirname "$0")"
|
||||
for f in *.hook; do
|
||||
echo Installing hook: ${f%.hook}
|
||||
cp $f ../../.git/hooks/${f%.hook}
|
||||
done
|
||||
for f in *.merge; do
|
||||
echo Installing merge driver: ${f%.merge}
|
||||
git config --replace-all merge.${f%.merge}.driver "tools/hooks/$f %P %O %A %B %L"
|
||||
done
|
||||
echo Installing Python dependencies
|
||||
./python.sh -m pip install -r ../mapmerge2/requirements.txt
|
||||
echo "Done"
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
exec tools/hooks/python.sh -m precommit
|
||||
@@ -1,7 +0,0 @@
|
||||
cd ../../maps/tether
|
||||
|
||||
FOR %%f IN (*.dmm) DO (
|
||||
copy %%f %%f.backup
|
||||
)
|
||||
|
||||
pause
|
||||
@@ -1,8 +0,0 @@
|
||||
SET z_levels=10
|
||||
cd
|
||||
|
||||
FOR %%f IN (../../maps/tether/*.dmm) DO (
|
||||
java -jar MapPatcher.jar -clean ../../maps/tether/%%f.backup ../../maps/tether/%%f ../../maps/tether/%%f
|
||||
)
|
||||
|
||||
pause
|
||||
Binary file not shown.
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
for MAPFILE in ../../maps/*.dmm
|
||||
do
|
||||
MAPNAME=$(basename $MAPFILE)
|
||||
git show HEAD:maps/$MAPNAME > tmp.dmm
|
||||
java -jar MapPatcher.jar -clean tmp.dmm $MAPFILE $MAPFILE
|
||||
rm tmp.dmm
|
||||
done
|
||||
@@ -1,6 +0,0 @@
|
||||
@echo off
|
||||
set tab=
|
||||
echo. >> ../../.git/config
|
||||
echo [merge "merge-dmm"] >> ../../.git/config
|
||||
echo %tab%name = mapmerge driver >> ../../.git/config
|
||||
echo %tab%driver = ./tools/mapmerge/mapmerge.sh %%O %%A %%B >> ../../.git/config
|
||||
@@ -1,6 +0,0 @@
|
||||
F="../../.git/config"
|
||||
|
||||
echo '' >> $F
|
||||
echo '[merge "merge-dmm"]' >> $F
|
||||
echo ' name = mapmerge driver' >> $F
|
||||
echo ' driver = ./tools/mapmerge/mapmerge.sh %O %A %B' >> $F
|
||||
@@ -1,19 +0,0 @@
|
||||
1. Install java(http://www.java.com/en/download/index.jsp)
|
||||
2. Make sure java is in your PATH. To test this, open git bash, and type "java". If it says unknown command, you need to add JAVA/bin to your PATH variable (A guide for this can be found at https://www.java.com/en/download/help/path.xml ).
|
||||
|
||||
Committing
|
||||
1. Before starting to edit the map, double-click "prepare_map.bat" in the tools/mapmerge/ directory.
|
||||
2. After finishing your edit, and before your commit, double-click "clean_map.bat" in the tools/mapmerge/ directory.
|
||||
|
||||
This will make sure in the new version of your map, no paths are needlessly changed, thus instead of 8000 lines changed you'll get 50 lines changed. This not only reduces size of your commit, it also makes it possible to get an overview of your map changes on the "files changed" page in your pull request.
|
||||
|
||||
Merging
|
||||
The easiest way to do merging is to install the merge driver. For this, open `Baystation12/.git/config` in a text editor, and paste the following lines to the end of it:
|
||||
|
||||
[merge "merge-dmm"]
|
||||
name = mapmerge driver
|
||||
driver = ./tools/mapmerge/mapmerge.sh %O %A %B
|
||||
|
||||
You may optionally instead run git_merge_installer.bat or git_merge_installer.sh which should automatically insert these lines for you at the appropriate location.
|
||||
|
||||
After this, merging maps should happen automagically unless there are conflicts(a tile that both you and someone else changed). If there are conflicts, you will unfortunately still be stuck with opening both versions in a map editor, and manually resolving the issues.
|
||||
@@ -1,9 +0,0 @@
|
||||
java -jar tools/mapmerge/MapPatcher.jar -merge $1 $2 $3 $2
|
||||
if [ "$?" -gt 0 ]
|
||||
then
|
||||
echo "Unable to automatically resolve map conflicts, please merge manually."
|
||||
exit 1
|
||||
fi
|
||||
java -jar tools/mapmerge/MapPatcher.jar -clean $3 $2 $2
|
||||
|
||||
exit 0
|
||||
@@ -1,52 +0,0 @@
|
||||
# Map Merge 2
|
||||
|
||||
**Map Merge 2** is an improvement over previous map merging scripts, with
|
||||
better merge-conflict prevention, multi-Z support, and automatic handling of
|
||||
key overflow. For up-to-date tips and tricks, also visit the [Map Merger] wiki article.
|
||||
|
||||
## What Map Merging Is
|
||||
|
||||
The "map merge" operation describes the process of rewriting a map file written
|
||||
by the DreamMaker map editor to A) use a format more amenable to Git's conflict
|
||||
resolution and B) differ in the least amount textually from the previous
|
||||
version of the map while maintaining all the actual changes. It requires an old
|
||||
version of the map to use as a reference and a new version of the map which
|
||||
contains the desired changes.
|
||||
|
||||
## Installation
|
||||
|
||||
To install Python dependencies, run `requirements-install.bat`, or run
|
||||
`python -m pip install -r requirements.txt` directly. See the [Git hooks]
|
||||
documentation to install the Git pre-commit hook which runs the map merger
|
||||
automatically, or use `tools/mapmerge/Prepare Maps.bat` to save backups before
|
||||
running `mapmerge.bat`.
|
||||
|
||||
For up-to-date installation and detailed troubleshooting instructions, visit
|
||||
the [Map Merger] wiki article.
|
||||
|
||||
## Code Structure
|
||||
|
||||
Frontend scripts are meant to be run directly. They obey the environment
|
||||
variables `TGM` to set whether files are saved in TGM (1) or DMM (0) format,
|
||||
and `MAPROOT` to determine where maps are kept. By default, TGM is used and
|
||||
the map root is autodetected. Each script may either prompt for the desired map
|
||||
or be run with command-line parameters indicating which maps to act on. The
|
||||
scripts include:
|
||||
|
||||
* `convert.py` for converting maps to and from the TGM format. Used by
|
||||
`tgm2dmm.bat` and `dmm2tgm.bat`.
|
||||
* `mapmerge.py` for running the map merge on map backups saved by
|
||||
`Prepare Maps.bat`. Used by `mapmerge.bat`
|
||||
|
||||
Implementation modules:
|
||||
|
||||
* `dmm.py` includes the map reader and writer.
|
||||
* `mapmerge.py` includes the implementation of the map merge operation.
|
||||
* `frontend.py` includes the common code for the frontend scripts.
|
||||
|
||||
`precommit.py` is run by the [Git hooks] if installed, and merges the new
|
||||
version of any map saved in the index (`git add`ed) with the old version stored
|
||||
in Git when run.
|
||||
|
||||
[Map Merger]: https://tgstation13.org/wiki/Map_Merger
|
||||
[Git hooks]: ../hooks/README.md
|
||||
@@ -0,0 +1,253 @@
|
||||
# Tools for working with modern DreamMaker icon files (PNGs + metadata)
|
||||
|
||||
import math
|
||||
from PIL import Image
|
||||
from PIL.PngImagePlugin import PngInfo
|
||||
|
||||
DEFAULT_SIZE = 32, 32
|
||||
LOOP_UNLIMITED = 0
|
||||
LOOP_ONCE = 1
|
||||
|
||||
NORTH = 1
|
||||
SOUTH = 2
|
||||
EAST = 4
|
||||
WEST = 8
|
||||
SOUTHEAST = SOUTH|EAST
|
||||
SOUTHWEST = SOUTH|WEST
|
||||
NORTHEAST = NORTH|EAST
|
||||
NORTHWEST = NORTH|WEST
|
||||
|
||||
CARDINALS = [NORTH, SOUTH, EAST, WEST]
|
||||
DIR_ORDER = [SOUTH, NORTH, EAST, WEST, SOUTHEAST, SOUTHWEST, NORTHEAST, NORTHWEST]
|
||||
DIR_NAMES = {
|
||||
'SOUTH': SOUTH,
|
||||
'NORTH': NORTH,
|
||||
'EAST': EAST,
|
||||
'WEST': WEST,
|
||||
'SOUTHEAST': SOUTHEAST,
|
||||
'SOUTHWEST': SOUTHWEST,
|
||||
'NORTHEAST': NORTHEAST,
|
||||
'NORTHWEST': NORTHWEST,
|
||||
**{str(x): x for x in DIR_ORDER},
|
||||
**{x: x for x in DIR_ORDER},
|
||||
'0': SOUTH,
|
||||
None: SOUTH,
|
||||
}
|
||||
|
||||
class Dmi:
|
||||
version = "4.0"
|
||||
|
||||
def __init__(self, width, height):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.states = []
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, fname):
|
||||
image = Image.open(fname)
|
||||
|
||||
# no metadata = regular image file
|
||||
if 'Description' not in image.info:
|
||||
dmi = Dmi(*image.size)
|
||||
state = dmi.state("")
|
||||
state.frame(image)
|
||||
return dmi
|
||||
|
||||
# read metadata
|
||||
metadata = image.info['Description']
|
||||
line_iter = iter(metadata.splitlines())
|
||||
assert next(line_iter) == "# BEGIN DMI"
|
||||
assert next(line_iter) == f"version = {cls.version}"
|
||||
|
||||
dmi = Dmi(*DEFAULT_SIZE)
|
||||
state = None
|
||||
|
||||
for line in line_iter:
|
||||
if line == "# END DMI":
|
||||
break
|
||||
key, value = line.lstrip().split(" = ")
|
||||
if key == 'width':
|
||||
dmi.width = int(value)
|
||||
elif key == 'height':
|
||||
dmi.height = int(value)
|
||||
elif key == 'state':
|
||||
state = dmi.state(unescape(value))
|
||||
elif key == 'dirs':
|
||||
state.dirs = int(value)
|
||||
elif key == 'frames':
|
||||
state._nframes = int(value)
|
||||
elif key == 'delay':
|
||||
state.delays = [parse_num(x) for x in value.split(',')]
|
||||
elif key == 'loop':
|
||||
state.loop = int(value)
|
||||
elif key == 'rewind':
|
||||
state.rewind = parse_bool(value)
|
||||
elif key == 'hotspot':
|
||||
x, y, frm = [int(x) for x in value.split(',')]
|
||||
state.hotspot(frm - 1, x, y)
|
||||
elif key == 'movement':
|
||||
state.movement = parse_bool(value)
|
||||
else:
|
||||
raise NotImplementedError(key)
|
||||
|
||||
# cut image into frames
|
||||
width, height = image.size
|
||||
gridwidth = width // dmi.width
|
||||
i = 0
|
||||
for state in dmi.states:
|
||||
for frame in range(state._nframes):
|
||||
for dir in range(state.dirs):
|
||||
px = dmi.width * (i % gridwidth)
|
||||
py = dmi.height * (i // gridwidth)
|
||||
im = image.crop((px, py, px + dmi.width, py + dmi.height))
|
||||
assert im.size == (dmi.width, dmi.height)
|
||||
state.frames.append(im)
|
||||
i += 1
|
||||
state._nframes = None
|
||||
|
||||
return dmi
|
||||
|
||||
def state(self, *args, **kwargs):
|
||||
s = State(self, *args, **kwargs)
|
||||
self.states.append(s)
|
||||
return s
|
||||
|
||||
@property
|
||||
def default_state(self):
|
||||
return self.states[0]
|
||||
|
||||
def get_state(self, name):
|
||||
for state in self.states:
|
||||
if state.name == name:
|
||||
return state
|
||||
raise KeyError(name)
|
||||
return self.default_state
|
||||
|
||||
def _assemble_comment(self):
|
||||
comment = "# BEGIN DMI\n"
|
||||
comment += f"version = {self.version}\n"
|
||||
comment += f"\twidth = {self.width}\n"
|
||||
comment += f"\theight = {self.height}\n"
|
||||
for state in self.states:
|
||||
comment += f"state = {escape(state.name)}\n"
|
||||
comment += f"\tdirs = {state.dirs}\n"
|
||||
comment += f"\tframes = {state.framecount}\n"
|
||||
if state.framecount > 1 and len(state.delays): #any(x != 1 for x in state.delays):
|
||||
comment += "\tdelay = " + ",".join(map(str, state.delays)) + "\n"
|
||||
if state.loop != 0:
|
||||
comment += f"\tloop = {state.loop}\n"
|
||||
if state.rewind:
|
||||
comment += "\trewind = 1\n"
|
||||
if state.movement:
|
||||
comment += "\tmovement = 1\n"
|
||||
if state.hotspots and any(state.hotspots):
|
||||
current = None
|
||||
for i, value in enumerate(state.hotspots):
|
||||
if value != current:
|
||||
x, y = value
|
||||
comment += f"\thotspot = {x},{y},{i + 1}\n"
|
||||
current = value
|
||||
comment += "# END DMI"
|
||||
return comment
|
||||
|
||||
def to_file(self, filename, *, palette=False):
|
||||
# assemble comment
|
||||
comment = self._assemble_comment()
|
||||
|
||||
# assemble spritesheet
|
||||
W, H = self.width, self.height
|
||||
num_frames = sum(len(state.frames) for state in self.states)
|
||||
sqrt = math.ceil(math.sqrt(num_frames))
|
||||
output = Image.new('RGBA', (sqrt * W, math.ceil(num_frames / sqrt) * H))
|
||||
|
||||
i = 0
|
||||
for state in self.states:
|
||||
for frame in state.frames:
|
||||
output.paste(frame, ((i % sqrt) * W, (i // sqrt) * H))
|
||||
i += 1
|
||||
|
||||
# save
|
||||
pnginfo = PngInfo()
|
||||
pnginfo.add_text('Description', comment, zip=True)
|
||||
if palette:
|
||||
output = output.convert('P')
|
||||
output.save(filename, 'png', optimize=True, pnginfo=pnginfo)
|
||||
|
||||
class State:
|
||||
def __init__(self, dmi, name, *, loop=LOOP_UNLIMITED, rewind=False, movement=False, dirs=1):
|
||||
self.dmi = dmi
|
||||
self.name = name
|
||||
self.loop = loop
|
||||
self.rewind = rewind
|
||||
self.movement = movement
|
||||
self.dirs = dirs
|
||||
|
||||
self._nframes = None # used during loading only
|
||||
self.frames = []
|
||||
self.delays = []
|
||||
self.hotspots = None
|
||||
|
||||
@property
|
||||
def framecount(self):
|
||||
if self._nframes is not None:
|
||||
return self._nframes
|
||||
else:
|
||||
return len(self.frames) // self.dirs
|
||||
|
||||
def frame(self, image, *, delay=1):
|
||||
assert image.size == (self.dmi.width, self.dmi.height)
|
||||
self.delays.append(delay)
|
||||
self.frames.append(image)
|
||||
|
||||
def hotspot(self, first_frame, x, y):
|
||||
if self.hotspots is None:
|
||||
self.hotspots = [None] * self.framecount
|
||||
for i in range(first_frame, self.framecount):
|
||||
self.hotspots[i] = x, y
|
||||
|
||||
def _frame_index(self, frame=0, dir=None):
|
||||
ofs = DIR_ORDER.index(DIR_NAMES[dir])
|
||||
if ofs >= self.dirs:
|
||||
ofs = 0
|
||||
return frame * self.dirs + ofs
|
||||
|
||||
def get_frame(self, *args, **kwargs):
|
||||
return self.frames[self._frame_index(*args, **kwargs)]
|
||||
|
||||
def escape(text):
|
||||
assert '\\' not in text and '"' not in text
|
||||
return f'"{text}"'
|
||||
|
||||
def unescape(text, quote='"'):
|
||||
if text == 'null':
|
||||
return None
|
||||
if not (text.startswith(quote) and text.endswith(quote)):
|
||||
raise ValueError(text)
|
||||
text = text[1:-1]
|
||||
assert '\\' not in text and quote not in text
|
||||
return text
|
||||
|
||||
def parse_num(value):
|
||||
if '.' in value:
|
||||
return float(value)
|
||||
return int(value)
|
||||
|
||||
def parse_bool(value):
|
||||
if value not in ('0', '1'):
|
||||
raise ValueError(value)
|
||||
return value == '1'
|
||||
|
||||
if __name__ == '__main__':
|
||||
# test: can we load every DMI in the tree
|
||||
import os
|
||||
|
||||
count = 0
|
||||
for dirpath, dirnames, filenames in os.walk('.'):
|
||||
if '.git' in dirnames:
|
||||
dirnames.remove('.git')
|
||||
for filename in filenames:
|
||||
if filename.endswith('.dmi'):
|
||||
Dmi.from_file(os.path.join(dirpath, filename))
|
||||
count += 1
|
||||
|
||||
print(f"Successfully parsed {count} dmi files")
|
||||
+70
-4
@@ -58,6 +58,23 @@ class DMM:
|
||||
|
||||
raise RuntimeError("ran out of keys, this shouldn't happen")
|
||||
|
||||
def overwrite_key(self, key, fixed, bad_keys):
|
||||
try:
|
||||
self.dictionary[key] = fixed
|
||||
return None
|
||||
except bidict.DuplicationError:
|
||||
old_key = self.dictionary.inv[fixed]
|
||||
bad_keys[key] = old_key
|
||||
print(f"Merging '{num_to_key(key, self.key_length)}' into '{num_to_key(old_key, self.key_length)}'")
|
||||
return old_key
|
||||
|
||||
def reassign_bad_keys(self, bad_keys):
|
||||
if not bad_keys:
|
||||
return
|
||||
for k, v in self.grid.items():
|
||||
# reassign the grid entries which used the old key
|
||||
self.grid[k] = bad_keys.get(v, v)
|
||||
|
||||
def _presave_checks(self):
|
||||
# last-second handling of bogus keys to help prevent and fix broken maps
|
||||
self._ensure_free_keys(0)
|
||||
@@ -70,9 +87,16 @@ class DMM:
|
||||
new_key = bad_keys[k] = self.generate_new_key()
|
||||
self.dictionary.forceput(new_key, self.dictionary[k])
|
||||
print(f" {num_to_key(k, self.key_length, True)} -> {num_to_key(new_key, self.key_length)}")
|
||||
for k, v in self.grid.items():
|
||||
# reassign the grid entries which used the old key
|
||||
self.grid[k] = bad_keys.get(v, v)
|
||||
|
||||
# handle entries in the dictionary which have atoms in the wrong order
|
||||
keys = list(self.dictionary.keys())
|
||||
for key in keys:
|
||||
value = self.dictionary[key]
|
||||
if is_bad_atom_ordering(num_to_key(key, self.key_length, True), value):
|
||||
fixed = tuple(fix_atom_ordering(value))
|
||||
self.overwrite_key(key, fixed, bad_keys)
|
||||
|
||||
self.reassign_bad_keys(bad_keys)
|
||||
|
||||
def _ensure_free_keys(self, desired):
|
||||
# ensure that free keys exist by increasing the key length if necessary
|
||||
@@ -179,6 +203,45 @@ def parse_map_atom(atom):
|
||||
|
||||
return path, vars
|
||||
|
||||
def is_bad_atom_ordering(key, atoms):
|
||||
seen_turfs = 0
|
||||
seen_areas = 0
|
||||
can_fix = False
|
||||
for each in atoms:
|
||||
if each.startswith('/turf'):
|
||||
if seen_turfs == 1:
|
||||
print(f"Warning: key '{key}' has multiple turfs!")
|
||||
if seen_areas:
|
||||
print(f"Warning: key '{key}' has area before turf (autofixing...)")
|
||||
can_fix = True
|
||||
seen_turfs += 1
|
||||
elif each.startswith('/area'):
|
||||
if seen_areas == 1:
|
||||
print(f"Warning: key '{key}' has multiple areas!!!")
|
||||
seen_areas += 1
|
||||
else:
|
||||
if (seen_turfs or seen_areas) and not can_fix:
|
||||
print(f"Warning: key '{key}' has movable after turf or area (autofixing...)")
|
||||
can_fix = True
|
||||
if not seen_areas or not seen_turfs:
|
||||
print(f"Warning: key '{key}' is missing either a turf or area")
|
||||
return can_fix
|
||||
|
||||
def fix_atom_ordering(atoms):
|
||||
movables = []
|
||||
turfs = []
|
||||
areas = []
|
||||
for each in atoms:
|
||||
if each.startswith('/turf'):
|
||||
turfs.append(each)
|
||||
elif each.startswith('/area'):
|
||||
areas.append(each)
|
||||
else:
|
||||
movables.append(each)
|
||||
movables.extend(turfs)
|
||||
movables.extend(areas)
|
||||
return movables
|
||||
|
||||
# ----------
|
||||
# TGM writer
|
||||
|
||||
@@ -307,7 +370,7 @@ def _parse(map_raw_text):
|
||||
continue
|
||||
elif in_comment_line:
|
||||
continue
|
||||
elif char == "\t":
|
||||
elif char in "\r\t":
|
||||
continue
|
||||
|
||||
if char == "/" and not in_quote_block:
|
||||
@@ -415,6 +478,9 @@ def _parse(map_raw_text):
|
||||
|
||||
# grid block
|
||||
for char in it:
|
||||
if char == "\r":
|
||||
continue
|
||||
|
||||
if in_coord_block:
|
||||
if char == ",":
|
||||
if reading_coord == "x":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@echo off
|
||||
set MAPROOT=../../_maps/
|
||||
set MAPROOT=../../maps/
|
||||
set TGM=1
|
||||
python convert.py
|
||||
pause
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
@echo off
|
||||
cd %~dp0
|
||||
for %%f in (*.hook) do (
|
||||
echo Installing hook: %%~nf
|
||||
mkdir ..\..\..\.git\hooks
|
||||
copy %%f ..\..\..\.git\hooks\%%~nf >nul
|
||||
)
|
||||
for %%f in (*.merge) do (
|
||||
echo Installing merge driver: %%~nf
|
||||
echo [merge "%%~nf"]^
|
||||
|
||||
driver = tools/hooks/%%f %%P %%O %%A %%B %%L >> ..\..\..\.git\config
|
||||
)
|
||||
echo Done
|
||||
pause
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
for f in *.hook; do
|
||||
echo Installing hook: ${f%.hook}
|
||||
cp $f ../../../.git/hooks/${f%.hook}
|
||||
done
|
||||
for f in *.merge; do
|
||||
echo Installing merge driver: ${f%.merge}
|
||||
git config --replace-all merge.${f%.merge}.driver "tools/mapmerge2/hooks/$f %P %O %A %B %L"
|
||||
done
|
||||
echo "Done"
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
exec tools/mapmerge2/hooks/python.sh -m precommit
|
||||
@@ -0,0 +1,465 @@
|
||||
/turf/open/floor/circuit/killroom : /turf/open/floor/circuit/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/airless/asteroid : /obj/effect/turf_decal/sand , /turf/open/floor/plasteel/airless {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/airless/bar : /obj/effect/turf_decal/tile/bar , /obj/effect/turf_decal/tile/bar {dir=1} , /turf/open/floor/plasteel/airless {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=1} : /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/arrival {dir=@UNSET} : /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=2} : /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=4} : /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=5} : /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/cafeteria {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=6} : /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival {dir=8} : /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/arrival {dir=9} : /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/arrival {dir=10} : /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/cafeteria {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival/corner {dir=1} : /turf/open/floor/plasteel/white/corner {@OLD}
|
||||
/turf/open/floor/plasteel/arrival/corner {dir=@UNSET} : /turf/open/floor/plasteel/white/corner {@OLD}
|
||||
/turf/open/floor/plasteel/arrival/corner {dir=2} : /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival/corner {dir=4} : /obj/effect/turf_decal/tile/blue {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/arrival/corner {dir=8} : /obj/effect/turf_decal/tile/blue {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/asteroid : /obj/effect/turf_decal/sand , /turf/open/floor/plasteel
|
||||
/turf/open/floor/plasteel/bar : /obj/effect/turf_decal/tile/bar , /obj/effect/turf_decal/tile/bar {dir=1} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/barber : /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/cafeteria {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/side {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blue/corner : /obj/effect/turf_decal/tile/blue {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/blueyellow/side {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=1} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=@UNSET} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=2} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=4} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=5} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=6} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=8} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=9} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown {dir=10} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/corner : /obj/effect/turf_decal/tile/brown {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=1} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=2} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=4} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=5} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=6} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=8} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=9} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms {dir=10} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=1} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=@UNSET} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=2} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=4} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=5} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=6} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=8} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=9} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brown/telecomms/mainframe {dir=10} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=1} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=@UNSET} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=2} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=4} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=5} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=6} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=8} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=9} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold {dir=10} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/brownold/corner : /obj/effect/turf_decal/tile/brown {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/caution {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=2} : /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=4} : /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/checker {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=6} : /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/caution {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/caution {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/checker {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution/corner {dir=1} : /turf/open/floor/plasteel/dark/corner {@OLD}
|
||||
/turf/open/floor/plasteel/caution/corner {dir=@UNSET} : /turf/open/floor/plasteel/dark/corner {@OLD}
|
||||
/turf/open/floor/plasteel/caution/corner {dir=2} : /turf/open/floor/plasteel/dark/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution/corner {dir=4} : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/caution/corner {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/cmo : /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/dark/telecomms/mainframe : /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/dark/telecomms/server : /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/dark/telecomms/server/walkway : /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/corner : /obj/effect/turf_decal/tile/blue {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkblue/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=1} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=@UNSET} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=2} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=4} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=5} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=6} : /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=8} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=9} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown {dir=4} , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/side {dir=10} : /obj/effect/turf_decal/tile/brown {dir=1} , /obj/effect/turf_decal/tile/brown , /obj/effect/turf_decal/tile/brown {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkbrown/corner : /obj/effect/turf_decal/tile/brown {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=1} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=@UNSET} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=2} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=4} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=5} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=6} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=8} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=9} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side {dir=10} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/corner : /obj/effect/turf_decal/tile/green {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkgreen/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=1} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=@UNSET} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=2} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=4} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=5} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=6} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=8} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=9} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side {dir=10} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/corner : /obj/effect/turf_decal/tile/purple {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkpurple/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/corner : /obj/effect/turf_decal/tile/red {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkred/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/corner : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/darkyellow/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=1} : /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/escape {dir=@UNSET} : /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=2} : /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=4} : /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=5} : /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/cafeteria {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=6} : /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape {dir=8} : /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/escape {dir=9} : /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white/corner {@OLD;dir=1}
|
||||
/turf/open/floor/plasteel/escape {dir=10} : /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/cafeteria {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape/corner {dir=1} : /turf/open/floor/plasteel/white/corner {@OLD}
|
||||
/turf/open/floor/plasteel/escape/corner {dir=@UNSET} : /turf/open/floor/plasteel/white/corner {@OLD}
|
||||
/turf/open/floor/plasteel/escape/corner {dir=2} : /turf/open/floor/plasteel/white/corner {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape/corner {dir=4} : /obj/effect/turf_decal/tile/red {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/escape/corner {dir=8} : /obj/effect/turf_decal/tile/red {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=1} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=@UNSET} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=2} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=4} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=5} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=6} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=8} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=9} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side {dir=10} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/corner : /obj/effect/turf_decal/tile/green {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/green/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenblue/side {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/greenyellow/side {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/hydrofloor : /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=1} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=@UNSET} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=2} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=4} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=5} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=6} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=8} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=9} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side {dir=10} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/corner : /obj/effect/turf_decal/tile/neutral {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/neutral/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/side {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/orange/corner : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=1} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=@UNSET} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=2} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=4} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=5} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=6} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=8} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=9} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/side {dir=10} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/purple/corner : /obj/effect/turf_decal/tile/purple {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/red/corner : /obj/effect/turf_decal/tile/red {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/redside {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redblue/blueside {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redgreen/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/redyellow/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/airless : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark/airless {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/snowdin : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark/snowdin {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/telecomms : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/telecomms/mainframe : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/killroom : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=1} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=@UNSET} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=2} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=4} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=5} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=6} : /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=8} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=9} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral {dir=4} , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/side {dir=10} : /obj/effect/turf_decal/tile/neutral {dir=1} , /obj/effect/turf_decal/tile/neutral , /obj/effect/turf_decal/tile/neutral {dir=8} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/vault/corner : /obj/effect/turf_decal/tile/neutral {dir=@OLD} , /turf/open/floor/plasteel/dark {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/corner : /obj/effect/turf_decal/tile/blue {dir=@OLD} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue {dir=4} , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteblue/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/blue {dir=1} , /obj/effect/turf_decal/tile/blue , /obj/effect/turf_decal/tile/blue {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=1} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=@UNSET} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=2} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=4} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=5} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=6} : /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=8} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=9} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green {dir=4} , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/side {dir=10} : /obj/effect/turf_decal/tile/green {dir=1} , /obj/effect/turf_decal/tile/green , /obj/effect/turf_decal/tile/green {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitegreen/corner : /obj/effect/turf_decal/tile/green {dir=@OLD} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=1} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=@UNSET} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=2} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=4} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=5} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=6} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=8} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=9} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side {dir=10} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/corner : /obj/effect/turf_decal/tile/purple {dir=@OLD} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=1} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=@UNSET} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=2} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=4} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=5} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=6} : /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=8} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=9} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple {dir=4} , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitepurple/side/telecomms {dir=10} : /obj/effect/turf_decal/tile/purple {dir=1} , /obj/effect/turf_decal/tile/purple , /obj/effect/turf_decal/tile/purple {dir=8} , /turf/open/floor/plasteel/white/telecomms {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=1} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=@UNSET} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=2} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=4} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=5} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=6} : /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=8} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=9} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red {dir=4} , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/side {dir=10} : /obj/effect/turf_decal/tile/red {dir=1} , /obj/effect/turf_decal/tile/red , /obj/effect/turf_decal/tile/red {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whitered/corner : /obj/effect/turf_decal/tile/red {dir=@OLD} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/side {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/whiteyellow/corner : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel/white {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=1} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=@UNSET} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=2} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=4} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=5} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=6} : /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=8} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=9} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow {dir=4} , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/side {dir=10} : /obj/effect/turf_decal/tile/yellow {dir=1} , /obj/effect/turf_decal/tile/yellow , /obj/effect/turf_decal/tile/yellow {dir=8} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
/turf/open/floor/plasteel/yellow/corner : /obj/effect/turf_decal/tile/yellow {dir=@OLD} , /turf/open/floor/plasteel {@OLD;dir=@SKIP}
|
||||
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import dmi
|
||||
|
||||
def images_equal(left, right):
|
||||
if left.size != right.size:
|
||||
return False
|
||||
w, h = left.size
|
||||
left_load, right_load = left.load(), right.load()
|
||||
for y in range(0, h):
|
||||
for x in range(0, w):
|
||||
lpixel, rpixel = left_load[x, y], right_load[x, y]
|
||||
# quietly ignore changes where both pixels are fully transparent
|
||||
if lpixel != rpixel and (lpixel[3] != 0 or rpixel[3] != 0):
|
||||
return False
|
||||
return True
|
||||
|
||||
def states_equal(left, right):
|
||||
result = True
|
||||
|
||||
# basic properties
|
||||
for attr in ('loop', 'rewind', 'movement', 'dirs', 'delays', 'hotspots', 'framecount'):
|
||||
lval, rval = getattr(left, attr), getattr(right, attr)
|
||||
if lval != rval:
|
||||
result = False
|
||||
|
||||
# frames
|
||||
for (left_frame, right_frame) in zip(left.frames, right.frames):
|
||||
if not images_equal(left_frame, right_frame):
|
||||
result = False
|
||||
|
||||
return result
|
||||
|
||||
def key_of(state):
|
||||
return (state.name, state.movement)
|
||||
|
||||
def dictify(sheet):
|
||||
result = {}
|
||||
for state in sheet.states:
|
||||
k = key_of(state)
|
||||
if k in result:
|
||||
print(f" duplicate {k!r}")
|
||||
result[k] = state
|
||||
return result
|
||||
|
||||
def three_way_merge(base, left, right):
|
||||
base_dims = base.width, base.height
|
||||
if base_dims != (left.width, left.height) or base_dims != (right.width, right.height):
|
||||
print("Dimensions have changed:")
|
||||
print(f" Base: {base.width} x {base.height}")
|
||||
print(f" Ours: {left.width} x {left.height}")
|
||||
print(f" Theirs: {right.width} x {right.height}")
|
||||
return True, None
|
||||
|
||||
base_states, left_states, right_states = dictify(base), dictify(left), dictify(right)
|
||||
|
||||
new_left = {k: v for k, v in left_states.items() if k not in base_states}
|
||||
new_right = {k: v for k, v in right_states.items() if k not in base_states}
|
||||
new_both = {}
|
||||
conflicts = []
|
||||
for key, state in list(new_left.items()):
|
||||
in_right = new_right.get(key, None)
|
||||
if in_right:
|
||||
if states_equal(state, in_right):
|
||||
# allow it
|
||||
new_both[key] = state
|
||||
else:
|
||||
# generate conflict states
|
||||
print(f" C: {state.name!r}: added differently in both!")
|
||||
state.name = f"{state.name} !CONFLICT! left"
|
||||
conflicts.append(state)
|
||||
in_right.name = f"{state.name} !CONFLICT! right"
|
||||
conflicts.append(in_right)
|
||||
# don't add it a second time
|
||||
del new_left[key]
|
||||
del new_right[key]
|
||||
|
||||
final_states = []
|
||||
# add states that are currently in the base
|
||||
for state in base.states:
|
||||
in_left = left_states.get(key_of(state), None)
|
||||
in_right = right_states.get(key_of(state), None)
|
||||
left_equals = in_left and states_equal(state, in_left)
|
||||
right_equals = in_right and states_equal(state, in_right)
|
||||
|
||||
if not in_left and not in_right:
|
||||
# deleted in both left and right, it's just deleted
|
||||
print(f" {state.name!r}: deleted in both")
|
||||
elif not in_left:
|
||||
# left deletes
|
||||
print(f" {state.name!r}: deleted in left")
|
||||
if not right_equals:
|
||||
print(f" ... but modified in right")
|
||||
final_states.append(in_right)
|
||||
elif not in_right:
|
||||
# right deletes
|
||||
print(f" {state.name!r}: deleted in right")
|
||||
if not left_equals:
|
||||
print(f" ... but modified in left")
|
||||
final_states.append(in_left)
|
||||
elif left_equals and right_equals:
|
||||
# changed in neither
|
||||
#print(f"Same in both: {state.name!r}")
|
||||
final_states.append(state)
|
||||
elif left_equals:
|
||||
# changed only in right
|
||||
print(f" {state.name!r}: changed in left")
|
||||
final_states.append(in_right)
|
||||
elif right_equals:
|
||||
# changed only in left
|
||||
print(f" {state.name!r}: changed in right")
|
||||
final_states.append(in_left)
|
||||
elif states_equal(in_left, in_right):
|
||||
# changed in both, to the same thing
|
||||
print(f" {state.name!r}: changed same in both")
|
||||
final_states.append(in_left) # either or
|
||||
else:
|
||||
# changed in both
|
||||
name = state.name
|
||||
print(f" C: {name!r}: changed differently in both!")
|
||||
state.name = f"{name} !CONFLICT! base"
|
||||
conflicts.append(state)
|
||||
in_left.name = f"{name} !CONFLICT! left"
|
||||
conflicts.append(in_left)
|
||||
in_right.name = f"{name} !CONFLICT! right"
|
||||
conflicts.append(in_right)
|
||||
|
||||
# add states which both left and right added the same
|
||||
for key, state in new_both.items():
|
||||
print(f" {state.name!r}: added same in both")
|
||||
final_states.append(state)
|
||||
|
||||
# add states that are brand-new in the left
|
||||
for key, state in new_left.items():
|
||||
print(f" {state.name!r}: added in left")
|
||||
final_states.append(state)
|
||||
|
||||
# add states that are brand-new in the right
|
||||
for key, state in new_right.items():
|
||||
print(f" {state.name!r}: added in right")
|
||||
final_states.append(state)
|
||||
|
||||
final_states.extend(conflicts)
|
||||
merged = dmi.Dmi(base.width, base.height)
|
||||
merged.states = final_states
|
||||
return len(conflicts), merged
|
||||
|
||||
def main(path, original, left, right):
|
||||
print(f"Merging icon: {path}")
|
||||
|
||||
icon_orig = dmi.Dmi.from_file(original)
|
||||
icon_left = dmi.Dmi.from_file(left)
|
||||
icon_right = dmi.Dmi.from_file(right)
|
||||
|
||||
trouble, merged = three_way_merge(icon_orig, icon_left, icon_right)
|
||||
if merged:
|
||||
merged.to_file(left)
|
||||
if trouble:
|
||||
print("!!! Manual merge required!")
|
||||
if merged:
|
||||
print(" A best-effort merge was performed. You must edit the icon and remove all")
|
||||
print(" icon states marked with !CONFLICT!, leaving only the desired icon.")
|
||||
else:
|
||||
print(" The icon was totally unable to be merged, you must start with one version")
|
||||
print(" or the other and manually resolve the conflict.")
|
||||
print(" Information about which states conflicted is listed above.")
|
||||
return trouble
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 6:
|
||||
print("DMI merge driver called with wrong number of arguments")
|
||||
print(" usage: merge-driver-dmi %P %O %A %B %L")
|
||||
exit(1)
|
||||
|
||||
# "left" is also the file that ought to be overwritten
|
||||
_, path, original, left, right, conflict_size_marker = sys.argv
|
||||
exit(main(path, original, left, right))
|
||||
@@ -9,6 +9,13 @@ def main(repo):
|
||||
print("You need to resolve merge conflicts first.")
|
||||
return 1
|
||||
|
||||
try:
|
||||
repo.lookup_reference('MERGE_HEAD')
|
||||
print("Not running mapmerge for merge commit.")
|
||||
return 0
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
changed = 0
|
||||
for path, status in repo.status().items():
|
||||
if path.endswith(".dmm") and (status & (pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_INDEX_NEW)):
|
||||
@@ -20,12 +27,12 @@ def main(repo):
|
||||
head_blob = repo[repo[repo.head.target].tree[path].id]
|
||||
except KeyError:
|
||||
# New map, no entry in HEAD
|
||||
print(f"Converting new map: {path}")
|
||||
print(f"Converting new map: {path}", flush=True)
|
||||
assert (status & pygit2.GIT_STATUS_INDEX_NEW)
|
||||
merged_map = index_map
|
||||
else:
|
||||
# Entry in HEAD, merge the index over it
|
||||
print(f"Merging map: {path}")
|
||||
print(f"Merging map: {path}", flush=True)
|
||||
assert not (status & pygit2.GIT_STATUS_INDEX_NEW)
|
||||
head_map = dmm.DMM.from_bytes(head_blob.read_raw())
|
||||
merged_map = merge_map(index_map, head_map)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user