Merge remote-tracking branch 'citadel/master' into combat_v7
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
#define GELADIKINESIS /datum/mutation/human/geladikinesis
|
||||
#define CRYOKINESIS /datum/mutation/human/cryokinesis
|
||||
#define SPIDER_WEB /datum/mutation/human/webbing
|
||||
#define CLUWNEMUT /datum/mutation/human/cluwne
|
||||
|
||||
#define UI_CHANGED "ui changed"
|
||||
#define UE_CHANGED "ue changed"
|
||||
|
||||
@@ -56,8 +56,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define UNUSED_RESERVATION_TURF_1 (1<<1)
|
||||
/// If a turf can be made dirty at roundstart. This is also used in areas.
|
||||
#define CAN_BE_DIRTY_1 (1<<2)
|
||||
/// If blood cultists can draw runes or build structures on this turf
|
||||
#define CULT_PERMITTED_1 (1<<3)
|
||||
/// Blocks lava rivers being generated on the turf
|
||||
#define NO_LAVA_GEN_1 (1<<6)
|
||||
/// Blocks ruins spawning on the turf
|
||||
@@ -92,6 +90,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define ABDUCTOR_PROOF (1<<11)
|
||||
/// If an area should be hidden from power consoles, power/atmosphere alerts, etc.
|
||||
#define NO_ALERTS (1<<12)
|
||||
/// If blood cultists can draw runes or build structures on this AREA.
|
||||
#define CULT_PERMITTED (1<<13)
|
||||
|
||||
/*
|
||||
These defines are used specifically with the atom/pass_flags bitmask
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#define ADMIN_PUNISHMENT_PICKLE "Pickle-ify"
|
||||
#define ADMIN_PUNISHMENT_FRY "Fry"
|
||||
#define ADMIN_PUNISHMENT_PERFORATE ":B:erforate"
|
||||
#define ADMIN_PUNISHMENT_CLUWNE "Cluwne"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
#define ATMOS_TANK_PLASMA "plasma=70000;TEMP=293.15"
|
||||
#define ATMOS_TANK_O2 "o2=100000;TEMP=293.15"
|
||||
#define ATMOS_TANK_N2 "n2=100000;TEMP=293.15"
|
||||
#define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15"
|
||||
#define ATMOS_TANK_AIRMIX "o2=2811;n2=10583;TEMP=293.15"
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
/// how long they're staggered for
|
||||
#define SHOVE_STAGGER_DURATION 35
|
||||
/// how long they're off balance for
|
||||
#define SHOVE_OFFBALANCE_DURATION 30
|
||||
#define SHOVE_OFFBALANCE_DURATION 3 SECONDS
|
||||
|
||||
|
||||
//Embedded objects
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
#define WINDOW_IN_FRAME 1
|
||||
#define WINDOW_SCREWED_TO_FRAME 2
|
||||
|
||||
//reinforced plasma window construction states
|
||||
#define PRWINDOW_FRAME_BOLTED 3
|
||||
#define PRWINDOW_BARS_CUT 4
|
||||
#define PRWINDOW_POPPED 5
|
||||
#define PRWINDOW_BOLTS_OUT 6
|
||||
#define PRWINDOW_BOLTS_HEATED 7
|
||||
#define PRWINDOW_SECURE 8
|
||||
|
||||
//airlock assembly construction states
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0
|
||||
#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1
|
||||
|
||||
@@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"ABDUCTOR_PROOF" = ABDUCTOR_PROOF,
|
||||
"BLOBS_ALLOWED" = BLOBS_ALLOWED,
|
||||
"BLOCK_SUICIDE" = BLOCK_SUICIDE,
|
||||
// "CULT_PERMITTED" = CULT_PERMITTED,
|
||||
"CULT_PERMITTED" = CULT_PERMITTED,
|
||||
"FLORA_ALLOWED" = FLORA_ALLOWED,
|
||||
"HIDDEN_AREA" = HIDDEN_AREA,
|
||||
"MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED,
|
||||
|
||||
@@ -84,7 +84,35 @@ GLOBAL_LIST_INIT(mutant_transform_list, list("wingsopen" = "wings",
|
||||
"waggingspines" = "spines",
|
||||
"mam_waggingtail" = "mam_tail"))
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list(
|
||||
"ghost",
|
||||
"ghostian",
|
||||
"ghostian2",
|
||||
"ghostking",
|
||||
"ghost_red",
|
||||
"ghost_black",
|
||||
"ghost_blue",
|
||||
"ghost_yellow",
|
||||
"ghost_green",
|
||||
"ghost_pink",
|
||||
"ghost_cyan",
|
||||
"ghost_dblue",
|
||||
"ghost_dred",
|
||||
"ghost_dgreen",
|
||||
"ghost_dcyan",
|
||||
"ghost_grey",
|
||||
"ghost_dyellow",
|
||||
"ghost_dpink",
|
||||
"skeleghost",
|
||||
"ghost_purpleswirl",
|
||||
"ghost_rainbow",
|
||||
"ghost_fire",
|
||||
"ghost_funkypurp",
|
||||
"ghost_pinksherbert",
|
||||
"ghost_blazeit",
|
||||
"ghost_mellow",
|
||||
"ghost_camo",
|
||||
"catghost")) //stores the ghost forms that support directional sprites
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list("ghost")) //stores the ghost forms that support hair and other such things
|
||||
|
||||
GLOBAL_LIST_INIT(ai_core_display_screens, list(
|
||||
|
||||
@@ -176,6 +176,11 @@
|
||||
scheduled_destruction = world.time + (lifespan - CHAT_MESSAGE_EOL_FADE)
|
||||
enter_subsystem()
|
||||
|
||||
var/mob/living/silicon/robot/R = target
|
||||
if(iscyborg(R))
|
||||
if(R.module.dogborg == TRUE || R.dogborg == TRUE) //I hate whoever that thought that putting two types of dogborg that don't even sync up properly was good
|
||||
message.pixel_x = 16
|
||||
|
||||
/**
|
||||
* Applies final animations to overlay CHAT_MESSAGE_EOL_FADE deciseconds prior to message deletion
|
||||
* Arguments:
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
var/left_hand
|
||||
var/inv_slots
|
||||
var/proctype //if present, will be invoked on headwear generation.
|
||||
var/escape_on_find = FALSE //if present, will be released upon the item being 'found' (i.e. opening a container or pocket with it present)
|
||||
|
||||
/datum/element/mob_holder/Attach(datum/target, worn_state, alt_worn, right_hand, left_hand, inv_slots = NONE, proctype)
|
||||
/datum/element/mob_holder/Attach(datum/target, worn_state, alt_worn, right_hand, left_hand, inv_slots = NONE, proctype, escape_on_find)
|
||||
. = ..()
|
||||
|
||||
if(!isliving(target))
|
||||
@@ -20,6 +21,7 @@
|
||||
src.left_hand = left_hand
|
||||
src.inv_slots = inv_slots
|
||||
src.proctype = proctype
|
||||
src.escape_on_find = escape_on_find
|
||||
|
||||
RegisterSignal(target, COMSIG_CLICK_ALT, .proc/mob_try_pickup)
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
@@ -55,6 +57,8 @@
|
||||
to_chat(user, "<span class='notice'>You pick [source] up.</span>")
|
||||
source.drop_all_held_items()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(source), source, worn_state, alt_worn, right_hand, left_hand, inv_slots)
|
||||
holder.escape_on_find = escape_on_find
|
||||
|
||||
if(proctype)
|
||||
INVOKE_ASYNC(src, proctype, source, holder, user)
|
||||
user.put_in_hands(holder)
|
||||
@@ -78,6 +82,7 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
dynamic_hair_suffix = ""
|
||||
var/mob/living/held_mob
|
||||
var/escape_on_find
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/target, worn_state, alt_worn, right_hand, left_hand, slots = NONE)
|
||||
. = ..()
|
||||
@@ -189,3 +194,9 @@
|
||||
if(ismob(location))
|
||||
return location.loc.remove_air(amount)
|
||||
return location.remove_air(amount)
|
||||
|
||||
// escape when found if applicable
|
||||
/obj/item/clothing/head/mob_holder/on_found(mob/living/finder)
|
||||
if(escape_on_find)
|
||||
finder.visible_message("[finder] accidentally releases the [held_mob]!")
|
||||
release()
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/datum/mutation/human/cluwne
|
||||
|
||||
name = "Cluwne"
|
||||
quality = NEGATIVE
|
||||
locked = TRUE
|
||||
text_gain_indication = "<span class='danger'>You feel like your brain is tearing itself apart.</span>"
|
||||
|
||||
/datum/mutation/human/cluwne/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
owner.dna.add_mutation(CLOWNMUT)
|
||||
owner.dna.add_mutation(EPILEPSY)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199)
|
||||
|
||||
var/mob/living/carbon/human/H = owner
|
||||
|
||||
if(!istype(H.wear_mask, /obj/item/clothing/mask/gas/cluwne))
|
||||
if(!H.dropItemToGround(H.wear_mask))
|
||||
qdel(H.wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/cluwne(H), SLOT_WEAR_MASK)
|
||||
if(!istype(H.w_uniform, /obj/item/clothing/under/cluwne))
|
||||
if(!H.dropItemToGround(H.w_uniform))
|
||||
qdel(H.w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/cluwne(H), SLOT_W_UNIFORM)
|
||||
if(!istype(H.shoes, /obj/item/clothing/shoes/clown_shoes/cluwne))
|
||||
if(!H.dropItemToGround(H.shoes))
|
||||
qdel(H.shoes)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/cluwne(H), SLOT_SHOES)
|
||||
|
||||
owner.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/white(owner), SLOT_GLOVES) // this is purely for cosmetic purposes incase they aren't wearing anything in that slot
|
||||
owner.equip_to_slot_or_del(new /obj/item/storage/backpack/clown(owner), SLOT_BACK) // ditto
|
||||
|
||||
/datum/mutation/human/cluwne/on_life(mob/living/carbon/human/owner)
|
||||
if((prob(15) && owner.IsUnconscious()))
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199) // there I changed it to setBrainLoss
|
||||
switch(rand(1, 6))
|
||||
if(1)
|
||||
owner.say("HONK")
|
||||
if(2 to 5)
|
||||
owner.emote("scream")
|
||||
if(6)
|
||||
owner.Stun(1)
|
||||
owner.Knockdown(20)
|
||||
owner.Jitter(500)
|
||||
|
||||
/datum/mutation/human/cluwne/on_losing(mob/living/carbon/human/owner)
|
||||
owner.adjust_fire_stacks(1)
|
||||
owner.IgniteMob()
|
||||
owner.dna.add_mutation(CLUWNEMUT)
|
||||
|
||||
/mob/living/carbon/human/proc/cluwneify()
|
||||
dna.add_mutation(CLUWNEMUT)
|
||||
emote("scream")
|
||||
regenerate_icons()
|
||||
visible_message("<span class='danger'>[src]'s body glows green, the glow dissipating only to leave behind a cluwne formerly known as [src]!</span>", \
|
||||
"<span class='danger'>Your brain feels like it's being torn apart, there is only the honkmother now.</span>")
|
||||
flash_act()
|
||||
@@ -8,23 +8,24 @@
|
||||
time_coeff = 5
|
||||
instability = 30
|
||||
|
||||
/datum/mutation/human/space_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut)
|
||||
..()
|
||||
if(!(type in visual_indicators))
|
||||
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "space_adapt", -MUTATIONS_LAYER))
|
||||
|
||||
/datum/mutation/human/space_adaptation/get_visual_indicator()
|
||||
return visual_indicators[type][1]
|
||||
|
||||
/datum/mutation/human/space_adaptation/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
ADD_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance")
|
||||
ADD_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance")
|
||||
owner.add_filter("space_glow", 2, list("type" = "outline", "color" = "#ffe46bd8", "size" = 1))
|
||||
addtimer(CALLBACK(src, .proc/glow_loop, owner), rand(1,19))
|
||||
|
||||
/datum/mutation/human/space_adaptation/proc/glow_loop(mob/living/carbon/human/owner)
|
||||
var/filter = owner.get_filter("space_glow")
|
||||
if(filter)
|
||||
animate(filter, alpha = 190, time = 15, loop = -1)
|
||||
animate(alpha = 110, time = 25)
|
||||
|
||||
/datum/mutation/human/space_adaptation/on_losing(mob/living/carbon/human/owner)
|
||||
if(..())
|
||||
return
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTCOLD, "cold_resistance")
|
||||
REMOVE_TRAIT(owner, TRAIT_RESISTLOWPRESSURE, "cold_resistance")
|
||||
owner.remove_filter("space_glow")
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
name = "Generic Maintenance"
|
||||
// ambience_index = AMBIENCE_MAINT
|
||||
ambientsounds = MAINTENANCE
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
// airlock_wires = /datum/wires/airlock/maint
|
||||
sound_environment = SOUND_AREA_TUNNEL_ENCLOSED
|
||||
|
||||
@@ -294,7 +294,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/maintenance/department/science/xenobiology
|
||||
name = "Xenobiology Maintenance"
|
||||
icon_state = "xenomaint"
|
||||
area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | XENOBIOLOGY_COMPATIBLE
|
||||
area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | XENOBIOLOGY_COMPATIBLE | CULT_PERMITTED
|
||||
|
||||
//Maintenance - Generic
|
||||
|
||||
@@ -598,11 +598,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/commons
|
||||
name = "Crew Quarters"
|
||||
sound_environment = SOUND_AREA_STANDARD_STATION
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
/area/commons/dorms
|
||||
name = "Dormitories"
|
||||
icon_state = "dorms"
|
||||
area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA
|
||||
|
||||
/area/commons/dorms/barracks
|
||||
name = "Sleep Barracks"
|
||||
@@ -899,7 +899,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
// mood_bonus = 5
|
||||
// mood_message = "<span class='nicegreen'>I love being in the library!</span>\n"
|
||||
// mood_trait = TRAIT_INTROVERT
|
||||
flags_1 = CULT_PERMITTED_1
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
sound_environment = SOUND_AREA_LARGE_SOFTFLOOR
|
||||
|
||||
/area/service/library/lounge
|
||||
@@ -926,7 +926,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/service/library/abandoned
|
||||
name = "Abandoned Library"
|
||||
icon_state = "abandoned_library"
|
||||
flags_1 = CULT_PERMITTED_1
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_NONE
|
||||
|
||||
/area/service/chapel
|
||||
@@ -973,8 +972,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/service/janitor
|
||||
name = "Custodial Closet"
|
||||
icon_state = "janitor"
|
||||
flags_1 = CULT_PERMITTED_1
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
/area/service/janitor/aux
|
||||
name = "Auxiliary Custodial Closet"
|
||||
@@ -1027,7 +1026,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engineering/atmos
|
||||
name = "Atmospherics"
|
||||
icon_state = "atmos"
|
||||
flags_1 = CULT_PERMITTED_1
|
||||
|
||||
/area/engineering/atmos/upper
|
||||
name = "Upper Atmospherics"
|
||||
@@ -1035,7 +1033,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engineering/atmospherics_engine
|
||||
name = "Atmospherics Engine"
|
||||
icon_state = "atmos_engine"
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
/area/engineering/lobby
|
||||
name = "Engineering Lobby"
|
||||
@@ -1044,7 +1042,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engineering/supermatter
|
||||
name = "Supermatter Engine"
|
||||
icon_state = "engine_sm"
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
sound_environment = SOUND_AREA_SMALL_ENCLOSED
|
||||
|
||||
/area/engineering/break_room
|
||||
@@ -1084,7 +1082,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/engineering/storage/tcomms
|
||||
name = "Telecomms Storage"
|
||||
icon_state = "tcom"
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
clockwork_warp_allowed = FALSE
|
||||
|
||||
//Engineering - Construction
|
||||
@@ -1314,7 +1312,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/medical/virology
|
||||
name = "Virology"
|
||||
icon_state = "virology"
|
||||
flags_1 = CULT_PERMITTED_1
|
||||
|
||||
/area/medical/morgue
|
||||
name = "Morgue"
|
||||
@@ -1608,7 +1605,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/science/test_area
|
||||
name = "Toxins Test Area"
|
||||
icon_state = "tox_test"
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
/area/science/mixing
|
||||
name = "Toxins Mixing Lab"
|
||||
@@ -1617,7 +1614,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
/area/science/mixing/chamber
|
||||
name = "Toxins Mixing Chamber"
|
||||
icon_state = "tox_mix_chamber"
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
|
||||
area_flags = BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
/area/science/misc_lab
|
||||
name = "Testing Lab"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
|
||||
var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA
|
||||
var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
var/fire = null
|
||||
///Whether there is an atmos alarm in this area
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
requires_power = FALSE
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
|
||||
area_flags = UNIQUE_AREA | NOTELEPORT
|
||||
flags_1 = NONE
|
||||
|
||||
/area/centcom/control
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
icon_state = "Holodeck"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
flags_1 = NONE
|
||||
area_flags = VALID_TERRITORY | UNIQUE_AREA
|
||||
sound_environment = SOUND_ENVIRONMENT_PADDED_CELL
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
@@ -87,9 +86,6 @@
|
||||
/area/holodeck/rec_center/lounge
|
||||
name = "Holodeck - Lounge"
|
||||
|
||||
/area/holodeck/rec_center/medical
|
||||
name = "Holodeck - Emergency Medical"
|
||||
|
||||
/area/holodeck/rec_center/pet_lounge
|
||||
name = "Holodeck - Pet Park"
|
||||
|
||||
@@ -128,6 +124,10 @@
|
||||
name = "Holodeck - Holdout Bunker"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/medical
|
||||
name = "Holodeck - Emergency Medical"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/anthophila
|
||||
name = "Holodeck - Anthophila"
|
||||
restricted = 1
|
||||
|
||||
@@ -157,10 +157,10 @@
|
||||
|
||||
/area/shuttle/escape
|
||||
name = "Emergency Shuttle"
|
||||
area_flags = BLOBS_ALLOWED
|
||||
area_flags = BLOBS_ALLOWED | CULT_PERMITTED
|
||||
// area_limited_icon_smoothing = /area/shuttle/escape
|
||||
canSmoothWithAreas = /area/shuttle/escape
|
||||
flags_1 = CAN_BE_DIRTY_1 // | CULT_PERMITTED_1
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
|
||||
/area/shuttle/escape/backup
|
||||
name = "Backup Emergency Shuttle"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/obj/machinery/computer/bank_machine
|
||||
name = "bank machine"
|
||||
desc = "A machine used to deposit and withdraw station funds."
|
||||
icon = 'goon/icons/obj/goon_terminals.dmi'
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "computer"
|
||||
icon_screen = "vault"
|
||||
icon_keyboard = "security_key"
|
||||
idle_power_usage = 100
|
||||
|
||||
var/siphoning = FALSE
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "A culinary marvel that uses matter-to-energy conversion to store dishes and shards. Convenient! \
|
||||
Additional features include a vacuum function to suck in nearby dishes, and an automatic transfer beam that empties its contents into nearby disposal bins every now and then. \
|
||||
Or you can just drop your plates on the floor, like civilized folk."
|
||||
icon = 'goon/icons/obj/kitchen.dmi'
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "synthesizer"
|
||||
idle_power_usage = 8 //5 with default parts
|
||||
active_power_usage = 13 //10 with default parts
|
||||
|
||||
@@ -341,6 +341,9 @@
|
||||
return TRUE
|
||||
. = ..()
|
||||
|
||||
/obj/structure/foamedmetal/resin/BlockSuperconductivity()
|
||||
return TRUE
|
||||
|
||||
#undef ALUMINUM_FOAM
|
||||
#undef IRON_FOAM
|
||||
#undef RESIN_FOAM
|
||||
|
||||
@@ -378,6 +378,12 @@
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/judgement_cut
|
||||
name = "judgement cut impact"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "impact_judgement"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/temp_visual/heart
|
||||
name = "heart"
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
@@ -535,3 +541,7 @@
|
||||
/obj/effect/temp_visual/slime_puddle/reverse
|
||||
icon_state = "from_puddle"
|
||||
duration = 7
|
||||
|
||||
/obj/effect/temp_visual/gib_animation
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
duration = 15
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
|
||||
var/obj/item/shockpaddles/paddles
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/combat = FALSE //can we revive through space suits?
|
||||
var/combat = FALSE //if true, revive through hardsuits, allow for combat shocking, and tint paddles syndicate colors
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
var/healdisk = FALSE // Does the unit have the healdisk upgrade?
|
||||
var/pullshocksafely = FALSE // Will we shock people dragging the body?
|
||||
@@ -176,7 +176,9 @@
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/defibrillator/proc/make_paddles()
|
||||
return new /obj/item/shockpaddles(src)
|
||||
if(!combat)
|
||||
return new /obj/item/shockpaddles(src)
|
||||
return new /obj/item/shockpaddles/syndicate(src)
|
||||
|
||||
/obj/item/defibrillator/equipped(mob/user, slot)
|
||||
..()
|
||||
@@ -245,6 +247,8 @@
|
||||
/obj/item/defibrillator/compact/combat
|
||||
name = "combat defibrillator"
|
||||
desc = "A belt-equipped blood-red defibrillator that can be rapidly deployed. Does not have the restrictions or safeties of conventional defibrillators and can revive through space suits."
|
||||
icon_state = "defibcombat" //needs defib inhand sprites
|
||||
item_state = "defibcombat"
|
||||
combat = TRUE
|
||||
safety = FALSE
|
||||
always_emagged = TRUE
|
||||
@@ -279,6 +283,7 @@
|
||||
var/combat = FALSE //If it penetrates armor and gives additional functionality
|
||||
var/grab_ghost = FALSE
|
||||
var/tlimit = DEFIB_TIME_LIMIT * 10
|
||||
var/base_icon_state = "defibpaddles"
|
||||
var/disarm_shock_time = 10
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
@@ -352,10 +357,10 @@
|
||||
return (OXYLOSS)
|
||||
|
||||
/obj/item/shockpaddles/update_icon_state()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
icon_state = "[base_icon_state][wielded]"
|
||||
item_state = icon_state
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
icon_state = "[base_icon_state][wielded]_cooldown"
|
||||
|
||||
/obj/item/shockpaddles/dropped(mob/user)
|
||||
if(!req_defib)
|
||||
@@ -704,8 +709,9 @@
|
||||
desc = "A pair of paddles used to revive deceased operatives. It possesses both the ability to penetrate armor and to deliver powerful shocks offensively."
|
||||
combat = TRUE
|
||||
icon = 'icons/obj/defibrillators.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
icon_state = "syndiepaddles0"
|
||||
item_state = "syndiepaddles0"
|
||||
base_icon_state = "syndiepaddles"
|
||||
req_defib = FALSE
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
@@ -77,8 +77,11 @@
|
||||
return
|
||||
if(!iscarbon(target))
|
||||
return
|
||||
if(!(target?.client?.prefs?.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
to_chat(user, "<span class='warning'>The user has opted out of the use of your [src].")
|
||||
return
|
||||
var/voracious = TRUE
|
||||
if(!target.client || !(target.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
if(target.buckled)
|
||||
to_chat(user, "<span class='warning'>The user is buckled and can not be put into your [src].</span>")
|
||||
|
||||
@@ -381,8 +381,8 @@ GENETICS SCANNER
|
||||
else if (S.mutantstomach != initial(S.mutantstomach))
|
||||
mutant = TRUE
|
||||
|
||||
msg += "\t<span class='info'>Reported Species: [H.dna.custom_species ? H.dna.custom_species : S.name]</span>\n"
|
||||
msg += "\t<span class='info'>Base Species: [S.name]</span>\n"
|
||||
msg += "\t<span class='info'>Reported Species: [H.spec_trait_examine_font()][H.dna.custom_species ? H.dna.custom_species : S.name]</font></span>\n"
|
||||
msg += "\t<span class='info'>Base Species: [H.spec_trait_examine_font()][S.name]</font></span>\n"
|
||||
if(mutant)
|
||||
msg += "\t<span class='info'>Subject has mutations present.</span>\n"
|
||||
msg += "\t<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)</span>\n"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/singularityhammer
|
||||
name = "singularity hammer"
|
||||
desc = "The pinnacle of close combat technology, the hammer harnesses the power of a miniaturized singularity to deal crushing blows."
|
||||
icon_state = "mjollnir0"
|
||||
icon_state = "singularity_hammer0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/item/singularityhammer/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=4, icon_wielded="mjollnir1")
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=4, icon_wielded="singularity_hammer1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/singularityhammer/proc/on_wield(obj/item/source, mob/user)
|
||||
@@ -36,7 +36,7 @@
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/singularityhammer/update_icon_state()
|
||||
icon_state = "mjollnir0"
|
||||
icon_state = "singularity_hammer0"
|
||||
|
||||
/obj/item/singularityhammer/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -593,7 +593,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
return
|
||||
var/turf/T = get_turf(user) //we may have moved. adjust as needed...
|
||||
var/area/A = get_area(user)
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !(A.flags_1 & CULT_PERMITTED_1)))
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & CULT_PERMITTED))
|
||||
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
name = "trash bag of holding"
|
||||
desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage."
|
||||
icon_state = "bluetrashbag"
|
||||
item_state = "bluetrashbag"
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
"<span class='userdanger'>YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! <i>THERE CAN BE ONLY ONE!!!</i></span>")
|
||||
user.update_icons()
|
||||
new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]"
|
||||
icon_state = "claymore_valhalla"
|
||||
item_state = "cultblade"
|
||||
icon_state = "claymore_gold"
|
||||
item_state = "claymore_gold"
|
||||
remove_atom_colour(ADMIN_COLOUR_PRIORITY)
|
||||
|
||||
name = new_name
|
||||
|
||||
@@ -13,15 +13,16 @@
|
||||
return 0
|
||||
. = ..()
|
||||
|
||||
// Exists to work around the minimum 700 cr price for goodies / small items
|
||||
/obj/structure/closet/secure_closet/goodies
|
||||
// Exists to work around the minimum 700 cr price for goodies / small items / materials
|
||||
/obj/structure/closet/secure_closet/cargo
|
||||
name = "cargo locker"
|
||||
icon_state = "goodies"
|
||||
desc = "A sturdier card-locked storage unit used for bulky shipments."
|
||||
max_integrity = 500 // Same as crates.
|
||||
melee_min_damage = 25 // Idem.
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned
|
||||
name = "private locker"
|
||||
/obj/structure/closet/secure_closet/cargo/owned
|
||||
name = "private cargo locker"
|
||||
desc = "A locker designed to only open for who purchased its contents."
|
||||
///Account of the person buying the crate if private purchasing.
|
||||
var/datum/bank_account/buyer_account
|
||||
@@ -32,18 +33,18 @@
|
||||
///Is the crate being bought by a person, or a budget card?
|
||||
var/department_purchase = FALSE
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/examine(mob/user)
|
||||
/obj/structure/closet/secure_closet/cargo/owned/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>It's locked with a privacy lock, and can only be unlocked by the buyer's ID.</span>"
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/Initialize(mapload, datum/bank_account/_buyer_account)
|
||||
/obj/structure/closet/secure_closet/cargo/owned/Initialize(mapload, datum/bank_account/_buyer_account)
|
||||
. = ..()
|
||||
buyer_account = _buyer_account
|
||||
if(istype(buyer_account, /datum/bank_account/department))
|
||||
department_purchase = TRUE
|
||||
department_account = buyer_account
|
||||
|
||||
/obj/structure/closet/secure_closet/goodies/owned/togglelock(mob/living/user, silent)
|
||||
/obj/structure/closet/secure_closet/cargo/owned/togglelock(mob/living/user, silent)
|
||||
if(privacy_lock)
|
||||
if(!broken)
|
||||
var/obj/item/card/id/id_card = user.get_idcard(TRUE)
|
||||
|
||||
@@ -21,6 +21,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
var/ini_dir = null
|
||||
var/state = WINDOW_OUT_OF_FRAME
|
||||
var/reinf = FALSE
|
||||
var/extra_reinforced = FALSE
|
||||
var/heat_resistance = 800
|
||||
var/decon_speed = 30
|
||||
var/wtype = "glass"
|
||||
@@ -65,6 +66,20 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
. += "<span class='notice'>The window is out of the frame, but could be <i>pried</i> in. It is <b>screwed</b> to the floor.</span>"
|
||||
else if(!anchored)
|
||||
. += "<span class='notice'>The window is <i>unscrewed</i> from the floor, and could be deconstructed by <b>wrenching</b>.</span>"
|
||||
switch(state)
|
||||
if(PRWINDOW_SECURE)
|
||||
if(extra_reinforced)
|
||||
. += "It's been screwed in with one way screws, you'd need to <b>heat their solder cover</b> to have any chance of backing them out."
|
||||
else
|
||||
. += "It's been screwed in with solid screws, you'd need to <b>screw them</b> out to unsecure the window."
|
||||
if(PRWINDOW_BOLTS_HEATED)
|
||||
. += "The solder cover melts away, and you'll likely be able to <b>unscrew them</b> now."
|
||||
if(PRWINDOW_BOLTS_OUT)
|
||||
. += "The screws have been removed, revealing a small gap you could fit a <b>prying tool</b> in."
|
||||
if(PRWINDOW_POPPED)
|
||||
. += "The main plate of the window has popped out of the frame, exposing some bars that look like they can be <b>cut</b>."
|
||||
if(PRWINDOW_BARS_CUT)
|
||||
. += "The main pane can be easily moved out of the way to reveal some <b>bolts</b> holding the frame in."
|
||||
else
|
||||
if(anchored)
|
||||
. += "<span class='notice'>The window is <b>screwed</b> to the floor.</span>"
|
||||
@@ -75,8 +90,13 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
. = ..()
|
||||
if(direct)
|
||||
setDir(direct)
|
||||
if(reinf && anchored)
|
||||
|
||||
if(extra_reinforced && anchored)
|
||||
state = PRWINDOW_SECURE
|
||||
|
||||
else if(reinf && anchored)
|
||||
state = WINDOW_SCREWED_TO_FRAME
|
||||
|
||||
|
||||
if(mapload && electrochromatic_id && electrochromatic_id[1] == "!")
|
||||
electrochromatic_id = SSmapping.get_obfuscated_id(electrochromatic_id)
|
||||
@@ -230,29 +250,26 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
make_electrochromatic(K.id)
|
||||
qdel(K)
|
||||
|
||||
if(!(flags_1&NODECONSTRUCT_1))
|
||||
if(!(flags_1 & NODECONSTRUCT_1) && !(state >= PRWINDOW_FRAME_BOLTED))
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
I.play_tool_sound(src, 75)
|
||||
if(reinf)
|
||||
if(state == WINDOW_SCREWED_TO_FRAME || state == WINDOW_IN_FRAME)
|
||||
to_chat(user, "<span class='notice'>You begin to [state == WINDOW_SCREWED_TO_FRAME ? "unscrew the window from":"screw the window to"] the frame...</span>")
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
|
||||
if(state == WINDOW_SCREWED_TO_FRAME || state == WINDOW_IN_FRAME && anchored)
|
||||
to_chat(user, "<span class='notice'>You begin to [state == WINDOW_SCREWED_TO_FRAME ? "unscrew the window from":"screw the window to"] the frame...</span>")
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
|
||||
if(extra_reinforced && state == WINDOW_IN_FRAME)
|
||||
state = PRWINDOW_SECURE
|
||||
else
|
||||
state = (state == WINDOW_IN_FRAME ? WINDOW_SCREWED_TO_FRAME : WINDOW_IN_FRAME)
|
||||
to_chat(user, "<span class='notice'>You [state == WINDOW_IN_FRAME ? "unfasten the window from":"fasten the window to"] the frame.</span>")
|
||||
else if(state == WINDOW_OUT_OF_FRAME)
|
||||
to_chat(user, "<span class='notice'>You begin to [anchored ? "unscrew the frame from":"screw the frame to"] the floor...</span>")
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
|
||||
setAnchored(!anchored)
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "fasten the frame to":"unfasten the frame from"] the floor.</span>")
|
||||
else //if we're not reinforced, we don't need to check or update state
|
||||
to_chat(user, "<span class='notice'>You begin to [anchored ? "unscrew the window from":"screw the window to"] the floor...</span>")
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_anchored, anchored)))
|
||||
to_chat(user, "<span class='notice'>You [state == WINDOW_IN_FRAME ? "unfasten the window from":"fasten the window to"] the frame.</span>")
|
||||
else if(state == WINDOW_OUT_OF_FRAME)
|
||||
to_chat(user, "<span class='notice'>You begin to [anchored ? "unscrew the frame from":"screw the frame to"] the floor...</span>")
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
|
||||
setAnchored(!anchored)
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "fasten the window to":"unfasten the window from"] the floor.</span>")
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "fasten the frame to":"unfasten the frame from"] the floor.</span>")
|
||||
return
|
||||
|
||||
|
||||
else if(I.tool_behaviour == TOOL_CROWBAR && reinf && (state == WINDOW_OUT_OF_FRAME || state == WINDOW_IN_FRAME))
|
||||
else if(I.tool_behaviour == TOOL_CROWBAR && reinf && (state == WINDOW_OUT_OF_FRAME || state == WINDOW_IN_FRAME) && anchored)
|
||||
to_chat(user, "<span class='notice'>You begin to lever the window [state == WINDOW_OUT_OF_FRAME ? "into":"out of"] the frame...</span>")
|
||||
I.play_tool_sound(src, 75)
|
||||
if(I.use_tool(src, user, decon_speed, extra_checks = CALLBACK(src, .proc/check_state_and_anchored, state, anchored)))
|
||||
@@ -270,8 +287,67 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
to_chat(user, "<span class='notice'>You successfully disassemble [src].</span>")
|
||||
qdel(src)
|
||||
return
|
||||
if(!reinf || !anchored)
|
||||
return ..()
|
||||
switch(state)
|
||||
if(PRWINDOW_SECURE)
|
||||
if(extra_reinforced)
|
||||
if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HARM)
|
||||
user.visible_message("<span class='notice'>[user] holds \the [I] to the security screws on \the [src]...</span>",
|
||||
"<span class='notice'>You begin heating the security screws on \the [src]...</span>")
|
||||
if(I.use_tool(src, user, 180, volume = 100))
|
||||
to_chat(user, "<span class='notice'>The security bolts are glowing white hot and look ready to be removed.</span>")
|
||||
state = PRWINDOW_BOLTS_HEATED
|
||||
addtimer(CALLBACK(src, .proc/cool_bolts), 300)
|
||||
return
|
||||
else
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user] digs into the screws and starts removing them...</span>",
|
||||
"<span class='notice'>You dig into the screws hard and they start turning...</span>")
|
||||
if(I.use_tool(src, user, 80, volume = 50))
|
||||
state = PRWINDOW_BOLTS_OUT
|
||||
to_chat(user, "<span class='notice'>The screws come out, and a gap forms around the edge of the pane.</span>")
|
||||
return
|
||||
if(PRWINDOW_BOLTS_HEATED)
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user] digs into the security screws and starts removing them...</span>",
|
||||
"<span class='notice'>You dig into the screws hard and they start turning...</span>")
|
||||
if(I.use_tool(src, user, 80, volume = 50))
|
||||
state = PRWINDOW_BOLTS_OUT
|
||||
to_chat(user, "<span class='notice'>The screws come out, and a gap forms around the edge of the pane.</span>")
|
||||
return
|
||||
if(PRWINDOW_BOLTS_OUT)
|
||||
if(I.tool_behaviour == TOOL_CROWBAR)
|
||||
user.visible_message("<span class='notice'>[user] wedges \the [I] into the gap in the frame and starts prying...</span>",
|
||||
"<span class='notice'>You wedge \the [I] into the gap in the frame and start prying...</span>")
|
||||
if(I.use_tool(src, user, 50, volume = 50))
|
||||
state = PRWINDOW_POPPED
|
||||
to_chat(user, "<span class='notice'>The panel pops out of the frame, exposing some thin metal bars that looks like they can be cut.</span>")
|
||||
return
|
||||
if(PRWINDOW_POPPED)
|
||||
if(I.tool_behaviour == TOOL_WIRECUTTER)
|
||||
user.visible_message("<span class='notice'>[user] starts cutting the exposed bars on \the [src]...</span>",
|
||||
"<span class='notice'>You start cutting the exposed bars on \the [src]</span>")
|
||||
if(I.use_tool(src, user, 30, volume = 50))
|
||||
state = PRWINDOW_BARS_CUT
|
||||
to_chat(user, "<span class='notice'>The panels falls out of the way exposing the frame bolts.</span>")
|
||||
return
|
||||
if(PRWINDOW_BARS_CUT)
|
||||
if(I.tool_behaviour == TOOL_WRENCH)
|
||||
user.visible_message("<span class='notice'>[user] starts unfastening \the [src] from the frame...</span>",
|
||||
"<span class='notice'>You start unfastening the bolts from the frame...</span>")
|
||||
if(I.use_tool(src, user, 50, volume = 50))
|
||||
to_chat(user, "<span class='notice'>You unscrew the bolts from the frame and the window pops loose.</span>")
|
||||
state = WINDOW_OUT_OF_FRAME
|
||||
setAnchored(FALSE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/window/proc/cool_bolts()
|
||||
if(state == PRWINDOW_BOLTS_HEATED)
|
||||
state = PRWINDOW_SECURE
|
||||
visible_message("<span class='notice'>The bolts on \the [src] look like they've cooled off...</span>")
|
||||
|
||||
/obj/structure/window/setAnchored(anchorvalue)
|
||||
..()
|
||||
air_update_turf(TRUE)
|
||||
@@ -577,6 +653,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
desc = "A window made out of a plasma-silicate alloy and a rod matrix. It looks hopelessly tough to break and is most likely nigh fireproof."
|
||||
icon_state = "plasmarwindow"
|
||||
reinf = TRUE
|
||||
extra_reinforced = TRUE
|
||||
heat_resistance = 50000
|
||||
armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100)
|
||||
max_integrity = 500
|
||||
@@ -642,6 +719,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
icon = 'icons/obj/smooth_structures/rplasma_window.dmi'
|
||||
icon_state = "rplasmawindow"
|
||||
dir = FULLTILE_WINDOW_DIR
|
||||
state = PRWINDOW_SECURE
|
||||
max_integrity = 1000
|
||||
fulltile = TRUE
|
||||
flags_1 = PREVENT_CLICK_UNDER_1
|
||||
@@ -726,6 +804,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
fulltile = TRUE
|
||||
flags_1 = PREVENT_CLICK_UNDER_1
|
||||
reinf = TRUE
|
||||
extra_reinforced = TRUE
|
||||
heat_resistance = 1600
|
||||
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100)
|
||||
smooth = SMOOTH_TRUE
|
||||
@@ -758,6 +837,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
wave_explosion_block = EXPLOSION_BLOCK_BOROSILICATE_WINDOW
|
||||
wave_explosion_multiply = EXPLOSION_DAMPEN_BOROSILICATE_WINDOW
|
||||
decon_speed = 40
|
||||
extra_reinforced = TRUE
|
||||
glass_type = /obj/item/stack/tile/brass
|
||||
glass_amount = 1
|
||||
reinf = FALSE
|
||||
|
||||
@@ -116,6 +116,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/show_tip,
|
||||
/client/proc/smite,
|
||||
/client/proc/admin_away,
|
||||
/client/proc/spawn_floor_cluwne,
|
||||
/client/proc/cmd_admin_toggle_fov, //CIT CHANGE - FOV
|
||||
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
|
||||
))
|
||||
|
||||
@@ -1333,9 +1333,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
ADMIN_PUNISHMENT_SHOES,
|
||||
ADMIN_PUNISHMENT_PICKLE,
|
||||
ADMIN_PUNISHMENT_FRY,
|
||||
ADMIN_PUNISHMENT_CRACK,
|
||||
ADMIN_PUNISHMENT_BLEED,
|
||||
ADMIN_PUNISHMENT_SCARIFY)
|
||||
ADMIN_PUNISHMENT_CRACK,
|
||||
ADMIN_PUNISHMENT_BLEED,
|
||||
ADMIN_PUNISHMENT_SCARIFY,
|
||||
ADMIN_PUNISHMENT_CLUWNE)
|
||||
|
||||
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
|
||||
|
||||
@@ -1501,6 +1502,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
to_chat(usr,"<span class='warning'>[C] does not have knottable shoes!</span>")
|
||||
return
|
||||
sick_kicks.adjust_laces(SHOES_KNOTTED)
|
||||
if(ADMIN_PUNISHMENT_CLUWNE)
|
||||
if(!iscarbon(target))
|
||||
to_chat(usr,"<span class='warning'>This must be used on a carbon mob.</span>")
|
||||
return
|
||||
target.cluwneify()
|
||||
|
||||
punish_log(target, punishment)
|
||||
|
||||
@@ -1691,3 +1697,23 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if(!source)
|
||||
return
|
||||
REMOVE_TRAIT(D,chosen_trait,source)
|
||||
|
||||
/client/proc/spawn_floor_cluwne()
|
||||
set category = "Admin.Fun"
|
||||
set name = "Unleash Floor Cluwne"
|
||||
set desc = "Pick a specific target or just let it select randomly and spawn the floor cluwne mob on the station. Be warned: spawning more than one may cause issues!"
|
||||
var/target
|
||||
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(usr)
|
||||
target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list
|
||||
if(target && ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(T)
|
||||
FC.Acquire_Victim(H)
|
||||
else
|
||||
new /mob/living/simple_animal/hostile/floor_cluwne(T)
|
||||
log_admin("[key_name(usr)] spawned floor cluwne.")
|
||||
message_admins("[key_name(usr)] spawned floor cluwne.")
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
/datum/clockwork_scripture/create_object/stargazer/check_special_requirements()
|
||||
var/area/A = get_area(invoker)
|
||||
var/turf/T = get_turf(invoker)
|
||||
if(!is_station_level(invoker.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY))
|
||||
if(!is_station_level(invoker.z) || isspaceturf(T) || !(A?.area_flags & CULT_PERMITTED))
|
||||
to_chat(invoker, "<span class='danger'>Stargazers can't be built off-station.</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
return FALSE
|
||||
var/area/A = get_area(invoker)
|
||||
var/turf/T = get_turf(invoker)
|
||||
if(!is_station_level(T.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY) || isshuttleturf(T))
|
||||
if(!is_station_level(T.z) || isspaceturf(T) || !(A?.area_flags & CULT_PERMITTED) || isshuttleturf(T))
|
||||
to_chat(invoker, "<span class='warning'>You must be on the station to activate the Ark!</span>")
|
||||
return FALSE
|
||||
if(GLOB.clockwork_gateway_activated)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
break
|
||||
if(has_starlight && anchored)
|
||||
var/area/A = get_area(src)
|
||||
if(A.outdoors || A.map_name == "Space" || !(A.area_flags & VALID_TERRITORY))
|
||||
if(A.outdoors || A.map_name == "Space" || !(A?.area_flags & CULT_PERMITTED))
|
||||
has_starlight = FALSE
|
||||
if(old_status != has_starlight)
|
||||
if(has_starlight)
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
var/sanity = 0
|
||||
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
|
||||
var/area/summon = pick(GLOB.sortedAreas - summon_spots)
|
||||
if(summon && is_station_level(summon.z) && !(summon.area_flags & VALID_TERRITORY))
|
||||
if(summon && is_station_level(summon.z) && (summon.area_flags & VALID_TERRITORY))
|
||||
summon_spots += summon
|
||||
sanity++
|
||||
update_explanation_text()
|
||||
|
||||
@@ -148,7 +148,7 @@ This file contains the cult dagger and rune list code
|
||||
to_chat(user, "<span class='cult'>There is already a rune here.</span>")
|
||||
return FALSE
|
||||
var/area/A = get_area(T)
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & VALID_TERRITORY))
|
||||
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & CULT_PERMITTED))
|
||||
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
var/list/lore = list()
|
||||
|
||||
data["charges"] = charge
|
||||
data["total_sacs"] = cultie.total_sacrifices
|
||||
|
||||
for(var/X in to_know)
|
||||
lore = list()
|
||||
@@ -96,7 +97,11 @@
|
||||
lore["type"] = EK.type
|
||||
lore["name"] = EK.name
|
||||
lore["cost"] = EK.cost
|
||||
lore["disabled"] = EK.cost <= charge ? FALSE : TRUE
|
||||
lore["sacs"] = EK.sacs_needed
|
||||
if(EK.cost <= charge && cultie.total_sacrifices >= EK.sacs_needed)
|
||||
lore["disabled"] = FALSE
|
||||
else
|
||||
lore["disabled"] = TRUE
|
||||
lore["path"] = EK.route
|
||||
lore["state"] = "Research"
|
||||
lore["flavour"] = EK.gain_text
|
||||
@@ -108,6 +113,7 @@
|
||||
var/datum/eldritch_knowledge/EK = known[X]
|
||||
lore["name"] = EK.name
|
||||
lore["cost"] = EK.cost
|
||||
lore["sacs"] = EK.sacs_needed
|
||||
lore["disabled"] = TRUE
|
||||
lore["path"] = EK.route
|
||||
lore["state"] = "Researched"
|
||||
|
||||
@@ -165,6 +165,25 @@
|
||||
new /obj/effect/reality_smash(chosen_location)
|
||||
ReworkNetwork()
|
||||
|
||||
/**
|
||||
*CIT CHANGE
|
||||
*
|
||||
*Creates a singular reality smash
|
||||
*Credit to slimelust
|
||||
*/
|
||||
|
||||
/datum/reality_smash_tracker/proc/RandomSpawnSmash(var/deferred = FALSE)
|
||||
var/turf/chosen_location = get_safe_random_station_turf()
|
||||
//we also dont want them close to each other, at least 1 tile of separation
|
||||
var/obj/effect/reality_smash/what_if_i_have_one = locate() in range(1, chosen_location)
|
||||
var/obj/effect/broken_illusion/what_if_i_had_one_but_got_used = locate() in range(1, chosen_location)
|
||||
var/tries = 10
|
||||
while((what_if_i_have_one || what_if_i_had_one_but_got_used) && tries-- > 0)
|
||||
chosen_location = get_safe_random_station_turf()
|
||||
new /obj/effect/reality_smash(chosen_location)
|
||||
if(!deferred)
|
||||
ReworkNetwork()
|
||||
|
||||
/**
|
||||
* Adds a mind to the list of people that can see the reality smashes
|
||||
*
|
||||
@@ -200,15 +219,23 @@
|
||||
/obj/effect/broken_illusion/Initialize()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src,.proc/show_presence),15 SECONDS)
|
||||
addtimer(CALLBACK(src,.proc/remove_presence),195 SECONDS)
|
||||
|
||||
var/image/I = image('icons/effects/eldritch.dmi',src,null,OBJ_LAYER)
|
||||
I.override = TRUE
|
||||
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/silicons, "pierced_reality", I)
|
||||
|
||||
/obj/effect/broken_illusion/Destroy()
|
||||
GLOB.reality_smash_track.RandomSpawnSmash()
|
||||
return ..()
|
||||
|
||||
///Makes this obj appear out of nothing
|
||||
/obj/effect/broken_illusion/proc/show_presence()
|
||||
animate(src,alpha = 255,time = 15 SECONDS)
|
||||
|
||||
/obj/effect/broken_illusion/proc/remove_presence()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/broken_illusion/attack_hand(mob/living/user, list/modifiers)
|
||||
if(!ishuman(user))
|
||||
return ..()
|
||||
|
||||
@@ -44,46 +44,6 @@
|
||||
if(target.stat == DEAD)
|
||||
to_chat(user,"<span class='warning'>[target.real_name] is dead. Bring them onto a transmutation rune!</span>")
|
||||
|
||||
/datum/action/innate/heretic_shatter
|
||||
name = "Shattering Offer"
|
||||
desc = "After a brief delay, you will be granted salvation from a dire situation at the cost of your blade. (Teleports you to a random safe turf on your current z level after a windup, but destroys your blade.)"
|
||||
background_icon_state = "bg_ecult"
|
||||
button_icon_state = "shatter"
|
||||
icon_icon = 'icons/mob/actions/actions_ecult.dmi'
|
||||
check_flags = MOBILITY_HOLD|MOBILITY_MOVE|MOBILITY_USE
|
||||
var/mob/living/carbon/human/holder
|
||||
var/obj/item/melee/sickly_blade/sword
|
||||
|
||||
/datum/action/innate/heretic_shatter/Grant(mob/user, obj/object)
|
||||
sword = object
|
||||
holder = user
|
||||
//i know what im doing
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/heretic_shatter/IsAvailable()
|
||||
if(IS_HERETIC(holder) || IS_HERETIC_MONSTER(holder))
|
||||
return ..()
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/heretic_shatter/Activate()
|
||||
if(do_after(holder,10, target = holder))
|
||||
if(!sword || QDELETED(sword))
|
||||
return
|
||||
if(!IsAvailable()) //Never trust the user.
|
||||
return
|
||||
var/swordz = (get_turf(sword))?.z //SHOULD usually have a turf but if it doesn't better be prepared.
|
||||
if(!swordz)
|
||||
to_chat(holder, "<span class='warning'>[sword] flickers but remains in place, as do you...</span>")
|
||||
return
|
||||
var/turf/safe_turf = find_safe_turf(zlevels = swordz, extended_safety_checks = TRUE)
|
||||
if(!safe_turf)
|
||||
to_chat(holder, "<span class='warning'>[sword] flickers but remains in place, as do you...</span>")
|
||||
return
|
||||
do_teleport(holder,safe_turf,forceMove = TRUE,channel=TELEPORT_CHANNEL_MAGIC)
|
||||
to_chat(holder,"<span class='warning'>You feel a gust of energy flow through your body... the Rusted Hills heard your call...</span>")
|
||||
qdel(sword)
|
||||
|
||||
/obj/item/melee/sickly_blade
|
||||
name = "sickly blade"
|
||||
desc = "A sickly green crescent blade, decorated with an ornamental eye. You feel like you're being watched..."
|
||||
@@ -101,11 +61,6 @@
|
||||
throwforce = 10
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "tore", "lacerated", "ripped", "diced", "rended")
|
||||
var/datum/action/innate/heretic_shatter/linked_action
|
||||
|
||||
/obj/item/melee/sickly_blade/Initialize()
|
||||
. = ..()
|
||||
linked_action = new(src)
|
||||
|
||||
/obj/item/melee/sickly_blade/attack(mob/living/target, mob/living/user)
|
||||
if(!(IS_HERETIC(user) || IS_HERETIC_MONSTER(user)))
|
||||
@@ -120,13 +75,17 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/sickly_blade/pickup(mob/user)
|
||||
. = ..()
|
||||
linked_action.Grant(user, src)
|
||||
|
||||
/obj/item/melee/sickly_blade/dropped(mob/user, silent)
|
||||
. = ..()
|
||||
linked_action.Remove(user, src)
|
||||
/obj/item/melee/sickly_blade/attack_self(mob/user)
|
||||
var/turf/safe_turf = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
|
||||
if(IS_HERETIC(user) || IS_HERETIC_MONSTER(user))
|
||||
if(do_teleport(user, safe_turf, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC))
|
||||
to_chat(user,"<span class='warning'>As you shatter [src], you feel a gust of energy flow through your body. The Rusted Hills heard your call...</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>You shatter [src], but your plea goes unanswered.</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>You shatter [src].</span>")
|
||||
playsound(src, "shatter", 70, TRUE) //copied from the code for smashing a glass sheet onto the ground to turn it into a shard
|
||||
qdel(src)
|
||||
|
||||
/obj/item/melee/sickly_blade/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
@@ -141,6 +100,11 @@
|
||||
else
|
||||
eldritch_knowledge_datum.on_ranged_attack_eldritch_blade(target,user,click_parameters)
|
||||
|
||||
/obj/item/melee/sickly_blade/examine(mob/user)
|
||||
. = ..()
|
||||
if(IS_HERETIC(user) || IS_HERETIC_MONSTER(user))
|
||||
. += "<span class='notice'><B>A heretic (or a servant of one) can shatter this blade to teleport to a random, mostly safe location by activating it in-hand.</B></span>"
|
||||
|
||||
/obj/item/melee/sickly_blade/rust
|
||||
name = "rusted blade"
|
||||
desc = "This crescent blade is decrepit, wasting to rust. Yet still it bites, ripping flesh and bone with jagged, rotten teeth."
|
||||
@@ -243,6 +207,7 @@
|
||||
// slightly worse than normal cult robes
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/void_cloak
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/void/ToggleHood()
|
||||
if(!iscarbon(loc))
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
var/gain_text = ""
|
||||
///Cost of knowledge in souls
|
||||
var/cost = 0
|
||||
///Required sacrifices to unlock
|
||||
var/sacs_needed = 0
|
||||
///Next knowledge in the research tree
|
||||
var/list/next_knowledge = list()
|
||||
///What knowledge is incompatible with this. This will simply make it impossible to research knowledges that are in banned_knowledge once this gets researched.
|
||||
@@ -230,7 +232,6 @@
|
||||
atoms -= H
|
||||
H.gib()
|
||||
|
||||
|
||||
///////////////
|
||||
///Base lore///
|
||||
///////////////
|
||||
|
||||
@@ -109,10 +109,15 @@
|
||||
gain_text = "When the Glory of the Lantern scorches and sears their skin, nothing will protect them from the ashes."
|
||||
desc = "Fire off five streams of fire from your hand, each setting ablaze targets hit and scorching them upon contact."
|
||||
cost = 2
|
||||
sacs_needed = 3
|
||||
spell_to_add = /obj/effect/proc_holder/spell/pointed/nightwatchers_rite
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/ash_final)
|
||||
route = PATH_ASH
|
||||
|
||||
/datum/eldritch_knowledge/spell/nightwatchers_rite/on_gain(mob/user)
|
||||
. = ..()
|
||||
priority_announce("Large heat signatures discovered! A swelling fiery horror is coming..", sound = 'sound/misc/notice1.ogg')
|
||||
|
||||
/datum/eldritch_knowledge/ash_blade_upgrade
|
||||
name = "Fiery Blade"
|
||||
gain_text = "Blade in hand, he swung and swung as the ash fell from the skies. His city, his people... all burnt to cinders, and yet life still remained in his charred body."
|
||||
@@ -181,6 +186,7 @@
|
||||
desc = "Bring 3 corpses onto a transmutation rune, you will become immune to fire, the vacuum of space, cold and other enviromental hazards and become overall sturdier to all other damages. You will gain a spell that passively creates ring of fire around you as well ,as you will gain a powerful ability that lets you create a wave of flames all around you."
|
||||
required_atoms = list(/mob/living/carbon/human)
|
||||
cost = 5
|
||||
sacs_needed = 8
|
||||
route = PATH_ASH
|
||||
var/list/trait_list = list(TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE)
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
gain_text = "The Uncanny Man, who walks alone in the valley between the worlds... I was able to summon his aid."
|
||||
desc = "You can now summon a Raw Prophet by transmutating a pair of eyes, a left arm and a pool of blood. Raw prophets have increased seeing range, as well as X-Ray vision, but they are very fragile."
|
||||
cost = 1
|
||||
required_atoms = list(/obj/item/organ/eyes,/obj/item/bodypart/l_arm,/obj/item/bodypart/r_arm,/obj/effect/decal/cleanable/blood)
|
||||
required_atoms = list(/obj/item/organ/eyes,/obj/item/bodypart/l_arm,/obj/effect/decal/cleanable/blood)
|
||||
mob_to_summon = /mob/living/simple_animal/hostile/eldritch/raw_prophet
|
||||
next_knowledge = list(/datum/eldritch_knowledge/flesh_blade_upgrade,/datum/eldritch_knowledge/rune_carver,/datum/eldritch_knowledge/curse/paralysis)
|
||||
route = PATH_FLESH
|
||||
@@ -217,6 +217,7 @@
|
||||
desc = "Bring 3 bodies onto a transmutation rune to shed your human form and ascend to untold power."
|
||||
required_atoms = list(/mob/living/carbon/human)
|
||||
cost = 5
|
||||
sacs_needed = 8
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/eldritch_knowledge/final/flesh_final/on_finished_recipe(mob/living/user, list/atoms, loc)
|
||||
@@ -257,6 +258,11 @@
|
||||
gain_text = "The ignorant mind that inhabits their feeble bodies will crumble when they acknowledge - willingly or not, the truth."
|
||||
desc = "By forcing the knowledge of the Mansus upon my foes, I can show them things that would drive any normal man insane."
|
||||
cost = 2
|
||||
sacs_needed = 3
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/mad_touch
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/flesh_final)
|
||||
route = PATH_FLESH
|
||||
|
||||
/datum/eldritch_knowledge/spell/touch_of_madness/on_gain(mob/user)
|
||||
. = ..()
|
||||
priority_announce("The stench of rotting flesh fills the air... An approaching abomination has been detected!", sound = 'sound/misc/notice1.ogg')
|
||||
|
||||
@@ -159,15 +159,21 @@
|
||||
desc = "Applying your knowledge of rust to the human body, a knowledge that could decay your foes from the inside out, resulting in organ failure, vomiting, or eventual death through the peeling of rotting flesh."
|
||||
gain_text = "Rust, decay, it's all the same. All that remains is application."
|
||||
cost = 2
|
||||
sacs_needed = 3
|
||||
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/grasp_of_decay
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/rust_final)
|
||||
route = PATH_RUST
|
||||
|
||||
/datum/eldritch_knowledge/spell/grasp_of_decay/on_gain(mob/user)
|
||||
. = ..()
|
||||
priority_announce("A foul wind is blowing... The floor creaks with rust as something sinister approaches!", sound = 'sound/misc/notice1.ogg')
|
||||
|
||||
/datum/eldritch_knowledge/final/rust_final
|
||||
name = "Rustbringer's Oath"
|
||||
desc = "Bring three corpses onto a transmutation rune. After you finish the ritual, rust will now automatically spread from the rune. Your healing on rust is also tripled, while you become more resilient overall."
|
||||
gain_text = "Champion of rust. Corruptor of steel. Fear the dark for the Rustbringer has come! Rusted Hills, CALL MY NAME!"
|
||||
cost = 5
|
||||
sacs_needed = 8
|
||||
required_atoms = list(/mob/living/carbon/human)
|
||||
route = PATH_RUST
|
||||
|
||||
|
||||
@@ -160,15 +160,21 @@
|
||||
gain_text = "This world will be my stage, and nothing will be out of my reach."
|
||||
desc = "Gain the ability to mark a 7x7 area as your domain after a short delay. Creatures in your domain are slowed and branded with a void mark, allowing you to quickly teleport to them and slash them, further inhibiting their ability to move."
|
||||
cost = 2
|
||||
sacs_needed = 3
|
||||
spell_to_add = /obj/effect/proc_holder/spell/aoe_turf/domain_expansion
|
||||
next_knowledge = list(/datum/eldritch_knowledge/final/void_final)
|
||||
route = PATH_VOID
|
||||
|
||||
/datum/eldritch_knowledge/spell/domain_expansion/on_gain(mob/user)
|
||||
. = ..()
|
||||
priority_announce("Echos of the lost in space are heard... An ominous presence is being detected! ", sound = 'sound/misc/notice1.ogg')
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final
|
||||
name = "Waltz at the End of Time"
|
||||
desc = "Bring 3 corpses onto the transmutation rune. After you finish the ritual you will automatically silence people around you and will summon a snow storm around you."
|
||||
gain_text = "The world falls into darkness. I stand in an empty plane, small flakes of ice fall from the sky. The Aristocrat stands before me, he motions to me. We will play a waltz to the whispers of dying reality, as the world is destroyed before our eyes."
|
||||
cost = 5
|
||||
sacs_needed = 8
|
||||
required_atoms = list(/mob/living/carbon/human)
|
||||
route = PATH_VOID
|
||||
///soundloop for the void theme
|
||||
|
||||
@@ -492,7 +492,7 @@
|
||||
var/targetAmount = 100
|
||||
|
||||
/datum/objective/revenant/New()
|
||||
targetAmount = rand(350,600)
|
||||
targetAmount = rand(150,300)
|
||||
explanation_text = "Absorb [targetAmount] points of essence from humans."
|
||||
..()
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
if("VICTIM")
|
||||
var/mob/living/carbon/human/T = target
|
||||
var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
|
||||
if(C?.cult_team.is_sacrifice_target(T.mind))
|
||||
if(C && C.cult_team.is_sacrifice_target(T.mind))
|
||||
if(iscultist(user))
|
||||
to_chat(user, "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>")
|
||||
else
|
||||
|
||||
@@ -252,6 +252,10 @@
|
||||
name = "Barnyard Curse"
|
||||
spell_type = /obj/effect/proc_holder/spell/pointed/barnyardcurse
|
||||
|
||||
/datum/spellbook_entry/cluwne
|
||||
name = "Cluwne Curse"
|
||||
spell_type = /obj/effect/proc_holder/spell/targeted/cluwnecurse
|
||||
|
||||
/datum/spellbook_entry/charge
|
||||
name = "Charge"
|
||||
spell_type = /obj/effect/proc_holder/spell/targeted/charge
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
var/static/list/blacklisted_error = typecacheof(list(
|
||||
/obj/structure/closet/crate/secure,
|
||||
/obj/structure/closet/crate/large,
|
||||
/obj/structure/closet/secure_closet/goodies
|
||||
/obj/structure/closet/secure_closet/cargo
|
||||
))
|
||||
if(is_type_in_list(container, blacklisted_error))
|
||||
P.errors &= ~MANIFEST_ERROR_ITEM
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
|
||||
var/obj/structure/closet/crate/C
|
||||
if(paying_account)
|
||||
if(ispath(crate_type, /obj/structure/closet/secure_closet/goodies)) // lets ensure private orders don't come in crates when the original one comes in lockers
|
||||
C = new /obj/structure/closet/secure_closet/goodies/owned(A, paying_account) // that would lead to infinite money exploits
|
||||
if(ispath(crate_type, /obj/structure/closet/secure_closet/cargo)) // lets ensure private orders don't come in crates when the original one comes in lockers
|
||||
C = new /obj/structure/closet/secure_closet/cargo/owned(A, paying_account) // that would lead to infinite money exploits
|
||||
else
|
||||
C = new /obj/structure/closet/crate/secure/owned(A, paying_account)
|
||||
C.name = "[crate_name] - Purchased by [paying_account.account_holder]"
|
||||
|
||||
@@ -14,56 +14,56 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/supply_pack/materials/cardboard50
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "50 Cardboard Sheets"
|
||||
desc = "Create a bunch of boxes."
|
||||
cost = 300 //thrice their export value
|
||||
contains = list(/obj/item/stack/sheet/cardboard/fifty)
|
||||
|
||||
/datum/supply_pack/materials/glass50
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "50 Glass Sheets"
|
||||
desc = "Let some nice light in with fifty glass sheets!"
|
||||
cost = 300 //double their export value
|
||||
contains = list(/obj/item/stack/sheet/glass/fifty)
|
||||
|
||||
/datum/supply_pack/materials/metal50
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "50 Metal Sheets"
|
||||
desc = "Any construction project begins with a good stack of fifty metal sheets!"
|
||||
cost = 300 //double their export value
|
||||
contains = list(/obj/item/stack/sheet/metal/fifty)
|
||||
|
||||
/datum/supply_pack/materials/plasteel20
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "20 Plasteel Sheets"
|
||||
desc = "Reinforce the station's integrity with twenty plasteel sheets!"
|
||||
cost = 4000
|
||||
contains = list(/obj/item/stack/sheet/plasteel/twenty)
|
||||
|
||||
/datum/supply_pack/materials/plastic50
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
name = "50 Plastic Sheets"
|
||||
/datum/supply_pack/materials/plastic20
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "20 Plastic Sheets"
|
||||
desc = "Build a limitless amount of toys with fifty plastic sheets!"
|
||||
cost = 200 // double their export
|
||||
contains = list(/obj/item/stack/sheet/plastic/twenty)
|
||||
|
||||
/datum/supply_pack/materials/sandstone30
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "30 Sandstone Blocks"
|
||||
desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
|
||||
cost = 150 // five times their export
|
||||
contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
|
||||
|
||||
/datum/supply_pack/materials/wood20
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "20 Wood Planks"
|
||||
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with twenty wooden planks!"
|
||||
cost = 400 // 6-7 planks shy from having equal import/export prices
|
||||
contains = list(/obj/item/stack/sheet/mineral/wood/twenty)
|
||||
|
||||
/datum/supply_pack/materials/rcdammo
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "Large RCD ammo Single-Pack"
|
||||
desc = "A single large compressed RCD matter pack, to help with any holes or projects people might be working on."
|
||||
cost = 600
|
||||
|
||||
@@ -370,7 +370,7 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/supply_pack/misc/carpet
|
||||
crate_type = /obj/structure/closet/secure_closet/goodies
|
||||
crate_type = /obj/structure/closet/secure_closet/cargo
|
||||
name = "Classic Carpet Single-Pack"
|
||||
desc = "Plasteel floor tiles getting on your nerves? This 50 units stack of extra soft carpet will tie any room together."
|
||||
cost = 200
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/obj/item/clothing/mask/gas/cluwne
|
||||
name = "clown wig and mask"
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
|
||||
flags_cover = MASKCOVERSEYES
|
||||
icon_state = "cluwne"
|
||||
item_state = "cluwne"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
clothing_flags = ALLOWINTERNALS
|
||||
item_flags = ABSTRACT | DROPDEL
|
||||
flags_inv = HIDEEARS|HIDEEYES
|
||||
var/voicechange = TRUE
|
||||
var/last_sound = 0
|
||||
var/delay = 15
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/Initialize()
|
||||
.=..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
|
||||
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh1()
|
||||
if(world.time - delay > last_sound)
|
||||
playsound (src, 'sound/voice/cluwnelaugh1.ogg', 30, 1)
|
||||
last_sound = world.time
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh2()
|
||||
if(world.time - delay > last_sound)
|
||||
playsound (src, 'sound/voice/cluwnelaugh2.ogg', 30, 1)
|
||||
last_sound = world.time
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh3()
|
||||
if(world.time - delay > last_sound)
|
||||
playsound (src, 'sound/voice/cluwnelaugh3.ogg', 30, 1)
|
||||
last_sound = world.time
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/equipped(mob/user, slot) //when you put it on
|
||||
var/mob/living/carbon/C = user
|
||||
if((C.wear_mask == src) && (voicechange))
|
||||
play_laugh1()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/handle_speech(datum/source, list/speech_args)
|
||||
if(voicechange)
|
||||
if(prob(5)) //the brain isn't fully gone yet...
|
||||
speech_args[SPEECH_MESSAGE] = pick("HELP ME!!","PLEASE KILL ME!!","I WANT TO DIE!!", "END MY SUFFERING", "I CANT TAKE THIS ANYMORE!!" ,"SOMEBODY STOP ME!!")
|
||||
play_laugh2()
|
||||
if(prob(3))
|
||||
speech_args[SPEECH_MESSAGE] = pick("HOOOOINKKKKKKK!!", "HOINK HOINK HOINK HOINK!!","HOINK HOINK!!","HOOOOOOIIINKKKK!!") //but most of the time they cant speak,
|
||||
play_laugh3()
|
||||
else
|
||||
speech_args[SPEECH_MESSAGE] = pick("HEEEENKKKKKK!!", "HONK HONK HONK HONK!!","HONK HONK!!","HOOOOOONKKKK!!") //More sounds,
|
||||
play_laugh1()
|
||||
return SPEECH_MESSAGE
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == SLOT_WEAR_MASK)
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.dna.add_mutation(CLUWNEMUT)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/happy_cluwne
|
||||
name = "Happy Cluwne Mask"
|
||||
desc = "The mask of a poor cluwne that has been scrubbed of its curse by the Nanotrasen supernatural machinations division. Guaranteed to be %99 curse free and %99.9 not haunted. "
|
||||
item_flags = ABSTRACT
|
||||
var/can_cluwne = FALSE
|
||||
var/is_cursed = FALSE //i don't care that this is *slightly* memory wasteful, it's just one more byte and it's not like some madman is going to spawn thousands of these
|
||||
var/is_very_cursed = FALSE
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/Initialize()
|
||||
.=..()
|
||||
if(prob(1)) //this function pre-determines the logic of the cluwne mask. applying and reapplying the mask does not alter or change anything
|
||||
is_cursed = TRUE
|
||||
is_very_cursed = FALSE
|
||||
else if(prob(0.1))
|
||||
is_cursed = FALSE
|
||||
is_very_cursed = TRUE
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/attack_self(mob/user)
|
||||
voicechange = !voicechange
|
||||
to_chat(user, "<span class='notice'>You turn the voice box [voicechange ? "on" : "off"]!</span>")
|
||||
if(voicechange)
|
||||
play_laugh1()
|
||||
|
||||
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(slot == SLOT_WEAR_MASK)
|
||||
if(is_cursed && can_cluwne) //logic predetermined
|
||||
log_admin("[key_name(H)] was made into a cluwne by [src]")
|
||||
message_admins("[key_name(H)] got cluwned by [src]")
|
||||
to_chat(H, "<span class='userdanger'>The masks straps suddenly tighten to your face and your thoughts are erased by a horrible green light!</span>")
|
||||
H.dropItemToGround(src)
|
||||
H.cluwneify()
|
||||
qdel(src)
|
||||
else if(is_very_cursed && can_cluwne)
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/simple_animal/hostile/floor_cluwne/S = new(T)
|
||||
S.Acquire_Victim(user)
|
||||
log_admin("[key_name(user)] summoned a floor cluwne using the [src]")
|
||||
message_admins("[key_name(user)] summoned a floor cluwne using the [src]")
|
||||
to_chat(H, "<span class='warning'>The mask suddenly slips off your face and... slides under the floor?</span>")
|
||||
to_chat(H, "<i>...dneirf uoy ot gnoleb ton seod tahT</i>")
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/item/clothing/shoes/clown_shoes/cluwne
|
||||
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"
|
||||
name = "clown shoes"
|
||||
icon_state = "cluwne"
|
||||
item_state = "cluwne"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
item_flags = DROPDEL
|
||||
var/footstep = 1
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/cluwne/Initialize()
|
||||
.=..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
|
||||
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/cluwne/step_action()
|
||||
if(footstep > 1)
|
||||
playsound(src, "clownstep", 50, 1)
|
||||
footstep = 0
|
||||
else
|
||||
footstep++
|
||||
|
||||
/obj/item/clothing/shoes/clown_shoes/cluwne/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == SLOT_SHOES)
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.dna.add_mutation(CLUWNEMUT)
|
||||
return
|
||||
@@ -255,6 +255,13 @@
|
||||
item_state = "maidapron"
|
||||
minimize_when_attached = FALSE
|
||||
|
||||
/obj/item/clothing/accessory/sleevecrop
|
||||
name = "one sleeved crop top"
|
||||
desc = "Off the shoulder crop top, for those nights out partying."
|
||||
icon_state = "sleevecrop"
|
||||
item_state = "sleevecrop"
|
||||
minimize_when_attached = FALSE
|
||||
|
||||
//////////
|
||||
//Medals//
|
||||
//////////
|
||||
@@ -466,6 +473,7 @@
|
||||
////////////////
|
||||
//HA HA! NERD!//
|
||||
////////////////
|
||||
|
||||
/obj/item/clothing/accessory/pocketprotector
|
||||
name = "pocket protector"
|
||||
desc = "Can protect your clothing from ink stains, but you'll look like a nerd if you're using one."
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/obj/item/clothing/under/cluwne
|
||||
name = "clown suit"
|
||||
desc = "<i>'HONK!'</i>"
|
||||
icon_state = "greenclown"
|
||||
item_state = "greenclown"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
item_flags = DROPDEL
|
||||
can_adjust = 0
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/under/cluwne/Initialize()
|
||||
.=..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
|
||||
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
|
||||
|
||||
/obj/item/clothing/under/cluwne/equipped(mob/living/carbon/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == SLOT_W_UNIFORM)
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.dna.add_mutation(CLUWNEMUT)
|
||||
return ..()
|
||||
@@ -56,7 +56,7 @@
|
||||
desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-."
|
||||
icon_state = "tactifool"
|
||||
item_state = "bl_suit"
|
||||
has_sensor = TRUE
|
||||
has_sensor = HAS_SENSORS
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5)
|
||||
|
||||
/obj/item/clothing/under/syndicate/cosmetic/skirt
|
||||
@@ -64,6 +64,7 @@
|
||||
icon_state = "tactifool_skirt"
|
||||
fitted = FEMALE_UNIFORM_TOP
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/syndicate/sniper
|
||||
name = "Tactical turtleneck suit"
|
||||
|
||||
@@ -102,9 +102,14 @@
|
||||
desc = "An uniform worn by command officers since 2420s."
|
||||
icon_state = "orv_com"
|
||||
|
||||
/obj/item/clothing/under/trek/engsec/orv
|
||||
/obj/item/clothing/under/trek/eng/orv
|
||||
desc = "An uniform worn by operations officers since 2420s."
|
||||
icon_state = "orv_ops"
|
||||
icon_state = "orv_eng"
|
||||
|
||||
/obj/item/clothing/under/trek/sec/orv
|
||||
desc = "An uniform worn by security officers since 2420s."
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
|
||||
icon_state = "orv_sec"
|
||||
|
||||
/obj/item/clothing/under/trek/medsci/orv
|
||||
desc = "An uniform worn by medsci officers since 2420s."
|
||||
@@ -114,13 +119,20 @@
|
||||
//honestly no idea why i added specified comm. uniforms but w/e
|
||||
/obj/item/clothing/under/trek/command/orv/captain
|
||||
name = "captain uniform"
|
||||
desc = "An uniform worn by captains since 2550s."
|
||||
desc = "An uniform worn by captains and commanders since 2550s."
|
||||
icon_state = "orv_com_capt"
|
||||
|
||||
/obj/item/clothing/under/trek/command/orv/engsec
|
||||
name = "operations command uniform"
|
||||
desc = "An uniform worn by operations command officers since 2550s."
|
||||
icon_state = "orv_com_ops"
|
||||
/obj/item/clothing/under/trek/command/orv/eng
|
||||
name = "engineering command uniform"
|
||||
desc = "An uniform worn by Chief Engineers since 2550s."
|
||||
icon_state = "orv_com_eng"
|
||||
|
||||
/obj/item/clothing/under/trek/command/orv/sec
|
||||
name = "security command uniform"
|
||||
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10)
|
||||
desc = "An uniform worn by Heads of Security since 2550s."
|
||||
icon_state = "orv_com_sec"
|
||||
|
||||
|
||||
/obj/item/clothing/under/trek/command/orv/medsci
|
||||
name = "medsci command uniform"
|
||||
@@ -131,13 +143,11 @@
|
||||
name = "adjutant uniform"
|
||||
desc = "An uniform worn by adjutants <i>(assistants)</i> since 2550s."
|
||||
icon_state = "orv_ass"
|
||||
item_state = "gy_suit"
|
||||
|
||||
/obj/item/clothing/under/trek/orv/service
|
||||
name = "service uniform"
|
||||
desc = "An uniform worn by service officers since 2550s."
|
||||
icon_state = "orv_srv"
|
||||
item_state = "g_suit"
|
||||
|
||||
//The Motion Picture
|
||||
/obj/item/clothing/under/trek/fedutil
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/datum/round_event_control/cat_surgeon
|
||||
name = "Cat Surgeon"
|
||||
typepath = /datum/round_event/cat_surgeon
|
||||
max_occurrences = 1
|
||||
weight = 10
|
||||
|
||||
|
||||
/datum/round_event/cat_surgeon/start()
|
||||
var/list/spawn_locs = list()
|
||||
for(var/X in GLOB.xeno_spawn)
|
||||
spawn_locs += X
|
||||
|
||||
if(!spawn_locs.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
|
||||
var/turf/T = get_turf(pick(spawn_locs))
|
||||
var/mob/living/simple_animal/hostile/cat_butcherer/S = new(T)
|
||||
playsound(S, 'sound/misc/catscream.ogg', 50, 1, -1)
|
||||
message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]")
|
||||
log_game("A cat surgeon has been spawned at [COORD(T)]")
|
||||
return SUCCESSFUL_SPAWN
|
||||
@@ -0,0 +1,23 @@
|
||||
/datum/round_event_control/floor_cluwne
|
||||
name = "Floor Cluwne"
|
||||
typepath = /datum/round_event/floor_cluwne
|
||||
max_occurrences = 1
|
||||
min_players = 20
|
||||
weight = 10
|
||||
|
||||
|
||||
/datum/round_event/floor_cluwne/start()
|
||||
var/list/spawn_locs = list()
|
||||
for(var/X in GLOB.xeno_spawn)
|
||||
spawn_locs += X
|
||||
|
||||
if(!spawn_locs.len)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
return MAP_ERROR
|
||||
|
||||
var/turf/T = get_turf(pick(spawn_locs))
|
||||
var/mob/living/simple_animal/hostile/floor_cluwne/S = new(T)
|
||||
playsound(S, 'sound/misc/bikehorn_creepy.ogg', 50, 1, -1)
|
||||
message_admins("A floor cluwne has been spawned at [COORD(T)][ADMIN_JMP(T)]")
|
||||
log_game("A floor cluwne has been spawned at [COORD(T)]")
|
||||
return SUCCESSFUL_SPAWN
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
@@ -391,6 +391,15 @@
|
||||
bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
|
||||
tastes = list("meat" = 3, "smokey sauce" = 1)
|
||||
foodtype = MEAT
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/goliathcalamari
|
||||
name = "goliath calamari"
|
||||
desc = "ACKCHYUALLY, this isn't calamari, guys!"
|
||||
icon_state = "goliathcalamari"
|
||||
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/consumable/capsaicin = 1)
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/capsaicin = 2)
|
||||
tastes = list("rock" = 1, "meat" = 1)
|
||||
foodtype = MEAT
|
||||
|
||||
////////////// Cubes //////////
|
||||
|
||||
|
||||
@@ -213,3 +213,12 @@
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/salad/gumbo
|
||||
subcategory = CAT_MEAT
|
||||
|
||||
/datum/crafting_recipe/food/goliathcalamari
|
||||
name = "Goliath Calamari"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2,
|
||||
/datum/reagent/consumable/cooking_oil = 10
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/goliathcalamari
|
||||
subcategory = CAT_MEAT
|
||||
|
||||
@@ -266,6 +266,8 @@
|
||||
desc = "A wooden rod about the size of your forearm with a snake carved around it, winding it's way up the sides of the rod. Something about it seems to inspire in you the responsibilty and duty to help others."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "asclepius_dormant"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
var/activated = FALSE
|
||||
var/usedHand
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
/obj/item/storage/bag/money/Initialize()
|
||||
. = ..()
|
||||
if(prob(20))
|
||||
icon_state = "moneybagalt"
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_items = 40
|
||||
|
||||
@@ -83,7 +83,8 @@
|
||||
|
||||
for (var/_A in mind.antag_datums)
|
||||
var/datum/antagonist/A = _A
|
||||
if (A.show_to_ghosts)
|
||||
var/mob/dead/observer/O = user
|
||||
if (A?.show_to_ghosts || !O?.can_reenter_corpse)
|
||||
was_antagonist = TRUE
|
||||
serialized["antag"] = A.name
|
||||
antagonists += list(serialized)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(skipface || get_visible_name() == "Unknown")
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
|
||||
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>!"
|
||||
|
||||
//uniform
|
||||
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
|
||||
|
||||
@@ -1083,6 +1083,30 @@
|
||||
. = ..()
|
||||
set_species(race)
|
||||
|
||||
/**
|
||||
* # `spec_trait_examine_font()`
|
||||
*
|
||||
* This gets a humanoid's special examine font, which is used to color their species name during examine / health analyzing.
|
||||
* The first of these that applies is returned.
|
||||
* Returns:
|
||||
* * Metallic font if robotic
|
||||
* * Cyan if a toxinlover
|
||||
* * Purple if plasmaperson
|
||||
* * Rock / Brownish if a golem
|
||||
* * Green if none of the others apply (aka, generic organic)
|
||||
*/
|
||||
/mob/living/carbon/human/proc/spec_trait_examine_font()
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
return "<font color='#aaa9ad'>"
|
||||
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
|
||||
return "<font color='#00ffff'>"
|
||||
if(isplasmaman(src))
|
||||
return "<font color='#800080'"
|
||||
if(isgolem(src))
|
||||
return "<font color='#8b4513'"
|
||||
return "<font color='#18d855'>"
|
||||
|
||||
|
||||
/mob/living/carbon/human/get_tooltip_data()
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_is = p_are()
|
||||
@@ -1091,7 +1115,7 @@
|
||||
if(skipface || get_visible_name() == "Unknown")
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]"
|
||||
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>"
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .)
|
||||
|
||||
/mob/living/carbon/human/species/abductor
|
||||
|
||||
@@ -1989,6 +1989,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
|
||||
var/mob/living/carbon/human/target_collateral_human
|
||||
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
|
||||
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
|
||||
|
||||
//Thank you based whoneedsspace
|
||||
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
|
||||
@@ -2003,7 +2004,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/append_message = ""
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
|
||||
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
|
||||
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
target.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
|
||||
@@ -2031,11 +2031,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
append_message += ", loosening their grip on [target_held_item]"
|
||||
else
|
||||
append_message += ", but couldn't loose their grip on [target_held_item]"
|
||||
else if(target_held_item)
|
||||
if(target.dropItemToGround(target_held_item))
|
||||
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
|
||||
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
append_message += ", causing them to drop [target_held_item]"
|
||||
else if(target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
|
||||
if(target_held_item)
|
||||
if(shove_blocked)
|
||||
if (target.buckled)
|
||||
return
|
||||
else if(target.dropItemToGround(target_held_item))
|
||||
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
|
||||
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
append_message += ", causing them to drop [target_held_item]"
|
||||
target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
|
||||
@@ -231,8 +231,11 @@
|
||||
R.update_module_innate()
|
||||
RM.rebuild_modules()
|
||||
INVOKE_ASYNC(RM, .proc/do_transform_animation)
|
||||
if(RM.dogborg)
|
||||
if(RM.dogborg || R.dogborg)
|
||||
RM.dogborg_equip()
|
||||
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine/dogborg
|
||||
else
|
||||
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
|
||||
R.maxHealth = borghealth
|
||||
R.health = min(borghealth, R.health)
|
||||
qdel(src)
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
var/hack_software = FALSE //Will be able to use hacking actions
|
||||
var/interaction_range = 7 //wireless control range
|
||||
|
||||
typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
|
||||
|
||||
/mob/living/silicon/Initialize()
|
||||
. = ..()
|
||||
GLOB.silicon_mobs += src
|
||||
|
||||
@@ -58,12 +58,17 @@
|
||||
var/icon_base = "bee"
|
||||
var/static/beehometypecache = typecacheof(/obj/structure/beebox)
|
||||
var/static/hydroponicstypecache = typecacheof(/obj/machinery/hydroponics)
|
||||
var/held_icon = "" // bees are small and have no held icon (aka the coder doesn't know how to sprite it)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Initialize()
|
||||
. = ..()
|
||||
generate_bee_visuals()
|
||||
AddComponent(/datum/component/swarming)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, held_icon, escape_on_find = TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Destroy()
|
||||
if(beehome)
|
||||
beehome.bees -= src
|
||||
|
||||
@@ -6,37 +6,108 @@
|
||||
icon_living = "cat_butcher"
|
||||
icon_dead = "syndicate_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
projectiletype = /obj/item/projectile/bullet/dart/catranq
|
||||
projectilesound = 'sound/items/syringeproj.ogg'
|
||||
ranged = 1
|
||||
ranged_message = "fires the syringe gun at"
|
||||
ranged_cooldown_time = 30
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
response_help_continuous = "pokes"
|
||||
response_harm_continuous = "hits"
|
||||
speed = 0
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attack_verb_continuous = "slashes at"
|
||||
attack_verb_simple = "slash at"
|
||||
attack_sound = 'sound/weapons/circsawhit.ogg'
|
||||
a_intent = INTENT_HARM
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw)
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw, /obj/item/gun/syringe)
|
||||
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("hostile")
|
||||
check_friendly_fire = 1
|
||||
status_flags = CANPUSH
|
||||
del_on_death = 1
|
||||
del_on_death = TRUE
|
||||
var/impatience = 0
|
||||
rapid_melee = 2 //this lets him attack nearly as fast as a normal player, instead of half as fast as one. Without this, due to mood differences, a greytider in melee can actually facetank and beat him to death with only fists
|
||||
dodging = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/cat_butcherer/Life()
|
||||
. = ..()
|
||||
if(prob(10) && health <= maxHealth && !target) //heal himself when not in combat
|
||||
var/healamount = min(maxHealth-health, 20)
|
||||
visible_message("[src] medicates themself.", "<span class='notice'>You medicate yourself.</span>")
|
||||
health += healamount
|
||||
|
||||
/mob/living/simple_animal/hostile/cat_butcherer/CanAttack(atom/the_target)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/human/C = target
|
||||
if(C.getorgan(/obj/item/organ/ears/cat) && C.getorgan(/obj/item/organ/tail/cat) && C.has_trauma_type(/datum/brain_trauma/severe/pacifism))//he wont attack his creations
|
||||
if(C.stat && !istype(C.dna.species, /datum/species/ipc))//unless they need healing
|
||||
return ..()
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/cat_butcherer/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && prob(35) && iscarbon(target))
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/human/L = target
|
||||
var/obj/item/organ/tail/cat/tail = L.getorgan(/obj/item/organ/tail/cat)
|
||||
if(!QDELETED(tail))
|
||||
visible_message("[src] severs [L]'s tail in one swift swipe!", "<span class='notice'>You sever [L]'s tail in one swift swipe.</span>")
|
||||
tail.Remove()
|
||||
var/obj/item/organ/tail/cat/dropped_tail = new(target.drop_location())
|
||||
dropped_tail.color = L.hair_color
|
||||
return 1
|
||||
if(!L.getorgan(/obj/item/organ/ears/cat) && L.stat) //target doesnt have cat ears
|
||||
if(L.getorgan(/obj/item/organ/ears)) //slice off the old ears
|
||||
var/obj/item/organ/ears/ears = L.getorgan(/obj/item/organ/ears)
|
||||
visible_message("[src] slices off [L]'s ears!", "<span class='notice'>You slice [L]'s ears off.</span>")
|
||||
ears.Remove(L)
|
||||
ears.forceMove(get_turf(L))
|
||||
else //implant new ears
|
||||
visible_message("[src] attaches a pair of cat ears to [L]!", "<span class='notice'>You attach a pair of cat ears to [L].</span>")
|
||||
var/obj/item/organ/ears/cat/newears = new
|
||||
newears.Insert(L, drop_if_replaced = FALSE)
|
||||
return
|
||||
else if(!L.getorgan(/obj/item/organ/tail/cat) && L.stat)
|
||||
if(L.getorgan(/obj/item/organ/tail)) //cut off the tail if they have one already
|
||||
var/obj/item/organ/tail/tail = L.getorgan(/obj/item/organ/tail)
|
||||
visible_message("[src] severs [L]'s tail in one swift swipe!", "<span class='notice'>You sever [L]'s tail in one swift swipe.</span>")
|
||||
tail.Remove(L)
|
||||
tail.forceMove(get_turf(L))
|
||||
else //put a cat tail on
|
||||
visible_message("[src] attaches a cat tail to [L]!", "<span class='notice'>You attach a tail to [L].</span>")
|
||||
var/obj/item/organ/tail/cat/newtail = new
|
||||
newtail.Insert(L, drop_if_replaced = FALSE)
|
||||
return
|
||||
else if(!L.has_trauma_type(/datum/brain_trauma/severe/pacifism) && L.getorgan(/obj/item/organ/ears/cat) && L.getorgan(/obj/item/organ/tail/cat)) //still does damage. This also lacks a Stat check- felinids beware.
|
||||
visible_message("[src] drills a hole in [L]'s skull!", "<span class='notice'>You pacify [L]. Another successful creation.</span>")
|
||||
if(L.stat == CONSCIOUS)
|
||||
L.emote("scream")
|
||||
L.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_BASIC)
|
||||
say("Such a GOOD KITTY!!")
|
||||
if(L.mind && maxHealth <= 300) //if he robusts a tider, he becomes stronger
|
||||
maxHealth += 20
|
||||
adjustHealth(-(maxHealth)) //he heals whenever he finishes
|
||||
else if(L.stat) //quickly heal them up and move on to our next target!
|
||||
visible_message("[src] injects [L] with an unknown medicine!", "<span class='notice'>You inject [L] with medicine.</span>")
|
||||
L.SetSleeping(0, FALSE)
|
||||
L.SetUnconscious(0, FALSE)
|
||||
L.adjustOxyLoss(-50)// do CPR first
|
||||
if(L.blood_volume <= 500) //bandage them up and give em some blood if they're bleeding
|
||||
L.blood_volume += 30
|
||||
L.bleedsuppress = 0
|
||||
if(L.getBruteLoss() >= 50)// first, did we beat them into crit? if so, heal that
|
||||
var/healing = min(L.getBruteLoss(), 120)
|
||||
L.adjustBruteLoss(-healing)
|
||||
L.bleedsuppress = 0 //bandage their ass
|
||||
return
|
||||
else if(L.getFireLoss() >= 50) // are they still down from other damage? fix it, but not as fast as the burns
|
||||
var/healing = min(L.getFireLoss(), 50)
|
||||
L.adjustFireLoss(-healing)
|
||||
impatience += 50
|
||||
if(prob(impatience))
|
||||
FindTarget()//so we don't focus on some unconscious dude when we could get our eyes on the prize
|
||||
impatience = 0
|
||||
say("Bah!!")
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,457 @@
|
||||
GLOBAL_VAR_INIT(floor_cluwnes, 0)
|
||||
|
||||
#define STAGE_HAUNT 1
|
||||
#define STAGE_SPOOK 2
|
||||
#define STAGE_TORMENT 3
|
||||
#define STAGE_ATTACK 4
|
||||
#define MANIFEST_DELAY 9
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne
|
||||
name = "???"
|
||||
desc = "...."
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = "cluwne"
|
||||
icon_living = "cluwne"
|
||||
icon_gib = "clown_gib"
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
speed = -1
|
||||
attack_verb_continuous = "attacks"
|
||||
attack_verb_simple = "attack"
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
del_on_death = TRUE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB | LETPASSTHROW | PASSGLASS | PASSBLOB//it's practically a ghost when unmanifested (under the floor)
|
||||
loot = list(/obj/item/clothing/mask/gas/cluwne)
|
||||
wander = FALSE
|
||||
minimum_distance = 2
|
||||
move_to_delay = 1
|
||||
movement_type = FLYING
|
||||
environment_smash = FALSE
|
||||
lose_patience_timeout = FALSE
|
||||
pixel_y = 8
|
||||
pressure_resistance = 200
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 1500
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
var/mob/living/carbon/human/current_victim
|
||||
var/manifested = FALSE
|
||||
var/switch_stage = 60
|
||||
var/stage = STAGE_HAUNT
|
||||
var/interest = 0
|
||||
var/target_area
|
||||
var/invalid_area_typecache = list(/area/space, /area/lavaland, /area/centcom, /area/reebe, /area/shuttle/syndicate)
|
||||
var/eating = FALSE
|
||||
var/dontkill = FALSE //for if we just wanna curse a fucker
|
||||
var/obj/effect/dummy/floorcluwne_orbit/poi
|
||||
var/obj/effect/temp_visual/fcluwne_manifest/cluwnehole
|
||||
move_resist = INFINITY
|
||||
hud_type = /datum/hud/ghost
|
||||
hud_possible = list(ANTAG_HUD)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/Initialize()
|
||||
. = ..()
|
||||
access_card = new /obj/item/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
invalid_area_typecache = typecacheof(invalid_area_typecache)
|
||||
Manifest()
|
||||
if(!current_victim)
|
||||
Acquire_Victim()
|
||||
poi = new(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/med_hud_set_health()
|
||||
return //we use a different hud
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/med_hud_set_status()
|
||||
return //we use a different hud
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/Destroy()
|
||||
QDEL_NULL(poi)
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/attack_hand(mob/living/carbon/human/M)
|
||||
..()
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/CanPass(atom/A, turf/target)
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/Life()
|
||||
do_jitter_animation(1000)
|
||||
pixel_y = 8
|
||||
|
||||
var/area/A = get_area(src.loc)
|
||||
if(is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(z))
|
||||
var/area = pick(GLOB.teleportlocs)
|
||||
var/area/tp = GLOB.teleportlocs[area]
|
||||
forceMove(pick(get_area_turfs(tp.type)))
|
||||
|
||||
if(!current_victim)
|
||||
Acquire_Victim()
|
||||
|
||||
if(stage && !manifested)
|
||||
INVOKE_ASYNC(src, .proc/On_Stage)
|
||||
|
||||
if(stage == STAGE_ATTACK)
|
||||
playsound(src, 'sound/misc/cluwne_breathing.ogg', 75, 1)
|
||||
|
||||
if(eating)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(current_victim)
|
||||
A = get_area(T)
|
||||
if(prob(5))//checks roughly every 20 ticks
|
||||
if(current_victim.stat == DEAD || current_victim.dna.check_mutation(CLUWNEMUT) || is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(current_victim.z))
|
||||
if(!Found_You())
|
||||
Acquire_Victim()
|
||||
|
||||
if(get_dist(src, current_victim) > 9 && !manifested && !is_type_in_typecache(A, invalid_area_typecache))//if cluwne gets stuck he just teleports
|
||||
do_teleport(src, T)
|
||||
|
||||
interest++
|
||||
if(interest >= switch_stage * 4 && !dontkill)
|
||||
stage = STAGE_ATTACK
|
||||
|
||||
else if(interest >= switch_stage * 2)
|
||||
stage = STAGE_TORMENT
|
||||
|
||||
else if(interest >= switch_stage)
|
||||
stage = STAGE_SPOOK
|
||||
|
||||
else if(interest < switch_stage)
|
||||
stage = STAGE_HAUNT
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/Goto(target, delay, minimum_distance)
|
||||
var/area/A = get_area(current_victim.loc)
|
||||
if(!manifested && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(current_victim.z))
|
||||
walk_to(src, target, minimum_distance, delay)
|
||||
else
|
||||
walk_to(src,0)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/FindTarget()
|
||||
return current_victim
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/CanAttack(atom/the_target)//you will not escape
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/AttackingTarget()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/LoseTarget()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)//prevents runtimes with machine fuckery
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Found_You()
|
||||
for(var/obj/structure/closet/hiding_spot in orange(7,src))
|
||||
if(current_victim.loc == hiding_spot)
|
||||
hiding_spot.bust_open()
|
||||
current_victim.Paralyze(40)
|
||||
to_chat(current_victim, "<span class='warning'>...edih t'nac uoY</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Acquire_Victim(specific)
|
||||
for(var/I in GLOB.player_list)//better than a potential recursive loop
|
||||
var/mob/living/carbon/human/H = pick(GLOB.player_list)//so the check is fair
|
||||
var/area/A
|
||||
|
||||
if(specific)
|
||||
H = specific
|
||||
A = get_area(H.loc)
|
||||
if(H.stat != DEAD && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
|
||||
return target = current_victim
|
||||
|
||||
A = get_area(H.loc)
|
||||
if(H && ishuman(H) && H.stat != DEAD && H != current_victim && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
|
||||
current_victim = H
|
||||
interest = 0
|
||||
stage = STAGE_HAUNT
|
||||
return target = current_victim
|
||||
|
||||
message_admins("Floor Cluwne was deleted due to a lack of valid targets, if this was a manually targeted instance please re-evaluate your choice.")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Manifest()//handles disappearing and appearance anim
|
||||
if(manifested)
|
||||
mobility_flags &= ~MOBILITY_MOVE
|
||||
update_mobility()
|
||||
cluwnehole = new(src.loc)
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Appear), MANIFEST_DELAY)
|
||||
else
|
||||
layer = GAME_PLANE
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
density = FALSE
|
||||
mobility_flags |= MOBILITY_MOVE
|
||||
update_mobility()
|
||||
if(cluwnehole)
|
||||
qdel(cluwnehole)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Appear()//handled in a seperate proc so floor cluwne doesn't appear before the animation finishes
|
||||
layer = LYING_MOB_LAYER
|
||||
invisibility = FALSE
|
||||
density = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Reset_View(screens, colour, mob/living/carbon/human/H)
|
||||
if(screens)
|
||||
for(var/whole_screen in screens)
|
||||
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
|
||||
if(colour && H)
|
||||
H.client.color = colour
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/On_Stage()
|
||||
var/mob/living/carbon/human/H = current_victim
|
||||
switch(stage)
|
||||
|
||||
if(STAGE_HAUNT)
|
||||
|
||||
if(prob(5))
|
||||
H.blur_eyes(1)
|
||||
|
||||
if(prob(5))
|
||||
H.playsound_local(src,'sound/voice/cluwnelaugh2_reversed.ogg', 1)
|
||||
|
||||
if(prob(5))
|
||||
H.playsound_local(src,'sound/misc/bikehorn_creepy.ogg', 5)
|
||||
|
||||
if(prob(3))
|
||||
var/obj/item/I = locate() in orange(H, 8)
|
||||
if(I && !I.anchored)
|
||||
I.throw_at(H, 4, 3)
|
||||
to_chat(H, "<span class='warning'>What threw that?</span>")
|
||||
|
||||
if(STAGE_SPOOK)
|
||||
|
||||
if(prob(4))
|
||||
var/turf/T = get_turf(H)
|
||||
T.handle_slip(H, 20)
|
||||
to_chat(H, "<span class='warning'>The floor shifts underneath you!</span>")
|
||||
|
||||
if(prob(5))
|
||||
H.playsound_local(src,'sound/voice/cluwnelaugh2.ogg', 2)
|
||||
|
||||
if(prob(5))
|
||||
H.playsound_local(src,'sound/voice/cluwnelaugh2_reversed.ogg', 2)
|
||||
|
||||
if(prob(5))
|
||||
H.playsound_local(src,'sound/misc/bikehorn_creepy.ogg', 10)
|
||||
to_chat(H, "<i>knoh</i>")
|
||||
|
||||
if(prob(5))
|
||||
var/obj/item/I = locate() in orange(H, 8)
|
||||
if(I && !I.anchored)
|
||||
I.throw_at(H, 4, 3)
|
||||
to_chat(H, "<span class='warning'>What threw that?</span>")
|
||||
|
||||
if(prob(2))
|
||||
to_chat(H, "<i>yalp ot tnaw I</i>")
|
||||
Appear()
|
||||
manifested = FALSE
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 1)
|
||||
|
||||
if(STAGE_TORMENT)
|
||||
|
||||
if(prob(5))
|
||||
var/turf/T = get_turf(H)
|
||||
T.handle_slip(H, 20)
|
||||
to_chat(H, "<span class='warning'>The floor shifts underneath you!</span>")
|
||||
|
||||
if(prob(3))
|
||||
playsound(src,pick('sound/spookoween/scary_horn.ogg', 'sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 30, 1)
|
||||
|
||||
if(prob(3))
|
||||
playsound(src,'sound/voice/cluwnelaugh1.ogg', 30, 1)
|
||||
|
||||
if(prob(3))
|
||||
playsound(src,'sound/voice/cluwnelaugh2_reversed.ogg', 30, 1)
|
||||
|
||||
if(prob(5))
|
||||
playsound(src,'sound/misc/bikehorn_creepy.ogg', 30, 1)
|
||||
|
||||
if(prob(4))
|
||||
for(var/obj/item/I in orange(8, H))
|
||||
if(!I.anchored)
|
||||
I.throw_at(H, 4, 3)
|
||||
to_chat(H, "<span class='warning'>What the hell?!</span>")
|
||||
|
||||
if(prob(2))
|
||||
to_chat(H, "<span class='warning'>Something feels very wrong...</span>")
|
||||
H.playsound_local(src,'sound/hallucinations/behind_you1.ogg', 25)
|
||||
H.flash_act()
|
||||
|
||||
if(prob(2))
|
||||
to_chat(H, "<i>!?REHTOMKNOH eht esiarp uoy oD</i>")
|
||||
to_chat(H, "<span class='warning'>Something grabs your foot!</span>")
|
||||
H.playsound_local(src,'sound/hallucinations/i_see_you1.ogg', 25)
|
||||
H.Stun(20)
|
||||
|
||||
if(prob(3))
|
||||
to_chat(H, "<i>KNOH ?od nottub siht seod tahW</i>")
|
||||
for(var/turf/open/O in RANGE_TURFS(6, src))
|
||||
O.MakeSlippery(TURF_WET_WATER, 10)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 30, 1)
|
||||
|
||||
if(prob(1))
|
||||
to_chat(H, "<span class='userdanger'>WHAT THE FUCK IS THAT?!</span>")
|
||||
to_chat(H, "<i>.KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH</i>")
|
||||
H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25)
|
||||
H.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 3)
|
||||
H.reagents.add_reagent(/datum/reagent/consumable/laughter, 5)
|
||||
H.reagents.add_reagent(/datum/reagent/mercury, 3)
|
||||
Appear()
|
||||
manifested = FALSE
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2)
|
||||
for(var/obj/machinery/light/L in range(8, H))
|
||||
L.flicker()
|
||||
|
||||
|
||||
if(STAGE_ATTACK)
|
||||
if(dontkill)
|
||||
stage = STAGE_TORMENT
|
||||
return
|
||||
if(!eating)
|
||||
Found_You()
|
||||
for(var/I in getline(src,H))
|
||||
var/turf/T = I
|
||||
if(T.density)
|
||||
forceMove(H.loc)
|
||||
for(var/obj/structure/O in T)
|
||||
if(O.density || istype(O, /obj/machinery/door/airlock))
|
||||
forceMove(H.loc)
|
||||
to_chat(H, "<span class='userdanger'>You feel the floor closing in on your feet!</span>")
|
||||
H.Paralyze(300)
|
||||
INVOKE_ASYNC(H, /mob.proc/emote, "scream")
|
||||
H.adjustBruteLoss(10)
|
||||
manifested = TRUE
|
||||
Manifest()
|
||||
if(!eating)
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Grab, H), 50, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
for(var/turf/open/O in RANGE_TURFS(6, src))
|
||||
O.MakeSlippery(TURF_WET_LUBE, 20)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 30, 1)
|
||||
eating = TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Grab(mob/living/carbon/human/H)
|
||||
if (H != current_victim)
|
||||
message_admins("Cluwne tried to grab someone who's not the target. Returning to life stage.")
|
||||
return
|
||||
to_chat(H, "<span class='userdanger'>You feel a cold, gloved hand clamp down on your ankle!</span>")
|
||||
for(var/I in 1 to get_dist(src, H))
|
||||
if(do_after(src, 5, target = H))
|
||||
step_towards(H, src)
|
||||
playsound(H, pick('sound/effects/bodyscrape-01.ogg', 'sound/effects/bodyscrape-02.ogg'), 20, 1, -4)
|
||||
if(prob(40))
|
||||
H.emote("scream")
|
||||
else if(prob(25))
|
||||
H.say(pick("HELP ME!!","IT'S GOT ME!!","DON'T LET IT TAKE ME!!",";SOMETHING'S KILLING ME!!","HOLY FUCK!!"))
|
||||
playsound(src, pick('sound/voice/cluwnelaugh1.ogg', 'sound/voice/cluwnelaugh2.ogg', 'sound/voice/cluwnelaugh3.ogg'), 50, 1)
|
||||
|
||||
if(get_dist(src,H) <= 1)
|
||||
visible_message("<span class='danger'>[src] begins dragging [H] under the floor!</span>")
|
||||
if(do_after(src, 50, target = H) && eating)
|
||||
H.become_blind()
|
||||
H.layer = GAME_PLANE
|
||||
H.invisibility = INVISIBILITY_OBSERVER
|
||||
H.density = FALSE
|
||||
H.anchored = TRUE
|
||||
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Kill, H), 100, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
visible_message("<span class='danger'>[src] pulls [H] under!</span>")
|
||||
to_chat(H, "<span class='userdanger'>[src] drags you underneath the floor!</span>")
|
||||
else
|
||||
eating = FALSE
|
||||
else
|
||||
eating = FALSE
|
||||
manifested = FALSE
|
||||
Manifest()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/floor_cluwne/proc/Kill(mob/living/carbon/human/H)
|
||||
if (H != current_victim)
|
||||
message_admins("Cluwne tried to kill someone who's not the target. Returning to life stage.")
|
||||
H.invisibility = initial(H.invisibility)
|
||||
return
|
||||
if(!istype(H) || !H.client)
|
||||
H.invisibility = initial(H.invisibility)
|
||||
Acquire_Victim()
|
||||
return
|
||||
playsound(H, 'sound/effects/cluwne_feast.ogg', 100, 0, -4)
|
||||
var/old_color = H.client.color
|
||||
var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
|
||||
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
|
||||
H.client.color = pure_red
|
||||
animate(H.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
|
||||
for(var/turf/T in orange(H, 4))
|
||||
H.add_splatter_floor(T)
|
||||
if(do_after(src, 50, target = H))
|
||||
H.unequip_everything()//more runtime prevention
|
||||
if(prob(75))
|
||||
H.gib(FALSE)
|
||||
else
|
||||
H.cluwneify()
|
||||
H.adjustBruteLoss(30)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 100)
|
||||
H.cure_blind()
|
||||
H.layer = initial(H.layer)
|
||||
H.invisibility = initial(H.invisibility)
|
||||
H.density = initial(H.density)
|
||||
H.anchored = initial(H.anchored)
|
||||
H.blur_eyes(10)
|
||||
animate(H.client,color = old_color, time = 20)
|
||||
|
||||
eating = FALSE
|
||||
switch_stage = switch_stage * 0.75 //he gets faster after each feast
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
M.playsound_local(get_turf(M), 'sound/misc/honk_echo_distant.ogg', 50, 1, pressure_affected = FALSE)
|
||||
|
||||
interest = 0
|
||||
stage = STAGE_HAUNT
|
||||
Acquire_Victim()
|
||||
|
||||
//manifestation animation
|
||||
/obj/effect/temp_visual/fcluwne_manifest
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "fcluwne_open"
|
||||
layer = TURF_LAYER
|
||||
duration = 600
|
||||
randomdir = FALSE
|
||||
|
||||
/obj/effect/temp_visual/fcluwne_manifest/Initialize()
|
||||
. = ..()
|
||||
playsound(src, 'sound/misc/floor_cluwne_emerge.ogg', 100, 1)
|
||||
flick("fcluwne_manifest",src)
|
||||
|
||||
/obj/effect/dummy/floorcluwne_orbit
|
||||
name = "floor cluwne"
|
||||
desc = "If you have this, tell a coder or admin!"
|
||||
|
||||
/obj/effect/dummy/floorcluwne_orbit/Initialize()
|
||||
. = ..()
|
||||
GLOB.floor_cluwnes++
|
||||
name += " ([GLOB.floor_cluwnes])"
|
||||
GLOB.poi_list += src
|
||||
|
||||
/obj/effect/dummy/floorcluwne_orbit/Destroy()
|
||||
. = ..()
|
||||
GLOB.poi_list -= src
|
||||
|
||||
#undef STAGE_HAUNT
|
||||
#undef STAGE_SPOOK
|
||||
#undef STAGE_TORMENT
|
||||
#undef STAGE_ATTACK
|
||||
#undef MANIFEST_DELAY
|
||||
@@ -6,6 +6,7 @@
|
||||
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
|
||||
var/SStun = 0 // stun variable
|
||||
|
||||
typing_indicator_state = /obj/effect/overlay/typing_indicator/slime
|
||||
|
||||
/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired)
|
||||
if(!(. = ..()))
|
||||
|
||||
@@ -55,3 +55,12 @@ GLOBAL_LIST_EMPTY(typing_indicator_overlays)
|
||||
icon_state = "normal_typing"
|
||||
appearance_flags = RESET_COLOR | TILE_BOUND | PIXEL_SCALE
|
||||
layer = ABOVE_FLY_LAYER
|
||||
|
||||
/obj/effect/overlay/typing_indicator/machine
|
||||
icon_state = "machine_typing"
|
||||
|
||||
/obj/effect/overlay/typing_indicator/machine/dogborg
|
||||
icon = 'icons/mob/talk_64x64.dmi'
|
||||
|
||||
/obj/effect/overlay/typing_indicator/slime
|
||||
icon_state = "slime_typing"
|
||||
|
||||
@@ -63,4 +63,4 @@
|
||||
if(printer_slot)
|
||||
. += "It has a printer installed."
|
||||
if(user_is_adjacent)
|
||||
. += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].</span>]"
|
||||
. += "The printer's paper levels are at: [printer_slot.stored_paper]/[printer_slot.max_paper].</span>"
|
||||
|
||||
@@ -114,6 +114,12 @@
|
||||
update_icon()
|
||||
if(user && istype(user))
|
||||
ui_interact(user) // Re-open the UI on this computer. It should show the main screen now.
|
||||
if("eject_pen")
|
||||
if(istype(src, /obj/item/modular_computer/tablet))
|
||||
var/obj/item/modular_computer/tablet/self = src
|
||||
if(self.can_have_pen)
|
||||
self.remove_pen()
|
||||
return
|
||||
|
||||
if("PC_killprogram")
|
||||
var/prog = params["name"]
|
||||
|
||||
@@ -18,6 +18,69 @@
|
||||
var/has_variants = TRUE
|
||||
var/finish_color = null
|
||||
|
||||
//Pen stuff
|
||||
var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette)
|
||||
var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above.
|
||||
var/can_have_pen = TRUE
|
||||
|
||||
/obj/item/modular_computer/tablet/examine(mob/user)
|
||||
. = ..()
|
||||
if(inserted_item && (!isturf(loc)))
|
||||
. += "<span class='notice'>Ctrl-click to remove [inserted_item].</span>"
|
||||
|
||||
/obj/item/modular_computer/tablet/Initialize()
|
||||
. = ..()
|
||||
if(can_have_pen)
|
||||
if(inserted_item)
|
||||
inserted_item = new inserted_item(src)
|
||||
else
|
||||
inserted_item = new /obj/item/pen(src)
|
||||
|
||||
/obj/item/modular_computer/tablet/proc/insert_pen(obj/item/pen)
|
||||
if(!usr.transferItemToLoc(pen, src))
|
||||
return
|
||||
to_chat(usr, "<span class='notice'>You slide \the [pen] into \the [src]'s pen slot.</span>")
|
||||
inserted_item = pen
|
||||
playsound(src, 'sound/machines/button.ogg', 50, 1)
|
||||
|
||||
/obj/item/modular_computer/tablet/proc/remove_pen()
|
||||
if(hasSiliconAccessInArea(usr) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
|
||||
if(inserted_item)
|
||||
usr.put_in_hands(inserted_item)
|
||||
to_chat(usr, "<span class='notice'>You remove [inserted_item] from \the [src]'s pen slot.</span>")
|
||||
inserted_item = null
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>\The [src] does not have a pen in it!</span>")
|
||||
|
||||
/obj/item/modular_computer/tablet/CtrlClick(mob/user)
|
||||
. = ..()
|
||||
if(isturf(loc))
|
||||
return
|
||||
|
||||
if(can_have_pen)
|
||||
remove_pen(user)
|
||||
|
||||
/obj/item/modular_computer/tablet/attackby(obj/item/W, mob/user)
|
||||
if(can_have_pen && is_type_in_list(W, contained_item))
|
||||
if(inserted_item)
|
||||
to_chat(user, "<span class='warning'>There is \a [inserted_item] blocking \the [src]'s pen slot!</span>")
|
||||
return
|
||||
else
|
||||
insert_pen(W)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/modular_computer/tablet/Destroy()
|
||||
if(istype(inserted_item))
|
||||
QDEL_NULL(inserted_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/tablet/ui_data(mob/user)
|
||||
. = ..()
|
||||
.["PC_showpeneject"] = inserted_item ? 1 : 0
|
||||
|
||||
/obj/item/modular_computer/tablet/update_icon_state()
|
||||
if(has_variants)
|
||||
if(!finish_color)
|
||||
@@ -64,6 +127,7 @@
|
||||
var/datum/computer_file/program/robotact/robotact
|
||||
///IC log that borgs can view in their personal management app
|
||||
var/list/borglog = list()
|
||||
can_have_pen = FALSE
|
||||
|
||||
/obj/item/modular_computer/tablet/integrated/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
/obj/item/ammo_casing/magic/spellblade
|
||||
projectile_type = /obj/item/projectile/magic/spellblade
|
||||
|
||||
/obj/item/ammo_casing/magic/judgement_cut
|
||||
projectile_type = /obj/item/projectile/judgement_cut
|
||||
|
||||
/obj/item/ammo_casing/magic/arcane_barrage
|
||||
projectile_type = /obj/item/projectile/magic/arcane_barrage
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/obj/item/gun/magic/staff/motivation
|
||||
name = "Motivation"
|
||||
desc = "Rumored to have the ability to open up a portal the depths of Lavaland."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "motivation"
|
||||
item_state = "motivation"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
fire_sound = 'sound/weapons/judgementhit.ogg'
|
||||
ammo_type = /obj/item/ammo_casing/magic/judgement_cut
|
||||
force = 20 //so it's worth that 20 tc
|
||||
armour_penetration = 50
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = SHARP_EDGED
|
||||
max_integrity = 200
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
max_charges = 3
|
||||
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
|
||||
/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>")
|
||||
|
||||
//action button to toggle judgement cuts on/off
|
||||
/datum/action/judgement_cut
|
||||
name = "Judgement Cut - Allows Motivation to slash at a longer distance."
|
||||
icon_icon = 'icons/obj/projectiles.dmi'
|
||||
button_icon_state = "judgement_fire"
|
||||
var/judgement_toggled = TRUE
|
||||
|
||||
//lets the user know that you toggled them on/off
|
||||
/datum/action/judgement_cut/Trigger()
|
||||
judgement_toggled = !judgement_toggled
|
||||
to_chat(owner, "<span class='notice'>You [judgement_toggled ? "enable" : "disable"] Judgement Cuts with Motivation.</span>")
|
||||
|
||||
//Prevents "firing" the judgement cuts if toggled off and lets the user know
|
||||
/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>")
|
||||
return FALSE
|
||||
|
||||
//adds/removes judgement cut and judgement cut end upon pickup/drop
|
||||
/obj/item/gun/magic/staff/motivation/pickup(mob/living/user)
|
||||
. = ..()
|
||||
judgementcut.Grant(user, src)
|
||||
user.update_icons()
|
||||
playsound(src, 'sound/items/unsheath.ogg', 25, 1)
|
||||
|
||||
/obj/item/gun/magic/staff/motivation/dropped(mob/user)
|
||||
. = ..()
|
||||
judgementcut.Remove(user)
|
||||
user.update_icons()
|
||||
|
||||
//A parry tight enough to stagger, but not to counter attack
|
||||
/datum/block_parry_data/motivation
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_attack_types = ALL
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 2
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 3
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1
|
||||
)
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 50 // useless after 3rd decisecond
|
||||
)
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 1
|
||||
parry_efficiency_perfect = 100
|
||||
parry_data = list(
|
||||
PARRY_STAGGER_ATTACKER = 10
|
||||
)
|
||||
parry_failed_stagger_duration = 2 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_RANGE
|
||||
parry_cooldown = 0
|
||||
@@ -38,6 +38,10 @@
|
||||
reagents.add_reagent(/datum/reagent/foaming_agent, 5)
|
||||
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
|
||||
|
||||
/obj/item/projectile/bullet/dart/catranq/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent(/datum/reagent/fermi/furranium, 5) // Turns out I don't even need to give this guy actual tranquilizer chems.
|
||||
|
||||
/obj/item/projectile/bullet/dart/syringe
|
||||
name = "syringe"
|
||||
icon_state = "syringeproj"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/obj/item/projectile/judgement_cut
|
||||
name = "judgement cut"
|
||||
icon_state = "judgement_fire"
|
||||
hitsound = 'sound/weapons/judgementfire.ogg'
|
||||
damage = 10
|
||||
damage_type = BRUTE
|
||||
range = 30
|
||||
is_reflectable = FALSE
|
||||
sharpness = SHARP_EDGED
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/judgement_cut
|
||||
|
||||
/obj/item/projectile/judgement_cut/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(ishuman(target))
|
||||
new /obj/effect/temp_visual/impact_effect/judgement_cut(src)
|
||||
@@ -741,6 +741,13 @@
|
||||
required_reagents = list(/datum/reagent/liquid_dark_matter = 5, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/oculine = 10, /datum/reagent/mutationtoxin = 1)
|
||||
required_temp = 600
|
||||
|
||||
/datum/chemical_reaction/slimejelly
|
||||
name = "slimejelly"
|
||||
results = list(/datum/reagent/toxin/slimejelly = 5)
|
||||
required_reagents = list(/datum/reagent/oil = 3, /datum/reagent/radium = 2, /datum/reagent/consumable/tinlux = 1)
|
||||
required_container = /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom
|
||||
mix_message = "The mushroom's insides bubble and pop and it becomes very limp."
|
||||
|
||||
/datum/chemical_reaction/slime_extractification
|
||||
required_reagents = list(/datum/reagent/toxin/slimejelly = 30, /datum/reagent/consumable/frostoil = 5, /datum/reagent/toxin/plasma = 5)
|
||||
mix_message = "The mixture condenses into a ball."
|
||||
|
||||
@@ -27,8 +27,6 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
/obj/machinery/syndicatebomb,
|
||||
/obj/item/hilbertshotel,
|
||||
/obj/machinery/launchpad,
|
||||
/obj/machinery/disposal,
|
||||
/obj/structure/disposalpipe,
|
||||
/obj/item/hilbertshotel,
|
||||
/obj/machinery/camera,
|
||||
/obj/item/gps,
|
||||
@@ -128,7 +126,8 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
var/value = 0
|
||||
var/purchases = 0
|
||||
var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties
|
||||
// var/list/lockers_by_buyer = list() // TODO, combine orders that come in lockers into a single locker to not crowd the shuttle
|
||||
var/list/lockers_by_buyer = list() // used to combine orders that come in lockers into a single locker to not crowd the shuttle
|
||||
|
||||
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
|
||||
if(!empty_turfs.len)
|
||||
break
|
||||
@@ -149,11 +148,15 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
D.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.")
|
||||
else
|
||||
D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
|
||||
if(D)
|
||||
if(!D.adjust_money(-price))
|
||||
if(SO.paying_account)
|
||||
D.bank_card_talk("Cargo order #[SO.id] rejected due to lack of funds. Credits required: [price]")
|
||||
continue
|
||||
else if(ispath(SO.pack.crate_type, /obj/structure/closet/secure_closet/cargo))
|
||||
LAZYADD(lockers_by_buyer[D], SO)
|
||||
|
||||
|
||||
if(SO.paying_account)
|
||||
if(SO.pack.goody)
|
||||
@@ -166,7 +169,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
SSshuttle.orderhistory += SO
|
||||
QDEL_NULL(SO.applied_coupon)
|
||||
|
||||
if(!SO.pack.goody) //we handle goody crates below
|
||||
if(!SO.pack.goody && !ispath(SO.pack.crate_type, /obj/structure/closet/secure_closet/cargo)) //we handle goody crates and material closets below
|
||||
SO.generate(pick_n_take(empty_turfs))
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
|
||||
@@ -200,6 +203,33 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
misc_contents[buyer] += item
|
||||
misc_order_num[buyer] = "[misc_order_num[buyer]]#[our_order.id] "
|
||||
|
||||
|
||||
// handling locker bundles
|
||||
for(var/D in lockers_by_buyer)
|
||||
var/list/buying_account_orders = lockers_by_buyer[D]
|
||||
|
||||
var/buyer
|
||||
|
||||
if(!istype(D, /datum/bank_account/department)) // department accounts break the secure closet for some reason
|
||||
var/obj/structure/closet/secure_closet/cargo/owned/our_closet = new /obj/structure/closet/secure_closet/cargo/owned(pick_n_take(empty_turfs))
|
||||
var/datum/bank_account/buying_account = D
|
||||
buyer = buying_account.account_holder
|
||||
our_closet.buyer_account = buying_account
|
||||
our_closet.name = "private cargo locker - purchased by [buyer]"
|
||||
miscboxes[buyer] = our_closet
|
||||
else
|
||||
var/obj/structure/closet/secure_closet/cargo/our_closet = new /obj/structure/closet/secure_closet/cargo(pick_n_take(empty_turfs))
|
||||
buyer = "Cargo"
|
||||
miscboxes[buyer] = our_closet
|
||||
|
||||
misc_contents[buyer] = list()
|
||||
for(var/O in buying_account_orders)
|
||||
var/datum/supply_order/our_order = O
|
||||
for(var/item in our_order.pack.contains)
|
||||
misc_contents[buyer] += item
|
||||
misc_order_num[buyer] = "[misc_order_num[buyer]]#[our_order.id] "
|
||||
|
||||
|
||||
for(var/I in miscboxes)
|
||||
var/datum/supply_order/SO = new/datum/supply_order()
|
||||
SO.id = misc_order_num[I]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/obj/effect/proc_holder/spell/targeted/cluwnecurse
|
||||
name = "Curse of the Cluwne"
|
||||
desc = "This spell dooms the fate of any unlucky soul to the live of a pitiful cluwne, a terrible creature that is hunted for fun."
|
||||
school = "transmutation"
|
||||
charge_type = "recharge"
|
||||
charge_max = 600
|
||||
charge_counter = 0
|
||||
clothes_req = SPELL_WIZARD_GARB
|
||||
stat_allowed = 0
|
||||
invocation = "CLU WO'NIS CA'TE'BEST'IS MAXIMUS!"
|
||||
invocation_type = "shout"
|
||||
range = 3
|
||||
cooldown_min = 75
|
||||
selection_type = "range"
|
||||
var/list/compatible_mobs = list(/mob/living/carbon/human)
|
||||
action_icon = 'icons/mob/actions/actions_spells.dmi'
|
||||
action_icon_state = "cluwne"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/cluwnecurse/cast(list/targets, mob/user = usr)
|
||||
if(!targets.len)
|
||||
to_chat(user, "<span class='notice'>No target found in range.</span>")
|
||||
return
|
||||
var/mob/living/carbon/target = targets[1]
|
||||
if(!(target.type in compatible_mobs))
|
||||
to_chat(user, "<span class='notice'>You are unable to curse [target]!</span>")
|
||||
return
|
||||
if(!(target in oview(range)))
|
||||
to_chat(user, "<span class='notice'>They are too far away!</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.cluwneify()
|
||||
|
||||
/datum/action/spell_action/New(Target)
|
||||
..()
|
||||
var/obj/effect/proc_holder/spell/S = Target
|
||||
icon_icon = S.action_icon
|
||||
@@ -215,7 +215,8 @@
|
||||
|
||||
switch(animal_origin)
|
||||
if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around
|
||||
burn *= 1.75
|
||||
burn *= 1.2
|
||||
stamina = 0
|
||||
|
||||
/*
|
||||
// START WOUND HANDLING
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/datum/unit_test/crafting_recipes/Run()
|
||||
for(var/i in GLOB.crafting_recipes)
|
||||
var/datum/crafting_recipe/R = i
|
||||
if(!R.subcategory)
|
||||
Fail("Invalid subcategory on [R] ([R.type]).")
|
||||
if(!R.category && (R.cateogry != CAT_NONE))
|
||||
Fail("Invalid category on [R] ([R.type])")
|
||||
@@ -104,7 +104,7 @@
|
||||
name = "Mechanical Eyepatch"
|
||||
desc = "An eyepatch that connects itself to your eye socket, enhancing your shooting to an impossible degree, allowing your bullets to ricochet far more often than usual."
|
||||
item = /obj/item/clothing/glasses/eyepatch/syndicate
|
||||
cost = 8
|
||||
cost = 4
|
||||
|
||||
/datum/uplink_item/device_tools/ablative_armwraps
|
||||
name = "Ablative Armwraps"
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \
|
||||
organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host."
|
||||
item = /obj/item/storage/box/syndie_kit/guardian
|
||||
cost = 15
|
||||
cost = 12
|
||||
limited_stock = 1 // you can only have one holopara apparently?
|
||||
refundable = TRUE
|
||||
cant_discount = TRUE
|
||||
@@ -204,7 +204,7 @@
|
||||
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \
|
||||
organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host."
|
||||
item = /obj/item/storage/box/syndie_kit/nukieguardian
|
||||
cost = 15
|
||||
cost = 8
|
||||
refundable = TRUE
|
||||
surplus = 50
|
||||
refund_path = /obj/item/guardiancreator/tech/choose/nukie
|
||||
@@ -286,3 +286,13 @@
|
||||
item = /obj/item/gun/ballistic/automatic/toy/pistol/riot
|
||||
cost = 3
|
||||
surplus = 10
|
||||
|
||||
/datum/uplink_item/dangerous/motivation
|
||||
name = "Motivation"
|
||||
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
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
|
||||
cant_discount = TRUE
|
||||
|
||||
@@ -76,11 +76,15 @@
|
||||
return FALSE
|
||||
if(occupant_amount() >= max_occupants)
|
||||
return FALSE
|
||||
if(do_mob(forcer, get_enter_delay(M), target = src))
|
||||
var/atom/old_loc = loc
|
||||
if(do_mob(forcer, M, get_enter_delay(M), extra_checks=CALLBACK(src, /obj/vehicle/sealed/car/proc/is_car_stationary, old_loc)))
|
||||
mob_forced_enter(M, silent)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/vehicle/sealed/car/proc/is_car_stationary(atom/old_loc)
|
||||
return (old_loc == loc)
|
||||
|
||||
/obj/vehicle/sealed/car/proc/mob_forced_enter(mob/M, silent = FALSE)
|
||||
if(!silent)
|
||||
M.visible_message("<span class='warning'>[M] is forced into \the [src]!</span>")
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
/obj/item/clothing/accessory/turtleneck/tactifool = 2,
|
||||
/obj/item/clothing/accessory/turtleneck/tactifool/green = 2,
|
||||
/obj/item/clothing/accessory/turtleneck/tactifool/blue = 2,
|
||||
/obj/item/clothing/accessory/sleevecrop = 2,
|
||||
/obj/item/clothing/under/sweater = 3,
|
||||
/obj/item/clothing/under/sweater/black = 3,
|
||||
/obj/item/clothing/under/sweater/purple = 3,
|
||||
|
||||
Reference in New Issue
Block a user