aaaand the rest of the modules folder

This commit is contained in:
deathride58
2018-01-04 01:45:38 -05:00
parent 8f593f0d00
commit aabbbb9dff
89 changed files with 629 additions and 788 deletions

View File

@@ -1,4 +1,4 @@
/obj/item/device/modular_computer/laptop/preset/New()
/obj/item/device/modular_computer/laptop/preset/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))

View File

@@ -3,7 +3,7 @@
/obj/item/device/modular_computer/tablet/preset/cheap
desc = "A low-end tablet often seen among low ranked station personnel."
/obj/item/device/modular_computer/tablet/preset/cheap/New()
/obj/item/device/modular_computer/tablet/preset/cheap/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer/micro))
@@ -11,7 +11,7 @@
install_component(new /obj/item/computer_hardware/network_card)
// Alternative version, an average one, for higher ranked positions mostly
/obj/item/device/modular_computer/tablet/preset/advanced/New()
/obj/item/device/modular_computer/tablet/preset/advanced/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
@@ -20,7 +20,7 @@
install_component(new /obj/item/computer_hardware/card_slot)
install_component(new /obj/item/computer_hardware/printer/mini)
/obj/item/device/modular_computer/tablet/preset/cargo/New()
/obj/item/device/modular_computer/tablet/preset/cargo/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))

View File

@@ -120,9 +120,9 @@
stored_files = null
return ..()
/obj/item/computer_hardware/hard_drive/New()
/obj/item/computer_hardware/hard_drive/Initialize()
. = ..()
install_default_programs()
..()
/obj/item/computer_hardware/hard_drive/advanced

View File

@@ -58,8 +58,8 @@ Contents:
/obj/item/clothing/suit/space/space_ninja/get_cell()
return cell
/obj/item/clothing/suit/space/space_ninja/New()
..()
/obj/item/clothing/suit/space/space_ninja/Initialize()
. = ..()
//Spark Init
spark_system = new
@@ -97,7 +97,7 @@ Contents:
if(!istype(H))
return FALSE
if(!is_ninja(H))
to_chat(H, "<span class='danger'><B>f<EFBFBD>TaL <EFBFBD><EFBFBD>RRoR</B>: 382200-*#00C<EFBFBD>DE <B>RED</B>\nUNAU?HORIZED US<EFBFBD> DET<EFBFBD>C???eD\nCoMM<EFBFBD>NCING SUB-R0U?IN3 13...\nT<EFBFBD>RMInATING U-U-US<EFBFBD>R...</span>")
to_chat(H, "<span class='danger'><B>fÄTaL ÈÈRRoR</B>: 382200-*#00CÖDE <B>RED</B>\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR...</span>")
H.gib()
return FALSE
if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))

View File

@@ -28,7 +28,7 @@
/obj/item/clothing/suit/space/space_ninja/proc/ninitialize_four(delay, mob/living/carbon/human/U)
if(U.stat == DEAD|| U.health <= 0)
to_chat(U, "<span class='danger'><B>F<EFBFBD>?AL <EFBFBD>Rr<EFBFBD>R</B>: 344--93#<EFBFBD>&&21 BR<EFBFBD><EFBFBD>N |/|/aV<EFBFBD> PATT$RN <B>RED</B>\nA-A-aB<EFBFBD>rT<EFBFBD>NG...</span>")
to_chat(U, "<span class='danger'><B>FĆAL �Rr�R</B>: 344--93#�&&21 BR��N |/|/aV� PATT$RN <B>RED</B>\nA-A-aB�rT�NG...</span>")
unlock_suit()
s_busy = FALSE
return

View File

@@ -45,6 +45,10 @@
if (!orbiter.orbiting) //admin wants to stop the orbit.
orbiter.orbiting = src //set it back to us first
orbiter.stop_orbit()
var/atom/movable/AM = orbiting
if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter)
orbiter.stop_orbit()
return
lastprocess = world.time
if (!targetloc)
targetloc = get_turf(orbiting)

View File

@@ -187,7 +187,6 @@ GLOBAL_LIST_EMPTY(employmentCabinets)
/obj/structure/filingcabinet/employment/Initialize()
. = ..()
GLOB.employmentCabinets += src
return ..()
/obj/structure/filingcabinet/employment/Destroy()
GLOB.employmentCabinets -= src
@@ -199,8 +198,9 @@ GLOBAL_LIST_EMPTY(employmentCabinets)
var/datum/data/record/G = record
if(!G)
continue
if(G.fields["reference"])
addFile(G.fields["reference"])
var/datum/mind/M = G.fields["mindref"]
if(M && ishuman(M.current))
addFile(M.current)
/obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee)

View File

@@ -374,4 +374,3 @@
/obj/item/paper/crumpled/bloody
icon_state = "scrap_bloodied"

View File

@@ -12,8 +12,8 @@
pass_flags = PASSTABLE
/obj/item/papercutter/New()
..()
/obj/item/papercutter/Initialize()
. = ..()
storedcutter = new /obj/item/hatchet/cutterblade(src)
update_icon()
@@ -111,8 +111,8 @@
resistance_flags = FLAMMABLE
max_integrity = 50
/obj/item/paperslip/New()
..()
/obj/item/paperslip/Initialize()
. = ..()
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)

File diff suppressed because one or more lines are too long

View File

