Merge remote-tracking branch 'ParadiseSS13/master' into maze-generator

This commit is contained in:
AffectedArc07
2021-02-15 10:20:52 +00:00
640 changed files with 36365 additions and 151321 deletions
+1 -1
View File
@@ -2194,7 +2194,7 @@
switch(punishment)
// These smiting types are valid for all living mobs
if("Lightning bolt")
M.electrocute_act(5, "Lightning Bolt", safety = TRUE, override = TRUE)
M.electrocute_act(5, "Lightning Bolt", flags = SHOCK_NOGLOVES)
playsound(get_turf(M), 'sound/magic/lightningshock.ogg', 50, 1, -1)
M.adjustFireLoss(75)
M.Weaken(5)
+12 -13
View File
@@ -1,7 +1,5 @@
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","monkey","alien","as"))
GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown", "the", "a", "an", "of", "monkey", "alien", "as"))
/client/verb/adminhelp()
set category = "Admin"
@@ -12,27 +10,28 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
to_chat(src, "<font color='red'>Error: Admin-PM: You cannot send adminhelps (Muted).</font>")
return
adminhelped = 1 //Determines if they get the message to reply by clicking the name.
adminhelped = TRUE //Determines if they get the message to reply by clicking the name.
var/msg
var/list/type = list("Mentorhelp","Adminhelp")
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
var/list/type = list("Mentorhelp", "Adminhelp")
var/selected_type = input("Pick a category.", "Admin Help") as null|anything in type
if(selected_type)
msg = clean_input("Please enter your message.", "Admin Help", null)
msg = clean_input("Please enter your message.", selected_type)
//clean the input msg
if(!msg)
return
if(handle_spam_prevention(msg, MUTE_ADMINHELP, OOC_COOLDOWN))
return
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
msg = sanitize_simple(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg) // No message after sanitisation
return
if(selected_type == "Mentorhelp")
SSmentor_tickets.newHelpRequest(src, msg)
SSmentor_tickets.newHelpRequest(src, msg) // Mhelp
else
SStickets.newHelpRequest(src, msg)
SStickets.newHelpRequest(src, msg) // Ahelp
//show it to the person adminhelping too
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [msg]</span>")
@@ -54,7 +53,7 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
var/inactive_mentors = mentorcount[3]
if(active_mentors <= 0)
if(inactive_mentors > 0)
if(inactive_mentors)
alerttext = " | **ALL MENTORS AFK**"
else
alerttext = " | **NO MENTORS ONLINE**"
+3 -3
View File
@@ -743,11 +743,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
for(var/obj/machinery/power/rad_collector/Rad in GLOB.machines)
if(Rad.anchored)
if(!Rad.P)
var/obj/item/tank/plasma/Plasma = new/obj/item/tank/plasma(Rad)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.toxins = 70
Rad.drainratio = 0
Rad.P = Plasma
Rad.loaded_tank = Plasma
Plasma.loc = Rad
if(!Rad.active)
@@ -133,7 +133,7 @@ GLOBAL_VAR_INIT(sent_syndicate_infiltration_team, 0)
new_syndicate_infiltrator.mind_initialize()
new_syndicate_infiltrator.mind.assigned_role = "Syndicate Infiltrator"
new_syndicate_infiltrator.mind.special_role = "Syndicate Infiltrator"
new_syndicate_infiltrator.mind.offstation_role = TRUE //they can flee to z2 so make them inelligible as antag targets
new_syndicate_infiltrator.mind.offstation_role = TRUE //they can flee to the syndicate base on the admin level so make them inelligible as antag targets
SSticker.mode.traitors |= new_syndicate_infiltrator.mind //Adds them to extra antag list
new_syndicate_infiltrator.equip_syndicate_infiltrator(syndicate_leader_selected, uplink_tc, is_mgmt)
return new_syndicate_infiltrator
+2 -6
View File
@@ -282,18 +282,14 @@
return 1
/datum/admins/proc/makeAliens()
var/datum/event/alien_infestation/E = new /datum/event/alien_infestation
var/antnum = input(owner, "How many aliens you want to create? Enter 0 to cancel.","Amount:", 0) as num
if(!antnum || antnum <= 0)
return
var/datum/event/alien_infestation/E = new /datum/event/alien_infestation
E.spawncount = antnum
log_admin("[key_name(owner)] tried making Aliens with One-Click-Antag")
message_admins("[key_name_admin(owner)] tried making Aliens with One-Click-Antag")
E.spawncount = antnum
// TODO The fact we have to do this rather than just have events start
// when we ask them to, is bad.
E.processing = TRUE
return TRUE
/*
+1 -1
View File
@@ -193,7 +193,7 @@ GLOBAL_VAR_INIT(sent_strike_team, 0)
equip_to_slot_or_del(new /obj/item/melee/energy/sword/saber(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/shield/energy(src), slot_r_store)
equip_to_slot_or_del(new /obj/item/tank/emergency_oxygen/double/full(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/tank/internals/emergency_oxygen/double(src), slot_s_store)
equip_to_slot_or_del(new /obj/item/gun/projectile/revolver/mateba(src), slot_belt)
equip_to_slot_or_del(new /obj/item/gun/energy/pulse(src), slot_r_hand)
+1 -1
View File
@@ -49,7 +49,7 @@ GLOBAL_VAR_INIT(vox_tick, 1)
equip_to_slot_or_del(new /obj/item/gun/dartgun/vox/medical, slot_r_hand)
equip_to_slot_or_del(new /obj/item/clothing/mask/breath/vox(src), slot_wear_mask)
equip_to_slot_or_del(new /obj/item/tank/nitrogen(src), slot_back)
equip_to_slot_or_del(new /obj/item/tank/internals/nitrogen(src), slot_back)
equip_to_slot_or_del(new /obj/item/flashlight(src), slot_r_store)
var/obj/item/card/id/syndicate/vox/W = new(src)
@@ -1,75 +0,0 @@
/**
* # Contractor antagonist datum
*
* A variant of the Traitor, Contractors rely on kidnapping crew members to earn TC.
*
* Contractors are supplied with some unique items
* and three random low cost contraband items to help kickstart their contracts.
* A Traitor may become a Contractor if given the chance (random).
* They will forfeit all their initial TC and receive the above items.
* The opportunity to become a Contractor goes away after some time or if the traitor spends any initial TC.
*/
/datum/antagonist/traitor/contractor
name = "Contractor"
// Settings
/// How many telecrystals a traitor must forfeit to become a contractor.
var/tc_cost = 20
/// How long a traitor's chance to become a contractor lasts before going away. In deciseconds.
var/offer_duration = 10 MINUTES
// Variables
/// The associated contractor uplink. Only present if the offer was accepted.
var/obj/item/contractor_uplink/contractor_uplink = null
/// world.time at which the offer will expire.
var/offer_deadline = -1
/datum/antagonist/traitor/contractor/finalize_traitor()
..()
// Setup the vars and contractor stuff in the uplink
var/obj/item/uplink/hidden/U = owner.find_syndicate_uplink()
if(!U)
stack_trace("Potential contractor [owner] spawned without a hidden uplink!")
return
U.contractor = src
offer_deadline = world.time + offer_duration
// Greet them with the unique message
var/greet_text = "Contractors forfeit [tc_cost] telecrystals for the privilege of taking on kidnapping contracts for credit and TC payouts that can add up to more than the normal starting amount of TC.<br>"\
+ "If you are interested, simply access your hidden uplink and select the \"Contracting Opportunity\" tab for more information.<br>"
to_chat(owner.current, "<b><font size=4 color=red>You have been offered a chance to become a Contractor.</font></b><br>")
to_chat(owner.current, "<font color=red>[greet_text]</font>")
to_chat(owner.current, "<b><i><font color=red>This offer will expire in 10 minutes starting now (expiry time: <u>[station_time_timestamp(time = offer_deadline)]</u>).</font></i></b>")
/datum/antagonist/traitor/contractor/update_traitor_icons_added(datum/mind/traitor_mind)
if(!contractor_uplink)
return ..()
var/hud_name = "hudcontractor"
if(locate(/datum/objective/hijack) in owner.objectives)
hud_name = "hudhijackcontractor"
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, hud_name)
/**
* Accepts the offer to be a contractor if possible.
*/
/datum/antagonist/traitor/contractor/proc/become_contractor(mob/living/carbon/human/M, obj/item/uplink/U)
if(contractor_uplink || !istype(M))
return
if(U.uses < tc_cost || world.time >= offer_deadline)
var/reason = (U.uses < tc_cost) ? \
"you have insufficient telecrystals ([tc_cost] needed in total)" : \
"the deadline has passed"
to_chat(M, "<span class='warning'>You can no longer become a contractor as [reason].</span>")
return
// Give the kit
var/obj/item/storage/box/syndie_kit/contractor/B = new(M)
M.put_in_hands(B)
contractor_uplink = locate(/obj/item/contractor_uplink, B)
contractor_uplink.hub = new(M.mind, contractor_uplink)
// Update AntagHUD icon
update_traitor_icons_added(owner)
// Remove the TC
U.uses -= tc_cost
@@ -17,7 +17,7 @@
EXTRACTION_DIFFICULTY_HARD = 40,
)
/// Maximum variation a single contract's TC reward can have upon generation.
/// In other words: final_reward = CEILING((tc_threshold / num_contracts) * (1 + (rand(-100, 100) / 100) * tc_variation), 1)
/// In other words: final_reward = CEILING((tc_threshold / num_contracts) * (1 - (rand(0, 100) / 100) * tc_variation), 1)
var/tc_variation = 0.25
/// TC reward multiplier if the target was extracted DEAD. Should be a penalty so between 0 and 1.
/// The final amount is rounded up.
@@ -98,9 +98,6 @@
C.reward_tc = list(null, null, null)
for(var/difficulty in EXTRACTION_DIFFICULTY_EASY to EXTRACTION_DIFFICULTY_HARD)
var/amount_tc = calculate_tc_reward(num_to_generate, difficulty)
// Bump up the TC reward a little if it's too close to the lower difficulty's reward
if(difficulty > EXTRACTION_DIFFICULTY_EASY)
amount_tc = max(amount_tc, C.reward_tc[difficulty - 1] + (difficulty - 1))
C.reward_tc[difficulty] = amount_tc
total_earnable_tc[difficulty] += amount_tc
// Add to lists
@@ -111,11 +108,10 @@
for(var/difficulty in EXTRACTION_DIFFICULTY_EASY to EXTRACTION_DIFFICULTY_HARD)
var/total = total_earnable_tc[difficulty]
var/missing = difficulty_tc_thresholds[difficulty] - total
if(missing <= 0)
continue
// Just add the missing TC to a random contract
var/datum/syndicate_contract/C = pick(contracts)
C.reward_tc[difficulty] += missing
// Increment the TC payout of a random contract till we're even
while(missing-- > 0)
var/datum/syndicate_contract/C = pick(contracts)
C.reward_tc[difficulty]++
/**
* Generates an amount of TC to be used as a contract reward for the given difficulty.
@@ -126,7 +122,7 @@
*/
/datum/contractor_hub/proc/calculate_tc_reward(total_contracts, difficulty = EXTRACTION_DIFFICULTY_EASY)
ASSERT(total_contracts > 0)
return CEILING((difficulty_tc_thresholds[difficulty] / total_contracts) * (1 + (rand(-100, 100) / 100) * tc_variation), 1)
return FLOOR((difficulty_tc_thresholds[difficulty] / total_contracts) * (1 - (rand(0, 100) / 100) * tc_variation), 1)
/**
* Called when a [/datum/syndicate_contract] has been completed.
@@ -180,4 +176,4 @@
* * M - The mob.
*/
/datum/contractor_hub/proc/is_user_authorized(mob/living/carbon/M)
return M.mind.has_antag_datum(/datum/antagonist/traitor/contractor)
return LAZYACCESS(GLOB.contractors, M.mind) && M.mind == owner
@@ -7,7 +7,7 @@
cost = 3
// Settings
/// How long a contractor must wait before calling another blackout, in deciseconds.
var/static/cooldown = 15 MINUTES
var/static/cooldown = 45 MINUTES
// Variables
/// Static cooldown variable for blackouts.
var/static/next_blackout = -1
@@ -10,7 +10,7 @@
/**
* # Syndicate Contract
*
* Describes a contract that can be completed by a [/datum/antagonist/traitor/contractor].
* Describes a contract that can be completed by a Contractor.
*/
/datum/syndicate_contract
// Settings
@@ -320,6 +320,7 @@
*/
/datum/syndicate_contract/proc/target_received(mob/living/M, obj/effect/portal/redspace/contractor/P)
INVOKE_ASYNC(src, .proc/clean_up)
add_attack_logs(owning_hub.owner.current, M, "extracted to Syndicate Jail")
complete(M.stat == DEAD)
handle_target_experience(M, P)
@@ -408,13 +409,13 @@
// Give some species the necessary to survive. Courtesy of the Syndicate.
if(istype(H))
var/obj/item/tank/emergency_oxygen/tank
var/obj/item/tank/internals/emergency_oxygen/tank
var/obj/item/clothing/mask/breath/mask
if(isvox(H))
tank = new /obj/item/tank/emergency_oxygen/nitrogen(H)
tank = new /obj/item/tank/internals/emergency_oxygen/nitrogen(H)
mask = new /obj/item/clothing/mask/breath/vox(H)
else if(isplasmaman(H))
tank = new /obj/item/tank/emergency_oxygen/plasma(H)
tank = new /obj/item/tank/internals/emergency_oxygen/plasma(H)
mask = new /obj/item/clothing/mask/breath(H)
if(tank)
@@ -12,8 +12,6 @@
var/should_equip = TRUE
var/traitor_kind = TRAITOR_HUMAN
var/list/assigned_targets = list() // This includes assassinate as well as steal objectives. prevents duplicate objectives
/// Whether the traitor can specialize into a contractor.
var/is_contractor = FALSE
/datum/antagonist/traitor/on_gain()
if(owner.current && isAI(owner.current))
@@ -251,14 +249,15 @@
/datum/antagonist/traitor/proc/update_traitor_icons_added(datum/mind/traitor_mind)
var/is_contractor = LAZYACCESS(GLOB.contractors, traitor_mind)
if(locate(/datum/objective/hijack) in owner.objectives)
var/datum/atom_hud/antag/hijackhud = GLOB.huds[ANTAG_HUD_TRAITOR]
hijackhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudhijack")
set_antag_hud(owner.current, is_contractor ? "hudhijackcontractor" : "hudhijack")
else
var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR]
traitorhud.join_hud(owner.current, null)
set_antag_hud(owner.current, "hudsyndicate")
set_antag_hud(owner.current, is_contractor ? "hudcontractor" : "hudsyndicate")
/datum/antagonist/traitor/proc/update_traitor_icons_removed(datum/mind/traitor_mind)
@@ -411,8 +410,3 @@
<b>The code responses were:</b> <span class='redtext'>[responses]</span><br>"
return message
/datum/antagonist/traitor/specialization(datum/mind/new_owner)
if(isAI(new_owner?.current) || !is_contractor)
return ..()
return new /datum/antagonist/traitor/contractor
+1 -1
View File
@@ -110,7 +110,7 @@
var/list/possible_areas = list()
//setup, sets all station areas (and subtypes) to weight 1
for(var/A in GLOB.the_station_areas)
if(A == /area/holodeck) //don't allow holodeck areas as possible spawns since it will allow it to spawn in the holodeck rooms on z2 as well
if(A == /area/holodeck) //don't allow holodeck areas as possible spawns since it will allow it to spawn in the holodeck rooms on CC level as well
continue
if(A in possible_areas)
continue
@@ -479,3 +479,4 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new())
/turf/template_noop
name = "Turf Passthrough"
icon_state = "noop"
@@ -27,3 +27,154 @@
spawn(1)
W.loc = get_step(W, dir)
water_timer = addtimer(CALLBACK(src, .proc/drip), water_frequency, TIMER_STOPPABLE)
/turf/simulated/floor/beach/away
name = "Beach"
icon = 'icons/misc/beach.dmi'
var/water_overlay_image = null
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
planetary_atmos = TRUE
/turf/simulated/floor/beach/away/Initialize(mapload)
. = ..()
if(water_overlay_image)
var/image/overlay_image = image('icons/misc/beach.dmi', icon_state = water_overlay_image, layer = ABOVE_MOB_LAYER)
overlay_image.plane = GAME_PLANE
overlays += overlay_image
/turf/simulated/floor/beach/away/sand
name = "Sand"
icon_state = "desert"
mouse_opacity = MOUSE_OPACITY_ICON
baseturf = /turf/simulated/floor/beach/away/sand
/turf/simulated/floor/beach/away/sand/Initialize(mapload)
. = ..() //adds some aesthetic randomness to the beach sand
icon_state = pick("desert", "desert0", "desert1", "desert2", "desert3", "desert4")
/turf/simulated/floor/beach/away/sand/dense //for boundary "walls"
density = TRUE
baseturf = /turf/simulated/floor/beach/away/sand/dense
/turf/simulated/floor/beach/away/coastline
name = "Coastline"
//icon = 'icons/misc/beach2.dmi'
//icon_state = "sandwater"
icon_state = "beach"
water_overlay_image = "water_coast"
baseturf = /turf/simulated/floor/beach/away/coastline
/turf/simulated/floor/beach/away/coastline/dense //for boundary "walls"
density = TRUE
baseturf = /turf/simulated/floor/beach/away/coastline/dense
/turf/simulated/floor/beach/away/water
name = "Shallow Water"
icon_state = "seashallow"
water_overlay_image = "water_shallow"
var/obj/machinery/poolcontroller/linkedcontroller = null
baseturf = /turf/simulated/floor/beach/away/water
/turf/simulated/floor/beach/away/water/Entered(atom/movable/AM, atom/OldLoc)
. = ..()
if(!linkedcontroller)
return
if(ismob(AM))
linkedcontroller.mobinpool += AM
/turf/simulated/floor/beach/away/water/Exited(atom/movable/AM, atom/newloc)
. = ..()
if(!linkedcontroller)
return
if(ismob(AM))
linkedcontroller.mobinpool -= AM
/turf/simulated/floor/beach/away/water/InitializedOn(atom/A)
if(!linkedcontroller)
return
if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday
linkedcontroller.decalinpool += A
/turf/simulated/floor/beach/away/water/dense //for boundary "walls"
density = TRUE
baseturf = /turf/simulated/floor/beach/away/water/dense
/turf/simulated/floor/beach/away/water/edge_drop
name = "Water"
icon_state = "seadrop"
water_overlay_image = "water_drop"
baseturf = /turf/simulated/floor/beach/away/water/edge_drop
/turf/simulated/floor/beach/away/water/drop
name = "Water"
icon = 'icons/turf/floors/seadrop.dmi'
icon_state = "seadrop"
water_overlay_image = null
smooth = SMOOTH_TRUE
canSmoothWith = list(
/turf/simulated/floor/beach/away/water/drop, /turf/simulated/floor/beach/away/water/drop/dense,
/turf/simulated/floor/beach/away/water, /turf/simulated/floor/beach/away/water/dense,
/turf/simulated/floor/beach/away/water/edge_drop)
var/obj/effect/beach_drop_overlay/water_overlay
baseturf = /turf/simulated/floor/beach/away/water/drop
/turf/simulated/floor/beach/away/water/drop/Initialize(mapload)
. = ..()
water_overlay = new(src)
/turf/simulated/floor/beach/away/water/drop/Destroy()
QDEL_NULL(water_overlay)
return ..()
/obj/effect/beach_drop_overlay
name = "Water"
icon = 'icons/turf/floors/seadrop-o.dmi'
layer = MOB_LAYER + 0.1
smooth = SMOOTH_TRUE
anchored = 1
canSmoothWith = list(
/turf/simulated/floor/beach/away/water/drop, /turf/simulated/floor/beach/away/water/drop/dense,
/turf/simulated/floor/beach/away/water, /turf/simulated/floor/beach/away/water/dense,
/turf/simulated/floor/beach/away/water/edge_drop)
/turf/simulated/floor/beach/away/water/drop/dense
density = TRUE
baseturf = /turf/simulated/floor/beach/away/water/drop/dense
/turf/simulated/floor/beach/away/water/deep
name = "Deep Water"
icon_state = "seadeep"
water_overlay_image = "water_deep"
baseturf = /turf/simulated/floor/beach/away/water/deep
/turf/simulated/floor/beach/away/water/deep/dense
density = TRUE
baseturf = /turf/simulated/floor/beach/away/water/deep/dense
/turf/simulated/floor/beach/away/water/deep/wood_floor
name = "Sunken Floor"
icon = 'icons/turf/floors.dmi'
icon_state = "wood"
baseturf = /turf/simulated/floor/beach/away/water/deep/wood_floor
/turf/simulated/floor/beach/away/water/deep/sand_floor
name = "Sea Floor"
icon_state = "sand"
baseturf = /turf/simulated/floor/beach/away/water/deep/sand_floor
/turf/simulated/floor/beach/away/water/deep/rock_wall
name = "Reef Stone"
icon_state = "desert7"
density = TRUE
opacity = TRUE
explosion_block = 2
mouse_opacity = MOUSE_OPACITY_ICON
baseturf = /turf/simulated/floor/beach/away/water/deep/rock_wall
/obj/effect/baseturf_helper/beach/away/sand
name = "beach away sand baseturf editor"
baseturf = /turf/simulated/floor/beach/away/sand
/obj/effect/baseturf_helper/beach/away/water
name = "beach away water baseturf editor"
baseturf = /turf/simulated/floor/beach/away/water/deep/sand_floor
@@ -71,7 +71,7 @@
shoes = /obj/item/clothing/shoes/workboots
id = /obj/item/card/id/away/old/eng
gloves = /obj/item/clothing/gloves/color/fyellow/old
l_pocket = /obj/item/tank/emergency_oxygen
l_pocket = /obj/item/tank/internals/emergency_oxygen
assignedrole = "Ancient Crew"
/obj/effect/mob_spawn/human/oldeng/Destroy()
@@ -62,7 +62,7 @@
item_state = "void"
desc = "A CentCom engineering dark red space suit. Age has degraded the suit making is difficult to move around in."
slowdown = 4
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/multitool)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/multitool)
/obj/item/clothing/head/helmet/old
name = "degrading helmet"
@@ -1,279 +0,0 @@
#define PAY_INTERVAL 6000 // amount of ticks between payment
/area/awaymission/spacehotel
name = "Deep Space Hotel 419"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/spacehotel/kitchen
name = "Hotel Kitchen"
icon_state = "kitchen"
/area/awaymission/spacehotel/reception
name = "Hotel Reception"
icon_state = "entry"
// "Directional" map template loader for N or S hotel room
/obj/effect/landmark/map_loader/hotel_room
icon = 'icons/testing/turf_analysis.dmi'
icon_state = "arrow"
/obj/item/paper/crumpled/hotel_scrap_1
name = "paper scrap"
info = "I can't believe this shitty hotel assigned me a purple-themed room. <i>Why does the shower dump grape drink everywhere??</i>"
/obj/item/paper/hotel_scrap_2
name = "Journal Entry #2"
info = "<h3>Day 7:</h3>Today, I stepped into my bathroom, only to discover that it had become a mountainside wilderness. I tried to wash my hands with snow, but it didn't particularly pan out.<br>I contacting the front desk regarding the issue, but the receptionist just stared at me with dead eyes and spouted unrepeatable curses at me. However, I convinced them to reassign me to an upgraded suite."
/obj/item/paper/hotel_scrap_3
name = "Journal Entry #3"
info = "<h3>Day 26:</h3>Well, that sucked royally. The queen-sized bed was nice, but the hottub in my room was, well, my wife described it as \"a portal to hell\". I don't know, I guess the lava and weird blood gave it that impression, but it was pretty nicely warm.<br>However, <i>\"we\"</i> decided to get assigned to a new room. Whatever."
/obj/item/paper/hotel_scrap_4
name = "Diary Page"
info = "<b>Day 7 of Bad Vacation</b><br>Thanks Qzxor this shit vacation is ending today. The novelty of the trashy pool wore off 2 days in and I'm not allowed in the bar. The tiny box they called a room that, we had to cram into, just had a poster and a couple of beds. Only one bedsheet to spare. Shower had brown water and sink just dumped its water back out the ceiling, somehow.<br><br>PS: The receptionist isn't paying attention to us when we try to check out. Apparently, we're staying another day."
/obj/item/paper/hotel_scrap_5
name = "Journal Entry #5"
info = "<h3>Day 185:</h3>I feel like the restaurant's chef is just making random dishes to mess with me. I request something from the menu, and he throws out something nobody asked for on the counter. The bartender isn't much better. At least both of them can make some nice food and drinks. I would complain to the management... but they never seem to care."
/obj/item/paper/crumpled/hotel_scrap_6
name = "Journal Entry #6"
info = "<h3>Day 386:</h3><span style='font-family: wingdings; color: red'>AMBGAT MEZLBNU</span>. Something wrong. Can't stop hugging plushies."
/obj/item/paper/crumpled/hotel_scrap_7
name = "Journal Entry #8"
info = "<span style='font-family: wingdings; color: red'>ASGATDHU NAMSPA KER OKS O OKDOFLI OSDSFKO OASKDAFO AOSDKF OINAIS ISJDDEF OSKFEREAODIK OSI ODIFOSA OEKRRO ASODFKAO PSSDOF SDFK OSDKF OSDKFSASPODFIOSASD UHGU DFYG FPO ASDFOS DFOASSD FAPSO FSPDFOIER OPWASDSA PS DODIOF OSDI</span> pizza <span style='font-family: wingdings; color: red'>OKSDFO AL OKEWORK CVBUASO SDFO AOE RAOWEIK SODDFI</span>"
/obj/item/paper/hotel_scrap_8
name = "Mysterious Note"
icon_state = "paper_talisman"
info = "<div style='text-align: center; color: red; font: 24pt comic sans ms'>There is only one way to leave.</div>"
/obj/item/paper/pamphlet/hotel
name = "space hotel pamphlet"
info = "<h3>Welcome to Deep Space Hotel 419!</h3>Thank you for choosing our hotel. Simply hand your credit or debit card to the concierge and get your room key! To check out, hand your credit card back.<small><h4>Conditions:</h4><ul><li>The hotel is not responsible for any losses due to time or space anomalies.<li>The hotel is not responsible for events that occur outside of the hotel station, including, but not limited to, events that occur inside of dimensional pockets.<li>The hotel is not responsible for overcharging your account.<li>The hotel is not responsible for missing persons.<li>The hotel is not responsible for mind-altering effects due to drugs, magic, demons, or space worms.</ul></small>"
/obj/effect/landmark/map_loader/hotel_room/Initialize()
..()
// load and randomly assign rooms
var/global/list/south_room_templates = list()
var/global/list/north_room_templates = list()
var/static/path = "_maps/map_files/templates/spacehotel/"
var/global/loaded = 0
if(!loaded)
loaded = 1
for(var/map in flist(path))
if(cmptext(copytext(map, length(map) - 3), ".dmm"))
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
if(copytext(map, 1, 3) == "n_")
north_room_templates += T
else if(copytext(map, 1, 3) == "s_")
south_room_templates += T
else
// omnidirectional rooms are randomly assigned
if(prob(50))
north_room_templates += T
else
south_room_templates += T
var/datum/map_template/M = safepick(dir == NORTH ? north_room_templates : south_room_templates)
if(M)
template = M
if(dir == NORTH)
north_room_templates -= M
else
south_room_templates -= M
load(M)
// The door to a hotel room, but also metadata for the room itself
/obj/machinery/door/unpowered/hotel_door
name = "Room Door"
icon = 'icons/obj/doors/doorsand.dmi'
icon_state = "door_closed"
autoclose = 1
var/doorOpen = 'sound/machines/airlock_open.ogg'
var/doorClose = 'sound/machines/airlock_close.ogg'
var/doorDeni = 'sound/machines/deniedbeep.ogg'
var/id // the room number, eg 101
var/obj/item/card/hotel_card/card// room's key card
var/mob/living/occupant = null // the current room occupant
var/datum/money_account/account // Account we're pulling from
var/roomtimer // timer PS handle for updating room
/obj/machinery/door/unpowered/hotel_door/New()
..()
if(id)
name = "Room [id]"
// in case we spawned after hotel
var/obj/effect/hotel_controller/H
H = H.controller
if(H)
H.add_room(src)
/obj/machinery/door/unpowered/hotel_door/Destroy()
if(roomtimer)
deltimer(roomtimer)
roomtimer = null
QDEL_NULL(card)
return ..()
/obj/machinery/door/unpowered/hotel_door/examine(mob/user)
. = ..()
. += "This room is currently [occupant ? "" : "un"]occupied."
/obj/machinery/door/unpowered/hotel_door/allowed(mob/living/carbon/user)
for(var/obj/item/card/hotel_card/C in user.get_all_slots())
if(C == card && occupant)
atom_say("Welcome, [occupant.real_name]!")
return 1
return 0
/obj/machinery/door/unpowered/hotel_door/update_icon()
overlays.Cut()
if(density)
icon_state = "door_closed"
else
icon_state = "door_open"
/obj/machinery/door/unpowered/hotel_door/do_animate(animation)
switch(animation)
if("opening")
playsound(loc, doorOpen, 30, 1)
flick("door_opening", src)
if("closing")
playsound(loc, doorClose, 30, 1)
flick("door_closing", src)
if("deny")
playsound(src.loc, doorDeni, 50, 0, 3)
flick("door_deny", src)
/obj/machinery/door/unpowered/hotel_door/autoclose()
if(!density && !operating && autoclose)
close()
/obj/item/card/hotel_card
name = "Key Card"
icon_state = "guest"
color = "#0CF"
var/id
/obj/item/card/hotel_card/New(loc, ID)
..()
if(ID)
id = ID
if(id)
name = "Key Card - [id]"
desc = "A key card to room [id]. Use it to open the door."
/obj/item/card/hotel_card/Destroy()
var/mob/user = get(loc, /mob)
if(user)
to_chat(user, "\The [src] suddenly disappears in a flash!")
return ..()
/obj/effect/hotel_controller
var/global/obj/effect/hotel_controller/controller
name = "Deep Space Hotel 419"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
invisibility = 101
anchored = 1
density = 0
opacity = 0
var/list/room_doors[0] // assoc list of [room id]=hotel_door
var/list/vacant_rooms[0] // list of vacant room doors
var/list/guests[0] // assoc list of [guest mob]=room id
var/obj/item/radio/radio // for shouting at deadbeats
/obj/effect/hotel_controller/New()
..()
if(controller)
qdel(src)
controller = src
radio = new()
radio.broadcasting = 0
radio.listening = 0
// get room doors
for(var/obj/machinery/door/unpowered/hotel_door/D in get_area(src))
add_room(D)
/obj/effect/hotel_controller/proc/add_room(obj/machinery/door/unpowered/hotel_door/D)
room_doors["[D.id]"] = D
vacant_rooms += D
/obj/effect/hotel_controller/Destroy()
room_doors.Cut()
vacant_rooms.Cut()
guests.Cut()
QDEL_NULL(radio)
return ..()
// to check a person into a room; no financial stuff; returns the keycard
/obj/effect/hotel_controller/proc/checkin(roomid, mob/living/carbon/occupant, obj/item/card/id/id)
if(!istype(occupant))
return null
var/obj/machinery/door/unpowered/hotel_door/D = room_doors["[roomid]"]
if(!D || D.occupant || (occupant in guests))
return null
D.account = get_card_account(id, occupant)
if(!D.account)
return null
if(!D.account.charge(100, null, "10 minutes hotel stay", "Biesel GalaxyNet Terminal [rand(111,1111)]", "[name]"))
return null
D.occupant = occupant
D.roomtimer = addtimer(CALLBACK(src, .proc/process_room, roomid), PAY_INTERVAL, TIMER_STOPPABLE)
vacant_rooms -= D
guests[occupant] = roomid
var/obj/item/card/hotel_card/C = new(ID = roomid)
D.card = C
return C
/obj/effect/hotel_controller/proc/process_room(roomid)
var/obj/machinery/door/unpowered/hotel_door/D = room_doors["[roomid]"]
if(!D || !D.occupant)
return
if(D.account.charge(100, null, "10 minutes hotel stay extension", "Biesel GalaxyNet Terminal [rand(111,1111)]", "[name]"))
D.roomtimer = addtimer(CALLBACK(src, .proc/process_room, roomid), PAY_INTERVAL, TIMER_STOPPABLE)
else
force_checkout(roomid)
// Checks a person out of a room; no financial stuff
/obj/effect/hotel_controller/proc/checkout(roomid)
var/obj/machinery/door/unpowered/hotel_door/D = room_doors["[roomid]"]
if(!D || !D.occupant)
return 0
guests -= D.occupant
D.occupant = null
D.account = null
deltimer(D.roomtimer)
D.roomtimer = null
qdel(D.card)
vacant_rooms += D
return 1
// The person's card bounced mid-stay
/obj/effect/hotel_controller/proc/force_checkout(roomid)
var/obj/machinery/door/unpowered/hotel_door/D = room_doors["[roomid]"]
if(!D || !D.occupant)
return 0
var/mob/deadbeat = D.occupant
radio.autosay("[deadbeat], your card has been rejected. You have 30 seconds to check out.", name)
spawn(300)
if(D.occupant == deadbeat)
// they still haven't checked out...
checkout(roomid)
-373
View File
@@ -1,373 +0,0 @@
/area/awaymission/upperlevel
name = "Open Space"
color = "#888"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
// Used by /turf/unsimulated/floor/upperlevel as a reference for where the other floor is
/obj/effect/levelref
name = "level reference"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
invisibility = 101
var/id = null
var/obj/effect/levelref/other = null
var/offset_x
var/offset_y
var/offset_z
var/global/list/levels[0]
/obj/effect/levelref/New()
..()
levels += src
/obj/effect/levelref/Initialize()
..()
for(var/obj/effect/levelref/O in levels)
if(id == O.id && O != src)
other = O
update_offset()
O.other = src
O.update_offset()
for(var/turf/unsimulated/floor/upperlevel/U in get_area(loc))
U.init(src)
return
/obj/effect/levelref/Destroy()
levels -= src
return ..()
/obj/effect/levelref/proc/update_offset()
offset_x = other.x - x
offset_y = other.y - y
offset_z = other.z - z
// Used by /turf/unsimulated/floor/upperlevel and /obj/effect/view_portal/visual
// to know if the world changed on the remote side
/obj/effect/portal_sensor
invisibility = 101
var/light_hash = -1
var/triggered_this_tick = 0
var/datum/owner // owner that receive signals
var/list/params[0] // what to send to the main object to indicate which sensor
var/trigger_limit = 5 // number of time we're allowed to trigger per ptick
/obj/effect/portal_sensor/New(loc, o, ...)
..()
owner = o
if(args.len >= 3)
params = args.Copy(3)
START_PROCESSING(SSobj, src)
trigger()
/obj/effect/portal_sensor/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/portal_sensor/Crossed(A, oldloc)
trigger()
/obj/effect/portal_sensor/Uncrossed(A)
trigger()
/obj/effect/portal_sensor/process()
check_light()
if(triggered_this_tick >= trigger_limit)
call(owner, "trigger")(arglist(params))
triggered_this_tick = 0
/obj/effect/portal_sensor/proc/trigger()
triggered_this_tick++
if(triggered_this_tick < trigger_limit)
call(owner, "trigger")(arglist(params))
/obj/effect/portal_sensor/proc/check_light()
var/turf/T = loc
if(istype(T) && T.lighting_object && !T.lighting_object.needs_update)
var/atom/movable/lighting_object/O = T.lighting_object
var/hash = 0
for(var/lighting_corner in O)
var/datum/lighting_corner/C = lighting_corner
hash = hash + C.lum_r + C.lum_g + C.lum_b
if(hash != light_hash)
light_hash = hash
trigger()
else
if(light_hash != -1)
light_hash = -1
trigger()
// for second floor showing floor below
/turf/unsimulated/floor/upperlevel
icon = 'icons/turf/areas.dmi'
icon_state = "dark128"
layer = AREA_LAYER + 0.5
appearance_flags = TILE_BOUND | KEEP_TOGETHER
var/turf/lower_turf
var/obj/effect/portal_sensor/sensor
/turf/unsimulated/floor/upperlevel/New()
..()
var/obj/effect/levelref/R = locate() in get_area(src)
if(R && R.other)
init(R)
/turf/unsimulated/floor/upperlevel/Destroy()
QDEL_NULL(sensor)
return ..()
/turf/unsimulated/floor/upperlevel/proc/init(var/obj/effect/levelref/R)
lower_turf = locate(x + R.offset_x, y + R.offset_y, z + R.offset_z)
if(lower_turf)
sensor = new(lower_turf, src)
/turf/unsimulated/floor/upperlevel/Entered(atom/movable/AM, atom/OL, ignoreRest = 0)
if(isliving(AM) || istype(AM, /obj))
if(isliving(AM))
var/mob/living/M = AM
M.emote("scream")
M.SpinAnimation(5, 1)
AM.forceMove(lower_turf)
/turf/unsimulated/floor/upperlevel/attack_ghost(mob/user)
user.forceMove(lower_turf)
/turf/unsimulated/floor/upperlevel/proc/trigger()
name = lower_turf.name
desc = lower_turf.desc
// render each atom
underlays.Cut()
for(var/X in list(lower_turf) + lower_turf.contents)
var/atom/A = X
if(A && A.invisibility <= SEE_INVISIBLE_LIVING)
var/image/I = image(A, layer = AREA_LAYER + A.layer * 0.01, dir = A.dir)
I.pixel_x = A.pixel_x
I.pixel_y = A.pixel_y
underlays += I
// remote end of narnia portal
/obj/effect/view_portal
name = "portal target"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
invisibility = 101
anchored = 1
var/id = null // id of other portal turf we connect to
var/obj/effect/view_portal/other = null
var/global/list/portals[0]
/obj/effect/view_portal/New()
..()
GLOB.portals += src
/obj/effect/view_portal/Initialize()
..()
if(id)
for(var/obj/effect/view_portal/O in GLOB.portals)
if(id == O.id && O != src && can_link(O))
other = O
O.other = src
linkup()
O.linkup()
if(other)
return
/obj/effect/view_portal/Destroy()
GLOB.portals -= src
return ..()
/obj/effect/view_portal/proc/can_link(obj/effect/view_portal/P)
return P.type == /obj/effect/view_portal/visual && !P.other
/obj/effect/view_portal/proc/linkup()
// allow it to link to multiple visual nodes
other = null
// near end of nania portal
/obj/effect/view_portal/visual
name = "???"
desc = "You'll have to get closer to clearly see what this is."
icon = 'icons/turf/floors.dmi'
icon_state = "loadingarea"
opacity = 1
density = 1
invisibility = 0
appearance_flags = TILE_BOUND | KEEP_TOGETHER
var/dist = 6 // dist that we render out
var/radius = 3 // dist we render on other axis, in each direction
var/frustrum = 0 // if 1, get wider and wider at each step outward
var/teleport = 1 // should teleport?
var/list/render_block
var/list/sensors[0]
var/list/tiles[0]
var/list/near_render_block
var/turf/near_viewpoint
/obj/effect/view_portal/visual/Destroy()
for(var/T in sensors)
qdel(sensors[T])
sensors.Cut()
sensors = null
for(var/T in tiles)
qdel(tiles[T])
tiles.Cut()
tiles = null
render_block = null
near_render_block = null
near_viewpoint = null
return ..()
/obj/effect/view_portal/visual/can_link(obj/effect/view_portal/P)
return P.type == /obj/effect/view_portal
/obj/effect/view_portal/visual/linkup()
icon = null
icon_state = null
var/turf/Tloc = get_turf(loc)
if(Tloc)
Tloc.icon = null
Tloc.icon_state = null
Tloc.dynamic_lighting = 0
layer = AREA_LAYER + 0.5
// setup references
var/crossdir = angle2dir((dir2angle(dir) + 90) % 360)
near_viewpoint = get_step(get_turf(src), GetOppositeDir(dir))
// setup far turfs
var/turf/T1 = get_turf(other)
var/turf/T2 = T1
for(var/i in 1 to radius)
T1 = get_step(T1, crossdir)
T2 = get_step(T2, GetOppositeDir(crossdir))
if(frustrum)
// make a trapazoid, with length dist, short end radius*2 long,
// and 45 degree angles
render_block = block(T1, T2)
for(var/i in 1 to dist)
T1 = get_step(get_step(T1, dir), crossdir)
T2 = get_step(get_step(T2, dir), GetOppositeDir(crossdir))
render_block += block(T1, T2)
else
// else make a box dist x radius*2
for(var/i in 1 to dist)
T2 = get_step(T2, dir)
render_block = block(T1, T2)
for(var/turf/T in render_block)
sensors[T] = new /obj/effect/portal_sensor(T, src, 0, T)
// setup turfs on this side of the portal to cover the map streaming
// has to be done later for view() to be correct (so it happens when the walls exist)
/obj/effect/view_portal/visual/proc/setup_near()
var/nvs = dir & (EAST|WEST) ? near_viewpoint.x - x : near_viewpoint.y - y
if(nvs)
nvs = SIGN(nvs)
// need a mob for view() to work correctly
var/mob/M = new(near_viewpoint)
M.see_invisible = SEE_INVISIBLE_LIVING
near_render_block = view(M, world.view)
qdel(M)
for(var/A in near_render_block)
var/turf/T = A
if(istype(T))
var/ts = dir & (EAST|WEST) ? T.x - x : T.y - y
if(ts)
ts = SIGN(ts)
if(nvs == ts)
sensors[T] = new /obj/effect/portal_sensor(T, src, 1, T)
else
near_render_block -= T
else
near_render_block -= T
/obj/effect/view_portal/visual/Bumped(atom/movable/thing)
if((istype(thing, /obj) || isliving(thing)) && other && teleport)
if(!near_render_block)
setup_near()
var/mob/living/M = thing
// make the person glide onto the dest, giving a smooth transition
var/ox = thing.x - x
var/oy = thing.y - y
if(istype(M) && M.client)
M.notransform = 1
// cover up client-side map loading
M.screen_loc = "CENTER"
M.client.screen += M
for(var/T in tiles)
M.client.screen += tiles[T]
// wait a tick for the screen to replicate across network
// or this whole exercise of covering the transition is pointless
spawn(1)
thing.forceMove(locate(other.x + ox, other.y + oy, other.z))
sleep(1)
if(istype(M) && M.client)
for(var/T in tiles)
M.client.screen -= tiles[T]
M.client.screen -= M
M.screen_loc = initial(M.screen_loc)
thing.forceMove(get_turf(other.loc))
if(istype(M) && M.client)
M.notransform = 0
/obj/effect/view_portal/visual/attack_ghost(mob/user)
user.forceMove(get_turf(other.loc))
/obj/effect/view_portal/visual/proc/trigger(near, turf/T)
var/obj/effect/view_portal_dummy/D = tiles[T]
if(D)
D.overlays.Cut()
else
D = new(src, near, T)
tiles[T] = D
// render atoms to overlays of a dummy object
if(D.name != T.name)
D.name = T.name
D.desc = T.desc
for(var/AX in list(T) + T.contents)
var/atom/A = AX
if(A && A.invisibility <= SEE_INVISIBLE_LIVING)
var/image/I = image(A, layer = D.layer + A.layer * 0.01, dir = A.dir)
I.pixel_x = A.pixel_x
I.pixel_y = A.pixel_y
D.overlays += I
// tile of rendered other side for narnia portal
/obj/effect/view_portal_dummy
var/obj/effect/view_portal/visual/owner
/obj/effect/view_portal_dummy/New(obj/effect/view_portal/visual/V, near, turf/T)
..()
if(!near)
loc = V.loc
owner = V
var/ox
var/oy
if(near)
ox = (T.x - V.near_viewpoint.x)
oy = (T.y - V.near_viewpoint.y)
layer = AREA_LAYER + 0.4
else
ox = T.x - V.other.x + V.x - V.near_viewpoint.x
oy = T.y - V.other.y + V.y - V.near_viewpoint.y
pixel_x = 32 * (T.x - V.other.x)
pixel_y = 32 * (T.y - V.other.y)
layer = AREA_LAYER + 0.5
if(abs(ox) <= world.view && abs(oy) <= world.view)
screen_loc = "CENTER[ox >= 0 ? "+" : ""][ox],CENTER[oy >= 0 ? "+" : ""][oy]"
/obj/effect/view_portal_dummy/attack_ghost(mob/user)
owner.attack_ghost(user)
+5
View File
@@ -391,8 +391,13 @@
GLOB.panic_bunker_enabled = FALSE
message_admins("Panic bunker has been automatically disabled due to playercount dropping below [threshold]")
// Tell clients about active testmerges
if(world.TgsAvailable() && length(GLOB.revision_info.testmerges))
to_chat(src, GLOB.revision_info.get_testmerge_chatmessage(TRUE))
INVOKE_ASYNC(src, .proc/cid_count_check)
/client/proc/is_connecting_from_localhost()
var/localhost_addresses = list("127.0.0.1", "::1") // Adresses
if(!isnull(address) && (address in localhost_addresses))
@@ -2114,11 +2114,9 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts
if("ambientocclusion")
toggles ^= PREFTOGGLE_AMBIENT_OCCLUSION
if(parent && parent.screen && parent.screen.len)
if(length(parent?.screen))
var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen
PM.filters -= FILTER_AMBIENT_OCCLUSION
if(toggles & PREFTOGGLE_AMBIENT_OCCLUSION)
PM.filters += FILTER_AMBIENT_OCCLUSION
PM.backdrop(parent.mob)
if("parallax")
var/parallax_styles = list(
@@ -436,7 +436,7 @@
"f_style" = f_style,
"markingstyleslist" = markingstyleslist,
"ha_style" = ha_style,
"alt_head" = alt_head,
"alt_head" = alt_head || "",
"e_colour" = e_colour,
"underwear" = underwear,
"undershirt" = undershirt,
@@ -277,15 +277,15 @@
return
/client/verb/numpad_target()
set name = "Toggle Numpad targetting"
set name = "Toggle Numpad Targeting"
set category = "Preferences"
set desc = "This button will allow you to enable or disable Numpad Targetting"
set desc = "This button will allow you to enable or disable Numpad Targeting"
prefs.toggles ^= PREFTOGGLE_NUMPAD_TARGET
prefs.save_preferences(src)
if (prefs.toggles & PREFTOGGLE_NUMPAD_TARGET)
to_chat(usr, "<span class='notice'>You have enabled Numpad Targetting.")
to_chat(usr, "<span class='notice'>You have enabled Numpad Targeting.")
else
to_chat(usr, "<span class='notice'>You have disabled Numpad Targetting.")
to_chat(usr, "<span class='notice'>You have disabled Numpad Targeting.")
return
/client/verb/azerty_toggle()
+2 -3
View File
@@ -204,7 +204,6 @@
var/invis_override = 0
var/lighting_alpha
var/emagged = 0
var/list/color_view = null//overrides client.color while worn
var/prescription = 0
var/prescription_upgradable = 0
@@ -513,7 +512,7 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/suits.dmi'
name = "suit"
var/fire_resist = T0C+100
allowed = list(/obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/tank/internals/emergency_oxygen)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
slot_flags = SLOT_OCLOTHING
var/blood_overlay_type = "suit"
@@ -627,7 +626,7 @@ BLIND // can't see anything
permeability_coefficient = 0.02
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/flashlight,/obj/item/tank)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals)
slowdown = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
@@ -0,0 +1,120 @@
//Engineering Mesons
#define MODE_NONE ""
#define MODE_MESON "meson"
#define MODE_TRAY "t-ray"
#define MODE_RAD "radiation"
/obj/item/clothing/glasses/meson/engine
name = "engineering scanner goggles"
desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, the T-ray Scanner mode lets you see underfloor objects such as cables and pipes, and the Radiation Scanner mode lets you see objects contaminated by radiation."
icon_state = "trayson-meson"
item_state = "trayson-meson"
actions_types = list(/datum/action/item_action/toggle_mode)
origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3"
vision_flags = NONE
invis_view = SEE_INVISIBLE_LIVING
var/list/modes = list(MODE_NONE = MODE_MESON, MODE_MESON = MODE_TRAY, MODE_TRAY = MODE_RAD, MODE_RAD = MODE_NONE)
var/mode = MODE_NONE
var/range = 1
/obj/item/clothing/glasses/meson/engine/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
update_icon()
/obj/item/clothing/glasses/meson/engine/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clothing/glasses/meson/engine/proc/toggle_mode(mob/user, voluntary)
mode = modes[mode]
to_chat(user, "<span class='[voluntary ? "notice" : "warning"]'>[voluntary ? "You turn the goggles" : "The goggles turn"] [mode ? "to [mode] mode" : "off"][voluntary ? "." : "!"]</span>")
switch(mode)
if(MODE_MESON)
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
if(MODE_TRAY) //undoes the last mode, meson
vision_flags = NONE
lighting_alpha = null
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.glasses == src)
H.update_sight()
update_icon()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/glasses/meson/engine/attack_self(mob/user)
toggle_mode(user, TRUE)
/obj/item/clothing/glasses/meson/engine/process()
if(!ishuman(loc))
return
var/mob/living/carbon/human/user = loc
if(user.glasses != src || !user.client)
return
switch(mode)
if(MODE_TRAY)
t_ray_scan(user, 8, range)
if(MODE_RAD)
show_rads()
/obj/item/clothing/glasses/meson/engine/proc/show_rads()
var/mob/living/carbon/human/user = loc
var/list/rad_places = list()
for(var/datum/component/radioactive/thing in SSradiation.processing)
var/atom/owner = thing.parent
var/turf/place = get_turf(owner)
if(rad_places[place])
rad_places[place] += thing.strength
else
rad_places[place] = thing.strength
for(var/i in rad_places)
var/turf/place = i
if(get_dist(user, place) >= range * 5) //Rads are easier to see than wires under the floor
continue
var/strength = round(rad_places[i] / 1000, 0.1)
var/image/pic = image(loc = place)
var/mutable_appearance/MA = new()
MA.maptext = MAPTEXT("[strength]k")
MA.color = "#04e604"
MA.layer = RAD_TEXT_LAYER
MA.plane = GAME_PLANE
pic.appearance = MA
flick_overlay(pic, list(user.client), 10)
/obj/item/clothing/glasses/meson/engine/update_icon()
icon_state = "trayson-[mode]"
update_mob()
/obj/item/clothing/glasses/meson/engine/proc/update_mob()
item_state = icon_state
if(isliving(loc))
var/mob/living/user = loc
if(user.get_item_by_slot(slot_glasses) == src)
user.update_inv_glasses()
else
user.update_inv_l_hand()
user.update_inv_r_hand()
/obj/item/clothing/glasses/meson/engine/tray //atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves
name = "optical t-ray scanner"
icon_state = "trayson-t-ray"
item_state = "trayson-t-ray"
desc = "Used by engineering staff to see underfloor objects such as cables and pipes."
range = 2
origin_tech = "materials=3;magnets=2;engineering=2"
modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE)
#undef MODE_NONE
#undef MODE_MESON
#undef MODE_TRAY
#undef MODE_RAD
+1 -2
View File
@@ -49,7 +49,7 @@
name = "Optical Meson Scanner"
desc = "Used for seeing walls, floors, and stuff through anything."
icon_state = "meson"
item_state = "glasses"
item_state = "meson"
origin_tech = "magnets=1;engineering=2"
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
@@ -66,7 +66,6 @@
name = "Night Vision Optical Meson Scanner"
desc = "An Optical Meson Scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness."
icon_state = "nvgmeson"
item_state = "glasses"
origin_tech = "magnets=4;engineering=5;plasmatech=4"
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+1 -1
View File
@@ -75,7 +75,7 @@
// Can't be equipped by any other species due to bone structure and vox cybernetics.
/obj/item/clothing/suit/space/vox
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs, /obj/item/tank/internals)
armor = list(melee = 40, bullet = 40, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30, fire = 80, acid = 85)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
+2 -2
View File
@@ -49,9 +49,9 @@
icon_state = "ert_commander"
item_state = "suit-command"
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank/internals)
armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50, fire = 80, acid = 80)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/rcd, /obj/item/crowbar, \
/obj/item/screwdriver, /obj/item/weldingtool, /obj/item/wirecutters, /obj/item/wrench, /obj/item/multitool, \
/obj/item/radio, /obj/item/analyzer, /obj/item/gun, /obj/item/melee/baton, /obj/item/reagent_containers/spray/pepper, \
/obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/restraints/handcuffs)
+65 -9
View File
@@ -12,7 +12,13 @@
var/on = FALSE
var/obj/item/clothing/suit/space/hardsuit/suit
item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite)
actions_types = list(/datum/action/item_action/toggle_helmet_light)
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_geiger_counter)
var/scanning = TRUE
var/current_tick_amount = 0
var/radiation_count = 0
var/grace = RAD_GEIGER_GRACE_PERIOD
var/datum/looping_sound/geiger/soundloop
//Species-specific stuff.
species_restricted = list("exclude","Wryn")
@@ -33,6 +39,17 @@
"Vulpkanin" = 'icons/obj/clothing/species/vulpkanin/hats.dmi'
)
/obj/item/clothing/head/helmet/space/hardsuit/Initialize(mapload)
. = ..()
soundloop = new(list(), FALSE, TRUE)
soundloop.volume = 5
START_PROCESSING(SSobj, src)
/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(soundloop)
return ..()
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
toggle_light(user)
@@ -61,6 +78,7 @@
..()
if(suit)
suit.RemoveHelmet()
soundloop.stop(user)
/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot)
if(slot == slot_head)
@@ -71,14 +89,53 @@
if(slot != slot_head)
if(suit)
suit.RemoveHelmet()
soundloop.stop(user)
else
qdel(src)
else if(scanning)
soundloop.start(user)
/obj/item/clothing/head/helmet/space/hardsuit/proc/display_visor_message(var/msg)
var/mob/wearer = loc
if(msg && ishuman(wearer))
wearer.show_message("<b><span class='robot'>[msg]</span></b>", 1)
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(amount)
. = ..()
if(amount <= RAD_BACKGROUND_RADIATION)
return
current_tick_amount += amount
/obj/item/clothing/head/helmet/space/hardsuit/process()
if(scanning)
radiation_count -= radiation_count / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count += current_tick_amount / RAD_GEIGER_MEASURE_SMOOTHING
if(current_tick_amount)
grace = RAD_GEIGER_GRACE_PERIOD
else
grace--
if(grace <= 0)
radiation_count = 0
current_tick_amount = 0
if(ishuman(loc))
update_sound()
/obj/item/clothing/head/helmet/space/hardsuit/proc/update_sound()
var/datum/looping_sound/geiger/loop = soundloop
if(!scanning || !radiation_count)
loop.stop(loc)
return
loop.last_radiation = radiation_count
loop.start(loc)
/obj/item/clothing/head/helmet/space/hardsuit/proc/toggle_geiger_counter()
scanning = !scanning
if(ishuman(loc))
to_chat(loc, "<span class='notice'>You toggle [src]'s internal geiger counter [scanning ? "on" : "off"].</span>")
/obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity)
..()
display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!")
@@ -90,7 +147,7 @@
item_state = "eng_hardsuit"
max_integrity = 300
armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75)
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals,/obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd)
siemens_coefficient = 0
var/obj/item/clothing/head/helmet/space/hardsuit/helmet
actions_types = list(/datum/action/item_action/toggle_helmet)
@@ -260,7 +317,7 @@
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/storage/bag/ore, /obj/item/pickaxe, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
@@ -351,7 +408,7 @@
var/on = 1
actions_types = list(/datum/action/item_action/toggle_hardsuit_mode)
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90)
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank)
allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank/internals)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi
jetpack = /obj/item/tank/jetpack/suit
@@ -422,7 +479,6 @@
item_color = "medical"
flash_protect = 0
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
flags = STOPSPRESSUREDMAGE | THICKMATERIAL
scan_reagents = 1 //Generally worn by the CMO, so they'd get utility off of seeing reagents
/obj/item/clothing/suit/space/hardsuit/medical
@@ -430,7 +486,7 @@
name = "medical hardsuit"
desc = "A special helmet designed for work in a hazardous, low pressure environment. Built with lightweight materials for extra comfort."
item_state = "medical_hardsuit"
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/storage/firstaid,/obj/item/healthanalyzer,/obj/item/stack/medical,/obj/item/rad_laser)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals,/obj/item/storage/firstaid,/obj/item/healthanalyzer,/obj/item/stack/medical,/obj/item/rad_laser)
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical
slowdown = 0.5
@@ -450,7 +506,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit"
armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75)
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/baton,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/restraints/handcuffs)
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank/internals,/obj/item/melee/baton,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/restraints/handcuffs)
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security
/obj/item/clothing/head/helmet/space/hardsuit/security/hos
@@ -497,7 +553,7 @@
desc = "A hardsuit with built in energy shielding. Will rapidly recharge when not under fire."
icon_state = "hardsuit-hos"
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded
allowed = list(/obj/item/flashlight,/obj/item/tank, /obj/item/gun,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals, /obj/item/gun,/obj/item/reagent_containers/spray/pepper,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs)
armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
var/current_charges = 3
@@ -557,7 +613,7 @@
item_state = "syndie_hardsuit"
item_color = "syndi"
armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank/internals)
slowdown = 0
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi
jetpack = /obj/item/tank/jetpack/suit
@@ -29,7 +29,7 @@
icon_state = "caparmor"
item_state = "capspacesuit"
w_class = WEIGHT_CLASS_BULKY
allowed = list(/obj/item/tank, /obj/item/flashlight,/obj/item/gun/energy, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton,/obj/item/restraints/handcuffs)
allowed = list(/obj/item/tank/internals, /obj/item/flashlight,/obj/item/gun/energy, /obj/item/gun/projectile, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton,/obj/item/restraints/handcuffs)
armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100)
species_restricted = list("exclude", "Wryn")
@@ -57,7 +57,7 @@
desc = "A heavily armored, advanced space suit that protects against most forms of damage."
icon_state = "deathsquad"
item_state = "swat_suit"
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/kitchen/knife/combat)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank/internals,/obj/item/kitchen/knife/combat)
armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -70,7 +70,7 @@
desc = "Space-proof tactical SWAT armor."
icon_state = "heavy"
item_state = "swat_suit"
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank,/obj/item/kitchen/knife/combat)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank/internals,/obj/item/kitchen/knife/combat)
armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 100, "acid" = 100)
strip_delay = 120
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -150,7 +150,7 @@
icon_state = "pirate"
item_state = "pirate"
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank/internals)
slowdown = 0
armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75)
strip_delay = 40
@@ -270,3 +270,9 @@
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
magical = TRUE
/obj/item/clothing/head/helmet/space/plasmaman/assistant
name = "assistant envirosuit helmet"
desc = "A plasmaman envirohelm designed for the common, maint-dwelling masses."
icon_state = "assistant_envirohelm"
item_state = "assistant_envirohelm"
+1 -1
View File
@@ -20,7 +20,7 @@
item_state = "space_suit_syndicate"
desc = "Has a tag on it: Totally not property of a hostile corporation, honest!"
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank/internals)
armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85)
sprite_sheets = list(
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
+2 -2
View File
@@ -18,7 +18,7 @@
icon_state = "void-red"
item_state = "void"
desc = "A high tech, NASA Centcom branch designed space suit. Used for AI satellite maintenance."
allowed = list(/obj/item/flashlight,/obj/item/tank,/obj/item/multitool)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals,/obj/item/multitool)
sprite_sheets = list(
"Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
"Unathi" = 'icons/mob/species/unathi/suit.dmi',
@@ -82,7 +82,7 @@
icon_state = "void-syndi"
desc = "A high tech, NASA Centcom branch designed space suit. This one looks rather suspicious."
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank)
allowed = list(/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/melee/energy/sword/saber,/obj/item/restraints/handcuffs,/obj/item/tank/internals)
armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85)
//random spawner
+5 -5
View File
@@ -252,7 +252,7 @@
icon_state = "detective-armor"
item_state = "armor"
blood_overlay_type = "armor"
allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/reagent_containers/spray/pepper,/obj/item/flashlight,/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/detective_scanner,/obj/item/taperecorder)
allowed = list(/obj/item/tank/internals/emergency_oxygen,/obj/item/reagent_containers/spray/pepper,/obj/item/flashlight,/obj/item/gun,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/detective_scanner,/obj/item/taperecorder)
resistance_flags = FLAMMABLE
dog_fashion = null
@@ -395,7 +395,7 @@
item_state = "centcom"
w_class = WEIGHT_CLASS_BULKY
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/gun/energy,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/gun/energy,/obj/item/melee/baton,/obj/item/restraints/handcuffs,/obj/item/tank/internals/emergency_oxygen)
flags = THICKMATERIAL
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
@@ -485,7 +485,7 @@
//same defense as basic sec armor
/obj/item/clothing/suit/storage/lawyer/blackjacket/armored
desc = "A snappy dress jacket, reinforced with a layer of armor protecting the torso."
allowed = list(/obj/item/tank/emergency_oxygen, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/automatic/pistol)
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/automatic/pistol)
body_parts_covered = UPPER_TORSO|LOWER_TORSO
cold_protection = UPPER_TORSO|LOWER_TORSO
min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
@@ -500,7 +500,7 @@
icon_state = "dragon"
item_state = "dragon"
desc = "A suit of armour fashioned from the remains of an ash drake."
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/spear)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/spear)
armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100)
hoodtype = /obj/item/clothing/head/hooded/drake
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
@@ -525,7 +525,7 @@
icon_state = "goliath_cloak"
item_state = "goliath_cloak"
desc = "A staunch, practical cape made out of numerous monster materials, it is coveted amongst exiles & hermits."
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/pickaxe, /obj/item/twohanded/spear, /obj/item/organ/internal/regenerative_core/legion, /obj/item/kitchen/knife/combat/survival)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/pickaxe, /obj/item/twohanded/spear, /obj/item/organ/internal/regenerative_core/legion, /obj/item/kitchen/knife/combat/survival)
armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) //a fair alternative to bone armor, requiring alternative materials and gaining a suit slot
hoodtype = /obj/item/clothing/head/hooded/goliath
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
+1 -1
View File
@@ -29,7 +29,7 @@
flags = THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
slowdown = 1
allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen)
allowed = list(/obj/item/tank/internals/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen)
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 80, "fire" = 30, "acid" = 100)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
strip_delay = 70
+11 -11
View File
@@ -8,7 +8,7 @@
icon_state = "paramedic-vest"
item_state = "paramedic-vest"
allowed = list(/obj/item/stack/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/reagent_containers/syringe,
/obj/item/healthanalyzer, /obj/item/flashlight, /obj/item/radio, /obj/item/tank/emergency_oxygen,/obj/item/rad_laser)
/obj/item/healthanalyzer, /obj/item/flashlight, /obj/item/radio, /obj/item/tank/internals/emergency_oxygen,/obj/item/rad_laser)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 10, fire = 50, acid = 50)
sprite_sheets = list(
@@ -23,7 +23,7 @@
item_state = "brigphysician-vest"
allowed = list(/obj/item/stack/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/reagent_containers/syringe,
/obj/item/healthanalyzer, /obj/item/flashlight, \
/obj/item/radio, /obj/item/tank/emergency_oxygen,/obj/item/rad_laser)
/obj/item/radio, /obj/item/tank/internals/emergency_oxygen,/obj/item/rad_laser)
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0, fire = 50, acid = 50)
sprite_sheets = list(
@@ -52,7 +52,7 @@
item_state = "bio_suit"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
allowed = list(/obj/item/disk, /obj/item/stamp, /obj/item/reagent_containers/food/drinks/flask, /obj/item/melee, /obj/item/storage/lockbox/medal, /obj/item/flash, /obj/item/storage/box/matches, /obj/item/lighter, /obj/item/clothing/mask/cigarette, /obj/item/storage/fancy/cigarettes, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/disk, /obj/item/stamp, /obj/item/reagent_containers/food/drinks/flask, /obj/item/melee, /obj/item/storage/lockbox/medal, /obj/item/flash, /obj/item/storage/box/matches, /obj/item/lighter, /obj/item/clothing/mask/cigarette, /obj/item/storage/fancy/cigarettes, /obj/item/tank/internals/emergency_oxygen)
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi'
@@ -85,7 +85,7 @@
item_state = "chaplain_hoodie"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/chaplain_hood
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi'
@@ -100,7 +100,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
flags_inv = HIDESHOES|HIDEJUMPSUIT
hoodtype = /obj/item/clothing/head/hooded/nun_hood
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi'
@@ -115,7 +115,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
flags_inv = HIDESHOES|HIDEJUMPSUIT
hoodtype = /obj/item/clothing/head/hooded/monk_hood
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
/obj/item/clothing/suit/witchhunter
name = "witchhunter garb"
@@ -123,7 +123,7 @@
icon_state = "witchhunter"
item_state = "witchhunter"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
//Chef
@@ -162,7 +162,7 @@
desc = "A slick, authoritative cloak designed for the Chief Engineer."
icon_state = "cemantle"
item_state = "cemantle"
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/rcd, /obj/item/rpd)
//Chief Medical Officer
/obj/item/clothing/suit/mantle/labcoat/chief_medical_officer
@@ -179,7 +179,7 @@
item_state = "det_suit"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
allowed = list(/obj/item/tank/emergency_oxygen, /obj/item/reagent_containers/spray/pepper, /obj/item/flashlight, /obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/detective_scanner, /obj/item/taperecorder)
allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/reagent_containers/spray/pepper, /obj/item/flashlight, /obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/detective_scanner, /obj/item/taperecorder)
armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45)
cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
@@ -231,7 +231,7 @@
icon_state = "hazard"
item_state = "hazard"
blood_overlay_type = "armor"
allowed = list (/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/emergency_oxygen, /obj/item/rcd, /obj/item/rpd)
allowed = list (/obj/item/flashlight, /obj/item/t_scanner, /obj/item/tank/internals/emergency_oxygen, /obj/item/rcd, /obj/item/rpd)
resistance_flags = NONE
sprite_sheets = list(
@@ -339,7 +339,7 @@
item_state = "fr_jacket_open"
blood_overlay_type = "armor"
allowed = list(/obj/item/stack/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/applicator, /obj/item/reagent_containers/syringe,
/obj/item/healthanalyzer, /obj/item/flashlight, /obj/item/radio, /obj/item/tank/emergency_oxygen,/obj/item/rad_laser)
/obj/item/healthanalyzer, /obj/item/flashlight, /obj/item/radio, /obj/item/tank/internals/emergency_oxygen,/obj/item/rad_laser)
ignore_suitadjust = 0
suit_adjusted = 1
actions_types = list(/datum/action/item_action/button)
+11 -11
View File
@@ -139,7 +139,7 @@
item_state = "syndicate-black-red"
desc = "A plastic replica of the syndicate space suit, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
w_class = WEIGHT_CLASS_NORMAL
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
resistance_flags = NONE
@@ -160,7 +160,7 @@
item_state = "imperium_monk"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDESHOES|HIDEJUMPSUIT
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
/obj/item/clothing/suit/chickensuit
name = "chicken suit"
@@ -223,7 +223,7 @@
item_state = "holidaypriest"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/storage/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen)
/obj/item/clothing/suit/cardborg
name = "cardborg suit"
@@ -299,7 +299,7 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too
allowed = list(/obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/tank/internals/emergency_oxygen)
hoodtype = /obj/item/clothing/head/hooded/carp_hood
/obj/item/clothing/head/hooded/carp_hood
@@ -371,7 +371,7 @@
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0)
allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi')
@@ -441,7 +441,7 @@
w_class = WEIGHT_CLASS_NORMAL
item_state = "coatengineer"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45)
allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/t_scanner, /obj/item/rcd)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/t_scanner, /obj/item/rcd)
hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering
/obj/item/clothing/head/hooded/winterhood/engineering
@@ -480,7 +480,7 @@
icon_state = "wintercoat_miner"
w_class = WEIGHT_CLASS_NORMAL
item_state = "coatminer"
allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
hoodtype = /obj/item/clothing/head/hooded/winterhood/miner
@@ -499,7 +499,7 @@
icon_state = "black_hoodie"
item_state = "blueshieldcoat"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen)
hoodtype = /obj/item/clothing/head/hooded/hood
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi'
@@ -690,7 +690,7 @@
ignore_suitadjust = 1
actions_types = list()
adjust_flavour = null
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/gun/projectile/automatic/pistol,/obj/item/gun/projectile/revolver,/obj/item/gun/projectile/revolver/detective)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter,/obj/item/gun/projectile/automatic/pistol,/obj/item/gun/projectile/revolver,/obj/item/gun/projectile/revolver/detective)
/obj/item/clothing/suit/jacket/miljacket/navy
name = "navy military jacket"
@@ -757,7 +757,7 @@
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.01
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/tank/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen)
allowed = list(/obj/item/tank/internals/emergency_oxygen,/obj/item/pen,/obj/item/flashlight/pen)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20, fire = 50, acid = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
@@ -778,7 +778,7 @@
icon_state = "bomber"
item_state = "bomber"
ignore_suitadjust = 0
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
+4 -4
View File
@@ -18,7 +18,7 @@
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.50
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/extinguisher)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/extinguisher)
slowdown = 1
armor = list("melee" = 15, "bullet" = 5, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
@@ -131,7 +131,7 @@
strip_delay = 60
put_on_delay = 60
resistance_flags = NONE
flags_2 = RAD_PROTECT_CONTENTS_2
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/head.dmi',
"Grey" = 'icons/mob/species/grey/head.dmi'
@@ -147,14 +147,14 @@
permeability_coefficient = 0.50
flags = THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen, /obj/item/geiger_counter)
slowdown = 1.5
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30)
flags_inv = HIDEJUMPSUIT|HIDETAIL
strip_delay = 60
put_on_delay = 60
resistance_flags = NONE
flags_2 = RAD_PROTECT_CONTENTS_2
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/suit.dmi'
)
@@ -270,7 +270,6 @@
item_color = "holobadge"
slot_flags = SLOT_BELT | SLOT_TIE
var/emagged = FALSE //Emagging removes Sec check.
var/stored_name = null
/obj/item/clothing/accessory/holobadge/cord
@@ -70,6 +70,13 @@
item_state = "clown_envirosuit"
item_color = "clown_envirosuit"
/obj/item/clothing/under/plasmaman/assistant
name = "Assistant envirosuit"
desc = "The finest from the bottom of the plasmamen clothing barrel."
icon_state = "assistant_envirosuit"
item_state = "assistant_envirosuit"
item_color = "assistant_envirosuit"
/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H)
if(!istype(H))
return
+11
View File
@@ -91,6 +91,17 @@
var/completion = round(C.get_completion())
return completion
/obj/effect/countdown/supermatter
name = "supermatter damage"
text_size = 1
color = "#00ff80"
/obj/effect/countdown/supermatter/get_value()
var/obj/machinery/power/supermatter_crystal/S = attached_to
if(!istype(S))
return
return "<div align='center' valign='middle' style='position:relative; top:0px; left:0px'>[round(S.get_integrity(), 1)]%</div>"
/obj/effect/countdown/anomaly
name = "anomaly countdown"
+8
View File
@@ -523,6 +523,14 @@
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
category = CAT_MISC
/datum/crafting_recipe/ghettojetpack
name = "Improvised Jetpack"
result = /obj/item/tank/jetpack/improvised
time = 30
reqs = list(/obj/item/tank/internals/oxygen = 2, /obj/item/extinguisher = 1, /obj/item/pipe = 3, /obj/item/stack/cable_coil = MAXCOIL)
category = CAT_MISC
tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
/datum/crafting_recipe/drill
name = "Thermal Drill"
result = /obj/item/thermal_drill
+6 -6
View File
@@ -807,7 +807,7 @@
item_state = "supplymaster_jacket_open"
ignore_suitadjust = 0
suit_adjusted = 1
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
actions_types = list(/datum/action/item_action/button)
@@ -971,7 +971,7 @@
icon_state = "xantholne_wintercoat"
hoodtype = /obj/item/clothing/head/hooded/hood/fluff/xantholne
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
/obj/item/clothing/head/hooded/hood/fluff/xantholne // Xantholne: Meex Zwichsnicrur
@@ -992,7 +992,7 @@
hoodtype = /obj/item/clothing/head/hooded/hood/fluff/xydonus
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
/obj/item/clothing/head/hooded/hood/fluff/xydonus
name = "custom fit hood"
@@ -1055,7 +1055,7 @@
icon_state = "dtxbomber"
item_state = "dtxbomber"
ignore_suitadjust = 0
allowed = list(/obj/item/flashlight,/obj/item/tank/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
allowed = list(/obj/item/flashlight,/obj/item/tank/internals/emergency_oxygen,/obj/item/toy,/obj/item/storage/fancy/cigarettes,/obj/item/lighter)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
actions_types = list(/datum/action/item_action/zipper)
@@ -1213,7 +1213,7 @@
icon = 'icons/obj/custom_items.dmi'
icon_state = "fox_jacket"
item_state = "fox_jacket"
allowed = list(/obj/item/flashlight, /obj/item/tank/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/projectile/automatic/pistol, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/revolver/detective)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/projectile/automatic/pistol, /obj/item/gun/projectile/revolver, /obj/item/gun/projectile/revolver/detective)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
@@ -1583,7 +1583,7 @@
item_state = "asmer_accordion"
/obj/item/clothing/head/fluff/pinesalad_horns //Pineapple Salad: Dan Jello
/obj/item/clothing/head/fluff/pinesalad_horns //Pineapple Salad: Dan Jello
name = "Bluespace Horns"
desc = "A pair of fake horns. Now with added bluespace!"
icon = 'icons/obj/custom_items.dmi'
@@ -28,7 +28,7 @@ GLOBAL_LIST_EMPTY(weighted_mundaneevent_locations)
/datum/trade_destination/anansi
name = "NSS Anansi"
description = "Medical station ran by Second Red Cross (but owned by NT) for handling emergency cases from nearby colonies."
description = "Medical station ran by Second Green Cross (but owned by NT) for handling emergency cases from nearby colonies."
distance = 1.7
willing_to_buy = list()
willing_to_sell = list()
@@ -37,7 +37,7 @@ GLOBAL_LIST_EMPTY(weighted_mundaneevent_locations)
/datum/trade_destination/anansi/get_custom_eventstring(var/event_type)
if(event_type == RESEARCH_BREAKTHROUGH)
return "Thanks to research conducted on the NSS Anansi, Second Red Cross Society wishes to announce a major breakthough in the field of \
return "Thanks to research conducted on the NSS Anansi, Second Green Cross Society wishes to announce a major breakthough in the field of \
[pick("mind-machine interfacing","neuroscience","nano-augmentation","genetics")]. Nanotrasen is expected to announce a co-exploitation deal within the fortnight."
return null
+4 -5
View File
@@ -1,12 +1,12 @@
/datum/event/abductor
/datum/event/abductor/start()
//spawn abductor team
processing = 0 //so it won't fire again in next tick
INVOKE_ASYNC(src, .proc/try_makeAbductorTeam)
/datum/event/abductor/proc/try_makeAbductorTeam()
if(!makeAbductorTeam())
message_admins("Abductor event failed to find players. Retrying in 30s.")
spawn(300)
makeAbductorTeam()
addtimer(CALLBACK(src, .proc/makeAbductorTeam), 30 SECONDS)
/datum/event/abductor/proc/makeAbductorTeam()
var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you wish to be considered for an Abductor Team?", ROLE_ABDUCTOR, TRUE)
@@ -46,7 +46,6 @@
if(SSticker.mode.config_tag != "abduction")
SSticker.mode.abductors |= temp.abductors
processing = 1 //So it will get gc'd
return 1
else
return 0
+16 -15
View File
@@ -15,23 +15,24 @@
log_and_message_admins("Warning: Could not spawn any mobs for event Alien Infestation")
/datum/event/alien_infestation/start()
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
playercount = length(GLOB.clients)//grab playercount when event starts not when game starts
if(playercount >= highpop_trigger) //spawn with 4 if highpop
spawncount = 4
INVOKE_ASYNC(src, .proc/spawn_xenos)
spawn()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as an alien?", ROLE_ALIEN, TRUE, source = /mob/living/carbon/alien/larva)
while(spawncount && length(vents) && length(candidates))
var/obj/vent = pick_n_take(vents)
var/mob/C = pick_n_take(candidates)
if(C)
GLOB.respawnable_list -= C.client
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.amount_grown += (0.75 * new_xeno.max_grown) //event spawned larva start off almost ready to evolve.
new_xeno.key = C.key
if(SSticker && SSticker.mode)
SSticker.mode.xenos += new_xeno.mind
/datum/event/alien_infestation/proc/spawn_xenos()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as an alien?", ROLE_ALIEN, TRUE, source = /mob/living/carbon/alien/larva)
var/list/vents = get_valid_vent_spawns(exclude_mobs_nearby = TRUE, exclude_visible_by_mobs = TRUE)
while(spawncount && length(vents) && length(candidates))
var/obj/vent = pick_n_take(vents)
var/mob/C = pick_n_take(candidates)
if(C)
GLOB.respawnable_list -= C.client
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.amount_grown += (0.75 * new_xeno.max_grown) //event spawned larva start off almost ready to evolve.
new_xeno.key = C.key
if(SSticker && SSticker.mode)
SSticker.mode.xenos += new_xeno.mind
spawncount--
successSpawn = TRUE
spawncount--
successSpawn = TRUE
+1
View File
@@ -29,6 +29,7 @@
/proc/apc_overload_failure(announce=TRUE)
var/list/skipped_areas_apc = list(
/area/engine/engineering,
/area/engine/supermatter,
/area/turret_protected/ai)
if(announce)
+1
View File
@@ -29,6 +29,7 @@
/proc/power_failure(announce=TRUE)
var/list/skipped_areas_apc = list(
/area/engine/engineering,
/area/engine/supermatter,
/area/turret_protected/ai)
if(announce)
+2 -3
View File
@@ -10,12 +10,12 @@
log_and_message_admins("Warning: Could not spawn any mobs for event Blob")
/datum/event/blob/start()
processing = FALSE //so it won't fire again in next tick
var/turf/T = pick(GLOB.blobstart)
if(!T)
return kill()
INVOKE_ASYNC(src, .proc/make_blob)
/datum/event/blob/proc/make_blob()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a blob infested mouse?", ROLE_BLOB, TRUE, source = /mob/living/simple_animal/mouse/blobinfected)
if(!length(candidates))
return kill()
@@ -32,4 +32,3 @@
to_chat(B, "<span class='userdanger'>You are now a mouse, infected with blob spores. Find somewhere isolated... before you burst and become the blob! Use ventcrawl (alt-click on vents) to move around.</span>")
notify_ghosts("Infected Mouse has appeared in [get_area(B)].", source = B)
successSpawn = TRUE
processing = TRUE // Let it naturally end, if it runs successfully
+24 -20
View File
@@ -18,6 +18,7 @@
var/strength = 2 //ex_act severity number
var/life = 2 //how many things we hit before qdel(src)
var/atom/goal = null
var/shake_chance = 50
/obj/effect/space_dust/weak
strength = 3
@@ -64,30 +65,33 @@
src.x = startx
src.y = starty
src.z = level_name_to_num(MAIN_STATION)
spawn(0)
walk_towards(src, goal, 1)
return
walk_towards(src, goal, 1)
/obj/effect/space_dust/Bump(atom/A)
spawn(0)
if(prob(50))
for(var/mob/M in range(10, src))
if(!M.stat && !istype(M, /mob/living/silicon/ai))
shake_camera(M, 3, 1)
if(A)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
if(QDELETED(src))
return
if(prob(shake_chance))
for(var/mob/M in range(10, src))
if(!M.stat && !istype(M, /mob/living/silicon/ai))
shake_camera(M, 3, 1)
playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1)
if(ismob(A))
A.ex_act(strength)//This should work for now I guess
else if(!istype(A,/obj/machinery/power/emitter) && !istype(A,/obj/machinery/field/generator)) //Protect the singularity from getting released every round!
A.ex_act(strength) //Changing emitter/field gen ex_act would make it immune to bombs and C4
INVOKE_ASYNC(src, .proc/impact_meteor, A) // ex_act can have some sleeps in it
life--
if(life <= 0)
walk(src,0)
spawn(1)
qdel(src)
return
/obj/effect/space_dust/proc/impact_meteor(atom/A)
var/turf/where = get_turf(A)
if(ismob(A))
A.ex_act(strength)//This should work for now I guess
else if(!istype(A, /obj/machinery/power/emitter) && !istype(A, /obj/machinery/field/generator)) //Protect the singularity from getting released every round!
A.ex_act(strength) //Changing emitter/field gen ex_act would make it immune to bombs and C4
life--
if(life <= 0)
walk(src, 0)
on_shatter(where)
qdel(src)
/obj/effect/space_dust/proc/on_shatter(turf/where)
return
/obj/effect/space_dust/Bumped(atom/A)
+5 -4
View File
@@ -53,7 +53,6 @@
/datum/event //NOTE: Times are measured in master controller ticks!
/// The human-readable name of the event
var/name
var/processing = 1
/// When in the lifetime to call start().
var/startWhen = 0
/// When in the lifetime to call announce().
@@ -93,6 +92,7 @@
*
* Allows you to start before announcing or vice versa.
* Only called once.
* Ensure no sleep is called. Use INVOKE_ASYNC to call procs which do.
*/
/datum/event/proc/start()
return
@@ -102,6 +102,7 @@
*
* Allows you to announce before starting or vice versa.
* Only called once.
* Ensure no sleep is called. Use INVOKE_ASYNC to call procs which do.
*/
/datum/event/proc/announce()
return
@@ -112,6 +113,7 @@
* You can include code related to your event or add your own
* time stamped events.
* Called more than once.
* Ensure no sleep is called. Use INVOKE_ASYNC to call procs which do.
*/
/datum/event/proc/tick()
return
@@ -124,6 +126,7 @@
* the activeFor variable.
* For example: if(activeFor == myOwnVariable + 30) doStuff()
* Only called once.
* Ensure no sleep is called. Use INVOKE_ASYNC to call procs which do.
*/
/datum/event/proc/end()
return
@@ -138,11 +141,9 @@
* Do not override this proc, instead use the appropiate procs.
*
* This proc will handle the calls to the appropiate procs.
* Ensure none of the code paths have a sleep in them. Use INVOKE_ASYNC to call procs which do.
*/
/datum/event/process()
if(!processing)
return
if(activeFor > startWhen && activeFor < endWhen || noAutoEnd)
tick()
+13 -11
View File
@@ -15,8 +15,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/datum/event/immovable_rod/start()
var/startside = pick(GLOB.cardinal)
var/turf/startT = spaceDebrisStartLoc(startside, 1)
var/turf/endT = spaceDebrisFinishLoc(startside, 1)
var/turf/startT = spaceDebrisStartLoc(startside, level_name_to_num(MAIN_STATION))
var/turf/endT = spaceDebrisFinishLoc(startside, level_name_to_num(MAIN_STATION))
new /obj/effect/immovablerod/event(startT, endT)
/obj/effect/immovablerod
@@ -25,8 +25,8 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
icon = 'icons/obj/objects.dmi'
icon_state = "immrod"
throwforce = 100
density = 1
anchored = 1
density = TRUE
anchored = TRUE
var/z_original = 0
var/destination
var/notify = TRUE
@@ -41,9 +41,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
if(notify)
notify_ghosts("\A [src] is inbound!",
enter_link="<a href=?src=[UID()];follow=1>(Click to follow)</a>",
source=src, action=NOTIFY_FOLLOW)
source = src, action = NOTIFY_FOLLOW)
GLOB.poi_list |= src
if(end && end.z==z_original)
if(end?.z == z_original)
walk_towards(src, destination, move_delay)
/obj/effect/immovablerod/Topic(href, href_list)
@@ -67,21 +67,23 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
/obj/effect/immovablerod/Bump(atom/clong)
if(prob(10))
playsound(src, 'sound/effects/bang.ogg', 50, 1)
playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
audible_message("CLANG")
if(clong && prob(25))
x = clong.x
y = clong.y
if(istype(clong, /turf) || istype(clong, /obj))
if(isturf(clong) || isobj(clong))
if(clong.density)
clong.ex_act(2)
else if(istype(clong, /mob))
if(istype(clong, /mob/living/carbon/human))
else if(ismob(clong))
if(ishuman(clong))
var/mob/living/carbon/human/H = clong
H.visible_message("<span class='danger'>[H.name] is penetrated by an immovable rod!</span>" , "<span class='userdanger'>The rod penetrates you!</span>" , "<span class ='danger'>You hear a CLANG!</span>")
H.visible_message("<span class='danger'>[H.name] is penetrated by an immovable rod!</span>" ,
"<span class='userdanger'>The rod penetrates you!</span>" ,
"<span class ='danger'>You hear a CLANG!</span>")
H.adjustBruteLoss(160)
if(clong.density || prob(10))
clong.ex_act(2)
+10 -13
View File
@@ -80,20 +80,17 @@
spawn_types = list(/obj/structure/spider/spiderling)
max_number = 3
vermstring = "spiders"
var/amount_to_spawn = rand(2, max_number)
while(length(turfs) && amount_to_spawn > 0)
var/turf/simulated/floor/T = pick_n_take(turfs)
amount_to_spawn--
spawn(0)
var/num = rand(2,max_number)
while(turfs.len > 0 && num > 0)
var/turf/simulated/floor/T = pick(turfs)
turfs.Remove(T)
num--
if(vermin == VERM_SPIDERS)
var/obj/structure/spider/spiderling/S = new(T)
S.amount_grown = -1
else
var/spawn_type = pick(spawn_types)
new spawn_type(T)
if(vermin == VERM_SPIDERS)
var/obj/structure/spider/spiderling/S = new(T)
S.amount_grown = -1
else
var/spawn_type = pick(spawn_types)
new spawn_type(T)
/datum/event/infestation/announce()
+4 -7
View File
@@ -4,14 +4,11 @@
/datum/event/meteor_wave/gore/setup()
waves = 3
/datum/event/meteor_wave/gore/get_meteor_count()
return rand(5, 8)
/datum/event/meteor_wave/gore/tick()
if(waves && activeFor >= next_meteor)
spawn() spawn_meteors(rand(5,8), GLOB.meteors_gore)
next_meteor += rand(15, 30)
waves--
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
/datum/event/meteor_wave/gore/get_meteors()
return GLOB.meteors_gore
/datum/event/meteor_wave/gore/end()
GLOB.event_announcement.Announce("The station has cleared the debris.", "Debris Alert")
+4 -8
View File
@@ -5,15 +5,11 @@
/datum/event/meteor_wave/goreop/setup()
waves = 3
/datum/event/meteor_wave/goreop/get_meteor_count()
return 5
/datum/event/meteor_wave/goreop/tick()
if(waves && activeFor >= next_meteor)
spawn() spawn_meteors(5, GLOB.meteors_ops)
next_meteor += rand(15, 30)
waves--
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
/datum/event/meteor_wave/goreop/get_meteors()
return GLOB.meteors_ops
/datum/event/meteor_wave/goreop/end()
GLOB.event_announcement.Announce("All MeteorOps are dead. Major Station Victory.", "MeteorOps")
+16 -30
View File
@@ -8,6 +8,9 @@
qnty = rand(45,125)
/datum/event/dust/meaty/start()
INVOKE_ASYNC(src, .proc/spawn_meaty_ores)
/datum/event/dust/meaty/proc/spawn_meaty_ores()
while(qnty-- > 0)
new /obj/effect/space_dust/meaty()
if(prob(10))
@@ -19,35 +22,18 @@
strength = 1
life = 3
shake_chance = 20
/obj/effect/space_dust/meaty/Bump(atom/A)
if(prob(20))
spawn(1)
for(var/mob/M in range(10, src))
if(!M.stat && !istype(M, /mob/living/silicon/ai))
shake_camera(M, 3, 1)
if(A)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
walk(src,0)
invisibility = 101
new /obj/effect/decal/cleanable/blood(get_turf(A))
if(ismob(A))
A.ex_act(strength)
else
spawn(0)
if(A)
A.ex_act(strength)
if(src)
walk_towards(src,goal,1)
life--
if(!life)
if(prob(80))
gibs(loc)
if(prob(45))
new /obj/item/reagent_containers/food/snacks/meat(loc)
else if(prob(10))
explosion(get_turf(loc), 0, pick(0,1), pick(2,3), 0)
else
new /mob/living/simple_animal/cow(loc)
/obj/effect/space_dust/meaty/impact_meteor(atom/A)
new /obj/effect/decal/cleanable/blood(get_turf(A))
..()
qdel(src)
/obj/effect/space_dust/meaty/on_shatter(turf/where)
if(prob(80))
gibs(where)
if(prob(45))
new /obj/item/reagent_containers/food/snacks/meat(where)
else if(prob(10))
explosion(where, 0, pick(0,1), pick(2,3), 0)
else
new /mob/living/simple_animal/cow(where)
+4 -1
View File
@@ -17,7 +17,7 @@
//meteor showers are lighter and more common,
/datum/event/meteor_wave/tick()
if(waves && activeFor >= next_meteor)
spawn() spawn_meteors(severity * rand(1,2), get_meteors())
INVOKE_ASYNC(GLOBAL_PROC, .proc/spawn_meteors, get_meteor_count(), get_meteors())
next_meteor += rand(15, 30) / severity
waves--
endWhen = (waves ? next_meteor + 1 : activeFor + 15)
@@ -37,3 +37,6 @@
return GLOB.meteors_threatening
else
return GLOB.meteors_normal
/datum/event/meteor_wave/proc/get_meteor_count()
return severity * rand(1, 2)
+2 -2
View File
@@ -1,8 +1,9 @@
/datum/event/sentience
/datum/event/sentience/start()
processing = FALSE //so it won't fire again in next tick
INVOKE_ASYNC(src, .proc/make_sentient_mob)
/datum/event/sentience/proc/make_sentient_mob()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to awaken as a sentient being?", ROLE_SENTIENT, TRUE)
var/list/potential = list()
var/sentience_type = SENTIENCE_ORGANIC
@@ -40,7 +41,6 @@
SA.del_on_death = FALSE
greet_sentient(SA)
print_command_report(sentience_report, "[command_name()] Update", FALSE)
processing = TRUE // Let it naturally end, if it runs successfully
/datum/event/sentience/proc/greet_sentient(var/mob/living/carbon/human/M)
to_chat(M, "<span class='userdanger'>Hello world!</span>")
+36 -37
View File
@@ -1,49 +1,48 @@
/datum/event/spawn_slaughter
var/key_of_slaughter
/datum/event/spawn_slaughter/proc/get_slaughter(var/end_if_fail = 0)
spawn()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a slaughter demon?", ROLE_DEMON, TRUE, source = /mob/living/simple_animal/slaughter)
if(!candidates.len)
key_of_slaughter = null
kill()
return
var/mob/C = pick(candidates)
key_of_slaughter = C.key
/datum/event/spawn_slaughter/proc/get_slaughter()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a slaughter demon?", ROLE_DEMON, TRUE, source = /mob/living/simple_animal/slaughter)
if(!length(candidates))
kill()
return
if(!key_of_slaughter)
kill()
return
var/mob/C = pick(candidates)
key_of_slaughter = C.key
var/datum/mind/player_mind = new /datum/mind(key_of_slaughter)
player_mind.active = 1
var/list/spawn_locs = list()
if(!key_of_slaughter)
kill()
return
var/datum/mind/player_mind = new /datum/mind(key_of_slaughter)
player_mind.active = TRUE
var/list/spawn_locs = list()
for(var/thing in GLOB.landmarks_list)
var/obj/effect/landmark/L = thing
if(isturf(L.loc))
switch(L.name)
if("revenantspawn")
spawn_locs += L.loc
if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns
for(var/thing in GLOB.landmarks_list)
var/obj/effect/landmark/L = thing
if(isturf(L.loc))
switch(L.name)
if("revenantspawn")
if("carpspawn")
spawn_locs += L.loc
if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns
for(var/thing in GLOB.landmarks_list)
var/obj/effect/landmark/L = thing
if(isturf(L.loc))
switch(L.name)
if("carpspawn")
spawn_locs += L.loc
if(!spawn_locs) //If we can't find either, just spawn the revenant at the player's location
spawn_locs += get_turf(player_mind.current)
if(!spawn_locs) //If we can't find THAT, then just retry
kill()
return
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
S.holder = holder
player_mind.transfer_to(S)
player_mind.assigned_role = "Slaughter Demon"
player_mind.special_role = SPECIAL_ROLE_SLAUGHTER_DEMON
message_admins("[key_name_admin(S)] has been made into a Slaughter Demon by an event.")
log_game("[key_name_admin(S)] was spawned as a Slaughter Demon by an event.")
if(!spawn_locs) //If we can't find either, just spawn the revenant at the player's location
spawn_locs += get_turf(player_mind.current)
if(!spawn_locs) //If we can't find THAT, then just retry
kill()
return
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
S.holder = holder
player_mind.transfer_to(S)
player_mind.assigned_role = "Slaughter Demon"
player_mind.special_role = SPECIAL_ROLE_SLAUGHTER_DEMON
message_admins("[key_name_admin(S)] has been made into a Slaughter Demon by an event.")
log_game("[key_name_admin(S)] was spawned as a Slaughter Demon by an event.")
/datum/event/spawn_slaughter/start()
get_slaughter()
INVOKE_ASYNC(src, .proc/get_slaughter)
+2 -3
View File
@@ -230,9 +230,8 @@
if(explosion_severity < 3)
qdel(holder)
else
. = 1
spawn(5)
holder.wither()
addtimer(CALLBACK(holder, /obj/structure/spacevine.proc/wither), 5)
return TRUE
/datum/spacevine_mutation/explosive/on_death(obj/structure/spacevine/holder, mob/hitter, obj/item/I)
explosion(holder.loc, 0, 0, severity, 0, 0)
+1 -3
View File
@@ -34,9 +34,7 @@
animation.icon_state = "newtear"
animation.icon = 'icons/effects/tear.dmi'
animation.master = src
spawn(15)
if(animation)
qdel(animation)
QDEL_IN(animation, 15)
addtimer(CALLBACK(src, .proc/spew_critters), rand(30, 120))
+27 -26
View File
@@ -33,38 +33,39 @@ GLOBAL_LIST_INIT(unused_trade_stations, list("sol"))
trader_objectives = forge_trader_objectives()
spawn()
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a Sol Trader?", ROLE_TRADER, TRUE)
var/index = 1
while(spawn_count > 0 && candidates.len > 0)
if(index > spawnlocs.len)
index = 1
INVOKE_ASYNC(src, .proc/spawn_traders, spawnlocs)
var/turf/picked_loc = spawnlocs[index]
index++
var/mob/C = pick_n_take(candidates)
spawn_count--
if(C)
GLOB.respawnable_list -= C.client
var/mob/living/carbon/human/M = new /mob/living/carbon/human(picked_loc)
M.ckey = C.ckey // must be before equipOutfit, or that will runtime due to lack of mind
M.equipOutfit(/datum/outfit/admin/sol_trader)
M.dna.species.after_equip_job(null, M)
M.mind.objectives += trader_objectives
M.mind.offstation_role = TRUE
greet_trader(M)
success_spawn = 1
if(success_spawn)
GLOB.event_announcement.Announce("A trading shuttle from Jupiter Station has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted")
else
GLOB.unused_trade_stations += station // Return the station to the list of usable stations.
/datum/event/traders/proc/spawn_traders(list/spawnlocs)
var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a Sol Trader?", ROLE_TRADER, TRUE)
var/index = 1
while(spawn_count > 0 && length(candidates))
if(index > length(spawnlocs))
index = 1
var/turf/picked_loc = spawnlocs[index]
index++
var/mob/C = pick_n_take(candidates)
spawn_count--
if(C)
GLOB.respawnable_list -= C.client
var/mob/living/carbon/human/M = new /mob/living/carbon/human(picked_loc)
M.ckey = C.ckey // must be before equipOutfit, or that will runtime due to lack of mind
M.equipOutfit(/datum/outfit/admin/sol_trader)
M.dna.species.after_equip_job(null, M)
M.mind.objectives += trader_objectives
M.mind.offstation_role = TRUE
greet_trader(M)
success_spawn = TRUE
if(success_spawn)
GLOB.event_announcement.Announce("A trading shuttle from Jupiter Station has been granted docking permission at [station_name()] arrivals port 4.", "Trader Shuttle Docking Request Accepted")
else
GLOB.unused_trade_stations += station // Return the station to the list of usable stations.
/datum/event/traders/proc/greet_trader(var/mob/living/carbon/human/M)
to_chat(M, "<span class='boldnotice'>You are a trader!</span>")
to_chat(M, "<span class='notice'>You are currently docked at [get_area(M)].</span>")
to_chat(M, "<span class='notice'>You are about to trade with [station_name()].</span>")
spawn(25)
show_objectives(M.mind)
addtimer(CALLBACK(GLOBAL_PROC, .proc/show_objectives, M.mind), 25)
/datum/event/traders/proc/forge_trader_objectives()
var/list/objs = list()
+24 -19
View File
@@ -6,26 +6,31 @@
GLOB.event_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert")
/datum/event/wallrot/start()
spawn()
var/turf/simulated/wall/center = null
INVOKE_ASYNC(src, .proc/spawn_wallrot)
// 100 attempts
for(var/i=0, i<100, i++)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1)
if(istype(candidate, /turf/simulated/wall))
center = candidate
/datum/event/wallrot/proc/spawn_wallrot()
var/turf/simulated/wall/center = null
if(center)
// Make sure at least one piece of wall rots!
center.rot()
// 100 attempts
for(var/i in 0 to 100)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), level_name_to_num(MAIN_STATION))
if(istype(candidate, /turf/simulated/wall))
center = candidate
break
// Have a chance to rot lots of other walls.
var/rotcount = 0
var/actual_severity = severity * rand(5, 10)
for(var/turf/simulated/wall/W in range(5, center)) if(prob(50))
W.rot()
rotcount++
if(!center)
return
// Make sure at least one piece of wall rots!
center.rot()
// Only rot up to severity walls
if(rotcount >= actual_severity)
break
// Have a chance to rot lots of other walls.
var/rotcount = 0
var/actual_severity = severity * rand(5, 10)
for(var/turf/simulated/wall/W in range(5, center))
if(prob(50))
W.rot()
rotcount++
// Only rot up to severity walls
if(rotcount >= actual_severity)
break
@@ -105,15 +105,9 @@
/obj/machinery/atmospherics/unary/vent_pump
description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
//Freezers
/obj/machinery/atmospherics/unary/cold_sink/freezer
description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
screwdriver, and then using a crowbar."
//Heaters
/obj/machinery/atmospherics/unary/heat_reservoir/heater
description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
//Freezer and Heater
/obj/machinery/atmospherics/unary/thermomachine
description_info = "Cools or heats the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
screwdriver, and then using a crowbar."
@@ -1,4 +1,4 @@
/obj/machinery/power/supermatter_shard
/obj/machinery/power/supermatter_crystal
description_info = "When energized by a laser (or something hitting it), it emits radiation and heat. If the heat reaches above 7000 kelvin, it will send an alert and start taking damage. \
After integrity falls to zero percent, it will delaminate, causing a massive explosion, station-wide radiation spikes, and hallucinations. \
Supermatter reacts badly to oxygen in the atmosphere. It'll also heat up really quick if it is in vacuum.<br>\
+1 -1
View File
@@ -705,7 +705,7 @@ GLOBAL_LIST_INIT(non_fakeattack_weapons, list(/obj/item/gun/projectile, /obj/ite
/obj/item/hand_tele, /obj/item/rcd, /obj/item/tank/jetpack,\
/obj/item/clothing/under/rank/captain, /obj/item/aicard,\
/obj/item/clothing/shoes/magboots, /obj/item/areaeditor/blueprints, /obj/item/disk/nuclear,\
/obj/item/clothing/suit/space/nasavoid, /obj/item/tank))
/obj/item/clothing/suit/space/nasavoid, /obj/item/tank/internals))
/obj/effect/hallucination/bolts
var/list/doors = list()
@@ -36,12 +36,6 @@
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
if(C.eat(src, user))
if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell
var/mob/living/silicon/robot/borg = user
borg.cell.use(30)
var/refill = reagents.get_master_reagent_id()
if(refill in GLOB.drinks) // Only synthesize drinks
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, bitesize), 600)
return TRUE
return FALSE
@@ -72,24 +66,9 @@
to_chat(user, "<span class='warning'> [target] is full.</span>")
return FALSE
var/datum/reagent/refill
var/datum/reagent/refillName
if(isrobot(user))
refill = reagents.get_master_reagent_id()
refillName = reagents.get_master_reagent_name()
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'> You transfer [trans] units of the solution to [target].</span>")
if(isrobot(user)) //Cyborg modules that include drinks automatically refill themselves, but drain the borg's cell
if(refill in GLOB.drinks) // Only synthesize drinks
var/mob/living/silicon/robot/bro = user
var/chargeAmount = max(30,4*trans)
bro.cell.use(chargeAmount)
to_chat(user, "<span class='notice'>Now synthesizing [trans] units of [refillName]...</span>")
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 300)
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, user, "<span class='notice'>Cyborg [src] refilled.</span>"), 300)
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!is_refillable())
to_chat(user, "<span class='warning'>[src]'s tab isn't open!</span>")
+25
View File
@@ -53,3 +53,28 @@
to_chat(user, "<span class='notice'>You mash [src] into a poultice.</span>")
user.drop_item()
qdel(src)
// mint
/obj/item/seeds/mint
name = "pack of mint seeds"
desc = "These seeds grow into mint plants."
icon_state = "seed-mint"
species = "mint"
plantname = "Mint Plant"
product = /obj/item/reagent_containers/food/snacks/grown/mint
lifespan = 20
maturation = 4
production = 5
yield = 5
growthstages = 3
icon_dead = "mint-dead"
reagents_add = list("mint" = 0.03, "plantmatter" = 0.03)
/obj/item/reagent_containers/food/snacks/grown/mint
seed = /obj/item/seeds/mint
name = "mint leaves"
desc = "Process for mint. Distill for menthol. No need to experi-mint." //haha
icon_state = "mint"
tastes = list("mint" = 1)
filling_color = "#A7EE9F"
distill_reagent = "menthol"
+5 -5
View File
@@ -224,7 +224,7 @@
// Cell recharging trait. Charges all mob's power cells to (potency*rate)% mark when eaten.
// Generates sparks on squash.
// Small (potency*rate*5) chance to shock squish or slip target for (potency*rate*5) damage.
// Multiplies max charge by (rate*1000) when used in potato power cells.
// Multiplies max charge by (rate*100) when used in potato power cells.
name = "Electrical Activity"
rate = 0.2
origin_tech = list("powerstorage" = 5)
@@ -233,14 +233,14 @@
/datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
var/power = G.seed.potency*rate
if(prob(power))
C.electrocute_act(round(power), G, 1, TRUE)
C.electrocute_act(round(power), G, 1, SHOCK_NOGLOVES)
/datum/plant_gene/trait/cell_charge/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
if(isliving(target))
var/mob/living/carbon/C = target
var/power = G.seed.potency*rate
if(prob(power))
C.electrocute_act(round(power), G, 1, TRUE)
C.electrocute_act(round(power), G, 1, SHOCK_NOGLOVES)
/datum/plant_gene/trait/cell_charge/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target)
if(!G.reagents.total_volume)
@@ -375,8 +375,8 @@
// The secret of potato supercells!
var/datum/plant_gene/trait/cell_charge/CG = G.seed.get_gene(/datum/plant_gene/trait/cell_charge)
if(CG) // 10x charge for deafult cell charge gene - 20 000 with 100 potency.
pocell.maxcharge *= CG.rate*1000
if(CG) // 20x charge for deafult cell charge gene - 40 000 with 100 potency.
pocell.maxcharge *= CG.rate*100
pocell.charge = pocell.maxcharge
pocell.name = "[G] battery"
pocell.desc = "A rechargable plant based power cell. This one has a power rating of [pocell.maxcharge], and you should not swallow it."
@@ -8,7 +8,8 @@
user.do_attack_animation(target, ATTACK_EFFECT_PUNCH)
target.visible_message("<span class='warning'>[user] elbow drops [target]!</span>", \
"<span class='userdanger'>[user] piledrives you with [user.p_their()] elbow!</span>")
target.death() //FINISH HIM!
if(target.health <= 0) //so it actually checks for crit now
target.death() //FINISH HIM!
target.apply_damage(50, BRUTE, "chest")
playsound(get_turf(target), 'sound/weapons/punch1.ogg', 75, 1, -1)
add_attack_logs(user, target, "Melee attacked with martial-art [src] : Elbow Drop", ATKLOG_ALL)
@@ -11,7 +11,7 @@
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/explorer
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
@@ -53,7 +53,7 @@
resistance_flags = FIRE_PROOF | LAVA_PROOF
slowdown = 0
armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
/obj/item/clothing/suit/space/hostile_environment/New()
..()
+2 -12
View File
@@ -70,23 +70,13 @@
//Pod turfs and objects
//Window
/obj/structure/window/shuttle/survival_pod
/obj/structure/window/full/shuttle/survival_pod
name = "pod window"
icon = 'icons/obj/smooth_structures/pod_window.dmi'
icon_state = "smooth"
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = TRUE
flags = PREVENT_CLICK_UNDER
reinf = TRUE
heat_resistance = 1600
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
smooth = SMOOTH_MORE
canSmoothWith = list(/turf/simulated/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/shuttle/survival_pod)
explosion_block = 3
level = 3
glass_type = /obj/item/stack/sheet/titaniumglass
glass_amount = 2
canSmoothWith = list(/turf/simulated/wall/mineral/titanium/survival, /obj/machinery/door/airlock/survival_pod, /obj/structure/window/full/shuttle/survival_pod)
/obj/structure/window/reinforced/survival_pod
name = "pod window"
@@ -11,7 +11,6 @@
throw_range = 5
origin_tech = "bluespace=2"
slot_flags = SLOT_BELT
var/emagged = FALSE
/obj/item/wormhole_jaunter/attack_self(mob/user)
user.visible_message("<span class='notice'>[user.name] activates the [name]!</span>")
@@ -73,7 +72,6 @@
icon_state = "bhole3"
desc = "A stable hole in the universe made by a wormhole jaunter. Turbulent doesn't even begin to describe how rough passage through one of these is, but at least it will always get you somewhere near a beacon."
failchance = 0
var/emagged = FALSE
/obj/effect/portal/jaunt_tunnel/can_teleport(atom/movable/M)
if(!emagged && ismegafauna(M))
@@ -335,7 +335,7 @@
if(ishuman(user))
var/mobcheck = 0
for(var/mob/living/simple_animal/A in range(1, src))
if(A.melee_damage_upper > 5 || A.mob_size >= MOB_SIZE_LARGE || A.ckey || A.stat)
if(A.melee_damage_upper > 5 || A.mob_size >= MOB_SIZE_LARGE || A.ckey || A.stat || isbot(A))
break
var/obj/structure/closet/stasis/S = new /obj/structure/closet/stasis(A)
user.forceMove(S)
+2 -2
View File
@@ -440,7 +440,7 @@
if(!is_station_level(z))
return
var/msg = "Now available in [get_area_name(src, TRUE) || "Unknown"]:"
var/list/msg = list("Now available in [get_area_name(src, TRUE) || "Unknown"]:")
var/mats_in_stock = list()
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/MAT in materials.materials)
@@ -448,7 +448,7 @@
var/mineral_amount = M.amount / MINERAL_MATERIAL_AMOUNT
if(mineral_amount)
mats_in_stock += M.id
msg += "[capitalize(M.name)]: [mineral_amount] sheets"
msg.Add("[capitalize(M.name)]: [mineral_amount] sheets")
// No point sending a message if we're dry
if(!length(mats_in_stock))
+1 -1
View File
@@ -7,7 +7,7 @@
/datum/map_template/shelter/New()
. = ..()
blacklisted_turfs = typecacheof(list(/turf/simulated/wall, /turf/simulated/mineral, /turf/simulated/shuttle/wall))
blacklisted_turfs = typecacheof(list(/turf/simulated/wall, /turf/simulated/mineral))
whitelisted_turfs = list()
banned_areas = typecacheof(/area/shuttle)
@@ -217,7 +217,8 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/proc/updatePlasmaDisplay()
if(hud_used) //clientless aliens
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='magenta'>[getPlasma()]</font></div>"
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font face='Small Fonts' color='magenta'>[getPlasma()]</font></div>"
hud_used.alien_plasma_display.maptext_x = -3
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
return
@@ -1,21 +1,3 @@
/mob/living/carbon/brain/handle_mutations_and_radiation()
if(radiation)
if(radiation > 100)
if(!container)
to_chat(src, "<span class='danger'>You feel weak.</span>")
else
to_chat(src, "<span class='danger'>STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED.</span>")
switch(radiation)
if(50 to 75)
if(prob(5))
if(!container)
to_chat(src, "<span class='danger'>You feel weak.</span>")
else
to_chat(src, "<span class='danger'>STATUS: DANGEROUS AMOUNTS OF RADIATION DETECTED.</span>")
..()
/mob/living/carbon/brain/proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(status_flags & GODMODE)
return
+38 -48
View File
@@ -144,54 +144,44 @@
M.forceMove(drop_location())
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
if(status_flags & GODMODE) //godmode
return FALSE
if(NO_SHOCK in mutations) //shockproof
return FALSE
if(tesla_shock && tesla_ignore)
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
if(shock_damage < 1 && !override)
return FALSE
if(reagents.has_reagent("teslium"))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
if(illusion)
adjustStaminaLoss(shock_damage)
else
take_overall_damage(0, shock_damage, TRUE, used_weapon = "Electrocution")
shock_internal_organs(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>",
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>",
"<span class='italics'>You hear a heavy electrical crack.</span>")
AdjustJitter(1000) //High numbers for violent convulsions
///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects.
/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
. = ..()
if(!.)
return
//Propagation through pulling
if(!(flags & SHOCK_ILLUSION))
var/list/shocking_queue = list()
if(iscarbon(pulling) && source != pulling)
shocking_queue += pulling
if(iscarbon(pulledby) && source != pulledby)
shocking_queue += pulledby
if(iscarbon(buckled) && source != buckled)
shocking_queue += buckled
for(var/mob/living/carbon/carried in buckled_mobs)
if(source != carried)
shocking_queue += carried
//Found our victims, now lets shock them all
for(var/victim in shocking_queue)
var/mob/living/carbon/C = victim
C.electrocute_act(shock_damage * 0.75, src, 1, flags)
//Stun
var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)
if(should_stun)
Stun(2)
//Jitter and other fluff.
AdjustJitter(1000)
do_jitter_animation(jitteriness)
AdjustStuttering(2)
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
Stun(2)
spawn(20)
AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
Stun(3)
Weaken(3)
if(shock_damage > 200)
src.visible_message(
"<span class='danger'>[src] was arc flashed by the [source]!</span>",
"<span class='userdanger'>The [source] arc flashes and electrocutes you!</span>",
"<span class='italics'>You hear a lightning-like crack!</span>")
playsound(loc, 'sound/effects/eleczap.ogg', 50, 1, -1)
explosion(loc, -1, 0, 2, 2)
if(override)
return override
else
return shock_damage
shock_internal_organs(shock_damage)
addtimer(CALLBACK(src, .proc/secondary_shock, should_stun), 20)
return shock_damage
///Called slightly after electrocute act to reduce jittering and apply a secondary stun.
/mob/living/carbon/proc/secondary_shock(should_stun)
AdjustJitter(-1000, bound_lower = 10) //Still jittery, but vastly less
if(should_stun)
Weaken(3)
/mob/living/carbon/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
@@ -1225,14 +1215,14 @@ so that different stomachs can handle things in different ways VB*/
I.extinguish() //extinguishes our clothes
..()
/mob/living/carbon/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
/mob/living/carbon/clean_blood(radiation_clean = FALSE, clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
if(head)
if(head.clean_blood())
if(head.clean_blood(radiation_clean))
update_inv_head()
if(head.flags_inv & HIDEMASK)
clean_mask = FALSE
if(wear_suit)
if(wear_suit.clean_blood())
if(wear_suit.clean_blood(radiation_clean))
update_inv_wear_suit()
if(wear_suit.flags_inv & HIDESHOES)
clean_feet = FALSE
@@ -412,6 +412,8 @@
. = list(msg)
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M, hudtype)
if(istype(M, /mob/living/carbon/human))
+29 -25
View File
@@ -4,6 +4,7 @@
voice_name = "unknown"
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
deathgasp_on_death = TRUE
/mob/living/carbon/human/New(loc)
@@ -580,37 +581,35 @@
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
if(tesla_shock)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(G.siemens_coefficient <= 0)
total_coeff -= 0.5
///Calculates the siemens coeff based on clothing and species, can also restart hearts.
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
//Calculates the siemens coeff based on clothing. Completely ignores the arguments
if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
if(gloves && gloves.siemens_coefficient <= 0)
siemens_coeff -= 0.5
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
else if(S.siemens_coefficient == (-1))
total_coeff -= 1
siemens_coeff = total_coeff
if(tesla_ignore)
siemens_coeff = 0
else if(!safety)
var/gloves_siemens_coeff = 1
if(wear_suit.siemens_coefficient == -1)
siemens_coeff -= 1
else if(wear_suit.siemens_coefficient <= 0)
siemens_coeff -= 0.95
siemens_coeff = max(siemens_coeff, 0)
else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(undergoing_cardiac_arrest() && !illusion)
siemens_coeff *= gloves.siemens_coefficient
siemens_coeff *= dna.species.siemens_coeff
. = ..()
//Don't go further if the shock was blocked/too weak.
if(!.)
return
//Note we both check that the user is in cardiac arrest and can actually heartattack
//If they can't, they're missing their heart and this would runtime
if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
set_heartattack(FALSE)
if(stat == CONSCIOUS)
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
dna.species.spec_electrocute_act(src, shock_damage, source, siemens_coeff, safety, override, tesla_shock, illusion, stun)
. = ..(shock_damage, source, siemens_coeff, safety, override, tesla_shock, illusion, stun)
dna.species.spec_electrocute_act(src, shock_damage, source, siemens_coeff, flags = NONE)
/mob/living/carbon/human/Topic(href, href_list)
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
@@ -1601,13 +1600,18 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
step_towards(hand, src)
to_chat(src, "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>")
apply_effect(current_size * 3, IRRADIATE)
rad_act(current_size * 3)
/mob/living/carbon/human/narsie_act()
if(iswizard(src) && iscultist(src)) //Wizard cultists are immune to narsie because it would prematurely end the wiz round that's about to end by the automated shuttle call anyway
return
..()
/mob/living/carbon/human/rad_act(amount)
if(RADIMMUNE in dna.species.species_traits)
return SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, amount)
. = ..()
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/human/H)
if(H == src)
to_chat(src, "<span class='warning'>You cannot perform CPR on yourself!</span>")
+3 -59
View File
@@ -193,64 +193,8 @@
if(gene_stability < GENETIC_DAMAGE_STAGE_3)
gib()
if(!(RADIMMUNE in dna.species.species_traits))
if(radiation)
radiation = clamp(radiation, 0, 200)
var/autopsy_damage = 0
switch(radiation)
if(1 to 49)
radiation = max(radiation-1, 0)
if(prob(25))
adjustToxLoss(1)
adjustFireLoss(1)
autopsy_damage = 2
if(50 to 74)
radiation = max(radiation-2, 0)
adjustToxLoss(1)
adjustFireLoss(1)
autopsy_damage = 2
if(prob(5))
radiation = max(radiation-5, 0)
Weaken(3)
to_chat(src, "<span class='danger'>You feel weak.</span>")
emote("collapse")
if(75 to 100)
radiation = max(radiation-2, 0)
adjustToxLoss(2)
adjustFireLoss(2)
autopsy_damage = 4
if(prob(2))
to_chat(src, "<span class='danger'>You mutate!</span>")
randmutb(src)
domutcheck(src, null)
if(101 to 150)
radiation = max(radiation-3, 0)
adjustToxLoss(2)
adjustFireLoss(3)
autopsy_damage = 5
if(prob(4))
to_chat(src, "<span class='danger'>You mutate!</span>")
randmutb(src)
domutcheck(src, null)
if(151 to INFINITY)
radiation = max(radiation-3, 0)
adjustToxLoss(2)
adjustFireLoss(3)
autopsy_damage = 5
if(prob(6))
to_chat(src, "<span class='danger'>You mutate!</span>")
randmutb(src)
domutcheck(src, null)
if(autopsy_damage)
var/obj/item/organ/external/chest/chest = get_organ("chest")
if(chest)
chest.add_autopsy_data("Radiation Poisoning", autopsy_damage)
if(!dna || !dna.species.handle_mutations_and_radiation(src))
..()
/mob/living/carbon/human/breathe()
if(!dna.species.breathe(src))
@@ -919,7 +863,7 @@
mind.changeling.regenerate(src)
if(hud_used)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font face='Small Fonts' color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
if(hud_used)
hud_used.lingchemdisplay.invisibility = 101
@@ -370,7 +370,7 @@
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
return
/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
/datum/species/proc/spec_electrocute_act(mob/living/carbon/human/H, shock_damage, source, siemens_coeff = 1, flags = NONE)
return
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
@@ -628,9 +628,9 @@
return FALSE
var/obj/item/organ/external/O = H.get_organ(BODY_ZONE_CHEST)
if(!H.w_uniform && !nojumpsuit && (!O || !(O.status & ORGAN_ROBOT)))
if(!H.w_uniform && !nojumpsuit && !(O?.status & ORGAN_ROBOT))
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
if(!(I.slot_flags & SLOT_BELT))
return
@@ -650,9 +650,9 @@
return FALSE
var/obj/item/organ/external/O = H.get_organ(BODY_ZONE_CHEST)
if(!H.w_uniform && !nojumpsuit && (!O || !(O.status & ORGAN_ROBOT)))
if(!H.w_uniform && !nojumpsuit && !(O?.status & ORGAN_ROBOT))
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
if(!(I.slot_flags & SLOT_ID))
return FALSE
@@ -662,9 +662,9 @@
return FALSE
var/obj/item/organ/external/O = H.get_organ(BODY_ZONE_CHEST)
if(!H.w_uniform && !nojumpsuit && (!O || !(O.status & ORGAN_ROBOT)))
if(!H.w_uniform && !nojumpsuit && !(O?.status & ORGAN_ROBOT))
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
if(!(I.slot_flags & SLOT_PDA))
return FALSE
@@ -676,9 +676,9 @@
return FALSE
var/obj/item/organ/external/O = H.get_organ(BODY_ZONE_L_LEG)
if(!H.w_uniform && !nojumpsuit && (!O || !(O.status & ORGAN_ROBOT)))
if(!H.w_uniform && !nojumpsuit && !(O?.status & ORGAN_ROBOT))
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
if(I.slot_flags & SLOT_DENYPOCKET)
return
@@ -691,9 +691,9 @@
return FALSE
var/obj/item/organ/external/O = H.get_organ(BODY_ZONE_R_LEG)
if(!H.w_uniform && !nojumpsuit && (!O || !(O.status & ORGAN_ROBOT)))
if(!H.w_uniform && !nojumpsuit && !(O?.status & ORGAN_ROBOT))
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
if(I.slot_flags & SLOT_DENYPOCKET)
return FALSE
@@ -707,7 +707,7 @@
return FALSE
if(!H.wear_suit)
if(!disable_warning)
to_chat(H, "<span class='alert'>You need a suit before you can attach this [name].</span>")
to_chat(H, "<span class='alert'>You need a suit before you can attach this [I.name].</span>")
return FALSE
if(!H.wear_suit.allowed)
if(!disable_warning)
@@ -715,7 +715,7 @@
return FALSE
if(I.w_class > WEIGHT_CLASS_BULKY)
if(!disable_warning)
to_chat(H, "The [name] is too big to attach.")
to_chat(H, "<span class='warning'>[I] is too big to attach.</span>")
return FALSE
if(istype(I, /obj/item/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed))
return TRUE
@@ -733,7 +733,7 @@
if(slot_tie)
if(!H.w_uniform)
if(!disable_warning)
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [name].</span>")
to_chat(H, "<span class='warning'>You need a jumpsuit before you can attach this [I.name].</span>")
return FALSE
var/obj/item/clothing/under/uniform = H.w_uniform
if(uniform.accessories.len && !uniform.can_attach_accessory(H))
@@ -749,6 +749,49 @@
/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
return FALSE
/datum/species/proc/handle_mutations_and_radiation(mob/living/carbon/human/H)
if(RADIMMUNE in species_traits)
H.radiation = 0
return TRUE
. = FALSE
var/radiation = H.radiation
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!H.IsWeakened())
H.emote("collapse")
H.Weaken(RAD_MOB_KNOCKDOWN_AMOUNT)
to_chat(H, "<span class='danger'>You feel weak.</span>")
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
H.vomit(10, TRUE)
if(radiation > RAD_MOB_MUTATE)
if(prob(1))
to_chat(H, "<span class='danger'>You mutate!</span>")
randmutb(H)
H.emote("gasp")
domutcheck(H, null)
if(radiation > RAD_MOB_HAIRLOSS)
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
if(!head_organ)
return
if(prob(15) && head_organ.h_style != "Bald")
to_chat(H, "<span class='danger'>Your hair starts to fall out in clumps...</span>")
addtimer(CALLBACK(src, .proc/go_bald, H), 5 SECONDS)
/datum/species/proc/go_bald(mob/living/carbon/human/H)
if(QDELETED(H)) //may be called from a timer
return
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
if(!head_organ)
return
head_organ.f_style = "Shaved"
head_organ.h_style = "Bald"
H.update_hair()
H.update_fhair()
/*
Returns the path corresponding to the corresponding organ
It'll return null if the organ doesn't correspond, so include null checks when using this!
@@ -389,13 +389,7 @@
special_names = list("Oxide", "Rod", "Meltdown")
/datum/species/golem/uranium/handle_life(mob/living/carbon/human/H)
for(var/mob/living/L in range(2, H))
if(ishuman(L))
var/mob/living/carbon/human/I = L
if(!(RADIMMUNE in I.dna.species.species_traits))
L.apply_effect(10, IRRADIATE)
if(prob(25)) //reduce spam
to_chat(L, "<span class='danger'>You are enveloped by a soft green glow emanating from [H].</span>")
radiation_pulse(H, 20)
..()
//Ventcrawler
@@ -134,6 +134,9 @@
if("Blueshield")
O = new /datum/outfit/plasmaman/blueshield
if("Assistant", "Tourist", "Civilian", "Businessman", "Trader")
O = new /datum/outfit/plasmaman/assistant
H.equipOutfit(O, visualsOnly)
H.internal = H.r_hand
H.update_action_buttons_icon()
@@ -86,9 +86,9 @@
var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null
var/obj/item/tank/internal_tank
if(tank_pref)//Diseasel, here you go
internal_tank = new /obj/item/tank/nitrogen(H)
internal_tank = new /obj/item/tank/internals/nitrogen(H)
else
internal_tank = new /obj/item/tank/emergency_oxygen/vox(H)
internal_tank = new /obj/item/tank/internals/emergency_oxygen/double/vox(H)
if(!H.equip_to_appropriate_slot(internal_tank))
if(!H.put_in_any_hand_if_possible(internal_tank))
H.unEquip(H.l_hand)
+6 -26
View File
@@ -47,7 +47,7 @@
else
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src,0)
location_as_object.handle_internal_lifeform(src, 0)
//Second link in a breath chain, calls check_breath()
/mob/living/carbon/proc/breathe()
@@ -81,7 +81,7 @@
if(isobj(loc)) //Breathe from loc as object
var/obj/loc_as_obj = loc
breath = loc_as_obj.handle_internal_lifeform(src, BREATH_MOLES)
breath = loc_as_obj.handle_internal_lifeform(src, BREATH_VOLUME)
else if(isturf(loc)) //Breathe from loc as turf
var/breath_moles = 0
@@ -92,7 +92,7 @@
else //Breathe from loc as obj again
if(istype(loc, /obj/))
var/obj/loc_as_obj = loc
loc_as_obj.handle_internal_lifeform(src,0)
loc_as_obj.handle_internal_lifeform(src, 0)
check_breath(breath)
@@ -226,29 +226,9 @@
return
/mob/living/carbon/handle_mutations_and_radiation()
if(radiation)
switch(radiation)
if(0 to 50)
radiation--
if(prob(25))
adjustToxLoss(1)
updatehealth("handle mutations and radiation(0-50)")
if(50 to 75)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
updatehealth("handle mutations and radiation(50-75)")
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
updatehealth("handle mutations and radiation(75-100)")
radiation = clamp(radiation, 0, 100)
radiation -= min(radiation, RAD_LOSS_PER_TICK)
if(radiation > RAD_MOB_SAFE)
adjustToxLoss(log(radiation - RAD_MOB_SAFE) * RAD_TOX_COEFFICIENT)
/mob/living/carbon/handle_chemicals_in_body()
reagents.metabolize(src)
+29 -21
View File
@@ -72,10 +72,10 @@
/mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/negate_armor = 0)
blocked = (100-blocked)/100
/mob/living/proc/apply_effect(effect = 0, effecttype = STUN, blocked = 0)
blocked = (100 - blocked) / 100
if(!effect || (blocked <= 0))
return 0
return FALSE
switch(effecttype)
if(STUN)
Stun(effect * blocked)
@@ -84,10 +84,7 @@
if(PARALYZE)
Paralyse(effect * blocked)
if(IRRADIATE)
var/rad_damage = effect
if(!negate_armor) // Setting negate_armor overrides radiation armor checks, which are automatic otherwise
rad_damage = max(effect * ((100-run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm."))/100),0)
radiation += rad_damage
radiation += max(effect * blocked, 0)
if(SLUR)
Slur(effect * blocked)
if(STUTTER)
@@ -100,21 +97,32 @@
if(status_flags & CANSTUN)
Jitter(effect * blocked)
updatehealth("apply effect")
return 1
return TRUE
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/slur = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/blocked = 0, var/stamina = 0, var/jitter = 0)
if(blocked >= 100) return 0
if(stun) apply_effect(stun, STUN, blocked)
if(weaken) apply_effect(weaken, WEAKEN, blocked)
if(paralyze) apply_effect(paralyze, PARALYZE, blocked)
if(irradiate) apply_effect(irradiate, IRRADIATE, blocked)
if(slur) apply_effect(slur, SLUR, blocked)
if(stutter) apply_effect(stutter, STUTTER, blocked)
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
if(stamina) apply_damage(stamina, STAMINA, null, blocked)
if(jitter) apply_effect(jitter, JITTER, blocked)
return 1
/mob/living/proc/apply_effects(stun = 0, weaken = 0, paralyze = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = 0, stamina = 0, jitter = 0)
if(blocked >= 100)
return FALSE
if(stun)
apply_effect(stun, STUN, blocked)
if(weaken)
apply_effect(weaken, WEAKEN, blocked)
if(paralyze)
apply_effect(paralyze, PARALYZE, blocked)
if(irradiate)
apply_effect(irradiate, IRRADIATE, blocked)
if(slur)
apply_effect(slur, SLUR, blocked)
if(stutter)
apply_effect(stutter, STUTTER, blocked)
if(eyeblur)
apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy)
apply_effect(drowsy, DROWSY, blocked)
if(stamina)
apply_damage(stamina, STAMINA, null, blocked)
if(jitter)
apply_effect(jitter, JITTER, blocked)
return TRUE
/mob/living/proc/getBruteLoss()
+15
View File
@@ -1033,6 +1033,21 @@
return 1
return 0
/mob/living/rad_act(amount)
. = ..()
if(!amount || (amount < RAD_MOB_SKIN_PROTECTION))
return
amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated
var/blocked = getarmor(null, "rad")
if(amount > RAD_BURN_THRESHOLD)
apply_damage(RAD_BURN_CURVE(amount), BURN, null, blocked)
apply_effect((amount * RAD_MOB_COEFFICIENT) / max(1, (radiation ** 2) * RAD_OVERDOSE_REDUCTION), IRRADIATE, blocked)
/mob/living/proc/fakefireextinguish()
return
+24 -11
View File
@@ -55,22 +55,35 @@
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
return 0
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
///As the name suggests, this should be called to apply electric shocks.
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
if(status_flags & GODMODE) //godmode
return FALSE
if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE))
return FALSE
if(NO_SHOCK in mutations) //shockproof
return FALSE
if(tesla_shock && tesla_ignore)
shock_damage *= siemens_coeff
if(shock_damage < 1)
return FALSE
if(shock_damage > 0)
if(!illusion)
adjustFireLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>",
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>",
"<span class='italics'>You hear a heavy electrical crack.</span>")
return shock_damage
if(!(flags & SHOCK_ILLUSION))
take_overall_damage(0, shock_damage, TRUE, used_weapon = "Electrocution")
if(shock_damage > 200)
visible_message(
"<span class='danger'>[src] was arc flashed by the [source]!</span>",
"<span class='userdanger'>The [source] arc flashes and electrocutes you!</span>",
"<span class='italics'>You hear a lightning-like crack!</span>")
playsound(loc, 'sound/effects/eleczap.ogg', 50, 1, -1)
explosion(loc, -1, 0, 2, 2)
else
adjustStaminaLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='hear'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
/mob/living/emp_act(severity)
..()
@@ -57,9 +57,6 @@
var/gene_stability = DEFAULT_GENE_STABILITY
var/ignore_gene_stability = 0
var/tesla_ignore = FALSE
var/list/say_log = list() //a log of what we've said, plain text, no spans or junk, essentially just each individual "message"
var/list/emote_log = list() //like say_log but for emotes
+7 -2
View File
@@ -108,7 +108,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
return returns
/mob/living/say(var/message, var/verb = "says", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
/mob/living/say(message, verb = "says", sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE)
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
@@ -137,7 +137,12 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
message = trim_left(message)
//parse the language code and consume it
var/list/message_pieces = parse_languages(message)
var/list/message_pieces = list()
if(ignore_languages)
message_pieces = message_to_multilingual(message)
else
message_pieces = parse_languages(message)
if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages
var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
S.speaking.broadcast(src, S.message)
+3
View File
@@ -1142,6 +1142,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
set category = "AI Commands"
var/newmsg = clean_input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg)
if(!newmsg)
return
newmsg = html_decode(newmsg) // This feels a bit redundant, but sanitisation is (probably) important.
if(newmsg != arrivalmsg)
arrivalmsg = newmsg
to_chat(usr, "The arrival message has been successfully changed.")
@@ -317,16 +317,17 @@
to_chat(usr, "<span class='warning'>You are already hacking that door!</span>")
else
hacking = TRUE
INVOKE_ASYNC(src, /datum/pai_software/door_jack/.proc/hackloop)
INVOKE_ASYNC(src, .proc/hackloop)
if("cancel")
hackdoor = null
if("cable")
if(cable)
to_chat(usr, "<span class='warning'>You already have a cable deployed!</span>")
return
var/turf/T = get_turf(pai_holder)
cable = new /obj/item/pai_cable(T)
pai_holder.visible_message("<span class='warning'>A port on [pai_holder] opens to reveal [cable], which promptly falls to the floor.</span>")
playsound(pai_holder, 'sound/mecha/mechmove03.ogg', 25, TRUE)
if(cable) // Retracting
pai_holder.visible_message("<span class='warning'>[cable] is pulled back into [pai_holder] with a quick snap.</span>")
QDEL_NULL(cable)
else // Extending
cable = new /obj/item/pai_cable(get_turf(pai_holder))
pai_holder.visible_message("<span class='warning'>A port on [pai_holder] opens to reveal [cable], which promptly falls to the floor.</span>")
/**
* Door jack hack loop
@@ -1,4 +1,4 @@
#define EMAG_TIMER 3000
#define EMAG_TIMER 5 MINUTES
/mob/living/silicon/robot/drone
name = "drone"
real_name = "drone"
@@ -7,21 +7,19 @@
maxHealth = 35
health = 35
bubble_icon = "machine"
universal_speak = 0
universal_understand = 1
gender = NEUTER
pass_flags = PASSTABLE
braintype = "Robot"
lawupdate = 0
density = 0
lawupdate = FALSE
density = FALSE
has_camera = FALSE
req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS)
ventcrawler = 2
magpulse = 1
ventcrawler = VENTCRAWLER_ALWAYS
magpulse = TRUE
mob_size = MOB_SIZE_SMALL
pull_force = MOVE_FORCE_VERY_WEAK // Can only drag small items
modules_break = FALSE
/// Cooldown for law syncs
var/sync_cooldown = 0
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
@@ -37,7 +35,7 @@
//Used for self-mailing.
var/mail_destination = 0
var/reboot_cooldown = 60 // one minute
var/reboot_cooldown = 1 MINUTES
var/last_reboot
var/list/pullable_drone_items = list(
/obj/item/pipe,
@@ -57,8 +55,8 @@
remove_language("Robot Talk")
remove_language("Galactic Common")
add_language("Drone Talk", 1)
add_language("Drone", 1)
add_language("Drone Talk", TRUE)
add_language("Drone", TRUE)
// Disable the microphone wire on Drones
if(radio)
@@ -86,13 +84,13 @@
radio.recalculateChannels()
//Grab stacks.
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module
stack_wood = locate(/obj/item/stack/sheet/wood) in src.module
stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in src.module
stack_plastic = locate(/obj/item/stack/sheet/plastic) in src.module
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in module
stack_wood = locate(/obj/item/stack/sheet/wood) in module
stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in module
stack_plastic = locate(/obj/item/stack/sheet/plastic) in module
//Grab decompiler.
decompiler = locate(/obj/item/matter_decompiler) in src.module
decompiler = locate(/obj/item/matter_decompiler) in module
//Some tidying-up.
flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'Nanotrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
@@ -103,10 +101,10 @@
laws = new /datum/ai_laws/drone()
connected_ai = null
aiCamera = new/obj/item/camera/siliconcam/drone_camera(src)
aiCamera = new /obj/item/camera/siliconcam/drone_camera(src)
additional_law_channels["Drone"] = ";"
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
playsound(loc, 'sound/machines/twobeep.ogg', 50)
//Redefining some robot procs...
/mob/living/silicon/robot/drone/rename_character(oldname, newname)
@@ -114,7 +112,7 @@
return ..(newname, newname)
/mob/living/silicon/robot/drone/get_default_name()
return "maintenance drone ([rand(100,999)])"
return "maintenance drone ([rand(100, 999)])"
/mob/living/silicon/robot/drone/update_icons()
overlays.Cut()
@@ -126,7 +124,6 @@
/mob/living/silicon/robot/drone/choose_icon()
return
/mob/living/silicon/robot/drone/pick_module()
return
@@ -136,25 +133,23 @@
return FALSE
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/borg/upgrade/))
to_chat(user, "<span class='warning'>The maintenance drone chassis not compatible with \the [W].</span>")
/mob/living/silicon/robot/drone/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/borg/upgrade))
to_chat(user, "<span class='warning'>The maintenance drone chassis is not compatible with [I].</span>")
return
else if(istype(W, /obj/item/crowbar))
to_chat(user, "The machine is hermetically sealed. You can't open the case.")
else if(istype(I, /obj/item/crowbar))
to_chat(user, "<span class='warning'>The machine is hermetically sealed. You can't open the case.</span>")
return
else if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
if(stat == DEAD)
if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
// Currently not functional, so commenting out until it's fixed to avoid confusion
/*if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
to_chat(user, "<span class='warning'>The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.</span>")
return
if(!allowed(W))
if(!allowed(I))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
@@ -164,25 +159,26 @@
to_chat(usr, "<span class='warning'>The reboot system is currently offline. Please wait another [cooldown_time] seconds.</span>")
return
user.visible_message("<span class='warning'>\the [user] swipes [user.p_their()] ID card through [src], attempting to reboot it.</span>", "<span class='warning'>You swipe your ID card through [src], attempting to reboot it.</span>")
user.visible_message("<span class='warning'>[user] swipes [user.p_their()] ID card through [src], attempting to reboot it.</span>",
"<span class='warning'>You swipe your ID card through [src], attempting to reboot it.</span>")
last_reboot = world.time / 10
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.key && D.client)
drones++
if(drones < config.max_maint_drones)
request_player()
request_player()*/
return
else
var/confirm = alert("Using your ID on a Maintenance Drone will shut it down, are you sure you want to do this?", "Disable Drone", "Yes", "No")
if(confirm == ("Yes") && (user in range(3, src)))
user.visible_message("<span class='warning'>\the [user] swipes [user.p_their()] ID card through [src], attempting to shut it down.</span>", "<span class='warning'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
user.visible_message("<span class='warning'>[user] swipes [user.p_their()] ID card through [src], attempting to shut it down.</span>",
"<span class='warning'>You swipe your ID card through [src], attempting to shut it down.</span>")
if(emagged)
return
if(allowed(W))
if(allowed(I))
shut_down()
else
to_chat(user, "<span class='warning'>Access denied.</span>")
@@ -191,7 +187,7 @@
..()
/mob/living/silicon/robot/drone/emag_act(user as mob)
/mob/living/silicon/robot/drone/emag_act(mob/user)
if(!client || stat == DEAD)
to_chat(user, "<span class='warning'>There's not much point subverting this heap of junk.</span>")
return
@@ -210,7 +206,7 @@
if(jobban_isbanned(src, ROLE_SYNDICATE))
SSticker.mode.replace_jobbanned_player(src, ROLE_SYNDICATE)
to_chat(src, "<span class='warning'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script. You sense you have five minutes before the drone server detects this and automatically shuts you down.</span>")
to_chat(src, "<span class='warning'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script. You sense you have <b>five minutes</b> before the drone server detects this and automatically shuts you down.</span>")
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
@@ -218,13 +214,12 @@
GLOB.lawchanges.Add("[time] <B>:</B> [H.name]([H.key]) emagged [name]([key])")
addtimer(CALLBACK(src, .proc/shut_down, TRUE), EMAG_TIMER)
emagged = 1
density = 1
emagged = TRUE
density = TRUE
pass_flags = 0
icon_state = "repairbot-emagged"
holder_type = /obj/item/holder/drone/emagged
update_icons()
lawupdate = 0
connected_ai = null
clear_supplied_laws()
clear_inherent_laws()
@@ -234,7 +229,6 @@
to_chat(src, "<b>Obey these laws:</b>")
laws.show_laws(src)
to_chat(src, "<span class='boldwarning'>ALERT: [H.real_name] is your new master. Obey your new laws and [H.real_name]'s commands.</span>")
return
//DRONE LIFE/DEATH
@@ -262,7 +256,7 @@
full_law_reset()
show_laws()
/mob/living/silicon/robot/drone/proc/shut_down(force=FALSE)
/mob/living/silicon/robot/drone/proc/shut_down(force = FALSE)
if(stat == DEAD)
return
@@ -285,32 +279,32 @@
for(var/mob/dead/observer/O in GLOB.player_list)
if(cannotPossess(O))
continue
if(jobban_isbanned(O,"nonhumandept") || jobban_isbanned(O,"Drone"))
if(jobban_isbanned(O, "nonhumandept") || jobban_isbanned(O, "Drone"))
continue
if(O.client)
if(ROLE_PAI in O.client.prefs.be_special)
question(O.client,O)
question(O.client, O)
/mob/living/silicon/robot/drone/proc/question(var/client/C,var/mob/M)
/mob/living/silicon/robot/drone/proc/question(client/C, mob/M)
spawn(0)
if(!C || !M || jobban_isbanned(M,"nonhumandept") || jobban_isbanned(M,"Drone")) return
if(!C || !M || jobban_isbanned(M, "nonhumandept") || jobban_isbanned(M, "Drone"))
return
var/response = alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", "Yes", "No")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
/mob/living/silicon/robot/drone/proc/transfer_personality(var/client/player)
/mob/living/silicon/robot/drone/proc/transfer_personality(client/player)
if(!player)
return
if(!player) return
if(player.mob && player.mob.mind)
if(player.mob?.mind)
player.mob.mind.transfer_to(src)
player.mob.mind.assigned_role = "Drone"
else
ckey = player.ckey
lawupdate = 0
to_chat(src, "<b>Systems rebooted</b>. Loading base pattern maintenance protocol... <b>loaded</b>.")
full_law_reset()
to_chat(src, "<br><b>You are a maintenance drone, a tiny-brained robotic repair machine</b>.")
@@ -358,21 +352,21 @@
to_chat(src, "<span class='warning'>You are too small to pull that.</span>")
/mob/living/silicon/robot/drone/add_robot_verbs()
src.verbs |= silicon_subsystems
verbs |= silicon_subsystems
/mob/living/silicon/robot/drone/remove_robot_verbs()
src.verbs -= silicon_subsystems
verbs -= silicon_subsystems
/mob/living/silicon/robot/drone/update_canmove(delay_action_updates = 0)
/mob/living/silicon/robot/drone/update_canmove(delay_action_updates = FALSE)
. = ..()
density = emagged //this is reset every canmove update otherwise
/mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
/mob/living/silicon/robot/drone/flash_eyes(intensity = 1, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE)
if(affect_silicon)
return ..()
/mob/living/silicon/robot/drone/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!client && istype(user, /mob/living/silicon/robot/drone))
if(!client && isdrone(user))
to_chat(user, "<span class='warning'>You begin decompiling the other drone.</span>")
if(!do_after(user, 5 SECONDS, target = loc))
to_chat(user, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
@@ -380,7 +374,7 @@
if(QDELETED(src) || QDELETED(user))
return ..()
to_chat(user, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
new /obj/effect/decal/cleanable/blood/oil(get_turf(src))
C.stored_comms["metal"] += 15
C.stored_comms["glass"] += 15
C.stored_comms["wood"] += 5
@@ -6,16 +6,18 @@
req_access = list(ACCESS_ENGINE_EQUIP)
circuit = /obj/item/circuitboard/drone_control
//Used when pinging drones.
var/drone_call_area = "Engineering"
//Used to enable or disable drone fabrication.
/// The linked fabricator
var/obj/machinery/drone_fabricator/dronefab
/// Used when pinging drones
var/drone_call_area = "Engineering"
/// Cooldown for area pings
var/ping_cooldown = 0
/obj/machinery/computer/drone_control/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/drone_control/Initialize(mapload)
. = ..()
find_fab()
/obj/machinery/computer/drone_control/attack_hand(var/mob/user as mob)
/obj/machinery/computer/drone_control/attack_hand(mob/user)
if(..())
return
@@ -23,105 +25,112 @@
to_chat(user, "<span class='warning'>Access denied.</span>")
return
interact(user)
ui_interact(user)
/obj/machinery/computer/drone_control/attack_ghost(mob/user as mob)
interact(user)
/obj/machinery/computer/drone_control/attack_ghost(mob/user)
ui_interact(user)
/obj/machinery/computer/drone_control/interact(mob/user)
// tgui\packages\tgui\interfaces\DroneConsole.js
/obj/machinery/computer/drone_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, 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)
ui = new(user, src, ui_key, "DroneConsole", "Drone Control Console", 420, 500, master_ui, state)
ui.open()
user.set_machine(src)
var/dat
dat += "<B>Maintenance Units</B><BR>"
/obj/machinery/computer/drone_control/ui_data(mob/user)
var/list/data = list()
data["drone_fab"] = FALSE
data["fab_power"] = null
data["drone_prod"] = null
data["drone_progress"] = null
if(dronefab)
data["drone_fab"] = TRUE
data["fab_power"] = dronefab.stat & NOPOWER ? FALSE : TRUE
data["drone_prod"] = dronefab.produce_drones
data["drone_progress"] = dronefab.drone_progress
data["selected_area"] = drone_call_area
data["ping_cd"] = ping_cooldown > world.time ? TRUE : FALSE
data["drones"] = list()
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE" : "<font color='green'>ACTIVE"]</FONT>)"
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
dat += "<BR>Currently located in: [get_area(D)]."
dat += "<BR><A href='?src=[UID()];resync=\ref[D]'>Resync</A> | <A href='?src=[UID()];shutdown=\ref[D]'>Shutdown</A></font>"
var/area/A = get_area(D)
var/turf/T = get_turf(D)
var/list/drone_data = list(
name = D.real_name,
uid = D.UID(),
stat = D.stat,
client = D.client ? TRUE : FALSE,
health = round(D.health / D.maxHealth, 0.1),
charge = round(D.cell.charge / D.cell.maxcharge, 0.1),
location = "[A] ([T.x], [T.y])",
sync_cd = D.sync_cooldown > world.time ? TRUE : FALSE
)
data["drones"] += list(drone_data)
return data
dat += "<BR><BR><B>Request drone presence in area:</B> <A href='?src=[UID()];setarea=1'>[drone_call_area]</A> (<A href='?src=[UID()];ping=1'>Send ping</A>)"
/obj/machinery/computer/drone_control/ui_static_data(mob/user)
var/list/data = list()
data["area_list"] = GLOB.TAGGERLOCATIONS
return data
dat += "<BR><BR><B>Drone fabricator</B>: "
dat += "[dronefab ? "<A href='?src=[UID()];toggle_fab=1'>[(dronefab.produce_drones && !(dronefab.stat & NOPOWER)) ? "ACTIVE" : "INACTIVE"]</A>" : "<font color='red'><b>FABRICATOR NOT DETECTED.</b></font> (<A href='?src=[UID()];search_fab=1'>search</a>)"]"
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
return
/obj/machinery/computer/drone_control/Topic(href, href_list)
/obj/machinery/computer/drone_control/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
if(..())
return
. = TRUE
if(!allowed(usr) && !usr.can_admin_interact())
to_chat(usr, "<span class='warning'>Access denied.</span>")
switch(action)
if("find_fab")
find_fab(usr)
if("toggle_fab")
if(QDELETED(dronefab))
dronefab = null
return
dronefab.produce_drones = !dronefab.produce_drones
var/toggle = dronefab.produce_drones ? "enable" : "disable"
to_chat(usr, "<span class='notice'>You [toggle] drone production in the nearby fabricator.</span>")
message_admins("[key_name_admin(usr)] [toggle]d maintenance drone production from the control console.")
log_game("[key_name(usr)] [toggle]d maintenance drone production from the control console.")
if("set_area")
drone_call_area = params["area"]
if("ping")
ping_cooldown = world.time + 1 MINUTES // One minute cooldown to prevent chat spam
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.client && D.stat == CONSCIOUS)
to_chat(D, "<span class='boldnotice'>-- Maintenance drone presence requested in: [drone_call_area].</span>")
if("resync")
var/mob/living/silicon/robot/drone/D = locateUID(params["uid"])
if(D)
D.sync_cooldown = world.time + 1 MINUTES // One minute cooldown to prevent chat spam
to_chat(usr, "<span class='notice'>You issue a law synchronization directive for the drone.</span>")
D.law_resync()
if("shutdown")
var/mob/living/silicon/robot/drone/D = locateUID(params["uid"])
if(D)
to_chat(usr, "<span class='warning'>You issue a kill command for the unfortunate drone.</span>")
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(D)] from control console.")
D.shut_down()
/obj/machinery/computer/drone_control/proc/find_fab(mob/user)
if(dronefab)
return
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
for(var/obj/machinery/drone_fabricator/fab in get_area(src))
if(href_list["setarea"])
if(fab.stat & NOPOWER)
continue
//Probably should consider using another list, but this one will do.
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in GLOB.TAGGERLOCATIONS
dronefab = fab
if(user)
to_chat(user, "<span class='notice'>Drone fabricator located.</span>")
return
if(!t_area || GLOB.TAGGERLOCATIONS[t_area])
return
drone_call_area = t_area
to_chat(usr, "<span class='notice'>You set the area selector to [drone_call_area].</span>")
else if(href_list["ping"])
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.client && D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
else if(href_list["resync"])
var/mob/living/silicon/robot/drone/D = locate(href_list["resync"])
if(D.stat != 2)
to_chat(usr, "<span class='warning'>You issue a law synchronization directive for the drone.</span>")
D.law_resync()
else if(href_list["shutdown"])
var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"])
if(D.stat != 2)
to_chat(usr, "<span class='warning'>You issue a kill command for the unfortunate drone.</span>")
message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console.")
log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.")
D.shut_down()
else if(href_list["search_fab"])
if(dronefab)
return
for(var/obj/machinery/drone_fabricator/fab in get_area(src))
if(fab.stat & NOPOWER)
continue
dronefab = fab
to_chat(usr, "<span class='notice'>Drone fabricator located.</span>")
return
to_chat(usr, "<span class='warning'>Unable to locate drone fabricator.</span>")
else if(href_list["toggle_fab"])
if(!dronefab)
return
if(get_dist(src,dronefab) > 3)
dronefab = null
to_chat(usr, "<span class='warning'>Unable to locate drone fabricator.</span>")
return
dronefab.produce_drones = !dronefab.produce_drones
to_chat(usr, "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>")
src.updateUsrDialog()
if(user)
to_chat(user, "<span class='warning'>Unable to locate drone fabricator.</span>")
@@ -1,22 +1,18 @@
/obj/machinery/drone_fabricator
name = "drone fabricator"
desc = "A large automated factory for producing maintenance drones."
icon = 'icons/obj/machines/drone_fab.dmi'
icon_state = "drone_fab_idle"
density = 1
anchored = 1
density = TRUE
anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 20
active_power_usage = 5000
var/drone_progress = 0
var/produce_drones = 1
var/time_last_drone = 500
icon = 'icons/obj/machines/drone_fab.dmi'
icon_state = "drone_fab_idle"
/obj/machinery/drone_fabricator/New()
..()
var/produce_drones = TRUE
var/drone_progress = 100
var/time_last_drone = 0
/obj/machinery/drone_fabricator/power_change()
if(powered())
@@ -31,7 +27,8 @@
return
if(stat & NOPOWER || !produce_drones)
if(icon_state != "drone_fab_nopower") icon_state = "drone_fab_nopower"
if(icon_state != "drone_fab_nopower")
icon_state = "drone_fab_nopower"
return
if(drone_progress >= 100)
@@ -40,14 +37,14 @@
icon_state = "drone_fab_active"
var/elapsed = world.time - time_last_drone
drone_progress = round((elapsed/config.drone_build_time)*100)
drone_progress = round((elapsed / config.drone_build_time) * 100)
if(drone_progress >= 100)
visible_message("\The [src] voices a strident beep, indicating a drone chassis is prepared.")
visible_message("[src] voices a strident beep, indicating a drone chassis is prepared.")
/obj/machinery/drone_fabricator/examine(mob/user)
. = ..()
if(produce_drones && drone_progress >= 100 && istype(user,/mob/dead) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
if(produce_drones && drone_progress >= 100 && isobserver(user) && config.allow_drone_spawn && count_drones() < config.max_maint_drones)
. += "<BR><B>A drone is prepared. Select 'Join As Drone' from the Ghost tab to spawn as a maintenance drone.</B>"
/obj/machinery/drone_fabricator/proc/count_drones()
@@ -57,18 +54,17 @@
drones++
return drones
/obj/machinery/drone_fabricator/proc/create_drone(var/client/player)
/obj/machinery/drone_fabricator/proc/create_drone(client/player)
if(stat & NOPOWER)
return
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
return
if(!player || !istype(player.mob,/mob/dead))
if(!player || !isobserver(player.mob))
return
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
visible_message("[src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
flick("h_lathe_leave",src)
time_last_drone = world.time
@@ -88,41 +84,40 @@
to_chat(src, "<span class='warning'>That verb is not currently permitted.</span>")
return
if(!src.stat)
if(stat != DEAD)
return
if(usr != src)
return 0 //something is terribly wrong
return FALSE //something is terribly wrong
if(jobban_isbanned(src,"nonhumandept") || jobban_isbanned(src,"Drone"))
to_chat(usr, "<span class='warning'>You are banned from playing drones and cannot spawn as a drone.</span>")
if(jobban_isbanned(src, "nonhumandept") || jobban_isbanned(src, "Drone"))
to_chat(usr, "<span class='warning'>You are banned from playing drones, and cannot spawn as one.</span>")
return
if(!SSticker || SSticker.current_state < 3)
if(!SSticker || SSticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='warning'>You can't join as a drone before the game starts!</span>")
return
var/drone_age = 14 // 14 days to play as a drone
var/player_age_check = check_client_age(usr.client, drone_age)
var/player_age_check = check_client_age(usr.client, 14) // 14 days to play as a drone
if(player_age_check && config.use_age_restriction_for_antags)
to_chat(usr, "<span class='warning'>This role is not yet available to you. You need to wait another [player_age_check] days.</span>")
return
var/pt_req = role_available_in_playtime(client, ROLE_DRONE)
var/pt_req = role_available_in_playtime(client, "Drone")
if(pt_req)
var/pt_req_string = get_exp_format(pt_req)
to_chat(usr, "<span class='warning'>This role is not yet available to you. Play another [pt_req_string] to unlock it.</span>")
return
var/deathtime = world.time - src.timeofdeath
var/joinedasobserver = 0
if(istype(src,/mob/dead/observer))
var/deathtime = world.time - timeofdeath
var/joinedasobserver = FALSE
if(isobserver(src))
var/mob/dead/observer/G = src
if(cannotPossess(G))
to_chat(usr, "<span class='warning'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
return
if(G.started_as_observer == 1)
joinedasobserver = 1
if(G.started_as_observer == TRUE)
joinedasobserver = TRUE
var/deathtimeminutes = round(deathtime / 600)
var/pluralcheck = "minute"
@@ -132,7 +127,7 @@
pluralcheck = " [deathtimeminutes] minute and"
else if(deathtimeminutes > 1)
pluralcheck = " [deathtimeminutes] minutes and"
var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1)
var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10, 1)
if(deathtime < 6000 && joinedasobserver == 0)
to_chat(usr, "You have been dead for[pluralcheck] [deathtimeseconds] seconds.")
@@ -151,7 +146,7 @@
return
if(DF.drone_progress >= 100)
DF.create_drone(src.client)
DF.create_drone(client)
return
to_chat(src, "<span class='warning'>There are no available drone spawn points, sorry.</span>")
@@ -474,6 +474,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
rename_character(real_name, get_default_name("Default"))
languages = list()
speech_synthesizer_langs = list()
radio.recalculateChannels()
update_icons()
update_headlamp()
@@ -481,7 +482,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
speed = 0 // Remove upgrades.
ionpulse = FALSE
magpulse = FALSE
add_language("Robot Talk", 1)
add_language("Robot Talk", TRUE)
if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade
weather_immunities -= "lava"
@@ -241,6 +241,7 @@
modules += new /obj/item/multitool/cyborg(src)
modules += new /obj/item/t_scanner(src)
modules += new /obj/item/analyzer(src)
modules += new /obj/item/geiger_counter/cyborg(src)
modules += new /obj/item/holosign_creator/engineering(src)
modules += new /obj/item/gripper(src)
modules += new /obj/item/matter_decompiler(src)
@@ -337,7 +338,7 @@
/obj/item/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R)
if(emag)
var/obj/item/reagent_containers/food/drinks/cans/beer/B = emag
B.reagents.add_reagent("beer2", 2)
B.reagents.add_reagent("beer2", 5)
..()
/obj/item/robot_module/butler/add_languages(var/mob/living/silicon/robot/R)
+5 -22
View File
@@ -5,6 +5,7 @@
bubble_icon = "machine"
has_unlimited_silicon_privilege = 1
weather_immunities = list("ash")
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
var/syndicate = 0
var/const/MAIN_CHANNEL = "Main Frequency"
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
@@ -161,7 +162,7 @@
/mob/living/silicon/drop_item()
return
/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
/mob/living/silicon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return FALSE //So borgs they don't die trying to fix wiring
/mob/living/silicon/emp_act(severity)
@@ -222,27 +223,9 @@
return 2
/mob/living/silicon/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/negate_armor = 0)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
/*
if(!effect || (blocked >= 2)) return 0
switch(effecttype)
if(STUN)
Stun(effect / (blocked + 1))
if(WEAKEN)
Weaken(effect / (blocked + 1))
if(PARALYZE)
Paralyse(effect / (blocked + 1))
if(IRRADIATE)
radiation += min((effect - (effect*getarmor(null, "rad"))), 0)//Rads auto check armor
if(STUTTER)
stuttering = max(stuttering,(effect/(blocked+1)))
if(EYE_BLUR)
eye_blurry = max(eye_blurry,(effect/(blocked+1)))
if(DROWSY)
drowsyness = max(drowsyness,(effect/(blocked+1)))
updatehealth()
return 1*/
/mob/living/silicon/apply_effect(effect = 0, effecttype = STUN, blocked = 0)
return FALSE //The only effect that can hit them atm is flashes and they still directly edit so this works for now
/proc/islinked(var/mob/living/silicon/robot/bot, var/mob/living/silicon/ai/ai)
if(!istype(bot) || !istype(ai))

Some files were not shown because too many files have changed in this diff Show More