Merge branch 'master' into silicons-patch-1
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
#define MEDAL_VOID_ASCENSION "Void"
|
||||
#define MEDAL_TOOLBOX_SOUL "Toolsoul"
|
||||
#define MEDAL_CHEM_TUT "Beginner Chemist"
|
||||
#define MEDAL_HOT_DAMN "Hot Damn!"
|
||||
#define MEDAL_CAYENNE_DISK "Very Important Piscis"
|
||||
#define MEDAL_TRAM_SURFER "Tram Surfer"
|
||||
|
||||
//Skill medal hub IDs
|
||||
#define MEDAL_LEGENDARY_MINER "Legendary Miner"
|
||||
@@ -106,3 +109,19 @@
|
||||
|
||||
// DB ID for amount of consumed maintenance pills
|
||||
#define MAINTENANCE_PILL_SCORE "Maintenance Pill Score"
|
||||
|
||||
// DB ID for intento score
|
||||
#define INTENTO_SCORE "Intento Score"
|
||||
|
||||
// Tourist related achievements and scores
|
||||
|
||||
//centcom grades (achievement)
|
||||
|
||||
#define MEDAL_BAD_SERVICE "Bad Service"
|
||||
#define MEDAL_OKAY_SERVICE "Okay Service"
|
||||
#define MEDAL_GOOD_SERVICE "Good Service"
|
||||
|
||||
//scores
|
||||
|
||||
#define CHEF_TOURISTS_SERVED "Tourists Served As Chef"
|
||||
#define BARTENDER_TOURISTS_SERVED "Tourists Served As Bartender"
|
||||
|
||||
@@ -59,3 +59,4 @@
|
||||
#define COLOR_SILVER "#C0C0C0"
|
||||
#define COLOR_GRAY "#808080"
|
||||
#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A"
|
||||
#define COLOR_BRIGHT_BLUE "#2CB2E8"
|
||||
|
||||
@@ -24,3 +24,11 @@
|
||||
#define POLICYCONFIG_ON_PYROCLASTIC_SENTIENT "PYROCLASTIC_SLIME"
|
||||
/// Displayed to pAIs on spawn
|
||||
#define POLICYCONFIG_PAI "PAI_SPAWN"
|
||||
/// displayed to lavaland elites on spawn, overriding the default if set
|
||||
#define POLICYCONFIG_ELITE_SPAWN "ELITE_FAUNA_SPAWN"
|
||||
/// displayed to lavaland elites on sentience potion, overriding the default if set
|
||||
#define POLICYCONFIG_ELITE_SENTIENCE "ELITE_FAUNA_SENTIENCE"
|
||||
/// displayed to lavaland elites on winning the fight, overriding the default if set
|
||||
#define POLICYCONFIG_ELITE_WIN "ELITE_FAUNA_WIN"
|
||||
/// displayed to prisoners on spawn, overriding the default if set
|
||||
#define POLICYCONFIG_JOB_PRISONER "JOB_PRISONER"
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
//INDEXES
|
||||
#define COOLDOWN_EMPLOYMENT_CABINET "employment cabinet"
|
||||
|
||||
//car cooldowns
|
||||
#define COOLDOWN_CAR_HONK "car_honk"
|
||||
|
||||
//clown car cooldowns
|
||||
#define COOLDOWN_CLOWNCAR_RANDOMNESS "clown_car_randomness"
|
||||
|
||||
//TIMER COOLDOWN MACROS
|
||||
|
||||
|
||||
@@ -81,7 +81,8 @@
|
||||
#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg')
|
||||
|
||||
#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\
|
||||
'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' )
|
||||
'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg',\
|
||||
'sound/ambience/ambimaint10.ogg' )
|
||||
|
||||
#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
//Vehicle control flags
|
||||
//Vehicle control flags. control flags describe access to actions in a vehicle.
|
||||
|
||||
#define VEHICLE_CONTROL_PERMISSION 1
|
||||
#define VEHICLE_CONTROL_DRIVE 2
|
||||
#define VEHICLE_CONTROL_KIDNAPPED 4 //Can't leave vehicle voluntarily, has to resist.
|
||||
///controls the vehicles movement
|
||||
#define VEHICLE_CONTROL_DRIVE (1<<0)
|
||||
///Can't leave vehicle voluntarily, has to resist.
|
||||
#define VEHICLE_CONTROL_KIDNAPPED (1<<1)
|
||||
///melee attacks/shoves a vehicle may have
|
||||
#define VEHICLE_CONTROL_MELEE (1<<2)
|
||||
///using equipment/weapons on the vehicle
|
||||
#define VEHICLE_CONTROL_EQUIPMENT (1<<3)
|
||||
///changing around settings and the like.
|
||||
#define VEHICLE_CONTROL_SETTINGS (1<<4)
|
||||
|
||||
//car_traits flags
|
||||
///Will this car kidnap people by ramming into them?
|
||||
#define CAN_KIDNAP (1<<0)
|
||||
|
||||
//Car trait flags
|
||||
#define CAN_KIDNAP 1
|
||||
#define CLOWN_CANNON_INACTIVE 0
|
||||
#define CLOWN_CANNON_BUSY 1
|
||||
#define CLOWN_CANNON_READY 2
|
||||
|
||||
@@ -12,3 +12,16 @@ GLOBAL_LIST_INIT(typecache_stack, typecacheof(/obj/item/stack))
|
||||
GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(/obj/machinery, /obj/structure)))
|
||||
|
||||
GLOBAL_LIST_INIT(freezing_objects, typecacheof(list(/obj/structure/closet/crate/freezer, /obj/structure/closet/secure_closet/freezer, /obj/structure/bodycontainer, /obj/item/autosurgeon, /obj/machinery/smartfridge/organ))) //list of all cold objects, that freeze organs when inside
|
||||
|
||||
GLOBAL_LIST_EMPTY(typecaches)
|
||||
|
||||
/**
|
||||
* Makes a typecache of a single typecache
|
||||
*
|
||||
* Obviously in BYOND we don't have the efficiency around here to have proper enforcement so
|
||||
* If you use this you better know what you're doing. The list you get back is globally cached and if it's modified, you might break multiple things.
|
||||
*/
|
||||
/proc/single_path_typecache_immutable(path)
|
||||
if(!GLOB.typecaches[path])
|
||||
GLOB.typecaches[path] = typecacheof(path)
|
||||
return GLOB.typecaches[path]
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
|
||||
/datum/achievement_data/ui_data(mob/user)
|
||||
var/ret_data = list() // screw standards (qustinnus you must rename src.data ok)
|
||||
ret_data["categories"] = list("Bosses", "Misc", "Mafia", "Scores")
|
||||
ret_data["categories"] = list("Bosses", "Jobs", "Misc", "Mafia", "Scores")
|
||||
ret_data["achievements"] = list()
|
||||
ret_data["user_key"] = user.ckey
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
///Name of the achievement, If null it won't show up in the achievement browser. (Handy for inheritance trees)
|
||||
var/name
|
||||
var/desc = "You did it."
|
||||
///Found in UI_Icons/Achievements
|
||||
///Found in ui_icons/achievements
|
||||
var/icon = "default"
|
||||
var/category = "Normal"
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
/datum/award/achievement/on_unlock(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='greenannounce'><B>Achievement unlocked: [name]!</B></span>")
|
||||
to_chat(user, span_greenannounce("<B>Achievement unlocked: [name]!</B>"))
|
||||
|
||||
///Scores are for leaderboarded things, such as killcount of a specific boss
|
||||
/datum/award/score
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
name = "Boss Killer"
|
||||
desc = "You've come a long ways from asking how to switch hands."
|
||||
database_id = "Boss Killer"
|
||||
// icon = "firstboss"
|
||||
icon = "firstboss"
|
||||
|
||||
/datum/award/achievement/boss/blood_miner_kill
|
||||
name = "Blood-Drunk Miner Killer"
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
/datum/award/achievement/jobs
|
||||
category = "Jobs"
|
||||
icon = "basemisc"
|
||||
|
||||
//chemistry
|
||||
|
||||
/datum/award/achievement/jobs/chemistry_tut
|
||||
name = "Perfect chemistry blossom"
|
||||
desc = "Passed the chemistry tutorial with perfect purity!"
|
||||
database_id = MEDAL_CHEM_TUT
|
||||
icon = "chem_tut"
|
||||
|
||||
//all of service! hip hip!
|
||||
|
||||
/datum/award/achievement/jobs/service_bad
|
||||
name = "Centcom Grade: Shitty Service"
|
||||
desc = "Well, you at least tried. How about trying harder?"
|
||||
database_id = MEDAL_BAD_SERVICE
|
||||
icon = "chem_tut"
|
||||
|
||||
/datum/award/achievement/jobs/service_okay
|
||||
name = "Centcom Grade: Acceptable Service"
|
||||
desc = "Well, it'll do! You and your department did just fine."
|
||||
database_id = MEDAL_OKAY_SERVICE
|
||||
icon = "chem_tut"
|
||||
|
||||
/datum/award/achievement/jobs/service_good
|
||||
name = "Centcom Grade: Exemplary Service"
|
||||
desc = "Centcom is very impressed with your department!"
|
||||
database_id = MEDAL_GOOD_SERVICE
|
||||
icon = "chem_tut"
|
||||
|
||||
//civilian achievies! while not recognized by the code, it is recognized by our hearts
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
//chef
|
||||
|
||||
/datum/award/score/chef_tourist_score
|
||||
name = "Tourists Served as Chef Highscore"
|
||||
desc = "Your highscore on serving tourist bots as chef."
|
||||
database_id = CHEF_TOURISTS_SERVED
|
||||
|
||||
//bartender
|
||||
|
||||
/datum/award/score/bartender_tourist_score
|
||||
name = "Tourists Served as Bartender Highscore"
|
||||
desc = "Your highscore on serving tourist bots as bartender."
|
||||
database_id = BARTENDER_TOURISTS_SERVED
|
||||
@@ -154,8 +154,20 @@
|
||||
database_id = MEDAL_TOOLBOX_SOUL
|
||||
icon = "toolbox_soul"
|
||||
|
||||
/datum/award/achievement/misc/chemistry_tut
|
||||
name = "Perfect chemistry blossom"
|
||||
desc = "Passed the chemistry tutorial with perfect purity!"
|
||||
database_id = MEDAL_CHEM_TUT
|
||||
icon = "chem_tut"
|
||||
/datum/award/achievement/misc/hot_damn
|
||||
name = "Hot Damn!"
|
||||
desc = "Sometimes you need to make some noise to make a point."
|
||||
database_id = MEDAL_HOT_DAMN
|
||||
icon = "hotdamn"
|
||||
|
||||
/datum/award/achievement/misc/cayenne_disk
|
||||
name = "Very Important Piscis"
|
||||
desc = "You can rest well now."
|
||||
database_id = MEDAL_CAYENNE_DISK
|
||||
icon = "cayenne_disk"
|
||||
|
||||
/datum/award/achievement/misc/tram_surfer
|
||||
name = "Tram Surfer"
|
||||
desc = "Lights out, guerilla radio!"
|
||||
database_id = MEDAL_TRAM_SURFER
|
||||
icon = "tram_surfer"
|
||||
|
||||
@@ -9,3 +9,9 @@
|
||||
name = "Maintenance Pills Consumed"
|
||||
desc = "Wait why?"
|
||||
database_id = MAINTENANCE_PILL_SCORE
|
||||
|
||||
///How high of a score on the Intento did we get?
|
||||
/datum/award/score/intento_score
|
||||
name = "Intento Score"
|
||||
desc = "A blast from the future?"
|
||||
database_id = INTENTO_SCORE
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
minimum_pressure = HAZARD_LOW_PRESSURE + 10
|
||||
maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1
|
||||
|
||||
minimum_temp = BODYTEMP_COLD_DAMAGE_LIMIT + 1
|
||||
minimum_temp = 270
|
||||
maximum_temp = 320
|
||||
|
||||
/datum/atmosphere/icemoon
|
||||
|
||||
@@ -83,13 +83,19 @@
|
||||
return
|
||||
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
|
||||
return
|
||||
|
||||
var/matches = FALSE
|
||||
var/mainsource
|
||||
for(var/word in trigger_words)
|
||||
var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
|
||||
var/regex/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "ig")
|
||||
|
||||
if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg))
|
||||
addtimer(CALLBACK(src, .proc/freak_out, null, word), 10) //to react AFTER the chat message
|
||||
hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "<span class='phobia'>$1</span>")
|
||||
break
|
||||
hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "<span class='phobia'>$0</span>")
|
||||
matches = TRUE
|
||||
mainsource = word
|
||||
|
||||
if(matches)
|
||||
addtimer(CALLBACK(src, .proc/freak_out, null, mainsource), 10) //to react AFTER the chat message
|
||||
|
||||
/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args)
|
||||
if(HAS_TRAIT(owner, TRAIT_FEARLESS))
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
|
||||
/datum/crafting_recipe/quiver
|
||||
name = "Quiver"
|
||||
always_availible = FALSE
|
||||
result = /obj/item/storage/belt/quiver
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/leather = 3,
|
||||
@@ -104,19 +103,18 @@
|
||||
name = "Bone Bow"
|
||||
result = /obj/item/gun/ballistic/bow/ashen
|
||||
time = 120 // 80+120 = 200
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/stack/sheet/bone = 8,
|
||||
/obj/item/stack/sheet/sinew = 4)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bow_tablet
|
||||
/*/datum/crafting_recipe/bow_tablet
|
||||
name = "Sandstone Bow Making Manual"
|
||||
result = /obj/item/book/granter/crafting_recipe/bone_bow
|
||||
time = 200 //Scribing // don't care
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/stack/rods = 1,
|
||||
/obj/item/stack/sheet/mineral/sandstone = 4)
|
||||
category = CAT_PRIMAL
|
||||
category = CAT_PRIMAL*/
|
||||
|
||||
/datum/crafting_recipe/rib
|
||||
name = "Collosal Rib"
|
||||
@@ -154,3 +152,158 @@
|
||||
/obj/item/shovel/spade = 1)
|
||||
result = /obj/item/shovel/serrated
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_screwdriver
|
||||
name = "Bone Screwdriver"
|
||||
result = /obj/item/screwdriver/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_crowbar
|
||||
name = "Bone Crowbar"
|
||||
result = /obj/item/crowbar/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_cutters
|
||||
name = "Bone Wirecutters"
|
||||
result = /obj/item/wirecutters/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_wrench
|
||||
name = "Bone Wrench"
|
||||
result = /obj/item/wrench/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/necropolis_welding
|
||||
name = "Necropolis Welding Torch"
|
||||
result = /obj/item/weldingtool/experimental/ashwalker
|
||||
time = 120
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 2,
|
||||
/obj/item/organ/regenerative_core = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/tribalbelt
|
||||
name = "Hunter's Belt"
|
||||
result = /obj/item/storage/belt/mining/primitive
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/sinew = 4)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/goliath_gloves
|
||||
name = "Goliath Gloves"
|
||||
result = /obj/item/clothing/gloves/tackler/combat/goliath
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/sinew = 2,
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide = 2,
|
||||
/obj/item/stack/sheet/cloth = 2,
|
||||
/obj/item/stack/sheet/leather = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/goliath_drapes
|
||||
name = "Goliath Drapes"
|
||||
result = /obj/item/surgical_drapes/goliath
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/sinew = 1,
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/diamond_scalpel
|
||||
name = "Diamond Scalpel"
|
||||
result = /obj/item/scalpel/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1,
|
||||
/obj/item/stack/sheet/mineral/diamond = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_retractor
|
||||
name = "Bone Retractor"
|
||||
result = /obj/item/retractor/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/diamond_bonesaw
|
||||
name = "Diamond Bonesaw"
|
||||
result = /obj/item/circular_saw/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1,
|
||||
/obj/item/organ/regenerative_core = 1,
|
||||
/obj/item/stack/sheet/mineral/diamond = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/femurstat
|
||||
name = "Bone Hemostat"
|
||||
result = /obj/item/hemostat/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_bonesetter
|
||||
name = "Bone Bonersetter"
|
||||
result = /obj/item/bonesetter/bone
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/coretery
|
||||
name = "Necropolis Cautery"
|
||||
result = /obj/item/cautery/ashwalker
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 1,
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide = 1,
|
||||
/obj/item/organ/regenerative_core = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_spade
|
||||
name = "Bone Spade"
|
||||
result = /obj/item/shovel/spade/bone
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 1,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_hatchet
|
||||
name = "Bone Hatchet"
|
||||
result = /obj/item/hatchet/bone
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 1,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_cultivator
|
||||
name = "Bone Cultivator"
|
||||
result = /obj/item/cultivator/bone
|
||||
time = 80
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/sinew = 1)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/bone_glaive
|
||||
name = "Necropolis Glaive"
|
||||
result = /obj/item/kinetic_crusher/glaive/bone
|
||||
time = 120
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2,
|
||||
/obj/item/stack/sheet/mineral/wood = 4,
|
||||
/obj/item/stack/sheet/sinew = 4,
|
||||
/obj/item/organ/regenerative_core = 2,
|
||||
/obj/item/stack/sheet/mineral/diamond = 2,
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide = 2,
|
||||
/obj/item/stack/sheet/leather = 2)
|
||||
category = CAT_PRIMAL
|
||||
|
||||
@@ -335,7 +335,6 @@
|
||||
name = "Bone Arrow"
|
||||
result = /obj/item/ammo_casing/caseless/arrow/bone
|
||||
time = 5
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/stack/sheet/bone = 1,
|
||||
/obj/item/stack/sheet/sinew = 1,
|
||||
/obj/item/ammo_casing/caseless/arrow/ash = 1)
|
||||
@@ -347,7 +346,6 @@
|
||||
result = /obj/item/ammo_casing/caseless/arrow/ash
|
||||
tools = list(TOOL_WELDER)
|
||||
time = 10 // 1.5 seconds minimum per actually worthwhile arrow excluding interface lag
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/ammo_casing/caseless/arrow/wood = 1)
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
@@ -206,6 +206,9 @@ GLOBAL_LIST_EMPTY(uplinks)
|
||||
return data
|
||||
|
||||
/datum/component/uplink/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!active)
|
||||
return
|
||||
switch(action)
|
||||
|
||||
@@ -331,6 +331,12 @@
|
||||
name = "Space Diner"
|
||||
description = "Come, traveler of the bluespace planes. Sit, enjoy a drink and take one of the fair maidens for a night. The exit is the way you came in, via that teleporter thingy, but do remember to stay safe."
|
||||
|
||||
/datum/map_template/ruin/space/suspicious
|
||||
id = "helterskelter"
|
||||
suffix = "skelter.dmm"
|
||||
name = "Helter Skelter"
|
||||
description = "You're looking mighty suspicious. Why don't you go and take a seat over in that driver?"
|
||||
|
||||
//Space ruins for the station z
|
||||
/datum/map_template/ruin/spacenearstation
|
||||
prefix = "_maps/RandomRuins/SpaceRuinsStation/"
|
||||
|
||||
+145
-116
@@ -23,6 +23,8 @@
|
||||
/obj/item/storage/backpack,
|
||||
/obj/item/storage/belt
|
||||
)
|
||||
/// Temporary messages
|
||||
var/temp
|
||||
|
||||
/obj/machinery/gear_painter/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -69,6 +71,8 @@
|
||||
if(!QDELETED(H))
|
||||
H.release()
|
||||
insert_mob(victim, user)
|
||||
temp = "[victim] has been inserted."
|
||||
SStgui.update_uis(src)
|
||||
|
||||
if(is_type_in_list(I, allowed_types) && is_operational())
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
@@ -80,6 +84,9 @@
|
||||
|
||||
inserted = I
|
||||
update_icon()
|
||||
temp = "[I] has been inserted."
|
||||
SStgui.update_uis(src)
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -101,137 +108,159 @@
|
||||
|
||||
/obj/machinery/gear_painter/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!user.CanReach(src))
|
||||
drop_item()
|
||||
|
||||
/obj/machinery/gear_painter/proc/drop_item()
|
||||
if(!usr.CanReach(src))
|
||||
return
|
||||
if(!inserted)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You remove [inserted] from [src]")
|
||||
to_chat(usr, "<span class='notice'>You remove [inserted] from [src]")
|
||||
inserted.forceMove(drop_location())
|
||||
var/mob/living/user = usr
|
||||
if(istype(user))
|
||||
user.put_in_hands(inserted)
|
||||
inserted = null
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
SStgui.update_uis(src)
|
||||
|
||||
/obj/machinery/gear_painter/ui_interact(mob/user)
|
||||
if(!is_operational())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/list/dat = list("<TITLE>Color Mate Control Panel</TITLE><BR>")
|
||||
if(!inserted)
|
||||
dat += "No item inserted."
|
||||
/obj/machinery/gear_painter/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Colormate", src.name)
|
||||
ui.set_autoupdate(FALSE) //This might be a bit intensive, better to not update it every few ticks
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/gear_painter/ui_data(mob/user)
|
||||
. = list()
|
||||
.["matrixactive"] = matrix_mode
|
||||
.["matrixcolors"] = list(
|
||||
"rr" = color_matrix_last[1],
|
||||
"rg" = color_matrix_last[2],
|
||||
"rb" = color_matrix_last[3],
|
||||
"gr" = color_matrix_last[4],
|
||||
"gg" = color_matrix_last[5],
|
||||
"gb" = color_matrix_last[6],
|
||||
"br" = color_matrix_last[7],
|
||||
"bg" = color_matrix_last[8],
|
||||
"bb" = color_matrix_last[9],
|
||||
"cr" = color_matrix_last[10],
|
||||
"cg" = color_matrix_last[11],
|
||||
"cb" = color_matrix_last[12]
|
||||
)
|
||||
if(temp)
|
||||
.["temp"] = temp
|
||||
if(inserted)
|
||||
.["item"] = list()
|
||||
.["item"]["name"] = inserted.name
|
||||
.["item"]["sprite"] = icon2base64(getFlatIcon(inserted,defdir=SOUTH,no_anim=TRUE))
|
||||
.["item"]["preview"] = icon2base64(build_preview())
|
||||
else
|
||||
dat += "Item inserted: [inserted]<HR>"
|
||||
dat += "<a href='?src=[REF(src)];toggle_matrix_mode=1'>Matrix mode: [matrix_mode? "On" : "Off"]</a>"
|
||||
if(!matrix_mode)
|
||||
dat += "<A href='?src=\ref[src];select=1'>Select new color.</A><BR>"
|
||||
dat += "Color: <font color='[activecolor]'>⚫</font>"
|
||||
dat += "<A href='?src=\ref[src];paint=1'>Apply new color.</A><BR><BR>"
|
||||
.["item"] = null
|
||||
|
||||
/obj/machinery/gear_painter/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(inserted)
|
||||
switch(action)
|
||||
if("switch_modes")
|
||||
matrix_mode = text2num(params["mode"])
|
||||
return TRUE
|
||||
if("choose_color")
|
||||
var/chosen_color = input(usr, "Choose a color: ", "Colormate color picking", activecolor) as color|null
|
||||
if(chosen_color)
|
||||
activecolor = chosen_color
|
||||
return TRUE
|
||||
if("paint")
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
return TRUE
|
||||
inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
temp = "Painted Successfully!"
|
||||
return TRUE
|
||||
if("drop")
|
||||
temp = "Ejected \the [inserted]!"
|
||||
drop_item()
|
||||
return TRUE
|
||||
if("clear")
|
||||
inserted.remove_atom_colour(FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
temp = "Cleared Successfully!"
|
||||
return TRUE
|
||||
if("set_matrix_color")
|
||||
color_matrix_last[params["color"]] = params["value"]
|
||||
return TRUE
|
||||
if("matrix_paint")
|
||||
var/list/cm = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(!check_valid_color(cm, usr))
|
||||
return TRUE
|
||||
inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
temp = "Matrix Painted Successfully!"
|
||||
return TRUE
|
||||
|
||||
/// Produces the preview image of the item, used in the UI, the way the color is not stacking is a sin.
|
||||
/obj/machinery/gear_painter/proc/build_preview()
|
||||
if(inserted) //sanity
|
||||
if(matrix_mode)
|
||||
var/list/cm = rgb_construct_color_matrix(
|
||||
text2num(color_matrix_last[1]),
|
||||
text2num(color_matrix_last[2]),
|
||||
text2num(color_matrix_last[3]),
|
||||
text2num(color_matrix_last[4]),
|
||||
text2num(color_matrix_last[5]),
|
||||
text2num(color_matrix_last[6]),
|
||||
text2num(color_matrix_last[7]),
|
||||
text2num(color_matrix_last[8]),
|
||||
text2num(color_matrix_last[9]),
|
||||
text2num(color_matrix_last[10]),
|
||||
text2num(color_matrix_last[11]),
|
||||
text2num(color_matrix_last[12])
|
||||
)
|
||||
if(!check_valid_color(cm, usr))
|
||||
temp = "Failed to generate preview: Invalid color!"
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
|
||||
var/cur_color = inserted.color
|
||||
inserted.color = null
|
||||
inserted.color = cm
|
||||
var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
inserted.color = cur_color
|
||||
|
||||
. = preview
|
||||
|
||||
else
|
||||
// POGGERS
|
||||
#define MATRIX_FIELD(field, default) "<b><label for='[##field]'>[##field]</label></b> <input type='number' step='0.001' name='[field]' value='[default]'>"
|
||||
dat += "<br><form name='matrix paint' action='?src=[REF(src)]'>"
|
||||
dat += "<input type='hidden' name='src' value='[REF(src)]'>"
|
||||
dat += "<input type='hidden' name='matrix_paint' value='1'"
|
||||
dat += "<br><br>"
|
||||
dat += MATRIX_FIELD("rr", color_matrix_last[1])
|
||||
dat += MATRIX_FIELD("gr", color_matrix_last[4])
|
||||
dat += MATRIX_FIELD("br", color_matrix_last[7])
|
||||
dat += "<br><br>"
|
||||
dat += MATRIX_FIELD("rg", color_matrix_last[2])
|
||||
dat += MATRIX_FIELD("gg", color_matrix_last[5])
|
||||
dat += MATRIX_FIELD("bg", color_matrix_last[8])
|
||||
dat += "<br><br>"
|
||||
dat += MATRIX_FIELD("rb", color_matrix_last[3])
|
||||
dat += MATRIX_FIELD("gb", color_matrix_last[6])
|
||||
dat += MATRIX_FIELD("bb", color_matrix_last[9])
|
||||
dat += "<br><br>"
|
||||
dat += MATRIX_FIELD("cr", color_matrix_last[10])
|
||||
dat += MATRIX_FIELD("cg", color_matrix_last[11])
|
||||
dat += MATRIX_FIELD("cb", color_matrix_last[12])
|
||||
dat += "<br><br>"
|
||||
dat += "<input type='submit' value='Matrix Paint'>"
|
||||
dat += "</form><br>"
|
||||
#undef MATRIX_FIELD
|
||||
dat += "<A href='?src=\ref[src];clear=1'>Remove paintjob.</A><BR><BR>"
|
||||
dat += "<A href='?src=\ref[src];eject=1'>Eject item.</A><BR><BR>"
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
temp = "Failed to generate preview: Invalid color!"
|
||||
return getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
|
||||
var/datum/browser/menu = new(user, "colormate","Color Mate Control Panel", 800, 600, src)
|
||||
menu.set_content(dat.Join(""))
|
||||
menu.open()
|
||||
var/cur_color = inserted.color
|
||||
inserted.color = null
|
||||
inserted.color = activecolor
|
||||
var/icon/preview = getFlatIcon(inserted, defdir=SOUTH, no_anim=TRUE)
|
||||
inserted.color = cur_color
|
||||
|
||||
/obj/machinery/gear_painter/Topic(href, href_list)
|
||||
if((. = ..()))
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=colormate")
|
||||
return
|
||||
|
||||
if(href_list["select"])
|
||||
var/newcolor = input(usr, "Choose a color.", "", activecolor) as color|null
|
||||
if(newcolor)
|
||||
activecolor = newcolor
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["paint"])
|
||||
if(!inserted)
|
||||
return
|
||||
if(!check_valid_color(activecolor, usr))
|
||||
return
|
||||
inserted.add_atom_colour(activecolor, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["toggle_matrix_mode"])
|
||||
matrix_mode = !matrix_mode
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["matrix_paint"])
|
||||
if(!inserted)
|
||||
return
|
||||
// assemble matrix
|
||||
var/list/cm = rgb_construct_color_matrix(
|
||||
text2num(href_list["rr"]),
|
||||
text2num(href_list["rg"]),
|
||||
text2num(href_list["rb"]),
|
||||
text2num(href_list["gr"]),
|
||||
text2num(href_list["gg"]),
|
||||
text2num(href_list["gb"]),
|
||||
text2num(href_list["br"]),
|
||||
text2num(href_list["bg"]),
|
||||
text2num(href_list["bb"]),
|
||||
text2num(href_list["cr"]),
|
||||
text2num(href_list["cg"]),
|
||||
text2num(href_list["cb"])
|
||||
)
|
||||
color_matrix_last = cm.Copy()
|
||||
if(!check_valid_color(cm, usr))
|
||||
return
|
||||
inserted.add_atom_colour(cm, FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["clear"])
|
||||
if(!inserted)
|
||||
return
|
||||
inserted.remove_atom_colour(FIXED_COLOUR_PRIORITY)
|
||||
playsound(src, 'sound/effects/spray3.ogg', 50, 1)
|
||||
updateUsrDialog()
|
||||
|
||||
if(href_list["eject"])
|
||||
if(!inserted)
|
||||
return
|
||||
inserted.forceMove(drop_location())
|
||||
inserted = null
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
. = preview
|
||||
|
||||
/obj/machinery/gear_painter/proc/check_valid_color(list/cm, mob/user)
|
||||
if(!islist(cm)) // normal
|
||||
var/list/HSV = ReadHSV(RGBtoHSV(cm))
|
||||
if(HSV[3] < minimum_normal_lightness)
|
||||
to_chat(user, "<span class='warning'>[cm] is far too dark (min lightness [minimum_normal_lightness]!</span>")
|
||||
temp = "[cm] is far too dark (min lightness [minimum_normal_lightness]!"
|
||||
return FALSE
|
||||
return TRUE
|
||||
else // matrix
|
||||
@@ -245,6 +274,6 @@
|
||||
COLORTEST("FFFFFF", cm)
|
||||
#undef COLORTEST
|
||||
if(passed < minimum_matrix_tests)
|
||||
to_chat(user, "<span class='warning'>[english_list(color)] is not allowed (pased [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness]).</span>")
|
||||
temp = "[english_list(color)] is not allowed (passed [passed] out of 4, minimum [minimum_matrix_tests], minimum lightness [minimum_matrix_lightness])."
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -17,12 +17,8 @@
|
||||
|
||||
/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C)
|
||||
. = ..()
|
||||
|
||||
power_change()
|
||||
|
||||
/obj/machinery/computer/Destroy()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/computer/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
@@ -119,6 +115,9 @@
|
||||
A.circuit = circuit
|
||||
// Circuit removal code is handled in /obj/machinery/Exited()
|
||||
circuit.forceMove(A)
|
||||
// no it's not 4head the circuit's in nullspace which means this won't be called!!
|
||||
circuit = null
|
||||
component_parts -= circuit
|
||||
A.set_anchored(TRUE)
|
||||
if(stat & BROKEN)
|
||||
if(user)
|
||||
|
||||
@@ -176,15 +176,6 @@
|
||||
table[y1][x1] -= 10
|
||||
else if(table[y1][x1] < 0) //If flagged, remove the flag
|
||||
table[y1][x1] += 10
|
||||
if(href_list["same_board"]) //Reset the board... kinda
|
||||
if(game_status != MINESWEEPER_GAME_PLAYING)
|
||||
mine_sound = TRUE
|
||||
game_status = MINESWEEPER_GAME_PLAYING
|
||||
if(table[y1][x1] >= 10) //If revealed, become unrevealed!
|
||||
if(mine_sound)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
mine_sound = FALSE
|
||||
table[y1][x1] -= 10
|
||||
if(table[y1][x1] > 10 && !reset_board)
|
||||
safe_squares_revealed += 1
|
||||
var/y2 = y1
|
||||
@@ -274,10 +265,10 @@
|
||||
prizevend(user, dope_prizes)
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_WON)
|
||||
web += "[(rows < 10 || columns < 10) ? "<font size='4'>You won, but your board was too small! Pick a bigger board next time!" : "<font size='6'>Congratulations, you have won!"]<br><font size='3'>Want to play again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];same_board=1'><font color='#cc66ff'>Play on the same board</font></a><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
web += "[(rows < 10 || columns < 10) ? "<font size='4'>You won, but your board was too small! Pick a bigger board next time!" : "<font size='6'>Congratulations, you have won!"]<br><font size='3'>Want to play again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_LOST)
|
||||
web += "<font size='6'>You have lost!<br><font size='3'>Try again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];same_board=1'><font color='#cc66ff'>Play on the same board</font></a><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
web += "<font size='6'>You have lost!<br><font size='3'>Try again?<br><b><a href='byond://?src=[REF(src)];Easy=1'><font color='#cc66ff'>Easy (9x9 board, 10 mines)</font></a><br><a href='byond://?src=[REF(src)];Intermediate=1'><font color='#cc66ff'>Intermediate (16x16 board, 40 mines)</font></a><br><a href='byond://?src=[REF(src)];Hard=1'><font color='#cc66ff'>Hard (16x30 board, 99 mines)</font></a><br><a href='byond://?src=[REF(src)];Custom=1'><font color='#cc66ff'>Custom</font></a></b><br><a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a></b><br>"
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_PLAYING)
|
||||
web += "<a href='byond://?src=[REF(src)];Main_Menu=1'><font color='#cc66ff'>Return to Main Menu</font></a><br>"
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
|
||||
new_computer.RefreshParts()
|
||||
new_computer.on_construction()
|
||||
new_computer.circuit.moveToNullspace()
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -200,6 +200,9 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
||||
return b["totaldam"] - a["totaldam"]
|
||||
|
||||
/datum/crewmonitor/ui_act(action,params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(!istype(AI))
|
||||
return
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
.["machine"]["chang_freq_value"] = change_freq_value
|
||||
|
||||
/obj/machinery/telecomms/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!canInteract(usr))
|
||||
if(ui)
|
||||
ui.close() //haha no.
|
||||
|
||||
@@ -269,6 +269,10 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
. = ..()
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/radio/headset/silicon/pai/emp_act(severity)
|
||||
. = ..()
|
||||
return EMP_PROTECT_SELF
|
||||
|
||||
/obj/item/radio/headset/silicon/ai
|
||||
name = "\proper Integrated Subspace Transceiver "
|
||||
keyslot2 = new /obj/item/encryptionkey/ai
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
/obj/item/dice/d100
|
||||
)
|
||||
|
||||
/obj/item/storage/dice/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.can_hold = single_path_typecache_immutable(/obj/item/dice)
|
||||
|
||||
/obj/item/storage/dice/PopulateContents()
|
||||
new /obj/item/dice/d4(src)
|
||||
new /obj/item/dice/d6(src)
|
||||
|
||||
@@ -535,13 +535,13 @@
|
||||
oneuse = FALSE
|
||||
remarks = list("Looks like these would sell much better in a plasma fire...", "Using glass bowls rather then cones?", "Mixing soda and ice-cream?", "Tall glasses with of liquids and solids...", "Just add a bit of icecream and cherry on top?")
|
||||
|
||||
/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers
|
||||
/*/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers
|
||||
name = "bowyery sandstone slab" // this is an actual word
|
||||
desc = "A sandstone slab with inscriptions describing the Ash Walkers of Lavaland's bowyery."
|
||||
crafting_recipe_types = list(/datum/crafting_recipe/bone_arrow, /datum/crafting_recipe/bone_bow, /datum/crafting_recipe/ashen_arrow, /datum/crafting_recipe/quiver, /datum/crafting_recipe/bow_tablet)
|
||||
icon_state = "stone_tablet"
|
||||
oneuse = FALSE
|
||||
remarks = list("Sticking burning arrows into the sand makes them stronger...", "Breaking the bone apart to get shards, not sharpening the bone...", "Sinew is just like rope...")
|
||||
remarks = list("Sticking burning arrows into the sand makes them stronger...", "Breaking the bone apart to get shards, not sharpening the bone...", "Sinew is just like rope...")*/
|
||||
|
||||
/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book
|
||||
name = "Under The Oven"
|
||||
|
||||
@@ -238,72 +238,73 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3
|
||||
var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I?
|
||||
var/concern = 20 //perhaps something might cloud true love with doubt
|
||||
var/loyalty = 30 //why should another get between us?
|
||||
var/duty = 50 //conquering another's is what I live for
|
||||
/obj/item/toy/plush/proc/love(obj/item/toy/plush/Kisser, mob/living/user) //~<3
|
||||
var/chance = 100 //to steal a kiss, surely there's a 100% chance no-one would reject a plush such as I?
|
||||
var/concern = 20 //perhaps something might cloud true love with doubt
|
||||
var/loyalty = 30 //why should another get between us?
|
||||
var/duty = 50 //conquering another's is what I live for
|
||||
|
||||
//we are not catholic
|
||||
if(young == TRUE || Kisser.young == TRUE)
|
||||
user.show_message("<span class='notice'>[src] plays tag with [Kisser].</span>", MSG_VISUAL,
|
||||
"<span class='notice'>They're happy.</span>", 0)
|
||||
user.show_message(span_notice("[src] plays tag with [Kisser]."), MSG_VISUAL,
|
||||
span_notice("They're happy."), NONE)
|
||||
Kisser.cheer_up()
|
||||
cheer_up()
|
||||
|
||||
//never again
|
||||
else if(Kisser in scorned)
|
||||
//message, visible, alternate message, neither visible nor audible
|
||||
user.show_message("<span class='notice'>[src] rejects the advances of [Kisser]!</span>", MSG_VISUAL,
|
||||
"<span class='notice'>That didn't feel like it worked.</span>", 0)
|
||||
user.show_message(span_notice("[src] rejects the advances of [Kisser]!"), MSG_VISUAL,
|
||||
span_notice("That didn't feel like it worked."), NONE)
|
||||
else if(src in Kisser.scorned)
|
||||
user.show_message("<span class='notice'>[Kisser] realises who [src] is and turns away.</span>", MSG_VISUAL,
|
||||
"<span class='notice'>That didn't feel like it worked.</span>", 0)
|
||||
user.show_message(span_notice("[Kisser] realises who [src] is and turns away."), MSG_VISUAL,
|
||||
span_notice("That didn't feel like it worked."), NONE)
|
||||
|
||||
//first comes love
|
||||
else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married
|
||||
if(Kisser.lover) //if the initiator has a lover
|
||||
Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun
|
||||
chance -= concern //one heart already broken, what does another mean?
|
||||
if(lover) //if the recipient has a lover
|
||||
chance -= loyalty //mustn't... but those lips
|
||||
if(partner) //if the recipient has a partner
|
||||
chance -= duty //do we mate for life?
|
||||
else if(Kisser.lover != src && Kisser.partner != src) //cannot be lovers or married
|
||||
if(Kisser.lover) //if the initiator has a lover
|
||||
Kisser.lover.heartbreak(Kisser) //the old lover can get over the kiss-and-run whilst the kisser has some fun
|
||||
chance -= concern //one heart already broken, what does another mean?
|
||||
if(lover) //if the recipient has a lover
|
||||
chance -= loyalty //mustn't... but those lips
|
||||
if(partner) //if the recipient has a partner
|
||||
chance -= duty //do we mate for life?
|
||||
|
||||
if(prob(chance)) //did we bag a date?
|
||||
user.visible_message("<span class='notice'>[user] makes [Kisser] kiss [src]!</span>",
|
||||
"<span class='notice'>You make [Kisser] kiss [src]!</span>")
|
||||
if(lover) //who cares for the past, we live in the present
|
||||
if(prob(chance)) //did we bag a date?
|
||||
user.visible_message(span_notice("[user] makes [Kisser] kiss [src]!"),
|
||||
span_notice("You make [Kisser] kiss [src]!"))
|
||||
if(lover) //who cares for the past, we live in the present
|
||||
lover.heartbreak(src)
|
||||
new_lover(Kisser)
|
||||
Kisser.new_lover(src)
|
||||
else
|
||||
user.show_message("<span class='notice'>[src] rejects the advances of [Kisser], maybe next time?</span>", MSG_VISUAL,
|
||||
"<span class='notice'>That didn't feel like it worked, this time.</span>", 0)
|
||||
user.show_message(span_notice("[src] rejects the advances of [Kisser], maybe next time?"), MSG_VISUAL,
|
||||
span_notice("That didn't feel like it worked, this time."), NONE)
|
||||
|
||||
//then comes marriage
|
||||
else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar)
|
||||
user.visible_message("<span class='notice'>[user] pronounces [Kisser] and [src] married! D'aw.</span>",
|
||||
"<span class='notice'>You pronounce [Kisser] and [src] married!</span>")
|
||||
else if(Kisser.lover == src && Kisser.partner != src) //need to be lovers (assumes loving is a two way street) but not married (also assumes similar)
|
||||
user.visible_message(span_notice("[user] pronounces [Kisser] and [src] married! D'aw."),
|
||||
span_notice("You pronounce [Kisser] and [src] married!"))
|
||||
new_partner(Kisser)
|
||||
Kisser.new_partner(src)
|
||||
|
||||
//then comes a baby in a baby's carriage, or an adoption in an adoption's orphanage
|
||||
else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop
|
||||
user.visible_message("<span class='notice'>[user] is going to break [Kisser] and [src] by bashing them like that.</span>",
|
||||
"<span class='notice'>[Kisser] passionately embraces [src] in your hands. Look away you perv!</span>")
|
||||
else if(Kisser.partner == src && !plush_child) //the one advancing does not take ownership of the child and we have a one child policy in the toyshop
|
||||
user.visible_message(span_notice("[user] is going to break [Kisser] and [src] by bashing them like that."),
|
||||
span_notice("[Kisser] passionately embraces [src] in your hands. Look away you perv!"))
|
||||
user.client.give_award(/datum/award/achievement/misc/rule8, user)
|
||||
if(plop(Kisser))
|
||||
user.visible_message("<span class='notice'>Something drops at the feet of [user].</span>",
|
||||
"<span class='notice'>The miracle of oh god did that just come out of [src]?!</span>")
|
||||
user.visible_message(span_notice("Something drops at the feet of [user]."),
|
||||
span_notice("The miracle of oh god did that just come out of [src]?!"))
|
||||
|
||||
//then comes protection, or abstinence if we are catholic
|
||||
else if(Kisser.partner == src && plush_child)
|
||||
user.visible_message("<span class='notice'>[user] makes [Kisser] nuzzle [src]!</span>",
|
||||
"<span class='notice'>You make [Kisser] nuzzle [src]!</span>")
|
||||
user.visible_message(span_notice("[user] makes [Kisser] nuzzle [src]!"),
|
||||
span_notice("You make [Kisser] nuzzle [src]!"))
|
||||
|
||||
//then oh fuck something unexpected happened
|
||||
else
|
||||
user.show_message("<span class='warning'>[Kisser] and [src] don't know what to do with one another.</span>", 0)
|
||||
user.show_message(span_warning("[Kisser] and [src] don't know what to do with one another."), NONE)
|
||||
|
||||
/obj/item/toy/plush/proc/heartbreak(obj/item/toy/plush/Brutus)
|
||||
if(lover != Brutus)
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
animate(effect, alpha = 0, pixel_x = px * 1.5, pixel_y = py * 1.5, time = 3, flags = ANIMATION_PARALLEL | ANIMATION_RELATIVE)
|
||||
|
||||
/obj/item/shield/proc/bash_target(mob/living/user, mob/living/target, bashdir, harmful)
|
||||
if(!(target.status_flags & CANKNOCKDOWN) || HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess..
|
||||
if(!(HAS_TRAIT(target, CANKNOCKDOWN)) || HAS_TRAIT(target, TRAIT_STUNIMMUNE)) // should probably add stun absorption check at some point I guess..
|
||||
// unified stun absorption system when lol
|
||||
target.visible_message("<span class='warning'>[user] slams [target] with [src], but [target] doesn't falter!</span>", "<span class='userdanger'>[user] slams you with [src], but it barely fazes you!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
/obj/item/storage/belt/mining/primitive/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 5
|
||||
STR.max_items = 8
|
||||
|
||||
/obj/item/storage/belt/soulstone
|
||||
name = "soul stone belt"
|
||||
|
||||
@@ -79,6 +79,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
name = "mechanical toolbox"
|
||||
icon_state = "blue"
|
||||
item_state = "toolbox_blue"
|
||||
/// If FALSE, someone with a ensouled soulstone can sacrifice a spirit to change the sprite of this toolbox.
|
||||
var/has_soul = FALSE
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/PopulateContents()
|
||||
new /obj/item/screwdriver(src)
|
||||
@@ -93,6 +95,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
icon_state = "toolbox_blue_old"
|
||||
has_latches = FALSE
|
||||
can_rubberify = FALSE
|
||||
has_soul = TRUE
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/old/heirloom
|
||||
name = "old, robust toolbox" //this will be named "X family toolbox"
|
||||
@@ -126,7 +129,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
/obj/item/storage/toolbox/mechanical/old/clean/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
calc_damage()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/storage/toolbox/mechanical/old/clean/PopulateContents()
|
||||
new /obj/item/screwdriver(src)
|
||||
new /obj/item/wrench(src)
|
||||
|
||||
@@ -41,6 +41,13 @@
|
||||
/obj/item/crowbar/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/crowbar/ashwalker
|
||||
name = "bone crowbar"
|
||||
desc = "A rudimentary crowbar made of bones."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "crowbar_bone"
|
||||
toolspeed = 0.75
|
||||
|
||||
/obj/item/crowbar/bronze
|
||||
name = "bronze plated crowbar"
|
||||
desc = "A bronze plated crowbar."
|
||||
|
||||
@@ -93,6 +93,14 @@
|
||||
/obj/item/screwdriver/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/screwdriver/ashwalker
|
||||
name = "bone screwdriver"
|
||||
desc = "A rudimentary screwdriver made of carved bones."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "screwdriver_bone"
|
||||
toolspeed = 0.75
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/screwdriver/bronze
|
||||
name = "bronze screwdriver"
|
||||
desc = "A screwdriver plated with bronze."
|
||||
|
||||
@@ -385,6 +385,16 @@
|
||||
icon_state = "clockwelder"
|
||||
item_state = "brasswelder"
|
||||
|
||||
/obj/item/weldingtool/experimental/ashwalker
|
||||
name = "necropolis welding torch"
|
||||
desc = "A mysterious welding tool with its origins in the depths of the necropolis. A mysterious force keeps replenishing its fuel."
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
refueling_interval = 5
|
||||
toolspeed = 0.75
|
||||
max_fuel = 20
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "ashwelder"
|
||||
|
||||
/obj/item/weldingtool/abductor
|
||||
name = "alien welding tool"
|
||||
desc = "An alien welding tool. Whatever fuel it uses, it never runs out."
|
||||
|
||||
@@ -90,6 +90,14 @@
|
||||
/obj/item/wirecutters/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/wirecutters/ashwalker
|
||||
name = "bone wirecutters"
|
||||
desc = "Rudimentary wirecutters made out of sharpened bones and sinew."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "cutters_bone"
|
||||
toolspeed = 0.75
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/wirecutters/bronze
|
||||
name = "bronze plated wirecutters"
|
||||
desc = "A pair of wirecutters plated with bronze."
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
/obj/item/wrench/brass/family
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/wrench/ashwalker
|
||||
name = "bone wrench"
|
||||
desc = "A shoddy wrench made out of bent bones and sinew."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "wrench_bone"
|
||||
toolspeed = 0.75
|
||||
|
||||
/obj/item/wrench/bronze
|
||||
name = "bronze plated wrench"
|
||||
desc = "A bronze plated wrench."
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
//returns the damage value of the attack after processing the obj's various armor protections
|
||||
/obj/proc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0)
|
||||
if(damage_flag == MELEE && damage_amount < damage_deflection)
|
||||
if(damage_flag == "melee" && damage_amount < damage_deflection) // TODO: Refactor armor datums and types entirely jfc
|
||||
return 0
|
||||
switch(damage_type)
|
||||
if(BRUTE)
|
||||
|
||||
@@ -66,12 +66,6 @@
|
||||
|
||||
//Ash walkers on birth understand how to make bone bows, bone arrows and ashen arrows
|
||||
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_arrow)
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_bow)
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/ashen_arrow)
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/quiver)
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bow_tablet)
|
||||
|
||||
if(ishuman(new_spawn))
|
||||
var/mob/living/carbon/human/H = new_spawn
|
||||
H.underwear = "Nude"
|
||||
@@ -634,9 +628,9 @@
|
||||
log_game("[key_name(user)] has successfully pried open [src] and disabled a space pirate spawner.")
|
||||
W.play_tool_sound(src)
|
||||
playsound(src.loc, 'modular_citadel/sound/voice/scream_skeleton.ogg', 50, 1, 4, 1.2)
|
||||
if(rank == "Captain")
|
||||
if(rank == "Captain")
|
||||
new /obj/effect/mob_spawn/human/pirate/corpse/captain(get_turf(src))
|
||||
else
|
||||
else
|
||||
new /obj/effect/mob_spawn/human/pirate/corpse(get_turf(src))
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
GLOBAL_VAR(restart_counter)
|
||||
|
||||
GLOBAL_VAR_INIT(tgs_initialized, FALSE)
|
||||
|
||||
GLOBAL_VAR(topic_status_lastcache)
|
||||
GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
@@ -76,7 +74,6 @@ GLOBAL_LIST(topic_status_cache)
|
||||
/world/proc/InitTgs()
|
||||
TgsNew(new /datum/tgs_event_handler/impl, TGS_SECURITY_TRUSTED)
|
||||
GLOB.revdata.load_tgs_info()
|
||||
GLOB.tgs_initialized = TRUE
|
||||
|
||||
/world/proc/HandleTestRun()
|
||||
//trigger things to run the whole process
|
||||
|
||||
@@ -226,16 +226,16 @@
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shed_human_form)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
var/datum/antagonist/heretic/heretic = user.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
var/datum/eldritch_knowledge/flesh_grasp/ghoul1 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_grasp)
|
||||
ghoul1.ghoul_amt *= 3
|
||||
var/datum/eldritch_knowledge/flesh_ghoul/ghoul2 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul)
|
||||
ghoul2.max_amt *= 3
|
||||
var/mob/living/carbon/human/lord_of_arms = user
|
||||
lord_of_arms.physiology.brute_mod *= 0.5
|
||||
lord_of_arms.physiology.burn_mod *= 0.5
|
||||
lord_of_arms.client?.give_award(/datum/award/achievement/misc/flesh_ascension, lord_of_arms)
|
||||
var/datum/antagonist/heretic/heretic_datum = user.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
var/datum/eldritch_knowledge/flesh_grasp/grasp_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_grasp)
|
||||
grasp_ghoul.ghoul_amt *= 3
|
||||
var/datum/eldritch_knowledge/flesh_ghoul/better_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul)
|
||||
better_ghoul.max_amt *= 3
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/flesh_blade_upgrade_2
|
||||
name = "Remembrance"
|
||||
|
||||
@@ -181,13 +181,13 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
H.client?.give_award(/datum/award/achievement/misc/rust_ascension, H)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
new /datum/rust_spread(loc)
|
||||
var/datum/antagonist/heretic/ascension = H.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
ascension.ascended = TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/eldritch_knowledge/final/rust_final/on_life(mob/user)
|
||||
. = ..()
|
||||
if(!finished)
|
||||
|
||||
@@ -183,14 +183,14 @@
|
||||
var/datum/weather/void_storm/storm
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final/on_finished_recipe(mob/living/user, list/atoms, loc)
|
||||
var/mob/living/carbon/human/H = user
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch)
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
ADD_TRAIT(H, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
|
||||
sound_loop = new(list(user),TRUE,TRUE)
|
||||
var/mob/living/carbon/human/waltzing = user
|
||||
waltzing.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch)
|
||||
waltzing.physiology.brute_mod *= 0.5
|
||||
waltzing.physiology.burn_mod *= 0.5
|
||||
ADD_TRAIT(waltzing, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
|
||||
waltzing.client?.give_award(/datum/award/achievement/misc/void_ascension, waltzing)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [waltzing.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
sound_loop = new(user, TRUE, TRUE)
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final/on_death()
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
A.death()
|
||||
return ..()
|
||||
|
||||
/obj/item/soulstone/proc/hot_potato(mob/living/user)
|
||||
to_chat(user, span_userdanger("Holy magics residing in \the [src] burn your hand!"))
|
||||
var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
|
||||
affecting.receive_damage( 0, 10 ) // 10 burn damage
|
||||
user.emote("scream")
|
||||
user.update_damage_overlays()
|
||||
user.dropItemToGround(src)
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user)
|
||||
@@ -94,6 +102,35 @@
|
||||
to_chat(A, "<b>You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.</b>")
|
||||
was_used()
|
||||
|
||||
/obj/item/soulstone/pre_attack(atom/A, mob/living/user, params)
|
||||
var/mob/living/simple_animal/hostile/construct/shade/occupant = (locate() in src)
|
||||
var/obj/item/storage/toolbox/mechanical/target_toolbox = A
|
||||
if(!occupant || !istype(target_toolbox) || target_toolbox.has_soul)
|
||||
return ..()
|
||||
|
||||
if(iscultist(user))
|
||||
hot_potato(user)
|
||||
return
|
||||
if(!iscultist(user, TRUE) && !iswizard(user) && !usability)
|
||||
user.Unconscious(10 SECONDS)
|
||||
to_chat(user, span_userdanger("Your body is wracked with debilitating pain!"))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] holds [src] above [user.p_their()] head and forces it into [target_toolbox] with a flash of light!", \
|
||||
span_notice("You hold [src] above your head briefly, then force it into [target_toolbox], transferring the [occupant]'s soul!"), ignored_mobs = occupant)
|
||||
to_chat(occupant, span_userdanger("[user] holds you up briefly, then forces you into [target_toolbox]!"))
|
||||
to_chat(occupant, span_deadsay("<b>Your eternal soul has been sacrificed to restore the soul of a toolbox. Them's the breaks!</b>"))
|
||||
|
||||
occupant.client?.give_award(/datum/award/achievement/misc/toolbox_soul, occupant)
|
||||
occupant.deathmessage = "shrieks out in unholy pain as [occupant.p_their()] soul is absorbed into [target_toolbox]!"
|
||||
release_shades(user, TRUE)
|
||||
occupant.death()
|
||||
|
||||
target_toolbox.name = "soulful toolbox"
|
||||
target_toolbox.icon_state = "toolbox_blue_old"
|
||||
target_toolbox.has_soul = TRUE
|
||||
target_toolbox.has_latches = FALSE
|
||||
|
||||
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
|
||||
/obj/structure/constructshell
|
||||
name = "empty shell"
|
||||
|
||||
@@ -11,6 +11,10 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
|
||||
/datum/asset
|
||||
var/_abstract = /datum/asset
|
||||
var/cached_url_mappings
|
||||
|
||||
/// Whether or not this asset should be loaded in the "early assets" SS
|
||||
var/early = FALSE
|
||||
|
||||
/datum/asset/New()
|
||||
GLOB.asset_datums[type] = src
|
||||
@@ -19,6 +23,13 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
/datum/asset/proc/get_url_mappings()
|
||||
return list()
|
||||
|
||||
/// Returns a cached tgui message of URL mappings
|
||||
/datum/asset/proc/get_serialized_url_mappings()
|
||||
if (isnull(cached_url_mappings))
|
||||
cached_url_mappings = TGUI_CREATE_MESSAGE("asset/mappings", get_url_mappings())
|
||||
|
||||
return cached_url_mappings
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
@@ -169,6 +180,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
|
||||
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
|
||||
return
|
||||
//any sprite modifications we want to do (aka, coloring a greyscaled asset)
|
||||
I = ModifyInserted(I)
|
||||
var/size_id = "[I.Width()]x[I.Height()]"
|
||||
var/size = sizes[size_id]
|
||||
|
||||
@@ -185,6 +198,15 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
sizes[size_id] = size = list(1, I, null)
|
||||
sprites[sprite_name] = list(size_id, 0)
|
||||
|
||||
/**
|
||||
* A simple proc handing the Icon for you to modify before it gets turned into an asset.
|
||||
*
|
||||
* Arguments:
|
||||
* * I: icon being turned into an asset
|
||||
*/
|
||||
/datum/asset/spritesheet/proc/ModifyInserted(icon/pre_asset)
|
||||
return pre_asset
|
||||
|
||||
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
|
||||
if (length(prefix))
|
||||
prefix = "[prefix]-"
|
||||
@@ -217,6 +239,19 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
return {"[name][size_id] [sprite_name]"}
|
||||
|
||||
/**
|
||||
* Returns the size class (ex design32x32) for a given sprite's icon
|
||||
*
|
||||
* Arguments:
|
||||
* * sprite_name - The sprite to get the size of
|
||||
*/
|
||||
/datum/asset/spritesheet/proc/icon_size_id(sprite_name)
|
||||
var/sprite = sprites[sprite_name]
|
||||
if (!sprite)
|
||||
return null
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
return "[name][size_id]"
|
||||
|
||||
#undef SPR_SIZE
|
||||
#undef SPR_IDX
|
||||
#undef SPRSZ_COUNT
|
||||
@@ -224,6 +259,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
#undef SPRSZ_STRIPPED
|
||||
|
||||
|
||||
/datum/asset/changelog_item
|
||||
_abstract = /datum/asset/changelog_item
|
||||
var/item_filename
|
||||
|
||||
/datum/asset/changelog_item/New(date)
|
||||
item_filename = sanitize_filename("[date].yml")
|
||||
SSassets.transport.register_asset(item_filename, file("html/changelogs/archive/" + item_filename))
|
||||
|
||||
/datum/asset/changelog_item/send(client)
|
||||
if (!item_filename)
|
||||
return
|
||||
. = SSassets.transport.send_assets(client, item_filename)
|
||||
|
||||
/datum/asset/changelog_item/get_url_mappings()
|
||||
if (!item_filename)
|
||||
return
|
||||
. = list("[item_filename]" = SSassets.transport.get_asset_url(item_filename))
|
||||
|
||||
/datum/asset/spritesheet/simple
|
||||
_abstract = /datum/asset/spritesheet/simple
|
||||
var/list/assets
|
||||
@@ -315,3 +368,28 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
/datum/asset/simple/namespaced/proc/get_htmlloader(filename)
|
||||
return url2htmlloader(SSassets.transport.get_asset_url(filename, assets[filename]))
|
||||
|
||||
/// A subtype to generate a JSON file from a list
|
||||
/datum/asset/json
|
||||
_abstract = /datum/asset/json
|
||||
/// The filename, will be suffixed with ".json"
|
||||
var/name
|
||||
|
||||
/datum/asset/json/send(client)
|
||||
return SSassets.transport.send_assets(client, "data/[name].json")
|
||||
|
||||
/datum/asset/json/get_url_mappings()
|
||||
return list(
|
||||
"[name].json" = SSassets.transport.get_asset_url("data/[name].json"),
|
||||
)
|
||||
|
||||
/datum/asset/json/register()
|
||||
var/filename = "data/[name].json"
|
||||
fdel(filename)
|
||||
text2file(json_encode(generate()), filename)
|
||||
SSassets.transport.register_asset(filename, fcopy_rsc(filename))
|
||||
fdel(filename)
|
||||
|
||||
/// Returns the data that will be JSON encoded
|
||||
/datum/asset/json/proc/generate()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("generate() not implemented for [type]!")
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
. += "can-open"
|
||||
if(connected_port)
|
||||
. += "can-connector"
|
||||
var/pressure = air_contents.return_pressure()
|
||||
var/pressure = air_contents?.return_pressure()
|
||||
if(pressure >= 40 * ONE_ATMOSPHERE)
|
||||
. += "can-o3"
|
||||
else if(pressure >= 10 * ONE_ATMOSPHERE)
|
||||
@@ -295,6 +295,7 @@
|
||||
density = FALSE
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
||||
investigate_log("was destroyed.", INVESTIGATE_ATMOS)
|
||||
update_icon_state()
|
||||
|
||||
if(holding)
|
||||
holding.forceMove(T)
|
||||
|
||||
@@ -211,11 +211,6 @@
|
||||
unit_name = "arrow"
|
||||
export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ash)
|
||||
|
||||
/datum/export/weapon/bow_teaching
|
||||
cost = 500
|
||||
unit_name = "bowyery tablet"
|
||||
export_types = list(/obj/item/book/granter/crafting_recipe/bone_bow)
|
||||
|
||||
/datum/export/weapon/quiver
|
||||
cost = 100
|
||||
unit_name = "quiver"
|
||||
|
||||
@@ -128,6 +128,9 @@
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("LZCargo")
|
||||
usingBeacon = FALSE
|
||||
|
||||
@@ -67,6 +67,20 @@
|
||||
resistance_flags = NONE
|
||||
strip_mod = 1.2 // because apparently black gloves had this
|
||||
|
||||
/obj/item/clothing/gloves/tackler/combat/goliath
|
||||
name = "goliath gloves"
|
||||
desc = "Rudimentary tackling gloves. The goliath hide makes it great for grappling with targets, while also being fireproof."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goligloves"
|
||||
item_state = "goligloves"
|
||||
|
||||
tackle_stam_cost = 25
|
||||
base_knockdown = 1 SECONDS
|
||||
tackle_range = 5
|
||||
tackle_speed = 2
|
||||
min_distance = 2
|
||||
skill_mod = 1
|
||||
|
||||
/obj/item/clothing/gloves/tackler/combat/insulated
|
||||
name = "guerrilla gloves"
|
||||
desc = "Superior quality combative gloves, good for performing tackle takedowns as well as absorbing electrical shocks."
|
||||
|
||||
@@ -427,25 +427,30 @@
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel"
|
||||
item_state = "flannel"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/red
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/red
|
||||
name = "red flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_red"
|
||||
item_state = "flannel_red"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/aqua
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/aqua
|
||||
name = "aqua flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_aqua"
|
||||
item_state = "flannel_aqua"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/brown
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/brown
|
||||
name = "brown flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_brown"
|
||||
item_state = "flannel_brown"
|
||||
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/whitehoodie
|
||||
name = "soft hoodie"
|
||||
desc = "A soft hoodie with a TailorCo brand on the tag."
|
||||
icon_state = "white_hoodie"
|
||||
item_state = "white_hoodie"
|
||||
togglename = "zipper"
|
||||
/obj/item/clothing/suit/jacket/purplehoodie
|
||||
name = "purple hoodie"
|
||||
desc = "A soft purple hoodie with a TailorCo brand on the tag."
|
||||
@@ -482,6 +487,24 @@
|
||||
icon_state = "gothic_shirtcross"
|
||||
item_state = "gothic_shirtcross"
|
||||
|
||||
/obj/item/clothing/suit/jacket/gentlecoat
|
||||
name = "grey jacket"
|
||||
desc = "A grey coat with a TailorCo brand on the tag. Looks expensive."
|
||||
icon_state = "gentlecoat"
|
||||
item_state = "gentlecoat"
|
||||
|
||||
/obj/item/clothing/suit/toggle/jacket/greenjacket
|
||||
name = "green outdoorsmans jacket"
|
||||
desc = "A green jacket with a TailorCo brand on the tag. Looks expensive."
|
||||
icon_state = "coatar"
|
||||
item_state = "coatar"
|
||||
togglename = "zipper"
|
||||
/obj/item/clothing/suit/toggle/jacket/fancytrench
|
||||
name = "grey trenchcoat"
|
||||
desc = "A custom-tailored trenchcoat with a TailorCo brand on the tag."
|
||||
icon_state = "fancytrench"
|
||||
item_state = "fancytrench"
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/jacket/leather
|
||||
name = "leather jacket"
|
||||
desc = "Pompadour not included."
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
/area/holodeck,
|
||||
/area/shuttle,
|
||||
/area/maintenance,
|
||||
/area/science/test_area)
|
||||
/area/science/test_area,
|
||||
/area/commons/cryopod)
|
||||
)
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
|
||||
@@ -84,6 +84,12 @@
|
||||
user.visible_message("<span class='suicide'>[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/cultivator/bone
|
||||
name = "bone cultivator"
|
||||
desc = "A handle and a few bones tied together to resemble a hoe. Should work for removing weeds."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "cultivator_bone"
|
||||
|
||||
/obj/item/hatchet
|
||||
name = "hatchet"
|
||||
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
|
||||
@@ -112,6 +118,12 @@
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/hatchet/bone
|
||||
name = "bone hatchet"
|
||||
desc = "A primitive hatchet made out of mostly bone, with some sinew to keep it together. It just might do for cutting logs into planks."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "hatchet_bone"
|
||||
|
||||
/obj/item/scythe
|
||||
icon_state = "scythe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
instrument_flags = INSTRUMENT_LEGACY
|
||||
volume_multiplier = 1 //not as loud as synth'd
|
||||
|
||||
/datum/instrument/hardcoded/accordian
|
||||
name = "Accordian"
|
||||
id = "accordian"
|
||||
/datum/instrument/hardcoded/accordion
|
||||
name = "Accordion"
|
||||
id = "accordion"
|
||||
legacy_instrument_ext = "mid"
|
||||
legacy_instrument_path = "accordian"
|
||||
legacy_instrument_path = "accordion"
|
||||
|
||||
/datum/instrument/hardcoded/bikehorn
|
||||
name = "Bike Horn"
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
"60"='sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg',
|
||||
"72"='sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg')
|
||||
|
||||
/datum/instrument/organ/crisis_accordian
|
||||
name = "Crisis Accordian"
|
||||
/datum/instrument/organ/crisis_accordion
|
||||
name = "Crisis Accordion"
|
||||
id = "crack"
|
||||
real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg',
|
||||
"48"='sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg',
|
||||
@@ -34,8 +34,8 @@
|
||||
"60"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg',
|
||||
"72"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg')
|
||||
|
||||
/datum/instrument/organ/crisis_tango_accordian
|
||||
name = "Crisis Tango Accordian"
|
||||
/datum/instrument/organ/crisis_tango_accordion
|
||||
name = "Crisis Tango Accordion"
|
||||
id = "crtango"
|
||||
real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg',
|
||||
"48"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg',
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_PRISONER
|
||||
|
||||
/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_JOB_PRISONER]
|
||||
if(policy)
|
||||
var/mob/found = (M?.client && M) || (H?.client && H)
|
||||
to_chat(found, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(found, "<br><br>")
|
||||
to_chat(found, "<span class='boldnotice'>[policy]</span>")
|
||||
|
||||
/datum/outfit/job/prisoner
|
||||
name = "Prisoner"
|
||||
jobtype = /datum/job/prisoner
|
||||
|
||||
@@ -232,6 +232,9 @@
|
||||
return data
|
||||
|
||||
/obj/structure/chisel_message/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/mob/user = usr
|
||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||
var/is_creator = user.ckey == creator_key
|
||||
|
||||
@@ -228,6 +228,13 @@
|
||||
/obj/item/kinetic_crusher/glaive/update_icon_state()
|
||||
item_state = "crusher[wielded]-glaive" // this is not icon_state and not supported by 2hcomponent
|
||||
|
||||
/obj/item/kinetic_crusher/glaive/bone
|
||||
name = "necropolis bone glaive"
|
||||
desc = "Tribals trying to immitate technology have spent a long time to somehow assemble bits and pieces to work together just like the real thing. \
|
||||
Although it does take a lot of effort and luck to create, it was a success."
|
||||
icon_state = "crusher-bone"
|
||||
item_state = "crusher0-bone"
|
||||
|
||||
//destablizing force
|
||||
/obj/item/projectile/destabilizer
|
||||
name = "destabilizing force"
|
||||
|
||||
@@ -179,6 +179,12 @@
|
||||
custom_materials = list(/datum/material/iron=50)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/shovel/spade/bone
|
||||
name = "bone spade"
|
||||
desc = "A bone spade, suitable for digging and moving dirt."
|
||||
icon_state = "spade_bone"
|
||||
toolspeed = 0.75
|
||||
|
||||
/obj/item/shovel/serrated
|
||||
name = "serrated bone shovel"
|
||||
desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient lavaland tribal designs."
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
else
|
||||
emp_damage = max(emp_damage-1, 0)
|
||||
|
||||
/mob/living/brain/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/brain/handle_traits()
|
||||
return
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/mob/living/carbon/Moved()
|
||||
. = ..()
|
||||
if(. && (movement_type & FLOATING)) //floating is easy
|
||||
if(. && !CHECK_BITFIELD(movement_type, FLOATING)) //floating is easy
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
|
||||
@@ -83,6 +83,33 @@
|
||||
. += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]"
|
||||
. += "Absorbed DNA: [changeling.absorbedcount]"
|
||||
|
||||
//NINJACODE
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja.
|
||||
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
|
||||
. += "SpiderOS Status: [SN.s_initialized ? "Initialized" : "Disabled"]"
|
||||
. += "Current Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]"
|
||||
if(SN.s_initialized)
|
||||
//Suit gear
|
||||
. += "Energy Charge: [round(SN.cell.charge/100)]%"
|
||||
//Ninja status
|
||||
. += "Fingerprints: [md5(dna.uni_identity)]"
|
||||
. += "Unique Identity: [dna.unique_enzymes]"
|
||||
. += "Overall Status: [stat > 1 ? "dead" : "[health]% healthy"]"
|
||||
. += "Nutrition Status: [nutrition]"
|
||||
. += "Oxygen Loss: [getOxyLoss()]"
|
||||
. += "Toxin Levels: [getToxLoss()]"
|
||||
. += "Burn Severity: [getFireLoss()]"
|
||||
. += "Brute Trauma: [getBruteLoss()]"
|
||||
. += "Radiation Levels: [radiation] rad"
|
||||
. += "Body Temperature: [bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)"
|
||||
|
||||
//Diseases
|
||||
if(length(diseases))
|
||||
. += "Viruses:"
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
. += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]"
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
|
||||
@@ -1397,7 +1397,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
////////////
|
||||
|
||||
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
if(HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
return //hunger is for BABIES
|
||||
|
||||
//The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
|
||||
|
||||
@@ -570,24 +570,15 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "jittery")
|
||||
|
||||
if(stuttering)
|
||||
stuttering = max(stuttering-1, 0)
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(slurring || drunkenness)
|
||||
slurring = max(slurring-1,0,drunkenness)
|
||||
|
||||
if(cultslurring)
|
||||
cultslurring = max(cultslurring-1, 0)
|
||||
|
||||
if(clockcultslurring)
|
||||
clockcultslurring = max(clockcultslurring-1, 0)
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness-1,0)
|
||||
|
||||
if(silent)
|
||||
silent = max(silent-1, 0)
|
||||
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(hallucination)
|
||||
handle_hallucinations()
|
||||
|
||||
|
||||
@@ -150,11 +150,26 @@
|
||||
/mob/living/proc/handle_stomach()
|
||||
return
|
||||
|
||||
//this updates all special effects: knockdown, druggy, stuttering, etc..
|
||||
/*
|
||||
* this updates some effects: mostly old stuff such as drunkness, druggy, stuttering, etc.
|
||||
* that should be converted to status effect datums one day.
|
||||
*/
|
||||
/mob/living/proc/handle_status_effects()
|
||||
if(confused)
|
||||
confused = max(0, confused - 1)
|
||||
|
||||
if(stuttering)
|
||||
stuttering = max(stuttering-1, 0)
|
||||
|
||||
if(slurring)
|
||||
slurring = max(slurring-1,0)
|
||||
|
||||
if(cultslurring)
|
||||
cultslurring = max(cultslurring-1, 0)
|
||||
|
||||
if(clockcultslurring)
|
||||
clockcultslurring = max(clockcultslurring-1, 0)
|
||||
|
||||
/mob/living/proc/handle_traits()
|
||||
//Eyes
|
||||
if(eye_blind) //blindness, heals slowly over time
|
||||
|
||||
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Clickdelay duration post-parry if you fail to parry an attack
|
||||
var/parry_failed_clickcd_duration = 0 SECONDS
|
||||
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
|
||||
var/parry_failed_cooldown_duration = 0 SECONDS
|
||||
var/parry_failed_cooldown_duration = 3.5 SECONDS
|
||||
|
||||
// Advanced
|
||||
/// Flags added to return value
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define PAI_EMP_SILENCE_DURATION 3 MINUTES
|
||||
|
||||
/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
@@ -9,7 +7,7 @@
|
||||
return
|
||||
take_holo_damage(severity/2)
|
||||
DefaultCombatKnockdown(severity*4)
|
||||
silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity)
|
||||
short_radio()
|
||||
if(holoform)
|
||||
fold_in(force = TRUE)
|
||||
emitter_next_use = world.time + emitter_emp_cd
|
||||
|
||||
@@ -66,6 +66,7 @@ GLOBAL_LIST(bad_gremlin_items)
|
||||
/mob/living/simple_animal/hostile/gremlin/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT)
|
||||
access_card = new /obj/item/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
|
||||
@@ -95,20 +95,78 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne
|
||||
name = "Cayenne"
|
||||
real_name = "Cayenne"
|
||||
desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
|
||||
gender = FEMALE
|
||||
regen_amount = 8
|
||||
|
||||
speak_emote = list("squeaks")
|
||||
maxHealth = 90
|
||||
health = 90
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
faction = list(ROLE_SYNDICATE, "carp") //They are still a carp
|
||||
AIStatus = AI_OFF
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
faction = list(ROLE_SYNDICATE)
|
||||
/// Keeping track of the nuke disk for the functionality of storing it.
|
||||
var/obj/item/disk/nuclear/disky
|
||||
/// Location of the file storing disk overlays
|
||||
// var/icon/disk_overlay_file = 'icons/mob/carp.dmi'
|
||||
/// Colored disk mouth appearance for adding it as a mouth overlay
|
||||
var/mutable_appearance/colored_disk_mouth
|
||||
|
||||
harm_intent_damage = 12
|
||||
obj_damage = 70
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 18
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Initialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/pet_bonus, "bloops happily!")
|
||||
// colored_disk_mouth = mutable_appearance(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/carp/disk_mouth, greyscale_colors), "disk_mouth")
|
||||
ADD_TRAIT(src, TRAIT_DISK_VERIFIER, INNATE_TRAIT) //carp can verify disky
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/IsAdvancedToolUser()
|
||||
return TRUE //carp SMART
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/death(gibbed)
|
||||
if(disky)
|
||||
disky.forceMove(drop_location())
|
||||
disky = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Destroy(force)
|
||||
QDEL_NULL(disky)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/examine(mob/user)
|
||||
. = ..()
|
||||
if(disky)
|
||||
. += span_notice("Wait... is that [disky] in [p_their()] mouth?")
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/AttackingTarget(atom/attacked_target)
|
||||
if(istype(attacked_target, /obj/item/disk/nuclear))
|
||||
var/obj/item/disk/nuclear/potential_disky = attacked_target
|
||||
if(potential_disky.anchored)
|
||||
return
|
||||
potential_disky.forceMove(src)
|
||||
disky = potential_disky
|
||||
to_chat(src, span_nicegreen("YES!! You manage to pick up [disky]. (Click anywhere to place it back down.)"))
|
||||
update_icon()
|
||||
if(!disky.fake)
|
||||
client.give_award(/datum/award/achievement/misc/cayenne_disk, src)
|
||||
return
|
||||
if(disky)
|
||||
if(isopenturf(attacked_target))
|
||||
to_chat(src, span_notice("You place [disky] on [attacked_target]"))
|
||||
disky.forceMove(attacked_target.drop_location())
|
||||
disky = null
|
||||
update_icon()
|
||||
else
|
||||
disky.melee_attack_chain(src, attacked_target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(disky == gone)
|
||||
disky = null
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/update_overlays()
|
||||
. = ..()
|
||||
if(!disky || stat == DEAD)
|
||||
return
|
||||
// . += colored_disk_mouth
|
||||
// . += mutable_appearance(disk_overlay_file, "disk_overlay")
|
||||
|
||||
#undef REGENERATION_DELAY
|
||||
|
||||
@@ -32,6 +32,9 @@ Difficulty: Hard
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
achievement_type = /datum/award/achievement/boss/wendigo_kill
|
||||
crusher_achievement_type = /datum/award/achievement/boss/wendigo_crusher
|
||||
score_achievement_type = /datum/award/score/wendigo_score
|
||||
deathmessage = "falls, shaking the ground around it"
|
||||
deathsound = 'sound/effects/gravhit.ogg'
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp,
|
||||
|
||||
@@ -176,6 +176,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
elitemind = pick(candidates)
|
||||
elitemind.playsound_local(get_turf(elitemind), 'sound/effects/magic.ogg', 40, 0)
|
||||
to_chat(elitemind, "<b>You have been chosen to play as a Lavaland Elite.\nIn a few seconds, you will be summoned on Lavaland as a monster to fight your activator, in a fight to the death.\nYour attacks can be switched using the buttons on the top left of the HUD, and used by clicking on targets or tiles similar to a gun.\nWhile the opponent might have an upper hand with powerful mining equipment and tools, you have great power normally limited by AI mobs.\nIf you want to win, you'll have to use your powers in creative ways to ensure the kill. It's suggested you try using them all as soon as possible.\nShould you win, you'll receive extra information regarding what to do after. Good luck!</b>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_SPAWN]
|
||||
if(policy)
|
||||
to_chat(elitemind, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(elitemind, "<br><br>")
|
||||
to_chat(elitemind, "<span class='boldnotice'>[policy]</span>")
|
||||
addtimer(CALLBACK(src, .proc/spawn_elite, elitemind), 100)
|
||||
else
|
||||
visible_message("<span class='boldwarning'>The stirring stops, and nothing emerges. Perhaps try again later.</span>")
|
||||
@@ -304,6 +310,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
to_chat(mychild, "<span class='boldwarning'>As the life in the activator's eyes fade, the forcefield around you dies out and you feel your power subside.\nDespite this inferno being your home, you feel as if you aren't welcome here anymore.\nWithout any guidance, your purpose is now for you to decide.</span>")
|
||||
to_chat(mychild, "<b>Your max health has been halved, but can now heal by standing on your tumor. Note, it's your only way to heal.\nBear in mind, if anyone interacts with your tumor, you'll be resummoned here to carry out another fight. In such a case, you will regain your full max health.\nAlso, be weary of your fellow inhabitants, they likely won't be happy to see you!</b>")
|
||||
to_chat(mychild, "<span class='big bold'>Note that you are a lavaland monster, and thus not allied to the station. You should not cooperate or act friendly with any station crew unless under extreme circumstances!</span>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_WIN]
|
||||
if(policy)
|
||||
to_chat(mychild, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(mychild, "<br><br>")
|
||||
to_chat(mychild, "<span class='boldnotice'>[policy]</span>")
|
||||
|
||||
/obj/item/tumor_shard
|
||||
name = "tumor shard"
|
||||
@@ -332,6 +344,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
E.playsound_local(get_turf(E), 'sound/effects/magic.ogg', 40, 0)
|
||||
to_chat(E, "<span class='userdanger'>You have been revived by [user]. While you can't speak to them, you owe [user] a great debt. Assist [user.p_them()] in achieving [user.p_their()] goals, regardless of risk.</span")
|
||||
to_chat(E, "<span class='big bold'>Note that you now share the loyalties of [user]. You are expected not to intentionally sabotage their faction unless commanded to!</span>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_SENTIENCE]
|
||||
if(policy)
|
||||
to_chat(E, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(E, "<br><br>")
|
||||
to_chat(E, "<span class='boldnotice'>[policy]</span>")
|
||||
E.maxHealth = E.maxHealth * 0.5
|
||||
E.health = E.maxHealth
|
||||
E.desc = "[E.desc] However, this one appears appears less wild in nature, and calmer around people."
|
||||
|
||||
@@ -136,7 +136,7 @@ GLOBAL_LIST_EMPTY(plague_rats)
|
||||
if(LAZYLEN(GLOB.plague_rats) >= cap)
|
||||
visible_message("<span class='warning'>[src] gnaws into its food, [cap] rats are now on the station!</span>")
|
||||
return
|
||||
var/mob/living/newmouse = new /mob/living/simple_animal/hostile/plaguerat(loc)
|
||||
new /mob/living/simple_animal/hostile/plaguerat(loc)
|
||||
visible_message("<span class='notice'>[src] gnaws into its food, attracting another rat!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/plaguerat/proc/exit_vents()
|
||||
|
||||
@@ -195,12 +195,6 @@
|
||||
stat = CONSCIOUS
|
||||
med_hud_set_status()
|
||||
|
||||
|
||||
/mob/living/simple_animal/handle_status_effects()
|
||||
..()
|
||||
if(stuttering)
|
||||
stuttering = 0
|
||||
|
||||
/mob/living/simple_animal/proc/handle_automated_action()
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN
|
||||
movetypes = CRAWLING
|
||||
flags = IGNORE_NOSLOW
|
||||
priority = 20000
|
||||
|
||||
/datum/movespeed_modifier/mob_config_speedmod
|
||||
variable = TRUE
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
//Defines for the suit's unique abilities
|
||||
#define IS_NINJA_SUIT_INITIALIZATION(action) (istype(action, /datum/action/item_action/initialize_ninja_suit))
|
||||
#define IS_NINJA_SUIT_STATUS(action) (istype(action, /datum/action/item_action/ninjastatus))
|
||||
#define IS_NINJA_SUIT_BOOST(action) (istype(action, /datum/action/item_action/ninjaboost))
|
||||
#define IS_NINJA_SUIT_EMP(action) (istype(action, /datum/action/item_action/ninjapulse))
|
||||
#define IS_NINJA_SUIT_STAR_CREATION(action) (istype(action, /datum/action/item_action/ninjastar))
|
||||
|
||||
@@ -5,35 +5,3 @@
|
||||
button_icon_state = "health"
|
||||
icon_icon = 'icons/obj/device.dmi'
|
||||
var/action_background_icon_state = "bg_default_on"
|
||||
|
||||
/**
|
||||
* Proc called to put a status readout to the ninja in chat.
|
||||
*
|
||||
* Called put some information about the ninja's current status into chat.
|
||||
* This information used to be displayed constantly on the status tab screen
|
||||
* when the suit was on, but was turned into this as to remove the code from
|
||||
* human.dm
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjastatus()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/list/info_list = list()
|
||||
info_list += "<span class='info'>SpiderOS Status: [s_initialized ? "Initialized" : "Disabled"]</span>\n"
|
||||
//Ninja status
|
||||
info_list += "<span class='info'>Fingerprints: [md5(ninja.dna.uni_identity)]</span>\n"
|
||||
info_list += "<span class='info'>Unique Identity: [ninja.dna.unique_enzymes]</span>\n"
|
||||
info_list += "<span class='info'>Overall Status: [ninja.stat > 1 ? "dead" : "[ninja.health]% healthy"]</span>\n"
|
||||
info_list += "<span class='info'>Nutrition Status: [ninja.nutrition]</span>\n"
|
||||
info_list += "<span class='info'>Oxygen Loss: [ninja.getOxyLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Toxin Levels: [ninja.getToxLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Burn Severity: [ninja.getFireLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Brute Trauma: [ninja.getBruteLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Radiation Levels: [ninja.radiation] rad</span>\n"
|
||||
info_list += "<span class='info'>Body Temperature: [ninja.bodytemperature-T0C] degrees C ([ninja.bodytemperature*1.8-459.67] degrees F)</span>\n"
|
||||
|
||||
//Diseases
|
||||
if(length(ninja.diseases))
|
||||
info_list += "Viruses:"
|
||||
for(var/datum/disease/ninja_disease in ninja.diseases)
|
||||
info_list += "<span class='info'>* [ninja_disease.name], Type: [ninja_disease.spread_text], Stage: [ninja_disease.stage]/[ninja_disease.max_stages], Possible Cure: [ninja_disease.cure_text]</span>\n"
|
||||
|
||||
to_chat(ninja, "[info_list.Join()]")
|
||||
|
||||
@@ -121,9 +121,6 @@
|
||||
if(s_coold > 0)
|
||||
to_chat(user, "<span class='warning'><b>ERROR</b>: suit is on cooldown.</span>")
|
||||
return FALSE
|
||||
if(IS_NINJA_SUIT_STATUS(action))
|
||||
ninjastatus()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_BOOST(action))
|
||||
ninjaboost()
|
||||
return TRUE
|
||||
|
||||
@@ -23,4 +23,10 @@
|
||||
|
||||
/obj/item/ammo_box/magazine/mm712x82/match
|
||||
name = "box magazine (Match 7.12x82mm)"
|
||||
icon_state = "a762-50"
|
||||
ammo_type = /obj/item/ammo_casing/mm712x82/match
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/mm712x82/update_icon()
|
||||
..()
|
||||
icon_state = "a762-[round(ammo_count(),10)]"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
playsound(user, 'sound/weapons/shotguninsert.ogg', 60, 1)
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
user.SetNextAction(CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/process_chamber(mob/living/user, empty_chamber = 0)
|
||||
return ..() //changed argument value
|
||||
@@ -240,7 +241,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact
|
||||
name = "warden's combat shotgun"
|
||||
desc = "A modified version of the semi automatic combat shotgun with a collapsible stock. For close encounters."
|
||||
desc = "A modified version of the semi-automatic combat shotgun with a collapsible stock and a safety that prevents firing while folded. For close encounters."
|
||||
icon_state = "cshotgunc"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
@@ -250,7 +251,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)) || item_flags && IN_STORAGE)
|
||||
return
|
||||
toggle_stock(user)
|
||||
return TRUE
|
||||
@@ -276,6 +277,14 @@
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state()
|
||||
icon_state = "[current_skin ? unique_reskin[current_skin] : "cshotgun"][stock ? "" : "c"]"
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!stock)
|
||||
shoot_with_empty_chamber(user)
|
||||
to_chat(user, "<span class='warning'>[src] won't fire with a folded stock!</span>")
|
||||
else
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
//Dual Feed Shotgun
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/dual_tube
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/gun/magic/staff/motivation
|
||||
name = "Motivation"
|
||||
desc = "Rumored to have the ability to open up a portal the depths of Lavaland."
|
||||
desc = "Rumored to have the ability to open up a portal to the depths of Lavaland."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "motivation"
|
||||
item_state = "motivation"
|
||||
@@ -21,15 +21,15 @@
|
||||
recharge_rate = 5
|
||||
var/datum/action/judgement_cut/judgementcut = new/datum/action/judgement_cut()
|
||||
block_parry_data = /datum/block_parry_data/motivation
|
||||
|
||||
|
||||
//to get this to toggle correctly
|
||||
/obj/item/gun/magic/staff/motivation/Initialize()
|
||||
. = ..()
|
||||
judgementcut = new(src)
|
||||
|
||||
//lets the user know that their judgment cuts are recharging
|
||||
//lets the user know that their judgement cuts are recharging
|
||||
/obj/item/gun/magic/staff/motivation/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
to_chat(user, "<span class='warning'>Judgment Cut is recharging.</span>")
|
||||
to_chat(user, "<span class='warning'>Judgement Cut is recharging.</span>")
|
||||
|
||||
//action button to toggle judgement cuts on/off
|
||||
/datum/action/judgement_cut
|
||||
@@ -47,7 +47,7 @@
|
||||
/obj/item/gun/magic/staff/motivation/can_trigger_gun(mob/living/user)
|
||||
. = ..()
|
||||
if(!judgementcut.judgement_toggled)
|
||||
to_chat(user, "<span class='notice'> Judgment Cut is disabled.</span>")
|
||||
to_chat(user, "<span class='notice'>Judgement Cut is disabled.</span>")
|
||||
return FALSE
|
||||
|
||||
//adds/removes judgement cut and judgement cut end upon pickup/drop
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
else
|
||||
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
|
||||
D.add_atom_colour(mix_color_from_reagents(D.reagents.reagent_list), TEMPORARY_COLOUR_PRIORITY)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
last_spray = world.time
|
||||
INVOKE_ASYNC(D, /obj/effect/decal/chempuff/proc/run_puff, A)
|
||||
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@
|
||||
build_path = /obj/item/storage/bag/tray
|
||||
category = list("initial","Dinnerware")
|
||||
|
||||
/datum/design/tray
|
||||
/datum/design/cafeteria_tray
|
||||
name = "Cafeteria Tray"
|
||||
id = "foodtray"
|
||||
build_type = AUTOLATHE
|
||||
|
||||
@@ -242,13 +242,24 @@
|
||||
sleep(30)
|
||||
playsound(C, 'sound/machines/defib_zap.ogg', 50, FALSE)
|
||||
if(check_revivable())
|
||||
var/tplus = world.time - C.timeofdeath
|
||||
playsound(C, 'sound/machines/defib_success.ogg', 50, FALSE)
|
||||
C.set_heartattack(FALSE)
|
||||
var/oxydamage = C.getOxyLoss()
|
||||
if(C.health < HEALTH_THRESHOLD_FULLCRIT && oxydamage)
|
||||
var/diff = C.health - HEALTH_THRESHOLD_FULLCRIT
|
||||
C.adjustOxyLoss(diff) //Heal their oxydamage up to hardcrit (or if less, as much as they have, since the proc has sanity)
|
||||
C.revive(full_heal = FALSE, admin_revive = FALSE)
|
||||
C.emote("gasp")
|
||||
C.Jitter(100)
|
||||
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
|
||||
log_game("[C] has been successfully defibrillated by nanites.")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/timelimit = CONFIG_GET(number/defib_cmd_time_limit) * 10 //the config is in seconds, not deciseconds
|
||||
var/late = timelimit && (tplus > timelimit)
|
||||
var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
|
||||
if(policy)
|
||||
to_chat(C, policy)
|
||||
C.log_message("has been successfully defibrillated by nanites, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
|
||||
else
|
||||
playsound(C, 'sound/machines/defib_failed.ogg', 50, FALSE)
|
||||
|
||||
|
||||
@@ -59,13 +59,13 @@
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
@@ -121,12 +121,12 @@
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
@@ -184,11 +184,11 @@
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
@@ -243,11 +243,10 @@
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 150
|
||||
disable_threshold = 75
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
|
||||
@@ -48,6 +48,13 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/retractor/ashwalker
|
||||
name = "bontractor"
|
||||
desc = "Kinda looks like a chicken bone."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "retractor_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/hemostat
|
||||
name = "hemostat"
|
||||
desc = "You think you have seen this before."
|
||||
@@ -78,6 +85,14 @@
|
||||
toolspeed = 0.5
|
||||
attack_verb = list("attacked", "pinched")
|
||||
|
||||
/obj/item/hemostat/ashwalker
|
||||
name = "femurstat"
|
||||
desc = "Bones that are strapped together with sinews. Used to stop bleeding."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "hemostat_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
|
||||
/obj/item/cautery
|
||||
name = "cautery"
|
||||
desc = "This stops bleeding."
|
||||
@@ -108,6 +123,13 @@
|
||||
toolspeed = 0.5
|
||||
attack_verb = list("burnt")
|
||||
|
||||
/obj/item/cautery/ashwalker
|
||||
name = "coretery"
|
||||
desc = "A legion core strapped to a bone. It can close wounds."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "cautery_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/surgicaldrill
|
||||
name = "surgical drill"
|
||||
desc = "You can drill using this item. You dig?"
|
||||
@@ -257,6 +279,14 @@
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/scalpel/ashwalker
|
||||
name = "diamond scalpel"
|
||||
desc = "Bones and a Diamond tied together to make a scalpel."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "scalpel_bone"
|
||||
force = 12
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/circular_saw
|
||||
name = "circular saw"
|
||||
desc = "For heavy duty cutting."
|
||||
@@ -309,6 +339,14 @@
|
||||
attack_verb = list("attacked", "slashed", "sawed", "cut")
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/circular_saw/ashwalker
|
||||
name = "diamond bonesaw"
|
||||
desc = "Bones designed like a skull, with diamond teeth to cut through bones."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "saw_bone"
|
||||
force = 12
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/surgical_drapes
|
||||
name = "surgical drapes"
|
||||
desc = "Nanotrasen brand surgical drapes provide optimal safety and infection control."
|
||||
@@ -341,6 +379,13 @@
|
||||
prototype = SSresearch.techweb_design_by_id(id)
|
||||
. |= prototype.surgery
|
||||
|
||||
|
||||
/obj/item/surgical_drapes/goliath
|
||||
name = "goliath drapes"
|
||||
desc = "Probably not the most hygienic but what the heck else are you gonna use?"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "surgical_drapes_goli"
|
||||
|
||||
/obj/item/organ_storage //allows medical cyborgs to manipulate organs without hands
|
||||
name = "organ storage bag"
|
||||
desc = "A container for holding body parts."
|
||||
@@ -433,3 +478,10 @@
|
||||
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/bonesetter/bone
|
||||
name = "bone bonesetter"
|
||||
desc = "A bonesetter made of bones... for setting bones with... bones?"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bone setter_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
* return bool If the user's input has been handled and the UI should update.
|
||||
*/
|
||||
/datum/proc/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
// SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
// If UI is not interactive or usr calling Topic is not the UI user, bail.
|
||||
if(!ui || ui.status != UI_INTERACTIVE)
|
||||
return TRUE
|
||||
@@ -145,6 +145,7 @@
|
||||
* client/verb/uiclose(), which closes the ui window
|
||||
*/
|
||||
/datum/proc/ui_close(mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
/**
|
||||
* verb
|
||||
|
||||
@@ -58,11 +58,16 @@
|
||||
src.interface = interface
|
||||
if(title)
|
||||
src.title = title
|
||||
src.state = src_object.ui_state()
|
||||
src.state = src_object.ui_state(user)
|
||||
// Deprecated
|
||||
if(ui_x && ui_y)
|
||||
src.window_size = list(ui_x, ui_y)
|
||||
|
||||
/datum/tgui/Destroy()
|
||||
user = null
|
||||
src_object = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
* * title - The of the alert modal, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout.
|
||||
* * autofocus - The bool that controls if this alert should grab window focus.
|
||||
*/
|
||||
/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0)
|
||||
/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0, autofocus = TRUE)
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
@@ -18,7 +19,7 @@
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout)
|
||||
var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout, autofocus)
|
||||
alert.ui_interact(user)
|
||||
alert.wait()
|
||||
if (alert)
|
||||
@@ -36,8 +37,9 @@
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise.
|
||||
* * autofocus - The bool that controls if this alert should grab window focus.
|
||||
*/
|
||||
/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0)
|
||||
/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0, autofocus = TRUE)
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
@@ -46,7 +48,7 @@
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout)
|
||||
var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout, autofocus)
|
||||
alert.ui_interact(user)
|
||||
|
||||
/**
|
||||
@@ -68,13 +70,16 @@
|
||||
var/start_time
|
||||
/// The lifespan of the tgui_modal, after which the window will close and delete itself.
|
||||
var/timeout
|
||||
/// The bool that controls if this modal should grab window focus
|
||||
var/autofocus
|
||||
/// Boolean field describing if the tgui_modal was closed by the user.
|
||||
var/closed
|
||||
|
||||
/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout)
|
||||
/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout, autofocus)
|
||||
src.title = title
|
||||
src.message = message
|
||||
src.buttons = buttons.Copy()
|
||||
src.autofocus = autofocus
|
||||
if (timeout)
|
||||
src.timeout = timeout
|
||||
start_time = world.time
|
||||
@@ -110,7 +115,8 @@
|
||||
. = list(
|
||||
"title" = title,
|
||||
"message" = message,
|
||||
"buttons" = buttons
|
||||
"buttons" = buttons,
|
||||
"autofocus" = autofocus
|
||||
)
|
||||
|
||||
if(timeout)
|
||||
@@ -140,8 +146,8 @@
|
||||
/// The callback to be invoked by the tgui_modal upon having a choice made.
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout)
|
||||
..(user, message, title, buttons, timeout)
|
||||
/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout, autofocus)
|
||||
..(user, message, title, buttons, timeout, autofocus)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_modal/async/Destroy(force, ...)
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
src.message = message
|
||||
src.buttons = list()
|
||||
src.buttons_map = list()
|
||||
var/list/repeat_buttons = list()
|
||||
|
||||
// Gets rid of illegal characters
|
||||
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
|
||||
@@ -89,6 +90,9 @@
|
||||
for(var/i in buttons)
|
||||
var/string_key = whitelistedWords.Replace("[i]", "")
|
||||
|
||||
//avoids duplicated keys E.g: when areas have the same name
|
||||
string_key = avoid_assoc_duplicate_keys(string_key, repeat_buttons)
|
||||
|
||||
src.buttons += string_key
|
||||
src.buttons_map[string_key] = i
|
||||
|
||||
@@ -144,7 +148,7 @@
|
||||
if("choose")
|
||||
if (!(params["choice"] in buttons))
|
||||
return
|
||||
choice = buttons_map[params["choice"]]
|
||||
set_choice(buttons_map[params["choice"]])
|
||||
SStgui.close_uis(src)
|
||||
return TRUE
|
||||
if("cancel")
|
||||
@@ -152,6 +156,9 @@
|
||||
closed = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_list_input/proc/set_choice(choice)
|
||||
src.choice = choice
|
||||
|
||||
/**
|
||||
* # async tgui_list_input
|
||||
*
|
||||
@@ -162,23 +169,17 @@
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, callback, timeout)
|
||||
..(user, title, message, buttons, timeout)
|
||||
..(user, message, title, buttons, timeout)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_list_input/async/Destroy(force, ...)
|
||||
QDEL_NULL(callback)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_list_input/async/ui_close(mob/user)
|
||||
/datum/tgui_list_input/async/set_choice(choice)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/datum/tgui_list_input/async/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if (!. || choice == null)
|
||||
return
|
||||
callback.InvokeAsync(choice)
|
||||
qdel(src)
|
||||
if(!isnull(src.choice))
|
||||
callback?.InvokeAsync(src.choice)
|
||||
|
||||
/datum/tgui_list_input/async/wait()
|
||||
return
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
if(istype(asset, /datum/asset/spritesheet))
|
||||
var/datum/asset/spritesheet/spritesheet = asset
|
||||
send_message("asset/stylesheet", spritesheet.css_filename())
|
||||
send_message("asset/mappings", asset.get_url_mappings())
|
||||
send_raw_message(asset.get_serialized_url_mappings())
|
||||
|
||||
/**
|
||||
* private
|
||||
|
||||
@@ -292,7 +292,5 @@
|
||||
desc = "An ancient blade said to have ties with Lavaland's most inner demons. \
|
||||
Allows you to cut from a far distance!"
|
||||
item = /obj/item/gun/magic/staff/motivation
|
||||
cost = 20
|
||||
player_minimum = 20
|
||||
cost = 10
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
|
||||
cant_discount = TRUE
|
||||
|
||||
@@ -91,9 +91,9 @@
|
||||
/obj/vehicle/proc/after_add_occupant(mob/M)
|
||||
auto_assign_occupant_flags(M)
|
||||
|
||||
/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max.
|
||||
/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max.
|
||||
if(driver_amount() < max_drivers)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/proc/remove_occupant(mob/M)
|
||||
if(!istype(M))
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE)
|
||||
if(car_traits & CAN_KIDNAP)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/DumpKidnappedMobs, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/dump_kidnapped_mobs, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/driver_move(mob/user, direction)
|
||||
if(key_type && !is_key(inserted_key))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/vehicle/sealed/car/clowncar
|
||||
name = "clown car"
|
||||
desc = "How someone could even fit in there is beyond me."
|
||||
desc = "How someone could even fit in there is byond me."
|
||||
icon_state = "clowncar"
|
||||
max_integrity = 150
|
||||
armor = list("melee" = 70, "bullet" = 40, "laser" = 40, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
@@ -10,25 +10,36 @@
|
||||
car_traits = CAN_KIDNAP
|
||||
key_type = /obj/item/bikehorn
|
||||
key_type_exact = FALSE
|
||||
var/droppingoil = FALSE
|
||||
var/RTDcooldown = 150
|
||||
var/lastRTDtime = 0
|
||||
///list of headlight colors we use to pick through when we have party mode due to emag
|
||||
var/headlight_colors = list(COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BRIGHT_BLUE, COLOR_CYAN, COLOR_PURPLE)
|
||||
///Cooldown time inbetween [/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice()] usages
|
||||
var/dice_cooldown_time = 150
|
||||
///How many times kidnappers in the clown car said thanks
|
||||
var/thankscount = 0
|
||||
///Current status of the cannon, alternates between CLOWN_CANNON_INACTIVE, CLOWN_CANNON_BUSY and CLOWN_CANNON_READY
|
||||
var/cannonmode = CLOWN_CANNON_INACTIVE
|
||||
var/light_on = TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/process()
|
||||
if(light_on && (obj_flags & EMAGGED))
|
||||
set_light_color(pick(headlight_colors))
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/generate_actions()
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn/clowncar, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/driver_move(mob/user, direction) //Prevent it from moving onto space
|
||||
if(isspaceturf(get_step(src, direction)))
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/thank, VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY)) //Ensures only clowns can drive the car. (Including more at once)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
|
||||
add_control_flags(H, VEHICLE_CONTROL_DRIVE)
|
||||
RegisterSignal(H, COMSIG_MOB_CLICKON, .proc/fire_cannon_at)
|
||||
M.log_message("has entered [src] as a possible driver", LOG_ATTACK)
|
||||
return
|
||||
add_control_flags(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
@@ -36,106 +47,195 @@
|
||||
. = ..()
|
||||
playsound(src, pick('sound/vehicles/clowncar_load1.ogg', 'sound/vehicles/clowncar_load2.ogg'), 75)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/after_add_occupant(mob/M, control_flags)
|
||||
. = ..()
|
||||
if(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED).len >= 30)
|
||||
for(var/mob/voreman as anything in return_drivers())
|
||||
voreman.client.give_award(/datum/award/achievement/misc/round_and_full, voreman)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/attack_animal(mob/living/simple_animal/user, list/modifiers)
|
||||
if((user.loc != src) || user.environment_smash & (ENVIRONMENT_SMASH_WALLS|ENVIRONMENT_SMASH_RWALLS))
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/mob_exit(mob/M, silent = FALSE, randomstep = FALSE)
|
||||
. = ..()
|
||||
UnregisterSignal(M, COMSIG_MOB_CLICKON)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
if(prob(33))
|
||||
visible_message("<span class='danger'>[src] spews out a ton of space lube!</span>")
|
||||
visible_message(span_danger("[src] spews out a ton of space lube!"))
|
||||
new /obj/effect/particle_effect/foam(loc) //YEET
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
if(istype(I, /obj/item/reagent_containers/food/snacks/grown/banana))
|
||||
var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I
|
||||
obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity)
|
||||
to_chat(user, "<span class='danger'>You use the [banana] to repair the [src]!</span>")
|
||||
qdel(banana)
|
||||
if(!istype(I, /obj/item/reagent_containers/food/snacks/grown/banana))
|
||||
return
|
||||
var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I
|
||||
obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity)
|
||||
to_chat(user, span_danger("You use the [banana] to repair the [src]!"))
|
||||
qdel(banana)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Bump(atom/movable/M)
|
||||
/obj/vehicle/sealed/car/clowncar/Bump(atom/bumped)
|
||||
. = ..()
|
||||
if(isliving(M))
|
||||
if(ismegafauna(M))
|
||||
if(isliving(bumped))
|
||||
if(ismegafauna(bumped))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.DefaultCombatKnockdown(40) //I play to make sprites go horizontal
|
||||
L.visible_message("<span class='warning'>[src] rams into [L] and sucks him up!</span>") //fuck off shezza this isn't ERP.
|
||||
mob_forced_enter(L)
|
||||
var/mob/living/hittarget_living = bumped
|
||||
if(iscarbon(hittarget_living))
|
||||
var/mob/living/carbon/carb = hittarget_living
|
||||
carb.DefaultCombatKnockdown(40) //I play to make sprites go horizontal
|
||||
hittarget_living.visible_message(span_warning("[src] rams into [hittarget_living] and sucks [hittarget_living.p_them()] up!")) //fuck off shezza this isn't ERP.
|
||||
mob_forced_enter(hittarget_living)
|
||||
playsound(src, pick('sound/vehicles/clowncar_ram1.ogg', 'sound/vehicles/clowncar_ram2.ogg', 'sound/vehicles/clowncar_ram3.ogg'), 75)
|
||||
else if(istype(M, /turf/closed) || istype(M, /obj/machinery/door/airlock/external))
|
||||
visible_message("<span class='warning'>[src] rams into [M] and crashes!</span>")
|
||||
playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75)
|
||||
playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75)
|
||||
DumpMobs(TRUE)
|
||||
log_combat(src, hittarget_living, "sucked up")
|
||||
return
|
||||
if(!istype(bumped, /turf/closed))
|
||||
return
|
||||
visible_message(span_warning("[src] rams into [bumped] and crashes!"))
|
||||
playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75)
|
||||
playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75)
|
||||
DumpMobs(TRUE)
|
||||
log_combat(src, bumped, "crashed into", null, "dumping all passengers")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='danger'>You scramble the clowncar child safety lock and a panel with 6 colorful buttons appears!</span>")
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/RollTheDice, VEHICLE_CONTROL_DRIVE)
|
||||
to_chat(user, span_danger("You scramble \the [src]'s child safety lock, and a panel with six colorful buttons appears!"))
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/roll_the_dice, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/cannon, VEHICLE_CONTROL_DRIVE)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Destroy()
|
||||
/obj/vehicle/sealed/car/clowncar/obj_destruction(damage_flag)
|
||||
playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100)
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/after_move(direction)
|
||||
. = ..()
|
||||
if(droppingoil)
|
||||
new /obj/effect/decal/cleanable/oil/slippery(loc)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/RollTheDice(mob/user)
|
||||
if(world.time - lastRTDtime < RTDcooldown)
|
||||
to_chat(user, "<span class='notice'>The button panel is currently recharging.</span>")
|
||||
/**
|
||||
* Plays a random funky effect
|
||||
* Only available while car is emagged
|
||||
* Possible effects:
|
||||
* * Spawn bananapeel
|
||||
* * Spawn random reagent foam
|
||||
* * Make the clown car look like a singulo temporarily
|
||||
* * Spawn Laughing chem gas
|
||||
* * Drop oil
|
||||
* * Fart and make everyone nearby laugh
|
||||
*/
|
||||
/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice(mob/user)
|
||||
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CLOWNCAR_RANDOMNESS))
|
||||
to_chat(user, span_notice("The button panel is currently recharging."))
|
||||
return
|
||||
lastRTDtime = world.time
|
||||
var/randomnum = rand(1,6)
|
||||
switch(randomnum)
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_CLOWNCAR_RANDOMNESS, dice_cooldown_time)
|
||||
switch(rand(1,6))
|
||||
if(1)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and a special banana peel drops out of it.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and a special banana peel drops out of it."))
|
||||
new /obj/item/grown/bananapeel/specialpeel(loc)
|
||||
if(2)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and unknown chemicals flood out of it.</span>")
|
||||
var/datum/reagents/R = new/datum/reagents(300)
|
||||
R.my_atom = src
|
||||
R.add_reagent(get_random_reagent_id(), 100)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and unknown chemicals flood out of it."))
|
||||
var/datum/reagents/randomchems = new/datum/reagents(300)
|
||||
randomchems.my_atom = src
|
||||
randomchems.add_reagent(get_random_reagent_id(), 100)
|
||||
var/datum/effect_system/foam_spread/foam = new
|
||||
foam.set_up(200, loc, R)
|
||||
foam.set_up(200, loc, randomchems)
|
||||
foam.start()
|
||||
if(3)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car turns on its singularity disguise system.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car turns on its singularity disguise system."))
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "singularity_s1"
|
||||
addtimer(CALLBACK(src, .proc/ResetIcon), 100)
|
||||
addtimer(CALLBACK(src, .proc/reset_icon), 10 SECONDS)
|
||||
if(4)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car spews out a cloud of laughing gas.</span>")
|
||||
var/datum/reagents/R = new/datum/reagents(300)
|
||||
R.my_atom = src
|
||||
R.add_reagent(/datum/reagent/consumable/superlaughter, 50)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car spews out a cloud of laughing gas."))
|
||||
var/datum/reagents/funnychems = new/datum/reagents(300)
|
||||
funnychems.my_atom = src
|
||||
funnychems.add_reagent(/datum/reagent/consumable/superlaughter, 50)
|
||||
var/datum/effect_system/smoke_spread/chem/smoke = new()
|
||||
smoke.set_up(R, 4)
|
||||
smoke.set_up(funnychems, 4)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
if(5)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car starts dropping an oil trail.</span>")
|
||||
droppingoil = TRUE
|
||||
addtimer(CALLBACK(src, .proc/StopDroppingOil), 30)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car starts dropping an oil trail."))
|
||||
RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/cover_in_oil)
|
||||
addtimer(CALLBACK(src, .proc/stop_dropping_oil), 3 SECONDS)
|
||||
if(6)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car lets out a comedic toot.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car lets out a comedic toot."))
|
||||
playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100)
|
||||
for(var/mob/living/L in orange(loc, 6))
|
||||
L.emote("laughs")
|
||||
for(var/mob/living/L in occupants)
|
||||
for(var/mob/living/L as anything in occupants)
|
||||
L.emote("laughs")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/ResetIcon()
|
||||
///resets the icon and iconstate of the clowncar after it was set to singulo states
|
||||
/obj/vehicle/sealed/car/clowncar/proc/reset_icon()
|
||||
icon = initial(icon)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil()
|
||||
droppingoil = FALSE
|
||||
///Deploys oil when the clowncar moves in oil deploy mode
|
||||
/obj/vehicle/sealed/car/clowncar/proc/cover_in_oil()
|
||||
SIGNAL_HANDLER
|
||||
new /obj/effect/decal/cleanable/oil/slippery(loc)
|
||||
|
||||
///Stops dropping oil after the time has run up
|
||||
/obj/vehicle/sealed/car/clowncar/proc/stop_dropping_oil()
|
||||
UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
///Toggles the on and off state of the clown cannon that shoots random kidnapped people
|
||||
/obj/vehicle/sealed/car/clowncar/proc/toggle_cannon(mob/user)
|
||||
if(cannonmode == CLOWN_CANNON_BUSY)
|
||||
to_chat(user, span_notice("Please wait for the vehicle to finish its current action first."))
|
||||
return
|
||||
if(cannonmode) //canon active, deactivate
|
||||
flick("clowncar_fromfire", src)
|
||||
icon_state = "clowncar"
|
||||
addtimer(CALLBACK(src, .proc/deactivate_cannon), 2 SECONDS)
|
||||
playsound(src, 'sound/vehicles/clowncar_cannonmode2.ogg', 75)
|
||||
visible_message(span_danger("The [src] starts going back into mobile mode."))
|
||||
else
|
||||
canmove = FALSE //anchor and activate canon
|
||||
flick("clowncar_tofire", src)
|
||||
icon_state = "clowncar_fire"
|
||||
visible_message(span_danger("The [src] opens up and reveals a large cannon."))
|
||||
addtimer(CALLBACK(src, .proc/activate_cannon), 2 SECONDS)
|
||||
playsound(src, 'sound/vehicles/clowncar_cannonmode1.ogg', 75)
|
||||
cannonmode = CLOWN_CANNON_BUSY
|
||||
|
||||
///Finalizes canon activation
|
||||
/obj/vehicle/sealed/car/clowncar/proc/activate_cannon()
|
||||
// mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
|
||||
cannonmode = CLOWN_CANNON_READY
|
||||
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
|
||||
driver.update_mouse_pointer()
|
||||
|
||||
///Finalizes canon deactivation
|
||||
/obj/vehicle/sealed/car/clowncar/proc/deactivate_cannon()
|
||||
canmove = TRUE
|
||||
// mouse_pointer = null
|
||||
cannonmode = CLOWN_CANNON_INACTIVE
|
||||
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
|
||||
driver.update_mouse_pointer()
|
||||
|
||||
///Fires the cannon where the user clicks
|
||||
/obj/vehicle/sealed/car/clowncar/proc/fire_cannon_at(mob/user, atom/A, params)
|
||||
SIGNAL_HANDLER
|
||||
if(cannonmode != CLOWN_CANNON_READY || !length(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED)))
|
||||
return NONE
|
||||
var/mob/living/unlucky_sod = pick(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED))
|
||||
mob_exit(unlucky_sod, TRUE)
|
||||
flick("clowncar_recoil", src)
|
||||
playsound(src, pick('sound/vehicles/carcannon1.ogg', 'sound/vehicles/carcannon2.ogg', 'sound/vehicles/carcannon3.ogg'), 75)
|
||||
unlucky_sod.throw_at(A, 10, 2)
|
||||
log_combat(user, unlucky_sod, "fired", src, "towards [A]") //this doesn't catch if the mob hits something between the car and the target
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
|
||||
///Increments the thanks counter every time someone thats been kidnapped thanks the driver
|
||||
/obj/vehicle/sealed/car/clowncar/proc/increment_thanks_counter()
|
||||
thankscount++
|
||||
if(thankscount < 100)
|
||||
return
|
||||
for(var/mob/busdriver as anything in return_drivers())
|
||||
busdriver.client.give_award(/datum/award/achievement/misc/the_best_driver, busdriver)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays
|
||||
key_type = null
|
||||
@@ -144,12 +244,10 @@
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/twitch_plays/simple_movement)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list |= src
|
||||
notify_ghosts("Twitch Plays: Clown Car")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list -= src
|
||||
return ..()
|
||||
|
||||
@@ -158,3 +256,4 @@
|
||||
if(!dir)
|
||||
return
|
||||
driver_move(null, dir)
|
||||
..()
|
||||
|
||||
@@ -126,44 +126,70 @@
|
||||
desc = "Honk your classy horn."
|
||||
button_icon_state = "car_horn"
|
||||
var/hornsound = 'sound/items/carhorn.ogg'
|
||||
var/last_honk_time
|
||||
|
||||
/datum/action/vehicle/sealed/horn/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
last_honk_time = world.time
|
||||
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CAR_HONK))
|
||||
return
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_CAR_HONK, 2 SECONDS)
|
||||
vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] loudly honks!"))
|
||||
to_chat(owner, span_notice("You press [vehicle_entered_target]'s horn."))
|
||||
if(istype(vehicle_target.inserted_key, /obj/item/bikehorn))
|
||||
vehicle_target.inserted_key.attack_self(owner) //The bikehorn plays a sound instead
|
||||
return
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
|
||||
/datum/action/vehicle/sealed/horn/clowncar/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
last_honk_time = world.time
|
||||
if(vehicle_target.inserted_key)
|
||||
vehicle_target.inserted_key.attack_self(owner) //The key plays a sound
|
||||
else
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs
|
||||
name = "Dump kidnapped mobs"
|
||||
/datum/action/vehicle/sealed/dump_kidnapped_mobs
|
||||
name = "Dump Kidnapped Mobs"
|
||||
desc = "Dump all objects and people in your car on the floor."
|
||||
button_icon_state = "car_dump"
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs/Trigger()
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] starts dumping the people inside of it.</span>")
|
||||
/datum/action/vehicle/sealed/dump_kidnapped_mobs/Trigger()
|
||||
vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] starts dumping the people inside of it."))
|
||||
vehicle_entered_target.DumpSpecificMobs(VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/RollTheDice
|
||||
name = "Press a colorful button"
|
||||
/datum/action/vehicle/sealed/roll_the_dice
|
||||
name = "Press Colorful Button"
|
||||
desc = "Press one of those colorful buttons on your display panel!"
|
||||
button_icon_state = "car_rtd"
|
||||
|
||||
/datum/action/vehicle/sealed/RollTheDice/Trigger()
|
||||
if(istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.RollTheDice(owner)
|
||||
/datum/action/vehicle/sealed/roll_the_dice/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.roll_the_dice(owner)
|
||||
|
||||
/datum/action/vehicle/sealed/cannon
|
||||
name = "Toggle Siege Mode"
|
||||
desc = "Destroy them with their own fodder!"
|
||||
button_icon_state = "car_cannon"
|
||||
|
||||
/datum/action/vehicle/sealed/cannon/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.toggle_cannon(owner)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/thank
|
||||
name = "Thank the Clown Car Driver"
|
||||
desc = "They're just doing their job."
|
||||
button_icon_state = "car_thanktheclown"
|
||||
COOLDOWN_DECLARE(thank_time_cooldown)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/thank/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, thank_time_cooldown))
|
||||
return
|
||||
COOLDOWN_START(src, thank_time_cooldown, 6 SECONDS)
|
||||
var/obj/vehicle/sealed/car/clowncar/clown_car = vehicle_entered_target
|
||||
var/mob/living/carbon/human/clown = pick(clown_car.return_drivers())
|
||||
if(!clown)
|
||||
return
|
||||
owner.say("Thank you for the fun ride, [clown.name]!")
|
||||
clown_car.increment_thanks_counter()
|
||||
|
||||
|
||||
/datum/action/vehicle/ridden/scooter/skateboard/ollie
|
||||
@@ -197,7 +223,9 @@
|
||||
L.Move(landing_turf, vehicle_target.dir)
|
||||
passtable_off(L, VEHICLE_TRAIT)
|
||||
V.pass_flags &= ~PASSTABLE
|
||||
if(locate(/obj/structure/table) in V.loc.contents)
|
||||
if((locate(/obj/structure/table) in V.loc.contents) || (locate(/obj/structure/fluff/railing) in V.loc.contents))
|
||||
if(locate(/obj/structure/fluff/railing) in V.loc.contents)
|
||||
L.client.give_award(/datum/award/achievement/misc/tram_surfer, L)
|
||||
V.grinding = TRUE
|
||||
V.icon_state = "[V.board_icon]-grind"
|
||||
addtimer(CALLBACK(V, /obj/vehicle/ridden/scooter/skateboard/.proc/grind), 2)
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
/obj/item/clothing/glasses/monocle = 3,
|
||||
/obj/item/clothing/suit/jacket = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/red = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/aqua = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/brown = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/red = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/aqua = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/brown = 4,
|
||||
/obj/item/clothing/suit/jacket/puffer/vest = 4,
|
||||
/obj/item/clothing/suit/jacket/puffer = 4,
|
||||
/obj/item/clothing/suit/hooded/cloak/david = 4,
|
||||
@@ -219,7 +219,17 @@
|
||||
/obj/item/clothing/under/misc/corporateuniform = 5,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/polychromic = 5,
|
||||
/obj/item/clothing/suit/toggle/wbreakpoly/polychromic = 5,
|
||||
/obj/item/clothing/shoes/sneakers/poly/polychromic = 10)
|
||||
/obj/item/clothing/shoes/sneakers/poly/polychromic = 10,
|
||||
/obj/item/clothing/suit/toggle/jacket/fancytrench = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/greenjacket = 4,
|
||||
/obj/item/clothing/suit/jacket/gentlecoat = 4,
|
||||
/obj/item/clothing/suit/jacket/gothicshirtcross = 4,
|
||||
/obj/item/clothing/suit/jacket/gothicshirt = 4,
|
||||
/obj/item/clothing/suit/jacket/gothiccoat = 4,
|
||||
/obj/item/clothing/suit/jacket/heartcoat = 4,
|
||||
/obj/item/clothing/suit/jacket/purplehoodie = 4,
|
||||
/obj/item/clothing/suit/jacket/bluehoodie = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/whitehoodie = 4)
|
||||
refill_canister = /obj/item/vending_refill/clothing
|
||||
default_price = PRICE_CHEAP
|
||||
extra_price = PRICE_BELOW_NORMAL
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
/obj/item/toy/cards/deck/unum = 3,
|
||||
/obj/item/cardpack/series_one = 10,
|
||||
/obj/item/dyespray=3,
|
||||
/obj/item/tcgcard_binder = 5)
|
||||
/obj/item/tcgcard_binder = 5,
|
||||
/obj/item/canvas = 3,
|
||||
/obj/item/toy/crayon/spraycan = 3)
|
||||
contraband = list(/obj/item/dice/fudge = 9)
|
||||
premium = list(/obj/item/melee/skateboard/pro = 3,
|
||||
/obj/item/melee/skateboard/hoverboard = 1)
|
||||
|
||||
Reference in New Issue
Block a user