@@ -181,7 +181,6 @@
reagents.add_reagent("chloralhydrate2", 20)
reagents.add_reagent("mutetoxin", 15)
reagents.add_reagent("tirizene", 10)
..()
/*
* (Alan) Edaggers

View File

@@ -76,7 +76,7 @@
return 0
charge = (charge - amount)
if(!istype(loc, /obj/machinery/power/apc))
SSblackbox.record_feedback("tally", "cell_used", 1, "[src.type]")
SSblackbox.record_feedback("tally", "cell_used", 1, type)
return 1
// recharge the cell

View File

@@ -53,7 +53,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
// You aren't allowed to move.
/obj/machinery/gravity_generator/Move()
..()
. = ..()
qdel(src)
/obj/machinery/gravity_generator/proc/set_broken()

View File

@@ -246,15 +246,15 @@
. = ..()
status = LIGHT_EMPTY
update(0)
..()
/obj/machinery/light/small/built
icon_state = "bulb-empty"
/obj/machinery/light/small/built/New()
/obj/machinery/light/small/built/Initialize()
. = ..()
status = LIGHT_EMPTY
update(0)
..()
// create a new lighting fixture
@@ -727,8 +727,8 @@
desc = "A broken [name]."
/obj/item/light/New()
..()
/obj/item/light/Initialize()
. = ..()
update()

View File

@@ -76,6 +76,7 @@
/obj/machinery/field/containment/Move()
qdel(src)
return FALSE
// Abstract Field Class

View File

@@ -152,7 +152,7 @@
qdel(src)
/obj/structure/particle_accelerator/Move()
..()
. = ..()
if(master && master.active)
master.toggle_power()
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)

View File

@@ -17,7 +17,7 @@
var/active = 0
var/strength = 0
var/powered = 0
mouse_opacity = 2
mouse_opacity = MOUSE_OPACITY_OPAQUE
/obj/machinery/particle_accelerator/control_box/Initialize()
. = ..()

View File

@@ -164,7 +164,7 @@
dissipate_track = 0
dissipate_strength = 1
if(STAGE_TWO)
if((check_turfs_in(1,1))&&(check_turfs_in(2,1))&&(check_turfs_in(4,1))&&(check_turfs_in(8,1)))
if(check_cardinals_range(1, TRUE))
current_size = STAGE_TWO
icon = 'icons/effects/96x96.dmi'
icon_state = "singularity_s3"
@@ -176,7 +176,7 @@
dissipate_track = 0
dissipate_strength = 5
if(STAGE_THREE)
if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2)))
if(check_cardinals_range(2, TRUE))
current_size = STAGE_THREE
icon = 'icons/effects/160x160.dmi'
icon_state = "singularity_s5"
@@ -188,7 +188,7 @@
dissipate_track = 0
dissipate_strength = 20
if(STAGE_FOUR)
if((check_turfs_in(1,3))&&(check_turfs_in(2,3))&&(check_turfs_in(4,3))&&(check_turfs_in(8,3)))
if(check_cardinals_range(3, TRUE))
current_size = STAGE_FOUR
icon = 'icons/effects/224x224.dmi'
icon_state = "singularity_s7"
@@ -296,6 +296,16 @@
step(src, movement_dir)
/obj/singularity/proc/check_cardinals_range(steps, retry_with_move = FALSE)
. = length(GLOB.cardinals) //Should be 4.
for(var/i in GLOB.cardinals)
. -= check_turfs_in(i, steps) //-1 for each working direction
if(. && retry_with_move) //If there's still a positive value it means it didn't pass. Retry with move if applicable
for(var/i in GLOB.cardinals)
if(step(src, i)) //Move in each direction.
if(check_cardinals_range(steps, FALSE)) //New location passes, return true.
return TRUE
. = !.
/obj/singularity/proc/check_turfs_in(direction = 0, step = 0)
if(!direction)

View File

@@ -521,6 +521,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_shard)
dust_mob(user, cause = "hand")
/obj/machinery/power/supermatter_shard/proc/dust_mob(mob/living/nom, vis_msg, mob_msg, cause)
if(nom.incorporeal_move)
return
if(!vis_msg)
vis_msg = "<span class='danger'>[nom] reaches out and touches [src], inducing a resonance... [nom.p_their()] body starts to glow and bursts into flames before flashing into ash"
if(!mob_msg)

View File

@@ -144,6 +144,10 @@
/obj/singularity/energy_ball/proc/dust_mobs(atom/A)
if(isliving(A))
var/mob/living/L = A
if(L.incorporeal_move)
return
if(!iscarbon(A))
return
for(var/obj/machinery/power/grounding_rod/GR in orange(src, 2))

View File

@@ -127,7 +127,7 @@ Variable Breakdown (For Mappers):
clusterCheckFlags - A Bitfield that controls how the cluster checks work, All based on clusterMin and clusterMax guides
allowAtomsOnSpace - A Boolean for if we allow atoms to spawn on space tiles
clusterCheckFlags flags_1:
clusterCheckFlags flags:
CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible
CLUSTER_CHECK_DIFFERENT_TURFS 2 //Don't let turfs of DIFFERENT types cluster
CLUSTER_CHECK_DIFFERENT_ATOMS 4 //Don't let atoms of DIFFERENT types cluster

View File

@@ -1,3 +1,4 @@
/datum/mapGenerator/lavaland
var/start_z = ZLEVEL_LAVALAND
var/min_x = 0

View File

@@ -1,3 +1,4 @@
// Modules
/turf/open/floor/plasteel/shuttle/red/syndicate
@@ -53,4 +54,4 @@
/datum/mapGeneratorModule/syndieFurniture, \
/datum/mapGeneratorModule/splatterLayer/syndieMobs, \
/datum/mapGeneratorModule/bottomLayer/repressurize)
buildmode_name = "Pattern: Shuttle Room: Syndicate: All"
buildmode_name = "Pattern: Shuttle Room: Syndicate: All"

View File

@@ -20,8 +20,8 @@
var/heavy_metal = TRUE
/obj/item/ammo_casing/New()
..()
/obj/item/ammo_casing/Initialize()
. = ..()
if(projectile_type)
BB = new projectile_type(src)
pixel_x = rand(-10, 10)

View File

@@ -296,8 +296,8 @@
/obj/item/ammo_casing/shotgun/dart/bioterror
desc = "A shotgun dart filled with deadly toxins."
/obj/item/ammo_casing/shotgun/dart/bioterror/New()
..()
/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize()
. = ..()
reagents.add_reagent("neurotoxin", 6)
reagents.add_reagent("spore", 6)
reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT

View File

@@ -22,8 +22,8 @@
var/multiload = 1
var/start_empty = 0
/obj/item/ammo_box/New()
..()
/obj/item/ammo_box/Initialize()
. = ..()
if(!start_empty)
for(var/i = 1, i <= max_ammo, i++)
stored_ammo += new ammo_type(src)

View File

@@ -2,6 +2,7 @@
/obj/item/ammo_box/magazine/internal
desc = "Oh god, this shouldn't be here"
flags_1 = CONDUCT_1|ABSTRACT_1
//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in
/obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R)
@@ -156,9 +157,9 @@
max_ammo = 6
multiload = 0
/obj/item/ammo_box/magazine/internal/rus357/New()
/obj/item/ammo_box/magazine/internal/rus357/Initialize()
stored_ammo += new ammo_type(src)
..()
. = ..()
/obj/item/ammo_box/magazine/internal/boltaction
name = "bolt action rifle internal magazine"

View File

@@ -24,7 +24,7 @@
var/can_suppress = FALSE
var/can_unsuppress = TRUE
var/recoil = 0 //boom boom shake the room
var/clumsy_check = 1
var/clumsy_check = TRUE
var/obj/item/ammo_casing/chambered = null
trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers
var/sawn_desc = null //description change if weapon is sawn-off
@@ -91,19 +91,17 @@
/obj/item/gun/equipped(mob/living/user, slot)
. = ..()
if(zoomable && user.get_active_held_item() != src)
zoom(user, FALSE) //we can only stay zoomed in if it's in our hands
if(zoomed && user.get_active_held_item() != src)
zoom(user, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!!
//called after the gun has successfully fired its chambered ammo.
/obj/item/gun/proc/process_chamber()
return 0
return FALSE
//check if there's enough ammo/energy/whatever to shoot one time
//i.e if clicking would make it shoot
/obj/item/gun/proc/can_shoot()
return 1
return TRUE
/obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj)
to_chat(user, "<span class='danger'>*click*</span>")
@@ -194,13 +192,13 @@
/obj/item/gun/proc/handle_pins(mob/living/user)
if(pin)
if(pin.pin_auth(user) || pin.emagged)
return 1
return TRUE
else
pin.auth_fail(user)
return 0
return FALSE
else
to_chat(user, "<span class='warning'>[src]'s trigger is locked. This weapon doesn't have a firing pin installed!</span>")
return 0
return FALSE
/obj/item/gun/proc/recharge_newshot()
return
@@ -400,7 +398,8 @@
/obj/item/gun/dropped(mob/user)
..()
zoom(user,FALSE)
if(zoomed)
zoom(user,FALSE)
if(azoom)
azoom.Remove(user)
if(alight)
@@ -420,7 +419,7 @@
target.visible_message("<span class='warning'>[user] points [src] at [target]'s head, ready to pull the trigger...</span>", \
"<span class='userdanger'>[user] points [src] at your head, ready to pull the trigger...</span>")
semicd = 1
semicd = TRUE
if(!do_mob(user, target, 120) || user.zone_selected != "mouth")
if(user)
@@ -428,10 +427,10 @@
user.visible_message("<span class='notice'>[user] decided not to shoot.</span>")
else if(target && target.Adjacent(user))
target.visible_message("<span class='notice'>[user] has decided to spare [target]</span>", "<span class='notice'>[user] has decided to spare your life!</span>")
semicd = 0
semicd = FALSE
return
semicd = 0
semicd = FALSE
target.visible_message("<span class='warning'>[user] pulls the trigger!</span>", "<span class='userdanger'>[user] pulls the trigger!</span>")

View File

@@ -178,6 +178,8 @@
#undef BRAINS_BLOWN_THROW_SPEED
#undef BRAINS_BLOWN_THROW_RANGE
/obj/item/gun/ballistic/proc/sawoff(mob/user)
if(sawn_state == SAWN_OFF)
to_chat(user, "<span class='warning'>\The [src] is already shortened!</span>")

View File

@@ -8,7 +8,7 @@
actions_types = list(/datum/action/item_action/toggle_firemode)
/obj/item/gun/ballistic/automatic/proto
name = "\improper NanoTrasen Saber SMG"
name = "\improper Nanotrasen Saber SMG"
desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors."
icon_state = "saber"
mag_type = /obj/item/ammo_box/magazine/smgm9mm
@@ -19,7 +19,6 @@
/obj/item/gun/ballistic/automatic/update_icon()
..()
cut_overlays()
if(!select)
add_overlay("[initial(icon_state)]semi")
if(select == 1)
@@ -93,6 +92,9 @@
fire_delay = 2
burst_size = 2
pin = /obj/item/device/firing_pin/implant/pindicate
can_bayonet = TRUE
knife_x_offset = 26
knife_y_offset = 12
/obj/item/gun/ballistic/automatic/c20r/unrestricted
pin = /obj/item/device/firing_pin
@@ -120,6 +122,9 @@
can_suppress = FALSE
burst_size = 0
actions_types = list()
can_bayonet = TRUE
knife_x_offset = 25
knife_y_offset = 12
/obj/item/gun/ballistic/automatic/wt550/update_icon()
..()
@@ -357,7 +362,8 @@
can_suppress = TRUE
w_class = WEIGHT_CLASS_NORMAL
zoomable = TRUE
zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you.
zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you.
zoom_out_amt = 13
slot_flags = SLOT_BACK
actions_types = list()

View File

@@ -105,6 +105,9 @@
slot_flags = 0 //no SLOT_BACK sprite, alas
mag_type = /obj/item/ammo_box/magazine/internal/boltaction
var/bolt_open = FALSE
can_bayonet = TRUE
knife_x_offset = 27
knife_y_offset = 13
/obj/item/gun/ballistic/shotgun/boltaction/pump(mob/M)
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
@@ -141,6 +144,7 @@
pin = /obj/item/device/firing_pin/magic
icon_state = "arcane_barrage"
item_state = "arcane_barrage"
can_bayonet = FALSE
flags_1 = DROPDEL_1

View File

@@ -4,9 +4,6 @@
#define ZOOM_LOCK_CENTER_VIEW 2
#define ZOOM_LOCK_OFF 3
#define ZOOM_SPEED_STEP 0
#define ZOOM_SPEED_INSTANT 1
#define AUTOZOOM_PIXEL_STEP_FACTOR 48
#define AIMING_BEAM_ANGLE_CHANGE_THRESHOLD 0.1
@@ -45,7 +42,7 @@
var/lastangle = 0
var/aiming_lastangle = 0
var/mob/current_user = null
var/obj/effect/projectile_beam/current_tracer
var/list/obj/effect/projectile_beam/current_tracers
var/structure_piercing = 2 //Amount * 2. For some reason structures aren't respecting this unless you have it doubled. Probably with the objects in question's Bump() code instead of this but I'll deal with this later.
var/structure_bleed_coeff = 0.7
@@ -64,14 +61,11 @@
var/delay = 65
var/lastfire = 0
var/lastprocess = 0
//ZOOMING
var/zoom_current_view_increase = 0
var/zoom_target_view_increase = 10
var/zoom_speed = ZOOM_SPEED_STEP
var/zooming = FALSE
var/zoom_lock = ZOOM_LOCK_AUTOZOOM_FREEMOVE
var/zoom_lock = ZOOM_LOCK_OFF
var/zooming_angle
var/current_zoom_x = 0
var/current_zoom_y = 0
@@ -80,7 +74,6 @@
var/static/image/charged_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_charged")
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
var/datum/action/item_action/zoom_speed_action/zoom_speed_action
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
/obj/item/gun/energy/beam_rifle/debug
@@ -103,15 +96,6 @@
. = ..()
/obj/item/gun/energy/beam_rifle/ui_action_click(owner, action)
if(istype(action, /datum/action/item_action/zoom_speed_action))
zoom_speed++
if(zoom_speed > 1)
zoom_speed = ZOOM_SPEED_STEP
switch(zoom_speed)
if(ZOOM_SPEED_STEP)
to_chat(owner, "<span class='boldnotice'>You switch [src]'s digital zoom to stepper mode.</span>")
if(ZOOM_SPEED_INSTANT)
to_chat(owner, "<span class='boldnotice'>You switch [src]'s digital zoom to instant mode.</span>")
if(istype(action, /datum/action/item_action/zoom_lock_action))
zoom_lock++
if(zoom_lock > 3)
@@ -135,8 +119,6 @@
var/total_time = SSfastprocess.wait
if(delay_override)
total_time = delay_override
if(zoom_speed == ZOOM_SPEED_INSTANT)
total_time = 0
zoom_animating = total_time
animate(current_user.client, pixel_x = current_zoom_x, pixel_y = current_zoom_y , total_time, SINE_EASING, ANIMATION_PARALLEL)
zoom_animating = 0
@@ -150,18 +132,10 @@
/obj/item/gun/energy/beam_rifle/proc/handle_zooming()
if(!zooming || !check_user())
return
if(zoom_speed == ZOOM_SPEED_INSTANT)
current_user.client.change_view(world.view + zoom_target_view_increase)
zoom_current_view_increase = zoom_target_view_increase
set_autozoom_pixel_offsets_immediate(zooming_angle)
smooth_zooming()
return
if(zoom_current_view_increase > zoom_target_view_increase)
return
zoom_current_view_increase++
current_user.client.change_view(zoom_current_view_increase + world.view)
current_user.client.change_view(world.view + zoom_target_view_increase)
zoom_current_view_increase = zoom_target_view_increase
set_autozoom_pixel_offsets_immediate(zooming_angle)
smooth_zooming(SSfastprocess.wait * zoom_target_view_increase * zoom_speed)
smooth_zooming()
/obj/item/gun/energy/beam_rifle/proc/start_zooming()
if(zoom_lock == ZOOM_LOCK_OFF)
@@ -169,8 +143,9 @@
zooming = TRUE
/obj/item/gun/energy/beam_rifle/proc/stop_zooming()
zooming = FALSE
reset_zooming()
if(zooming)
zooming = FALSE
reset_zooming()
/obj/item/gun/energy/beam_rifle/proc/reset_zooming()
if(!check_user(FALSE))
@@ -204,14 +179,14 @@
/obj/item/gun/energy/beam_rifle/Initialize()
. = ..()
current_tracers = list()
START_PROCESSING(SSprojectiles, src)
zoom_speed_action = new(src)
zoom_lock_action = new(src)
/obj/item/gun/energy/beam_rifle/Destroy()
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
QDEL_NULL(current_tracer)
QDEL_LIST(current_tracers)
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -245,6 +220,7 @@
/obj/item/gun/energy/beam_rifle/process()
if(!aiming)
last_process = world.time
return
check_user()
handle_zooming()
@@ -299,7 +275,7 @@
set waitfor = FALSE
aiming_time_left = aiming_time
aiming = FALSE
QDEL_NULL(current_tracer)
QDEL_LIST(current_tracers)
stop_zooming()
/obj/item/gun/energy/beam_rifle/proc/set_user(mob/user)
@@ -341,7 +317,7 @@
sync_ammo()
afterattack(M.client.mouseObject, M, FALSE, M.client.mouseParams, passthrough = TRUE)
stop_aiming()
QDEL_NULL(current_tracer)
QDEL_LIST(current_tracers)
return ..()
/obj/item/gun/energy/beam_rifle/afterattack(atom/target, mob/living/user, flag, params, passthrough = FALSE)
@@ -555,136 +531,103 @@
handle_impact(target)
/obj/item/projectile/beam/beam_rifle/Collide(atom/target)
paused = TRUE
if(check_pierce(target))
permutated += target
return FALSE
if(!QDELETED(target))
cached = get_turf(target)
paused = FALSE
. = ..()
/obj/item/projectile/beam/beam_rifle/on_hit(atom/target, blocked = FALSE)
paused = TRUE
if(!QDELETED(target))
cached = get_turf(target)
handle_hit(target)
paused = FALSE
. = ..()
/obj/item/projectile/beam/beam_rifle/hitscan
icon_state = ""
var/tracer_type = /obj/effect/projectile_beam/tracer
var/starting_z
var/starting_p_x
var/starting_p_y
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end.
var/constant_tracer = FALSE
var/travelled_p_x = 0
var/travelled_p_y = 0
var/tracer_spawned = FALSE
var/beam_index
/obj/item/projectile/beam/beam_rifle/hitscan/Destroy()
paused = TRUE //STOP HITTING WHEN YOU'RE ALREADY BEING DELETED!
spawn_tracer(constant_tracer)
if(loc)
var/datum/point/pcache = trajectory.copy_to()
beam_segments[beam_index] = pcache
generate_tracers(constant_tracer)
return ..()
/obj/item/projectile/beam/beam_rifle/hitscan/proc/spawn_tracer(put_in_rifle = FALSE)
if(tracer_spawned)
return
tracer_spawned = TRUE
//Remind me to port baystation trajectories so this shit isn't needed...
var/pixels_travelled = round(sqrt(travelled_p_x**2 + travelled_p_y**2),1)
var/scaling = pixels_travelled/world.icon_size
var/midpoint_p_x = round(starting_p_x + (travelled_p_x / 2))
var/midpoint_p_y = round(starting_p_y + (travelled_p_y / 2))
var/tracer_px = midpoint_p_x % world.icon_size
var/tracer_py = midpoint_p_y % world.icon_size
var/tracer_lx = (midpoint_p_x - tracer_px) / world.icon_size
var/tracer_ly = (midpoint_p_y - tracer_py) / world.icon_size
var/obj/effect/projectile_beam/PB = new tracer_type(src)
PB.apply_vars(Angle, tracer_px, tracer_py, color, scaling, locate(tracer_lx,tracer_ly,starting_z))
if(put_in_rifle && istype(gun))
if(gun.current_tracer)
QDEL_NULL(gun.current_tracer)
gun.current_tracer = PB
else
QDEL_IN(PB, 5)
/obj/item/projectile/beam/beam_rifle/hitscan/Collide(atom/target)
var/datum/point/pcache = trajectory.copy_to()
. = ..()
if(. && !QDELETED(src)) //successful touch and not destroyed.
beam_segments[beam_index] = pcache
beam_index = pcache
beam_segments[beam_index] = null
/obj/item/projectile/beam/beam_rifle/hitscan/proc/check_for_turf_edge(turf/T)
if(!istype(T))
return TRUE
var/tx = T.x
var/ty = T.y
if(tx < 10 || tx > (world.maxx - 10) || ty < 10 || ty > (world.maxy-10))
return TRUE
return FALSE
/obj/item/projectile/beam/beam_rifle/hitscan/before_z_change(turf/oldloc, turf/newloc)
var/datum/point/pcache = trajectory.copy_to()
beam_segments[beam_index] = pcache
beam_index = RETURN_PRECISE_POINT(newloc)
beam_segments[beam_index] = null
return ..()
/obj/item/projectile/beam/beam_rifle/hitscan/proc/generate_tracers(highlander = FALSE, cleanup = TRUE)
set waitfor = FALSE
if(highlander && istype(gun))
QDEL_LIST(gun.current_tracers)
for(var/datum/point/p in beam_segments)
gun.current_tracers += generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 0)
else
for(var/datum/point/p in beam_segments)
generate_projectile_beam_between_points(p, beam_segments[p], tracer_type, color, 5)
if(cleanup)
QDEL_LIST(beam_segments)
beam_segments = null
QDEL_NULL(beam_index)
/obj/item/projectile/beam/beam_rifle/hitscan/fire(setAngle, atom/direct_target) //oranges didn't let me make this a var the first time around so copypasta time
set waitfor = 0
set waitfor = FALSE
var/turf/starting = get_turf(src)
trajectory = new(starting.x, starting.y, starting.z, 0, 0, setAngle? setAngle : Angle, 33)
if(!log_override && firer && original)
add_logs(firer, original, "fired at", src, " [get_area(src)]")
fired = TRUE
if(setAngle)
Angle = setAngle
var/next_run = world.time
var/old_pixel_x = pixel_x
var/old_pixel_y = pixel_y
var/safety = 0 //The code works fine, but... just in case...
var/turf/c2
var/starting_x = loc.x
var/starting_y = loc.y
starting_z = loc.z
starting_p_x = starting_x * world.icon_size + pixel_x
starting_p_y = starting_y * world.icon_size + pixel_y
beam_segments = list() //initialize segment list with the list for the first segment
beam_index = RETURN_PRECISE_POINT(src)
beam_segments[beam_index] = null //record start.
if(spread)
Angle += (rand() - 0.5) * spread
while(loc)
if(paused || QDELETED(src))
return
if(++safety > (range * 3)) //If it's looping for way, way too long...
qdel(src)
stack_trace("WARNING: [type] projectile encountered infinite recursion in [__FILE__]/[__LINE__]!")
return //Kill!
if(spread)
Angle += (rand() - 0.5) * spread
var/matrix/M = new
M.Turn(Angle)
transform = M
var/Pixel_x=sin(Angle)+16*sin(Angle)*2
var/Pixel_y=cos(Angle)+16*cos(Angle)*2
travelled_p_x += Pixel_x
travelled_p_y += Pixel_y
var/pixel_x_offset = old_pixel_x + Pixel_x
var/pixel_y_offset = old_pixel_y + Pixel_y
var/new_x = x
var/new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
pixel_x = old_pixel_x
pixel_y = old_pixel_y
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
if(delay <= world.tick_lag*2)
pixel_x = pixel_x_offset
pixel_y = pixel_y_offset
trajectory.increment()
var/turf/T = trajectory.return_turf()
if(T.z != loc.z)
before_z_change(loc, T)
trajectory_ignore_forcemove = TRUE
forceMove(T)
trajectory_ignore_forcemove = FALSE
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
step_towards(src, T)
animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
if(can_hit_target(original, permutated))
Collide(original)
c2 = loc
Range()
if(check_for_turf_edge(loc))
spawn_tracer(constant_tracer)
c2 = get_turf(src)
if(istype(c2))
cached = c2
@@ -704,38 +647,3 @@
/obj/item/projectile/beam/beam_rifle/hitscan/aiming_beam/on_hit()
qdel(src)
return FALSE
/obj/effect/projectile_beam
icon = 'icons/obj/projectiles.dmi'
layer = ABOVE_MOB_LAYER
anchored = TRUE
light_power = 1
light_range = 2
light_color = "#00ffff"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
flags_1 = ABSTRACT_1
appearance_flags = 0
/obj/effect/projectile_beam/tracer
icon_state = "tracer_beam"
/obj/effect/projectile_beam/tracer/aiming
icon_state = "gbeam"
/datum/action/item_action/zoom_speed_action
name = "Toggle Zooming Speed"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "projectile"
background_icon_state = "bg_tech"
/datum/action/item_action/zoom_lock_action
name = "Switch Zoom Mode"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "zoom_mode"
background_icon_state = "bg_tech"
/obj/effect/projectile_beam/singularity_pull()
return
/obj/effect/projectile_beam/singularity_act()
return

View File

@@ -16,8 +16,8 @@
var/unique_frequency = FALSE // modified by KA modkits
var/overheat = FALSE
can_bayonet = TRUE
knife_x_offset = 15
knife_y_offset = 13
knife_x_offset = 20
knife_y_offset = 12
var/max_mod_capacity = 100
var/list/modkits = list()

View File

@@ -13,10 +13,10 @@
var/obj/item/device/transfer_valve/bomb
/obj/item/gun/blastcannon/New()
/obj/item/gun/blastcannon/Initialize()
. = ..()
if(!pin)
pin = new
return ..()
/obj/item/gun/blastcannon/Destroy()
if(bomb)

View File

@@ -31,16 +31,11 @@
var/last_projectile_move = 0
var/last_process = 0
var/time_offset = 0
var/old_pixel_x = 0
var/old_pixel_y = 0
var/pixel_x_increment = 0
var/pixel_y_increment = 0
var/pixel_x_offset = 0
var/pixel_y_offset = 0
var/new_x = 0
var/new_y = 0
var/datum/point/vector/trajectory
var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location!
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
var/pixel_speed = 33 //pixels per move - DO NOT FUCK WITH THIS UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING OR UNEXPECTED THINGS /WILL/ HAPPEN!
var/Angle = 0
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
var/spread = 0 //amount (in degrees) of projectile spread
@@ -48,6 +43,9 @@
var/ricochets = 0
var/ricochets_max = 2
var/ricochet_chance = 30
var/colliding = FALSE //pause processing..
var/ignore_source_check = FALSE
var/damage = 10
@@ -73,9 +71,9 @@
var/impact_effect_type //what type of impact effect to show when hitting something
var/log_override = FALSE //is this type spammed enough to not log? (KAs)
/obj/item/projectile/New()
/obj/item/projectile/Initialize()
. = ..()
permutated = list()
return ..()
/obj/item/projectile/proc/Range()
range--
@@ -168,20 +166,28 @@
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100
return CLAMP((src.damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then CLAMP the value between 30 and 100
else
return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume
/obj/item/projectile/proc/on_ricochet(atom/A)
return
/obj/item/projectile/Collide(atom/A)
colliding = TRUE
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
ricochets++
if(A.handle_ricochet(src))
on_ricochet(A)
ignore_source_check = TRUE
range = initial(range)
return FALSE
return TRUE
if(firer && !ignore_source_check)
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
loc = A.loc
trajectory_ignore_forcemove = TRUE
forceMove(get_turf(A))
trajectory_ignore_forcemove = FALSE
colliding = FALSE
return FALSE
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
@@ -197,25 +203,32 @@
if(!prehit(A))
if(forcedodge)
loc = target_turf
trajectory_ignore_forcemove = TRUE
forceMove(target_turf)
trajectory_ignore_forcemove = FALSE
colliding = FALSE
return FALSE
var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null
if(permutation == -1 || forcedodge)// the bullet passes through a dense object!
loc = target_turf
trajectory_ignore_forcemove = TRUE
forceMove(target_turf)
trajectory_ignore_forcemove = FALSE
if(A)
permutated.Add(A)
colliding = FALSE
return FALSE
else
var/atom/alt = select_target(A)
if(alt)
if(!prehit(alt))
colliding = FALSE
return FALSE
alt.bullet_act(src, def_zone)
qdel(src)
colliding = FALSE
return TRUE
/obj/item/projectile/proc/select_target(atom/A) //Selects another target from a wall if we hit a wall.
if(!A || !A.density || (A.flags_1 & ON_BORDER_1) || ismob(A) || A == original) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs or machines/structures on that tile.
return
@@ -246,12 +259,30 @@
return TRUE
return FALSE
/obj/item/projectile/proc/return_predicted_turf_after_moves(moves, forced_angle) //I say predicted because there's no telling that the projectile won't change direction/location in flight.
if(!trajectory && isnull(forced_angle) && isnull(Angle))
return FALSE
var/datum/point/vector/current = trajectory
if(!current)
var/turf/T = get_turf(src)
current = new(T.x, T.y, T.z, pixel_x, pixel_y, isnull(forced_angle)? Angle : forced_angle, pixel_speed)
var/datum/point/vector/v = current.return_vector_after_increments(moves)
return v.return_turf()
/obj/item/projectile/proc/return_pathing_turfs_in_moves(moves, forced_angle)
var/turf/current = get_turf(src)
var/turf/ending = return_predicted_turf_after_moves(moves, forced_angle)
return getline(current, ending)
/obj/item/projectile/proc/before_z_change(turf/oldloc, turf/newloc)
return
/obj/item/projectile/Process_Spacemove(var/movement_dir = 0)
return TRUE //Bullets don't drift in space
/obj/item/projectile/process()
last_process = world.time
if(!loc || !fired)
if(!loc || !fired || !trajectory)
fired = FALSE
return PROCESS_KILL
if(paused || !isturf(loc))
@@ -285,73 +316,70 @@
setAngle(angle)
if(spread)
setAngle(Angle + ((rand() - 0.5) * spread))
var/turf/starting = get_turf(src)
if(isnull(Angle)) //Try to resolve through offsets if there's no angle set.
var/turf/starting = get_turf(src)
if(isnull(xo) || isnull(yo))
stack_trace("WARNING: Projectile [type] deleted due to being unable to resolve a target after angle was null!")
qdel(src)
return
var/turf/target = locate(CLAMP(starting + xo, 1, world.maxx), CLAMP(starting + yo, 1, world.maxy), starting.z)
setAngle(Get_Angle(src, target))
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
old_pixel_x = pixel_x
old_pixel_y = pixel_y
trajectory = new(starting.x, starting.y, starting.z, 0, 0, Angle, pixel_speed)
last_projectile_move = world.time
fired = TRUE
if(!isprocessing)
START_PROCESSING(SSprojectiles, src)
pixel_move(1) //move it now!
/obj/item/projectile/proc/setAngle(new_angle) //wrapper for overrides.
Angle = new_angle
return TRUE
/obj/item/projectile/proc/pixel_move(moves)
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
if(trajectory)
trajectory.set_angle(new_angle)
return TRUE
pixel_x_increment=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
pixel_y_increment=round((cos(Angle)+16*cos(Angle)*2), 1)
pixel_x_offset = old_pixel_x + pixel_x_increment
pixel_y_offset = old_pixel_y + pixel_y_increment
new_x = x
new_y = y
/obj/item/projectile/forceMove(atom/target)
. = ..()
if(trajectory && !trajectory_ignore_forcemove && isturf(target))
trajectory.initialize_location(target.x, target.y, target.z, 0, 0)
while(pixel_x_offset > 16)
pixel_x_offset -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
old_pixel_y += 32
new_y--
/obj/item/projectile/proc/pixel_move(moves, trajectory_multiplier = 1)
if(!loc || !trajectory)
return
last_projectile_move = world.time
if(!nondirectional_sprite)
var/matrix/M = new
M.Turn(Angle)
transform = M
trajectory.increment(trajectory_multiplier)
var/turf/T = trajectory.return_turf()
if(T.z != loc.z)
before_z_change(loc, T)
trajectory_ignore_forcemove = TRUE
forceMove(T)
trajectory_ignore_forcemove = FALSE
pixel_x = trajectory.return_px()
pixel_y = trajectory.return_py()
else
step_towards(src, T)
pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier
pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier
animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
step_towards(src, locate(new_x, new_y, z))
pixel_x = old_pixel_x
pixel_y = old_pixel_y
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = 1, flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(can_hit_target(original, permutated))
Collide(original)
Range()
last_projectile_move = world.time
//Returns true if the target atom is on our current turf and above the right layer
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
if(target && (target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target))
if(loc == get_turf(target))
if(!(target in passthrough))
return TRUE
return FALSE
return (target && ((target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough)))
/obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0)
var/turf/curloc = get_turf(source)
@@ -362,7 +390,8 @@
if(targloc || !params)
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
setAngle(Get_Angle(src, targloc))
if(isliving(source) && params)
var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params)
p_x = calculated[2]
@@ -372,8 +401,13 @@
setAngle(calculated[1] + spread)
else
setAngle(calculated[1])
else
else if(targloc)
yo = targloc.y - curloc.y
xo = targloc.x - curloc.x
setAngle(Get_Angle(src, targloc))
else
stack_trace("WARNING: Projectile [type] fired without either mouse parameters, or a target atom to aim at!")
qdel(src)
/proc/calculate_projectile_angle_and_pixel_offsets(mob/user, params)
var/list/mouse_control = params2list(params)

View File

@@ -341,8 +341,8 @@
icon_state = "banana"
range = 200
/obj/item/projectile/bullet/honker/New()
..()
/obj/item/projectile/bullet/honker/Initialize()
. = ..()
SpinAnimation()
// Mime
@@ -364,8 +364,8 @@
damage = 6
var/piercing = FALSE
/obj/item/projectile/bullet/dart/New()
..()
/obj/item/projectile/bullet/dart/Initialize()
. = ..()
create_reagents(50)
reagents.set_reacting(FALSE)
@@ -388,8 +388,8 @@
reagents.handle_reactions()
return TRUE
/obj/item/projectile/bullet/dart/metalfoam/New()
..()
/obj/item/projectile/bullet/dart/metalfoam/Initialize()
. = ..()
reagents.add_reagent("aluminium", 15)
reagents.add_reagent("foaming_agent", 5)
reagents.add_reagent("facid", 5)

View File

@@ -15,6 +15,7 @@
/datum/reagents/New(maximum=100)
maximum_volume = maximum
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
if(!GLOB.chemical_reagents_list)
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
@@ -295,6 +296,7 @@
C.update_stamina()
update_total()
/datum/reagents/proc/set_reacting(react = TRUE)
if(react)
flags &= ~(REAGENT_NOREACT)
@@ -743,8 +745,7 @@
out += "[taste_desc]"
return english_list(out, "something indescribable")
/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02)
var/temp_delta = (temperature - chem_temp) * coeff
if(temp_delta > 0)

View File

@@ -70,7 +70,7 @@
//nothing
if(21 to INFINITY)
if(prob(current_cycle-10))
M.cure_nearsighted()
M.cure_nearsighted(list(EYE_DAMAGE))
..()
return
@@ -172,6 +172,22 @@
M.emote("laugh")
..()
/datum/reagent/consumable/superlaughter
name = "Super Laughter"
id = "superlaughter"
description = "Funny until you're the one laughing."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
color = "#FF4DD2"
taste_description = "laughter"
/datum/reagent/consumable/superlaughter/on_mob_life(mob/living/carbon/M)
if(!iscarbon(M))
return
if(prob(30))
M.visible_message("<span class='danger'>[M] bursts out into a fit of uncontrollable laughter!</span>", "<span class='userdanger'>You burst out in a fit of uncontrollable laughter!</span>")
M.Stun(5)
..()
/datum/reagent/consumable/potato_juice
name = "Potato Juice"
id = "potato"

View File

@@ -44,7 +44,7 @@
M.adjustToxLoss(-5, 0)
M.hallucination = 0
M.setBrainLoss(0)
M.disabilities = 0
M.remove_all_disabilities()
M.set_blurriness(0)
M.set_blindness(0)
M.SetKnockdown(0, 0)
@@ -129,31 +129,16 @@
taste_description = "sludge"
/datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M)
switch(M.bodytemperature) // Low temperatures are required to take effect.
if(0 to 100) // At extreme temperatures (upgraded cryo) the effect is greatly increased.
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-1, 0)
M.adjustOxyLoss(-9, 0)
M.adjustBruteLoss(-5, 0)
M.adjustFireLoss(-5, 0)
M.adjustToxLoss(-5, 0)
. = 1
if(100 to 225) // At lower temperatures (cryo) the full effect is boosted
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-1, 0)
M.adjustOxyLoss(-7, 0)
M.adjustBruteLoss(-3, 0)
M.adjustFireLoss(-3, 0)
M.adjustToxLoss(-3, 0)
. = 1
if(225 to T0C)
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-1, 0)
M.adjustOxyLoss(-5, 0)
M.adjustBruteLoss(-1, 0)
M.adjustFireLoss(-1, 0)
M.adjustToxLoss(-1, 0)
. = 1
var/power = -0.00003 * (M.bodytemperature ** 2) + 3
if(M.bodytemperature < T0C)
M.adjustOxyLoss(-3 * power, 0)
M.adjustBruteLoss(-power, 0)
M.adjustFireLoss(-power, 0)
M.adjustToxLoss(-power, 0)
M.adjustCloneLoss(-power, 0)
M.status_flags &= ~DISFIGURED
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5)
..()
/datum/reagent/medicine/clonexadone
@@ -670,13 +655,13 @@
if(M.has_disability(DISABILITY_BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "<span class='warning'>Your vision slowly returns...</span>")
M.cure_blind()
M.cure_nearsighted()
M.cure_blind(EYE_DAMAGE)
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(35)
else if(M.has_disability(DISABILITY_NEARSIGHT, EYE_DAMAGE))
to_chat(M, "<span class='warning'>The blackness in your peripheral vision fades.</span>")
M.cure_nearsighted()
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
M.set_blindness(0)

View File

@@ -119,6 +119,6 @@
/obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M)
reagents.expose_temperature(1000)
..()
/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
reagents.expose_temperature(exposed_temperature)
reagents.expose_temperature(exposed_temperature)

View File

@@ -130,6 +130,18 @@ Borg Hypospray
reagent_ids = list ("facid", "mutetoxin", "cyanide", "sodium_thiopental", "heparin", "lexorin")
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown
name = "laughter injector"
desc = "Keeps the crew happy and productive!"
reagent_ids = list("laughter")
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/clown/hacked
name = "laughter injector"
desc = "Keeps the crew so happy they don't work!"
reagent_ids = list("superlaughter")
accepts_reagent_upgrades = FALSE
/obj/item/reagent_containers/borghypo/syndicate
name = "syndicate cyborg hypospray"
desc = "An experimental piece of Syndicate technology used to produce powerful restorative nanites used to very quickly restore injuries of all types. Also metabolizes potassium iodide, for radiation poisoning, and morphine, for offense."

View File

@@ -311,4 +311,4 @@
/obj/item/reagent_containers/glass/bottle/tuberculosiscure
name = "BVAK bottle"
desc = "A small bottle containing Bio Virus Antidote Kit."
list_reagents = list("atropine" = 5, "epinephrine" = 5, "salbutamol" = 10, "spaceacillin" = 10)
list_reagents = list("atropine" = 5, "epinephrine" = 5, "salbutamol" = 10, "spaceacillin" = 10)

View File

@@ -397,4 +397,4 @@
/obj/item/reagent_containers/glass/beaker/large/bromine
name = "bromine beaker"
list_reagents = list("bromine" = 50)
list_reagents = list("bromine" = 50)

View File

@@ -157,4 +157,4 @@
desc = "I wouldn't eat this if I were you."
icon_state = "pill9"
color = "#454545"
list_reagents = list("shadowmutationtoxin" = 1)
list_reagents = list("shadowmutationtoxin" = 1)

View File

@@ -18,16 +18,16 @@
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
var/can_fill_from_container = TRUE
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
/obj/item/reagent_containers/spray/afterattack(atom/A, mob/user)
if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1)
if((A.is_drainable() && !A.is_refillable()) && get_dist(src,A) <= 1 && can_fill_from_container)
if(!A.reagents.total_volume)
to_chat(user, "<span class='warning'>[A] is empty.</span>")
return
@@ -130,7 +130,6 @@
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
return ..()
/obj/item/reagent_containers/spray/verb/empty()
set name = "Empty Spray Bottle"
set category = "Object"
@@ -205,6 +204,46 @@
/obj/item/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
/obj/item/reagent_containers/spray/waterflower/cyborg
container_type = NONE
volume = 100
list_reagents = list("water" = 100)
var/generate_amount = 5
var/generate_type = "water"
var/last_generate = 0
var/generate_delay = 10 //deciseconds
can_fill_from_container = FALSE
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked
name = "nova flower"
desc = "This doesn't look safe at all..."
list_reagents = list("clf3" = 3)
volume = 3
generate_type = "clf3"
generate_amount = 1
generate_delay = 40 //deciseconds
/obj/item/reagent_containers/spray/waterflower/cyborg/Initialize()
. = ..()
START_PROCESSING(SSfastprocess, src)
/obj/item/reagent_containers/spray/waterflower/cyborg/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/item/reagent_containers/spray/waterflower/cyborg/process()
if(world.time > last_generate + generate_delay)
return
last_generate = world.time
generate_reagents()
/obj/item/reagent_containers/spray/waterflower/cyborg/empty()
to_chat(usr, "<span class='warning'>You can not empty this!</span>")
return
/obj/item/reagent_containers/spray/waterflower/cyborg/proc/generate_reagents()
reagents.add_reagent(generate_type, generate_amount)
//chemsprayer
/obj/item/reagent_containers/spray/chemsprayer
name = "chem sprayer"

View File

@@ -190,6 +190,7 @@
deconstruct()
// Straight/bent pipe segment
/obj/structure/disposalpipe/segment
icon_state = "pipe"
initialize_dirs = DISP_DIR_FLIP

View File

@@ -51,40 +51,8 @@ other types of metals and chemistry for reagents).
return ..()
/datum/design/proc/icon_html(client/user)
if (!icon_cache)
// construct the icon and slap it into the resource cache
var/atom/item = build_path
if (!ispath(item, /atom))
// biogenerator outputs to beakers by default
if (build_type & BIOGENERATOR)
item = /obj/item/reagent_containers/glass/beaker/large
else
return // shouldn't happen, but just in case
// circuit boards become their resulting machines or computers
if (ispath(item, /obj/item/circuitboard))
var/obj/item/circuitboard/C = item
var/machine = initial(C.build_path)
if (machine)
item = machine
var/icon_file = initial(item.icon)
var/icon/I = icon(icon_file, initial(item.icon_state), SOUTH)
// computers (and snowflakes) get their screen and keyboard sprites
if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control))
var/obj/machinery/computer/C = item
var/screen = initial(C.icon_screen)
var/keyboard = initial(C.icon_keyboard)
if (screen)
I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY)
if (keyboard)
I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY)
// based on icon2html
icon_cache = "[generate_asset_name(I)].png"
register_asset(icon_cache, I)
send_asset(user, icon_cache, FALSE)
return "<img class='icon' src=\"[url_encode(icon_cache)]\">"
send_asset(user, "design_[id].png", FALSE)
return "<img class='icon' src=\"design_[id].png\">"
////////////////////////////////////////
//Disks for transporting design datums//

View File

@@ -111,6 +111,7 @@
desc = "The circuit board for a sleeper."
id = "sleeper"
build_path = /obj/item/circuitboard/machine/sleeper
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
category = list ("Medical Machinery")
/datum/design/board/cryotube
@@ -118,6 +119,7 @@
desc = "The circuit board for a cryotube."
id = "cryotube"
build_path = /obj/item/circuitboard/machine/cryo_tube
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
category = list ("Medical Machinery")
/datum/design/board/chem_dispenser
@@ -125,12 +127,14 @@
desc = "The circuit board for a portable chem dispenser."
id = "chem_dispenser"
build_path = /obj/item/circuitboard/machine/chem_dispenser
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
category = list ("Medical Machinery")
/datum/design/board/chem_master
name = "Machine Design (Chem Master Board)"
desc = "The circuit board for a Chem Master 3000."
id = "chem_master"
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
build_path = /obj/item/circuitboard/machine/chem_master
category = list ("Medical Machinery")
@@ -138,6 +142,7 @@
name = "Machine Design (Chemical Heater Board)"
desc = "The circuit board for a chemical heater."
id = "chem_heater"
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
build_path = /obj/item/circuitboard/machine/chem_heater
category = list ("Medical Machinery")
@@ -153,12 +158,14 @@
desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console."
id = "clonecontrol"
build_path = /obj/item/circuitboard/computer/cloning
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
category = list("Medical Machinery")
/datum/design/board/clonepod
name = "Machine Design (Clone Pod)"
desc = "Allows for the construction of circuit boards used to build a Cloning Pod."
id = "clonepod"
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
build_path = /obj/item/circuitboard/machine/clonepod
category = list("Medical Machinery")
@@ -166,6 +173,7 @@
name = "Machine Design (Cloning Scanner)"
desc = "Allows for the construction of circuit boards used to build a Cloning Scanner."
id = "clonescanner"
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_MEDICAL
build_path = /obj/item/circuitboard/machine/clonescanner
category = list("Medical Machinery")

View File

@@ -114,6 +114,6 @@
else
var/obj/item/stack/S = type_inserted
stack_name = initial(S.name)
use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * amount_inserted / 10)))
use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * amount_inserted / 100)))
add_overlay("protolathe_[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10)

View File

@@ -98,7 +98,7 @@
death = FALSE
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
flavour_text = "<font size=3>You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. <b>Continue your research as best you can, and try to keep a low profile. <font size=6><b>DON'T</b></font> abandon the base without good cause.</b> The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!</b>"
flavour_text = "<span class='big bold'>You are a syndicate agent,</span><b> employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. <b>Continue your research as best you can, and try to keep a low profile. <font size=6>DON'T</font> abandon the base without good cause.</b> The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!</b>"
id_access_list = list(ACCESS_SYNDICATE)
outfit = /datum/outfit/lavaland_syndicate
assignedrole = "Lavaland Syndicate"
@@ -121,7 +121,7 @@
/obj/effect/mob_spawn/human/lavaland_syndicate/comms
name = "Syndicate Comms Agent"
flavour_text = "<font size=3>You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. <b>Monitor enemy activity as best you can, and try to keep a low profile. <font size=6><b>DON'T</b></font> abandon the base without good cause.</b> Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!</b>"
flavour_text = "<span class='big bold'>You are a syndicate agent,</span><b> employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. <b>Monitor enemy activity as best you can, and try to keep a low profile. <font size=6>DON'T</font> abandon the base without good cause.</b> Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!</b>"
outfit = /datum/outfit/lavaland_syndicate/comms
/datum/outfit/lavaland_syndicate/comms

View File

@@ -9,7 +9,7 @@
faction = list("ashwalker")
health = 200
maxHealth = 200
loot = null
loot = list(/obj/effect/collapse)
var/meat_counter = 6
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death()

View File

@@ -399,7 +399,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
name = "burnt stone surrounding tile"
icon_state = "burnt_surrounding_tile1"
tile_key = "burnt_surrounding_tile"
#undef STABLE
#undef COLLAPSE_ON_CROSS
#undef DESTROY_ON_CROSS

View File

@@ -24,7 +24,7 @@
/obj/item/paper/fluff/ruins/listeningstation/reports/june
name = "june report"
info = "Nanotrasen communications have been noticably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."
info = "Nanotrasen communications have been noticeably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it."
/obj/item/paper/fluff/ruins/listeningstation/reports/may
name = "may report"

View File

@@ -44,6 +44,6 @@
/obj/item/paper/fluff/ruins/oldstation/report
name = "Crew Reawakening Report"
info = "Artifical Program's report to surviving crewmembers.<br><br>Crew were placed into cryostasis on March 10th, 2445.<br><br>Crew were awoken from cryostasis around June, 2557.<br><br> \
<b>SIGNIFICANT EVENTS OF NOTE</b><br>1: The primary radiation detectors were taken offline after 112 years due to power failure, secondary radioation detectors showed no residual \
radioation on station. Deduction, primariy detector was malfunctioning and was producing a radioation signal when there was none.<br><br>2: A data burst from a nearby Nanotrasen Space \
<b>SIGNIFICANT EVENTS OF NOTE</b><br>1: The primary radiation detectors were taken offline after 112 years due to power failure, secondary radiation detectors showed no residual \
radiation on station. Deduction, primarily detector was malfunctioning and was producing a radiation signal when there was none.<br><br>2: A data burst from a nearby Nanotrasen Space \
Station was recieved, this data burst contained research data that has been uploaded to our RnD labs.<br><br>3: Unknown invasion force has occupied Delta station."

View File

@@ -7,6 +7,6 @@
/obj/item/paper/pamphlet/ruin/spacehotel
name = "hotel pamphlet"
info = "<center><b>The Twin Nexus Hotel</center></b><br><center><i>A place of Sanctuary</i></center><br><br><center>Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff stride to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more infomation.</center>"
info = "<center><b>The Twin Nexus Hotel</center></b><br><center><i>A place of Sanctuary</i></center><br><br><center>Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff stride to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more information.</center>"

View File

@@ -76,7 +76,12 @@ GLOBAL_VAR_INIT(security_level, 0)
FA.update_icon()
for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines)
pod.admin_controlled = 0
SSblackbox.record_feedback("tally", "security_level_changes", 1, level)
if(level >= SEC_LEVEL_RED)
for(var/obj/machinery/door/D in GLOB.machines)
if(D.red_alert_access)
D.visible_message("<span class='notice'>[D] whirrs as it automatically lifts access requirements!</span>")
playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE)
SSblackbox.record_feedback("tally", "security_level_changes", 1, get_security_level())
else
return

View File

@@ -200,5 +200,5 @@
/obj/docking_port/mobile/arrivals/vv_edit_var(var_name, var_value)
switch(var_name)
if("perma_docked")
SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "ShA[var_value ? "s" : "g"]")
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("arrivals shuttle", "[var_value ? "stopped" : "started"]"))
return ..()

View File

@@ -301,6 +301,7 @@
var/datum/DBQuery/query_round_shuttle_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shuttle_name = '[name]' WHERE id = [GLOB.round_id]")
query_round_shuttle_name.Execute()
if(SHUTTLE_DOCKED)
if(time_left <= ENGINES_START_TIME)
mode = SHUTTLE_IGNITING

View File

@@ -119,7 +119,7 @@
return
if(!my_port)
my_port = new(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z))
my_port = new()
my_port.name = shuttlePortName
my_port.id = shuttlePortId
my_port.height = shuttle_port.height
@@ -128,6 +128,7 @@
my_port.dwidth = shuttle_port.dwidth
my_port.hidden = shuttle_port.hidden
my_port.dir = the_eye.dir
my_port.forceMove(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z))
if(current_user.client)
current_user.client.images -= the_eye.placed_images

View File

@@ -22,6 +22,10 @@ All ShuttleMove procs go here
// Only gets called if fromShuttleMove returns true first
// returns the new move_mode (based on the old)
/turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle)
. = move_mode
if(!(. & MOVE_TURF))
return
var/shuttle_dir = shuttle.dir
for(var/i in contents)
var/atom/movable/thing = i
@@ -45,8 +49,6 @@ All ShuttleMove procs go here
else
qdel(thing)
return move_mode
// Called on the old turf to move the turf data
/turf/proc/onShuttleMove(turf/newT, list/movement_force, move_dir)
if(newT == src) // In case of in place shuttle rotation shenanigans.
@@ -176,10 +178,6 @@ All ShuttleMove procs go here
. = ..()
GLOB.cameranet.addCamera(src)
/obj/machinery/telecomms/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
listening_level = z // Update listening Z, just in case you have telecomm relay on a shuttle
/obj/machinery/mech_bay_recharge_port/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir)
. = ..()
recharging_turf = get_step(loc, dir)

View File

@@ -746,4 +746,4 @@
mode = SHUTTLE_ENDGAME
/obj/docking_port/mobile/emergency/on_emergency_dock()
return
return

View File

@@ -56,8 +56,8 @@
shuttlePortName = "custom location"
jumpto_ports = list("syndicate_ne" = 1, "syndicate_nw" = 1, "syndicate_n" = 1, "syndicate_se" = 1, "syndicate_sw" = 1, "syndicate_s" = 1)
view_range = 13
x_offset = -4
y_offset = -2
x_offset = -7
y_offset = -1
see_hidden = TRUE
#undef SYNDICATE_CHALLENGE_TIMER

View File

@@ -17,3 +17,4 @@
x_offset = -6
y_offset = -10
designate_time = 100

View File

@@ -190,7 +190,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/mob/living/carbon/human/H = user
if((invocation_type == "whisper" || invocation_type == "shout") && H.is_muzzled())
if((invocation_type == "whisper" || invocation_type == "shout") && !H.can_speak_vocal())
to_chat(user, "<span class='notice'>You can't get the words out!</span>")
return 0

View File

@@ -279,4 +279,4 @@
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem
charge_max = 800
jaunt_in_type = /obj/effect/temp_visual/dir_setting/cult/phase
jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out
jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out

View File

@@ -1,41 +1,41 @@
//NEEDS MAJOR CODE CLEANUP
/obj/effect/proc_holder/spell/dumbfire
var/projectile_type = ""
var/activate_on_collision = 1
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
var/turf/T = get_turf(user)
for(var/i = 1; i < range; i++)
var/turf/new_turf = get_step(T, user.dir)
if(new_turf.density)
break
T = new_turf
perform(list(T),user = user)
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
playMagSound()
for(var/turf/target in targets)
/obj/effect/proc_holder/spell/dumbfire
var/projectile_type = ""
var/activate_on_collision = 1
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 100 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)
var/turf/T = get_turf(user)
for(var/i = 1; i < range; i++)
var/turf/new_turf = get_step(T, user.dir)
if(new_turf.density)
break
T = new_turf
perform(list(T),user = user)
/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
playMagSound()
for(var/turf/target in targets)
launch_at(target, user)
/obj/effect/proc_holder/spell/dumbfire/proc/launch_at(turf/target, mob/user)

View File

@@ -1,32 +1,34 @@
/obj/effect/proc_holder/spell/targeted/genetic
name = "Genetic"
desc = "This spell inflicts a set of mutations and disabilities upon the target."
var/disabilities = 0 //bits
var/list/mutations = list() //mutation strings
var/duration = 100 //deciseconds
/*
Disabilities
1st bit - ?
2nd bit - ?
3rd bit - ?
4th bit - ?
5th bit - ?
6th bit - ?
*/
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
playMagSound()
for(var/mob/living/carbon/target in targets)
if(!target.dna)
continue
for(var/A in mutations)
target.dna.add_mutation(A)
target.disabilities |= disabilities
/obj/effect/proc_holder/spell/targeted/genetic
name = "Genetic"
desc = "This spell inflicts a set of mutations and disabilities upon the target."
var/list/disabilities = list() //disabilities
var/list/mutations = list() //mutation strings
var/duration = 100 //deciseconds
/*
Disabilities
1st bit - ?
2nd bit - ?
3rd bit - ?
4th bit - ?
5th bit - ?
6th bit - ?
*/
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
playMagSound()
for(var/mob/living/carbon/target in targets)
if(!target.dna)
continue
for(var/A in mutations)
target.dna.add_mutation(A)
for(var/A in disabilities)
target.add_disability(A, GENETICS_SPELL)
addtimer(CALLBACK(src, .proc/remove, target), duration)
/obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target)
if(!QDELETED(target))
for(var/A in mutations)
target.dna.remove_mutation(A)
target.disabilities &= ~disabilities
for(var/A in disabilities)
target.remove_disability(A, GENETICS_SPELL)

