Merge remote-tracking branch 'upstream-polaris/master' into polaris-sync-2018-02-07

# Conflicts:
#	code/__defines/subsystems.dm
#	code/controllers/master_controller.dm
#	code/controllers/subsystems/atoms.dm
#	code/game/machinery/Sleeper.dm
#	code/game/machinery/doors/airlock.dm
#	code/game/machinery/vr_console.dm
#	code/game/objects/items/devices/communicator/phone.dm
#	code/game/turfs/flooring/flooring_decals.dm
#	code/modules/admin/admin_verbs.dm
#	code/modules/mob/living/carbon/carbon.dm
#	code/modules/multiz/movement.dm
#	code/modules/projectiles/gun.dm
#	code/modules/shuttles/shuttle.dm
#	code/modules/shuttles/shuttles_web.dm
#	icons/obj/doors/doormed.dmi
#	maps/southern_cross/items/headset_sc.dm
#	maps/southern_cross/southern_cross-3.dmm
#	vorestation.dme
This commit is contained in:
Leshana
2018-02-07 19:30:50 -05:00
179 changed files with 1959 additions and 1011 deletions
+3 -3
View File
@@ -897,13 +897,13 @@ var/list/admin_verbs_event_manager = list(
if(!H.client)
usr << "Only mobs with clients can alter their own appearance."
return
var/datum/gender/T = gender_datums[H.get_visible_gender()]
switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
if("Yes")
log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
log_and_message_admins("has allowed [H] to change [T.his] appearance, without whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
if("No")
log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
log_and_message_admins("has allowed [H] to change [T.his] appearance, with whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -8,6 +8,11 @@
display_name = "clipboard"
path = /obj/item/weapon/clipboard
/datum/gear/utility/tts_device
display_name = "text to speech device"
path = /obj/item/device/text_to_speech
cost = 3 //Not extremely expensive, but it's useful for mute chracters.
/datum/gear/utility/communicator
display_name = "communicator selection"
path = /obj/item/device/communicator
+1 -1
View File
@@ -196,7 +196,7 @@
gender = PLURAL //Carn: for grammarically correct text-parsing
w_class = ITEMSIZE_SMALL
icon = 'icons/obj/clothing/gloves.dmi'
siemens_coefficient = 0.75
siemens_coefficient = 0.9
var/wired = 0
var/obj/item/weapon/cell/cell = 0
var/fingerprint_chance = 0 //How likely the glove is to let fingerprints through
+7 -6
View File
@@ -6,21 +6,22 @@
permeability_coefficient = 0.05
/obj/item/clothing/gloves/fyellow //Cheap Chinese Crap
desc = "These gloves are cheap copies of the coveted gloves, no way this can end badly."
desc = "These gloves are cheap copies of proper insulated gloves. No way this can end badly."
name = "budget insulated gloves"
icon_state = "yellow"
siemens_coefficient = 1 //Set to a default of 1, gets overridden in New()
siemens_coefficient = 1 //Set to a default of 1, gets overridden in initialize()
permeability_coefficient = 0.05
New()
//average of 0.5, somewhat better than regular gloves' 0.75
siemens_coefficient = pick(0,0.1,0.3,0.5,0.5,0.75,1.35)
/obj/item/clothing/gloves/fyellow/initialize()
. = ..()
//Picks a value between 0 and 1, in 5% increments
var/shock_pick = rand(0,20)
siemens_coefficient = shock_pick * 0.05
/obj/item/clothing/gloves/black
desc = "These work gloves are thick and fire-resistant."
name = "black gloves"
icon_state = "black"
siemens_coefficient = 0.50
permeability_coefficient = 0.05
cold_protection = HANDS
@@ -16,7 +16,6 @@
name = "forensic gloves"
icon_state = "forensic"
item_state = "black"
siemens_coefficient = 0.50
permeability_coefficient = 0.05
cold_protection = HANDS
@@ -81,14 +80,13 @@
icon_state = "leather"
item_state_slots = list(slot_r_hand_str = "lightbrown", slot_l_hand_str = "lightbrown")
permeability_coefficient = 0.05
siemens_coefficient = 0.50 //thick work gloves
siemens_coefficient = 0.75 //thick work gloves
/obj/item/clothing/gloves/duty
desc = "These brown duty gloves are made from a durable synthetic."
name = "work gloves"
icon_state = "work"
item_state = "wgloves"
siemens_coefficient = 0.50
armor = list(melee = 10, bullet = 10, laser = 10, energy = 5, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/gloves/tactical
@@ -97,7 +95,7 @@
icon_state = "work"
item_state = "wgloves"
force = 5
siemens_coefficient = 0.50
siemens_coefficient = 0.75
permeability_coefficient = 0.05
armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0)
@@ -46,9 +46,6 @@
var/obj/item/ai_card // Reference to the MMI, posibrain, intellicard or pAI card previously holding the AI.
var/obj/item/ai_verbs/verb_holder
/mob
var/get_rig_stats = 0
/obj/item/rig_module/ai_container/process()
if(integrated_ai)
var/obj/item/weapon/rig/rig = get_rig()
@@ -153,10 +153,10 @@
//Medical Streamlined Voidsuit
/obj/item/clothing/head/helmet/space/void/medical/alt
name = "streamlined medical voidsuit helmet"
desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a fetching green."
desc = "A trendy, lightly radiation-shielded voidsuit helmet trimmed in a sleek blue."
icon_state = "rig0-medicalalt"
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 80)
light_overlay = "helmet_light_dual_green"
light_overlay = "helmet_light_dual_blue"
/obj/item/clothing/suit/space/void/medical/alt
icon_state = "rig-medicalalt"
+1 -1
View File
@@ -269,7 +269,7 @@
//Medical
/obj/item/clothing/suit/armor/vest/ert/medical
name = "emergency response team medical armor"
desc = "A set of armor worn by medical members of the Emergency Response Team. Has red and white highlights."
desc = "A set of armor worn by medical members of the Emergency Response Team. Has blue and white highlights."
icon_state = "ertarmor_med"
//New Vests
+2 -2
View File
@@ -782,7 +782,7 @@ obj/item/clothing/suit/storage/toggle/peacoat
hooded = TRUE
hoodtype = /obj/item/clothing/head/hood/explorer
siemens_coefficient = 0.9
armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 50, bio = 100, rad = 50) // Inferior to sec vests in bullet/laser but better for environmental protection.
armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 35, bio = 75, rad = 35) // Inferior to sec vests in bullet/laser but better for environmental protection.
allowed = list(
/obj/item/device/flashlight,
/obj/item/weapon/gun,
@@ -807,7 +807,7 @@ obj/item/clothing/suit/storage/toggle/peacoat
flags_inv = HIDEEARS | BLOCKHAIR
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 50, bio = 100, rad = 50)
armor = list(melee = 30, bullet = 20, laser = 20, energy = 20, bomb = 35, bio = 75, rad = 35)
/obj/item/clothing/suit/varsity
name = "black varsity jacket"
+3 -3
View File
@@ -26,13 +26,13 @@
var/rng = rand(1,5)
switch(rng)
if(1)
msg = "A combat drone wing operating near various asteroids in the Kara subsystem has failed to return from a anti-piracy sweep. If any are sighted, \
msg = "A combat drone wing operating in close orbit above Sif has failed to return from a anti-piracy sweep. If any are sighted, \
approach with caution."
if(2)
msg = "Contact has been lost with a combat drone wing operating out in the asteroid field near Kara. If any are sighted in the area, approach with \
msg = "Contact has been lost with a combat drone wing in Sif orbit. If any are sighted in the area, approach with \
caution."
if(3)
msg = "Unidentified hackers have targeted a combat drone wing deployed in the Kara subsystem. If any are sighted in the area, approach with caution."
msg = "Unidentified hackers have targeted a combat drone wing deployed around Sif. If any are sighted in the area, approach with caution."
if(4)
msg = "A passing derelict ship's drone defense systems have just activated. If any are sighted in the area, use caution."
if(5)
+2 -1
View File
@@ -173,7 +173,8 @@
H.concealed = 1
H.update_icon()
if(user==target)
user.visible_message("<span class = 'notice'>\The [user] deals [dcard] card(s) to \himself.</span>")
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class = 'notice'>\The [user] deals [dcard] card(s) to [TU.himself].</span>")
else
user.visible_message("<span class = 'notice'>\The [user] deals [dcard] card(s) to \the [target].</span>")
H.throw_at(get_step(target,target.dir),10,1,H)
+2 -1
View File
@@ -68,7 +68,8 @@
duration = 10*30
start(mob/living/carbon/human/H)
H.emote("me", 1, "has drool running down from [H.gender == MALE ? "his" : H.gender == FEMALE ? "her" : "their"] mouth.")
var/datum/gender/T = gender_datums[H.get_visible_gender()]
H.emote("me", 1, "has drool running down from [T.his] mouth.")
finish(mob/living/carbon/human/H)
if(!H.reagents.has_reagent("anti_toxin"))
+2 -1
View File
@@ -149,8 +149,9 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
dat += "<A href='?src=\ref[src];switchscreen=7'>7. Access the Forbidden Lore Vault</A><BR>"
if(src.arcanecheckout)
new /obj/item/weapon/book/tome(src.loc)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user << "<span class='warning'>Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.</span>"
user.visible_message("<span class='notice'>\The [user] stares at the blank screen for a few moments, \his expression frozen in fear. When \he finally awakens from it, \he looks a lot older.</span>", 2)
user.visible_message("<span class='notice'>\The [user] stares at the blank screen for a few moments, [T.his] expression frozen in fear. When [T.he] finally awakens from it, [T.he] looks a lot older.</span>", 2)
src.arcanecheckout = 0
if(1)
// Inventory
+15 -1
View File
@@ -5,6 +5,7 @@
articles. You are encouraged to check back frequently."
children = list(
/datum/lore/codex/page/article1,
/datum/lore/codex/page/article2,
/datum/lore/codex/page/about_news,
)
@@ -31,4 +32,17 @@
<br></br>\
The bill passed fairly quietly this afternoon, owing to the closed nature of the Bicamarial. A post-facto Occulum poll of voting-age\
VGA citizens suggest that fully 80% of them did not even know what a Promethean was prior to the most recent general election. A\
follow-up poll indicates that an appreciable number of Sivians do not support the framework's current implementation."
follow-up poll indicates that an appreciable number of Sivians do not support the framework's current implementation."
/datum/lore/codex/page/article2
name = "2/3/62-- Corporate Coup on Aetolus"
data = "A recent incident aboard the NRS Prometheus issued in a major change in the leadership of the Promethean homeworld. During \
a late-night meeting of the Nanotrasen Board of Trustees, several high-ranking personnel, including Head of Research Naomi Harper,\
announced their intention to assume direct control of Nanotrasen facilities in the system. It is known that several dissenting \
members of the board were shot to death by Promethean test subjects. Our information comes from a survivor of the coup, who for \
reasons of security has chosen to remain annonymous. All outbound shipments affiliated with Nanotrasen have ceased.\
<br><br>\
While neither Grayson Manufacturies nor Nanotrasen have made an official statement, Nanotrasen CEO Albary Moravec has called the \
incident \"shocking, if the allegations are to be believed\" and has assured shareholders that Nanotrasen will respond to the \
incident with as much force as it warrents.<br><br>Requests for a statement directed to the Board of Trustees or Dr. Harper were \
not responded to. Free Traders are recommended to stay clear of the region until the situation resolves itself."
@@ -94,6 +94,13 @@
apply_colour = 1
no_variants = FALSE
/obj/item/stack/material/lead
name = "lead"
icon_state = "sheet-adamantine"
default_type = "lead"
apply_colour = 1
no_variants = TRUE
/obj/item/stack/material/sandstone
name = "sandstone brick"
icon_state = "sheet-sandstone"
+28 -3
View File
@@ -99,6 +99,7 @@ var/list/name_to_material
var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10.
var/list/composite_material // If set, object matter var will be a list containing these values.
var/luminescence
var/radiation_resistance = 20 // Radiation resistance, used in calculating how much radiation a material absorbs. Equivlent to weight, but does not affect weaponry.
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
var/created_window
@@ -236,6 +237,7 @@ var/list/name_to_material
weight = 22
stack_origin_tech = list(TECH_MATERIAL = 5)
door_icon_base = "stone"
radiation_resistance = 80 //dense, so it's okay-ish as rad shielding.
/material/diamond
name = "diamond"
@@ -261,6 +263,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 4)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
radiation_resistance = 120 //gold is dense.
/material/gold/bronze //placeholder for ashtrays
name = "bronze"
@@ -276,7 +279,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 3)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
radiation_resistance = 22
//R-UST port
/material/supermatter
name = "supermatter"
@@ -337,6 +340,7 @@ var/list/name_to_material
door_icon_base = "stone"
sheet_singular_name = "brick"
sheet_plural_name = "bricks"
radiation_resistance = 22
/material/stone/marble
name = "marble"
@@ -345,6 +349,7 @@ var/list/name_to_material
hardness = 100
integrity = 201 //hack to stop kitchen benches being flippable, todo: refactor into weight system
stack_type = /obj/item/stack/material/marble
radiation_resistance = 26
/material/steel
name = DEFAULT_WALL_MATERIAL
@@ -391,6 +396,7 @@ var/list/name_to_material
conductivity = 13 // For the purposes of balance.
stack_origin_tech = list(TECH_MATERIAL = 2)
composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo
radiation_resistance = 60 //Plasteel is presumably dense and is the dominant material used in the engine. Still not great.
// Very rare alloy that is reflective, should be used sparingly.
/material/durasteel
@@ -408,6 +414,7 @@ var/list/name_to_material
reflectivity = 0.7 // Not a perfect mirror, but close.
stack_origin_tech = list(TECH_MATERIAL = 8)
composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug
radiation_resistance = 120 //it reflects XRAY LASERS.
/material/plasteel/titanium
name = "titanium"
@@ -436,6 +443,7 @@ var/list/name_to_material
window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2)
created_window = /obj/structure/window/basic
rod_product = /obj/item/stack/material/glass/reinforced
radiation_resistance = 15
/material/glass/build_windows(var/mob/living/user, var/obj/item/stack/used_stack)
@@ -527,6 +535,7 @@ var/list/name_to_material
created_window = /obj/structure/window/reinforced
wire_product = null
rod_product = null
radiation_resistance = 30
/material/glass/phoron
name = "borosilicate glass"
@@ -554,6 +563,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 2)
composite_material = list() //todo
rod_product = null
radiation_resistance = 30
/material/plastic
name = "plastic"
@@ -568,6 +578,7 @@ var/list/name_to_material
conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator.
melting_point = T0C+371 //assuming heat resistant plastic
stack_origin_tech = list(TECH_MATERIAL = 3)
radiation_resistance = 12
/material/plastic/holographic
name = "holoplastic"
@@ -618,6 +629,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 2)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
radiation_resistance = 27
/material/iron
name = "iron"
@@ -627,6 +639,17 @@ var/list/name_to_material
conductivity = 10
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
radiation_resistance = 22
/material/lead
name = "lead"
stack_type = /obj/item/stack/material/lead
icon_colour = "#273956"
weight = 35
conductivity = 10
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
radiation_resistance = 350 //actual radiation shielding, yay...
// Adminspawn only, do not let anyone get this.
/material/alienalloy
@@ -640,6 +663,7 @@ var/list/name_to_material
hardness = 500
weight = 500
protectiveness = 80 // 80%
radiation_resistance = 500
// Likewise.
/material/alienalloy/elevatorium
@@ -697,6 +721,7 @@ var/list/name_to_material
destruction_desc = "splinters"
sheet_singular_name = "plank"
sheet_plural_name = "planks"
radiation_resistance = 18
/material/wood/log
name = MAT_LOG
@@ -739,7 +764,7 @@ var/list/name_to_material
stack_origin_tech = list(TECH_MATERIAL = 1)
door_icon_base = "wood"
destruction_desc = "crumples"
radiation_resistance = 1
/material/snow
name = MAT_SNOW
stack_type = /obj/item/stack/material/snow
@@ -756,7 +781,7 @@ var/list/name_to_material
destruction_desc = "crumples"
sheet_singular_name = "pile"
sheet_plural_name = "pile" //Just a bigger pile
radiation_resistance = 1
/material/cloth //todo
name = "cloth"
stack_origin_tech = list(TECH_MATERIAL = 2)
+2 -1
View File
@@ -630,8 +630,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
)
toggle_visibility(TRUE)
else
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message ( \
"<span class='warning'>\The [user] just tried to smash \his book into that ghost! It's not very effective.</span>", \
"<span class='warning'>\The [user] just tried to smash [T.his] book into that ghost! It's not very effective.</span>", \
"<span class='warning'>You get the feeling that the ghost can't become any more visible.</span>" \
)
+12
View File
@@ -18,6 +18,9 @@
var/has = "have"
var/is = "are"
var/does = "do"
var/himself = "themselves"
var/s = ""
var/hes = "they're"
/datum/gender/male
key = "male"
@@ -30,6 +33,9 @@
has = "has"
is = "is"
does = "does"
himself = "himself"
s = "s"
hes = "he's"
/datum/gender/female
key = "female"
@@ -42,6 +48,9 @@
has = "has"
is = "is"
does = "does"
himself = "herself"
s = "s"
hes = "she's"
/datum/gender/neuter
key = "neuter"
@@ -54,3 +63,6 @@
has = "has"
is = "is"
does = "does"
himself = "itself"
s = "s"
hes = "it's"
+12 -14
View File
@@ -168,8 +168,9 @@
if (src.health >= config.health_threshold_crit)
if(src == M && istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/datum/gender/T = gender_datums[H.get_visible_gender()]
src.visible_message( \
text("<font color='blue'>[src] examines [].</font>",src.gender==MALE?"himself":"herself"), \
"<font color='blue'>[src] examines [T.himself].</font>", \
"<font color='blue'>You check yourself for injuries.</font>" \
)
@@ -243,33 +244,30 @@
src.ExtinguishMob()
src.fire_stacks = 0
else
var/t_him = "it"
if (src.gender == MALE)
t_him = "him"
else if (src.gender == FEMALE)
t_him = "her"
if (istype(src,/mob/living/carbon/human) && src:w_uniform)
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
var/show_ssd
var/mob/living/carbon/human/H = src
var/datum/gender/T = gender_datums[H.get_visible_gender()] // make sure to cast to human before using get_gender() or get_visible_gender()!
if(istype(H)) show_ssd = H.species.show_ssd
if(show_ssd && !client && !teleop)
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
"<span class='notice'>You shake [src], but they do not respond... Maybe they have S.S.D?</span>")
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [T.him] up!</span>", \
"<span class='notice'>You shake [src], but [T.he] [T.does] not respond... Maybe [T.he] [T.has] S.S.D?</span>")
else if(lying || src.sleeping)
src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0)
src.resting = 0
if(H) H.in_stasis = 0 //VOREStation Add - Just In Case
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
"<span class='notice'>You shake [src] trying to wake [t_him] up!</span>")
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [T.him] up!</span>", \
"<span class='notice'>You shake [src] trying to wake [T.him] up!</span>")
else
var/mob/living/carbon/human/hugger = M
var/datum/gender/TM = gender_datums[M.get_visible_gender()]
if(M.resting == 1) //Are they resting on the ground?
M.visible_message("<span class='notice'>[M] grabs onto [src] and pulls \himself up</span>", \
"<span class='notice'>You grip onto [src] and pull yourself up off the ground!</span>") //AHHH gender checks are hard, but this should work
M.visible_message("<span class='notice'>[M] grabs onto [src] and pulls [TM.himself] up</span>", \
"<span class='notice'>You grip onto [src] and pull yourself up off the ground!</span>")
if(M.fire_stacks >= (src.fire_stacks + 3)) //Fire checks.
src.adjust_fire_stacks(1)
M.adjust_fire_stacks(-1)
@@ -280,8 +278,8 @@
else if(istype(hugger))
hugger.species.hug(hugger,src)
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [src] to make [t_him] feel better!</span>")
M.visible_message("<span class='notice'>[M] hugs [src] to make [T.him] feel better!</span>", \
"<span class='notice'>You hug [src] to make [T.him] feel better!</span>")
if(M.fire_stacks >= (src.fire_stacks + 3))
src.adjust_fire_stacks(1)
M.adjust_fire_stacks(-1)
+22 -18
View File
@@ -1,5 +1,7 @@
/mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null)
var/param = null
var/datum/gender/T = gender_datums[get_visible_gender()]
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
@@ -58,13 +60,13 @@
use_sound = 'sound/machines/synth_no.ogg'
else if(act == "rcough")
display_msg = "emits a robotic cough"
if(gender == FEMALE)
if(get_gender() == FEMALE)
use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg')
else
use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg')
else if(act == "rsneeze")
display_msg = "emits a robotic sneeze"
if(gender == FEMALE)
if(get_gender() == FEMALE)
use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg'
else
use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
@@ -162,7 +164,7 @@
if ("choke")
if(miming)
message = "clutches [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] throat desperately!"
message = "clutches [T.his] throat desperately!"
m_type = 1
else
if (!muzzled)
@@ -182,14 +184,14 @@
if ("flap")
if (!src.restrained())
message = "flaps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] wings."
message = "flaps [T.his] wings."
m_type = 2
if(miming)
m_type = 1
if ("aflap")
if (!src.restrained())
message = "flaps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] wings ANGRILY!"
message = "flaps [T.his] wings ANGRILY!"
m_type = 2
if(miming)
m_type = 1
@@ -243,7 +245,7 @@
robotic = 1
if(!robotic)
message = "coughs!"
if(gender == FEMALE)
if(get_gender() == FEMALE)
if(species.female_cough_sounds)
playsound(src, pick(species.female_cough_sounds), 120)
else
@@ -252,7 +254,7 @@
else
message = "emits a robotic cough"
var/use_sound
if(gender == FEMALE)
if(get_gender() == FEMALE)
use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg')
else
use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg')
@@ -365,7 +367,7 @@
message = "cries."
m_type = 2
else
message = "makes a weak noise. [get_visible_gender() == MALE ? "He" : get_visible_gender() == FEMALE ? "She" : "They"] [get_visible_gender() == NEUTER ? "frown" : "frowns"]."
message = "makes a weak noise. [T.he] [get_visible_gender() == NEUTER ? "frown" : "frowns"]." // no good, non-unwieldy alternative to this ternary at the moment
m_type = 2
if ("sigh")
@@ -468,7 +470,7 @@
m_type = 1
if("shake")
message = "shakes [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] head."
message = "shakes [T.his] head."
m_type = 1
if ("shrug")
@@ -517,7 +519,7 @@
robotic = 1
if(!robotic)
message = "sneezes."
if(gender == FEMALE)
if(get_gender() == FEMALE)
playsound(src, species.female_sneeze_sound, 70)
else
playsound(src, species.male_sneeze_sound, 70)
@@ -525,7 +527,7 @@
else
message = "emits a robotic sneeze"
var/use_sound
if(gender == FEMALE)
if(get_gender() == FEMALE)
use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg'
else
use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
@@ -597,7 +599,7 @@
if (M)
message = "hugs [M]."
else
message = "hugs [get_visible_gender() == MALE ? "himself" : get_visible_gender() == FEMALE ? "herself" : "themselves"]."
message = "hugs [T.himself]."
if ("handshake")
m_type = 1
@@ -615,7 +617,7 @@
if (M.canmove && !M.r_hand && !M.restrained())
message = "shakes hands with [M]."
else
message = "holds out [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] hand to [M]."
message = "holds out [T.his] hand to [M]."
if("dap")
m_type = 1
@@ -629,7 +631,7 @@
if (M)
message = "gives daps to [M]."
else
message = "sadly can't find anybody to give daps to, and daps [get_visible_gender() == MALE ? "himself" : get_visible_gender() == FEMALE ? "herself" : "themselves"]. Shameful."
message = "sadly can't find anybody to give daps to, and daps [T.himself]. Shameful."
if("slap", "slaps")
m_type = 1
@@ -644,7 +646,7 @@
message = "<span class='danger'>slaps [M] across the face. Ouch!</span>"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
else
message = "<span class='danger'>slaps [get_visible_gender() == MALE ? "himself" : get_visible_gender() == FEMALE ? "herself" : "themselves"]!</span>"
message = "<span class='danger'>slaps [T.himself]!</span>"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
if("scream", "screams")
@@ -656,7 +658,7 @@
message = "[species.scream_verb]!"
m_type = 2
/* Removed, pending the location of some actually good, properly licensed sounds.
if(gender == FEMALE)
if(get_gender() == FEMALE)
playsound(loc, "[species.female_scream_sound]", 80, 1)
else
playsound(loc, "[species.male_scream_sound]", 80, 1) //default to male screams if no gender is present.
@@ -681,7 +683,7 @@
to_chat(usr, "You need at least one hand in good working order to snap your fingers.")
return
message = "snaps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] fingers."
message = "snaps [T.his] fingers."
playsound(loc, 'sound/effects/fingersnap.ogg', 50, 1, -3)
if("swish")
@@ -735,8 +737,10 @@
set name = "Set Pose"
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
var/datum/gender/T = gender_datums[get_visible_gender()]
pose = sanitize(input(usr, "This is [src]. [get_visible_gender() == MALE ? "He" : get_visible_gender() == FEMALE ? "She" : "They"]...", "Pose", null) as text)
pose = sanitize(input(usr, "This is [src]. [T.he]...", "Pose", null) as text)
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavour Text"
@@ -85,7 +85,7 @@
var/list/msg = list("<span class='info'>*---------*\nThis is ")
var/datum/gender/T = gender_datums[get_gender()]
var/datum/gender/T = gender_datums[get_visible_gender()]
if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender
T = gender_datums[PLURAL]
+18 -11
View File
@@ -773,7 +773,8 @@
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)
visible_message("<font color='red'>\The [src] begins playing \his ribcage like a xylophone. It's quite spooky.</font>","<font color='blue'>You begin to play a spooky refrain on your ribcage.</font>","<font color='red'>You hear a spooky xylophone melody.</font>")
var/datum/gender/T = gender_datums[get_visible_gender()]
visible_message("<font color='red'>\The [src] begins playing [T.his] ribcage like a xylophone. It's quite spooky.</font>","<font color='blue'>You begin to play a spooky refrain on your ribcage.</font>","<font color='red'>You hear a spooky xylophone melody.</font>")
var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg')
playsound(loc, song, 50, 1, -1)
xylophone = 1
@@ -863,8 +864,8 @@
gender = NEUTER
regenerate_icons()
check_dna()
visible_message("<font color='blue'>\The [src] morphs and changes [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] appearance!</font>", "<font color='blue'>You change your appearance!</font>", "<font color='red'>Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!</font>")
var/datum/gender/T = gender_datums[get_visible_gender()]
visible_message("<font color='blue'>\The [src] morphs and changes [T.his] appearance!</font>", "<font color='blue'>You change your appearance!</font>", "<font color='red'>Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!</font>")
/mob/living/carbon/human/proc/remotesay()
set name = "Project mind"
@@ -932,10 +933,13 @@
remoteview_target = null
reset_view(0)
/mob/living/carbon/human/proc/get_visible_gender()
/mob/living/carbon/human/get_visible_gender()
if(wear_suit && wear_suit.flags_inv & HIDEJUMPSUIT && ((head && head.flags_inv & HIDEMASK) || wear_mask))
return NEUTER
return gender
return PLURAL //plural is the gender-neutral default
if(species)
if(species.ambiguous_genders)
return PLURAL // regardless of what you're wearing, your gender can't be figured out
return get_gender()
/mob/living/carbon/human/proc/increase_germ_level(n)
if(gloves)
@@ -1091,14 +1095,17 @@
var/self = 0
if(usr.stat || usr.restrained() || !isliving(usr)) return
var/datum/gender/TU = gender_datums[usr.get_visible_gender()]
var/datum/gender/T = gender_datums[get_visible_gender()]
if(usr == src)
self = 1
if(!self)
usr.visible_message("<span class='notice'>[usr] kneels down, puts \his hand on [src]'s wrist and begins counting their pulse.</span>",\
usr.visible_message("<span class='notice'>[usr] kneels down, puts [TU.his] hand on [src]'s wrist and begins counting [T.his] pulse.</span>",\
"You begin counting [src]'s pulse")
else
usr.visible_message("<span class='notice'>[usr] begins counting their pulse.</span>",\
usr.visible_message("<span class='notice'>[usr] begins counting [T.his] pulse.</span>",\
"You begin counting your pulse.")
if(src.pulse)
@@ -1356,9 +1363,9 @@
if(..(slipped_on,stun_duration))
return 1
/mob/living/carbon/human/proc/undislocate()
/mob/living/carbon/human/proc/relocate()
set category = "Object"
set name = "Undislocate Joint"
set name = "Relocate Joint"
set desc = "Pop a joint back into place. Extremely painful."
set src in view(1)
@@ -1406,7 +1413,7 @@
else
U << "<span class='danger'>You pop [S]'s [current_limb.joint] back in!</span>"
S << "<span class='danger'>[U] pops your [current_limb.joint] back in!</span>"
current_limb.undislocate()
current_limb.relocate()
/mob/living/carbon/human/drop_from_inventory(var/obj/item/W, var/atom/Target = null)
if(W in organs)
@@ -18,6 +18,7 @@
return null
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
var/datum/gender/TT = gender_datums[M.get_visible_gender()]
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
@@ -131,7 +132,7 @@
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
if(buckled)
M << "<span class='notice'>You cannot grab [src], \he is buckled in!</span>"
M << "<span class='notice'>You cannot grab [src], [TT.he] is buckled in!</span>"
if(!G) //the grab will delete itself in New if affecting is anchored
return
M.put_in_active_hand(G)
@@ -228,7 +229,7 @@
if(!src.lying)
attack_message = "[H] attempted to strike [src], but missed!"
else
attack_message = "[H] attempted to strike [src], but \he rolled out of the way!"
attack_message = "[H] attempted to strike [src], but [TT.he] rolled out of the way!"
src.set_dir(pick(cardinal))
miss_type = 1
@@ -417,8 +418,10 @@
user << "<span class='warning'>Someone is already applying pressure to [user == src? "your [organ.name]" : "[src]'s [organ.name]"].</span>"
return 0
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if(user == src)
user.visible_message("\The [user] starts applying pressure to \his [organ.name]!", "You start applying pressure to your [organ.name]!")
user.visible_message("\The [user] starts applying pressure to [TU.his] [organ.name]!", "You start applying pressure to your [organ.name]!")
else
user.visible_message("\The [user] starts applying pressure to [src]'s [organ.name]!", "You start applying pressure to [src]'s [organ.name]!")
spawn(0)
@@ -430,7 +433,7 @@
organ.applied_pressure = null
if(user == src)
user.visible_message("\The [user] stops applying pressure to \his [organ.name]!", "You stop applying pressure to your [organ]!")
user.visible_message("\The [user] stops applying pressure to [TU.his] [organ.name]!", "You stop applying pressure to your [organ]!")
else
user.visible_message("\The [user] stops applying pressure to [src]'s [organ.name]!", "You stop applying pressure to [src]'s [organ.name]!")
@@ -24,12 +24,13 @@
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/skill = user.skills["combat"]
var/obj/item/organ/external/affecting = target.get_organ(zone)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
if(!skill) skill = 1
attack_damage = Clamp(attack_damage, 1, 5)
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.name]!</span>")
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [T.himself] in the [affecting.name]!</span>")
return 0
switch(zone)
@@ -37,20 +38,20 @@
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2)
user.visible_message("<span class='danger'>[user] scratched [target] across \his cheek!</span>")
user.visible_message("<span class='danger'>[user] scratched [target] across [TT.his] cheek!</span>")
if(3 to 4)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target]'s [pick("head", "neck")]!</span>") //'with spread claws' sounds a little bit odd, just enough that conciseness is better here I think
if(5)
user.visible_message(pick(
"<span class='danger'>[user] rakes \his [pick(attack_noun)] across [target]'s face!</span>",
"<span class='danger'>[user] tears \his [pick(attack_noun)] into [target]'s face!</span>",
"<span class='danger'>[user] rakes [T.his] [pick(attack_noun)] across [target]'s face!</span>",
"<span class='danger'>[user] tears [T.his] [pick(attack_noun)] into [target]'s face!</span>",
))
else
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target]'s [affecting.name]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears [T.his] [pick(attack_noun)] [pick("deep into", "into", "across")] [target]'s [affecting.name]!</span>")
/datum/unarmed_attack/claws/strong
attack_verb = list("slashed")
@@ -44,6 +44,7 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
var/stun_chance = rand(0, 100)
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
switch(zone) // strong punches can have effects depending on where they hit
@@ -74,7 +75,7 @@ var/global/list/sparring_attack_cache = list()
target.set_dir(reverse_dir[target.dir])
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if(BP_GROIN)
target.visible_message("<span class='warning'>[target] looks like \he is in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>")
target.visible_message("<span class='warning'>[target] looks like [TT.he] [TT.is] in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>") // I see no easy way to fix this for non-organic or neuter characters.
target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour)
if("l_leg", "l_foot", "r_leg", "r_foot")
if(!target.lying)
@@ -94,13 +95,15 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target)
var/obj/item/organ/internal/eyes/eyes = target.internal_organs_by_name[O_EYES]
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
if(eyes)
eyes.take_damage(rand(3,4), 1)
user.visible_message("<span class='danger'>[user] presses \his [eye_attack_text] into [target]'s [eyes.name]!</span>")
user.visible_message("<span class='danger'>[user] presses [TU.his] [eye_attack_text] into [target]'s [eyes.name]!</span>")
var/eye_pain = eyes.organ_can_feel_pain()
target << "<span class='danger'>You experience[(eye_pain) ? "" : " immense pain as you feel" ] [eye_attack_text_victim] being pressed into your [eyes.name][(eye_pain)? "." : "!"]</span>"
return
user.visible_message("<span class='danger'>[user] attempts to press \his [eye_attack_text] into [target]'s eyes, but they don't have any!</span>")
user.visible_message("<span class='danger'>[user] attempts to press [TU.his] [eye_attack_text] into [target]'s eyes, but [TT.he] [TT.does]n't have any!</span>")
/datum/unarmed_attack/bite
attack_verb = list("bit")
@@ -128,11 +131,14 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/obj/item/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.name
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case.
if(target == user)
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] \himself in the [organ]!</span>")
user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [TU.himself] in the [organ]!</span>")
return 0
if(!target.lying)
@@ -141,7 +147,7 @@ var/global/list/sparring_attack_cache = list()
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2)
user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
user.visible_message("<span class='danger'>[user] slapped [target] across [TT.his] cheek!</span>")
if(3 to 4)
user.visible_message(pick(
40; "<span class='danger'>[user] [pick(attack_verb)] [target] in the head!</span>",
@@ -151,21 +157,21 @@ var/global/list/sparring_attack_cache = list()
if(5)
user.visible_message(pick(
30; "<span class='danger'>[user] gave [target] a resounding [pick("slap", "punch")] to the face!</span>",
40; "<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s face!</span>",
40; "<span class='danger'>[user] smashed [TU.his] [pick(attack_noun)] into [target]'s face!</span>",
30; "<span class='danger'>[user] gave a strong blow against [target]'s jaw!</span>"
))
else
// ----- BODY ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] threw a glancing punch at [target]'s [organ]!</span>")
if(1 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(1 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in [TT.his] [organ]!</span>")
if(5)
user.visible_message(pick(
50; "<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s [organ]!</span>",
50; "<span class='danger'>[user] smashed [TU.his] [pick(attack_noun)] into [target]'s [organ]!</span>",
50; "<span class='danger'>[user] landed a striking [pick(attack_noun)] on [target]'s [organ]!</span>"
))
else
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch against", "struck", "slammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>") //why do we have a separate set of verbs for lying targets?
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch against", "struck", "slammed [TU.his] [pick(attack_noun)] into")] [target]'s [organ]!</span>") //why do we have a separate set of verbs for lying targets?
/datum/unarmed_attack/kick
attack_verb = list("kicked", "kicked", "kicked", "kneed")
@@ -198,13 +204,14 @@ var/global/list/sparring_attack_cache = list()
/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/obj/item/organ/external/affecting = target.get_organ(zone)
var/datum/gender/TT = gender_datums[target.get_visible_gender()]
var/organ = affecting.name
attack_damage = Clamp(attack_damage, 1, 5)
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] threw [target] a glancing [pick(attack_noun)] to the [organ]!</span>") //it's not that they're kicking lightly, it's that the kick didn't quite connect
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in [TT.his] [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!</span>")
/datum/unarmed_attack/stomp
@@ -242,12 +249,13 @@ var/global/list/sparring_attack_cache = list()
var/obj/item/organ/external/affecting = target.get_organ(zone)
var/organ = affecting.name
var/obj/item/clothing/shoes = user.shoes
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
attack_damage = Clamp(attack_damage, 1, 5)
switch(attack_damage)
if(1 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
if(1 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed [TU.his] [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed [TU.his] [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
/datum/unarmed_attack/light_strike
deal_halloss = 3
@@ -62,11 +62,12 @@
count++
// Check the carrier
var/datum/gender/TM = gender_datums[M.get_visible_gender()]
var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No")
if(answer == "Yes")
var/turf/T = get_turf_or_move(P.loc)
for (var/mob/v in viewers(T))
v.show_message("<span class='notice'>[M] presses \his thumb against [P].</span>", 3, "<span class='notice'>[P] makes a sharp clicking sound as it extracts DNA material from [M].</span>", 2)
v.show_message("<span class='notice'>[M] presses [TM.his] thumb against [P].</span>", 3, "<span class='notice'>[P] makes a sharp clicking sound as it extracts DNA material from [M].</span>", 2)
var/datum/dna/dna = M.dna
P << "<font color = red><h3>[M]'s UE string : [dna.unique_enzymes]</h3></font>"
if(dna.unique_enzymes == P.master_dna)
@@ -74,7 +75,7 @@
else
P << "<b>DNA does not match stored Master DNA.</b>"
else
P << "[M] does not seem like \he is going to provide a DNA sample willingly."
P << "[M] does not seem like [TM.he] is going to provide a DNA sample willingly."
return 1
/datum/pai_software/radio_config
@@ -173,7 +173,7 @@ var/list/mob_hat_cache = list()
return
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if(stat == 2)
if(!config.allow_drone_spawn || emagged || health < -35) //It's dead, Dave.
@@ -184,7 +184,7 @@ var/list/mob_hat_cache = list()
to_chat(user, "<span class='danger'>Access denied.</span>")
return
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to reboot it.</span>", "<span class='danger'>>You swipe your ID card through \the [src], attempting to reboot it.</span>")
user.visible_message("<span class='danger'>\The [user] swipes [TU.his] ID card through \the [src], attempting to reboot it.</span>", "<span class='danger'>>You swipe your ID card through \the [src], attempting to reboot it.</span>")
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
if(D.key && D.client)
@@ -194,7 +194,7 @@ var/list/mob_hat_cache = list()
return
else
user.visible_message("<span class='danger'>\The [user] swipes \his ID card through \the [src], attempting to shut it down.</span>", "<span class='danger'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
user.visible_message("<span class='danger'>\The [user] swipes [TU.his] ID card through \the [src], attempting to shut it down.</span>", "<span class='danger'>You swipe your ID card through \the [src], attempting to shut it down.</span>")
if(emagged)
return
@@ -232,11 +232,12 @@ var/list/mob_hat_cache = list()
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>"
src << "<span class='danger'>ALERT: [user.real_name] [TU.is] your new master. Obey your new laws and [TU.his] commands.</span>"
return 1
//DRONE LIFE/DEATH
@@ -1071,7 +1071,8 @@
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people \he designates as being such are operatives.")
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.")
. = 1
spawn()
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
@@ -1089,7 +1090,7 @@
src << "<span class='danger'>ERRORERRORERROR</span>"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and his commands.</span>"
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and [TU.his] commands.</span>"
updateicon()
else
user << "You fail to hack [src]'s interface."
@@ -219,7 +219,7 @@
speak_chance = 5
speak = list("Shuhn","Shrunnph?","Shunpf")
emote_see = list("scratches the ground","shakes out it's mane","tinkles gently")
emote_see = list("scratches the ground","shakes out its mane","clinks gently as it moves")
/mob/living/simple_animal/yithian
name = "yithian"
@@ -584,7 +584,8 @@
if ((M.client && !( M.blinded )))
M.show_message("<span class='notice'>[user] applies the [MED] on [src].</span>")
else
user << "<span class='notice'>\The [src] is dead, medical items won't bring \him back to life.</span>"
var/datum/gender/T = gender_datums[src.get_visible_gender()]
user << "<span class='notice'>\The [src] is dead, medical items won't bring [T.him] back to life.</span>" // the gender lookup is somewhat overkill, but it functions identically to the obsolete gender macros and future-proofs this code
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/material/knife) || istype(O, /obj/item/weapon/material/knife/butch))
harvest(user)
@@ -752,13 +753,13 @@
if(stat || M == target_mob) return //Not if we're dead or already hitting them
if(M in friends || M.faction == faction) return //I'll overlook it THIS time...
ai_log("react_to_attack([M])",1)
if(retaliate && set_target(M))
if(retaliate && set_target(M, 1))
handle_stance(STANCE_ATTACK)
return M
return 0
/mob/living/simple_animal/proc/set_target(var/mob/M)
/mob/living/simple_animal/proc/set_target(var/mob/M, forced = 0)
ai_log("SetTarget([M])",2)
if(!M || (world.time - last_target_time < 5 SECONDS) && target_mob)
ai_log("SetTarget() can't set it again so soon",3)
@@ -772,7 +773,7 @@
annoyed += 14
sleep(1 SECOND) //For realism
if(M in ListTargets(view_range))
if(forced || (M in ListTargets(view_range)))
try_say_list(say_got_target)
target_mob = M
last_target_time = world.time
+3
View File
@@ -648,6 +648,9 @@
/mob/proc/get_gender()
return gender
/mob/proc/get_visible_gender()
return gender
/mob/proc/see(message)
if(!is_active())
return 0
+1 -4
View File
@@ -218,7 +218,4 @@
var/seedarkness = 1 //Determines mob's ability to see shadows. 1 = Normal vision, 0 = darkvision
// Falling things
var/hovering = FALSE // Is the mob floating or flying in some way? If so, don't fall normally. //Not implemented yet, idea is to let them ignore terrain slowdown and falling down floors
var/softfall = FALSE // Is the mob able to lessen their impact upon falling?
var/parachuting = FALSE // Is the mob able to jump out of planes and survive? Don't check this directly outside of CanParachute().
var/get_rig_stats = 0 //Moved from computer.dm
+7 -4
View File
@@ -236,6 +236,8 @@
if(!assailant.canmove || assailant.lying)
qdel(src)
return
var/datum/gender/TU = gender_datums[assailant.get_visible_gender()]
last_action = world.time
@@ -256,7 +258,7 @@
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
return
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
assailant.visible_message("<span class='warning'>[assailant] has reinforced [TU.his] grip on [affecting] (now neck)!</span>")
state = GRAB_NECK
icon_state = "grabbed+1"
assailant.set_dir(get_dir(assailant, affecting))
@@ -267,11 +269,11 @@
hud.name = "kill"
affecting.Stun(10) //10 ticks of ensured grab
else if(state < GRAB_UPGRADING)
assailant.visible_message("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
assailant.visible_message("<span class='danger'>[assailant] starts to tighten [TU.his] grip on [affecting]'s neck!</span>")
hud.icon_state = "kill1"
state = GRAB_KILL
assailant.visible_message("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
assailant.visible_message("<span class='danger'>[assailant] has tightened [TU.his] grip on [affecting]'s neck!</span>")
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
@@ -347,7 +349,8 @@
/obj/item/weapon/grab/proc/reset_kill_state()
if(state == GRAB_KILL)
assailant.visible_message("<span class='warning'>[assailant] lost \his tight grip on [affecting]'s neck!</span>")
var/datum/gender/T = gender_datums[assailant.get_visible_gender()]
assailant.visible_message("<span class='warning'>[assailant] lost [T.his] tight grip on [affecting]'s neck!</span>")
hud.icon_state = "kill"
state = GRAB_NECK
+2 -1
View File
@@ -93,7 +93,8 @@
return
if(target.lying)
return
attacker.visible_message("<span class='danger'>[attacker] thrusts \his head into [target]'s skull!</span>")
var/datum/gender/T = gender_datums[attacker.get_visible_gender()]
attacker.visible_message("<span class='danger'>[attacker] thrusts [T.his] head into [target]'s skull!</span>")
var/damage = 20
var/obj/item/clothing/hat = attacker.head
+63 -76
View File
@@ -403,8 +403,12 @@
/atom/movable/proc/fall_impact(var/atom/hit_atom, var/damage_min = 0, var/damage_max = 10, var/silent = FALSE, var/planetary = FALSE)
if(!silent)
visible_message("\The [src] falls from above and slams into \the [hit_atom]!", "You hear something slam into \the [hit_atom].")
for(var/atom/movable/A in src.contents)
A.fall_impact(hit_atom, damage_min, damage_max, silent = TRUE)
/mob/living/fall_impact(var/turf/landing, var/damage_min = 0, var/damage_max = 30, var/silent = FALSE, var/planetary = FALSE)
// Take damage from falling and hitting the ground
/mob/living/fall_impact(var/atom/hit_atom, var/damage_min = 0, var/damage_max = 10, var/silent = FALSE, var/planetary = FALSE)
var/turf/landing = get_turf(hit_atom)
if(planetary && src.CanParachute())
if(!silent)
visible_message("<span class='warning'>\The [src] glides in from above and lands on \the [landing]!</span>", \
@@ -431,67 +435,32 @@
"You hear something slam into \the [landing].")
playsound(loc, "punch", 25, 1, -1)
if(planetary) //Since the planetary fall damage is calibrated for humans, we need to up this a bit
damage_min *= 2
damage_max *= 2
adjustBruteLoss(rand(damage_min, damage_max))
return
return
/mob/living/carbon/human/fall_impact(var/turf/landing, var/damage_min = 0, var/damage_max = 10, var/silent = FALSE, var/planetary = FALSE)
if(planetary && src.CanParachute())
if(!silent)
visible_message("<span class='warning'>\The [src] glides in from above and lands on \the [landing]!</span>", \
"<span class='danger'>You land on \the [landing]!</span>", \
"You hear something land \the [landing].")
return
else if(!planetary && src.softfall) // Falling one floor and falling one atmosphere are very different things
if(!silent)
visible_message("<span class='warning'>\The [src] falls from above and lands on \the [landing]!</span>", \
"<span class='danger'>You land on \the [landing]!</span>", \
"You hear something land \the [landing].")
return
else
if(!silent)
if(planetary)
visible_message("<span class='danger'><font size='3'>\A [src] falls out of the sky and crashes into \the [landing]!</font></span>", \
"<span class='danger'><font size='3'> You fall out of the skiy and crash into \the [landing]!</font></span>", \
"You hear something slam into \the [landing].")
var/turf/T = get_turf(landing)
explosion(T, 0, 1, 2)
else
visible_message("<span class='warning'>\The [src] falls from above and slams into \the [landing]!</span>", \
"<span class='danger'>You fall off and hit \the [landing]!</span>", \
"You hear something slam into \the [landing].")
playsound(loc, "punch", 25, 1, -1)
var/mob/living/carbon/human/pred = src //VOREStation Edit Start
if(istype(landing, /mob)) //If you land on someone, don't get hurt a second time
Weaken(10) //In exchange, you're going to be aching! This prevents you from taking damage twice from hitting the floor and the person.
return
var/belly = src.vore_selected
var/datum/belly/belly_target = pred.vore_organs[belly]
if(belly_target && belly_target.internal_contents.len != 0) //Having stuff in your gut will pad the landing a bit.
damage_max = 5 //VOREStation Edit End
// Because wounds heal rather quickly, 10 should be enough to discourage jumping off but not be enough to ruin you, at least for the first time.
apply_damage(rand(damage_min, damage_max), BRUTE, BP_HEAD)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_TORSO)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_GROIN)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_L_LEG)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_R_LEG)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_L_FOOT)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_R_FOOT)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_L_ARM)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_R_ARM)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_L_HAND)
apply_damage(rand(damage_min, damage_max), BRUTE, BP_R_HAND)
// Because wounds heal rather quickly, 10 (the default for this proc) should be enough to discourage jumping off but not be enough to ruin you, at least for the first time.
// Hits 10 times, because apparently targeting individual limbs lets certain species survive the fall from atmosphere
for(var/i = 1 to 10)
adjustBruteLoss(rand(damage_min, damage_max))
Weaken(4)
updatehealth()
return
return
//Checks if the mob is allowed to survive a fall from space
/mob/living/proc/CanParachute()
//Using /atom/movable instead of /obj/item because I'm not sure what all humans can pick up or wear
/atom/movable
var/parachute = FALSE // Is this thing a parachute itself?
var/hovering = FALSE // Is the thing floating or flying in some way? If so, don't fall normally. //Not implemented yet, idea is to let mobs/mechs ignore terrain slowdown and falling down floors
var/softfall = FALSE // Is the thing able to lessen their impact upon falling?
var/parachuting = FALSE // Is the thing able to jump out of planes and survive? Don't check this directly outside of CanParachute().
/atom/movable/proc/isParachute()
return parachute
//This is what makes the parachute items know they've been used.
//I made it /atom/movable so it can be retooled for other things (mobs, mechs, etc), though it's only currently called in human/CanParachute().
/atom/movable/proc/handleParachute()
return
//Checks if the thing is allowed to survive a fall from space
/atom/movable/proc/CanParachute()
return parachuting
//For humans, this needs to be a wee bit more complicated
@@ -516,19 +485,6 @@
else
return parachuting
//For human falling code
//Using /obj instead of /obj/item because I'm not sure what all humans can pick up or wear
/obj
var/parachute = FALSE
/obj/proc/isParachute()
return parachute
//This is what makes the parachute items know they've been used.
//I made it /atom/movable so it can be retooled for other things (mobs, mechs, etc), though it's only currently called in human/CanParachute().
/atom/movable/proc/handleParachute()
return
//Mech Code
/obj/mecha/handle_fall(var/turf/landing)
// First things first, break any lattice
@@ -542,18 +498,49 @@
return ..()
/obj/mecha/fall_impact(var/atom/hit_atom, var/damage_min = 15, var/damage_max = 30, var/silent = FALSE, var/planetary = FALSE)
// Tell the pilot that they just dropped down with a superheavy mecha.
if(occupant)
to_chat(occupant, "<span class='warning'>\The [src] crashed down onto \the [hit_atom]!</span>")
// Anything on the same tile as the landing tile is gonna have a bad day.
for(var/mob/living/L in hit_atom.contents)
L.visible_message("<span class='danger'>\The [src] crushes \the [L] as it lands on them!</span>")
L.adjustBruteLoss(rand(70, 100))
L.Weaken(8)
// Now to hurt the mech.
take_damage(rand(damage_min, damage_max))
var/turf/landing = get_turf(hit_atom)
if(planetary && src.CanParachute())
if(!silent)
visible_message("<span class='warning'>\The [src] glides in from above and lands on \the [landing]!</span>", \
"<span class='danger'>You land on \the [landing]!</span>", \
"You hear something land \the [landing].")
return
else if(!planetary && src.softfall) // Falling one floor and falling one atmosphere are very different things
if(!silent)
visible_message("<span class='warning'>\The [src] falls from above and lands on \the [landing]!</span>", \
"<span class='danger'>You land on \the [landing]!</span>", \
"You hear something land \the [landing].")
return
else
if(!silent)
if(planetary)
visible_message("<span class='danger'><font size='3'>\A [src] falls out of the sky and crashes into \the [landing]!</font></span>", \
"<span class='danger'><font size='3'> You fall out of the skiy and crash into \the [landing]!</font></span>", \
"You hear something slam into \the [landing].")
var/turf/T = get_turf(landing)
explosion(T, 0, 1, 2)
else
visible_message("<span class='warning'>\The [src] falls from above and slams into \the [landing]!</span>", \
"<span class='danger'>You fall off and hit \the [landing]!</span>", \
"You hear something slam into \the [landing].")
playsound(loc, "punch", 25, 1, -1)
// Now to hurt everything in the mech (if the fall is planetary, the mech blows up, so we do this first)
for(var/atom/movable/A in src.contents)
A.fall_impact(hit_atom, damage_min, damage_max, silent = TRUE)
// And now the Mech
if(!planetary)
take_damage(rand(damage_min, damage_max))
else
qdel(src)
// And hurt the floor.
if(istype(hit_atom, /turf/simulated/floor))
+7 -5
View File
@@ -195,9 +195,9 @@
dislocated = 1
if(owner)
owner.verbs |= /mob/living/carbon/human/proc/undislocate
owner.verbs |= /mob/living/carbon/human/proc/relocate
/obj/item/organ/external/proc/undislocate()
/obj/item/organ/external/proc/relocate()
if(dislocated == -1)
return
@@ -209,7 +209,7 @@
for(var/obj/item/organ/external/limb in owner.organs)
if(limb.dislocated == 1)
return
owner.verbs -= /mob/living/carbon/human/proc/undislocate
owner.verbs -= /mob/living/carbon/human/proc/relocate
/obj/item/organ/external/update_health()
damage = min(max_damage, (brute_dam + burn_dam))
@@ -325,7 +325,8 @@
// sync the organ's damage with its wounds
src.update_damages()
owner.updatehealth() //droplimb will call updatehealth() again if it does end up being called
if(owner)
owner.updatehealth() //droplimb will call updatehealth() again if it does end up being called
//If limb took enough damage, try to cut or tear it off
if(owner && loc == owner && !is_stump())
@@ -426,7 +427,8 @@
if(damage_desc)
if(user == src.owner)
user.visible_message("<span class='notice'>\The [user] patches [damage_desc] on \his [src.name] with [tool].</span>")
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='notice'>\The [user] patches [damage_desc] on [T.his] [src.name] with [tool].</span>")
else
user.visible_message("<span class='notice'>\The [user] patches [damage_desc] on [owner]'s [src.name] with [tool].</span>")
+3 -2
View File
@@ -314,12 +314,13 @@
/obj/item/weapon/paper/proc/burnpaper(obj/item/weapon/flame/P, mob/user)
var/class = "warning"
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if(P.lit && !user.restrained())
if(istype(P, /obj/item/weapon/flame/lighter/zippo))
class = "rose"
user.visible_message("<span class='[class]'>[user] holds \the [P] up to \the [src], it looks like \he's trying to burn it!</span>", \
user.visible_message("<span class='[class]'>[user] holds \the [P] up to \the [src], it looks like [TU.hes] trying to burn it!</span>", \
"<span class='[class]'>You hold \the [P] up to \the [src], burning it slowly.</span>")
spawn(20)
+2 -2
View File
@@ -75,8 +75,8 @@
if(P.lit && !user.restrained())
if(istype(P, /obj/item/weapon/flame/lighter/zippo))
class = "rose>"
user.visible_message("<span class='[class]'>[user] holds \the [P] up to \the [src], it looks like \he's trying to burn it!</span>", \
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='[class]'>[user] holds \the [P] up to \the [src], it looks like [TU.he] [TU.is] trying to burn it!</span>", \
"<span class='[class]'>You hold \the [P] up to \the [src], burning it slowly.</span>")
spawn(20)
+2 -1
View File
@@ -167,12 +167,13 @@
..()
/obj/item/weapon/shreddedp/proc/burnpaper(var/obj/item/weapon/flame/lighter/P, var/mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if(user.restrained())
return
if(!P.lit)
user << "<span class='warning'>\The [P] is not lit.</span>"
return
user.visible_message("<span class='warning'>\The [user] holds \the [P] up to \the [src]. It looks like \he's trying to burn it!</span>", \
user.visible_message("<span class='warning'>\The [user] holds \the [P] up to \the [src]. It looks like [TU.he] [TU.is] trying to burn it!</span>", \
"<span class='warning'>You hold \the [P] up to \the [src], burning it slowly.</span>")
if(!do_after(user,20))
user << "<span class='warning'>You must hold \the [P] steady to burn \the [src].</span>"
+2 -1
View File
@@ -196,7 +196,8 @@
var/colourName = "red" //for updateIcon purposes
suicide_act(mob/user)
viewers(user) << "<font color='red'><b>[user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide.</b></font>"
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
viewers(user) << "<font color='red'><b>[user] is jamming the [src.name] up [TU.his] nose and into [TU.his] brain. It looks like [TU.he] [TU.is] trying to commit suicide.</b></font>"
return (BRUTELOSS|OXYLOSS)
New()
+3 -2
View File
@@ -497,10 +497,11 @@ obj/structure/cable/proc/cableColor(var/colorC)
charge_costs = list(1)
/obj/item/stack/cable_coil/suicide_act(mob/user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
if(locate(/obj/item/weapon/stool) in user.loc)
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
else
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
user.visible_message("<span class='suicide'>[user] is strangling [TU.himself] with the [src.name]! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")
return(OXYLOSS)
/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
+2 -1
View File
@@ -234,5 +234,6 @@
return 0
/obj/item/weapon/cell/suicide_act(mob/user)
viewers(user) << "<span class='danger'>\The [user] is licking the electrodes of \the [src]! It looks like \he's trying to commit suicide.</span>"
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
viewers(user) << "<span class='danger'>\The [user] is licking the electrodes of \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.</span>"
return (FIRELOSS)
+1 -1
View File
@@ -77,7 +77,7 @@ var/list/fusion_cores = list()
if(owned_field)
icon_state = "core0"
if(force_rupture || owned_field.plasma_temperature > 1000)
owned_field.Rupture()
owned_field.MRC()
else
owned_field.RadiateAll()
qdel(owned_field)
+161 -32
View File
@@ -1,6 +1,7 @@
#define FUSION_ENERGY_PER_K 20
#define FUSION_MAX_ENVIRO_HEAT 5000 //raise this if you want the reactor to dump more energy into the atmosphere
#define PLASMA_TEMP_RADIATION_DIVISIOR 15 //radiation divisior. plasma temp / divisor = radiation.
#define PLASMA_TEMP_RADIATION_DIVISIOR 20 //radiation divisior. plasma temp / divisor = radiation.
/obj/effect/fusion_em_field
name = "electromagnetic field"
@@ -19,6 +20,8 @@
var/tick_instability = 0
var/percent_unstable = 0
var/stable = 1
var/id_tag
var/critical = 0
var/obj/machinery/power/fusion_core/owned_core
var/list/dormant_reactant_quantities = list()
@@ -31,7 +34,8 @@
/obj/structure/cable,
/obj/machinery/atmospherics,
/obj/machinery/air_sensor,
/mob/observer/dead
/mob/observer/dead,
/obj/machinery/power/hydromagnetic_trap
)
var/light_min_range = 2
@@ -52,7 +56,7 @@
owned_core = new_owned_core
if(!owned_core)
qdel(src)
id_tag = owned_core.id_tag
//create the gimmicky things to handle field collisions
var/obj/effect/fusion_particle_catcher/catcher
@@ -194,37 +198,46 @@
if(percent_unstable >= 1)
owned_core.Shutdown(force_rupture=1)
else
if(percent_unstable > 0.5 && prob(percent_unstable*100))
if(percent_unstable > 0.1 && prob(percent_unstable*100))
if(plasma_temperature < 2000)
visible_message("<span class='danger'>\The [src] ripples uneasily, like a disturbed pond.</span>")
else
var/flare
var/fuel_loss
var/rupture
if(percent_unstable < 0.2)
if(percent_unstable > 0.2)
visible_message("<span class='danger'>\The [src] ripples uneasily, like a disturbed pond.</span>")
fuel_loss = prob(5)
flare = prob(50)
else if(percent_unstable < 0.9)
flare = prob(25)
else if(percent_unstable > 0.5)
visible_message("<span class='danger'>\The [src] undulates violently, shedding plumes of plasma!</span>")
flare = prob(50)
fuel_loss = prob(20)
rupture = prob(5)
else
else if(percent_unstable > 0.8)
visible_message("<span class='danger'>\The [src] is wracked by a series of horrendous distortions, buckling and twisting like a living thing!</span>")
flare = 1
fuel_loss = prob(50)
rupture = prob(25)
if(rupture)
owned_core.Shutdown(force_rupture=1)
if(prob(80))
MagneticQuench()
return
else if(prob(15))
MRC()
return
else if(prob(5))
QuantumFluxCascade()
return
else if(prob(5))
BluespaceQuenchEvent()
return
else
var/lost_plasma = (plasma_temperature*percent_unstable)
radiation += lost_plasma
if(flare)
radiation += plasma_temperature/2
plasma_temperature -= lost_plasma
spawn(1)
emflare()
if(fuel_loss)
for(var/particle in dormant_reactant_quantities)
var/lost_fuel = dormant_reactant_quantities[particle]*percent_unstable
@@ -234,17 +247,19 @@
dormant_reactant_quantities.Remove(particle)
Radiate()
return
/obj/effect/fusion_em_field/proc/Rupture()
visible_message("<span class='danger'>\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!</span>")
set_light(15, 15, "#CCCCFF")
empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
sleep(5)
global_announcer.autosay("WARNING: FIELD RUPTURE IMMINENT!", "Containment Monitor")
RadiateAll()
explosion(get_turf(owned_core),-1,-1,8,10) // Blow out all the windows.
return
/*/obj/effect/fusion_em_field/proc/CheckCriticality()
if (plasma_temperature > 70000)
critical += 0.2
else if (instability > 0.45)
critical += 0.6
if(critical >= 25 && prob(percent_unstable*100))
if (critical >= 90)
visible_message("<span class='danger'>\The [src] rumbles and quivers violently, threatening to break free!</span>")
else if(critical >= 50)
visible_message("<span class='danger'>\The [src] rumbles and quivers energetically, the walls distorting slightly.</span>")
else if(critical >= 25)
visible_message("<span class='danger'>\The [src] rumbles and quivers slightly, vibrating the deck.</span>")
*/
/obj/effect/fusion_em_field/proc/ChangeFieldStrength(var/new_strength)
var/calc_size = 1
if(new_strength <= 50)
@@ -490,19 +505,19 @@
//All procs below this point are called in _core.dm, starting at line 41.
//Stability monitoring. Gives radio annoucements if field stability is below 80%
/obj/effect/fusion_em_field/proc/stability_monitor()
var/warnpoint = 0.10
var/warnpoint = 0.10 //start warning at 10% instability
var/warnmessage = "Warning! Field unstable! Instability at [percent_unstable * 100]%, plasma temperature at [plasma_temperature + 295]k."
var/stablemessage = "Containment field returning to stable conditions."
if(percent_unstable >= warnpoint)
if(percent_unstable >= warnpoint) //we're unstable, start warning engineering
global_announcer.autosay(warnmessage, "Field Stability Monitor", "Engineering")
stable = 0
sleep(20 SECONDS)
return
if(percent_unstable < warnpoint && stable == 0)
stable = 0 //we know we're not stable, so let's not state the safe message.
sleep(20)
return
if(percent_unstable < warnpoint && stable == 0) //The field is stable again. Let's set our safe variable and state the safe message.
global_announcer.autosay(stablemessage, "Field Stability Monitor", "Engineering")
stable = 1
return
return
//Reaction radiation is fairly buggy and there's at least three procs dealing with radiation here, this is to ensure constant radiation output.
/obj/effect/fusion_em_field/proc/radiation_scale()
@@ -513,7 +528,8 @@
if(owned_core && owned_core.loc)
var/datum/gas_mixture/environment = owned_core.loc.return_air()
if(environment && environment.temperature < (T0C+FUSION_MAX_ENVIRO_HEAT))
environment.add_thermal_energy(plasma_temperature*20000)
environment.add_thermal_energy(plasma_temperature*5000)
check_instability()
//Temperature changes depending on color.
/obj/effect/fusion_em_field/proc/temp_color()
@@ -538,8 +554,121 @@
light_max_range = 5
light_max_power = 5
return
//moved the flare to a proc for various reasons. Called on line 225.
/obj/effect/fusion_em_field/proc/emflare()
radiation += plasma_temperature/2
light_color = "#ff0000"
light_max_power = 30
light_min_power = 30
light_min_range = 30
light_max_range = 30
visible_message("<span class='danger'>\The [src] flares to eye-searing brightness!</span>")
sleep(60)
temp_color()
//plasma_temperature -= lost_plasma
return
//Rupture() is no longer the end all be all. Fear the magnetic resonance cascade and quantum flux cascade
/obj/effect/fusion_em_field/proc/Rupture()
visible_message("<span class='danger'>\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!</span>")
set_light(15, 15, "#CCCCFF")
empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
global_announcer.autosay("WARNING: FIELD RUPTURE IMMINENT!", "Containment Monitor")
RadiateAll()
var/list/things_in_range = range(10, owned_core)
var/list/turfs_in_range = list()
var/turf/T
for (T in things_in_range)
turfs_in_range.Add(T)
explosion(pick(things_in_range), -1, 5, 5, 5)
empulse(pick(things_in_range), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
spawn(25)
explosion(pick(things_in_range), -1, 5, 5, 5)
spawn(25)
explosion(pick(things_in_range), -1, 5, 5, 5)
spawn(25)
explosion(pick(things_in_range), -1, 5, 5, 5)
spawn(10)
explosion(pick(things_in_range), -1, 5, 5, 5)
spawn(10)
explosion(pick(things_in_range), -1, 5, 5, 5)
spawn(10)
explosion(pick(things_in_range), -1, 5, 5, 5)
return
/obj/effect/fusion_em_field/proc/MRC() //spews electromagnetic pulses in an area around the core.
visible_message("<span class='danger'>\The [src] glows an extremely bright pink and flares out of existance!</span>")
global_announcer.autosay("Warning! Magnetic Resonance Cascade detected! Brace for electronic system distruption.", "Field Stability Monitor")
set_light(15, 15, "#ff00d8")
var/list/things_in_range = range(15, owned_core)
var/list/turfs_in_range = list()
var/turf/T
for (T in things_in_range)
turfs_in_range.Add(T)
for(var/loopcount = 1 to 10)
spawn(200)
empulse(pick(things_in_range), 10, 15)
Destroy()
return
/obj/effect/fusion_em_field/proc/QuantumFluxCascade() //spews hot phoron and oxygen in a radius around the RUST. Will probably set fire to things
global_announcer.autosay("Warning! Quantum fluxuation detected! Flammable gas release expected.", "Field Stability Monitor")
var/list/things_in_range = range(15, owned_core)
var/list/turfs_in_range = list()
var/turf/T
for (T in things_in_range)
turfs_in_range.Add(T)
for(var/loopcount = 1 to 10)
var/turf/TT = get_turf(pick(turfs_in_range))
if(istype(TT))
var/datum/gas_mixture/plasma = new
plasma.adjust_gas("oxygen", (size*100), 0)
plasma.adjust_gas("phoron", (size*100), 0)
plasma.temperature = (plasma_temperature/2)
plasma.update_values()
TT.assume_air(plasma)
TT.hotspot_expose(plasma_temperature)
plasma = null
Destroy()
return
/obj/effect/fusion_em_field/proc/MagneticQuench() //standard hard shutdown. dumps hot oxygen/phoron into the core's area and releases an EMP in the area around the core.
global_announcer.autosay("Warning! Magnetic Quench event detected, engaging hard shutdown.", "Field Stability Monitor")
empulse(owned_core, 10, 15)
var/turf/TT = get_turf(owned_core)
if(istype(TT))
var/datum/gas_mixture/plasma = new
plasma.adjust_gas("oxygen", (size*100), 0)
plasma.adjust_gas("phoron", (size*100), 0)
plasma.temperature = (plasma_temperature/2)
plasma.update_values()
TT.assume_air(plasma)
TT.hotspot_expose(plasma_temperature)
plasma = null
Destroy()
owned_core.Shutdown()
return
/obj/effect/fusion_em_field/proc/BluespaceQuenchEvent() //!!FUN!! causes a number of explosions in an area around the core. Will likely destory or heavily damage the reactor.
visible_message("<span class='danger'>\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!</span>")
set_light(15, 15, "#CCCCFF")
empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
global_announcer.autosay("WARNING: FIELD RUPTURE IMMINENT!", "Containment Monitor")
RadiateAll()
var/list/things_in_range = range(10, owned_core)
var/list/turfs_in_range = list()
var/turf/T
for (T in things_in_range)
turfs_in_range.Add(T)
for(var/loopcount = 1 to 10)
explosion(pick(things_in_range), -1, 5, 5, 5)
empulse(pick(things_in_range), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
Destroy()
owned_core.Shutdown()
return
#undef FUSION_HEAT_CAP
#undef FUSION_MAX_ENVIRO_HEAT
#undef PLASMA_TEMP_RADIATION_DIVISIOR
@@ -117,7 +117,7 @@ proc/get_fusion_reaction(var/p_react, var/s_react, var/m_energy)
var/turf/origin = get_turf(holder)
holder.Rupture()
qdel(holder)
var/radiation_level = rand(100, 200)
var/radiation_level = 200
// Copied from the SM for proof of concept. //Not any more --Cirra //Use the whole z proc --Leshana
radiation_repository.z_radiate(locate(1, 1, holder.z), radiation_level, 1)
@@ -141,7 +141,6 @@ proc/get_fusion_reaction(var/p_react, var/s_react, var/m_energy)
return 1
// High end reactions.
/decl/fusion_reaction/boron_hydrogen
p_react = "boron"
+11 -1
View File
@@ -5,4 +5,14 @@
description = "A colorless, odorless, tasteless and generally inert gas used in fusion reactors. Non-radioactive."
id = "helium-3"
reagent_state = GAS
color = "#808080"
color = "#808080"
/obj/structure/reagent_dispensers/he3
name = "fueltank"
desc = "A fueltank."
icon = 'icons/obj/objects.dmi'
icon_state = "weldtank"
amount_per_transfer_from_this = 10
New()
..()
reagents.add_reagent("helium-3",1000)
+54
View File
@@ -0,0 +1,54 @@
#define ENERGY_PER_K 20
#define MINIMUM_PLASMA_TEMPERATURE 10000
/obj/machinery/power/hydromagnetic_trap
name = "\improper hydromagnetic trap"
desc = "A device for extracting power from high-energy plasma in toroidal fields."
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "mag_trap0"
anchored = 1
var/list/things_in_range = list()//what is in a radius of us?
var/list/fields_in_range = list()//What EM fields are in that radius?
var/list/active_field = list()//Our active field.
var/active = 0 //are we even on?
var/id_tag //needed for !!rasins!!
/obj/machinery/power/hydromagnetic_trap/process()
if(!powernet && anchored == 1)
return
spawn(1)
Active()
Search()
/obj/machinery/power/hydromagnetic_trap/proc/Search()//let's not have +100 instances of the same field in active_field.
things_in_range = range(7, src)
var/obj/effect/fusion_em_field/FFF
for (FFF in things_in_range)
fields_in_range.Add(FFF)
for (FFF in fields_in_range)
if (active_field.len > 0)
return
else if (active_field.len == 0)
Link()
return
/obj/machinery/power/hydromagnetic_trap/proc/Link() //discover our EM field
var/obj/effect/fusion_em_field/FFF
for(FFF in fields_in_range)
if (FFF.id_tag != id_tag)
return
active_field += FFF
active = 1
return
/obj/machinery/power/hydromagnetic_trap/proc/Active()//POWERRRRR
var/obj/effect/fusion_em_field/FF
if (active == 0)
return
for (FF in active_field)
if (FF.plasma_temperature >= MINIMUM_PLASMA_TEMPERATURE)
icon_state = "mag_trap1"
add_avail(ENERGY_PER_K * FF.plasma_temperature)
if (FF.plasma_temperature <= MINIMUM_PLASMA_TEMPERATURE)
icon_state = "mag_trap0"
return
@@ -53,7 +53,7 @@
if(isliving(user))
hasShocked = 1
var/shock_damage = min(rand(30,40),rand(30,40))
user.electrocute_act(shock_damage, src)
user.electrocute_act(shock_damage, src, 1, BP_TORSO)
var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
user.throw_at(target, 200, 4)
@@ -61,7 +61,6 @@
sleep(20)
hasShocked = 0
return
/obj/machinery/containment_field/proc/set_master(var/master1,var/master2)
if(!master1 || !master2)
@@ -291,7 +291,8 @@
ui_interact(user)
/obj/machinery/power/supermatter/attack_hand(mob/user as mob)
user.visible_message("<span class=\"warning\">\The [user] reaches out and touches \the [src], inducing a resonance... \his body starts to glow and bursts into flames before flashing into ash.</span>",\
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message("<span class=\"warning\">\The [user] reaches out and touches \the [src], inducing a resonance... [TU.his] body starts to glow and bursts into flames before flashing into ash.</span>",\
"<span class=\"danger\">You reach out and touch \the [src]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"</span>",\
"<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
@@ -337,7 +338,9 @@
if(istype(AM, /obj/effect))
return
if(istype(AM, /mob/living))
AM.visible_message("<span class=\"warning\">\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.</span>",\
var/mob/living/M = AM
var/datum/gender/T = gender_datums[M.get_visible_gender()]
AM.visible_message("<span class=\"warning\">\The [AM] slams into \the [src] inducing a resonance... [T.his] body starts to glow and catch flame before flashing into ash.</span>",\
"<span class=\"danger\">You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"</span>",\
"<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
else if(!grav_pulling) //To prevent spam, detonating supermatter does not indicate non-mobs being destroyed
+1 -1
View File
@@ -288,7 +288,7 @@
else if(closest_mob)
var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5)
closest_mob.electrocute_act(shock_damage, source, 1/*, tesla_shock = 1, stun = stun_mobs*/)
closest_mob.electrocute_act(shock_damage, source, 1, ran_zone())
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
if(stun_mobs)
+53 -3
View File
@@ -51,6 +51,7 @@
attack_verb = list("struck", "hit", "bashed")
zoomdevicename = "scope"
var/automatic = 0
var/burst = 1
var/fire_delay = 6 //delay after shooting before the gun can be used again
var/burst_delay = 2 //delay between shots, if firing in bursts
@@ -68,7 +69,8 @@
var/requires_two_hands
var/wielded_icon = "gun_wielded"
var/one_handed_penalty = 0 // Penalty applied if someone fires a two-handed gun with one hand.
var/obj/screen/auto_target/auto_target
var/shooting = 0
var/next_fire_time = 0
var/sel_mode = 1 //index of the currently selected mode
@@ -180,8 +182,9 @@
if(P)
if(process_projectile(P, user, user, pick("l_foot", "r_foot")))
handle_post_fire(user, user)
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
user.visible_message(
"<span class='danger'>\The [user] shoots \himself in the foot with \the [src]!</span>",
"<span class='danger'>\The [user] shoots [TU.himself] in the foot with \the [src]!</span>",
"<span class='danger'>You shoot yourself in the foot with \the [src]!</span>"
)
M.drop_item()
@@ -206,8 +209,29 @@
if(user && user.a_intent == I_HELP && user.is_preference_enabled(/datum/client_preference/safefiring)) //regardless of what happens, refuse to shoot if help intent is on
user << "<span class='warning'>You refrain from firing your [src] as your intent is set to help.</span>"
return
else
Fire(A,user,params) //Otherwise, fire normally.
Fire(A, user, params) //Otherwise, fire normally.
return
/* //Commented out for quality control and testing
if(automatic == 1)//Are we are going to be using automatic shooting
//We check to make sure they can fire
if(!special_check(user))
return
if(auto_target)//If they already have one then update it
auto_target.loc = get_turf(A)
auto_target.delay_del = 1//And reset the del so its like they got a new one and doesnt instantly vanish
to_chat(user, "<span class='notice'>You ready \the [src]! Click and drag the target around to shoot.</span>")
else//Otherwise just make a new one
auto_target = new/obj/screen/auto_target(get_turf(A), src)
visible_message("<span class='danger'>\[user] readies the [src]!</span>")
playsound(src, 'sound/weapons/TargetOn.ogg', 50, 1)
to_chat(user, "<span class='notice'>You ready \the [src]! Click and drag the target around to shoot.</span>")
return
Fire(A,user,params) //Otherwise, fire normally.
*/
/obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone)
if (A == user && user.zone_sel.selecting == O_MOUTH && !mouthshoot)
@@ -307,8 +331,11 @@
return
var/shoot_time = (burst - 1)* burst_delay
//These should apparently be disabled to allow for the automatic system to function without causing near-permanant paralysis. Re-enabling them while we sort that out.
user.setClickCooldown(shoot_time) //no clicking on things while shooting
user.setMoveCooldown(shoot_time) //no moving while shooting either
next_fire_time = world.time + shoot_time
var/held_acc_mod = 0
@@ -320,7 +347,27 @@
//actually attempt to shoot
var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed.
/* // Commented out for quality control and testing.
shooting = 1
if(automatic == 1 && auto_target && auto_target.active)//When we are going to shoot and have an auto_target AND its active meaning we clicked on it we tell it to burstfire 1000 rounds
burst = 1000//Yes its not EXACTLY full auto but when are we shooting more than 1000 normally and it can easily be made higher
*/
for(var/i in 1 to burst)
/* // Commented out for quality control and testing.
if(!reflex && automatic)//If we are shooting automatic then check our target, however if we are shooting reflex we dont use automatic
//extra sanity checking.
if(user.incapacitated())
return
if(user.get_active_hand() != src)
break
if(!auto_target) break//Stopped shooting
else if(auto_target.loc)
target = auto_target.loc
//Lastly just update our dir if needed
if(user.dir != get_dir(user, auto_target))
user.face_atom(auto_target)
*/
var/obj/projectile = consume_next_projectile(user)
if(!projectile)
handle_click_empty(user)
@@ -346,6 +393,9 @@
last_shot = world.time
/* // Commented out for quality control and testing.
shooting = 0
*/
// We do this down here, so we don't get the message if we fire an empty gun.
if(requires_two_hands)
if(user.item_is_in_hands(src) && user.hands_are_full())
@@ -0,0 +1,73 @@
//This entire file is unticked for quality control and testing
//True automagic gun modes. Dakka dakka.
//A significant portion of this code was donated by Mport from SS:CM
//This is used by guns shooting in automatic mode
/obj/screen/auto_target
name = "targeter"
icon = null//We dont want people to see this guy
density = 0
anchored = 1
var/obj/item/weapon/gun/gun
var/active = 0//Just tells us that it was clicked on so we should start shooting
var/delay_del = 0//Delays the del if we retarget without shooting
/obj/screen/auto_target/New(loc, var/obj/item/weapon/gun/G)
..()
gun = G
var/image/I = image('icons/effects/Targeted.dmi', src, "locked")
I.override = 1
usr << I
//autodel() //Currently doesn't really work right.
return
/obj/screen/auto_target/CanPass()//Everything should ignore this guy and just pass by
return 1
//Used to get rid of this if they target but dont actually shoot or stop shooting (no ammo) yet are still dragging us around
/obj/screen/auto_target/proc/autodel()
set waitfor=0
if(active == 1)
return
sleep(20)
if(!src) return//Might not really be needed
if(delay_del)//This says we want to wait another X seconds before trying to del
delay_del = 0
autodel()
return
if(gun.shooting == 0)
qdel(src)
else
autodel()//Yes in theory this could hit the inf loop
return
//When the player clicks on the target it will disable the autodel and tell the gun to shoot
/obj/screen/auto_target/MouseDown(location,control,params)
active += 1//Tell the autodel that we are actually using this now
if(gun.shooting == 0)//If we are not shooting start shooting, we need this here or they have to drag to a new turf before it starts shooting, felt weird
gun.Fire(loc, usr, params)
return
//Called when they drag the object somewhere else
//If its not already shooting (should be though due to the above, but this does let it click at you when it runs dry) then start shooting,
/obj/screen/auto_target/MouseDrag(over_object,src_location,over_location,src_control,over_control,params)
if(gun.shooting == 0)//If we are not shooting start shooting
gun.Fire(loc, usr, params)
if(over_location != loc)//This updates the loc to our new location when we drag it to a new turf
loc = over_location
if((usr.get_active_hand() != gun))
qdel(src)
//This gets rid of us when they let go of the click, but only after they actually drag the target to a new turf which is why the below also has to exist
/obj/screen/auto_target/MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
qdel(src)
return
//This is needed so if they just MouseDown and then let go it will stop shooting, otherwise we stick around till they run out of bullets
/obj/screen/auto_target/MouseUp(object,location,control,params)
qdel(src)
return
//This pseudo code is being left in place to serve as references to the modifications to gun.dm, the Fire() proc, and the afterattack() proc. -k22
//Code donated by Mport.
@@ -25,6 +25,16 @@
charge_cost = 480
projectile_type = /obj/item/projectile/ion
/obj/item/weapon/gun/energy/phasegun
name = "phase pistol"
desc = "The NT Mk26 EW Apollo is an energy handgun, specifically designed for use against wildlife."
icon_state = "phase"
item_state = "taser" //I don't have an in-hand sprite, taser will be fine
slot_flags = SLOT_BELT|SLOT_HOLSTER
charge_cost = 300
projectile_type = /obj/item/projectile/energy/phase
/obj/item/weapon/gun/energy/decloner
name = "biological demolecularisor"
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
@@ -199,5 +209,5 @@ obj/item/weapon/gun/energy/staff/focus
firemodes = list(
list(mode_name="single shot", burst = 1, burst_accuracy = list(5), dispersion = list(0), charge_cost = 24),
list(mode_name="five shot burst", burst = 5, burst_accuracy = list(5,5,5,5,5), dispersion = list(1,1,1,1,1)),
list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
)
list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2))
)
@@ -0,0 +1,174 @@
//This will likely drive me insane, but fuck it. Let's give it a shot. -k22
//This was heavily assisted by MoondancerPony
/obj/item/weapon/gun/energy/modular
name = "modular weapon"
desc = "You shouldn't be seeing this. Contact your local time-police station."
icon_state = "mod_pistol"
cell_type = /obj/item/weapon/cell/device/weapon
charge_cost = 120
var/max_components = 3 //How many components we can hold.
var/capacitor_rating = 0 //How good are the capacitors inside us?
var/laser_rating = 0 //How good are the lasers inside of us?
var/manipulator_rating = 0 //How good are the manipulators inside us?
var/assembled = 1 //Are we closed up?
var/max_burst_size = 5 //Don't let our maximum burst size get too high.
var/list/guncomponents = list() //Generate our list of components.
var/accepted_components = list(
/obj/item/weapon/stock_parts/capacitor/,
/obj/item/weapon/stock_parts/capacitor/adv,
/obj/item/weapon/stock_parts/capacitor/super,
/obj/item/weapon/stock_parts/micro_laser/,
/obj/item/weapon/stock_parts/micro_laser/high,
/obj/item/weapon/stock_parts/micro_laser/ultra,
/obj/item/weapon/stock_parts/manipulator/,
/obj/item/weapon/stock_parts/manipulator/nano,
/obj/item/weapon/stock_parts/manipulator/pico,
)
//Excessively long because it won't accept subtypes for some reason!
/obj/item/weapon/gun/energy/modular/New() //Initialize our components.
..()
guncomponents = list()
guncomponents += new /obj/item/weapon/stock_parts/capacitor
guncomponents += new /obj/item/weapon/stock_parts/micro_laser
guncomponents += new /obj/item/weapon/stock_parts/manipulator
CheckParts()
FireModeModify()
/obj/item/weapon/gun/energy/modular/proc/CheckParts() //What parts do we have inside us, and how good are they?
capacitor_rating = 0
laser_rating = 0
manipulator_rating = 0
for(var/obj/item/weapon/stock_parts/capacitor/CA in guncomponents)
capacitor_rating += CA.rating
for(var/obj/item/weapon/stock_parts/micro_laser/ML in guncomponents)
laser_rating += ML.rating
for(var/obj/item/weapon/stock_parts/manipulator/MA in guncomponents)
manipulator_rating += MA.rating
FireModeModify()
/obj/item/weapon/gun/energy/modular/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/weapon/screwdriver))
to_chat(user, "<span class='notice'>You [assembled ? "disassemble" : "assemble"] the gun.</span>")
assembled = !assembled
playsound(src, O.usesound, 50, 1)
return
if(istype(O, /obj/item/weapon/crowbar))
if(assembled == 1)
to_chat(user, "<span class='warning'>Disassemble the [src] first!</span>")
return
for(var/obj/item/I in guncomponents)
to_chat(user, "<span class='notice'>You remove the gun's components.</span>")
playsound(src, O.usesound, 50, 1)
I.forceMove(get_turf(src))
guncomponents.Remove(I)
CheckParts()
return
//Someone's attacking us, and it's not anything we have a special case for (i.e. a tool)
..()
if(assembled) // can't put anything in
return
if(!(O.type in accepted_components))//check if we can accept it
to_chat(user, "<span class='warning'>You can't add this to [src]!</span>")
return
if(guncomponents.len >= max_components) //We have too many componenets and can't fit more.
to_chat(user, "<span class='warning'>You can't add any more components!</span>")
return
if(istype(O, /obj/item/weapon/stock_parts/capacitor) && capacitor_rating == 5)
to_chat(user, "<span class='warning'>You can't add any more capacitors!</span>")
return
user.drop_item()
guncomponents += O
O.forceMove(src)
to_chat(user, "<span class='notice'>You add a component to the [src]</span>")
CheckParts()
/obj/item/weapon/gun/energy/modular/proc/FireModeModify() //Check our laser, manipulator, and capacitor ratings, adjust stun and lethal firemodes depending on laser / manipulator rating and burst size depending on capacitors.
//check our lethal and stun ratings depending on laser and manipulator rating.
var/burstmode = capacitor_rating
var/beammode
var/beammode_lethal
var/chargecost
var/chargecost_lethal
if(laser_rating >= 15)
beammode_lethal = /obj/item/projectile/beam/sniper
beammode = /obj/item/projectile/beam/stun
chargecost = 300
chargecost_lethal = 600
else if(laser_rating >= 10)
beammode_lethal = /obj/item/projectile/beam/xray
beammode = /obj/item/projectile/beam/stun
chargecost = 300
chargecost_lethal = 200
else if(laser_rating == 8 && manipulator_rating == 5) //very specific set of combinations. No, you can't make a pulse rifle. Sorry research.
beammode_lethal = /obj/item/projectile/beam/heavylaser
beammode = /obj/item/projectile/beam/stun
chargecost = 300
chargecost_lethal = 600
else if(laser_rating >= 5)
beammode_lethal = /obj/item/projectile/beam/midlaser
beammode = /obj/item/projectile/beam/stun/med
chargecost = 180
chargecost_lethal = 240
else if(laser_rating < 5)
beammode_lethal = /obj/item/projectile/beam/weaklaser
beammode = /obj/item/projectile/beam/stun/weak
chargecost = 100
chargecost_lethal = 200
firemodes = list(
new /datum/firemode(src, list(mode_name="stun", projectile_type=beammode, fire_sound='sound/weapons/Taser.ogg', charge_cost = chargecost)),
new /datum/firemode(src, list(mode_name="lethal", projectile_type=beammode_lethal, fire_sound='sound/weapons/Laser.ogg', charge_cost = chargecost_lethal)),
new /datum/firemode(src, list(mode_name="[burstmode] shot stun", projectile_type=beammode, fire_sound='sound/weapons/Taser.ogg', charge_cost = chargecost, burst = burstmode)),
new /datum/firemode(src, list(mode_name="[burstmode] shot lethal", projectile_type=beammode_lethal, fire_sound='sound/weapons/Laser.ogg', charge_cost = chargecost_lethal, burst = burstmode)),
)
/obj/item/weapon/gun/energy/modular/load_ammo(var/obj/item/C, mob/user)
if(istype(C, cell_type))
if(self_recharge || battery_lock)
user << "<span class='notice'>[src] does not have a battery port.</span>"
return
var/obj/item/weapon/cell/P = C
if(power_supply)
user << "<span class='notice'>[src] already has a power cell.</span>"
else
user.visible_message("[user] is reloading [src].", "<span class='notice'>You start to insert [P] into [src].</span>")
if(do_after(user, 10))
user.remove_from_mob(P)
power_supply = P
P.loc = src
user.visible_message("[user] inserts [P] into [src].", "<span class='notice'>You insert [P] into [src].</span>")
playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1)
update_icon()
update_held_icon()
return
/obj/item/weapon/gun/energy/modular/pistol
name = "modular pistol"
icon_state = "mod_pistol"
max_components = 6
desc = "A bulky modular pistol frame. This only only accepts six parts."
origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 3)
burst_delay = 2
/obj/item/weapon/gun/energy/modular/carbine
name = "modular carbine"
icon_state = "mod_carbine"
max_components = 8
desc = "A modular version of the standard laser carbine. This one can hold 8 components."
origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3, TECH_MATERIAL = 3)
burst_delay = 2
/obj/item/weapon/gun/energy/modular/cannon
name = "modular cannon"
icon_state = "mod_cannon"
max_components = 14
desc = "Say hello, to my little friend!"
one_handed_penalty = 4 //dual wielding = no.
cell_type = /obj/item/weapon/cell //We're bigger. We can use much larger power cells.
origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 4) //its a damn cannon capable of holding a huge amount of parts.
burst_delay = 4 //preventing extreme silliness.
@@ -190,14 +190,23 @@
one_handed_penalty = 6
var/cover_open = 0
/* Commented out for quality control and testing.
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null, automatic = 0),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), automatic = 0),
list(mode_name="short bursts", burst=5, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2), automatic = 0),
list(mode_name="automatic", burst=1, fire_delay=-1, move_delay=null, burst_accuracy=null, dispersion=null, automatic = 1),
)
*/
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
list(mode_name="short bursts", burst=5, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2))
list(mode_name="short bursts", burst=5, move_delay=6, burst_accuracy = list(0,-1,-1,-2,-2), dispersion = list(0.6, 1.0, 1.0, 1.0, 1.2)),
)
var/cover_open = 0
/obj/item/weapon/gun/projectile/automatic/l6_saw/special_check(mob/user)
if(cover_open)
user << "<span class='warning'>[src]'s cover is open! Close it before firing!</span>"
@@ -370,4 +379,4 @@
icon_state = "bullpup"
else
item_state = "bullpup-empty"
if(!ignore_inhands) update_held_icon()
if(!ignore_inhands) update_held_icon()
@@ -195,4 +195,10 @@
light_color = "#0000FF"
embed_chance = 0
muzzle_type = /obj/effect/projectile/pulse/muzzle
muzzle_type = /obj/effect/projectile/pulse/muzzle
/obj/item/projectile/energy/phase
kill_count = 4
damage = 5
SA_bonus_damage = 55 // 60 total on animals.
SA_vulnerability = SA_ANIMAL
@@ -121,8 +121,9 @@
if(prob(15))
M.apply_effect((rand(30,80)),IRRADIATE)
M.Weaken(5)
var/datum/gender/TM = gender_datums[M.get_visible_gender()]
for (var/mob/V in viewers(src))
V.show_message("<font color='red'>[M] writhes in pain as \his vacuoles boil.</font>", 3, "<font color='red'>You hear the crunching of leaves.</font>", 2)
V.show_message("<font color='red'>[M] writhes in pain as [TM.his] vacuoles boil.</font>", 3, "<font color='red'>You hear the crunching of leaves.</font>", 2)
if(prob(35))
// for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan
// V.show_message("<font color='red'>[M] is mutated by the radiation beam.</font>", 3, "<font color='red'> You hear the snapping of twigs.</font>", 2)
@@ -31,7 +31,7 @@
/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob)
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty.</span>"
to_chat(user, "<span class='warning'>[src] is empty.</span>")
return
if (!istype(M))
return
@@ -40,21 +40,29 @@
if(istype(H))
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
if(!affected)
user << "<span class='danger'>\The [H] is missing that limb!</span>"
to_chat(user, "<span class='danger'>\The [H] is missing that limb!</span>")
return
else if(affected.robotic >= ORGAN_ROBOT)
user << "<span class='danger'>You cannot inject a robotic limb.</span>"
to_chat(user, "<span class='danger'>You cannot inject a robotic limb.</span>")
return
if(!H.stat)
if(H != user)
if(H.a_intent != I_HELP)
to_chat(user, "<span class='notice'>[H] is resisting your attempt to inject them with \the [src].</span>")
to_chat(H, "<span class='danger'> [user] is trying to inject you with \the [src]!</span>")
if(!do_after(user, 30))
return
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user << "<span class='notice'>You inject [M] with [src].</span>"
M << "<span class='notice'>You feel a tiny prick!</span>"
to_chat(user, "<span class='notice'>You inject [M] with \the [src].</span>")
to_chat(M, "<span class='notice'>You feel a tiny prick!</span>")
if(M.reagents)
var/contained = reagentlist()
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
admin_inject_log(user, M, src, contained, trans)
user << "<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>"
to_chat(user, "<span class='notice'>[trans] units injected. [reagents.total_volume] units remaining in \the [src].</span>")
if(!reusable && !used)
used = !used
@@ -110,7 +118,7 @@
user << "<span class='notice'>\The [src] already has a vial.</span>"
else
..()
/obj/item/weapon/reagent_containers/hypospray/autoinjector
name = "autoinjector"
desc = "A rapid and safe way to administer small amounts of drugs by untrained or trained personnel."
+9
View File
@@ -491,6 +491,15 @@ other types of metals and chemistry for reagents).
build_path = /obj/item/roller/adv
sort_string = "MBBAF"
/datum/design/item/medical/enhanced_analyzer
name = "enhanced health analyzer"
desc = "A prototype version of the regular health analyzer, able to distinguish the location of more serious injuries as well as accurately determine radiation levels."
id = "advanced_analyzer"
req_tech = list(TECH_MAGNET = 5, TECH_BIO = 6)
materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1000, "silver" = 1000, "gold" = 1500)
build_path = /obj/item/device/healthanalyzer/advanced
sort_string = "MBBAG"
/datum/design/item/implant
materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+2 -1
View File
@@ -95,5 +95,6 @@
/datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/simple_animal/slime/target, target_zone, obj/item/tool)
user.visible_message("<font color='red'>[user]'s hand slips, causing \him to miss the core!</font>", \
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message("<font color='red'>[user]'s hand slips, causing [T.him] to miss the core!</font>", \
"<font color='red'>Your hand slips, causing you to miss the core!</font>")
+2 -1
View File
@@ -121,9 +121,10 @@
stage = 4
badness = 3
activate(var/mob/living/carbon/mob,var/multiplier)
var/datum/gender/TM = gender_datums[mob.get_visible_gender()]
mob.suiciding = 30
//instead of killing them instantly, just put them at -175 health and let 'em gasp for a while
viewers(mob) << "<font color='red'><b>[mob.name] is holding \his breath. It looks like \he's trying to commit suicide.</b></font>"
viewers(mob) << "<font color='red'><b>[mob.name] is holding [TM.his] breath. It looks like [TM.he] [TM.is] trying to commit suicide.</b></font>"
mob.adjustOxyLoss(175 - mob.getToxLoss() - mob.getFireLoss() - mob.getBruteLoss() - mob.getOxyLoss())
mob.updatehealth()
@@ -1,95 +0,0 @@
/datum/controller/game_controller
var/list/artifact_spawning_turfs = list()
var/list/digsite_spawning_turfs = list()
#define XENOARCH_SPAWN_CHANCE 0.5
#define DIGSITESIZE_LOWER 4
#define DIGSITESIZE_UPPER 12
#define ARTIFACTSPAWNNUM_LOWER 6
#define ARTIFACTSPAWNNUM_UPPER 12
/datum/controller/game_controller/proc/SetupXenoarch()
for(var/turf/simulated/mineral/M in world)
if(!M.density)
continue
if(isnull(M.geologic_data))
M.geologic_data = new /datum/geosample(M)
if(!prob(XENOARCH_SPAWN_CHANCE))
continue
var/farEnough = 1
for(var/A in digsite_spawning_turfs)
var/turf/T = A
if(T in range(5, M))
farEnough = 0
break
if(!farEnough)
continue
digsite_spawning_turfs.Add(M)
var/digsite = get_random_digsite_type()
var/target_digsite_size = rand(DIGSITESIZE_LOWER, DIGSITESIZE_UPPER)
var/list/processed_turfs = list()
var/list/turfs_to_process = list(M)
var/list/viable_adjacent_turfs = list()
if(target_digsite_size > 1)
for(var/turf/simulated/mineral/T in orange(2, M))
if(!T.density)
continue
if(T.finds)
continue
if(T in processed_turfs)
continue
viable_adjacent_turfs.Add(T)
target_digsite_size = min(target_digsite_size, viable_adjacent_turfs.len)
for(var/i = 1 to target_digsite_size)
turfs_to_process += pick_n_take(viable_adjacent_turfs)
while(turfs_to_process.len)
var/turf/simulated/mineral/archeo_turf = pop(turfs_to_process)
processed_turfs.Add(archeo_turf)
if(isnull(archeo_turf.finds))
archeo_turf.finds = list()
if(prob(50))
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 190)))
else if(prob(75))
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 90)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(110, 190)))
else
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 50)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(60, 140)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(150, 190)))
//sometimes a find will be close enough to the surface to show
var/datum/find/F = archeo_turf.finds[1]
if(F.excavation_required <= F.view_range)
archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
archeo_turf.update_icon()
//have a chance for an artifact to spawn here, but not in animal or plant digsites
if(isnull(M.artifact_find) && digsite != DIGSITE_GARDEN && digsite != DIGSITE_ANIMAL)
artifact_spawning_turfs.Add(archeo_turf)
//create artifact machinery
var/num_artifacts_spawn = rand(ARTIFACTSPAWNNUM_LOWER, ARTIFACTSPAWNNUM_UPPER)
while(artifact_spawning_turfs.len > num_artifacts_spawn)
pick_n_take(artifact_spawning_turfs)
var/list/artifacts_spawnturf_temp = artifact_spawning_turfs.Copy()
while(artifacts_spawnturf_temp.len > 0)
var/turf/simulated/mineral/artifact_turf = pop(artifacts_spawnturf_temp)
artifact_turf.artifact_find = new()
#undef XENOARCH_SPAWN_CHANCE
#undef DIGSITESIZE_LOWER
#undef DIGSITESIZE_UPPER
#undef ARTIFACTSPAWNNUM_LOWER
#undef ARTIFACTSPAWNNUM_UPPER
+3 -3
View File
@@ -70,15 +70,15 @@
artifact_distance = rand()
artifact_id = container.artifact_find.artifact_id
else
if(master_controller) //Sanity check due to runtimes ~Z
for(var/turf/simulated/mineral/T in master_controller.artifact_spawning_turfs)
if(SSxenoarch) //Sanity check due to runtimes ~Z
for(var/turf/simulated/mineral/T in SSxenoarch.artifact_spawning_turfs)
if(T.artifact_find)
var/cur_dist = get_dist(container, T) * 2
if( (artifact_distance < 0 || cur_dist < artifact_distance))
artifact_distance = cur_dist + rand() * 2 - 1
artifact_id = T.artifact_find.artifact_id
else
master_controller.artifact_spawning_turfs.Remove(T)
SSxenoarch.artifact_spawning_turfs.Remove(T)
/obj/item/device/core_sampler
name = "core sampler"
+5 -5
View File
@@ -57,8 +57,8 @@
var/nearestSimpleTargetDist = -1
var/turf/cur_turf = get_turf(src)
if(master_controller) //Sanity check due to runtimes ~Z
for(var/A in master_controller.artifact_spawning_turfs)
if(SSxenoarch) //Sanity check due to runtimes ~Z
for(var/A in SSxenoarch.artifact_spawning_turfs)
var/turf/simulated/mineral/T = A
if(T.density && T.artifact_find)
if(T.z == cur_turf.z)
@@ -67,9 +67,9 @@
nearestTargetDist = cur_dist + rand() * 2 - 1
nearestTargetId = T.artifact_find.artifact_id
else
master_controller.artifact_spawning_turfs.Remove(T)
SSxenoarch.artifact_spawning_turfs.Remove(T)
for(var/A in master_controller.digsite_spawning_turfs)
for(var/A in SSxenoarch.digsite_spawning_turfs)
var/turf/simulated/mineral/T = A
if(T.density && T.finds && T.finds.len)
if(T.z == cur_turf.z)
@@ -77,7 +77,7 @@
if(nearestSimpleTargetDist < 0 || cur_dist < nearestSimpleTargetDist)
nearestSimpleTargetDist = cur_dist + rand() * 2 - 1
else
master_controller.digsite_spawning_turfs.Remove(T)
SSxenoarch.digsite_spawning_turfs.Remove(T)
if(nearestTargetDist >= 0)
user << "Exotic energy detected on wavelength '[nearestTargetId]' in a radius of [nearestTargetDist]m[nearestSimpleTargetDist > 0 ? "; small anomaly detected in a radius of [nearestSimpleTargetDist]m" : ""]"
+1
View File
@@ -970,6 +970,7 @@
if(S)
new S(get_turf(holder.my_atom))
..()
/datum/chemical_reaction/slime/rainbow_unity
name = "Slime Unity"