mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-27 14:08:44 +01:00
Merge branch 'master' into nova-ert
This commit is contained in:
@@ -176,19 +176,15 @@
|
||||
add_fingerprint(user)
|
||||
return M
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
// if(!L.Move(newloc, direct))
|
||||
if(!L.forceMove(newloc, direct))
|
||||
loc = L.loc
|
||||
last_move = L.last_move
|
||||
L.inertia_dir = last_move
|
||||
return FALSE
|
||||
else
|
||||
L.set_dir(dir)
|
||||
return TRUE
|
||||
/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct)
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
L.forceMove(loc, direct)
|
||||
L.last_move = last_move
|
||||
L.inertia_dir = last_move
|
||||
|
||||
if(!buckle_dir)
|
||||
L.set_dir(dir)
|
||||
|
||||
/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE)
|
||||
if(!buckled_mobs)
|
||||
|
||||
@@ -113,12 +113,11 @@ steam.start() -- spawns the effect
|
||||
T.hotspot_expose(1000,100)
|
||||
return ..()
|
||||
|
||||
/obj/effect/effect/sparks/Move()
|
||||
..()
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
/obj/effect/effect/sparks/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.hotspot_expose(1000,100)
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/spark_spread
|
||||
var/total_sparks = 0 // To stop it being spammed and lagging!
|
||||
@@ -225,8 +224,8 @@ steam.start() -- spawns the effect
|
||||
time_to_live = 600
|
||||
//var/list/projectiles
|
||||
|
||||
/obj/effect/effect/smoke/bad/Move()
|
||||
..()
|
||||
/obj/effect/effect/smoke/bad/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
for(var/mob/living/L in get_turf(src))
|
||||
affect(L)
|
||||
|
||||
@@ -281,8 +280,8 @@ steam.start() -- spawns the effect
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/effect/smoke/elemental/Move()
|
||||
..()
|
||||
/obj/effect/effect/smoke/elemental/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
for(var/mob/living/L in range(1, src))
|
||||
affect(L)
|
||||
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/effect/expl_particles/Move()
|
||||
..()
|
||||
return
|
||||
|
||||
/datum/effect/system/expl_particles
|
||||
var/number = 10
|
||||
var/turf/location
|
||||
|
||||
@@ -17,10 +17,38 @@
|
||||
/obj/item/device/encryptionkey/heads/rd
|
||||
name = "research director's encryption key"
|
||||
icon_state = "rd_cypherkey"
|
||||
channels = list("Command" = 1, "Science" = 1, "Explorer" = 1)
|
||||
channels = list("Command" = 1, "Science" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/ert
|
||||
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/omni //Literally only for the admin intercoms
|
||||
channels = list("Mercenary" = 1, "Raider" = 1, "Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/pathfinder
|
||||
name = "pathfinder's encryption key"
|
||||
icon_state = "com_cypherkey"
|
||||
channels = list("Command" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/qm
|
||||
name = "quartermaster's encryption key"
|
||||
icon_state = "qm_cypherkey"
|
||||
channels = list("Command" = 1, "Supply" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/pilot
|
||||
name = "pilot's encryption key"
|
||||
icon_state = "cypherkey"
|
||||
channels = list("Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/explorer
|
||||
name = "explorer's encryption key"
|
||||
icon_state = "rob_cypherkey"
|
||||
channels = list("Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/sar
|
||||
name = "fm's encryption key"
|
||||
icon_state = "med_cypherkey"
|
||||
channels = list("Medical" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/talon
|
||||
channels = list("Talon" = 1)
|
||||
|
||||
@@ -48,4 +48,83 @@
|
||||
M.mob_radio.forceMove(M.loc)
|
||||
M.mob_radio = null
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
/obj/item/device/radio/headset/headset_cargo
|
||||
desc = "A headset used by the QM's slaves."
|
||||
|
||||
/obj/item/device/radio/headset/headset_cargo/alt
|
||||
desc = "A bowman headset used by the QM's slaves."
|
||||
|
||||
/obj/item/device/radio/headset/headset_qm
|
||||
name = "qm radio headset"
|
||||
desc = "A headset used by the QM."
|
||||
icon_state = "cargo_headset"
|
||||
ks2type = /obj/item/device/encryptionkey/qm
|
||||
|
||||
/obj/item/device/radio/headset/headset_qm/alt
|
||||
name = "qm bowman headset"
|
||||
desc = "A bowman headset used by the QM."
|
||||
icon_state = "cargo_headset_alt"
|
||||
|
||||
/obj/item/device/radio/headset/pathfinder
|
||||
name = "pathfinder's headset"
|
||||
desc = "Headset used by pathfinders for exploring. Access to the explorer and command channels."
|
||||
icon_state = "exp_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/pathfinder
|
||||
|
||||
/obj/item/device/radio/headset/pathfinder/alt
|
||||
name = "pathfinder's bowman headset"
|
||||
desc = "Bowman headset used by pathfinders for exploring. Access to the explorer and command channels."
|
||||
icon_state = "exp_headset_alt"
|
||||
|
||||
/obj/item/device/radio/headset/pilot
|
||||
name = "pilot's headset"
|
||||
desc = "A headset used by pilots, has access to the explorer channel."
|
||||
icon_state = "pilot_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/pilot
|
||||
|
||||
/obj/item/device/radio/headset/pilot/alt
|
||||
name = "pilot's bowman headset"
|
||||
desc = "A bowman headset used by pilots, has access to the explorer channel."
|
||||
icon_state = "pilot_headset_alt"
|
||||
|
||||
/obj/item/device/radio/headset/explorer
|
||||
name = "explorer's headset"
|
||||
desc = "Headset used by explorers for exploring. Access to the explorer channel."
|
||||
icon_state = "exp_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/explorer
|
||||
|
||||
/obj/item/device/radio/headset/explorer/alt
|
||||
name = "explorer's bowman headset"
|
||||
desc = "Bowman headset used by explorers for exploring. Access to the explorer channel."
|
||||
icon_state = "exp_headset_alt"
|
||||
|
||||
/obj/item/device/radio/headset/sar
|
||||
name = "fm radio headset"
|
||||
desc = "A headset for field medics."
|
||||
icon_state = "sar_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/sar
|
||||
|
||||
/obj/item/device/radio/headset/sar/alt
|
||||
name = "fm radio bowman headset"
|
||||
desc = "A bowman headset for field medics."
|
||||
icon_state = "sar_headset_alt"
|
||||
|
||||
/obj/item/device/radio/headset/volunteer
|
||||
name = "volunteer's headset"
|
||||
desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
|
||||
icon_state = "pilot_headset"
|
||||
adhoc_fallback = TRUE
|
||||
ks2type = /obj/item/device/encryptionkey/pilot
|
||||
|
||||
/obj/item/device/radio/headset/talon
|
||||
name = "talon headset"
|
||||
desc = "A headset for communication between the crew of the ITV Talon."
|
||||
adhoc_fallback = TRUE
|
||||
icon_state = "pilot_headset"
|
||||
ks2type = /obj/item/device/encryptionkey/talon
|
||||
|
||||
@@ -11,10 +11,10 @@ var/global/list/default_internal_channels = list(
|
||||
num2text(MED_I_FREQ)=list(access_medical_equip),
|
||||
num2text(SEC_FREQ) = list(access_security),
|
||||
num2text(SEC_I_FREQ)=list(access_security),
|
||||
num2text(SCI_FREQ) = list(access_tox, access_robotics, access_xenobiology, access_explorer),
|
||||
num2text(SCI_FREQ) = list(access_tox, access_robotics, access_xenobiology),
|
||||
num2text(SUP_FREQ) = list(access_cargo, access_mining_station),
|
||||
num2text(SRV_FREQ) = list(access_janitor, access_library, access_hydroponics, access_bar, access_kitchen),
|
||||
num2text(EXP_FREQ) = list(access_explorer, access_pilot, access_rd)
|
||||
num2text(EXP_FREQ) = list(access_explorer, access_pilot)
|
||||
)
|
||||
|
||||
var/global/list/default_medbay_channels = list(
|
||||
@@ -287,7 +287,7 @@ var/global/list/default_medbay_channels = list(
|
||||
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel, var/list/zlevels) //BS12 EDIT
|
||||
var/datum/radio_frequency/connection = null
|
||||
if(channel && channels && channels.len > 0)
|
||||
if (channel == "department")
|
||||
if(channel == "department")
|
||||
channel = channels[1]
|
||||
connection = secure_radio_connections[channel]
|
||||
else
|
||||
@@ -304,7 +304,7 @@ var/global/list/default_medbay_channels = list(
|
||||
Broadcast_Message(connection, A,
|
||||
0, "*garbled automated announcement*", src,
|
||||
message_to_multilingual(message), from, "Automated Announcement", from, "synthesized voice",
|
||||
4, 0, zlevels, connection.frequency, "states")
|
||||
DATA_FAKE, 0, zlevels, connection.frequency, "states")
|
||||
|
||||
// Interprets the message mode when talking into a radio, possibly returning a connection datum
|
||||
/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, list/message_pieces, message_mode)
|
||||
@@ -363,8 +363,8 @@ var/global/list/default_medbay_channels = list(
|
||||
if(!istype(message_mode, /datum/radio_frequency))
|
||||
return FALSE
|
||||
|
||||
var/datum/radio_frequency/connection = message_mode
|
||||
var/pos_z = get_z(src)
|
||||
var/datum/radio_frequency/connection = message_mode
|
||||
|
||||
//#### Tagging the signal with all appropriate identity values ####//
|
||||
|
||||
@@ -479,7 +479,6 @@ var/global/list/default_medbay_channels = list(
|
||||
signal.transmission_method = TRANSMISSION_SUBSPACE
|
||||
|
||||
//#### Sending the signal to all subspace receivers ####//
|
||||
|
||||
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
|
||||
R.receive_signal(signal)
|
||||
|
||||
@@ -494,7 +493,7 @@ var/global/list/default_medbay_channels = list(
|
||||
else if(adhoc_fallback) //Less huzzah, we have to fallback
|
||||
to_chat(loc, "<span class='warning'>\The [src] pings as it falls back to local radio transmission.</span>")
|
||||
subspace_transmission = FALSE
|
||||
|
||||
|
||||
else //Oh well
|
||||
return FALSE
|
||||
|
||||
@@ -536,8 +535,6 @@ var/global/list/default_medbay_channels = list(
|
||||
if(get_dist(src, M) <= canhear_range)
|
||||
talk_into(M, message_pieces, null, verb)
|
||||
|
||||
|
||||
|
||||
/obj/item/device/radio/proc/receive_range(freq, level)
|
||||
// check if this radio can receive on the given frequency, and if so,
|
||||
// what the range is in which mobs will hear the radio
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
break
|
||||
..() // delete target
|
||||
|
||||
Move()
|
||||
..()
|
||||
Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
// After target moves, check for nearby stakes. If associated, move to target
|
||||
for(var/obj/structure/target_stake/M in view(3,src))
|
||||
if(M.density == 0 && M.pinned_target == src)
|
||||
M.loc = loc
|
||||
M.forceMove(loc)
|
||||
|
||||
// This may seem a little counter-intuitive but I assure you that's for a purpose.
|
||||
// Stakes are the ones that carry targets, yes, but in the stake code we set
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
#define UAV_OFF 0
|
||||
#define UAV_ON 1
|
||||
#define UAV_PAIRING 2
|
||||
#define UAV_PACKED 3
|
||||
|
||||
/obj/item/device/uav
|
||||
name = "recon skimmer"
|
||||
desc = "A semi-portable reconisance drone that folds into a backpack-sized carrying case."
|
||||
icon = 'icons/obj/uav.dmi'
|
||||
icon_state = "uav"
|
||||
|
||||
var/obj/item/weapon/cell/cell
|
||||
var/cell_type = null //Can put a starting cell here
|
||||
|
||||
density = 1 //Is dense, but not anchored, so you can swap with it
|
||||
slowdown = 3 //Heevvee.
|
||||
|
||||
health = 100
|
||||
var/power_per_process = 50 // About 6.5 minutes of use on a high-cell (10,000)
|
||||
var/state = UAV_OFF
|
||||
|
||||
var/datum/effect/effect/system/ion_trail_follow/ion_trail
|
||||
|
||||
var/list/mob/living/masters
|
||||
|
||||
// So you know which is which
|
||||
var/nickname = "Generic Droan"
|
||||
|
||||
// Radial menu
|
||||
var/static/image/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup")
|
||||
var/static/image/radial_wrench = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_wrench")
|
||||
var/static/image/radial_power = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_power")
|
||||
var/static/image/radial_pair = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pair")
|
||||
|
||||
// Movement cooldown
|
||||
var/next_move = 0
|
||||
|
||||
// Idle shutdown time
|
||||
var/no_masters_time = 0
|
||||
|
||||
/obj/item/device/uav/loaded
|
||||
cell_type = /obj/item/weapon/cell/high
|
||||
|
||||
/obj/item/device/uav/Initialize()
|
||||
. = ..()
|
||||
|
||||
if(!cell && cell_type)
|
||||
cell = new cell_type
|
||||
|
||||
ion_trail = new /datum/effect/effect/system/ion_trail_follow()
|
||||
ion_trail.set_up(src)
|
||||
ion_trail.stop()
|
||||
|
||||
/obj/item/device/uav/Destroy()
|
||||
qdel_null(cell)
|
||||
qdel_null(ion_trail)
|
||||
LAZYCLEARLIST(masters)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/uav/attack_hand(var/mob/user)
|
||||
//Has to be on the ground to work with it properly
|
||||
if(!isturf(loc))
|
||||
return ..()
|
||||
|
||||
var/list/options = list(
|
||||
"Pick Up" = radial_pickup,
|
||||
"(Dis)Assemble" = radial_wrench,
|
||||
"Toggle Power" = radial_power,
|
||||
"Pairing Mode" = radial_pair)
|
||||
var/choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
|
||||
|
||||
switch(choice)
|
||||
// Can pick up when off or packed
|
||||
if("Pick Up")
|
||||
if(state == UAV_OFF || state == UAV_PACKED)
|
||||
return ..()
|
||||
else
|
||||
to_chat(user,"<span class='warning'>Turn [nickname] off or pack it first!</span>")
|
||||
return
|
||||
// Can disasemble or reassemble from packed or off (and this one takes time)
|
||||
if("(Dis)Assemble")
|
||||
if(can_transition_to(state == UAV_PACKED ? UAV_OFF : UAV_PACKED, user) && do_after(user, 10 SECONDS, src))
|
||||
return toggle_packed(user)
|
||||
// Can toggle power from on and off
|
||||
if("Toggle Power")
|
||||
if(can_transition_to(state == UAV_ON ? UAV_OFF : UAV_ON, user))
|
||||
return toggle_power(user)
|
||||
// Can pair when off
|
||||
if("Pairing Mode")
|
||||
if(can_transition_to(state == UAV_PAIRING ? UAV_OFF : UAV_PAIRING, user))
|
||||
return toggle_pairing(user)
|
||||
|
||||
/obj/item/device/uav/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/modular_computer) && state == UAV_PAIRING)
|
||||
var/obj/item/modular_computer/MC = I
|
||||
LAZYDISTINCTADD(MC.paired_uavs, weakref(src))
|
||||
playsound(src, 'sound/machines/buttonbeep.ogg', 50, 1)
|
||||
visible_message("<span class='notice'>[user] pairs [I] to [nickname]</span>")
|
||||
toggle_pairing()
|
||||
|
||||
else if(I.is_screwdriver() && cell)
|
||||
if(do_after(user, 3 SECONDS, src))
|
||||
to_chat(user, "<span class='notice'>You remove [cell] into [nickname].</span>")
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
power_down()
|
||||
cell.forceMove(get_turf(src))
|
||||
cell = null
|
||||
|
||||
else if(istype(I, /obj/item/weapon/cell) && !cell)
|
||||
if(do_after(user, 3 SECONDS, src))
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [nickname].</span>")
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
power_down()
|
||||
cell.forceMove(get_turf(src))
|
||||
cell = null
|
||||
|
||||
else if(istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/device/flashlight/pen))
|
||||
var/tmp_label = sanitizeSafe(input(user, "Enter a nickname for [src]", "Nickname", nickname), MAX_NAME_LEN)
|
||||
if(length(tmp_label) > 50 || length(tmp_label) < 3)
|
||||
to_chat(user, "<span class='notice'>The nickname must be between 3 and 50 characters.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You scribble your new nickname on the side of [src].</span>")
|
||||
nickname = tmp_label
|
||||
desc = initial(desc) + " This one has <span class='notice'>'[nickname]'</span> scribbled on the side."
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/uav/proc/can_transition_to(var/new_state, var/mob/user)
|
||||
switch(state) //Current one
|
||||
if(UAV_ON)
|
||||
if(new_state == UAV_OFF || new_state == UAV_PACKED)
|
||||
. = TRUE
|
||||
if(UAV_OFF)
|
||||
if(new_state == UAV_ON || new_state == UAV_PACKED || new_state == UAV_PAIRING)
|
||||
. = TRUE
|
||||
if(UAV_PAIRING)
|
||||
if(new_state == UAV_OFF)
|
||||
. = TRUE
|
||||
if(UAV_PACKED)
|
||||
if(new_state == UAV_OFF)
|
||||
. = TRUE
|
||||
|
||||
if(!.)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You can't do that while [nickname] is in this state.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/uav/update_icon()
|
||||
cut_overlays()
|
||||
switch(state)
|
||||
if(UAV_PAIRING)
|
||||
add_overlay("[initial(icon_state)]_pairing")
|
||||
icon_state = "[initial(icon_state)]"
|
||||
if(UAV_ON)
|
||||
icon_state = "[initial(icon_state)]_on"
|
||||
if(UAV_OFF)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
if(UAV_PACKED)
|
||||
icon_state = "[initial(icon_state)]_packed"
|
||||
|
||||
/obj/item/device/uav/process()
|
||||
if(cell?.use(power_per_process) != power_per_process)
|
||||
visible_message("<span class='warning'>[src] sputters and thuds to the ground, inert.</span>")
|
||||
playsound(src, 'sound/items/drop/metalboots.ogg', 75, 1)
|
||||
power_down()
|
||||
health -= initial(health)*0.25 //Lose 25% of your original health
|
||||
|
||||
if(LAZYLEN(masters))
|
||||
no_masters_time = 0
|
||||
else if(no_masters_time++ > 50)
|
||||
power_down()
|
||||
|
||||
/obj/item/device/uav/proc/toggle_pairing()
|
||||
switch(state)
|
||||
if(UAV_PAIRING)
|
||||
state = UAV_OFF
|
||||
update_icon()
|
||||
return TRUE
|
||||
if(UAV_OFF)
|
||||
state = UAV_PAIRING
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/uav/proc/toggle_power()
|
||||
switch(state)
|
||||
if(UAV_OFF)
|
||||
power_up()
|
||||
return TRUE
|
||||
if(UAV_ON)
|
||||
power_down()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/uav/proc/toggle_packed()
|
||||
if(UAV_ON)
|
||||
power_down()
|
||||
switch(state)
|
||||
if(UAV_OFF) //Packing
|
||||
state = UAV_PACKED
|
||||
w_class = ITEMSIZE_LARGE
|
||||
slowdown = 1
|
||||
density = FALSE
|
||||
update_icon()
|
||||
return TRUE
|
||||
if(UAV_PACKED) //Unpacking
|
||||
state = UAV_OFF
|
||||
w_class = ITEMSIZE_HUGE
|
||||
slowdown = 3
|
||||
density = TRUE
|
||||
update_icon()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/uav/proc/power_up()
|
||||
if(state != UAV_OFF || !isturf(loc))
|
||||
return
|
||||
if(cell?.use(power_per_process) != power_per_process)
|
||||
visible_message("<span class='warning'>[src] sputters and chugs as it tries, and fails, to power up.</span>")
|
||||
return
|
||||
|
||||
state = UAV_ON
|
||||
update_icon()
|
||||
start_hover()
|
||||
set_light(4, 4, "#FFFFFF")
|
||||
START_PROCESSING(SSobj, src)
|
||||
no_masters_time = 0
|
||||
visible_message("<span class='notice'>[nickname] buzzes and lifts into the air.</span>")
|
||||
|
||||
/obj/item/device/uav/proc/power_down()
|
||||
if(state != UAV_ON)
|
||||
return
|
||||
|
||||
state = UAV_OFF
|
||||
update_icon()
|
||||
stop_hover()
|
||||
set_light(0)
|
||||
LAZYCLEARLIST(masters)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
visible_message("<span class='notice'>[nickname] gracefully settles onto the ground.</span>")
|
||||
|
||||
//////////////// Helpers
|
||||
/obj/item/device/uav/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/device/uav/relaymove(var/mob/user, direction, signal = 1)
|
||||
if(signal && state == UAV_ON && (weakref(user) in masters))
|
||||
if(next_move <= world.time)
|
||||
next_move = world.time + (1 SECOND/signal)
|
||||
step(src, direction)
|
||||
return TRUE // Even if we couldn't step, we're taking credit for absorbing the move
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/uav/proc/get_status_string()
|
||||
return "[nickname] - [get_x(src)],[get_y(src)],[get_z(src)] - I:[health]/[initial(health)] - C:[cell ? "[cell.charge]/[cell.maxcharge]" : "Not Installed"]"
|
||||
|
||||
/obj/item/device/uav/proc/add_master(var/mob/living/M)
|
||||
LAZYDISTINCTADD(masters, weakref(M))
|
||||
|
||||
/obj/item/device/uav/proc/remove_master(var/mob/living/M)
|
||||
LAZYREMOVE(masters, weakref(M))
|
||||
|
||||
/obj/item/device/uav/check_eye()
|
||||
if(state == UAV_ON)
|
||||
return 0
|
||||
else
|
||||
return -1
|
||||
|
||||
/obj/item/device/uav/proc/start_hover()
|
||||
if(!ion_trail.on) //We'll just use this to store if we're floating or not
|
||||
ion_trail.start()
|
||||
var/amplitude = 2 //maximum displacement from original position
|
||||
var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4
|
||||
|
||||
var/top = old_y + amplitude
|
||||
var/bottom = old_y - amplitude
|
||||
var/half_period = period / 2
|
||||
var/quarter_period = period / 4
|
||||
|
||||
animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up
|
||||
animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down
|
||||
animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back
|
||||
|
||||
/obj/item/device/uav/proc/stop_hover()
|
||||
if(ion_trail.on)
|
||||
ion_trail.stop()
|
||||
animate(src, pixel_y = old_y, time = 5, easing = SINE_EASING | EASE_IN) //halt animation
|
||||
|
||||
/obj/item/device/uav/hear_talk(var/mob/M, list/message_pieces, verb)
|
||||
var/name_used = M.GetVoice()
|
||||
for(var/wr_master in masters)
|
||||
var/weakref/wr = wr_master
|
||||
var/mob/master = wr.resolve()
|
||||
var/message = master.combine_message(message_pieces, verb, M)
|
||||
var/rendered = "<i><span class='game say'>UAV received: <span class='name'>[name_used]</span> [message]</span></i>"
|
||||
master.show_message(rendered, 2)
|
||||
|
||||
/obj/item/device/uav/see_emote(var/mob/living/M, text)
|
||||
for(var/wr_master in masters)
|
||||
var/weakref/wr = wr_master
|
||||
var/mob/master = wr.resolve()
|
||||
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[text]</span></span></i>"
|
||||
master.show_message(rendered, 2)
|
||||
|
||||
/obj/item/device/uav/show_message(msg, type, alt, alt_type)
|
||||
for(var/wr_master in masters)
|
||||
var/weakref/wr = wr_master
|
||||
var/mob/master = wr.resolve()
|
||||
var/rendered = "<i><span class='game say'>UAV received, <span class='message'>[msg]</span></span></i>"
|
||||
master.show_message(rendered, type)
|
||||
|
||||
/obj/item/device/uav/take_damage(var/damage)
|
||||
health -= damage
|
||||
CheckHealth()
|
||||
return
|
||||
|
||||
/obj/item/device/uav/attack_generic(var/mob/user, var/damage, var/attack_verb)
|
||||
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
|
||||
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
|
||||
user.do_attack_animation(src)
|
||||
health -= damage
|
||||
CheckHealth()
|
||||
return
|
||||
|
||||
/obj/item/device/uav/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
die()
|
||||
if(2.0)
|
||||
health -= 25
|
||||
CheckHealth()
|
||||
|
||||
/obj/item/device/uav/proc/CheckHealth()
|
||||
if(health <= 0)
|
||||
die()
|
||||
|
||||
/obj/item/device/uav/proc/die()
|
||||
visible_message("<span class='danger'>[src] shorts out and explodes!</span>")
|
||||
power_down()
|
||||
var/turf/T = get_turf(src)
|
||||
qdel(src)
|
||||
explosion(T, -1, 0, 1, 2) //Not very large
|
||||
|
||||
#undef UAV_OFF
|
||||
#undef UAV_ON
|
||||
#undef UAV_PACKED
|
||||
@@ -68,6 +68,11 @@
|
||||
if(!S || S.robotic < ORGAN_ROBOT || S.open == 3)
|
||||
return ..()
|
||||
|
||||
//VOREStation Add - No welding nanoform limbs
|
||||
if(S.robotic > ORGAN_LIFELIKE)
|
||||
return ..()
|
||||
//VOREStation Add End
|
||||
|
||||
if(S.organ_tag == BP_HEAD)
|
||||
if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space))
|
||||
to_chat(user, "<span class='warning'>You can't apply [src] through [H.head]!</span>")
|
||||
|
||||
@@ -122,18 +122,6 @@
|
||||
if(!has_buckled_mobs())
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/energy_net/Move()
|
||||
..()
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/occupant = A
|
||||
occupant.buckled = null
|
||||
occupant.forceMove(src.loc)
|
||||
occupant.buckled = src
|
||||
if (occupant && (src.loc != occupant.loc))
|
||||
unbuckle_mob(occupant)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
visible_message("<span class='danger'>[user] begins to tear at \the [src]!</span>")
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
return
|
||||
|
||||
/mob/proc/unset_machine()
|
||||
machine?.remove_visual(src)
|
||||
src.machine = null
|
||||
|
||||
/mob/proc/set_machine(var/obj/O)
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
//Gun Cabinets
|
||||
|
||||
/obj/structure/closet/secure_closet/guncabinet/sidearm
|
||||
name = "emergency weapon cabinet"
|
||||
req_one_access = list(access_armory,access_captain)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/gun/energy/gun = 4)
|
||||
|
||||
|
||||
/obj/structure/closet/secure_closet/guncabinet/rifle
|
||||
name = "rifle cabinet"
|
||||
req_one_access = list(access_explorer,access_brig)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/ammo_magazine/clip/c762/hunter = 9,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle = 2)
|
||||
|
||||
/obj/structure/closet/secure_closet/guncabinet/rifle/Initialize()
|
||||
if(prob(85))
|
||||
starts_with += /obj/item/weapon/gun/projectile/shotgun/pump/rifle
|
||||
else
|
||||
starts_with += /obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/guncabinet/phase
|
||||
name = "explorer weapon cabinet"
|
||||
req_one_access = list(access_explorer,access_brig)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/gun/energy/phasegun = 2,
|
||||
/obj/item/weapon/gun/energy/phasegun/pistol,
|
||||
/obj/item/weapon/cell/device/weapon = 2,
|
||||
/obj/item/clothing/accessory/permit/gun/planetside)
|
||||
|
||||
//Explorer Lockers
|
||||
|
||||
/obj/structure/closet/secure_closet/explorer
|
||||
name = "explorer locker"
|
||||
icon = 'icons/obj/closet_vr.dmi'
|
||||
icon_state = "secureexp1"
|
||||
icon_closed = "secureexp"
|
||||
icon_locked = "secureexp1"
|
||||
icon_opened = "secureexpopen"
|
||||
icon_broken = "secureexpbroken"
|
||||
icon_off = "secureexpoff"
|
||||
req_access = list(access_explorer)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/clothing/under/explorer,
|
||||
/obj/item/clothing/suit/storage/hooded/explorer,
|
||||
/obj/item/clothing/mask/gas/explorer,
|
||||
/obj/item/clothing/shoes/boots/winter/explorer,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/device/radio/headset/explorer,
|
||||
/obj/item/device/radio/headset/explorer/alt,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/device/gps/explorer,
|
||||
/obj/item/weapon/storage/box/flare,
|
||||
/obj/item/device/geiger,
|
||||
/obj/item/weapon/cell/device,
|
||||
/obj/item/device/radio,
|
||||
/obj/item/stack/marker_beacon/thirty,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/material/knife/machete,
|
||||
/obj/item/clothing/accessory/holster/machete,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
|
||||
/obj/item/device/cataloguer)
|
||||
|
||||
/obj/structure/closet/secure_closet/explorer/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/norm
|
||||
return ..()
|
||||
|
||||
//SAR Lockers
|
||||
|
||||
/obj/structure/closet/secure_closet/sar
|
||||
name = "field medic locker"
|
||||
desc = "Supplies for a wilderness first responder."
|
||||
icon_state = "medical1"
|
||||
icon_closed = "medical"
|
||||
icon_locked = "medical1"
|
||||
icon_opened = "medicalopen"
|
||||
icon_broken = "medicalbroken"
|
||||
icon_off = "medicaloff"
|
||||
req_access = list(access_medical_equip)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/storage/backpack/dufflebag/emt,
|
||||
/obj/item/weapon/storage/box/autoinjectors,
|
||||
/obj/item/weapon/storage/box/syringes,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/antitoxin,
|
||||
/obj/item/weapon/storage/belt/medical/emt,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/gun/energy/locked/frontier/holdout,
|
||||
/obj/item/clothing/mask/gas/explorer,
|
||||
/obj/item/clothing/suit/storage/hooded/explorer/medic,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar,
|
||||
/obj/item/clothing/shoes/boots/winter/explorer,
|
||||
/obj/item/device/radio/headset/sar,
|
||||
/obj/item/device/radio/headset/sar/alt,
|
||||
/obj/item/weapon/cartridge/medical,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/tank/emergency/oxygen/engi,
|
||||
/obj/item/clothing/glasses/hud/health,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/device/radio/off,
|
||||
/obj/random/medical,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood = 2,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 2,
|
||||
/obj/item/weapon/tool/crowbar,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/storage/box/freezer,
|
||||
/obj/item/clothing/accessory/storage/white_vest,
|
||||
/obj/item/taperoll/medical,
|
||||
/obj/item/device/gps/medical,
|
||||
/obj/item/device/geiger,
|
||||
/obj/item/bodybag/cryobag,
|
||||
/obj/item/device/cataloguer/compact)
|
||||
|
||||
//Pilot Locker
|
||||
|
||||
/obj/structure/closet/secure_closet/pilot
|
||||
name = "pilot locker"
|
||||
req_access = list(access_pilot)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/weapon/storage/backpack/parachute,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/gun/energy/locked/frontier/holdout,
|
||||
/obj/item/clothing/head/pilot,
|
||||
/obj/item/clothing/under/rank/pilot1,
|
||||
/obj/item/clothing/suit/storage/toggle/bomber/pilot,
|
||||
/obj/item/clothing/shoes/boots/winter/explorer,
|
||||
/obj/item/clothing/mask/gas/half,
|
||||
/obj/item/clothing/shoes/black,
|
||||
/obj/item/clothing/gloves/fingerless,
|
||||
/obj/item/device/radio/headset/pilot,
|
||||
/obj/item/device/radio/headset/pilot/alt,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle,
|
||||
/obj/item/weapon/storage/box/flare,
|
||||
/obj/item/weapon/cell/device,
|
||||
/obj/item/device/radio,
|
||||
/obj/item/device/gps/explorer,
|
||||
/obj/item/device/cataloguer/compact)
|
||||
|
||||
/obj/structure/closet/secure_closet/pilot/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/norm
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/pathfinder
|
||||
name = "pathfinder locker"
|
||||
icon = 'icons/obj/closet_vr.dmi'
|
||||
icon_state = "secureexp1"
|
||||
icon_closed = "secureexp"
|
||||
icon_locked = "secureexp1"
|
||||
icon_opened = "secureexpopen"
|
||||
icon_broken = "secureexpbroken"
|
||||
icon_off = "secureexpoff"
|
||||
req_access = list(access_gateway)
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/clothing/under/explorer,
|
||||
/obj/item/clothing/suit/storage/hooded/explorer,
|
||||
/obj/item/clothing/mask/gas/explorer,
|
||||
/obj/item/clothing/shoes/boots/winter/explorer,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/device/radio/headset/pathfinder,
|
||||
/obj/item/device/radio/headset/pathfinder/alt,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/device/gps/explorer,
|
||||
/obj/item/weapon/storage/box/flare,
|
||||
/obj/item/weapon/storage/box/explorerkeys,
|
||||
/obj/item/device/geiger,
|
||||
/obj/item/weapon/cell/device,
|
||||
/obj/item/device/radio,
|
||||
/obj/item/device/bluespaceradio/tether_prelinked,
|
||||
/obj/item/stack/marker_beacon/thirty,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/material/knife/machete/deluxe,
|
||||
/obj/item/weapon/gun/energy/locked/frontier/carbine,
|
||||
/obj/item/clothing/accessory/holster/machete,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
|
||||
/obj/item/device/cataloguer/compact/pathfinder)
|
||||
|
||||
/obj/structure/closet/secure_closet/pathfinder/Initialize()
|
||||
if(prob(50))
|
||||
starts_with += /obj/item/weapon/storage/backpack
|
||||
else
|
||||
starts_with += /obj/item/weapon/storage/backpack/satchel/norm
|
||||
return ..()
|
||||
|
||||
//Exotic Seeds Crate
|
||||
|
||||
/obj/structure/closet/crate/hydroponics/exotic
|
||||
name = "exotic seeds crate"
|
||||
desc = "All you need to destroy that pesky planet."
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/seeds/random = 6,
|
||||
/obj/item/seeds/replicapod = 2,
|
||||
/obj/item/seeds/ambrosiavulgarisseed = 2,
|
||||
/obj/item/seeds/kudzuseed,
|
||||
/obj/item/seeds/libertymycelium,
|
||||
/obj/item/seeds/reishimycelium)
|
||||
@@ -47,8 +47,8 @@
|
||||
/obj/item/clothing/under/rank/cargo/jeans,
|
||||
/obj/item/clothing/under/rank/cargo/jeans/female,
|
||||
/obj/item/clothing/shoes/brown,
|
||||
/obj/item/device/radio/headset/headset_cargo,
|
||||
/obj/item/device/radio/headset/headset_cargo/alt,
|
||||
/obj/item/device/radio/headset/headset_qm, //VOREStation Edit,
|
||||
/obj/item/device/radio/headset/headset_qm/alt, //VOREStation Edit,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/gloves/fingerless,
|
||||
/obj/item/clothing/suit/fire/firefighter,
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
bound_height = width * world.icon_size
|
||||
update_state()
|
||||
|
||||
Move()
|
||||
Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
|
||||
@@ -230,15 +230,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart)
|
||||
to_chat(user, "<span class='notice'>You'll need the keys in one of your hands to drive this [callme].</span>")
|
||||
|
||||
|
||||
/obj/structure/bed/chair/janicart/Move()
|
||||
..()
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
if(L.buckled == src)
|
||||
L.loc = loc
|
||||
|
||||
|
||||
/obj/structure/bed/chair/janicart/post_buckle_mob(mob/living/M)
|
||||
update_mob()
|
||||
return ..()
|
||||
|
||||
@@ -286,15 +286,10 @@
|
||||
held = null
|
||||
|
||||
|
||||
/obj/structure/bed/roller/Move()
|
||||
..()
|
||||
/obj/structure/bed/roller/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
playsound(src, 'sound/effects/roll.ogg', 100, 1)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
|
||||
if(L.buckled == src)
|
||||
L.loc = src.loc
|
||||
|
||||
/obj/structure/bed/roller/post_buckle_mob(mob/living/M as mob)
|
||||
if(M.buckled == src)
|
||||
|
||||
@@ -140,22 +140,24 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/bed/chair/office/Move()
|
||||
..()
|
||||
/obj/structure/bed/chair/office/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
playsound(src, 'sound/effects/roll.ogg', 100, 1)
|
||||
if(has_buckled_mobs())
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/occupant = A
|
||||
occupant.buckled = null
|
||||
occupant.Move(src.loc)
|
||||
occupant.buckled = src
|
||||
if (occupant && (src.loc != occupant.loc))
|
||||
if (propelled)
|
||||
for (var/mob/O in src.loc)
|
||||
if (O != occupant)
|
||||
Bump(O)
|
||||
else
|
||||
unbuckle_mob()
|
||||
|
||||
/obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction)
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/occupant = A
|
||||
occupant.buckled = null
|
||||
occupant.Move(src.loc)
|
||||
occupant.buckled = src
|
||||
if (occupant && (src.loc != occupant.loc))
|
||||
if (propelled)
|
||||
for (var/mob/O in src.loc)
|
||||
if (O != occupant)
|
||||
Bump(O)
|
||||
else
|
||||
unbuckle_mob()
|
||||
|
||||
/obj/structure/bed/chair/office/Bump(atom/A)
|
||||
..()
|
||||
|
||||
@@ -91,8 +91,9 @@
|
||||
create_track()
|
||||
driving = 0
|
||||
|
||||
/obj/structure/bed/chair/wheelchair/Move()
|
||||
..()
|
||||
/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
cut_overlays()
|
||||
playsound(src, 'sound/effects/roll.ogg', 75, 1)
|
||||
if(has_buckled_mobs())
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
w_class = ITEMSIZE_HUGE
|
||||
var/obj/item/target/pinned_target // the current pinned target
|
||||
|
||||
Move()
|
||||
..()
|
||||
Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
// Move the pinned target along with the stake
|
||||
if(pinned_target in view(3, src))
|
||||
pinned_target.loc = loc
|
||||
pinned_target.forceMove(loc)
|
||||
|
||||
else // Sanity check: if the pinned target can't be found in immediate view
|
||||
pinned_target = null
|
||||
|
||||
@@ -413,7 +413,7 @@
|
||||
/obj/structure/window/Move()
|
||||
var/ini_dir = dir
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
..()
|
||||
. = ..()
|
||||
set_dir(ini_dir)
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user