View File

@@ -1,31 +1,31 @@
/obj/effect/proc_holder/spell/aoe_turf/knock
name = "Knock"
desc = "This spell opens nearby doors and does not require wizard garb."
school = "transmutation"
charge_max = 100
clothes_req = 0
invocation = "AULIE OXIN FIERA"
invocation_type = "whisper"
range = 3
cooldown_min = 20 //20 deciseconds reduction per rank
action_icon_state = "knock"
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
/obj/effect/proc_holder/spell/aoe_turf/knock
name = "Knock"
desc = "This spell opens nearby doors and does not require wizard garb."
school = "transmutation"
charge_max = 100
clothes_req = 0
invocation = "AULIE OXIN FIERA"
invocation_type = "whisper"
range = 3
cooldown_min = 20 //20 deciseconds reduction per rank
action_icon_state = "knock"
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
SEND_SOUND(user, sound('sound/magic/knock.ogg'))
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
INVOKE_ASYNC(src, .proc/open_door, door)
for(var/obj/structure/closet/C in T.contents)
INVOKE_ASYNC(src, .proc/open_closet, C)
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door)
if(istype(door, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/A = door
A.locked = FALSE
door.open()
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C)
C.locked = FALSE
C.open()
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
INVOKE_ASYNC(src, .proc/open_door, door)
for(var/obj/structure/closet/C in T.contents)
INVOKE_ASYNC(src, .proc/open_closet, C)
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door)
if(istype(door, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/A = door
A.locked = FALSE
door.open()
/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C)
C.locked = FALSE
C.open()

View File

@@ -125,146 +125,6 @@
..()
/obj/item/spellbook/oneuse/mimery_blockade
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime
spellname = ""
name = "Guide to Advanced Mimery Vol 1"
desc = "The pages don't make any sound when turned."
icon_state ="bookmime"
/obj/item/spellbook/oneuse/mimery_guns
spell = /obj/effect/proc_holder/spell/aimed/finger_guns
spellname = ""
name = "Guide to Advanced Mimery Vol 2"
desc = "There aren't any words written..."
icon_state ="bookmime"
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall
name = "Invisible Wall"
desc = "The mime's performance transmutates into physical reality."
school = "mime"
panel = "Mime"
summon_type = list(/obj/effect/forcefield/mime)
invocation_type = "emote"
invocation_emote_self = "<span class='notice'>You form a wall in front of yourself.</span>"
summon_lifespan = 300
charge_max = 300
clothes_req = 0
range = 0
cast_sound = null
human_req = 1
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
if(usr && usr.mind)
if(!usr.mind.miming)
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
return
invocation = "<B>[usr.real_name]</B> looks as if a wall is in front of [usr.p_them()]."
else
invocation_type ="none"
..()
/obj/effect/proc_holder/spell/targeted/mime/speak
name = "Speech"
desc = "Make or break a vow of silence."
school = "mime"
panel = "Mime"
clothes_req = 0
human_req = 1
charge_max = 3000
range = -1
include_user = 1
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
if(!usr)
return
if(!ishuman(usr))
return
var/mob/living/carbon/human/H = usr
if(H.mind.miming)
still_recharging_msg = "<span class='warning'>You can't break your vow of silence that fast!</span>"
else
still_recharging_msg = "<span class='warning'>You'll have to wait before you can give your vow of silence again!</span>"
..()
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
for(var/mob/living/carbon/human/H in targets)
H.mind.miming=!H.mind.miming
if(H.mind.miming)
to_chat(H, "<span class='notice'>You make a vow of silence.</span>")
else
to_chat(H, "<span class='notice'>You break your vow of silence.</span>")
// These spells can only be gotten from the "Guide for Advanced Mimery series" for Mime Traitors.
/obj/effect/proc_holder/spell/targeted/forcewall/mime
name = "Invisible Blockade"
desc = "Form an invisible three tile wide blockade."
wall_type = /obj/effect/forcefield/mime/advanced
invocation_type = "emote"
invocation_emote_self = "<span class='notice'>You form a blockade in front of yourself.</span>"
charge_max = 600
sound = null
clothes_req = 0
range = -1
include_user = 1
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click()
if(usr && usr.mind)
if(!usr.mind.miming)
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
return
invocation = "<B>[usr.real_name]</B> looks as if a blockade is in front of [usr.p_them()]."
else
invocation_type ="none"
..()
/obj/effect/proc_holder/spell/aimed/finger_guns
name = "Finger Guns"
desc = "Shoot a mimed bullet from your fingers that stuns and does some damage."
school = "mime"
panel = "Mime"
charge_max = 300
clothes_req = 0
invocation_type = "emote"
invocation_emote_self = "<span class='dangers'>You fire your finger gun!</span>"
range = 20
projectile_type = /obj/item/projectile/bullet/mime
projectile_amount = 3
sound = null
active_msg = "You draw your fingers!"
deactive_msg = "You put your fingers at ease. Another time."
active = FALSE
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
base_icon_state = "mime"
/obj/effect/proc_holder/spell/aimed/finger_guns/Click()
var/mob/living/carbon/human/owner = usr
if(owner.incapacitated())
to_chat(owner, "<span class='warning'>You can't properly point your fingers while incapacitated.</span>")
return
if(usr && usr.mind)
if(!usr.mind.miming)
to_chat(usr, "<span class='notice'>You must dedicate yourself to silence first.</span>")
return
invocation = "<B>[usr.real_name]</B> fires [usr.p_their()] finger gun!"
else
invocation_type ="none"
..()
/obj/item/spellbook/oneuse/mimery_blockade
spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime
spellname = ""

View File

@@ -1,79 +1,79 @@
/obj/effect/proc_holder/spell/targeted/mind_transfer
name = "Mind Transfer"
desc = "This spell allows the user to switch bodies with a target."
school = "transmutation"
charge_max = 600
clothes_req = 0
invocation = "GIN'YU CAPAN"
invocation_type = "whisper"
range = 1
cooldown_min = 200 //100 deciseconds reduction per rank
var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell
var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
action_icon_state = "mindswap"
/*
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
/obj/effect/proc_holder/spell/targeted/mind_transfer
name = "Mind Transfer"
desc = "This spell allows the user to switch bodies with a target."
school = "transmutation"
charge_max = 600
clothes_req = 0
invocation = "GIN'YU CAPAN"
invocation_type = "whisper"
range = 1
cooldown_min = 200 //100 deciseconds reduction per rank
var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell
var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell
var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell
action_icon_state = "mindswap"
/*
Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do.
Make sure spells that are removed from spell_list are actually removed and deleted when mind transferring.
Also, you never added distance checking after target is selected. I've went ahead and did that.
*/
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride)
if(!targets.len)
to_chat(user, "<span class='warning'>No mind found!</span>")
return
if(targets.len > 1)
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
return
var/mob/living/target = targets[1]
var/t_He = target.p_they(TRUE)
var/t_is = target.p_are()
if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
to_chat(user, "<span class='warning'>[t_He] [t_is] too far away!</span>")
return
if(ismegafauna(target))
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
return
if(target.stat == DEAD)
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
return
if(!target.key || !target.mind)
to_chat(user, "<span class='warning'>[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.</span>")
return
if(user.suiciding)
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
return
if((target.mind.special_role in protected_roles) || cmptext(copytext(target.key,1,2),"@"))
to_chat(user, "<span class='warning'>[target.p_their(TRUE)] mind is resisting your spell!</span>")
return
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize(0)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
caster.key = ghost.key //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
//Here we knock both mobs out for a time.
caster.Unconscious(unconscious_amount_caster)
victim.Unconscious(unconscious_amount_victim)
Also, you never added distance checking after target is selected. I've went ahead and did that.
*/
/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride)
if(!targets.len)
to_chat(user, "<span class='warning'>No mind found!</span>")
return
if(targets.len > 1)
to_chat(user, "<span class='warning'>Too many minds! You're not a hive damnit!</span>")
return
var/mob/living/target = targets[1]
var/t_He = target.p_they(TRUE)
var/t_is = target.p_are()
if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it.
to_chat(user, "<span class='warning'>[t_He] [t_is] too far away!</span>")
return
if(ismegafauna(target))
to_chat(user, "<span class='warning'>This creature is too powerful to control!</span>")
return
if(target.stat == DEAD)
to_chat(user, "<span class='warning'>You don't particularly want to be dead!</span>")
return
if(!target.key || !target.mind)
to_chat(user, "<span class='warning'>[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.</span>")
return
if(user.suiciding)
to_chat(user, "<span class='warning'>You're killing yourself! You can't concentrate enough to do this!</span>")
return
if((target.mind.special_role in protected_roles) || cmptext(copytext(target.key,1,2),"@"))
to_chat(user, "<span class='warning'>[target.p_their(TRUE)] mind is resisting your spell!</span>")
return
var/mob/living/victim = target//The target of the spell whos body will be transferred to.
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize(0)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
caster.key = ghost.key //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
//Here we knock both mobs out for a time.
caster.Unconscious(unconscious_amount_caster)
victim.Unconscious(unconscious_amount_victim)
SEND_SOUND(caster, sound('sound/magic/mandswap.ogg'))
SEND_SOUND(victim, sound('sound/magic/mandswap.ogg'))// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened

