Merge branch 'master' into shield_bashing
This commit is contained in:
@@ -179,7 +179,7 @@
|
||||
// #define SPEECH_FORCED 7
|
||||
#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
|
||||
|
||||
#define COMSIG_MOB_SPELL_CAST_CHECK "mob_spell_cast_check" //called from base of /obj/effect/proc_holder/spell/cast_check(): (spell)
|
||||
#define COMSIG_MOB_SPELL_CAN_CAST "mob_spell_can_cast" //called from base of /obj/effect/proc_holder/spell/can_cast(): (spell)
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
|
||||
@@ -190,6 +190,7 @@
|
||||
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
|
||||
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGOUT "comsig_mob_client_logout" //sent when a mob/logout() starts: (client)
|
||||
#define COMSIG_MOB_CLIENT_MOVE "comsig_mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc)
|
||||
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
|
||||
// This returns flags as defined for block in __DEFINES/combat.dm!
|
||||
@@ -242,12 +243,14 @@
|
||||
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
|
||||
#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
|
||||
#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed" //called on item when crossed by something (): (/atom/movable)
|
||||
#define COMSIG_ITEM_WORN_OVERLAYS "item_worn_overlays" //from base of obj/item/worn_overlays(): (isinhands, icon_file, used_state, style_flags, list/overlays)
|
||||
// THE FOLLOWING TWO BLOCKS SHOULD RETURN BLOCK FLAGS AS DEFINED IN __DEFINES/combat.dm!
|
||||
#define COMSIG_ITEM_CHECK_BLOCK "check_block" //from base of obj/item/check_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
#define COMSIG_ITEM_RUN_BLOCK "run_block" //from base of obj/item/run_block(): (mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
|
||||
// /obj/item/clothing signals
|
||||
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
|
||||
#define COMSIG_SUIT_MADE_HELMET "suit_made_helmet" //from base of obj/item/clothing/suit/MakeHelmet(): (helmet)
|
||||
|
||||
// /obj/item/implant signals
|
||||
#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#define DYE_REGISTRY_UNDER "under"
|
||||
#define DYE_REGISTRY_JUMPSKIRT "jumpskirt"
|
||||
#define DYE_REGISTRY_GLOVES "gloves"
|
||||
#define DYE_REGISTRY_SNEAKERS "sneakers"
|
||||
#define DYE_REGISTRY_FANNYPACK "fannypack"
|
||||
#define DYE_REGISTRY_BEDSHEET "bedsheet"
|
||||
|
||||
#define DYE_RED "red"
|
||||
#define DYE_ORANGE "orange"
|
||||
#define DYE_YELLOW "yellow"
|
||||
#define DYE_GREEN "green"
|
||||
#define DYE_BLUE "blue"
|
||||
#define DYE_PURPLE "purple"
|
||||
#define DYE_BLACK "black"
|
||||
#define DYE_WHITE "white"
|
||||
#define DYE_RAINBOW "rainbow"
|
||||
#define DYE_MIME "mime"
|
||||
#define DYE_COSMIC "cosmic"
|
||||
#define DYE_QM "qm"
|
||||
#define DYE_LAW "law"
|
||||
#define DYE_CAPTAIN "captain"
|
||||
#define DYE_HOP "hop"
|
||||
#define DYE_HOS "hos"
|
||||
#define DYE_CE "ce"
|
||||
#define DYE_RD "rd"
|
||||
#define DYE_CMO "cmo"
|
||||
#define DYE_REDCOAT "redcoat"
|
||||
#define DYE_CLOWN "clown"
|
||||
@@ -1,13 +1,5 @@
|
||||
/*ALL DEFINES RELATED TO INVENTORY OBJECTS, MANAGEMENT, ETC, GO HERE*/
|
||||
|
||||
//ITEM INVENTORY WEIGHT, FOR w_class
|
||||
#define WEIGHT_CLASS_TINY 1 //Usually items smaller then a human hand, ex: Playing Cards, Lighter, Scalpel, Coins/Money
|
||||
#define WEIGHT_CLASS_SMALL 2 //Pockets can hold small and tiny items, ex: Flashlight, Multitool, Grenades, GPS Device
|
||||
#define WEIGHT_CLASS_NORMAL 3 //Standard backpacks can carry tiny, small & normal items, ex: Fire extinguisher, Stunbaton, Gas Mask, Metal Sheets
|
||||
#define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in a normal bag, ex: Defibrillator, Backpack, Space Suits
|
||||
#define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons - Can not fit in Boh
|
||||
#define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe - Can not fit in Boh
|
||||
|
||||
//Inventory depth: limits how many nested storage items you can access directly.
|
||||
//1: stuff in mob, 2: stuff in backpack, 3: stuff in box in backpack, etc
|
||||
#define INVENTORY_DEPTH 3
|
||||
@@ -155,7 +147,7 @@
|
||||
|
||||
//flags for covering body parts
|
||||
#define GLASSESCOVERSEYES (1<<0)
|
||||
#define MASKCOVERSEYES (1<<1) // get rid of some of the other retardation in these flags
|
||||
#define MASKCOVERSEYES (1<<1) // get rid of some of the other stupidity in these flags
|
||||
#define HEADCOVERSEYES (1<<2) // feel free to realloc these numbers for other purposes
|
||||
#define MASKCOVERSMOUTH (1<<3) // on other items, these are just for mask/head
|
||||
#define HEADCOVERSMOUTH (1<<4)
|
||||
|
||||
@@ -67,6 +67,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
|
||||
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid) )
|
||||
#define isdwarf(A) (is_species(A, /datum/species/dwarf))
|
||||
#define isdullahan(A) (is_species(A, /datum/species/dullahan))
|
||||
#define isvampire(A) (is_species(A,/datum/species/vampire))
|
||||
|
||||
// Citadel specific species
|
||||
#define isipcperson(A) (is_species(A, /datum/species/ipc))
|
||||
@@ -263,4 +264,4 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
|
||||
|
||||
#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob))
|
||||
|
||||
#define isshuttleturf(T) (length(T.baseturfs) && (/turf/baseturf_skipover/shuttle in T.baseturfs))
|
||||
#define isshuttleturf(T) (length(T.baseturfs) && (/turf/baseturf_skipover/shuttle in T.baseturfs))
|
||||
|
||||
@@ -129,11 +129,20 @@
|
||||
#define HUD_PLANE 21
|
||||
#define HUD_LAYER 21
|
||||
#define HUD_RENDER_TARGET "HUD_PLANE"
|
||||
#define ABOVE_HUD_PLANE 22
|
||||
#define ABOVE_HUD_LAYER 22
|
||||
|
||||
#define VOLUMETRIC_STORAGE_BOX_PLANE 23
|
||||
#define VOLUMETRIC_STORAGE_BOX_LAYER 23
|
||||
#define VOLUMETRIC_STORAGE_BOX_RENDER_TARGET "VOLUME_STORAGE_BOX_PLANE"
|
||||
|
||||
#define VOLUMETRIC_STORAGE_ITEM_PLANE 24
|
||||
#define VOLUMETRIC_STORAGE_ITEM_LAYER 24
|
||||
#define VOLUMETRIC_STORAGE_ITEM_RENDER_TARGET "VOLUME_STORAGE_ITEM_PLANE"
|
||||
|
||||
#define ABOVE_HUD_PLANE 25
|
||||
#define ABOVE_HUD_LAYER 25
|
||||
#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE"
|
||||
|
||||
#define SPLASHSCREEN_LAYER 23
|
||||
#define SPLASHSCREEN_PLANE 23
|
||||
#define SPLASHSCREEN_LAYER 30
|
||||
#define SPLASHSCREEN_PLANE 30
|
||||
#define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE"
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
|
||||
#define MOVESPEED_ID_SPECIES "SPECIES_SPEED_MOD"
|
||||
|
||||
#define MOVESPEED_ID_SMALL_STRIDE "SMALL_STRIDE"
|
||||
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
|
||||
@@ -78,4 +79,6 @@
|
||||
#define MOVESPEED_ID_COLD "COLD"
|
||||
#define MOVESPEED_ID_HUNGRY "HUNGRY"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
|
||||
|
||||
#define MOVESPEED_ID_CIRRHOSIS "CIRRHOSIS"
|
||||
@@ -45,9 +45,9 @@ Ask ninjanomnom if they're around
|
||||
// WARNING: The deines below could have disastrous consequences if tweaked incorrectly. See: The great SM purge of Oct.6.2017
|
||||
// contamination_chance = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_CHANCE_COEFFICIENT * min(1/(steps*RAD_DISTANCE_COEFFICIENT), 1))
|
||||
// contamination_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
|
||||
#define RAD_MINIMUM_CONTAMINATION 350 // How strong does a radiation wave have to be to contaminate objects
|
||||
#define RAD_MINIMUM_CONTAMINATION 300 // How strong does a radiation wave have to be to contaminate objects
|
||||
#define RAD_CONTAMINATION_CHANCE_COEFFICIENT 0.005 // Higher means higher strength scaling contamination chance
|
||||
#define RAD_CONTAMINATION_STR_COEFFICIENT 0.3 // Higher means higher strength scaling contamination strength
|
||||
#define RAD_CONTAMINATION_STR_COEFFICIENT 0.99 // Higher means higher strength scaling contamination strength
|
||||
#define RAD_DISTANCE_COEFFICIENT 1 // Lower means further rad spread
|
||||
|
||||
#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
|
||||
#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// storage_flags variable on /datum/component/storage
|
||||
|
||||
// Storage limits. These can be combined (and usually are combined).
|
||||
/// Check max_items and contents.len when trying to insert
|
||||
#define STORAGE_LIMIT_MAX_ITEMS (1<<0)
|
||||
/// Check max_combined_w_class.
|
||||
#define STORAGE_LIMIT_COMBINED_W_CLASS (1<<1)
|
||||
/// Use the new volume system. Will automatically force rendering to use the new volume/baystation scaling UI so this is kind of incompatible with stuff like stack storage etc etc.
|
||||
#define STORAGE_LIMIT_VOLUME (1<<2)
|
||||
/// Use max_w_class
|
||||
#define STORAGE_LIMIT_MAX_W_CLASS (1<<3)
|
||||
|
||||
#define STORAGE_FLAGS_LEGACY_DEFAULT (STORAGE_LIMIT_MAX_ITEMS | STORAGE_LIMIT_COMBINED_W_CLASS | STORAGE_LIMIT_MAX_W_CLASS)
|
||||
#define STORAGE_FLAGS_VOLUME_DEFAULT (STORAGE_LIMIT_MAX_ITEMS | STORAGE_LIMIT_VOLUME | STORAGE_LIMIT_MAX_W_CLASS)
|
||||
|
||||
//ITEM INVENTORY WEIGHT, FOR w_class
|
||||
/// Usually items smaller then a human hand, ex: Playing Cards, Lighter, Scalpel, Coins/Money
|
||||
#define WEIGHT_CLASS_TINY 1
|
||||
/// Pockets can hold small and tiny items, ex: Flashlight, Multitool, Grenades, GPS Device
|
||||
#define WEIGHT_CLASS_SMALL 2
|
||||
/// Standard backpacks can carry tiny, small & normal items, ex: Fire extinguisher, Stunbaton, Gas Mask, Metal Sheets
|
||||
#define WEIGHT_CLASS_NORMAL 3
|
||||
/// Items that can be weilded or equipped but not stored in a normal bag, ex: Defibrillator, Backpack, Space Suits
|
||||
#define WEIGHT_CLASS_BULKY 4
|
||||
/// Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons - Can not fit in Boh
|
||||
#define WEIGHT_CLASS_HUGE 5
|
||||
/// Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe - Can not fit in Boh
|
||||
#define WEIGHT_CLASS_GIGANTIC 6
|
||||
|
||||
/// Macro for automatically getting the volume of an item from its w_class.
|
||||
#define AUTO_SCALE_VOLUME(w_class) (2 ** w_class)
|
||||
/// Macro for automatically getting the volume of a storage item from its max_w_class and max_combined_w_class.
|
||||
#define AUTO_SCALE_STORAGE_VOLUME(w_class, max_combined_w_class) (AUTO_SCALE_VOLUME(w_class) * (max_combined_w_class / w_class))
|
||||
|
||||
// UI defines
|
||||
/// Size of volumetric box icon
|
||||
#define VOLUMETRIC_STORAGE_BOX_ICON_SIZE 32
|
||||
/// Size of EACH left/right border icon for volumetric boxes
|
||||
#define VOLUMETRIC_STORAGE_BOX_BORDER_SIZE 1
|
||||
/// Minimum pixels an item must have in volumetric scaled storage UI
|
||||
#define MINIMUM_PIXELS_PER_ITEM 6
|
||||
/// Maximum number of objects that will be allowed to be displayed using the volumetric display system. Arbitrary number to prevent server lockups.
|
||||
#define MAXIMUM_VOLUMETRIC_ITEMS 256
|
||||
/// How much padding to give between items
|
||||
#define VOLUMETRIC_STORAGE_ITEM_PADDING 1
|
||||
/// How much padding to give to edges
|
||||
#define VOLUMETRIC_STORAGE_EDGE_PADDING 1
|
||||
@@ -550,6 +550,27 @@
|
||||
for(var/thing in flat_list)
|
||||
.[thing] = TRUE
|
||||
|
||||
/proc/deep_list2params(list/deep_list)
|
||||
var/list/L = list()
|
||||
for(var/i in deep_list)
|
||||
var/key = i
|
||||
if(isnum(key))
|
||||
L += "[key]"
|
||||
continue
|
||||
if(islist(key))
|
||||
key = deep_list2params(key)
|
||||
else if(!istext(key))
|
||||
key = "[REF(key)]"
|
||||
L += "[key]"
|
||||
var/value = deep_list[key]
|
||||
if(!isnull(value))
|
||||
if(islist(value))
|
||||
value = deep_list2params(value)
|
||||
else if(!(istext(key) || isnum(key)))
|
||||
value = "[REF(value)]"
|
||||
L["[key]"] = "[value]"
|
||||
return list2params(L)
|
||||
|
||||
//Picks from the list, with some safeties, and returns the "default" arg if it fails
|
||||
#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
return
|
||||
|
||||
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy.
|
||||
// Better recursive loop, technically sort of not actually recursive cause that shit is stupid, enjoy.
|
||||
//No need for a recursive limit either
|
||||
/proc/recursive_mob_check(atom/O,client_check=1,sight_check=1,include_radio=1)
|
||||
|
||||
|
||||
@@ -89,6 +89,14 @@
|
||||
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/init_ref_coin_values) //so the current procedure doesn't sleep because of UNTIL()
|
||||
|
||||
for(var/path in subtypesof(/area/holodeck))
|
||||
var/area/holodeck/A = path
|
||||
var/list/compatibles = initial(A.compatible_holodeck_comps)
|
||||
if(!compatibles || initial(A.abstract_type) == path)
|
||||
continue
|
||||
for(var/comp in compatibles)
|
||||
LAZYADD(GLOB.holodeck_areas_prototypes[comp], A)
|
||||
|
||||
//creates every subtype of prototype (excluding prototype) and adds it to list L.
|
||||
//if no list/L is provided, one is created.
|
||||
/proc/init_subtypes(prototype, list/L)
|
||||
|
||||
@@ -209,7 +209,8 @@
|
||||
"ipc_antenna" = "None",
|
||||
"flavor_text" = "",
|
||||
"meat_type" = "Mammalian",
|
||||
"body_model" = MALE
|
||||
"body_model" = MALE,
|
||||
"body_size" = RESIZE_DEFAULT_SIZE
|
||||
))
|
||||
|
||||
/proc/random_hair_style(gender)
|
||||
|
||||
@@ -27,12 +27,20 @@
|
||||
return
|
||||
var/area/A = get_area(source)
|
||||
var/atom/nested_loc = source.loc
|
||||
var/spawn_waves = TRUE
|
||||
while(nested_loc != A)
|
||||
if(nested_loc.rad_flags & RAD_PROTECT_CONTENTS)
|
||||
return
|
||||
spawn_waves = FALSE
|
||||
break
|
||||
nested_loc = nested_loc.loc
|
||||
for(var/dir in GLOB.cardinals)
|
||||
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate)
|
||||
if(spawn_waves)
|
||||
for(var/dir in GLOB.cardinals)
|
||||
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate)
|
||||
|
||||
var/static/last_huge_pulse = 0
|
||||
if(intensity > 3000 && world.time > last_huge_pulse + 200)
|
||||
last_huge_pulse = world.time
|
||||
log = TRUE
|
||||
|
||||
var/list/things = get_rad_contents(source) //copypasta because I don't want to put special code in waves to handle their origin
|
||||
for(var/k in 1 to things.len)
|
||||
@@ -41,11 +49,7 @@
|
||||
continue
|
||||
thing.rad_act(intensity)
|
||||
|
||||
var/static/last_huge_pulse = 0
|
||||
if(intensity > 3000 && world.time > last_huge_pulse + 200)
|
||||
last_huge_pulse = world.time
|
||||
log = TRUE
|
||||
if(log)
|
||||
var/turf/_source_T = isturf(source) ? source : get_turf(source)
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ")
|
||||
var/turf/_source_T = get_turf(source)
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)][spawn_waves ? "" : " (contained by [nested_loc.name])"]")
|
||||
return TRUE
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
if(owner && GLOB.common_report && SSticker.current_state == GAME_STATE_FINISHED)
|
||||
SSticker.show_roundend_report(owner.client, FALSE)
|
||||
|
||||
/datum/action/report/IsAvailable()
|
||||
/datum/action/report/IsAvailable(silent = FALSE)
|
||||
return 1
|
||||
|
||||
/datum/action/report/Topic(href,href_list)
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
/proc/invertHTML(HTMLstring)
|
||||
if(!istext(HTMLstring))
|
||||
CRASH("Given non-text argument!")
|
||||
return
|
||||
else if(length(HTMLstring) != 7)
|
||||
CRASH("Given non-HTML argument!")
|
||||
return
|
||||
else if(length_char(HTMLstring) != 7)
|
||||
CRASH("Given non-hex symbols in argument!")
|
||||
var/textr = copytext(HTMLstring, 2, 4)
|
||||
@@ -1565,3 +1563,16 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
if(channels_to_use.len)
|
||||
world.TgsChatBroadcast()
|
||||
|
||||
//Checks to see if either the victim has a garlic necklace or garlic in their blood
|
||||
/proc/blood_sucking_checks(var/mob/living/carbon/target, check_neck, check_blood)
|
||||
//Bypass this if the target isnt carbon.
|
||||
if(!iscarbon(target))
|
||||
return TRUE
|
||||
if(check_neck)
|
||||
if(istype(target.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/garlic_necklace))
|
||||
return FALSE
|
||||
if(check_blood)
|
||||
if(target.reagents.has_reagent(/datum/reagent/consumable/garlic))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -251,13 +251,19 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST
|
||||
),
|
||||
"shield_flags" = list(
|
||||
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
|
||||
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
|
||||
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
|
||||
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
|
||||
"SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM,
|
||||
"SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM,
|
||||
"SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM,
|
||||
"SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM
|
||||
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
|
||||
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
|
||||
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
|
||||
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
|
||||
"SHIELD_BASH_WALL_DISARM" = SHIELD_BASH_WALL_DISARM,
|
||||
"SHIELD_BASH_ALWAYS_DISARM" = SHIELD_BASH_ALWAYS_DISARM,
|
||||
"SHIELD_BASH_GROUND_SLAM" = SHIELD_BASH_GROUND_SLAM,
|
||||
"SHIELD_BASH_GROUND_SLAM_DISARM" = SHIELD_BASH_GROUND_SLAM_DISARM
|
||||
),
|
||||
"storage_flags" = list(
|
||||
"STORAGE_LIMIT_MAX_ITEMS" = STORAGE_LIMIT_MAX_ITEMS,
|
||||
"STORAGE_LIMIT_MAX_W_CLASS" = STORAGE_LIMIT_MAX_W_CLASS,
|
||||
"STORAGE_LIMIT_COMBINED_W_CLASS" = STORAGE_LIMIT_COMBINED_W_CLASS,
|
||||
"STORAGE_LIMIT_VOLUME" = STORAGE_LIMIT_VOLUME
|
||||
)
|
||||
))
|
||||
|
||||
@@ -50,3 +50,5 @@ GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
|
||||
GLOBAL_LIST_EMPTY(all_abstract_markers)
|
||||
|
||||
GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms
|
||||
|
||||
GLOBAL_LIST_EMPTY(holodeck_areas_prototypes) //List of holodeck area prototypes per holodeck computer type
|
||||
@@ -334,7 +334,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
return
|
||||
|
||||
var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
|
||||
if(!antag)
|
||||
if(!antag?.cult_team)
|
||||
return
|
||||
var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
blood_display.hud = src
|
||||
infodisplay += blood_display
|
||||
|
||||
vamprank_display = new /obj/screen/bloodsucker/rank_counter // Vampire Rank
|
||||
vamprank_display = new /obj/screen/bloodsucker/rank_counter // Bloodsucker Rank
|
||||
vamprank_display.hud = src
|
||||
infodisplay += vamprank_display
|
||||
|
||||
|
||||
@@ -210,20 +210,6 @@
|
||||
user.swap_hand(held_index)
|
||||
return TRUE
|
||||
|
||||
/obj/screen/close
|
||||
name = "close"
|
||||
layer = ABOVE_HUD_LAYER
|
||||
plane = ABOVE_HUD_PLANE
|
||||
icon_state = "backpack_close"
|
||||
|
||||
/obj/screen/close/Initialize(mapload, new_master)
|
||||
. = ..()
|
||||
master = new_master
|
||||
|
||||
/obj/screen/close/Click()
|
||||
var/datum/component/storage/S = master
|
||||
S.hide_from(usr)
|
||||
return TRUE
|
||||
|
||||
/obj/screen/drop
|
||||
name = "drop"
|
||||
@@ -406,30 +392,6 @@
|
||||
else
|
||||
icon_state = "act_rest0"
|
||||
|
||||
/obj/screen/storage
|
||||
name = "storage"
|
||||
icon_state = "block"
|
||||
screen_loc = "7,7 to 10,8"
|
||||
layer = HUD_LAYER
|
||||
plane = HUD_PLANE
|
||||
|
||||
/obj/screen/storage/Initialize(mapload, new_master)
|
||||
. = ..()
|
||||
master = new_master
|
||||
|
||||
/obj/screen/storage/Click(location, control, params)
|
||||
if(world.time <= usr.next_move)
|
||||
return TRUE
|
||||
if(usr.incapacitated())
|
||||
return TRUE
|
||||
if (ismecha(usr.loc)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_held_item()
|
||||
if(I)
|
||||
master.attackby(null, I, usr, params)
|
||||
return TRUE
|
||||
|
||||
/obj/screen/throw_catch
|
||||
name = "throw/catch"
|
||||
icon = 'icons/mob/screen_midnight.dmi'
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/obj/screen/storage
|
||||
name = "storage"
|
||||
var/insertion_click = FALSE
|
||||
|
||||
/obj/screen/storage/Initialize(mapload, new_master)
|
||||
. = ..()
|
||||
master = new_master
|
||||
|
||||
/obj/screen/storage/Click(location, control, params)
|
||||
if(!insertion_click)
|
||||
return ..()
|
||||
if(world.time <= usr.next_move)
|
||||
return TRUE
|
||||
if(usr.incapacitated())
|
||||
return TRUE
|
||||
if (ismecha(usr.loc)) // stops inventory actions in a mech
|
||||
return TRUE
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_held_item()
|
||||
if(I)
|
||||
master.attackby(null, I, usr, params)
|
||||
return TRUE
|
||||
|
||||
/obj/screen/storage/boxes
|
||||
name = "storage"
|
||||
icon_state = "block"
|
||||
screen_loc = "7,7 to 10,8"
|
||||
layer = HUD_LAYER
|
||||
plane = HUD_PLANE
|
||||
insertion_click = TRUE
|
||||
|
||||
/obj/screen/storage/close
|
||||
name = "close"
|
||||
layer = ABOVE_HUD_LAYER
|
||||
plane = ABOVE_HUD_PLANE
|
||||
icon_state = "backpack_close"
|
||||
|
||||
/obj/screen/storage/close/Click()
|
||||
var/datum/component/storage/S = master
|
||||
S.close(usr)
|
||||
return TRUE
|
||||
|
||||
/obj/screen/storage/left
|
||||
icon_state = "storage_start"
|
||||
insertion_click = TRUE
|
||||
|
||||
/obj/screen/storage/right
|
||||
icon_state = "storage_end"
|
||||
insertion_click = TRUE
|
||||
|
||||
/obj/screen/storage/continuous
|
||||
icon_state = "storage_continue"
|
||||
insertion_click = TRUE
|
||||
|
||||
/obj/screen/storage/volumetric_box
|
||||
icon_state = "stored_continue"
|
||||
var/obj/item/our_item
|
||||
|
||||
/obj/screen/storage/volumetric_box/Initialize(mapload, new_master, our_item)
|
||||
src.our_item = our_item
|
||||
return ..()
|
||||
|
||||
/obj/screen/storage/volumetric_box/Destroy()
|
||||
our_item = null
|
||||
return ..()
|
||||
|
||||
/obj/screen/storage/volumetric_box/Click(location, control, params)
|
||||
return our_item.Click(location, control, params)
|
||||
|
||||
/obj/screen/storage/volumetric_box/center
|
||||
icon_state = "stored_continue"
|
||||
var/obj/screen/storage/stored_left/left
|
||||
var/obj/screen/storage/stored_right/right
|
||||
var/pixel_size
|
||||
|
||||
/obj/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item)
|
||||
left = new(null, src, our_item)
|
||||
right = new(null, src, our_item)
|
||||
return ..()
|
||||
|
||||
/obj/screen/storage/volumetric_box/center/Destroy()
|
||||
QDEL_NULL(left)
|
||||
QDEL_NULL(right)
|
||||
return ..()
|
||||
|
||||
/obj/screen/storage/volumetric_box/center/proc/on_screen_objects()
|
||||
return list(src, left, right)
|
||||
|
||||
/**
|
||||
* Sets the size of this box screen object and regenerates its left/right borders. This includes the actual border's size!
|
||||
*/
|
||||
/obj/screen/storage/volumetric_box/center/proc/set_pixel_size(pixels)
|
||||
if(pixel_size == pixels)
|
||||
return
|
||||
pixel_size = pixels
|
||||
cut_overlays()
|
||||
//our icon size is 32 pixels.
|
||||
transform = matrix((pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE, 0, 0, 0, 1, 0)
|
||||
left.pixel_x = -((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) - VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
|
||||
right.pixel_x = ((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) + VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
|
||||
add_overlay(left)
|
||||
add_overlay(right)
|
||||
|
||||
/obj/screen/storage/stored_left
|
||||
icon_state = "stored_start"
|
||||
appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM // Yes I know RESET_TRANSFORM is in APPEARANCE_UI but we're hard-asserting this incase someone changes it.
|
||||
|
||||
/obj/screen/storage/stored_right
|
||||
icon_state = "stored_end"
|
||||
appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM
|
||||
@@ -131,7 +131,7 @@
|
||||
I.do_stagger_action(src, user)
|
||||
if(I.force)
|
||||
apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW))
|
||||
if(I.damtype == BRUTE)
|
||||
if(prob(33))
|
||||
I.add_mob_blood(src)
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
@@ -449,3 +449,27 @@
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_FLAG
|
||||
config_entry_value = list(GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER) //refer to cit_helpers for all toggles.
|
||||
|
||||
//Body size configs, the feature will be disabled if both min and max have the same value.
|
||||
/datum/config_entry/number/body_size_min
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE
|
||||
min_val = 0.1 //to avoid issues with zeros and negative values.
|
||||
max_val = RESIZE_DEFAULT_SIZE
|
||||
|
||||
/datum/config_entry/number/body_size_max
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE
|
||||
min_val = RESIZE_DEFAULT_SIZE
|
||||
|
||||
//Pun-Pun movement slowdown given to characters with a body size smaller than this value,
|
||||
//to compensate for their smaller hitbox.
|
||||
//To disable, just make sure the value is lower than 'body_size_min'
|
||||
/datum/config_entry/number/threshold_body_size_slowdown
|
||||
config_entry_value = RESIZE_DEFAULT_SIZE * 0.85
|
||||
min_val = 0
|
||||
max_val = RESIZE_DEFAULT_SIZE
|
||||
|
||||
//multiplicative slowdown multiplier. See 'dna.update_body_size' for the operation.
|
||||
//doesn't apply to floating or crawling mobs
|
||||
/datum/config_entry/number/body_size_slowdown_multiplier
|
||||
config_entry_value = 0.25
|
||||
min_val = 0.1 //To encourage folks to disable the slowdown through the above config instead.
|
||||
|
||||
@@ -27,13 +27,11 @@
|
||||
var/hook_path = text2path("/hook/[hook]")
|
||||
if(!hook_path)
|
||||
CRASH("Invalid hook '/hook/[hook]' called.")
|
||||
return 0
|
||||
|
||||
var/caller = new hook_path
|
||||
var/status = 1
|
||||
for(var/P in typesof("[hook_path]/proc"))
|
||||
if(!call(caller, P)(arglist(args)))
|
||||
CRASH("Hook '[P]' failed or runtimed.")
|
||||
status = 0
|
||||
|
||||
return status
|
||||
|
||||
@@ -38,11 +38,17 @@ PROCESSING_SUBSYSTEM_DEF(dcs)
|
||||
if(istext(key))
|
||||
value = arguments[key]
|
||||
if(!(istext(key) || isnum(key)))
|
||||
key = REF(key)
|
||||
if(islist(key)) // CITADEL EDIT
|
||||
key = deep_list2params(key)
|
||||
else
|
||||
key = REF(key)
|
||||
key = "[key]" // Key is stringified so numbers dont break things
|
||||
if(!isnull(value))
|
||||
if(!(istext(value) || isnum(value)))
|
||||
value = REF(value)
|
||||
if(islist(value)) // CITADEL EDIT
|
||||
value = deep_list2params(value)
|
||||
else
|
||||
value = REF(value)
|
||||
named_arguments["[key]"] = value
|
||||
else
|
||||
fullid += "[key]"
|
||||
|
||||
@@ -21,9 +21,6 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
|
||||
DropFirewallRule() // Clear the old bans if any still remain
|
||||
|
||||
if (world.system_type == UNIX && enabled)
|
||||
enabled = FALSE
|
||||
subsystem_log("DISABLED - UNIX systems are not supported.")
|
||||
if(!enabled)
|
||||
flags |= SS_NO_FIRE
|
||||
can_fire = FALSE
|
||||
@@ -90,7 +87,10 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
fail_counts -= ip
|
||||
rate_limiting -= ip
|
||||
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
if (world.system_type == UNIX)
|
||||
. = shell("iptables -A [rule_name] -s [ip] -j DROP")
|
||||
else
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
|
||||
if (.)
|
||||
subsystem_log("Failed to ban [ip]. Exit code: [.].")
|
||||
@@ -105,7 +105,10 @@ SUBSYSTEM_DEF(fail2topic)
|
||||
|
||||
active_bans = list()
|
||||
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[rule_name]\"")
|
||||
if (world.system_type == UNIX)
|
||||
. = shell("iptables -F [rule_name]") //Let's just assume that folks running linux are smart enough to have a dedicated chain configured for this.
|
||||
else
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[rule_name]\"")
|
||||
|
||||
if (.)
|
||||
subsystem_log("Failed to drop firewall rule. Exit code: [.].")
|
||||
|
||||
@@ -192,7 +192,8 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!json)
|
||||
return
|
||||
saved_storytellers = json["data"]
|
||||
average_dynamic_threat = saved_storytellers[4]
|
||||
if(saved_storytellers.len > 3)
|
||||
average_dynamic_threat = saved_storytellers[4]
|
||||
saved_storytellers.len = 3
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
|
||||
|
||||
@@ -86,7 +86,6 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
|
||||
circuit_fabricator_recipe_list["Tools"] = list(
|
||||
/obj/item/integrated_electronics/wirer,
|
||||
/obj/item/integrated_electronics/debugger,
|
||||
/obj/item/integrated_electronics/analyzer,
|
||||
/obj/item/integrated_electronics/detailer,
|
||||
/obj/item/card/data,
|
||||
/obj/item/card/data/full_color,
|
||||
|
||||
@@ -47,7 +47,6 @@ PROCESSING_SUBSYSTEM_DEF(weather)
|
||||
break
|
||||
if (!ispath(weather_datum_type, /datum/weather))
|
||||
CRASH("run_weather called with invalid weather_datum_type: [weather_datum_type || "null"]")
|
||||
return
|
||||
|
||||
if (isnull(z_levels))
|
||||
z_levels = SSmapping.levels_by_trait(initial(weather_datum_type.target_trait))
|
||||
@@ -55,7 +54,6 @@ PROCESSING_SUBSYSTEM_DEF(weather)
|
||||
z_levels = list(z_levels)
|
||||
else if (!islist(z_levels))
|
||||
CRASH("run_weather called with invalid z_levels: [z_levels || "null"]")
|
||||
return
|
||||
|
||||
var/datum/weather/W = new weather_datum_type(z_levels)
|
||||
W.telegraph()
|
||||
|
||||
@@ -763,7 +763,7 @@ SUBSYSTEM_DEF(vote)
|
||||
remove_from_client()
|
||||
Remove(owner)
|
||||
|
||||
/datum/action/vote/IsAvailable()
|
||||
/datum/action/vote/IsAvailable(silent = FALSE)
|
||||
return 1
|
||||
|
||||
/datum/action/vote/proc/remove_from_client()
|
||||
|
||||
+51
-52
@@ -6,13 +6,15 @@
|
||||
/datum/action
|
||||
var/name = "Generic Action"
|
||||
var/desc = null
|
||||
var/obj/target = null
|
||||
var/atom/target = null
|
||||
var/check_flags = 0
|
||||
var/required_mobility_flags = MOBILITY_USE
|
||||
var/processing = FALSE
|
||||
var/obj/screen/movable/action_button/button = null
|
||||
var/buttontooltipstyle = ""
|
||||
var/transparent_when_unavailable = TRUE
|
||||
var/use_target_appearance = FALSE
|
||||
var/list/target_appearance_matrix //if set, will be used to transform the target button appearance as an arglist.
|
||||
|
||||
var/button_icon = 'icons/mob/actions/backgrounds.dmi' //This is the file for the BACKGROUND icon
|
||||
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND //And this is the state for the background icon
|
||||
@@ -88,14 +90,14 @@
|
||||
/datum/action/proc/Trigger()
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER)
|
||||
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, target) & COMPONENT_ACTION_BLOCK_TRIGGER)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/proc/Process()
|
||||
return
|
||||
|
||||
/datum/action/proc/IsAvailable()
|
||||
/datum/action/proc/IsAvailable(silent = FALSE)
|
||||
if(!owner)
|
||||
return FALSE
|
||||
var/mob/living/L = owner
|
||||
@@ -116,29 +118,42 @@
|
||||
return TRUE
|
||||
|
||||
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
|
||||
if(button)
|
||||
if(!status_only)
|
||||
button.name = name
|
||||
button.desc = desc
|
||||
if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
|
||||
var/list/settings = owner.hud_used.get_action_buttons_icons()
|
||||
if(button.icon != settings["bg_icon"])
|
||||
button.icon = settings["bg_icon"]
|
||||
if(button.icon_state != settings["bg_state"])
|
||||
button.icon_state = settings["bg_state"]
|
||||
else
|
||||
if(button.icon != button_icon)
|
||||
button.icon = button_icon
|
||||
if(button.icon_state != background_icon_state)
|
||||
button.icon_state = background_icon_state
|
||||
if(!button)
|
||||
return
|
||||
if(!status_only)
|
||||
button.name = name
|
||||
button.desc = desc
|
||||
if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
|
||||
var/list/settings = owner.hud_used.get_action_buttons_icons()
|
||||
if(button.icon != settings["bg_icon"])
|
||||
button.icon = settings["bg_icon"]
|
||||
if(button.icon_state != settings["bg_state"])
|
||||
button.icon_state = settings["bg_state"]
|
||||
else
|
||||
if(button.icon != button_icon)
|
||||
button.icon = button_icon
|
||||
if(button.icon_state != background_icon_state)
|
||||
button.icon_state = background_icon_state
|
||||
|
||||
if(!use_target_appearance)
|
||||
ApplyIcon(button, force)
|
||||
|
||||
if(!IsAvailable())
|
||||
button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0)
|
||||
else
|
||||
button.color = rgb(255,255,255,255)
|
||||
return 1
|
||||
else if(target && button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid.
|
||||
var/mutable_appearance/M = new(target)
|
||||
M.layer = FLOAT_LAYER
|
||||
M.plane = FLOAT_PLANE
|
||||
if(target_appearance_matrix)
|
||||
var/list/L = target_appearance_matrix
|
||||
M.transform = matrix(L[1], L[2], L[3], L[4], L[5], L[6])
|
||||
button.cut_overlays()
|
||||
button.add_overlay(M)
|
||||
button.appearance_cache = target.appearance
|
||||
|
||||
if(!IsAvailable(TRUE))
|
||||
button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0)
|
||||
else
|
||||
button.color = rgb(255,255,255,255)
|
||||
return 1
|
||||
|
||||
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button, force = FALSE)
|
||||
if(icon_icon && button_icon_state && ((current_button.button_icon_state != button_icon_state) || force))
|
||||
@@ -165,6 +180,7 @@
|
||||
/datum/action/item_action
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
|
||||
button_icon_state = null
|
||||
use_target_appearance = TRUE
|
||||
// If you want to override the normal icon being the item
|
||||
// then change this to an icon state
|
||||
|
||||
@@ -188,23 +204,6 @@
|
||||
I.ui_action_click(owner, src)
|
||||
return 1
|
||||
|
||||
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button, force)
|
||||
if(button_icon && button_icon_state)
|
||||
// If set, use the custom icon that we set instead
|
||||
// of the item appearence
|
||||
..()
|
||||
else if(target && current_button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid.
|
||||
var/obj/item/I = target
|
||||
var/old_layer = I.layer
|
||||
var/old_plane = I.plane
|
||||
I.layer = FLOAT_LAYER //AAAH
|
||||
I.plane = FLOAT_PLANE //^ what that guy said
|
||||
current_button.cut_overlays()
|
||||
current_button.add_overlay(I)
|
||||
I.layer = old_layer
|
||||
I.plane = old_plane
|
||||
current_button.appearance_cache = I.appearance
|
||||
|
||||
/datum/action/item_action/toggle_light
|
||||
name = "Toggle Light"
|
||||
|
||||
@@ -308,7 +307,7 @@
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "vortex_recall"
|
||||
|
||||
/datum/action/item_action/vortex_recall/IsAvailable()
|
||||
/datum/action/item_action/vortex_recall/IsAvailable(silent = FALSE)
|
||||
if(istype(target, /obj/item/hierophant_club))
|
||||
var/obj/item/hierophant_club/H = target
|
||||
if(H.teleporting)
|
||||
@@ -320,7 +319,7 @@
|
||||
background_icon_state = "bg_clock"
|
||||
buttontooltipstyle = "clockcult"
|
||||
|
||||
/datum/action/item_action/clock/IsAvailable()
|
||||
/datum/action/item_action/clock/IsAvailable(silent = FALSE)
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -329,7 +328,7 @@
|
||||
name = "Create Judicial Marker"
|
||||
desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable."
|
||||
|
||||
/datum/action/item_action/clock/toggle_visor/IsAvailable()
|
||||
/datum/action/item_action/clock/toggle_visor/IsAvailable(silent = FALSE)
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
return 0
|
||||
if(istype(target, /obj/item/clothing/glasses/judicial_visor))
|
||||
@@ -408,7 +407,7 @@
|
||||
/datum/action/item_action/jetpack_stabilization
|
||||
name = "Toggle Jetpack Stabilization"
|
||||
|
||||
/datum/action/item_action/jetpack_stabilization/IsAvailable()
|
||||
/datum/action/item_action/jetpack_stabilization/IsAvailable(silent = FALSE)
|
||||
var/obj/item/tank/jetpack/J = target
|
||||
if(!istype(J) || !J.on)
|
||||
return 0
|
||||
@@ -465,7 +464,7 @@
|
||||
/datum/action/item_action/organ_action
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/item_action/organ_action/IsAvailable()
|
||||
/datum/action/item_action/organ_action/IsAvailable(silent = FALSE)
|
||||
var/obj/item/organ/I = target
|
||||
if(!I.owner)
|
||||
return 0
|
||||
@@ -634,32 +633,32 @@
|
||||
return FALSE
|
||||
if(target)
|
||||
var/obj/effect/proc_holder/S = target
|
||||
S.Click()
|
||||
S.Trigger(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/spell_action/IsAvailable()
|
||||
/datum/action/spell_action/IsAvailable(silent = FALSE)
|
||||
if(!target)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/spell_action/spell
|
||||
|
||||
/datum/action/spell_action/spell/IsAvailable()
|
||||
/datum/action/spell_action/spell/IsAvailable(silent = FALSE)
|
||||
if(!target)
|
||||
return FALSE
|
||||
var/obj/effect/proc_holder/spell/S = target
|
||||
if(owner)
|
||||
return S.can_cast(owner, FALSE, TRUE)
|
||||
return S.can_cast(owner, FALSE, silent)
|
||||
return FALSE
|
||||
|
||||
/datum/action/spell_action/alien
|
||||
|
||||
/datum/action/spell_action/alien/IsAvailable()
|
||||
/datum/action/spell_action/alien/IsAvailable(silent = FALSE)
|
||||
if(!target)
|
||||
return FALSE
|
||||
var/obj/effect/proc_holder/alien/ab = target
|
||||
if(owner)
|
||||
return ab.cost_check(ab.check_turf,owner,1)
|
||||
return ab.cost_check(ab.check_turf,owner,silent)
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -701,7 +700,7 @@
|
||||
button.maptext_width = 24
|
||||
button.maptext_height = 12
|
||||
|
||||
/datum/action/cooldown/IsAvailable()
|
||||
/datum/action/cooldown/IsAvailable(silent = FALSE)
|
||||
return next_use_time <= world.time
|
||||
|
||||
/datum/action/cooldown/proc/StartCooldown()
|
||||
|
||||
@@ -294,3 +294,12 @@
|
||||
/obj/item/bedsheet/cosmos = 1)
|
||||
time = 60
|
||||
category = CAT_CLOTHING
|
||||
|
||||
|
||||
/datum/crafting_recipe/garlic_necklace
|
||||
name = "Garlic Necklace"
|
||||
result = /obj/item/clothing/neck/garlic_necklace
|
||||
reqs = list(/obj/item/reagent_containers/food/snacks/grown/garlic = 15,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
time = 100 //Takes awhile to put all the garlics on the coil and knot it.
|
||||
category = CAT_CLOTHING
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//This component applies a customizable drop_shadow filter to its wearer when they toggle combat mode on or off. This can stack.
|
||||
|
||||
/datum/component/wearertargeting/phantomthief
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
signals = list(COMSIG_LIVING_COMBAT_ENABLED)
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
signals = list(COMSIG_LIVING_COMBAT_ENABLED, COMSIG_LIVING_COMBAT_DISABLED)
|
||||
proctype = .proc/handlefilterstuff
|
||||
var/filter_x
|
||||
var/filter_y
|
||||
@@ -19,8 +19,8 @@
|
||||
filter_color = _color
|
||||
valid_slots = _valid_slots
|
||||
|
||||
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(datum/source, mob/user, combatmodestate)
|
||||
if(!combatmodestate)
|
||||
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(mob/living/user, was_forced = FALSE)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
user.remove_filter("phantomthief")
|
||||
else
|
||||
user.add_filter("phantomthief", 4, list(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, color = filter_color))
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, .proc/rad_attack)
|
||||
else
|
||||
CRASH("Something that wasn't an atom was given /datum/component/radioactive")
|
||||
return
|
||||
|
||||
if(strength > RAD_MINIMUM_CONTAMINATION)
|
||||
SSradiation.warn(src)
|
||||
@@ -84,4 +83,4 @@
|
||||
#undef RAD_AMOUNT_LOW
|
||||
#undef RAD_AMOUNT_MEDIUM
|
||||
#undef RAD_AMOUNT_HIGH
|
||||
#undef RAD_AMOUNT_EXTREME
|
||||
#undef RAD_AMOUNT_EXTREME
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
_contents_limbo = null
|
||||
if(_user_limbo)
|
||||
for(var/i in _user_limbo)
|
||||
show_to(i)
|
||||
ui_show(i)
|
||||
_user_limbo = null
|
||||
|
||||
/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
return
|
||||
. = COMPONENT_NO_ATTACK_HAND
|
||||
if(!check_locked(source, user, TRUE))
|
||||
show_to(user)
|
||||
ui_show(user)
|
||||
A.do_jiggle()
|
||||
if(rustle_sound)
|
||||
playsound(A, "rustle", 50, 1, -5)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
allow_quick_gather = TRUE
|
||||
allow_quick_empty = TRUE
|
||||
click_gather = TRUE
|
||||
storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = 100
|
||||
max_items = 100
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//Stack-only storage.
|
||||
/datum/component/storage/concrete/stack
|
||||
display_numerical_stacking = TRUE
|
||||
storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
var/max_combined_stack_amount = 300
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = WEIGHT_CLASS_NORMAL * 14
|
||||
|
||||
@@ -21,9 +21,16 @@
|
||||
|
||||
var/locked = FALSE //when locked nothing can see inside or use it.
|
||||
|
||||
var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit.
|
||||
var/max_combined_w_class = 14 //max combined sizes of objects that will fit.
|
||||
var/max_items = 7 //max number of objects that will fit.
|
||||
/// Storage flags, including what kinds of limiters we use for how many items we can hold
|
||||
var/storage_flags = STORAGE_FLAGS_LEGACY_DEFAULT
|
||||
/// Max w_class we can hold. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS] and [STORAGE_LIMIT_VOLUME]
|
||||
var/max_w_class = WEIGHT_CLASS_SMALL
|
||||
/// Max combined w_class. Applies to [STORAGE_LIMIT_COMBINED_W_CLASS]
|
||||
var/max_combined_w_class = WEIGHT_CLASS_SMALL * 7
|
||||
/// Max items we can hold. Applies to [STORAGE_LIMIT_MAX_ITEMS]
|
||||
var/max_items = 7
|
||||
/// Max volume we can hold. Applies to [STORAGE_LIMIT_VOLUME]. Auto scaled on New() if unset.
|
||||
var/max_volume
|
||||
|
||||
var/emp_shielded = FALSE
|
||||
|
||||
@@ -39,8 +46,17 @@
|
||||
|
||||
var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
|
||||
|
||||
var/obj/screen/storage/boxes //storage display object
|
||||
var/obj/screen/close/closer //close button object
|
||||
/// "legacy"/default view mode's storage "boxes"
|
||||
var/obj/screen/storage/boxes/ui_boxes
|
||||
/// New volumetric storage display mode's left side
|
||||
var/obj/screen/storage/left/ui_left
|
||||
/// New volumetric storage display mode's center 'blocks'
|
||||
var/obj/screen/storage/continuous/ui_continuous
|
||||
/// The close button, used in all modes. Frames right side in volumetric mode.
|
||||
var/obj/screen/storage/close/ui_close
|
||||
/// Associative list of list(item = screen object) for volumetric storage item screen blocks
|
||||
var/list/ui_item_blocks
|
||||
|
||||
var/current_maxscreensize
|
||||
|
||||
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
|
||||
@@ -68,9 +84,6 @@
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(master)
|
||||
change_master(master)
|
||||
boxes = new(null, src)
|
||||
closer = new(null, src)
|
||||
orient2hud()
|
||||
|
||||
RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check)
|
||||
RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked)
|
||||
@@ -111,8 +124,15 @@
|
||||
|
||||
/datum/component/storage/Destroy()
|
||||
close_all()
|
||||
QDEL_NULL(boxes)
|
||||
QDEL_NULL(closer)
|
||||
QDEL_NULL(ui_boxes)
|
||||
QDEL_NULL(ui_close)
|
||||
QDEL_NULL(ui_continuous)
|
||||
QDEL_NULL(ui_left)
|
||||
// DO NOT USE QDEL_LIST_ASSOC.
|
||||
if(ui_item_blocks)
|
||||
for(var/i in ui_item_blocks)
|
||||
qdel(ui_item_blocks[i]) //qdel the screen object not the item
|
||||
ui_item_blocks.Cut()
|
||||
LAZYCLEARLIST(is_using)
|
||||
return ..()
|
||||
|
||||
@@ -286,7 +306,7 @@
|
||||
if(!_target)
|
||||
_target = get_turf(parent)
|
||||
if(usr)
|
||||
hide_from(usr)
|
||||
ui_hide(usr)
|
||||
var/list/contents = contents()
|
||||
var/atom/real_location = real_location()
|
||||
for(var/obj/item/I in contents)
|
||||
@@ -300,106 +320,8 @@
|
||||
if(check_locked())
|
||||
close_all()
|
||||
|
||||
/datum/component/storage/proc/_process_numerical_display()
|
||||
. = list()
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(QDELETED(I))
|
||||
continue
|
||||
if(!.[I.type])
|
||||
.[I.type] = new /datum/numbered_display(I, 1)
|
||||
else
|
||||
var/datum/numbered_display/ND = .[I.type]
|
||||
ND.number++
|
||||
. = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE)
|
||||
|
||||
//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing.
|
||||
/datum/component/storage/proc/orient2hud(mob/user, maxcolumns)
|
||||
var/list/accessible_contents = accessible_items()
|
||||
var/adjusted_contents = length(accessible_contents)
|
||||
|
||||
//Numbered contents display
|
||||
var/list/datum/numbered_display/numbered_contents
|
||||
if(display_numerical_stacking)
|
||||
numbered_contents = _process_numerical_display()
|
||||
adjusted_contents = numbered_contents.len
|
||||
|
||||
var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns)
|
||||
var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
|
||||
standard_orient_objs(rows, columns, numbered_contents)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. It uses the standard position.
|
||||
/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents)
|
||||
boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
var/cx = screen_start_x
|
||||
var/cy = screen_start_y
|
||||
if(islist(numerical_display_contents))
|
||||
for(var/type in numerical_display_contents)
|
||||
var/datum/numbered_display/ND = numerical_display_contents[type]
|
||||
ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
|
||||
ND.sample_object.layer = ABOVE_HUD_LAYER
|
||||
ND.sample_object.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx - screen_start_x >= cols)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
else
|
||||
for(var/obj/O in accessible_items())
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx - screen_start_x >= cols)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
|
||||
|
||||
/datum/component/storage/proc/show_to(mob/M, set_screen_size = TRUE)
|
||||
if(!M.client)
|
||||
return FALSE
|
||||
var/list/cview = getviewsize(M.client.view)
|
||||
var/maxallowedscreensize = cview[1]-8
|
||||
if(set_screen_size)
|
||||
current_maxscreensize = maxallowedscreensize
|
||||
else if(current_maxscreensize)
|
||||
maxallowedscreensize = current_maxscreensize
|
||||
if(M.active_storage != src && (M.stat == CONSCIOUS))
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(I.on_found(M))
|
||||
return FALSE
|
||||
if(M.active_storage)
|
||||
M.active_storage.hide_from(M)
|
||||
orient2hud(M, (isliving(M) ? maxallowedscreensize : 7))
|
||||
M.client.screen |= boxes
|
||||
M.client.screen |= closer
|
||||
M.client.screen |= accessible_items()
|
||||
M.active_storage = src
|
||||
LAZYOR(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/hide_from(mob/M)
|
||||
if(!M.client)
|
||||
return TRUE
|
||||
var/atom/real_location = real_location()
|
||||
M.client.screen -= boxes
|
||||
M.client.screen -= closer
|
||||
M.client.screen -= real_location.contents
|
||||
if(M.active_storage == src)
|
||||
M.active_storage = null
|
||||
LAZYREMOVE(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/close(mob/M)
|
||||
hide_from(M)
|
||||
ui_hide(M)
|
||||
|
||||
/datum/component/storage/proc/close_all()
|
||||
. = FALSE
|
||||
@@ -418,25 +340,6 @@
|
||||
var/datum/component/storage/concrete/master = master()
|
||||
master.emp_act(source, severity)
|
||||
|
||||
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
|
||||
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
|
||||
/datum/component/storage/proc/orient_objs(tx, ty, mx, my)
|
||||
var/atom/real_location = real_location()
|
||||
var/cx = tx
|
||||
var/cy = ty
|
||||
boxes.screen_loc = "[tx]:,[ty] to [mx],[my]"
|
||||
for(var/obj/O in real_location)
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.screen_loc = "[cx],[cy]"
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
cx++
|
||||
if(cx > mx)
|
||||
cx = tx
|
||||
cy--
|
||||
closer.screen_loc = "[mx+1],[my]"
|
||||
|
||||
//Resets something that is being removed from storage.
|
||||
/datum/component/storage/proc/_removal_reset(atom/movable/thing)
|
||||
if(!istype(thing))
|
||||
@@ -448,6 +351,9 @@
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
|
||||
_removal_reset(thing)
|
||||
if(LAZYACCESS(ui_item_blocks, thing))
|
||||
qdel(ui_item_blocks[thing])
|
||||
ui_item_blocks -= thing
|
||||
refresh_mob_views()
|
||||
|
||||
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
|
||||
@@ -462,7 +368,7 @@
|
||||
/datum/component/storage/proc/refresh_mob_views()
|
||||
var/list/seeing = can_see_contents()
|
||||
for(var/i in seeing)
|
||||
show_to(i)
|
||||
ui_show(i)
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/can_see_contents()
|
||||
@@ -559,7 +465,7 @@
|
||||
A.add_fingerprint(M)
|
||||
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
|
||||
return FALSE
|
||||
show_to(M, !ghost)
|
||||
ui_show(M, !ghost)
|
||||
|
||||
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
|
||||
if(isitem(O))
|
||||
@@ -587,10 +493,6 @@
|
||||
if(M && !stop_messages)
|
||||
host.add_fingerprint(M)
|
||||
return FALSE
|
||||
if(real_location.contents.len >= max_items)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] is full, make some space!</span>")
|
||||
return FALSE //Storage item is full
|
||||
if(length(can_hold))
|
||||
if(!is_type_in_typecache(I, can_hold))
|
||||
if(!stop_messages)
|
||||
@@ -600,17 +502,34 @@
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] cannot hold [I]!</span>")
|
||||
return FALSE
|
||||
if(I.w_class > max_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too big for [host]!</span>")
|
||||
return FALSE
|
||||
var/sum_w_class = I.w_class
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
|
||||
if(sum_w_class > max_combined_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] won't fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
// STORAGE LIMITS
|
||||
if(storage_flags & STORAGE_LIMIT_MAX_ITEMS)
|
||||
if(real_location.contents.len >= max_items)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[host] has too many things in it, make some space!</span>")
|
||||
return FALSE //Storage item is full
|
||||
if(storage_flags & STORAGE_LIMIT_MAX_W_CLASS)
|
||||
if(I.w_class > max_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too long for [host]!</span>")
|
||||
return FALSE
|
||||
if(storage_flags & STORAGE_LIMIT_COMBINED_W_CLASS)
|
||||
var/sum_w_class = I.w_class
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
|
||||
if(sum_w_class > max_combined_w_class)
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] won't fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
if(storage_flags & STORAGE_LIMIT_VOLUME)
|
||||
var/sum_volume = I.get_w_volume()
|
||||
for(var/obj/item/_I in real_location)
|
||||
sum_volume += _I.get_w_volume()
|
||||
if(sum_volume > get_max_volume())
|
||||
if(!stop_messages)
|
||||
to_chat(M, "<span class='warning'>[I] is too spacious to fit in [host], make some space!</span>")
|
||||
return FALSE
|
||||
/////////////////
|
||||
if(isitem(host))
|
||||
var/obj/item/IP = host
|
||||
var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage)
|
||||
@@ -742,7 +661,7 @@
|
||||
if(A.loc == user)
|
||||
. = COMPONENT_NO_ATTACK_HAND
|
||||
if(!check_locked(source, user, TRUE))
|
||||
show_to(user)
|
||||
ui_show(user)
|
||||
A.do_jiggle()
|
||||
|
||||
/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user)
|
||||
@@ -761,7 +680,7 @@
|
||||
return do_quick_empty(loctarget)
|
||||
|
||||
/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target)
|
||||
return hide_from(target)
|
||||
return ui_hide(target)
|
||||
|
||||
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
|
||||
if(!isliving(user) || !user.CanReach(parent))
|
||||
@@ -790,7 +709,7 @@
|
||||
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
/datum/component/storage/proc/action_trigger(datum/action/source, obj/target)
|
||||
gather_mode_switch(source.owner)
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
@@ -803,3 +722,9 @@
|
||||
to_chat(user, "[parent] now picks up all items in a tile at once.")
|
||||
if(COLLECT_ONE)
|
||||
to_chat(user, "[parent] now picks up one item at a time.")
|
||||
|
||||
/**
|
||||
* Gets our max volume
|
||||
*/
|
||||
/datum/component/storage/proc/get_max_volume()
|
||||
return max_volume || AUTO_SCALE_STORAGE_VOLUME(max_w_class, max_combined_w_class)
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* Generates a list of numbered_display datums for the numerical display system.
|
||||
*/
|
||||
/datum/component/storage/proc/_process_numerical_display()
|
||||
. = list()
|
||||
for(var/obj/item/I in accessible_items())
|
||||
if(QDELETED(I))
|
||||
continue
|
||||
if(!.[I.type])
|
||||
.[I.type] = new /datum/numbered_display(I, 1)
|
||||
else
|
||||
var/datum/numbered_display/ND = .[I.type]
|
||||
ND.number++
|
||||
. = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE)
|
||||
|
||||
/**
|
||||
* Orients all objects in legacy mode, and returns the objects to show to the user.
|
||||
*/
|
||||
/datum/component/storage/proc/orient2hud_legacy(mob/user, maxcolumns)
|
||||
. = list()
|
||||
var/list/accessible_contents = accessible_items()
|
||||
var/adjusted_contents = length(accessible_contents)
|
||||
|
||||
//Numbered contents display
|
||||
var/list/datum/numbered_display/numbered_contents
|
||||
if(display_numerical_stacking)
|
||||
numbered_contents = _process_numerical_display()
|
||||
adjusted_contents = numbered_contents.len
|
||||
|
||||
var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns)
|
||||
var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
|
||||
|
||||
// First, boxes.
|
||||
ui_boxes = get_ui_boxes()
|
||||
ui_boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_boxes
|
||||
// Then, closer.
|
||||
ui_close = get_ui_close()
|
||||
ui_close.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
|
||||
. += ui_close
|
||||
// Then orient the actual items.
|
||||
var/cx = screen_start_x
|
||||
var/cy = screen_start_y
|
||||
if(islist(numbered_contents))
|
||||
for(var/type in numbered_contents)
|
||||
var/datum/numbered_display/ND = numbered_contents[type]
|
||||
ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
ND.sample_object.maptext = "<font color='white'>[(ND.number > 1)? "[ND.number]" : ""]</font>"
|
||||
ND.sample_object.layer = ABOVE_HUD_LAYER
|
||||
ND.sample_object.plane = ABOVE_HUD_PLANE
|
||||
. += ND.sample_object
|
||||
cx++
|
||||
if(cx - screen_start_x >= columns)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
else
|
||||
for(var/obj/O in accessible_items())
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
|
||||
O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
|
||||
O.maptext = ""
|
||||
O.layer = ABOVE_HUD_LAYER
|
||||
O.plane = ABOVE_HUD_PLANE
|
||||
. += O
|
||||
cx++
|
||||
if(cx - screen_start_x >= columns)
|
||||
cx = screen_start_x
|
||||
cy++
|
||||
if(cy - screen_start_y >= rows)
|
||||
break
|
||||
|
||||
/**
|
||||
* Orients all objects in .. volumetric mode. Does not support numerical display!
|
||||
*/
|
||||
/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
|
||||
. = list()
|
||||
|
||||
// Generate ui_item_blocks for missing ones and render+orient.
|
||||
var/list/atom/contents = accessible_items()
|
||||
// our volume
|
||||
var/our_volume = get_max_volume()
|
||||
var/horizontal_pixels = (maxcolumns * world.icon_size) - (VOLUMETRIC_STORAGE_EDGE_PADDING * 2)
|
||||
var/max_horizontal_pixels = horizontal_pixels * screen_max_rows
|
||||
// sigh loopmania time
|
||||
var/used = 0
|
||||
// define outside for performance
|
||||
var/volume
|
||||
var/list/volume_by_item = list()
|
||||
var/list/percentage_by_item = list()
|
||||
for(var/obj/item/I in contents)
|
||||
volume = I.get_w_volume()
|
||||
used += volume
|
||||
volume_by_item[I] = volume
|
||||
percentage_by_item[I] = volume / get_max_volume()
|
||||
var/padding_pixels = ((length(percentage_by_item) - 1) * VOLUMETRIC_STORAGE_ITEM_PADDING) + VOLUMETRIC_STORAGE_EDGE_PADDING * 2
|
||||
var/min_pixels = (MINIMUM_PIXELS_PER_ITEM * length(percentage_by_item)) + padding_pixels
|
||||
// do the check for fallback for when someone has too much gamer gear
|
||||
if((min_pixels) > (max_horizontal_pixels + 4)) // 4 pixel grace zone
|
||||
to_chat(user, "<span class='warning'>[parent] was showed to you in legacy mode due to your items overrunning the three row limit! Consider not carrying too much or bugging a maintainer to raise this limit!</span>")
|
||||
return orient2hud_legacy(user, maxcolumns)
|
||||
// after this point we are sure we can somehow fit all items into our max number of rows.
|
||||
|
||||
// determine rows
|
||||
var/rows = CLAMP(CEILING(min_pixels / horizontal_pixels, 1), 1, screen_max_rows)
|
||||
|
||||
var/overrun = FALSE
|
||||
if(used > our_volume)
|
||||
// congratulations we are now in overrun mode. everything will be crammed to minimum storage pixels.
|
||||
to_chat(user, "<span class='warning'>[parent] rendered in overrun mode due to more items inside than the maximum volume supports.</span>")
|
||||
overrun = TRUE
|
||||
|
||||
// how much we are using
|
||||
var/using_horizontal_pixels = horizontal_pixels * rows
|
||||
|
||||
// item padding
|
||||
using_horizontal_pixels -= padding_pixels
|
||||
|
||||
// define outside for marginal performance boost
|
||||
var/obj/item/I
|
||||
// start at this pixel from screen_start_x.
|
||||
var/current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
var/row = 1
|
||||
|
||||
LAZYINITLIST(ui_item_blocks)
|
||||
|
||||
for(var/i in percentage_by_item)
|
||||
I = i
|
||||
var/percent = percentage_by_item[I]
|
||||
if(!ui_item_blocks[I])
|
||||
ui_item_blocks[I] = new /obj/screen/storage/volumetric_box/center(null, src, I)
|
||||
var/obj/screen/storage/volumetric_box/center/B = ui_item_blocks[I]
|
||||
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
|
||||
var/addrow = FALSE
|
||||
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
|
||||
pixels_to_use = horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
addrow = TRUE
|
||||
|
||||
// now that we have pixels_to_use, place our thing and add it to the returned list.
|
||||
|
||||
B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + VOLUMETRIC_STORAGE_ITEM_PADDING, 1)],[screen_start_y+row-1]:[screen_pixel_y]"
|
||||
// add the used pixels to pixel after we place the object
|
||||
current_pixel += pixels_to_use + VOLUMETRIC_STORAGE_ITEM_PADDING
|
||||
|
||||
// set various things
|
||||
B.set_pixel_size(pixels_to_use)
|
||||
B.layer = VOLUMETRIC_STORAGE_BOX_LAYER
|
||||
B.plane = VOLUMETRIC_STORAGE_BOX_PLANE
|
||||
B.name = I.name
|
||||
|
||||
I.mouse_opacity = MOUSE_OPACITY_ICON
|
||||
I.maptext = ""
|
||||
I.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
|
||||
I.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
|
||||
|
||||
// finally add our things.
|
||||
. += B.on_screen_objects()
|
||||
. += I
|
||||
|
||||
// go up a row if needed
|
||||
if(addrow)
|
||||
row++
|
||||
current_pixel = VOLUMETRIC_STORAGE_EDGE_PADDING
|
||||
|
||||
// Then, continuous section.
|
||||
ui_continuous = get_ui_continuous()
|
||||
ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_continuous
|
||||
// Then, left.
|
||||
ui_left = get_ui_left()
|
||||
ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]"
|
||||
. += ui_left
|
||||
// Then, closer, which is also our right element.
|
||||
ui_close = get_ui_close()
|
||||
ui_close.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y + row - 1]:[screen_pixel_y]"
|
||||
. += ui_close
|
||||
|
||||
/**
|
||||
* Shows our UI to a mob.
|
||||
*/
|
||||
/datum/component/storage/proc/ui_show(mob/M, set_screen_size = TRUE)
|
||||
if(!M.client)
|
||||
return FALSE
|
||||
var/list/cview = getviewsize(M.client.view)
|
||||
// in tiles
|
||||
var/maxallowedscreensize = cview[1]-8
|
||||
if(set_screen_size)
|
||||
current_maxscreensize = maxallowedscreensize
|
||||
else if(current_maxscreensize)
|
||||
maxallowedscreensize = current_maxscreensize
|
||||
// we got screen size, register signal
|
||||
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout, override = TRUE)
|
||||
if(M.active_storage != src)
|
||||
if(M.active_storage)
|
||||
M.active_storage.ui_hide(M)
|
||||
M.active_storage = src
|
||||
LAZYOR(is_using, M)
|
||||
if(volumetric_ui())
|
||||
//new volumetric ui bay-style
|
||||
M.client.screen |= orient2hud_volumetric(M, maxallowedscreensize)
|
||||
else
|
||||
//old ui
|
||||
M.client.screen |= orient2hud_legacy(M, maxallowedscreensize)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* VV hooked to ensure no lingering screen objects.
|
||||
*/
|
||||
/datum/component/storage/vv_edit_var(var_name, var_value)
|
||||
var/list/old
|
||||
if(var_name == NAMEOF(src, storage_flags))
|
||||
old = is_using.Copy()
|
||||
for(var/i in is_using)
|
||||
ui_hide(i)
|
||||
. = ..()
|
||||
if(old)
|
||||
for(var/i in old)
|
||||
ui_show(i)
|
||||
|
||||
/**
|
||||
* Proc triggered by signal to ensure logging out clients don't linger.
|
||||
*/
|
||||
/datum/component/storage/proc/on_logout(datum/source, client/C)
|
||||
ui_hide(source)
|
||||
|
||||
/**
|
||||
* Hides our UI from a mob
|
||||
*/
|
||||
/datum/component/storage/proc/ui_hide(mob/M)
|
||||
if(!M.client)
|
||||
return TRUE
|
||||
UnregisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT)
|
||||
M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide()
|
||||
if(M.active_storage == src)
|
||||
M.active_storage = null
|
||||
LAZYREMOVE(is_using, M)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Returns TRUE if we are using volumetric UI instead of box UI
|
||||
*/
|
||||
/datum/component/storage/proc/volumetric_ui()
|
||||
var/atom/real_location = real_location()
|
||||
return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_ITEMS) && !display_numerical_stacking
|
||||
|
||||
/**
|
||||
* Gets the ui item objects to ui_hide.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_item_objects_hide()
|
||||
if(!volumetric_ui())
|
||||
var/atom/real_location = real_location()
|
||||
return real_location.contents
|
||||
else
|
||||
. = list()
|
||||
for(var/i in ui_item_blocks)
|
||||
// get both the box and the item
|
||||
. += ui_item_blocks[i]
|
||||
. += i
|
||||
|
||||
/**
|
||||
* Gets our ui_boxes, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_boxes()
|
||||
if(!ui_boxes)
|
||||
ui_boxes = new(null, src)
|
||||
return ui_boxes
|
||||
|
||||
/**
|
||||
* Gets our ui_left, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_left()
|
||||
if(!ui_left)
|
||||
ui_left = new(null, src)
|
||||
return ui_left
|
||||
|
||||
/**
|
||||
* Gets our ui_close, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_close()
|
||||
if(!ui_close)
|
||||
ui_close = new(null, src)
|
||||
return ui_close
|
||||
|
||||
/**
|
||||
* Gets our ui_continuous, making it if it doesn't exist.
|
||||
*/
|
||||
/datum/component/storage/proc/get_ui_continuous()
|
||||
if(!ui_continuous)
|
||||
ui_continuous = new(null, src)
|
||||
return ui_continuous
|
||||
@@ -176,7 +176,7 @@
|
||||
/**
|
||||
*The following procs simply acts as hooks for quit(), since components do not use callbacks anymore
|
||||
*/
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
|
||||
/datum/component/virtual_reality/proc/action_trigger(datum/action/source, obj/target)
|
||||
quit()
|
||||
return COMPONENT_ACTION_BLOCK_TRIGGER
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
var/datum/component/wet_floor/WF = newcomp //Lets make an assumption
|
||||
if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us.
|
||||
CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!")
|
||||
return
|
||||
for(var/i in WF.time_left_list)
|
||||
add_wet(text2num(i), WF.time_left_list[i])
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
dashing_item = dasher
|
||||
holder = user
|
||||
|
||||
/datum/action/innate/dash/IsAvailable()
|
||||
/datum/action/innate/dash/IsAvailable(silent = FALSE)
|
||||
if(current_charges > 0)
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -175,11 +175,9 @@
|
||||
if(!islist(jsonlist))
|
||||
if(!istext(jsonlist))
|
||||
CRASH("Invalid JSON")
|
||||
return
|
||||
jsonlist = json_decode(jsonlist)
|
||||
if(!islist(jsonlist))
|
||||
CRASH("Invalid JSON")
|
||||
return
|
||||
if(!jsonlist["DATUM_TYPE"])
|
||||
return
|
||||
if(!ispath(jsonlist["DATUM_TYPE"]))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
|
||||
permeability_mod = 0.75
|
||||
desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
|
||||
desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental hysteria, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
|
||||
severity = DISEASE_SEVERITY_HARMFUL
|
||||
required_organs = list(/obj/item/bodypart/head)
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
|
||||
if(!istype(destination))
|
||||
return
|
||||
var/old_size = destination.dna.features["body_size"]
|
||||
destination.dna.unique_enzymes = unique_enzymes
|
||||
destination.dna.uni_identity = uni_identity
|
||||
destination.dna.blood_type = blood_type
|
||||
@@ -56,6 +57,8 @@
|
||||
if(transfer_SE)
|
||||
destination.dna.mutation_index = mutation_index
|
||||
|
||||
destination.dna.update_body_size(old_size)
|
||||
|
||||
SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE)
|
||||
|
||||
/datum/dna/proc/copy_dna(datum/dna/new_dna)
|
||||
@@ -368,7 +371,9 @@
|
||||
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures)
|
||||
|
||||
if(newfeatures)
|
||||
var/old_size = dna.features["body_size"]
|
||||
dna.features = newfeatures
|
||||
dna.update_body_size(old_size)
|
||||
|
||||
if(mrace)
|
||||
var/datum/species/newrace = new mrace.type
|
||||
@@ -644,3 +649,15 @@
|
||||
gib()
|
||||
else
|
||||
set_species(/datum/species/dullahan)
|
||||
|
||||
/datum/dna/proc/update_body_size(old_size)
|
||||
if(!holder || features["body_size"] == old_size)
|
||||
return
|
||||
holder.resize = features["body_size"] / old_size
|
||||
holder.update_transform()
|
||||
var/danger = CONFIG_GET(number/threshold_body_size_slowdown)
|
||||
if(features["body_size"] < danger)
|
||||
var/slowdown = 1 + round(danger/features["body_size"], 0.1) * CONFIG_GET(number/body_size_slowdown_multiplier)
|
||||
holder.add_movespeed_modifier(MOVESPEED_ID_SMALL_STRIDE, TRUE, 100, NONE, TRUE, slowdown, ALL, FLOATING|CRAWLING)
|
||||
else if(old_size < danger)
|
||||
holder.remove_movespeed_modifier(MOVESPEED_ID_SMALL_STRIDE)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
name = "bugged mob"
|
||||
desc = "Yell at coderbrush."
|
||||
icon = null
|
||||
alternate_worn_icon = 'icons/mob/animals_held.dmi'
|
||||
mob_overlay_icon = 'icons/mob/animals_held.dmi'
|
||||
righthand_file = 'icons/mob/animals_held_rh.dmi'
|
||||
lefthand_file = 'icons/mob/animals_held_lh.dmi'
|
||||
icon_state = ""
|
||||
@@ -86,7 +86,7 @@
|
||||
assimilate(target)
|
||||
|
||||
if(alt_worn)
|
||||
alternate_worn_icon = alt_worn
|
||||
mob_overlay_icon = alt_worn
|
||||
if(worn_state)
|
||||
item_state = worn_state
|
||||
icon_state = worn_state
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
#define POLYCHROMIC_ALTCLICK (1<<0)
|
||||
#define POLYCHROMIC_ACTION (1<<1)
|
||||
#define POLYCHROMIC_NO_HELD (1<<2)
|
||||
#define POLYCHROMIC_NO_WORN (1<<3)
|
||||
|
||||
/datum/element/polychromic
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 3
|
||||
var/overlays_states //A list or a number of states. In the latter case, the atom icon_state/item_state will be used followed by a number.
|
||||
var/list/colors_by_atom = list() //list of color strings or mutable appearances, depending on the above variable.
|
||||
var/icon_file
|
||||
var/worn_file //used in place of items' held or mob overlay icons if present.
|
||||
var/list/overlays_names //wrap numbers into text strings please.
|
||||
var/list/actions_by_atom = list()
|
||||
var/poly_flags
|
||||
var/static/list/suits_with_helmet_typecache = typecacheof(list(/obj/item/clothing/suit/hooded, /obj/item/clothing/suit/space/hardsuit))
|
||||
var/list/helmet_by_suit = list() //because poly winter coats exist.
|
||||
var/list/suit_by_helmet = list() //Idem.
|
||||
|
||||
/datum/element/polychromic/Attach(datum/target, list/colors, states, _flags = POLYCHROMIC_ACTION|POLYCHROMIC_NO_HELD, _icon, _worn, list/names = list("Primary", "Secondary", "Tertiary", "Quaternary", "Quinary", "Senary"))
|
||||
. = ..()
|
||||
var/make_appearances = islist(states)
|
||||
var/states_len = make_appearances ? length(states) : states
|
||||
var/names_len = length(names)
|
||||
if(!states_len || !names_len || colors_by_atom[target] || !isatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
var/atom/A = target
|
||||
|
||||
overlays_states = states
|
||||
icon_file = _icon
|
||||
worn_file = _worn
|
||||
poly_flags = _flags
|
||||
|
||||
var/mut_icon = icon_file || A.icon
|
||||
var/list/L = list()
|
||||
for(var/I in 1 to states_len)
|
||||
var/col = LAZYACCESS(colors, I) || "#FFFFFF"
|
||||
L += make_appearances ? mutable_appearance(mut_icon, overlays_states[I], color = col) : col
|
||||
colors_by_atom[A] = L
|
||||
|
||||
RegisterSignal(A, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlays)
|
||||
|
||||
if(_flags & POLYCHROMIC_ALTCLICK)
|
||||
RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
RegisterSignal(A, COMSIG_CLICK_ALT, .proc/set_color)
|
||||
|
||||
if(!overlays_names && names) //generate
|
||||
overlays_names = names
|
||||
var/diff = states_len - names_len
|
||||
if(diff > 0)
|
||||
for(var/i in 1 to diff)
|
||||
overlays_names += "[names_len + i]°"
|
||||
else if(diff < 0)
|
||||
overlays_names.len += diff
|
||||
|
||||
if(isitem(A))
|
||||
if(_flags & POLYCHROMIC_ACTION)
|
||||
RegisterSignal(A, COMSIG_ITEM_EQUIPPED, .proc/grant_user_action)
|
||||
RegisterSignal(A, COMSIG_ITEM_DROPPED, .proc/remove_user_action)
|
||||
if(!(_flags & POLYCHROMIC_NO_WORN) || !(_flags & POLYCHROMIC_NO_HELD))
|
||||
A.AddElement(/datum/element/update_icon_updates_onmob)
|
||||
RegisterSignal(A, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays)
|
||||
if(suits_with_helmet_typecache[A.type])
|
||||
RegisterSignal(A, COMSIG_SUIT_MADE_HELMET, .proc/register_helmet)
|
||||
else if(_flags & POLYCHROMIC_ACTION && ismob(A)) //in the event mob update icon procs are ever standarized.
|
||||
var/datum/action/polychromic/P = new(A)
|
||||
RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action)
|
||||
actions_by_atom[A] = P
|
||||
P.Grant(A)
|
||||
|
||||
A.update_icon() //apply the overlays.
|
||||
|
||||
/datum/element/polychromic/Detach(atom/A)
|
||||
. = ..()
|
||||
colors_by_atom -= A
|
||||
var/datum/action/polychromic/P = actions_by_atom[A]
|
||||
if(P)
|
||||
actions_by_atom -= A
|
||||
qdel(P)
|
||||
UnregisterSignal(A, list(COMSIG_PARENT_EXAMINE, COMSIG_CLICK_ALT, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_ITEM_WORN_OVERLAYS, COMSIG_SUIT_MADE_HELMET))
|
||||
if(isitem(A))
|
||||
var/obj/item/clothing/head/H = helmet_by_suit[A]
|
||||
if(H)
|
||||
UnregisterSignal(H, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ITEM_WORN_OVERLAYS, COMSIG_PARENT_QDELETING))
|
||||
helmet_by_suit -= A
|
||||
suit_by_helmet -= H
|
||||
colors_by_atom -= H
|
||||
if(!QDELETED(H))
|
||||
H.update_icon() //removing the overlays
|
||||
if(!(poly_flags & POLYCHROMIC_NO_WORN) || !(poly_flags & POLYCHROMIC_NO_HELD))
|
||||
A.RemoveElement(/datum/element/update_icon_updates_onmob)
|
||||
if(!QDELETED(A) && ismob(A.loc))
|
||||
var/mob/M = A.loc
|
||||
if(!(poly_flags & POLYCHROMIC_NO_HELD) && M.is_holding(A))
|
||||
M.update_inv_hands()
|
||||
else if(!(poly_flags & POLYCHROMIC_NO_WORN))
|
||||
M.regenerate_icons()
|
||||
if(!QDELETED(A))
|
||||
A.update_icon() //removing the overlays
|
||||
|
||||
/datum/element/polychromic/proc/apply_overlays(atom/source, list/overlays)
|
||||
var/list/L = colors_by_atom[source]
|
||||
var/f_icon = icon_file || source.icon
|
||||
if(isnum(overlays_states))
|
||||
for(var/i in 1 to overlays_states)
|
||||
overlays += mutable_appearance(f_icon, "[source.icon_state]-[i]", color = L[i])
|
||||
else
|
||||
overlays += colors_by_atom[source]
|
||||
|
||||
/datum/element/polychromic/proc/apply_worn_overlays(obj/item/source, isinhands, icon, used_state, style_flags, list/overlays)
|
||||
if(poly_flags & (isinhands ? POLYCHROMIC_NO_HELD : POLYCHROMIC_NO_WORN))
|
||||
return
|
||||
var/f_icon = worn_file || icon
|
||||
var/list/L = colors_by_atom[source]
|
||||
|
||||
if(isnum(overlays_states))
|
||||
for(var/i in 1 to overlays_states)
|
||||
overlays += mutable_appearance(f_icon, "[used_state]-[i]", color = L[i])
|
||||
else
|
||||
for(var/i in 1 to length(overlays_states))
|
||||
var/mutable_appearance/M = L[i]
|
||||
overlays += mutable_appearance(f_icon, overlays_states[i], color = M.color)
|
||||
|
||||
/datum/element/polychromic/proc/set_color(atom/source, mob/user)
|
||||
var/choice = input(user,"Polychromic options", "Recolor [source]") as null|anything in overlays_names
|
||||
if(!choice || QDELETED(source) || !user.canUseTopic(source, BE_CLOSE, NO_DEXTERY))
|
||||
return
|
||||
var/index = overlays_names.Find(choice)
|
||||
var/list/L = colors_by_atom[source]
|
||||
if(!L) // Ummmmmh.
|
||||
return
|
||||
var/mutable_appearance/M = L[index]
|
||||
var/old_color = istype(M) ? M.color : M
|
||||
var/ncolor = input(user, "Polychromic options", "Choose [choice] Color", old_color) as color|null
|
||||
if(!ncolor || QDELETED(source) || !colors_by_atom[source] || !user.canUseTopic(source, BE_CLOSE, NO_DEXTERY))
|
||||
return
|
||||
ncolor = sanitize_hexcolor(ncolor, 6, TRUE, old_color)
|
||||
if(istype(M))
|
||||
M.color = ncolor
|
||||
else
|
||||
L[index] = ncolor
|
||||
|
||||
source.update_icon()
|
||||
return TRUE
|
||||
|
||||
/datum/element/polychromic/proc/grant_user_action(atom/source, mob/user, slot)
|
||||
if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED || slot == SLOT_HANDCUFFED || slot == SLOT_GENERC_DEXTROUS_STORAGE)
|
||||
return
|
||||
var/datum/action/polychromic/P = actions_by_atom[source]
|
||||
if(!P)
|
||||
P = new (source)
|
||||
P.name = "Modify [source]'\s Colors"
|
||||
actions_by_atom[source] = P
|
||||
P.check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
|
||||
RegisterSignal(P, COMSIG_ACTION_TRIGGER, .proc/activate_action)
|
||||
P.Grant(user)
|
||||
|
||||
/datum/element/polychromic/proc/remove_user_action(atom/source, mob/user)
|
||||
var/datum/action/polychromic/P = actions_by_atom[source]
|
||||
P?.Remove(user)
|
||||
|
||||
/datum/element/polychromic/proc/activate_action(datum/action/source, atom/target)
|
||||
set_color(target, source.owner)
|
||||
|
||||
/datum/element/polychromic/proc/on_examine(atom/source, mob/user, list/examine_list)
|
||||
examine_list += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/datum/element/polychromic/proc/register_helmet(atom/source, obj/item/clothing/head/H)
|
||||
suit_by_helmet[H] = source
|
||||
helmet_by_suit[source] = H
|
||||
colors_by_atom[H] = colors_by_atom[source]
|
||||
RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlays)
|
||||
RegisterSignal(H, COMSIG_ITEM_WORN_OVERLAYS, .proc/apply_worn_overlays)
|
||||
RegisterSignal(H, COMSIG_PARENT_QDELETING, .proc/unregister_helmet)
|
||||
|
||||
/datum/element/polychromic/proc/unregister_helmet(atom/source)
|
||||
var/obj/item/clothing/suit/S = suit_by_helmet[source]
|
||||
suit_by_helmet -= source
|
||||
helmet_by_suit -= S
|
||||
colors_by_atom -= source
|
||||
|
||||
/datum/action/polychromic
|
||||
name = "Modify Polychromic Colors"
|
||||
background_icon_state = "bg_polychromic"
|
||||
use_target_appearance = TRUE
|
||||
button_icon_state = null
|
||||
target_appearance_matrix = list(0.8,0,0,0,0.8,0)
|
||||
@@ -12,7 +12,7 @@
|
||||
RegisterSignal(target, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
|
||||
RegisterSignal(target, COMSIG_ITEM_DROPPED, .proc/on_drop)
|
||||
else if(ismob(target))
|
||||
RegisterSignal(target, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
|
||||
RegisterSignal(target, COMSIG_MOB_SPELL_CAN_CAST, .proc/on_cast)
|
||||
stacked_spellcasting_by_user[target]++
|
||||
else
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
@@ -21,24 +21,24 @@
|
||||
|
||||
/datum/element/spellcasting/Detach(datum/target)
|
||||
. = ..()
|
||||
UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOB_SPELL_CAST_CHECK))
|
||||
UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOB_SPELL_CAN_CAST))
|
||||
if(users_by_item[target])
|
||||
var/mob/user = users_by_item[target]
|
||||
stacked_spellcasting_by_user[user]--
|
||||
if(!stacked_spellcasting_by_user[user])
|
||||
stacked_spellcasting_by_user -= user
|
||||
UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
|
||||
UnregisterSignal(user, COMSIG_MOB_SPELL_CAN_CAST)
|
||||
else if(ismob(target))
|
||||
stacked_spellcasting_by_user[target]--
|
||||
if(!stacked_spellcasting_by_user[target])
|
||||
stacked_spellcasting_by_user -= target
|
||||
|
||||
/datum/element/spellcasting/proc/on_equip(datum/source, mob/equipper, slot)
|
||||
if(!(slot in cast_slots))
|
||||
if(!(cast_slots & slotdefine2slotbit(slot)))
|
||||
return
|
||||
users_by_item[source] = equipper
|
||||
if(!stacked_spellcasting_by_user[equipper])
|
||||
RegisterSignal(equipper, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
|
||||
RegisterSignal(equipper, COMSIG_MOB_SPELL_CAN_CAST, .proc/on_cast)
|
||||
stacked_spellcasting_by_user[equipper]++
|
||||
|
||||
/datum/element/spellcasting/proc/on_drop(datum/source, mob/user)
|
||||
@@ -48,7 +48,7 @@
|
||||
stacked_spellcasting_by_user[user]--
|
||||
if(!stacked_spellcasting_by_user[user])
|
||||
stacked_spellcasting_by_user -= user
|
||||
UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
|
||||
UnregisterSignal(user, COMSIG_MOB_SPELL_CAN_CAST)
|
||||
|
||||
/datum/element/spellcasting/proc/on_cast(mob/caster, obj/effect/proc_holder/spell)
|
||||
return cast_flags
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
. = ..()
|
||||
if(!istype(target, /obj/item))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, .proc/update_onmob)
|
||||
RegisterSignal(target, COMSIG_ATOM_UPDATED_ICON, .proc/update_onmob, override = TRUE)
|
||||
|
||||
/datum/element/update_icon_updates_onmob/proc/update_onmob(obj/item/target)
|
||||
if(ismob(target.loc))
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
// Can most things breathe?
|
||||
if(trace_gases)
|
||||
continue
|
||||
if(A_gases[/datum/gas/oxygen] >= 16)
|
||||
if(A_gases[/datum/gas/oxygen] <= 16)
|
||||
continue
|
||||
if(A_gases[/datum/gas/plasma])
|
||||
continue
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
log_combat(A, D, "punched")
|
||||
var/picked_hit_type = pick("punches", "kicks")
|
||||
var/bonus_damage = damage_roll(A,D)
|
||||
if(CHECK_MOBILITY(D, MOBILITY_STAND))
|
||||
if(!CHECK_MOBILITY(D, MOBILITY_STAND))
|
||||
bonus_damage += 10
|
||||
picked_hit_type = "stomps on"
|
||||
D.apply_damage(bonus_damage, BRUTE, affecting, armor_block)
|
||||
@@ -165,7 +165,7 @@
|
||||
return TRUE
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
var/damage = damage_roll(A,D)
|
||||
var/damage = (damage_roll(A,D)*2)
|
||||
if(D.mobility_flags & MOBILITY_STAND)
|
||||
D.visible_message("<span class='danger'>[A] reprimands [D]!</span>", \
|
||||
"<span class='userdanger'>You're slapped by [A]!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
. = ..()
|
||||
if(A.incapacitated(FALSE, TRUE)) //NO STUN
|
||||
return BULLET_ACT_HIT
|
||||
if(CHECK_ALL_MOBILITY(A, MOBILITY_USE|MOBILITY_STAND)) //NO UNABLE TO USE, NO DODGING ON THE FLOOR
|
||||
if(!CHECK_ALL_MOBILITY(A, MOBILITY_USE|MOBILITY_STAND)) //NO UNABLE TO USE, NO DODGING ON THE FLOOR
|
||||
return BULLET_ACT_HIT
|
||||
if(A.dna && A.dna.check_mutation(HULK)) //NO HULK
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
. = ..()
|
||||
if(A.incapacitated(FALSE, TRUE)) //NO STUN
|
||||
return BULLET_ACT_HIT
|
||||
if(CHECK_ALL_MOBILITY(A, MOBILITY_USE|MOBILITY_STAND)) //NO UNABLE TO USE, NO DEFLECTION ON THE FLOOR
|
||||
if(!CHECK_ALL_MOBILITY(A, MOBILITY_USE|MOBILITY_STAND)) //NO UNABLE TO USE, NO DEFLECTION ON THE FLOOR
|
||||
return BULLET_ACT_HIT
|
||||
if(A.dna && A.dna.check_mutation(HULK)) //NO HULK
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
integrity_modifier = 0.1
|
||||
sheet_type = /obj/item/stack/sheet/glass
|
||||
value_per_unit = 0.0025
|
||||
armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok retard
|
||||
armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok
|
||||
|
||||
/*
|
||||
Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel.
|
||||
|
||||
@@ -26,3 +26,7 @@
|
||||
/datum/generecipe/tonguechem
|
||||
required = "/datum/mutation/human/tongue_spike; /datum/mutation/human/stimmed"
|
||||
result = TONGUESPIKECHEM
|
||||
|
||||
/datum/generecipe/hulk
|
||||
required = "/datum/mutation/human/strong; /datum/mutation/human/radioactive"
|
||||
result = HULK
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
message = " [message] "
|
||||
//Time for a friendly game of SS13
|
||||
message = replacetext(message," stupid "," smart ")
|
||||
message = replacetext(message," retard "," genius ")
|
||||
message = replacetext(message," idiot "," genius ")
|
||||
message = replacetext(message," unrobust "," robust ")
|
||||
message = replacetext(message," dumb "," smart ")
|
||||
message = replacetext(message," awful "," great ")
|
||||
@@ -263,7 +263,7 @@
|
||||
message = replacetext(message," thank you "," thank you, thank you very much ")
|
||||
message = replacetext(message," what are you "," whatcha ")
|
||||
message = replacetext(message," yes ",pick(" sure", "yea "))
|
||||
message = replacetext(message," faggot "," square ")
|
||||
message = replacetext(message," dumbass "," square ")
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
speech_args[SPEECH_MESSAGE] = trim(message)
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
continue
|
||||
contam_atoms += thing
|
||||
var/did_contam = 0
|
||||
if(length(can_contam))
|
||||
if(can_contam)
|
||||
var/rad_strength = ((strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT)/contam_atoms.len
|
||||
for(var/k in 1 to contam_atoms.len)
|
||||
var/atom/thing = contam_atoms[k]
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
..()
|
||||
if(!istype(holder, holder_type))
|
||||
CRASH("Wire holder is not of the expected type!")
|
||||
return
|
||||
|
||||
src.holder = holder
|
||||
if(randomize)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
hidden = TRUE
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
var/list/compatible_holodeck_comps
|
||||
var/abstract_type = /area/holodeck
|
||||
var/restricted = 0 // if true, program goes on emag list
|
||||
|
||||
/*
|
||||
@@ -53,6 +55,8 @@
|
||||
*/
|
||||
/area/holodeck/rec_center
|
||||
name = "\improper Recreational Holodeck"
|
||||
compatible_holodeck_comps = list(/obj/machinery/computer/holodeck)
|
||||
abstract_type = /area/holodeck/rec_center
|
||||
|
||||
/area/holodeck/rec_center/offline
|
||||
name = "Holodeck - Offline"
|
||||
|
||||
+1
-4
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
|
||||
@@ -205,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
|
||||
@@ -247,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))
|
||||
@@ -257,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))
|
||||
@@ -496,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)
|
||||
@@ -723,7 +725,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
|
||||
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) / (threat_average_weight + cur_sample_weight)
|
||||
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
|
||||
|
||||
@@ -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 //
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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]"
|
||||
|
||||
@@ -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,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
|
||||
@@ -449,6 +450,7 @@
|
||||
/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,
|
||||
@@ -458,41 +460,42 @@
|
||||
/obj/item/clothing/glasses/sunglasses/blindfold = 4,
|
||||
/obj/item/clothing/glasses/sunglasses = 1,
|
||||
/obj/item/toy/plush/random = 5,
|
||||
/obj/effect/spawner/lootdrop/gloves = 5,
|
||||
/obj/effect/spawner/lootdrop/glowstick = 5,
|
||||
/obj/effect/spawner/lootdrop/coin = 3,
|
||||
/obj/effect/spawner/lootdrop/cig_packs = 10,
|
||||
/obj/effect/spawner/lootdrop/cigars_cases = 2,
|
||||
/obj/effect/spawner/lootdrop/space_cash = 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 = 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 = 5,
|
||||
/obj/effect/spawner/lootdrop/cig_packs = 10,
|
||||
/obj/effect/spawner/lootdrop/cigars_cases = 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 = 5,
|
||||
/obj/effect/spawner/lootdrop/druggie_pill/no_turf = 5,
|
||||
/obj/item/kitchen/knife = 5,
|
||||
/obj/item/screwdriver = 5,
|
||||
/obj/item/crowbar/red = 0.5, //Dont you need a crowbar to open this?
|
||||
/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.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,
|
||||
@@ -502,13 +505,14 @@
|
||||
/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 = 5,
|
||||
/obj/effect/spawner/lootdrop/space_cash = 5,
|
||||
/obj/effect/spawner/lootdrop/druggie_pill = 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,
|
||||
@@ -521,3 +525,24 @@
|
||||
/obj/item/clothing/gloves/combat = 10,
|
||||
/obj/item/clothing/shoes/sneakers/noslip = 10
|
||||
)
|
||||
|
||||
/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
|
||||
|
||||
@@ -8,9 +8,20 @@ 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 ssize.
|
||||
var/alternate_worn_layer
|
||||
|
||||
var/list/alternate_screams = list() //REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
||||
|
||||
//Dimensions of the icon file used when this item is worn, eg: hats.dmi
|
||||
@@ -22,10 +33,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 +41,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 +72,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
|
||||
@@ -109,6 +118,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!
|
||||
@@ -422,6 +438,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
|
||||
@@ -845,6 +868,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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
desc = "Looks like some cables tied together. Could be used to tie something up."
|
||||
icon_state = "cuff"
|
||||
item_state = "coil"
|
||||
color = "red"
|
||||
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)
|
||||
@@ -132,35 +132,28 @@
|
||||
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
|
||||
|
||||
@@ -209,7 +202,7 @@
|
||||
custom_materials = null
|
||||
breakouttime = 450 //Deciseconds = 45s
|
||||
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
|
||||
item_color = "white"
|
||||
color = null
|
||||
|
||||
/obj/item/restraints/handcuffs/cable/zipties/used
|
||||
desc = "A pair of broken zipties."
|
||||
|
||||
@@ -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
|
||||
@@ -303,8 +303,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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,12 +106,19 @@
|
||||
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)
|
||||
@@ -119,7 +129,9 @@
|
||||
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
|
||||
@@ -152,15 +164,13 @@
|
||||
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,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
|
||||
|
||||
@@ -214,7 +214,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user