@@ -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."
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
if(S && S.bloody_shoes[blood_state])
|
||||
if(color != bloodtype_to_color(S.last_bloodtype))
|
||||
if(color != S.last_blood_color)
|
||||
return
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
shoe_types |= S.type
|
||||
@@ -104,7 +104,7 @@
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
if(S && S.bloody_shoes[blood_state])
|
||||
if(color != bloodtype_to_color(S.last_bloodtype))//last entry - we check its color
|
||||
if(color != S.last_blood_color)//last entry - we check its color
|
||||
return
|
||||
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
|
||||
shoe_types |= S.type
|
||||
|
||||
@@ -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)
|
||||
@@ -128,14 +146,13 @@
|
||||
spawn(0)
|
||||
new /datum/hallucination/delusion(victim, TRUE, "demon",duration,0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
var/obj/item/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
victim.log_message("entered a blood frenzy", LOG_ATTACK)
|
||||
|
||||
ADD_TRAIT(chainsaw, TRAIT_NODROP, CHAINSAW_FRENZY_TRAIT)
|
||||
victim.drop_all_held_items()
|
||||
victim.put_in_hands(chainsaw, forced = TRUE)
|
||||
chainsaw.attack_self(victim)
|
||||
chainsaw.wield(victim)
|
||||
victim.reagents.add_reagent(/datum/reagent/medicine/adminordrazine,25)
|
||||
to_chat(victim, "<span class='warning'>KILL, KILL, KILL! YOU HAVE NO ALLIES ANYMORE, KILL THEM ALL!</span>")
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
|
||||
//This is ment for "low" loot that anyone could fine in a toilet, for better gear use high loot toilet
|
||||
//This is meant for "low" loot that anyone could find in a toilet, for better gear use high loot toilet
|
||||
loot = list("" = 30,
|
||||
/obj/item/lighter = 2,
|
||||
/obj/item/tape/random = 1,
|
||||
@@ -476,7 +476,7 @@
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
//Note this is out of a 100 - Meaning the number you see is also the percent its going to pick that
|
||||
//This is ment for "prison" loot that is rather rare and ment for "prisoners if they get a crowbar to fine, or sec.
|
||||
//This is meant for "prison" loot that is rather rare and meant for "prisoners if they get a crowbar to fine, or sec.
|
||||
loot = list("" = 10,
|
||||
/obj/item/lighter = 5,
|
||||
/obj/item/poster/random_contraband = 5,
|
||||
@@ -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,
|
||||
@@ -611,13 +611,13 @@
|
||||
/obj/item/clothing/mask/breath = 5,
|
||||
/obj/item/clothing/mask/breath/medical = 1
|
||||
)
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/welder_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
/obj/effect/spawner/lootdrop/low_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/breathing_tanks/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
@@ -644,3 +644,76 @@
|
||||
|
||||
/obj/effect/spawner/lootdrop/glowstick/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
// Random Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/stock_parts
|
||||
name = "random stock parts spawner"
|
||||
lootcount = 1
|
||||
loot = list(
|
||||
/obj/item/stock_parts/capacitor,
|
||||
/obj/item/stock_parts/scanning_module,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stock_parts/micro_laser,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/cell
|
||||
)
|
||||
|
||||
// Random Weapon Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 13,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 12,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 20%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 80,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 5,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo
|
||||
name = "random ammo 75%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 25,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 1,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 7,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 7,
|
||||
/obj/item/ammo_casing/a762 = 15,
|
||||
/obj/item/ammo_box/a762 = 15,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/fiftypercent
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 2,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 10,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 10,
|
||||
/obj/item/ammo_casing/a762 = 7,
|
||||
/obj/item/ammo_box/a762 = 7,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/shotgun
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/shotgun/loaded/buckshot = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/beanbag = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/incendiary = 5,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 8,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 9,
|
||||
/obj/item/ammo_casing/shotgun = 8,
|
||||
/obj/item/ammo_casing/shotgun/incendiary = 10,
|
||||
)
|
||||
|
||||
+209
-23
@@ -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'
|
||||
@@ -65,6 +68,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/click_delay = CLICK_CD_MELEE
|
||||
|
||||
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
|
||||
var/current_equipped_slot
|
||||
pass_flags = PASSTABLE
|
||||
pressure_resistance = 4
|
||||
var/obj/item/master = null
|
||||
@@ -104,7 +108,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
|
||||
@@ -141,6 +145,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
|
||||
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
|
||||
|
||||
/* Our block parry data. Should be set in init, or something if you are using it.
|
||||
* This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory.
|
||||
* If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy.
|
||||
* If this is set to a path, it'll run get_block_parry_data(path). YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
*/
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
|
||||
///Skills vars
|
||||
//list of skill PATHS exercised when using this item. An associated bitfield can be set to indicate additional ways the skill is used by this specific item.
|
||||
var/list/datum/skill/used_skills
|
||||
@@ -152,7 +163,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
/obj/item/Initialize()
|
||||
|
||||
if (attack_verb)
|
||||
if(attack_verb)
|
||||
attack_verb = typelist("attack_verb", attack_verb)
|
||||
|
||||
. = ..()
|
||||
@@ -160,9 +171,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
|
||||
|
||||
@@ -172,15 +180,10 @@ 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)
|
||||
if(used_skills)
|
||||
for(var/path in used_skills)
|
||||
var/datum/skill/S = GLOB.skill_datums[path]
|
||||
LAZYADD(used_skills[path], S.skill_traits)
|
||||
|
||||
/obj/item/Destroy()
|
||||
item_flags &= ~DROPDEL //prevent reqdels
|
||||
@@ -191,6 +194,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
|
||||
@@ -241,8 +264,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
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>"
|
||||
|
||||
if(!user.research_scanner)
|
||||
return
|
||||
@@ -297,6 +321,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return
|
||||
if(anchored)
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
if(resistance_flags & ON_FIRE)
|
||||
var/mob/living/carbon/C = user
|
||||
@@ -318,7 +346,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
C.update_damage_overlays()
|
||||
return
|
||||
|
||||
if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid.
|
||||
if(acid_level > 20 && ismob(loc))// so we can still remove the clothes on us that have acid.
|
||||
var/mob/living/carbon/C = user
|
||||
if(istype(C))
|
||||
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
|
||||
@@ -361,6 +389,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return
|
||||
if(anchored)
|
||||
return
|
||||
if(loc == user && current_equipped_slot && current_equipped_slot != SLOT_HANDS)
|
||||
if(current_equipped_slot in user.check_obscured_slots())
|
||||
to_chat(src, "<span class='warning'>You are unable to unequip that while wearing other garments over it!</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
SEND_SIGNAL(loc, COMSIG_TRY_STORAGE_TAKE, src, user.loc, TRUE)
|
||||
|
||||
@@ -404,6 +437,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/obj/item/proc/dropped(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
current_equipped_slot = null
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(user)
|
||||
@@ -416,6 +451,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_PICKUP, user)
|
||||
item_flags |= IN_INVENTORY
|
||||
|
||||
@@ -450,7 +486,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// for items that can be placed in multiple slots
|
||||
// note this isn't called during the initial dressing of a player
|
||||
/obj/item/proc/equipped(mob/user, slot)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
. = SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
|
||||
current_equipped_slot = slot
|
||||
if(!(. & COMPONENT_NO_GRANT_ACTIONS))
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
@@ -476,11 +514,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
|
||||
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
|
||||
//Set disable_warning to TRUE if you wish it to not give you outputs.
|
||||
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, clothing_check = FALSE, list/return_warning)
|
||||
if(!M)
|
||||
return FALSE
|
||||
|
||||
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
|
||||
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self, clothing_check, return_warning)
|
||||
|
||||
/obj/item/verb/verb_pickup()
|
||||
set src in oview(1)
|
||||
@@ -615,6 +653,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)
|
||||
@@ -746,6 +796,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
..()
|
||||
|
||||
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_MICROWAVE_ACT, M)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
M.dirty++
|
||||
|
||||
@@ -802,7 +853,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
|
||||
// Called when a mob tries to use the item as a tool.
|
||||
// Handles most checks.
|
||||
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks, skill_gain_mult = 1, max_level = INFINITY)
|
||||
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks, skill_gain_mult = STD_USE_TOOL_MULT)
|
||||
// No delay means there is no start message, and no reason to call tool_start_check before use_tool.
|
||||
// Run the start check here so we wouldn't have to call it manually.
|
||||
if(!delay && !tool_start_check(user, amount))
|
||||
@@ -847,7 +898,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
for(var/skill in used_skills)
|
||||
if(!(SKILL_TRAINING_TOOL in used_skills[skill]))
|
||||
continue
|
||||
user.mind.auto_gain_experience(skill, gain*skill_gain_mult, GET_STANDARD_LVL(max_level))
|
||||
var/datum/skill/S = GLOB.skill_datums[skill]
|
||||
user.mind.auto_gain_experience(skill, gain*skill_gain_mult*S.item_skill_gain_multi)
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -908,11 +960,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.
|
||||
@@ -928,3 +982,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
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/item/twohanded/rcl
|
||||
/obj/item/rcl
|
||||
name = "rapid cable layer"
|
||||
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
@@ -23,15 +23,26 @@
|
||||
var/datum/radial_menu/persistent/wiring_gui_menu
|
||||
var/mob/listeningTo
|
||||
|
||||
/obj/item/twohanded/rcl/Initialize()
|
||||
/obj/item/rcl/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/rcl/ComponentInitialize()
|
||||
/obj/item/rcl/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
AddComponent(/datum/component/two_handed)
|
||||
|
||||
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/rcl/proc/on_wield(obj/item/source, mob/user)
|
||||
active = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/rcl/proc/on_unwield(obj/item/source, mob/user)
|
||||
active = FALSE
|
||||
|
||||
/obj/item/rcl/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
|
||||
@@ -86,26 +97,26 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/twohanded/rcl/examine(mob/user)
|
||||
/obj/item/rcl/examine(mob/user)
|
||||
. = ..()
|
||||
if(loaded)
|
||||
. += "<span class='info'>It contains [loaded.amount]/[max_amount] cables.</span>"
|
||||
|
||||
/obj/item/twohanded/rcl/Destroy()
|
||||
/obj/item/rcl/Destroy()
|
||||
QDEL_NULL(loaded)
|
||||
last = null
|
||||
listeningTo = null
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/rcl/update_icon_state()
|
||||
/obj/item/rcl/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
item_state = initial(item_state)
|
||||
if(!loaded || !loaded.amount)
|
||||
icon_state += "-empty"
|
||||
item_state += "-0"
|
||||
|
||||
/obj/item/twohanded/rcl/update_overlays()
|
||||
/obj/item/rcl/update_overlays()
|
||||
. = ..()
|
||||
if(!loaded || !loaded.amount)
|
||||
return
|
||||
@@ -113,7 +124,7 @@
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
/obj/item/twohanded/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
/obj/item/rcl/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands || !(loaded?.amount))
|
||||
return
|
||||
@@ -121,7 +132,7 @@
|
||||
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
|
||||
. += cable_overlay
|
||||
|
||||
/obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
|
||||
/obj/item/rcl/proc/is_empty(mob/user, loud = 1)
|
||||
update_icon()
|
||||
if(!loaded || !loaded.amount)
|
||||
if(loud)
|
||||
@@ -130,26 +141,23 @@
|
||||
QDEL_NULL(loaded)
|
||||
loaded = null
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
unwield(user)
|
||||
active = wielded
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/rcl/pickup(mob/user)
|
||||
/obj/item/rcl/pickup(mob/user)
|
||||
..()
|
||||
getMobhook(user)
|
||||
|
||||
|
||||
|
||||
/obj/item/twohanded/rcl/dropped(mob/wearer)
|
||||
/obj/item/rcl/dropped(mob/wearer)
|
||||
..()
|
||||
UnregisterSignal(wearer, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
last = null
|
||||
|
||||
/obj/item/twohanded/rcl/attack_self(mob/user)
|
||||
/obj/item/rcl/attack_self(mob/user)
|
||||
..()
|
||||
active = wielded
|
||||
if(!active)
|
||||
last = null
|
||||
else if(!last)
|
||||
@@ -158,7 +166,7 @@
|
||||
last = C
|
||||
break
|
||||
|
||||
obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
obj/item/rcl/proc/getMobhook(mob/to_hook)
|
||||
if(listeningTo == to_hook)
|
||||
return
|
||||
if(listeningTo)
|
||||
@@ -166,7 +174,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
RegisterSignal(to_hook, COMSIG_MOVABLE_MOVED, .proc/trigger)
|
||||
listeningTo = to_hook
|
||||
|
||||
/obj/item/twohanded/rcl/proc/trigger(mob/user)
|
||||
/obj/item/rcl/proc/trigger(mob/user)
|
||||
if(active)
|
||||
layCable(user)
|
||||
if(wiring_gui_menu) //update the wire options as you move
|
||||
@@ -174,7 +182,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
|
||||
//previous contents of trigger(), lays cable each time the player moves
|
||||
/obj/item/twohanded/rcl/proc/layCable(mob/user)
|
||||
/obj/item/rcl/proc/layCable(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
if(is_empty(user, 0))
|
||||
@@ -207,7 +215,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
update_icon()
|
||||
|
||||
//searches the current tile for a stub cable of the same colour
|
||||
/obj/item/twohanded/rcl/proc/findLinkingCable(mob/user)
|
||||
/obj/item/rcl/proc/findLinkingCable(mob/user)
|
||||
var/turf/T
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
@@ -223,10 +231,8 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
continue
|
||||
if(C.d1 == 0)
|
||||
return C
|
||||
return
|
||||
|
||||
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiGenerateChoices(mob/user)
|
||||
/obj/item/rcl/proc/wiringGuiGenerateChoices(mob/user)
|
||||
var/fromdir = 0
|
||||
var/obj/structure/cable/linkingCable = findLinkingCable(user)
|
||||
if(linkingCable)
|
||||
@@ -243,12 +249,12 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
wiredirs[icondir] = img
|
||||
return wiredirs
|
||||
|
||||
/obj/item/twohanded/rcl/proc/showWiringGui(mob/user)
|
||||
/obj/item/rcl/proc/showWiringGui(mob/user)
|
||||
var/list/choices = wiringGuiGenerateChoices(user)
|
||||
|
||||
wiring_gui_menu = show_radial_menu_persistent(user, src , choices, select_proc = CALLBACK(src, .proc/wiringGuiReact, user), radius = 42)
|
||||
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiUpdate(mob/user)
|
||||
/obj/item/rcl/proc/wiringGuiUpdate(mob/user)
|
||||
if(!wiring_gui_menu)
|
||||
return
|
||||
|
||||
@@ -259,7 +265,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
|
||||
//Callback used to respond to interactions with the wiring menu
|
||||
/obj/item/twohanded/rcl/proc/wiringGuiReact(mob/living/user,choice)
|
||||
/obj/item/rcl/proc/wiringGuiReact(mob/living/user,choice)
|
||||
if(!choice) //close on a null choice (the center button)
|
||||
QDEL_NULL(wiring_gui_menu)
|
||||
return
|
||||
@@ -290,7 +296,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
|
||||
wiringGuiUpdate(user)
|
||||
|
||||
/obj/item/twohanded/rcl/ui_action_click(mob/user, action)
|
||||
/obj/item/rcl/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/rcl_col))
|
||||
current_color_index++;
|
||||
if (current_color_index > colors.len)
|
||||
@@ -308,13 +314,13 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
|
||||
else //open the menu
|
||||
showWiringGui(user)
|
||||
|
||||
/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
/obj/item/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff
|
||||
loaded = new()
|
||||
loaded.max_amount = max_amount
|
||||
loaded.amount = max_amount
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/rcl/ghetto
|
||||
/obj/item/rcl/ghetto
|
||||
actions_types = list()
|
||||
max_amount = 30
|
||||
name = "makeshift rapid cable layer"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/obj/item/binoculars
|
||||
name = "binoculars"
|
||||
desc = "Used for long-distance surveillance."
|
||||
item_state = "binoculars"
|
||||
icon_state = "binoculars"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/mob/listeningTo
|
||||
var/zoom_out_amt = 6
|
||||
var/zoom_amt = 10
|
||||
|
||||
/obj/item/binoculars/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/binoculars/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12)
|
||||
|
||||
/obj/item/binoculars/Destroy()
|
||||
listeningTo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/binoculars/proc/on_wield(obj/item/source, mob/user)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/unwield)
|
||||
listeningTo = user
|
||||
user.visible_message("<span class='notice'>[user] holds [src] up to [user.p_their()] eyes.</span>", "<span class='notice'>You hold [src] up to your eyes.</span>")
|
||||
item_state = "binoculars_wielded"
|
||||
user.regenerate_icons()
|
||||
if(!user?.client)
|
||||
return
|
||||
var/client/C = user.client
|
||||
var/_x = 0
|
||||
var/_y = 0
|
||||
switch(user.dir)
|
||||
if(NORTH)
|
||||
_y = zoom_amt
|
||||
if(EAST)
|
||||
_x = zoom_amt
|
||||
if(SOUTH)
|
||||
_y = -zoom_amt
|
||||
if(WEST)
|
||||
_x = -zoom_amt
|
||||
C.change_view(world.view + zoom_out_amt)
|
||||
C.pixel_x = world.icon_size*_x
|
||||
C.pixel_y = world.icon_size*_y
|
||||
/obj/item/binoculars/proc/on_unwield(obj/item/source, mob/user)
|
||||
unwield(user)
|
||||
|
||||
/obj/item/binoculars/proc/unwield(mob/user)
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
user.visible_message("<span class='notice'>[user] lowers [src].</span>", "<span class='notice'>You lower [src].</span>")
|
||||
item_state = "binoculars"
|
||||
user.regenerate_icons()
|
||||
if(user && user.client)
|
||||
user.regenerate_icons()
|
||||
var/client/C = user.client
|
||||
C.change_view(CONFIG_GET(string/default_view))
|
||||
user.client.pixel_x = 0
|
||||
user.client.pixel_y = 0
|
||||
@@ -0,0 +1,69 @@
|
||||
/obj/item/broom
|
||||
name = "broom"
|
||||
desc = "This is my BROOMSTICK! It can be used manually or braced with two hands to sweep items as you move. It has a telescopic handle for compact storage."
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "broom0"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
|
||||
force = 8
|
||||
throwforce = 10
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
attack_verb = list("swept", "brushed off", "bludgeoned", "whacked")
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/broom/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/broom/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12, icon_wielded="broom1")
|
||||
|
||||
/obj/item/broom/update_icon_state()
|
||||
icon_state = "broom0"
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/broom/proc/on_wield(obj/item/source, mob/user)
|
||||
to_chat(user, "<span class='notice'>You brace the [src] against the ground in a firm sweeping stance.</span>")
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/sweep)
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/broom/proc/on_unwield(obj/item/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
|
||||
/obj/item/broom/afterattack(atom/A, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
sweep(user, A, FALSE)
|
||||
|
||||
/obj/item/broom/proc/sweep(mob/user, atom/A, moving = TRUE)
|
||||
var/turf/target
|
||||
if (!moving)
|
||||
if (isturf(A))
|
||||
target = A
|
||||
else
|
||||
target = A.loc
|
||||
else
|
||||
target = user.loc
|
||||
if (!isturf(target))
|
||||
return
|
||||
if (locate(/obj/structure/table) in target.contents)
|
||||
return
|
||||
var/i = 0
|
||||
for(var/obj/item/garbage in target.contents)
|
||||
if(!garbage.anchored)
|
||||
garbage.Move(get_step(target, user.dir), user.dir)
|
||||
i++
|
||||
if(i >= 20)
|
||||
break
|
||||
if(i >= 1)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1)
|
||||
|
||||
/obj/item/broom/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) //bless you whoever fixes this copypasta
|
||||
J.put_in_cart(src, user)
|
||||
J.mybroom=src
|
||||
J.update_icon()
|
||||
@@ -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)
|
||||
. = ..()
|
||||
@@ -187,6 +190,15 @@
|
||||
if(ID_LOCKED_BANK_ACCOUNT)
|
||||
registered_account = new /datum/bank_account/remote/non_transferable(pick(GLOB.redacted_strings))
|
||||
|
||||
/obj/item/card/id/Destroy()
|
||||
if(bank_support == ID_LOCKED_BANK_ACCOUNT)
|
||||
QDEL_NULL(registered_account)
|
||||
else
|
||||
registered_account = null
|
||||
if(my_store)
|
||||
my_store.my_card = null
|
||||
my_store = null
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
@@ -353,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"
|
||||
@@ -379,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"
|
||||
|
||||
@@ -530,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"
|
||||
|
||||
@@ -539,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"
|
||||
|
||||
@@ -547,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"
|
||||
|
||||
@@ -555,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"
|
||||
|
||||
@@ -563,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"
|
||||
|
||||
@@ -615,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
|
||||
@@ -691,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
|
||||
|
||||
@@ -703,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()
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
// CHAINSAW
|
||||
/obj/item/chainsaw
|
||||
name = "chainsaw"
|
||||
desc = "A versatile power tool. Useful for limbing trees and delimbing humans."
|
||||
icon_state = "chainsaw_off"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 13
|
||||
var/force_on = 24
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
throwforce = 13
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
custom_materials = list(/datum/material/iron=13000)
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = "swing_hit"
|
||||
sharpness = IS_SHARP
|
||||
actions_types = list(/datum/action/item_action/startchainsaw)
|
||||
tool_behaviour = TOOL_SAW
|
||||
toolspeed = 0.5
|
||||
var/on = FALSE
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/chainsaw/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/chainsaw/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 30, 100, 0, 'sound/weapons/chainsawhit.ogg', TRUE)
|
||||
AddComponent(/datum/component/two_handed, require_twohands=TRUE)
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/chainsaw/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/chainsaw/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/chainsaw/suicide_act(mob/living/carbon/user)
|
||||
if(on)
|
||||
user.visible_message("<span class='suicide'>[user] begins to tear [user.p_their()] head off with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/chainsawhit.ogg', 100, 1)
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(myhead)
|
||||
myhead.dismember()
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] smashes [src] into [user.p_their()] neck, destroying [user.p_their()] esophagus! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(src, 'sound/weapons/genhit1.ogg', 100, 1)
|
||||
return(BRUTELOSS)
|
||||
|
||||
/obj/item/chainsaw/attack_self(mob/user)
|
||||
on = !on
|
||||
to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]")
|
||||
force = on ? force_on : initial(force)
|
||||
throwforce = on ? force_on : force
|
||||
update_icon()
|
||||
var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
|
||||
butchering.butchering_enabled = on
|
||||
|
||||
if(on)
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
else
|
||||
hitsound = "swing_hit"
|
||||
|
||||
/obj/item/chainsaw/update_icon_state()
|
||||
icon_state = "chainsaw_[on ? "on" : "off"]"
|
||||
|
||||
/obj/item/chainsaw/get_dismemberment_chance()
|
||||
if(wielded)
|
||||
. = ..()
|
||||
|
||||
/obj/item/chainsaw/doomslayer
|
||||
name = "THE GREAT COMMUNICATOR"
|
||||
desc = "<span class='warning'>VRRRRRRR!!!</span>"
|
||||
armour_penetration = 100
|
||||
force_on = 30
|
||||
|
||||
/obj/item/chainsaw/doomslayer/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
block_return[BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE] = 100
|
||||
return ..()
|
||||
|
||||
/obj/item/chainsaw/doomslayer/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(attack_type & ATTACK_TYPE_PROJECTILE)
|
||||
owner.visible_message("<span class='danger'>Ranged attacks just make [owner] angrier!</span>")
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return ..()
|
||||
@@ -794,6 +794,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
reagents.clear_reagents()
|
||||
|
||||
/obj/item/clothing/mask/vape/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(slot == SLOT_WEAR_MASK)
|
||||
if(!screw)
|
||||
to_chat(user, "<span class='notice'>You start puffing on the vape.</span>")
|
||||
@@ -803,6 +804,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
to_chat(user, "<span class='warning'>You need to close the cap first!</span>")
|
||||
|
||||
/obj/item/clothing/mask/vape/dropped(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.get_item_by_slot(SLOT_WEAR_MASK) == src)
|
||||
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -61,6 +61,14 @@
|
||||
name = "Experimental Clone Pod (Machine Board)"
|
||||
build_path = /obj/machinery/clonepod/experimental
|
||||
|
||||
/obj/item/circuitboard/machine/sheetifier
|
||||
name = "Sheet-meister 2000 (Machine Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/sheetifier
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/manipulator = 2,
|
||||
/obj/item/stock_parts/matter_bin = 2)
|
||||
|
||||
/obj/item/circuitboard/machine/abductor
|
||||
name = "alien board (Report This)"
|
||||
icon_state = "abductor_mod"
|
||||
@@ -1102,3 +1110,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)
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
target.clean_blood()
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
target.wash_cream()
|
||||
return
|
||||
@@ -180,4 +181,4 @@
|
||||
name = "Canned Laughter"
|
||||
desc = "Just looking at this makes you want to giggle."
|
||||
icon_state = "laughter"
|
||||
list_reagents = list(/datum/reagent/consumable/laughter = 50)
|
||||
list_reagents = list(/datum/reagent/consumable/laughter = 50)
|
||||
|
||||
@@ -737,12 +737,7 @@
|
||||
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
if(istype(target, /obj/structure/window))
|
||||
var/obj/structure/window/W = target
|
||||
W.spraycan_paint(paint_color)
|
||||
else
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
. = use_charges(user, 2)
|
||||
var/fraction = min(1, . / reagents.maximum_volume)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
var/on = FALSE //if the paddles are equipped (1) or on the defib (0)
|
||||
var/safety = TRUE //if you can zap people with the defibs on harm mode
|
||||
var/powered = FALSE //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
|
||||
var/obj/item/twohanded/shockpaddles/paddles
|
||||
var/obj/item/shockpaddles/paddles
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
var/combat = FALSE //can we revive through space suits?
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
@@ -106,7 +106,6 @@
|
||||
|
||||
/obj/item/defibrillator/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
else if(istype(W, /obj/item/stock_parts/cell))
|
||||
var/obj/item/stock_parts/cell/C = W
|
||||
@@ -170,7 +169,6 @@
|
||||
return
|
||||
else
|
||||
//Remove from their hands and back onto the defib unit
|
||||
paddles.unwield()
|
||||
remove_paddles(user)
|
||||
|
||||
update_power()
|
||||
@@ -179,7 +177,7 @@
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/defibrillator/proc/make_paddles()
|
||||
return new /obj/item/twohanded/shockpaddles(src)
|
||||
return new /obj/item/shockpaddles(src)
|
||||
|
||||
/obj/item/defibrillator/equipped(mob/user, slot)
|
||||
..()
|
||||
@@ -256,13 +254,12 @@
|
||||
|
||||
/obj/item/defibrillator/compact/combat/loaded/attackby(obj/item/W, mob/user, params)
|
||||
if(W == paddles)
|
||||
paddles.unwield()
|
||||
toggle_paddles()
|
||||
return
|
||||
|
||||
//paddles
|
||||
|
||||
/obj/item/twohanded/shockpaddles
|
||||
/obj/item/shockpaddles
|
||||
name = "defibrillator paddles"
|
||||
desc = "A pair of plastic-gripped paddles with flat metal surfaces that are used to deliver powerful electric shocks."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
@@ -284,24 +281,48 @@
|
||||
var/grab_ghost = FALSE
|
||||
var/tlimit = DEFIB_TIME_LIMIT * 10
|
||||
var/disarm_shock_time = 10
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
var/mob/listeningTo
|
||||
/obj/item/shockpaddles/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
if(!req_defib)
|
||||
return //If it doesn't need a defib, just say it exists
|
||||
if (!loc || !istype(loc, /obj/item/defibrillator)) //To avoid weird issues from admin spawns
|
||||
return INITIALIZE_HINT_QDEL
|
||||
defib = loc
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/ComponentInitialize()
|
||||
/obj/item/shockpaddles/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=8, force_wielded=12)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/equipped(mob/user, slot)
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/shockpaddles/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/shockpaddles/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/shockpaddles/Destroy()
|
||||
defib = null
|
||||
return ..()
|
||||
|
||||
/obj/item/shockpaddles/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!req_defib)
|
||||
return
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/check_range)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/Moved()
|
||||
/obj/item/shockpaddles/Moved()
|
||||
. = ..()
|
||||
check_range()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/check_range()
|
||||
/obj/item/shockpaddles/proc/check_range()
|
||||
if(!req_defib || !defib)
|
||||
return
|
||||
if(!in_range(src,defib))
|
||||
@@ -312,7 +333,7 @@
|
||||
visible_message("<span class='notice'>[src] snap back into [defib].</span>")
|
||||
snap_back()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/recharge(var/time)
|
||||
/obj/item/shockpaddles/proc/recharge(var/time)
|
||||
if(req_defib || !time)
|
||||
return
|
||||
cooldown = TRUE
|
||||
@@ -324,57 +345,36 @@
|
||||
cooldown = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/New(mainunit)
|
||||
..()
|
||||
if(check_defib_exists(mainunit, src) && req_defib)
|
||||
defib = mainunit
|
||||
forceMove(defib)
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/update_icon_state()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
|
||||
/obj/item/twohanded/shockpaddles/suicide_act(mob/user)
|
||||
/obj/item/shockpaddles/suicide_act(mob/user)
|
||||
user.visible_message("<span class='danger'>[user] is putting the live paddles on [user.p_their()] chest! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(req_defib)
|
||||
defib.deductcharge(revivecost)
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
return (OXYLOSS)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/dropped(mob/user)
|
||||
/obj/item/shockpaddles/update_icon_state()
|
||||
icon_state = "defibpaddles[wielded]"
|
||||
item_state = "defibpaddles[wielded]"
|
||||
if(cooldown)
|
||||
icon_state = "defibpaddles[wielded]_cooldown"
|
||||
|
||||
/obj/item/shockpaddles/dropped(mob/user)
|
||||
if(!req_defib)
|
||||
return ..()
|
||||
if(user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
var/obj/item/twohanded/offhand/O = user.get_inactive_held_item()
|
||||
if(istype(O))
|
||||
O.unwield()
|
||||
if(user != loc)
|
||||
to_chat(user, "<span class='notice'>The paddles snap back into the main unit.</span>")
|
||||
snap_back()
|
||||
return unwield(user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/snap_back()
|
||||
/obj/item/shockpaddles/proc/snap_back()
|
||||
if(!defib)
|
||||
return
|
||||
defib.on = FALSE
|
||||
forceMove(defib)
|
||||
defib.update_power()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/check_defib_exists(mainunit, mob/living/carbon/M, obj/O)
|
||||
if(!req_defib)
|
||||
return TRUE //If it doesn't need a defib, just say it exists
|
||||
if (!mainunit || !istype(mainunit, /obj/item/defibrillator)) //To avoid weird issues from admin spawns
|
||||
qdel(O)
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/shockpaddles/attack(mob/M, mob/user)
|
||||
/obj/item/shockpaddles/attack(mob/M, mob/user)
|
||||
|
||||
if(busy)
|
||||
return
|
||||
@@ -426,7 +426,7 @@
|
||||
|
||||
do_help(H, user)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
|
||||
/obj/item/shockpaddles/proc/shock_touching(dmg, mob/H)
|
||||
if(!H.pulledby || !isliving(H.pulledby))
|
||||
return
|
||||
if(req_defib && defib.pullshocksafely)
|
||||
@@ -437,7 +437,7 @@
|
||||
M.visible_message("<span class='danger'>[M] is electrocuted by [M.p_their()] contact with [H]!</span>")
|
||||
M.emote("scream")
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
|
||||
if(req_defib && defib.safety)
|
||||
return
|
||||
if(!req_defib && !combat)
|
||||
@@ -465,7 +465,7 @@
|
||||
else
|
||||
recharge(60)
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_harm(mob/living/carbon/H, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_harm(mob/living/carbon/H, mob/living/user)
|
||||
if(req_defib && defib.safety)
|
||||
return
|
||||
if(!req_defib && !combat)
|
||||
@@ -520,7 +520,7 @@
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/proc/do_help(mob/living/carbon/H, mob/living/user)
|
||||
/obj/item/shockpaddles/proc/do_help(mob/living/carbon/H, mob/living/user)
|
||||
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>", "<span class='warning'>You begin to place [src] on [H]'s chest...</span>")
|
||||
busy = TRUE
|
||||
update_icon()
|
||||
@@ -677,14 +677,14 @@
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/cyborg
|
||||
/obj/item/shockpaddles/cyborg
|
||||
name = "cyborg defibrillator paddles"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
req_defib = FALSE
|
||||
|
||||
/obj/item/twohanded/shockpaddles/cyborg/attack(mob/M, mob/user)
|
||||
/obj/item/shockpaddles/cyborg/attack(mob/M, mob/user)
|
||||
if(iscyborg(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.emagged)
|
||||
@@ -696,7 +696,7 @@
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/item/twohanded/shockpaddles/syndicate
|
||||
/obj/item/shockpaddles/syndicate
|
||||
name = "syndicate defibrillator paddles"
|
||||
desc = "A pair of paddles used to revive deceased operatives. It possesses both the ability to penetrate armor and to deliver powerful shocks offensively."
|
||||
combat = TRUE
|
||||
|
||||
@@ -258,6 +258,9 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
name = "\proper mini Integrated Subspace Transceiver "
|
||||
subspace_transmission = FALSE
|
||||
|
||||
/obj/item/radio/headset/silicon/pai/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/item/radio/headset/silicon/ai
|
||||
name = "\proper Integrated Subspace Transceiver "
|
||||
|
||||
@@ -655,9 +655,10 @@ GENETICS SCANNER
|
||||
amount += inaccurate
|
||||
return DisplayTimeText(max(1,amount))
|
||||
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src, visible = TRUE)
|
||||
var/icon = target
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
if(visible)
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Results of analysis of [icon2html(icon, user)] [target].</span>")
|
||||
|
||||
var/list/airs = islist(mixture) ? mixture : list(mixture)
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Double-Bladed Energy Swords - Cheridan
|
||||
*/
|
||||
/obj/item/dualsaber
|
||||
icon_state = "dualsaber0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
name = "double-bladed energy sword"
|
||||
desc = "Handle with care."
|
||||
force = 3
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
var/w_class_on = WEIGHT_CLASS_BULKY
|
||||
hitsound = "swing_hit"
|
||||
var/hitsound_on = 'sound/weapons/blade1.ogg'
|
||||
armour_penetration = 35
|
||||
var/saber_color = "green"
|
||||
light_color = "#00ff00"//green
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
var/hacked = FALSE
|
||||
/// Can this reflect all energy projectiles?
|
||||
var/can_reflect = TRUE
|
||||
var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/list/possible_colors = list("red", "blue", "green", "purple")
|
||||
var/list/rainbow_colors = list(LIGHT_COLOR_RED, LIGHT_COLOR_GREEN, LIGHT_COLOR_LIGHT_CYAN, LIGHT_COLOR_LAVENDER)
|
||||
var/spinnable = TRUE
|
||||
total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces.
|
||||
var/total_mass_on = 3.4
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
var/slowdown_wielded = 0
|
||||
|
||||
/datum/block_parry_data/dual_esword
|
||||
block_damage_absorption = 2
|
||||
block_damage_multiplier = 0.15
|
||||
block_damage_multiplier_override = list(
|
||||
ATTACK_TYPE_MELEE = 0.25
|
||||
)
|
||||
block_start_delay = 0 // instantaneous block
|
||||
block_stamina_cost_per_second = 2.5
|
||||
block_stamina_efficiency = 3
|
||||
block_lock_sprinting = TRUE
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 8
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 4
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while parrying.
|
||||
parry_time_perfect = 2 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 10
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 25 // VERY generous
|
||||
parry_efficiency_perfect = 90
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_MELEE
|
||||
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
)
|
||||
|
||||
/obj/item/dualsaber/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/dualsaber/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=3, force_wielded=34, \
|
||||
wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
|
||||
/obj/item/dualsaber/Initialize()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
saber_color = pick(possible_colors)
|
||||
switch(saber_color)
|
||||
if("red")
|
||||
light_color = LIGHT_COLOR_RED
|
||||
if("green")
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
if("blue")
|
||||
light_color = LIGHT_COLOR_LIGHT_CYAN
|
||||
if("purple")
|
||||
light_color = LIGHT_COLOR_LAVENDER
|
||||
|
||||
/// Triggered on wield of two handed item
|
||||
/// Specific hulk checks due to reflection chance for balance issues and switches hitsounds.
|
||||
/obj/item/dualsaber/proc/on_wield(obj/item/source, mob/living/carbon/user)
|
||||
if(user.has_dna() && user.dna.check_mutation(HULK))
|
||||
to_chat(user, "<span class='warning'>You lack the grace to wield this!</span>")
|
||||
return COMPONENT_TWOHANDED_BLOCK_WIELD
|
||||
wielded = TRUE
|
||||
sharpness = IS_SHARP
|
||||
w_class = w_class_on
|
||||
total_mass = total_mass_on
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
slowdown += slowdown_wielded
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(brightness_on)
|
||||
AddElement(/datum/element/sword_point)
|
||||
item_flags |= (ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
|
||||
/// Triggered on unwield of two handed item
|
||||
/// switch hitsounds
|
||||
/obj/item/dualsaber/proc/on_unwield(obj/item/source, mob/living/carbon/user)
|
||||
sharpness = initial(sharpness)
|
||||
w_class = initial(w_class)
|
||||
total_mass = initial(total_mass)
|
||||
wielded = FALSE
|
||||
hitsound = "swing_hit"
|
||||
slowdown_wielded -= slowdown_wielded
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_light(0)
|
||||
RemoveElement(/datum/element/sword_point)
|
||||
item_flags &= ~(ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
|
||||
/obj/item/dualsaber/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/dualsaber/update_icon_state()
|
||||
if(wielded)
|
||||
icon_state = "dualsaber[saber_color][wielded]"
|
||||
else
|
||||
icon_state = "dualsaber0"
|
||||
clean_blood()
|
||||
|
||||
/obj/item/dualsaber/suicide_act(mob/living/carbon/user)
|
||||
if(wielded)
|
||||
user.visible_message("<span class='suicide'>[user] begins spinning way too fast! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)//stole from chainsaw code
|
||||
var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
B.organ_flags &= ~ORGAN_VITAL //this cant possibly be a good idea
|
||||
var/randdir
|
||||
for(var/i in 1 to 24)//like a headless chicken!
|
||||
if(user.is_holding(src))
|
||||
randdir = pick(GLOB.alldirs)
|
||||
user.Move(get_step(user, randdir),randdir)
|
||||
user.emote("spin")
|
||||
if (i == 3 && myhead)
|
||||
myhead.drop_limb()
|
||||
sleep(3)
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] panics and starts choking to death!</span>")
|
||||
return OXYLOSS
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] begins beating [user.p_them()]self to death with \the [src]'s handle! It probably would've been cooler if [user.p_they()] turned it on first!</span>")
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/dualsaber/attack(mob/target, mob/living/carbon/human/user)
|
||||
if(user.has_dna() && user.dna.check_mutation(HULK))
|
||||
to_chat(user, "<span class='warning'>You grip the blade too hard and accidentally drop it!</span>")
|
||||
user.dropItemToGround(src)
|
||||
return
|
||||
..()
|
||||
if(HAS_TRAIT(user, TRAIT_CLUMSY) && (wielded) && prob(40))
|
||||
impale(user)
|
||||
return
|
||||
if(spinnable && (wielded) && prob(50))
|
||||
INVOKE_ASYNC(src, .proc/jedi_spin, user)
|
||||
|
||||
/obj/item/dualsaber/proc/jedi_spin(mob/living/user)
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
user.setDir(i)
|
||||
if(i == WEST)
|
||||
user.emote("flip")
|
||||
sleep(1)
|
||||
|
||||
/obj/item/dualsaber/proc/impale(mob/living/user)
|
||||
to_chat(user, "<span class='warning'>You twirl around a bit before losing your balance and impaling yourself on [src].</span>")
|
||||
if (force)
|
||||
user.take_bodypart_damage(20,25)
|
||||
else
|
||||
user.adjustStaminaLoss(25)
|
||||
|
||||
/obj/item/dualsaber/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!wielded)
|
||||
return NONE
|
||||
if(can_reflect && is_energy_reflectable_projectile(object) && (attack_type & ATTACK_TYPE_PROJECTILE))
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_RETURN_TO_SENDER //no you
|
||||
return BLOCK_SHOULD_REDIRECT | BLOCK_SUCCESS | BLOCK_REDIRECTED
|
||||
return ..()
|
||||
|
||||
/obj/item/dualsaber/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up
|
||||
if(wielded)
|
||||
to_chat(user, "<span class='warning'>You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!</span>")
|
||||
return 1
|
||||
|
||||
/obj/item/dualsaber/process()
|
||||
if(wielded)
|
||||
if(hacked)
|
||||
rainbow_process()
|
||||
open_flame()
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/dualsaber/proc/rainbow_process()
|
||||
light_color = pick(rainbow_colors)
|
||||
|
||||
/obj/item/dualsaber/ignition_effect(atom/A, mob/user)
|
||||
// same as /obj/item/melee/transforming/energy, mostly
|
||||
if(!wielded)
|
||||
return ""
|
||||
var/in_mouth = ""
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.wear_mask)
|
||||
in_mouth = ", barely missing [user.p_their()] nose"
|
||||
. = "<span class='warning'>[user] swings [user.p_their()] [name][in_mouth]. [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [A.name] in the process.</span>"
|
||||
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
|
||||
add_fingerprint(user)
|
||||
// Light your candles while spinning around the room
|
||||
if(spinnable)
|
||||
INVOKE_ASYNC(src, .proc/jedi_spin, user)
|
||||
|
||||
/obj/item/dualsaber/green
|
||||
possible_colors = list("green")
|
||||
|
||||
/obj/item/dualsaber/red
|
||||
possible_colors = list("red")
|
||||
|
||||
/obj/item/dualsaber/blue
|
||||
possible_colors = list("blue")
|
||||
|
||||
/obj/item/dualsaber/purple
|
||||
possible_colors = list("purple")
|
||||
|
||||
/obj/item/dualsaber/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/multitool))
|
||||
if(!hacked)
|
||||
hacked = TRUE
|
||||
to_chat(user, "<span class='warning'>2XRNBW_ENGAGE</span>")
|
||||
saber_color = "rainbow"
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It's starting to look like a triple rainbow - no, nevermind.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// HYPEREUTACTIC Blades /////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/dualsaber/hypereutactic
|
||||
icon = 'icons/obj/1x2.dmi'
|
||||
icon_state = "hypereutactic"
|
||||
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
|
||||
item_state = "hypereutactic"
|
||||
inhand_x_dimension = 64
|
||||
inhand_y_dimension = 64
|
||||
name = "hypereutactic blade"
|
||||
desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
|
||||
force = 7
|
||||
hitsound_on = 'sound/weapons/nebhit.ogg'
|
||||
armour_penetration = 60
|
||||
light_color = "#37FFF7"
|
||||
rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
|
||||
spinnable = FALSE
|
||||
total_mass_on = 4
|
||||
slowdown_wielded = 1
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=7, force_wielded=40, \
|
||||
wieldsound='sound/weapons/nebon.ogg', unwieldsound='sound/weapons/nebhit.ogg')
|
||||
AddElement(/datum/element/update_icon_updates_onmob)
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/update_overlays()
|
||||
. = ..()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "hypereutactic_blade")
|
||||
var/mutable_appearance/gem_overlay = mutable_appearance(icon, "hypereutactic_gem")
|
||||
|
||||
if(light_color)
|
||||
blade_overlay.color = light_color
|
||||
gem_overlay.color = light_color
|
||||
|
||||
. += gem_overlay
|
||||
|
||||
if(wielded)
|
||||
. += blade_overlay
|
||||
|
||||
clean_blood()
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
|
||||
if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
update_light()
|
||||
return TRUE
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(isinhands)
|
||||
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
|
||||
gem_inhand.color = light_color
|
||||
. += gem_inhand
|
||||
if(wielded)
|
||||
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/examine(mob/user)
|
||||
. = ..()
|
||||
if(!hacked)
|
||||
. += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/rainbow_process()
|
||||
. = ..()
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain
|
||||
name = "divine lightblade"
|
||||
desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
|
||||
force = 5
|
||||
block_chance = 50
|
||||
armour_penetration = 0
|
||||
var/chaplain_spawnable = TRUE
|
||||
can_reflect = FALSE
|
||||
obj_flags = UNIQUE_RENAME
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/chaplain/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=20, \
|
||||
wieldsound='sound/weapons/nebon.ogg', unwieldsound='sound/weapons/nebhit.ogg')
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
@@ -0,0 +1,263 @@
|
||||
|
||||
/obj/item/electrostaff
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "electrostaff"
|
||||
item_state = "electrostaff"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
name = "riot suppression electrostaff"
|
||||
desc = "A large quarterstaff, with massive silver electrodes mounted at the end."
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING
|
||||
throwforce = 15 //if you are a madman and finish someone off with this, power to you.
|
||||
throw_speed = 1
|
||||
item_flags = NO_MAT_REDEMPTION
|
||||
attack_verb = list("struck", "beaten", "thwacked", "pulped")
|
||||
total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on)
|
||||
block_parry_data = /datum/block_parry_data/electrostaff
|
||||
var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high
|
||||
var/on = FALSE
|
||||
var/can_block_projectiles = FALSE //can't block guns
|
||||
var/lethal_cost = 400 //10000/400*20 = 500. decent enough?
|
||||
var/lethal_damage = 20
|
||||
var/lethal_stam_cost = 4
|
||||
var/stun_cost = 333 //10000/333*25 = 750. stunbatons are at time of writing 10000/1000*49 = 490.
|
||||
var/stun_status_effect = STATUS_EFFECT_ELECTROSTAFF //a small slowdown effect
|
||||
var/stun_stamdmg = 40
|
||||
var/stun_status_duration = 25
|
||||
var/stun_stam_cost = 3.5
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
// haha security desword time /s
|
||||
/datum/block_parry_data/electrostaff
|
||||
block_damage_absorption = 0
|
||||
block_damage_multiplier = 1
|
||||
can_block_attack_types = ~ATTACK_TYPE_PROJECTILE // only able to parry non projectiles
|
||||
block_damage_multiplier_override = list(
|
||||
TEXT_ATTACK_TYPE_MELEE = 0.5, // only useful on melee and unarmed
|
||||
TEXT_ATTACK_TYPE_UNARMED = 0.3
|
||||
)
|
||||
block_start_delay = 0.5 // near instantaneous block
|
||||
block_stamina_cost_per_second = 3
|
||||
block_stamina_efficiency = 2 // haha this is a horrible idea
|
||||
// more slowdown that deswords because security
|
||||
block_slowdown = 2
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
|
||||
parry_time_windup = 1
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_spindown_visual_override = 1
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING // no attacking while parrying
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 0.5
|
||||
parry_efficiency_perfect = 100
|
||||
parry_imperfect_falloff_percent = 1
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 45 // really crappy vs projectiles
|
||||
)
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1 // extremely harsh window for projectiles
|
||||
)
|
||||
// not extremely punishing to fail, but no spamming the parry.
|
||||
parry_cooldown = 2.5 SECONDS
|
||||
parry_failed_stagger_duration = 1.5 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
|
||||
/obj/item/electrostaff/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ispath(cell))
|
||||
cell = new cell
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/turn_on)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/turn_off)
|
||||
|
||||
/obj/item/electrostaff/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=2, wieldsound="sparks", unwieldsound="sparks")
|
||||
|
||||
/obj/item/electrostaff/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(cell)
|
||||
return ..()
|
||||
|
||||
/obj/item/electrostaff/get_cell()
|
||||
. = cell
|
||||
if(iscyborg(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
. = R.get_cell()
|
||||
|
||||
/obj/item/electrostaff/proc/min_hitcost()
|
||||
return min(stun_cost, lethal_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/turn_on(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
item_flags |= (ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
if(!cell)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] has no cell.</span>")
|
||||
return
|
||||
if(cell.charge < min_hitcost())
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
|
||||
return
|
||||
on = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You turn [src] on.</span>")
|
||||
|
||||
/obj/item/electrostaff/proc/turn_off(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
item_flags &= ~(ITEM_CAN_BLOCK|ITEM_CAN_PARRY)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You turn [src] off.</span>")
|
||||
on = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/electrostaff/update_icon_state()
|
||||
if(!wielded)
|
||||
icon_state = item_state = "electrostaff"
|
||||
else
|
||||
icon_state = item_state = (on? "electrostaff_1" : "electrostaff_0")
|
||||
set_light(7, on? 1 : 0, LIGHT_COLOR_CYAN)
|
||||
|
||||
/obj/item/electrostaff/examine(mob/living/user)
|
||||
. = ..()
|
||||
if(cell)
|
||||
. += "<span class='notice'>The cell charge is [round(cell.percent())]%.</span>"
|
||||
else
|
||||
. += "<span class='warning'>There is no cell installed!</span>"
|
||||
|
||||
/obj/item/electrostaff/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
var/obj/item/stock_parts/cell/C = W
|
||||
if(cell)
|
||||
to_chat(user, "<span class='warning'>[src] already has a cell!</span>")
|
||||
else
|
||||
if(C.maxcharge < min_hit_cost())
|
||||
to_chat(user, "<span class='notice'>[src] requires a higher capacity cell.</span>")
|
||||
return
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
cell = C
|
||||
to_chat(user, "<span class='notice'>You install a cell in [src].</span>")
|
||||
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(cell)
|
||||
cell.update_icon()
|
||||
cell.forceMove(get_turf(src))
|
||||
cell = null
|
||||
to_chat(user, "<span class='notice'>You remove the cell from [src].</span>")
|
||||
turn_off(user, TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/electrostaff/process()
|
||||
deductcharge(50) //Wasteful!
|
||||
|
||||
/obj/item/electrostaff/proc/min_hit_cost()
|
||||
return min(lethal_cost, stun_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/deductcharge(amount)
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
if(!C)
|
||||
turn_off()
|
||||
return FALSE
|
||||
C.use(min(amount, C.charge))
|
||||
if(QDELETED(src))
|
||||
return FALSE
|
||||
if(C.charge < min_hit_cost())
|
||||
turn_off()
|
||||
|
||||
/obj/item/electrostaff/attack(mob/living/target, mob/living/user)
|
||||
if(IS_STAMCRIT(user))//CIT CHANGE - makes it impossible to baton in stamina softcrit
|
||||
to_chat(user, "<span class='danger'>You're too exhausted to use [src] properly.</span>")//CIT CHANGE - ditto
|
||||
return //CIT CHANGE - ditto
|
||||
if(on && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
||||
clowning_around(user) //ouch!
|
||||
return
|
||||
if(iscyborg(target))
|
||||
return ..()
|
||||
var/list/return_list = list()
|
||||
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; run_block() handles that
|
||||
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
if(stun_act(target, user, null, return_list))
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(stun_stam_cost)
|
||||
return
|
||||
else if(!harm_act(target, user, null, return_list))
|
||||
return ..() //if you can't fry them just beat them with it
|
||||
else //we did harm act them
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(lethal_stam_cost)
|
||||
|
||||
/obj/item/electrostaff/proc/stun_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/stunforce = block_calculate_resultant_damage(stun_stamdmg, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
target.visible_message("<span class='warning'>[user] has bapped [target] with [src]. Luckily it was off.</span>", \
|
||||
"<span class='warning'>[user] has bapped you with [src]. Luckily it was off</span>")
|
||||
turn_off() //if it wasn't already off
|
||||
return FALSE
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
var/chargeleft = C.charge
|
||||
deductcharge(stun_cost)
|
||||
if(QDELETED(src) || QDELETED(C)) //boom
|
||||
return FALSE
|
||||
if(chargeleft < stun_cost)
|
||||
stunforce *= round(chargeleft/stun_cost, 0.1)
|
||||
target.adjustStaminaLoss(stunforce)
|
||||
target.apply_effect(EFFECT_STUTTER, stunforce)
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has shocked [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has shocked you with [src]!</span>")
|
||||
log_combat(user, target, "stunned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/staff.ogg', 50, 1, -1)
|
||||
target.apply_status_effect(stun_status_effect, stun_status_duration)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.forcesay(GLOB.hit_appends)
|
||||
return TRUE
|
||||
|
||||
/obj/item/electrostaff/proc/harm_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/lethal_force = block_calculate_resultant_damage(lethal_damage, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
return FALSE //standard item attack
|
||||
var/obj/item/stock_parts/cell/C = get_cell()
|
||||
var/chargeleft = C.charge
|
||||
deductcharge(lethal_cost)
|
||||
if(QDELETED(src) || QDELETED(C)) //boom
|
||||
return FALSE
|
||||
if(chargeleft < stun_cost)
|
||||
lethal_force *= round(chargeleft/lethal_cost, 0.1)
|
||||
target.adjustFireLoss(lethal_force) //good against ointment spam
|
||||
SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK)
|
||||
if(user)
|
||||
target.lastattacker = user.real_name
|
||||
target.lastattackerckey = user.ckey
|
||||
target.visible_message("<span class='danger'>[user] has seared [target] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has seared you with [src]!</span>")
|
||||
log_combat(user, target, "burned with an electrostaff")
|
||||
playsound(src, 'sound/weapons/sear.ogg', 50, 1, -1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/electrostaff/proc/clowning_around(mob/living/user)
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
harm_act(user, user, TRUE)
|
||||
stun_act(user, user, TRUE)
|
||||
deductcharge(lethal_cost)
|
||||
|
||||
/obj/item/electrostaff/emp_act(severity)
|
||||
. = ..()
|
||||
if (!(. & EMP_PROTECT_SELF))
|
||||
turn_off()
|
||||
if(!iscyborg(loc))
|
||||
deductcharge(1000 / severity, TRUE, FALSE)
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Fireaxe
|
||||
*/
|
||||
/obj/item/fireaxe // DEM AXES MAN, marker -Agouri
|
||||
icon_state = "fireaxe0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/axes_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/axes_righthand.dmi'
|
||||
name = "fire axe"
|
||||
desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?"
|
||||
force = 5
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/fireaxe/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/fireaxe/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 100, 80, 0 , hitsound) //axes are not known for being precision butchering tools
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=24, icon_wielded="fireaxe1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/fireaxe/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/fireaxe/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/fireaxe/update_icon_state()
|
||||
icon_state = "fireaxe0"
|
||||
|
||||
/obj/item/fireaxe/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] axes [user.p_them()]self from head to toe! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/fireaxe/afterattack(atom/A, mob/living/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity || !wielded || IS_STAMCRIT(user))
|
||||
return
|
||||
if(istype(A, /obj/structure/window)) //destroys windows and grilles in one hit (or more if it has a ton of health like plasmaglass)
|
||||
var/obj/structure/window/W = A
|
||||
W.take_damage(200, BRUTE, "melee", 0)
|
||||
else if(istype(A, /obj/structure/grille))
|
||||
var/obj/structure/grille/G = A
|
||||
G.take_damage(40, BRUTE, "melee", 0)
|
||||
|
||||
/*
|
||||
* Bone Axe
|
||||
*/
|
||||
/obj/item/fireaxe/boneaxe // Blatant imitation of the fireaxe, but made out of bone.
|
||||
icon_state = "bone_axe0"
|
||||
name = "bone axe"
|
||||
desc = "A large, vicious axe crafted out of several sharpened bone plates and crudely tied together. Made of monsters, by killing monsters, for killing monsters."
|
||||
|
||||
/obj/item/fireaxe/boneaxe/update_icon_state()
|
||||
icon_state = "bone_axe0"
|
||||
|
||||
/obj/item/fireaxe/boneaxe/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=5, force_wielded=23, icon_wielded="bone_axe1")
|
||||
@@ -510,7 +510,7 @@
|
||||
oneuse = FALSE
|
||||
remarks = list("So that is how icing is made!", "Placing fruit on top? How simple...", "Huh layering cake seems harder then this...", "This book smells like candy", "A clown must have made this page, or they forgot to spell check it before printing...", "Wait, a way to cook slime to be safe?")
|
||||
|
||||
/obj/item/book/granter/crafting_recipe/coldcooking //IceCream
|
||||
/obj/item/book/granter/crafting_recipe/coldcooking //Icecream
|
||||
name = "Cooking with Ice"
|
||||
desc = "A cook book that teaches you many old icecream treats."
|
||||
crafting_recipe_types = list(/datum/crafting_recipe/food/banana_split, /datum/crafting_recipe/food/root_float, /datum/crafting_recipe/food/bluecharrie_float, /datum/crafting_recipe/food/charrie_float)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
to_chat(user, "<span class='notice'>You add [A] to the [initial(name)] assembly.</span>")
|
||||
|
||||
else if(stage == EMPTY && istype(I, /obj/item/stack/cable_coil))
|
||||
if (I.use_tool(src, user, 0, 1, max_level = JOB_SKILL_BASIC))
|
||||
if (I.use_tool(src, user, 0, 1, skill_gain_mult = TRIVIAL_USE_TOOL_MULT))
|
||||
det_time = 50 // In case the cable_coil was removed and readded.
|
||||
stage_change(WIRED)
|
||||
to_chat(user, "<span class='notice'>You rig the [initial(name)] assembly.</span>")
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
icon_state = "witchhunterhat"
|
||||
item_state = "witchhunterhat"
|
||||
flags_cover = HEADCOVERSEYES
|
||||
flags_inv = HIDEHAIR
|
||||
|
||||
/obj/item/storage/box/holy/follower
|
||||
name = "Followers of the Chaplain Kit"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -103,11 +103,30 @@
|
||||
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
|
||||
block_chance = 50
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/energy_sword
|
||||
var/list/possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
|
||||
|
||||
/datum/block_parry_data/energy_sword
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 25
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 12
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while
|
||||
parry_time_perfect = 2.5 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1.5
|
||||
parry_imperfect_falloff_percent = 5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 65 // VERY generous
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 4 SECONDS
|
||||
parry_cooldown = 0.5 SECONDS
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color()
|
||||
@@ -350,7 +369,7 @@
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You combine the two light swords, making a single supermassive blade! You're cool.</span>")
|
||||
new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
|
||||
new /obj/item/dualsaber/hypereutactic(user.drop_location())
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -61,13 +61,25 @@
|
||||
force = 18
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
block_chance = 50
|
||||
armour_penetration = 75
|
||||
sharpness = IS_SHARP
|
||||
attack_verb = list("slashed", "cut")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
custom_materials = list(/datum/material/iron = 1000)
|
||||
total_mass = 3.4
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/captain_saber
|
||||
|
||||
/datum/block_parry_data/captain_saber
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 4
|
||||
parry_time_spindown = 1
|
||||
parry_time_perfect = 0.75
|
||||
parry_time_perfect_leeway = 0.75
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = 2 SECONDS
|
||||
|
||||
/obj/item/melee/sabre/Initialize()
|
||||
. = ..()
|
||||
@@ -150,7 +162,6 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
force = 15
|
||||
throwforce = 25
|
||||
block_chance = 50
|
||||
armour_penetration = 200 //Apparently this gives it the ability to pierce block
|
||||
flags_1 = CONDUCT_1
|
||||
obj_flags = UNIQUE_RENAME
|
||||
@@ -159,16 +170,47 @@
|
||||
attack_verb = list("stabs", "punctures", "pierces", "pokes")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
total_mass = 0.4
|
||||
item_flags = ITEM_CAN_PARRY | NEEDS_PERMIT
|
||||
block_parry_data = /datum/block_parry_data/traitor_rapier
|
||||
|
||||
// Fast, efficient parry.
|
||||
/datum/block_parry_data/traitor_rapier
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 2
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 3
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1
|
||||
)
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 50 // useless after 3rd decisecond
|
||||
)
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 1
|
||||
parry_efficiency_perfect = 100
|
||||
parry_data = list(
|
||||
PARRY_DISARM_ATTACKER = TRUE,
|
||||
PARRY_KNOCKDOWN_ATTACKER = 10
|
||||
)
|
||||
parry_failed_stagger_duration = 2 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_RANGE
|
||||
parry_cooldown = 0
|
||||
|
||||
/obj/item/melee/rapier/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text)
|
||||
. = ..()
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && (parry_efficiency >= 100))
|
||||
. |= BLOCK_SHOULD_REDIRECT
|
||||
return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
||||
|
||||
/obj/item/melee/rapier/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 20, 65, 0)
|
||||
|
||||
/obj/item/melee/rapier/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(attack_type == ATTACK_TYPE_PROJECTILE)
|
||||
final_block_chance = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/rapier/on_exit_storage(datum/component/storage/S)
|
||||
var/obj/item/storage/belt/sabre/rapier/B = S.parent
|
||||
if(istype(B))
|
||||
@@ -191,10 +233,9 @@
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/H = target
|
||||
var/loss = H.getStaminaLoss()
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
if((loss > 40) && prob(loss)) // if above 40, roll for sleep using 1% every 1 stamina damage
|
||||
if(CHECK_STAMCRIT(H) != NOT_STAMCRIT)
|
||||
H.Sleeping(180)
|
||||
|
||||
/obj/item/melee/classic_baton
|
||||
@@ -648,7 +689,7 @@
|
||||
item_state = "mace_greyscale"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS //Material type changes the prefix as well as the color.
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Material type changes the prefix as well as the color.
|
||||
custom_materials = list(/datum/material/iron = 12000) //Defaults to an Iron Mace.
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
force = 14
|
||||
@@ -664,4 +705,4 @@
|
||||
. = ..()
|
||||
overlay = mutable_appearance(icon, overlay_state)
|
||||
overlay.appearance_flags = RESET_COLOR
|
||||
add_overlay(overlay)
|
||||
add_overlay(overlay)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
. = ..()
|
||||
@@ -0,0 +1,101 @@
|
||||
/obj/item/pitchfork
|
||||
icon_state = "pitchfork0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "pitchfork"
|
||||
desc = "A simple tool used for moving hay."
|
||||
force = 7
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("attacked", "impaled", "pierced")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/pitchfork/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/pitchfork/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=7, force_wielded=15, icon_wielded="pitchfork1")
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/pitchfork/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/pitchfork/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/pitchfork/update_icon_state()
|
||||
icon_state = "pitchfork0"
|
||||
|
||||
/obj/item/pitchfork/demonic
|
||||
name = "demonic pitchfork"
|
||||
desc = "A red pitchfork, it looks like the work of the devil."
|
||||
force = 19
|
||||
throwforce = 24
|
||||
|
||||
/obj/item/pitchfork/demonic/Initialize()
|
||||
. = ..()
|
||||
set_light(3,6,LIGHT_COLOR_RED)
|
||||
|
||||
/obj/item/pitchfork/demonic/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=19, force_wielded=25)
|
||||
|
||||
/obj/item/pitchfork/demonic/greater
|
||||
force = 24
|
||||
throwforce = 50
|
||||
|
||||
/obj/item/pitchfork/demonic/greater/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=24, force_wielded=34)
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended
|
||||
force = 100
|
||||
throwforce = 100
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=100, force_wielded=500000) // Kills you DEAD
|
||||
|
||||
/obj/item/pitchfork/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] impales [user.p_them()]self in [user.p_their()] abdomen with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/pitchfork/demonic/pickup(mob/living/user)
|
||||
. = ..()
|
||||
if(isliving(user) && user.mind && user.owns_soul() && !is_devil(user))
|
||||
var/mob/living/U = user
|
||||
U.visible_message("<span class='warning'>As [U] picks [src] up, [U]'s arms briefly catch fire.</span>", \
|
||||
"<span class='warning'>\"As you pick up [src] your arms ignite, reminding you of all your past sins.\"</span>")
|
||||
if(ishuman(U))
|
||||
var/mob/living/carbon/human/H = U
|
||||
H.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
else
|
||||
U.adjustFireLoss(rand(force/2,force))
|
||||
|
||||
/obj/item/pitchfork/demonic/attack(mob/target, mob/living/carbon/human/user)
|
||||
if(user.mind && user.owns_soul() && !is_devil(user))
|
||||
to_chat(user, "<span class='warning'>[src] burns in your hands.</span>")
|
||||
user.apply_damage(rand(force/2, force), BURN, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
..()
|
||||
|
||||
/obj/item/pitchfork/demonic/ascended/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity || !wielded)
|
||||
return
|
||||
if(iswallturf(target))
|
||||
var/turf/closed/wall/W = target
|
||||
user.visible_message("<span class='danger'>[user] blasts \the [target] with \the [src]!</span>")
|
||||
playsound(target, 'sound/magic/disintegrate.ogg', 100, TRUE)
|
||||
W.break_wall()
|
||||
W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
|
||||
return
|
||||
@@ -140,7 +140,8 @@
|
||||
if(jsonlist["icon_state"])
|
||||
icon_state = jsonlist["icon_state"]
|
||||
item_state = jsonlist["item_state"]
|
||||
icon = 'config/plushies/sprites.dmi'
|
||||
var/static/config_sprites = file("config/plushies/sprites.dmi")
|
||||
icon = config_sprites
|
||||
if(jsonlist["attack_verb"])
|
||||
attack_verb = jsonlist["attack_verb"]
|
||||
if(jsonlist["squeak_override"])
|
||||
|
||||
@@ -355,9 +355,11 @@
|
||||
emaggedhitdamage = 0
|
||||
|
||||
/obj/item/borg/lollipop/equipped()
|
||||
. = ..()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/dropped(mob/user)
|
||||
. = ..()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/proc/check_amount() //Doesn't even use processing ticks.
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
/obj/item/borg/upgrade/defib/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
var/obj/item/twohanded/shockpaddles/cyborg/S = locate() in R.module
|
||||
var/obj/item/shockpaddles/cyborg/S = locate() in R.module
|
||||
R.module.remove_module(S, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/processor
|
||||
@@ -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()
|
||||
|
||||
@@ -24,24 +24,22 @@
|
||||
if(istype(I, /obj/item/melee/transforming/energy))
|
||||
to_chat(user, "<span class='warning'>You don't think \the [I] will be the thing getting modified if you use it on \the [src]!</span>")
|
||||
return
|
||||
if(istype(I, /obj/item/twohanded))//some twohanded items should still be sharpenable, but handle force differently. therefore i need this stuff
|
||||
var/obj/item/twohanded/TH = I
|
||||
if(TH.force_wielded >= max)
|
||||
to_chat(user, "<span class='warning'>[TH] is much too powerful to sharpen further!</span>")
|
||||
return
|
||||
if(TH.wielded)
|
||||
to_chat(user, "<span class='warning'>[TH] must be unwielded before it can be sharpened!</span>")
|
||||
return
|
||||
if(TH.force_wielded > initial(TH.force_wielded))
|
||||
to_chat(user, "<span class='warning'>[TH] has already been refined before. It cannot be sharpened further!</span>")
|
||||
return
|
||||
TH.force_wielded = clamp(TH.force_wielded + increment, 0, max)//wieldforce is increased since normal force wont stay
|
||||
if(I.force > initial(I.force))
|
||||
|
||||
var/signal_out = SEND_SIGNAL(I, COMSIG_ITEM_SHARPEN_ACT, increment, max)
|
||||
if(signal_out & COMPONENT_BLOCK_SHARPEN_MAXED)
|
||||
to_chat(user, "<span class='warning'>[I] is much too powerful to sharpen further!</span>")
|
||||
return
|
||||
if(signal_out & COMPONENT_BLOCK_SHARPEN_BLOCKED)
|
||||
to_chat(user, "<span class='warning'>[I] is not able to be sharpened right now!</span>")
|
||||
return
|
||||
if((signal_out & COMPONENT_BLOCK_SHARPEN_ALREADY) || (I.force > initial(I.force) && !signal_out))
|
||||
to_chat(user, "<span class='warning'>[I] has already been refined before. It cannot be sharpened further!</span>")
|
||||
return
|
||||
if(!(signal_out & COMPONENT_BLOCK_SHARPEN_APPLIED))
|
||||
I.force = clamp(I.force + increment, 0, max)
|
||||
|
||||
user.visible_message("<span class='notice'>[user] sharpens [I] with [src]!</span>", "<span class='notice'>You sharpen [I], making it much more deadly than before.</span>")
|
||||
I.sharpness = IS_SHARP_ACCURATE
|
||||
I.force = clamp(I.force + increment, 0, max)
|
||||
I.throwforce = clamp(I.throwforce + increment, 0, max)
|
||||
I.name = "[prefix] [I.name]"
|
||||
name = "worn out [name]"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/obj/item/shield
|
||||
name = "shield"
|
||||
icon = 'icons/obj/shields.dmi'
|
||||
block_chance = 50
|
||||
item_flags = ITEM_CAN_BLOCK
|
||||
block_parry_data = /datum/block_parry_data/shield
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
|
||||
/// Shield flags
|
||||
var/shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
@@ -22,6 +23,18 @@
|
||||
/// Shield bashing push distance
|
||||
var/shieldbash_push_distance = 1
|
||||
|
||||
/datum/block_parry_data/shield
|
||||
block_damage_multiplier = 0.25
|
||||
block_stamina_efficiency = 2.5
|
||||
block_stamina_cost_per_second = 2.5
|
||||
block_slowdown = 0
|
||||
block_lock_attacking = FALSE
|
||||
block_lock_sprinting = TRUE
|
||||
block_start_delay = 1.5
|
||||
block_damage_absorption = 5
|
||||
block_resting_stamina_penalty_multiplier = 2
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
/obj/item/shield/examine(mob/user)
|
||||
. = ..()
|
||||
if(shield_flags & SHIELD_CAN_BASH)
|
||||
@@ -154,6 +167,22 @@
|
||||
icon_state = "shield_bash"
|
||||
duration = 3
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
|
||||
/obj/item/shield/on_active_block(mob/living/owner, atom/object, damage, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance)
|
||||
|
||||
/obj/item/shield/riot
|
||||
name = "riot shield"
|
||||
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
|
||||
@@ -172,20 +201,7 @@
|
||||
var/repair_material = /obj/item/stack/sheet/mineral/titanium
|
||||
var/can_shatter = TRUE
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
|
||||
max_integrity = 75
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
max_integrity = 450
|
||||
|
||||
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/melee/baton))
|
||||
@@ -238,13 +254,13 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55 //Weak
|
||||
max_integrity = 300
|
||||
|
||||
obj/item/shield/riot/bullet_proof
|
||||
name = "bullet resistant shield"
|
||||
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
max_integrity = 55 //Weaker
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/roman
|
||||
name = "\improper Roman shield"
|
||||
@@ -255,13 +271,13 @@ obj/item/shield/riot/bullet_proof
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 65
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/roman/fake
|
||||
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
||||
block_chance = 0
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
max_integrity = 30
|
||||
max_integrity = 40
|
||||
|
||||
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/grillehit.ogg', 100)
|
||||
@@ -279,7 +295,7 @@ obj/item/shield/riot/bullet_proof
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
block_chance = 30
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55
|
||||
max_integrity = 150
|
||||
|
||||
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/bang.ogg', 50)
|
||||
@@ -297,13 +313,16 @@ obj/item/shield/riot/bullet_proof
|
||||
throw_speed = 3
|
||||
throw_range = 4
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/active = 0
|
||||
var/active = FALSE
|
||||
|
||||
/obj/item/shield/riot/tele/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!active)
|
||||
return BLOCK_NONE
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/tele/can_active_block()
|
||||
return ..() && active
|
||||
|
||||
/obj/item/shield/riot/tele/attack_self(mob/living/user)
|
||||
active = !active
|
||||
icon_state = "teleriot[active]"
|
||||
@@ -335,8 +354,7 @@ obj/item/shield/riot/bullet_proof
|
||||
icon_state = "makeshift_shield"
|
||||
custom_materials = list(/datum/material/iron = 18000)
|
||||
slot_flags = null
|
||||
block_chance = 35
|
||||
max_integrity = 100 //Made of metal welded together its strong but not unkillable
|
||||
max_integrity = 300 //Made of metal welded together its strong but not unkillable
|
||||
force = 10
|
||||
throwforce = 7
|
||||
|
||||
@@ -346,7 +364,6 @@ obj/item/shield/riot/bullet_proof
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 75 //1/4 shots will hit*
|
||||
force = 16
|
||||
slowdown = 2
|
||||
throwforce = 15 //Massive pice of metal
|
||||
@@ -357,21 +374,19 @@ obj/item/shield/riot/bullet_proof
|
||||
/obj/item/shield/riot/tower/swat
|
||||
name = "swat shield"
|
||||
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
|
||||
max_integrity = 175
|
||||
block_chance = 50
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/implant
|
||||
name = "telescoping shield implant"
|
||||
desc = "A compact, arm-mounted telescopic shield. While nigh-indestructible when powered by a host user, it will eventually overload from damage. Recharges while inside its implant."
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 50
|
||||
slowdown = 1
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 60
|
||||
obj_integrity = 60
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
can_shatter = FALSE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
item_flags = SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
var/recharge_timerid
|
||||
var/recharge_delay = 15 SECONDS
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/item/twohanded/singularityhammer
|
||||
/obj/item/singularityhammer
|
||||
name = "singularity hammer"
|
||||
desc = "The pinnacle of close combat technology, the hammer harnesses the power of a miniaturized singularity to deal crushing blows."
|
||||
icon_state = "mjollnir0"
|
||||
@@ -7,35 +7,47 @@
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
force = 5
|
||||
force_unwielded = 5
|
||||
force_wielded = 20
|
||||
throwforce = 15
|
||||
throw_range = 1
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/charged = 5
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
force_string = "LORD SINGULOTH HIMSELF"
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
var/charged = 5
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/twohanded/singularityhammer/New()
|
||||
/obj/item/singularityhammer/New()
|
||||
..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/twohanded/singularityhammer/Destroy()
|
||||
/obj/item/singularityhammer/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=4, icon_wielded="mjollnir1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/singularityhammer/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/singularityhammer/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/singularityhammer/update_icon_state()
|
||||
icon_state = "mjollnir0"
|
||||
|
||||
/obj/item/singularityhammer/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/singularityhammer/process()
|
||||
/obj/item/singularityhammer/process()
|
||||
if(charged < 5)
|
||||
charged++
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/update_icon_state() //Currently only here to fuck with the on-mob icons.
|
||||
icon_state = "mjollnir[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/proc/vortex(turf/pull, mob/wielder)
|
||||
/obj/item/singularityhammer/proc/vortex(turf/pull, mob/wielder)
|
||||
for(var/atom/X in orange(5,pull))
|
||||
if(ismovable(X))
|
||||
var/atom/movable/A = X
|
||||
@@ -55,9 +67,8 @@
|
||||
step_towards(H,pull)
|
||||
step_towards(H,pull)
|
||||
step_towards(H,pull)
|
||||
return
|
||||
|
||||
/obj/item/twohanded/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
/obj/item/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
@@ -71,7 +82,7 @@
|
||||
var/turf/target = get_turf(A)
|
||||
vortex(target,user)
|
||||
|
||||
/obj/item/twohanded/mjollnir
|
||||
/obj/item/mjollnir
|
||||
name = "Mjolnir"
|
||||
desc = "A weapon worthy of a god, able to strike with the force of a lightning bolt. It crackles with barely contained energy."
|
||||
icon_state = "mjollnir0"
|
||||
@@ -80,14 +91,33 @@
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
force = 5
|
||||
force_unwielded = 5
|
||||
force_wielded = 25
|
||||
throwforce = 30
|
||||
throw_range = 7
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/twohanded/mjollnir/proc/shock(mob/living/target)
|
||||
/obj/item/mjollnir/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/mjollnir/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=5, icon_wielded="mjollnir1", attacksound="sparks")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/mjollnir/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/mjollnir/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/mjollnir/update_icon_state()
|
||||
icon_state = "mjollnir0"
|
||||
|
||||
/obj/item/mjollnir/proc/shock(mob/living/target)
|
||||
target.Stun(60)
|
||||
var/datum/effect_system/lightning_spread/s = new /datum/effect_system/lightning_spread
|
||||
s.set_up(5, 1, target.loc)
|
||||
@@ -99,17 +129,12 @@
|
||||
target.throw_at(throw_target, 200, 4)
|
||||
return
|
||||
|
||||
/obj/item/twohanded/mjollnir/attack(mob/living/M, mob/user)
|
||||
/obj/item/mjollnir/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
if(wielded)
|
||||
playsound(src.loc, "sparks", 50, 1)
|
||||
shock(M)
|
||||
|
||||
/obj/item/twohanded/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
/obj/item/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
. = ..()
|
||||
if(isliving(hit_atom))
|
||||
shock(hit_atom)
|
||||
|
||||
/obj/item/twohanded/mjollnir/update_icon_state() //Currently only here to fuck with the on-mob icons.
|
||||
icon_state = "mjollnir[wielded]"
|
||||
return
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
//spears
|
||||
/obj/item/spear
|
||||
icon_state = "spearglass0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "spear"
|
||||
desc = "A haphazardly-constructed yet still deadly weapon of ancient design."
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
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'
|
||||
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
|
||||
sharpness = IS_SHARP
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
|
||||
var/obj/item/grenade/explosive = null
|
||||
var/war_cry = "AAAAARGH!!!"
|
||||
var/icon_prefix = "spearglass"
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/spear/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/spear/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 100, 70) //decent in a pinch, but pretty bad.
|
||||
AddComponent(/datum/component/jousting)
|
||||
AddElement(/datum/element/sword_point)
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=10, force_wielded=18, icon_wielded="[icon_prefix]1")
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/spear/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/spear/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/spear/rightclick_attack_self(mob/user)
|
||||
if(explosive)
|
||||
explosive.attack_self(user)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/spear/update_icon_state()
|
||||
icon_state = "[icon_prefix]0"
|
||||
|
||||
/obj/item/spear/update_overlays()
|
||||
. = ..()
|
||||
if(explosive)
|
||||
. += "spearbomb_overlay"
|
||||
|
||||
/obj/item/spear/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins to sword-swallow \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
if(explosive) //Citadel Edit removes qdel and explosive.forcemove(AM)
|
||||
user.say("[war_cry]", forced="spear warcry")
|
||||
explosive.prime()
|
||||
user.gib()
|
||||
return BRUTELOSS
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/spear/examine(mob/user)
|
||||
. = ..()
|
||||
if(explosive)
|
||||
. += "<span class='notice'>Alt-click to set your war cry.</span>"
|
||||
. += "<span class='notice'>Right-click in combat mode to activate the attached explosive.</span>"
|
||||
|
||||
/obj/item/spear/afterattack(atom/movable/AM, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
if(isopenturf(AM)) //So you can actually melee with it
|
||||
return
|
||||
if(explosive && wielded) //Citadel edit removes qdel and explosive.forcemove(AM)
|
||||
user.say("[war_cry]", forced="spear warcry")
|
||||
explosive.prime()
|
||||
|
||||
/obj/item/spear/grenade_prime_react(obj/item/grenade/nade) //Citadel edit, removes throw_impact because memes
|
||||
nade.forceMove(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spear/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.canUseTopic(src, BE_CLOSE))
|
||||
..()
|
||||
if(!explosive)
|
||||
return
|
||||
if(istype(user) && loc == user)
|
||||
var/input = stripped_input(user,"What do you want your war cry to be? You will shout it when you hit someone in melee.", ,"", 50)
|
||||
if(input)
|
||||
src.war_cry = input
|
||||
return TRUE
|
||||
|
||||
/obj/item/spear/CheckParts(list/parts_list)
|
||||
var/obj/item/shard/tip = locate() in parts_list
|
||||
if (istype(tip, /obj/item/shard/plasma))
|
||||
throwforce = 21
|
||||
embedding = list(embed_chance = 75, pain_mult = 1.5) //plasmaglass spears are sharper
|
||||
updateEmbedding()
|
||||
icon_prefix = "spearplasma"
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=11, force_wielded=19, icon_wielded="[icon_prefix]1")
|
||||
qdel(tip)
|
||||
var/obj/item/spear/S = locate() in parts_list
|
||||
if(S)
|
||||
if(S.explosive)
|
||||
S.explosive.forceMove(get_turf(src))
|
||||
S.explosive = null
|
||||
parts_list -= S
|
||||
qdel(S)
|
||||
..()
|
||||
var/obj/item/grenade/G = locate() in contents
|
||||
if(G)
|
||||
explosive = G
|
||||
name = "explosive lance"
|
||||
embedding = list(embed_chance = 0, pain_mult = 1)//elances should not be embeddable
|
||||
updateEmbedding()
|
||||
desc = "A makeshift spear with \a [G] attached to it."
|
||||
update_icon()
|
||||
|
||||
//GREY TIDE
|
||||
/obj/item/spear/grey_tide
|
||||
icon_state = "spearglass0"
|
||||
name = "\improper Grey Tide"
|
||||
desc = "Recovered from the aftermath of a revolt aboard Defense Outpost Theta Aegis, in which a seemingly endless tide of Assistants caused heavy casualities among Nanotrasen military forces."
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
attack_verb = list("gored")
|
||||
var/clonechance = 50
|
||||
var/clonedamage = 12
|
||||
var/clonespeed = 0
|
||||
var/clone_replication_chance = 30
|
||||
var/clone_lifespan = 100
|
||||
|
||||
/obj/item/spear/grey_tide/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=15, force_wielded=25, icon_wielded="[icon_prefix]1")
|
||||
|
||||
/obj/item/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
user.faction |= "greytide([REF(user)])"
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(istype (L, /mob/living/simple_animal/hostile/illusion))
|
||||
return
|
||||
if(!L.stat && prob(clonechance))
|
||||
var/mob/living/simple_animal/hostile/illusion/M = new(user.loc)
|
||||
M.faction = user.faction.Copy()
|
||||
M.set_varspeed(clonespeed)
|
||||
M.Copy_Parent(user, clone_lifespan, user.health/2.5, clonedamage, clone_replication_chance)
|
||||
M.GiveTarget(L)
|
||||
|
||||
/*
|
||||
* Bone Spear
|
||||
*/
|
||||
/obj/item/spear/bonespear //Blatant imitation of spear, but made out of bone. Not valid for explosive modification.
|
||||
icon_state = "bone_spear0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/polearms_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/polearms_righthand.dmi'
|
||||
name = "bone spear"
|
||||
desc = "A haphazardly-constructed yet still deadly weapon. The pinnacle of modern technology."
|
||||
force = 11
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
reach = 2
|
||||
throwforce = 22
|
||||
embedding = list("embedded_impact_pain_multiplier" = 3)
|
||||
armour_penetration = 15 //Enhanced armor piercing
|
||||
custom_materials = null
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "poked", "jabbed", "torn", "gored")
|
||||
sharpness = IS_SHARP
|
||||
icon_prefix = "bone_spear"
|
||||
|
||||
/obj/item/spear/bonespear/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=11, force_wielded=20, icon_wielded="[icon_prefix]1")
|
||||
@@ -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
|
||||
. = ..()
|
||||
|
||||
@@ -17,10 +17,10 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
custom_materials = list(/datum/material/iron=1000)
|
||||
mats_per_stack = 1000
|
||||
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)
|
||||
|
||||
@@ -69,7 +69,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
if (get_amount() < 1 || CC.get_amount() < 5)
|
||||
to_chat(user, "<span class='warning>You need five lengths of coil and one sheet of glass to make wired glass!</span>")
|
||||
return
|
||||
CC.use_tool(src, user, 0, 5, max_level = JOB_SKILL_BASIC)
|
||||
CC.use_tool(src, user, 0, 5, skill_gain_mult = TRIVIAL_USE_TOOL_MULT)
|
||||
use(1)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
var/obj/item/stack/light_w/new_tile = new(user.loc)
|
||||
@@ -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)
|
||||
|
||||
@@ -39,9 +39,11 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
|
||||
item_state = "sheet-sandstone"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT)
|
||||
custom_materials = list(/datum/material/sandstone=MINERAL_MATERIAL_AMOUNT)
|
||||
sheettype = "sandstone"
|
||||
merge_type = /obj/item/stack/sheet/mineral/sandstone
|
||||
walltype = /turf/closed/wall/mineral/sandstone
|
||||
material_type = /datum/material/sandstone
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -107,6 +109,7 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
point_value = 25
|
||||
merge_type = /obj/item/stack/sheet/mineral/diamond
|
||||
material_type = /datum/material/diamond
|
||||
walltype = /turf/closed/wall/mineral/diamond
|
||||
|
||||
GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -135,6 +138,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/uranium
|
||||
material_type = /datum/material/uranium
|
||||
walltype = /turf/closed/wall/mineral/uranium
|
||||
|
||||
GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -163,6 +167,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/plasma
|
||||
material_type = /datum/material/plasma
|
||||
walltype = /turf/closed/wall/mineral/plasma
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] begins licking \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -205,6 +210,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/gold
|
||||
material_type = /datum/material/gold
|
||||
walltype = /turf/closed/wall/mineral/gold
|
||||
|
||||
GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -236,6 +242,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
merge_type = /obj/item/stack/sheet/mineral/silver
|
||||
material_type = /datum/material/silver
|
||||
tableVariant = /obj/structure/table/optable
|
||||
walltype = /turf/closed/wall/mineral/silver
|
||||
|
||||
GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -266,6 +273,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
point_value = 50
|
||||
merge_type = /obj/item/stack/sheet/mineral/bananium
|
||||
material_type = /datum/material/bananium
|
||||
walltype = /turf/closed/wall/mineral/bananium
|
||||
|
||||
GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
@@ -294,6 +302,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
point_value = 20
|
||||
merge_type = /obj/item/stack/sheet/mineral/titanium
|
||||
material_type = /datum/material/titanium
|
||||
walltype = /turf/closed/wall/mineral/titanium
|
||||
|
||||
GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
|
||||
@@ -324,6 +333,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 45
|
||||
merge_type = /obj/item/stack/sheet/mineral/plastitanium
|
||||
walltype = /turf/closed/wall/mineral/plastitanium
|
||||
|
||||
/obj/item/stack/sheet/mineral/plastitanium/fifty
|
||||
amount = 50
|
||||
@@ -390,11 +400,14 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
name = "snow"
|
||||
icon_state = "sheet-snow"
|
||||
item_state = "sheet-snow"
|
||||
custom_materials = list(/datum/material/snow = MINERAL_MATERIAL_AMOUNT)
|
||||
singular_name = "snow block"
|
||||
force = 1
|
||||
throwforce = 2
|
||||
grind_results = list(/datum/reagent/consumable/ice = 20)
|
||||
merge_type = /obj/item/stack/sheet/mineral/snow
|
||||
walltype = /turf/closed/wall/mineral/snow
|
||||
material_type = /datum/material/snow
|
||||
|
||||
GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -417,6 +430,7 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
singular_name = "alien alloy sheet"
|
||||
sheettype = "abductor"
|
||||
merge_type = /obj/item/stack/sheet/mineral/abductor
|
||||
walltype = /turf/closed/wall/mineral/abductor
|
||||
|
||||
GLOBAL_LIST_INIT(abductor_recipes, list ( \
|
||||
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
|
||||
|
||||
@@ -205,7 +205,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
|
||||
desc = "This sheet is an alloy of iron and plasma."
|
||||
icon_state = "sheet-plasteel"
|
||||
item_state = "sheet-metal"
|
||||
custom_materials = list(/datum/material/iron=2000, /datum/material/plasma=2000)
|
||||
custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 10
|
||||
flags_1 = CONDUCT_1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
|
||||
@@ -240,8 +240,8 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
new /datum/stack_recipe("pew (right)", /obj/structure/chair/pew/right, 3, one_per_turf = TRUE, on_floor = TRUE),\
|
||||
)),
|
||||
null, \
|
||||
new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 40), \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
|
||||
new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 20), \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 20), \
|
||||
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \
|
||||
@@ -288,6 +288,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
novariants = TRUE
|
||||
material_type = /datum/material/wood
|
||||
grind_results = list(/datum/reagent/carbon = 20)
|
||||
walltype = /turf/closed/wall/mineral/wood
|
||||
|
||||
/obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there.
|
||||
// Taken from /obj/item/stack/rods/attackby in [rods.dm]
|
||||
@@ -343,11 +344,13 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \
|
||||
icon_state = "sheet-bamboo"
|
||||
item_state = "sheet-bamboo"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/bamboo = MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 15
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0)
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/mineral/bamboo
|
||||
grind_results = list(/datum/reagent/carbon = 5)
|
||||
material_type = /datum/material/bamboo
|
||||
|
||||
/obj/item/stack/sheet/mineral/bamboo/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -378,6 +381,7 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \
|
||||
new/datum/stack_recipe("chemistry bag", /obj/item/storage/bag/chemistry, 4), \
|
||||
new/datum/stack_recipe("bio bag", /obj/item/storage/bag/bio, 4), \
|
||||
null, \
|
||||
new/datum/stack_recipe("string", /obj/item/weaponcrafting/string, 1, time = 10), \
|
||||
new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 6), \
|
||||
new/datum/stack_recipe("rag", /obj/item/reagent_containers/rag, 1), \
|
||||
new/datum/stack_recipe("towel", /obj/item/reagent_containers/rag/towel, 3), \
|
||||
@@ -425,7 +429,6 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \
|
||||
new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \
|
||||
new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \
|
||||
new/datum/stack_recipe("durathread bandana", /obj/item/clothing/mask/bandana/durathread, 1, time = 25), \
|
||||
new/datum/stack_recipe("durathread string", /obj/item/weaponcrafting/durathread_string, 1, time = 40), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/durathread
|
||||
@@ -512,12 +515,14 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
|
||||
desc = "Large sheets of card, like boxes folded flat."
|
||||
singular_name = "cardboard sheet"
|
||||
icon_state = "sheet-card"
|
||||
custom_materials = list(/datum/material/cardboard = MINERAL_MATERIAL_AMOUNT)
|
||||
item_state = "sheet-card"
|
||||
resistance_flags = FLAMMABLE
|
||||
force = 0
|
||||
throwforce = 0
|
||||
merge_type = /obj/item/stack/sheet/cardboard
|
||||
novariants = TRUE
|
||||
material_type = /datum/material/cardboard
|
||||
|
||||
/obj/item/stack/sheet/cardboard/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -557,10 +562,12 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
icon_state = "sheet-runed"
|
||||
item_state = "sheet-runed"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/runedmetal = MINERAL_MATERIAL_AMOUNT)
|
||||
sheettype = "runed"
|
||||
merge_type = /obj/item/stack/sheet/runed_metal
|
||||
novariants = TRUE
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/blood = 15)
|
||||
material_type = /datum/material/runedmetal
|
||||
|
||||
/obj/item/stack/sheet/runed_metal/ratvar_act()
|
||||
new /obj/item/stack/tile/brass(loc, amount)
|
||||
@@ -679,6 +686,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
icon_state = "sheet-brass"
|
||||
item_state = "sheet-brass"
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
custom_materials = list(/datum/material/bronze = MINERAL_MATERIAL_AMOUNT)
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
throwforce = 10
|
||||
max_amount = 50
|
||||
@@ -689,6 +697,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
grind_results = list(/datum/reagent/iron = 5, /datum/reagent/copper = 3) //we have no "tin" reagent so this is the closest thing
|
||||
merge_type = /obj/item/stack/tile/bronze
|
||||
tableVariant = /obj/structure/table/bronze
|
||||
material_type = /datum/material/bronze
|
||||
|
||||
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
|
||||
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
|
||||
@@ -736,6 +745,7 @@ GLOBAL_LIST_INIT(bone_recipes, list(
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bone"
|
||||
item_state = "sheet-bone"
|
||||
custom_materials = list(/datum/material/bone = MINERAL_MATERIAL_AMOUNT)
|
||||
singular_name = "bone"
|
||||
desc = "Someone's been drinking their milk."
|
||||
force = 7
|
||||
@@ -746,6 +756,7 @@ GLOBAL_LIST_INIT(bone_recipes, list(
|
||||
throw_range = 3
|
||||
grind_results = list(/datum/reagent/carbon = 10)
|
||||
merge_type = /obj/item/stack/sheet/bone
|
||||
material_type = /datum/material/bone
|
||||
|
||||
/obj/item/stack/sheet/bone/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -773,11 +784,15 @@ GLOBAL_LIST_INIT(plastic_recipes, list(
|
||||
custom_materials = list(/datum/material/plastic=MINERAL_MATERIAL_AMOUNT)
|
||||
throwforce = 7
|
||||
grind_results = list(/datum/reagent/glitter/white = 60)
|
||||
material_type = /datum/material/plastic
|
||||
merge_type = /obj/item/stack/sheet/plastic
|
||||
|
||||
/obj/item/stack/sheet/plastic/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/sheet/plastic/twenty
|
||||
amount = 20
|
||||
|
||||
/obj/item/stack/sheet/plastic/five
|
||||
amount = 5
|
||||
|
||||
@@ -795,9 +810,11 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
singular_name = "paper frame"
|
||||
icon_state = "sheet-paper"
|
||||
item_state = "sheet-paper"
|
||||
custom_materials = list(/datum/material/paper = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/paperframes
|
||||
resistance_flags = FLAMMABLE
|
||||
merge_type = /obj/item/stack/sheet/paperframes
|
||||
material_type = /datum/material/paper
|
||||
|
||||
/obj/item/stack/sheet/paperframes/get_main_recipes()
|
||||
. = ..()
|
||||
@@ -838,3 +855,55 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra
|
||||
merge_type = /obj/item/stack/sheet/cotton/durathread
|
||||
pull_effort = 70
|
||||
loom_result = /obj/item/stack/sheet/durathread
|
||||
|
||||
/obj/item/stack/sheet/meat
|
||||
name = "meat sheets"
|
||||
desc = "Something's bloody meat compressed into a nice solid sheet"
|
||||
singular_name = "meat sheet"
|
||||
icon_state = "sheet-meat"
|
||||
material_flags = MATERIAL_COLOR
|
||||
custom_materials = list(/datum/material/meat = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/meat
|
||||
material_type = /datum/material/meat
|
||||
material_modifier = 1 //None of that wussy stuff
|
||||
|
||||
/obj/item/stack/sheet/meat/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/meat/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/meat/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/sheet/pizza
|
||||
name = "pepperoni sheetzzas"
|
||||
desc = "It's a delicious pepperoni sheetzza!"
|
||||
singular_name = "pepperoni sheetzza"
|
||||
icon_state = "sheet-pizza"
|
||||
custom_materials = list(/datum/material/pizza = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/pizza
|
||||
material_type = /datum/material/pizza
|
||||
material_modifier = 1
|
||||
|
||||
/obj/item/stack/sheet/pizza/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/pizza/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/pizza/five
|
||||
amount = 5
|
||||
|
||||
/obj/item/stack/sheet/sandblock
|
||||
name = "blocks of sand"
|
||||
desc = "You're too old to be playing with sandcastles. Now you build... sandstations."
|
||||
singular_name = "block of sand"
|
||||
icon_state = "sheet-sandstone"
|
||||
custom_materials = list(/datum/material/sand = MINERAL_MATERIAL_AMOUNT)
|
||||
merge_type = /obj/item/stack/sheet/sandblock
|
||||
material_type = /datum/material/sand
|
||||
material_modifier = 1
|
||||
|
||||
/obj/item/stack/sheet/sandblock/fifty
|
||||
amount = 50
|
||||
/obj/item/stack/sheet/sandblock/twenty
|
||||
amount = 20
|
||||
/obj/item/stack/sheet/sandblock/five
|
||||
amount = 5
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
throw_range = 3
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
|
||||
novariants = FALSE
|
||||
mats_per_stack = MINERAL_MATERIAL_AMOUNT
|
||||
var/sheettype = null //this is used for girders in the creation of walls/false walls
|
||||
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity
|
||||
var/shard_type // the shard debris typepath left over by solar panels and windows etc.
|
||||
///this is used for girders in the creation of walls/false walls
|
||||
var/sheettype = null
|
||||
///turn-in value for the gulag stacker - loosely relative to its rarity
|
||||
var/point_value = 0
|
||||
/// the shard debris typepath left over by solar panels and windows etc.
|
||||
var/shard_type
|
||||
///What type of wall does this sheet spawn
|
||||
var/walltype
|
||||
|
||||
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge)
|
||||
. = ..()
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
|
||||
var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
|
||||
var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
|
||||
var/mats_per_stack = 0
|
||||
var/list/mats_per_unit //list that tells you how much is in a single unit.
|
||||
///Datum material type that this stack is made of
|
||||
var/material_type
|
||||
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
|
||||
@@ -47,8 +47,11 @@
|
||||
if(!merge_type)
|
||||
merge_type = type
|
||||
if(custom_materials && custom_materials.len)
|
||||
mats_per_unit = list()
|
||||
var/in_process_mat_list = custom_materials.Copy()
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[SSmaterials.GetMaterialRef(i)] = mats_per_stack * amount
|
||||
mats_per_unit[SSmaterials.GetMaterialRef(i)] = in_process_mat_list[i]
|
||||
custom_materials[i] *= amount
|
||||
. = ..()
|
||||
if(merge)
|
||||
for(var/obj/item/stack/S in loc)
|
||||
@@ -60,7 +63,7 @@
|
||||
var/datum/material/M = SSmaterials.GetMaterialRef(material_type) //First/main material
|
||||
for(var/i in M.categories)
|
||||
switch(i)
|
||||
if(MAT_CATEGORY_RIGID)
|
||||
if(MAT_CATEGORY_BASE_RECIPES)
|
||||
var/list/temp = SSmaterials.rigid_stack_recipes.Copy()
|
||||
recipes += temp
|
||||
update_weight()
|
||||
@@ -315,10 +318,13 @@
|
||||
if (amount < used)
|
||||
return FALSE
|
||||
amount -= used
|
||||
if(check)
|
||||
zero_amount()
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[i] = amount * mats_per_stack
|
||||
if(check && zero_amount())
|
||||
return TRUE
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_icon()
|
||||
update_weight()
|
||||
return TRUE
|
||||
@@ -350,10 +356,11 @@
|
||||
source.add_charge(amount * cost)
|
||||
else
|
||||
src.amount += amount
|
||||
if(custom_materials && custom_materials.len)
|
||||
for(var/i in custom_materials)
|
||||
custom_materials[SSmaterials.GetMaterialRef(i)] = MINERAL_MATERIAL_AMOUNT * src.amount
|
||||
set_custom_materials() //Refresh
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_icon()
|
||||
update_weight()
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -9,16 +9,35 @@
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
max_amount = 60
|
||||
mats_per_stack = 500
|
||||
var/turf_type = null
|
||||
var/mineralType = null
|
||||
novariants = TRUE
|
||||
var/human_maxHealth = 100
|
||||
|
||||
/obj/item/stack/tile/Initialize(mapload, amount)
|
||||
. = ..()
|
||||
pixel_x = rand(-3, 3)
|
||||
pixel_y = rand(-3, 3) //randomize a little
|
||||
|
||||
/obj/item/stack/tile/examine(mob/user)
|
||||
. = ..()
|
||||
if(throwforce && !is_cyborg) //do not want to divide by zero or show the message to borgs who can't throw
|
||||
var/verb
|
||||
switch(CEILING(human_maxHealth / throwforce, 1)) //throws to crit a human
|
||||
if(1 to 3)
|
||||
verb = "superb"
|
||||
if(4 to 6)
|
||||
verb = "great"
|
||||
if(7 to 9)
|
||||
verb = "good"
|
||||
if(10 to 12)
|
||||
verb = "fairly decent"
|
||||
if(13 to 15)
|
||||
verb = "mediocre"
|
||||
if(!verb)
|
||||
return
|
||||
. += "<span class='notice'>Those could work as a [verb] throwing weapon.</span>"
|
||||
|
||||
/obj/item/stack/tile/attackby(obj/item/W, mob/user, params)
|
||||
|
||||
if (istype(W, /obj/item/weldingtool))
|
||||
@@ -266,6 +285,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 +297,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 +309,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 +321,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 +333,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 +345,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 +357,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 +369,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 +381,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 +393,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
|
||||
|
||||
@@ -440,7 +489,7 @@
|
||||
/obj/item/stack/tile/plasteel
|
||||
name = "floor tile"
|
||||
singular_name = "floor tile"
|
||||
desc = "Those could work as a pretty decent throwing weapon."
|
||||
desc = "The ground you walk on."
|
||||
icon_state = "tile"
|
||||
force = 6
|
||||
custom_materials = list(/datum/material/iron=500)
|
||||
@@ -452,7 +501,15 @@
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
/obj/item/stack/tile/plasteel/cyborg
|
||||
desc = "The ground you walk on." //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR
|
||||
custom_materials = null // All other Borg versions of items have no Metal or Glass - RR
|
||||
is_cyborg = 1
|
||||
cost = 125
|
||||
|
||||
/obj/item/stack/tile/material
|
||||
name = "floor tile"
|
||||
singular_name = "floor tile"
|
||||
desc = "The ground you walk on."
|
||||
throwforce = 10
|
||||
icon_state = "material_tile"
|
||||
turf_type = /turf/open/floor/material
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
|
||||
@@ -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)
|
||||
@@ -444,4 +444,22 @@
|
||||
STR.max_combined_w_class = 30
|
||||
STR.max_items = 3
|
||||
STR.display_numerical_stacking = FALSE
|
||||
STR.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing))
|
||||
STR.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing))
|
||||
|
||||
/obj/item/storage/bag/material
|
||||
name = "material pouch"
|
||||
desc = "A pouch for sheets and RCD ammunition that manages to hang where you would normally put things in your pocket."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "materialpouch"
|
||||
slot_flags = ITEM_SLOT_POCKET
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/storage/bag/material/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_NORMAL
|
||||
STR.max_combined_w_class = INFINITY
|
||||
STR.max_items = 2
|
||||
STR.display_numerical_stacking = TRUE
|
||||
STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet))
|
||||
@@ -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)
|
||||
@@ -585,7 +586,7 @@
|
||||
/obj/item/key/janitor,
|
||||
/obj/item/clothing/gloves,
|
||||
/obj/item/melee/flyswatter,
|
||||
/obj/item/twohanded/broom,
|
||||
/obj/item/broom,
|
||||
/obj/item/paint/paint_remover,
|
||||
/obj/item/assembly/mousetrap,
|
||||
/obj/item/screwdriver,
|
||||
|
||||
@@ -173,12 +173,12 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
|
||||
var/unholy2clean = A.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.del_reagent(/datum/reagent/fuel/unholywater)
|
||||
A.reagents.add_reagent(/datum/reagent/water/holywater,unholy2clean)
|
||||
if(istype(A, /obj/item/twohanded/required/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
|
||||
if(istype(A, /obj/item/cult_bastard) || istype(A, /obj/item/melee/cultblade) && !iscultist(user))
|
||||
to_chat(user, "<span class='notice'>You begin to exorcise [A].</span>")
|
||||
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1)
|
||||
if(do_after(user, 40, target = A))
|
||||
playsound(src,'sound/effects/pray_chaplain.ogg',60,1)
|
||||
if(istype(A, /obj/item/twohanded/required/cult_bastard))
|
||||
if(istype(A, /obj/item/cult_bastard))
|
||||
for(var/obj/item/soulstone/SS in A.contents)
|
||||
SS.usability = TRUE
|
||||
for(var/mob/living/simple_animal/shade/EX in SS)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -106,10 +106,10 @@
|
||||
/obj/item/storage/briefcase/medical
|
||||
name = "medical briefcase"
|
||||
icon_state = "medbriefcase"
|
||||
desc = "A white with a blue cross brieface, this is ment to hold medical gear that would not be able to normally fit in a bag."
|
||||
desc = "A white with a blue cross brieface, this is meant to hold medical gear that would not be able to normally fit in a bag."
|
||||
|
||||
/obj/item/storage/briefcase/medical/PopulateContents()
|
||||
new /obj/item/clothing/neck/stethoscope(src)
|
||||
new /obj/item/healthanalyzer(src)
|
||||
..() //In case of paperwork
|
||||
..() //Incase of paperwork
|
||||
|
||||
|
||||
@@ -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)))
|
||||
@@ -189,18 +207,18 @@
|
||||
cig_position++
|
||||
|
||||
/obj/item/storage/fancy/cigarettes/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!ismob(M))
|
||||
return
|
||||
if(M != user || !istype(M))
|
||||
return ..()
|
||||
var/obj/item/clothing/mask/cigarette/cig = locate(/obj/item/clothing/mask/cigarette) in contents
|
||||
if(cig)
|
||||
if(M == user && contents.len > 0 && !user.wear_mask)
|
||||
if(!user.wear_mask && !(SLOT_WEAR_MASK in M.check_obscured_slots()))
|
||||
var/obj/item/clothing/mask/cigarette/W = cig
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_TAKE, W, M)
|
||||
M.equip_to_slot_if_possible(W, SLOT_WEAR_MASK)
|
||||
contents -= W
|
||||
to_chat(user, "<span class='notice'>You take \a [W] out of the pack.</span>")
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no [icon_type]s left in the pack.</span>")
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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"
|
||||
@@ -370,6 +370,14 @@
|
||||
for(var/i in 1 to 7)
|
||||
new /obj/item/reagent_containers/pill/breast_enlargement(src)
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine
|
||||
name = "bottle of neurine pills"
|
||||
desc = "Contains pills to treat non-severe mental traumas."
|
||||
|
||||
/obj/item/storage/pill_bottle/neurine/PopulateContents()
|
||||
for(var/i in 1 to 5)
|
||||
new /obj/item/reagent_containers/pill/neurine(src)
|
||||
|
||||
/////////////
|
||||
//Organ Box//
|
||||
/////////////
|
||||
@@ -418,7 +426,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
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -25,7 +25,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
|
||||
icon_state = "toolbox_default"
|
||||
item_state = "toolbox_default"
|
||||
can_rubberify = FALSE
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
|
||||
/obj/item/storage/toolbox/Initialize(mapload)
|
||||
if(has_latches)
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
new /obj/item/pizzabox/bomb
|
||||
|
||||
if("darklord") //20 tc + tk + summon item close enough for now
|
||||
new /obj/item/twohanded/dualsaber(src)
|
||||
new /obj/item/dualsaber(src)
|
||||
new /obj/item/dnainjector/telemut/darkbundle(src)
|
||||
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
|
||||
new /obj/item/card/id/syndicate(src)
|
||||
|
||||
@@ -170,10 +170,12 @@
|
||||
return disarming || (user.a_intent != INTENT_HARM)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
var/list/return_list = list()
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
var/stunpwr = stamforce
|
||||
stunpwr = block_calculate_resultant_damage(stunpwr, return_list)
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
if(!our_cell)
|
||||
switch_status(FALSE)
|
||||
|
||||
@@ -153,6 +153,10 @@
|
||||
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/tank/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
atmosanalyzer_scan(air_contents, O, src, FALSE)
|
||||
|
||||
/obj/item/tank/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(W, /obj/item/assembly_holder))
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/obj/item/hatchet/saw
|
||||
name = "handsaw"
|
||||
desc = "A very sharp handsaw, it's compact."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "saw"
|
||||
item_state = "sawhandle_greyscale"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
|
||||
tool_behaviour = TOOL_SAW
|
||||
force = 10
|
||||
throwforce = 8
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
custom_materials = list(/datum/material/iron = 5000)
|
||||
attack_verb = list("sawed", "sliced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP
|
||||
var/random_color = TRUE //code taken from screwdrivers.dm; cool handles are cool.
|
||||
var/static/list/saw_colors = list(
|
||||
"blue" = rgb(24, 97, 213),
|
||||
"red" = rgb(255, 0, 0),
|
||||
"pink" = rgb(213, 24, 141),
|
||||
"brown" = rgb(160, 82, 18),
|
||||
"green" = rgb(14, 127, 27),
|
||||
"cyan" = rgb(24, 162, 213),
|
||||
"yellow" = rgb(255, 165, 0)
|
||||
)
|
||||
|
||||
/obj/item/hatchet/saw/Initialize()
|
||||
. = ..()
|
||||
if(random_color)
|
||||
icon_state = "sawhandle_greyscale"
|
||||
var/our_color = pick(saw_colors)
|
||||
add_atom_colour(saw_colors[our_color], FIXED_COLOUR_PRIORITY)
|
||||
update_icon()
|
||||
if(prob(75))
|
||||
pixel_y = rand(-8, 8)
|
||||
|
||||
/obj/item/hatchet/saw/update_overlays()
|
||||
. = ..()
|
||||
if(!random_color) //icon override
|
||||
return
|
||||
var/mutable_appearance/base_overlay = mutable_appearance(icon, "sawblade")
|
||||
base_overlay.appearance_flags = RESET_COLOR
|
||||
. += base_overlay
|
||||
|
||||
// END
|
||||
@@ -272,7 +272,7 @@
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You attach the ends of the two plastic swords, making a single double-bladed toy! You're fake-cool.</span>")
|
||||
var/obj/item/twohanded/dualsaber/toy/newSaber = new /obj/item/twohanded/dualsaber/toy(user.loc)
|
||||
var/obj/item/dualsaber/toy/newSaber = new /obj/item/dualsaber/toy(user.loc)
|
||||
if(hacked) // That's right, we'll only check the "original" "sword".
|
||||
newSaber.hacked = TRUE
|
||||
qdel(W)
|
||||
@@ -363,7 +363,7 @@
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You combine the two plastic swords, making a single supermassive toy! You're fake-cool.</span>")
|
||||
new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
|
||||
new /obj/item/dualsaber/hypereutactic/toy(user.loc)
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
else
|
||||
@@ -437,40 +437,44 @@
|
||||
/*
|
||||
* Subtype of Double-Bladed Energy Swords
|
||||
*/
|
||||
/obj/item/twohanded/dualsaber/toy
|
||||
/obj/item/dualsaber/toy
|
||||
name = "double-bladed toy sword"
|
||||
desc = "A cheap, plastic replica of TWO energy swords. Double the fun!"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
force_unwielded = 0
|
||||
force_wielded = 0
|
||||
block_parry_data = null
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
sharpness = IS_BLUNT
|
||||
|
||||
/obj/item/twohanded/dualsaber/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/dualsaber/toy/ComponentInitialize()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
|
||||
/obj/item/dualsaber/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
return BLOCK_NONE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy
|
||||
/obj/item/dualsaber/hypereutactic/toy
|
||||
name = "\improper DX Hyper-Euplastic LightSword"
|
||||
desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
|
||||
force = 0
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
force_unwielded = 0
|
||||
force_wielded = 0
|
||||
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
slowdown_wielded = 0
|
||||
sharpness = IS_BLUNT
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/dualsaber/hypereutactic/toy/ComponentInitialize()
|
||||
AddComponent(/datum/component/two_handed, force_unwielded=0, force_wielded=0, wieldsound='sound/weapons/saberon.ogg', unwieldsound='sound/weapons/saberoff.ogg')
|
||||
|
||||
/obj/item/dualsaber/hypereutactic/toy/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
return BLOCK_NONE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
|
||||
/obj/item/dualsaber/hypereutactic/toy/rainbow
|
||||
name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
|
||||
desc = "A custom-built toy with fancy rainbow lights built-in."
|
||||
hacked = TRUE
|
||||
@@ -822,12 +826,11 @@
|
||||
var/obj/item/toy/cards/singlecard/H = new/obj/item/toy/cards/singlecard(user.loc)
|
||||
if(holo)
|
||||
holo.spawned += H // track them leaving the holodeck
|
||||
choice = cards[1]
|
||||
choice = popleft(cards)
|
||||
H.cardname = choice
|
||||
H.parentdeck = src
|
||||
var/O = src
|
||||
H.apply_card_vars(H,O)
|
||||
src.cards -= choice
|
||||
H.pickup(user)
|
||||
user.put_in_hands(H)
|
||||
user.visible_message("[user] draws a card from the deck.", "<span class='notice'>You draw a card from the deck.</span>")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -122,11 +122,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
|
||||
/obj/item/claymore/highlander/pickup(mob/living/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>The power of Scotland protects you! You are shielded from all stuns and knockdowns.</span>")
|
||||
user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!")
|
||||
user.ignore_slowdown(HIGHLANDER)
|
||||
|
||||
/obj/item/claymore/highlander/dropped(mob/living/user)
|
||||
. = ..()
|
||||
user.unignore_slowdown(HIGHLANDER)
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //If this ever happens, it's because you lost an arm
|
||||
@@ -261,7 +263,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/wirerod/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/shard))
|
||||
var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear
|
||||
var/obj/item/spear/S = new /obj/item/spear
|
||||
|
||||
remove_item_from_storage(user)
|
||||
if (!user.transferItemToLoc(I, S))
|
||||
@@ -297,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"
|
||||
@@ -457,7 +475,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/mounted_chainsaw/Destroy()
|
||||
var/obj/item/bodypart/part
|
||||
new /obj/item/twohanded/required/chainsaw(get_turf(src))
|
||||
new /obj/item/chainsaw(get_turf(src))
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/holder = loc
|
||||
var/index = holder.get_held_index_of_item(src)
|
||||
@@ -741,3 +759,59 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
to_chat(user, "<span class='warning'>[M] is too close to use [src] on.</span>")
|
||||
return
|
||||
M.attack_hand(user)
|
||||
|
||||
//HF blade
|
||||
|
||||
/obj/item/vibro_weapon
|
||||
icon_state = "hfrequency0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
name = "vibro sword"
|
||||
desc = "A potent weapon capable of cutting through nearly anything. Wielding it in two hands will allow you to deflect gunfire."
|
||||
armour_penetration = 100
|
||||
block_chance = 40
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
sharpness = IS_SHARP
|
||||
attack_verb = list("cut", "sliced", "diced")
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
|
||||
/obj/item/vibro_weapon/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_WIELD, .proc/on_wield)
|
||||
RegisterSignal(src, COMSIG_TWOHANDED_UNWIELD, .proc/on_unwield)
|
||||
|
||||
/obj/item/vibro_weapon/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 20, 105)
|
||||
AddComponent(/datum/component/two_handed, force_multiplier=2, icon_wielded="hfrequency1")
|
||||
AddElement(/datum/element/sword_point)
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/vibro_weapon/proc/on_wield(obj/item/source, mob/user)
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/vibro_weapon/proc/on_unwield(obj/item/source, mob/user)
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/vibro_weapon/update_icon_state()
|
||||
icon_state = "hfrequency0"
|
||||
|
||||
/obj/item/vibro_weapon/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(wielded)
|
||||
final_block_chance *= 2
|
||||
if(wielded || !(attack_type & ATTACK_TYPE_PROJECTILE))
|
||||
if(prob(final_block_chance))
|
||||
if(attack_type & ATTACK_TYPE_PROJECTILE)
|
||||
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
|
||||
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
|
||||
block_return[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
||||
return BLOCK_SUCCESS | BLOCK_REDIRECTED | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL
|
||||
else
|
||||
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
|
||||
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return NONE
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -102,6 +103,8 @@
|
||||
take_damage(400, BRUTE, "melee", 0, get_dir(src, B))
|
||||
|
||||
/obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) //used by attack_alien, attack_animal, and attack_slime
|
||||
if(SEND_SIGNAL(src, COMSIG_OBJ_ATTACK_GENERIC, user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) & COMPONENT_STOP_GENERIC_ATTACK)
|
||||
return FALSE
|
||||
user.do_attack_animation(src)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return take_damage(damage_amount, damage_type, damage_flag, sound_effect, get_dir(src, user), armor_penetration)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
///Material chair
|
||||
/obj/structure/chair/greyscale
|
||||
icon_state = "chair_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
item_chair = /obj/item/chair/greyscale
|
||||
buildstacktype = null //Custom mats handle this
|
||||
|
||||
@@ -384,7 +384,7 @@
|
||||
/obj/item/chair/greyscale
|
||||
icon_state = "chair_greyscale_toppled"
|
||||
item_state = "chair_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
origin_type = /obj/structure/chair/greyscale
|
||||
|
||||
/obj/item/chair/stool
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -273,8 +273,8 @@
|
||||
icon_state = "tac"
|
||||
/obj/structure/closet/secure_closet/lethalshots/PopulateContents()
|
||||
..()
|
||||
new /obj/item/twohanded/electrostaff(src)
|
||||
new /obj/item/twohanded/electrostaff(src)
|
||||
new /obj/item/electrostaff(src)
|
||||
new /obj/item/electrostaff(src)
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/storage/box/lethalshot(src)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
integrity_failure = 0.33
|
||||
var/locked = TRUE
|
||||
var/open = FALSE
|
||||
var/obj/item/twohanded/fireaxe/fireaxe
|
||||
var/obj/item/fireaxe/fireaxe
|
||||
|
||||
/obj/structure/fireaxecabinet/Initialize()
|
||||
. = ..()
|
||||
@@ -50,8 +50,8 @@
|
||||
obj_integrity = max_integrity
|
||||
update_icon()
|
||||
else if(open || broken)
|
||||
if(istype(I, /obj/item/twohanded/fireaxe) && !fireaxe)
|
||||
var/obj/item/twohanded/fireaxe/F = I
|
||||
if(istype(I, /obj/item/fireaxe) && !fireaxe)
|
||||
var/obj/item/fireaxe/F = I
|
||||
if(F.wielded)
|
||||
to_chat(user, "<span class='warning'>Unwield the [F.name] first.</span>")
|
||||
return
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
icon_state = "fullgrass_[rand(1, 3)]"
|
||||
. = ..()
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants
|
||||
/obj/item/kirbyplants
|
||||
name = "potted plant"
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "plant-01"
|
||||
@@ -300,24 +300,25 @@
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/Initialize()
|
||||
/obj/item/kirbyplants/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/tactical)
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 500)), 0)
|
||||
AddComponent(/datum/component/two_handed, require_twohands=TRUE, force_unwielded=10, force_wielded=10)
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random
|
||||
/obj/item/kirbyplants/random
|
||||
icon = 'icons/obj/flora/_flora.dmi'
|
||||
icon_state = "random_plant"
|
||||
var/list/static/states
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random/Initialize()
|
||||
/obj/item/kirbyplants/random/Initialize()
|
||||
. = ..()
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
if(!states)
|
||||
generate_states()
|
||||
icon_state = pick(states)
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random/proc/generate_states()
|
||||
/obj/item/kirbyplants/random/proc/generate_states()
|
||||
states = list()
|
||||
for(var/i in 1 to 25)
|
||||
var/number
|
||||
@@ -329,12 +330,12 @@
|
||||
states += "applebush"
|
||||
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/dead
|
||||
/obj/item/kirbyplants/dead
|
||||
name = "RD's potted plant"
|
||||
desc = "A gift from the botanical staff, presented after the RD's reassignment. There's a tag on it that says \"Y'all come back now, y'hear?\"\nIt doesn't look very healthy..."
|
||||
icon_state = "plant-25"
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/photosynthetic
|
||||
/obj/item/kirbyplants/photosynthetic
|
||||
name = "photosynthetic potted plant"
|
||||
desc = "A bioluminescent plant."
|
||||
icon_state = "plant-09"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(S.sheettype && S.sheettype != "runed")
|
||||
if(S.sheettype != "runed")
|
||||
var/M = S.sheettype
|
||||
if(state == GIRDER_DISPLACED)
|
||||
var/F = text2path("/obj/structure/falsewall/[M]")
|
||||
@@ -188,9 +188,13 @@
|
||||
transfer_fingerprints_to(FW)
|
||||
qdel(src)
|
||||
else
|
||||
var/F = text2path("/turf/closed/wall/mineral/[M]")
|
||||
var/list/material_list
|
||||
var/F = S.walltype
|
||||
if(!F)
|
||||
return
|
||||
F = /turf/closed/wall/material
|
||||
if(S.material_type)
|
||||
material_list = list()
|
||||
material_list[SSmaterials.GetMaterialRef(S.material_type)] = MINERAL_MATERIAL_AMOUNT * 2
|
||||
if(S.get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two sheets to add plating!</span>")
|
||||
return
|
||||
@@ -201,7 +205,9 @@
|
||||
S.use(2)
|
||||
to_chat(user, "<span class='notice'>You add the plating.</span>")
|
||||
var/turf/T = get_turf(src)
|
||||
T.PlaceOnTop(F)
|
||||
var/turf/newturf = T.PlaceOnTop(F)
|
||||
if(material_list)
|
||||
newturf.set_custom_materials(material_list)
|
||||
transfer_fingerprints_to(T)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
var/bonespear = FALSE
|
||||
var/obj/item/twohanded/spear/spear
|
||||
var/obj/item/spear/spear
|
||||
var/obj/item/bodypart/head/victim
|
||||
|
||||
/obj/structure/headpike/bone //for bone spears
|
||||
@@ -20,9 +20,9 @@
|
||||
name = "[victim.name] on a spear"
|
||||
update_icon()
|
||||
if(bonespear)
|
||||
spear = locate(/obj/item/twohanded/bonespear) in parts_list
|
||||
spear = locate(/obj/item/spear/bonespear) in parts_list
|
||||
else
|
||||
spear = locate(/obj/item/twohanded/spear) in parts_list
|
||||
spear = locate(/obj/item/spear) in parts_list
|
||||
|
||||
/obj/structure/headpike/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
//copypaste sorry
|
||||
var/obj/item/storage/bag/trash/mybag
|
||||
var/obj/item/mop/mymop
|
||||
var/obj/item/twohanded/broom/mybroom
|
||||
var/obj/item/broom/mybroom
|
||||
var/obj/item/reagent_containers/spray/cleaner/myspray
|
||||
var/obj/item/lightreplacer/myreplacer
|
||||
var/signs = 0
|
||||
@@ -48,9 +48,9 @@
|
||||
m.janicart_insert(user, src)
|
||||
else
|
||||
to_chat(user, fail_msg)
|
||||
else if(istype(I, /obj/item/twohanded/broom))
|
||||
else if(istype(I, /obj/item/broom))
|
||||
if(!mybroom)
|
||||
var/obj/item/twohanded/broom/b=I
|
||||
var/obj/item/broom/b=I
|
||||
b.janicart_insert(user,src)
|
||||
else
|
||||
to_chat(user, fail_msg)
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
icon_state = "human_male"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
max_integrity = 200
|
||||
var/timer = 240 //eventually the person will be freed
|
||||
var/timer = 8 MINUTES //eventually the person will be freed
|
||||
var/mob/living/petrified_mob
|
||||
|
||||
/obj/structure/statue/petrified/New(loc, mob/living/L, statue_timer)
|
||||
/obj/structure/statue/petrified/Initialize(mapload, mob/living/L, statue_timer)
|
||||
. = ..()
|
||||
if(statue_timer)
|
||||
timer = statue_timer
|
||||
if(L)
|
||||
@@ -17,25 +19,18 @@
|
||||
L.buckled.unbuckle_mob(L,force=1)
|
||||
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
|
||||
L.forceMove(src)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
|
||||
L.status_flags |= GODMODE
|
||||
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
|
||||
max_integrity = obj_integrity
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/statue/petrified/process()
|
||||
if(!petrified_mob)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
timer--
|
||||
petrified_mob.Stun(40) //So they can't do anything while petrified
|
||||
if(timer <= 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/statue/petrified/contents_explosion(severity, target)
|
||||
return
|
||||
QDEL_IN(src, timer)
|
||||
|
||||
/obj/structure/statue/petrified/handle_atom_del(atom/A)
|
||||
if(A == petrified_mob)
|
||||
@@ -59,7 +54,13 @@
|
||||
if(petrified_mob)
|
||||
petrified_mob.status_flags &= ~GODMODE
|
||||
petrified_mob.forceMove(loc)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
|
||||
petrified_mob.faction -= "mimic"
|
||||
petrified_mob = null
|
||||
|
||||
@@ -134,6 +134,8 @@
|
||||
if(!ishuman(pushed_mob))
|
||||
return
|
||||
var/mob/living/carbon/human/H = pushed_mob
|
||||
if(iscatperson(H))
|
||||
H.emote("nya")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
|
||||
|
||||
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
|
||||
@@ -218,7 +220,7 @@
|
||||
/obj/structure/table/greyscale
|
||||
icon = 'icons/obj/smooth_structures/table_greyscale.dmi'
|
||||
icon_state = "table"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS | MATERIAL_EFFECTS
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
|
||||
buildstack = null //No buildstack, so generate from mat datums
|
||||
|
||||
///Table on wheels
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -157,7 +157,6 @@
|
||||
secret_type = /obj/effect/spawner/lootdrop/prison_loot_toilet
|
||||
|
||||
/obj/structure/toilet/greyscale
|
||||
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
|
||||
buildstacktype = null
|
||||
|
||||
@@ -582,6 +581,12 @@
|
||||
G.use(1)
|
||||
return
|
||||
|
||||
if(istype(O, /obj/item/stack/ore/glass))
|
||||
new /obj/item/stack/sheet/sandblock(loc)
|
||||
to_chat(user, "<span class='notice'>You wet the sand in the sink and form it into a block.</span>")
|
||||
O.use(1)
|
||||
return
|
||||
|
||||
if(!istype(O))
|
||||
return
|
||||
if(O.item_flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand.
|
||||
@@ -673,7 +678,7 @@
|
||||
if(steps == 4 && istype(S, /obj/item/stack/sheet/mineral/wood))
|
||||
if(S.use(3))
|
||||
steps = 5
|
||||
desc = "A dug out well, A dug out well with out rope. Just add some cloth!"
|
||||
desc = "A dug out well, A dug out well without rope. Just add some cloth!"
|
||||
icon_state = "well_4"
|
||||
return TRUE
|
||||
else
|
||||
@@ -702,11 +707,6 @@
|
||||
icon_state = "puddle"
|
||||
resistance_flags = UNACIDABLE
|
||||
|
||||
/obj/structure/sink/greyscale
|
||||
icon_state = "sink_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
|
||||
buildstacktype = null
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/structure/sink/puddle/attack_hand(mob/M)
|
||||
icon_state = "puddle-splash"
|
||||
@@ -722,6 +722,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/sink/greyscale
|
||||
icon_state = "sink_greyscale"
|
||||
material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
|
||||
buildstacktype = null
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -269,29 +271,27 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
air_update_turf(TRUE)
|
||||
update_nearby_icons()
|
||||
|
||||
/obj/structure/window/proc/spraycan_paint(paint_color)
|
||||
if(color_hex2num(paint_color) < 255)
|
||||
set_opacity(255)
|
||||
else
|
||||
set_opacity(initial(opacity))
|
||||
add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_dim()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_DIMMED)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_DIMMED
|
||||
animate(src, color = "#222222", time = 2)
|
||||
set_opacity(TRUE)
|
||||
var/current = color
|
||||
add_atom_colour("#222222", FIXED_COLOUR_PRIORITY)
|
||||
var/newcolor = color
|
||||
if(color != current)
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
|
||||
/obj/structure/window/proc/electrochromatic_off()
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_OFF)
|
||||
return
|
||||
electrochromatic_status = ELECTROCHROMATIC_OFF
|
||||
var/current = color
|
||||
update_atom_colour()
|
||||
remove_atom_colour(FIXED_COLOUR_PRIORITY, "#222222")
|
||||
var/newcolor = color
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
if(color != current)
|
||||
color = current
|
||||
animate(src, color = newcolor, time = 2)
|
||||
|
||||
/obj/structure/window/proc/remove_electrochromatic()
|
||||
electrochromatic_off()
|
||||
@@ -346,11 +346,9 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
GLOB.electrochromatic_window_lookup[electrochromatic_id] |= src
|
||||
|
||||
/obj/structure/window/update_atom_colour()
|
||||
if((electrochromatic_status != ELECTROCHROMATIC_OFF) && (electrochromatic_status != ELECTROCHROMATIC_DIMMED))
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(color && (color_hex2num(color) < 255))
|
||||
set_opacity(255)
|
||||
if(electrochromatic_status == ELECTROCHROMATIC_DIMMED || (color && (color_hex2num(color) < 255)))
|
||||
set_opacity(TRUE)
|
||||
else
|
||||
set_opacity(FALSE)
|
||||
|
||||
@@ -525,6 +523,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 +689,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)
|
||||
|
||||
Reference in New Issue
Block a user