View File

@@ -1,33 +1,33 @@
//NEEDS MAJOR CODE CLEANUP.
/obj/effect/proc_holder/spell/targeted/projectile
name = "Projectile"
desc = "This spell summons projectiles which try to hit the targets."
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
var/proj_homing = 1 //if it follows the target
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
playMagSound()
for(var/mob/living/target in targets)
/obj/effect/proc_holder/spell/targeted/projectile
name = "Projectile"
desc = "This spell summons projectiles which try to hit the targets."
var/proj_icon = 'icons/obj/projectiles.dmi'
var/proj_icon_state = "spell"
var/proj_name = "a spell projectile"
var/proj_trail = 0 //if it leaves a trail
var/proj_trail_lifespan = 0 //deciseconds
var/proj_trail_icon = 'icons/obj/wizard.dmi'
var/proj_trail_icon_state = "trail"
var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
var/proj_homing = 1 //if it follows the target
var/proj_insubstantial = 0 //if it can pass through dense objects or not
var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target)
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
var/proj_step_delay = 1 //lower = faster
/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr)
playMagSound()
for(var/mob/living/target in targets)
launch(target, user)
/obj/effect/proc_holder/spell/targeted/projectile/proc/launch(mob/living/target, mob/user)

View File

@@ -13,7 +13,7 @@
if(H.stat == DEAD || !(H.client))
continue
if(H.mind)
if(H.mind.special_role == "Wizard" || H.mind.special_role == "apprentice" || H.mind.special_role == "survivalist")
if(iswizard(H) || H.mind.special_role == "survivalist")
continue
if(prob(survivor_probability) && !(H.mind in SSticker.mode.traitors))
SSticker.mode.traitors += H.mind
@@ -220,4 +220,4 @@
SSevents.reschedule()
message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.")
log_game("Summon Events was increased!")
log_game("Summon Events was increased!")

