Merge branch 'master' into punch-bundle

This commit is contained in:
kiwedespars
2020-04-19 16:50:01 -07:00
committed by GitHub
1014 changed files with 182479 additions and 42577 deletions
+201 -1
View File
@@ -324,6 +324,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Service Hallway"
icon_state = "hall_service"
/area/hallway/secondary/civilian
name = "Civilian Wing"
icon_state = "hallFS"
//Command
/area/bridge
@@ -1046,7 +1051,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Monastery Garden"
icon_state = "hydro"
//Science
/area/science
@@ -1393,3 +1397,199 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/crew_quarters/fitness/pool
name = "Pool Area"
icon_state = "pool"
/area/crew_quarters/dorms/blue
name = "Blue Dorms"
icon_state = "Sleep"
nightshift_public_area = NIGHTSHIFT_AREA_NONE
/area/crew_quarters/dorms/purple
name = "Purple Dorms"
icon_state = "Sleep"
nightshift_public_area = NIGHTSHIFT_AREA_NONE
/area/crew_quarters/lounge/jazz
name = "Jazz Lounge"
icon_state = "yellow"
ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg')
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
/area/crew_quarters/fitness/recreation
name = "Recreation Area"
icon_state = "fitness"
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
/area/crew_quarters/fitness/cogpool
name = "Pool"
icon_state = "fitness"
clockwork_warp_fail = "Pool's closed."
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
/area/crew_quarters/barbershop
name = "Barbershop"
icon_state = "blue"
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
/area/crew_quarters/observatory
name = "Observatory"
icon_state = "Sleep"
//Engineering
/area/engine/teg_hot
name = "Hot Loop"
icon_state = "red"
/area/engine/teg_cold
name = "Cold Loop"
icon_state = "blue"
/area/engine/workshop
name = "Engineering Workshop"
icon_state = "engine"
/area/security/courtroom/jury
name = "Jury Room"
icon_state = "courtroom"
/area/quartermaster/miningdock/airless
name = "Mining Dock"
icon_state = "mining"
has_gravity = STANDARD_GRAVITY
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //While part of the station, what good will it do you?
/area/quartermaster/miningdock/airless/no_grav
name = "Mining Dock"
icon_state = "mining"
dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //While part of the station, what good will it do you?
/area/janitor/aux
name = "Auxiliary Custodial Closet"
icon_state = "janitor"
flags_1 = NONE
/area/hydroponics/lobby
name = "Hydroponics Lobby"
icon_state = "hydro"
//Storage
/area/storage/emergency/generic
name = "Emergency Storage"
icon_state = "emergencystorage"
//Construction
/area/construction
name = "Construction Area"
icon_state = "yellow"
ambientsounds = ENGINEERING
/area/construction/secondary
name = "Secondary Construction Area"
icon_state = "yellow"
/area/construction/minisat_exterior
name = "Minisat Exterior"
icon_state = "yellow"
/area/construction/mining/aux_base
name = "Auxiliary Base Construction"
icon_state = "yellow"
/area/construction/mining/aux_base/closet
name = "Auxiliary Closet Construction"
icon_state = "yellow"
/area/construction/supplyshuttle
name = "Supply Shuttle"
icon_state = "yellow"
/area/construction/quarters
name = "Engineers' Quarters"
icon_state = "yellow"
/area/construction/qmaint
name = "Maintenance"
icon_state = "yellow"
/area/construction/hallway
name = "Hallway"
icon_state = "yellow"
/area/construction/solars
name = "Solar Panels"
icon_state = "yellow"
/area/construction/solarscontrol
name = "Solar Panel Control"
icon_state = "yellow"
/area/construction/storage
name = "Construction Site Storage"
icon_state = "yellow"
/area/construction/storage/wing
name = "Storage Wing"
icon_state = "storage_wing"
//Routers
/area/router
name = "Router"
icon_state = "yellow"
ambientsounds = ENGINEERING
/area/router/service
name = "Service Router"
icon_state = "green"
/area/router/public
name = "Public Router"
icon_state = "yellow"
/area/router/sec
name = "Security Router"
icon_state = "blue"
/area/router/medsci
name = "MedSci Router"
icon_state = "yellow"
/area/router/eva
name = "EVA Router"
icon_state = "yellow"
/area/router/air
name = "Airbridge Router"
icon_state = "red"
/area/router/eng
name = "Engineering Router"
icon_state = "yellow"
/area/router/aux
name = "Routing System"
icon_state = "yellow"
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
always_unpowered = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT
power_light = FALSE
power_equip = FALSE
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
ambientsounds = SPACE
blob_allowed = FALSE //While part of the station, what good will it do you?
+1
View File
@@ -63,6 +63,7 @@
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with
/// Color on minimaps, if it's null (which is default) it makes one at random.
var/minimap_color
+13
View File
@@ -13,6 +13,16 @@
Asserts are to avoid the inevitable infinite loops
*/
/area/holodeck/Initialize()
. = ..()
var/list/update_holodeck_cache = SSholodeck?.rejected_areas[type]
if(update_holodeck_cache)
var/list/info_this = list("name" = name, "type" = type)
var/list/target = restricted ? SSholodeck.emag_program_cache : SSholodeck.program_cache
for(var/A in update_holodeck_cache)
LAZYADD(target[A], info_this)
SSholodeck.rejected_areas -= type
/area/holodeck/powered(var/chan)
if(!requires_power)
return 1
@@ -99,6 +109,9 @@
/area/holodeck/rec_center/winterwonderland
name = "Holodeck - Winter Wonderland"
/area/holodeck/rec_center/wrestlingarena
name = "Holodeck - Wrestling Arena"
// Bad programs
/area/holodeck/rec_center/burn
+64 -14
View File
@@ -397,13 +397,13 @@
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
/mob/living/proc/get_blood_dna_list()
var/blood_id = get_blood_id()
if(!(blood_id =="blood" || blood_id == "jellyblood"))
if(!(blood_id in GLOB.blood_reagent_types))
return
return list("ANIMAL DNA" = "Y-")
/mob/living/carbon/get_blood_dna_list()
var/blood_id = get_blood_id()
if(!(blood_id =="blood" || blood_id == "jellyblood"))
if(!(blood_id in GLOB.blood_reagent_types))
return
var/list/blood_dna = list()
if(dna)
@@ -584,11 +584,8 @@
stoplag(1)
qdel(progress)
to_chat(user, "<span class='notice'>You dump as much of [src_object.parent]'s contents into [STR.insert_preposition]to [src] as you can.</span>")
STR.orient2hud(user)
src_object.orient2hud(user)
if(user.active_storage) //refresh the HUD to show the transfered contents
user.active_storage.close(user)
user.active_storage.show_to(user)
user.active_storage.ui_show(user)
return TRUE
/atom/proc/get_dumping_location(obj/item/storage/source,mob/user)
@@ -694,14 +691,64 @@
/atom/vv_get_dropdown()
. = ..()
. += "---"
var/turf/curturf = get_turf(src)
if (curturf)
.["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
.["Modify Transform"] = "?_src_=vars;[HrefToken()];modtransform=[REF(src)]"
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]"
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]"
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]"
VV_DROPDOWN_OPTION("", "---------")
if(!ismovableatom(src))
var/turf/curturf = get_turf(src)
if(curturf)
. += "<option value='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]'>Jump To</option>"
VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRANSFORM, "Modify Transform")
VV_DROPDOWN_OPTION(VV_HK_ADD_REAGENT, "Add Reagent")
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EMP, "EMP Pulse")
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion")
/atom/vv_do_topic(list/href_list)
. = ..()
if(href_list[VV_HK_ADD_REAGENT] && check_rights(R_VAREDIT))
if(!reagents)
var/amount = input(usr, "Specify the reagent size of [src]", "Set Reagent Size", 50) as num
if(amount)
create_reagents(amount)
if(reagents)
var/chosen_id = choose_reagent_id(usr)
if(chosen_id)
var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", reagents.maximum_volume) as num
if(amount)
reagents.add_reagent(chosen_id, amount)
log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to [src]")
message_admins("<span class='notice'>[key_name(usr)] has added [amount] units of [chosen_id] to [src]</span>")
if(href_list[VV_HK_TRIGGER_EXPLOSION] && check_rights(R_FUN))
usr.client.cmd_admin_explosion(src)
if(href_list[VV_HK_TRIGGER_EMP] && check_rights(R_FUN))
usr.client.cmd_admin_emp(src)
if(href_list[VV_HK_MODIFY_TRANSFORM] && check_rights(R_VAREDIT))
var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate")
var/matrix/M = transform
switch(result)
if("Scale")
var/x = input(usr, "Choose x mod","Transform Mod") as null|num
var/y = input(usr, "Choose y mod","Transform Mod") as null|num
if(!isnull(x) && !isnull(y))
transform = M.Scale(x,y)
if("Translate")
var/x = input(usr, "Choose x mod","Transform Mod") as null|num
var/y = input(usr, "Choose y mod","Transform Mod") as null|num
if(!isnull(x) && !isnull(y))
transform = M.Translate(x,y)
if("Rotate")
var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num
if(!isnull(angle))
transform = M.Turn(angle)
if(href_list[VV_HK_AUTO_RENAME] && check_rights(R_VAREDIT))
var/newname = input(usr, "What do you want to rename this to?", "Automatic Rename") as null|text
if(newname)
vv_auto_rename(newname)
/atom/vv_get_header()
. = ..()
var/refid = REF(src)
. += "[VV_HREF_TARGETREF(refid, VV_HK_AUTO_RENAME, "<b id='name'>[src]</b>")]"
. += "<br><font size='1'><a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=left'><<</a> <a href='?_src_=vars;[HrefToken()];datumedit=[refid];varnameedit=dir' id='dir'>[dir2text(dir) || dir]</a> <a href='?_src_=vars;[HrefToken()];rotatedatum=[refid];rotatedir=right'>>></a></font>"
/atom/proc/drop_location()
var/atom/L = loc
@@ -709,6 +756,9 @@
return null
return L.AllowDrop() ? L : L.drop_location()
/atom/proc/vv_auto_rename(newname)
name = newname
/atom/Entered(atom/movable/AM, atom/oldLoc)
SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc)
+2 -3
View File
@@ -468,9 +468,8 @@
/atom/movable/vv_get_dropdown()
. = ..()
. -= "Jump to"
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]"
.["Get"] = "?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]"
. += "<option value='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]'>Follow</option>"
. += "<option value='?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]'>Get</option>"
/atom/movable/proc/ex_check(ex_id)
if(!ex_id)
-2
View File
@@ -147,7 +147,6 @@
return "health-85"
else
return "health-100"
return "0"
//HOOKS
@@ -323,7 +322,6 @@
return "crit"
else
return "dead"
return "dead"
//Sillycone hooks
/mob/living/silicon/proc/diag_hud_set_health()
+34 -55
View File
@@ -9,8 +9,14 @@
var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \
/datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,)
// The antags you're allowed to be if turning Vassal.
/proc/isvamp(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/bloodsucker)
/proc/AmBloodsucker(mob/living/M, falseIfInDisguise = FALSE)
if(!M.mind)
return FALSE
// No Datum
if(!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
return FALSE
return TRUE
/datum/game_mode/bloodsucker
name = "bloodsucker"
@@ -70,49 +76,27 @@
// Gamemode is all done being set up. We have all our Vamps. We now pick objectives and let them know what's happening.
/datum/game_mode/bloodsucker/post_setup()
// Sunlight (Creating Bloodsuckers manually will check to create this, too)
check_start_sunlight()
// Vamps
for(var/datum/mind/bloodsucker in bloodsuckers)
// spawn() --> Run block of code but game continues on past it.
// sleep() --> Run block of code and freeze code there (including whoever called us) until it's resolved.
//Clean Bloodsucker Species (racist?)
//clean_invalid_species(bloodsucker)
// TO-DO !!!
// Add Bloodsucker Antag Datum (or remove from list on Fail)
if (!make_bloodsucker(bloodsucker))
if(!make_bloodsucker(bloodsucker))
bloodsuckers -= bloodsucker
// NOTE: Hunters are done in ..() parent proc
return ..()
// Checking for ACTUALLY Dead Vamps
/datum/game_mode/bloodsucker/are_special_antags_dead()
// Bloodsucker not Final Dead
for(var/datum/mind/bloodsucker in bloodsuckers)
if(!bloodsucker.AmFinalDeath())
return FALSE
return TRUE
// Init Sunlight (called from datum_bloodsucker.on_gain(), in case game mode isn't even Bloodsucker
/datum/game_mode/proc/check_start_sunlight()
// Already Sunlight (and not about to cancel)
if (istype(bloodsucker_sunlight) && !bloodsucker_sunlight.cancel_me)
if(istype(bloodsucker_sunlight) && !bloodsucker_sunlight.cancel_me)
return
bloodsucker_sunlight = new ()
// End Sun (last bloodsucker removed)
/datum/game_mode/proc/check_cancel_sunlight()
// No Sunlight
if (!istype(bloodsucker_sunlight))
if(!istype(bloodsucker_sunlight))
return
if (bloodsuckers.len <= 0)
if(bloodsuckers.len <= 0)
bloodsucker_sunlight.cancel_me = TRUE
qdel(bloodsucker_sunlight)
bloodsucker_sunlight = null
@@ -151,43 +135,37 @@
// Not High Enough
if(creator)
var/datum/antagonist/bloodsucker/creator_bloodsucker = creator.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
if(!istype(creator_bloodsucker) || creator_bloodsucker.vamplevel < BLOODSUCKER_LEVEL_TO_EMBRACE)
if(!istype(creator_bloodsucker) || creator_bloodsucker.bloodsucker_level < BLOODSUCKER_LEVEL_TO_EMBRACE)
to_chat(creator, "<span class='danger'>Your blood is too thin to turn this corpse!</span>")
return FALSE
return TRUE
/datum/game_mode/proc/make_bloodsucker(datum/mind/bloodsucker, datum/mind/creator = null) // NOTE: This is a game_mode/proc, NOT a game_mode/bloodsucker/proc! We need to access this function despite the game mode.
if (!can_make_bloodsucker(bloodsucker))
if(!can_make_bloodsucker(bloodsucker))
return FALSE
// Create Datum: Fledgling
var/datum/antagonist/bloodsucker/A
// [FLEDGLING]
if (creator)
if(creator)
A = new (bloodsucker)
A.creator = creator
bloodsucker.add_antag_datum(A)
// Log
message_admins("[bloodsucker] has become a Bloodsucker, and was created by [creator].")
log_admin("[bloodsucker] has become a Bloodsucker, and was created by [creator].")
// [MASTER]
else
A = bloodsucker.add_antag_datum(ANTAG_DATUM_BLOODSUCKER)
return TRUE
/datum/game_mode/proc/remove_bloodsucker(datum/mind/bloodsucker)
bloodsucker.remove_antag_datum(ANTAG_DATUM_BLOODSUCKER)
/datum/game_mode/proc/clean_invalid_species(datum/mind/bloodsucker)
// Only checking for Humans here
if (!ishuman(bloodsucker.current) || !bloodsucker.current.client)
if(!ishuman(bloodsucker.current) || !bloodsucker.current.client)
return
var/am_valid = TRUE
var/mob/living/carbon/human/H = bloodsucker.current
@@ -202,7 +180,7 @@
// everyone will wonder why you're a human with Plasma clothes (jk they'll know you're antag)
// Convert to HUMAN (along with ID and PDA)
if (!am_valid)
if(!am_valid)
H.set_species(/datum/species/human)
H.real_name = H.client.prefs.custom_names["human"]
var/obj/item/card/id/ID = H.wear_id?.GetID()
@@ -211,12 +189,13 @@
ID.update_label()
/datum/game_mode/proc/can_make_vassal(mob/living/target, datum/mind/creator, display_warning=TRUE)//, check_antag_or_loyal=FALSE)
/datum/game_mode/proc/can_make_vassal(mob/living/target, datum/mind/creator, display_warning = TRUE)//, check_antag_or_loyal=FALSE)
// Not Correct Type: Abort
if (!iscarbon(target) || !creator)
if(!iscarbon(target) || !creator)
return FALSE
if (target.stat > UNCONSCIOUS)
if(target.stat > UNCONSCIOUS)
return FALSE
// Check Overdose: Am I even addicted to blood? Do I even have any in me?
//if (!target.reagents.addiction_list || !target.reagents.reagent_list)
//message_admins("DEBUG2: can_make_vassal() Abort: No reagents")
@@ -233,23 +212,23 @@
//message_admins("DEBUG4: can_make_vassal() Abort: No Blood")
// return 0
// No Mind!
if (!target.mind || !target.mind.key)
if (display_warning)
if(!target.mind || !target.mind.key)
if(display_warning)
to_chat(creator, "<span class='danger'>[target] isn't self-aware enough to be made into a Vassal.</span>")
return FALSE
// Already MY Vassal
var/datum/antagonist/vassal/V = target.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
if (istype(V) && V.master)
if (V.master.owner == creator)
if (display_warning)
if(istype(V) && V.master)
if(V.master.owner == creator)
if(display_warning)
to_chat(creator, "<span class='danger'>[target] is already your loyal Vassal!</span>")
else
if (display_warning)
if(display_warning)
to_chat(creator, "<span class='danger'>[target] is the loyal Vassal of another Bloodsucker!</span>")
return FALSE
// Already Antag or Loyal (Vamp Hunters count as antags)
if (target.mind.enslaved_to || AmInvalidAntag(target.mind)) //!VassalCheckAntagValid(target.mind, check_antag_or_loyal)) // HAS_TRAIT(target, TRAIT_MINDSHIELD, "implant") ||
if (display_warning)
if(target.mind.enslaved_to || AmInvalidAntag(target.mind)) //!VassalCheckAntagValid(target.mind, check_antag_or_loyal)) // HAS_TRAIT(target, TRAIT_MINDSHIELD, "implant") ||
if(display_warning)
to_chat(creator, "<span class='danger'>[target] resists the power of your blood to dominate their mind!</span>")
return FALSE
return TRUE
@@ -268,24 +247,24 @@
return FALSE
// Does even ONE antag appear in this mind that isn't in the list? Then FAIL!
for(var/datum/antagonist/antag_datum in M.antag_datums)
if (!(antag_datum.type in vassal_allowed_antags)) // vassal_allowed_antags is a list stored in the game mode, above.
if(!(antag_datum.type in vassal_allowed_antags)) // vassal_allowed_antags is a list stored in the game mode, above.
//message_admins("DEBUG VASSAL: Found Invalid: [antag_datum] // [antag_datum.type]")
return TRUE
//message_admins("DEBUG VASSAL: Valid Antags! (total of [M.antag_datums.len])")
// WHEN YOU DELETE THE ABOVE: Remove the 3 second timer on converting the vassal too.
return FALSE
/datum/game_mode/proc/make_vassal(mob/living/target, datum/mind/creator)
if (!can_make_vassal(target,creator))
/datum/game_mode/proc/make_vassal(var/mob/living/target, var/datum/mind/creator)
if(!can_make_vassal(target, creator))
return FALSE
// Make Vassal
var/datum/antagonist/vassal/V = new (target.mind)
var/datum/antagonist/vassal/V = new(target.mind)
var/datum/antagonist/bloodsucker/B = creator.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
V.master = B
target.mind.add_antag_datum(V, V.master.get_team())
// Update Bloodsucker Title (we're a daddy now)
B.SelectTitle(am_fledgling = FALSE) // Only works if you have no title yet.
// Log
// Log it
message_admins("[target] has become a Vassal, and is enslaved to [creator].")
log_admin("[target] has become a Vassal, and is enslaved to [creator].")
return TRUE
@@ -119,7 +119,6 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
C.appearance = chosen_prof.appearance_list[slot]
C.name = chosen_prof.name_list[slot]
C.flags_cover = chosen_prof.flags_cover_list[slot]
C.item_color = chosen_prof.item_color_list[slot]
C.item_state = chosen_prof.item_state_list[slot]
if(equip)
user.equip_to_slot_or_del(C, GLOB.slot2slot[slot])
+8 -6
View File
@@ -45,8 +45,11 @@ Credit where due:
// PROCS //
///////////
/proc/is_servant_of_ratvar(mob/M)
return istype(M) && !isobserver(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/clockcult)
/proc/is_servant_of_ratvar(mob/M, require_full_power = FALSE, holy_water_check = FALSE)
if(!istype(M) || isobserver(M))
return FALSE
var/datum/antagonist/clockcult/D = M?.mind?.has_antag_datum(/datum/antagonist/clockcult)
return D && (!require_full_power || !D.neutered) && (!holy_water_check || !D.ignore_holy_water)
/proc/is_eligible_servant(mob/M)
if(!istype(M))
@@ -70,12 +73,14 @@ Credit where due:
return TRUE
return FALSE
/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE)
/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE, override_type)
if(!L || !L.mind)
return
var/update_type = /datum/antagonist/clockcult
if(silent)
update_type = /datum/antagonist/clockcult/silent
if(override_type) //prioritizes
update_type = override_type
var/datum/antagonist/clockcult/C = new update_type(L.mind)
C.make_team = create_team
C.show_in_roundend = create_team //tutorial scarabs begone
@@ -105,9 +110,6 @@ Credit where due:
L.playsound_local(get_turf(L), 'sound/ambience/antag/clockcultalr.ogg', 40, TRUE, frequency = 100000, pressure_affected = FALSE)
flash_color(L, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 5)
/proc/remove_servant_of_ratvar(mob/L, silent = FALSE)
if(!L || !L.mind)
return
@@ -63,7 +63,7 @@
attack_verb_on = list("slipped")
clumsy_check = FALSE
sharpness = IS_BLUNT
item_color = "yellow"
sword_color = "yellow"
heat = 0
light_color = "#ffff00"
var/next_trombone_allowed = 0
+6 -3
View File
@@ -3,8 +3,11 @@
/datum/game_mode
var/list/datum/mind/cult = list()
/proc/iscultist(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/cult)
/proc/iscultist(mob/living/M, require_full_power = FALSE, holy_water_check = FALSE)
if(!istype(M))
return FALSE
var/datum/antagonist/cult/D = M?.mind?.has_antag_datum(/datum/antagonist/cult)
return D && (!require_full_power || !D.neutered) && (!holy_water_check || !D.ignore_holy_water)
/datum/team/cult/proc/is_sacrifice_target(datum/mind/mind)
for(var/datum/objective/sacrifice/sac_objective in objectives)
@@ -93,7 +96,7 @@
add_cultist(cult_mind, 0, equip=TRUE)
if(!main_cult)
var/datum/antagonist/cult/C = cult_mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(C && C.cult_team)
if(C?.cult_team)
main_cult = C.cult_team
..()
+36 -17
View File
@@ -54,12 +54,18 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
// Current storyteller
var/datum/dynamic_storyteller/storyteller = null
// Threat logging vars
/// Starting threat level, for things that increase it but can bring it back down.
var/initial_threat_level = 0
/// Target threat level right now. Events and antags will try to keep the round at this level.
var/threat_level = 0
/// The current antag threat. Recalculated every time a ruletype starts or ends.
var/threat = 0
/// Starting threat level, for things that increase it but can bring it back down.
var/initial_threat_level = 0
/// Threat average over the course of the round, for endgame logs.
var/threat_average = 0
/// Number of times threat average has been calculated, for calculating above.
var/threat_average_weight = 0
/// Last time a threat average sample was taken. Used for weighting the rolling average.
var/last_threat_sample_time = 0
/// Things that cause a rolling threat adjustment to be displayed at roundend.
var/list/threat_tallies = list()
/// Running information about the threat. Can store text or datum entries.
@@ -127,6 +133,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
var/only_ruleset_executed = FALSE
/// Antags rolled by rules so far, to keep track of and discourage scaling past a certain ratio of crew/antags especially on lowpop.
var/antags_rolled = 0
// Arbitrary threat addition, for fudging purposes.
var/added_threat = 50
/datum/game_mode/dynamic/New() // i have NO IDEA if this is the proper way to do this.
..()
@@ -172,9 +180,9 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
else
dat += "none.<br>"
dat += "<br>Injection Timers: (<b>[storyteller.get_injection_chance(TRUE)]%</b> chance)<BR>"
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
dat += "Latejoin: [(latejoin_injection_cooldown-world.time)>60*10 ? "[round((latejoin_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(latejoin_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectlate=1'>\[Now!\]</a><BR>"
dat += "Midround: [(midround_injection_cooldown-world.time)>60*10 ? "[round((midround_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(midround_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];injectmid=1'>\[Now!\]</a><BR>"
dat += "Event: [(event_injection_cooldown-world.time)>60*10 ? "[round((event_injection_cooldown-world.time)/60/10,0.1)] minutes" : "[(event_injection_cooldown-world.time)/10] seconds"] <a href='?src=\ref[src];[HrefToken()];forceevent=1'>\[Now!\]</a><BR>"
usr << browse(dat.Join(), "window=gamemode_panel;size=500x500")
/datum/game_mode/dynamic/Topic(href, href_list)
@@ -197,7 +205,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if(threatadd > 0)
create_threat(threatadd)
else
spend_threat(-threatadd)
remove_threat(threatadd)
else if (href_list["injectlate"])
latejoin_injection_cooldown = 0
forced_injection = TRUE
@@ -239,6 +247,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
. += "<b>Peaceful Waypoint</b></center><BR>"
. += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble."
set_security_level(SEC_LEVEL_GREEN)
station_goals.len = 0
for(var/T in subtypesof(/datum/station_goal))
var/datum/station_goal/G = new T
if(!(G in station_goals))
@@ -249,6 +258,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
. += "<b>Core Territory</b></center><BR>"
. += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station."
set_security_level(SEC_LEVEL_GREEN)
station_goals.len = 0
for(var/T in subtypesof(/datum/station_goal))
var/datum/station_goal/G = new T
if(!(G in station_goals))
@@ -488,7 +498,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
starting_rule = pickweight(drafted_rules)
// Check if the ruleset is highlander and if a highlander ruleset has been executed
else if(starting_rule.flags & HIGHLANDER_RULESET) // Should already be filtered out, but making sure. Check filtering at end of proc if reported.
if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
if(threat_level <= GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
if(highlander_executed)
drafted_rules -= starting_rule
if(drafted_rules.len <= 0)
@@ -509,9 +519,9 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
drafted_rules -= starting_rule
starting_rule.trim_candidates()
starting_rule.scale_up(extra_rulesets_amount, threat)
starting_rule.scale_up(extra_rulesets_amount, threat_level)
if (starting_rule.pre_execute())
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> -[starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
log_threat("[starting_rule.ruletype] - <b>[starting_rule.name]</b> [starting_rule.cost + starting_rule.scaled_times * starting_rule.scaling_cost] threat", verbose = TRUE)
if(starting_rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
else if(starting_rule.flags & ONLY_RULESET)
@@ -605,7 +615,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if ((forced || (new_rule.acceptable(current_players[CURRENT_LIVING_PLAYERS].len, threat_level) && new_rule.cost <= threat)))
new_rule.trim_candidates()
if (new_rule.ready(forced))
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> -[new_rule.cost] threat", verbose = TRUE)
log_threat("[new_rule.ruletype] - <b>[new_rule.name]</b> [new_rule.cost] threat", verbose = TRUE)
if (new_rule.execute()) // This should never fail since ready() returned 1
if(new_rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
@@ -625,7 +635,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
var/datum/dynamic_ruleset/rule = sent_rule
if (rule.execute())
log_game("DYNAMIC: Injected a [rule.ruletype == "latejoin" ? "latejoin" : "midround"] ruleset [rule.name].")
log_threat("[rule.ruletype] [rule.name] spent [rule.cost]", verbose = TRUE)
log_threat("[rule.ruletype] [rule.name] added [rule.cost]", verbose = TRUE)
if(rule.flags & HIGHLANDER_RULESET)
highlander_executed = TRUE
else if(rule.flags & ONLY_RULESET)
@@ -712,7 +722,16 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
current_players[CURRENT_OBSERVERS].Add(M)
continue
current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow)
threat = storyteller.calculate_threat() + 50 // 50 is the centerpoint, so we want it to be around 50
threat = storyteller.calculate_threat() + added_threat
if(threat_average_weight)
var/cur_sample_weight = world.time - last_threat_sample_time
threat_average = ((threat_average * threat_average_weight) + (threat * cur_sample_weight)) / (threat_average_weight + cur_sample_weight)
threat_average_weight += cur_sample_weight
last_threat_sample_time = world.time
else
threat_average = threat
threat_average_weight++
last_threat_sample_time = world.time
/// Removes type from the list
/datum/game_mode/dynamic/proc/remove_from_list(list/type_list, type)
@@ -766,20 +785,20 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
/// Increase the threat level.
/datum/game_mode/dynamic/proc/create_threat(gain)
threat_level += gain
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat")
SSblackbox.record_feedback("tally","dynamic_threat",gain,"Created threat level")
log_threat("[gain] created. Threat level is now [threat_level].", verbose = TRUE)
/// Decrease the threat level.
/datum/game_mode/dynamic/proc/remove_threat(loss)
threat_level -= loss
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat")
SSblackbox.record_feedback("tally","dynamic_threat",loss,"Removed threat level")
log_threat("[loss] removed. Threat level is now [threat_level].", verbose = TRUE)
/// Fill up more of the threat level.
/datum/game_mode/dynamic/proc/spend_threat(cost)
threat += cost
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat spent")
log_threat("[cost] spent. Threat is now [threat].", verbose = TRUE)
added_threat += cost
SSblackbox.record_feedback("tally","dynamic_threat",cost,"Threat added")
log_threat("[cost] added. Threat is now [threat].", verbose = TRUE)
/// Turns the value generated by lorentz distribution to threat value between 0 and 100.
/datum/game_mode/dynamic/proc/lorentz_to_threat(x)
@@ -222,6 +222,26 @@
message_admins("[M.name] was made into a bloodsucker by dynamic.")
return TRUE
//////////////////////////////////////////////
// //
// CHANGELINGS //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/latejoin/changeling
name = "Changeling Infiltrator"
config_tag = "latejoin_changeling"
antag_flag = ROLE_CHANGELING
antag_datum = /datum/antagonist/changeling
restricted_roles = list("AI", "Cyborg")
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
weight = 3
cost = 15
requirements = list(101,101,101,101,101,101,101,101,101,101)
property_weights = list("trust" = -2, "valid" = 2)
high_population_requirement = 101
//////////////////////////////////////////////
// //
// COLLECTOR //
@@ -241,5 +261,5 @@
requirements = list(10,10,10,10,10,10,10,10,10,10)
high_population_requirement = 10
repeatable = TRUE
flags = TRAITOR_RULESET
flags = TRAITOR_RULESET | MINOR_RULESET
property_weights = list("story_potential" = 2, "trust" = -1, "extended" = 2)
@@ -34,8 +34,7 @@
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(list(/datum/element/ghost_role_eligibility))
ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
ghost_eligible = trim_list(get_all_ghost_role_eligible())
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
var/list/trimmed_list = L.Copy()
@@ -415,7 +414,7 @@
required_candidates = 1
blocking_rules = list(/datum/dynamic_ruleset/roundstart/clockcult)
weight = 4
cost = 10
cost = 20
requirements = list(101,101,101,80,60,50,50,50,50,50)
high_population_requirement = 50
repeatable = TRUE
@@ -11,12 +11,14 @@
WAROPS_ALWAYS_ALLOWED: Can always do warops, regardless of threat level.
USE_PREF_WEIGHTS: Will use peoples' preferences to change the threat centre.
FORCE_IF_WON: If this mode won the vote, forces it
USE_PREV_ROUND_WEIGHTS: Changes its threat centre based on the average chaos of previous rounds.
*/
var/flags = 0
var/dead_player_weight = 1 // How much dead players matter for threat calculation
var/weight = 3 // Weights for randomly picking storyteller. Multiplied by score after voting.
var/event_frequency_lower = 6 MINUTES // How rare events will be, at least.
var/event_frequency_upper = 20 MINUTES // How rare events will be, at most.
var/min_players = -1 // How many players are required for this one to start.
var/datum/game_mode/dynamic/mode = null // Cached as soon as it's made, by dynamic.
/**
@@ -52,6 +54,8 @@ Property weights are:
var/turf/T = get_turf(H)
if(H.stat != DEAD && is_station_level(T.z) && !("Station" in H.faction))
threat += H.threat()
for(var/obj/item/phylactery/P in GLOB.poi_list)
threat += 25 // can't be giving them too much of a break
for (var/mob/M in mode.current_players[CURRENT_LIVING_PLAYERS])
if (M?.mind?.assigned_role && M.stat != DEAD)
var/datum/job/J = SSjob.GetJob(M.mind.assigned_role)
@@ -89,6 +93,8 @@ Property weights are:
mean += 5
if(voters)
GLOB.dynamic_curve_centre += (mean/voters)
if(flags & USE_PREV_ROUND_WEIGHTS)
GLOB.dynamic_curve_centre += (50 - SSpersistence.average_dynamic_threat) / 10
GLOB.dynamic_forced_threat_level = forced_threat_level
/datum/dynamic_storyteller/proc/get_midround_cooldown()
@@ -114,7 +120,7 @@ Property weights are:
/datum/dynamic_storyteller/proc/roundstart_draft()
var/list/drafted_rules = list()
for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules)
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level) && mode.threat >= rule.cost) // If we got the population and threat required
if (rule.acceptable(mode.roundstart_pop_ready, mode.threat_level)) // If we got the population and threat required
rule.candidates = mode.candidates.Copy()
rule.trim_candidates()
if (rule.ready() && rule.candidates.len > 0)
@@ -134,17 +140,19 @@ Property weights are:
if (GLOB.dynamic_classic_secret && !((rule.flags & TRAITOR_RULESET) || (rule.flags & MINOR_RULESET)))
continue
rule.trim_candidates()
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
/* Basically, the closer the cost is to the current threat-level-away-from-threat, the more likely it is to
pick this particular ruleset.
Let's use a toy example: there's 60 threat level and 10 threat spent.
We want to pick a ruleset that's close to that, so we run the below equation, on two rulesets.
Ruleset 1 has 30 cost, ruleset 2 has 5 cost.
When we do the math, ruleset 1's threat_weight is 0.538, and ruleset 2's is 0.238, meaning ruleset 1
is 2.26 times as likely to be picked, all other things considered.
Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight.
*/
var/threat_weight = 1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0))
var/threat_weight = 1
if(!(rule.flags & MINOR_RULESET)) // makes the traitor rulesets always possible anyway
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
/* Basically, the closer the cost is to the current threat-level-away-from-threat, the more likely it is to
pick this particular ruleset.
Let's use a toy example: there's 60 threat level and 10 threat spent.
We want to pick a ruleset that's close to that, so we run the below equation, on two rulesets.
Ruleset 1 has 30 cost, ruleset 2 has 5 cost.
When we do the math, ruleset 1's threat_weight is 0.538, and ruleset 2's is 0.238, meaning ruleset 1
is 2.26 times as likely to be picked, all other things considered.
Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight.
*/
threat_weight = 1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0))
if (rule.ready())
var/property_weight = 0
for(var/property in property_weights)
@@ -167,8 +175,10 @@ Property weights are:
rule.candidates = list(newPlayer)
rule.trim_candidates()
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
var/threat_weight = 1-abs(1-(LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
var/threat_weight = 1
if(!(rule.flags & MINOR_RULESET))
var/cost_difference = abs(rule.cost-(mode.threat_level-mode.threat))
threat_weight = 1-abs(1-(LOGISTIC_FUNCTION(2,0.05,cost_difference,0)))
if (rule.ready())
var/property_weight = 0
for(var/property in property_weights)
@@ -195,11 +205,12 @@ Property weights are:
config_tag = "chaotic"
curve_centre = 10
desc = "High chaos modes. Revs, wizard, clock cult. Multiple antags at once. Chaos is kept up all round."
property_weights = list("extended" = -1, "chaos" = 2)
property_weights = list("extended" = -1, "chaos" = 1)
weight = 1
event_frequency_lower = 2 MINUTES
event_frequency_upper = 10 MINUTES
flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON
flags = WAROPS_ALWAYS_ALLOWED
min_players = 40
var/refund_cooldown = 0
/datum/dynamic_storyteller/chaotic/do_process()
@@ -221,7 +232,8 @@ Property weights are:
curve_centre = 2
curve_width = 1.5
weight = 2
flags = WAROPS_ALWAYS_ALLOWED
min_players = 30
flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS
property_weights = list("valid" = 3, "trust" = 5)
/datum/dynamic_storyteller/team/get_injection_chance(dry_run = FALSE)
@@ -242,7 +254,10 @@ Property weights are:
config_tag = "random"
weight = 1
desc = "No weighting at all; every ruleset has the same chance of happening. Cooldowns vary wildly. As random as it gets."
forced_threat_level = 100
/datum/dynamic_storyteller/random/on_start()
..()
GLOB.dynamic_forced_threat_level = rand(0,100)
/datum/dynamic_storyteller/random/get_midround_cooldown()
return rand(GLOB.dynamic_midround_delay_min/2, GLOB.dynamic_midround_delay_max*2)
@@ -256,9 +271,6 @@ Property weights are:
/datum/dynamic_storyteller/random/get_injection_chance()
return 50 // i would do rand(0,100) but it's actually the same thing when you do the math
/datum/dynamic_storyteller/random/calculate_threat()
return 0 // what IS threat
/datum/dynamic_storyteller/random/roundstart_draft()
var/list/drafted_rules = list()
for (var/datum/dynamic_ruleset/roundstart/rule in mode.roundstart_rules)
@@ -312,18 +324,20 @@ Property weights are:
desc = "Antags with options for loadouts and gimmicks. Traitor, wizard, nukies. Has a buildup-climax-falling action threat curve."
weight = 2
curve_width = 2
flags = USE_PREV_ROUND_WEIGHTS
property_weights = list("story_potential" = 2)
/datum/dynamic_storyteller/story/do_process()
/datum/dynamic_storyteller/story/calculate_threat()
var/current_time = (world.time / SSautotransfer.targettime)*180
mode.threat_level = round(mode.initial_threat_level*(sin(current_time)+0.5),0.1)
mode.threat_level = round(mode.initial_threat_level*(sin(current_time)+0.25),0.1)
..()
/datum/dynamic_storyteller/classic
name = "Classic"
config_tag = "classic"
desc = "No special antagonist weights. Good variety, but not like random. Uses your chaos preference to weight."
flags = USE_PREF_WEIGHTS
flags = USE_PREF_WEIGHTS | USE_PREV_ROUND_WEIGHTS
/datum/dynamic_storyteller/suspicion
name = "Intrigue"
@@ -332,6 +346,7 @@ Property weights are:
weight = 2
curve_width = 2
dead_player_weight = 2
flags = USE_PREV_ROUND_WEIGHTS
property_weights = list("trust" = -3)
/datum/dynamic_storyteller/liteextended
+11 -2
View File
@@ -19,6 +19,15 @@ GLOBAL_LIST_EMPTY(objectives)
if(text)
explanation_text = text
/datum/objective/Destroy(force, ...)
GLOB.objectives -= src
if(owner)
for(var/datum/antagonist/A in owner.antag_datums)
A.objectives -= src
if(team)
team.objectives -= src
. = ..()
/datum/objective/proc/get_owners() // Combine owner and team into a single list.
. = (team && team.members) ? team.members.Copy() : list()
if(owner)
@@ -663,7 +672,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
/*
/datum/objective/capture
name = "capture"
var/captured_amount = 0
@@ -709,7 +718,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
*/
//Changeling Objectives
/datum/objective/absorb
+5 -2
View File
@@ -77,14 +77,14 @@
/datum/sabotage_objective/processing/supermatter/can_run()
return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines)
/*
/datum/sabotage_objective/station_integrity
name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal."
sabotage_type = "integrity"
/datum/sabotage_objective/station_integrity/check_conditions()
return 5-(max(SSticker.station_integrity*4,320)/80)
*/
/datum/sabotage_objective/cloner
name = "Destroy all Nanotrasen cloning machines."
sabotage_type = "cloner"
@@ -98,6 +98,9 @@
special_equipment = list(/obj/item/aiModule/syndicate)
excludefromjob = list("Chief Engineer","Research Director","Head of Personnel","Captain","Chief Medical Officer","Head Of Security")
/datum/sabotage_objective/ai_law/can_run()
return length(active_ais())
/datum/sabotage_objective/ai_law/check_conditions()
for (var/i in GLOB.ai_list)
var/mob/living/silicon/ai/aiPlayer = i
+33 -23
View File
@@ -207,11 +207,14 @@
/obj/machinery/sleeper/ui_data()
var/list/data = list()
var/chemical_list = list()
var/blood_percent = 0
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["efficiency"] = efficiency
data["current_vol"] = reagents.total_volume
data["tot_capacity"] = reagents.maximum_volume
data["blood_levels"] = blood_percent
data["blood_status"] = "Patient either has no blood, or does not require it to function."
data["chemical_list"] = chemical_list
data["chems"] = list()
for(var/chem in available_chems)
@@ -247,10 +250,13 @@
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
data["occupant"]["reagents"] = list()
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
if(mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
chemical_list += list(list("name" = R.name, "volume" = R.volume))
else
chemical_list = "Patient has no reagents."
data["occupant"]["failing_organs"] = list()
var/mob/living/carbon/C = mob_occupant
if(C)
@@ -259,21 +265,25 @@
continue
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
var/blood_id = C.get_blood_id()
if(blood_id)
data["occupant"]["blood"] = list() // We can start populating this list.
var/blood_type = C.dna.blood_type
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
data["occupant"]["blood"]["maxBloodVolume"] = (BLOOD_VOLUME_NORMAL*C.blood_ratio)
data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume
data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE
data["occupant"]["blood"]["bloodType"] = blood_type
if(istype(C)) //Non-carbons shouldn't be able to enter sleepers, but this is to prevent runtimes if something ever breaks
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_id = C.get_blood_id()
var/blood_warning = ""
if(blood_percent < 80)
blood_warning = "Patient has low blood levels."
if(blood_percent < 60)
blood_warning = "Patient has DANGEROUSLY low blood levels."
if(blood_id)
var/blood_type = C.dna.blood_type
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
data["blood_status"] = "Patient has [blood_type] type blood. [blood_warning]"
data["blood_levels"] = blood_percent
return data
/obj/machinery/sleeper/ui_act(action, params)
@@ -309,14 +319,14 @@
if(allowed(usr))
if(!is_operational())
return
reagents.remove_reagent(chem, 10)
reagents.remove_reagent(chem, 1000)
return
if(chem in available_chems)
if(!is_operational())
return
/*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in
if(R.purity < 0.8)*/
reagents.remove_reagent(chem, 10)
reagents.remove_reagent(chem, 1000)
else
visible_message("<span class='warning'>Access Denied.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
-2
View File
@@ -381,14 +381,12 @@
for(var/obj/machinery/camera/C in oview(4, M))
if(C.can_use()) // check if camera disabled
return C
break
return null
/proc/near_range_camera(var/mob/M)
for(var/obj/machinery/camera/C in range(4, M))
if(C.can_use()) // check if camera disabled
return C
break
return null
+2 -2
View File
@@ -144,6 +144,8 @@
return FALSE
if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
return FALSE
if(AmBloodsucker(clonemind.current)) //If the mind is a bloodsucker
return FALSE
if(clonemind.active) //somebody is using that mind
if( ckey(clonemind.key)!=ckey )
return FALSE
@@ -159,8 +161,6 @@
mess = TRUE
update_icon()
return FALSE
if(isvamp(clonemind)) //If the mind is a bloodsucker
return FALSE
attempting = TRUE //One at a time!!
countdown.start()
+1 -1
View File
@@ -55,7 +55,7 @@
/obj/item/stack/tile/fakespace/loaded = ARCADE_WEIGHT_TRICK,
/obj/item/stack/tile/fakepit/loaded = ARCADE_WEIGHT_TRICK,
/obj/item/restraints/handcuffs/fake = ARCADE_WEIGHT_TRICK,
/obj/item/clothing/gloves/rapid/hug = ARCADE_WEIGHT_TRICK,
/obj/item/clothing/gloves/fingerless/pugilist/hug = ARCADE_WEIGHT_TRICK,
/obj/item/grenade/chem_grenade/glitter/pink = ARCADE_WEIGHT_TRICK,
/obj/item/grenade/chem_grenade/glitter/blue = ARCADE_WEIGHT_TRICK,
@@ -159,6 +159,8 @@
if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell)
exploding_hell = TRUE
explode_EVERYTHING()
if(QDELETED(src))
return
if(mine_sound)
switch(rand(1,3)) //Play every time a mine is hit
if(1)
@@ -367,10 +369,10 @@
var/row_limit = rows-1
var/column_limit = columns-1
var/mine_limit_v2 = mine_limit
if(rows > 11)
row_limit = 10
if(columns > 11)
column_limit = 10
if(rows > 21)
row_limit = 20
if(columns > 21)
column_limit = 20
if(mine_limit > (rows*columns) * 0.25)
mine_limit_v2 = 24
message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!")
@@ -378,15 +380,38 @@
explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh??
else
explosion(loc, 1, 3, rand(1,5), rand(1,10))
for(var/y69=y-row_limit;y69<y+row_limit;y69++) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us
for(var/x69=x-column_limit;x69<x+column_limit;x69++)
if(prob(mine_limit_v2)) //Probability of explosion happening, according to how many mines were on the board... up to a limit
var/explosionloc
explosionloc = locate(y69,x69,z)
explosion(explosionloc, 0, rand(1,2),rand(1,5),rand(3,10), adminlog = FALSE)
var/list/targets = list()
var/cur_y = y - round(row_limit * 0.5, 1)
var/starting_row = 1
if(cur_y < 1)
starting_row -= cur_y - 1
cur_y = 1
var/start_x = x - round(column_limit * 0.5, 1)
var/starting_column = 1
if(start_x < 1)
starting_column -= start_x - 1
start_x = 1
for(var/row in starting_row to length(table)) //translate the mines locations into actual turf coordinates.
if(!locate(cur_y, start_x, z))
break
var/cur_x = start_x
for(var/column in starting_column to length(table[row]))
var/coord_value = table[row][column]
if(coord_value == 10 || coord_value == 0) //there is a mine in here.
var/turf/T = locate(cur_y, cur_x, z)
if(!T)
break
targets += T
cur_x++
cur_y++
var/num_explosions = 0
for(var/T in shuffle(targets)) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us
addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, rand(1,2),rand(1,5),rand(3,10), FALSE), 15 * ++num_explosions)
if(num_explosions == mine_limit_v2)
return
#undef MINESWEEPERIMG
#undef MINESWEEPER_GAME_MAIN_MENU
#undef MINESWEEPER_GAME_PLAYING
#undef MINESWEEPER_GAME_LOST
#undef MINESWEEPER_GAME_WON
#undef MINESWEEPER_GAME_WON
+2 -2
View File
@@ -45,11 +45,11 @@
if (ismob(user) && !isliving(user)) // ghosts don't need cameras
return
if (!network)
CRASH("No camera network")
stack_trace("No camera network")
user.unset_machine()
return FALSE
if (!(islist(network)))
CRASH("Camera network is not a list")
stack_trace("Camera network is not a list")
user.unset_machine()
return FALSE
@@ -292,6 +292,10 @@
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
CentCom_announce(input, usr)
to_chat(usr, "<span class='notice'>Message transmitted to Central Command.</span>")
for(var/client/X in GLOB.admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(X, sound('sound/effects/printer.ogg'))
window_flash(X, ignorepref = FALSE)
usr.log_talk(input, LOG_SAY, tag="CentCom announcement")
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has messaged CentCom, \"[input]\" at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
CM.lastTimeUsed = world.time
@@ -309,6 +313,10 @@
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
Syndicate_announce(input, usr)
to_chat(usr, "<span class='danger'>SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.</span>")
for(var/client/X in GLOB.admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(X, sound('sound/effects/printer.ogg'))
window_flash(X, ignorepref = FALSE)
usr.log_talk(input, LOG_SAY, tag="Syndicate announcement")
deadchat_broadcast("<span class='deadsay'><span class='name'>[usr.real_name]</span> has messaged the Syndicate, \"[input]\" at <span class='name'>[get_area_name(usr, TRUE)]</span>.</span>", usr)
CM.lastTimeUsed = world.time
@@ -12,5 +12,5 @@
for(var/obj/machinery/door/D in locate(src.x,src.y,src.z))
if(!istype(D, /obj/machinery/door/window) && D.density)
return 0
//There are no false wall checks because that would be fucking retarded
//There are no false wall checks because that would be fucking
return 1
+2 -2
View File
@@ -57,7 +57,7 @@
var/turf/target = locate(target_x, target_y, z)
ghost.forceMove(target)
/obj/machinery/launchpad/proc/isAvailable()
/obj/machinery/launchpad/proc/isAvailable(silent = FALSE)
if(stat & NOPOWER)
return FALSE
if(panel_open)
@@ -198,7 +198,7 @@
QDEL_NULL(briefcase)
return ..()
/obj/machinery/launchpad/briefcase/isAvailable()
/obj/machinery/launchpad/briefcase/isAvailable(silent = FALSE)
if(closed)
return FALSE
return ..()
-1
View File
@@ -469,7 +469,6 @@ GLOBAL_LIST_EMPTY(allConsoles)
if(newmessagepriority < EXTREME_MESSAGE_PRIORITY)
newmessagepriority = EXTREME_MESSAGE_PRIORITY
update_icon()
if(1)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
say(title)
messages += "<span class='bad'>!!!Extreme Priority!!!</span><BR><b>From:</b> [linkedsender]<BR>[message]"
@@ -17,6 +17,11 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
idle_power_usage = 25
circuit = /obj/item/circuitboard/machine/telecomms/broadcaster
/obj/machinery/telecomms/broadcaster/RefreshParts()
idle_power_usage = 25
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 1.5) //Has 2 manipulators
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
// Don't broadcast rejected signals
if(!istype(signal))
@@ -19,6 +19,11 @@
circuit = /obj/item/circuitboard/machine/telecomms/bus
var/change_frequency = 0
/obj/machinery/telecomms/bus/RefreshParts()
idle_power_usage = 50
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 2) //Has 2 manipulators
/obj/machinery/telecomms/bus/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
if(!istype(signal) || !is_freq_listening(signal))
return
@@ -19,6 +19,11 @@
netspeed = 40
circuit = /obj/item/circuitboard/machine/telecomms/hub
/obj/machinery/telecomms/hub/RefreshParts()
idle_power_usage = 80
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 5) //Has 2 manipulators
/obj/machinery/telecomms/hub/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(!is_freq_listening(signal))
return
@@ -16,6 +16,11 @@
circuit = /obj/item/circuitboard/machine/telecomms/processor
var/process_mode = 1 // 1 = Uncompress Signals, 0 = Compress Signals
/obj/machinery/telecomms/processor/RefreshParts()
idle_power_usage = 30
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 1.5) //Has 2 manipulators
/obj/machinery/telecomms/processor/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
if(!is_freq_listening(signal))
return
@@ -15,6 +15,11 @@
idle_power_usage = 30
circuit = /obj/item/circuitboard/machine/telecomms/receiver
/obj/machinery/telecomms/receiver/RefreshParts()
idle_power_usage = 30
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 1.5) //Has 2 manipulators
/obj/machinery/telecomms/receiver/receive_signal(datum/signal/subspace/signal)
if(!on || !istype(signal) || !check_receive_level(signal) || signal.transmission_method != TRANSMISSION_SUBSPACE)
return
@@ -19,6 +19,11 @@
var/broadcasting = 1
var/receiving = 1
/obj/machinery/telecomms/relay/RefreshParts()
idle_power_usage = 30
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating * 1.5) //Has 2 manipulators
/obj/machinery/telecomms/relay/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
// Add our level and send it back
var/turf/T = get_turf(src)
@@ -19,6 +19,11 @@
/obj/machinery/telecomms/server/Initialize()
. = ..()
/obj/machinery/telecomms/server/RefreshParts()
idle_power_usage = 15
for(var/obj/item/stock_parts/manipulator/P in component_parts)
idle_power_usage -= (P.rating) //has 2 manipulators
/obj/machinery/telecomms/server/receive_information(datum/signal/subspace/vocal/signal, obj/machinery/telecomms/machine_from)
// can't log non-vocal signals
if(!istype(signal) || !signal.data["message"] || !is_freq_listening(signal))
+148 -101
View File
@@ -1,3 +1,111 @@
//dye registry, add dye colors and their resulting output here if you want the sprite to change instead of just the color.
GLOBAL_LIST_INIT(dye_registry, list(
DYE_REGISTRY_UNDER = list(
DYE_RED = /obj/item/clothing/under/color/red,
DYE_ORANGE = /obj/item/clothing/under/color/orange,
DYE_YELLOW = /obj/item/clothing/under/color/yellow,
DYE_GREEN = /obj/item/clothing/under/color/green,
DYE_BLUE = /obj/item/clothing/under/color/blue,
DYE_PURPLE = /obj/item/clothing/under/color/lightpurple,
DYE_BLACK = /obj/item/clothing/under/color/black,
DYE_WHITE = /obj/item/clothing/under/color/white,
DYE_RAINBOW = /obj/item/clothing/under/color/rainbow,
DYE_MIME = /obj/item/clothing/under/rank/civilian/mime,
DYE_CLOWN = /obj/item/clothing/under/rank/civilian/clown,
DYE_QM = /obj/item/clothing/under/rank/cargo/qm,
DYE_LAW = /obj/item/clothing/under/suit/black,
DYE_CAPTAIN = /obj/item/clothing/under/rank/captain,
DYE_HOP = /obj/item/clothing/under/rank/civilian/head_of_personnel,
DYE_HOS = /obj/item/clothing/under/rank/security/head_of_security,
DYE_CE = /obj/item/clothing/under/rank/engineering/chief_engineer,
DYE_RD = /obj/item/clothing/under/rank/rnd/research_director,
DYE_CMO = /obj/item/clothing/under/rank/medical/chief_medical_officer,
DYE_REDCOAT = /obj/item/clothing/under/costume/redcoat
),
DYE_REGISTRY_JUMPSKIRT = list(
DYE_RED = /obj/item/clothing/under/color/jumpskirt/red,
DYE_ORANGE = /obj/item/clothing/under/color/jumpskirt/orange,
DYE_YELLOW = /obj/item/clothing/under/color/jumpskirt/yellow,
DYE_GREEN = /obj/item/clothing/under/color/jumpskirt/green,
DYE_BLUE = /obj/item/clothing/under/color/jumpskirt/blue,
DYE_PURPLE = /obj/item/clothing/under/color/jumpskirt/lightpurple,
DYE_BLACK = /obj/item/clothing/under/color/jumpskirt/black,
DYE_WHITE = /obj/item/clothing/under/color/jumpskirt/white,
DYE_RAINBOW = /obj/item/clothing/under/color/jumpskirt/rainbow
),
DYE_REGISTRY_GLOVES = list(
DYE_RED = /obj/item/clothing/gloves/color/red,
DYE_ORANGE = /obj/item/clothing/gloves/color/orange,
DYE_YELLOW = /obj/item/clothing/gloves/color/yellow,
DYE_GREEN = /obj/item/clothing/gloves/color/green,
DYE_BLUE = /obj/item/clothing/gloves/color/blue,
DYE_PURPLE = /obj/item/clothing/gloves/color/purple,
DYE_BLACK = /obj/item/clothing/gloves/color/black,
DYE_WHITE = /obj/item/clothing/gloves/color/white,
DYE_RAINBOW = /obj/item/clothing/gloves/color/rainbow,
DYE_MIME = /obj/item/clothing/gloves/color/white,
DYE_CLOWN = /obj/item/clothing/gloves/color/rainbow,
DYE_QM = /obj/item/clothing/gloves/color/brown,
DYE_CAPTAIN = /obj/item/clothing/gloves/color/captain,
DYE_HOP = /obj/item/clothing/gloves/color/grey,
DYE_HOS = /obj/item/clothing/gloves/color/black,
DYE_CE = /obj/item/clothing/gloves/color/black,
DYE_RD = /obj/item/clothing/gloves/color/grey,
DYE_CMO = /obj/item/clothing/gloves/color/latex/nitrile,
DYE_REDCOAT = /obj/item/clothing/gloves/color/white
),
DYE_REGISTRY_SNEAKERS = list(
DYE_RED = /obj/item/clothing/shoes/sneakers/red,
DYE_ORANGE = /obj/item/clothing/shoes/sneakers/orange,
DYE_YELLOW = /obj/item/clothing/shoes/sneakers/yellow,
DYE_GREEN = /obj/item/clothing/shoes/sneakers/green,
DYE_BLUE = /obj/item/clothing/shoes/sneakers/blue,
DYE_PURPLE = /obj/item/clothing/shoes/sneakers/purple,
DYE_BLACK = /obj/item/clothing/shoes/sneakers/black,
DYE_WHITE = /obj/item/clothing/shoes/sneakers/white,
DYE_RAINBOW = /obj/item/clothing/shoes/sneakers/rainbow,
DYE_MIME = /obj/item/clothing/shoes/sneakers/black,
DYE_QM = /obj/item/clothing/shoes/sneakers/brown,
DYE_CAPTAIN = /obj/item/clothing/shoes/sneakers/brown,
DYE_HOP = /obj/item/clothing/shoes/sneakers/brown,
DYE_CE = /obj/item/clothing/shoes/sneakers/brown,
DYE_RD = /obj/item/clothing/shoes/sneakers/brown,
DYE_CMO = /obj/item/clothing/shoes/sneakers/brown
),
DYE_REGISTRY_FANNYPACK = list(
DYE_RED = /obj/item/storage/belt/fannypack/red,
DYE_ORANGE = /obj/item/storage/belt/fannypack/orange,
DYE_YELLOW = /obj/item/storage/belt/fannypack/yellow,
DYE_GREEN = /obj/item/storage/belt/fannypack/green,
DYE_BLUE = /obj/item/storage/belt/fannypack/blue,
DYE_PURPLE = /obj/item/storage/belt/fannypack/purple,
DYE_BLACK = /obj/item/storage/belt/fannypack/black,
DYE_WHITE = /obj/item/storage/belt/fannypack/white
),
DYE_REGISTRY_BEDSHEET = list(
DYE_RED = /obj/item/bedsheet/red,
DYE_ORANGE = /obj/item/bedsheet/orange,
DYE_YELLOW = /obj/item/bedsheet/yellow,
DYE_GREEN = /obj/item/bedsheet/green,
DYE_BLUE = /obj/item/bedsheet/blue,
DYE_PURPLE = /obj/item/bedsheet/purple,
DYE_BLACK = /obj/item/bedsheet/black,
DYE_WHITE = /obj/item/bedsheet,
DYE_RAINBOW = /obj/item/bedsheet/rainbow,
DYE_MIME = /obj/item/bedsheet/mime,
DYE_CLOWN = /obj/item/bedsheet/clown,
DYE_QM = /obj/item/bedsheet/qm,
DYE_LAW = /obj/item/bedsheet/black,
DYE_CAPTAIN = /obj/item/bedsheet/captain,
DYE_HOP = /obj/item/bedsheet/hop,
DYE_HOS = /obj/item/bedsheet/hos,
DYE_CE = /obj/item/bedsheet/ce,
DYE_RD = /obj/item/bedsheet/rd,
DYE_CMO = /obj/item/bedsheet/cmo,
DYE_COSMIC = /obj/item/bedsheet/cosmos
)
))
/obj/machinery/washing_machine
name = "washing machine"
desc = "Gets rid of those pesky bloodstains, or your money back!"
@@ -13,27 +121,22 @@
/obj/machinery/washing_machine/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click it to start a wash cycle.</span>"
if(!busy)
. += "<span class='notice'><b>Alt-click</b> it to start a wash cycle.</span>"
/obj/machinery/washing_machine/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src))
return
if(busy)
return
if(state_open)
to_chat(user, "<span class='notice'>Close the door first</span>")
return TRUE
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return TRUE
if(has_corgi)
bloody_mess = 1
busy = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/wash_cycle), 200)
@@ -76,6 +179,28 @@
color_source = null
update_icon()
/obj/item/proc/dye_item(dye_color)
if(undyeable)
return FALSE
if(dying_key)
if(!GLOB.dye_registry[dying_key])
log_runtime("Item just tried to be dyed with an invalid registry key: [dying_key]")
return FALSE
var/obj/item/target_type = GLOB.dye_registry[dying_key][dye_color]
if(target_type)
icon = initial(target_type.icon)
icon_state = initial(target_type.icon_state)
lefthand_file = initial(target_type.lefthand_file)
righthand_file = initial(target_type.righthand_file)
item_state = initial(target_type.item_state)
mob_overlay_icon = initial(target_type.mob_overlay_icon)
inhand_x_dimension = initial(target_type.inhand_x_dimension)
inhand_y_dimension = initial(target_type.inhand_y_dimension)
name = initial(target_type.name)
desc = "[initial(target_type.desc)] The colors look a little dodgy."
return target_type //successfully "appearance copy" dyed something; returns the target type as a hacky way of extending
add_atom_colour(dye_color, FIXED_COLOUR_PRIORITY)
return FALSE
//what happens to this object when washed inside a washing machine
/atom/movable/proc/machine_wash(obj/machinery/washing_machine/WM)
@@ -89,105 +214,27 @@
new /obj/item/reagent_containers/food/snacks/meat/slab/corgi(loc)
qdel(src)
/obj/item/paper/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/obj/item/reagents_containers/rag/towel/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
if(istype(WM.color_source, /obj/item/toy/crayon))
var/obj/item/toy/crayon/CR = WM.color_source
add_atom_colour(CR.paint_color, WASHABLE_COLOUR_PRIORITY)
/mob/living/simple_animal/pet/dog/corgi/machine_wash(obj/machinery/washing_machine/WM)
gib()
/obj/item/clothing/under/color/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/rank/machine_wash(obj/machinery/washing_machine/WM)
jumpsuit_wash(WM)
/obj/item/clothing/under/proc/jumpsuit_wash(obj/machinery/washing_machine/WM)
/obj/item/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
var/obj/item/clothing/under/U
for(var/T in typesof(/obj/item/clothing/under/color))
var/obj/item/clothing/under/color/J = T
if(wash_color == initial(J.item_color))
U = J
break
if(!U)
for(var/T in typesof(/obj/item/clothing/under/rank))
var/obj/item/clothing/under/rank/R = T
if(wash_color == initial(R.item_color))
U = R
break
if(U)
item_state = initial(U.item_state)
icon_state = initial(U.icon_state)
item_color = wash_color
name = initial(U.name)
desc = "The colors are a bit dodgy."
can_adjust = initial(U.can_adjust)
if(!can_adjust && adjusted) //we deadjust the uniform if it's now unadjustable
toggle_jumpsuit_adjust()
dye_item(WM.color_source.dye_color)
/obj/item/clothing/gloves/color/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/gloves/color))
var/obj/item/clothing/gloves/color/G = T
if(wash_color == initial(G.item_color))
item_state = initial(G.item_state)
icon_state = initial(G.icon_state)
item_color = wash_color
name = initial(G.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/under/dye_item(dye_color, dye_key)
. = ..()
if(.)
var/obj/item/clothing/under/U = .
can_adjust = initial(U.can_adjust)
if(!can_adjust && adjusted) //we deadjust the uniform if it's now unadjustable
toggle_jumpsuit_adjust()
/obj/item/clothing/shoes/sneakers/machine_wash(obj/machinery/washing_machine/WM)
if(chained)
chained = 0
slowdown = SHOES_SLOWDOWN
new /obj/item/restraints/handcuffs(loc)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/shoes/sneakers))
var/obj/item/clothing/shoes/sneakers/S = T
if(wash_color == initial(S.item_color))
icon_state = initial(S.icon_state)
item_color = wash_color
name = initial(S.name)
desc = "The colors are a bit dodgy."
break
/obj/item/bedsheet/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/bedsheet))
var/obj/item/bedsheet/B = T
if(wash_color == initial(B.item_color))
icon_state = initial(B.icon_state)
item_color = wash_color
name = initial(B.name)
desc = "The colors are a bit dodgy."
break
/obj/item/clothing/head/soft/machine_wash(obj/machinery/washing_machine/WM)
if(WM.color_source)
var/wash_color = WM.color_source.item_color
for(var/T in typesof(/obj/item/clothing/head/soft))
var/obj/item/clothing/head/soft/H = T
if(wash_color == initial(H.item_color))
icon_state = initial(H.icon_state)
item_color = wash_color
name = initial(H.name)
desc = "The colors are a bit dodgy."
break
..()
/obj/machinery/washing_machine/relaymove(mob/user)
container_resist(user)
@@ -223,27 +270,27 @@
if(istype(W, /obj/item/clothing/head/mob_holder))
to_chat(user, "<span class='warning'>It's too unwieldly to put in this way.</span>")
return 1
return TRUE
else if(user.a_intent != INTENT_HARM)
if (!state_open)
to_chat(user, "<span class='warning'>Open the door first!</span>")
return 1
return TRUE
if(bloody_mess)
to_chat(user, "<span class='warning'>[src] must be cleaned up first.</span>")
return 1
return TRUE
if(contents.len >= max_wash_capacity)
to_chat(user, "<span class='warning'>The washing machine is full!</span>")
return 1
return TRUE
if(!user.transferItemToLoc(W, src))
to_chat(user, "<span class='warning'>\The [W] is stuck to your hand, you cannot put it in the washing machine!</span>")
return 1
return TRUE
if(istype(W, /obj/item/toy/crayon) || istype(W, /obj/item/stamp))
if(W.dye_color)
color_source = W
update_icon()
+2 -2
View File
@@ -384,8 +384,8 @@
desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad."
icon_state = "poster39"
/obj/structure/sign/poster/contraband/sun_kist
name = "Sun-kist"
/obj/structure/sign/poster/contraband/starkist
name = "Star-kist"
desc = "Drink the stars!"
icon_state = "poster40"
@@ -0,0 +1,119 @@
// Full credit goes to VG station for these assets. https://github.com/vgstation-coders/vgstation13
// All items in this .dm and the associated .dmi were made by VG station and all credit should go to them.
// -<| IMPORTANT MAPPER NOTE |>-
// Change the 'color' variable on any white sprite to simply recolour it!
/obj/effect/turf_decal/vg_decals
icon = 'icons/turf/vgstation_decals.dmi'
icon_state = "no"
// NUMBERS START
/obj/effect/turf_decal/vg_decals/numbers
icon_state = "no"
/obj/effect/turf_decal/vg_decals/numbers/one
icon_state = "1"
/obj/effect/turf_decal/vg_decals/numbers/two
icon_state = "2"
/obj/effect/turf_decal/vg_decals/numbers/three
icon_state = "3"
/obj/effect/turf_decal/vg_decals/numbers/four
icon_state = "4"
/obj/effect/turf_decal/vg_decals/numbers/five
icon_state = "5"
/obj/effect/turf_decal/vg_decals/numbers/six
icon_state = "6"
/obj/effect/turf_decal/vg_decals/numbers/seven
icon_state = "7"
/obj/effect/turf_decal/vg_decals/numbers/eight
icon_state = "8"
/obj/effect/turf_decal/vg_decals/numbers/nine
icon_state = "9"
/obj/effect/turf_decal/vg_decals/numbers/zero
icon_state = "0"
// NUMBERS END
// ATMOS START
/obj/effect/turf_decal/vg_decals/atmos
icon_state = "no"
/obj/effect/turf_decal/vg_decals/atmos/oxygen
icon_state = "oxygen"
/obj/effect/turf_decal/vg_decals/atmos/carbon_dioxide
icon_state = "carbon_dioxide"
/obj/effect/turf_decal/vg_decals/atmos/nitrogen
icon_state = "nitrogen"
/obj/effect/turf_decal/vg_decals/atmos/air
icon_state = "air"
/obj/effect/turf_decal/vg_decals/atmos/nitrous_oxide
icon_state = "nitrous_oxide"
/obj/effect/turf_decal/vg_decals/atmos/plasma
icon_state = "plasma"
/obj/effect/turf_decal/vg_decals/atmos/mix
icon_state = "mix"
// ATMOS END
// DEPARTMENT START
/obj/effect/turf_decal/vg_decals/department/hop
icon_state = "hop"
/obj/effect/turf_decal/vg_decals/department/bar
icon_state = "bar"
/obj/effect/turf_decal/vg_decals/department/cargo
icon_state = "cargo"
/obj/effect/turf_decal/vg_decals/department/med
icon_state = "med"
/obj/effect/turf_decal/vg_decals/department/sci
icon_state = "sci"
/obj/effect/turf_decal/vg_decals/department/sec
icon_state = "sec"
/obj/effect/turf_decal/vg_decals/department/mining
icon_state = "mine"
/obj/effect/turf_decal/vg_decals/department/zoo
icon_state = "zoo"
// DEPARTMENT END
// MISC START
/obj/effect/turf_decal/vg_decals/no
icon = 'icons/turf/vgstation_decals.dmi'
icon_state = "no"
/obj/effect/turf_decal/vg_decals/radiation_huge
icon_state = "radiation_huge"
/obj/effect/turf_decal/vg_decals/radiation
icon_state = "radiation"
/obj/effect/turf_decal/vg_decals/radiation_custom
icon_state = "radiation-w"
// MISC END
@@ -37,7 +37,7 @@
if(ishuman(source_mob))
var/mob/living/carbon/human/H = source_mob
if(H.dna.species.use_skintones)
body_coloring = "#[skintone2hex(H.skin_tone)]"
body_coloring = SKINTONE2HEX(H.skin_tone)
else
body_coloring = "#[H.dna.features["mcolor"]]"
@@ -49,7 +49,7 @@
H.set_species(gib_mob_species)
dna_to_add = temp_mob.get_blood_dna_list()
if(H.dna.species.use_skintones)
body_coloring = "#[skintone2hex(H.skin_tone)]"
body_coloring = SKINTONE2HEX(H.skin_tone)
else
body_coloring = "#[H.dna.features["mcolor"]]"
else
+264 -6
View File
@@ -2,6 +2,7 @@
icon = 'icons/effects/landmarks_static.dmi'
icon_state = "random_loot"
layer = OBJ_LAYER
var/spawn_on_turf = TRUE
var/lootcount = 1 //how many items will be spawned
var/lootdoubles = TRUE //if the same item can be spawned twice
var/list/loot //a list of possible items to spawn e.g. list(/obj/item, /obj/structure, /obj/effect)
@@ -10,7 +11,7 @@
/obj/effect/spawner/lootdrop/Initialize(mapload)
..()
if(loot && loot.len)
var/turf/T = get_turf(src)
var/atom/A = spawn_on_turf ? get_turf(src) : loc
var/loot_spawned = 0
while((lootcount-loot_spawned) && loot.len)
var/lootspawn = pickweight(loot)
@@ -18,7 +19,7 @@
loot.Remove(lootspawn)
if(lootspawn)
var/atom/movable/spawned_loot = new lootspawn(T)
var/atom/movable/spawned_loot = new lootspawn(A)
if (!fan_out_items)
if (pixel_x != 0)
spawned_loot.pixel_x = pixel_x
@@ -45,7 +46,6 @@
/obj/effect/spawner/lootdrop/armory_contraband
name = "armory contraband gun spawner"
lootdoubles = FALSE
loot = list(
/obj/item/gun/ballistic/automatic/pistol = 8,
/obj/item/gun/ballistic/shotgun/automatic/combat = 5,
@@ -129,7 +129,6 @@
loot = typesof(/obj/item/flashlight/glowstick)
. = ..()
/obj/effect/spawner/lootdrop/gloves
name = "random gloves"
desc = "These gloves are supposed to be a random color..."
@@ -150,7 +149,6 @@
/obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = FALSE
loot = list(
/obj/structure/closet/crate/secure/loot = 20,
"" = 80
@@ -266,7 +264,6 @@
LAZYSET(loot, M, our_chance)
return ..()
// Tech storage circuit board spawners
// For these, make sure that lootcount equals the number of list items
@@ -386,3 +383,264 @@
/obj/structure/reagent_dispensers/keg/aphro = 2,
/obj/structure/reagent_dispensers/keg/aphro/strong = 2,
/obj/structure/reagent_dispensers/keg/gargle = 1)
/obj/effect/spawner/lootdrop/coin
lootcount = 1
loot = list(
/obj/item/coin/silver = 30,
/obj/item/coin/iron = 30,
/obj/item/coin/gold = 10,
/obj/item/coin/diamond = 10,
/obj/item/coin/plasma = 10,
/obj/item/coin/uranium = 10,
)
/obj/effect/spawner/lootdrop/cig_packs
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes = 20,
/obj/item/storage/fancy/cigarettes/dromedaryco = 10,
/obj/item/storage/fancy/cigarettes/cigpack_robust = 5,
/obj/item/storage/fancy/cigarettes/cigpack_robustgold = 5,
/obj/item/storage/fancy/cigarettes/cigpack_carp = 15,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 2,
/obj/item/storage/fancy/cigarettes/cigpack_midori = 10,
/obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 5,
/obj/item/storage/fancy/cigarettes/cigpack_xeno = 3,
/obj/item/storage/fancy/cigarettes/cigpack_cannabis = 10,
/obj/item/storage/fancy/cigarettes/cigpack_mindbreaker = 10,
/obj/item/storage/fancy/rollingpapers = 10
)
/obj/effect/spawner/lootdrop/cigars_cases
lootcount = 1
loot = list(
/obj/item/storage/fancy/cigarettes/cigars = 50,
/obj/item/storage/fancy/cigarettes/cigars/cohiba = 25,
/obj/item/storage/fancy/cigarettes/cigars/havana = 25,
)
/obj/effect/spawner/lootdrop/space_cash
lootcount = 1
loot = list(
/obj/item/stack/spacecash/c1 = 1,
/obj/item/stack/spacecash/c10 = 9,
/obj/item/stack/spacecash/c20 = 10,
/obj/item/stack/spacecash/c50 = 15,
/obj/item/stack/spacecash/c100 = 25,
/obj/item/stack/spacecash/c200 = 20,
/obj/item/stack/spacecash/c500 = 19,
/obj/item/stack/spacecash/c1000 = 1,
)
/obj/effect/spawner/lootdrop/druggie_pill
lootcount = 1
loot = list(
/obj/item/reagent_containers/pill/stimulant = 1,
/obj/item/reagent_containers/pill/zoom = 9,
/obj/item/reagent_containers/pill/happy = 10,
/obj/item/reagent_containers/pill/lsd = 15,
/obj/item/reagent_containers/pill/aranesp = 25,
/obj/item/reagent_containers/pill/psicodine = 20,
/obj/item/reagent_containers/pill/mannitol = 19,
/obj/item/reagent_containers/pill/happiness = 1,
)
/obj/effect/spawner/lootdrop/low_loot_toilet
name = "random low toilet spawner"
lootcount = 1
spawn_on_turf = FALSE
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "low" loot that anyone could fine in a toilet, for better gear use high loot toilet
loot = list("" = 30,
/obj/item/lighter = 2,
/obj/item/tape/random = 1,
/obj/item/poster/random_contraband = 1,
/obj/item/clothing/glasses/sunglasses/blindfold = 4,
/obj/item/clothing/glasses/sunglasses = 1,
/obj/item/toy/plush/random = 5,
/obj/effect/spawner/lootdrop/gloves/no_turf = 5,
/obj/effect/spawner/lootdrop/glowstick/no_turf = 5,
/obj/effect/spawner/lootdrop/coin/no_turf = 3,
/obj/effect/spawner/lootdrop/cig_packs/no_turf = 10,
/obj/effect/spawner/lootdrop/cigars_cases/no_turf = 2,
/obj/effect/spawner/lootdrop/space_cash/no_turf = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5
)
/obj/effect/spawner/lootdrop/prison_loot_toilet
name = "random prison toilet spawner"
lootcount = 1
spawn_on_turf = FALSE
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//This is ment for "prison" loot that is rather rare and ment for "prisoners if they get a crowbar to fine, or sec.
loot = list("" = 10,
/obj/item/lighter = 5,
/obj/item/poster/random_contraband = 5,
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin/no_turf = 5,
/obj/effect/spawner/lootdrop/cig_packs/no_turf = 10,
/obj/effect/spawner/lootdrop/cigars_cases/no_turf = 5,
/obj/item/reagent_containers/food/snacks/grown/cannabis = 5,
/obj/item/storage/pill_bottle/dice = 5,
/obj/item/toy/cards/deck = 5,
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5,
/obj/item/kitchen/knife = 5,
/obj/item/screwdriver = 5,
/obj/item/crowbar/red = 1, //Dont you need a crowbar to open this?
/obj/item/stack/medical/bruise_pack = 3,
/obj/item/reagent_containers/food/drinks/bottle/vodka = 2,
/obj/item/radio = 5,
/obj/item/flashlight = 4,
/obj/item/clothing/mask/breath = 2,
/obj/item/tank/internals/emergency_oxygen = 3,
/obj/item/storage/box/mre/menu4/safe = 3,
/obj/item/grenade/smokebomb = 2
)
/obj/effect/spawner/lootdrop/high_loot_toilet
name = "random high toilet spawner"
lootcount = 1
spawn_on_turf = FALSE
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
//The items inside are always going to be something usefull, illegal and likely traitorous.
loot = list(
/obj/item/clothing/glasses/sunglasses = 5,
/obj/effect/spawner/lootdrop/coin/no_turf = 5,
/obj/effect/spawner/lootdrop/space_cash/no_turf = 5,
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate = 5,
/obj/item/suppressor = 5,
/obj/item/toy/cards/deck/syndicate = 5,
/obj/item/clothing/under/syndicate = 5,
/obj/item/clothing/mask/gas/syndicate = 5,
/obj/item/grenade/smokebomb = 10,
/obj/item/gun/ballistic/automatic/toy/pistol = 5,
/obj/item/firing_pin = 5,
/obj/item/grenade/empgrenade = 15,
/obj/item/clothing/gloves/combat = 10,
/obj/item/clothing/shoes/sneakers/noslip = 10
)
/obj/effect/spawner/lootdrop/low_tools
name = "random basic tool(s) spawner"
lootcount = 1
loot = list(
/obj/item/screwdriver = 1,
/obj/item/wrench = 1,
/obj/item/weldingtool/mini = 1,
/obj/item/crowbar = 1,
/obj/item/wirecutters = 1,
/obj/item/analyzer = 1,
/obj/item/t_scanner = 1
)
/obj/effect/spawner/lootdrop/high_tools
name = "random adv tool(s) spawner"
lootcount = 1
loot = list(
/obj/item/screwdriver/power = 1,
/obj/item/weldingtool/experimental = 1,
/obj/item/crowbar/power = 1,
/obj/item/analyzer = 1,
/obj/item/multitool = 1
)
/obj/effect/spawner/lootdrop/welder_tools
name = "random safe welder tool(s) spawner"
lootcount = 1
loot = list(
/obj/item/weldingtool = 1,
/obj/item/weldingtool/mini = 1,
/obj/item/weldingtool/hugetank = 1,
/obj/item/weldingtool/largetank = 1
)
/obj/effect/spawner/lootdrop/tool_box
name = "random safe tool box(es) spawner"
lootcount = 1
loot = list(
/obj/item/storage/toolbox/mechanical = 1,
/obj/item/storage/toolbox/mechanical/old = 1,
/obj/item/storage/toolbox/emergency = 1,
/obj/item/storage/toolbox/emergency/old = 1,
/obj/item/storage/toolbox/electrical = 1,
/obj/item/storage/toolbox/syndicate = 1,
/obj/item/storage/toolbox/artistic = 1,
/obj/item/storage/toolbox/gold_fake = 1,
/obj/item/storage/toolbox/rubber = 1
)
/obj/effect/spawner/lootdrop/healing_kits
name = "random safe medical kit(s) spawner"
lootcount = 1
loot = list(
/obj/item/storage/firstaid/regular = 1,
/obj/item/storage/firstaid/ancient = 1,
/obj/item/storage/firstaid/fire = 1,
/obj/item/storage/firstaid/toxin = 1,
/obj/item/storage/firstaid/radbgone = 1,
/obj/item/storage/firstaid/o2 = 1,
/obj/item/storage/firstaid/brute = 1
)
/obj/effect/spawner/lootdrop/breathing_tanks
name = "random internal tank(s) spawner"
lootcount = 1
loot = list(
/obj/item/tank/internals/oxygen = 1,
/obj/item/tank/internals/oxygen/yellow = 1,
/obj/item/tank/internals/oxygen/red = 1,
/obj/item/tank/internals/air = 1,
/obj/item/tank/internals/plasmaman = 1,
/obj/item/tank/internals/plasmaman/belt = 1,
/obj/item/tank/internals/emergency_oxygen = 1,
/obj/item/tank/internals/emergency_oxygen/engi = 1,
/obj/item/tank/internals/emergency_oxygen/double = 1
)
/obj/effect/spawner/lootdrop/breathing_masks
name = "random internal mask(s) spawner"
lootcount = 1
loot = list(
/obj/item/clothing/mask/gas = 2,
/obj/item/clothing/mask/gas/glass = 4,
/obj/item/clothing/mask/breath = 5,
/obj/item/clothing/mask/breath/medical = 1
)
/obj/effect/spawner/lootdrop/welder_tools/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/low_tools/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/breathing_tanks/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/breathing_masks/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/coin/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/space_cash/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/druggie_pill/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/gloves/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/cig_packs/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/cigars_cases/no_turf
spawn_on_turf = FALSE
/obj/effect/spawner/lootdrop/glowstick/no_turf
spawn_on_turf = FALSE
+37 -18
View File
@@ -8,9 +8,23 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
///icon state name for inhand overlays
var/item_state = null
///Icon file for left hand inhand overlays
var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
///Icon file for right inhand overlays
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
///Icon file for mob worn overlays.
///no var for state because it should *always* be the same as icon_state
var/icon/mob_overlay_icon
//Forced mob worn layer instead of the standard preferred size.
var/alternate_worn_layer
var/icon/anthro_mob_worn_overlay //Version of the above dedicated to muzzles/digitigrade
var/icon/taur_mob_worn_overlay // Idem but for taurs. Currently only used by suits.
var/list/alternate_screams = list() //REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
//Dimensions of the icon file used when this item is worn, eg: hats.dmi
@@ -22,10 +36,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/inhand_x_dimension = 32
var/inhand_y_dimension = 32
//Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery.
var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events
var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default
max_integrity = 200
obj_flags = NONE
@@ -34,7 +44,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/hitsound = null
var/usesound = null
var/throwhitsound = null
/// Weight class for how much storage capacity it uses and how big it physically is meaning storages can't hold it if their maximum weight class isn't as high as it.
var/w_class = WEIGHT_CLASS_NORMAL
/// Volume override for the item, otherwise automatically calculated from w_class.
var/w_volume
/// The amount of stamina it takes to swing an item in a normal melee attack do not lie to me and say it's for realism because it ain't. If null it will autocalculate from w_class.
var/total_mass //Total mass in arbitrary pound-like values. If there's no balance reasons for an item to have otherwise, this var should be the item's weight in pounds.
@@ -61,8 +75,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//Citadel Edit for digitigrade stuff
var/mutantrace_variation = NONE //Are there special sprites for specific situations? Don't use this unless you need to.
var/item_color = null //this needs deprecating, soonish
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets)
var/permeability_coefficient = 1 // for chemicals/diseases
@@ -93,8 +105,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/tool_behaviour = NONE
var/toolspeed = 1
var/block_chance = 0
var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom
var/reach = 1 //In tiles, how far this weapon can reach; 1 for adjacent, which is default
//The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot.
@@ -111,6 +121,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/trigger_guard = TRIGGER_GUARD_NONE
///Used as the dye color source in the washing machine only (at the moment). Can be a hex color or a key corresponding to a registry entry, see washing_machine.dm
var/dye_color
///Whether the item is unaffected by standard dying.
var/undyeable = FALSE
///What dye registry should be looked at when dying this item; see washing_machine.dm
var/dying_key
//Grinder vars
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
@@ -365,13 +382,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency
/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
SEND_SIGNAL(src, COMSIG_ITEM_HIT_REACT, args)
if(prob(final_block_chance))
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
return 1
return 0
/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language)
return ITALICS | REDUCE_RANGE
@@ -431,6 +441,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
item_flags |= IN_INVENTORY
user.update_equipment_speed_mods()
//Overlays for the worn overlay so you can overlay while you overlay
//eg: ammo counters, primed grenade flashing, etc.
//"icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file
/obj/item/proc/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = list()
SEND_SIGNAL(src, COMSIG_ITEM_WORN_OVERLAYS, isinhands, icon_file, used_state, style_flags, .)
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there
@@ -464,9 +481,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/ui_action_click(mob/user, actiontype)
attack_self(user)
/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit
return 0
/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user)
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm [M]!</span>")
@@ -857,6 +871,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return
return ..()
/// Get an item's volume that it uses when being stored.
/obj/item/proc/get_w_volume()
// if w_volume is 0 you fucked up anyways lol
return w_volume || AUTO_SCALE_VOLUME(w_class)
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
return
+4 -5
View File
@@ -113,7 +113,7 @@
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
. += cable_overlay
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands || !(loaded?.amount))
return
@@ -201,7 +201,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
return //If we've run out, display message and exit
else
last = null
loaded.item_color = colors[current_color_index]
loaded.color = colors[current_color_index]
last = loaded.place_turf(get_turf(src), user, turn(user.dir, 180))
is_empty(user) //If we've run out, display message
update_icon()
@@ -223,7 +223,6 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
continue
if(C.d1 == 0)
return C
break
return
@@ -277,7 +276,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
if(T.intact || !T.can_have_cabling())
return
loaded.item_color = colors[current_color_index]
loaded.color = colors[current_color_index]
var/obj/structure/cable/linkingCable = findLinkingCable(user)
if(linkingCable)
@@ -299,7 +298,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
var/cwname = colors[current_color_index]
to_chat(user, "Color changed to [cwname]!")
if(loaded)
loaded.item_color= colors[current_color_index]
loaded.color = colors[current_color_index]
update_icon()
if(wiring_gui_menu)
wiringGuiUpdate(user)
+1 -1
View File
@@ -15,7 +15,7 @@
lefthand_file = 'modular_citadel/icons/mob/inhands/balls_left.dmi'
righthand_file = 'modular_citadel/icons/mob/inhands/balls_right.dmi'
item_state = "tennis_classic"
alternate_worn_icon = 'modular_citadel/icons/mob/mouthball.dmi'
mob_overlay_icon = 'modular_citadel/icons/mob/mouthball.dmi'
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS //Fluff item, put it wherever you want!
throw_range = 14
w_class = WEIGHT_CLASS_SMALL
+10 -1
View File
@@ -38,7 +38,6 @@
/obj/item/bodybag/bluespace
name = "bluespace body bag"
desc = "A folded bluespace body bag designed for the storage and transportation of cadavers."
icon = 'icons/obj/bodybag.dmi'
icon_state = "bluebodybag_folded"
unfoldedbag_path = /obj/structure/closet/body_bag/bluespace
w_class = WEIGHT_CLASS_SMALL
@@ -81,3 +80,13 @@
return
loc.visible_message("<span class='warning'>[user] suddenly appears in front of [loc]!</span>", "<span class='userdanger'>[user] breaks free of [src]!</span>")
qdel(src)
// Containment bodybag
/obj/item/bodybag/containment
name = "radiation containment body bag"
desc = "A folded heavy body bag designed for the storage and transportation of heavily irradiated cadavers."
icon_state = "radbodybag_folded"
unfoldedbag_path = /obj/structure/closet/body_bag/containment
w_class = WEIGHT_CLASS_NORMAL
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+7 -2
View File
@@ -13,6 +13,7 @@
var/lit = FALSE
var/infinite = FALSE
var/start_lit = FALSE
var/heats_space = TRUE
/obj/item/candle/Initialize()
. = ..()
@@ -35,7 +36,7 @@
return ..()
/obj/item/candle/get_temperature()
return lit * heat
return lit * heat * heats_space
/obj/item/candle/proc/light(show_message)
if(!lit)
@@ -67,7 +68,8 @@
new /obj/item/trash/candle(loc)
qdel(src)
update_icon()
open_flame()
if(heats_space)
open_flame()
/obj/item/candle/attack_self(mob/user)
if(put_out_candle())
@@ -77,4 +79,7 @@
infinite = TRUE
start_lit = TRUE
/obj/item/candle/infinite/hugbox
heats_space = FALSE
#undef CANDLE_LUMINOSITY
+8 -9
View File
@@ -706,11 +706,11 @@ CIGARETTE PACKETS ARE IN FANCY.DM
name = "\improper E-Cigarette"
desc = "A classy and highly sophisticated electronic cigarette, for classy and dignified gentlemen. A warning label reads \"Warning: Do not fill with flammable materials.\""//<<< i'd vape to that.
icon = 'icons/obj/clothing/masks.dmi'
icon_state = null
item_state = null
icon_state = "black_vape"
item_state = "black_vape"
w_class = WEIGHT_CLASS_TINY
var/chem_volume = 100
var/vapetime = FALSE //this so it won't puff out clouds every tick
var/vapetime = FALSE //this so it won't puff out clouds every tick
var/screw = FALSE // kinky
var/super = FALSE //for the fattest vapes dude.
@@ -723,11 +723,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
. = ..()
create_reagents(chem_volume, NO_REACT, NO_REAGENTS_VALUE) // so it doesn't react until you light it
reagents.add_reagent(/datum/reagent/drug/nicotine, 50)
if(!icon_state)
if(!param_color)
param_color = pick("red","blue","black","white","green","purple","yellow","orange")
icon_state = "[param_color]_vape"
item_state = "[param_color]_vape"
if(!param_color)
param_color = pick("red","blue","black","white","green","purple","yellow","orange")
icon_state = "[param_color]_vape"
item_state = "[param_color]_vape"
/obj/item/clothing/mask/vape/attackby(obj/item/O, mob/user, params)
if(O.tool_behaviour == TOOL_SCREWDRIVER)
@@ -1067,4 +1066,4 @@ CIGARETTE PACKETS ARE IN FANCY.DM
name = "coconut bong"
icon_off = "coconut_bong"
icon_on = "coconut_bong_lit"
desc = "A water bong used for smoking dried plants. This one's made out of a coconut and some bamboo."
desc = "A water bong used for smoking dried plants. This one's made out of a coconut and some bamboo."
@@ -293,10 +293,6 @@
name = "Mining Shuttle (Computer Board)"
build_path = /obj/machinery/computer/shuttle/mining
/obj/item/circuitboard/computer/mining_shuttle/common
name = "Lavaland Shuttle (Computer Board)"
build_path = /obj/machinery/computer/shuttle/mining/common
/obj/item/circuitboard/computer/white_ship
name = "White Ship (Computer Board)"
build_path = /obj/machinery/computer/shuttle/white_ship
@@ -244,7 +244,7 @@
/obj/machinery/vending/autodrobe = "AutoDrobe",
/obj/machinery/vending/assist = "\improper Vendomat",
/obj/machinery/vending/engivend = "\improper Engi-Vend",
/obj/machinery/vending/engivend = "\improper YouTool",
/obj/machinery/vending/tool = "\improper YouTool",
/obj/machinery/vending/sustenance = "\improper Sustenance Vendor",
/obj/machinery/vending/dinnerware = "\improper Plasteel Chef's Dinnerware Vendor",
/obj/machinery/vending/cart = "\improper PTech",
+26 -14
View File
@@ -26,7 +26,7 @@
var/icon_uncapped
var/use_overlays = FALSE
item_color = "red"
var/crayon_color = "red"
w_class = WEIGHT_CLASS_TINY
attack_verb = list("attacked", "coloured")
grind_results = list()
@@ -83,7 +83,9 @@
. = ..()
// Makes crayons identifiable in things like grinders
if(name == "crayon")
name = "[item_color] crayon"
name = "[crayon_color] crayon"
dye_color = crayon_color
drawtype = pick(all_drawables)
@@ -484,65 +486,75 @@
/obj/item/toy/crayon/red
icon_state = "crayonred"
paint_color = "#DA0000"
item_color = "red"
crayon_color = "red"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1)
dye_color = DYE_RED
/obj/item/toy/crayon/orange
icon_state = "crayonorange"
paint_color = "#FF9300"
item_color = "orange"
crayon_color = "orange"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/orange = 1)
dye_color = DYE_ORANGE
/obj/item/toy/crayon/yellow
icon_state = "crayonyellow"
paint_color = "#FFF200"
item_color = "yellow"
crayon_color = "yellow"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/yellow = 1)
dye_color = DYE_YELLOW
/obj/item/toy/crayon/green
icon_state = "crayongreen"
paint_color = "#A8E61D"
item_color = "green"
crayon_color = "green"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/green = 1)
dye_color = DYE_GREEN
/obj/item/toy/crayon/blue
icon_state = "crayonblue"
paint_color = "#00B7EF"
item_color = "blue"
crayon_color = "blue"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/blue = 1)
dye_color = DYE_BLUE
/obj/item/toy/crayon/purple
icon_state = "crayonpurple"
paint_color = "#DA00FF"
item_color = "purple"
crayon_color = "purple"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/purple = 1)
dye_color = DYE_PURPLE
/obj/item/toy/crayon/black
icon_state = "crayonblack"
paint_color = "#1C1C1C" //Not completely black because total black looks bad. So Mostly Black.
item_color = "black"
crayon_color = "black"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/black = 1)
dye_color = DYE_BLACK
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
paint_color = "#FFFFFF"
item_color = "white"
crayon_color = "white"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/white = 1)
dye_color = DYE_WHITE
/obj/item/toy/crayon/mime
icon_state = "crayonmime"
desc = "A very sad-looking crayon."
paint_color = "#FFFFFF"
item_color = "mime"
crayon_color = "mime"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent/crayonpowder/invisible = 1)
charges = -1
dye_color = DYE_MIME
/obj/item/toy/crayon/rainbow
icon_state = "crayonrainbow"
paint_color = "#FFF000"
item_color = "rainbow"
crayon_color = "rainbow"
reagent_contents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/colorful_reagent = 1)
drawtype = RANDOM_ANY // just the default starter.
dye_color = DYE_RAINBOW
charges = -1
@@ -580,12 +592,12 @@
/obj/item/storage/crayons/update_overlays()
. = ..()
for(var/obj/item/toy/crayon/crayon in contents)
add_overlay(mutable_appearance('icons/obj/crayons.dmi', crayon.item_color))
add_overlay(mutable_appearance('icons/obj/crayons.dmi', crayon.crayon_color))
/obj/item/storage/crayons/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/toy/crayon))
var/obj/item/toy/crayon/C = W
switch(C.item_color)
switch(C.crayon_color)
if("mime")
to_chat(usr, "This crayon is too sad to be contained in this box.")
return
+2 -2
View File
@@ -807,9 +807,9 @@ GLOBAL_LIST_EMPTY(PDAs)
// If it didn't reach, note that fact
if (!signal.data["done"])
to_chat(user, "<span class='notice'>ERROR: Server isn't responding.</span>")
return
if (!silent)
playsound(src, 'sound/machines/terminal_error.ogg', 15, 1)
return
var/target_text = signal.format_target()
if(allow_emojis)
@@ -998,9 +998,9 @@ GLOBAL_LIST_EMPTY(PDAs)
var/obj/item/card/id/idcard = C
if(!idcard.registered_name)
to_chat(user, "<span class='warning'>\The [src] rejects the ID!</span>")
return
if (!silent)
playsound(src, 'sound/machines/terminal_error.ogg', 15, 1)
return
if(!owner)
owner = idcard.registered_name
+2 -2
View File
@@ -692,14 +692,14 @@ Code:
return
GLOB.news_network.SubmitArticle(message,host_pda.owner,current_channel)
host_pda.Topic(null,list("choice"=num2text(host_pda.mode)))
return
playsound(src, 'sound/machines/terminal_select.ogg', 50, 1)
return
if("Newscaster Switch Channel")
current_channel = host_pda.msg_input()
host_pda.Topic(null,list("choice"=num2text(host_pda.mode)))
return
playsound(src, 'sound/machines/terminal_select.ogg', 50, 1)
return
//emoji previews
if(href_list["emoji"])
@@ -324,7 +324,7 @@
cleaning_cycles--
cleaning = TRUE
for(var/mob/living/carbon/C in (touchable_items))
if((C.status_flags & GODMODE) || !C.digestable)
if((C.status_flags & GODMODE) || !CHECK_BITFIELD(C.vore_flags, DIGESTABLE))
items_preserved += C
else
C.adjustBruteLoss(2)
@@ -333,7 +333,7 @@
var/atom/target = pick(touchable_items)
if(iscarbon(target)) //Handle the target being a mob
var/mob/living/carbon/T = target
if(T.stat == DEAD && T.digestable) //Mob is now dead
if(T.stat == DEAD && CHECK_BITFIELD(T.vore_flags, DIGESTABLE)) //Mob is now dead
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound,"<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T,"<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
@@ -445,7 +445,7 @@
var/mob/living/silicon/robot/hound = get_host()
if(!hound || !istype(target) || !proximity || target.anchored)
return
if (!target.devourable)
if (!CHECK_BITFIELD(target.vore_flags,DEVOURABLE))
to_chat(user, "The target registers an error code. Unable to insert into [src].")
return
if(patient)
@@ -509,7 +509,7 @@
if(iscarbon(target) || issilicon(target))
var/mob/living/trashman = target
if(!trashman.devourable)
if(!CHECK_BITFIELD(trashman.vore_flags,DEVOURABLE))
to_chat(user, "<span class='warning'>[target] registers an error code to your [src]</span>")
return
if(patient)
@@ -528,4 +528,4 @@
/obj/item/dogborg/sleeper/K9/flavour
name = "Recreational Sleeper"
desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
desc = "A mounted, underslung sleeper, intended for holding willing occupants for leisurely purposes."
@@ -1,317 +0,0 @@
//copy pasta of the space piano, don't hurt me -Pete
/obj/item/instrument
name = "generic instrument"
resistance_flags = FLAMMABLE
force = 10
max_integrity = 100
icon = 'icons/obj/musician.dmi'
lefthand_file = 'icons/mob/inhands/equipment/instruments_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/instruments_righthand.dmi'
var/datum/song/handheld/song
var/instrumentId = "generic"
var/instrumentExt = "mid"
var/tune_time = 0
/obj/item/instrument/Initialize()
. = ..()
song = new(instrumentId, src, instrumentExt)
/obj/item/instrument/Destroy()
if (tune_time)
STOP_PROCESSING(SSobj, src)
qdel(song)
song = null
return ..()
/obj/item/instrument/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS)
/obj/item/instrument/Initialize(mapload)
. = ..()
if(mapload)
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/item/instrument/attack_self(mob/user)
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
interact(user)
/obj/item/instrument/interact(mob/user)
ui_interact(user)
/obj/item/instrument/ui_interact(mob/user)
if(!user)
return
if(!isliving(user) || user.stat || user.restrained() || user.lying)
return
user.set_machine(src)
song.interact(user)
/obj/item/instrument/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/musicaltuner))
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_MUSICIAN))
if (!tune_time)
H.visible_message("[H] tunes the [src] to perfection!", "<span class='notice'>You tune the [src] to perfection!</span>")
tune_time = 300
START_PROCESSING(SSobj, src)
else
to_chat(H, "<span class='notice'>[src] is already well tuned!</span>")
else
to_chat(H, "<span class='warning'>You have no idea how to use this.</span>")
/obj/item/instrument/process()
if (tune_time)
if (song.playing)
for (var/mob/living/M in song.hearing_mobs)
M.dizziness = max(0,M.dizziness-2)
M.jitteriness = max(0,M.jitteriness-2)
M.confused = max(M.confused-1)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "goodmusic", /datum/mood_event/goodmusic)
tune_time--
else
if (!tune_time)
if (song.playing)
loc.visible_message("<span class='warning'>[src] starts sounding a little off...</span>")
STOP_PROCESSING(SSobj, src)
/obj/item/instrument/violin
name = "space violin"
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "violin"
item_state = "violin"
hitsound = "swing_hit"
instrumentId = "violin"
/obj/item/instrument/violin/golden
name = "golden violin"
desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "golden_violin"
item_state = "golden_violin"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/instrument/piano_synth
name = "synthesizer"
desc = "An advanced electronic synthesizer that can be used as various instruments."
icon_state = "synth"
item_state = "synth"
instrumentId = "piano"
instrumentExt = "ogg"
var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "banjo" = "ogg", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers.
actions_types = list(/datum/action/item_action/synthswitch)
/obj/item/instrument/piano_synth/proc/changeInstrument(name = "piano")
song.instrumentDir = name
song.instrumentExt = insTypes[name]
/obj/item/instrument/piano_synth/proc/selectInstrument() // Moved here so it can be used by the action and PAI software panel without copypasta
var/chosen = input("Choose the type of instrument you want to use", "Instrument Selection", song.instrumentDir) as null|anything in insTypes
if(!insTypes[chosen])
return
return changeInstrument(chosen)
/obj/item/instrument/banjo
name = "banjo"
desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings."
icon_state = "banjo"
item_state = "banjo"
instrumentExt = "ogg"
attack_verb = list("scruggs-styled", "hum-diggitied", "shin-digged", "clawhammered")
hitsound = 'sound/weapons/banjoslap.ogg'
instrumentId = "banjo"
/obj/item/instrument/guitar
name = "guitar"
desc = "It's made of wood and has bronze strings."
icon_state = "guitar"
item_state = "guitar"
instrumentExt = "ogg"
attack_verb = list("played metal on", "serenaded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "guitar"
/obj/item/instrument/eguitar
name = "electric guitar"
desc = "Makes all your shredding needs possible."
icon_state = "eguitar"
item_state = "eguitar"
force = 12
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "eguitar"
instrumentExt = "ogg"
/obj/item/instrument/glockenspiel
name = "glockenspiel"
desc = "Smooth metal bars perfect for any marching band."
icon_state = "glockenspiel"
item_state = "glockenspiel"
instrumentId = "glockenspiel"
/obj/item/instrument/accordion
name = "accordion"
desc = "Pun-Pun not included."
icon_state = "accordion"
item_state = "accordion"
instrumentId = "accordion"
/obj/item/instrument/trumpet
name = "trumpet"
desc = "To announce the arrival of the king!"
icon_state = "trumpet"
item_state = "trombone"
instrumentId = "trombone"
/obj/item/instrument/trumpet/spectral
name = "spectral trumpet"
desc = "Things are about to get spooky!"
icon_state = "trumpet"
item_state = "trombone"
force = 0
instrumentId = "trombone"
attack_verb = list("played","jazzed","trumpeted","mourned","dooted","spooked")
/obj/item/instrument/trumpet/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/trumpet/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/En4.mid', 100,1,-1)
..()
/obj/item/instrument/saxophone
name = "saxophone"
desc = "This soothing sound will be sure to leave your audience in tears."
icon_state = "saxophone"
item_state = "saxophone"
instrumentId = "saxophone"
/obj/item/instrument/saxophone/spectral
name = "spectral saxophone"
desc = "This spooky sound will be sure to leave mortals in bones."
icon_state = "saxophone"
item_state = "saxophone"
instrumentId = "saxophone"
force = 0
attack_verb = list("played","jazzed","saxxed","mourned","dooted","spooked")
/obj/item/instrument/saxophone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/saxophone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/saxophone/En4.mid', 100,1,-1)
..()
/obj/item/instrument/trombone
name = "trombone"
desc = "How can any pool table ever hope to compete?"
icon_state = "trombone"
item_state = "trombone"
instrumentId = "trombone"
/obj/item/instrument/trombone/spectral
name = "spectral trombone"
desc = "A skeleton's favorite instrument. Apply directly on the mortals."
instrumentId = "trombone"
icon_state = "trombone"
item_state = "trombone"
force = 0
attack_verb = list("played","jazzed","tromboned","mourned","dooted","spooked")
/obj/item/instrument/trombone/spectral/Initialize()
. = ..()
AddComponent(/datum/component/spooky)
/obj/item/instrument/trombone/spectral/attack(mob/living/carbon/C, mob/user)
playsound (loc, 'sound/instruments/trombone/Cn4.mid', 100,1,-1)
..()
/obj/item/instrument/recorder
name = "recorder"
desc = "Just like in school, playing ability and all."
force = 5
icon_state = "recorder"
item_state = "recorder"
instrumentId = "recorder"
/obj/item/instrument/harmonica
name = "harmonica"
desc = "For when you get a bad case of the space blues."
icon_state = "harmonica"
item_state = "harmonica"
instrumentId = "harmonica"
slot_flags = ITEM_SLOT_MASK
force = 5
w_class = WEIGHT_CLASS_SMALL
actions_types = list(/datum/action/item_action/instrument)
/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args)
if(song.playing && ismob(loc))
to_chat(loc, "<span class='warning'>You stop playing the harmonica to talk...</span>")
song.playing = FALSE
/obj/item/instrument/harmonica/equipped(mob/M, slot)
. = ..()
RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
/obj/item/instrument/harmonica/dropped(mob/M)
. = ..()
UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/instrument/bikehorn
name = "gilded bike horn"
desc = "An exquisitely decorated bike horn, capable of honking in a variety of notes."
icon_state = "bike_horn"
item_state = "bike_horn"
lefthand_file = 'icons/mob/inhands/equipment/horns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/horns_righthand.dmi'
attack_verb = list("beautifully honks")
instrumentId = "bikehorn"
instrumentExt = "ogg"
w_class = WEIGHT_CLASS_TINY
force = 0
throw_speed = 3
throw_range = 15
hitsound = 'sound/items/bikehorn.ogg'
/obj/item/musicaltuner
name = "musical tuner"
desc = "A device for tuning musical instruments both manual and electronic alike."
icon = 'icons/obj/device.dmi'
icon_state = "musicaltuner"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
/obj/item/choice_beacon/music
name = "instrument delivery beacon"
desc = "Summon your tool of art."
icon_state = "gangtool-red"
/obj/item/choice_beacon/music/generate_display_names()
var/static/list/instruments
if(!instruments)
instruments = list()
var/list/templist = list(/obj/item/instrument/violin,
/obj/item/instrument/piano_synth,
/obj/item/instrument/guitar,
/obj/item/instrument/eguitar,
/obj/item/instrument/glockenspiel,
/obj/item/instrument/accordion,
/obj/item/instrument/trumpet,
/obj/item/instrument/saxophone,
/obj/item/instrument/trombone,
/obj/item/instrument/recorder,
/obj/item/instrument/harmonica
)
for(var/V in templist)
var/atom/A = V
instruments[initial(A.name)] = A
return instruments
@@ -18,7 +18,6 @@
var/recharge_locked = FALSE
var/obj/item/stock_parts/micro_laser/diode //used for upgrading!
/obj/item/laser_pointer/red
pointer_icon_state = "red_laser"
/obj/item/laser_pointer/green
@@ -28,6 +27,9 @@
/obj/item/laser_pointer/purple
pointer_icon_state = "purple_laser"
/obj/item/laser_pointer/blue/handmade
diode = null
/obj/item/laser_pointer/New()
..()
diode = new(src)
@@ -149,7 +149,7 @@ Code:
name = "shock collar"
desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.."
icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/citadel/neck.dmi'
mob_overlay_icon = 'modular_citadel/icons/mob/citadel/neck.dmi'
icon_state = "shockcollar"
item_state = "shockcollar"
body_parts_covered = NECK
+4 -6
View File
@@ -275,10 +275,8 @@ SLIME SCANNER
//LIVER
else if(istype(O, /obj/item/organ/liver))
var/obj/item/organ/liver/L = O
if(H.undergoing_liver_failure() && H.stat != DEAD) //might be depreciated
if(L.organ_flags & ORGAN_FAILING && H.stat != DEAD) //might be depreciated
temp_message += "<span class='danger'>Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!</span>"
if(L.swelling > 20)
temp_message += " <span class='danger'>Subject is suffering from an enlarged liver.</span>" //i.e. shrink their liver or give them a transplant.
//HEART
else if(ishuman(M) && (istype(O, /obj/item/organ/heart)))
@@ -310,11 +308,11 @@ SLIME SCANNER
//GENERAL HANDLER
if(!damage_message)
if(O.organ_flags & ORGAN_FAILING)
damage_message += " <span class='alert'><b>End Stage [O.name] failure detected.</b></span>"
damage_message += " <span class='alert'><b>Chronic [O.name] failure detected.</b></span>"
else if(O.damage > O.high_threshold)
damage_message += " <span class='alert'>Chronic [O.name] failure detected.</span>"
damage_message += " <span class='alert'>Acute [O.name] failure detected.</span>"
else if(O.damage > O.low_threshold && advanced)
damage_message += " <font color='red'>Acute [O.name] failure detected.</span>"
damage_message += " <font color='red'>Minor [O.name] failure detected.</span>"
if(temp_message || damage_message)
msg += "\t<b><span class='info'>[uppertext(O.name)]:</b></span> [damage_message] [temp_message]\n"
+5 -5
View File
@@ -51,8 +51,8 @@
to_chat(user, "<span class='warning'>You have already forged a seal on [src]!</span>")
else
var/obj/item/toy/crayon/C = O
name = "[C.item_color] secret documents"
icon_state = "docs_[C.item_color]"
forgedseal = C.item_color
to_chat(user, "<span class='notice'>You forge the official seal with a [C.item_color] crayon. No one will notice... right?</span>")
update_icon()
name = "[C.crayon_color] secret documents"
icon_state = "docs_[C.crayon_color]"
forgedseal = C.crayon_color
to_chat(user, "<span class='notice'>You forge the official seal with a [C.crayon_color] crayon. No one will notice... right?</span>")
update_icon()
+10 -9
View File
@@ -234,15 +234,16 @@
/obj/item/flamethrower/full/tank
create_with_tank = TRUE
/obj/item/flamethrower/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!</span>")
var/target_turf = get_turf(owner)
igniter.ignite_turf(src,target_turf, release_amount = 100)
qdel(ptank)
return 1 //It hit the flamethrower, not them
/obj/item/flamethrower/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE)
var/obj/item/projectile/P = object
if(istype(P) && (P.damage_type != STAMINA) && damage && !P.nodamage && prob(15))
owner.visible_message("<span class='danger'>\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!</span>")
var/target_turf = get_turf(owner)
igniter.ignite_turf(src,target_turf, release_amount = 100)
qdel(ptank)
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return ..()
/obj/item/assembly/igniter/proc/flamethrower_process(turf/open/location)
location.hotspot_expose(700,2)
+8 -6
View File
@@ -115,12 +115,14 @@
/obj/item/grenade/attack_paw(mob/user)
return attack_hand(user)
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
prime()
return TRUE //It hit the grenade, not them
/obj/item/grenade/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE)
var/obj/item/projectile/P = object
if(damage && !P.nodamage && (P.damage_type != STAMINA) && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
prime()
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return ..()
/obj/item/proc/grenade_prime_react(obj/item/grenade/nade)
return
+25 -23
View File
@@ -113,57 +113,56 @@
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff"
item_state = "coil"
item_color = "red"
color = "#ff0000"
color = "#ff0000"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
custom_materials = list(/datum/material/iron=150, /datum/material/glass=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/Initialize(mapload, param_color)
. = ..()
var/list/cable_colors = GLOB.cable_colors
item_color = param_color || item_color || pick(cable_colors)
if(cable_colors[item_color])
item_color = cable_colors[item_color]
color = null
add_atom_colour(item_color, FIXED_COLOUR_PRIORITY)
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/attack_self(mob/user)
to_chat(user, "<span class='notice'>You start unwinding the cable restraints back into coil</span>")
if(!do_after(user, 25, TRUE, user))
return
qdel(src)
var/obj/item/stack/cable_coil/coil = new(get_turf(user))
coil.amount = 15
user.put_in_hands(coil)
coil.color = color
to_chat(user, "<span class='notice'>You unwind the cable restraints back into coil</span>")
/obj/item/restraints/handcuffs/cable/red
item_color = "red"
color = "#ff0000"
/obj/item/restraints/handcuffs/cable/yellow
item_color = "yellow"
color = "#ffff00"
/obj/item/restraints/handcuffs/cable/blue
item_color = "blue"
color = "#1919c8"
/obj/item/restraints/handcuffs/cable/green
item_color = "green"
color = "#00aa00"
/obj/item/restraints/handcuffs/cable/pink
item_color = "pink"
color = "#ff3ccd"
/obj/item/restraints/handcuffs/cable/orange
item_color = "orange"
color = "#ff8000"
/obj/item/restraints/handcuffs/cable/cyan
item_color = "cyan"
color = "#00ffff"
/obj/item/restraints/handcuffs/cable/white
item_color = "white"
color = null
/obj/item/restraints/handcuffs/cable/random
/obj/item/restraints/handcuffs/cable/random/Initialize(mapload)
. = ..()
var/list/cable_colors = GLOB.cable_colors
color = pick(cable_colors)
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
var/obj/item/stack/rods/R = I
if (R.use(1))
@@ -197,12 +196,15 @@
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
item_state = "zipties"
color = "white"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
custom_materials = null
breakouttime = 450 //Deciseconds = 45s
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
item_color = "white"
/obj/item/restraints/handcuffs/cable/zipties/attack_self() //Zipties arent cable
return
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
+8 -7
View File
@@ -122,7 +122,7 @@
/obj/item/clothing/head/helmet/chaplain/cage
name = "cage"
desc = "A cage that restrains the will of the self, allowing one to see the profane world for what it is."
alternate_worn_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
icon_state = "cage"
item_state = "cage"
worn_x_dimension = 64
@@ -187,6 +187,7 @@
body_parts_covered = CHEST|GROIN|LEGS|ARMS
allowed = list(/obj/item/storage/book/bible, HOLY_WEAPONS, /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/tank/internals/plasmaman)
hoodtype = /obj/item/clothing/head/hooded/chaplain_hood
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/head/hooded/chaplain_hood
name = "follower hood"
@@ -303,8 +304,8 @@
block_chance = 50
var/shield_icon = "shield-red"
/obj/item/nullrod/staff/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = list()
/obj/item/nullrod/staff/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands)
. += mutable_appearance('icons/effects/effects.dmi', shield_icon, MOB_LAYER + 0.01)
@@ -328,9 +329,9 @@
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a sword to a gunfight
/obj/item/nullrod/claymore/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE) // Don't bring a sword to a gunfight
return NONE
return ..()
/obj/item/nullrod/claymore/darkblade
@@ -494,7 +495,7 @@
S.ckey = C.ckey
S.status_flags |= GODMODE
S.language_holder = user.language_holder.copy(S)
S.AddElement(/datum/element/ghost_role_eligibility)
S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
START_PROCESSING(SSprocessing,src)
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
+1 -1
View File
@@ -5,7 +5,7 @@
actions_types = list(/datum/action/item_action/hands_free/activate)
var/activated = TRUE //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants
var/mob/living/imp_in = null
item_color = "b"
var/implant_color = "b"
var/allow_multiple = FALSE
var/uses = -1
item_flags = DROPDEL
@@ -2,7 +2,7 @@
name = "freedom implant"
desc = "Use this to escape from those evil Red Shirts."
icon_state = "freedom"
item_color = "r"
implant_color = "r"
uses = 4
@@ -21,7 +21,7 @@
if (!spell)
return FALSE
if (autorobeless && spell.clothes_req)
spell.clothes_req = FALSE
spell.clothes_req = NONE
target.AddSpell(spell)
return TRUE
@@ -2,7 +2,7 @@
name = "storage implant"
desc = "Stores up to two big items in a bluespace pocket."
icon_state = "storage"
item_color = "r"
implant_color = "r"
var/max_slot_stacking = 4
var/obj/item/storage/bluespace_pocket/pocket
@@ -15,7 +15,7 @@
/obj/item/implantcase/update_icon_state()
if(imp)
icon_state = "implantcase-[imp.item_color]"
icon_state = "implantcase-[imp.implant_color]"
else
icon_state = "implantcase-0"
+1
View File
@@ -142,6 +142,7 @@
name = "plastic knife"
desc = "A plastic knife. Rather harmless to anything."
force = 1
throwforce = 1
bayonet = FALSE
/obj/item/kitchen/knife/combat/cyborg
+1 -1
View File
@@ -172,7 +172,7 @@
It can cook multiple items at once.
<h2>Processor:</h2>
Use it to process certain ingredients (meat into faggot, doughslice into spaghetti, potato into fries,etc...)
Use it to process certain ingredients (meat into meatball, doughslice into spaghetti, potato into fries,etc...)
<h2>Gibber:</h2>
Stuff an animal in it to grind it into meat.
+33 -46
View File
@@ -5,12 +5,15 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
resistance_flags = FIRE_PROOF
var/brightness_on = 3
var/sword_color
total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces.
/obj/item/melee/transforming/energy/Initialize()
. = ..()
total_mass_on = (total_mass_on ? total_mass_on : (w_class_on * 0.75))
if(active)
if(sword_color)
icon_state = "sword[sword_color]"
set_light(brightness_on)
START_PROCESSING(SSobj, src)
@@ -37,8 +40,8 @@
. = ..()
if(.)
if(active)
if(item_color)
icon_state = "sword[item_color]"
if(sword_color)
icon_state = "sword[sword_color]"
START_PROCESSING(SSobj, src)
set_light(brightness_on)
else
@@ -103,23 +106,32 @@
embedding = list("embed_chance" = 75, "embedded_impact_pain_multiplier" = 10)
armour_penetration = 35
block_chance = 50
var/list/possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
/obj/item/melee/transforming/energy/sword/Initialize(mapload)
. = ..()
set_sword_color()
/obj/item/melee/transforming/energy/sword/proc/set_sword_color()
if(LAZYLEN(possible_colors))
light_color = possible_colors[pick(possible_colors)]
/obj/item/melee/transforming/energy/sword/transform_weapon(mob/living/user, supress_message_text)
. = ..()
if(active)
if(. && item_color)
icon_state = "sword[item_color]"
AddElement(/datum/element/sword_point)
else
RemoveElement(/datum/element/sword_point)
/obj/item/melee/transforming/energy/sword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/melee/transforming/energy/sword/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!active)
return NONE
return ..()
/obj/item/melee/transforming/energy/sword/cyborg
item_color = "red"
sword_color = "red"
light_color = "#ff0000"
possible_colors = null
var/hitcost = 50
/obj/item/melee/transforming/energy/sword/cyborg/attack(mob/M, var/mob/living/silicon/robot/R)
@@ -140,7 +152,7 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "esaw_0"
icon_state_on = "esaw_1"
item_color = null //stops icon from breaking when turned on.
sword_color = null //stops icon from breaking when turned on.
hitcost = 75 //Costs more than a standard cyborg esword
w_class = WEIGHT_CLASS_NORMAL
sharpness = IS_SHARP
@@ -148,19 +160,17 @@
tool_behaviour = TOOL_SAW
toolspeed = 0.7
/obj/item/melee/transforming/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/melee/transforming/energy/sword/cyborg/saw/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
return NONE
/obj/item/melee/transforming/energy/sword/saber
var/list/possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
var/hacked = FALSE
/obj/item/melee/transforming/energy/sword/saber/Initialize(mapload)
. = ..()
/obj/item/melee/transforming/energy/sword/saber/set_sword_color()
if(LAZYLEN(possible_colors))
var/set_color = pick(possible_colors)
item_color = set_color
light_color = possible_colors[set_color]
sword_color = pick(possible_colors)
light_color = possible_colors[sword_color]
/obj/item/melee/transforming/energy/sword/saber/process()
. = ..()
@@ -185,7 +195,7 @@
if(istype(W, /obj/item/multitool))
if(!hacked)
hacked = TRUE
item_color = "rainbow"
sword_color = "rainbow"
to_chat(user, "<span class='warning'>RNBW_ENGAGE</span>")
if(active)
@@ -204,6 +214,7 @@
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
icon_state_on = "cutlass1"
light_color = "#ff0000"
possible_colors = null
/obj/item/melee/transforming/energy/blade
name = "energy blade"
@@ -271,32 +282,8 @@
return TRUE
/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
if(active) //also I'd need to rip out the iconstate changing bits
force = force_on
throwforce = throwforce_on
hitsound = hitsound_on
throw_speed = 4
if(attack_verb_on.len)
attack_verb = attack_verb_on
w_class = w_class_on
START_PROCESSING(SSobj, src)
set_light(brightness_on)
update_icon()
else
force = initial(force)
throwforce = initial(throwforce)
hitsound = initial(hitsound)
throw_speed = initial(throw_speed)
if(attack_verb_off.len)
attack_verb = attack_verb_off
w_class = initial(w_class)
STOP_PROCESSING(SSobj, src)
set_light(0)
update_icon()
transform_messages(user, supress_message_text)
add_fingerprint(user)
return TRUE
. = ..()
update_icon()
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
@@ -337,7 +324,7 @@
. = ..()
. += "<span class='notice'>Alt-click to recolor it.</span>"
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(active)
if(isinhands)
+7 -8
View File
@@ -2,13 +2,12 @@
item_flags = NEEDS_PERMIT
/obj/item/melee/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user)
if(target.check_block())
if(target.check_martial_melee_block())
target.visible_message("<span class='danger'>[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!</span>",
"<span class='userdanger'>You block the attack!</span>")
user.Stun(40)
return TRUE
/obj/item/melee/chainofcommand
name = "chain of command"
desc = "A tool used by great men to placate the frothing masses."
@@ -75,9 +74,9 @@
AddComponent(/datum/component/butchering, 30, 95, 5) //fast and effective, but as a sword, it might damage the results.
AddElement(/datum/element/sword_point)
/obj/item/melee/sabre/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a sword to a gunfight
/obj/item/melee/sabre/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE) // Don't bring a sword to a gunfight.
return BLOCK_NONE
return ..()
/obj/item/melee/sabre/on_exit_storage(datum/component/storage/S)
@@ -165,8 +164,8 @@
. = ..()
AddComponent(/datum/component/butchering, 20, 65, 0)
/obj/item/melee/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
/obj/item/melee/rapier/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type == ATTACK_TYPE_PROJECTILE)
final_block_chance = 0
return ..()
@@ -305,7 +304,7 @@
return
else
if(cooldown_check < world.time)
if(target.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK))
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS)
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
return
if(ishuman(target))
+22 -22
View File
@@ -7,7 +7,7 @@
desc = "Used to recolor floors and walls. Can be removed by the janitor."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "paint_neutral"
item_color = "FFFFFF"
var/paint_color = "FFFFFF"
item_state = "paintcan"
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = FLAMMABLE
@@ -16,37 +16,37 @@
/obj/item/paint/red
name = "red paint"
item_color = "C73232" //"FF0000"
paint_color = "C73232" //"FF0000"
icon_state = "paint_red"
/obj/item/paint/green
name = "green paint"
item_color = "2A9C3B" //"00FF00"
paint_color = "2A9C3B" //"00FF00"
icon_state = "paint_green"
/obj/item/paint/blue
name = "blue paint"
item_color = "5998FF" //"0000FF"
paint_color = "5998FF" //"0000FF"
icon_state = "paint_blue"
/obj/item/paint/yellow
name = "yellow paint"
item_color = "CFB52B" //"FFFF00"
paint_color = "CFB52B" //"FFFF00"
icon_state = "paint_yellow"
/obj/item/paint/violet
name = "violet paint"
item_color = "AE4CCD" //"FF00FF"
paint_color = "AE4CCD" //"FF00FF"
icon_state = "paint_violet"
/obj/item/paint/black
name = "black paint"
item_color = "333333"
paint_color = "333333"
icon_state = "paint_black"
/obj/item/paint/white
name = "white paint"
item_color = "FFFFFF"
paint_color = "FFFFFF"
icon_state = "paint_white"
@@ -61,31 +61,31 @@
return
switch(t1)
if("red")
item_color = "C73232"
paint_color = "C73232"
if("pink")
item_color = "FFC0CD"
paint_color = "FFC0CD"
if("blue")
item_color = "5998FF"
paint_color = "5998FF"
if("cyan")
item_color = "00FFFF"
paint_color = "00FFFF"
if("green")
item_color = "2A9C3B"
paint_color = "2A9C3B"
if("lime")
item_color = "00FF00"
paint_color = "00FF00"
if("yellow")
item_color = "CFB52B"
paint_color = "CFB52B"
if("orange")
item_color = "fFA700"
paint_color = "fFA700"
if("violet")
item_color = "AE4CCD"
paint_color = "AE4CCD"
if("purple")
item_color = "800080"
paint_color = "800080"
if("white")
item_color = "FFFFFF"
paint_color = "FFFFFF"
if("gray")
item_color = "808080"
paint_color = "808080"
if("black")
item_color = "333333"
paint_color = "333333"
icon_state = "paint_[t1]"
add_fingerprint(user)
@@ -99,7 +99,7 @@
return
if(!isturf(target) || isspaceturf(target))
return
var/newcolor = "#" + item_color
var/newcolor = "#" + paint_color
target.add_atom_colour(newcolor, WASHABLE_COLOUR_PRIORITY)
/obj/item/paint/paint_remover
+1 -1
View File
@@ -83,7 +83,7 @@
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
if(H && (H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
// Suit sensors must be on maximum.
+9 -1
View File
@@ -434,7 +434,15 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
can_random_spawn = FALSE
/obj/item/toy/plush/random/Initialize()
var/newtype = prob(CONFIG_GET(number/snowflake_plushie_prob))? /obj/item/toy/plush/random_snowflake : pick(GLOB.valid_plushie_paths)
var/newtype
var/list/snowflake_list = CONFIG_GET(keyed_list/snowflake_plushies)
/// If there are no snowflake plushies we'll default to base plush, so we grab from the valid list
if (snowflake_list.len)
newtype = prob(CONFIG_GET(number/snowflake_plushie_prob)) ? /obj/item/toy/plush/random_snowflake : pick(GLOB.valid_plushie_paths)
else
newtype = pick(GLOB.valid_plushie_paths)
new newtype(loc)
return INITIALIZE_HINT_QDEL
+2 -1
View File
@@ -189,6 +189,7 @@
slowdown = 2.0 //gotta pretend we're balanced.
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60)
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/suit/armor/plate/crusader/red
icon_state = "crusader-red"
@@ -214,7 +215,7 @@
/obj/item/clothing/head/helmet/plate/crusader/prophet
name = "Prophet's Hat"
desc = "A religious-looking hat."
alternate_worn_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
flags_1 = 0
armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 50, "bomb" = 70, "bio" = 50, "rad" = 50, "fire" = 60, "acid" = 60) //religion protects you from disease and radiation, honk.
worn_x_dimension = 64
+1 -1
View File
@@ -11,7 +11,7 @@
var/charge_cost = 30
/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
if(M.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
if(M.run_block(src, 0, "[M]'s [name]", ATTACK_TYPE_MELEE, 0, user, ran_zone(user.zone_selected)) & BLOCK_SUCCESS)
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(iscyborg(user))
@@ -663,21 +663,19 @@
var/maxReduction = 1
/obj/effect/proc_holder/silicon/cyborg/vtecControl/Click(mob/living/silicon/robot/user)
var/mob/living/silicon/robot/self = usr
/obj/effect/proc_holder/silicon/cyborg/vtecControl/Trigger(mob/living/silicon/robot/user)
currentState = (currentState + 1) % 3
if(istype(self))
if(istype(user))
switch(currentState)
if (0)
self.speed = initial(self.speed)
user.speed = initial(user.speed)
if (1)
self.speed = initial(self.speed) - maxReduction * 0.5
user.speed = initial(user.speed) - maxReduction * 0.5
if (2)
self.speed = initial(self.speed) - maxReduction * 1
user.speed = initial(user.speed) - maxReduction * 1
action.button_icon_state = "Chevron_State_[currentState]"
action.UpdateButtonIcon()
return
return TRUE
+245 -76
View File
@@ -1,13 +1,153 @@
/obj/item/shield
name = "shield"
icon = 'icons/obj/items_and_weapons.dmi'
icon = 'icons/obj/shields.dmi'
block_chance = 50
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
var/transparent = FALSE // makes beam projectiles pass through the shield
/// Shield flags
var/shield_flags = SHIELD_FLAGS_DEFAULT
/// Last shieldbash world.time
var/last_shieldbash = 0
/// Shieldbashing cooldown
var/shieldbash_cooldown = 5 SECONDS
/// Shieldbashing stamina cost
var/shieldbash_stamcost = 7.5
/// Shieldbashing knockback
var/shieldbash_knockback = 2
/// Shield bashing brute damage
var/shieldbash_brutedamage = 5
/// Shield bashing stamina damage
var/shieldbash_stamdmg = 15
/// Shield bashing stagger duration
var/shieldbash_stagger_duration = 3.5 SECONDS
/// Shield bashing push distance
var/shieldbash_push_distance = 1
/obj/item/shield/proc/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
/obj/item/shield/examine(mob/user)
. = ..()
if(shield_flags & SHIELD_CAN_BASH)
. += "<span class='notice'>Right click on combat mode attack with [src] to shield bash!</span>"
if(shield_flags & SHIELD_BASH_GROUND_SLAM)
. += "<span class='notice'>Directly rightclicking on a downed target with [src] will slam them instead of bashing.</span>"
/obj/item/shield/proc/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance)
return TRUE
/obj/item/shield/alt_pre_attack(atom/A, mob/living/user, params)
user_shieldbash(user, A, user.a_intent != INTENT_HARM)
return TRUE
/obj/item/shield/altafterattack(atom/target, mob/user, proximity_flag, click_parameters)
user_shieldbash(user, target, user.a_intent != INTENT_HARM)
return TRUE
/obj/item/shield/proc/do_shieldbash_effect(mob/living/user, dir, harmful)
var/px = 0
var/py = 0
switch(dir)
if(NORTH)
py = 12
if(SOUTH)
py = -12
if(EAST)
px = 12
if(WEST)
px = -12
var/oldpx = user.pixel_x
var/oldpy = user.pixel_y
animate(user, pixel_x = px, pixel_y = py, time = 3, easing = SINE_EASING | EASE_OUT, flags = ANIMATION_END_NOW)
animate(user, pixel_x = oldpx, pixel_y = oldpy, time = 3)
user.visible_message("<span class='warning'>[user] [harmful? "charges forwards with" : "sweeps"] [src]!</span>")
var/obj/effect/temp_visual/dir_setting/shield_bash/effect = new(user.loc, dir)
animate(effect, alpha = 0, pixel_x = px + 4, pixel_y = py + 4, time = 3)
/obj/item/shield/proc/bash_target(mob/living/user, mob/living/target, bashdir, harmful)
if(!(target.status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess..
// unified stun absorption system when lol
target.visible_message("<span class='warning'>[user] slams [target] with [src], but [target] doesn't falter!</span>", "<span class='userdanger'>[user] slams you with [src], but it barely fazes you!</span>")
return FALSE
var/target_downed = !CHECK_MOBILITY(target, MOBILITY_STAND)
var/wallhit = FALSE
var/turf/target_current_turf = get_turf(target)
if(harmful)
target.visible_message("<span class='warning'>[target_downed? "[user] slams [src] into [target]" : "[user] bashes [target] with [src]"]!</span>",
"<span class='warning'>[target_downed? "[user] slams [src] into you" : "[user] bashes you with [src]"]!</span>")
else
target.visible_message("<span class='warning'>[user] shoves [target] with [src]!</span>",
"<span class='warning'>[user] shoves you with [src]!</span>")
for(var/i in 1 to harmful? shieldbash_knockback : shieldbash_push_distance)
var/turf/new_turf = get_step(target, bashdir)
var/mob/living/carbon/human/H = locate() in new_turf
if(H && harmful)
H.visible_message("<span class='warning'>[target] is sent crashing into [H]!</span>",
"<span class='userdanger'>[target] is sent crashing into you!</span>")
H.KnockToFloor()
wallhit = TRUE
break
else
step(target, bashdir)
if(get_turf(target) == target_current_turf)
wallhit = TRUE
break
else
target_current_turf = get_turf(target)
var/disarming = (target_downed && (shield_flags & SHIELD_BASH_GROUND_SLAM_DISARM)) || (shield_flags & SHIELD_BASH_ALWAYS_DISARM) || (wallhit && (shield_flags & SHIELD_BASH_WALL_DISARM))
var/knockdown = !target_downed && ((shield_flags & SHIELD_BASH_ALWAYS_KNOCKDOWN) || (wallhit && (shield_flags & SHIELD_BASH_WALL_KNOCKDOWN)))
if(shieldbash_stagger_duration || knockdown)
target.visible_message("<span class='warning'>[target] is knocked [knockdown? "to the floor" : "off balanace"]!</span>",
"<span class='userdanger'>You are knocked [knockdown? "to the floor" : "off balanace"]!</span>")
if(knockdown)
target.KnockToFloor(disarming)
else if(disarming)
target.drop_all_held_items()
if(harmful)
target.apply_damage(shieldbash_stamdmg, STAMINA, BODY_ZONE_CHEST)
target.apply_damage(shieldbash_brutedamage, BRUTE, BODY_ZONE_CHEST)
target.Stagger(shieldbash_stagger_duration)
return TRUE
/obj/item/shield/proc/user_shieldbash(mob/living/user, atom/target, harmful)
if(!(shield_flags & SHIELD_CAN_BASH))
to_chat(user, "<span class='warning'>[src] can't be used to shield bash!</span>")
return FALSE
if(world.time < last_shieldbash + shieldbash_cooldown)
to_chat(user, "<span class='warning'>You can't bash with [src] again so soon!</span>")
return FALSE
if(isliving(target)) //GROUND SLAAAM
if(!(shield_flags & SHIELD_BASH_GROUND_SLAM))
to_chat(user, "<span class='warning'>You can't ground slam with [src]!</span>")
return FALSE
bash_target(user, target, NONE, harmful)
user.do_attack_animation(target, used_item = src)
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
last_shieldbash = world.time
user.adjustStaminaLossBuffered(shieldbash_stamcost)
return 1
// Directional sweep!
last_shieldbash = world.time
user.adjustStaminaLossBuffered(shieldbash_stamcost)
// Since we are in combat mode, we can probably safely use the user's dir instead of getting their mouse pointing cardinal dir.
var/bashdir = user.dir
do_shieldbash_effect(user, bashdir, harmful)
var/list/checking = list(get_step(user, user.dir), get_step(user, turn(user.dir, 45)), get_step(user, turn(user.dir, -45)))
var/list/victims = list()
for(var/i in checking)
var/turf/T = i
for(var/mob/living/L in T.contents)
victims += L
if(length(victims))
for(var/i in victims)
bash_target(user, i, bashdir, harmful)
playsound(src, harmful? "swing_hit" : 'sound/weapons/thudswoosh.ogg', 75, 1)
else
playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1)
return length(victims)
/obj/effect/temp_visual/dir_setting/shield_bash
icon = 'icons/effects/96x96_attack_sweep.dmi'
icon_state = "shield_bash"
duration = 3
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
@@ -23,19 +163,22 @@
custom_materials = list(/datum/material/glass=7500, /datum/material/iron=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
transparent = TRUE
var/repair_material = /obj/item/stack/sheet/mineral/titanium
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
max_integrity = 75
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(transparent && (hitby.pass_flags & PASSGLASS))
return FALSE
if(attack_type == THROWN_PROJECTILE_ATTACK)
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(ismovableatom(object))
var/atom/movable/AM = object
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
return BLOCK_NONE
if(attack_type & ATTACK_TYPE_THROWN)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
if(attack_type & ATTACK_TYPE_TACKLE)
final_block_chance = 100
. = ..()
if(.)
on_shield_block(owner, hitby, attack_text, damage, attack_type)
if(. & BLOCK_SUCCESS)
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
@@ -43,7 +186,7 @@
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else if(istype(W, /obj/item/stack/sheet/mineral/titanium))
else if(istype(W, repair_material))
if(obj_integrity >= max_integrity)
to_chat(user, "<span class='warning'>[src] is already in perfect condition.</span>")
else
@@ -69,16 +212,33 @@
playsound(owner, 'sound/effects/glassbr3.ogg', 100)
new /obj/item/shard((get_turf(src)))
/obj/item/shield/riot/on_shield_block(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK)
/obj/item/shield/riot/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(obj_integrity <= damage)
var/turf/T = get_turf(owner)
T.visible_message("<span class='warning'>[hitby] destroys [src]!</span>")
T.visible_message("<span class='warning'>[attack_text] destroys [src]!</span>")
shatter(owner)
qdel(src)
return FALSE
take_damage(damage)
return ..()
/obj/item/shield/riot/laser_proof
name = "laser resistant shield"
desc = "A far more frail shield made of dark glass meant to block lasers but suffers from being being weak to ballistic projectiles."
armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
icon_state = "riot_laser"
item_state = "riot_laser"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 55 //Weak
obj/item/shield/riot/bullet_proof
name = "bullet resistant shield"
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
max_integrity = 55 //Weaker
/obj/item/shield/riot/roman
name = "\improper Roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
@@ -86,7 +246,8 @@
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
transparent = FALSE
repair_material = /obj/item/stack/sheet/mineral/wood
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 65
/obj/item/shield/riot/roman/fake
@@ -108,66 +269,15 @@
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
custom_materials = null
resistance_flags = FLAMMABLE
repair_material = /obj/item/stack/sheet/mineral/wood
block_chance = 30
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
max_integrity = 55
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
playsound(owner, 'sound/effects/bang.ogg', 50)
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
throw_range = 5
force = 3
throwforce = 3
throw_speed = 3
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
var/on_force = 10
var/on_throwforce = 8
var/on_throw_speed = 2
var/active = 0
var/clumsy_check = TRUE
/obj/item/shield/energy/Initialize()
. = ..()
icon_state = "[base_icon_state]0"
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/shield/energy/IsReflect()
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
if(active)
force = on_force
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
@@ -182,10 +292,10 @@
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/shield/riot/tele/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!active)
return BLOCK_NONE
return ..()
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
@@ -220,6 +330,7 @@
custom_materials = list(/datum/material/iron = 18000)
slot_flags = null
block_chance = 35
max_integrity = 100 //Made of metal welded together its strong but not unkillable
force = 10
throwforce = 7
@@ -236,7 +347,13 @@
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
item_flags = SLOWS_WHILE_IN_HAND
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
/obj/item/shield/riot/tower/swat
name = "swat shield"
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
max_integrity = 175
block_chance = 50
/obj/item/shield/riot/implant
name = "riot tower shield"
@@ -246,10 +363,62 @@
icon = 'icons/obj/items_and_weapons.dmi'
block_chance = 30 //May be big but hard to move around to block.
slowdown = 1
transparent = FALSE
shield_flags = SHIELD_FLAGS_DEFAULT
item_flags = SLOWS_WHILE_IN_HAND
/obj/item/shield/riot/implant/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
/obj/item/shield/riot/implant/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE)
final_block_chance = 60 //Massive shield
return ..()
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield that reflects almost all energy projectiles, but is useless against physical attacks. It can be retracted, expanded, and stored anywhere."
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
throw_range = 5
force = 3
throwforce = 3
throw_speed = 3
var/base_icon_state = "eshield" // [base_icon_state]1 for expanded, [base_icon_state]0 for contracted
var/on_force = 10
var/on_throwforce = 8
var/on_throw_speed = 2
var/active = 0
var/clumsy_check = TRUE
/obj/item/shield/energy/Initialize()
. = ..()
icon_state = "[base_icon_state]0"
/obj/item/shield/energy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT
return ..()
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(clumsy_check && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, "<span class='userdanger'>You beat yourself in the head with [src]!</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "[base_icon_state][active]"
if(active)
force = on_force
throwforce = on_throwforce
throw_speed = on_throw_speed
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = initial(force)
throwforce = initial(throwforce)
throw_speed = initial(throw_speed)
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, TRUE)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
@@ -5,6 +5,7 @@
icon = 'icons/obj/telescience.dmi'
icon_state = "bluespace_crystal"
singular_name = "bluespace crystal"
dye_color = DYE_COSMIC
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/bluespace=MINERAL_MATERIAL_AMOUNT)
points = 50
@@ -72,6 +72,8 @@
to_chat(user, "<span class='notice'> [M] is at full health.</span>")
return FALSE
user.visible_message("<span class='green'>[user] applies \the [src] on [M].</span>", "<span class='green'>You apply \the [src] on [M].</span>")
if(AmBloodsucker(M))
return
M.heal_bodypart_damage((heal_brute/2))
return TRUE
if(iscarbon(M))
@@ -148,6 +150,8 @@
return
if(iscarbon(M))
return heal_carbon(M, user, 0, heal_burn)
if(AmBloodsucker(M))
return
to_chat(user, "<span class='notice'>You can't heal [M] with the \the [src]!</span>")
/obj/item/stack/medical/ointment/suicide_act(mob/living/user)
@@ -22,6 +22,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
new/datum/stack_recipe("spout flask", /obj/item/glasswork/glass_base/spouty, 20), \
new/datum/stack_recipe("small bulb flask", /obj/item/glasswork/glass_base/flask_small, 5), \
new/datum/stack_recipe("large bottle flask", /obj/item/glasswork/glass_base/flask_large, 15), \
new/datum/stack_recipe("tea cup", /obj/item/glasswork/glass_base/tea_plate, 5), \
new/datum/stack_recipe("tea plate", /obj/item/glasswork/glass_base/tea_cup, 5), \
)), \
))
@@ -137,7 +139,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
return ..()
/obj/item/stack/sheet/plasmaglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 1.2
S.max_integrity *= 1.2
S.efficiency *= 1.2
/*
@@ -170,7 +172,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
..()
/obj/item/stack/sheet/rglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
S.max_integrity *= 2
/obj/item/stack/sheet/rglass/cyborg
custom_materials = null
@@ -218,7 +220,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \
. += GLOB.prglass_recipes
/obj/item/stack/sheet/plasmarglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.2
S.max_integrity *= 2.2
S.efficiency *= 1.2
GLOBAL_LIST_INIT(titaniumglass_recipes, list(
@@ -242,7 +244,7 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list(
. += GLOB.titaniumglass_recipes
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2.5
S.max_integrity *= 2.5
S.efficiency *= 1.5
GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
@@ -270,7 +272,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
. += GLOB.plastitaniumglass_recipes
/obj/item/stack/sheet/titaniumglass/on_solar_construction(obj/machinery/power/solar/S)
S.obj_integrity *= 2
S.max_integrity *= 2
S.efficiency *= 2
/obj/item/shard
@@ -179,11 +179,24 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \
null, \
new /datum/stack_recipe_list("crates", list( \
new /datum/stack_recipe("gray crate", /obj/structure/closet/crate, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("internals crate", /obj/structure/closet/crate/internals, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("trash cart", /obj/structure/closet/crate/trashcart, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("medical crate", /obj/structure/closet/crate/medical, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("freezer crate", /obj/structure/closet/crate/freezer, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("blood bag crate", /obj/structure/closet/crate/freezer/blood, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("surplus limbs crate", /obj/structure/closet/crate/freezer/surplus_limbs, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("radiation containment crate", /obj/structure/closet/crate/radiation, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("hydroponics crate", /obj/structure/closet/crate/hydroponics, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("engineering crate", /obj/structure/closet/crate/engineering, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("eletrical crate", /obj/structure/closet/crate/engineering/electrical, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("RCD storage crate", /obj/structure/closet/crate/rcd, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("science crate", /obj/structure/closet/crate/science, 5, time = 50, one_per_turf = 1, on_floor = 1), \
)), \
new /datum/stack_recipe_list("airlock assemblies", list( \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 8, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("vault door assembly", /obj/structure/door_assembly/door_assembly_vault, 6, time = 50, one_per_turf = 1, on_floor = 1), \
)), \
))
@@ -368,6 +381,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \
new/datum/stack_recipe("bedsheet", /obj/item/bedsheet, 3), \
new/datum/stack_recipe("empty sandbag", /obj/item/emptysandbag, 4), \
new/datum/stack_recipe("padded floor tile", /obj/item/stack/tile/padded, 1, 4, 20), \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1),\
new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 1),\
@@ -768,6 +782,7 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
new /datum/stack_recipe("water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/empty), \
new /datum/stack_recipe("large water bottle", /obj/item/reagent_containers/glass/beaker/waterbottle/large/empty,3), \
new /datum/stack_recipe("shower curtain", /obj/structure/curtain, 10, time = 10, one_per_turf = 1, on_floor = 1), \
new /datum/stack_recipe("laser pointer case", /obj/item/glasswork/glass_base/laserpointer_shell, 30), \
new /datum/stack_recipe("wet floor sign", /obj/item/caution, 2)))
/obj/item/stack/sheet/plastic
@@ -845,4 +860,3 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
merge_type = /obj/item/stack/sheet/cotton/durathread
pull_effort = 70
loom_result = /obj/item/stack/sheet/durathread
+1 -2
View File
@@ -240,8 +240,7 @@
else if(istype(O, /obj/item/restraints/handcuffs/cable))
var/obj/item/cuffs = O
cuffs.item_color = item_color
cuffs.update_icon()
cuffs.color = color
if (QDELETED(O))
return //It's a stack and has already been merged
@@ -142,6 +142,14 @@
turf_type = /turf/open/floor/wood
resistance_flags = FLAMMABLE
//Cloth Floors
/obj/item/stack/tile/padded
name = "padded floor tile"
desc = "These are soft and cushy, they'd make good pillows. They look very comfortable, although what they're used for is discomforting."
icon_state = "tile_padded"
turf_type = /turf/open/floor/padded
//Basalt
/obj/item/stack/tile/basalt
name = "basalt tile"
+3 -1
View File
@@ -22,7 +22,7 @@
for(var/obj/item/I in contents)
. += I.get_belt_overlay()
/obj/item/storage/belt/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/storage/belt/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands && onmob_overlays)
for(var/obj/item/I in contents)
@@ -708,6 +708,7 @@
desc = "A dorky fannypack for keeping small items in."
icon_state = "fannypack_leather"
item_state = "fannypack_leather"
dying_key = DYE_REGISTRY_FANNYPACK
/obj/item/storage/belt/fannypack/ComponentInitialize()
. = ..()
@@ -804,3 +805,4 @@
attack_verb = list("bashed", "slashes", "prods", "pokes")
fitting_swords = list(/obj/item/melee/rapier)
starting_sword = /obj/item/melee/rapier
+4 -4
View File
@@ -953,7 +953,7 @@
/obj/item/reagent_containers/food/snacks/grown/corn,
/obj/item/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
/obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle,
/obj/item/reagent_containers/food/snacks/faggot,
/obj/item/reagent_containers/food/snacks/meatball,
/obj/item/reagent_containers/food/snacks/grown/citrus/orange,
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon,
/obj/item/reagent_containers/food/snacks/grown/citrus/lime,
@@ -1005,7 +1005,7 @@
/obj/item/storage/box/ingredients/italian/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/reagent_containers/food/snacks/grown/tomato(src)
new /obj/item/reagent_containers/food/snacks/faggot(src)
new /obj/item/reagent_containers/food/snacks/meatball(src)
new /obj/item/reagent_containers/food/drinks/bottle/wine(src)
/obj/item/storage/box/ingredients/vegetarian
@@ -1028,7 +1028,7 @@
new /obj/item/reagent_containers/food/snacks/grown/potato(src)
new /obj/item/reagent_containers/food/snacks/grown/tomato(src)
new /obj/item/reagent_containers/food/snacks/grown/corn(src)
new /obj/item/reagent_containers/food/snacks/faggot(src)
new /obj/item/reagent_containers/food/snacks/meatball(src)
/obj/item/storage/box/ingredients/fruity
theme_name = "fruity"
@@ -1084,7 +1084,7 @@
new /obj/item/reagent_containers/food/snacks/carpmeat(src)
new /obj/item/reagent_containers/food/snacks/meat/slab/xeno(src)
new /obj/item/reagent_containers/food/snacks/meat/slab/corgi(src)
new /obj/item/reagent_containers/food/snacks/faggot(src)
new /obj/item/reagent_containers/food/snacks/meatball(src)
/obj/item/storage/box/ingredients/exotic
theme_name = "exotic"
+5
View File
@@ -274,6 +274,7 @@
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/cigarettes.dmi'
icon_state = "cig_paper_pack"
///The value in here has NOTHING to do with icons. It needs to be this for the proper examine.
icon_type = "rolling paper"
spawn_type = /obj/item/rollingpaper
@@ -283,6 +284,10 @@
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/rollingpaper))
///Overrides to do nothing because fancy boxes are fucking insane.
/obj/item/storage/fancy/rollingpapers/update_icon_state()
return
/obj/item/storage/fancy/rollingpapers/update_overlays()
. = ..()
if(!contents.len)
+1 -1
View File
@@ -16,7 +16,7 @@
AddComponent(component_type)
/obj/item/storage/AllowDrop()
return FALSE
return TRUE
/obj/item/storage/contents_explosion(severity, target)
for(var/atom/A in contents)
@@ -404,6 +404,12 @@
new /obj/item/gun/ballistic/revolver(src)
new /obj/item/ammo_box/a357(src)
/obj/item/storage/box/syndie_kit/pistol
/obj/item/storage/box/syndie_kit/pistol/PopulateContents()
new /obj/item/gun/ballistic/automatic/pistol(src)
new /obj/item/ammo_box/magazine/m10mm(src)
/obj/item/storage/box/syndie_kit/contract_kit
name = "contractor kit"
desc = "Supplied to Syndicate contractors in active mission areas."
@@ -494,7 +500,7 @@
new item1(src) // Create three, non repeat items from the list.
new item2(src)
new item3(src)
new /obj/item/paper/contractor_guide(src) //Paper guide
new /obj/item/paper/contractor_guide(src) //Paper guide
/obj/item/storage/box/syndie_kit/northstar
@@ -503,4 +509,4 @@
new /obj/item/clothing/accessory/padding(src)
new /obj/item/clothing/under/chameleon(src)
new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(src)
new /obj/item/lighter(src)
new /obj/item/lighter(src)
+3 -3
View File
@@ -101,11 +101,11 @@
icon_state = "random_wallet"
/obj/item/storage/wallet/random/PopulateContents()
var/item1_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500)
var/item1_type = /obj/effect/spawner/lootdrop/space_cash/no_turf
var/item2_type
if(prob(50))
item2_type = pick( /obj/item/stack/spacecash/c10, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c1000, /obj/item/stack/spacecash/c20, /obj/item/stack/spacecash/c200, /obj/item/stack/spacecash/c50, /obj/item/stack/spacecash/c500)
var/item3_type = pick( /obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/gold, /obj/item/coin/iron, /obj/item/coin/iron, /obj/item/coin/iron )
item2_type = /obj/effect/spawner/lootdrop/space_cash/no_turf
var/item3_type = /obj/effect/spawner/lootdrop/coin/no_turf
spawn(2)
if(item1_type)
+2 -2
View File
@@ -15,7 +15,7 @@
attack_verb = list("beaten")
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
var/stamforce = 25
var/stamforce = 35
var/status = FALSE
var/knockdown = TRUE
var/obj/item/stock_parts/cell/cell
@@ -170,7 +170,7 @@
return disarming || (user.a_intent != INTENT_HARM)
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
if(L.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
if(L.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; check_shields() handles that
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
var/stunpwr = stamforce
+2 -2
View File
@@ -376,8 +376,8 @@
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/reagent_containers/chemtank/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE) //apply chemcolor and level
. = list()
/obj/item/reagent_containers/chemtank/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE) //apply chemcolor and level
. = ..()
//inhands + reagent_filling
if(!isinhands && reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpackmob-10")
+2 -2
View File
@@ -53,8 +53,8 @@
base_overlay.appearance_flags = RESET_COLOR
. += base_overlay
/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands && random_color)
var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head")
M.appearance_flags = RESET_COLOR
+5 -14
View File
@@ -273,15 +273,12 @@
var/obj/item/twohanded/dualsaber/toy/newSaber = new /obj/item/twohanded/dualsaber/toy(user.loc)
if(hacked) // That's right, we'll only check the "original" "sword".
newSaber.hacked = TRUE
newSaber.item_color = "rainbow"
qdel(W)
qdel(src)
else if(istype(W, /obj/item/multitool))
if(!hacked)
hacked = TRUE
item_color = "rainbow"
to_chat(user, "<span class='warning'>RNBW_ENGAGE</span>")
if(active)
update_icon()
user.update_inv_hands()
@@ -352,7 +349,7 @@
update_light()
return TRUE
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(active)
if(isinhands)
@@ -454,11 +451,8 @@
total_mass_on = TOTAL_MASS_TOY_SWORD
sharpness = IS_BLUNT
/obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
/obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
return FALSE
/obj/item/twohanded/dualsaber/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
return BLOCK_NONE
/obj/item/twohanded/dualsaber/hypereutactic/toy
name = "\improper DX Hyper-Euplastic LightSword"
@@ -474,11 +468,8 @@
slowdown_wielded = 0
sharpness = IS_BLUNT
/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return FALSE
/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
return FALSE
/obj/item/twohanded/dualsaber/hypereutactic/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
return BLOCK_NONE
/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
+35 -33
View File
@@ -281,7 +281,7 @@
hitsound = "swing_hit"
var/hitsound_on = 'sound/weapons/blade1.ogg'
armour_penetration = 35
item_color = "green"
var/saber_color = "green"
light_color = "#00ff00"//green
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
block_chance = 75
@@ -289,6 +289,8 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
resistance_flags = FIRE_PROOF
var/hacked = FALSE
/// Can this reflect all energy projectiles?
var/can_reflect = TRUE
var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD
var/list/possible_colors = list("red", "blue", "green", "purple")
var/list/rainbow_colors = list(LIGHT_COLOR_RED, LIGHT_COLOR_GREEN, LIGHT_COLOR_LIGHT_CYAN, LIGHT_COLOR_LAVENDER)
@@ -324,8 +326,8 @@
/obj/item/twohanded/dualsaber/Initialize()
. = ..()
if(LAZYLEN(possible_colors))
item_color = pick(possible_colors)
switch(item_color)
saber_color = pick(possible_colors)
switch(saber_color)
if("red")
light_color = LIGHT_COLOR_RED
if("green")
@@ -341,7 +343,7 @@
/obj/item/twohanded/dualsaber/update_icon_state()
if(wielded)
icon_state = "dualsaber[item_color][wielded]"
icon_state = "dualsaber[saber_color][wielded]"
else
icon_state = "dualsaber0"
clean_blood()
@@ -373,10 +375,13 @@
else
user.adjustStaminaLoss(25)
/obj/item/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
return ..()
return 0
/obj/item/twohanded/dualsaber/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!wielded)
return NONE
if(can_reflect && is_energy_reflectable_projectile(object) && (attack_type & ATTACK_TYPE_PROJECTILE))
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER //no you
return BLOCK_SHOULD_REDIRECT | BLOCK_SUCCESS | BLOCK_REDIRECTED
return ..()
/obj/item/twohanded/dualsaber/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up
if(wielded)
@@ -419,10 +424,6 @@
/obj/item/twohanded/dualsaber/proc/rainbow_process()
light_color = pick(rainbow_colors)
/obj/item/twohanded/dualsaber/IsReflect()
if(wielded)
return 1
/obj/item/twohanded/dualsaber/ignition_effect(atom/A, mob/user)
// same as /obj/item/melee/transforming/energy, mostly
if(!wielded)
@@ -456,7 +457,7 @@
if(!hacked)
hacked = TRUE
to_chat(user, "<span class='warning'>2XRNBW_ENGAGE</span>")
item_color = "rainbow"
saber_color = "rainbow"
update_icon()
else
to_chat(user, "<span class='warning'>It's starting to look like a triple rainbow - no, nevermind.</span>")
@@ -530,7 +531,7 @@
update_light()
return TRUE
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, style_flags = NONE)
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
. = ..()
if(isinhands)
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
@@ -560,15 +561,13 @@
block_chance = 50
armour_penetration = 0
var/chaplain_spawnable = TRUE
can_reflect = FALSE
obj_flags = UNIQUE_RENAME
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/ComponentInitialize()
. = ..()
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
return FALSE
//spears
/obj/item/twohanded/spear
icon_state = "spearglass0"
@@ -752,12 +751,16 @@
armour_penetration = 100
force_on = 30
/obj/item/twohanded/required/chainsaw/doomslayer/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
/obj/item/twohanded/required/chainsaw/doomslayer/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = 100
return ..()
/obj/item/twohanded/required/chainsaw/doomslayer/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("<span class='danger'>Ranged attacks just make [owner] angrier!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return ..()
//GREY TIDE
/obj/item/twohanded/spear/grey_tide
@@ -897,19 +900,20 @@
AddComponent(/datum/component/butchering, 20, 105)
AddElement(/datum/element/sword_point)
/obj/item/twohanded/vibro_weapon/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
/obj/item/twohanded/vibro_weapon/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(wielded)
final_block_chance *= 2
if(wielded || attack_type != PROJECTILE_ATTACK)
if(wielded || !(attack_type & ATTACK_TYPE_PROJECTILE))
if(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
if(attack_type & ATTACK_TYPE_PROJECTILE)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 1
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL
else
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
return 1
return 0
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return NONE
/obj/item/twohanded/vibro_weapon/update_icon_state()
icon_state = "hfrequency[wielded]"
@@ -1055,11 +1059,9 @@
var/mob/living/silicon/robot/R = loc
. = R.get_cell()
/obj/item/twohanded/electrostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!on)
return FALSE
if((attack_type == PROJECTILE_ATTACK) && !can_block_projectiles)
return FALSE
/obj/item/twohanded/electrostaff/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!on || (!can_block_projectiles && (attack_type & ATTACK_TYPE_PROJECTILE)))
return BLOCK_NONE
return ..()
/obj/item/twohanded/electrostaff/proc/min_hitcost()
@@ -1180,7 +1182,7 @@
if(iscyborg(target))
..()
return
if(target.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; run_block() handles that
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(user.a_intent != INTENT_HARM)
+40 -12
View File
@@ -84,6 +84,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
name = "purified longsword"
desc = "A hastily-purified longsword. While not as holy as it could be, it's still a formidable weapon against those who would rather see you dead."
force = 25
block_chance = 0
/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "<b><i>THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!</i></b>\nActivate it in your hand to point to the nearest victim."
@@ -155,8 +156,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
return
to_chat(user, "<span class='danger'>[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].</span>")
/obj/item/claymore/highlander/IsReflect()
return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME?
/obj/item/claymore/highlander/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED
return ..()
/obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE
notches++
@@ -498,7 +501,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
icon_state = "catwhip"
/obj/item/melee/skateboard
name = "skateboard"
name = "improvised skateboard"
desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon."
icon_state = "skateboard"
item_state = "skateboard"
@@ -506,11 +509,37 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
throwforce = 4
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("smacked", "whacked", "slammed", "smashed")
///The vehicle counterpart for the board
var/board_item_type = /obj/vehicle/ridden/scooter/skateboard
/obj/item/melee/skateboard/attack_self(mob/user)
new /obj/vehicle/ridden/scooter/skateboard(get_turf(user))
if(!user.canUseTopic(src, TRUE, FALSE, TRUE))
return
var/obj/vehicle/ridden/scooter/skateboard/S = new board_item_type(get_turf(user))
S.buckle_mob(user)
qdel(src)
/obj/item/melee/skateboard/pro
name = "skateboard"
desc = "A RaDSTORMz brand professional skateboard. It looks sturdy and well made."
icon_state = "skateboard2"
item_state = "skateboard2"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/pro
/obj/item/melee/skateboard/hoverboard
name = "hoverboard"
desc = "A blast from the past, so retro!"
icon_state = "hoverboard_red"
item_state = "hoverboard_red"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard
/obj/item/melee/skateboard/hoverboard/admin
name = "\improper Board Of Directors"
desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too."
icon_state = "hoverboard_nt"
item_state = "hoverboard_nt"
board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard/admin
/obj/item/melee/baseball_bat
name = "baseball bat"
desc = "There ain't a skull in the league that can withstand a swatter."
@@ -581,14 +610,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
force = 12
throwforce = 15
/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers
var/picksound = rand(1,2)
var/turf = get_turf(src)
if(picksound == 1)
playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1)
if(picksound == 2)
playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1)
return 1
/obj/item/melee/baseball_bat/ablative/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
//some day this will reflect thrown items instead of lasers
if(is_energy_reflectable_projectile(object) && (attack_type == ATTACK_TYPE_PROJECTILE))
var/turf = get_turf(src)
playsound(turf, pick('sound/weapons/effects/batreflect1.ogg', 'sound/weapons/effects/batreflect2.ogg'), 50, 1)
return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED
return ..()
/obj/item/melee/baseball_bat/ablative/syndi
name = "syndicate major league bat"
+72 -3
View File
@@ -213,9 +213,78 @@
/obj/vv_get_dropdown()
. = ..()
.["Delete all of type"] = "?_src_=vars;[HrefToken()];delall=[REF(src)]"
.["Osay"] = "?_src_=vars;[HrefToken()];osay[REF(src)]"
.["Modify armor values"] = "?_src_=vars;[HrefToken()];modarmor=[REF(src)]"
VV_DROPDOWN_OPTION("", "---")
VV_DROPDOWN_OPTION(VV_HK_MASS_DEL_TYPE, "Delete all of type")
VV_DROPDOWN_OPTION(VV_HK_OSAY, "Object Say")
VV_DROPDOWN_OPTION(VV_HK_ARMOR_MOD, "Modify armor values")
/obj/vv_do_topic(list/href_list)
if(!(. = ..()))
return
if(href_list[VV_HK_OSAY])
if(check_rights(R_FUN, FALSE))
usr.client.object_say(src)
if(href_list[VV_HK_ARMOR_MOD])
var/list/pickerlist = list()
var/list/armorlist = armor.getList()
for (var/i in armorlist)
pickerlist += list(list("value" = armorlist[i], "name" = i))
var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [src]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist)
if (islist(result))
if (result["button"] != 2) // If the user pressed the cancel button
// text2num conveniently returns a null on invalid values
armor = armor.setRating(melee = text2num(result["values"]["melee"]),\
bullet = text2num(result["values"]["bullet"]),\
laser = text2num(result["values"]["laser"]),\
energy = text2num(result["values"]["energy"]),\
bomb = text2num(result["values"]["bomb"]),\
bio = text2num(result["values"]["bio"]),\
rad = text2num(result["values"]["rad"]),\
fire = text2num(result["values"]["fire"]),\
acid = text2num(result["values"]["acid"]))
log_admin("[key_name(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]")
message_admins("<span class='notice'>[key_name_admin(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]</span>")
if(href_list[VV_HK_MASS_DEL_TYPE])
if(check_rights(R_DEBUG|R_SERVER))
var/action_type = alert("Strict type ([type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
if(action_type == "Cancel" || !action_type)
return
if(alert("Are you really sure you want to delete all objects of type [type]?",,"Yes","No") != "Yes")
return
if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
return
var/O_type = type
switch(action_type)
if("Strict type")
var/i = 0
for(var/obj/Obj in world)
if(Obj.type == O_type)
i++
qdel(Obj)
CHECK_TICK
if(!i)
to_chat(usr, "No objects of this type exist")
return
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) </span>")
if("Type and subtypes")
var/i = 0
for(var/obj/Obj in world)
if(istype(Obj,O_type))
i++
qdel(Obj)
CHECK_TICK
if(!i)
to_chat(usr, "No objects of this type exist")
return
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) </span>")
/obj/examine(mob/user)
. = ..()
@@ -317,7 +317,7 @@
throwforce = 10
throw_range = 3
hitsound = 'sound/items/trayhit1.ogg'
hit_reaction_chance = 50
block_chance = 50
custom_materials = list(/datum/material/iron = 2000)
var/break_chance = 5 //Likely hood of smashing the chair.
var/obj/structure/chair/origin_type = /obj/structure/chair
@@ -362,18 +362,17 @@
new stack_type(get_turf(loc))
qdel(src)
/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance))
owner.visible_message("<span class='danger'>[owner] fends off [attack_text] with [src]!</span>")
return 1
return 0
/obj/item/chair/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(!(attack_type & ATTACK_TYPE_UNARMED))
return NONE
return ..()
/obj/item/chair/afterattack(atom/target, mob/living/carbon/user, proximity)
. = ..()
if(!proximity)
return
if(prob(break_chance))
user.visible_message("<span class='danger'>[user] smashes \the [src] to pieces against \the [target]</span>")
user.visible_message("<span class='danger'>[user] smashes [src] to pieces against [target]</span>")
if(iscarbon(target))
var/mob/living/carbon/C = target
if(C.health < C.maxHealth*0.5)
+2 -34
View File
@@ -16,8 +16,8 @@ LINEN BINS
throw_speed = 1
throw_range = 2
w_class = WEIGHT_CLASS_TINY
item_color = "white"
resistance_flags = FLAMMABLE
dying_key = DYE_REGISTRY_BEDSHEET
dog_fashion = /datum/dog_fashion/head/ghost
var/list/dream_messages = list("white")
@@ -52,79 +52,66 @@ LINEN BINS
/obj/item/bedsheet/blue
icon_state = "sheetblue"
item_color = "blue"
dream_messages = list("blue")
/obj/item/bedsheet/green
icon_state = "sheetgreen"
item_color = "green"
dream_messages = list("green")
/obj/item/bedsheet/grey
icon_state = "sheetgrey"
item_color = "grey"
dream_messages = list("grey")
/obj/item/bedsheet/orange
icon_state = "sheetorange"
item_color = "orange"
dream_messages = list("orange")
/obj/item/bedsheet/purple
icon_state = "sheetpurple"
item_color = "purple"
dream_messages = list("purple")
/obj/item/bedsheet/patriot
name = "patriotic bedsheet"
desc = "You've never felt more free than when sleeping on this."
icon_state = "sheetUSA"
item_color = "sheetUSA"
dream_messages = list("America", "freedom", "fireworks", "bald eagles")
/obj/item/bedsheet/rainbow
name = "rainbow bedsheet"
desc = "A multicolored blanket. It's actually several different sheets cut up and sewn together."
icon_state = "sheetrainbow"
item_color = "rainbow"
dream_messages = list("red", "orange", "yellow", "green", "blue", "purple", "a rainbow")
/obj/item/bedsheet/red
icon_state = "sheetred"
item_color = "red"
dream_messages = list("red")
/obj/item/bedsheet/yellow
icon_state = "sheetyellow"
item_color = "yellow"
dream_messages = list("yellow")
/obj/item/bedsheet/mime
name = "mime's blanket"
desc = "A very soothing striped blanket. All the noise just seems to fade out when you're under the covers in this."
icon_state = "sheetmime"
item_color = "mime"
dream_messages = list("silence", "gestures", "a pale face", "a gaping mouth", "the mime")
/obj/item/bedsheet/clown
name = "clown's blanket"
desc = "A rainbow blanket with a clown mask woven in. It smells faintly of bananas."
icon_state = "sheetclown"
item_color = "clown"
dream_messages = list("honk", "laughter", "a prank", "a joke", "a smiling face", "the clown")
/obj/item/bedsheet/captain
name = "captain's bedsheet"
desc = "It has a Nanotrasen symbol on it, and was woven with a revolutionary new kind of thread guaranteed to have 0.01% permeability for most non-chemical substances, popular among most modern captains."
icon_state = "sheetcaptain"
item_color = "captain"
dream_messages = list("authority", "a golden ID", "sunglasses", "a green disc", "an antique gun", "the captain")
/obj/item/bedsheet/rd
name = "research director's bedsheet"
desc = "It appears to have a beaker emblem, and is made out of fire-resistant material, although it probably won't protect you in the event of fires you're familiar with every day."
icon_state = "sheetrd"
item_color = "director"
dream_messages = list("authority", "a silvery ID", "a bomb", "a mech", "a facehugger", "maniacal laughter", "the research director")
// for Free Golems.
@@ -137,111 +124,94 @@ LINEN BINS
name = "medical blanket"
desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station."
icon_state = "sheetmedical"
item_color = "medical"
dream_messages = list("healing", "life", "surgery", "a doctor")
/obj/item/bedsheet/cmo
name = "chief medical officer's bedsheet"
desc = "It's a sterilized blanket that has a cross emblem. There's some cat fur on it, likely from Runtime."
icon_state = "sheetcmo"
item_color = "cmo"
dream_messages = list("authority", "a silvery ID", "healing", "life", "surgery", "a cat", "the chief medical officer")
/obj/item/bedsheet/hos
name = "head of security's bedsheet"
desc = "It is decorated with a shield emblem. While crime doesn't sleep, you do, but you are still THE LAW!"
icon_state = "sheethos"
item_color = "hosred"
dream_messages = list("authority", "a silvery ID", "handcuffs", "a baton", "a flashbang", "sunglasses", "the head of security")
/obj/item/bedsheet/hop
name = "head of personnel's bedsheet"
desc = "It is decorated with a key emblem. For those rare moments when you can rest and cuddle with Ian without someone screaming for you over the radio."
icon_state = "sheethop"
item_color = "hop"
dream_messages = list("authority", "a silvery ID", "obligation", "a computer", "an ID", "a corgi", "the head of personnel")
/obj/item/bedsheet/ce
name = "chief engineer's bedsheet"
desc = "It is decorated with a wrench emblem. It's highly reflective and stain resistant, so you don't need to worry about ruining it with oil."
icon_state = "sheetce"
item_color = "chief"
dream_messages = list("authority", "a silvery ID", "the engine", "power tools", "an APC", "a parrot", "the chief engineer")
/obj/item/bedsheet/qm
name = "quartermaster's bedsheet"
desc = "It is decorated with a crate emblem in silver lining. It's rather tough, and just the thing to lie on after a hard day of pushing paper."
icon_state = "sheetqm"
item_color = "qm"
dream_messages = list("a grey ID", "a shuttle", "a crate", "a sloth", "the quartermaster")
/obj/item/bedsheet/brown
icon_state = "sheetbrown"
item_color = "cargo"
dream_messages = list("brown")
/obj/item/bedsheet/black
icon_state = "sheetblack"
item_color = "black"
dream_messages = list("black")
/obj/item/bedsheet/centcom
name = "\improper CentCom bedsheet"
desc = "Woven with advanced nanothread for warmth as well as being very decorated, essential for all officials."
icon_state = "sheetcentcom"
item_color = "centcom"
dream_messages = list("a unique ID", "authority", "artillery", "an ending")
/obj/item/bedsheet/syndie
name = "syndicate bedsheet"
desc = "It has a syndicate emblem and it has an aura of evil."
icon_state = "sheetsyndie"
item_color = "syndie"
dream_messages = list("a green disc", "a red crystal", "a glowing blade", "a wire-covered ID")
/obj/item/bedsheet/cult
name = "cultist's bedsheet"
desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence."
icon_state = "sheetcult"
item_color = "cult"
dream_messages = list("a tome", "a floating red crystal", "a glowing sword", "a bloody symbol", "a massive humanoid figure")
/obj/item/bedsheet/wiz
name = "wizard's bedsheet"
desc = "A special fabric enchanted with magic so you can have an enchanted night. It even glows!"
icon_state = "sheetwiz"
item_color = "wiz"
dream_messages = list("a book", "an explosion", "lightning", "a staff", "a skeleton", "a robe", "magic")
/obj/item/bedsheet/nanotrasen
name = "nanotrasen bedsheet"
desc = "It has the Nanotrasen logo on it and has an aura of duty."
icon_state = "sheetNT"
item_color = "nanotrasen"
dream_messages = list("authority", "an ending")
/obj/item/bedsheet/ian
icon_state = "sheetian"
item_color = "ian"
dream_messages = list("a dog", "a corgi", "woof", "bark", "arf")
/obj/item/bedsheet/runtime
icon_state = "sheetruntime"
item_color = "runtime"
dream_messages = list("a kitty", "a cat", "meow", "purr", "nya~")
/obj/item/bedsheet/pirate
name = "pirate's bedsheet"
desc = "It has a Jolly Roger emblem on it and has a faint scent of grog."
icon_state = "sheetpirate"
item_color = "black"
dream_messages = list("doing whatever oneself wants", "cause a pirate is free", "being a pirate", "stealing", "landlubbers", "gold", "a buried treasure", "yarr", "avast", "a swashbuckler", "sailing the Seven Seas", "a parrot", "a monkey", "an island", "a talking skull")
/obj/item/bedsheet/gondola
name = "gondola bedsheet"
desc = "A precious bedsheet made from the hide of a rare and peculiar critter."
icon_state = "sheetgondola"
item_color = "cargo"
var/g_mouth
var/g_eyes
@@ -252,7 +222,7 @@ LINEN BINS
add_overlay(g_mouth)
add_overlay(g_eyes)
/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
/obj/item/bedsheet/gondola/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
. = ..()
if(!isinhands)
. += mutable_appearance(icon_file, g_mouth)
@@ -262,14 +232,12 @@ LINEN BINS
name = "cosmic space bedsheet"
desc = "Made from the dreams of those who wonder at the stars."
icon_state = "sheetcosmos"
item_color = "cosmos"
dream_messages = list("the infinite cosmos", "Hans Zimmer music", "a flight through space", "the galaxy", "being fabulous", "shooting stars")
light_power = 2
light_range = 1.4
/obj/item/bedsheet/random
icon_state = "random_bedsheet"
item_color = "rainbow"
name = "random bedsheet"
desc = "If you're reading this description ingame, something has gone wrong! Honk!"
@@ -100,3 +100,12 @@
if(isliving(A))
to_chat(A, "<span class='userdanger'>You're suddenly forced into a tiny, compressed space!</span>")
qdel(src)
/obj/structure/closet/body_bag/containment
name = "containment body bag"
desc = "A folded heavy body bag designed for the storage and transportation of cadavers with heavy radiation."
icon = 'icons/obj/bodybag.dmi'
icon_state = "radbodybag"
mob_storage_capacity = 1
foldedbag_path = /obj/item/bodybag/containment
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
@@ -26,7 +26,7 @@
if (prob(40))
new /obj/item/storage/toolbox/emergency(src)
switch (pickweight(list("small" = 40, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 5)))
switch (pickweight(list("small" = 35, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 5, "rng" = 5)))
if ("small")
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/tank/internals/emergency_oxygen(src)
@@ -49,6 +49,12 @@
if ("nothing")
// doot
if ("rng")
new /obj/effect/spawner/lootdrop/breathing_tanks/no_turf(src)
new /obj/effect/spawner/lootdrop/breathing_tanks/no_turf(src)
new /obj/effect/spawner/lootdrop/breathing_masks/no_turf(src)
new /obj/effect/spawner/lootdrop/breathing_masks/no_turf(src)
return
/*
@@ -100,13 +106,15 @@
if(prob(70))
new /obj/item/wrench(src)
if(prob(70))
new /obj/item/weldingtool(src)
new /obj/effect/spawner/lootdrop/welder_tools/no_turf(src)
if(prob(70))
new /obj/item/crowbar(src)
if(prob(70))
new /obj/item/wirecutters(src)
if(prob(70))
new /obj/item/t_scanner(src)
if(prob(70))
new /obj/effect/spawner/lootdrop/low_tools/no_turf(src) //Spare random basic tool
if(prob(20))
new /obj/item/storage/belt/utility(src)
if(prob(30))
@@ -179,6 +179,7 @@
desc = "A crate with a radiation sign on it."
name = "radiation crate"
icon_state = "radiation"
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/structure/closet/crate/hydroponics
name = "hydroponics crate"

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