mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-28 14:37:04 +01:00
Merge remote-tracking branch 'upstream/master' into tail-markings
This commit is contained in:
@@ -8,8 +8,9 @@ var/global/nologevent = 0
|
||||
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message\">[msg]</span></span>"
|
||||
log_adminwarn(msg)
|
||||
for(var/client/C in admins)
|
||||
if(R_SERVER & C.holder.rights)
|
||||
to_chat(C, msg)
|
||||
if(R_ADMIN & C.holder.rights)
|
||||
if(C.prefs && !(C.prefs.toggles & CHAT_NO_ADMINLOGS))
|
||||
to_chat(C, msg)
|
||||
|
||||
/proc/msg_admin_attack(var/text) //Toggleable Attack Messages
|
||||
log_attack(text)
|
||||
|
||||
@@ -56,6 +56,7 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/show_player_notes,
|
||||
/client/proc/free_slot, /*frees slot for chosen job*/
|
||||
/client/proc/toggleattacklogs,
|
||||
/client/proc/toggleadminlogs,
|
||||
/client/proc/toggledebuglogs,
|
||||
/client/proc/update_mob_sprite,
|
||||
/client/proc/toggledrones,
|
||||
@@ -883,6 +884,20 @@ var/list/admin_verbs_snpc = list(
|
||||
else
|
||||
to_chat(usr, "You now won't get attack log messages")
|
||||
|
||||
/client/proc/toggleadminlogs()
|
||||
set name = "Toggle Admin Log Messages"
|
||||
set category = "Preferences"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
prefs.toggles ^= CHAT_NO_ADMINLOGS
|
||||
prefs.save_preferences(src)
|
||||
if(prefs.toggles & CHAT_NO_ADMINLOGS)
|
||||
to_chat(usr, "You now won't get admin log messages.")
|
||||
else
|
||||
to_chat(usr, "You now will get admin log messages.")
|
||||
|
||||
/client/proc/toggledrones()
|
||||
set name = "Toggle Maintenance Drones"
|
||||
set category = "Server"
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
qdel(I)
|
||||
|
||||
/obj/effect/buildmode_line
|
||||
var/image/I
|
||||
var/image/I
|
||||
var/client/cl
|
||||
|
||||
/obj/effect/buildmode_line/New(var/client/c, var/atom/atom_a, var/atom/atom_b, var/linename)
|
||||
@@ -101,13 +101,13 @@
|
||||
I = image('icons/misc/mark.dmi', src, "line", 19.0)
|
||||
var/x_offset = ((atom_b.x * 32) + atom_b.pixel_x) - ((atom_a.x * 32) + atom_a.pixel_x)
|
||||
var/y_offset = ((atom_b.y * 32) + atom_b.pixel_y) - ((atom_a.y * 32) + atom_a.pixel_y)
|
||||
|
||||
|
||||
var/matrix/M = matrix()
|
||||
M.Translate(0, 16)
|
||||
M.Scale(1, sqrt((x_offset * x_offset) + (y_offset * y_offset)) / 32)
|
||||
M.Turn(90 - Atan2(x_offset, y_offset)) // So... You pass coords in order x,y to this version of atan2. It should be called acsc2.
|
||||
M.Translate(atom_a.pixel_x, atom_a.pixel_y)
|
||||
|
||||
|
||||
transform = M
|
||||
cl = c
|
||||
cl.images += I
|
||||
@@ -242,6 +242,7 @@
|
||||
if(FILL_BUILDMODE)
|
||||
to_chat(user, "<span class='notice'>***********************************************************</span>")
|
||||
to_chat(user, "<span class='notice'>Left Mouse Button on turf/obj/mob = Select corner</span>")
|
||||
to_chat(user, "<span class='notice'>Left Mouse Button + Alt on turf/obj/mob = Delete region</span>")
|
||||
to_chat(user, "<span class='notice'>Right Mouse Button on buildmode button = Select object type</span>")
|
||||
to_chat(user, "<span class='notice'>***********************************************************</span>")
|
||||
if(LINK_BUILDMODE)
|
||||
@@ -509,16 +510,20 @@
|
||||
cornerB = select_tile(get_turf(object))
|
||||
if(left_click) //rectangular
|
||||
if(cornerA && cornerB)
|
||||
if(!objholder)
|
||||
to_chat(user, "<span class='warning'>Select object type first.</span>")
|
||||
if(alt_click)
|
||||
empty_region(block(get_turf(cornerA),get_turf(cornerB)))
|
||||
deselect_region()
|
||||
else
|
||||
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
|
||||
if(ispath(objholder,/turf))
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.dir = build_dir
|
||||
deselect_region()
|
||||
if(!objholder)
|
||||
to_chat(user, "<span class='warning'>Select object type first.</span>")
|
||||
else
|
||||
for(var/turf/T in block(get_turf(cornerA),get_turf(cornerB)))
|
||||
if(ispath(objholder,/turf))
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.dir = build_dir
|
||||
deselect_region()
|
||||
return
|
||||
|
||||
//Something wrong - Reset
|
||||
@@ -567,13 +572,13 @@
|
||||
if(P.id_tag && P.id_tag != 1 && alert(holder, "Warning: This will unlink something else from the door. Continue?", "Buildmode", "Yes", "No") == "No")
|
||||
goto(line_jump)
|
||||
P.id_tag = M.id
|
||||
|
||||
|
||||
line_jump // For the goto
|
||||
valid_links = 0
|
||||
for(var/obj/effect/buildmode_line/L in link_lines)
|
||||
qdel(L)
|
||||
link_lines -= L
|
||||
|
||||
|
||||
if(istype(link_obj, /obj/machinery/door_control))
|
||||
var/obj/machinery/door_control/M = link_obj
|
||||
for(var/obj/machinery/door/airlock/P in range(M.range,M))
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
<A href='?src=\ref[src];secretsfun=securitylevel3'>Security Level - Gamma</A>
|
||||
<A href='?src=\ref[src];secretsfun=securitylevel4'>Security Level - Epsilon</A>
|
||||
<A href='?src=\ref[src];secretsfun=securitylevel5'>Security Level - Delta</A><BR>
|
||||
<b>Create Weather</b><BR>
|
||||
<A href='?src=\ref[src];secretsfun=weatherashstorm'>Weather - Ash Storm</A>
|
||||
<A href='?src=\ref[src];secretsfun=weatherdarkness'>Weather - Advanced Darkness</A>
|
||||
<BR>
|
||||
</center>"}
|
||||
|
||||
@@ -104,6 +107,7 @@
|
||||
<A href='?src=\ref[src];secretsfun=onlyoneteam'>Dodgeball (TDM)!</A><BR>
|
||||
<b>Round-enders</b><br>
|
||||
<A href='?src=\ref[src];secretsfun=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=fakelava'>The floor is fake-lava! (non-harmful)</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=monkey'>Turn all humans into monkeys</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=fakeguns'>Make all items look like guns</A><BR>
|
||||
<A href='?src=\ref[src];secretsfun=prisonwarp'>Warp all Players to Prison</A><BR>
|
||||
|
||||
+29
-52
@@ -2548,60 +2548,37 @@
|
||||
L.fix()
|
||||
message_admins("[key_name_admin(usr)] fixed all lights", 1)
|
||||
if("floorlava")
|
||||
if(floorIsLava)
|
||||
to_chat(usr, "The floor is lava already.")
|
||||
feedback_inc("admin_secrets_fun_used", 1)
|
||||
feedback_add_details("admin_secrets_fun_used", "LF")
|
||||
var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No")
|
||||
if(sure == "No")
|
||||
return
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","LF")
|
||||
|
||||
//Options
|
||||
var/length = input(usr, "How long will the lava last? (in seconds)", "Length", 180) as num
|
||||
length = min(abs(length), 1200)
|
||||
|
||||
var/damage = input(usr, "How deadly will the lava be?", "Damage", 2) as num
|
||||
damage = min(abs(damage), 100)
|
||||
|
||||
var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "YES!", "Nah")
|
||||
if(sure == "Nah")
|
||||
weather_master.run_weather("the floor is lava")
|
||||
message_admins("[key_name_admin(usr)] made the floor lava")
|
||||
if("fakelava")
|
||||
feedback_inc("admin_secrets_fun_used", 1)
|
||||
feedback_add_details("admin_secrets_fun_used", "LZ")
|
||||
var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No")
|
||||
if(sure == "No")
|
||||
return
|
||||
floorIsLava = 1
|
||||
|
||||
message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.", 1)
|
||||
|
||||
for(var/turf/simulated/floor/F in world)
|
||||
if((F.z in config.station_levels))
|
||||
F.name = "lava"
|
||||
F.desc = "The floor is LAVA!"
|
||||
F.overlays += "lava"
|
||||
F.lava = 1
|
||||
|
||||
spawn(0)
|
||||
for(var/i = i, i < length, i++) // 180 = 3 minutes
|
||||
if(damage)
|
||||
for(var/mob/living/carbon/L in living_mob_list)
|
||||
if(istype(L.loc, /turf/simulated/floor)) // Are they on LAVA?!
|
||||
var/turf/simulated/floor/F = L.loc
|
||||
if(F.lava)
|
||||
var/safe = 0
|
||||
for(var/obj/structure/O in F.contents)
|
||||
if(O.level > F.level && !istype(O, /obj/structure/window)) // Something to stand on and it isn't under the floor!
|
||||
safe = 1
|
||||
break
|
||||
if(!safe)
|
||||
L.adjustFireLoss(damage)
|
||||
|
||||
|
||||
sleep(10)
|
||||
|
||||
for(var/turf/simulated/floor/F in world) // Reset everything.
|
||||
if((F.z in config.station_levels))
|
||||
F.name = initial(F.name)
|
||||
F.desc = initial(F.desc)
|
||||
F.overlays.Cut()
|
||||
F.lava = 0
|
||||
F.update_icon()
|
||||
floorIsLava = 0
|
||||
return
|
||||
weather_master.run_weather("fake lava")
|
||||
message_admins("[key_name_admin(usr)] made aesthetic lava on the floor")
|
||||
if("weatherashstorm")
|
||||
feedback_inc("admin_secrets_fun_used", 1)
|
||||
feedback_add_details("admin_secrets_fun_used", "WA")
|
||||
var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No")
|
||||
if(sure == "No")
|
||||
return
|
||||
weather_master.run_weather("ash storm")
|
||||
message_admins("[key_name_admin(usr)] spawned an ash storm on the mining asteroid")
|
||||
if("weatherdarkness")
|
||||
feedback_inc("admin_secrets_fun_used", 1)
|
||||
feedback_add_details("admin_secrets_fun_used", "WD")
|
||||
var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No")
|
||||
if(sure == "No")
|
||||
return
|
||||
weather_master.run_weather("advanced darkness")
|
||||
message_admins("[key_name_admin(usr)] made the station go through advanced darkness")
|
||||
if("retardify")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","RET")
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
admin_forcemove(usr, T)
|
||||
log_admin("[key_name(usr)] jumped to [A]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [A]")
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to [A]")
|
||||
feedback_add_details("admin_verb","JA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/jumptoturf(var/turf/T in world)
|
||||
@@ -35,7 +36,8 @@
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]", 1)
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to [T.x], [T.y], [T.z] in [T.loc]", 1)
|
||||
admin_forcemove(usr, T)
|
||||
feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -48,7 +50,8 @@
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] jumped to [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
if(src.mob)
|
||||
var/mob/A = src.mob
|
||||
var/turf/T = get_turf(M)
|
||||
@@ -69,7 +72,8 @@
|
||||
if(T)
|
||||
admin_forcemove(usr, T)
|
||||
feedback_add_details("admin_verb","JC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
|
||||
|
||||
/client/proc/jumptokey()
|
||||
set category = "Admin"
|
||||
@@ -87,7 +91,8 @@
|
||||
return
|
||||
var/mob/M = selection:mob
|
||||
log_admin("[key_name(usr)] jumped to [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
if(!isobserver(usr))
|
||||
message_admins("[key_name_admin(usr)] jumped to [key_name_admin(M)]", 1)
|
||||
|
||||
admin_forcemove(usr, M.loc)
|
||||
|
||||
|
||||
@@ -843,7 +843,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
sec_briefcase.contents += new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow
|
||||
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba
|
||||
sec_briefcase.contents += new /obj/item/ammo_box/a357
|
||||
sec_briefcase.contents += new /obj/item/weapon/c4
|
||||
sec_briefcase.contents += new /obj/item/weapon/grenade/plastic/c4
|
||||
M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
|
||||
|
||||
var/obj/item/device/pda/heads/pda = new(M)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/client/proc/map_template_load()
|
||||
set category = "Debug"
|
||||
set name = "Map Template - Place"
|
||||
set name = "Map template - Place"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/datum/map_template/template
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in map_templates
|
||||
@@ -16,22 +15,27 @@
|
||||
if(!T)
|
||||
return
|
||||
|
||||
if(!template.fits_in_map_bounds(T, centered = TRUE))
|
||||
to_chat(usr, "Map is too large to fit in bounds. Map's dimensions: ([template.width], [template.height])")
|
||||
return
|
||||
|
||||
var/list/preview = list()
|
||||
for(var/S in template.get_affected_turfs(T,centered = TRUE))
|
||||
preview += image('icons/turf/overlays.dmi',S,"greenOverlay")
|
||||
usr.client.images += preview
|
||||
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
template.load(T, centered = TRUE)
|
||||
message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</A>")
|
||||
var/timer = start_watch()
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has started to place the map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a></span>")
|
||||
if(template.load(T, centered = TRUE))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a>. Took [stop_watch(timer)]s.</span>")
|
||||
else
|
||||
to_chat(usr, "Failed to place map")
|
||||
usr.client.images -= preview
|
||||
|
||||
/client/proc/map_template_upload()
|
||||
set category = "Debug"
|
||||
set name = "Map Template - Upload"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
|
||||
if(!map)
|
||||
return
|
||||
@@ -39,7 +43,12 @@
|
||||
to_chat(usr, "Bad map file: [map]")
|
||||
return
|
||||
|
||||
var/timer = start_watch()
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has begun uploading a map template ([map])</span>")
|
||||
var/datum/map_template/M = new(map=map, rename="[map]")
|
||||
M.preload_size(map)
|
||||
map_templates[M.name] = M
|
||||
message_admins("[key_name_admin(usr)] has uploaded a map template ([map])")
|
||||
if(M.preload_size(map))
|
||||
to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])")
|
||||
map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map]). Took [stop_watch(timer)]s.</span>")
|
||||
else
|
||||
to_chat(usr, "Map template '[map]' failed to load properly")
|
||||
|
||||
@@ -144,7 +144,7 @@ var/global/sent_strike_team = 0
|
||||
equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
|
||||
if(!leader_selected)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
|
||||
else
|
||||
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack)
|
||||
|
||||
@@ -148,10 +148,10 @@ var/global/sent_syndicate_strike_team = 0
|
||||
|
||||
equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m45(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack)
|
||||
if(!syndicate_leader_selected)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/c4(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/grenade/plastic/x4(src), slot_in_backpack)
|
||||
equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_in_backpack)
|
||||
else
|
||||
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack)
|
||||
|
||||
@@ -76,7 +76,9 @@
|
||||
var/dat = text("<TT><B>Health Sensor</B> <A href='?src=\ref[src];scanning=1'>[scanning?"On":"Off"]</A>")
|
||||
if(scanning && health_scan)
|
||||
dat += "<BR>Health: [health_scan]"
|
||||
user << browse(dat, "window=hscan")
|
||||
var/datum/browser/popup = new(user, "hscan", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "hscan")
|
||||
return
|
||||
|
||||
|
||||
@@ -139,7 +139,9 @@
|
||||
</TT>
|
||||
<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>
|
||||
<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"}
|
||||
user << browse(dat, "window=infra")
|
||||
var/datum/browser/popup = new(user, "infra", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "infra")
|
||||
|
||||
/obj/item/device/assembly/infra/Topic(href, href_list)
|
||||
|
||||
@@ -114,7 +114,9 @@
|
||||
dat += "<BR><A href='?src=\ref[src];scanning=1'>[scanning?"Armed":"Unarmed"]</A> (Movement sensor active when armed!)"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];refresh=1'>Refresh</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
user << browse(dat, "window=prox")
|
||||
var/datum/browser/popup = new(user, "prox", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "prox")
|
||||
return
|
||||
|
||||
|
||||
@@ -81,7 +81,9 @@
|
||||
[t1]
|
||||
</TT>
|
||||
"}
|
||||
user << browse(dat, "window=radio")
|
||||
var/datum/browser/popup = new(user, "radio", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
|
||||
@@ -96,7 +96,9 @@
|
||||
<A href='?src=\ref[src];refresh=1'>Refresh</A>
|
||||
<BR><BR>
|
||||
<A href='?src=\ref[src];close=1'>Close</A>"}
|
||||
user << browse(dat, "window=timer")
|
||||
var/datum/browser/popup = new(user, "timer", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "timer")
|
||||
return
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
/obj/effect/landmark/corpse
|
||||
name = "Unknown"
|
||||
var/mobname = "Unknown" //Unused now but it'd fuck up maps to remove it now
|
||||
var/mob_species = null //Set to make a mob of another race, currently used only in ruins
|
||||
var/corpseuniform = null //Set this to an object path to have the slot filled with said object on the corpse.
|
||||
var/corpsesuit = null
|
||||
var/corpseshoes = null
|
||||
@@ -37,6 +38,8 @@
|
||||
M.real_name = src.name
|
||||
M.death(1) //Kills the new mob
|
||||
M.timeofdeath = timeofdeath
|
||||
if(src.mob_species)
|
||||
M.set_species(src.mob_species)
|
||||
if(src.corpseuniform)
|
||||
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
|
||||
if(src.corpsesuit)
|
||||
@@ -285,3 +288,10 @@
|
||||
corpseid = 1
|
||||
corpseidjob = "Commander"
|
||||
corpseidaccess = "Captain"
|
||||
|
||||
/obj/effect/landmark/corpse/abductor //Connected to ruins, for some reason?
|
||||
name = "abductor"
|
||||
mobname = "???"
|
||||
mob_species = "abductor"
|
||||
corpseuniform = /obj/item/clothing/under/color/grey
|
||||
corpseshoes = /obj/item/clothing/shoes/combat
|
||||
|
||||
@@ -9,30 +9,43 @@
|
||||
var/template_name = null
|
||||
var/datum/map_template/template = null
|
||||
var/centered = 1
|
||||
var/loaded = 0
|
||||
|
||||
/obj/effect/landmark/map_loader/New(loc, tname)
|
||||
/obj/effect/landmark/map_loader/New(turf/loc, tname)
|
||||
..()
|
||||
|
||||
if(tname)
|
||||
template_name = tname
|
||||
if(template_name)
|
||||
template = map_templates[template_name]
|
||||
|
||||
/obj/effect/landmark/map_loader/initialize()
|
||||
..()
|
||||
if(template)
|
||||
load(template)
|
||||
|
||||
/obj/effect/landmark/map_loader/set_tag()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/map_loader/proc/load(datum/map_template/t)
|
||||
spawn(1)
|
||||
if(!t)
|
||||
return
|
||||
t.load(get_turf(src), centered = centered)
|
||||
t.loaded++
|
||||
qdel(src)
|
||||
if(!t)
|
||||
return
|
||||
if(loaded) // I wanna be super sure this loads only once
|
||||
return
|
||||
loaded = 1
|
||||
var/turf/pos = get_turf(src)
|
||||
// Hop to nullspace so we don't get re-initialized by the map we're loading
|
||||
loc = null
|
||||
t.load(pos, centered = centered)
|
||||
t.loaded++
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/map_loader/random
|
||||
var/template_list = ""
|
||||
|
||||
/obj/effect/landmark/map_loader/random/New()
|
||||
/obj/effect/landmark/map_loader/random/initialize()
|
||||
..()
|
||||
if(template_list)
|
||||
template_name = safepick(splittext(template_list, ";"))
|
||||
template = map_templates[template_name]
|
||||
load(template)
|
||||
load(template)
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
//SS13 Optimized Map loader
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//As of 3.6.2016
|
||||
//global datum that will preload variables on atoms instanciation
|
||||
var/global/use_preloader = FALSE
|
||||
var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite
|
||||
// These regexes are global - meaning that starting the maploader again mid-load will
|
||||
// reset progress - which means we need to track our index per-map, or we'll
|
||||
// eternally recurse
|
||||
// /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g
|
||||
var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g")
|
||||
// /^[\s\n]+"?|"?[\s\n]+$|^"|"$/g
|
||||
var/static/regex/trimQuotesRegex = new/regex({"^\[\\s\n]+"?|"?\[\\s\n]+$|^"|"$"}, "g")
|
||||
// /^[\s\n]+|[\s\n]+$/
|
||||
var/static/regex/trimRegex = new/regex("^\[\\s\n]+|\[\\s\n]+$", "g")
|
||||
var/static/list/modelCache = list()
|
||||
|
||||
/**
|
||||
* Construct the model map and control the loading process
|
||||
@@ -16,87 +28,156 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* e.g aa = /turf/unsimulated/wall{icon_state = "rock"}
|
||||
* 2) Read the map line by line, parsing the result (using parse_grid)
|
||||
*
|
||||
* If `measureOnly` is set, then no atoms will be created, and all this will do
|
||||
* is return the bounds after parsing the file
|
||||
*
|
||||
* If you need to freeze init while you're working, you can use the spacial allocator's
|
||||
* "add_dirt" and "remove_dirt" which will put initializations on hold until you say
|
||||
* the word. This is important for loading large maps such as the cyberiad, where
|
||||
* atmos will attempt to start before it's ready, causing runtimes galore if init is
|
||||
* allowed to romp unchecked.
|
||||
*/
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset = 0 as num, y_offset = 0 as num, z_offset as num, do_sleep = 1 as num)
|
||||
if(!z_offset)//what z_level we are creating the map on
|
||||
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num)
|
||||
var/tfile = dmm_file//the map file we're creating
|
||||
var/fname = "Lambda"
|
||||
if(isfile(tfile))
|
||||
fname = "[tfile]"
|
||||
tfile = file2text(tfile)
|
||||
|
||||
if(!x_offset)
|
||||
x_offset = 1
|
||||
if(!y_offset)
|
||||
y_offset = 1
|
||||
if(!z_offset)
|
||||
z_offset = world.maxz + 1
|
||||
|
||||
var/quote = ascii2text(34)
|
||||
var/tfile = file2text(dmm_file)//the map file we're creating
|
||||
var/tfile_len = length(tfile)
|
||||
var/lpos = 1 // the models definition index
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//first let's map model keys (e.g "aa") to their contents (e.g /turf/space{variables})
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
|
||||
var/list/grid_models = list()
|
||||
var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))//the length of the model key (e.g "aa" or "aba")
|
||||
var/key_len = 0
|
||||
|
||||
//proceed line by line
|
||||
for(lpos=1; lpos<tfile_len; lpos=findtext(tfile,"\n",lpos,0)+1)
|
||||
var/tline = copytext(tfile,lpos,findtext(tfile,"\n",lpos,0))
|
||||
if(copytext(tline,1,2) != quote)//we reached the map "layout"
|
||||
break
|
||||
var/model_key = copytext(tline,2,2+key_len)
|
||||
var/model_contents = copytext(tline,findtext(tfile,"=")+3,length(tline))
|
||||
grid_models[model_key] = model_contents
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//now let's fill the map with turf and objects using the constructed model map
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//position of the currently processed square
|
||||
var/zcrd=-1
|
||||
var/ycrd=y_offset
|
||||
var/xcrd=x_offset
|
||||
var/dmm_suite/loaded_map/LM = new
|
||||
// This try-catch is used as a budget "Finally" clause, as the dirt count
|
||||
// needs to be reset
|
||||
var/watch = start_watch()
|
||||
log_debug("[measureOnly ? "Measuring" : "Loading"] map: [fname]")
|
||||
try
|
||||
LM.index = 1
|
||||
while(dmmRegex.Find(tfile, LM.index))
|
||||
LM.index = dmmRegex.next
|
||||
|
||||
for(var/zpos=findtext(tfile,"\n(1,1,",lpos,0);zpos!=0;zpos=findtext(tfile,"\n(1,1,",zpos+1,0)) //in case there's several maps to load
|
||||
// "aa" = (/type{vars=blah})
|
||||
if(dmmRegex.group[1]) // Model
|
||||
var/key = dmmRegex.group[1]
|
||||
if(grid_models[key]) // Duplicate model keys are ignored in DMMs
|
||||
continue
|
||||
if(key_len != length(key))
|
||||
if(!key_len)
|
||||
key_len = length(key)
|
||||
else
|
||||
throw EXCEPTION("Inconsistant key length in DMM")
|
||||
if(!measureOnly)
|
||||
grid_models[key] = dmmRegex.group[2]
|
||||
|
||||
zcrd++
|
||||
world.maxz = max(world.maxz, zcrd+z_offset)//create a new z_level if needed
|
||||
// (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
|
||||
else if(dmmRegex.group[3]) // Coords
|
||||
if(!key_len)
|
||||
throw EXCEPTION("Coords before model definition in DMM")
|
||||
|
||||
var/zgrid = copytext(tfile,findtext(tfile,quote+"\n",zpos,0)+2,findtext(tfile,"\n"+quote,zpos,0)+1) //copy the whole map grid
|
||||
var/z_depth = length(zgrid)
|
||||
var/xcrdStart = text2num(dmmRegex.group[3]) + x_offset - 1
|
||||
//position of the currently processed square
|
||||
var/xcrd
|
||||
var/ycrd = text2num(dmmRegex.group[4]) + y_offset - 1
|
||||
var/zcrd = text2num(dmmRegex.group[5]) + z_offset - 1
|
||||
|
||||
//if exceeding the world max x or y, increase it
|
||||
var/x_depth = length(copytext(zgrid,1,findtext(zgrid,"\n",2,0)))
|
||||
var/x_tilecount = x_depth/key_len
|
||||
if(world.maxx<x_tilecount)
|
||||
world.maxx=x_tilecount
|
||||
if(!measureOnly)
|
||||
if(zcrd > world.maxz)
|
||||
if(cropMap)
|
||||
continue
|
||||
else
|
||||
zlevels.increase_max_zlevel_to(zcrd) //create a new z_level if needed
|
||||
|
||||
var/y_depth = z_depth / (x_depth+1)//x_depth + 1 because we're counting the '\n' characters in z_depth
|
||||
if(world.maxy<y_depth)
|
||||
world.maxy=y_depth
|
||||
bounds[MAP_MINX] = min(bounds[MAP_MINX], xcrdStart)
|
||||
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], zcrd)
|
||||
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], zcrd)
|
||||
|
||||
//then proceed it line by line, starting from top
|
||||
ycrd = y_depth
|
||||
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
|
||||
|
||||
for(var/gpos=1;gpos!=0;gpos=findtext(zgrid,"\n",gpos,0)+1)
|
||||
var/grid_line = copytext(zgrid,gpos,findtext(zgrid,"\n",gpos,0))
|
||||
var/leadingBlanks = 0
|
||||
while(leadingBlanks < gridLines.len && gridLines[++leadingBlanks] == "")
|
||||
if(leadingBlanks > 1)
|
||||
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
|
||||
|
||||
//fill the current square using the model map
|
||||
xcrd=0
|
||||
if(!gridLines.len) // Skip it if only blank lines exist.
|
||||
continue
|
||||
|
||||
for(var/mpos in 1 to x_depth step key_len)
|
||||
xcrd++
|
||||
var/model_key = copytext(grid_line,mpos,mpos+key_len)
|
||||
parse_grid(grid_models[model_key], xcrd + x_offset, ycrd + y_offset, zcrd + z_offset, do_sleep)
|
||||
if(gridLines.len && gridLines[gridLines.len] == "")
|
||||
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
|
||||
|
||||
//reached end of current map
|
||||
if(gpos+x_depth+1>z_depth)
|
||||
break
|
||||
bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd)
|
||||
ycrd += gridLines.len - 1 // Start at the top and work down
|
||||
|
||||
ycrd--
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
if(!cropMap && ycrd > world.maxy)
|
||||
if(!measureOnly)
|
||||
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd)
|
||||
else
|
||||
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], min(ycrd, world.maxy))
|
||||
|
||||
//reached End Of File
|
||||
if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len)
|
||||
break
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
var/maxx = xcrdStart
|
||||
if(measureOnly)
|
||||
for(var/line in gridLines)
|
||||
maxx = max(maxx, xcrdStart + length(line) / key_len - 1)
|
||||
else
|
||||
for(var/line in gridLines)
|
||||
if(ycrd <= world.maxy && ycrd >= 1)
|
||||
xcrd = xcrdStart
|
||||
for(var/tpos = 1 to length(line) - key_len + 1 step key_len)
|
||||
if(xcrd > world.maxx)
|
||||
if(cropMap)
|
||||
break
|
||||
else
|
||||
world.maxx = xcrd
|
||||
|
||||
if(xcrd >= 1)
|
||||
var/model_key = copytext(line, tpos, tpos + key_len)
|
||||
if(!grid_models[model_key])
|
||||
throw EXCEPTION("Undefined model key in DMM: [model_key]. Map file: [fname].")
|
||||
parse_grid(grid_models[model_key], xcrd, ycrd, zcrd, LM)
|
||||
// After this call, it is NOT safe to reference `dmmRegex` without another call to
|
||||
// "Find" - we might've hit a map loader here and changed its state
|
||||
CHECK_TICK
|
||||
|
||||
maxx = max(maxx, xcrd)
|
||||
++xcrd
|
||||
--ycrd
|
||||
|
||||
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx)
|
||||
|
||||
CHECK_TICK
|
||||
catch(var/exception/e)
|
||||
_preloader.reset()
|
||||
throw e
|
||||
|
||||
_preloader.reset()
|
||||
log_debug("Loaded map in [stop_watch(watch)]s.")
|
||||
qdel(LM)
|
||||
if(bounds[MAP_MINX] == 1.#INF) // Shouldn't need to check every item
|
||||
log_debug("Min x: bounds[MAP_MINX]")
|
||||
log_debug("Min y: bounds[MAP_MINY]")
|
||||
log_debug("Min z: bounds[MAP_MINZ]")
|
||||
log_debug("Max x: bounds[MAP_MAXX]")
|
||||
log_debug("Max y: bounds[MAP_MAXY]")
|
||||
log_debug("Max z: bounds[MAP_MAXZ]")
|
||||
return null
|
||||
else
|
||||
if(!measureOnly)
|
||||
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
|
||||
var/turf/T = t
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(1,keep_cabling = TRUE)
|
||||
return bounds
|
||||
|
||||
/**
|
||||
* Fill a given tile with its area/turf/objects/mobs
|
||||
@@ -115,48 +196,60 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
* 4) Instanciates the atom with its variables
|
||||
*
|
||||
*/
|
||||
/dmm_suite/proc/parse_grid(model as text, xcrd as num, ycrd as num, zcrd as num, do_sleep = 1)
|
||||
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num, dmm_suite/loaded_map/LM)
|
||||
/*Method parse_grid()
|
||||
- Accepts a text string containing a comma separated list of type paths of the
|
||||
same construction as those contained in a .dmm file, and instantiates them.
|
||||
*/
|
||||
|
||||
var/list/members = list()//will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes = list()//will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/members //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
|
||||
var/list/members_attributes //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
|
||||
var/list/cached = modelCache[model]
|
||||
var/index
|
||||
|
||||
if(cached)
|
||||
members = cached[1]
|
||||
members_attributes = cached[2]
|
||||
else
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//Constructing members and corresponding variables lists
|
||||
////////////////////////////////////////////////////////
|
||||
members = list()
|
||||
members_attributes = list()
|
||||
index = 1
|
||||
|
||||
var/index=1
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
var/old_position = 1
|
||||
var/dpos
|
||||
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos= find_next_delimiter_position(model,old_position,",","{","}")//find next delimiter (comma here) that's not within {...}
|
||||
do
|
||||
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
|
||||
dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...}
|
||||
|
||||
var/full_def = copytext(model,old_position,dpos)//full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))//path definition, e.g /obj/foo/bar
|
||||
members.Add(atom_def)
|
||||
old_position = dpos + 1
|
||||
var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp}
|
||||
var/variables_start = findtext(full_def, "{")
|
||||
var/atom_def = text2path(trim_text(copytext(full_def, 1, variables_start))) //path definition, e.g /obj/foo/bar
|
||||
old_position = dpos + 1
|
||||
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
|
||||
continue
|
||||
members.Add(atom_def)
|
||||
|
||||
var/variables_start = findtext(full_def,"{")
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
|
||||
var/list/fields = list()
|
||||
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
if(variables_start)//if there's any variable
|
||||
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
|
||||
fields = readlist(full_def, ";")
|
||||
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
while(dpos != 0)
|
||||
//then fill the members_attributes list with the corresponding variables
|
||||
members_attributes.len++
|
||||
members_attributes[index++] = fields
|
||||
|
||||
CHECK_TICK
|
||||
while(dpos != 0)
|
||||
|
||||
modelCache[model] = list(members, members_attributes)
|
||||
|
||||
|
||||
////////////////
|
||||
@@ -165,24 +258,25 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
|
||||
//in case of multiples turfs on one tile,
|
||||
//will contains the images of all underlying turfs, to simulate the DMM multiple tiles piling
|
||||
var/list/turfs_underlays = list()
|
||||
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
|
||||
var/turf/crds = locate(xcrd,ycrd,zcrd)
|
||||
if(members[index] != /area/template_noop)
|
||||
// We assume `members[index]` is an area path, as above, yes? I will operate
|
||||
// on that assumption.
|
||||
if(!ispath(members[index], /area))
|
||||
throw EXCEPTION("Oh no, I thought this was an area!")
|
||||
|
||||
var/atom/instance
|
||||
_preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation
|
||||
instance = LM.area_path_to_real_area(members[index])
|
||||
|
||||
instance = locate(members[index])
|
||||
var/turf/crds = locate(xcrd,ycrd,zcrd)
|
||||
if(crds)
|
||||
instance.contents.Add(crds)
|
||||
|
||||
if(use_preloader && instance)
|
||||
_preloader.load(instance)
|
||||
members.Remove(members[index])
|
||||
|
||||
//then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect
|
||||
|
||||
@@ -198,18 +292,20 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
if(T)
|
||||
//if others /turf are presents, simulates the underlays piling effect
|
||||
index = first_turf_index + 1
|
||||
while(index <= members.len)
|
||||
turfs_underlays.Insert(1,image(T.icon,null,T.icon_state,T.layer,T.dir))//add the current turf image to the underlays list
|
||||
var/turf/UT = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
add_underlying_turf(UT,T,turfs_underlays)//simulates the DMM piling effect
|
||||
T = UT
|
||||
while(index <= members.len - 1) // Last item is an /area
|
||||
var/underlay
|
||||
if(istype(T, /turf)) // I blame this on the stupid clown who coded the BYOND map editor
|
||||
underlay = T.appearance
|
||||
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
|
||||
if(ispath(members[index],/turf))
|
||||
T.underlays += underlay
|
||||
|
||||
index++
|
||||
|
||||
//finally instance all remainings objects/mobs
|
||||
for(index in 1 to first_turf_index - 1)
|
||||
for(index in 1 to first_turf_index-1)
|
||||
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)
|
||||
if(do_sleep)
|
||||
sleep(-1)
|
||||
CHECK_TICK
|
||||
|
||||
////////////////
|
||||
//Helpers procs
|
||||
@@ -222,7 +318,13 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
var/turf/T = locate(x,y,z)
|
||||
if(T)
|
||||
instance = new path (T)//first preloader pass
|
||||
if(ispath(path, /turf))
|
||||
T.ChangeTurf(path, 1, 0)
|
||||
instance = T
|
||||
else if(ispath(path, /area))
|
||||
|
||||
else
|
||||
instance = new path (T)//first preloader pass
|
||||
|
||||
if(use_preloader && instance)//second preloader pass, for those atoms that don't ..() in New()
|
||||
_preloader.load(instance)
|
||||
@@ -232,16 +334,11 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//text trimming (both directions) helper proc
|
||||
//optionally removes quotes before and after the text (for variable name)
|
||||
/dmm_suite/proc/trim_text(what as text,trim_quotes=0)
|
||||
while(length(what) && (findtext(what," ",1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what," ",length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
if(trim_quotes)
|
||||
while(length(what) && (findtext(what,quote,1,2)))
|
||||
what=copytext(what,2,0)
|
||||
while(length(what) && (findtext(what,quote,length(what),0)))
|
||||
what=copytext(what,1,length(what))
|
||||
return what
|
||||
return trimQuotesRegex.Replace(what, "")
|
||||
else
|
||||
return trimRegex.Replace(what, "")
|
||||
|
||||
|
||||
//find the position of the next delimiter,skipping whatever is comprised between opening_escape and closing_escape
|
||||
//returns 0 if reached the last delimiter
|
||||
@@ -313,14 +410,6 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
return to_return
|
||||
|
||||
//simulates the DM multiple turfs on one tile underlaying
|
||||
/dmm_suite/proc/add_underlying_turf(turf/placed,turf/underturf, list/turfs_underlays)
|
||||
if(underturf.density)
|
||||
placed.density = 1
|
||||
if(underturf.opacity)
|
||||
placed.opacity = 1
|
||||
placed.underlays += turfs_underlays
|
||||
|
||||
//atom creation method that preloads variables at creation
|
||||
/atom/New()
|
||||
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -336,6 +425,7 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
//Preloader datum
|
||||
//////////////////
|
||||
|
||||
// This ain't re-entrant, but we had this before the maploader update
|
||||
/dmm_suite/preloader
|
||||
parent_type = /datum
|
||||
var/list/attributes
|
||||
@@ -349,11 +439,41 @@ var/global/dmm_suite/preloader/_preloader = new
|
||||
|
||||
/dmm_suite/preloader/proc/load(atom/what)
|
||||
for(var/attribute in attributes)
|
||||
what.vars[attribute] = attributes[attribute]
|
||||
var/value = attributes[attribute]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
what.vars[attribute] = value
|
||||
use_preloader = FALSE
|
||||
|
||||
// If the map loader fails, make this safe
|
||||
/dmm_suite/preloader/proc/reset()
|
||||
use_preloader = FALSE
|
||||
attributes = list()
|
||||
target_path = null
|
||||
|
||||
// A datum for use within the context of loading a single map,
|
||||
// so that one can have separate "unpowered" areas for ruins or whatever,
|
||||
// yet have a single area type for use of mapping, instead of creating
|
||||
// a new area type for each new ruin
|
||||
/dmm_suite/loaded_map
|
||||
parent_type = /datum
|
||||
var/list/area_list = list()
|
||||
var/index = 1 // To store the state of the regex
|
||||
|
||||
/dmm_suite/loaded_map/proc/area_path_to_real_area(area/A)
|
||||
if(!ispath(A, /area))
|
||||
throw EXCEPTION("Wrong argument to `area_path_to_real_area`")
|
||||
|
||||
if(!(A in area_list))
|
||||
if(initial(A.there_can_be_many))
|
||||
area_list[A] = new A
|
||||
else
|
||||
area_list[A] = locate(A)
|
||||
|
||||
return area_list[A]
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
/turf/template_noop
|
||||
name = "Turf Passthrough"
|
||||
name = "Turf Passthrough"
|
||||
|
||||
@@ -326,7 +326,7 @@ swapmap
|
||||
x2+=x1-1
|
||||
y2+=y1-1
|
||||
z2+=z1-1
|
||||
world.maxz=max(z2,world.maxz) // stretch z if necessary
|
||||
zlevels.increase_max_zlevel_to(z2) // stretch z if necessary
|
||||
if(!ischunk)
|
||||
swapmaps_loaded[src]=null
|
||||
swapmaps_byname[id]=src
|
||||
@@ -373,7 +373,7 @@ swapmap
|
||||
mz=max(mz,M.z2)
|
||||
world.maxx=mx
|
||||
world.maxy=my
|
||||
world.maxz=mz
|
||||
zlevels.cut_levels_downto(mz)
|
||||
|
||||
// save and delete
|
||||
proc/Unload()
|
||||
|
||||
@@ -54,9 +54,8 @@
|
||||
name = "space hotel pamphlet"
|
||||
info = "<h3>Welcome to Deep Space Hotel 419!</h3>Thank you for choosing our hotel. Simply hand your credit or debit card to the concierge and get your room key! To check out, hand your credit card back.<small><h4>Conditions:</h4><ul><li>The hotel is not responsible for any losses due to time or space anomalies.<li>The hotel is not responsible for events that occur outside of the hotel station, including, but not limited to, events that occur inside of dimensional pockets.<li>The hotel is not responsible for overcharging your account.<li>The hotel is not responsible for missing persons.<li>The hotel is not responsible for mind-altering effects due to drugs, magic, demons, or space worms.</ul></small>"
|
||||
|
||||
/obj/effect/landmark/map_loader/hotel_room/New()
|
||||
/obj/effect/landmark/map_loader/hotel_room/initialize()
|
||||
..()
|
||||
|
||||
// load and randomly assign rooms
|
||||
var/global/list/south_room_templates = list()
|
||||
var/global/list/north_room_templates = list()
|
||||
@@ -65,26 +64,27 @@
|
||||
if(!loaded)
|
||||
loaded = 1
|
||||
for(var/map in flist(path))
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
if(copytext(map, 1, 3) == "n_")
|
||||
north_room_templates += T
|
||||
else if(copytext(map, 1, 3) == "s_")
|
||||
south_room_templates += T
|
||||
else
|
||||
// omnidirectional rooms are randomly assigned
|
||||
if(prob(50))
|
||||
if(cmptext(copytext(map, length(map) - 3), ".dmm"))
|
||||
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
|
||||
if(copytext(map, 1, 3) == "n_")
|
||||
north_room_templates += T
|
||||
else
|
||||
else if(copytext(map, 1, 3) == "s_")
|
||||
south_room_templates += T
|
||||
else
|
||||
// omnidirectional rooms are randomly assigned
|
||||
if(prob(50))
|
||||
north_room_templates += T
|
||||
else
|
||||
south_room_templates += T
|
||||
|
||||
var/datum/map_template/M = safepick(dir == NORTH ? north_room_templates : south_room_templates)
|
||||
if(M)
|
||||
template = M
|
||||
load(M)
|
||||
if(dir == NORTH)
|
||||
north_room_templates -= M
|
||||
else
|
||||
south_room_templates -= M
|
||||
load(M)
|
||||
|
||||
// The door to a hotel room, but also metadata for the room itself
|
||||
/obj/machinery/door/unpowered/hotel_door
|
||||
@@ -305,4 +305,4 @@
|
||||
S.retal_target = target
|
||||
S.retal = 1
|
||||
|
||||
#undef CHECKOUT_TIME
|
||||
#undef CHECKOUT_TIME
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away_mission_config.txt")
|
||||
|
||||
// Call this before you remove the last dirt on a z level - that way, all objects
|
||||
// will have proper atmos and other important enviro things
|
||||
/proc/late_setup_level(turfs, smoothTurfs)
|
||||
var/total_timer = start_watch()
|
||||
var/subtimer = start_watch()
|
||||
if(!smoothTurfs)
|
||||
smoothTurfs = turfs
|
||||
|
||||
log_debug("Setting up atmos")
|
||||
if(air_master)
|
||||
air_master.setup_allturfs(turfs)
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Initializing lighting")
|
||||
for(var/turf/T in turfs)
|
||||
if(T.dynamic_lighting)
|
||||
T.lighting_build_overlays()
|
||||
for(var/obj/structure/cable/PC in T)
|
||||
makepowernet_for(PC)
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Smoothing tiles")
|
||||
for(var/turf/T in smoothTurfs)
|
||||
if(T.smooth)
|
||||
smooth_icon(T)
|
||||
@@ -16,20 +29,95 @@
|
||||
var/atom/A = R
|
||||
if(A.smooth)
|
||||
smooth_icon(A)
|
||||
if(istype(T, /turf/simulated/mineral)) // For the listening post, among other maps
|
||||
var/turf/simulated/mineral/MT = T
|
||||
MT.add_edges()
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
log_debug("Late setup finished - took [stop_watch(total_timer)]s")
|
||||
|
||||
/proc/empty_rect(low_x,low_y, hi_x,hi_y, z)
|
||||
var/timer = start_watch()
|
||||
log_debug("Emptying region: ([low_x], [low_y]) to ([hi_x], [hi_y]) on z '[z]'")
|
||||
empty_region(block(locate(low_x, low_y, z), locate(hi_x, hi_y, z)))
|
||||
log_debug("Took [stop_watch(timer)]s")
|
||||
|
||||
/proc/empty_region(list/turfs)
|
||||
for(var/thing in turfs)
|
||||
var/turf/T = thing
|
||||
for(var/otherthing in T)
|
||||
qdel(otherthing)
|
||||
T.ChangeTurf(/turf/space)
|
||||
|
||||
/proc/createRandomZlevel()
|
||||
if(awaydestinations.len) //crude, but it saves another var!
|
||||
return
|
||||
|
||||
var/list/potentialRandomZlevels = list()
|
||||
log_startup_progress("Searching for away missions...")
|
||||
var/list/Lines
|
||||
if(fexists("config/away_mission_config.txt"))
|
||||
Lines = file2list("config/away_mission_config.txt")
|
||||
else
|
||||
Lines = file2list("config/example/away_mission_config.txt")
|
||||
if(potentialRandomZlevels && potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away mission...")
|
||||
|
||||
if(!Lines.len) return
|
||||
var/map = pick(potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
var/zlev = zlevels.add_new_zlevel()
|
||||
zlevels.add_dirt(zlev)
|
||||
maploader.load_map(file, z_offset = zlev)
|
||||
late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev)))
|
||||
zlevels.remove_dirt(zlev)
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
|
||||
//map_transition_config.Add(AWAY_MISSION_LIST)
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
|
||||
/proc/createALLZlevels()
|
||||
if(awaydestinations.len) //crude, but it saves another var!
|
||||
return
|
||||
|
||||
if(potentialRandomZlevels && potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away missions...")
|
||||
|
||||
for(var/map in potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
log_startup_progress("Loading away mission: [map]")
|
||||
var/zlev = zlevels.add_new_zlevel()
|
||||
zlevels.add_dirt(zlev)
|
||||
maploader.load_map(file, z_offset = zlev)
|
||||
late_setup_level(block(locate(1, 1, zlev), locate(world.maxx, world.maxy, zlev)))
|
||||
zlevels.remove_dirt(zlev)
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
|
||||
//map_transition_config.Add(AWAY_MISSION_LIST)
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
watch = start_watch()
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
|
||||
/proc/generateMapList(filename)
|
||||
var/list/potentialMaps = list()
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
if(!Lines.len)
|
||||
return
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
continue
|
||||
@@ -42,38 +130,87 @@
|
||||
|
||||
var/pos = findtext(t, " ")
|
||||
var/name = null
|
||||
// var/value = null
|
||||
|
||||
if(pos)
|
||||
name = lowertext(copytext(t, 1, pos))
|
||||
// value = copytext(t, pos + 1)
|
||||
|
||||
else
|
||||
name = lowertext(t)
|
||||
|
||||
if(!name)
|
||||
continue
|
||||
|
||||
potentialRandomZlevels.Add(t)
|
||||
potentialMaps.Add(t)
|
||||
|
||||
return potentialMaps
|
||||
|
||||
|
||||
if(potentialRandomZlevels.len)
|
||||
var/watch = start_watch()
|
||||
log_startup_progress("Loading away mission...")
|
||||
/proc/seedRuins(z_level = 1, budget = 0, whitelist = /area/space, list/potentialRuins = space_ruins_templates)
|
||||
var/overall_sanity = 100
|
||||
var/ruins = potentialRuins.Copy()
|
||||
var/initialbudget = budget
|
||||
var/watch = start_watch()
|
||||
|
||||
var/map = pick(potentialRandomZlevels)
|
||||
var/file = file(map)
|
||||
if(isfile(file))
|
||||
maploader.load_map(file, do_sleep = 0)
|
||||
late_setup_level(block(locate(1, 1, world.maxz), locate(world.maxx, world.maxy, world.maxz)))
|
||||
log_to_dd(" Away mission loaded: [map]")
|
||||
log_startup_progress("Loading ruins...")
|
||||
|
||||
for(var/obj/effect/landmark/L in landmarks_list)
|
||||
if(L.name != "awaystart")
|
||||
while(budget > 0 && overall_sanity > 0)
|
||||
// Pick a ruin
|
||||
var/datum/map_template/ruin/ruin = ruins[pick(ruins)]
|
||||
// Can we afford it
|
||||
if(ruin.cost > budget)
|
||||
overall_sanity--
|
||||
continue
|
||||
// If so, try to place it
|
||||
var/sanity = 100
|
||||
// And if we can't fit it anywhere, give up, try again
|
||||
|
||||
while(sanity > 0)
|
||||
sanity--
|
||||
var/turf/T = locate(rand(25, world.maxx - 25), rand(25, world.maxy - 25), z_level)
|
||||
var/valid = 1
|
||||
|
||||
for(var/turf/check in ruin.get_affected_turfs(T,1))
|
||||
var/area/new_area = get_area(check)
|
||||
if(!(istype(new_area, whitelist)))
|
||||
valid = 0
|
||||
break
|
||||
|
||||
if(!valid)
|
||||
continue
|
||||
awaydestinations.Add(L)
|
||||
|
||||
log_startup_progress(" Away mission loaded in [stop_watch(watch)]s.")
|
||||
log_to_dd(" Ruin \"[ruin.name]\" loaded in [stop_watch(watch)]s at ([T.x], [T.y], [T.z]).")
|
||||
|
||||
else
|
||||
log_startup_progress(" No away missions found.")
|
||||
return
|
||||
var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T)
|
||||
R.Load(ruins,ruin)
|
||||
budget -= ruin.cost
|
||||
if(!ruin.allow_duplicates)
|
||||
ruins -= ruin.name
|
||||
break
|
||||
|
||||
to_chat(world, "<span class='danger'> Loaded ruins. Or not.</span>") //So the players don't know if we loaded ruins, but we do have a message
|
||||
|
||||
if(initialbudget == budget) //Kill me
|
||||
log_to_dd(" No ruins loaded.")
|
||||
|
||||
|
||||
/obj/effect/ruin_loader
|
||||
name = "random ruin"
|
||||
desc = "If you got lucky enough to see this..."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "syndballoon"
|
||||
invisibility = 0
|
||||
|
||||
/obj/effect/ruin_loader/proc/Load(list/potentialRuins = space_ruins_templates, datum/map_template/template = null)
|
||||
var/list/possible_ruins = list()
|
||||
for(var/A in potentialRuins)
|
||||
var/datum/map_template/T = potentialRuins[A]
|
||||
if(!T.loaded)
|
||||
possible_ruins += T
|
||||
if(!template && possible_ruins.len)
|
||||
template = safepick(possible_ruins)
|
||||
if(!template)
|
||||
return 0
|
||||
template.load(get_turf(src),centered = 1)
|
||||
template.loaded++
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
/obj/effect/levelref/New()
|
||||
..()
|
||||
levels += src
|
||||
|
||||
/obj/effect/levelref/initialize()
|
||||
..()
|
||||
for(var/obj/effect/levelref/O in levels)
|
||||
if(id == O.id && O != src)
|
||||
other = O
|
||||
@@ -104,7 +107,7 @@
|
||||
/turf/unsimulated/floor/upperlevel/New()
|
||||
..()
|
||||
var/obj/effect/levelref/R = locate() in get_area(src)
|
||||
if(R)
|
||||
if(R && R.other)
|
||||
init(R)
|
||||
|
||||
/turf/unsimulated/floor/upperlevel/Destroy()
|
||||
@@ -159,6 +162,8 @@
|
||||
..()
|
||||
portals += src
|
||||
|
||||
/obj/effect/view_portal/initialize()
|
||||
..()
|
||||
if(id)
|
||||
for(var/obj/effect/view_portal/O in portals)
|
||||
if(id == O.id && O != src && can_link(O))
|
||||
@@ -361,4 +366,4 @@
|
||||
screen_loc = "CENTER[ox >= 0 ? "+" : ""][ox],CENTER[oy >= 0 ? "+" : ""][oy]"
|
||||
|
||||
/obj/effect/view_portal_dummy/attack_ghost(mob/user)
|
||||
owner.attack_ghost(user)
|
||||
owner.attack_ghost(user)
|
||||
|
||||
@@ -97,18 +97,18 @@
|
||||
display_name = "cowboy hat"
|
||||
path = /obj/item/clothing/head/cowboyhat
|
||||
|
||||
/datum/gear/hat/beret/purple
|
||||
/datum/gear/hat/pr_beret
|
||||
display_name = "beret, purple"
|
||||
path = /obj/item/clothing/head/beret/purple_normal
|
||||
|
||||
/datum/gear/hat/beret/black
|
||||
/datum/gear/hat/bl_beret
|
||||
display_name = "beret, black"
|
||||
path = /obj/item/clothing/head/beret/black
|
||||
|
||||
/datum/gear/hat/beret/blue
|
||||
/datum/gear/hat/blu_beret
|
||||
display_name = "beret, blue"
|
||||
path = /obj/item/clothing/head/beret/blue
|
||||
|
||||
/datum/gear/hat/beret/red
|
||||
/datum/gear/hat/red_beret
|
||||
display_name = "beret, red"
|
||||
path = /obj/item/clothing/head/beret
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/datum/gear/suit
|
||||
subtype_path = /datum/gear/suit
|
||||
slot = slot_wear_suit
|
||||
cost = 2
|
||||
sort_category = "External Wear"
|
||||
|
||||
//WINTER COATS
|
||||
/datum/gear/suit/coat
|
||||
subtype_path = /datum/gear/suit/coat
|
||||
cost = 2
|
||||
|
||||
/datum/gear/suit/coat/grey
|
||||
display_name = "winter coat"
|
||||
path = /obj/item/clothing/suit/hooded/wintercoat
|
||||
|
||||
/datum/gear/suit/coat/job
|
||||
subtype_path = /datum/gear/suit/coat
|
||||
subtype_path = /datum/gear/suit/coat/job
|
||||
subtype_cost_overlap = FALSE
|
||||
|
||||
/datum/gear/suit/coat/job/sec
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/datum/gear/uniform
|
||||
subtype_path = /datum/gear/uniform
|
||||
slot = slot_w_uniform
|
||||
cost = 2
|
||||
sort_category = "Uniforms and Casual Dress"
|
||||
|
||||
/datum/gear/uniform/skirt
|
||||
@@ -24,7 +25,6 @@
|
||||
path = /obj/item/clothing/under/blackskirt
|
||||
|
||||
/datum/gear/uniform/skirt/job
|
||||
cost = 2
|
||||
subtype_path = /datum/gear/uniform/skirt/job
|
||||
subtype_cost_overlap = FALSE
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
|
||||
/datum/gear/uniform/sec
|
||||
subtype_path = /datum/gear/uniform/sec
|
||||
cost = 2
|
||||
|
||||
/datum/gear/uniform/sec/formal
|
||||
display_name = "security uniform, formal"
|
||||
@@ -122,6 +121,9 @@ datum/gear/uniform/secorporate
|
||||
path = /obj/item/clothing/under/rank/security2
|
||||
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Detective", "Security Pod Pilot")
|
||||
|
||||
/datum/gear/uniform/shorts
|
||||
subtype_path = /datum/gear/uniform/shorts
|
||||
|
||||
/datum/gear/uniform/shorts/red
|
||||
display_name = "shorts, red"
|
||||
path = /obj/item/clothing/under/shorts/red
|
||||
@@ -142,6 +144,9 @@ datum/gear/uniform/secorporate
|
||||
display_name = "shorts, grey"
|
||||
path = /obj/item/clothing/under/shorts/grey
|
||||
|
||||
/datum/gear/uniform/pants
|
||||
subtype_path = /datum/gear/uniform/pants
|
||||
|
||||
/datum/gear/uniform/pants/jeans
|
||||
display_name = "jeans, classic"
|
||||
path = /obj/item/clothing/under/pants/classicjeans
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
..()
|
||||
return
|
||||
|
||||
if(flags & NODROP)
|
||||
if(!usr.canUnEquip(src))
|
||||
return
|
||||
|
||||
var/obj/item/clothing/ears/O
|
||||
@@ -634,8 +634,10 @@ BLIND // can't see anything
|
||||
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
|
||||
if(!(src.loc == usr))
|
||||
return
|
||||
|
||||
if(!( usr.restrained() ) && !( usr.stat ) && ( over_object ))
|
||||
if(!usr.canUnEquip(src))
|
||||
to_chat(usr, "[src] appears stuck on you!")
|
||||
return
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
usr.unEquip(src)
|
||||
|
||||
@@ -114,4 +114,19 @@
|
||||
prescription_upgradable = 1
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/sunglasses/prescription
|
||||
prescription = 1
|
||||
prescription = 1
|
||||
|
||||
/obj/item/clothing/glasses/hud/hydroponic
|
||||
name = "Hydroponic HUD"
|
||||
desc = "A heads-up display capable of analyzing the health and status of plants growing in hydro trays and soil."
|
||||
icon_state = "hydroponichud"
|
||||
HUDType = DATA_HUD_HYDROPONIC
|
||||
|
||||
/obj/item/clothing/glasses/hud/hydroponic/night
|
||||
name = "Night Vision Hydroponic HUD"
|
||||
desc = "A hydroponic HUD fitted with a light amplifier."
|
||||
icon_state = "hydroponichudnight"
|
||||
item_state = "glasses"
|
||||
darkness_view = 8
|
||||
see_darkness = 0
|
||||
prescription_upgradable = 0
|
||||
@@ -292,7 +292,7 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/syndi
|
||||
name = "blood-red hardsuit helmet"
|
||||
desc = "A dual-mode advanced helmet designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
icon_state = "rig1-syndi"
|
||||
item_state = "syndie_helm"
|
||||
item_color = "syndi"
|
||||
armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
@@ -301,7 +301,7 @@
|
||||
action_button_name = "Toggle Helmet Mode"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/syndi/update_icon()
|
||||
icon_state = "hardsuit[on]-[item_color]"
|
||||
icon_state = "rig[on]-[item_color]"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
@@ -334,7 +334,7 @@
|
||||
/obj/item/clothing/suit/space/rig/syndi
|
||||
name = "blood-red hardsuit"
|
||||
desc = "A dual-mode advanced hardsuit designed for work in special operations. It is in travel mode. Property of Gorlex Marauders."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
icon_state = "rig1-syndi"
|
||||
item_state = "syndie_hardsuit"
|
||||
item_color = "syndi"
|
||||
w_class = 3
|
||||
@@ -344,7 +344,7 @@
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword/saber,/obj/item/weapon/restraints/handcuffs,/obj/item/weapon/tank)
|
||||
|
||||
/obj/item/clothing/suit/space/rig/syndi/update_icon()
|
||||
icon_state = "hardsuit[on]-[item_color]"
|
||||
icon_state = "rig[on]-[item_color]"
|
||||
|
||||
/obj/item/clothing/suit/space/rig/syndi/attack_self(mob/user)
|
||||
on = !on
|
||||
@@ -374,7 +374,7 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/syndi/elite
|
||||
name = "elite syndicate hardsuit helmet"
|
||||
desc = "An elite version of the syndicate helmet, with improved armour and fire shielding. It is in travel mode. Property of Gorlex Marauders."
|
||||
icon_state = "hardsuit0-syndielite"
|
||||
icon_state = "rig0-syndielite"
|
||||
item_color = "syndielite"
|
||||
armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70)
|
||||
heat_protection = HEAD
|
||||
@@ -393,7 +393,7 @@
|
||||
/obj/item/clothing/suit/space/rig/syndi/elite
|
||||
name = "elite syndicate hardsuit"
|
||||
desc = "An elite version of the syndicate hardsuit, with improved armour and fire shielding. It is in travel mode."
|
||||
icon_state = "hardsuit0-syndielite"
|
||||
icon_state = "rig0-syndielite"
|
||||
item_color = "syndielite"
|
||||
armor = list(melee = 60, bullet = 60, laser = 50, energy = 25, bomb = 55, bio = 100, rad = 70)
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
@@ -516,14 +516,14 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/security/hos
|
||||
name = "head of security's hardsuit helmet"
|
||||
desc = "a special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor."
|
||||
icon_state = "hardsuit0-hos"
|
||||
icon_state = "rig0-hos"
|
||||
item_color = "hos"
|
||||
armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50)
|
||||
sprite_sheets = null
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/rig/security/hos
|
||||
icon_state = "hardsuit-hos"
|
||||
icon_state = "rig-hos"
|
||||
name = "head of security's hardsuit"
|
||||
desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
|
||||
armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50)
|
||||
@@ -535,7 +535,7 @@
|
||||
/obj/item/clothing/suit/space/rig/shielded
|
||||
name = "shielded hardsuit"
|
||||
desc = "A hardsuit with built in energy shielding. Will rapidly recharge when not under fire."
|
||||
icon_state = "hardsuit-hos"
|
||||
icon_state = "rig-hos"
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank, /obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs)
|
||||
armor = list(melee = 30, bullet = 15, laser = 30, energy = 10, bomb = 10, bio = 100, rad = 50)
|
||||
var/current_charges = 3
|
||||
@@ -585,7 +585,7 @@
|
||||
/obj/item/clothing/suit/space/rig/shielded/syndi
|
||||
name = "blood-red hardsuit"
|
||||
desc = "An advanced hardsuit with built in energy shielding."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
icon_state = "rig1-syndi"
|
||||
item_state = "syndie_hardsuit"
|
||||
item_color = "syndi"
|
||||
armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
@@ -603,7 +603,7 @@
|
||||
/obj/item/clothing/head/helmet/space/rig/shielded/syndi
|
||||
name = "blood-red hardsuit helmet"
|
||||
desc = "An advanced hardsuit helmet with built in energy shielding."
|
||||
icon_state = "hardsuit1-syndi"
|
||||
icon_state = "rig1-syndi"
|
||||
item_state = "syndie_helm"
|
||||
item_color = "syndi"
|
||||
armor = list(melee = 40, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 50)
|
||||
@@ -298,9 +298,7 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0)
|
||||
allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/toy, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/lighter)
|
||||
species_fit = list("Vox")
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/suit.dmi'
|
||||
)
|
||||
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
|
||||
|
||||
/obj/item/clothing/head/winterhood
|
||||
name = "winter hood"
|
||||
@@ -327,7 +325,7 @@
|
||||
/obj/item/clothing/suit/hooded/wintercoat/security
|
||||
name = "security winter coat"
|
||||
icon_state = "wintercoat_sec"
|
||||
armor = list(melee = 15, bullet = 10, laser = 20, energy = 5, bomb = 15, bio = 0, rad = 0) //worse stats than normal armor, but this one protects arms and makes space hurt less, CHOICES!
|
||||
armor = list(melee = 10, bullet = 10, laser = 10, energy = 5, bomb = 15, bio = 0, rad = 0)
|
||||
allowed = list(/obj/item/weapon/gun/energy, /obj/item/weapon/reagent_containers/spray/pepper, /obj/item/weapon/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/weapon/melee/baton, /obj/item/weapon/restraints/handcuffs, /obj/item/device/flashlight/seclite, /obj/item/weapon/melee/classic_baton/telescopic)
|
||||
hoodtype = /obj/item/clothing/head/winterhood/security
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/clothing/under/syndicate
|
||||
name = "tactical turtleneck"
|
||||
desc = "It's some non-descript, slightly suspicious looking, support clothing."
|
||||
desc = "A non-descript and slightly suspicious looking turtleneck with digital camouflage cargo pants."
|
||||
icon_state = "syndicate"
|
||||
item_state = "bl_suit"
|
||||
item_color = "syndicate"
|
||||
@@ -11,8 +11,9 @@
|
||||
name = "combat turtleneck"
|
||||
|
||||
/obj/item/clothing/under/syndicate/tacticool
|
||||
name = "\improper Tacticool turtleneck"
|
||||
name = "tacticool turtleneck"
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
icon_state = "tactifool"
|
||||
item_state = "bl_suit"
|
||||
item_color = "tactifool"
|
||||
item_color = "tactifool"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
|
||||
@@ -209,7 +209,9 @@ log transactions
|
||||
dat += "<span class='warning'>Unable to connect to accounts database, please retry and if the issue persists contact Nanotrasen IT support.</span>"
|
||||
reconnect_database()
|
||||
|
||||
user << browse(dat,"window=atm;size=550x650")
|
||||
var/datum/browser/popup = new(user, "atm", name, 550, 650)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
else
|
||||
user << browse(null,"window=atm")
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
|
||||
/obj/item/clothing/mask/gas/voice, /obj/item/clothing/glasses/thermal,\
|
||||
/obj/item/device/chameleon, /obj/item/weapon/card/emag,\
|
||||
/obj/item/weapon/storage/toolbox/syndicate, /obj/item/weapon/aiModule,\
|
||||
/obj/item/device/radio/headset/syndicate, /obj/item/weapon/c4,\
|
||||
/obj/item/device/radio/headset/syndicate, /obj/item/weapon/grenade/plastic/c4,\
|
||||
/obj/item/device/powersink, /obj/item/weapon/storage/box/syndie_kit,\
|
||||
/obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/laser/captain,\
|
||||
/obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
|
||||
|
||||
@@ -251,4 +251,4 @@
|
||||
if(!user.put_in_active_hand(QB))
|
||||
QB.forceMove(get_turf(src))
|
||||
visible_message("<span class='notice'>[user] removes the queen from the apiary.</span>")
|
||||
queen_bee = null
|
||||
queen_bee = null
|
||||
@@ -7,6 +7,8 @@
|
||||
flags = OPENCONTAINER
|
||||
volume = 100
|
||||
|
||||
hud_possible = list (PLANT_NUTRIENT_HUD, PLANT_WATER_HUD, PLANT_STATUS_HUD, PLANT_HEALTH_HUD, PLANT_TOXIN_HUD, PLANT_PEST_HUD, PLANT_WEED_HUD)
|
||||
|
||||
var/mechanical = 1 // Set to 0 to stop it from drawing the alert lights.
|
||||
var/base_name = "tray"
|
||||
|
||||
@@ -73,10 +75,12 @@
|
||||
if(weedlevel > 0)
|
||||
nymph.reagents.add_reagent("nutriment", weedlevel)
|
||||
weedlevel = 0
|
||||
plant_hud_set_weed()
|
||||
nymph.visible_message("<font color='blue'><b>[nymph]</b> begins rooting through [src], ripping out weeds and eating them noisily.</font>","<font color='blue'>You begin rooting through [src], ripping out weeds and eating them noisily.</font>")
|
||||
else if(nymph.nutrition > 100 && nutrilevel < 10)
|
||||
nymph.nutrition -= ((10-nutrilevel)*5)
|
||||
nutrilevel = 10
|
||||
plant_hud_set_nutrient()
|
||||
nymph.visible_message("<font color='blue'><b>[nymph]</b> secretes a trickle of green liquid, refilling [src].</font>","<font color='blue'>You secrete a trickle of green liquid, refilling [src].</font>")
|
||||
else
|
||||
nymph.visible_message("<font color='blue'><b>[nymph]</b> rolls around in [src] for a bit.</font>","<font color='blue'>You roll around in [src] for a bit.</font>")
|
||||
@@ -85,6 +89,17 @@
|
||||
/obj/machinery/portable_atmospherics/hydroponics/New()
|
||||
..()
|
||||
|
||||
var/datum/atom_hud/data/hydroponic/hydro_hud = huds[DATA_HUD_HYDROPONIC]
|
||||
prepare_huds()
|
||||
hydro_hud.add_to_hud(src)
|
||||
plant_hud_set_nutrient()
|
||||
plant_hud_set_water()
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
plant_hud_set_toxin()
|
||||
plant_hud_set_pest()
|
||||
plant_hud_set_weed()
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/hydroponics(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
|
||||
@@ -101,6 +116,7 @@
|
||||
if(closed_system)
|
||||
flags &= ~OPENCONTAINER
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/upgraded/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
@@ -118,6 +134,8 @@
|
||||
maxnutri = tmp_capacity * 5 // Up to 30
|
||||
//waterlevel = maxwater
|
||||
//nutrilevel = 3
|
||||
plant_hud_set_nutrient()
|
||||
plant_hud_set_water()
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj)
|
||||
|
||||
@@ -150,12 +168,18 @@
|
||||
die()
|
||||
check_level_sanity()
|
||||
update_icon()
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/proc/die()
|
||||
dead = 1
|
||||
harvest = 0
|
||||
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
|
||||
pestlevel = 0
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
plant_hud_set_weed()
|
||||
plant_hud_set_pest()
|
||||
|
||||
//Harvests the product of a plant.
|
||||
/obj/machinery/portable_atmospherics/hydroponics/proc/harvest(var/mob/user)
|
||||
@@ -233,6 +257,9 @@
|
||||
pestlevel = 0
|
||||
sampled = 0
|
||||
update_icon()
|
||||
plant_hud_set_weed()
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
visible_message("<span class='notice'>[src] has been overtaken by [seed.display_name].</span>")
|
||||
|
||||
return
|
||||
@@ -391,6 +418,14 @@
|
||||
toxins = max(0,min(toxins,10))
|
||||
yield_mod = min(100, yield_mod)
|
||||
|
||||
plant_hud_set_nutrient()
|
||||
plant_hud_set_water()
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
plant_hud_set_toxin()
|
||||
plant_hud_set_pest()
|
||||
plant_hud_set_weed()
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species()
|
||||
|
||||
var/previous_plant = seed.display_name
|
||||
@@ -409,6 +444,9 @@
|
||||
harvest = 0
|
||||
weedlevel = 0
|
||||
|
||||
plant_hud_set_health()
|
||||
plant_hud_set_weed()
|
||||
|
||||
update_icon()
|
||||
visible_message("\red The \blue [previous_plant] \red has suddenly mutated into \blue [seed.display_name]!")
|
||||
|
||||
@@ -585,6 +623,7 @@
|
||||
user.visible_message("<span class='danger'>[user] starts uprooting the weeds.</span>", "<span class='danger'>You remove the weeds from the [src].</span>")
|
||||
weedlevel = 0
|
||||
update_icon()
|
||||
plant_hud_set_weed()
|
||||
else
|
||||
to_chat(user, "<span class='danger'>This plot is completely devoid of weeds. It doesn't need uprooting.</span>")
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
// Bonus chance if the tray is unoccupied.
|
||||
if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 6 : 3))
|
||||
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
|
||||
plant_hud_set_weed()
|
||||
|
||||
// There's a chance for a weed explosion to happen if the weeds take over.
|
||||
// Plants that are themselves weeds (weed_tolerance > 10) are unaffected.
|
||||
@@ -48,8 +49,10 @@
|
||||
// Maintain tray nutrient and water levels.
|
||||
if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0 && nutrilevel > 0 && prob(25))
|
||||
nutrilevel -= max(0,seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER)
|
||||
plant_hud_set_nutrient()
|
||||
if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 0 && waterlevel > 0 && prob(25))
|
||||
waterlevel -= max(0,seed.get_trait(TRAIT_WATER_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER)
|
||||
plant_hud_set_water()
|
||||
|
||||
// Make sure the plant is not starving or thirsty. Adequate
|
||||
// water and nutrients will cause a plant to become healthier.
|
||||
@@ -91,6 +94,7 @@
|
||||
if(toxins > seed.get_trait(TRAIT_TOXINS_TOLERANCE))
|
||||
health -= toxin_uptake
|
||||
toxins -= toxin_uptake
|
||||
plant_hud_set_toxin()
|
||||
|
||||
// Check for pests and weeds.
|
||||
// Some carnivorous plants happily eat pests.
|
||||
@@ -100,6 +104,7 @@
|
||||
pestlevel -= HYDRO_SPEED_MULTIPLIER
|
||||
else if(pestlevel >= seed.get_trait(TRAIT_PEST_TOLERANCE))
|
||||
health -= HYDRO_SPEED_MULTIPLIER
|
||||
plant_hud_set_pest()
|
||||
|
||||
// Some plants thrive and live off of weeds.
|
||||
if(weedlevel > 0)
|
||||
@@ -108,6 +113,7 @@
|
||||
weedlevel -= HYDRO_SPEED_MULTIPLIER
|
||||
else if(weedlevel >= seed.get_trait(TRAIT_WEED_TOLERANCE))
|
||||
health -= HYDRO_SPEED_MULTIPLIER
|
||||
plant_hud_set_weed()
|
||||
|
||||
// Handle life and death.
|
||||
// If the plant gets too old, begin killing it each cycle
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
/obj/item/weapon/storage/bible)
|
||||
|
||||
/obj/structure/bookcase/initialize()
|
||||
..()
|
||||
for(var/obj/item/I in loc)
|
||||
if(is_type_in_list(I, valid_types))
|
||||
I.forceMove(src)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
color = "#000000"
|
||||
icon_state = "light1"
|
||||
auto_init = 0 // doesn't need special init
|
||||
|
||||
var/lum_r
|
||||
var/lum_g
|
||||
@@ -104,4 +105,4 @@
|
||||
if(istype(T))
|
||||
T.lighting_overlay = null
|
||||
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/on=0
|
||||
|
||||
/obj/machinery/media/receiver/boombox/initialize()
|
||||
..()
|
||||
if(on)
|
||||
update_on()
|
||||
update_icon()
|
||||
@@ -80,4 +81,4 @@
|
||||
if(on)
|
||||
icon_state="wallradio-p"
|
||||
else
|
||||
icon_state="wallradio"
|
||||
icon_state="wallradio"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/const/MAX_TEMP=70 // Celsius
|
||||
|
||||
/obj/machinery/media/transmitter/broadcast/initialize()
|
||||
..()
|
||||
testing("[type]/initialize() called!")
|
||||
if(autolink && autolink.len)
|
||||
for(var/obj/machinery/media/source in orange(20, src))
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
var/ore_pickup_rate = 15
|
||||
var/sheet_per_ore = 1
|
||||
var/point_upgrade = 1
|
||||
var/list/ore_values = list(("sand" = 1), ("iron" = 1), ("plasma" = 15), ("silver" = 16), ("gold" = 18), ("uranium" = 30), ("diamond" = 50), ("bananium" = 60), ("tranquillite" = 60))
|
||||
var/list/ore_values = list(("sand" = 1), ("iron" = 1), ("plasma" = 15), ("silver" = 16), ("gold" = 18), ("uranium" = 30), ("diamond" = 50), ("bluespace crystal" = 50), ("bananium" = 60), ("tranquillite" = 60))
|
||||
var/list/supply_consoles = list("Science", "Robotics", "Research Director's Desk", "Mechanic", "Engineering" = list("metal", "glass", "plasma"), "Chief Engineer's Desk" = list("metal", "glass", "plasma"), "Atmospherics" = list("metal", "glass", "plasma"), "Bar" = list("uranium", "plasma"), "Virology" = list("plasma", "uranium", "gold"))
|
||||
|
||||
/obj/machinery/mineral/ore_redemption/New()
|
||||
@@ -958,14 +958,15 @@
|
||||
/**********************Mining Scanner**********************/
|
||||
|
||||
/obj/item/device/mining_scanner
|
||||
desc = "A scanner that checks surrounding rock for useful minerals, it can also be used to stop gibtonite detonations. Requires you to wear mesons to work properly."
|
||||
name = "mining scanner"
|
||||
desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results."
|
||||
name = "manual mining scanner"
|
||||
icon_state = "mining1"
|
||||
item_state = "analyzer"
|
||||
w_class = 2
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
var/cooldown = 0
|
||||
origin_tech = "engineering=1;magnets=1"
|
||||
|
||||
/obj/item/device/mining_scanner/attack_self(mob/user)
|
||||
if(!user.client)
|
||||
@@ -989,29 +990,51 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner
|
||||
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Requires you to wear mesons to function properly."
|
||||
name = "advanced mining scanner"
|
||||
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range."
|
||||
name = "advanced automatic mining scanner"
|
||||
icon_state = "mining0"
|
||||
item_state = "analyzer"
|
||||
w_class = 2
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
var/cooldown = 0
|
||||
var/cooldown = 35
|
||||
var/on_cooldown = 0
|
||||
var/range = 7
|
||||
var/meson = TRUE
|
||||
origin_tech = "engineering=3;magnets=3"
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner/cyborg
|
||||
flags = CONDUCT | NODROP
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner/material
|
||||
meson = FALSE
|
||||
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results. This one has an extended range."
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner/lesser
|
||||
name = "automatic mining scanner"
|
||||
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results."
|
||||
range = 4
|
||||
cooldown = 50
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner/lesser/material
|
||||
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results."
|
||||
meson = FALSE
|
||||
|
||||
/obj/item/device/t_scanner/adv_mining_scanner/scan()
|
||||
if(!cooldown)
|
||||
cooldown = 1
|
||||
spawn(35)
|
||||
cooldown = 0
|
||||
if(!on_cooldown)
|
||||
on_cooldown = 1
|
||||
spawn(cooldown)
|
||||
on_cooldown = 0
|
||||
var/turf/t = get_turf(src)
|
||||
var/list/mobs = recursive_mob_check(t, client_check = 1, sight_check = 0, include_radio = 0)
|
||||
if(!mobs.len)
|
||||
return
|
||||
mineral_scan_pulse(mobs, t)
|
||||
if(meson)
|
||||
mineral_scan_pulse(mobs, t, range)
|
||||
else
|
||||
mineral_scan_pulse_material(mobs, t, range)
|
||||
|
||||
//For use with mesons
|
||||
/proc/mineral_scan_pulse(list/mobs, turf/T, range = world.view)
|
||||
var/list/minerals = list()
|
||||
for(var/turf/simulated/mineral/M in range(range, T))
|
||||
@@ -1029,6 +1052,26 @@
|
||||
if(C)
|
||||
C.images -= I
|
||||
|
||||
//For use with material scanners
|
||||
/proc/mineral_scan_pulse_material(list/mobs, turf/T, range = world.view)
|
||||
var/list/minerals = list()
|
||||
for(var/turf/simulated/mineral/M in range(range, T))
|
||||
if(M.scan_state)
|
||||
minerals += M
|
||||
if(minerals.len)
|
||||
for(var/turf/simulated/mineral/M in minerals)
|
||||
var/obj/effect/overlay/temp/mining_overlay/C = new/obj/effect/overlay/temp/mining_overlay(M)
|
||||
C.icon_state = M.scan_state
|
||||
|
||||
/obj/effect/overlay/temp/mining_overlay
|
||||
layer = 18
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
duration = 30
|
||||
pixel_x = -4
|
||||
pixel_y = -4
|
||||
|
||||
/**********************Xeno Warning Sign**********************/
|
||||
/obj/structure/sign/xeno_warning_mining
|
||||
name = "DANGEROUS ALIEN LIFE"
|
||||
|
||||
@@ -9,6 +9,27 @@
|
||||
|
||||
/**********************Miner Lockers**************************/
|
||||
|
||||
/obj/structure/closet/wardrobe/miner
|
||||
name = "mining wardrobe"
|
||||
icon_state = "mixed"
|
||||
icon_closed = "mixed"
|
||||
|
||||
/obj/structure/closet/wardrobe/miner/New()
|
||||
..()
|
||||
contents = list()
|
||||
new /obj/item/weapon/storage/backpack/duffel(src)
|
||||
new /obj/item/weapon/storage/backpack/industrial(src)
|
||||
new /obj/item/weapon/storage/backpack/satchel_eng(src)
|
||||
new /obj/item/clothing/under/rank/miner(src)
|
||||
new /obj/item/clothing/under/rank/miner(src)
|
||||
new /obj/item/clothing/under/rank/miner(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
new /obj/item/clothing/shoes/workboots(src)
|
||||
new /obj/item/clothing/gloves/fingerless(src)
|
||||
new /obj/item/clothing/gloves/fingerless(src)
|
||||
new /obj/item/clothing/gloves/fingerless(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/miner
|
||||
name = "miner's equipment"
|
||||
icon_state = "miningsec1"
|
||||
@@ -21,20 +42,11 @@
|
||||
|
||||
/obj/structure/closet/secure_closet/miner/New()
|
||||
..()
|
||||
sleep(2)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/storage/backpack/industrial(src)
|
||||
else
|
||||
new /obj/item/weapon/storage/backpack/satchel_eng(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo(src)
|
||||
new /obj/item/clothing/under/rank/miner(src)
|
||||
new /obj/item/clothing/gloves/fingerless(src)
|
||||
new /obj/item/clothing/shoes/black(src)
|
||||
new /obj/item/device/mining_scanner(src)
|
||||
new /obj/item/weapon/storage/bag/ore(src)
|
||||
new /obj/item/device/flashlight/lantern(src)
|
||||
new /obj/item/weapon/shovel(src)
|
||||
new /obj/item/weapon/pickaxe(src)
|
||||
new /obj/item/device/radio/headset/headset_cargo/mining(src)
|
||||
new /obj/item/device/t_scanner/adv_mining_scanner/lesser(src)
|
||||
new /obj/item/weapon/storage/bag/ore(src)
|
||||
new /obj/item/clothing/glasses/meson(src)
|
||||
|
||||
/**********************Shuttle Computer**************************/
|
||||
|
||||
@@ -79,7 +79,9 @@
|
||||
dat += text("Bluespace crystals: [amt_bluespace]<br>")
|
||||
|
||||
dat += text("<br><br><A href='?src=\ref[src];removeall=1'>Empty box</A>")
|
||||
user << browse("[dat]", "window=orebox")
|
||||
var/datum/browser/popup = new(user, "orebox", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
return
|
||||
|
||||
/obj/structure/ore_box/Topic(href, href_list)
|
||||
|
||||
@@ -490,6 +490,16 @@
|
||||
return
|
||||
if(RESIST_HEAT in mutations)
|
||||
return
|
||||
var/thermal_protection = get_thermal_protection()
|
||||
|
||||
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
|
||||
return
|
||||
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
bodytemperature += 11
|
||||
else
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
|
||||
/mob/living/carbon/human/proc/get_thermal_protection()
|
||||
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
|
||||
if(wear_suit)
|
||||
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
@@ -498,34 +508,9 @@
|
||||
if(head.max_heat_protection_temperature >= FIRE_HELM_MAX_TEMP_PROTECT)
|
||||
thermal_protection += (head.max_heat_protection_temperature*THERMAL_PROTECTION_HEAD)
|
||||
thermal_protection = round(thermal_protection)
|
||||
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
|
||||
return
|
||||
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
bodytemperature += 11
|
||||
return
|
||||
else
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
return
|
||||
//END FIRE CODE
|
||||
return thermal_protection
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/proc/adjust_body_temperature(current, loc_temp, boost)
|
||||
var/temperature = current
|
||||
var/difference = abs(current-loc_temp) //get difference
|
||||
var/increments// = difference/10 //find how many increments apart they are
|
||||
if(difference > 50)
|
||||
increments = difference/5
|
||||
else
|
||||
increments = difference/10
|
||||
var/change = increments*boost // Get the amount to change by (x per increment)
|
||||
var/temp_change
|
||||
if(current < loc_temp)
|
||||
temperature = min(loc_temp, temperature+change)
|
||||
else if(current > loc_temp)
|
||||
temperature = max(loc_temp, temperature-change)
|
||||
temp_change = (temperature - current)
|
||||
return temp_change
|
||||
*/
|
||||
//END FIRE CODE
|
||||
|
||||
/mob/living/carbon/human/proc/stabilize_temperature_from_calories()
|
||||
if(bodytemperature <= species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
var/list/butcher_results = null
|
||||
|
||||
var/list/weather_immunities = list()
|
||||
|
||||
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
|
||||
|
||||
var/gene_stability = DEFAULT_GENE_STABILITY
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
|
||||
|
||||
/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if (!yes || ( \
|
||||
if(!yes || ( \
|
||||
!istype(AM,/obj/machinery/door) && \
|
||||
!istype(AM,/obj/machinery/recharge_station) && \
|
||||
!istype(AM,/obj/machinery/disposal/deliveryChute) && \
|
||||
|
||||
@@ -315,7 +315,7 @@ var/list/robot_verbs_default = list(
|
||||
if(camera && "Robots" in camera.network)
|
||||
camera.network.Add("Medical")
|
||||
module_sprites["Basic"] = "Medbot"
|
||||
module_sprites["Standard"] = "surgeon"
|
||||
module_sprites["Surgeon"] = "surgeon"
|
||||
module_sprites["Advanced Droid"] = "droid-medical"
|
||||
module_sprites["Needles"] = "medicalrobot"
|
||||
module_sprites["Standard"] = "robotMedi"
|
||||
@@ -1486,4 +1486,4 @@ var/list/robot_verbs_default = list(
|
||||
if(1)
|
||||
disable_component("comms", 160)
|
||||
if(2)
|
||||
disable_component("comms", 60)
|
||||
disable_component("comms", 60)
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
if(!item_to_add)
|
||||
usr.visible_message("[usr] pets [src].","<span class='notice'>You rest your hand on [src]'s back for a moment.</span>")
|
||||
return
|
||||
if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess
|
||||
if(istype(item_to_add,/obj/item/weapon/grenade/plastic/c4)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,usr,1)
|
||||
return
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
//Many hats added, Some will probably be removed, just want to see which ones are popular.
|
||||
/mob/living/simple_animal/pet/corgi/proc/place_on_head(obj/item/item_to_add, var/mob/user as mob)
|
||||
|
||||
if(istype(item_to_add,/obj/item/weapon/c4)) // last thing he ever wears, I guess
|
||||
if(istype(item_to_add,/obj/item/weapon/grenade/plastic/c4)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,user,1)
|
||||
return
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
var/alerted = 0
|
||||
var/ore_eaten = 1
|
||||
var/chase_time = 100
|
||||
var/will_burrow = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/New()
|
||||
..()
|
||||
@@ -170,7 +171,7 @@
|
||||
visible_message("<span class='notice'>The ore was swallowed whole!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time
|
||||
if(!alerted)
|
||||
if(!alerted && will_burrow)
|
||||
alerted = 1
|
||||
spawn(chase_time)
|
||||
if(alerted)
|
||||
|
||||
@@ -60,7 +60,9 @@
|
||||
for(var/obj/item/P in src)
|
||||
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
|
||||
var/datum/browser/popup = new(user, "filingcabinet", name, 350, 300)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
|
||||
return
|
||||
|
||||
@@ -83,7 +85,7 @@
|
||||
|
||||
/obj/structure/filingcabinet/Topic(href, href_list)
|
||||
if(href_list["retrieve"])
|
||||
usr << browse("", "window=filingcabinet") // Close the menu
|
||||
usr << browse(null, "window=filingcabinet") // Close the menu
|
||||
|
||||
//var/retrieveindex = text2num(href_list["retrieve"])
|
||||
var/obj/item/P = locate(href_list["retrieve"])//contents[retrieveindex]
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
explosive.forceMove(user.loc)
|
||||
explosive = null
|
||||
qdel(src)
|
||||
if(istype(I, /obj/item/weapon/grenade) || istype(I, /obj/item/weapon/c4))
|
||||
if(istype(I, /obj/item/weapon/grenade) || istype(I, /obj/item/weapon/grenade/plastic/c4))
|
||||
if(explosive)
|
||||
to_chat(user, "<span class='warning'>There is already a device attached behind \the [src], remove it first.</span>")
|
||||
return 1
|
||||
@@ -268,11 +268,6 @@
|
||||
var/obj/item/weapon/grenade/G = explosive
|
||||
explosive = null
|
||||
G.prime()
|
||||
else if(istype(explosive, /obj/item/weapon/c4))
|
||||
var/obj/item/weapon/c4/C = explosive
|
||||
explosive = null
|
||||
C.target = get_step(get_turf(src), dir)
|
||||
C.explode(get_turf(loc))
|
||||
|
||||
/obj/structure/sign/picture_frame/proc/toggle_tilt(mob/user)
|
||||
if(!isliving(usr) || usr.stat)
|
||||
@@ -312,4 +307,4 @@
|
||||
/obj/structure/sign/picture_frame/hear_message(mob/living/M as mob, msg)
|
||||
..()
|
||||
for(var/obj/O in contents)
|
||||
O.hear_message(M, msg)
|
||||
O.hear_message(M, msg)
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
dat += "Current toner level: [toner]"
|
||||
if(!toner)
|
||||
dat +="<BR>Please insert a new toner cartridge!"
|
||||
user << browse(dat, "window=copier")
|
||||
var/datum/browser/popup = new(user, "copier", name, 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "copier")
|
||||
return
|
||||
|
||||
|
||||
@@ -99,11 +99,22 @@
|
||||
var/global/list/status_overlays_lighting
|
||||
var/global/list/status_overlays_environ
|
||||
var/indestructible = 0 // If set, prevents aliens from destroying it
|
||||
var/keep_preset_name = 0
|
||||
|
||||
var/report_power_alarm = 1
|
||||
|
||||
var/shock_proof = 0 //if set to 1, this APC will not arc bolts of electricity if it's overloaded.
|
||||
|
||||
/obj/machinery/power/apc/worn_out
|
||||
name = "\improper Worn out APC"
|
||||
keep_preset_name = 1
|
||||
locked = 0
|
||||
environ = 0
|
||||
equipment = 0
|
||||
lighting = 0
|
||||
operating = 0
|
||||
|
||||
|
||||
/obj/machinery/power/apc/noalarm
|
||||
report_power_alarm = 0
|
||||
|
||||
@@ -192,15 +203,19 @@
|
||||
cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively)
|
||||
cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value)
|
||||
|
||||
var/area/A = src.loc.loc
|
||||
var/area/A = get_area(src)
|
||||
|
||||
|
||||
//if area isn't specified use current
|
||||
if(isarea(A) && src.areastring == null)
|
||||
src.area = A
|
||||
if(keep_preset_name)
|
||||
if(isarea(A))
|
||||
area = A
|
||||
// no-op, keep the name
|
||||
else if(isarea(A) && src.areastring == null)
|
||||
area = A
|
||||
name = "\improper [area.name] APC"
|
||||
else
|
||||
src.area = get_area_name(areastring)
|
||||
area = get_area_name(areastring)
|
||||
name = "\improper [area.name] APC"
|
||||
area.apc |= src
|
||||
update_icon()
|
||||
@@ -623,7 +638,7 @@
|
||||
else
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return src.attack_hand(user)
|
||||
if (!opened && wiresexposed && \
|
||||
if(!opened && wiresexposed && \
|
||||
(istype(W, /obj/item/device/multitool) || \
|
||||
istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/device/assembly/signaler)))
|
||||
return src.attack_hand(user)
|
||||
@@ -853,7 +868,7 @@
|
||||
if(istype(user, /mob/living/silicon))
|
||||
var/mob/living/silicon/ai/AI = user
|
||||
var/mob/living/silicon/robot/robot = user
|
||||
if ( \
|
||||
if( \
|
||||
src.aidisabled || \
|
||||
malfhack && istype(malfai) && \
|
||||
( \
|
||||
@@ -1382,4 +1397,4 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
#undef APC_UPDATE_ICON_COOLDOWN
|
||||
|
||||
@@ -82,6 +82,7 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
//
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/initialize()
|
||||
..()
|
||||
setup_parts()
|
||||
middle.overlays += "activated"
|
||||
update_list()
|
||||
@@ -215,17 +216,17 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
/obj/machinery/gravity_generator/main/attack_hand(mob/user as mob)
|
||||
if(!..())
|
||||
return interact(user)
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/attack_ai(mob/user as mob)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/attack_ghost(mob/user as mob)
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/gravity_generator/main/interact(mob/user as mob)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
|
||||
var/dat = "Gravity Generator Breaker: "
|
||||
if(breaker)
|
||||
dat += "<span class='linkOn'>ON</span> <A href='?src=\ref[src];gentoggle=1'>OFF</A>"
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
var/redeem_immediately = 0 // redeem immediately for holding cell
|
||||
|
||||
/obj/machinery/treadmill_monitor/initialize()
|
||||
..()
|
||||
if(id)
|
||||
for(var/obj/machinery/power/treadmill/T in machines)
|
||||
if(T.id == id)
|
||||
@@ -222,4 +223,4 @@
|
||||
#undef FONT_SIZE
|
||||
#undef FONT_COLOR
|
||||
#undef FONT_STYLE
|
||||
#undef CHARS_PER_LINE
|
||||
#undef CHARS_PER_LINE
|
||||
|
||||
@@ -86,20 +86,49 @@
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator
|
||||
name = "proto-kinetic accelerator"
|
||||
desc = "According to Nanotrasen accounting, this is mining equipment. It's been modified for extreme power output to crush rocks, but often serves as a miner's first defense against hostile alien life; it's not very powerful unless used in a low pressure environment."
|
||||
desc = "In the year 2544, only a year after the discovery of a potentially \
|
||||
world-changing substance, now colloquially referred to as plasma, the \
|
||||
Nanotrasen-UEG mining conglomerate introduced a prototype of a gun-like \
|
||||
device intended for quick, effective mining of plasma in the low \
|
||||
pressures of the solar system. Included in this presentation were \
|
||||
demonstrations of the gun being fired at collections of rocks contained \
|
||||
in vacuumed environments, obliterating them instantly while maintaining \
|
||||
the structure of the ores buried within them. Additionally, volunteers \
|
||||
were called from the crowd to have the gun used on them, only proving that \
|
||||
the gun caused little harm to objects in standard pressure. \n\
|
||||
An official from an unnamed, now long dissipated company observed this \
|
||||
presentation and offered to share their self-recharger cells, powered \
|
||||
by the user's bioelectrical field, another new and unknown technology. \
|
||||
They warned that the cells were incredibly experimental and several times \
|
||||
had injured workers, but the scientists as Nanotrasen were unable to resist \
|
||||
the money-saving potential of self recharging cells. Upon accepting this \
|
||||
offer, it took only a matter of days to prove the volatility of these cells, \
|
||||
as they exploded left and right whenever inserted into the prototype devices, \
|
||||
only throwing more money in the bin. \n\
|
||||
Whenever the Nanotrasen scientists were on the edge of giving up, a \
|
||||
breakthrough was made by head researcher Miles Parks McCollum, who \
|
||||
demonstrated that the cells could be stabilized when exposed to radium \
|
||||
then cooled with cryostylane. After this discovery, the low pressure gun, \
|
||||
now named the Kinetic Accelerator, was hastily completed and made compatible \
|
||||
with the self-recharging cells. As a result of poor testing, the currently \
|
||||
used guns lose their charge when not in use, and when two Kinetic Accelerators \
|
||||
come in proximity of one another, they will interfere with each other. Despite \
|
||||
this, the shoddy guns still see use in the mining of plasma to this day."
|
||||
icon_state = "kineticgun"
|
||||
item_state = "kineticgun"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
|
||||
cell_type = /obj/item/weapon/stock_parts/cell/emproof
|
||||
// Apparently these are safe to carry? I'm sure goliaths would disagree.
|
||||
needs_permit = 0
|
||||
var/overheat_time = 16
|
||||
unique_rename = 1
|
||||
origin_tech = "combat=3;powerstorage=3;engineering=3"
|
||||
weapon_weight = WEAPON_LIGHT
|
||||
origin_tech = "combat=2;powerstorage=1"
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 9
|
||||
var/overheat_time = 16
|
||||
var/holds_charge = FALSE
|
||||
var/unique_frequency = FALSE // modified by KA modkits
|
||||
|
||||
var/overheat = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/super
|
||||
|
||||
@@ -265,7 +265,9 @@
|
||||
dat += "<BR><A href='?src=\ref[src];eject=1'>Eject beaker</A>[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];empty_beaker=1'>Empty beaker</A>":"")]<BR>"
|
||||
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
|
||||
|
||||
user << browse("<TITLE>[src.name]</TITLE><BR>[dat]", "window=pandemic;size=575x400")
|
||||
var/datum/browser/popup = new(user, "pandemic", name, 575, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "pandemic")
|
||||
return
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
return
|
||||
else
|
||||
return 1
|
||||
if ( \
|
||||
if( \
|
||||
!isturf(src.loc) || \
|
||||
!(locate(/obj/structure/table) in src.loc) && \
|
||||
!(locate(/obj/machinery/optable) in src.loc) && \
|
||||
@@ -712,6 +712,18 @@
|
||||
reagents.add_reagent("toxin", 3)
|
||||
bitesize = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/lizardmeat
|
||||
name = "mutant lizard meat"
|
||||
desc = "Seems to be a slab of meat from some mutant lizard thing?"
|
||||
icon_state = "xenomeat"
|
||||
filling_color = "#43DE18"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("protein", 3)
|
||||
reagents.add_reagent("toxin", 3)
|
||||
bitesize = 3
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/spiderleg
|
||||
name = "spider leg"
|
||||
desc = "A still twitching leg of a giant spider... you don't really want to eat this, do you?"
|
||||
|
||||
@@ -21,6 +21,16 @@
|
||||
build_path = /obj/item/clothing/glasses/hud/health
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/health_hud_night
|
||||
name = "Night Vision Health Scanner HUD"
|
||||
desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness."
|
||||
id = "health_hud_night"
|
||||
req_tech = list("biotech" = 4, "magnets" = 5)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_URANIUM = 1000, MAT_SILVER = 250)
|
||||
build_path = /obj/item/clothing/glasses/hud/health/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/magboots
|
||||
name = "Magnetic Boots"
|
||||
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle."
|
||||
@@ -41,14 +51,14 @@
|
||||
build_path = /obj/item/clothing/glasses/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/health_hud_night
|
||||
name = "Night Vision Health Scanner HUD"
|
||||
desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness."
|
||||
id = "health_hud_night"
|
||||
req_tech = list("biotech" = 4, "magnets" = 5)
|
||||
/datum/design/security_hud
|
||||
name = "Security HUD"
|
||||
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status."
|
||||
id = "security_hud"
|
||||
req_tech = list("magnets" = 3, "combat" = 2)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_URANIUM = 1000, MAT_SILVER = 250)
|
||||
build_path = /obj/item/clothing/glasses/hud/health/night
|
||||
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
|
||||
build_path = /obj/item/clothing/glasses/hud/security
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/security_hud_night
|
||||
@@ -61,16 +71,6 @@
|
||||
build_path = /obj/item/clothing/glasses/hud/security/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/nvgmesons
|
||||
name = "Night Vision Optical Meson Scanners"
|
||||
desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display."
|
||||
id = "nvgmesons"
|
||||
req_tech = list("materials" = 5, "magnets" = 5, "engineering" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 300, MAT_GLASS = 400, MAT_PLASMA = 250, MAT_URANIUM = 1000)
|
||||
build_path = /obj/item/clothing/glasses/meson/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/mesons
|
||||
name = "Optical Meson Scanners"
|
||||
desc = "Used for seeing walls, floors, and stuff through anything."
|
||||
@@ -81,14 +81,14 @@
|
||||
build_path = /obj/item/clothing/glasses/meson
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/security_hud
|
||||
name = "Security HUD"
|
||||
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status."
|
||||
id = "security_hud"
|
||||
req_tech = list("magnets" = 3, "combat" = 2)
|
||||
/datum/design/nvgmesons
|
||||
name = "Night Vision Optical Meson Scanners"
|
||||
desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display."
|
||||
id = "nvgmesons"
|
||||
req_tech = list("materials" = 5, "magnets" = 5, "engineering" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 50, MAT_GLASS = 50)
|
||||
build_path = /obj/item/clothing/glasses/hud/security
|
||||
materials = list(MAT_METAL = 300, MAT_GLASS = 400, MAT_PLASMA = 250, MAT_URANIUM = 1000)
|
||||
build_path = /obj/item/clothing/glasses/meson/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/air_horn
|
||||
@@ -170,3 +170,23 @@
|
||||
materials = list("$metal" = 200, "$glass" = 200, "$uranium" = 1000, "$plasma" = 300)
|
||||
build_path = /obj/item/clothing/glasses/hud/diagnostic/night
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/hydroponic_hud
|
||||
name = "Hydroponic HUD"
|
||||
desc = "A HUD used to analyze the health and status of plants growing in hydro trays and soil."
|
||||
id = "hydroponic_hud"
|
||||
req_tech = list("magnets" = 3, "biotech" = 3)
|
||||
build_type = PROTOLATHE
|
||||
materials = list("$metal" = 50, "$glass" = 50)
|
||||
build_path = /obj/item/clothing/glasses/hud/hydroponic
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/hydroponic_hud_night
|
||||
name = "Night Vision Hydroponic HUD"
|
||||
desc = "A HUD used to analyze the health and status of plants growing in low-light environments."
|
||||
id = "hydroponic_hud_night"
|
||||
req_tech = list("magnets" = 5, "biotech" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list("$metal" = 200, "$glass" = 200, "$uranium" = 1000, "$plasma" = 200)
|
||||
build_path = /obj/item/clothing/glasses/hud/hydroponic/night
|
||||
category = list("Equipment")
|
||||
@@ -192,16 +192,6 @@
|
||||
build_path = /obj/item/weapon/circuitboard/sleeper
|
||||
category = list("Medical Machinery")
|
||||
|
||||
/datum/design/sleep_console
|
||||
name = "Machine Board (Sleeper Console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a Sleeper Console."
|
||||
id = "sleeper_console"
|
||||
req_tech = list("programming" = 3, "biotech" = 2, "materials" = 3, "engineering" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000, "sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/sleep_console
|
||||
category = list("Medical Machinery")
|
||||
|
||||
/datum/design/biogenerator
|
||||
name = "Machine Board (Biogenerator)"
|
||||
desc = "The circuit board for a Biogenerator."
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//Parent types
|
||||
|
||||
/area/ruin/
|
||||
name = "\improper Unexplored Location"
|
||||
icon_state = "away"
|
||||
has_gravity = 1
|
||||
there_can_be_many = 1
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
always_unpowered = 0
|
||||
|
||||
/area/ruin/unpowered/no_grav
|
||||
has_gravity = 0
|
||||
|
||||
/area/ruin/powered
|
||||
requires_power = 0
|
||||
|
||||
|
||||
|
||||
|
||||
//Areas
|
||||
|
||||
/area/ruin/unpowered/no_grav/way_home
|
||||
name = "\improper Salvation"
|
||||
icon_state = "away"
|
||||
|
||||
/area/ruin/powered/snow_biodome
|
||||
|
||||
/area/ruin/powered/golem_ship
|
||||
name = "Free Golem Ship"
|
||||
|
||||
// Ruins of "onehalf" ship
|
||||
/area/ruin/onehalf/hallway
|
||||
name = "Hallway"
|
||||
icon_state = "hallC"
|
||||
|
||||
|
||||
/area/ruin/onehalf/drone_bay
|
||||
name = "Mining Drone Bay"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/ruin/onehalf/dorms_med
|
||||
name = "Crew Quarters"
|
||||
icon_state = "Sleep"
|
||||
|
||||
/area/ruin/onehalf/bridge
|
||||
name = "Bridge"
|
||||
icon_state = "bridge"
|
||||
@@ -843,7 +843,7 @@
|
||||
name = "\improper Airtight plastic flaps"
|
||||
desc = "Heavy duty, airtight, plastic flaps."
|
||||
|
||||
/obj/structure/plasticflaps/mining/New()
|
||||
/obj/structure/plasticflaps/mining/initialize()
|
||||
air_update_turf(1)
|
||||
..()
|
||||
|
||||
@@ -857,4 +857,4 @@
|
||||
#undef ORDER_SCREEN_WIDTH
|
||||
#undef ORDER_SCREEN_HEIGHT
|
||||
#undef SUPPLY_SCREEN_WIDTH
|
||||
#undef SUPPLY_SCREEN_HEIGHT
|
||||
#undef SUPPLY_SCREEN_HEIGHT
|
||||
|
||||
@@ -319,9 +319,8 @@
|
||||
if("parts")
|
||||
left_part += output_parts_list(part_set)
|
||||
left_part += "<hr><a href='?src=\ref[src];screen=main'>Return</a>"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<title>[name]</title>
|
||||
dat = {"
|
||||
<title>[name]</title>
|
||||
<style>
|
||||
.res_name {font-weight: bold; text-transform: capitalize;}
|
||||
.red {color: #f00;}
|
||||
@@ -335,21 +334,19 @@
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
</script>
|
||||
</head><body>
|
||||
<body>
|
||||
<table style='width: 100%;'>
|
||||
<tr>
|
||||
<td style='width: 65%; padding-right: 10px;'>
|
||||
[left_part]
|
||||
</td>
|
||||
<td style='width: 35%; background: #ccc;' id='queue'>
|
||||
<td style='width: 35%; background: #000;' id='queue'>
|
||||
[list_queue()]
|
||||
</td>
|
||||
<tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse(dat, "window=mecha_fabricator;size=1000x430")
|
||||
</table>"}
|
||||
var/datum/browser/popup = new(user, "mecha_fabricator", name, 1000, 430)
|
||||
popup.set_content(dat)
|
||||
popup.open(0)
|
||||
onclose(user, "mecha_fabricator")
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/datum/zlevel
|
||||
var/flags = 0
|
||||
var/dirt_count = 0
|
||||
var/zpos
|
||||
var/list/init_list = list()
|
||||
|
||||
/datum/zlevel/New(z)
|
||||
zpos = z
|
||||
|
||||
/datum/zlevel/proc/resume_init()
|
||||
if(dirt_count > 0)
|
||||
throw EXCEPTION("Init told to resume when z-level still dirty. Z level: '[zpos]'")
|
||||
log_debug("Releasing freeze on z-level '[zpos]'!")
|
||||
log_debug("Beginning initialization!")
|
||||
var/list/our_atoms = init_list // OURS NOW!!! (Keeping this list to ourselves will prevent hijack)
|
||||
init_list = list()
|
||||
var/list/late_maps = list()
|
||||
var/list/pipes = list()
|
||||
var/list/cables = list()
|
||||
var/watch = start_watch()
|
||||
for(var/schmoo in our_atoms)
|
||||
var/atom/movable/AM = schmoo
|
||||
if(AM) // to catch stuff like the nuke disk that no longer exists
|
||||
|
||||
// This can mess with our state - we leave these for last
|
||||
if(istype(AM, /obj/effect/landmark/map_loader))
|
||||
late_maps.Add(AM)
|
||||
continue
|
||||
AM.initialize()
|
||||
if(istype(AM, /obj/machinery/atmospherics))
|
||||
pipes.Add(AM)
|
||||
else if(istype(AM, /obj/structure/cable))
|
||||
cables.Add(AM)
|
||||
log_debug("Primary initialization finished in [stop_watch(watch)]s.")
|
||||
our_atoms.Cut()
|
||||
if(pipes.len)
|
||||
do_pipes(pipes)
|
||||
if(cables.len)
|
||||
do_cables(cables)
|
||||
if(late_maps.len)
|
||||
do_late_maps(late_maps)
|
||||
|
||||
/datum/zlevel/proc/do_pipes(list/pipes)
|
||||
var/watch = start_watch()
|
||||
log_debug("Building pipenets on z-level '[zpos]'!")
|
||||
for(var/schmoo in pipes)
|
||||
var/obj/machinery/atmospherics/machine = schmoo
|
||||
if(machine)
|
||||
machine.build_network()
|
||||
pipes.Cut()
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
|
||||
/datum/zlevel/proc/do_cables(list/cables)
|
||||
var/watch = start_watch()
|
||||
log_debug("Building powernets on z-level '[zpos]'!")
|
||||
for(var/schmoo in cables)
|
||||
var/obj/structure/cable/C = schmoo
|
||||
if(C)
|
||||
makepowernet_for(C)
|
||||
cables.Cut()
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
|
||||
/datum/zlevel/proc/do_late_maps(list/late_maps)
|
||||
var/watch = start_watch()
|
||||
log_debug("Loading map templates on z-level '[zpos]'!")
|
||||
zlevels.add_dirt(zpos) // Let's not repeatedly resume init for each template
|
||||
for(var/schmoo in late_maps)
|
||||
var/obj/effect/landmark/map_loader/ML = schmoo
|
||||
if(ML)
|
||||
ML.initialize()
|
||||
late_maps.Cut()
|
||||
zlevels.remove_dirt(zpos)
|
||||
log_debug("Took [stop_watch(watch)]s")
|
||||
@@ -0,0 +1,89 @@
|
||||
var/global/datum/zlev_manager/zlevels = new
|
||||
|
||||
/datum/zlev_manager
|
||||
// A list of z-levels
|
||||
var/list/z_list = list()
|
||||
|
||||
|
||||
// Populate our z level list
|
||||
/datum/zlev_manager/proc/initialize()
|
||||
z_list.len = world.maxz
|
||||
for(var/i = 1, i <= world.maxz, i++)
|
||||
z_list[i] = new /datum/zlevel(i)
|
||||
|
||||
|
||||
|
||||
/datum/zlev_manager/proc/get_zlev(z)
|
||||
if(z < 1)
|
||||
throw EXCEPTION("Non-positive z level given!")
|
||||
else if(z > z_list.len)
|
||||
throw EXCEPTION("Untracked z level: '[z]'")
|
||||
else
|
||||
return z_list[z]
|
||||
|
||||
// For when you need the z-level to be at a certain point
|
||||
/datum/zlev_manager/proc/increase_max_zlevel_to(new_maxz)
|
||||
if(world.maxz>=new_maxz)
|
||||
return
|
||||
while(world.maxz<new_maxz)
|
||||
add_new_zlevel()
|
||||
|
||||
// Increments the max z-level by one
|
||||
// For convenience's sake returns the z-level added
|
||||
/datum/zlev_manager/proc/add_new_zlevel()
|
||||
world.maxz++
|
||||
var/our_z = world.maxz
|
||||
z_list.len++
|
||||
z_list[our_z] = new /datum/zlevel(our_z)
|
||||
return our_z
|
||||
|
||||
/datum/zlev_manager/proc/cut_levels_downto(new_maxz)
|
||||
if(world.maxz <= new_maxz)
|
||||
return
|
||||
while(world.maxz>new_maxz)
|
||||
kill_topmost_zlevel()
|
||||
|
||||
// Decrements the max z-level by one
|
||||
// not normally used, but hey the swapmap loader wanted it
|
||||
/datum/zlev_manager/proc/kill_topmost_zlevel()
|
||||
var/our_z = world.maxz
|
||||
qdel(z_list[our_z])
|
||||
z_list.len--
|
||||
world.maxz--
|
||||
|
||||
/*
|
||||
* "Dirt" management
|
||||
* "Dirt" is used to keep track of whether a z level should automatically have
|
||||
* stuff on it initialize or not - the map loaders, when set to defer init, place
|
||||
* a freeze on the z levels they touch so as to prevent atmos from exploding,
|
||||
* among other things
|
||||
*/
|
||||
|
||||
|
||||
// Returns whether the given z level has a freeze on initialization
|
||||
/datum/zlev_manager/proc/is_zlevel_dirty(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
return (our_z.dirt_count > 0)
|
||||
|
||||
|
||||
// Increases the dirt count on a z level
|
||||
/datum/zlev_manager/proc/add_dirt(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
if(our_z.dirt_count == 0)
|
||||
log_debug("Placing an init freeze on z-level '[our_z.zpos]'!")
|
||||
our_z.dirt_count++
|
||||
|
||||
|
||||
// Decreases the dirt count on a z level
|
||||
/datum/zlev_manager/proc/remove_dirt(z)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
our_z.dirt_count--
|
||||
if(our_z.dirt_count == 0)
|
||||
our_z.resume_init()
|
||||
if(our_z.dirt_count < 0)
|
||||
log_debug("WARNING: Imbalanced dirt removal")
|
||||
our_z.dirt_count = 0
|
||||
|
||||
/datum/zlev_manager/proc/postpone_init(z, thing)
|
||||
var/datum/zlevel/our_z = get_zlev(z)
|
||||
our_z.init_list.Add(thing)
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
/obj/item/organ/internal/eyes/luminescent_crystal/New()
|
||||
set_light(2)
|
||||
..()
|
||||
|
||||
/obj/item/organ/internal/brain/crystal
|
||||
name = "crystalized brain"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
origin_tech = "bluespace=4;materials=3"
|
||||
points = 50
|
||||
var/blink_range = 8 // The teleport range when crushed/thrown at someone.
|
||||
refined_type = /obj/item/stack/sheet/bluespace_crystal
|
||||
|
||||
/obj/item/weapon/ore/bluespace_crystal/New()
|
||||
..()
|
||||
@@ -38,4 +39,22 @@
|
||||
name = "artificial bluespace crystal"
|
||||
desc = "An artificially made bluespace crystal, it looks delicate."
|
||||
origin_tech = "bluespace=2"
|
||||
blink_range = 4 // Not as good as the organic stuff!
|
||||
blink_range = 4 // Not as good as the organic stuff!
|
||||
|
||||
// Polycrystals, aka stacks
|
||||
|
||||
var/global/list/datum/stack_recipe/bluespace_crystal_recipes = list(new/datum/stack_recipe("Breadkdown into bluespace crystal", /obj/item/weapon/ore/bluespace_crystal, 1, one_per_turf = 0, on_floor = 1))
|
||||
|
||||
/obj/item/stack/sheet/bluespace_crystal
|
||||
name = "bluespace polycrystal"
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "polycrystal"
|
||||
desc = "A stable polycrystal, made of fused-together bluespace crystals. You could probably break one off."
|
||||
origin_tech = "bluespace=4;materials=3"
|
||||
attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed")
|
||||
|
||||
/obj/item/stack/sheet/bluespace_crystal/New()
|
||||
..()
|
||||
recipes = bluespace_crystal_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
Reference in New Issue
Block a user