View File

@@ -57,13 +57,15 @@
var/mob/living/shape = new shapeshift_type(caster.loc)
H = new(shape,src,caster)
clothes_req = 0
human_req = 0
/obj/effect/proc_holder/spell/targeted/shapeshift/proc/Restore(mob/living/shape)
var/obj/shapeshift_holder/H = locate() in shape
if(!H)
return
return
H.restore()
clothes_req = initial(clothes_req)
@@ -156,4 +158,4 @@
/datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer)
if(source)
source.shapeDeath(gibbed)
source.shapeDeath(gibbed)

View File

@@ -22,4 +22,4 @@
var/obj/item/bodypart/target_limb = surgery.operated_bodypart
target_limb.drop_limb()
return 1
return 1

View File

@@ -23,9 +23,9 @@
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] successfully fixes [target]'s eyes!", "<span class='notice'>You succeed in fixing [target]'s eyes.</span>")
target.cure_blind()
target.cure_blind(list(EYE_DAMAGE))
target.set_blindness(0)
target.cure_nearsighted()
target.cure_nearsighted(list(EYE_DAMAGE))
target.blur_eyes(35) //this will fix itself slowly.
target.set_eye_damage(0)
return TRUE

View File

@@ -169,3 +169,4 @@
return 0
return 1

