Merge branch 'master' into silicons-patch-1
This commit is contained in:
@@ -226,16 +226,16 @@
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shed_human_form)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
var/datum/antagonist/heretic/heretic = user.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
var/datum/eldritch_knowledge/flesh_grasp/ghoul1 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_grasp)
|
||||
ghoul1.ghoul_amt *= 3
|
||||
var/datum/eldritch_knowledge/flesh_ghoul/ghoul2 = heretic.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul)
|
||||
ghoul2.max_amt *= 3
|
||||
var/mob/living/carbon/human/lord_of_arms = user
|
||||
lord_of_arms.physiology.brute_mod *= 0.5
|
||||
lord_of_arms.physiology.burn_mod *= 0.5
|
||||
lord_of_arms.client?.give_award(/datum/award/achievement/misc/flesh_ascension, lord_of_arms)
|
||||
var/datum/antagonist/heretic/heretic_datum = user.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
var/datum/eldritch_knowledge/flesh_grasp/grasp_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_grasp)
|
||||
grasp_ghoul.ghoul_amt *= 3
|
||||
var/datum/eldritch_knowledge/flesh_ghoul/better_ghoul = heretic_datum.get_knowledge(/datum/eldritch_knowledge/flesh_ghoul)
|
||||
better_ghoul.max_amt *= 3
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/flesh_blade_upgrade_2
|
||||
name = "Remembrance"
|
||||
|
||||
@@ -181,13 +181,13 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
H.client?.give_award(/datum/award/achievement/misc/rust_ascension, H)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
new /datum/rust_spread(loc)
|
||||
var/datum/antagonist/heretic/ascension = H.mind.has_antag_datum(/datum/antagonist/heretic)
|
||||
ascension.ascended = TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/eldritch_knowledge/final/rust_final/on_life(mob/user)
|
||||
. = ..()
|
||||
if(!finished)
|
||||
|
||||
@@ -183,14 +183,14 @@
|
||||
var/datum/weather/void_storm/storm
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final/on_finished_recipe(mob/living/user, list/atoms, loc)
|
||||
var/mob/living/carbon/human/H = user
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch)
|
||||
H.physiology.brute_mod *= 0.5
|
||||
H.physiology.burn_mod *= 0.5
|
||||
ADD_TRAIT(H, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
|
||||
sound_loop = new(list(user),TRUE,TRUE)
|
||||
var/mob/living/carbon/human/waltzing = user
|
||||
waltzing.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/eldritch)
|
||||
waltzing.physiology.brute_mod *= 0.5
|
||||
waltzing.physiology.burn_mod *= 0.5
|
||||
ADD_TRAIT(waltzing, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
|
||||
waltzing.client?.give_award(/datum/award/achievement/misc/void_ascension, waltzing)
|
||||
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [waltzing.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/announcer/classic/spanomalies.ogg')
|
||||
sound_loop = new(user, TRUE, TRUE)
|
||||
return ..()
|
||||
|
||||
/datum/eldritch_knowledge/final/void_final/on_death()
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
A.death()
|
||||
return ..()
|
||||
|
||||
/obj/item/soulstone/proc/hot_potato(mob/living/user)
|
||||
to_chat(user, span_userdanger("Holy magics residing in \the [src] burn your hand!"))
|
||||
var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
|
||||
affecting.receive_damage( 0, 10 ) // 10 burn damage
|
||||
user.emote("scream")
|
||||
user.update_damage_overlays()
|
||||
user.dropItemToGround(src)
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user)
|
||||
@@ -94,6 +102,35 @@
|
||||
to_chat(A, "<b>You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.</b>")
|
||||
was_used()
|
||||
|
||||
/obj/item/soulstone/pre_attack(atom/A, mob/living/user, params)
|
||||
var/mob/living/simple_animal/hostile/construct/shade/occupant = (locate() in src)
|
||||
var/obj/item/storage/toolbox/mechanical/target_toolbox = A
|
||||
if(!occupant || !istype(target_toolbox) || target_toolbox.has_soul)
|
||||
return ..()
|
||||
|
||||
if(iscultist(user))
|
||||
hot_potato(user)
|
||||
return
|
||||
if(!iscultist(user, TRUE) && !iswizard(user) && !usability)
|
||||
user.Unconscious(10 SECONDS)
|
||||
to_chat(user, span_userdanger("Your body is wracked with debilitating pain!"))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] holds [src] above [user.p_their()] head and forces it into [target_toolbox] with a flash of light!", \
|
||||
span_notice("You hold [src] above your head briefly, then force it into [target_toolbox], transferring the [occupant]'s soul!"), ignored_mobs = occupant)
|
||||
to_chat(occupant, span_userdanger("[user] holds you up briefly, then forces you into [target_toolbox]!"))
|
||||
to_chat(occupant, span_deadsay("<b>Your eternal soul has been sacrificed to restore the soul of a toolbox. Them's the breaks!</b>"))
|
||||
|
||||
occupant.client?.give_award(/datum/award/achievement/misc/toolbox_soul, occupant)
|
||||
occupant.deathmessage = "shrieks out in unholy pain as [occupant.p_their()] soul is absorbed into [target_toolbox]!"
|
||||
release_shades(user, TRUE)
|
||||
occupant.death()
|
||||
|
||||
target_toolbox.name = "soulful toolbox"
|
||||
target_toolbox.icon_state = "toolbox_blue_old"
|
||||
target_toolbox.has_soul = TRUE
|
||||
target_toolbox.has_latches = FALSE
|
||||
|
||||
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
|
||||
/obj/structure/constructshell
|
||||
name = "empty shell"
|
||||
|
||||
@@ -11,6 +11,10 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
|
||||
/datum/asset
|
||||
var/_abstract = /datum/asset
|
||||
var/cached_url_mappings
|
||||
|
||||
/// Whether or not this asset should be loaded in the "early assets" SS
|
||||
var/early = FALSE
|
||||
|
||||
/datum/asset/New()
|
||||
GLOB.asset_datums[type] = src
|
||||
@@ -19,6 +23,13 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
/datum/asset/proc/get_url_mappings()
|
||||
return list()
|
||||
|
||||
/// Returns a cached tgui message of URL mappings
|
||||
/datum/asset/proc/get_serialized_url_mappings()
|
||||
if (isnull(cached_url_mappings))
|
||||
cached_url_mappings = TGUI_CREATE_MESSAGE("asset/mappings", get_url_mappings())
|
||||
|
||||
return cached_url_mappings
|
||||
|
||||
/datum/asset/proc/register()
|
||||
return
|
||||
|
||||
@@ -169,6 +180,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
|
||||
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
|
||||
return
|
||||
//any sprite modifications we want to do (aka, coloring a greyscaled asset)
|
||||
I = ModifyInserted(I)
|
||||
var/size_id = "[I.Width()]x[I.Height()]"
|
||||
var/size = sizes[size_id]
|
||||
|
||||
@@ -185,6 +198,15 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
sizes[size_id] = size = list(1, I, null)
|
||||
sprites[sprite_name] = list(size_id, 0)
|
||||
|
||||
/**
|
||||
* A simple proc handing the Icon for you to modify before it gets turned into an asset.
|
||||
*
|
||||
* Arguments:
|
||||
* * I: icon being turned into an asset
|
||||
*/
|
||||
/datum/asset/spritesheet/proc/ModifyInserted(icon/pre_asset)
|
||||
return pre_asset
|
||||
|
||||
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
|
||||
if (length(prefix))
|
||||
prefix = "[prefix]-"
|
||||
@@ -217,6 +239,19 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
return {"[name][size_id] [sprite_name]"}
|
||||
|
||||
/**
|
||||
* Returns the size class (ex design32x32) for a given sprite's icon
|
||||
*
|
||||
* Arguments:
|
||||
* * sprite_name - The sprite to get the size of
|
||||
*/
|
||||
/datum/asset/spritesheet/proc/icon_size_id(sprite_name)
|
||||
var/sprite = sprites[sprite_name]
|
||||
if (!sprite)
|
||||
return null
|
||||
var/size_id = sprite[SPR_SIZE]
|
||||
return "[name][size_id]"
|
||||
|
||||
#undef SPR_SIZE
|
||||
#undef SPR_IDX
|
||||
#undef SPRSZ_COUNT
|
||||
@@ -224,6 +259,24 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
#undef SPRSZ_STRIPPED
|
||||
|
||||
|
||||
/datum/asset/changelog_item
|
||||
_abstract = /datum/asset/changelog_item
|
||||
var/item_filename
|
||||
|
||||
/datum/asset/changelog_item/New(date)
|
||||
item_filename = sanitize_filename("[date].yml")
|
||||
SSassets.transport.register_asset(item_filename, file("html/changelogs/archive/" + item_filename))
|
||||
|
||||
/datum/asset/changelog_item/send(client)
|
||||
if (!item_filename)
|
||||
return
|
||||
. = SSassets.transport.send_assets(client, item_filename)
|
||||
|
||||
/datum/asset/changelog_item/get_url_mappings()
|
||||
if (!item_filename)
|
||||
return
|
||||
. = list("[item_filename]" = SSassets.transport.get_asset_url(item_filename))
|
||||
|
||||
/datum/asset/spritesheet/simple
|
||||
_abstract = /datum/asset/spritesheet/simple
|
||||
var/list/assets
|
||||
@@ -315,3 +368,28 @@ GLOBAL_LIST_EMPTY(asset_datums)
|
||||
/datum/asset/simple/namespaced/proc/get_htmlloader(filename)
|
||||
return url2htmlloader(SSassets.transport.get_asset_url(filename, assets[filename]))
|
||||
|
||||
/// A subtype to generate a JSON file from a list
|
||||
/datum/asset/json
|
||||
_abstract = /datum/asset/json
|
||||
/// The filename, will be suffixed with ".json"
|
||||
var/name
|
||||
|
||||
/datum/asset/json/send(client)
|
||||
return SSassets.transport.send_assets(client, "data/[name].json")
|
||||
|
||||
/datum/asset/json/get_url_mappings()
|
||||
return list(
|
||||
"[name].json" = SSassets.transport.get_asset_url("data/[name].json"),
|
||||
)
|
||||
|
||||
/datum/asset/json/register()
|
||||
var/filename = "data/[name].json"
|
||||
fdel(filename)
|
||||
text2file(json_encode(generate()), filename)
|
||||
SSassets.transport.register_asset(filename, fcopy_rsc(filename))
|
||||
fdel(filename)
|
||||
|
||||
/// Returns the data that will be JSON encoded
|
||||
/datum/asset/json/proc/generate()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
CRASH("generate() not implemented for [type]!")
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
. += "can-open"
|
||||
if(connected_port)
|
||||
. += "can-connector"
|
||||
var/pressure = air_contents.return_pressure()
|
||||
var/pressure = air_contents?.return_pressure()
|
||||
if(pressure >= 40 * ONE_ATMOSPHERE)
|
||||
. += "can-o3"
|
||||
else if(pressure >= 10 * ONE_ATMOSPHERE)
|
||||
@@ -295,6 +295,7 @@
|
||||
density = FALSE
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
||||
investigate_log("was destroyed.", INVESTIGATE_ATMOS)
|
||||
update_icon_state()
|
||||
|
||||
if(holding)
|
||||
holding.forceMove(T)
|
||||
|
||||
@@ -211,11 +211,6 @@
|
||||
unit_name = "arrow"
|
||||
export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ash)
|
||||
|
||||
/datum/export/weapon/bow_teaching
|
||||
cost = 500
|
||||
unit_name = "bowyery tablet"
|
||||
export_types = list(/obj/item/book/granter/crafting_recipe/bone_bow)
|
||||
|
||||
/datum/export/weapon/quiver
|
||||
cost = 100
|
||||
unit_name = "quiver"
|
||||
|
||||
@@ -128,6 +128,9 @@
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("LZCargo")
|
||||
usingBeacon = FALSE
|
||||
|
||||
@@ -67,6 +67,20 @@
|
||||
resistance_flags = NONE
|
||||
strip_mod = 1.2 // because apparently black gloves had this
|
||||
|
||||
/obj/item/clothing/gloves/tackler/combat/goliath
|
||||
name = "goliath gloves"
|
||||
desc = "Rudimentary tackling gloves. The goliath hide makes it great for grappling with targets, while also being fireproof."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goligloves"
|
||||
item_state = "goligloves"
|
||||
|
||||
tackle_stam_cost = 25
|
||||
base_knockdown = 1 SECONDS
|
||||
tackle_range = 5
|
||||
tackle_speed = 2
|
||||
min_distance = 2
|
||||
skill_mod = 1
|
||||
|
||||
/obj/item/clothing/gloves/tackler/combat/insulated
|
||||
name = "guerrilla gloves"
|
||||
desc = "Superior quality combative gloves, good for performing tackle takedowns as well as absorbing electrical shocks."
|
||||
|
||||
@@ -427,25 +427,30 @@
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel"
|
||||
item_state = "flannel"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/red
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/red
|
||||
name = "red flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_red"
|
||||
item_state = "flannel_red"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/aqua
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/aqua
|
||||
name = "aqua flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_aqua"
|
||||
item_state = "flannel_aqua"
|
||||
|
||||
/obj/item/clothing/suit/jacket/flannel/brown
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/brown
|
||||
name = "brown flannel jacket"
|
||||
desc = "Comfy and supposedly flammable."
|
||||
icon_state = "flannel_brown"
|
||||
item_state = "flannel_brown"
|
||||
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/toggle/jacket/whitehoodie
|
||||
name = "soft hoodie"
|
||||
desc = "A soft hoodie with a TailorCo brand on the tag."
|
||||
icon_state = "white_hoodie"
|
||||
item_state = "white_hoodie"
|
||||
togglename = "zipper"
|
||||
/obj/item/clothing/suit/jacket/purplehoodie
|
||||
name = "purple hoodie"
|
||||
desc = "A soft purple hoodie with a TailorCo brand on the tag."
|
||||
@@ -482,6 +487,24 @@
|
||||
icon_state = "gothic_shirtcross"
|
||||
item_state = "gothic_shirtcross"
|
||||
|
||||
/obj/item/clothing/suit/jacket/gentlecoat
|
||||
name = "grey jacket"
|
||||
desc = "A grey coat with a TailorCo brand on the tag. Looks expensive."
|
||||
icon_state = "gentlecoat"
|
||||
item_state = "gentlecoat"
|
||||
|
||||
/obj/item/clothing/suit/toggle/jacket/greenjacket
|
||||
name = "green outdoorsmans jacket"
|
||||
desc = "A green jacket with a TailorCo brand on the tag. Looks expensive."
|
||||
icon_state = "coatar"
|
||||
item_state = "coatar"
|
||||
togglename = "zipper"
|
||||
/obj/item/clothing/suit/toggle/jacket/fancytrench
|
||||
name = "grey trenchcoat"
|
||||
desc = "A custom-tailored trenchcoat with a TailorCo brand on the tag."
|
||||
icon_state = "fancytrench"
|
||||
item_state = "fancytrench"
|
||||
togglename = "buttons"
|
||||
/obj/item/clothing/suit/jacket/leather
|
||||
name = "leather jacket"
|
||||
desc = "Pompadour not included."
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
/area/holodeck,
|
||||
/area/shuttle,
|
||||
/area/maintenance,
|
||||
/area/science/test_area)
|
||||
/area/science/test_area,
|
||||
/area/commons/cryopod)
|
||||
)
|
||||
|
||||
//Subtypes from the above that actually should explode.
|
||||
|
||||
@@ -84,6 +84,12 @@
|
||||
user.visible_message("<span class='suicide'>[user] is scratching [user.p_their()] back as hard as [user.p_they()] can with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/cultivator/bone
|
||||
name = "bone cultivator"
|
||||
desc = "A handle and a few bones tied together to resemble a hoe. Should work for removing weeds."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "cultivator_bone"
|
||||
|
||||
/obj/item/hatchet
|
||||
name = "hatchet"
|
||||
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
|
||||
@@ -112,6 +118,12 @@
|
||||
playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/hatchet/bone
|
||||
name = "bone hatchet"
|
||||
desc = "A primitive hatchet made out of mostly bone, with some sinew to keep it together. It just might do for cutting logs into planks."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "hatchet_bone"
|
||||
|
||||
/obj/item/scythe
|
||||
icon_state = "scythe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
instrument_flags = INSTRUMENT_LEGACY
|
||||
volume_multiplier = 1 //not as loud as synth'd
|
||||
|
||||
/datum/instrument/hardcoded/accordian
|
||||
name = "Accordian"
|
||||
id = "accordian"
|
||||
/datum/instrument/hardcoded/accordion
|
||||
name = "Accordion"
|
||||
id = "accordion"
|
||||
legacy_instrument_ext = "mid"
|
||||
legacy_instrument_path = "accordian"
|
||||
legacy_instrument_path = "accordion"
|
||||
|
||||
/datum/instrument/hardcoded/bikehorn
|
||||
name = "Bike Horn"
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
"60"='sound/instruments/synthesis_samples/organ/crisis_hammond/c4.ogg',
|
||||
"72"='sound/instruments/synthesis_samples/organ/crisis_hammond/c5.ogg')
|
||||
|
||||
/datum/instrument/organ/crisis_accordian
|
||||
name = "Crisis Accordian"
|
||||
/datum/instrument/organ/crisis_accordion
|
||||
name = "Crisis Accordion"
|
||||
id = "crack"
|
||||
real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_accordian/c2.ogg',
|
||||
"48"='sound/instruments/synthesis_samples/organ/crisis_accordian/c3.ogg',
|
||||
@@ -34,8 +34,8 @@
|
||||
"60"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c4.ogg',
|
||||
"72"='sound/instruments/synthesis_samples/organ/crisis_harmonica/c5.ogg')
|
||||
|
||||
/datum/instrument/organ/crisis_tango_accordian
|
||||
name = "Crisis Tango Accordian"
|
||||
/datum/instrument/organ/crisis_tango_accordion
|
||||
name = "Crisis Tango Accordion"
|
||||
id = "crtango"
|
||||
real_samples = list("36"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c2.ogg',
|
||||
"48"='sound/instruments/synthesis_samples/organ/crisis_tangaccordian/c3.ogg',
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_PRISONER
|
||||
|
||||
/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_JOB_PRISONER]
|
||||
if(policy)
|
||||
var/mob/found = (M?.client && M) || (H?.client && H)
|
||||
to_chat(found, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(found, "<br><br>")
|
||||
to_chat(found, "<span class='boldnotice'>[policy]</span>")
|
||||
|
||||
/datum/outfit/job/prisoner
|
||||
name = "Prisoner"
|
||||
jobtype = /datum/job/prisoner
|
||||
|
||||
@@ -232,6 +232,9 @@
|
||||
return data
|
||||
|
||||
/obj/structure/chisel_message/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/mob/user = usr
|
||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||
var/is_creator = user.ckey == creator_key
|
||||
|
||||
@@ -228,6 +228,13 @@
|
||||
/obj/item/kinetic_crusher/glaive/update_icon_state()
|
||||
item_state = "crusher[wielded]-glaive" // this is not icon_state and not supported by 2hcomponent
|
||||
|
||||
/obj/item/kinetic_crusher/glaive/bone
|
||||
name = "necropolis bone glaive"
|
||||
desc = "Tribals trying to immitate technology have spent a long time to somehow assemble bits and pieces to work together just like the real thing. \
|
||||
Although it does take a lot of effort and luck to create, it was a success."
|
||||
icon_state = "crusher-bone"
|
||||
item_state = "crusher0-bone"
|
||||
|
||||
//destablizing force
|
||||
/obj/item/projectile/destabilizer
|
||||
name = "destabilizing force"
|
||||
|
||||
@@ -179,6 +179,12 @@
|
||||
custom_materials = list(/datum/material/iron=50)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/shovel/spade/bone
|
||||
name = "bone spade"
|
||||
desc = "A bone spade, suitable for digging and moving dirt."
|
||||
icon_state = "spade_bone"
|
||||
toolspeed = 0.75
|
||||
|
||||
/obj/item/shovel/serrated
|
||||
name = "serrated bone shovel"
|
||||
desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient lavaland tribal designs."
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
else
|
||||
emp_damage = max(emp_damage-1, 0)
|
||||
|
||||
/mob/living/brain/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/brain/handle_traits()
|
||||
return
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/mob/living/carbon/Moved()
|
||||
. = ..()
|
||||
if(. && (movement_type & FLOATING)) //floating is easy
|
||||
if(. && !CHECK_BITFIELD(movement_type, FLOATING)) //floating is easy
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
|
||||
@@ -83,6 +83,33 @@
|
||||
. += "Chemical Storage: [changeling.chem_charges]/[changeling.chem_storage]"
|
||||
. += "Absorbed DNA: [changeling.absorbedcount]"
|
||||
|
||||
//NINJACODE
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja.
|
||||
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
|
||||
. += "SpiderOS Status: [SN.s_initialized ? "Initialized" : "Disabled"]"
|
||||
. += "Current Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]"
|
||||
if(SN.s_initialized)
|
||||
//Suit gear
|
||||
. += "Energy Charge: [round(SN.cell.charge/100)]%"
|
||||
//Ninja status
|
||||
. += "Fingerprints: [md5(dna.uni_identity)]"
|
||||
. += "Unique Identity: [dna.unique_enzymes]"
|
||||
. += "Overall Status: [stat > 1 ? "dead" : "[health]% healthy"]"
|
||||
. += "Nutrition Status: [nutrition]"
|
||||
. += "Oxygen Loss: [getOxyLoss()]"
|
||||
. += "Toxin Levels: [getToxLoss()]"
|
||||
. += "Burn Severity: [getFireLoss()]"
|
||||
. += "Brute Trauma: [getBruteLoss()]"
|
||||
. += "Radiation Levels: [radiation] rad"
|
||||
. += "Body Temperature: [bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)"
|
||||
|
||||
//Diseases
|
||||
if(length(diseases))
|
||||
. += "Viruses:"
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
. += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]"
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
|
||||
@@ -1397,7 +1397,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
////////////
|
||||
|
||||
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
if(HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
return //hunger is for BABIES
|
||||
|
||||
//The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
|
||||
|
||||
@@ -570,24 +570,15 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "jittery")
|
||||
|
||||
if(stuttering)
|
||||
stuttering = max(stuttering-1, 0)
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(slurring || drunkenness)
|
||||
slurring = max(slurring-1,0,drunkenness)
|
||||
|
||||
if(cultslurring)
|
||||
cultslurring = max(cultslurring-1, 0)
|
||||
|
||||
if(clockcultslurring)
|
||||
clockcultslurring = max(clockcultslurring-1, 0)
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness-1,0)
|
||||
|
||||
if(silent)
|
||||
silent = max(silent-1, 0)
|
||||
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(hallucination)
|
||||
handle_hallucinations()
|
||||
|
||||
|
||||
@@ -150,11 +150,26 @@
|
||||
/mob/living/proc/handle_stomach()
|
||||
return
|
||||
|
||||
//this updates all special effects: knockdown, druggy, stuttering, etc..
|
||||
/*
|
||||
* this updates some effects: mostly old stuff such as drunkness, druggy, stuttering, etc.
|
||||
* that should be converted to status effect datums one day.
|
||||
*/
|
||||
/mob/living/proc/handle_status_effects()
|
||||
if(confused)
|
||||
confused = max(0, confused - 1)
|
||||
|
||||
if(stuttering)
|
||||
stuttering = max(stuttering-1, 0)
|
||||
|
||||
if(slurring)
|
||||
slurring = max(slurring-1,0)
|
||||
|
||||
if(cultslurring)
|
||||
cultslurring = max(cultslurring-1, 0)
|
||||
|
||||
if(clockcultslurring)
|
||||
clockcultslurring = max(clockcultslurring-1, 0)
|
||||
|
||||
/mob/living/proc/handle_traits()
|
||||
//Eyes
|
||||
if(eye_blind) //blindness, heals slowly over time
|
||||
|
||||
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Clickdelay duration post-parry if you fail to parry an attack
|
||||
var/parry_failed_clickcd_duration = 0 SECONDS
|
||||
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
|
||||
var/parry_failed_cooldown_duration = 0 SECONDS
|
||||
var/parry_failed_cooldown_duration = 3.5 SECONDS
|
||||
|
||||
// Advanced
|
||||
/// Flags added to return value
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define PAI_EMP_SILENCE_DURATION 3 MINUTES
|
||||
|
||||
/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
@@ -9,7 +7,7 @@
|
||||
return
|
||||
take_holo_damage(severity/2)
|
||||
DefaultCombatKnockdown(severity*4)
|
||||
silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity)
|
||||
short_radio()
|
||||
if(holoform)
|
||||
fold_in(force = TRUE)
|
||||
emitter_next_use = world.time + emitter_emp_cd
|
||||
|
||||
@@ -66,6 +66,7 @@ GLOBAL_LIST(bad_gremlin_items)
|
||||
/mob/living/simple_animal/hostile/gremlin/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
ADD_TRAIT(src, TRAIT_SHOCKIMMUNE, INNATE_TRAIT)
|
||||
access_card = new /obj/item/card/id(src)
|
||||
var/datum/job/captain/C = new /datum/job/captain
|
||||
access_card.access = C.get_access()
|
||||
|
||||
@@ -95,20 +95,78 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne
|
||||
name = "Cayenne"
|
||||
real_name = "Cayenne"
|
||||
desc = "A failed Syndicate experiment in weaponized space carp technology, it now serves as a lovable mascot."
|
||||
gender = FEMALE
|
||||
regen_amount = 8
|
||||
|
||||
speak_emote = list("squeaks")
|
||||
maxHealth = 90
|
||||
health = 90
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
faction = list(ROLE_SYNDICATE, "carp") //They are still a carp
|
||||
AIStatus = AI_OFF
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
faction = list(ROLE_SYNDICATE)
|
||||
/// Keeping track of the nuke disk for the functionality of storing it.
|
||||
var/obj/item/disk/nuclear/disky
|
||||
/// Location of the file storing disk overlays
|
||||
// var/icon/disk_overlay_file = 'icons/mob/carp.dmi'
|
||||
/// Colored disk mouth appearance for adding it as a mouth overlay
|
||||
var/mutable_appearance/colored_disk_mouth
|
||||
|
||||
harm_intent_damage = 12
|
||||
obj_damage = 70
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 18
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Initialize()
|
||||
. = ..()
|
||||
// AddElement(/datum/element/pet_bonus, "bloops happily!")
|
||||
// colored_disk_mouth = mutable_appearance(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/carp/disk_mouth, greyscale_colors), "disk_mouth")
|
||||
ADD_TRAIT(src, TRAIT_DISK_VERIFIER, INNATE_TRAIT) //carp can verify disky
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/IsAdvancedToolUser()
|
||||
return TRUE //carp SMART
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/death(gibbed)
|
||||
if(disky)
|
||||
disky.forceMove(drop_location())
|
||||
disky = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Destroy(force)
|
||||
QDEL_NULL(disky)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/examine(mob/user)
|
||||
. = ..()
|
||||
if(disky)
|
||||
. += span_notice("Wait... is that [disky] in [p_their()] mouth?")
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/AttackingTarget(atom/attacked_target)
|
||||
if(istype(attacked_target, /obj/item/disk/nuclear))
|
||||
var/obj/item/disk/nuclear/potential_disky = attacked_target
|
||||
if(potential_disky.anchored)
|
||||
return
|
||||
potential_disky.forceMove(src)
|
||||
disky = potential_disky
|
||||
to_chat(src, span_nicegreen("YES!! You manage to pick up [disky]. (Click anywhere to place it back down.)"))
|
||||
update_icon()
|
||||
if(!disky.fake)
|
||||
client.give_award(/datum/award/achievement/misc/cayenne_disk, src)
|
||||
return
|
||||
if(disky)
|
||||
if(isopenturf(attacked_target))
|
||||
to_chat(src, span_notice("You place [disky] on [attacked_target]"))
|
||||
disky.forceMove(attacked_target.drop_location())
|
||||
disky = null
|
||||
update_icon()
|
||||
else
|
||||
disky.melee_attack_chain(src, attacked_target)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(disky == gone)
|
||||
disky = null
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/hostile/carp/cayenne/update_overlays()
|
||||
. = ..()
|
||||
if(!disky || stat == DEAD)
|
||||
return
|
||||
// . += colored_disk_mouth
|
||||
// . += mutable_appearance(disk_overlay_file, "disk_overlay")
|
||||
|
||||
#undef REGENERATION_DELAY
|
||||
|
||||
@@ -32,6 +32,9 @@ Difficulty: Hard
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
achievement_type = /datum/award/achievement/boss/wendigo_kill
|
||||
crusher_achievement_type = /datum/award/achievement/boss/wendigo_crusher
|
||||
score_achievement_type = /datum/award/score/wendigo_score
|
||||
deathmessage = "falls, shaking the ground around it"
|
||||
deathsound = 'sound/effects/gravhit.ogg'
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp,
|
||||
|
||||
@@ -176,6 +176,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
elitemind = pick(candidates)
|
||||
elitemind.playsound_local(get_turf(elitemind), 'sound/effects/magic.ogg', 40, 0)
|
||||
to_chat(elitemind, "<b>You have been chosen to play as a Lavaland Elite.\nIn a few seconds, you will be summoned on Lavaland as a monster to fight your activator, in a fight to the death.\nYour attacks can be switched using the buttons on the top left of the HUD, and used by clicking on targets or tiles similar to a gun.\nWhile the opponent might have an upper hand with powerful mining equipment and tools, you have great power normally limited by AI mobs.\nIf you want to win, you'll have to use your powers in creative ways to ensure the kill. It's suggested you try using them all as soon as possible.\nShould you win, you'll receive extra information regarding what to do after. Good luck!</b>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_SPAWN]
|
||||
if(policy)
|
||||
to_chat(elitemind, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(elitemind, "<br><br>")
|
||||
to_chat(elitemind, "<span class='boldnotice'>[policy]</span>")
|
||||
addtimer(CALLBACK(src, .proc/spawn_elite, elitemind), 100)
|
||||
else
|
||||
visible_message("<span class='boldwarning'>The stirring stops, and nothing emerges. Perhaps try again later.</span>")
|
||||
@@ -304,6 +310,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
to_chat(mychild, "<span class='boldwarning'>As the life in the activator's eyes fade, the forcefield around you dies out and you feel your power subside.\nDespite this inferno being your home, you feel as if you aren't welcome here anymore.\nWithout any guidance, your purpose is now for you to decide.</span>")
|
||||
to_chat(mychild, "<b>Your max health has been halved, but can now heal by standing on your tumor. Note, it's your only way to heal.\nBear in mind, if anyone interacts with your tumor, you'll be resummoned here to carry out another fight. In such a case, you will regain your full max health.\nAlso, be weary of your fellow inhabitants, they likely won't be happy to see you!</b>")
|
||||
to_chat(mychild, "<span class='big bold'>Note that you are a lavaland monster, and thus not allied to the station. You should not cooperate or act friendly with any station crew unless under extreme circumstances!</span>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_WIN]
|
||||
if(policy)
|
||||
to_chat(mychild, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(mychild, "<br><br>")
|
||||
to_chat(mychild, "<span class='boldnotice'>[policy]</span>")
|
||||
|
||||
/obj/item/tumor_shard
|
||||
name = "tumor shard"
|
||||
@@ -332,6 +344,12 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
E.playsound_local(get_turf(E), 'sound/effects/magic.ogg', 40, 0)
|
||||
to_chat(E, "<span class='userdanger'>You have been revived by [user]. While you can't speak to them, you owe [user] a great debt. Assist [user.p_them()] in achieving [user.p_their()] goals, regardless of risk.</span")
|
||||
to_chat(E, "<span class='big bold'>Note that you now share the loyalties of [user]. You are expected not to intentionally sabotage their faction unless commanded to!</span>")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_ELITE_SENTIENCE]
|
||||
if(policy)
|
||||
to_chat(E, "<br><span class='userdanger'>!!READ THIS!!</span><br><span class='warning'>The following is server-specific policy configuration and overrides anything said above if conflicting.</span>")
|
||||
to_chat(E, "<br><br>")
|
||||
to_chat(E, "<span class='boldnotice'>[policy]</span>")
|
||||
E.maxHealth = E.maxHealth * 0.5
|
||||
E.health = E.maxHealth
|
||||
E.desc = "[E.desc] However, this one appears appears less wild in nature, and calmer around people."
|
||||
|
||||
@@ -136,7 +136,7 @@ GLOBAL_LIST_EMPTY(plague_rats)
|
||||
if(LAZYLEN(GLOB.plague_rats) >= cap)
|
||||
visible_message("<span class='warning'>[src] gnaws into its food, [cap] rats are now on the station!</span>")
|
||||
return
|
||||
var/mob/living/newmouse = new /mob/living/simple_animal/hostile/plaguerat(loc)
|
||||
new /mob/living/simple_animal/hostile/plaguerat(loc)
|
||||
visible_message("<span class='notice'>[src] gnaws into its food, attracting another rat!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/plaguerat/proc/exit_vents()
|
||||
|
||||
@@ -195,12 +195,6 @@
|
||||
stat = CONSCIOUS
|
||||
med_hud_set_status()
|
||||
|
||||
|
||||
/mob/living/simple_animal/handle_status_effects()
|
||||
..()
|
||||
if(stuttering)
|
||||
stuttering = 0
|
||||
|
||||
/mob/living/simple_animal/proc/handle_automated_action()
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN
|
||||
movetypes = CRAWLING
|
||||
flags = IGNORE_NOSLOW
|
||||
priority = 20000
|
||||
|
||||
/datum/movespeed_modifier/mob_config_speedmod
|
||||
variable = TRUE
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
//Defines for the suit's unique abilities
|
||||
#define IS_NINJA_SUIT_INITIALIZATION(action) (istype(action, /datum/action/item_action/initialize_ninja_suit))
|
||||
#define IS_NINJA_SUIT_STATUS(action) (istype(action, /datum/action/item_action/ninjastatus))
|
||||
#define IS_NINJA_SUIT_BOOST(action) (istype(action, /datum/action/item_action/ninjaboost))
|
||||
#define IS_NINJA_SUIT_EMP(action) (istype(action, /datum/action/item_action/ninjapulse))
|
||||
#define IS_NINJA_SUIT_STAR_CREATION(action) (istype(action, /datum/action/item_action/ninjastar))
|
||||
|
||||
@@ -5,35 +5,3 @@
|
||||
button_icon_state = "health"
|
||||
icon_icon = 'icons/obj/device.dmi'
|
||||
var/action_background_icon_state = "bg_default_on"
|
||||
|
||||
/**
|
||||
* Proc called to put a status readout to the ninja in chat.
|
||||
*
|
||||
* Called put some information about the ninja's current status into chat.
|
||||
* This information used to be displayed constantly on the status tab screen
|
||||
* when the suit was on, but was turned into this as to remove the code from
|
||||
* human.dm
|
||||
*/
|
||||
/obj/item/clothing/suit/space/space_ninja/proc/ninjastatus()
|
||||
var/mob/living/carbon/human/ninja = affecting
|
||||
var/list/info_list = list()
|
||||
info_list += "<span class='info'>SpiderOS Status: [s_initialized ? "Initialized" : "Disabled"]</span>\n"
|
||||
//Ninja status
|
||||
info_list += "<span class='info'>Fingerprints: [md5(ninja.dna.uni_identity)]</span>\n"
|
||||
info_list += "<span class='info'>Unique Identity: [ninja.dna.unique_enzymes]</span>\n"
|
||||
info_list += "<span class='info'>Overall Status: [ninja.stat > 1 ? "dead" : "[ninja.health]% healthy"]</span>\n"
|
||||
info_list += "<span class='info'>Nutrition Status: [ninja.nutrition]</span>\n"
|
||||
info_list += "<span class='info'>Oxygen Loss: [ninja.getOxyLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Toxin Levels: [ninja.getToxLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Burn Severity: [ninja.getFireLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Brute Trauma: [ninja.getBruteLoss()]</span>\n"
|
||||
info_list += "<span class='info'>Radiation Levels: [ninja.radiation] rad</span>\n"
|
||||
info_list += "<span class='info'>Body Temperature: [ninja.bodytemperature-T0C] degrees C ([ninja.bodytemperature*1.8-459.67] degrees F)</span>\n"
|
||||
|
||||
//Diseases
|
||||
if(length(ninja.diseases))
|
||||
info_list += "Viruses:"
|
||||
for(var/datum/disease/ninja_disease in ninja.diseases)
|
||||
info_list += "<span class='info'>* [ninja_disease.name], Type: [ninja_disease.spread_text], Stage: [ninja_disease.stage]/[ninja_disease.max_stages], Possible Cure: [ninja_disease.cure_text]</span>\n"
|
||||
|
||||
to_chat(ninja, "[info_list.Join()]")
|
||||
|
||||
@@ -121,9 +121,6 @@
|
||||
if(s_coold > 0)
|
||||
to_chat(user, "<span class='warning'><b>ERROR</b>: suit is on cooldown.</span>")
|
||||
return FALSE
|
||||
if(IS_NINJA_SUIT_STATUS(action))
|
||||
ninjastatus()
|
||||
return TRUE
|
||||
if(IS_NINJA_SUIT_BOOST(action))
|
||||
ninjaboost()
|
||||
return TRUE
|
||||
|
||||
@@ -23,4 +23,10 @@
|
||||
|
||||
/obj/item/ammo_box/magazine/mm712x82/match
|
||||
name = "box magazine (Match 7.12x82mm)"
|
||||
icon_state = "a762-50"
|
||||
ammo_type = /obj/item/ammo_casing/mm712x82/match
|
||||
max_ammo = 50
|
||||
|
||||
/obj/item/ammo_box/magazine/mm712x82/update_icon()
|
||||
..()
|
||||
icon_state = "a762-[round(ammo_count(),10)]"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
playsound(user, 'sound/weapons/shotguninsert.ogg', 60, 1)
|
||||
A.update_icon()
|
||||
update_icon()
|
||||
user.SetNextAction(CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/process_chamber(mob/living/user, empty_chamber = 0)
|
||||
return ..() //changed argument value
|
||||
@@ -240,7 +241,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact
|
||||
name = "warden's combat shotgun"
|
||||
desc = "A modified version of the semi automatic combat shotgun with a collapsible stock. For close encounters."
|
||||
desc = "A modified version of the semi-automatic combat shotgun with a collapsible stock and a safety that prevents firing while folded. For close encounters."
|
||||
icon_state = "cshotgunc"
|
||||
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
@@ -250,7 +251,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)) || item_flags && IN_STORAGE)
|
||||
return
|
||||
toggle_stock(user)
|
||||
return TRUE
|
||||
@@ -276,6 +277,14 @@
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state()
|
||||
icon_state = "[current_skin ? unique_reskin[current_skin] : "cshotgun"][stock ? "" : "c"]"
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!stock)
|
||||
shoot_with_empty_chamber(user)
|
||||
to_chat(user, "<span class='warning'>[src] won't fire with a folded stock!</span>")
|
||||
else
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
//Dual Feed Shotgun
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/automatic/dual_tube
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/gun/magic/staff/motivation
|
||||
name = "Motivation"
|
||||
desc = "Rumored to have the ability to open up a portal the depths of Lavaland."
|
||||
desc = "Rumored to have the ability to open up a portal to the depths of Lavaland."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "motivation"
|
||||
item_state = "motivation"
|
||||
@@ -21,15 +21,15 @@
|
||||
recharge_rate = 5
|
||||
var/datum/action/judgement_cut/judgementcut = new/datum/action/judgement_cut()
|
||||
block_parry_data = /datum/block_parry_data/motivation
|
||||
|
||||
|
||||
//to get this to toggle correctly
|
||||
/obj/item/gun/magic/staff/motivation/Initialize()
|
||||
. = ..()
|
||||
judgementcut = new(src)
|
||||
|
||||
//lets the user know that their judgment cuts are recharging
|
||||
//lets the user know that their judgement cuts are recharging
|
||||
/obj/item/gun/magic/staff/motivation/shoot_with_empty_chamber(mob/living/user as mob|obj)
|
||||
to_chat(user, "<span class='warning'>Judgment Cut is recharging.</span>")
|
||||
to_chat(user, "<span class='warning'>Judgement Cut is recharging.</span>")
|
||||
|
||||
//action button to toggle judgement cuts on/off
|
||||
/datum/action/judgement_cut
|
||||
@@ -47,7 +47,7 @@
|
||||
/obj/item/gun/magic/staff/motivation/can_trigger_gun(mob/living/user)
|
||||
. = ..()
|
||||
if(!judgementcut.judgement_toggled)
|
||||
to_chat(user, "<span class='notice'> Judgment Cut is disabled.</span>")
|
||||
to_chat(user, "<span class='notice'>Judgement Cut is disabled.</span>")
|
||||
return FALSE
|
||||
|
||||
//adds/removes judgement cut and judgement cut end upon pickup/drop
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
else
|
||||
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
|
||||
D.add_atom_colour(mix_color_from_reagents(D.reagents.reagent_list), TEMPORARY_COLOUR_PRIORITY)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
last_spray = world.time
|
||||
INVOKE_ASYNC(D, /obj/effect/decal/chempuff/proc/run_puff, A)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
build_path = /obj/item/storage/bag/tray
|
||||
category = list("initial","Dinnerware")
|
||||
|
||||
/datum/design/tray
|
||||
/datum/design/cafeteria_tray
|
||||
name = "Cafeteria Tray"
|
||||
id = "foodtray"
|
||||
build_type = AUTOLATHE
|
||||
|
||||
@@ -242,13 +242,24 @@
|
||||
sleep(30)
|
||||
playsound(C, 'sound/machines/defib_zap.ogg', 50, FALSE)
|
||||
if(check_revivable())
|
||||
var/tplus = world.time - C.timeofdeath
|
||||
playsound(C, 'sound/machines/defib_success.ogg', 50, FALSE)
|
||||
C.set_heartattack(FALSE)
|
||||
var/oxydamage = C.getOxyLoss()
|
||||
if(C.health < HEALTH_THRESHOLD_FULLCRIT && oxydamage)
|
||||
var/diff = C.health - HEALTH_THRESHOLD_FULLCRIT
|
||||
C.adjustOxyLoss(diff) //Heal their oxydamage up to hardcrit (or if less, as much as they have, since the proc has sanity)
|
||||
C.revive(full_heal = FALSE, admin_revive = FALSE)
|
||||
C.emote("gasp")
|
||||
C.Jitter(100)
|
||||
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
|
||||
log_game("[C] has been successfully defibrillated by nanites.")
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/timelimit = CONFIG_GET(number/defib_cmd_time_limit) * 10 //the config is in seconds, not deciseconds
|
||||
var/late = timelimit && (tplus > timelimit)
|
||||
var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
|
||||
if(policy)
|
||||
to_chat(C, policy)
|
||||
C.log_message("has been successfully defibrillated by nanites, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
|
||||
else
|
||||
playsound(C, 'sound/machines/defib_failed.ogg', 50, FALSE)
|
||||
|
||||
|
||||
@@ -59,13 +59,13 @@
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
@@ -121,12 +121,12 @@
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
@@ -184,11 +184,11 @@
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 150
|
||||
max_damage = 50
|
||||
disable_threshold = 75
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
@@ -243,11 +243,10 @@
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 150
|
||||
disable_threshold = 75
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.25
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
|
||||
@@ -48,6 +48,13 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/retractor/ashwalker
|
||||
name = "bontractor"
|
||||
desc = "Kinda looks like a chicken bone."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "retractor_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/hemostat
|
||||
name = "hemostat"
|
||||
desc = "You think you have seen this before."
|
||||
@@ -78,6 +85,14 @@
|
||||
toolspeed = 0.5
|
||||
attack_verb = list("attacked", "pinched")
|
||||
|
||||
/obj/item/hemostat/ashwalker
|
||||
name = "femurstat"
|
||||
desc = "Bones that are strapped together with sinews. Used to stop bleeding."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "hemostat_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
|
||||
/obj/item/cautery
|
||||
name = "cautery"
|
||||
desc = "This stops bleeding."
|
||||
@@ -108,6 +123,13 @@
|
||||
toolspeed = 0.5
|
||||
attack_verb = list("burnt")
|
||||
|
||||
/obj/item/cautery/ashwalker
|
||||
name = "coretery"
|
||||
desc = "A legion core strapped to a bone. It can close wounds."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "cautery_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/surgicaldrill
|
||||
name = "surgical drill"
|
||||
desc = "You can drill using this item. You dig?"
|
||||
@@ -257,6 +279,14 @@
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/scalpel/ashwalker
|
||||
name = "diamond scalpel"
|
||||
desc = "Bones and a Diamond tied together to make a scalpel."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "scalpel_bone"
|
||||
force = 12
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/circular_saw
|
||||
name = "circular saw"
|
||||
desc = "For heavy duty cutting."
|
||||
@@ -309,6 +339,14 @@
|
||||
attack_verb = list("attacked", "slashed", "sawed", "cut")
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/circular_saw/ashwalker
|
||||
name = "diamond bonesaw"
|
||||
desc = "Bones designed like a skull, with diamond teeth to cut through bones."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "saw_bone"
|
||||
force = 12
|
||||
toolspeed = 0.85
|
||||
|
||||
/obj/item/surgical_drapes
|
||||
name = "surgical drapes"
|
||||
desc = "Nanotrasen brand surgical drapes provide optimal safety and infection control."
|
||||
@@ -341,6 +379,13 @@
|
||||
prototype = SSresearch.techweb_design_by_id(id)
|
||||
. |= prototype.surgery
|
||||
|
||||
|
||||
/obj/item/surgical_drapes/goliath
|
||||
name = "goliath drapes"
|
||||
desc = "Probably not the most hygienic but what the heck else are you gonna use?"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "surgical_drapes_goli"
|
||||
|
||||
/obj/item/organ_storage //allows medical cyborgs to manipulate organs without hands
|
||||
name = "organ storage bag"
|
||||
desc = "A container for holding body parts."
|
||||
@@ -433,3 +478,10 @@
|
||||
to_chat(user, "<span class='warning'>You refrain from hitting [L] with [src], as you are in help intent.</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/bonesetter/bone
|
||||
name = "bone bonesetter"
|
||||
desc = "A bonesetter made of bones... for setting bones with... bones?"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bone setter_bone"
|
||||
toolspeed = 0.85
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
* return bool If the user's input has been handled and the UI should update.
|
||||
*/
|
||||
/datum/proc/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
// SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
// If UI is not interactive or usr calling Topic is not the UI user, bail.
|
||||
if(!ui || ui.status != UI_INTERACTIVE)
|
||||
return TRUE
|
||||
@@ -145,6 +145,7 @@
|
||||
* client/verb/uiclose(), which closes the ui window
|
||||
*/
|
||||
/datum/proc/ui_close(mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
/**
|
||||
* verb
|
||||
|
||||
@@ -58,11 +58,16 @@
|
||||
src.interface = interface
|
||||
if(title)
|
||||
src.title = title
|
||||
src.state = src_object.ui_state()
|
||||
src.state = src_object.ui_state(user)
|
||||
// Deprecated
|
||||
if(ui_x && ui_y)
|
||||
src.window_size = list(ui_x, ui_y)
|
||||
|
||||
/datum/tgui/Destroy()
|
||||
user = null
|
||||
src_object = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
* * title - The of the alert modal, shown on the top of the TGUI window.
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Set to zero for no timeout.
|
||||
* * autofocus - The bool that controls if this alert should grab window focus.
|
||||
*/
|
||||
/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0)
|
||||
/proc/tgui_alert(mob/user, message = null, title = null, list/buttons = list("Ok"), timeout = 0, autofocus = TRUE)
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
@@ -18,7 +19,7 @@
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout)
|
||||
var/datum/tgui_modal/alert = new(user, message, title, buttons, timeout, autofocus)
|
||||
alert.ui_interact(user)
|
||||
alert.wait()
|
||||
if (alert)
|
||||
@@ -36,8 +37,9 @@
|
||||
* * buttons - The options that can be chosen by the user, each string is assigned a button on the UI.
|
||||
* * callback - The callback to be invoked when a choice is made.
|
||||
* * timeout - The timeout of the alert, after which the modal will close and qdel itself. Disabled by default, can be set to seconds otherwise.
|
||||
* * autofocus - The bool that controls if this alert should grab window focus.
|
||||
*/
|
||||
/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0)
|
||||
/proc/tgui_alert_async(mob/user, message = null, title = null, list/buttons = list("Ok"), datum/callback/callback, timeout = 0, autofocus = TRUE)
|
||||
if (!user)
|
||||
user = usr
|
||||
if (!istype(user))
|
||||
@@ -46,7 +48,7 @@
|
||||
user = client.mob
|
||||
else
|
||||
return
|
||||
var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout)
|
||||
var/datum/tgui_modal/async/alert = new(user, message, title, buttons, callback, timeout, autofocus)
|
||||
alert.ui_interact(user)
|
||||
|
||||
/**
|
||||
@@ -68,13 +70,16 @@
|
||||
var/start_time
|
||||
/// The lifespan of the tgui_modal, after which the window will close and delete itself.
|
||||
var/timeout
|
||||
/// The bool that controls if this modal should grab window focus
|
||||
var/autofocus
|
||||
/// Boolean field describing if the tgui_modal was closed by the user.
|
||||
var/closed
|
||||
|
||||
/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout)
|
||||
/datum/tgui_modal/New(mob/user, message, title, list/buttons, timeout, autofocus)
|
||||
src.title = title
|
||||
src.message = message
|
||||
src.buttons = buttons.Copy()
|
||||
src.autofocus = autofocus
|
||||
if (timeout)
|
||||
src.timeout = timeout
|
||||
start_time = world.time
|
||||
@@ -110,7 +115,8 @@
|
||||
. = list(
|
||||
"title" = title,
|
||||
"message" = message,
|
||||
"buttons" = buttons
|
||||
"buttons" = buttons,
|
||||
"autofocus" = autofocus
|
||||
)
|
||||
|
||||
if(timeout)
|
||||
@@ -140,8 +146,8 @@
|
||||
/// The callback to be invoked by the tgui_modal upon having a choice made.
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout)
|
||||
..(user, message, title, buttons, timeout)
|
||||
/datum/tgui_modal/async/New(mob/user, message, title, list/buttons, callback, timeout, autofocus)
|
||||
..(user, message, title, buttons, timeout, autofocus)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_modal/async/Destroy(force, ...)
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
src.message = message
|
||||
src.buttons = list()
|
||||
src.buttons_map = list()
|
||||
var/list/repeat_buttons = list()
|
||||
|
||||
// Gets rid of illegal characters
|
||||
var/static/regex/whitelistedWords = regex(@{"([^\u0020-\u8000]+)"})
|
||||
@@ -89,6 +90,9 @@
|
||||
for(var/i in buttons)
|
||||
var/string_key = whitelistedWords.Replace("[i]", "")
|
||||
|
||||
//avoids duplicated keys E.g: when areas have the same name
|
||||
string_key = avoid_assoc_duplicate_keys(string_key, repeat_buttons)
|
||||
|
||||
src.buttons += string_key
|
||||
src.buttons_map[string_key] = i
|
||||
|
||||
@@ -144,7 +148,7 @@
|
||||
if("choose")
|
||||
if (!(params["choice"] in buttons))
|
||||
return
|
||||
choice = buttons_map[params["choice"]]
|
||||
set_choice(buttons_map[params["choice"]])
|
||||
SStgui.close_uis(src)
|
||||
return TRUE
|
||||
if("cancel")
|
||||
@@ -152,6 +156,9 @@
|
||||
closed = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_list_input/proc/set_choice(choice)
|
||||
src.choice = choice
|
||||
|
||||
/**
|
||||
* # async tgui_list_input
|
||||
*
|
||||
@@ -162,23 +169,17 @@
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/tgui_list_input/async/New(mob/user, message, title, list/buttons, callback, timeout)
|
||||
..(user, title, message, buttons, timeout)
|
||||
..(user, message, title, buttons, timeout)
|
||||
src.callback = callback
|
||||
|
||||
/datum/tgui_list_input/async/Destroy(force, ...)
|
||||
QDEL_NULL(callback)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_list_input/async/ui_close(mob/user)
|
||||
/datum/tgui_list_input/async/set_choice(choice)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
/datum/tgui_list_input/async/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if (!. || choice == null)
|
||||
return
|
||||
callback.InvokeAsync(choice)
|
||||
qdel(src)
|
||||
if(!isnull(src.choice))
|
||||
callback?.InvokeAsync(src.choice)
|
||||
|
||||
/datum/tgui_list_input/async/wait()
|
||||
return
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
if(istype(asset, /datum/asset/spritesheet))
|
||||
var/datum/asset/spritesheet/spritesheet = asset
|
||||
send_message("asset/stylesheet", spritesheet.css_filename())
|
||||
send_message("asset/mappings", asset.get_url_mappings())
|
||||
send_raw_message(asset.get_serialized_url_mappings())
|
||||
|
||||
/**
|
||||
* private
|
||||
|
||||
@@ -292,7 +292,5 @@
|
||||
desc = "An ancient blade said to have ties with Lavaland's most inner demons. \
|
||||
Allows you to cut from a far distance!"
|
||||
item = /obj/item/gun/magic/staff/motivation
|
||||
cost = 20
|
||||
player_minimum = 20
|
||||
cost = 10
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
|
||||
cant_discount = TRUE
|
||||
|
||||
@@ -91,9 +91,9 @@
|
||||
/obj/vehicle/proc/after_add_occupant(mob/M)
|
||||
auto_assign_occupant_flags(M)
|
||||
|
||||
/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max.
|
||||
/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max.
|
||||
if(driver_amount() < max_drivers)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/proc/remove_occupant(mob/M)
|
||||
if(!istype(M))
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/remove_key, VEHICLE_CONTROL_DRIVE)
|
||||
if(car_traits & CAN_KIDNAP)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/DumpKidnappedMobs, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/dump_kidnapped_mobs, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/driver_move(mob/user, direction)
|
||||
if(key_type && !is_key(inserted_key))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/vehicle/sealed/car/clowncar
|
||||
name = "clown car"
|
||||
desc = "How someone could even fit in there is beyond me."
|
||||
desc = "How someone could even fit in there is byond me."
|
||||
icon_state = "clowncar"
|
||||
max_integrity = 150
|
||||
armor = list("melee" = 70, "bullet" = 40, "laser" = 40, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
|
||||
@@ -10,25 +10,36 @@
|
||||
car_traits = CAN_KIDNAP
|
||||
key_type = /obj/item/bikehorn
|
||||
key_type_exact = FALSE
|
||||
var/droppingoil = FALSE
|
||||
var/RTDcooldown = 150
|
||||
var/lastRTDtime = 0
|
||||
///list of headlight colors we use to pick through when we have party mode due to emag
|
||||
var/headlight_colors = list(COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BRIGHT_BLUE, COLOR_CYAN, COLOR_PURPLE)
|
||||
///Cooldown time inbetween [/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice()] usages
|
||||
var/dice_cooldown_time = 150
|
||||
///How many times kidnappers in the clown car said thanks
|
||||
var/thankscount = 0
|
||||
///Current status of the cannon, alternates between CLOWN_CANNON_INACTIVE, CLOWN_CANNON_BUSY and CLOWN_CANNON_READY
|
||||
var/cannonmode = CLOWN_CANNON_INACTIVE
|
||||
var/light_on = TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/process()
|
||||
if(light_on && (obj_flags & EMAGGED))
|
||||
set_light_color(pick(headlight_colors))
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/generate_actions()
|
||||
. = ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn/clowncar, VEHICLE_CONTROL_DRIVE)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/driver_move(mob/user, direction) //Prevent it from moving onto space
|
||||
if(isspaceturf(get_step(src, direction)))
|
||||
return FALSE
|
||||
else
|
||||
return ..()
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/horn, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/thank, VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/auto_assign_occupant_flags(mob/M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.mind && HAS_TRAIT(H.mind, TRAIT_CLOWN_MENTALITY)) //Ensures only clowns can drive the car. (Including more at once)
|
||||
add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_PERMISSION)
|
||||
add_control_flags(H, VEHICLE_CONTROL_DRIVE)
|
||||
RegisterSignal(H, COMSIG_MOB_CLICKON, .proc/fire_cannon_at)
|
||||
M.log_message("has entered [src] as a possible driver", LOG_ATTACK)
|
||||
return
|
||||
add_control_flags(M, VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
@@ -36,106 +47,195 @@
|
||||
. = ..()
|
||||
playsound(src, pick('sound/vehicles/clowncar_load1.ogg', 'sound/vehicles/clowncar_load2.ogg'), 75)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/after_add_occupant(mob/M, control_flags)
|
||||
. = ..()
|
||||
if(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED).len >= 30)
|
||||
for(var/mob/voreman as anything in return_drivers())
|
||||
voreman.client.give_award(/datum/award/achievement/misc/round_and_full, voreman)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/attack_animal(mob/living/simple_animal/user, list/modifiers)
|
||||
if((user.loc != src) || user.environment_smash & (ENVIRONMENT_SMASH_WALLS|ENVIRONMENT_SMASH_RWALLS))
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/mob_exit(mob/M, silent = FALSE, randomstep = FALSE)
|
||||
. = ..()
|
||||
UnregisterSignal(M, COMSIG_MOB_CLICKON)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
. = ..()
|
||||
if(prob(33))
|
||||
visible_message("<span class='danger'>[src] spews out a ton of space lube!</span>")
|
||||
visible_message(span_danger("[src] spews out a ton of space lube!"))
|
||||
new /obj/effect/particle_effect/foam(loc) //YEET
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
/obj/vehicle/sealed/car/clowncar/attacked_by(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
if(istype(I, /obj/item/reagent_containers/food/snacks/grown/banana))
|
||||
var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I
|
||||
obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity)
|
||||
to_chat(user, "<span class='danger'>You use the [banana] to repair the [src]!</span>")
|
||||
qdel(banana)
|
||||
if(!istype(I, /obj/item/reagent_containers/food/snacks/grown/banana))
|
||||
return
|
||||
var/obj/item/reagent_containers/food/snacks/grown/banana/banana = I
|
||||
obj_integrity += min(banana.seed.potency, max_integrity-obj_integrity)
|
||||
to_chat(user, span_danger("You use the [banana] to repair the [src]!"))
|
||||
qdel(banana)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Bump(atom/movable/M)
|
||||
/obj/vehicle/sealed/car/clowncar/Bump(atom/bumped)
|
||||
. = ..()
|
||||
if(isliving(M))
|
||||
if(ismegafauna(M))
|
||||
if(isliving(bumped))
|
||||
if(ismegafauna(bumped))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/C = L
|
||||
C.DefaultCombatKnockdown(40) //I play to make sprites go horizontal
|
||||
L.visible_message("<span class='warning'>[src] rams into [L] and sucks him up!</span>") //fuck off shezza this isn't ERP.
|
||||
mob_forced_enter(L)
|
||||
var/mob/living/hittarget_living = bumped
|
||||
if(iscarbon(hittarget_living))
|
||||
var/mob/living/carbon/carb = hittarget_living
|
||||
carb.DefaultCombatKnockdown(40) //I play to make sprites go horizontal
|
||||
hittarget_living.visible_message(span_warning("[src] rams into [hittarget_living] and sucks [hittarget_living.p_them()] up!")) //fuck off shezza this isn't ERP.
|
||||
mob_forced_enter(hittarget_living)
|
||||
playsound(src, pick('sound/vehicles/clowncar_ram1.ogg', 'sound/vehicles/clowncar_ram2.ogg', 'sound/vehicles/clowncar_ram3.ogg'), 75)
|
||||
else if(istype(M, /turf/closed) || istype(M, /obj/machinery/door/airlock/external))
|
||||
visible_message("<span class='warning'>[src] rams into [M] and crashes!</span>")
|
||||
playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75)
|
||||
playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75)
|
||||
DumpMobs(TRUE)
|
||||
log_combat(src, hittarget_living, "sucked up")
|
||||
return
|
||||
if(!istype(bumped, /turf/closed))
|
||||
return
|
||||
visible_message(span_warning("[src] rams into [bumped] and crashes!"))
|
||||
playsound(src, pick('sound/vehicles/clowncar_crash1.ogg', 'sound/vehicles/clowncar_crash2.ogg'), 75)
|
||||
playsound(src, 'sound/vehicles/clowncar_crashpins.ogg', 75)
|
||||
DumpMobs(TRUE)
|
||||
log_combat(src, bumped, "crashed into", null, "dumping all passengers")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='danger'>You scramble the clowncar child safety lock and a panel with 6 colorful buttons appears!</span>")
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/RollTheDice, VEHICLE_CONTROL_DRIVE)
|
||||
to_chat(user, span_danger("You scramble \the [src]'s child safety lock, and a panel with six colorful buttons appears!"))
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/roll_the_dice, VEHICLE_CONTROL_DRIVE)
|
||||
initialize_controller_action_type(/datum/action/vehicle/sealed/cannon, VEHICLE_CONTROL_DRIVE)
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/Destroy()
|
||||
/obj/vehicle/sealed/car/clowncar/obj_destruction(damage_flag)
|
||||
playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100)
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/after_move(direction)
|
||||
. = ..()
|
||||
if(droppingoil)
|
||||
new /obj/effect/decal/cleanable/oil/slippery(loc)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/RollTheDice(mob/user)
|
||||
if(world.time - lastRTDtime < RTDcooldown)
|
||||
to_chat(user, "<span class='notice'>The button panel is currently recharging.</span>")
|
||||
/**
|
||||
* Plays a random funky effect
|
||||
* Only available while car is emagged
|
||||
* Possible effects:
|
||||
* * Spawn bananapeel
|
||||
* * Spawn random reagent foam
|
||||
* * Make the clown car look like a singulo temporarily
|
||||
* * Spawn Laughing chem gas
|
||||
* * Drop oil
|
||||
* * Fart and make everyone nearby laugh
|
||||
*/
|
||||
/obj/vehicle/sealed/car/clowncar/proc/roll_the_dice(mob/user)
|
||||
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CLOWNCAR_RANDOMNESS))
|
||||
to_chat(user, span_notice("The button panel is currently recharging."))
|
||||
return
|
||||
lastRTDtime = world.time
|
||||
var/randomnum = rand(1,6)
|
||||
switch(randomnum)
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_CLOWNCAR_RANDOMNESS, dice_cooldown_time)
|
||||
switch(rand(1,6))
|
||||
if(1)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and a special banana peel drops out of it.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and a special banana peel drops out of it."))
|
||||
new /obj/item/grown/bananapeel/specialpeel(loc)
|
||||
if(2)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and unknown chemicals flood out of it.</span>")
|
||||
var/datum/reagents/R = new/datum/reagents(300)
|
||||
R.my_atom = src
|
||||
R.add_reagent(get_random_reagent_id(), 100)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and unknown chemicals flood out of it."))
|
||||
var/datum/reagents/randomchems = new/datum/reagents(300)
|
||||
randomchems.my_atom = src
|
||||
randomchems.add_reagent(get_random_reagent_id(), 100)
|
||||
var/datum/effect_system/foam_spread/foam = new
|
||||
foam.set_up(200, loc, R)
|
||||
foam.set_up(200, loc, randomchems)
|
||||
foam.start()
|
||||
if(3)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car turns on its singularity disguise system.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car turns on its singularity disguise system."))
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "singularity_s1"
|
||||
addtimer(CALLBACK(src, .proc/ResetIcon), 100)
|
||||
addtimer(CALLBACK(src, .proc/reset_icon), 10 SECONDS)
|
||||
if(4)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car spews out a cloud of laughing gas.</span>")
|
||||
var/datum/reagents/R = new/datum/reagents(300)
|
||||
R.my_atom = src
|
||||
R.add_reagent(/datum/reagent/consumable/superlaughter, 50)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car spews out a cloud of laughing gas."))
|
||||
var/datum/reagents/funnychems = new/datum/reagents(300)
|
||||
funnychems.my_atom = src
|
||||
funnychems.add_reagent(/datum/reagent/consumable/superlaughter, 50)
|
||||
var/datum/effect_system/smoke_spread/chem/smoke = new()
|
||||
smoke.set_up(R, 4)
|
||||
smoke.set_up(funnychems, 4)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
if(5)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car starts dropping an oil trail.</span>")
|
||||
droppingoil = TRUE
|
||||
addtimer(CALLBACK(src, .proc/StopDroppingOil), 30)
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car starts dropping an oil trail."))
|
||||
RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/cover_in_oil)
|
||||
addtimer(CALLBACK(src, .proc/stop_dropping_oil), 3 SECONDS)
|
||||
if(6)
|
||||
visible_message("<span class='danger'>[user] has pressed one of the colorful buttons on [src] and the clown car lets out a comedic toot.</span>")
|
||||
visible_message(span_danger("[user] presses one of the colorful buttons on [src], and the clown car lets out a comedic toot."))
|
||||
playsound(src, 'sound/vehicles/clowncar_fart.ogg', 100)
|
||||
for(var/mob/living/L in orange(loc, 6))
|
||||
L.emote("laughs")
|
||||
for(var/mob/living/L in occupants)
|
||||
for(var/mob/living/L as anything in occupants)
|
||||
L.emote("laughs")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/ResetIcon()
|
||||
///resets the icon and iconstate of the clowncar after it was set to singulo states
|
||||
/obj/vehicle/sealed/car/clowncar/proc/reset_icon()
|
||||
icon = initial(icon)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/proc/StopDroppingOil()
|
||||
droppingoil = FALSE
|
||||
///Deploys oil when the clowncar moves in oil deploy mode
|
||||
/obj/vehicle/sealed/car/clowncar/proc/cover_in_oil()
|
||||
SIGNAL_HANDLER
|
||||
new /obj/effect/decal/cleanable/oil/slippery(loc)
|
||||
|
||||
///Stops dropping oil after the time has run up
|
||||
/obj/vehicle/sealed/car/clowncar/proc/stop_dropping_oil()
|
||||
UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
///Toggles the on and off state of the clown cannon that shoots random kidnapped people
|
||||
/obj/vehicle/sealed/car/clowncar/proc/toggle_cannon(mob/user)
|
||||
if(cannonmode == CLOWN_CANNON_BUSY)
|
||||
to_chat(user, span_notice("Please wait for the vehicle to finish its current action first."))
|
||||
return
|
||||
if(cannonmode) //canon active, deactivate
|
||||
flick("clowncar_fromfire", src)
|
||||
icon_state = "clowncar"
|
||||
addtimer(CALLBACK(src, .proc/deactivate_cannon), 2 SECONDS)
|
||||
playsound(src, 'sound/vehicles/clowncar_cannonmode2.ogg', 75)
|
||||
visible_message(span_danger("The [src] starts going back into mobile mode."))
|
||||
else
|
||||
canmove = FALSE //anchor and activate canon
|
||||
flick("clowncar_tofire", src)
|
||||
icon_state = "clowncar_fire"
|
||||
visible_message(span_danger("The [src] opens up and reveals a large cannon."))
|
||||
addtimer(CALLBACK(src, .proc/activate_cannon), 2 SECONDS)
|
||||
playsound(src, 'sound/vehicles/clowncar_cannonmode1.ogg', 75)
|
||||
cannonmode = CLOWN_CANNON_BUSY
|
||||
|
||||
///Finalizes canon activation
|
||||
/obj/vehicle/sealed/car/clowncar/proc/activate_cannon()
|
||||
// mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
|
||||
cannonmode = CLOWN_CANNON_READY
|
||||
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
|
||||
driver.update_mouse_pointer()
|
||||
|
||||
///Finalizes canon deactivation
|
||||
/obj/vehicle/sealed/car/clowncar/proc/deactivate_cannon()
|
||||
canmove = TRUE
|
||||
// mouse_pointer = null
|
||||
cannonmode = CLOWN_CANNON_INACTIVE
|
||||
for(var/mob/living/driver as anything in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))
|
||||
driver.update_mouse_pointer()
|
||||
|
||||
///Fires the cannon where the user clicks
|
||||
/obj/vehicle/sealed/car/clowncar/proc/fire_cannon_at(mob/user, atom/A, params)
|
||||
SIGNAL_HANDLER
|
||||
if(cannonmode != CLOWN_CANNON_READY || !length(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED)))
|
||||
return NONE
|
||||
var/mob/living/unlucky_sod = pick(return_controllers_with_flag(VEHICLE_CONTROL_KIDNAPPED))
|
||||
mob_exit(unlucky_sod, TRUE)
|
||||
flick("clowncar_recoil", src)
|
||||
playsound(src, pick('sound/vehicles/carcannon1.ogg', 'sound/vehicles/carcannon2.ogg', 'sound/vehicles/carcannon3.ogg'), 75)
|
||||
unlucky_sod.throw_at(A, 10, 2)
|
||||
log_combat(user, unlucky_sod, "fired", src, "towards [A]") //this doesn't catch if the mob hits something between the car and the target
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
|
||||
///Increments the thanks counter every time someone thats been kidnapped thanks the driver
|
||||
/obj/vehicle/sealed/car/clowncar/proc/increment_thanks_counter()
|
||||
thankscount++
|
||||
if(thankscount < 100)
|
||||
return
|
||||
for(var/mob/busdriver as anything in return_drivers())
|
||||
busdriver.client.give_award(/datum/award/achievement/misc/the_best_driver, busdriver)
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays
|
||||
key_type = null
|
||||
@@ -144,12 +244,10 @@
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/twitch_plays/simple_movement)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list |= src
|
||||
notify_ghosts("Twitch Plays: Clown Car")
|
||||
|
||||
/obj/vehicle/sealed/car/clowncar/twitch_plays/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.poi_list -= src
|
||||
return ..()
|
||||
|
||||
@@ -158,3 +256,4 @@
|
||||
if(!dir)
|
||||
return
|
||||
driver_move(null, dir)
|
||||
..()
|
||||
|
||||
@@ -126,44 +126,70 @@
|
||||
desc = "Honk your classy horn."
|
||||
button_icon_state = "car_horn"
|
||||
var/hornsound = 'sound/items/carhorn.ogg'
|
||||
var/last_honk_time
|
||||
|
||||
/datum/action/vehicle/sealed/horn/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
last_honk_time = world.time
|
||||
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_CAR_HONK))
|
||||
return
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_CAR_HONK, 2 SECONDS)
|
||||
vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] loudly honks!"))
|
||||
to_chat(owner, span_notice("You press [vehicle_entered_target]'s horn."))
|
||||
if(istype(vehicle_target.inserted_key, /obj/item/bikehorn))
|
||||
vehicle_target.inserted_key.attack_self(owner) //The bikehorn plays a sound instead
|
||||
return
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
|
||||
/datum/action/vehicle/sealed/horn/clowncar/Trigger()
|
||||
if(world.time - last_honk_time > 20)
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] loudly honks</span>")
|
||||
to_chat(owner, "<span class='notice'>You press the vehicle's horn.</span>")
|
||||
last_honk_time = world.time
|
||||
if(vehicle_target.inserted_key)
|
||||
vehicle_target.inserted_key.attack_self(owner) //The key plays a sound
|
||||
else
|
||||
playsound(vehicle_entered_target, hornsound, 75)
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs
|
||||
name = "Dump kidnapped mobs"
|
||||
/datum/action/vehicle/sealed/dump_kidnapped_mobs
|
||||
name = "Dump Kidnapped Mobs"
|
||||
desc = "Dump all objects and people in your car on the floor."
|
||||
button_icon_state = "car_dump"
|
||||
|
||||
/datum/action/vehicle/sealed/DumpKidnappedMobs/Trigger()
|
||||
vehicle_entered_target.visible_message("<span class='danger'>[vehicle_entered_target] starts dumping the people inside of it.</span>")
|
||||
/datum/action/vehicle/sealed/dump_kidnapped_mobs/Trigger()
|
||||
vehicle_entered_target.visible_message(span_danger("[vehicle_entered_target] starts dumping the people inside of it."))
|
||||
vehicle_entered_target.DumpSpecificMobs(VEHICLE_CONTROL_KIDNAPPED)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/RollTheDice
|
||||
name = "Press a colorful button"
|
||||
/datum/action/vehicle/sealed/roll_the_dice
|
||||
name = "Press Colorful Button"
|
||||
desc = "Press one of those colorful buttons on your display panel!"
|
||||
button_icon_state = "car_rtd"
|
||||
|
||||
/datum/action/vehicle/sealed/RollTheDice/Trigger()
|
||||
if(istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.RollTheDice(owner)
|
||||
/datum/action/vehicle/sealed/roll_the_dice/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.roll_the_dice(owner)
|
||||
|
||||
/datum/action/vehicle/sealed/cannon
|
||||
name = "Toggle Siege Mode"
|
||||
desc = "Destroy them with their own fodder!"
|
||||
button_icon_state = "car_cannon"
|
||||
|
||||
/datum/action/vehicle/sealed/cannon/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
var/obj/vehicle/sealed/car/clowncar/C = vehicle_entered_target
|
||||
C.toggle_cannon(owner)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/thank
|
||||
name = "Thank the Clown Car Driver"
|
||||
desc = "They're just doing their job."
|
||||
button_icon_state = "car_thanktheclown"
|
||||
COOLDOWN_DECLARE(thank_time_cooldown)
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/thank/Trigger()
|
||||
if(!istype(vehicle_entered_target, /obj/vehicle/sealed/car/clowncar))
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, thank_time_cooldown))
|
||||
return
|
||||
COOLDOWN_START(src, thank_time_cooldown, 6 SECONDS)
|
||||
var/obj/vehicle/sealed/car/clowncar/clown_car = vehicle_entered_target
|
||||
var/mob/living/carbon/human/clown = pick(clown_car.return_drivers())
|
||||
if(!clown)
|
||||
return
|
||||
owner.say("Thank you for the fun ride, [clown.name]!")
|
||||
clown_car.increment_thanks_counter()
|
||||
|
||||
|
||||
/datum/action/vehicle/ridden/scooter/skateboard/ollie
|
||||
@@ -197,7 +223,9 @@
|
||||
L.Move(landing_turf, vehicle_target.dir)
|
||||
passtable_off(L, VEHICLE_TRAIT)
|
||||
V.pass_flags &= ~PASSTABLE
|
||||
if(locate(/obj/structure/table) in V.loc.contents)
|
||||
if((locate(/obj/structure/table) in V.loc.contents) || (locate(/obj/structure/fluff/railing) in V.loc.contents))
|
||||
if(locate(/obj/structure/fluff/railing) in V.loc.contents)
|
||||
L.client.give_award(/datum/award/achievement/misc/tram_surfer, L)
|
||||
V.grinding = TRUE
|
||||
V.icon_state = "[V.board_icon]-grind"
|
||||
addtimer(CALLBACK(V, /obj/vehicle/ridden/scooter/skateboard/.proc/grind), 2)
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
/obj/item/clothing/glasses/monocle = 3,
|
||||
/obj/item/clothing/suit/jacket = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/red = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/aqua = 4,
|
||||
/obj/item/clothing/suit/jacket/flannel/brown = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/red = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/aqua = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/flannel/brown = 4,
|
||||
/obj/item/clothing/suit/jacket/puffer/vest = 4,
|
||||
/obj/item/clothing/suit/jacket/puffer = 4,
|
||||
/obj/item/clothing/suit/hooded/cloak/david = 4,
|
||||
@@ -219,7 +219,17 @@
|
||||
/obj/item/clothing/under/misc/corporateuniform = 5,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/polychromic = 5,
|
||||
/obj/item/clothing/suit/toggle/wbreakpoly/polychromic = 5,
|
||||
/obj/item/clothing/shoes/sneakers/poly/polychromic = 10)
|
||||
/obj/item/clothing/shoes/sneakers/poly/polychromic = 10,
|
||||
/obj/item/clothing/suit/toggle/jacket/fancytrench = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/greenjacket = 4,
|
||||
/obj/item/clothing/suit/jacket/gentlecoat = 4,
|
||||
/obj/item/clothing/suit/jacket/gothicshirtcross = 4,
|
||||
/obj/item/clothing/suit/jacket/gothicshirt = 4,
|
||||
/obj/item/clothing/suit/jacket/gothiccoat = 4,
|
||||
/obj/item/clothing/suit/jacket/heartcoat = 4,
|
||||
/obj/item/clothing/suit/jacket/purplehoodie = 4,
|
||||
/obj/item/clothing/suit/jacket/bluehoodie = 4,
|
||||
/obj/item/clothing/suit/toggle/jacket/whitehoodie = 4)
|
||||
refill_canister = /obj/item/vending_refill/clothing
|
||||
default_price = PRICE_CHEAP
|
||||
extra_price = PRICE_BELOW_NORMAL
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
/obj/item/toy/cards/deck/unum = 3,
|
||||
/obj/item/cardpack/series_one = 10,
|
||||
/obj/item/dyespray=3,
|
||||
/obj/item/tcgcard_binder = 5)
|
||||
/obj/item/tcgcard_binder = 5,
|
||||
/obj/item/canvas = 3,
|
||||
/obj/item/toy/crayon/spraycan = 3)
|
||||
contraband = list(/obj/item/dice/fudge = 9)
|
||||
premium = list(/obj/item/melee/skateboard/pro = 3,
|
||||
/obj/item/melee/skateboard/hoverboard = 1)
|
||||
|
||||
Reference in New Issue
Block a user