Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit490
This commit is contained in:
@@ -224,6 +224,8 @@ GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list(
|
||||
|
||||
#define isorgan(A) (istype(A, /obj/item/organ))
|
||||
|
||||
#define isclothing(A) (istype(A, /obj/item/clothing))
|
||||
|
||||
GLOBAL_LIST_INIT(pointed_types, typecacheof(list(
|
||||
/obj/item/pen,
|
||||
/obj/item/screwdriver,
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
#define MARTIALART_MUSHPUNCH "mushroom punch"
|
||||
#define MARTIALART_KRAVMAGA "krav maga"
|
||||
#define MARTIALART_CQC "CQC"
|
||||
#define MARTIALART_PLASMAFIST "plasma fist"
|
||||
#define MARTIALART_PLASMAFIST "plasma fist"
|
||||
#define MARTIALART_RISINGBASS "rising bass"
|
||||
@@ -41,6 +41,7 @@
|
||||
#define VOICEBOX_TOGGLABLE (1<<6) //The voicebox in this clothing can be toggled.
|
||||
#define VOICEBOX_DISABLED (1<<7) //The voicebox is currently turned off.
|
||||
#define IGNORE_HAT_TOSS (1<<8) //Hats with negative effects when worn (i.e the tinfoil hat).
|
||||
#define SCAN_REAGENTS (1<<9) // Allows helmets and glasses to scan reagents.
|
||||
|
||||
// Flags for the organ_flags var on /obj/item/organ
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
#define NINJA_SUIT_TRAIT "ninja-suit"
|
||||
#define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant"
|
||||
#define SLEEPING_CARP_TRAIT "sleeping_carp"
|
||||
#define RISING_BASS_TRAIT "rising_bass"
|
||||
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
|
||||
#define MADE_UNCLONEABLE "made-uncloneable"
|
||||
#define NUKEOP_TRAIT "nuke-op"
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list)
|
||||
if(!GLOB.insect_fluffs_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list)
|
||||
if(!GLOB.insect_markings_list.len)
|
||||
init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_markings, GLOB.insect_markings_list)
|
||||
|
||||
//CIT CHANGES - genitals and such
|
||||
if(!GLOB.cock_shapes_list.len)
|
||||
@@ -151,6 +153,7 @@
|
||||
"caps" = pick(GLOB.caps_list),
|
||||
"insect_wings" = pick(GLOB.insect_wings_list),
|
||||
"insect_fluff" = "None",
|
||||
"insect_markings" = pick(GLOB.insect_markings_list),
|
||||
"taur" = "None",
|
||||
"mam_body_markings" = pick(snowflake_markings_list),
|
||||
"mam_ears" = pick(snowflake_ears_list),
|
||||
|
||||
@@ -143,6 +143,7 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
|
||||
"VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
|
||||
"IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS,
|
||||
"SCAN_REAGENTS" = SCAN_REAGENTS
|
||||
),
|
||||
"tesla_flags" = list(
|
||||
"TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
|
||||
|
||||
@@ -37,6 +37,7 @@ GLOBAL_LIST_EMPTY(deco_wings_list)
|
||||
GLOBAL_LIST_EMPTY(r_wings_list)
|
||||
GLOBAL_LIST_EMPTY(insect_wings_list)
|
||||
GLOBAL_LIST_EMPTY(insect_fluffs_list)
|
||||
GLOBAL_LIST_EMPTY(insect_markings_list)
|
||||
GLOBAL_LIST_EMPTY(caps_list)
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
var/deflection_chance = 0 //Chance to deflect projectiles
|
||||
var/reroute_deflection = FALSE //Delete the bullet, or actually deflect it in some direction?
|
||||
var/block_chance = 0 //Chance to block melee attacks using items while on throw mode.
|
||||
var/dodge_chance = 0
|
||||
var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not
|
||||
var/help_verb
|
||||
var/pacifism_check = TRUE //are the martial arts combos/attacks unable to be used by pacifist.
|
||||
var/allow_temp_override = TRUE //if this martial art can be overridden by temporary martial arts
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
help_verb = /mob/living/carbon/human/proc/CQC_help
|
||||
block_chance = 75
|
||||
var/old_grab_state = null
|
||||
var/restraining = FALSE
|
||||
|
||||
/datum/martial_art/cqc/reset_streak(mob/living/carbon/human/new_target)
|
||||
. = ..()
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
#define SIDE_KICK_COMBO "DH"
|
||||
#define SHOULDER_FLIP_COMBO "GHDGHH"
|
||||
#define REPULSE_PUNCH_COMBO "GHGH"
|
||||
#define FOOT_SMASH_COMBO "HH"
|
||||
#define DEFT_SWITCH_COMBO "GDD"
|
||||
|
||||
/datum/martial_art/the_rising_bass
|
||||
name = "The Rising Bass"
|
||||
id = MARTIALART_RISINGBASS
|
||||
dodge_chance = 100
|
||||
allow_temp_override = FALSE
|
||||
help_verb = /mob/living/carbon/human/proc/rising_bass_help
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,SIDE_KICK_COMBO))
|
||||
streak = ""
|
||||
sideKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,SHOULDER_FLIP_COMBO))
|
||||
streak = ""
|
||||
shoulderFlip(A,D)
|
||||
return 1
|
||||
if(findtext(streak,REPULSE_PUNCH_COMBO))
|
||||
streak = ""
|
||||
repulsePunch(A,D)
|
||||
return 1
|
||||
if(findtext(streak,FOOT_SMASH_COMBO))
|
||||
streak = ""
|
||||
footSmash(A,D)
|
||||
return 1
|
||||
if(findtext(streak,DEFT_SWITCH_COMBO))
|
||||
streak = ""
|
||||
deftSwitch(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/sideKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.IsKnockdown() || D.lying == 0)
|
||||
var/turf/H = get_step(D, A.dir & (NORTH | SOUTH) ? pick(EAST, WEST) : pick(NORTH, SOUTH))
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the side, sliding them over!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the side, forcing you to step away!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE, BODY_ZONE_CHEST)
|
||||
D.Knockdown(60)
|
||||
var/L = H
|
||||
for(var/obj/i in H.contents)
|
||||
if(!istype(i,/mob) && i.density == 1)
|
||||
L = D.loc
|
||||
D.forceMove(L)
|
||||
log_combat(A, D, "side kicked (Rising Bass)")
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/shoulderFlip(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.IsKnockdown() || !D.lying)
|
||||
var/turf/H = get_step(A, get_dir(D,A))
|
||||
var/L = H
|
||||
for(var/obj/i in H.contents)
|
||||
if(!istype(i,/mob) && i.density == 1)//(i.anchored == 1 && i.density == 1) || istype(i,/obj/structure) || istype(i,/turf/closed)
|
||||
L = A.loc
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] flips [D] over their shoulder, slamming them into the ground!</span>", \
|
||||
"<span class='userdanger'>[A] flips you over their shoulder, slamming you into the ground!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
D.emote("scream")
|
||||
D.apply_damage(10, BRUTE, BODY_ZONE_CHEST)
|
||||
D.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
|
||||
D.Sleeping(60)
|
||||
D.Knockdown(300)
|
||||
D.forceMove(L)
|
||||
log_combat(A, D, "shoulder flipped (Rising Bass)")
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/repulsePunch(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.IsKnockdown() || !D.lying)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] smashes [D] in the chest, throwing them away!</span>", \
|
||||
"<span class='userdanger'>[A] smashes you in the chest, repelling you away!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
var/atom/F = get_edge_target_turf(D, get_dir(A, get_step_away(D, A)))
|
||||
D.throw_at(F, 10, 1)
|
||||
D.apply_damage(10, BRUTE, BODY_ZONE_CHEST)
|
||||
D.Knockdown(90)
|
||||
log_combat(A, D, "repulse punched (Rising Bass)")
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/footSmash(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.IsKnockdown() || !D.lying)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] smashes their foot down on [D]'s foot!</span>", \
|
||||
"<span class='userdanger'>[A] smashes your foot!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.apply_damage(5, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
D.dropItemToGround(D.get_active_held_item())
|
||||
log_combat(A, D, "foot smashed (Rising Bass)")
|
||||
return 1
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_rising_bass/proc/deftSwitch(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.IsKnockdown() || !D.lying)
|
||||
if (D.get_active_held_item())
|
||||
var/obj/item/G = D.get_active_held_item()
|
||||
if (G && !(G.item_flags & (ABSTRACT|DROPDEL)) && D.temporarilyRemoveItemFromInventory(G))
|
||||
A.put_in_hands(G)
|
||||
D.visible_message("<span class='warning'>[A] slaps [D]'s hands, taking [G] from them!</span>", \
|
||||
"<span class='userdanger'>[A] slaps you, taking [G] from you!</span>")
|
||||
log_combat(A, D, "deft switched (Rising Bass)")
|
||||
return 1
|
||||
else
|
||||
to_chat(A, "<i>[G] can't be taken out of [D]'s hands!</i>")
|
||||
return 0
|
||||
|
||||
/datum/martial_art/the_rising_bass/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/datum/martial_art/the_rising_bass/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/datum/martial_art/the_rising_bass/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/rising_bass_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Rising Bass clan."
|
||||
set category = "Rising Bass"
|
||||
|
||||
to_chat(usr, "<b><i>You retreat inward and recall the teachings of the Rising Bass...</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Side Kick</span>: Disarm Harm. Forces opponent to step to the side.")
|
||||
to_chat(usr, "<span class='notice'>Shoulder Flip</span>: Grab Harm Disarm Grab Harm Harm. Flips opponent over your shoulder and stuns.")
|
||||
to_chat(usr, "<span class='notice'>Repulse Punch</span>: Grab Harm Grab Harm. Slams the opponent far away from you.")
|
||||
to_chat(usr, "<span class='notice'>Foot Smash</span>: Harm Harm. Stuns opponent, minor damage.")
|
||||
to_chat(usr, "<span class='notice'>Deft Switch</span>: Grab Disarm Disarm. Switches the opponent's held item for your own. Most useful with nothing in your hand.")
|
||||
|
||||
/datum/martial_art/the_rising_bass/teach(mob/living/carbon/human/H, make_temporary = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
ADD_TRAIT(H, TRAIT_NOGUNS, RISING_BASS_TRAIT)
|
||||
|
||||
/datum/martial_art/the_rising_bass/on_remove(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(H, TRAIT_NOGUNS, RISING_BASS_TRAIT)
|
||||
@@ -67,7 +67,9 @@
|
||||
/obj/item/clothing/shoes/kindleKicks = ARCADE_WEIGHT_RARE,
|
||||
/obj/item/storage/belt/military/snack = ARCADE_WEIGHT_RARE,
|
||||
|
||||
/obj/item/clothing/mask/fakemoustache/italian = ARCADE_WEIGHT_RARE
|
||||
/obj/item/clothing/mask/fakemoustache/italian = ARCADE_WEIGHT_RARE,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/ratvar/fake = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie/fake = ARCADE_WEIGHT_TRICK
|
||||
)
|
||||
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
@@ -230,6 +230,14 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
icon_state = "srv_headset"
|
||||
keyslot = new /obj/item/encryptionkey/headset_service
|
||||
|
||||
/obj/item/radio/headset/headset_clown
|
||||
name = "clown's headset"
|
||||
desc = "A headset for the clown. Finally. A megaphone you can't take away."
|
||||
icon_state = "srv_headset"
|
||||
keyslot = new /obj/item/encryptionkey/headset_service
|
||||
command = TRUE
|
||||
commandspan = SPAN_CLOWN
|
||||
|
||||
/obj/item/radio/headset/headset_cent
|
||||
name = "\improper CentCom headset"
|
||||
desc = "A headset used by the upper echelons of Nanotrasen."
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
var/freqlock = FALSE // Frequency lock to stop the user from untuning specialist radios.
|
||||
var/use_command = FALSE // If true, broadcasts will be large and BOLD.
|
||||
var/command = FALSE // If true, use_command can be toggled at will.
|
||||
var/commandspan = SPAN_COMMAND //allow us to set what the fuck we want for headsets
|
||||
|
||||
// Encryption key handling
|
||||
var/obj/item/encryptionkey/keyslot
|
||||
@@ -206,7 +207,7 @@
|
||||
return
|
||||
|
||||
if(use_command)
|
||||
spans |= SPAN_COMMAND
|
||||
spans |= commandspan
|
||||
|
||||
/*
|
||||
Roughly speaking, radios attempt to make a subspace transmission (which
|
||||
|
||||
@@ -414,6 +414,23 @@
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
/obj/item/book/granter/martial/bass
|
||||
martial = /datum/martial_art/the_rising_bass
|
||||
name = "shifting scroll"
|
||||
martialname = "rising bass"
|
||||
desc = "A paper scroll that seems to move even as you read it, the letters never seem to stay still."
|
||||
greet = "<span class='sciradio'>You have learned the ancient martial art of the Rising Bass. Your skill at running away has increased quite a bit. Use the combos to get away from opponents quickly. Along with this, you now dodge all projectiles and catch anything thrown at you.</span>"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
remarks = list("The trick is to disarm them...","Running away helps in many situations...","Never stay still...","Fighting won't help unless you're forced to...", "Crush their limbs to incapacitate them...", "Stay as far away as possible...")
|
||||
|
||||
/obj/item/book/granter/martial/bass/onlearned(mob/living/carbon/user)
|
||||
..()
|
||||
if(oneuse == TRUE)
|
||||
desc = "It's completely blank."
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
/obj/item/book/granter/martial/plasma_fist
|
||||
martial = /datum/martial_art/plasma_fist
|
||||
name = "frayed scroll"
|
||||
|
||||
@@ -390,4 +390,10 @@
|
||||
new /obj/item/seeds/random(src)
|
||||
|
||||
if(prob(50))
|
||||
new /obj/item/seeds/random(src) //oops, an additional packet might have slipped its way into the box
|
||||
new /obj/item/seeds/random(src) //oops, an additional packet might have slipped its way into the box
|
||||
|
||||
/obj/item/storage/box/syndie_kit/revolver
|
||||
|
||||
/obj/item/storage/box/syndie_kit/revolver/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver(src)
|
||||
new /obj/item/ammo_box/a357(src)
|
||||
|
||||
@@ -595,3 +595,48 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/pirate/gunner
|
||||
rank = "Gunner"
|
||||
|
||||
/obj/effect/mob_spawn/human/ghostcafe
|
||||
name = "ghost cafe sleeper"
|
||||
uses = -1
|
||||
icon = 'icons/obj/machines/sleeper.dmi'
|
||||
icon_state = "sleeper"
|
||||
mob_name = "a ghost cafe visitor"
|
||||
roundstart = FALSE
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
death = FALSE
|
||||
assignedrole = "Ghost Cafe Visitor"
|
||||
flavour_text = "Is this what life after death is like?"
|
||||
skip_reentry_check = TRUE
|
||||
banType = "ghostcafe"
|
||||
|
||||
/obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn)
|
||||
if(new_spawn.client)
|
||||
new_spawn.client.prefs.copy_to(new_spawn)
|
||||
var/datum/outfit/O = new /datum/outfit/ghostcafe()
|
||||
O.equip(new_spawn, FALSE, new_spawn.client)
|
||||
SSjob.equip_loadout(null, new_spawn, FALSE)
|
||||
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
|
||||
|
||||
/datum/outfit/ghostcafe
|
||||
name = "ID, jumpsuit and shoes"
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
id = /obj/item/card/id
|
||||
|
||||
|
||||
/datum/outfit/ghostcafe/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
..()
|
||||
var/suited = !preference_source || preference_source.prefs.jumpsuit_style == PREF_SUIT
|
||||
if (CONFIG_GET(flag/grey_assistants))
|
||||
if(suited)
|
||||
uniform = /obj/item/clothing/under/color/grey
|
||||
else
|
||||
uniform = /obj/item/clothing/under/skirt/color/grey
|
||||
else
|
||||
if(suited)
|
||||
uniform = /obj/item/clothing/under/color/random
|
||||
else
|
||||
uniform = /obj/item/clothing/under/skirt/color/random
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
/mob/living/carbon/human/ShowAsPaleExamine()
|
||||
// Check for albino, as per human/examine.dm's check.
|
||||
if(skin_tone == "albino")
|
||||
if(dna.species.use_skintones && skin_tone == "albino")
|
||||
return TRUE
|
||||
|
||||
return ..() // Return vamp check
|
||||
|
||||
@@ -345,3 +345,8 @@
|
||||
if(!power_amount)
|
||||
power_amount = -(CLOCKCULT_POWER_UNIT*0.02)
|
||||
return ..()
|
||||
|
||||
|
||||
// Winter coat
|
||||
/obj/item/clothing/suit/hooded/wintercoat/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal
|
||||
return list("operation_time" = 30, "new_obj_type" = /obj/item/clothing/suit/hooded/wintercoat/ratvar, "power_cost" = POWER_METAL * 4, "spawn_dir" = SOUTH)
|
||||
|
||||
@@ -585,6 +585,12 @@
|
||||
new /obj/item/stack/sheet/runed_metal(T,quantity)
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
if(istype(target, /obj/item/clothing/suit/hooded/wintercoat) && target.type != /obj/item/clothing/suit/hooded/wintercoat/narsie)
|
||||
if (do_after(user,30,target=target))
|
||||
new /obj/item/clothing/suit/hooded/wintercoat/narsie(T)
|
||||
qdel(target)
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
else if(istype(target,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/candidate = target
|
||||
if(candidate.mmi)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
var/show_flavour = TRUE
|
||||
var/banType = "lavaland"
|
||||
var/ghost_usable = TRUE
|
||||
var/skip_reentry_check = FALSE //Skips the ghost role blacklist time for people who ghost/suicide/cryo
|
||||
|
||||
//ATTACK GHOST IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/mob_spawn/attack_ghost(mob/user, latejoinercalling)
|
||||
@@ -44,7 +45,7 @@
|
||||
return
|
||||
if(isobserver(user))
|
||||
var/mob/dead/observer/O = user
|
||||
if(!O.can_reenter_round())
|
||||
if(!O.can_reenter_round() && !skip_reentry_check)
|
||||
return FALSE
|
||||
var/ghost_role = alert(latejoinercalling ? "Latejoin as [mob_name]? (This is a ghost role, and as such, it's very likely to be off-station.)" : "Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(ghost_role == "No" || !loc)
|
||||
|
||||
@@ -103,6 +103,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"legs" = "Plantigrade",
|
||||
"insect_wings" = "Plain",
|
||||
"insect_fluff" = "None",
|
||||
"insect_markings" = "None",
|
||||
"mcolor2" = "FFF",
|
||||
"mcolor3" = "FFF",
|
||||
"mam_body_markings" = "Plain",
|
||||
@@ -620,6 +621,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a>"
|
||||
|
||||
if("insect_markings" in pref_species.default_features)
|
||||
if(!mutant_category)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
|
||||
dat += "<h3>Insect markings</h3>"
|
||||
|
||||
dat += "<a href='?_src_=prefs;preference=insect_markings;task=input'>[features["insect_markings"]]</a><BR>"
|
||||
|
||||
mutant_category++
|
||||
if(mutant_category >= MAX_MUTANT_ROWS)
|
||||
dat += "</td>"
|
||||
mutant_category = 0
|
||||
|
||||
mutant_category++
|
||||
if(mutant_category >= MAX_MUTANT_ROWS)
|
||||
dat += "</td>"
|
||||
@@ -1743,6 +1757,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(new_insect_fluff)
|
||||
features["insect_fluff"] = new_insect_fluff
|
||||
|
||||
if("insect_markings")
|
||||
var/new_insect_markings
|
||||
new_insect_markings = input(user, "Choose your character's markings:", "Character Preference") as null|anything in GLOB.insect_markings_list
|
||||
if(new_insect_markings)
|
||||
features["insect_markings"] = new_insect_markings
|
||||
|
||||
if("s_tone")
|
||||
var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones
|
||||
if(new_s_tone)
|
||||
|
||||
@@ -366,9 +366,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_lizard_legs"] >> features["legs"]
|
||||
S["feature_human_tail"] >> features["tail_human"]
|
||||
S["feature_human_ears"] >> features["ears"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
S["feature_insect_wings"] >> features["insect_wings"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
S["feature_insect_fluff"] >> features["insect_fluff"]
|
||||
S["feature_insect_markings"] >> features["insect_markings"]
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
@@ -503,9 +504,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["spines"] = sanitize_inlist(features["spines"], GLOB.spines_list)
|
||||
features["body_markings"] = sanitize_inlist(features["body_markings"], GLOB.body_markings_list)
|
||||
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], GLOB.legs_list)
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None")
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
//Validate job prefs
|
||||
@@ -570,11 +572,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["feature_lizard_spines"] , features["spines"])
|
||||
WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"])
|
||||
WRITE_FILE(S["feature_lizard_legs"] , features["legs"])
|
||||
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
|
||||
WRITE_FILE(S["feature_deco_wings"] , features["deco_wings"])
|
||||
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
|
||||
WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"])
|
||||
WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"])
|
||||
WRITE_FILE(S["feature_meat"] , features["meat_type"])
|
||||
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
var/cooldown = 0
|
||||
var/obj/item/flashlight/F = null
|
||||
var/can_flashlight = 0
|
||||
var/scan_reagents = 0 //Can the wearer see reagents while it's equipped?
|
||||
|
||||
var/blocks_shove_knockdown = FALSE //Whether wearing the clothing item blocks the ability for shove to knock down.
|
||||
|
||||
@@ -47,6 +46,17 @@
|
||||
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
|
||||
//You append this to clothing objects.
|
||||
|
||||
//Polychrome stuff:
|
||||
var/hasprimary = FALSE //These vars allow you to choose which overlays a clothing has
|
||||
var/hassecondary = FALSE
|
||||
var/hastertiary = FALSE
|
||||
var/primary_color = "#FFFFFF" //RGB in hexcode
|
||||
var/secondary_color = "#FFFFFF"
|
||||
var/tertiary_color = "#808080"
|
||||
|
||||
//No idea what this is but eh -tori
|
||||
var/force_alternate_icon = FALSE
|
||||
|
||||
|
||||
/obj/item/clothing/Initialize()
|
||||
. = ..()
|
||||
@@ -54,6 +64,8 @@
|
||||
actions_types += /datum/action/item_action/toggle_voice_box
|
||||
if(ispath(pocket_storage_component_path))
|
||||
LoadComponent(pocket_storage_component_path)
|
||||
if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
|
||||
update_icon() //Applies the overlays and default colors onto the clothes on spawn.
|
||||
|
||||
/obj/item/clothing/MouseDrop(atom/over_object)
|
||||
. = ..()
|
||||
@@ -138,6 +150,8 @@
|
||||
how_cool_are_your_threads += "Adding or removing items from [src] makes no noise.\n"
|
||||
how_cool_are_your_threads += "</span>"
|
||||
. += how_cool_are_your_threads.Join()
|
||||
if(hasprimary | hassecondary | hastertiary) //Checks if polychrome is enabled
|
||||
. += "<span class='notice'>Alt-click to recolor it.</span>"
|
||||
|
||||
/obj/item/clothing/obj_break(damage_flag)
|
||||
if(!damaged_clothes)
|
||||
@@ -260,8 +274,31 @@ BLIND // can't see anything
|
||||
remove_accessory(user)
|
||||
else
|
||||
rolldown()
|
||||
// Polychrome stuff:
|
||||
if(hasprimary | hassecondary | hastertiary)
|
||||
var/choice = input(user,"polychromic thread options", "Clothing Recolor") as null|anything in list("[hasprimary ? "Primary Color" : ""]", "[hassecondary ? "Secondary Color" : ""]", "[hastertiary ? "Tertiary Color" : ""]") //generates a list depending on the enabled overlays
|
||||
switch(choice) //Lets the list's options actually lead to something
|
||||
if("Primary Color")
|
||||
var/primary_color_input = input(usr,"","Choose Primary Color",primary_color) as color|null //color input menu, the "|null" adds a cancel button to it.
|
||||
if(primary_color_input) //Checks if the color selected is NULL, rejects it if it is NULL.
|
||||
primary_color = sanitize_hexcolor(primary_color_input, desired_format=6, include_crunch=1) //formats the selected color properly
|
||||
update_icon() //updates the item icon
|
||||
user.regenerate_icons() //updates the worn icon. Probably a bad idea, but it works.
|
||||
if("Secondary Color")
|
||||
var/secondary_color_input = input(usr,"","Choose Secondary Color",secondary_color) as color|null
|
||||
if(secondary_color_input)
|
||||
secondary_color = sanitize_hexcolor(secondary_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
user.regenerate_icons()
|
||||
if("Tertiary Color")
|
||||
var/tertiary_color_input = input(usr,"","Choose Tertiary Color",tertiary_color) as color|null
|
||||
if(tertiary_color_input)
|
||||
tertiary_color = sanitize_hexcolor(tertiary_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
user.regenerate_icons()
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/clothing/under/verb/jumpsuit_adjust()
|
||||
set name = "Adjust Jumpsuit Style"
|
||||
set category = null
|
||||
@@ -377,3 +414,18 @@ BLIND // can't see anything
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/update_icon() // Polychrome stuff
|
||||
..()
|
||||
if(hasprimary) //Checks if the overlay is enabled
|
||||
var/mutable_appearance/primary_overlay = mutable_appearance(icon, "[item_color]-primary") //Automagically picks overlays
|
||||
primary_overlay.color = primary_color //Colors the greyscaled overlay
|
||||
add_overlay(primary_overlay) //Applies the coloured overlay onto the item sprite. but NOT the mob sprite.
|
||||
if(hassecondary)
|
||||
var/mutable_appearance/secondary_overlay = mutable_appearance(icon, "[item_color]-secondary")
|
||||
secondary_overlay.color = secondary_color
|
||||
add_overlay(secondary_overlay)
|
||||
if(hastertiary)
|
||||
var/mutable_appearance/tertiary_overlay = mutable_appearance(icon, "[item_color]-tertiary")
|
||||
tertiary_overlay.color = tertiary_color
|
||||
add_overlay(tertiary_overlay)
|
||||
@@ -99,7 +99,7 @@
|
||||
desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents."
|
||||
icon_state = "purple"
|
||||
item_state = "glasses"
|
||||
scan_reagents = TRUE //You can see reagents while wearing science goggles
|
||||
clothing_flags = SCAN_REAGENTS //You can see reagents while wearing science goggles
|
||||
actions_types = list(/datum/action/item_action/toggle_research_scanner)
|
||||
glass_colour_type = /datum/client_colour/glass_colour/purple
|
||||
resistance_flags = ACID_PROOF
|
||||
@@ -203,7 +203,7 @@
|
||||
/obj/item/clothing/glasses/sunglasses/reagent
|
||||
name = "beer goggles"
|
||||
desc = "A pair of sunglasses outfitted with apparatus to scan reagents."
|
||||
scan_reagents = TRUE
|
||||
clothing_flags = SCAN_REAGENTS
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/garb
|
||||
name = "black gar glasses"
|
||||
@@ -405,7 +405,7 @@
|
||||
item_state = "godeye"
|
||||
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
darkness_view = 8
|
||||
scan_reagents = TRUE
|
||||
clothing_flags = SCAN_REAGENTS
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@
|
||||
flash_protect = 0
|
||||
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75)
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
scan_reagents = TRUE
|
||||
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/medical
|
||||
icon_state = "hardsuit-medical"
|
||||
@@ -467,7 +467,7 @@
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80)
|
||||
var/obj/machinery/doppler_array/integrated/bomb_radar
|
||||
scan_reagents = TRUE
|
||||
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
|
||||
actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/rd/Initialize()
|
||||
@@ -638,7 +638,7 @@
|
||||
armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
item_color = "ancient"
|
||||
brightness_on = 16
|
||||
scan_reagents = TRUE
|
||||
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
|
||||
flash_protect = 5 //We will not be flash by bombs
|
||||
tint = 1
|
||||
var/obj/machinery/doppler_array/integrated/bomb_radar
|
||||
|
||||
@@ -742,6 +742,7 @@
|
||||
name = "assistant's formal winter coat"
|
||||
icon_state = "coataformal"
|
||||
item_state = "coataformal"
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter,/obj/item/clothing/gloves/color/yellow)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/aformal
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/aformal
|
||||
@@ -762,7 +763,10 @@
|
||||
name = "ratvarian winter coat"
|
||||
icon_state = "coatratvar"
|
||||
item_state = "coatratvar"
|
||||
armor = list("melee" = 30, "bullet" = 45, "laser" = -10, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/clockwork/replica_fabricator, /obj/item/clockwork/integration_cog, /obj/item/clockwork/slab, /obj/item/clockwork/weapon/ratvarian_spear)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/ratvar
|
||||
var/real = TRUE
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/ratvar
|
||||
icon_state = "winterhood_ratvar"
|
||||
@@ -770,15 +774,59 @@
|
||||
light_power = 1
|
||||
light_color = "#B18B25" //clockwork slab background top color
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/ratvar/equipped(mob/living/user,slot)
|
||||
..()
|
||||
if (slot != SLOT_WEAR_SUIT || !real)
|
||||
return
|
||||
if (is_servant_of_ratvar(user))
|
||||
return
|
||||
else
|
||||
user.dropItemToGround(src)
|
||||
to_chat(user,"<span class='large_brass'>\"Amusing that you think you are fit to wear this.\"</span>")
|
||||
to_chat(user,"<span class='userdanger'>Your skin burns where the coat touched your skin!</span>")
|
||||
user.adjustFireLoss(rand(10,16))
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie
|
||||
name = "narsian winter coat"
|
||||
icon_state = "coatnarsie"
|
||||
item_state = "coatnarsie"
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 30,"energy" = 10, "bomb" = 30, "bio" = 10, "rad" = 10, "fire" = 30, "acid" = 30)
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/restraints/legcuffs/bola/cult,/obj/item/melee/cultblade,/obj/item/melee/cultblade/dagger,/obj/item/reagent_containers/glass/beaker/unholywater,/obj/item/cult_shift,/obj/item/flashlight/flare/culttorch,/obj/item/twohanded/cult_spear)
|
||||
hoodtype = /obj/item/clothing/head/hooded/winterhood/narsie
|
||||
var/real = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie/equipped(mob/living/user,slot)
|
||||
..()
|
||||
if (slot != SLOT_WEAR_SUIT || !real)
|
||||
return
|
||||
if (iscultist(user))
|
||||
return
|
||||
else
|
||||
user.dropItemToGround(src)
|
||||
to_chat(user,"<span class='cultlarge'>\"You are not fit to wear my follower's coat!\"</span>")
|
||||
to_chat(user,"<span class='userdanger'>Sharp spines jab you from within the coat!</span>")
|
||||
user.adjustBruteLoss(rand(10,16))
|
||||
|
||||
/obj/item/clothing/head/hooded/winterhood/narsie
|
||||
icon_state = "winterhood_narsie"
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/ratvar/fake
|
||||
name = "brass winter coat"
|
||||
icon_state = "coatratvar"
|
||||
item_state = "coatratvar"
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
real = FALSE
|
||||
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie/fake
|
||||
name = "runed winter coat"
|
||||
icon_state = "coatnarsie"
|
||||
item_state = "coatnarsie"
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
real = FALSE
|
||||
|
||||
|
||||
/obj/item/clothing/suit/spookyghost
|
||||
name = "spooky ghost"
|
||||
desc = "This is obviously just a bedsheet, but maybe try it on?"
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Polychromic Uniforms: //
|
||||
// //
|
||||
// Polychromic clothes simply consist of 4 sprites: A base, unrecoloured sprite, and up to 3 greyscaled sprites. //
|
||||
// In order to add more polychromic clothes, simply create a base sprite, and up to 3 recolourable overlays for it, //
|
||||
// and then name them as follows: [name], [name]-primary, [name]-secondary, [name]-tertiary. The sprites should //
|
||||
// ideally be in 'icons/obj/clothing/uniform.dmi' and 'icons/mob/uniform.dmi' for the //
|
||||
// worn sprites. After that, copy paste the code from any of the example clothes and //
|
||||
// change the names around. [name] should go in BOTH icon_state and item_color. You can preset colors and disable //
|
||||
// any overlays using the self-explainatory vars. //
|
||||
// //
|
||||
// -Tori //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/clothing/under/polychromic //enables all three overlays to reduce copypasta and defines basic stuff
|
||||
name = "polychromic suit"
|
||||
desc = "For when you want to show off your horrible colour coordination skills."
|
||||
icon_state = "polysuit"
|
||||
item_color = "polysuit"
|
||||
item_state = "sl_suit"
|
||||
hasprimary = TRUE
|
||||
hassecondary = TRUE
|
||||
hastertiary = TRUE
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#FFFFFF"
|
||||
tertiary_color = "#808080"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION //Not all clothes are currently digi-compatible (only the shorts are as of time of writing)
|
||||
|
||||
/obj/item/clothing/under/polychromic/worn_overlays(isinhands, icon_file) //this is where the main magic happens.
|
||||
. = ..()
|
||||
if(hasprimary | hassecondary | hastertiary)
|
||||
if(!isinhands) //prevents the worn sprites from showing up if you're just holding them
|
||||
if(hasprimary) //checks if overlays are enabled
|
||||
var/mutable_appearance/primary_worn = mutable_appearance(icon_file, "[item_color]-primary") //automagical sprite selection
|
||||
primary_worn.color = primary_color //colors the overlay
|
||||
. += primary_worn //adds the overlay onto the buffer list to draw on the mob sprite.
|
||||
if(hassecondary)
|
||||
var/mutable_appearance/secondary_worn = mutable_appearance(icon_file, "[item_color]-secondary")
|
||||
secondary_worn.color = secondary_color
|
||||
. += secondary_worn
|
||||
if(hastertiary)
|
||||
var/mutable_appearance/tertiary_worn = mutable_appearance(icon_file, "[item_color]-tertiary")
|
||||
tertiary_worn.color = tertiary_color
|
||||
. += tertiary_worn
|
||||
|
||||
/obj/item/clothing/under/polychromic/shirt //COPY PASTE THIS TO MAKE A NEW THING
|
||||
name = "polychromic button-up shirt"
|
||||
desc = "A fancy button-up shirt made with polychromic threads."
|
||||
icon_state = "polysuit"
|
||||
item_color = "polysuit"
|
||||
item_state = "sl_suit"
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#353535"
|
||||
tertiary_color = "#353535"
|
||||
|
||||
/obj/item/clothing/under/polychromic/kilt
|
||||
name = "polychromic kilt"
|
||||
desc = "It's not a skirt!"
|
||||
icon_state = "polykilt"
|
||||
item_color = "polykilt"
|
||||
item_state = "kilt"
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#F08080"
|
||||
hastertiary = FALSE // so it doesn't futz with digilegs
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
|
||||
/obj/item/clothing/under/polychromic/skirt
|
||||
name = "polychromic skirt"
|
||||
desc = "A fancy skirt made with polychromic threads."
|
||||
icon_state = "polyskirt"
|
||||
item_color = "polyskirt"
|
||||
item_state = "rainbow"
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#F08080"
|
||||
tertiary_color = "#808080"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
|
||||
/obj/item/clothing/under/polychromic/shorts
|
||||
name = "polychromic shorts"
|
||||
desc = "For ease of movement and style."
|
||||
icon_state = "polyshorts"
|
||||
item_color = "polyshorts"
|
||||
item_state = "rainbow"
|
||||
primary_color = "#353535" //RGB in hexcode
|
||||
secondary_color = "#808080"
|
||||
tertiary_color = "#808080"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
mutantrace_variation = MUTANTRACE_VARIATION //to enable digitigrade wearing
|
||||
|
||||
/obj/item/clothing/under/polychromic/jumpsuit
|
||||
name = "polychromic tri-tone jumpsuit"
|
||||
desc = "A fancy jumpsuit made with polychromic threads."
|
||||
icon_state = "polyjump"
|
||||
item_color = "polyjump"
|
||||
item_state = "rainbow"
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#808080"
|
||||
tertiary_color = "#FF3535"
|
||||
|
||||
/obj/item/clothing/under/polychromic/shortpants
|
||||
name = "polychromic athletic shorts"
|
||||
desc = "95% Polychrome, 5% Spandex!"
|
||||
icon_state = "polyshortpants"
|
||||
item_color = "polyshortpants"
|
||||
item_state = "rainbow"
|
||||
hastertiary = FALSE
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#F08080"
|
||||
gender = PLURAL //Because shortS
|
||||
body_parts_covered = GROIN //Because there's no shirt included
|
||||
|
||||
/obj/item/clothing/under/polychromic/pleat
|
||||
name = "polychromic pleated skirt"
|
||||
desc = "A magnificent pleated skirt complements the woolen polychromatic sweater."
|
||||
icon_state = "polypleat"
|
||||
item_color = "polypleat"
|
||||
item_state = "rainbow"
|
||||
primary_color = "#8CC6FF" //RGB in hexcode
|
||||
secondary_color = "#808080"
|
||||
tertiary_color = "#FF3535"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
|
||||
/obj/item/clothing/under/polychromic/femtank
|
||||
name = "polychromic feminine tank top"
|
||||
desc = "Great for showing off your chest in style. Not recommended for males."
|
||||
icon_state = "polyfemtankpantsu"
|
||||
item_color = "polyfemtankpantsu"
|
||||
item_state = "rainbow"
|
||||
hastertiary = FALSE
|
||||
primary_color = "#808080" //RGB in hexcode
|
||||
secondary_color = "#FF3535"
|
||||
body_parts_covered = CHEST|GROIN|ARMS
|
||||
|
||||
/obj/item/clothing/under/polychromic/shortpants/pantsu
|
||||
name = "polychromic panties"
|
||||
desc = "Topless striped panties. Now with 120% more polychrome!"
|
||||
icon_state = "polypantsu"
|
||||
item_color = "polypantsu"
|
||||
item_state = "rainbow"
|
||||
hastertiary = FALSE
|
||||
primary_color = "#FFFFFF" //RGB in hexcode
|
||||
secondary_color = "#8CC6FF"
|
||||
body_parts_covered = GROIN
|
||||
|
||||
/obj/item/clothing/under/polychromic/bottomless
|
||||
name = "polychromic bottomless shirt"
|
||||
desc = "Great for showing off your junk in dubious style."
|
||||
icon_state = "polybottomless"
|
||||
item_color = "polybottomless"
|
||||
item_state = "rainbow"
|
||||
hastertiary = FALSE
|
||||
primary_color = "#808080" //RGB in hexcode
|
||||
secondary_color = "#FF3535"
|
||||
body_parts_covered = CHEST|ARMS //Because there's no bottom included
|
||||
|
||||
/obj/item/clothing/under/polychromic/shimatank
|
||||
name = "polychromic tank top"
|
||||
desc = "For those lazy summer days."
|
||||
icon_state = "polyshimatank"
|
||||
item_color = "polyshimatank"
|
||||
item_state = "rainbow"
|
||||
primary_color = "#808080" //RGB in hexcode
|
||||
secondary_color = "#FFFFFF"
|
||||
tertiary_color = "#8CC6FF"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
@@ -275,6 +275,18 @@
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored
|
||||
name = "Colored (Hair)"
|
||||
icon_state = "snow"
|
||||
|
||||
@@ -213,4 +213,81 @@
|
||||
|
||||
/datum/sprite_accessory/insect_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
//insect markings
|
||||
/datum/sprite_accessory/insect_markings // Extra markings for insects ported from tg.
|
||||
icon = 'icons/mob/insect_markings.dmi'
|
||||
color_src = null
|
||||
|
||||
/datum/sprite_accessory/insect_markings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "reddish"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/gothic
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/punished
|
||||
name = "Punished"
|
||||
icon_state = "punished"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/moonfly
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
@@ -977,3 +977,14 @@
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/can_see_reagents()
|
||||
. = ..()
|
||||
if(.) //No need to run through all of this if it's already true.
|
||||
return
|
||||
if(isclothing(head))
|
||||
var/obj/item/clothing/H = head
|
||||
if(H.clothing_flags & SCAN_REAGENTS)
|
||||
return TRUE
|
||||
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
|
||||
return TRUE
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
|
||||
/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check)
|
||||
. = FALSE
|
||||
if(mind)
|
||||
if(mind.martial_art && mind.martial_art.dodge_chance == 100)
|
||||
return TRUE
|
||||
if(!skip_throw_mode_check && !in_throw_mode)
|
||||
return
|
||||
if(get_active_held_item())
|
||||
@@ -63,6 +66,13 @@
|
||||
if(can_catch_item())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if (mind)
|
||||
if (mind.martial_art && mind.martial_art.dodge_chance == 100) //autocatch for rising bass
|
||||
if (get_active_held_item())
|
||||
visible_message("<span class='warning'>[I] falls to the ground as [src] chops it out of the air!</span>")
|
||||
return 1
|
||||
if(!in_throw_mode)
|
||||
throw_mode_on()
|
||||
if(isturf(I.loc))
|
||||
I.attack_hand(src)
|
||||
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
return spec_return
|
||||
|
||||
if(mind)
|
||||
if (mind.martial_art && mind.martial_art.dodge_chance)
|
||||
if(!lying && dna && !dna.check_mutation(HULK))
|
||||
if(prob(mind.martial_art.dodge_chance))
|
||||
var/dodgemessage = pick("dodges under the projectile!","dodges to the right of the projectile!","jumps over the projectile!")
|
||||
visible_message("<span class='danger'>[src] [dodgemessage]</span>", "<span class='userdanger'>You dodge the projectile!</span>")
|
||||
return -1
|
||||
if(mind.martial_art && !incapacitated(FALSE, TRUE) && mind.martial_art.can_use(src) && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(prob(mind.martial_art.deflection_chance))
|
||||
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
@@ -145,7 +151,7 @@
|
||||
skipcatch = TRUE
|
||||
blocked = TRUE
|
||||
else if(I)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD && !(mind.martial_art && mind.martial_art.dodge_chance == 100))
|
||||
if(can_embed(I))
|
||||
if(prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE))
|
||||
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
|
||||
@@ -158,7 +164,9 @@
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
|
||||
hitpush = FALSE
|
||||
skipcatch = TRUE //can't catch the now embedded item
|
||||
|
||||
if (mind)
|
||||
if (mind.martial_art && mind.martial_art.dodge_chance == 100)
|
||||
skipcatch = FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
|
||||
@@ -117,7 +117,8 @@
|
||||
|
||||
/mob/living/carbon/human/can_use_guns(obj/item/G)
|
||||
. = ..()
|
||||
|
||||
if(!.)
|
||||
return
|
||||
if(G.trigger_guard == TRIGGER_GUARD_NORMAL)
|
||||
if(HAS_TRAIT(src, TRAIT_CHUNKYFINGERS))
|
||||
to_chat(src, "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>")
|
||||
@@ -126,7 +127,13 @@
|
||||
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
|
||||
return FALSE
|
||||
|
||||
return .
|
||||
/mob/living/carbon/human/can_see_reagents()
|
||||
. = ..()
|
||||
if(.) //No need to run through all of this if it's already true.
|
||||
return
|
||||
if(isclothing(glasses) && (glasses.clothing_flags & SCAN_REAGENTS))
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/transfer_blood_dna(list/blood_dna)
|
||||
..()
|
||||
|
||||
@@ -781,6 +781,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
S = GLOB.insect_wings_list[H.dna.features["insect_wings"]]
|
||||
if("insect_fluff")
|
||||
S = GLOB.insect_fluffs_list[H.dna.features["insect_fluff"]]
|
||||
if("insect_markings")
|
||||
S = GLOB.insect_markings_list[H.dna.features["insect_markings"]]
|
||||
if("caps")
|
||||
S = GLOB.caps_list[H.dna.features["caps"]]
|
||||
if("ipc_screen")
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
|
||||
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
|
||||
mutant_bodyparts = list("mam_ears","mam_tail", "taur", "insect_wings","mam_snout", "mam_snouts", "insect_fluff","insect_markings")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None","horns" = "None")
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -275,6 +275,15 @@
|
||||
/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
return 0 //So they don't die trying to fix wiring
|
||||
|
||||
/mob/living/simple_animal/drone/can_see_reagents()
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(isclothing(head))
|
||||
var/obj/item/clothing/H = head
|
||||
if(H.clothing_flags & SCAN_REAGENTS)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/drone/generate_mob_holder()
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "[visualAppearence]_hat", null, null, null, TRUE)
|
||||
return holder
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2)
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
|
||||
@@ -811,26 +811,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
/mob/proc/can_interact_with(atom/A)
|
||||
return IsAdminGhost(src) || Adjacent(A)
|
||||
|
||||
//Can the mob see reagents inside of containers?
|
||||
/mob/proc/can_see_reagents()
|
||||
if(stat == DEAD) //Ghosts and such can always see reagents
|
||||
return 1
|
||||
if(has_unlimited_silicon_privilege) //Silicons can automatically view reagents
|
||||
return 1
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.head && istype(H.head, /obj/item/clothing))
|
||||
var/obj/item/clothing/CL = H.head
|
||||
if(CL.scan_reagents)
|
||||
return 1
|
||||
if(H.wear_mask && H.wear_mask.scan_reagents)
|
||||
return 1
|
||||
if(H.glasses && istype(H.glasses, /obj/item/clothing))
|
||||
var/obj/item/clothing/CL = H.glasses
|
||||
if(CL.scan_reagents)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Can the mob use Topic to interact with machines
|
||||
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
return
|
||||
|
||||
@@ -532,3 +532,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if(!held_item)
|
||||
return
|
||||
return held_item.GetID()
|
||||
|
||||
//Can the mob see reagents inside of containers?
|
||||
/mob/proc/can_see_reagents()
|
||||
return stat == DEAD || has_unlimited_silicon_privilege //Dead guys and silicons can always see reagents
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/datum/reagent/drug/space_drugs
|
||||
name = "Space drugs"
|
||||
id = "space_drugs"
|
||||
value = 6
|
||||
description = "An illegal chemical compound used as drug."
|
||||
color = "#60A584" // rgb: 96, 165, 132
|
||||
overdose_threshold = 30
|
||||
@@ -40,6 +41,7 @@
|
||||
/datum/reagent/drug/nicotine
|
||||
name = "Nicotine"
|
||||
id = "nicotine"
|
||||
value = 0
|
||||
description = "Slightly reduces stun times. If overdosed it will deal toxin and oxygen damage."
|
||||
reagent_state = LIQUID
|
||||
color = "#60A584" // rgb: 96, 165, 132
|
||||
|
||||
@@ -1095,13 +1095,13 @@
|
||||
continue
|
||||
boost_item_paths |= UI.item //allows deconning to unlock.
|
||||
|
||||
/datum/techweb_node/advanced_illegl_ballistics
|
||||
/datum/techweb_node/advanced_illegal_ballistics
|
||||
id = "advanced_illegal_ballistics"
|
||||
display_name = "Advanced Illegal Ballistics"
|
||||
description = "Advanced Ballistic for Illegal weaponds."
|
||||
design_ids = list("10mm","10mmap","10mminc","10mmhp","pistolm9mm","m45","bolt_clip")
|
||||
display_name = "Advanced Non-Standard Ballistics"
|
||||
description = "Ballistic ammunition for non-standard firearms. Usually the ones you don't have nor want to be involved with."
|
||||
design_ids = list("10mm","10mmap","10mminc","10mmhp","sl357","pistolm9mm","m45","bolt_clip")
|
||||
prereq_ids = list("ballistic_weapons","syndicate_basic","explosive_weapons")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns form traitors or space.
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 25000) //This gives sec lethal mags/clips for guns from traitors, space, or anything in between.
|
||||
export_price = 7000
|
||||
|
||||
//Helpers for debugging/balancing the techweb in its entirety!
|
||||
|
||||
@@ -357,9 +357,9 @@
|
||||
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/dangerous/revolver
|
||||
name = "Syndicate Revolver"
|
||||
desc = "A brutally simple syndicate revolver that fires .357 Magnum rounds and has 7 chambers."
|
||||
item = /obj/item/gun/ballistic/revolver
|
||||
name = "Syndicate Revolver Kit"
|
||||
desc = "A sleek box containing a brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers, and an extra speedloader."
|
||||
item = /obj/item/storage/box/syndie_kit/revolver
|
||||
cost = 13
|
||||
surplus = 50
|
||||
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
|
||||
@@ -641,7 +641,7 @@
|
||||
cost = 2
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/martialarts
|
||||
name = "Martial Arts Scroll"
|
||||
name = "Sleeping Carp Scroll"
|
||||
desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \
|
||||
deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry."
|
||||
item = /obj/item/book/granter/martial/carp
|
||||
@@ -649,6 +649,15 @@
|
||||
surplus = 0
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/martialartstwo
|
||||
name = "Rising Bass Scroll"
|
||||
desc = "This scroll contains the secrets of an ancient martial arts technique. You will become proficient in fleeing situations, \
|
||||
and dodging all ranged weapon fire, but you will refuse to use dishonorable ranged weaponry."
|
||||
item = /obj/item/book/granter/martial/bass
|
||||
cost = 18
|
||||
surplus = 0
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/crossbow
|
||||
name = "Miniature Energy Crossbow"
|
||||
desc = "A short bow mounted across a tiller in miniature. Small enough to \
|
||||
|
||||
Reference in New Issue
Block a user