View File

@@ -34,7 +34,7 @@
case = locate(/obj/item/implantcase) in get_turf(target)
if(case && !case.imp)
case.imp = I
I.loc = case
I.forceMove(case)
case.update_icon()
user.visible_message("[user] places [I] into [case]!", "<span class='notice'>You place [I] into [case].</span>")
else
@@ -53,4 +53,4 @@
/datum/surgery_step/mechanic_unwrench,
/datum/surgery_step/extract_implant,
/datum/surgery_step/mechanic_wrench,
/datum/surgery_step/mechanic_close)
/datum/surgery_step/mechanic_close)

View File

@@ -1,3 +1,4 @@
/////AUGMENTATION SURGERIES//////

View File

@@ -50,4 +50,4 @@
newmeat.subjectjob = H.job
newmeat.reagents.add_reagent ("nutriment", (removednutriment / 15)) //To balance with nutriment_factor of nutriment
newmeat.forceMove(target.loc)
return 1
return 1

View File

@@ -82,4 +82,4 @@
/datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].",
"<span class='notice'>You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...</span>")
"<span class='notice'>You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...</span>")

View File

@@ -126,7 +126,7 @@
return TRUE
if(!organs.len)
to_chat(user, "<span class='notice'>There are no removeable organs in [target]'s [parse_zone(target_zone)]!</span>")
to_chat(user, "<span class='notice'>There are no removable organs in [target]'s [parse_zone(target_zone)]!</span>")
return -1
else
for(var/obj/item/organ/O in organs)

