Conflicts!!!

This commit is contained in:
Artur
2020-06-22 17:39:24 +03:00
395 changed files with 84463 additions and 336540 deletions
+5
View File
@@ -428,6 +428,11 @@
desc = "A poster decipting a snake shaped into an ominous 'S'!"
icon_state = "poster47"
/obj/structure/sign/poster/contraband/bountyhunters
name = "Bounty Hunters"
desc = "A poster advertising bounty hunting services. \"I hear you got a problem.\""
icon_state = "poster48"
/obj/structure/sign/poster/official
poster_item_name = "motivational poster"
poster_item_desc = "An official Nanotrasen-issued poster to foster a compliant and obedient workforce. It comes with state-of-the-art adhesive backing, for easy pinning to any vertical surface."
+28 -10
View File
@@ -5,19 +5,21 @@
anchored = TRUE
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "uglymine"
var/triggered = 0
/// We manually check to see if we've been triggered in case multiple atoms cross us in the time between the mine being triggered and it actually deleting, to avoid a race condition with multiple detonations
var/triggered = FALSE
/obj/effect/mine/proc/mineEffect(mob/victim)
to_chat(victim, "<span class='danger'>*click*</span>")
/obj/effect/mine/Crossed(AM as mob|obj)
if(isturf(loc))
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
triggermine(AM)
else
triggermine(AM)
/obj/effect/mine/Crossed(atom/movable/AM)
if(triggered || !isturf(loc))
return
. = ..()
if(AM.movement_type & FLYING)
return
triggermine(AM)
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
@@ -27,9 +29,13 @@
s.set_up(3, 1, src)
s.start()
mineEffect(victim)
SEND_SIGNAL(src, COMSIG_MINE_TRIGGERED)
triggered = 1
qdel(src)
/obj/effect/mine/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir)
. = ..()
triggermine()
/obj/effect/mine/explosive
name = "explosive mine"
@@ -50,6 +56,18 @@
if(isliving(victim))
victim.DefaultCombatKnockdown(stun_time)
/obj/effect/mine/shrapnel
name = "shrapnel mine"
var/shrapnel_type = /obj/item/projectile/bullet/shrapnel
var/shrapnel_magnitude = 3
/obj/effect/mine/shrapnel/mineEffect(mob/victim)
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_magnitude)
/obj/effect/mine/shrapnel/sting
name = "stinger mine"
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
/obj/effect/mine/kickmine
name = "kick mine"
@@ -105,7 +123,7 @@
/obj/effect/mine/pickup/triggermine(mob/victim)
if(triggered)
return
triggered = 1
triggered = TRUE
invisibility = INVISIBILITY_ABSTRACT
mineEffect(victim)
qdel(src)
@@ -491,7 +491,7 @@
/obj/item/kitchen/knife = 5,
/obj/item/screwdriver = 5,
/obj/item/crowbar/red = 1, //Dont you need a crowbar to open this?
/obj/item/stack/medical/bruise_pack = 3,
/obj/item/stack/medical/suture = 3,
/obj/item/reagent_containers/food/drinks/bottle/vodka = 2,
/obj/item/radio = 5,
/obj/item/flashlight = 4,
+174 -18
View File
@@ -4,6 +4,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// if true, everyone item when created will have its name changed to be
// more... RPG-like.
GLOBAL_VAR_INIT(stickpocalypse, FALSE) // if true, all non-embeddable items will be able to harmlessly stick to people when thrown
GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to embed in people, takes precedence over stickpocalypse
/obj/item
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
@@ -104,7 +107,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged
var/datum/embedding_behavior/embedding
var/list/embedding = NONE
var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES
var/heat = 0
@@ -159,7 +162,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/Initialize()
if (attack_verb)
if(attack_verb)
attack_verb = typelist("attack_verb", attack_verb)
. = ..()
@@ -167,9 +170,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
new path(src)
actions_types = null
if(GLOB.rpg_loot_items)
AddComponent(/datum/component/fantasy)
if(force_string)
item_flags |= FORCE_STRING_OVERRIDE
@@ -179,16 +179,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(damtype == "brute")
hitsound = "swing_hit"
if (!embedding)
embedding = getEmbeddingBehavior()
else if (islist(embedding))
embedding = getEmbeddingBehavior(arglist(embedding))
else if (!istype(embedding, /datum/embedding_behavior))
stack_trace("Invalid type [embedding.type] found in .embedding during /obj/item Initialize()")
if(sharpness) //give sharp objects butchering functionality, for consistency
AddComponent(/datum/component/butchering, 80 * toolspeed)
/obj/item/Destroy()
item_flags &= ~DROPDEL //prevent reqdels
if(ismob(loc))
@@ -198,6 +188,26 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
qdel(X)
return ..()
/obj/item/ComponentInitialize()
. = ..()
// this proc says it's for initializing components, but we're initializing elements too because it's you and me against the world >:)
if(!LAZYLEN(embedding))
if(GLOB.embedpocalypse)
embedding = EMBED_POINTY
name = "pointy [name]"
else if(GLOB.stickpocalypse)
embedding = EMBED_HARMLESS
name = "sticky [name]"
updateEmbedding()
if(GLOB.rpg_loot_items)
AddComponent(/datum/component/fantasy)
if(sharpness) //give sharp objects butchering functionality, for consistency
AddComponent(/datum/component/butchering, 80 * toolspeed)
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside))
return 0
@@ -247,7 +257,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
. += "[src] is made of cold-resistant materials."
if(resistance_flags & FIRE_PROOF)
. += "[src] is made of fire-retardant materials."
if(item_flags & (ITEM_CAN_BLOCK | ITEM_CAN_PARRY))
var/datum/block_parry_data/data = return_block_parry_datum(block_parry_data)
. += "[src] has the capacity to be used to block and/or parry. <a href='?src=[REF(data)];name=[name];block=[item_flags & ITEM_CAN_BLOCK];parry=[item_flags & ITEM_CAN_PARRY];render=1'>\[Show Stats\]</a>"
@@ -625,6 +635,18 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
var/volume = get_volume_by_throwforce_and_or_w_class()
if (throwforce > 0)
if (throwhitsound)
playsound(hit_atom, throwhitsound, volume, TRUE, -1)
else if(hitsound)
playsound(hit_atom, hitsound, volume, TRUE, -1)
else
playsound(hit_atom, 'sound/weapons/genhit.ogg',volume, TRUE, -1)
else
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
return hit_atom.hitby(src, 0, itempush, throwingdatum=throwingdatum)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, messy_throw = TRUE)
@@ -918,11 +940,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// if w_volume is 0 you fucked up anyways lol
return w_volume || AUTO_SCALE_VOLUME(w_class)
/obj/item/proc/embedded(mob/living/carbon/human/embedded_mob)
/obj/item/proc/embedded(atom/embedded_target)
return
/obj/item/proc/unembedded()
return
if(item_flags & DROPDEL)
QDEL_NULL(src)
return TRUE
/**
* Sets our slowdown and updates equipment slowdown of any mob we're equipped on.
@@ -938,3 +962,135 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
. = ..()
if(var_name == NAMEOF(src, slowdown))
set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior.
/**
* Does the current embedding var meet the criteria for being harmless? Namely, does it explicitly define the pain multiplier and jostle pain mult to be 0? If so, return true.
*
*/
/obj/item/proc/isEmbedHarmless()
if(embedding)
return !isnull(embedding["pain_mult"]) && !isnull(embedding["jostle_pain_mult"]) && embedding["pain_mult"] == 0 && embedding["jostle_pain_mult"] == 0
///In case we want to do something special (like self delete) upon failing to embed in something, return true
/obj/item/proc/failedEmbed()
if(item_flags & DROPDEL)
QDEL_NULL(src)
return TRUE
/**
* tryEmbed() is for when you want to try embedding something without dealing with the damage + hit messages of calling hitby() on the item while targetting the target.
*
* Really, this is used mostly with projectiles with shrapnel payloads, from [/datum/element/embed/proc/checkEmbedProjectile], and called on said shrapnel. Mostly acts as an intermediate between different embed elements.
*
* Arguments:
* * target- Either a body part, a carbon, or a closed turf. What are we hitting?
* * forced- Do we want this to go through 100%?
*/
/obj/item/proc/tryEmbed(atom/target, forced=FALSE, silent=FALSE)
if(!isbodypart(target) && !iscarbon(target) && !isclosedturf(target))
return
if(!forced && !LAZYLEN(embedding))
return
if(SEND_SIGNAL(src, COMSIG_EMBED_TRY_FORCE, target, forced, silent))
return TRUE
failedEmbed()
///For when you want to disable an item's embedding capabilities (like transforming weapons and such), this proc will detach any active embed elements from it.
/obj/item/proc/disableEmbedding()
SEND_SIGNAL(src, COMSIG_ITEM_DISABLE_EMBED)
return
///For when you want to add/update the embedding on an item. Uses the vars in [/obj/item/embedding], and defaults to config values for values that aren't set. Will automatically detach previous embed elements on this item.
/obj/item/proc/updateEmbedding()
if(!islist(embedding) || !LAZYLEN(embedding))
return
AddElement(/datum/element/embed,\
embed_chance = (!isnull(embedding["embed_chance"]) ? embedding["embed_chance"] : EMBED_CHANCE),\
fall_chance = (!isnull(embedding["fall_chance"]) ? embedding["fall_chance"] : EMBEDDED_ITEM_FALLOUT),\
pain_chance = (!isnull(embedding["pain_chance"]) ? embedding["pain_chance"] : EMBEDDED_PAIN_CHANCE),\
pain_mult = (!isnull(embedding["pain_mult"]) ? embedding["pain_mult"] : EMBEDDED_PAIN_MULTIPLIER),\
remove_pain_mult = (!isnull(embedding["remove_pain_mult"]) ? embedding["remove_pain_mult"] : EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER),\
rip_time = (!isnull(embedding["rip_time"]) ? embedding["rip_time"] : EMBEDDED_UNSAFE_REMOVAL_TIME),\
ignore_throwspeed_threshold = (!isnull(embedding["ignore_throwspeed_threshold"]) ? embedding["ignore_throwspeed_threshold"] : FALSE),\
impact_pain_mult = (!isnull(embedding["impact_pain_mult"]) ? embedding["impact_pain_mult"] : EMBEDDED_IMPACT_PAIN_MULTIPLIER),\
jostle_chance = (!isnull(embedding["jostle_chance"]) ? embedding["jostle_chance"] : EMBEDDED_JOSTLE_CHANCE),\
jostle_pain_mult = (!isnull(embedding["jostle_pain_mult"]) ? embedding["jostle_pain_mult"] : EMBEDDED_JOSTLE_PAIN_MULTIPLIER),\
pain_stam_pct = (!isnull(embedding["pain_stam_pct"]) ? embedding["pain_stam_pct"] : EMBEDDED_PAIN_STAM_PCT),\
embed_chance_turf_mod = (!isnull(embedding["embed_chance_turf_mod"]) ? embedding["embed_chance_turf_mod"] : EMBED_CHANCE_TURF_MOD))
return TRUE
+46 -9
View File
@@ -83,7 +83,7 @@
/obj/item/card/emag/bluespace
name = "bluespace cryptographic sequencer"
desc = "It's a blue card with a magnetic strip attached to some circuitry. It appears to have some sort of transmitter attached to it."
color = rgb(40, 130, 255)
icon_state = "emag_bs"
prox_check = FALSE
/obj/item/card/emag/attack()
@@ -166,6 +166,7 @@
slot_flags = ITEM_SLOT_ID
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
var/id_type_name = "identification card"
var/mining_points = 0 //For redeeming at mining equipment vendors
var/list/access = list()
var/registered_name = null // The name registered_name on the card
@@ -174,6 +175,8 @@
var/bank_support = ID_FREE_BANK_ACCOUNT
var/datum/bank_account/registered_account
var/obj/machinery/paystand/my_store
var/uses_overlays = TRUE
var/icon/cached_flat_icon
/obj/item/card/id/Initialize(mapload)
. = ..()
@@ -362,20 +365,38 @@
/obj/item/card/id/RemoveID()
return src
/*
Usage:
update_label()
Sets the id name to whatever registered_name and assignment is
/obj/item/card/id/update_overlays()
. = ..()
if(!uses_overlays)
return
cached_flat_icon = null
var/job = assignment ? ckey(GetJobName()) : null
if(registered_name == "Captain")
job = "captain"
if(registered_name && registered_name != "Captain")
. += mutable_appearance(icon, "assigned")
if(job)
. += mutable_appearance(icon, "id[job]")
/obj/item/card/id/proc/get_cached_flat_icon()
if(!cached_flat_icon)
cached_flat_icon = getFlatIcon(src)
return cached_flat_icon
/obj/item/card/id/get_examine_string(mob/user, thats = FALSE)
if(uses_overlays)
return "[icon2html(get_cached_flat_icon(), user)] [thats? "That's ":""][get_examine_name(user)]" //displays all overlays in chat
return ..()
update_label("John Doe", "Clowny")
Properly formats the name and occupation and sets the id name to the arguments
*/
/obj/item/card/id/proc/update_label(newname, newjob)
if(newname || newjob)
name = "[(!newname) ? "identification card" : "[newname]'s ID Card"][(!newjob) ? "" : " ([newjob])"]"
update_icon()
return
name = "[(!registered_name) ? "identification card" : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"
update_icon()
/obj/item/card/id/silver
name = "silver identification card"
@@ -388,6 +409,7 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/silver/reaper
name = "Thirteen's ID Card (Reaper)"
access = list(ACCESS_MAINT_TUNNELS)
icon_state = "reaper"
assignment = "Reaper"
registered_name = "Thirteen"
@@ -539,7 +561,7 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/ert
name = "\improper CentCom ID"
desc = "An ERT ID card."
icon_state = "centcom"
icon_state = "ert_commander"
registered_name = "Emergency Response Team Commander"
assignment = "Emergency Response Team Commander"
@@ -548,6 +570,7 @@ update_label("John Doe", "Clowny")
. = ..()
/obj/item/card/id/ert/Security
icon_state = "ert_security"
registered_name = "Security Response Officer"
assignment = "Security Response Officer"
@@ -556,6 +579,7 @@ update_label("John Doe", "Clowny")
. = ..()
/obj/item/card/id/ert/Engineer
icon_state = "ert_engineer"
registered_name = "Engineer Response Officer"
assignment = "Engineer Response Officer"
@@ -564,6 +588,7 @@ update_label("John Doe", "Clowny")
. = ..()
/obj/item/card/id/ert/Medical
icon_state = "ert_medical"
registered_name = "Medical Response Officer"
assignment = "Medical Response Officer"
@@ -572,6 +597,7 @@ update_label("John Doe", "Clowny")
. = ..()
/obj/item/card/id/ert/chaplain
icon_state = "ert_chaplain"
registered_name = "Religious Response Officer"
assignment = "Religious Response Officer"
@@ -624,40 +650,49 @@ update_label("John Doe", "Clowny")
. += "<span class='notice'>Your sentence is up! You're free!</span>"
/obj/item/card/id/prisoner/one
icon_state = "prisoner_001"
name = "Prisoner #13-001"
registered_name = "Prisoner #13-001"
/obj/item/card/id/prisoner/two
icon_state = "prisoner_002"
name = "Prisoner #13-002"
registered_name = "Prisoner #13-002"
/obj/item/card/id/prisoner/three
icon_state = "prisoner_003"
name = "Prisoner #13-003"
registered_name = "Prisoner #13-003"
/obj/item/card/id/prisoner/four
icon_state = "prisoner_004"
name = "Prisoner #13-004"
registered_name = "Prisoner #13-004"
/obj/item/card/id/prisoner/five
icon_state = "prisoner_005"
name = "Prisoner #13-005"
registered_name = "Prisoner #13-005"
/obj/item/card/id/prisoner/six
icon_state = "prisoner_006"
name = "Prisoner #13-006"
registered_name = "Prisoner #13-006"
/obj/item/card/id/prisoner/seven
icon_state = "prisoner_007"
name = "Prisoner #13-007"
registered_name = "Prisoner #13-007"
/obj/item/card/id/mining
name = "mining ID"
icon_state = "retro"
access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
/obj/item/card/id/away
name = "a perfectly generic identification card"
desc = "A perfectly generic identification card. Looks like it could use some flavor."
icon_state = "retro"
access = list(ACCESS_AWAY_GENERAL)
/obj/item/card/id/away/hotel
@@ -700,6 +735,7 @@ update_label("John Doe", "Clowny")
/obj/item/card/id/departmental_budget
name = "departmental card (FUCK)"
desc = "Provides access to the departmental budget."
icon_state = "budgetcard"
var/department_ID = ACCOUNT_CIV
var/department_name = ACCOUNT_CIV_NAME
@@ -712,6 +748,7 @@ update_label("John Doe", "Clowny")
B.bank_cards += src
name = "departmental card ([department_name])"
desc = "Provides access to the [department_name]."
icon_state = "[lowertext(department_ID)]_budget"
SSeconomy.dep_cards += src
/obj/item/card/id/departmental_budget/Destroy()
@@ -14,6 +14,10 @@
name = "Security Cameras (Computer Board)"
build_path = /obj/machinery/computer/security
/obj/item/circuitboard/computer/security/shuttle
name = "Shuttlelinking Security Cameras (Computer Board)"
build_path = /obj/machinery/computer/security/shuttle
/obj/item/circuitboard/computer/xenobiology
name = "circuit board (Xenobiology Console)"
build_path = /obj/machinery/computer/camera_advanced/xenobio
@@ -379,3 +383,11 @@
/obj/item/circuitboard/computer/nanite_cloud_controller
name = "Nanite Cloud Control (Computer Board)"
build_path = /obj/machinery/computer/nanite_cloud_controller
/obj/item/circuitboard/computer/shuttle/flight_control
name = "Shuttle Flight Control (Computer Board)"
build_path = /obj/machinery/computer/custom_shuttle
/obj/item/circuitboard/computer/shuttle/docker
name = "Shuttle Navigation Computer (Computer Board)"
build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/custom
@@ -1102,3 +1102,28 @@
/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/scanning_module = 2
)
/obj/item/circuitboard/machine/shuttle/engine
name = "Thruster (Machine Board)"
build_path = /obj/machinery/shuttle/engine
req_components = list()
/obj/item/circuitboard/machine/shuttle/engine/plasma
name = "Plasma Thruster (Machine Board)"
build_path = /obj/machinery/shuttle/engine/plasma
req_components = list(/obj/item/stock_parts/capacitor = 2,
/obj/item/stack/cable_coil = 5,
/obj/item/stock_parts/micro_laser = 1)
/obj/item/circuitboard/machine/shuttle/engine/void
name = "Void Thruster (Machine Board)"
build_path = /obj/machinery/shuttle/engine/void
req_components = list(/obj/item/stock_parts/capacitor/quadratic = 2,
/obj/item/stack/cable_coil = 5,
/obj/item/stock_parts/micro_laser/quadultra = 1)
/obj/item/circuitboard/machine/shuttle/heater
name = "Electronic Engine Heater (Machine Board)"
build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater
req_components = list(/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/matter_bin = 1)
@@ -7,7 +7,8 @@
var/forced_value = 0
var/duration = 300
/obj/item/grenade/antigravity/prime()
/obj/item/grenade/antigravity/prime(mob/living/lanced_by)
. = ..()
update_mob()
for(var/turf/T in view(range,src))
@@ -174,10 +174,11 @@
message_admins(message)
user.log_message("primed [src] ([reagent_string])",LOG_GAME)
/obj/item/grenade/chem_grenade/prime()
/obj/item/grenade/chem_grenade/prime(mob/living/lanced_by)
if(stage != READY)
return FALSE
. = ..()
var/list/datum/reagents/reactants = list()
for(var/obj/item/reagent_containers/glass/G in beakers)
reactants += G.reagents
@@ -217,7 +218,7 @@
ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades.
threatscale = 1.1 // 10% more effective.
/obj/item/grenade/chem_grenade/large/prime()
/obj/item/grenade/chem_grenade/large/prime(mob/living/lanced_by)
if(stage != READY)
return FALSE
@@ -286,7 +287,7 @@
return
..()
/obj/item/grenade/chem_grenade/adv_release/prime()
/obj/item/grenade/chem_grenade/adv_release/prime(mob/living/lanced_by)
if(stage != READY)
return FALSE
@@ -14,7 +14,8 @@
var/max_spawned = 8
var/segment_chance = 35
/obj/item/grenade/clusterbuster/prime()
/obj/item/grenade/clusterbuster/prime(mob/living/lanced_by)
. = ..()
update_mob()
var/numspawned = rand(min_spawned,max_spawned)
var/again = 0
@@ -59,7 +60,7 @@
step_away(src,loc)
addtimer(CALLBACK(src, .proc/prime), rand(15,60))
/obj/item/grenade/clusterbuster/segment/prime()
/obj/item/grenade/clusterbuster/segment/prime(mob/living/lanced_by)
new payload_spawner(drop_location(), payload, rand(min_spawned,max_spawned))
playsound(src, prime_sound, 75, 1, -3)
qdel(src)
@@ -4,7 +4,8 @@
icon_state = "emp"
item_state = "emp"
/obj/item/grenade/empgrenade/prime()
/obj/item/grenade/empgrenade/prime(mob/living/lanced_by)
. = ..()
update_mob()
empulse(src, 4, 10)
qdel(src)
+91 -1
View File
@@ -6,7 +6,8 @@
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
var/flashbang_range = 7 //how many tiles away the mob will be stunned.
/obj/item/grenade/flashbang/prime()
/obj/item/grenade/flashbang/prime(mob/living/lanced_by)
. = ..()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
@@ -42,3 +43,92 @@
var/distance = get_dist(get_turf(M), source)
if(M.flash_act(affect_silicon = 1))
M.DefaultCombatKnockdown(max(200/max(1,distance), 60))
/obj/item/grenade/stingbang
name = "stingbang"
icon_state = "timeg"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
var/flashbang_range = 1 //how many tiles away the mob will be stunned.
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
shrapnel_radius = 5
custom_premium_price = 700 // mostly gotten through cargo, but throw in one for the sec vendor ;)
/obj/item/grenade/stingbang/mega
name = "mega stingbang"
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball/mega
shrapnel_radius = 12
/obj/item/grenade/stingbang/prime(mob/living/lanced_by)
if(iscarbon(loc))
var/mob/living/carbon/C = loc
var/obj/item/bodypart/B = C.get_holding_bodypart_of_item(src)
if(B)
C.visible_message("<b><span class='danger'>[src] goes off in [C]'s hand, blowing [C.p_their()] [B.name] to bloody shreds!</span></b>", "<span class='userdanger'>[src] goes off in your hand, blowing your [B.name] to bloody shreds!</span>")
B.dismember()
. = ..()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
return
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/weapons/flashbang.ogg', 50, TRUE, 8, 0.9)
new /obj/effect/dummy/lighting_obj (flashbang_turf, LIGHT_COLOR_WHITE, (flashbang_range + 2), 2, 1)
for(var/mob/living/M in get_hearers_in_view(flashbang_range, flashbang_turf))
pop(get_turf(M), M)
qdel(src)
/obj/item/grenade/stingbang/proc/pop(turf/T , mob/living/M)
if(M.stat == DEAD) //They're dead!
return
M.show_message("<span class='warning'>POP</span>", MSG_AUDIBLE)
var/distance = max(0,get_dist(get_turf(src),T))
//Flash
if(M.flash_act(affect_silicon = 1))
M.Paralyze(max(10/max(1,distance), 5))
M.Knockdown(max(100/max(1,distance), 60))
//Bang
if(!distance || loc == M || loc == M.loc)
M.Paralyze(20)
M.Knockdown(200)
M.soundbang_act(1, 200, 10, 15)
if(M.apply_damages(10, 10))
to_chat(M, "<span class='userdanger'>The blast from \the [src] bruises and burns you!</span>")
// only checking if they're on top of the tile, cause being one tile over will be its own punishment
// Grenade that releases more shrapnel the more times you use it in hand between priming and detonation (sorta like the 9bang from MW3), for admin goofs
/obj/item/grenade/primer
name = "rotfrag grenade"
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases shrapnel shards."
icon_state = "timeg"
item_state = "flashbang"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
var/rots_per_mag = 3 /// how many times we need to "rotate" the charge in hand per extra tile of magnitude
shrapnel_type = /obj/item/projectile/bullet/shrapnel
var/rots = 1 /// how many times we've "rotated" the charge
/obj/item/grenade/primer/attack_self(mob/user)
. = ..()
if(active)
user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE)
rots++
user.changeNext_move(CLICK_CD_RAPID)
/obj/item/grenade/primer/prime(mob/living/lanced_by)
shrapnel_radius = round(rots / rots_per_mag)
. = ..()
qdel(src)
/obj/item/grenade/primer/stingbang
name = "rotsting"
desc = "A grenade that generates more shrapnel the more you rotate it in your hand after pulling the pin. This one releases stingballs."
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
rots_per_mag = 2
shrapnel_type = /obj/item/projectile/bullet/pellet/stingball
@@ -45,12 +45,13 @@
/obj/item/grenade/iedcasing/attack_self(mob/user) //
if(!active)
if(clown_check(user))
if(!botch_check(user))
to_chat(user, "<span class='warning'>You light the [name]!</span>")
cut_overlay("improvised_grenade_filled")
preprime(user, null, FALSE)
/obj/item/grenade/iedcasing/prime() //Blowing that can up
/obj/item/grenade/iedcasing/prime(mob/living/lanced_by) //Blowing that can up
. = ..()
update_mob()
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
qdel(src)
+45 -6
View File
@@ -17,10 +17,31 @@
var/det_time = 50
var/display_timer = 1
var/clumsy_check = GRENADE_CLUMSY_FUMBLE
var/sticky = FALSE
// I moved the explosion vars and behavior to base grenades because we want all grenades to call [/obj/item/grenade/proc/prime] so we can send COMSIG_GRENADE_PRIME
///how big of a devastation explosion radius on prime
var/ex_dev = 0
///how big of a heavy explosion radius on prime
var/ex_heavy = 0
///how big of a light explosion radius on prime
var/ex_light = 0
///how big of a flame explosion radius on prime
var/ex_flame = 0
// dealing with creating a [/datum/component/pellet_cloud] on prime
/// if set, will spew out projectiles of this type
var/shrapnel_type
/// the higher this number, the more projectiles are created as shrapnel
var/shrapnel_radius
var/shrapnel_initialized
/obj/item/grenade/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] primes [src], then eats it! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if(shrapnel_type && shrapnel_radius)
shrapnel_initialized = TRUE
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
playsound(src, 'sound/items/eatfood.ogg', 50, 1)
SEND_SIGNAL(src, COMSIG_GRENADE_ARMED, det_time)
preprime(user, det_time)
user.transferItemToLoc(src, user, TRUE)//>eat a grenade set to 5 seconds >rush captain
sleep(det_time)//so you dont die instantly
@@ -32,19 +53,21 @@
if(!QDELETED(src))
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
/obj/item/grenade/proc/botch_check(mob/living/carbon/human/user)
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
if(clumsy)
if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
return TRUE
else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
preprime(user, 5, FALSE)
return FALSE
return TRUE
return TRUE
else if(sticky && prob(50)) // to add risk to sticky tape grenade cheese, no return cause we still prime as normal after
to_chat(user, "<span class='warning'>What the... [src] is stuck to your hand!</span>")
ADD_TRAIT(src, TRAIT_NODROP, STICKY_NODROP)
/obj/item/grenade/examine(mob/user)
. = ..()
@@ -56,8 +79,16 @@
/obj/item/grenade/attack_self(mob/user)
if(HAS_TRAIT(src, TRAIT_NODROP))
to_chat(user, "<span class='notice'>You try prying [src] off your hand...</span>")
if(do_after(user, 70, target=src))
to_chat(user, "<span class='notice'>You manage to remove [src] from your hand.</span>")
REMOVE_TRAIT(src, TRAIT_NODROP, STICKY_NODROP)
return
if(!active)
if(clown_check(user))
if(!botch_check(user)) // if they botch the prime, it'll be handled in botch_check
preprime(user)
/obj/item/grenade/proc/log_grenade(mob/user, turf/T)
@@ -81,10 +112,18 @@
icon_state = initial(icon_state) + "_active"
addtimer(CALLBACK(src, .proc/prime), isnull(delayoverride)? det_time : delayoverride)
/obj/item/grenade/proc/prime()
/obj/item/grenade/proc/prime(mob/living/lanced_by)
var/turf/T = get_turf(src)
log_game("Grenade detonation at [AREACOORD(T)], location [loc]")
if(shrapnel_type && shrapnel_radius && !shrapnel_initialized) // add a second check for adding the component in case whatever triggered the grenade went straight to prime (badminnery for example)
shrapnel_initialized = TRUE
AddComponent(/datum/component/pellet_cloud, projectile_type=shrapnel_type, magnitude=shrapnel_radius)
SEND_SIGNAL(src, COMSIG_GRENADE_PRIME, lanced_by)
if(ex_dev || ex_heavy || ex_light || ex_flame)
explosion(loc, ex_dev, ex_heavy, ex_light, flame_range = ex_flame)
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
+5 -2
View File
@@ -122,7 +122,9 @@
var/obj/item/I = AM
I.throw_speed = max(1, (I.throw_speed - 3))
I.throw_range = max(1, (I.throw_range - 3))
I.embedding = I.embedding.setRating(embed_chance = 0)
if(I.embedding)
I.embedding["embed_chance"] = 0
I.updateEmbedding()
target.add_overlay(plastic_overlay, TRUE)
if(!nadeassembly)
@@ -205,9 +207,10 @@
else
return ..()
/obj/item/grenade/plastic/c4/prime()
/obj/item/grenade/plastic/c4/prime(mob/living/lanced_by)
if(QDELETED(src))
return
. = ..()
var/turf/location
if(target)
if(!QDELETED(target))
@@ -17,7 +17,8 @@
qdel(smoke)
return ..()
/obj/item/grenade/smokebomb/prime()
/obj/item/grenade/smokebomb/prime(mob/living/lanced_by)
. = ..()
update_mob()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
smoke.set_up(4, src)
@@ -7,7 +7,8 @@
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
/obj/item/grenade/spawnergrenade/prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
/obj/item/grenade/spawnergrenade/prime(mob/living/lanced_by) // Prime now just handles the two loops that query for people in lockers and people who can see it.
. = ..()
update_mob()
if(spawner_type && deliveryamt)
// Make a quick flash
@@ -4,27 +4,45 @@
icon = 'icons/obj/grenade.dmi'
icon_state = "syndicate"
item_state = "flashbang"
ex_dev = 1
ex_heavy = 2
ex_light = 4
ex_flame = 2
/obj/item/grenade/syndieminibomb/prime()
/obj/item/grenade/syndieminibomb/prime(mob/living/lanced_by)
. = ..()
update_mob()
explosion(src.loc,1,2,4,flame_range = 2)
qdel(src)
/obj/item/grenade/syndieminibomb/concussion
name = "HE Grenade"
desc = "A compact shrapnel grenade meant to devastate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction."
icon_state = "concussion"
ex_heavy = 2
ex_light = 3
ex_flame = 3
/obj/item/grenade/syndieminibomb/concussion/prime()
update_mob()
explosion(src.loc,0,2,3,flame_range = 3)
qdel(src)
/obj/item/grenade/syndieminibomb/concussion/frag
/obj/item/grenade/frag
name = "frag grenade"
desc = "Fire in the hole."
desc = "An anti-personnel fragmentation grenade, this weapon excels at killing soft targets by shredding them with metal shrapnel."
icon_state = "frag"
shrapnel_type = /obj/item/projectile/bullet/shrapnel
shrapnel_radius = 4
ex_heavy = 1
ex_light = 3
ex_flame = 4
/obj/item/grenade/frag/mega
name = "FRAG grenade"
desc = "An anti-everything fragmentation grenade, this weapon excels at killing anything any everything by shredding them with metal shrapnel."
shrapnel_type = /obj/item/projectile/bullet/shrapnel/mega
shrapnel_radius = 12
/obj/item/grenade/frag/prime(mob/living/lanced_by)
. = ..()
update_mob()
qdel(src)
/obj/item/grenade/gluon
desc = "An advanced grenade that releases a harmful stream of gluons inducing radiation in those nearby. These gluon streams will also make victims feel exhausted, and induce shivering. This extreme coldness will also likely wet any nearby floors."
@@ -36,7 +54,8 @@
var/rad_damage = 350
var/stamina_damage = 30
/obj/item/grenade/gluon/prime()
/obj/item/grenade/gluon/prime(mob/living/lanced_by)
. = ..()
update_mob()
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
radiation_pulse(src, rad_damage)
+3
View File
@@ -138,6 +138,7 @@
icon_state = "buckknife"
item_state = "knife"
desc = "A military combat utility survival knife."
embedding = list("pain_mult" = 4, "embed_chance" = 65, "fall_chance" = 10, "ignore_throwspeed_threshold" = TRUE)
force = 20
throwforce = 20
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
@@ -148,6 +149,7 @@
icon_state = "survivalknife"
item_state = "knife"
desc = "A hunting grade survival knife."
embedding = list("pain_mult" = 4, "embed_chance" = 35, "fall_chance" = 10)
force = 15
throwforce = 15
bayonet = TRUE
@@ -159,6 +161,7 @@
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
desc = "A sharpened bone. The bare minimum in survival."
embedding = list("pain_mult" = 4, "embed_chance" = 35, "fall_chance" = 10)
force = 15
throwforce = 15
custom_materials = null
+1 -1
View File
@@ -103,7 +103,7 @@
throw_speed = 3
throw_range = 5
sharpness = IS_SHARP
embedding = list("embed_chance" = 75, "embedded_impact_pain_multiplier" = 10)
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
armour_penetration = 35
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
block_parry_data = /datum/block_parry_data/energy_sword
@@ -53,6 +53,8 @@
throw_speed = 4
if(attack_verb_on.len)
attack_verb = attack_verb_on
if(embedding)
updateEmbedding()
icon_state = icon_state_on
w_class = w_class_on
else
@@ -62,6 +64,8 @@
throw_speed = initial(throw_speed)
if(attack_verb_off.len)
attack_verb = attack_verb_off
if(embedding)
updateEmbedding()
icon_state = initial(icon_state)
w_class = initial(w_class)
total_mass = initial(total_mass)
+24
View File
@@ -129,6 +129,30 @@
hos_gun_list[initial(A.name)] = A
return hos_gun_list
/obj/item/choice_beacon/augments
name = "augment beacon"
desc = "Summons augmentations."
/obj/item/choice_beacon/augments/generate_display_names()
var/static/list/augment_list
if(!augment_list)
augment_list = list()
var/list/templist = list(
/obj/item/organ/cyberimp/brain/anti_drop,
/obj/item/organ/cyberimp/arm/toolset,
/obj/item/organ/cyberimp/arm/surgery,
/obj/item/organ/cyberimp/chest/thrusters,
/obj/item/organ/lungs/cybernetic,
/obj/item/organ/liver/cybernetic) //cyberimplants range from a nice bonus to fucking broken bullshit so no subtypesof
for(var/V in templist)
var/atom/A = V
augment_list[initial(A.name)] = A
return augment_list
/obj/item/choice_beacon/augments/spawn_option(obj/choice,mob/living/M)
new choice(get_turf(M))
to_chat(M, "<span class='hear'>You hear something crackle from the beacon for a moment before a voice speaks. \"Please stand by for a message from S.E.L.F. Message as follows: <b>Item request received. Your package has been transported, use the autosurgeon supplied to apply the upgrade.</b> Message ends.\"</span>")
/obj/item/skub
desc = "It's skub."
name = "skub"
+17
View File
@@ -183,3 +183,20 @@
A.other_pair = B
B.other_pair = A
/obj/item/pinpointer/shuttle
name = "fugitive pinpointer"
desc = "A handheld tracking device that locates the bounty hunter shuttle for quick escapes."
icon_state = "pinpointer_hunter"
var/obj/shuttleport
/obj/item/pinpointer/shuttle/Initialize(mapload)
. = ..()
shuttleport = SSshuttle.getShuttle("huntership")
/obj/item/pinpointer/shuttle/scan_for_target()
target = shuttleport
/obj/item/pinpointer/shuttle/Destroy()
shuttleport = null
. = ..()
@@ -545,7 +545,7 @@
to_chat(usr, "<span class='notice'>This unit already has an expand module installed!</span>")
return FALSE
R.notransform = TRUE
R.mob_transforming = TRUE
var/prev_locked_down = R.locked_down
R.SetLockdown(1)
R.anchored = TRUE
@@ -559,7 +559,7 @@
if(!prev_locked_down)
R.SetLockdown(0)
R.anchored = FALSE
R.notransform = FALSE
R.mob_transforming = FALSE
R.resize = 2
R.hasExpanded = TRUE
R.update_transform()
+64
View File
@@ -0,0 +1,64 @@
/obj/item/shrapnel // frag grenades
name = "shrapnel shard"
embedding = list(embed_chance=70, ignore_throwspeed_threshold=TRUE, fall_chance=4, embed_chance_turf_mod=-100)
custom_materials = list(/datum/material/iron=50)
armour_penetration = -20
icon = 'icons/obj/shards.dmi'
icon_state = "large"
w_class = WEIGHT_CLASS_TINY
item_flags = DROPDEL
/obj/item/shrapnel/stingball // stingbang grenades
name = "stingball"
embedding = list(embed_chance=90, fall_chance=3, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.7, pain_mult=5, jostle_pain_mult=6, rip_time=15, embed_chance_turf_mod=-100)
icon_state = "tiny"
/obj/item/shrapnel/bullet // bullets
name = "bullet"
icon = 'icons/obj/ammo.dmi'
icon_state = "s-casing"
item_flags = NONE
/obj/item/shrapnel/bullet/c38 // .38 round
name = "\improper .38 bullet"
/obj/item/shrapnel/bullet/c38/dumdum // .38 DumDum round
name = "\improper .38 DumDum bullet"
embedding = list(embed_chance=70, fall_chance=7, jostle_chance=7, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10, embed_chance_turf_mod=-100)
/obj/item/projectile/bullet/shrapnel
name = "flying shrapnel shard"
damage = 9
range = 10
armour_penetration = -30
dismemberment = 5
ricochets_max = 2
ricochet_chance = 40
shrapnel_type = /obj/item/shrapnel
ricochet_incidence_leeway = 60
/obj/item/projectile/bullet/shrapnel/mega
name = "flying shrapnel hunk"
range = 25
dismemberment = 10
ricochets_max = 4
ricochet_chance = 90
ricochet_decay_chance = 0.9
/obj/item/projectile/bullet/pellet/stingball
name = "stingball pellet"
damage = 3
stamina = 8
ricochets_max = 4
ricochet_chance = 66
ricochet_decay_chance = 1
ricochet_decay_damage = 0.9
ricochet_auto_aim_angle = 10
ricochet_auto_aim_range = 2
ricochet_incidence_leeway = 0
shrapnel_type = /obj/item/shrapnel/stingball
/obj/item/projectile/bullet/pellet/stingball/mega
name = "megastingball pellet"
ricochets_max = 6
ricochet_chance = 110
+121 -1
View File
@@ -13,18 +13,33 @@
novariants = FALSE
item_flags = NOBLUDGEON
var/self_delay = 50
var/other_delay = 0
var/repeating = FALSE
/obj/item/stack/medical/attack(mob/living/M, mob/user)
. = ..()
try_heal(M, user)
/obj/item/stack/medical/proc/try_heal(mob/living/M, mob/user, silent = FALSE)
if(!M.can_inject(user, TRUE))
return
if(M == user)
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [user.p_them()]self...</span>", "<span class='notice'>You begin applying \the [src] on yourself...</span>")
if(!silent)
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [user.p_them()]self...</span>", "<span class='notice'>You begin applying \the [src] on yourself...</span>")
if(!do_mob(user, M, self_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE)))
return
else if(other_delay)
if(!silent)
user.visible_message("<span class='notice'>[user] starts to apply \the [src] on [M].</span>", "<span class='notice'>You begin applying \the [src] on [M]...</span>")
if(!do_mob(user, M, other_delay, extra_checks=CALLBACK(M, /mob/living/proc/can_inject, user, TRUE)))
return
if(heal(M, user))
log_combat(user, M, "healed", src.name)
use(1)
if(repeating && amount > 0)
try_heal(M, user, TRUE)
/obj/item/stack/medical/proc/heal(mob/living/M, mob/user)
@@ -174,3 +189,108 @@
/obj/item/stack/medical/ointment/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] is squeezing \the [src] into [user.p_their()] mouth! [user.p_do(TRUE)]n't [user.p_they()] know that stuff is toxic?</span>")
return TOXLOSS
/obj/item/stack/medical/suture
name = "suture"
desc = "Sterile sutures used to seal up cuts and lacerations."
gender = PLURAL
singular_name = "suture"
icon_state = "suture"
self_delay = 30
other_delay = 10
amount = 15
max_amount = 15
repeating = TRUE
var/heal_brute = 10
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
/obj/item/stack/medical/suture/one
amount = 1
/obj/item/stack/medical/suture/heal(mob/living/M, mob/user)
. = ..()
if(M.stat == DEAD)
to_chat(user, "<span class='warning'>[M] is dead! You can not help [M.p_them()].</span>")
return
if(iscarbon(M))
return heal_carbon(M, user, heal_brute, 0)
if(isanimal(M))
var/mob/living/simple_animal/critter = M
if (!(critter.healable))
to_chat(user, "<span class='warning'>You cannot use \the [src] on [M]!</span>")
return FALSE
else if (critter.health == critter.maxHealth)
to_chat(user, "<span class='notice'>[M] is at full health.</span>")
return FALSE
user.visible_message("<span class='green'>[user] applies \the [src] on [M].</span>", "<span class='green'>You apply \the [src] on [M].</span>")
M.heal_bodypart_damage(heal_brute)
return TRUE
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
/obj/item/stack/medical/mesh
name = "regenerative mesh"
desc = "A bacteriostatic mesh used to dress burns."
gender = PLURAL
singular_name = "regenerative mesh"
icon_state = "regen_mesh"
self_delay = 30
other_delay = 10
amount = 15
max_amount = 15
repeating = TRUE
var/heal_burn = 10
var/is_open = TRUE ///This var determines if the sterile packaging of the mesh has been opened.
grind_results = list(/datum/reagent/medicine/spaceacillin = 2)
/obj/item/stack/medical/mesh/one
amount = 1
/obj/item/stack/medical/mesh/Initialize()
. = ..()
if(amount == max_amount) //only seal full mesh packs
is_open = FALSE
update_icon()
/obj/item/stack/medical/mesh/update_icon_state()
if(!is_open)
icon_state = "regen_mesh_closed"
else
return ..()
/obj/item/stack/medical/mesh/heal(mob/living/M, mob/user)
. = ..()
if(M.stat == DEAD)
to_chat(user, "<span class='warning'>[M] is dead! You can not help [M.p_them()].</span>")
return
if(iscarbon(M))
return heal_carbon(M, user, 0, heal_burn)
to_chat(user, "<span class='warning'>You can't heal [M] with the \the [src]!</span>")
/obj/item/stack/medical/mesh/try_heal(mob/living/M, mob/user, silent = FALSE)
if(!is_open)
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
return
. = ..()
/obj/item/stack/medical/mesh/AltClick(mob/living/user)
if(!is_open)
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
return
. = ..()
/obj/item/stack/medical/mesh/attack_hand(mob/user)
if(!is_open & user.get_inactive_held_item() == src)
to_chat(user, "<span class='warning'>You need to open [src] first.</span>")
return
. = ..()
/obj/item/stack/medical/mesh/attack_self(mob/user)
if(!is_open)
is_open = TRUE
to_chat(user, "<span class='notice'>You open the sterile mesh package.</span>")
update_icon()
playsound(src, 'sound/items/poster_ripped.ogg', 20, TRUE)
return
. = ..()
+1
View File
@@ -21,6 +21,7 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
max_amount = 50
attack_verb = list("hit", "bludgeoned", "whacked")
hitsound = 'sound/weapons/grenadelaunch.ogg'
embedding = list()
novariants = TRUE
/obj/item/stack/rods/suicide_act(mob/living/carbon/user)
@@ -291,6 +291,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
max_integrity = 40
sharpness = IS_SHARP
var/icon_prefix
embedding = list("embed_chance" = 65)
/obj/item/shard/suicide_act(mob/user)
@@ -780,6 +780,9 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
/obj/item/stack/sheet/plastic/fifty
amount = 50
/obj/item/stack/sheet/plastic/twenty
amount = 20
/obj/item/stack/sheet/plastic/five
amount = 5
+61
View File
@@ -0,0 +1,61 @@
/obj/item/stack/sticky_tape
name = "sticky tape"
singular_name = "sticky tape"
desc = "Used for sticking to things for sticking said things to people."
icon = 'icons/obj/tapes.dmi'
icon_state = "tape_w"
var/prefix = "sticky"
item_flags = NOBLUDGEON
amount = 5
max_amount = 5
resistance_flags = FLAMMABLE
var/list/conferred_embed = EMBED_HARMLESS
var/overwrite_existing = FALSE
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
if(!istype(I))
return
if(I.embedding && I.embedding == conferred_embed)
to_chat(user, "<span class='warning'>[I] is already coated in [src]!</span>")
return
user.visible_message("<span class='notice'>[user] begins wrapping [I] with [src].</span>", "<span class='notice'>You begin wrapping [I] with [src].</span>")
if(do_after(user, 30, target=I))
I.embedding = conferred_embed
I.updateEmbedding()
to_chat(user, "<span class='notice'>You finish wrapping [I] with [src].</span>")
use(1)
I.name = "[prefix] [I.name]"
if(istype(I, /obj/item/grenade))
var/obj/item/grenade/sticky_bomb = I
sticky_bomb.sticky = TRUE
/obj/item/stack/sticky_tape/super
name = "super sticky tape"
singular_name = "super sticky tape"
desc = "Quite possibly the most mischevious substance in the galaxy. Use with extreme lack of caution."
icon_state = "tape_y"
prefix = "super sticky"
conferred_embed = EMBED_HARMLESS_SUPERIOR
/obj/item/stack/sticky_tape/pointy
name = "pointy tape"
singular_name = "pointy tape"
desc = "Used for sticking to things for sticking said things inside people."
icon_state = "tape_evil"
prefix = "pointy"
conferred_embed = EMBED_POINTY
/obj/item/stack/sticky_tape/pointy/super
name = "super pointy tape"
singular_name = "super pointy tape"
desc = "You didn't know tape could look so sinister. Welcome to Space Station 13."
icon_state = "tape_spikes"
prefix = "super pointy"
conferred_embed = EMBED_POINTY_SUPERIOR
@@ -266,6 +266,9 @@
/obj/item/stack/tile/carpet/blackred/twenty
amount = 20
/obj/item/stack/tile/carpet/blackred/thirty
amount = 30
/obj/item/stack/tile/carpet/blackred/fifty
amount = 50
@@ -275,6 +278,9 @@
/obj/item/stack/tile/carpet/monochrome/twenty
amount = 20
/obj/item/stack/tile/carpet/monochrome/thirty
amount = 30
/obj/item/stack/tile/carpet/monochrome/fifty
amount = 50
@@ -284,6 +290,9 @@
/obj/item/stack/tile/carpet/blue/twenty
amount = 20
/obj/item/stack/tile/carpet/blue/thirty
amount = 30
/obj/item/stack/tile/carpet/blue/fifty
amount = 50
@@ -293,6 +302,9 @@
/obj/item/stack/tile/carpet/cyan/twenty
amount = 20
/obj/item/stack/tile/carpet/cyan/thirty
amount = 30
/obj/item/stack/tile/carpet/cyan/fifty
amount = 50
@@ -302,6 +314,9 @@
/obj/item/stack/tile/carpet/green/twenty
amount = 20
/obj/item/stack/tile/carpet/green/thirty
amount = 30
/obj/item/stack/tile/carpet/green/fifty
amount = 50
@@ -311,6 +326,9 @@
/obj/item/stack/tile/carpet/orange/twenty
amount = 20
/obj/item/stack/tile/carpet/orange/thirty
amount = 30
/obj/item/stack/tile/carpet/orange/fifty
amount = 50
@@ -320,6 +338,9 @@
/obj/item/stack/tile/carpet/purple/twenty
amount = 20
/obj/item/stack/tile/carpet/purple/thirty
amount = 30
/obj/item/stack/tile/carpet/purple/fifty
amount = 50
@@ -329,6 +350,9 @@
/obj/item/stack/tile/carpet/red/twenty
amount = 20
/obj/item/stack/tile/carpet/red/thirty
amount = 30
/obj/item/stack/tile/carpet/red/fifty
amount = 50
@@ -338,6 +362,9 @@
/obj/item/stack/tile/carpet/royalblack/twenty
amount = 20
/obj/item/stack/tile/carpet/royalblack/thirty
amount = 30
/obj/item/stack/tile/carpet/royalblack/fifty
amount = 50
@@ -347,6 +374,9 @@
/obj/item/stack/tile/carpet/royalblue/twenty
amount = 20
/obj/item/stack/tile/carpet/royalblue/thirty
amount = 30
/obj/item/stack/tile/carpet/royalblue/fifty
amount = 50
+1 -1
View File
@@ -391,7 +391,7 @@
STR.storage_flags = STORAGE_FLAGS_VOLUME_DEFAULT
STR.max_volume = STORAGE_VOLUME_CHEMISTRY_BAG
STR.insert_preposition = "in"
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart))
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart, /obj/item/reagent_containers/chem_pack))
/*
* Biowaste bag (mostly for xenobiologists)
+12 -11
View File
@@ -180,7 +180,8 @@
/obj/item/implantcase,
/obj/item/implant,
/obj/item/implanter,
/obj/item/pinpointer/crew
/obj/item/pinpointer/crew,
/obj/item/reagent_containers/chem_pack
))
/obj/item/storage/belt/medical/surgery_belt_adv
@@ -512,16 +513,16 @@
new /obj/item/grenade/smokebomb(src)
new /obj/item/grenade/empgrenade(src)
new /obj/item/grenade/empgrenade(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/syndieminibomb/concussion/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/frag(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
+12 -2
View File
@@ -275,6 +275,16 @@
for(var/i in 1 to 7)
new /obj/item/grenade/flashbang(src)
obj/item/storage/box/stingbangs
name = "box of stingbangs (WARNING)"
desc = "<B>WARNING: These devices are extremely dangerous and can cause severe injuries or death in repeated use.</B>"
icon_state = "secbox"
illustration = "flashbang"
/obj/item/storage/box/stingbangs/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/grenade/stingbang(src)
/obj/item/storage/box/flashes
name = "box of flashbulbs"
desc = "<B>WARNING: Flashes can cause serious eye damage, protective eyewear is required.</B>"
@@ -745,8 +755,8 @@
//////
/obj/item/storage/box/hug/medical/PopulateContents()
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/mesh(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
// Clown survival box
+19
View File
@@ -138,6 +138,22 @@
icon_type = "cigarette"
spawn_type = /obj/item/clothing/mask/cigarette/space_cigarette
custom_price = PRICE_ALMOST_CHEAP
var/spawn_coupon = TRUE
/obj/item/storage/fancy/cigarettes/attack_self(mob/user)
if(contents.len == 0 && spawn_coupon)
to_chat(user, "<span class='notice'>You rip the back off \the [src] and get a coupon!</span>")
var/obj/item/coupon/attached_coupon = new
user.put_in_hands(attached_coupon)
attached_coupon.generate()
attached_coupon = null
spawn_coupon = FALSE
name = "discarded cigarette packet"
desc = "An old cigarette packet with the back torn off, worth less than nothing now."
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 0
return
return ..()
/obj/item/storage/fancy/cigarettes/ComponentInitialize()
. = ..()
@@ -148,6 +164,8 @@
/obj/item/storage/fancy/cigarettes/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to extract contents.</span>"
if(spawn_coupon)
. += "<span class='notice'>There's a coupon on the back of the pack! You can tear it off once it's empty.</span>"
/obj/item/storage/fancy/cigarettes/AltClick(mob/living/carbon/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
@@ -308,6 +326,7 @@
w_class = WEIGHT_CLASS_NORMAL
icon_type = "premium cigar"
spawn_type = /obj/item/clothing/mask/cigarette/cigar
spawn_coupon = FALSE
/obj/item/storage/fancy/cigarettes/cigars/ComponentInitialize()
. = ..()
+12 -11
View File
@@ -37,10 +37,10 @@
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/mesh(src)
new /obj/item/stack/medical/mesh(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
new /obj/item/healthanalyzer(src)
@@ -52,12 +52,12 @@
if(empty)
return
new /obj/item/stack/medical/gauze(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/bruise_pack(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/ointment(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/suture(src)
new /obj/item/stack/medical/mesh(src)
new /obj/item/stack/medical/mesh(src)
new /obj/item/stack/medical/mesh(src)
/obj/item/storage/firstaid/fire
name = "burn treatment kit"
@@ -418,7 +418,8 @@
/obj/item/circuitboard/computer/crew,
/obj/item/stack/sheet/glass,
/obj/item/stack/sheet/mineral/silver,
/obj/item/organ_storage
/obj/item/organ_storage,
/obj/item/reagent_containers/chem_pack
))
//hijacking the minature first aids for hypospray boxes. <3
+43 -10
View File
@@ -188,19 +188,52 @@
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
/obj/item/storage/lockbox/medal/engineering
name = "engineering medal box"
desc = "A locked box used to store medals to be given to the members of the engineering department."
req_access = list(ACCESS_CE)
name = "engineering medal box"
desc = "A locked box used to store medals to be given to the members of the engineering department."
req_access = list(ACCESS_CE)
/obj/item/storage/lockbox/medal/engineering/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/engineer(src)
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/engineer(src)
/obj/item/storage/lockbox/medal/medical
name = "medical medal box"
desc = "A locked box used to store medals to be given to the members of the medical department."
req_access = list(ACCESS_CMO)
name = "medical medal box"
desc = "A locked box used to store medals to be given to the members of the medical department."
req_access = list(ACCESS_CMO)
/obj/item/storage/lockbox/medal/medical/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/ribbon/medical_doctor(src)
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/ribbon/medical_doctor(src)
/obj/item/storage/lockbox/order
name = "order lockbox"
desc = "A box used to secure small cargo orders from being looted by those who didn't order it. Yeah, cargo tech, that means you."
icon = 'icons/obj/storage.dmi'
icon_state = "secure"
item_state = "sec-case"
lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi'
w_class = WEIGHT_CLASS_HUGE
var/datum/bank_account/buyer_account
var/privacy_lock = TRUE
/obj/item/storage/lockbox/order/Initialize(datum/bank_account/_buyer_account)
. = ..()
buyer_account = _buyer_account
/obj/item/storage/lockbox/order/attackby(obj/item/W, mob/user, params)
if(!istype(W, /obj/item/card/id))
return ..()
var/obj/item/card/id/id_card = W
if(iscarbon(user))
add_fingerprint(user)
if(id_card.registered_account != buyer_account)
to_chat(user, "<span class='notice'>Bank account does not match with buyer!</span")
return
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !privacy_lock)
privacy_lock = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
user.visible_message("<span class='notice'>[user] [privacy_lock ? "" : "un"]locks [src]'s privacy lock.</span>",
"<span class='notice'>You [privacy_lock ? "" : "un"]lock [src]'s privacy lock.</span>")
+4 -4
View File
@@ -628,7 +628,7 @@
force_wielded = 18
throwforce = 20
throw_speed = 4
embedding = list("embedded_impact_pain_multiplier" = 1.5, "embed_chance" = 65)
embedding = list("impact_pain_mult" = 3)
armour_penetration = 10
custom_materials = list(/datum/material/iron=1150, /datum/material/glass=2075)
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -713,7 +713,7 @@
force_wielded = 19
force_unwielded = 11
throwforce = 21
embedding = getEmbeddingBehavior(embed_chance = 75, embedded_pain_multiplier = 1.5) //plasmaglass spears are sharper
embedding = list(embed_chance = 75, pain_mult = 1.5) //plasmaglass spears are sharper
icon_prefix = "spearplasma"
qdel(tip)
var/obj/item/twohanded/spear/S = locate() in parts_list
@@ -728,7 +728,7 @@
if(G)
explosive = G
name = "explosive lance"
embedding = getEmbeddingBehavior(embed_chance = 0, embedded_pain_multiplier = 1)//elances should not be embeddable
embedding = list(embed_chance = 0, pain_mult = 1)//elances should not be embeddable
desc = "A makeshift spear with [G] attached to it."
update_icon()
@@ -1108,7 +1108,7 @@
block_slowdown = 2
// no attacking while blocking
block_lock_attacking = TRUE
parry_time_windup = 1
parry_time_active = 5
parry_time_spindown = 0
+17 -1
View File
@@ -299,12 +299,28 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
force = 2
throwforce = 20 //This is never used on mobs since this has a 100% embed chance.
throw_speed = 4
embedding = list("embedded_pain_multiplier" = 4, "embed_chance" = 100, "embedded_fall_chance" = 0)
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
armour_penetration = 40
w_class = WEIGHT_CLASS_SMALL
sharpness = IS_SHARP
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)
resistance_flags = FIRE_PROOF
/obj/item/throwing_star/stamina
name = "shock throwing star"
desc = "An aerodynamic disc designed to cause excruciating pain when stuck inside fleeing targets, hopefully without causing fatal harm."
throwforce = 5
embedding = list("pain_chance" = 5, "embed_chance" = 100, "fall_chance" = 0, "jostle_chance" = 10, "pain_stam_pct" = 0.8, "jostle_pain_mult" = 3)
/obj/item/throwing_star/toy
name = "toy throwing star"
desc = "An aerodynamic disc strapped with adhesive for sticking to people, good for playing pranks and getting yourself killed by security."
sharpness = IS_BLUNT
force = 0
throwforce = 0
embedding = list("pain_mult" = 0, "jostle_pain_mult" = 0, "embed_chance" = 100, "fall_chance" = 0)
/obj/item/switchblade
name = "switchblade"
icon_state = "switchblade"
+2 -1
View File
@@ -74,7 +74,8 @@
/obj/bullet_act(obj/item/projectile/P)
. = ..()
playsound(src, P.hitsound, 50, 1)
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(P.suppressed != SUPPRESSED_VERY)
visible_message("<span class='danger'>[src] is hit by \a [P]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)
+5
View File
@@ -323,3 +323,8 @@
/obj/proc/rnd_crafted(obj/machinery/rnd/production/P)
return
/obj/handle_ricochet(obj/item/projectile/P)
. = ..()
if(. && ricochet_damage_mod)
take_damage(P.damage * ricochet_damage_mod, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration) // pass along ricochet_damage_mod damage to the structure for the ricochet
+2
View File
@@ -9,6 +9,8 @@
var/mob/living/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
layer = BELOW_OBJ_LAYER
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.5
/obj/structure/Initialize()
if (!armor)
@@ -6,8 +6,16 @@
max_integrity = 250
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80)
secure = TRUE
var/melee_min_damage = 20
/obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(damage_flag == "melee" && damage_amount < 20)
if(damage_flag == "melee" && damage_amount < melee_min_damage)
return 0
. = ..()
. = ..()
// Exists to work around the minimum 700 cr price for goodies / small items
/obj/structure/closet/secure_closet/goodies
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.
@@ -0,0 +1,66 @@
/obj/effect/mob_spawn/human/fugitive
assignedrole = "Fugitive Hunter"
flavour_text = "" //the flavor text will be the backstory argument called on the antagonist's greet, see hunter.dm for details
roundstart = FALSE
death = FALSE
random = TRUE
show_flavour = FALSE
density = TRUE
var/back_story = "error"
/obj/effect/mob_spawn/human/fugitive/Initialize(mapload)
. = ..()
notify_ghosts("Hunters are waking up looking for refugees!", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_FUGITIVE)
/obj/effect/mob_spawn/human/fugitive/special(mob/living/new_spawn)
var/datum/antagonist/fugitive_hunter/fughunter = new
fughunter.backstory = back_story
new_spawn.mind.add_antag_datum(fughunter)
fughunter.greet()
message_admins("[ADMIN_LOOKUPFLW(new_spawn)] has been made into a Fugitive Hunter by an event.")
log_game("[key_name(new_spawn)] was spawned as a Fugitive Hunter by an event.")
/obj/effect/mob_spawn/human/fugitive/spacepol
name = "police pod"
desc = "A small sleeper typically used to put people to sleep for briefing on the mission."
mob_name = "a spacepol officer"
flavour_text = "Justice has arrived. I am a member of the Spacepol!"
back_story = "space cop"
outfit = /datum/outfit/spacepol
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
/obj/effect/mob_spawn/human/fugitive/russian
name = "russian pod"
flavour_text = "Ay blyat. I am a space-russian smuggler! We were mid-flight when our cargo was beamed off our ship!"
back_story = "russian"
desc = "A small sleeper typically used to make long distance travel a bit more bearable."
mob_name = "russian"
outfit = /datum/outfit/russiancorpse/hunter
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
/obj/effect/mob_spawn/human/fugitive/bounty
name = "bounty hunter pod"
flavour_text = "We got a new bounty on some fugitives, dead or alive."
back_story = "bounty hunters"
desc = "A small sleeper typically used to make long distance travel a bit more bearable."
mob_name = "bounty hunter"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
/obj/effect/mob_spawn/human/fugitive/bounty/Destroy()
var/obj/structure/fluff/empty_sleeper/S = new(drop_location())
S.setDir(dir)
return ..()
/obj/effect/mob_spawn/human/fugitive/bounty/armor
outfit = /datum/outfit/bountyarmor
/obj/effect/mob_spawn/human/fugitive/bounty/hook
outfit = /datum/outfit/bountyhook
/obj/effect/mob_spawn/human/fugitive/bounty/synth
outfit = /datum/outfit/bountysynth
@@ -581,7 +581,7 @@
uniform = /obj/item/clothing/under/rank/rnd/scientist
shoes = /obj/item/clothing/shoes/laceup
id = /obj/item/card/id/away/old/sci
l_pocket = /obj/item/stack/medical/bruise_pack
l_pocket = /obj/item/stack/medical/suture
assignedrole = "Ancient Crew"
job_description = "Oldstation Crew"
+74 -1
View File
@@ -80,10 +80,11 @@
name = "shock trap"
desc = "A trap that will shock and render you immobile. You'd better avoid it."
icon_state = "trap-shock"
var/stun_time = 100
/obj/structure/trap/stun/trap_effect(mob/living/L)
L.electrocute_act(30, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
L.DefaultCombatKnockdown(100)
L.Paralyze(stun_time)
/obj/structure/trap/fire
name = "flame trap"
@@ -151,3 +152,75 @@
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
QDEL_IN(src, 30)
//fugitive traps
/obj/structure/trap/stun/hunter
name = "bounty trap"
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. You'd better avoid it."
icon = 'icons/obj/objects.dmi'
icon_state = "bounty_trap_on"
stun_time = 200
var/obj/item/bountytrap/stored_item
var/caught = FALSE
/obj/structure/trap/stun/hunter/Initialize(mapload)
. = ..()
time_between_triggers = 10
/obj/structure/trap/stun/hunter/Crossed(atom/movable/AM)
if(isliving(AM))
var/mob/living/L = AM
if(!L.mind?.has_antag_datum(/datum/antagonist/fugitive))
return
caught = TRUE
. = ..()
/obj/structure/trap/stun/hunter/flare()
..()
stored_item.forceMove(get_turf(src))
forceMove(stored_item)
if(caught)
stored_item.announce_fugitive()
caught = FALSE
/obj/item/bountytrap
name = "bounty trap"
desc = "A trap that only goes off when a fugitive steps on it, announcing the location and stunning the target. It's currently inactive."
icon = 'icons/obj/objects.dmi'
icon_state = "bounty_trap_off"
var/obj/structure/trap/stun/hunter/stored_trap
var/obj/item/radio/radio
var/datum/effect_system/spark_spread/spark_system
/obj/item/bountytrap/Initialize(mapload)
. = ..()
radio = new(src)
radio.subspace_transmission = TRUE
radio.canhear_range = 0
radio.recalculateChannels()
spark_system = new
spark_system.set_up(4,1,src)
spark_system.attach(src)
name = "[name] #[rand(1, 999)]"
stored_trap = new(src)
stored_trap.name = name
stored_trap.stored_item = src
/obj/item/bountytrap/proc/announce_fugitive()
spark_system.start()
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
radio.talk_into(src, "Fugitive has triggered this trap in the [get_area_name(src)]!", RADIO_CHANNEL_COMMON)
/obj/item/bountytrap/attack_self(mob/living/user)
var/turf/T = get_turf(src)
if(!user || !user.transferItemToLoc(src, T))//visibly unequips
return
to_chat(user, "<span class=notice>You set up [src]. Examine while close to disarm it.</span>")
stored_trap.forceMove(T)//moves trap to ground
forceMove(stored_trap)//moves item into trap
/obj/item/bountytrap/Destroy()
qdel(stored_trap)
QDEL_NULL(radio)
QDEL_NULL(spark_system)
. = ..()
+4
View File
@@ -38,6 +38,8 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
var/hitsound = 'sound/effects/Glasshit.ogg'
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_flags = RAD_PROTECT_CONTENTS
flags_ricochet = RICOCHET_HARD
ricochet_chance_mod = 0.4
/// Electrochromatic status
var/electrochromatic_status = NOT_ELECTROCHROMATIC
@@ -525,6 +527,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
explosion_block = 1
glass_type = /obj/item/stack/sheet/rglass
rad_insulation = RAD_HEAVY_INSULATION
ricochet_chance_mod = 0.8
/obj/structure/window/reinforced/spawner/east
dir = EAST
@@ -690,6 +693,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
level = 3
glass_type = /obj/item/stack/sheet/titaniumglass
glass_amount = 2
ricochet_chance_mod = 0.9
/obj/structure/window/shuttle/narsie_act()
add_atom_colour("#3C3434", FIXED_COLOUR_PRIORITY)