Merge branch 'master' into upstream-merge-37406
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items.
|
||||
#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location.
|
||||
#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into)
|
||||
#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
|
||||
#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool
|
||||
|
||||
/*******Non-Signal Component Related Defines*******/
|
||||
|
||||
@@ -446,5 +446,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
#define EGG_LAYING_MESSAGES list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")
|
||||
|
||||
// Used by PDA and cartridge code to reduce repetitiveness of spritesheets
|
||||
#define PDAIMG(what) {"<span class="pda16x16 [#what]"></span>"}
|
||||
//Filters
|
||||
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA")
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#define EXP_TYPE_ANTAG "Antag"
|
||||
#define EXP_TYPE_SPECIAL "Special"
|
||||
#define EXP_TYPE_GHOST "Ghost"
|
||||
#define EXP_TYPE_ADMIN "Admin"
|
||||
|
||||
//Flags in the players table in the db
|
||||
#define DB_FLAG_EXEMPT 1
|
||||
|
||||
@@ -6,9 +6,10 @@ SUBSYSTEM_DEF(assets)
|
||||
var/list/preload = list()
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
for(var/type in typesof(/datum/asset))
|
||||
var/datum/asset/A = type
|
||||
if (type != initial(A._abstract))
|
||||
get_asset_datum(type)
|
||||
|
||||
preload = cache.Copy() //don't preload assets generated during the round
|
||||
|
||||
|
||||
@@ -28,13 +28,7 @@
|
||||
CRASH("Unable to find a blobstart landmark")
|
||||
|
||||
var/atom/movable/AM = parent
|
||||
if(ismob(AM.loc))
|
||||
var/mob/M = AM.loc
|
||||
M.transferItemToLoc(AM, targetturf, TRUE) //nodrops disks when?
|
||||
else if(AM.loc.SendSignal(COMSIG_CONTAINS_STORAGE))
|
||||
AM.loc.SendSignal(COMSIG_TRY_STORAGE_TAKE, src, targetturf, TRUE)
|
||||
else
|
||||
AM.forceMove(targetturf)
|
||||
AM.forceMove(targetturf)
|
||||
// move the disc, so ghosts remain orbiting it even if it's "destroyed"
|
||||
return targetturf
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@
|
||||
slave.refresh_mob_views()
|
||||
|
||||
/datum/component/storage/concrete/emp_act(severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/atom/real_location = real_location()
|
||||
for(var/i in real_location)
|
||||
var/atom/A = i
|
||||
|
||||
@@ -369,10 +369,10 @@
|
||||
. = TRUE //returns TRUE if any mobs actually got a close(M) call
|
||||
|
||||
/datum/component/storage/proc/emp_act(severity)
|
||||
var/atom/A = parent
|
||||
if(!isliving(A.loc) && !emp_shielded)
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(severity)
|
||||
if(emp_shielded)
|
||||
return
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(severity)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
|
||||
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
|
||||
@@ -455,23 +455,24 @@
|
||||
return FALSE
|
||||
handle_item_insertion(I, FALSE, M)
|
||||
|
||||
/datum/component/storage/proc/return_inv()
|
||||
. = list()
|
||||
. += contents()
|
||||
for(var/i in contents())
|
||||
var/atom/a = i
|
||||
GET_COMPONENT_FROM(STR, /datum/component/storage, a)
|
||||
if(STR)
|
||||
. += STR.return_inv()
|
||||
/datum/component/storage/proc/return_inv(recursive)
|
||||
var/list/ret = list()
|
||||
ret |= contents()
|
||||
if(recursive)
|
||||
for(var/i in ret.Copy())
|
||||
var/atom/A = i
|
||||
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
|
||||
return ret
|
||||
|
||||
/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS!
|
||||
var/atom/real_location = real_location()
|
||||
return real_location.contents.Copy()
|
||||
|
||||
/datum/component/storage/proc/signal_return_inv(list/interface)
|
||||
//Abuses the fact that lists are just references, or something like that.
|
||||
/datum/component/storage/proc/signal_return_inv(list/interface, recursive = TRUE)
|
||||
if(!islist(interface))
|
||||
return FALSE
|
||||
interface |= return_inv()
|
||||
interface |= return_inv(recursive)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/mousedrop_onto(atom/over_object, mob/M)
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
var/where = H.equip_in_one_of_slots(heirloom, slots)
|
||||
if(!where)
|
||||
where = "at your feet"
|
||||
if(where == "in your backpack")
|
||||
H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H)
|
||||
else if(where == "in your backpack")
|
||||
H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H)
|
||||
where_text = "<span class='boldnotice'>There is a precious family [heirloom.name] [where], passed down from generation to generation. Keep it safe!</span>"
|
||||
|
||||
/datum/trait/family_heirloom/post_add()
|
||||
|
||||
@@ -164,9 +164,16 @@
|
||||
.["security_level"] = get_security_level()
|
||||
.["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
|
||||
// Amount of world's ticks in seconds, useful for calculating round duration
|
||||
|
||||
//Time dilation stats.
|
||||
.["time_dilation_current"] = SStime_track.time_dilation_current
|
||||
.["time_dilation_avg"] = SStime_track.time_dilation_avg
|
||||
.["time_dilation_avg_slow"] = SStime_track.time_dilation_avg_slow
|
||||
.["time_dilation_avg_fast"] = SStime_track.time_dilation_avg_fast
|
||||
|
||||
if(SSshuttle && SSshuttle.emergency)
|
||||
.["shuttle_mode"] = SSshuttle.emergency.mode
|
||||
// Shuttle status, see /__DEFINES/stat.dm
|
||||
.["shuttle_timer"] = SSshuttle.emergency.timeLeft()
|
||||
// Shuttle timer, in seconds
|
||||
|
||||
|
||||
@@ -291,6 +291,7 @@
|
||||
/obj/machinery/computer/arcade/battle/emag_act(mob/user)
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
to_chat(user, "<span class='warning'>A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!</span>")
|
||||
temp = "If you die in the game, you die for real!"
|
||||
player_hp = 30
|
||||
player_mp = 10
|
||||
@@ -614,7 +615,7 @@
|
||||
L.Stun(200, ignore_canstun = TRUE) //you can't run :^)
|
||||
var/S = new /obj/singularity/academy(usr.loc)
|
||||
addtimer(CALLBACK(src, /atom/movable/proc/say, "[S] winks out, just as suddenly as it appeared."), 50)
|
||||
QDEL_IN(src, 50)
|
||||
QDEL_IN(S, 50)
|
||||
else
|
||||
event = null
|
||||
turns += 1
|
||||
|
||||
@@ -812,16 +812,18 @@
|
||||
to_chat(usr, "<span class='warning'>The [name] is already occupied!</span>")
|
||||
log_append_to_last("Permission denied.")
|
||||
return
|
||||
var/passed
|
||||
if(dna_lock)
|
||||
var/passed = FALSE
|
||||
if(user.has_dna())
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.dna.unique_enzymes==dna_lock)
|
||||
passed = 1
|
||||
else if(operation_allowed(user))
|
||||
passed = 1
|
||||
if(!passed)
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
passed = TRUE
|
||||
if (!passed)
|
||||
to_chat(user, "<span class='warning'>Access denied. [name] is secured with a DNA lock.</span>")
|
||||
log_append_to_last("Permission denied.")
|
||||
return
|
||||
if(!operation_allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied. Insufficient operation keycodes.</span>")
|
||||
log_append_to_last("Permission denied.")
|
||||
return
|
||||
if(user.buckled)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
anchored = TRUE
|
||||
light_range = 3
|
||||
var/movechance = 70
|
||||
var/obj/item/assembly/signaler/anomaly/aSignal = null
|
||||
var/obj/item/assembly/signaler/anomaly/aSignal
|
||||
var/area/impact_area
|
||||
|
||||
var/lifespan = 990
|
||||
@@ -26,10 +26,12 @@
|
||||
aSignal = new(src)
|
||||
aSignal.name = "[name] core"
|
||||
aSignal.code = rand(1,100)
|
||||
aSignal.anomaly_type = type
|
||||
|
||||
aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ)
|
||||
if(ISMULTIPLE(aSignal.frequency, 2))//signaller frequencies are always uneven!
|
||||
aSignal.frequency++
|
||||
var/frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ)
|
||||
if(ISMULTIPLE(frequency, 2))//signaller frequencies are always uneven!
|
||||
frequency++
|
||||
aSignal.set_frequency(frequency)
|
||||
|
||||
if(new_lifespan)
|
||||
lifespan = new_lifespan
|
||||
|
||||
@@ -766,3 +766,18 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// Returns a numeric value for sorting items used as parts in machines, so they can be replaced by the rped
|
||||
/obj/item/proc/get_part_rating()
|
||||
return 0
|
||||
|
||||
/obj/item/doMove(atom/destination)
|
||||
if (ismob(loc))
|
||||
var/mob/M = loc
|
||||
var/hand_index = M.get_held_index_of_item(src)
|
||||
if(hand_index)
|
||||
M.held_items[hand_index] = null
|
||||
M.update_inv_hands()
|
||||
if(M.client)
|
||||
M.client.screen -= src
|
||||
layer = initial(layer)
|
||||
plane = initial(plane)
|
||||
appearance_flags &= ~NO_CLIENT_COLOR
|
||||
dropped(M)
|
||||
return ..()
|
||||
|
||||
@@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
return "makepipe=[id]&type=[dirtype]"
|
||||
|
||||
/datum/pipe_info/meter
|
||||
icon_state = "meterX"
|
||||
icon_state = "meter"
|
||||
dirtype = PIPE_ONEDIR
|
||||
|
||||
/datum/pipe_info/meter/New(label)
|
||||
@@ -228,7 +228,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/icon_states/multiple_icons/pipes)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
|
||||
assets.send(user)
|
||||
|
||||
ui = new(user, src, ui_key, "rpd", name, 300, 550, master_ui, state)
|
||||
|
||||
@@ -178,20 +178,20 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
. = ..()
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/pda)
|
||||
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
|
||||
assets.send(user)
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = "<!DOCTYPE html><html><head><title>Personal Data Assistant</title><link href=\"https://fonts.googleapis.com/css?family=Orbitron|Share+Tech+Mono|VT323\" rel=\"stylesheet\"></head><body bgcolor=\"" + background_color + "\"><style>body{" + font_mode + "}ul,ol{list-style-type: none;}a, a:link, a:visited, a:active, a:hover { color: #000000;text-decoration:none; }img {border-style:none;}a img{padding-right: 9px;}</style>"
|
||||
dat += assets.css_tag()
|
||||
|
||||
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'><img src=pda_refresh.png>Refresh</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'>[PDAIMG(refresh)]Refresh</a>"
|
||||
|
||||
if ((!isnull(cartridge)) && (mode == 0))
|
||||
dat += " | <a href='byond://?src=[REF(src)];choice=Eject'><img src=pda_eject.png>Eject [cartridge]</a>"
|
||||
dat += " | <a href='byond://?src=[REF(src)];choice=Eject'>[PDAIMG(eject)]Eject [cartridge]</a>"
|
||||
if (mode)
|
||||
dat += " | <a href='byond://?src=[REF(src)];choice=Return'><img src=pda_menu.png>Return</a>"
|
||||
dat += " | <a href='byond://?src=[REF(src)];choice=Return'>[PDAIMG(menu)]Return</a>"
|
||||
|
||||
if (mode == 0)
|
||||
dat += "<div align=\"center\">"
|
||||
@@ -205,7 +205,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
if (!owner)
|
||||
dat += "Warning: No owner information entered. Please swipe card.<br><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'><img src=pda_refresh.png>Retry</a>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Refresh'>[PDAIMG(refresh)]Retry</a>"
|
||||
else
|
||||
switch (mode)
|
||||
if (0)
|
||||
@@ -221,38 +221,38 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
|
||||
dat += "<h4>General Functions</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=1'><img src=pda_notes.png>Notekeeper</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=2'><img src=pda_mail.png>Messenger</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=1'>[PDAIMG(notes)]Notekeeper</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=2'>[PDAIMG(mail)]Messenger</a></li>"
|
||||
|
||||
if (cartridge)
|
||||
if (cartridge.access & CART_CLOWN)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Honk'><img src=pda_honk.png>Honk Synthesizer</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Trombone'><img src=pda_honk.png>Sad Trombone</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Honk'>[PDAIMG(honk)]Honk Synthesizer</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Trombone'>[PDAIMG(honk)]Sad Trombone</a></li>"
|
||||
if (cartridge.access & CART_MANIFEST)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=41'><img src=pda_notes.png>View Crew Manifest</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=41'>[PDAIMG(notes)]View Crew Manifest</a></li>"
|
||||
if(cartridge.access & CART_STATUS_DISPLAY)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=42'><img src=pda_status.png>Set Status Display</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=42'>[PDAIMG(status)]Set Status Display</a></li>"
|
||||
dat += "</ul>"
|
||||
if (cartridge.access & CART_ENGINE)
|
||||
dat += "<h4>Engineering Functions</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=43'><img src=pda_power.png>Power Monitor</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=43'>[PDAIMG(power)]Power Monitor</a></li>"
|
||||
dat += "</ul>"
|
||||
if (cartridge.access & CART_MEDICAL)
|
||||
dat += "<h4>Medical Functions</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=44'><img src=pda_medical.png>Medical Records</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Medical Scan'><img src=pda_scanner.png>[scanmode == 1 ? "Disable" : "Enable"] Medical Scanner</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=44'>[PDAIMG(medical)]Medical Records</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Medical Scan'>[PDAIMG(scanner)][scanmode == 1 ? "Disable" : "Enable"] Medical Scanner</a></li>"
|
||||
dat += "</ul>"
|
||||
if (cartridge.access & CART_SECURITY)
|
||||
dat += "<h4>Security Functions</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=45'><img src=pda_cuffs.png>Security Records</A></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=45'>[PDAIMG(cuffs)]Security Records</A></li>"
|
||||
dat += "</ul>"
|
||||
if(cartridge.access & CART_QUARTERMASTER)
|
||||
dat += "<h4>Quartermaster Functions:</h4>"
|
||||
dat += "<ul>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=47'><img src=pda_crate.png>Supply Records</A></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=47'>[PDAIMG(crate)]Supply Records</A></li>"
|
||||
dat += "</ul>"
|
||||
dat += "</ul>"
|
||||
|
||||
@@ -260,25 +260,25 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
dat += "<ul>"
|
||||
if (cartridge)
|
||||
if(cartridge.bot_access_flags)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=54'><img src=pda_medbot.png>Bots Access</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=54'>[PDAIMG(medbot)]Bots Access</a></li>"
|
||||
if (cartridge.access & CART_JANITOR)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=49'><img src=pda_bucket.png>Custodial Locator</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=49'>[PDAIMG(bucket)]Custodial Locator</a></li>"
|
||||
if (istype(cartridge.radio))
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=40'><img src=pda_signaler.png>Signaler System</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=40'>[PDAIMG(signaler)]Signaler System</a></li>"
|
||||
if (cartridge.access & CART_NEWSCASTER)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=53'><img src=pda_notes.png>Newscaster Access </a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=53'>[PDAIMG(notes)]Newscaster Access </a></li>"
|
||||
if (cartridge.access & CART_REAGENT_SCANNER)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Reagent Scan'><img src=pda_reagent.png>[scanmode == 3 ? "Disable" : "Enable"] Reagent Scanner</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Reagent Scan'>[PDAIMG(reagent)][scanmode == 3 ? "Disable" : "Enable"] Reagent Scanner</a></li>"
|
||||
if (cartridge.access & CART_ENGINE)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Halogen Counter'><img src=pda_reagent.png>[scanmode == 4 ? "Disable" : "Enable"] Halogen Counter</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Halogen Counter'>[PDAIMG(reagent)][scanmode == 4 ? "Disable" : "Enable"] Halogen Counter</a></li>"
|
||||
if (cartridge.access & CART_ATMOS)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Gas Scan'><img src=pda_reagent.png>[scanmode == 5 ? "Disable" : "Enable"] Gas Scanner</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Gas Scan'>[PDAIMG(reagent)][scanmode == 5 ? "Disable" : "Enable"] Gas Scanner</a></li>"
|
||||
if (cartridge.access & CART_REMOTE_DOOR)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Toggle Door'><img src=pda_rdoor.png>Toggle Remote Door</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Toggle Door'>[PDAIMG(rdoor)]Toggle Remote Door</a></li>"
|
||||
if (cartridge.access & CART_DRONEPHONE)
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Drone Phone'><img src=pda_dronephone.png>Drone Phone</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=3'><img src=pda_atmos.png>Atmospheric Scan</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Light'><img src=pda_flashlight.png>[fon ? "Disable" : "Enable"] Flashlight</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Drone Phone'>[PDAIMG(dronephone)]Drone Phone</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=3'>[PDAIMG(atmos)]Atmospheric Scan</a></li>"
|
||||
dat += "<li><a href='byond://?src=[REF(src)];choice=Light'>[PDAIMG(flashlight)][fon ? "Disable" : "Enable"] Flashlight</a></li>"
|
||||
if (pai)
|
||||
if(pai.loc != src)
|
||||
pai = null
|
||||
@@ -289,23 +289,23 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
dat += "</ul>"
|
||||
|
||||
if (1)
|
||||
dat += "<h4><img src=pda_notes.png> Notekeeper V2.2</h4>"
|
||||
dat += "<h4>[PDAIMG(notes)] Notekeeper V2.2</h4>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Edit'>Edit</a><br>"
|
||||
if(notescanned)
|
||||
dat += "(This is a scanned image, editing it may cause some text formatting to change.)<br>"
|
||||
dat += "<HR><font face=\"[PEN_FONT]\">[(!notehtml ? note : notehtml)]</font>"
|
||||
|
||||
if (2)
|
||||
dat += "<h4><img src=pda_mail.png> SpaceMessenger V3.9.6</h4>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Toggle Ringer'><img src=pda_bell.png>Ringer: [silent == 1 ? "Off" : "On"]</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Toggle Messenger'><img src=pda_mail.png>Send / Receive: [toff == 1 ? "Off" : "On"]</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Ringtone'><img src=pda_bell.png>Set Ringtone</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=21'><img src=pda_mail.png>Messages</a><br>"
|
||||
dat += "<h4>[PDAIMG(mail)] SpaceMessenger V3.9.6</h4>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Toggle Ringer'>[PDAIMG(bell)]Ringer: [silent == 1 ? "Off" : "On"]</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Toggle Messenger'>[PDAIMG(mail)]Send / Receive: [toff == 1 ? "Off" : "On"]</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Ringtone'>[PDAIMG(bell)]Set Ringtone</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=21'>[PDAIMG(mail)]Messages</a><br>"
|
||||
|
||||
if(cartridge)
|
||||
dat += cartridge.message_header()
|
||||
|
||||
dat += "<h4><img src=pda_menu.png> Detected PDAs</h4>"
|
||||
dat += "<h4>[PDAIMG(menu)] Detected PDAs</h4>"
|
||||
|
||||
dat += "<ul>"
|
||||
var/count = 0
|
||||
@@ -326,16 +326,16 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=MessageAll'>Send To All</a>"
|
||||
|
||||
if(21)
|
||||
dat += "<h4><img src=pda_mail.png> SpaceMessenger V3.9.6</h4>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Clear'><img src=pda_blank.png>Clear Messages</a>"
|
||||
dat += "<h4>[PDAIMG(mail)] SpaceMessenger V3.9.6</h4>"
|
||||
dat += "<a href='byond://?src=[REF(src)];choice=Clear'>[PDAIMG(blank)]Clear Messages</a>"
|
||||
|
||||
dat += "<h4><img src=pda_mail.png> Messages</h4>"
|
||||
dat += "<h4>[PDAIMG(mail)] Messages</h4>"
|
||||
|
||||
dat += tnote
|
||||
dat += "<br>"
|
||||
|
||||
if (3)
|
||||
dat += "<h4><img src=pda_atmos.png> Atmospheric Readings</h4>"
|
||||
dat += "<h4>[PDAIMG(atmos)] Atmospheric Readings</h4>"
|
||||
|
||||
var/turf/T = user.loc
|
||||
if (isnull(T))
|
||||
@@ -617,7 +617,8 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
return
|
||||
if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY))
|
||||
return
|
||||
|
||||
if(prob(1))
|
||||
message += "\nSent from my PDA"
|
||||
// Send the signal
|
||||
var/list/string_targets = list()
|
||||
for (var/obj/item/pda/P in targets)
|
||||
@@ -1017,4 +1018,4 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
#undef PDA_SCANNER_REAGENT
|
||||
#undef PDA_SCANNER_HALOGEN
|
||||
#undef PDA_SCANNER_GAS
|
||||
#undef PDA_SPAM_DELAY
|
||||
#undef PDA_SPAM_DELAY
|
||||
|
||||
@@ -207,13 +207,12 @@
|
||||
|
||||
frequency.post_signal(src, status_signal)
|
||||
|
||||
|
||||
/obj/item/cartridge/proc/generate_menu(mob/user)
|
||||
if(!host_pda)
|
||||
return
|
||||
switch(host_pda.mode)
|
||||
if(40) //signaller
|
||||
menu = "<h4><img src=pda_signaler.png> Remote Signaling System</h4>"
|
||||
menu = "<h4>[PDAIMG(signaler)] Remote Signaling System</h4>"
|
||||
|
||||
menu += {"
|
||||
<a href='byond://?src=[REF(src)];choice=Send Signal'>Send Signal</A><BR>
|
||||
@@ -232,7 +231,7 @@ Code:
|
||||
<a href='byond://?src=[REF(src)];choice=Signal Code;scode=5'>+</a><br>"}
|
||||
if (41) //crew manifest
|
||||
|
||||
menu = "<h4><img src=pda_notes.png> Crew Manifest</h4>"
|
||||
menu = "<h4>[PDAIMG(notes)] Crew Manifest</h4>"
|
||||
menu += "Entries cannot be modified from this terminal.<br><br>"
|
||||
if(GLOB.data_core.general)
|
||||
for (var/datum/data/record/t in sortRecord(GLOB.data_core.general))
|
||||
@@ -241,7 +240,7 @@ Code:
|
||||
|
||||
|
||||
if (42) //status displays
|
||||
menu = "<h4><img src=pda_status.png> Station Status Display Interlink</h4>"
|
||||
menu = "<h4>[PDAIMG(status)] Station Status Display Interlink</h4>"
|
||||
|
||||
menu += "\[ <A HREF='?src=[REF(src)];choice=Status;statdisp=blank'>Clear</A> \]<BR>"
|
||||
menu += "\[ <A HREF='?src=[REF(src)];choice=Status;statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
|
||||
@@ -254,7 +253,7 @@ Code:
|
||||
menu += " <A HREF='?src=[REF(src)];choice=Status;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR>"
|
||||
|
||||
if (43)
|
||||
menu = "<h4><img src=pda_power.png> Power Monitors - Please select one</h4><BR>"
|
||||
menu = "<h4>[PDAIMG(power)] Power Monitors - Please select one</h4><BR>"
|
||||
powmonitor = null
|
||||
powermonitors = list()
|
||||
var/powercount = 0
|
||||
@@ -280,7 +279,7 @@ Code:
|
||||
menu += "</FONT>"
|
||||
|
||||
if (433)
|
||||
menu = "<h4><img src=pda_power.png> Power Monitor </h4><BR>"
|
||||
menu = "<h4>[PDAIMG(power)] Power Monitor </h4><BR>"
|
||||
if(!powmonitor)
|
||||
menu += "<span class='danger'>No connection<BR></span>"
|
||||
else
|
||||
@@ -307,13 +306,13 @@ Code:
|
||||
menu += "</FONT></PRE>"
|
||||
|
||||
if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working.
|
||||
menu = "<h4><img src=pda_medical.png> Medical Record List</h4>"
|
||||
menu = "<h4>[PDAIMG(medical)] Medical Record List</h4>"
|
||||
if(GLOB.data_core.general)
|
||||
for(var/datum/data/record/R in sortRecord(GLOB.data_core.general))
|
||||
menu += "<a href='byond://?src=[REF(src)];choice=Medical Records;target=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<br>"
|
||||
menu += "<br>"
|
||||
if(441)
|
||||
menu = "<h4><img src=pda_medical.png> Medical Record</h4>"
|
||||
menu = "<h4>[PDAIMG(medical)] Medical Record</h4>"
|
||||
|
||||
if(active1 in GLOB.data_core.general)
|
||||
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
|
||||
@@ -328,7 +327,7 @@ Code:
|
||||
|
||||
menu += "<br>"
|
||||
|
||||
menu += "<h4><img src=pda_medical.png> Medical Data</h4>"
|
||||
menu += "<h4>[PDAIMG(medical)] Medical Data</h4>"
|
||||
if(active2 in GLOB.data_core.medical)
|
||||
menu += "Blood Type: [active2.fields["blood_type"]]<br><br>"
|
||||
|
||||
@@ -350,14 +349,14 @@ Code:
|
||||
|
||||
menu += "<br>"
|
||||
if (45) //security records
|
||||
menu = "<h4><img src=pda_cuffs.png> Security Record List</h4>"
|
||||
menu = "<h4>[PDAIMG(cuffs)] Security Record List</h4>"
|
||||
if(GLOB.data_core.general)
|
||||
for (var/datum/data/record/R in sortRecord(GLOB.data_core.general))
|
||||
menu += "<a href='byond://?src=[REF(src)];choice=Security Records;target=[R.fields["id"]]'>[R.fields["id"]]: [R.fields["name"]]<br>"
|
||||
|
||||
menu += "<br>"
|
||||
if(451)
|
||||
menu = "<h4><img src=pda_cuffs.png> Security Record</h4>"
|
||||
menu = "<h4>[PDAIMG(cuffs)] Security Record</h4>"
|
||||
|
||||
if(active1 in GLOB.data_core.general)
|
||||
menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]<br>"
|
||||
@@ -372,7 +371,7 @@ Code:
|
||||
|
||||
menu += "<br>"
|
||||
|
||||
menu += "<h4><img src=pda_cuffs.png> Security Data</h4>"
|
||||
menu += "<h4>[PDAIMG(cuffs)] Security Data</h4>"
|
||||
if(active3 in GLOB.data_core.security)
|
||||
menu += "Criminal Status: [active3.fields["criminal"]]<br>"
|
||||
|
||||
@@ -418,7 +417,7 @@ Code:
|
||||
menu += "<br>"
|
||||
|
||||
if (47) //quartermaster order records
|
||||
menu = "<h4><img src=pda_crate.png> Supply Record Interlink</h4>"
|
||||
menu = "<h4>[PDAIMG(crate)] Supply Record Interlink</h4>"
|
||||
|
||||
menu += "<BR><B>Supply shuttle</B><BR>"
|
||||
menu += "Location: "
|
||||
@@ -449,7 +448,7 @@ Code:
|
||||
menu += "</ol><font size=\"-3\">Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
|
||||
|
||||
if (49) //janitorial locator
|
||||
menu = "<h4><img src=pda_bucket.png> Persistent Custodial Object Locator</h4>"
|
||||
menu = "<h4>[PDAIMG(bucket)] Persistent Custodial Object Locator</h4>"
|
||||
|
||||
var/turf/cl = get_turf(src)
|
||||
if (cl)
|
||||
@@ -511,7 +510,7 @@ Code:
|
||||
menu += "<br><br><A href='byond://?src=[REF(src)];choice=49'>Refresh GPS Locator</a>"
|
||||
|
||||
if (53) // Newscaster
|
||||
menu = "<h4><img src=pda_notes.png> Newscaster Access</h4>"
|
||||
menu = "<h4>[PDAIMG(notes)] Newscaster Access</h4>"
|
||||
menu += "<br> Current Newsfeed: <A href='byond://?src=[REF(src)];choice=Newscaster Switch Channel'>[current_channel ? current_channel : "None"]</a> <br>"
|
||||
var/datum/newscaster/feed_channel/current
|
||||
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
|
||||
@@ -533,7 +532,7 @@ Code:
|
||||
menu += "<br> <A href='byond://?src=[REF(src)];choice=Newscaster Message'>Post Message</a>"
|
||||
|
||||
if (54) // Beepsky, Medibot, Floorbot, and Cleanbot access
|
||||
menu = "<h4><img src=pda_medbot.png> Bots Interlink</h4>"
|
||||
menu = "<h4>[PDAIMG(medbot)] Bots Interlink</h4>"
|
||||
bot_control()
|
||||
if (99) //Newscaster message permission error
|
||||
menu = "<h5> ERROR : NOT AUTHORIZED [host_pda.id ? "" : "- ID SLOT EMPTY"] </h5>"
|
||||
@@ -652,7 +651,7 @@ Code:
|
||||
var/mob/living/simple_animal/bot/Bot
|
||||
|
||||
if(active_bot)
|
||||
menu += "<B>[active_bot]</B><BR> Status: (<A href='byond://?src=[REF(src)];op=control;bot=[REF(active_bot)]'><img src=pda_refresh.png><i>refresh</i></A>)<BR>"
|
||||
menu += "<B>[active_bot]</B><BR> Status: (<A href='byond://?src=[REF(src)];op=control;bot=[REF(active_bot)]'>[PDAIMG(refresh)]<i>refresh</i></A>)<BR>"
|
||||
menu += "Model: [active_bot.model]<BR>"
|
||||
menu += "Location: [get_area(active_bot)]<BR>"
|
||||
menu += "Mode: [active_bot.get_mode()]"
|
||||
@@ -688,9 +687,9 @@ Code:
|
||||
menu += "\[<A href='byond://?src=[REF(src)];op=summon'>Summon Bot</A>\]<BR>" //summon
|
||||
menu += "Keep an ID inserted to upload access codes upon summoning."
|
||||
|
||||
menu += "<HR><A href='byond://?src=[REF(src)];op=botlist'><img src=pda_back.png>Return to bot list</A>"
|
||||
menu += "<HR><A href='byond://?src=[REF(src)];op=botlist'>[PDAIMG(back)]Return to bot list</A>"
|
||||
else
|
||||
menu += "<BR><A href='byond://?src=[REF(src)];op=botlist'><img src=pda_refresh.png>Scan for active bots</A><BR><BR>"
|
||||
menu += "<BR><A href='byond://?src=[REF(src)];op=botlist'>[PDAIMG(refresh)]Scan for active bots</A><BR><BR>"
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/zlevel = current_turf.z
|
||||
var/botcount = 0
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
return (H.z != 0 || (there && there.z == here.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
|
||||
/obj/item/shield/riot/roman/fake
|
||||
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
||||
block_chance = 0
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
/obj/item/shield/riot/buckler
|
||||
name = "wooden buckler"
|
||||
desc = "A medieval wooden buckler."
|
||||
|
||||
@@ -453,7 +453,7 @@
|
||||
/obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun/PopulateContents()
|
||||
for(var/i in 1 to 6)
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/stun(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/slug(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/dragon(src)
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
/obj/item/storage/backpack/duffelbag/syndie/bulldogbundle/PopulateContents()
|
||||
new /obj/item/ammo_box/magazine/m12g(src)
|
||||
new /obj/item/gun/ballistic/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src)
|
||||
new /obj/item/ammo_box/magazine/m12g/stun(src)
|
||||
new /obj/item/clothing/glasses/thermal/syndi(src)
|
||||
|
||||
/obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle
|
||||
|
||||
@@ -111,8 +111,8 @@
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc
|
||||
new /obj/item/gun/ballistic/automatic/shotgun/bulldog/unrestricted(src) // 8 tc
|
||||
new /obj/item/implanter/explosive(src) // 2 tc
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
|
||||
new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
|
||||
new /obj/item/ammo_box/magazine/m12g(src) // 2 tc
|
||||
new /obj/item/ammo_box/magazine/m12g(src) // 2 tc
|
||||
new /obj/item/grenade/plastic/c4 (src) // 1 tc
|
||||
new /obj/item/grenade/plastic/c4 (src) // 1 tc
|
||||
new /obj/item/card/emag(src) // 6 tc
|
||||
|
||||
@@ -219,3 +219,17 @@
|
||||
if(active_portal_pairs[i] == P)
|
||||
return DESTINATION_PORTAL
|
||||
return FALSE
|
||||
|
||||
/obj/item/hand_tele/suicide_act(mob/user)
|
||||
if(iscarbon(user))
|
||||
user.visible_message("<span class='suicide'>[user] is creating a weak portal and sticking [user.p_their()] head through! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
var/mob/living/carbon/itemUser = user
|
||||
var/obj/item/bodypart/head/head = itemUser.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(head)
|
||||
head.drop_limb()
|
||||
var/list/safeLevels = SSmapping.levels_by_any_trait(list(ZTRAIT_SPACE_RUINS, ZTRAIT_LAVA_RUINS, ZTRAIT_STATION, ZTRAIT_MINING))
|
||||
head.forceMove(locate(rand(1, world.maxx), rand(1, world.maxy), pick(safeLevels)))
|
||||
itemUser.visible_message("<span class='suicide'>The portal snaps closed taking [user]'s head with it!</span>")
|
||||
else
|
||||
itemUser.visible_message("<span class='suicide'>[user] looks even further depressed as they realize they do not have a head...and suddenly dies of shame!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
//the essential proc to call when an obj must receive damage of any kind.
|
||||
/obj/proc/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0)
|
||||
if(QDELETED(src))
|
||||
stack_trace("[src] taking damage after deletion")
|
||||
return
|
||||
if(sound_effect)
|
||||
play_attack_sound(damage_amount, damage_type, damage_flag)
|
||||
if(!(resistance_flags & INDESTRUCTIBLE) && obj_integrity > 0)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
|
||||
M.show_message(rendered, 2)
|
||||
to_chat(M, rendered)
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Dsay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -33,10 +33,8 @@
|
||||
desc = "A sword humming with unholy energy. It glows with a dim red light."
|
||||
icon_state = "cultblade"
|
||||
item_state = "cultblade"
|
||||
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
|
||||
inhand_x_dimension = 64
|
||||
inhand_y_dimension = 64
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
sharpness = IS_SHARP
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/AttackingTarget()
|
||||
if(!melee_damage_disguised)
|
||||
if(morphed && !melee_damage_disguised)
|
||||
to_chat(src, "<span class='warning'>You can not attack while disguised!</span>")
|
||||
return
|
||||
if(isliving(target)) //Eat Corpses to regen health
|
||||
|
||||
@@ -111,7 +111,7 @@ Code:
|
||||
var/obj/item/assembly/signaler/signaler2 = W
|
||||
if(secured && signaler2.secured)
|
||||
code = signaler2.code
|
||||
frequency = signaler2.frequency
|
||||
set_frequency(signaler2.frequency)
|
||||
to_chat(user, "You transfer the frequency and code of \the [signaler2.name] to \the [name]")
|
||||
..()
|
||||
|
||||
@@ -186,6 +186,7 @@ Code:
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
var/anomaly_type = /obj/effect/anomaly
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
|
||||
if(!signal)
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again.
|
||||
/datum/gas_reaction/fusion
|
||||
exclude = FALSE
|
||||
exclude = TRUE
|
||||
priority = 2
|
||||
name = "Plasmic Fusion"
|
||||
id = "fusion"
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
export_types = list(/obj/machinery/iv_drip)
|
||||
|
||||
/datum/export/large/barrier
|
||||
cost = 325
|
||||
cost = 100
|
||||
unit_name = "security barrier"
|
||||
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
|
||||
|
||||
|
||||
@@ -1649,8 +1649,9 @@
|
||||
. = ..()
|
||||
if(prob(50))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
|
||||
qdel(D)
|
||||
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
|
||||
if(D.gender == FEMALE)
|
||||
qdel(D)
|
||||
new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
|
||||
|
||||
/datum/supply_pack/critter/cow
|
||||
name = "Cow Crate"
|
||||
|
||||
@@ -161,8 +161,12 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
return new type()
|
||||
return GLOB.asset_datums[type]
|
||||
|
||||
/datum/asset
|
||||
var/_abstract = /datum/asset
|
||||
|
||||
/datum/asset/New()
|
||||
GLOB.asset_datums[type] = src
|
||||
register()
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
@@ -170,20 +174,173 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
/datum/asset/proc/send(client)
|
||||
return
|
||||
|
||||
|
||||
//If you don't need anything complicated.
|
||||
/datum/asset/simple
|
||||
_abstract = /datum/asset/simple
|
||||
var/assets = list()
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/simple/register()
|
||||
for(var/asset_name in assets)
|
||||
register_asset(asset_name, assets[asset_name])
|
||||
|
||||
/datum/asset/simple/send(client)
|
||||
send_asset_list(client,assets,verify)
|
||||
|
||||
|
||||
// For registering or sending multiple others at once
|
||||
/datum/asset/group
|
||||
_abstract = /datum/asset/group
|
||||
var/list/children
|
||||
|
||||
/datum/asset/group/register()
|
||||
for(var/type in children)
|
||||
get_asset_datum(type)
|
||||
|
||||
/datum/asset/group/send(client/C)
|
||||
for(var/type in children)
|
||||
var/datum/asset/A = get_asset_datum(type)
|
||||
A.send(C)
|
||||
|
||||
|
||||
// spritesheet implementation - coalesces various icons into a single .png file
|
||||
// and uses CSS to select icons out of that file - saves on transferring some
|
||||
// 1400-odd individual PNG files
|
||||
#define SPR_SIZE 1
|
||||
#define SPR_IDX 2
|
||||
#define SPRSZ_COUNT 1
|
||||
#define SPRSZ_ICON 2
|
||||
#define SPRSZ_STRIPPED 3
|
||||
|
||||
/datum/asset/spritesheet
|
||||
_abstract = /datum/asset/spritesheet
|
||||
var/name
|
||||
var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped)
|
||||
var/list/sprites = list() // "foo_bar" -> list("32x32", 5)
|
||||
var/verify = FALSE
|
||||
|
||||
/datum/asset/spritesheet/register()
|
||||
if (!name)
|
||||
CRASH("spritesheet [type] cannot register without a name")
|
||||
ensure_stripped()
|
||||
|
||||
var/res_name = "spritesheet_[name].css"
|
||||
var/fname = "data/spritesheets/[res_name]"
|
||||
call("rust_g", "file_write")(generate_css(), fname)
|
||||
register_asset(res_name, file(fname))
|
||||
|
||||
for(var/size_id in sizes)
|
||||
var/size = sizes[size_id]
|
||||
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
|
||||
|
||||
/datum/asset/spritesheet/send(client/C)
|
||||
if (!name)
|
||||
return
|
||||
var/all = list("spritesheet_[name].css")
|
||||
for(var/size_id in sizes)
|
||||
all += "[name]_[size_id].png"
|
||||
send_asset_list(C, all, verify)
|
||||
|
||||
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
|
||||
for(var/size_id in sizes_to_strip)
|
||||
var/size = sizes[size_id]
|
||||
if (size[SPRSZ_STRIPPED])
|
||||
continue
|
||||
|
||||
// save flattened version
|
||||
var/fname = "data/spritesheets/[name]_[size_id].png"
|
||||
fcopy(size[SPRSZ_ICON], fname)
|
||||
var/error = call("rust_g", "dmi_strip_metadata")(fname)
|
||||
if(length(error))
|
||||
stack_trace("Failed to strip [name]_[size_id].png: [error]")
|
||||
size[SPRSZ_STRIPPED] = icon(fname)
|
||||
|
||||
/datum/asset/spritesheet/proc/generate_css()
|
||||
var/list/out = list()
|
||||
|
||||
for (var/size_id in sizes)
|
||||
var/size = sizes[size_id]
|
||||
var/icon/tiny = size[SPRSZ_ICON]
|
||||
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[name]_[size_id].png') no-repeat;}"
|
||||
|
||||
for (var/sprite_id in sprites)
|
||||
var/sprite = sprites[sprite_id]
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
var/idx = sprite[SPR_IDX]
|
||||
var/size = sizes[size_id]
|
||||
|
||||
var/icon/tiny = size[SPRSZ_ICON]
|
||||
var/icon/big = size[SPRSZ_STRIPPED]
|
||||
var/per_line = big.Width() / tiny.Width()
|
||||
var/x = (idx % per_line) * tiny.Width()
|
||||
var/y = round(idx / per_line) * tiny.Height()
|
||||
|
||||
out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}"
|
||||
|
||||
return out.Join("\n")
|
||||
|
||||
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
|
||||
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
|
||||
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
|
||||
return
|
||||
var/size_id = "[I.Width()]x[I.Height()]"
|
||||
var/size = sizes[size_id]
|
||||
|
||||
if (sprites[sprite_name])
|
||||
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
|
||||
|
||||
if (size)
|
||||
var/position = size[SPRSZ_COUNT]++
|
||||
var/icon/sheet = size[SPRSZ_ICON]
|
||||
size[SPRSZ_STRIPPED] = null
|
||||
sheet.Insert(I, icon_state=sprite_name)
|
||||
sprites[sprite_name] = list(size_id, position)
|
||||
else
|
||||
sizes[size_id] = size = list(1, I, null)
|
||||
sprites[sprite_name] = list(size_id, 0)
|
||||
|
||||
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
|
||||
if (length(prefix))
|
||||
prefix = "[prefix]-"
|
||||
|
||||
if (!directions)
|
||||
directions = list(SOUTH)
|
||||
|
||||
for (var/icon_state_name in icon_states(I))
|
||||
for (var/direction in directions)
|
||||
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
|
||||
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
|
||||
|
||||
/datum/asset/spritesheet/proc/css_tag()
|
||||
return {"<link rel="stylesheet" href="spritesheet_[name].css" />"}
|
||||
|
||||
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
|
||||
var/sprite = sprites[sprite_name]
|
||||
if (!sprite)
|
||||
return null
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
return {"<span class="[name][size_id] [sprite_name]"></span>"}
|
||||
|
||||
#undef SPR_SIZE
|
||||
#undef SPR_IDX
|
||||
#undef SPRSZ_COUNT
|
||||
#undef SPRSZ_ICON
|
||||
#undef SPRSZ_STRIPPED
|
||||
|
||||
|
||||
/datum/asset/spritesheet/simple
|
||||
_abstract = /datum/asset/spritesheet/simple
|
||||
var/list/assets
|
||||
|
||||
/datum/asset/spritesheet/simple/register()
|
||||
for (var/key in assets)
|
||||
Insert(key, assets[key])
|
||||
..()
|
||||
|
||||
//Generates assets based on iconstates of a single icon
|
||||
/datum/asset/simple/icon_states
|
||||
_abstract = /datum/asset/simple/icon_states
|
||||
var/icon
|
||||
var/list/directions = list(SOUTH)
|
||||
var/frame = 1
|
||||
@@ -209,6 +366,7 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
register_asset(asset_name, asset)
|
||||
|
||||
/datum/asset/simple/icon_states/multiple_icons
|
||||
_abstract = /datum/asset/simple/icon_states/multiple_icons
|
||||
var/list/icons
|
||||
|
||||
/datum/asset/simple/icon_states/multiple_icons/register()
|
||||
@@ -260,50 +418,52 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif'
|
||||
)
|
||||
|
||||
/datum/asset/simple/pda
|
||||
/datum/asset/spritesheet/simple/pda
|
||||
name = "pda"
|
||||
assets = list(
|
||||
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
|
||||
"pda_back.png" = 'icons/pda_icons/pda_back.png',
|
||||
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
|
||||
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
|
||||
"pda_boom.png" = 'icons/pda_icons/pda_boom.png',
|
||||
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
|
||||
"pda_medbot.png" = 'icons/pda_icons/pda_medbot.png',
|
||||
"pda_floorbot.png" = 'icons/pda_icons/pda_floorbot.png',
|
||||
"pda_cleanbot.png" = 'icons/pda_icons/pda_cleanbot.png',
|
||||
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
|
||||
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
|
||||
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
|
||||
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
|
||||
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
|
||||
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
|
||||
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
|
||||
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
|
||||
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
|
||||
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
|
||||
"pda_power.png" = 'icons/pda_icons/pda_power.png',
|
||||
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
|
||||
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
|
||||
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
|
||||
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
|
||||
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
|
||||
"pda_status.png" = 'icons/pda_icons/pda_status.png',
|
||||
"pda_dronephone.png" = 'icons/pda_icons/pda_dronephone.png'
|
||||
"atmos" = 'icons/pda_icons/pda_atmos.png',
|
||||
"back" = 'icons/pda_icons/pda_back.png',
|
||||
"bell" = 'icons/pda_icons/pda_bell.png',
|
||||
"blank" = 'icons/pda_icons/pda_blank.png',
|
||||
"boom" = 'icons/pda_icons/pda_boom.png',
|
||||
"bucket" = 'icons/pda_icons/pda_bucket.png',
|
||||
"medbot" = 'icons/pda_icons/pda_medbot.png',
|
||||
"floorbot" = 'icons/pda_icons/pda_floorbot.png',
|
||||
"cleanbot" = 'icons/pda_icons/pda_cleanbot.png',
|
||||
"crate" = 'icons/pda_icons/pda_crate.png',
|
||||
"cuffs" = 'icons/pda_icons/pda_cuffs.png',
|
||||
"eject" = 'icons/pda_icons/pda_eject.png',
|
||||
"flashlight" = 'icons/pda_icons/pda_flashlight.png',
|
||||
"honk" = 'icons/pda_icons/pda_honk.png',
|
||||
"mail" = 'icons/pda_icons/pda_mail.png',
|
||||
"medical" = 'icons/pda_icons/pda_medical.png',
|
||||
"menu" = 'icons/pda_icons/pda_menu.png',
|
||||
"mule" = 'icons/pda_icons/pda_mule.png',
|
||||
"notes" = 'icons/pda_icons/pda_notes.png',
|
||||
"power" = 'icons/pda_icons/pda_power.png',
|
||||
"rdoor" = 'icons/pda_icons/pda_rdoor.png',
|
||||
"reagent" = 'icons/pda_icons/pda_reagent.png',
|
||||
"refresh" = 'icons/pda_icons/pda_refresh.png',
|
||||
"scanner" = 'icons/pda_icons/pda_scanner.png',
|
||||
"signaler" = 'icons/pda_icons/pda_signaler.png',
|
||||
"status" = 'icons/pda_icons/pda_status.png',
|
||||
"dronephone" = 'icons/pda_icons/pda_dronephone.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/paper
|
||||
/datum/asset/spritesheet/simple/paper
|
||||
name = "paper"
|
||||
assets = list(
|
||||
"large_stamp-clown.png" = 'icons/stamp_icons/large_stamp-clown.png',
|
||||
"large_stamp-deny.png" = 'icons/stamp_icons/large_stamp-deny.png',
|
||||
"large_stamp-ok.png" = 'icons/stamp_icons/large_stamp-ok.png',
|
||||
"large_stamp-hop.png" = 'icons/stamp_icons/large_stamp-hop.png',
|
||||
"large_stamp-cmo.png" = 'icons/stamp_icons/large_stamp-cmo.png',
|
||||
"large_stamp-ce.png" = 'icons/stamp_icons/large_stamp-ce.png',
|
||||
"large_stamp-hos.png" = 'icons/stamp_icons/large_stamp-hos.png',
|
||||
"large_stamp-rd.png" = 'icons/stamp_icons/large_stamp-rd.png',
|
||||
"large_stamp-cap.png" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||
"large_stamp-qm.png" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
"stamp-clown" = 'icons/stamp_icons/large_stamp-clown.png',
|
||||
"stamp-deny" = 'icons/stamp_icons/large_stamp-deny.png',
|
||||
"stamp-ok" = 'icons/stamp_icons/large_stamp-ok.png',
|
||||
"stamp-hop" = 'icons/stamp_icons/large_stamp-hop.png',
|
||||
"stamp-cmo" = 'icons/stamp_icons/large_stamp-cmo.png',
|
||||
"stamp-ce" = 'icons/stamp_icons/large_stamp-ce.png',
|
||||
"stamp-hos" = 'icons/stamp_icons/large_stamp-hos.png',
|
||||
"stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png',
|
||||
"stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||
"stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||
"stamp-law" = 'icons/stamp_icons/large_stamp-law.png'
|
||||
)
|
||||
|
||||
/datum/asset/simple/IRV
|
||||
@@ -335,6 +495,9 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
"changelog.css" = 'html/changelog.css'
|
||||
)
|
||||
|
||||
/datum/asset/group/goonchat
|
||||
children = list(/datum/asset/simple/goonchat, /datum/asset/spritesheet/goonchat)
|
||||
|
||||
/datum/asset/simple/goonchat
|
||||
verify = FALSE
|
||||
assets = list(
|
||||
@@ -350,6 +513,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
|
||||
)
|
||||
|
||||
/datum/asset/spritesheet/goonchat
|
||||
name = "chat"
|
||||
|
||||
/datum/asset/spritesheet/goonchat/register()
|
||||
InsertAll("emoji", 'icons/emoji.dmi')
|
||||
|
||||
// pre-loading all lanugage icons also helps to avoid meta
|
||||
InsertAll("language", 'icons/misc/language.dmi')
|
||||
// catch languages which are pulling icons from another file
|
||||
for(var/path in typesof(/datum/language))
|
||||
var/datum/language/L = path
|
||||
var/icon = initial(L.icon)
|
||||
if (icon != 'icons/misc/language.dmi')
|
||||
var/icon_state = initial(L.icon_state)
|
||||
Insert("language-[icon_state]", icon, icon_state=icon_state)
|
||||
|
||||
..()
|
||||
|
||||
/datum/asset/simple/permissions
|
||||
assets = list(
|
||||
"padlock.png" = 'html/padlock.png'
|
||||
@@ -362,26 +543,19 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/datum/language/L = new path ()
|
||||
L.get_icon()
|
||||
|
||||
/datum/asset/simple/icon_states/emojis
|
||||
icon = 'icons/emoji.dmi'
|
||||
generic_icon_names = TRUE
|
||||
/datum/asset/spritesheet/pipes
|
||||
name = "pipes"
|
||||
|
||||
/datum/asset/simple/icon_states/multiple_icons/pipes
|
||||
icons = list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi')
|
||||
prefix = "pipe"
|
||||
|
||||
/datum/asset/simple/icon_states/multiple_icons/pipes/New()
|
||||
directions = GLOB.alldirs
|
||||
/datum/asset/spritesheet/pipes/register()
|
||||
for (var/each in list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi'))
|
||||
InsertAll("", each, GLOB.alldirs)
|
||||
..()
|
||||
|
||||
/datum/asset/simple/icon_states/multiple_icons/pipes/register()
|
||||
..()
|
||||
var/meter = icon('icons/obj/atmospherics/pipes/simple.dmi', "meterX", SOUTH, frame, movement_states)
|
||||
if(meter)
|
||||
register_asset(sanitize_filename("[prefix].south.meterX.png"), fcopy_rsc(meter))
|
||||
|
||||
// Representative icons for each research design
|
||||
/datum/asset/simple/research_designs/register()
|
||||
/datum/asset/spritesheet/research_designs
|
||||
name = "design"
|
||||
|
||||
/datum/asset/spritesheet/research_designs/register()
|
||||
for (var/path in subtypesof(/datum/design))
|
||||
var/datum/design/D = path
|
||||
|
||||
@@ -401,7 +575,6 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
if (machine)
|
||||
item = machine
|
||||
var/icon_file = initial(item.icon)
|
||||
var/all_states = icon_states(icon_file)
|
||||
var/icon/I = icon(icon_file, initial(item.icon_state), SOUTH)
|
||||
|
||||
// computers (and snowflakes) get their screen and keyboard sprites
|
||||
@@ -409,10 +582,11 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/obj/machinery/computer/C = item
|
||||
var/screen = initial(C.icon_screen)
|
||||
var/keyboard = initial(C.icon_keyboard)
|
||||
var/all_states = icon_states(icon_file)
|
||||
if (screen && (screen in all_states))
|
||||
I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY)
|
||||
if (keyboard && (keyboard in all_states))
|
||||
I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY)
|
||||
|
||||
assets["design_[initial(D.id)].png"] = I
|
||||
Insert(initial(D.id), I)
|
||||
return ..()
|
||||
|
||||
@@ -81,12 +81,14 @@
|
||||
|
||||
/obj/item/clothing/equipped(mob/user, slot)
|
||||
..()
|
||||
|
||||
if (!istype(user))
|
||||
return
|
||||
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
|
||||
for(var/variable in user_vars_to_edit)
|
||||
if(variable in user.vars)
|
||||
user_vars_remembered[variable] = user.vars[variable]
|
||||
user.vars[variable] = user_vars_to_edit[variable]
|
||||
if (LAZYLEN(user_vars_to_edit))
|
||||
for(var/variable in user_vars_to_edit)
|
||||
if(variable in user.vars)
|
||||
LAZYSET(user_vars_remembered, variable, user.vars[variable])
|
||||
user.vv_edit_var(variable, user_vars_to_edit[variable])
|
||||
|
||||
/obj/item/clothing/examine(mob/user)
|
||||
..()
|
||||
@@ -285,4 +287,4 @@ BLIND // can't see anything
|
||||
Shreds.desc = "The sad remains of what used to be [name]."
|
||||
deconstruct(FALSE)
|
||||
else
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -365,6 +365,7 @@
|
||||
scan_reagents = 1
|
||||
flags_1 = NODROP_1
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF
|
||||
|
||||
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(istype(W, src) && W != src && W.loc == user)
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
MA.alpha = 180
|
||||
MA.maptext = "[strength]k"
|
||||
MA.color = "#64C864"
|
||||
MA.layer = AREA_LAYER
|
||||
MA.layer = FLY_LAYER
|
||||
pic.appearance = MA
|
||||
flick_overlay(pic, list(user.client), 8)
|
||||
|
||||
|
||||
@@ -158,12 +158,20 @@
|
||||
strip_delay = 100
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/clothing/head/helmet/roman/fake
|
||||
desc = "An ancient helmet made of plastic and leather."
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
/obj/item/clothing/head/helmet/roman/legionaire
|
||||
name = "roman legionaire helmet"
|
||||
desc = "An ancient helmet made of bronze and leather. Has a red crest on top of it."
|
||||
icon_state = "roman_c"
|
||||
item_state = "roman_c"
|
||||
|
||||
/obj/item/clothing/head/helmet/roman/legionaire/fake
|
||||
desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it."
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
/obj/item/clothing/head/helmet/gladiator
|
||||
name = "gladiator helmet"
|
||||
desc = "Ave, Imperator, morituri te salutant."
|
||||
|
||||
@@ -321,4 +321,27 @@
|
||||
name = "headress of Nemes"
|
||||
desc = "Lavish space tomb not included."
|
||||
icon_state = "nemes_headdress"
|
||||
icon_state = "nemes_headdress"
|
||||
icon_state = "nemes_headdress"
|
||||
|
||||
/obj/item/clothing/head/frenchberet
|
||||
name = "french beret"
|
||||
desc = "A quality beret, infused with the aroma of chain-smoking, wine-swilling Parisians. You feel less inclined to engage military conflict, for some reason."
|
||||
icon_state = "beretblack"
|
||||
|
||||
/obj/item/clothing/head/frenchberet/speechModification(M)
|
||||
if(copytext(M, 1, 2) != "*")
|
||||
M = " [M]"
|
||||
var/list/french_words = strings("french_replacement.json", "french")
|
||||
|
||||
for(var/key in french_words)
|
||||
var/value = french_words[key]
|
||||
if(islist(value))
|
||||
value = pick(value)
|
||||
|
||||
M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
|
||||
M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
|
||||
M = replacetextEx(M, " [key]", " [value]")
|
||||
|
||||
if(prob(3))
|
||||
M += pick(" Honh honh honh!"," Honh!"," Zut Alors!")
|
||||
return trim(M)
|
||||
@@ -47,7 +47,7 @@
|
||||
/obj/item/clothing/mask/fakemoustache/italian/speechModification(M)
|
||||
if(copytext(M, 1, 2) != "*")
|
||||
M = " [M]"
|
||||
var/list/italian_words = strings("word_replacement.json", "italian")
|
||||
var/list/italian_words = strings("italian_replacement.json", "italian")
|
||||
|
||||
for(var/key in italian_words)
|
||||
var/value = italian_words[key]
|
||||
|
||||
@@ -165,186 +165,6 @@
|
||||
. = ..()
|
||||
allowed = GLOB.detective_vest_allowed
|
||||
|
||||
//Reactive armor
|
||||
/obj/item/clothing/suit/armor/reactive
|
||||
name = "reactive armor"
|
||||
desc = "Doesn't seem to do much for some reason."
|
||||
var/active = 0
|
||||
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
|
||||
var/reactivearmor_cooldown = 0
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
blood_overlay_type = "armor"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
actions_types = list(/datum/action/item_action/toggle)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
hit_reaction_chance = 50
|
||||
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
|
||||
src.active = !( src.active )
|
||||
if (src.active)
|
||||
to_chat(user, "<span class='notice'>[src] is now active.</span>")
|
||||
src.icon_state = "reactive"
|
||||
src.item_state = "reactive"
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
|
||||
src.icon_state = "reactiveoff"
|
||||
src.item_state = "reactiveoff"
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
|
||||
active = 0
|
||||
src.icon_state = "reactiveoff"
|
||||
src.item_state = "reactiveoff"
|
||||
reactivearmor_cooldown = world.time + 200
|
||||
..()
|
||||
|
||||
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
|
||||
/obj/item/clothing/suit/armor/reactive/teleport
|
||||
name = "reactive teleport armor"
|
||||
desc = "Someone separated our Research Director from his own head!"
|
||||
var/tele_range = 6
|
||||
var/rad_amount= 15
|
||||
reactivearmor_cooldown_duration = 100
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(tele_range, H))
|
||||
if(T.density)
|
||||
continue
|
||||
if(T.x>world.maxx-tele_range || T.x<tele_range)
|
||||
continue
|
||||
if(T.y>world.maxy-tele_range || T.y<tele_range)
|
||||
continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
turfs += pick(/turf in orange(tele_range, H))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
H.forceMove(picked)
|
||||
H.rad_act(rad_amount)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/fire
|
||||
name = "reactive incendiary armor"
|
||||
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
|
||||
for(var/mob/living/carbon/C in range(6, owner))
|
||||
if(C != owner)
|
||||
C.fire_stacks += 8
|
||||
C.IgniteMob()
|
||||
owner.fire_stacks = -20
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/stealth
|
||||
name = "reactive stealth armor"
|
||||
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
|
||||
E.Copy_Parent(owner, 50)
|
||||
E.GiveTarget(owner) //so it starts running right away
|
||||
E.Goto(owner, E.move_to_delay, E.minimum_distance)
|
||||
owner.alpha = 0
|
||||
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
|
||||
spawn(40)
|
||||
owner.alpha = initial(owner.alpha)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla
|
||||
name = "reactive tesla armor"
|
||||
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
|
||||
siemens_coefficient = -1
|
||||
var/tesla_power = 25000
|
||||
var/tesla_range = 20
|
||||
var/tesla_boom = FALSE
|
||||
var/tesla_stun = FALSE
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
|
||||
sparks.set_up(1, 1, src)
|
||||
sparks.start()
|
||||
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
|
||||
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table
|
||||
name = "reactive table armor"
|
||||
desc = "If you can't beat the memes, embrace them."
|
||||
var/tele_range = 10
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
|
||||
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
|
||||
owner.Knockdown(40)
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(tele_range, H))
|
||||
if(T.density)
|
||||
continue
|
||||
if(T.x>world.maxx-tele_range || T.x<tele_range)
|
||||
continue
|
||||
if(T.y>world.maxy-tele_range || T.y<tele_range)
|
||||
continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
turfs += pick(/turf in orange(tele_range, H))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
H.forceMove(picked)
|
||||
new /obj/structure/table(get_turf(owner))
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table/emp_act()
|
||||
return
|
||||
|
||||
//All of the armor below is mostly unused
|
||||
|
||||
/obj/item/clothing/suit/armor/centcom
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
/obj/item/reactive_armour_shell
|
||||
name = "reactive armour shell"
|
||||
desc = "An experimental suit of armour, awaiting installation of an anomaly core."
|
||||
icon_state = "reactiveoff"
|
||||
icon = 'icons/obj/clothing/suits.dmi'
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/reactive_armour_shell/attackby(obj/item/I, mob/user, params)
|
||||
..()
|
||||
var/static/list/anomaly_armour_types = list(
|
||||
/obj/effect/anomaly/grav = /obj/item/clothing/suit/armor/reactive/repulse,
|
||||
/obj/effect/anomaly/flux = /obj/item/clothing/suit/armor/reactive/tesla,
|
||||
/obj/effect/anomaly/bluespace = /obj/item/clothing/suit/armor/reactive/teleport,
|
||||
/obj/effect/anomaly/pyro = /obj/item/clothing/suit/armor/reactive/fire)
|
||||
|
||||
if(istype(I, /obj/item/assembly/signaler/anomaly))
|
||||
var/obj/item/assembly/signaler/anomaly/A = I
|
||||
var/armour_path = anomaly_armour_types[A.anomaly_type]
|
||||
if(!armour_path)
|
||||
armour_path = /obj/item/clothing/suit/armor/reactive/stealth //Lets not cheat the player if an anomaly type doesnt have its own armour coded
|
||||
to_chat(user, "You insert [A] into the chest plate, and the armour gently hums to life.")
|
||||
new armour_path(get_turf(src))
|
||||
qdel(src)
|
||||
qdel(A)
|
||||
|
||||
//Reactive armor
|
||||
/obj/item/clothing/suit/armor/reactive
|
||||
name = "reactive armor"
|
||||
desc = "Doesn't seem to do much for some reason."
|
||||
var/active = 0
|
||||
var/reactivearmor_cooldown_duration = 0 //cooldown specific to reactive armor
|
||||
var/reactivearmor_cooldown = 0
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
blood_overlay_type = "armor"
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
actions_types = list(/datum/action/item_action/toggle)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
hit_reaction_chance = 50
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/attack_self(mob/user)
|
||||
active = !(active)
|
||||
if(active)
|
||||
to_chat(user, "<span class='notice'>[src] is now active.</span>")
|
||||
icon_state = "reactive"
|
||||
item_state = "reactive"
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] is now inactive.</span>")
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/emp_act(severity)
|
||||
active = 0
|
||||
icon_state = "reactiveoff"
|
||||
item_state = "reactiveoff"
|
||||
reactivearmor_cooldown = world.time + 200
|
||||
..()
|
||||
|
||||
//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!)
|
||||
/obj/item/clothing/suit/armor/reactive/teleport
|
||||
name = "reactive teleport armor"
|
||||
desc = "Someone separated our Research Director from his own head!"
|
||||
var/tele_range = 6
|
||||
var/rad_amount= 15
|
||||
reactivearmor_cooldown_duration = 100
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system is still recharging! It fails to teleport [H]!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!</span>")
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(tele_range, H))
|
||||
if(T.density)
|
||||
continue
|
||||
if(T.x>world.maxx-tele_range || T.x<tele_range)
|
||||
continue
|
||||
if(T.y>world.maxy-tele_range || T.y<tele_range)
|
||||
continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
turfs += pick(/turf in orange(tele_range, H))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
H.forceMove(picked)
|
||||
H.rad_act(rad_amount)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Fire
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/fire
|
||||
name = "reactive incendiary armor"
|
||||
desc = "An experimental suit of armor with a reactive sensor array rigged to a flame emitter. For the stylish pyromaniac."
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/fire/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive incendiary armor on [owner] activates, but fails to send out flames as it is still recharging its flame jets!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out jets of flame!</span>")
|
||||
for(var/mob/living/carbon/C in range(6, owner))
|
||||
if(C != owner)
|
||||
C.fire_stacks += 8
|
||||
C.IgniteMob()
|
||||
owner.fire_stacks = -20
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Stealth
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/stealth
|
||||
name = "reactive stealth armor"
|
||||
desc = "An experimental suit of armor that renders the wearer invisible on detection of imminent harm, and creates a decoy that runs away from the owner. You can't fight what you can't see."
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive stealth system on [owner] activates, but is still recharging its holographic emitters!</span>")
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc)
|
||||
E.Copy_Parent(owner, 50)
|
||||
E.GiveTarget(owner) //so it starts running right away
|
||||
E.Goto(owner, E.move_to_delay, E.minimum_distance)
|
||||
owner.alpha = 0
|
||||
owner.visible_message("<span class='danger'>[owner] is hit by [attack_text] in the chest!</span>") //We pretend to be hit, since blocking it would stop the message otherwise
|
||||
spawn(40)
|
||||
owner.alpha = initial(owner.alpha)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
//Tesla
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla
|
||||
name = "reactive tesla armor"
|
||||
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
|
||||
siemens_coefficient = -1
|
||||
var/tesla_power = 25000
|
||||
var/tesla_range = 20
|
||||
var/tesla_boom = FALSE
|
||||
var/tesla_stun = FALSE
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread
|
||||
sparks.set_up(1, 1, src)
|
||||
sparks.start()
|
||||
owner.visible_message("<span class='danger'>The tesla capacitors on [owner]'s reactive tesla armor are still recharging! The armor merely emits some sparks.</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
|
||||
tesla_zap(owner,tesla_range,tesla_power,tesla_boom, tesla_stun)
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
|
||||
//Repulse
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/repulse
|
||||
name = "reactive repulse armor"
|
||||
desc = "An experimental suit of armor that violently throws back attackers."
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/repulse/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The repulse generator is still recharging!</span>")
|
||||
return 0
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], converting the attack into a wave of force!</span>")
|
||||
var/turf/T = get_turf(owner)
|
||||
var/list/thrown_items = list()
|
||||
for(var/atom/movable/A in range(T, 7))
|
||||
if(A == owner || A.anchored || thrown_items[A])
|
||||
continue
|
||||
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(A, src)))
|
||||
A.throw_at(throwtarget,10,1)
|
||||
thrown_items[A] = A
|
||||
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table
|
||||
name = "reactive table armor"
|
||||
desc = "If you can't beat the memes, embrace them."
|
||||
var/tele_range = 10
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(!active)
|
||||
return 0
|
||||
if(prob(hit_reaction_chance))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(world.time < reactivearmor_cooldown)
|
||||
owner.visible_message("<span class='danger'>The reactive table armor's fabricators are still on cooldown!</span>")
|
||||
return
|
||||
owner.visible_message("<span class='danger'>The reactive teleport system flings [H] clear of [attack_text] and slams them into a fabricated table!</span>")
|
||||
owner.visible_message("<font color='red' size='3'>[H] GOES ON THE TABLE!!!</font>")
|
||||
owner.Knockdown(40)
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(tele_range, H))
|
||||
if(T.density)
|
||||
continue
|
||||
if(T.x>world.maxx-tele_range || T.x<tele_range)
|
||||
continue
|
||||
if(T.y>world.maxy-tele_range || T.y<tele_range)
|
||||
continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
turfs += pick(/turf in orange(tele_range, H))
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
return
|
||||
H.forceMove(picked)
|
||||
new /obj/structure/table(get_turf(owner))
|
||||
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/table/emp_act()
|
||||
return
|
||||
@@ -15,8 +15,10 @@
|
||||
search = findtext(text, ":", pos+1)
|
||||
if(search)
|
||||
emoji = lowertext(copytext(text, pos+1, search))
|
||||
if(emoji in emojis)
|
||||
parsed += icon2html('icons/emoji.dmi', world, emoji)
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
|
||||
var/tag = sheet.icon_tag("emoji-[emoji]")
|
||||
if(tag)
|
||||
parsed += tag
|
||||
pos = search + 1
|
||||
else
|
||||
parsed += copytext(text, pos, search)
|
||||
|
||||
@@ -46,8 +46,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
var/datum/asset/stuff = get_asset_datum(/datum/asset/simple/goonchat)
|
||||
stuff.register()
|
||||
var/datum/asset/stuff = get_asset_datum(/datum/asset/group/goonchat)
|
||||
stuff.send(owner)
|
||||
|
||||
owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput")
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="font-awesome.css" />
|
||||
<link rel="stylesheet" type="text/css" href="browserOutput.css" />
|
||||
<link rel="stylesheet" type="text/css" href="spritesheet_chat.css" />
|
||||
<script type="text/javascript" src="errorHandler.js"></script>
|
||||
<script type="text/javascript" src="jquery.min.js"></script>
|
||||
<script type="text/javascript" src="json2.min.js"></script>
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
begin_month = DECEMBER
|
||||
end_day = 2
|
||||
end_month = JANUARY
|
||||
drone_hat = /obj/item/clothing/head/festive
|
||||
|
||||
/datum/holiday/new_year/getStationPrefix()
|
||||
return pick("Party","New","Hangover","Resolution")
|
||||
@@ -78,6 +79,7 @@
|
||||
name = "Groundhog Day"
|
||||
begin_day = 2
|
||||
begin_month = FEBRUARY
|
||||
drone_hat = /obj/item/clothing/head/helmet/space/chronos
|
||||
|
||||
/datum/holiday/valentines
|
||||
name = VALENTINES
|
||||
@@ -92,6 +94,7 @@
|
||||
name = "Birthday of Space Station 13"
|
||||
begin_day = 16
|
||||
begin_month = FEBRUARY
|
||||
drone_hat = /obj/item/clothing/head/festive
|
||||
|
||||
/datum/holiday/birthday/greet()
|
||||
var/game_age = text2num(time2text(world.timeofday, "YY")) - 3
|
||||
@@ -202,6 +205,7 @@
|
||||
name = "UFO Day"
|
||||
begin_day = 2
|
||||
begin_month = JULY
|
||||
drone_hat = /obj/item/clothing/mask/facehugger/dead
|
||||
|
||||
/datum/holiday/UFO/getStationPrefix() //Is such a thing even possible?
|
||||
return pick("Ayy","Truth","Tsoukalos","Mulder") //Yes it is!
|
||||
@@ -272,11 +276,13 @@
|
||||
name = "Smiling Day"
|
||||
begin_day = 7
|
||||
begin_month = OCTOBER
|
||||
drone_hat = /obj/item/clothing/head/papersack/smiley
|
||||
|
||||
/datum/holiday/boss
|
||||
name = "Boss' Day"
|
||||
begin_day = 16
|
||||
begin_month = OCTOBER
|
||||
drone_hat = /obj/item/clothing/head/that
|
||||
|
||||
/datum/holiday/halloween
|
||||
name = HALLOWEEN
|
||||
@@ -305,6 +311,7 @@
|
||||
name = "Flowers Day"
|
||||
begin_day = 19
|
||||
begin_month = NOVEMBER
|
||||
drone_hat = /obj/item/reagent_containers/food/snacks/grown/moonflower
|
||||
|
||||
/datum/holiday/hello
|
||||
name = "Saying-'Hello' Day"
|
||||
@@ -312,7 +319,7 @@
|
||||
begin_month = NOVEMBER
|
||||
|
||||
/datum/holiday/hello/greet()
|
||||
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy"))]! " + ..()
|
||||
return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy", "Ni hao", "Guten Tag", "Konnichiwa", "G'day cunt"))]! " + ..()
|
||||
|
||||
/datum/holiday/human_rights
|
||||
name = "Human-Rights Day"
|
||||
@@ -323,6 +330,7 @@
|
||||
name = "Monkey Day"
|
||||
begin_day = 14
|
||||
begin_month = DECEMBER
|
||||
drone_hat = /obj/item/clothing/mask/gas/monkeymask
|
||||
|
||||
/datum/holiday/thanksgiving
|
||||
name = "Thanksgiving in the United States"
|
||||
|
||||
@@ -142,21 +142,18 @@
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator
|
||||
name = "concatenator"
|
||||
desc = "This joins many strings together to get one big string."
|
||||
desc = "This can join up to 8 strings together to get one big string."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_STRING,
|
||||
"B" = IC_PINTYPE_STRING,
|
||||
"C" = IC_PINTYPE_STRING,
|
||||
"D" = IC_PINTYPE_STRING,
|
||||
"E" = IC_PINTYPE_STRING,
|
||||
"F" = IC_PINTYPE_STRING,
|
||||
"G" = IC_PINTYPE_STRING,
|
||||
"H" = IC_PINTYPE_STRING
|
||||
)
|
||||
inputs = list()
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/number_of_pins = 8
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/Initialize()
|
||||
for(var/i = 1 to number_of_pins)
|
||||
inputs["input [i]"] = IC_PINTYPE_STRING
|
||||
. = ..()
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/do_work()
|
||||
var/result = null
|
||||
@@ -169,6 +166,18 @@
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/small
|
||||
name = "small concatenator"
|
||||
desc = "This can join up to 4 strings together to get one big string."
|
||||
complexity = 2
|
||||
number_of_pins = 4
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/large
|
||||
name = "large concatenator"
|
||||
desc = "This can join up to 16 strings together to get one very big string."
|
||||
complexity = 6
|
||||
number_of_pins = 16
|
||||
|
||||
/obj/item/integrated_circuit/converter/separator
|
||||
name = "separator"
|
||||
desc = "This splits as single string into two at the relative split point."
|
||||
@@ -203,6 +212,32 @@
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/indexer
|
||||
name = "indexer"
|
||||
desc = "This circuit takes a string and an index value, then returns the character found at in the string at the given index."
|
||||
extended_desc = "Make sure the index is not longer or shorter than the string length. If you don't, the circuit will return empty."
|
||||
icon_state = "split"
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to index" = IC_PINTYPE_STRING,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
outputs = list(
|
||||
"found character" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("index" = IC_PINTYPE_PULSE_IN, "on indexed" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/indexer/do_work()
|
||||
var/strin = get_pin_data(IC_INPUT, 1)
|
||||
var/ind = get_pin_data(IC_INPUT, 2)
|
||||
if(ind > 0 && ind <= length(strin))
|
||||
set_pin_data(IC_OUTPUT, 1, strin[ind])
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, "")
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring
|
||||
name = "find text"
|
||||
desc = "This gives position of sample in the string. Or returns 0."
|
||||
@@ -216,14 +251,38 @@
|
||||
outputs = list(
|
||||
"position" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
|
||||
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT, "found" = IC_PINTYPE_PULSE_OUT, "not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring/do_work()
|
||||
var/position = findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2))
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
|
||||
set_pin_data(IC_OUTPUT, 1, position)
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
if(position)
|
||||
activate_pin(3)
|
||||
else
|
||||
activate_pin(4)
|
||||
|
||||
/obj/item/integrated_circuit/converter/stringlength
|
||||
name = "get length"
|
||||
desc = "This circuit will return the number of characters in a string."
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"string" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list(
|
||||
"length" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("get length" = IC_PINTYPE_PULSE_IN, "on acquisition" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/stringlength/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, length(get_pin_data(IC_INPUT, 1)))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
@@ -232,7 +291,8 @@
|
||||
name = "string exploder"
|
||||
desc = "This splits a single string into a list of strings."
|
||||
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
|
||||
For example, 'eat this burger' will be converted to list('eat','this','burger')."
|
||||
For example, 'eat this burger' will be converted to list('eat','this','burger'). Leave the delimiter null to get a list \
|
||||
of every individual character."
|
||||
icon_state = "split"
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
@@ -248,7 +308,10 @@
|
||||
/obj/item/integrated_circuit/converter/exploders/do_work()
|
||||
var/strin = get_pin_data(IC_INPUT, 1)
|
||||
var/delimiter = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
|
||||
if(delimiter == null)
|
||||
set_pin_data(IC_OUTPUT, 1, string2charlist(strin))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, splittext(strin, delimiter))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
@@ -226,9 +226,14 @@ GLOBAL_PROTECT(exp_to_update)
|
||||
if(!rolefound)
|
||||
play_records["Unknown"] += minutes
|
||||
else
|
||||
play_records[EXP_TYPE_GHOST] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
||||
if(holder && !holder.deadmined)
|
||||
play_records[EXP_TYPE_ADMIN] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Admin EXP!</span>")
|
||||
else
|
||||
play_records[EXP_TYPE_GHOST] += minutes
|
||||
if(announce_changes)
|
||||
to_chat(src,"<span class='notice'>You got: [minutes] Ghost EXP!</span>")
|
||||
else if(isobserver(mob))
|
||||
play_records[EXP_TYPE_GHOST] += minutes
|
||||
if(announce_changes)
|
||||
|
||||
@@ -91,7 +91,7 @@ Mime
|
||||
uniform = /obj/item/clothing/under/rank/mime
|
||||
mask = /obj/item/clothing/mask/gas/mime
|
||||
gloves = /obj/item/clothing/gloves/color/white
|
||||
head = /obj/item/clothing/head/beret
|
||||
head = /obj/item/clothing/head/frenchberet
|
||||
suit = /obj/item/clothing/suit/suspenders
|
||||
backpack_contents = list(/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing=1)
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
return TRUE
|
||||
|
||||
/datum/language/proc/get_icon()
|
||||
return "[icon2html(icon, world, icon_state)]"
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
|
||||
return sheet.icon_tag("language-[icon_state]")
|
||||
|
||||
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
|
||||
if(!syllables || !syllables.len)
|
||||
|
||||
@@ -326,7 +326,10 @@
|
||||
I.plane = initial(I.plane)
|
||||
I.appearance_flags &= ~NO_CLIENT_COLOR
|
||||
if(!no_move && !(I.flags_1 & DROPDEL_1)) //item may be moved/qdel'd immedietely, don't bother moving it
|
||||
I.forceMove(newloc)
|
||||
if (isnull(newloc))
|
||||
I.moveToNullspace()
|
||||
else
|
||||
I.forceMove(newloc)
|
||||
I.dropped(src)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
message = T.TongueSpeech(message)
|
||||
if(wear_mask)
|
||||
message = wear_mask.speechModification(message)
|
||||
|
||||
if(head)
|
||||
message = head.speechModification(message)
|
||||
return message
|
||||
|
||||
/mob/living/carbon/can_speak_vocal(message)
|
||||
|
||||
@@ -407,16 +407,14 @@
|
||||
*/
|
||||
//Recursive function to find everything a mob is holding. Really shitty proc tbh.
|
||||
/mob/living/get_contents()
|
||||
. = list()
|
||||
. |= list(src)
|
||||
for(var/obj/o in .)
|
||||
var/list/newlist = list()
|
||||
o.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, newlist)
|
||||
. |= newlist
|
||||
for(var/obj/item/clothing/under/U in .)
|
||||
. |= U.contents
|
||||
for(var/obj/item/folder/F in .)
|
||||
. |= F.contents
|
||||
var/list/ret = list()
|
||||
ret |= contents //add our contents
|
||||
for(var/i in ret.Copy()) //iterate storage objects
|
||||
var/atom/A = i
|
||||
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret)
|
||||
for(var/obj/item/folder/F in ret.Copy()) //very snowflakey-ly iterate folders
|
||||
ret |= F.contents
|
||||
return ret
|
||||
|
||||
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
|
||||
/mob/living/proc/can_inject()
|
||||
|
||||
@@ -317,8 +317,7 @@
|
||||
return shock_damage
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
var/list/L = src.get_contents()
|
||||
for(var/obj/O in L)
|
||||
for(var/obj/O in contents)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
attacktext = "pummels"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
dextrous = TRUE
|
||||
held_items = list(null, null)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM)
|
||||
faction = list("jungle")
|
||||
robust_searching = TRUE
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to fold it.</span>")
|
||||
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/simple/paper)
|
||||
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/paper)
|
||||
assets.send(user)
|
||||
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
@@ -300,7 +300,10 @@
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
|
||||
stamps += "<img src=large_[P.icon_state].png>"
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
|
||||
if (isnull(stamps))
|
||||
stamps = sheet.css_tag()
|
||||
stamps += sheet.icon_tag(P.icon_state)
|
||||
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[P.icon_state]")
|
||||
stampoverlay.pixel_x = rand(-2, 2)
|
||||
stampoverlay.pixel_y = rand(-3, 2)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/obj/item/ammo_box/magazine/m12g
|
||||
name = "shotgun magazine (12g taser slugs)"
|
||||
name = "shotgun magazine (12g buckshot slugs)"
|
||||
desc = "A drum magazine."
|
||||
icon_state = "m12gs"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
|
||||
icon_state = "m12gb"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
caliber = "shotgun"
|
||||
max_ammo = 8
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
..()
|
||||
icon_state = "[initial(icon_state)]-[CEILING(ammo_count(0)/8, 1)*8]"
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/buckshot
|
||||
name = "shotgun magazine (12g buckshot slugs)"
|
||||
icon_state = "m12gb"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
|
||||
/obj/item/ammo_box/magazine/m12g/stun
|
||||
name = "shotgun magazine (12g taser slugs)"
|
||||
icon_state = "m12gs"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/slug
|
||||
name = "shotgun magazine (12g slugs)"
|
||||
icon_state = "m12gb"
|
||||
icon_state = "m12gb" //this may need an unique sprite
|
||||
ammo_type = /obj/item/ammo_casing/shotgun
|
||||
|
||||
/obj/item/ammo_box/magazine/m12g/dragon
|
||||
|
||||
@@ -51,8 +51,9 @@ other types of metals and chemistry for reagents).
|
||||
return ..()
|
||||
|
||||
/datum/design/proc/icon_html(client/user)
|
||||
send_asset(user, "design_[id].png", FALSE)
|
||||
return "<img class='icon' src=\"design_[id].png\">"
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
sheet.send(user)
|
||||
return sheet.icon_tag(id)
|
||||
|
||||
////////////////////////////////////////
|
||||
//Disks for transporting design datums//
|
||||
|
||||
@@ -354,3 +354,17 @@
|
||||
build_path = /obj/item/weldingtool/experimental
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
|
||||
/////////////////////////////////////////
|
||||
////////////Armour//////////////
|
||||
/////////////////////////////////////////
|
||||
|
||||
/datum/design/reactive_armour
|
||||
name = "Reactive Armour Shell"
|
||||
desc = "An experimental suit of armour capable of utilizing an implanted anomaly core to protect the user."
|
||||
id = "reactive_armour"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 10000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000)
|
||||
build_path = /obj/item/reactive_armour_shell
|
||||
category = list("Equipment")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING
|
||||
@@ -217,6 +217,8 @@ doesn't have toxins access.
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/ui_header()
|
||||
var/list/l = list()
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
|
||||
l += "[sheet.css_tag()][RDSCREEN_NOBREAK]"
|
||||
l += "<div class='statusDisplay'><b>[stored_research.organization] Research and Development Network</b>"
|
||||
l += "Available points: [round(stored_research.research_points)] (+[round(stored_research.last_bitcoins * 60)] / minute)"
|
||||
l += "Security protocols: [obj_flags & EMAGGED ? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
|
||||
|
||||
@@ -106,6 +106,15 @@
|
||||
research_cost = 2500
|
||||
export_price = 5000
|
||||
|
||||
/datum/techweb_node/anomaly
|
||||
id = "anomaly_research"
|
||||
display_name = "Anomaly Research"
|
||||
description = "Unlock the potential of the mysterious anomalies that appear on station."
|
||||
prereq_ids = list("adv_engi", "practical_bluespace")
|
||||
design_ids = list("reactive_armour")
|
||||
research_cost = 2500
|
||||
export_price = 5000
|
||||
|
||||
/datum/techweb_node/high_efficiency
|
||||
id = "high_efficiency"
|
||||
display_name = "High Efficiency Parts"
|
||||
@@ -153,7 +162,6 @@
|
||||
research_cost = 5000
|
||||
export_price = 5000
|
||||
|
||||
|
||||
/datum/techweb_node/bluespace_power
|
||||
id = "bluespace_power"
|
||||
display_name = "Bluespace Power Technology"
|
||||
|
||||
@@ -453,7 +453,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
/datum/uplink_item/ammo/shotgun/buck
|
||||
name = "12g Buckshot Drum"
|
||||
desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy."
|
||||
item = /obj/item/ammo_box/magazine/m12g/buckshot
|
||||
item = /obj/item/ammo_box/magazine/m12g
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/slug
|
||||
name = "12g Slug Drum"
|
||||
@@ -466,7 +466,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
name = "12g Stun Slug Drum"
|
||||
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
|
||||
Saying that they're completely non-lethal would be lying."
|
||||
item = /obj/item/ammo_box/magazine/m12g
|
||||
item = /obj/item/ammo_box/magazine/m12g/stun
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/ammo/shotgun/dragon
|
||||
|
||||
@@ -114,11 +114,11 @@
|
||||
/obj/item/clothing/mask/muzzle = 2)
|
||||
premium = list(/obj/item/clothing/suit/pirate/captain = 2,
|
||||
/obj/item/clothing/head/pirate/captain = 2,
|
||||
/obj/item/clothing/head/helmet/roman = 1,
|
||||
/obj/item/clothing/head/helmet/roman/legionaire = 1,
|
||||
/obj/item/clothing/head/helmet/roman/fake = 1,
|
||||
/obj/item/clothing/head/helmet/roman/legionaire/fake = 1,
|
||||
/obj/item/clothing/under/roman = 1,
|
||||
/obj/item/clothing/shoes/roman = 1,
|
||||
/obj/item/shield/riot/roman = 1,
|
||||
/obj/item/shield/riot/roman/fake = 1,
|
||||
/obj/item/skub = 1)
|
||||
refill_canister = /obj/item/vending_refill/autodrobe
|
||||
|
||||
|
||||
Reference in New Issue
Block a user