View File

@@ -116,7 +116,7 @@
/obj/item/organ/cyberimp/chest/thrusters
name = "implantable thrusters set"
desc = "An implantable set of thruster ports. They use the gas from environment or subject's internals for propulsion in zero-gravity areas. \
Unlike regular jetpack, this device has no stabilization system."
Unlike regular jetpacks, this device has no stabilization system."
slot = ORGAN_SLOT_THRUSTERS
icon_state = "imp_jetpack"
implant_overlay = null

View File

@@ -85,3 +85,4 @@
var/obj/item/melee/arm_blade/new_arm = new(target,TRUE,TRUE)
target_zone == "r_arm" ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm)
return 1

View File

@@ -6,7 +6,7 @@
var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
var/list/species = list(/mob/living/carbon/human) //Acceptable Species
var/location = "chest" //Surgery location
var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on robotic limbs
var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type
var/list/possible_locs = list() //Multiple locations
var/ignore_clothes = 0 //This surgery ignores clothes
var/mob/living/carbon/target //Operation target mob

View File

@@ -5,7 +5,7 @@
var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
var/time = 10 //how long does the step take?
var/repeatable = 0
var/repeatable = 0 //does this step may be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)

View File

@@ -17,7 +17,6 @@ GLOBAL_LIST_EMPTY(uplinks)
var/selected_cat
var/owner = null
var/datum/game_mode/gamemode
var/spent_telecrystals = 0
var/datum/uplink_purchase_log/purchase_log
var/list/uplink_items
var/hidden_crystals = 0
@@ -89,7 +88,7 @@ GLOBAL_LIST_EMPTY(uplinks)
var/refundable = initial(UI.refundable)
if(I.type == path && refundable && I.check_uplink_validity())
telecrystals += cost
spent_telecrystals -= cost
purchase_log.total_spent -= cost
to_chat(user, "<span class='notice'>[I] refunded.</span>")
qdel(I)
return

