Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-27503

This commit is contained in:
LetterJay
2017-05-24 08:11:07 -05:00
105 changed files with 2783 additions and 2423 deletions
@@ -19,7 +19,7 @@
/obj/machinery/meter/Initialize(mapload)
. = ..()
SSair.atmos_machinery += src
if (mapload && !target)
if (!target)
target = locate(/obj/machinery/atmospherics/pipe) in loc
/obj/machinery/meter/Destroy()
+2
View File
@@ -271,6 +271,8 @@ BLIND // can't see anything
/obj/item/clothing/head
name = "head"
icon = 'icons/obj/clothing/hats.dmi'
icon_state = "top_hat"
item_state = "that"
body_parts_covered = HEAD
slot_flags = SLOT_HEAD
var/blockTracking = 0 //For AI tracking
+29 -16
View File
@@ -7,25 +7,34 @@
actions_types = list(/datum/action/item_action/toggle_mode)
origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3"
var/mode = 0 //0 - regular mesons mode 1 - t-ray mode
mode = FALSE //FALSE - regular mesons mode TRUE - t-ray mode
var/range = 1
/obj/item/clothing/glasses/meson/engine/attack_self(mob/user)
/obj/item/clothing/glasses/meson/engine/toggle_mode(mob/user, voluntary)
var/turf/T = get_turf(src)
if(T && T.z == ZLEVEL_MINING && mode)
if(picked_excuse)
to_chat(user, "<span class='warning'>Due to [picked_excuse], the [name] cannot currently be swapped to \[Meson] mode.</span>")
return
mode = !mode
if(mode)
START_PROCESSING(SSobj, src)
vision_flags = 0
darkness_view = 2
invis_view = SEE_INVISIBLE_LIVING
lighting_alpha = null
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[T-Ray].</span>")
if(voluntary)
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[T-Ray].</span>")
else
to_chat(user, "<span class='warning'>The goggles abruptly toggle to \[T-Ray] mode!</span>")
else
STOP_PROCESSING(SSobj, src)
vision_flags = SEE_TURFS
darkness_view = 1
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
to_chat(loc, "<span class='notice'>You toggle the goggles' scanning mode to \[Meson].</span>")
if(voluntary)
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[Meson].</span>")
else
to_chat(user, "<span class='warning'>The goggles abruptly toggle to \[Meson] mode!</span>")
if(ishuman(user))
var/mob/living/carbon/human/H = user
@@ -37,8 +46,14 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/glasses/meson/engine/attack_self(mob/user)
toggle_mode(user, TRUE)
/obj/item/clothing/glasses/meson/engine/process()
if(!mode)
var/turf/T = get_turf(src)
if(T && T.z == ZLEVEL_MINING)
toggle_mode(loc)
return
if(!ishuman(loc))
@@ -47,7 +62,6 @@
var/mob/living/carbon/human/user = loc
if(user.glasses != src)
return
scan()
/obj/item/clothing/glasses/meson/engine/proc/scan()
@@ -89,13 +103,17 @@
icon_state = "trayson-tray_off"
origin_tech = "materials=3;magnets=2;engineering=2"
mode = 1
var/on = 0
mode = TRUE
var/on = FALSE
vision_flags = 0
darkness_view = 2
invis_view = SEE_INVISIBLE_LIVING
range = 2
/obj/item/clothing/glasses/meson/engine/tray/Initialize()
. = ..()
picked_excuse = null
/obj/item/clothing/glasses/meson/engine/tray/process()
if(!on)
return
@@ -108,15 +126,10 @@
if(user.glasses == src)
user.update_inv_glasses()
/obj/item/clothing/glasses/meson/engine/tray/attack_self(mob/user)
/obj/item/clothing/glasses/meson/engine/tray/toggle_mode(mob/user, voluntary)
on = !on
if(on)
START_PROCESSING(SSobj, src)
to_chat(user, "<span class='notice'>You turn the goggles on.</span>")
else
STOP_PROCESSING(SSobj, src)
to_chat(user, "<span class='notice'>You turn the goggles off.</span>")
to_chat(user, "<span class='[voluntary ? "notice":"warning"]'>[voluntary ? "You turn the goggles":"The goggles turn"] [on ? "on":"off"][voluntary ? ".":"!"]</span>")
update_icon()
for(var/X in actions)
+49 -3
View File
@@ -31,14 +31,60 @@
/obj/item/clothing/glasses/meson
name = "Optical Meson Scanner"
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition."
desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions."
icon_state = "meson"
item_state = "meson"
origin_tech = "magnets=1;engineering=2"
darkness_view = 2
vision_flags = SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
var/static/list/meson_mining_failure_excuses = list("seismic activity", "excessive lava", "ambient radiation", "electromagnetic storms", "bluespace disruption", \
"gravity", "dust", "dense rock", "ash", "badly understood science", "radiant heat")
var/picked_excuse
var/mode = FALSE //if FALSE, is in normal meson mode.
/obj/item/clothing/glasses/meson/Initialize()
. = ..()
picked_excuse = pick(meson_mining_failure_excuses)
START_PROCESSING(SSobj, src)
/obj/item/clothing/glasses/meson/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clothing/glasses/meson/examine(mob/user)
..()
var/turf/T = get_turf(src)
if(T && T.z == ZLEVEL_MINING && mode && picked_excuse)
to_chat(user, "<span class='warning'>Due to [picked_excuse], these Meson Scanners will not be able to display terrain layouts in this area.</span>")
/obj/item/clothing/glasses/meson/proc/toggle_mode(mob/user)
if(vision_flags & SEE_TURFS)
mode = TRUE
vision_flags &= ~SEE_TURFS
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(picked_excuse)
to_chat(H, "<span class='warning'>Due to [picked_excuse], your Meson Scanners will not be able to display terrain layouts in this area.</span>")
if(H.glasses == src)
H.update_sight()
else if(!(vision_flags & SEE_TURFS))
mode = FALSE
vision_flags |= SEE_TURFS
if(ishuman(user))
var/mob/living/carbon/human/H = user
to_chat(H, "<span class='notice'>Your Meson Scanners have reactivated.</span>")
if(H.glasses == src)
H.update_sight()
/obj/item/clothing/glasses/meson/process()
var/turf/T = get_turf(src)
if(T && T.z == ZLEVEL_MINING)
if(!mode)
toggle_mode(loc)
else if(mode)
toggle_mode(loc)
/obj/item/clothing/glasses/meson/night
name = "Night Vision Optical Meson Scanner"
@@ -47,7 +93,7 @@
item_state = "nvgmeson"
origin_tech = "magnets=4;engineering=5;plasmatech=4"
darkness_view = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
glass_colour_type = /datum/client_colour/glass_colour/green
/obj/item/clothing/glasses/meson/gar
+6 -6
View File
@@ -14,14 +14,14 @@
/obj/item/clothing/suit/armor/vest
name = "armor vest"
desc = "A slim armored vest that protects against most types of damage."
desc = "A slim Type I armored vest that provides decent protection against most types of damage."
icon_state = "armoralt"
item_state = "armoralt"
blood_overlay_type = "armor"
dog_fashion = /datum/dog_fashion/back
/obj/item/clothing/suit/armor/vest/alt
desc = "An armored vest that protects against most types of damage."
desc = "A Type I armored vest that provides decent protection against most types of damage."
icon_state = "armor"
item_state = "armor"
@@ -31,7 +31,7 @@
/obj/item/clothing/suit/armor/hos
name = "armored greatcoat"
desc = "A greatcoat enchanced with a special alloy for some protection and style for those with a commanding presence."
desc = "A greatcoat enhanced with a special alloy for some extra protection and style for those with a commanding presence."
icon_state = "hos"
item_state = "greatcoat"
body_parts_covered = CHEST|GROIN|ARMS|LEGS
@@ -77,7 +77,7 @@
/obj/item/clothing/suit/armor/vest/capcarapace
name = "captain's carapace"
desc = "An armored vest reinforced with ceramic plates and pauldrons to provide additional protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest, although it does chafe your nipples."
desc = "An fireproof armored chestpiece reinforced with ceramic plates and plasteel pauldrons to provide additional protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest, although it does chafe your nipples."
icon_state = "capcarapace"
item_state = "armor"
body_parts_covered = CHEST|GROIN
@@ -93,7 +93,7 @@
/obj/item/clothing/suit/armor/riot
name = "riot suit"
desc = "A suit of armor with heavy padding to protect against melee attacks."
desc = "A suit of semi-flexible polycarbonate body armor with heavy padding to protect against melee attacks."
icon_state = "riot"
item_state = "swat_suit"
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
@@ -115,7 +115,7 @@
/obj/item/clothing/suit/armor/bulletproof
name = "bulletproof armor"
desc = "A bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent."
desc = "A Type III heavy bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent."
icon_state = "bulletproof"
item_state = "armor"
blood_overlay_type = "armor"
-5
View File
@@ -28,7 +28,6 @@
var/square_depth_up = 0
var/square_depth_down = 0
//Processing
var/requires_processing = FALSE
var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary
var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
@@ -40,11 +39,7 @@
var/list/turf/field_turfs_new = list()
var/list/turf/edge_turfs_new = list()
/datum/proximity_monitor/advanced/New()
SSfields.register_new_field(src)
/datum/proximity_monitor/advanced/Destroy()
SSfields.unregister_field(src)
full_cleanup()
return ..()
+5 -1
View File
@@ -3,7 +3,6 @@
//Only use square radius for this!
/datum/proximity_monitor/advanced/peaceborg_dampener
name = "\improper Hyperkinetic Dampener Field"
requires_processing = TRUE
setup_edge_turfs = TRUE
setup_field_turfs = TRUE
field_shape = FIELD_SHAPE_RADIUS_SQUARE
@@ -22,10 +21,15 @@
use_host_turf = TRUE
/datum/proximity_monitor/advanced/peaceborg_dampener/New()
START_PROCESSING(SSfields, src)
tracked = list()
staging = list()
..()
/datum/proximity_monitor/advanced/peaceborg_dampener/Destroy()
STOP_PROCESSING(SSfields, src)
return ..()
/datum/proximity_monitor/advanced/peaceborg_dampener/process()
if(!istype(projector))
qdel(src)
+1 -1
View File
@@ -125,7 +125,7 @@
/datum/language_holder/synthetic
languages = list(/datum/language/common)
shadow_languages = list(/datum/language/machine, /datum/language/draconic)
shadow_languages = list(/datum/language/common, /datum/language/machine, /datum/language/draconic)
/datum/language_holder/universal/New()
..()
+2 -2
View File
@@ -270,7 +270,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
if(5)
dat += "<H3>Upload a New Title</H3>"
if(!scanner)
findscanner(9)
scanner = findscanner(9)
if(!scanner)
dat += "<FONT color=red>No scanner found within wireless network range.</FONT><BR>"
else if(!scanner.cache)
@@ -314,7 +314,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
popup.open()
/obj/machinery/computer/libraryconsole/bookmanagement/proc/findscanner(viewrange)
for(var/obj/machinery/libraryscanner/S in range(viewrange))
for(var/obj/machinery/libraryscanner/S in range(viewrange, get_turf(src)))
return S
return null
+78 -99
View File
@@ -169,7 +169,7 @@
icon = 'icons/obj/mining.dmi'
icon_state = "resonator"
item_state = "resonator"
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in a vacuum."
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It's more effective in a vacuum."
w_class = WEIGHT_CLASS_NORMAL
force = 15
throwforce = 10
@@ -188,18 +188,6 @@
fieldlimit = 6
quick_burst_mod = 1
/obj/item/weapon/resonator/proc/CreateResonance(target, creator)
var/turf/T = get_turf(target)
var/obj/effect/resonance/R = locate(/obj/effect/resonance) in T
if(R)
R.resonance_damage *= quick_burst_mod
R.burst()
return
if(fields.len < fieldlimit)
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
var/obj/effect/resonance/RE = new(T, creator, burst_time, src)
fields += RE
/obj/item/weapon/resonator/attack_self(mob/user)
if(burst_time == 50)
burst_time = 30
@@ -208,57 +196,76 @@
burst_time = 50
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 5 seconds.</span>")
/obj/item/weapon/resonator/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag)
if(!check_allowed_items(target, 1))
return
/obj/item/weapon/resonator/proc/CreateResonance(target, mob/user)
var/turf/T = get_turf(target)
var/obj/effect/temp_visual/resonance/R = locate(/obj/effect/temp_visual/resonance) in T
if(R)
R.damage_multiplier = quick_burst_mod
R.burst()
return
if(LAZYLEN(fields) < fieldlimit)
new /obj/effect/temp_visual/resonance(T, user, src, burst_time)
user.changeNext_move(CLICK_CD_MELEE)
CreateResonance(target, user)
/obj/effect/resonance
/obj/item/weapon/resonator/pre_attackby(atom/target, mob/user, params)
if(check_allowed_items(target, 1))
CreateResonance(target, user)
return TRUE
/obj/effect/temp_visual/resonance
name = "resonance field"
desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures. More damaging in low pressure environments."
icon = 'icons/effects/effects.dmi'
icon_state = "shield1"
layer = ABOVE_ALL_MOB_LAYER
anchored = TRUE
mouse_opacity = 0
duration = 50
var/resonance_damage = 20
var/damage_multiplier = 1
var/creator
var/obj/item/weapon/resonator/res
/obj/effect/resonance/New(loc, set_creator, timetoburst, set_resonator)
..()
/obj/effect/temp_visual/resonance/Initialize(mapload, set_creator, set_resonator, set_duration)
duration = set_duration
. = ..()
creator = set_creator
res = set_resonator
check_pressure()
addtimer(CALLBACK(src, .proc/burst), timetoburst)
if(res)
res.fields += src
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
transform = matrix()*0.75
animate(src, transform = matrix()*1.5, time = duration)
deltimer(timerid)
timerid = addtimer(CALLBACK(src, .proc/burst), duration, TIMER_STOPPABLE)
/obj/effect/resonance/Destroy()
/obj/effect/temp_visual/resonance/Destroy()
if(res)
res.fields -= src
res = null
creator = null
. = ..()
/obj/effect/resonance/proc/check_pressure()
var/turf/proj_turf = get_turf(src)
/obj/effect/temp_visual/resonance/proc/check_pressure(turf/proj_turf)
if(!proj_turf)
proj_turf = get_turf(src)
if(!istype(proj_turf))
return
var/datum/gas_mixture/environment = proj_turf.return_air()
var/pressure = environment.return_pressure()
resonance_damage = initial(resonance_damage)
if(pressure < 50)
name = "strong [initial(name)]"
resonance_damage = 60
resonance_damage *= 3
else
name = initial(name)
resonance_damage = initial(resonance_damage)
resonance_damage *= damage_multiplier
/obj/effect/resonance/proc/burst()
check_pressure()
/obj/effect/temp_visual/resonance/proc/burst()
var/turf/T = get_turf(src)
playsound(src,'sound/weapons/resonator_blast.ogg',50,1)
new /obj/effect/temp_visual/resonance_crush(T)
if(ismineralturf(T))
var/turf/closed/mineral/M = T
M.gets_drilled(creator)
check_pressure(T)
playsound(T,'sound/weapons/resonator_blast.ogg',50,1)
for(var/mob/living/L in T)
if(creator)
add_logs(creator, L, "used a resonator field on", "resonator")
@@ -266,6 +273,16 @@
L.apply_damage(resonance_damage, BRUTE)
qdel(src)
/obj/effect/temp_visual/resonance_crush
icon_state = "shield1"
layer = ABOVE_ALL_MOB_LAYER
duration = 4
/obj/effect/temp_visual/resonance_crush/Initialize()
. = ..()
transform = matrix()*1.5
animate(src, transform = matrix()*0.1, alpha = 50, time = 4)
/**********************Facehugger toy**********************/
/obj/item/clothing/mask/facehugger/toy
@@ -345,28 +362,23 @@
/**********************Mining Scanners**********************/
/obj/item/device/mining_scanner
desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results."
desc = "A scanner that checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations."
name = "manual mining scanner"
icon_state = "mining1"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
var/cooldown = 0
var/cooldown = 35
var/current_cooldown = 0
origin_tech = "engineering=1;magnets=1"
/obj/item/device/mining_scanner/attack_self(mob/user)
if(!user.client)
return
if(!cooldown)
cooldown = TRUE
addtimer(CALLBACK(src, .proc/clear_cooldown), 40)
var/list/mobs = list()
mobs |= user
mineral_scan_pulse(mobs, get_turf(user))
/obj/item/device/mining_scanner/proc/clear_cooldown()
cooldown = FALSE
if(current_cooldown <= world.time)
current_cooldown = world.time + cooldown
mineral_scan_pulse(get_turf(user))
//Debug item to identify all ore spread quickly
@@ -379,7 +391,7 @@
qdel(src)
/obj/item/device/t_scanner/adv_mining_scanner
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results. This one has an extended range."
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. This one has an extended range."
name = "advanced automatic mining scanner"
icon_state = "mining0"
item_state = "analyzer"
@@ -387,77 +399,47 @@
flags = CONDUCT
slot_flags = SLOT_BELT
var/cooldown = 35
var/on_cooldown = 0
var/current_cooldown = 0
var/range = 7
var/meson = TRUE
origin_tech = "engineering=3;magnets=3"
/obj/item/device/t_scanner/adv_mining_scanner/material
meson = FALSE
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results. This one has an extended range."
/obj/item/device/t_scanner/adv_mining_scanner/lesser
name = "automatic mining scanner"
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear meson scanners for optimal results."
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations."
range = 4
cooldown = 50
/obj/item/device/t_scanner/adv_mining_scanner/lesser/material
desc = "A scanner that automatically checks surrounding rock for useful minerals; it can also be used to stop gibtonite detonations. Wear material scanners for optimal results."
meson = FALSE
/obj/item/device/t_scanner/adv_mining_scanner/scan()
if(!on_cooldown)
on_cooldown = 1
spawn(cooldown)
on_cooldown = 0
if(current_cooldown <= world.time)
current_cooldown = world.time + cooldown
var/turf/t = get_turf(src)
var/list/mobs = recursive_mob_check(t, 1,0,0)
if(!mobs.len)
return
if(meson)
mineral_scan_pulse(mobs, t, range)
else
mineral_scan_pulse_material(mobs, t, range)
mineral_scan_pulse(t, range)
//For use with mesons
/proc/mineral_scan_pulse(list/mobs, turf/T, range = world.view)
/proc/mineral_scan_pulse(turf/T, range = world.view)
var/list/minerals = list()
for(var/turf/closed/mineral/M in range(range, T))
if(M.scan_state)
minerals += M
if(minerals.len)
for(var/mob/user in mobs)
if(user.client)
var/client/C = user.client
for(var/turf/closed/mineral/M in minerals)
var/turf/F = get_turf(M)
var/image/I = image('icons/turf/smoothrocks.dmi', loc = F, icon_state = M.scan_state, layer = FLASH_LAYER)
I.plane = FULLSCREEN_PLANE
C.images += I
spawn(30)
if(C)
C.images -= I
//For use with material scanners
/proc/mineral_scan_pulse_material(list/mobs, turf/T, range = world.view)
var/list/minerals = list()
for(var/turf/closed/mineral/M in range(range, T))
if(M.scan_state)
minerals += M
if(minerals.len)
if(LAZYLEN(minerals))
for(var/turf/closed/mineral/M in minerals)
var/obj/effect/temp_visual/mining_overlay/oldC = locate(/obj/effect/temp_visual/mining_overlay) in M
if(oldC)
qdel(oldC)
var/obj/effect/temp_visual/mining_overlay/C = new /obj/effect/temp_visual/mining_overlay(M)
C.icon_state = M.scan_state
/obj/effect/temp_visual/mining_overlay
plane = FULLSCREEN_PLANE
layer = FLASH_LAYER
icon = 'icons/turf/smoothrocks.dmi'
anchored = 1
mouse_opacity = 0
duration = 30
pixel_x = -4
pixel_y = -4
icon = 'icons/effects/ore_visuals.dmi'
appearance_flags = 0 //to avoid having TILE_BOUND in the flags, so that the 480x480 icon states let you see it no matter where you are
duration = 35
pixel_x = -224
pixel_y = -224
/obj/effect/temp_visual/mining_overlay/Initialize()
. = ..()
animate(src, alpha = 0, time = duration, easing = EASE_IN)
/**********************Xeno Warning Sign**********************/
@@ -529,7 +511,6 @@
return ..()
/obj/item/projectile/destabilizer/on_hit(atom/target, blocked = 0)
if(isliving(target))
var/mob/living/L = target
var/datum/status_effect/crusher_mark/CM = L.apply_status_effect(STATUS_EFFECT_CRUSHERMARK)
@@ -539,7 +520,6 @@
var/turf/closed/mineral/M = target_turf
new /obj/effect/temp_visual/kinetic_blast(M)
M.gets_drilled(firer)
..()
/obj/item/weapon/twohanded/required/mining_hammer/afterattack(atom/target, mob/user, proximity_flag)
@@ -570,7 +550,6 @@
else
L.apply_damage(50, BRUTE, blocked = def_check)
/obj/item/weapon/twohanded/required/mining_hammer/proc/Recharge()
if(!charged)
charged = TRUE
@@ -821,7 +821,9 @@
timer = world.time + cooldown_time
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
chaser_timer = world.time + chaser_cooldown
new /obj/effect/temp_visual/hierophant/chaser(get_turf(user), user, target, chaser_speed, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(user), user, target, chaser_speed, friendly_fire_check)
C.damage = 30
C.monster_damage_boost = FALSE
add_logs(user, target, "fired a chaser at", src)
else
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
+1 -1
View File
@@ -19,7 +19,7 @@
new /datum/data/mining_equipment("Stabilizing Serum", /obj/item/weapon/hivelordstabilizer, 400),
new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 400),
new /datum/data/mining_equipment("Shelter Capsule", /obj/item/weapon/survivalcapsule, 400),
new /datum/data/mining_equipment("GAR scanners", /obj/item/clothing/glasses/meson/gar, 500),
new /datum/data/mining_equipment("GAR Meson Scanners", /obj/item/clothing/glasses/meson/gar, 500),
new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/weapon/storage/belt/mining, 500),
new /datum/data/mining_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/medipen/survival, 500),
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/weapon/storage/firstaid/brute, 600),
-20
View File
@@ -44,7 +44,6 @@
var/light_on = 0
var/datum/action/innate/minedrone/toggle_light/toggle_light_action
var/datum/action/innate/minedrone/toggle_meson_vision/toggle_meson_vision_action
var/datum/action/innate/minedrone/toggle_mode/toggle_mode_action
var/datum/action/innate/minedrone/dump_ore/dump_ore_action
@@ -52,8 +51,6 @@
..()
toggle_light_action = new()
toggle_light_action.Grant(src)
toggle_meson_vision_action = new()
toggle_meson_vision_action.Grant(src)
toggle_mode_action = new()
toggle_mode_action.Grant(src)
dump_ore_action = new()
@@ -189,23 +186,6 @@
user.light_on = !user.light_on
to_chat(user, "<span class='notice'>You toggle your light [user.light_on ? "on" : "off"].</span>")
/datum/action/innate/minedrone/toggle_meson_vision
name = "Toggle Meson Vision"
button_icon_state = "meson"
/datum/action/innate/minedrone/toggle_meson_vision/Activate()
var/mob/living/simple_animal/hostile/mining_drone/user = owner
if(user.sight & SEE_TURFS)
user.sight &= ~SEE_TURFS
user.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
else
user.sight |= SEE_TURFS
user.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
user.sync_lighting_plane_alpha()
to_chat(user, "<span class='notice'>You toggle your meson vision [(user.sight & SEE_TURFS) ? "on" : "off"].</span>")
/datum/action/innate/minedrone/toggle_mode
name = "Toggle Mode"
button_icon_state = "mech_cycle_equip_off"
@@ -36,7 +36,8 @@
//initialise organs
create_internal_organs()
martial_art = default_martial_art
if(mind)
mind.martial_art = mind.default_martial_art
handcrafting = new()
@@ -40,12 +40,13 @@
if(spec_return)
return spec_return
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
if(mind)
if(mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -103,10 +104,11 @@
return 0
/mob/living/carbon/human/proc/check_block()
if(martial_art && martial_art.block_chance \
&& prob(martial_art.block_chance) && in_throw_mode \
&& !stat && !weakened && !stunned)
return TRUE
if(mind)
if(mind.martial_art && mind.martial_art.block_chance \
&& prob(mind.martial_art.block_chance) && in_throw_mode \
&& !stat && !weakened && !stunned)
return TRUE
return FALSE
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
@@ -39,9 +39,6 @@
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
var/datum/martial_art/martial_art = null
var/static/default_martial_art = new/datum/martial_art
var/name_override //For temporary visible name changes
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
@@ -144,9 +144,9 @@
if(NOGUNS in src.dna.species.species_traits)
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
return 0
if(martial_art && martial_art.no_guns) //great dishonor to famiry
to_chat(src, "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>")
return 0
if(mind)
if(mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry
to_chat(src, "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>")
return 0
return .
@@ -0,0 +1,9 @@
/mob/living/carbon/human/Login()
..()
if(src.martial_art == default_martial_art && mind.stored_martial_art) //If the mind has a martial art stored and the body has the default one.
src.mind.stored_martial_art.teach(src) //Running teach so that it deals with help verbs.
else if(src.martial_art != default_martial_art && src.martial_art != mind.stored_martial_art) //If the body has a martial art which is not the default one and is not stored in the mind.
if(src.martial_art_owner != mind)
src.martial_art.remove(src)
else
src.mind.stored_martial_art = src.martial_art
@@ -1304,7 +1304,7 @@
/datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
return
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
if(!istype(M))
return
CHECK_DNA_AND_SPECIES(M)
@@ -1312,6 +1312,8 @@
if(!istype(M)) //sanity check for drones.
return
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK))
add_logs(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
@@ -406,7 +406,7 @@
else
reactive_teleport(H)
/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP)
reactive_teleport(H)
@@ -490,7 +490,7 @@
var/golem_name = "[uppertext(clown_name)]"
return golem_name
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
@@ -526,7 +526,6 @@
name = "Miner"
basic_modules = list(
/obj/item/device/assembly/flash/cyborg,
/obj/item/borg/sight/meson,
/obj/item/weapon/storage/bag/ore/cyborg,
/obj/item/weapon/pickaxe/drill/cyborg,
/obj/item/weapon/shovel,
@@ -123,8 +123,9 @@ Difficulty: Very Hard
/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.martial_art && prob(H.martial_art.deflection_chance))
. = TRUE
if(H.mind)
if(H.mind.martial_art && prob(H.mind.martial_art.deflection_chance))
. = TRUE
/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots()
dir_shots(GLOB.diagonals)
@@ -525,7 +525,9 @@ Difficulty: Hard
targetturf = get_turf(target)
/obj/effect/temp_visual/hierophant/chaser/proc/make_blast()
new /obj/effect/temp_visual/hierophant/blast(loc, caster, friendly_fire_check)
var/obj/effect/temp_visual/hierophant/blast/B = new(loc, caster, friendly_fire_check)
B.damage = damage
B.monster_damage_boost = monster_damage_boost
/obj/effect/temp_visual/hierophant/telegraph
icon = 'icons/effects/96x96.dmi'
+5 -1
View File
@@ -295,8 +295,12 @@
return A
else
var/atom/movable/AM = A
if(AM == buckled) //Kind of unnecessary but let's just be sure
if(AM == buckled)
continue
if(ismob(AM))
var/mob/M = AM
if(M.buckled)
continue
if(!AM.CanPass(src) || AM.density)
if(AM.anchored)
return AM
+2 -2
View File
@@ -44,8 +44,8 @@
..()
/obj/item/weapon/paper/New()
..()
/obj/item/weapon/paper/Initialize()
. = ..()
pixel_y = rand(-8, 8)
pixel_x = rand(-9, 9)
update_icon()
+1 -1
View File
@@ -110,7 +110,7 @@
papers.Add(P)
total_paper++
update_icon()
else if(istype(I, /obj/item/weapon/pen))
else if(istype(I, /obj/item/weapon/pen) && !bin_pen)
var/obj/item/weapon/pen/P = I
if(!user.transferItemToLoc(P, src))
return
@@ -13,6 +13,21 @@
max_ammo = 8
multiple_sprites = 2
/obj/item/ammo_box/magazine/m10mm/rifle
name = "rifle magazine (10mm)"
desc = "A well-worn magazine fitted for the surplus rifle."
icon_state = "75-8"
origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c10mm
caliber = "10mm"
max_ammo = 10
/obj/item/ammo_box/magazine/m10mm/rifle/update_icon()
if(ammo_count())
icon_state = "75-8"
else
icon_state = "75-0"
/obj/item/ammo_box/magazine/m10mm/fire
name = "pistol magazine (10mm incendiary)"
desc = "A gun magazine. Loaded with rounds which ignite the target."
@@ -52,16 +67,31 @@
/obj/item/ammo_box/magazine/wt550m9/wtap
name = "wt550 magazine (Armour Piercing 4.6x30mm)"
icon_state = "46x30mmtA-20"
ammo_type = /obj/item/ammo_casing/c46x30mmap
/obj/item/ammo_box/magazine/wt550m9/wtap/update_icon()
..()
icon_state = "46x30mmtA-[round(ammo_count(),4)]"
/obj/item/ammo_box/magazine/wt550m9/wttx
name = "wt550 magazine (Toxin Tipped 4.6x30mm)"
icon_state = "46x30mmtT-20"
ammo_type = /obj/item/ammo_casing/c46x30mmtox
/obj/item/ammo_box/magazine/wt550m9/wttx/update_icon()
..()
icon_state = "46x30mmtT-[round(ammo_count(),4)]"
/obj/item/ammo_box/magazine/wt550m9/wtic
name = "wt550 magazine (Incindiary 4.6x30mm)"
icon_state = "46x30mmtI-20"
ammo_type = /obj/item/ammo_casing/c46x30mminc
/obj/item/ammo_box/magazine/wt550m9/wtic/update_icon()
..()
icon_state = "46x30mmtI-[round(ammo_count(),4)]"
/obj/item/ammo_box/magazine/uzim9mm
name = "uzi magazine (9mm)"
icon_state = "uzi9mm-32"
@@ -109,6 +109,11 @@
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
max_ammo = 6
/obj/item/ammo_box/magazine/internal/shot/com/compact
name = "compact combat shotgun internal magazine"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
max_ammo = 4
/obj/item/ammo_box/magazine/internal/shot/dual
name = "double-barrel shotgun internal magazine"
max_ammo = 2
@@ -375,8 +375,29 @@
pin = /obj/item/device/firing_pin/implant/pindicate
origin_tech = "combat=7;syndicate=6"
// Old Semi-Auto Rifle //
/obj/item/weapon/gun/ballistic/automatic/surplus
name = "Surplus Rifle"
desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing."
origin_tech = "combat=3;materials=2"
icon_state = "surplus"
item_state = "moistnugget"
weapon_weight = WEAPON_HEAVY
mag_type = /obj/item/ammo_box/magazine/m10mm/rifle
fire_delay = 30
burst_size = 1
can_unsuppress = 1
can_suppress = 1
w_class = WEIGHT_CLASS_HUGE
slot_flags = SLOT_BACK
actions_types = list()
/obj/item/weapon/gun/ballistic/automatic/surplus/update_icon()
if(magazine)
icon_state = "surplus"
else
icon_state = "surplus-e"
// Laser rifle (rechargeable magazine) //
@@ -344,6 +344,15 @@
slung = 0
update_icon()
/obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun, better not miss"
icon_state = "ishotgun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
sawn_state = SAWN_OFF
slot_flags = SLOT_BELT
/obj/item/weapon/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
clumsy_check = 0
@@ -192,6 +192,14 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
w_class = WEIGHT_CLASS_HUGE
/obj/item/weapon/gun/ballistic/shotgun/automatic/combat/compact
name = "compact combat shotgun"
desc = "A compact version of the semi automatic combat shotgun. For close encounters."
icon_state = "cshotgunc"
origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact
w_class = WEIGHT_CLASS_BULKY
//Dual Feed Shotgun
/obj/item/weapon/gun/ballistic/shotgun/automatic/dual_tube
@@ -1,10 +0,0 @@
diff a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm (rejected hunks)
@@ -203,7 +203,7 @@
range = 4
dismemberment = 20
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
- var/mine_range = 4 //mines this many additional tiles
+ var/mine_range = 3 //mines this many additional tiles
/obj/item/projectile/plasma/Initialize()
. = ..()
+2 -2
View File
@@ -453,14 +453,14 @@
/datum/reagents/proc/check_ignoreslow(mob/M)
if(istype(M, /mob))
if(M.reagents.has_reagent("morphine")||M.reagents.has_reagent("ephedrine"))
if(M.reagents.has_reagent("morphine"))
return 1
else
M.status_flags &= ~IGNORESLOWDOWN
/datum/reagents/proc/check_gofast(mob/M)
if(istype(M, /mob))
if(M.reagents.has_reagent("unholywater")||M.reagents.has_reagent("nuka_cola")||M.reagents.has_reagent("stimulants"))
if(M.reagents.has_reagent("unholywater")||M.reagents.has_reagent("nuka_cola")||M.reagents.has_reagent("stimulants")||M.reagents.has_reagent("ephedrine"))
return 1
else
M.status_flags &= ~GOTTAGOFAST
@@ -1,285 +1,183 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
density = 1
anchored = 1
density = TRUE
anchored = TRUE
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0"
circuit = /obj/item/weapon/circuitboard/computer/pandemic
use_power = 1
use_power = TRUE
idle_power_usage = 20
resistance_flags = ACID_PROOF
var/temp_html = ""
var/wait = null
var/obj/item/weapon/reagent_containers/beaker = null
var/wait
var/obj/item/weapon/reagent_containers/beaker
/obj/machinery/computer/pandemic/Initialize()
. = ..()
update_icon()
/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["viruses"])
var/list/viruses = BL.data["viruses"]
return viruses[index]
return null
/obj/machinery/computer/pandemic/Destroy()
QDEL_NULL(beaker)
return ..()
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["resistances"])
var/list/resistances = BL.data["resistances"]
return resistances[index]
return null
/obj/machinery/computer/pandemic/proc/get_by_index(thing, index)
if(!beaker || !beaker.reagents)
return
var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list
if(B && B.data[thing])
return B.data[thing][index]
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
var/datum/disease/D = GetVirusByIndex(index)
/obj/machinery/computer/pandemic/proc/get_virus_id_by_index(index)
var/datum/disease/D = get_by_index("viruses", index)
if(D)
return D.GetDiseaseID()
return null
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
wait = 1
/obj/machinery/computer/pandemic/proc/get_viruses_data(datum/reagent/blood/B)
. = list()
if(!islist(B.data["viruses"]))
return
var/list/V = B.data["viruses"]
var/index = 1
for(var/virus in V)
var/datum/disease/D = virus
if(!istype(D) || D.visibility_flags & HIDDEN_PANDEMIC)
continue
var/list/this = list()
this["name"] = D.name
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = SSdisease.archive_diseases[D.GetDiseaseID()]
if(A.name == "Unknown")
this["can_rename"] = TRUE
this["name"] = A.name
this["is_adv"] = TRUE
this["resistance"] = A.totalResistance()
this["stealth"] = A.totalStealth()
this["stage_speed"] = A.totalStageSpeed()
this["transmission"] = A.totalTransmittable()
this["symptoms"] = list()
for(var/symptom in A.symptoms)
var/datum/symptom/S = symptom
var/list/this_symptom = list()
this_symptom["name"] = S.name
this["symptoms"] += list(this_symptom)
this["index"] = index++
this["agent"] = D.agent
this["description"] = D.desc || "none"
this["spread"] = D.spread_text || "none"
this["cure"] = D.cure_text || "none"
. += list(this)
/obj/machinery/computer/pandemic/proc/get_resistance_data(datum/reagent/blood/B)
. = list()
if(!islist(B.data["resistances"]))
return
var/list/resistances = B.data["resistances"]
for(var/id in resistances)
var/list/this = list()
var/datum/disease/D = SSdisease.archive_diseases[id]
if(D)
this["id"] = id
this["name"] = D.name
. += list(this)
/obj/machinery/computer/pandemic/proc/reset_replicator_cooldown()
wait = FALSE
update_icon()
spawn(waittime)
wait = null
update_icon()
playsound(src.loc, 'sound/machines/ping.ogg', 30, 1)
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
/obj/machinery/computer/pandemic/update_icon()
if(stat & BROKEN)
icon_state = (beaker ? "mixer1_b" : "mixer0_b")
return
icon_state = "mixer[(beaker)?"1":"0"][(powered()) ? "" : "_nopower"]"
icon_state = "mixer[(beaker) ? "1" : "0"][powered() ? "" : "_nopower"]"
if(wait)
cut_overlays()
else
add_overlay("waitlight")
/obj/machinery/computer/pandemic/Topic(href, href_list)
/obj/machinery/computer/pandemic/proc/eject_beaker()
beaker.forceMove(get_turf(src))
beaker = null
update_icon()
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "pandemic", name, 575, 500, master_ui, state)
ui.open()
/obj/machinery/computer/pandemic/ui_data(mob/user)
var/list/data = list()
data["is_ready"] = !wait
if(beaker)
data["has_beaker"] = TRUE
if(!beaker.reagents.total_volume || !beaker.reagents.reagent_list)
data["beaker_empty"] = TRUE
var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list
if(B)
data["has_blood"] = TRUE
data["blood"] = list()
data["blood"]["dna"] = B.data["blood_DNA"] || "none"
data["blood"]["type"] = B.data["blood_type"] || "none"
data["viruses"] = get_viruses_data(B)
data["resistances"] = get_resistance_data(B)
return data
/obj/machinery/computer/pandemic/ui_act(action, params)
if(..())
return
usr.set_machine(src)
if(!beaker) return
if (href_list["create_vaccine"])
if(!src.wait)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
if(B)
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
var/path = GetResistancesByIndex(text2num(href_list["create_vaccine"]))
var/vaccine_type = path
var/vaccine_name = "Unknown"
if(!ispath(vaccine_type))
if(SSdisease.archive_diseases[path])
var/datum/disease/D = SSdisease.archive_diseases[path]
if(D)
vaccine_name = D.name
vaccine_type = path
else if(vaccine_type)
var/datum/disease/D = new vaccine_type(0, null)
if(D)
vaccine_name = D.name
if(vaccine_type)
B.name = "[vaccine_name] vaccine bottle"
B.reagents.add_reagent("vaccine", 15, list(vaccine_type))
replicator_cooldown(200)
else
temp_html = "The replicator is not ready yet."
updateUsrDialog()
return
else if (href_list["create_virus_culture"])
if(!wait)
var/type = GetVirusTypeByIndex(text2num(href_list["create_virus_culture"]))//the path is received as string - converting
var/datum/disease/D = null
if(!ispath(type))
D = GetVirusByIndex(text2num(href_list["create_virus_culture"]))
var/datum/disease/advance/A = SSdisease.archive_diseases[D.GetDiseaseID()]
if(A)
D = new A.type(0, A)
else if(type)
if(type in SSdisease.diseases) // Make sure this is a disease
D = new type(0, null)
if(!D)
return
var/name = stripped_input(usr,"Name:","Name the culture",D.name,MAX_NAME_LEN)
if(name == null || wait)
return
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
B.icon_state = "bottle3"
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
replicator_cooldown(50)
var/list/data = list("viruses"=list(D))
B.name = "[name] culture bottle"
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
B.reagents.add_reagent("blood",20,data)
updateUsrDialog()
else
temp_html = "The replicator is not ready yet."
updateUsrDialog()
return
else if (href_list["empty_beaker"])
beaker.reagents.clear_reagents()
updateUsrDialog()
return
else if (href_list["eject"])
beaker.forceMove(get_turf(loc))
beaker = null
icon_state = "mixer0"
updateUsrDialog()
return
else if (href_list["emptyeject_beaker"])
beaker.reagents.clear_reagents()
beaker.forceMove(get_turf(loc))
beaker = null
icon_state = "mixer0"
updateUsrDialog()
return
else if(href_list["clear"])
temp_html = ""
updateUsrDialog()
return
else if(href_list["name_disease"])
var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN)
if(!new_name)
return
if(..())
return
var/id = GetVirusTypeByIndex(text2num(href_list["name_disease"]))
if(SSdisease.archive_diseases[id])
switch(action)
if("eject_beaker")
eject_beaker()
. = TRUE
if("empty_beaker")
beaker.reagents.clear_reagents()
. = TRUE
if("empty_eject_beaker")
beaker.reagents.clear_reagents()
eject_beaker()
. = TRUE
if("rename_disease")
var/id = get_virus_id_by_index(text2num(params["index"]))
var/datum/disease/advance/A = SSdisease.archive_diseases[id]
A.AssignName(new_name)
for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
updateUsrDialog()
else
usr << browse(null, "window=pandemic")
updateUsrDialog()
return
add_fingerprint(usr)
return
/obj/machinery/computer/pandemic/attack_hand(mob/user)
if(..())
return
user.set_machine(src)
var/dat = ""
if(temp_html)
dat = "[src.temp_html]<BR><BR><A href='?src=\ref[src];clear=1'>Main Menu</A>"
else if(!beaker)
dat += "Please insert beaker.<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
else
var/datum/reagents/R = beaker.reagents
var/datum/reagent/blood/Blood = null
for(var/datum/reagent/blood/B in R.reagent_list)
if(B)
Blood = B
break
if(!R.total_volume||!R.reagent_list.len)
dat += "The beaker is empty<BR>"
else if(!Blood)
dat += "No blood sample found in beaker."
else if(!Blood.data)
dat += "No blood data found in beaker."
else
dat += "<h3>Blood sample data:</h3>"
dat += "<b>Blood DNA:</b> [(Blood.data["blood_DNA"]||"none")]<BR>"
dat += "<b>Blood Type:</b> [(Blood.data["blood_type"]||"none")]<BR>"
if(Blood.data["viruses"])
var/list/vir = Blood.data["viruses"]
if(vir.len)
var/i = 0
for(var/datum/disease/D in Blood.data["viruses"])
i++
if(!(D.visibility_flags & HIDDEN_PANDEMIC))
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
D = SSdisease.archive_diseases[A.GetDiseaseID()]
if(D && D.name == "Unknown")
dat += "<b><a href='?src=\ref[src];name_disease=[i]'>Name Disease</a></b><BR>"
if(!D)
CRASH("We weren't able to get the advance disease from the archive.")
dat += "<b>Disease Agent:</b> [D?"[D.agent] - <A href='?src=\ref[src];create_virus_culture=[i]'>Create virus culture bottle</A>":"none"]<BR>"
dat += "<b>Common name:</b> [(D.name||"none")]<BR>"
dat += "<b>Description: </b> [(D.desc||"none")]<BR>"
dat += "<b>Spread:</b> [(D.spread_text||"none")]<BR>"
dat += "<b>Possible cure:</b> [(D.cure_text||"none")]<BR><BR>"
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
dat += "<b>Stealth:</b> [(A.totalStealth())]<BR>"
dat += "<b>Resistance:</b> [(A.totalResistance())]<BR>"
dat += "<b>Stage Speed:</b> [(A.totalStageSpeed())]<BR>"
dat += "<b>Transmission:</b> [(A.totalTransmittable())]<BR><BR>"
dat += "<b>Symptoms:</b> "
var/english_symptoms = list()
for(var/datum/symptom/S in A.symptoms)
english_symptoms += S.name
dat += english_list(english_symptoms)
else
dat += "No detectable virus in the sample."
else
dat += "No detectable virus in the sample."
dat += "<BR><b>Contains antibodies to:</b> "
if(Blood.data["resistances"])
var/list/res = Blood.data["resistances"]
if(res.len)
dat += "<ul>"
var/i = 0
for(var/type in Blood.data["resistances"])
i++
var/disease_name = "Unknown"
if(!ispath(type))
var/datum/disease/advance/A = SSdisease.archive_diseases[type]
if(A)
disease_name = A.name
else
var/datum/disease/D = new type(0, null)
disease_name = D.name
dat += "<li>[disease_name] - <A href='?src=\ref[src];create_vaccine=[i]'>Create vaccine bottle</A></li>"
dat += "</ul><BR>"
else
dat += "nothing<BR>"
else
dat += "nothing<BR>"
dat += "<BR><A href='?src=\ref[src];eject=1'>Eject beaker</A>[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];empty_beaker=1'>Empty beaker</A>":"")]"
dat += "[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];emptyeject_beaker=1'>Empty and Eject beaker</A>":"")]<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
user << browse("<TITLE>[src.name]</TITLE><BR>[dat]", "window=pandemic;size=575x400")
onclose(user, "pandemic")
return
if(A)
var/new_name = stripped_input(usr, "Name the disease", "New name", "", MAX_NAME_LEN)
if(!new_name || ..())
return
A.AssignName(new_name)
for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
. = TRUE
if("create_culture_bottle")
var/id = get_virus_id_by_index(text2num(params["index"]))
var/datum/disease/advance/A = new(FALSE, SSdisease.archive_diseases[id])
var/list/data = list("viruses" = list(A))
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(get_turf(src))
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
B.reagents.add_reagent("blood", 20, data)
wait = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE
if("create_vaccine_bottle")
var/index = params["index"]
var/datum/disease/D = SSdisease.archive_diseases[index]
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(get_turf(src))
B.name = "[D.name] vaccine bottle"
B.reagents.add_reagent("vaccine", 15, list(index))
wait = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200)
. = TRUE
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/reagent_containers) && (I.container_type & OPENCONTAINER))
. = 1 //no afterattack
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
@@ -288,15 +186,15 @@
if(!user.drop_item())
return
beaker = I
beaker.loc = src
beaker = I
beaker.forceMove(src)
to_chat(user, "<span class='notice'>You add the beaker to the machine.</span>")
updateUsrDialog()
icon_state = "mixer1"
update_icon()
else
return ..()
/obj/machinery/computer/pandemic/on_deconstruction()
if(beaker)
beaker.loc = get_turf(src)
..()
beaker.forceMove(get_turf(src))
beaker = null
. = ..()
@@ -160,6 +160,12 @@
var/obj/item/toy/carpplushie/dehy_carp/dehy = O
dehy.Swell() // Makes a carp
else if(istype(O, /obj/item/stack/sheet/hairlesshide))
var/obj/item/stack/sheet/hairlesshide/HH = O
var/obj/item/stack/sheet/wetleather/WL = new(get_turf(HH))
WL.amount = HH.amount
qdel(HH)
/*
* Water reaction to a mob
*/
@@ -367,11 +373,15 @@
if(ishuman(M))
var/mob/living/carbon/human/N = M
if(N.dna.species.id == "human") // If they're human, turn em to the "orange" race, and give em spiky black hair
N.hair_style = "Spiky"
N.facial_hair_style = "Shaved"
N.facial_hair_color = "000"
N.hair_color = "000"
if(!(HAIR in N.dna.species.species_traits)) //No hair? No problem!
N.dna.species.species_traits += HAIR
if(N.dna.species.use_skintones)
N.skin_tone = "orange"
N.hair_style = "Spiky"
N.hair_color = "000"
if(MUTCOLORS in N.dna.species.species_traits) //Aliens with custom colors simply get turned orange
else if(MUTCOLORS in N.dna.species.species_traits) //Aliens with custom colors simply get turned orange
N.dna.features["mcolor"] = "f80"
N.regenerate_icons()
if(prob(7))
@@ -380,7 +390,7 @@
else
M.visible_message("<b>[M]</b> flexes [M.p_their()] arms.")
if(prob(10))
M.say(pick("Check these sweet biceps bro!", "Deal with it.", "CHUG! CHUG! CHUG! CHUG!", "Winning!", "NERDS!", "My name is John and I hate every single one of you."))
M.say(pick("Shit was SO cash.", "You are everything bad in the world.", "What sports do you play, other than 'jack off to naked drawn Japanese people?'", "Dont be a stranger. Just hit me with your best shot.", "My name is John and I hate every single one of you."))
..()
return
@@ -1126,7 +1136,7 @@
/datum/reagent/nitrous_oxide/reaction_mob(mob/M, method=TOUCH, reac_volume)
if(method == VAPOR)
M.drowsyness += max(round(reac_volume, 1), 2)
/datum/reagent/nitrous_oxide/on_mob_life(mob/living/M)
M.drowsyness += 2
if(ishuman(M))
+4 -3
View File
@@ -104,11 +104,12 @@
if(!operating)
return
use_power(100)
affecting = loc.contents - src // moved items will be all in loc
sleep(1)
addtimer(CALLBACK(src, .proc/convey, affecting), 1)
/obj/machinery/conveyor/proc/convey(list/affecting)
for(var/atom/movable/A in affecting)
if(A.loc == loc)
if((A.loc == loc) && A.has_gravity())
A.ConveyorMove(movedir)
// attack with item, place item on conveyor
+7 -3
View File
@@ -83,14 +83,18 @@
//sometimes we want to ignore that we don't have the required amount of legs.
/mob/proc/get_leg_ignore()
return 0
return FALSE
/mob/living/carbon/alien/larva/get_leg_ignore()
return 1
return TRUE
/mob/living/carbon/human/get_leg_ignore()
if(movement_type & FLYING)
return 1
return TRUE
var/obj/item/weapon/tank/jetpack/J = get_jetpack()
if(J && J.on && !has_gravity())
return TRUE
return FALSE
/mob/living/proc/get_missing_limbs()
return list()
+2 -2
View File
@@ -914,8 +914,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 3
/datum/uplink_item/device_tools/military_belt
name = "Military Belt"
desc = "A robust seven-slot red belt that is capable of holding all manner of tatical equipment."
name = "Chest Rig"
desc = "A robust seven-slot set of webbing that is capable of holding all manner of tatical equipment."
item = /obj/item/weapon/storage/belt/military
cost = 1
exclude_modes = list(/datum/game_mode/nuclear)