View File

@@ -91,7 +91,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/proc/spawn_item(turf/loc, datum/component/uplink/U, mob/user)
if(item)
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]"))
return new item(loc)
/datum/uplink_item/Destroy()
@@ -611,7 +610,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
name = "Sleepy Pen"
desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \
strong anesthetic and a chemical that prevents the target from speaking. \
The pen holds one dose of the mixture, and cannot be refilled. Note that before the target \
The pen holds one dose of the mixture, and can be refilled. Note that before the target \
falls asleep, they will be able to move and act."
item = /obj/item/pen/sleepy
cost = 4
@@ -700,7 +699,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/stealthy_tools/chameleon/nuke
cost = 6
exclude_modes = list()
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/syndigaloshes
@@ -1391,7 +1389,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
if(possible_items.len)
var/datum/uplink_item/I = pick(possible_items)
U.telecrystals -= I.cost
U.spent_telecrystals += I.cost
U.purchase_log.total_spent += I.cost
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(I.name)]", "[cost]"))
SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name))
return new I.item(loc)

View File

@@ -13,6 +13,9 @@
var/datum/component/riding/D = LoadComponent(/datum/component/riding)
D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 7), TEXT_EAST = list(-12, 7), TEXT_WEST = list( 12, 7)))
if(floorbuffer)
AddComponent(/datum/component/cleaning)
/obj/vehicle/ridden/janicart/Destroy()
if(mybag)
qdel(mybag)
@@ -47,7 +50,7 @@
floorbuffer = TRUE
qdel(I)
to_chat(user, "<span class='notice'>You upgrade [src] with the floor buffer.</span>")
flags_1 |= CLEAN_ON_MOVE_1
AddComponent(/datum/component/cleaning)
update_icon()
else
return ..()

View File

@@ -58,8 +58,8 @@
life has not abandoned your broken form. You can only feel a deep and immutable hunger that \
not even death can stop, you will rise again!</span>")
var/revive_time = rand(revive_time_min, revive_time_max)
var/flags_1 = TIMER_STOPPABLE
timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags_1)
var/flags = TIMER_STOPPABLE
timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags)
/obj/item/organ/zombie_infection/proc/zombify()
timer_id = null