mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-29 06:58:30 +01:00
Merge branch 'master' into nova-ert
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
// This is a datum-based artificial intelligence for simple mobs (and possibly others) to use.
|
||||
// The neat thing with having this here instead of on the mob is that it is independant of Life(), and that different mobs
|
||||
// can use a more or less complex AI by giving it a different datum.
|
||||
#define AI_NO_PROCESS 0
|
||||
#define AI_PROCESSING (1<<0)
|
||||
#define AI_FASTPROCESSING (1<<1)
|
||||
|
||||
#define START_AIPROCESSING(Datum) if (!(Datum.process_flags & AI_PROCESSING)) {Datum.process_flags |= AI_PROCESSING;SSai.processing += Datum}
|
||||
#define STOP_AIPROCESSING(Datum) Datum.process_flags &= ~AI_PROCESSING;SSai.processing -= Datum
|
||||
#define START_AIFASTPROCESSING(Datum) if (!(Datum.process_flags & AI_FASTPROCESSING)) {Datum.process_flags |= AI_FASTPROCESSING;SSaifast.processing += Datum}
|
||||
#define STOP_AIFASTPROCESSING(Datum) Datum.process_flags &= ~AI_FASTPROCESSING;SSaifast.processing -= Datum
|
||||
|
||||
/mob/living
|
||||
var/datum/ai_holder/ai_holder = null
|
||||
@@ -27,7 +35,20 @@
|
||||
var/busy = FALSE // If true, the ticker will skip processing this mob until this is false. Good for if you need the
|
||||
// mob to stay still (e.g. delayed attacking). If you need the mob to be inactive for an extended period of time,
|
||||
// consider sleeping the AI instead.
|
||||
|
||||
var/process_flags = 0 // Where we're processing, see flag defines.
|
||||
var/list/static/fastprocess_stances = list(
|
||||
STANCE_ALERT,
|
||||
STANCE_APPROACH,
|
||||
STANCE_FIGHT,
|
||||
STANCE_BLINDFIGHT,
|
||||
STANCE_REPOSITION,
|
||||
STANCE_MOVE,
|
||||
STANCE_FOLLOW,
|
||||
STANCE_FLEE
|
||||
)
|
||||
var/list/static/noprocess_stances = list(
|
||||
STANCE_SLEEP
|
||||
)
|
||||
|
||||
|
||||
/datum/ai_holder/hostile
|
||||
@@ -40,16 +61,34 @@
|
||||
/datum/ai_holder/New(var/new_holder)
|
||||
ASSERT(new_holder)
|
||||
holder = new_holder
|
||||
SSai.processing += src
|
||||
home_turf = get_turf(holder)
|
||||
manage_processing(AI_PROCESSING)
|
||||
GLOB.stat_set_event.register(holder, src, .proc/holder_stat_change)
|
||||
..()
|
||||
|
||||
/datum/ai_holder/Destroy()
|
||||
holder = null
|
||||
SSai.processing -= src // We might've already been asleep and removed, but byond won't care if we do this again and it saves a conditional.
|
||||
manage_processing(AI_NO_PROCESS)
|
||||
home_turf = null
|
||||
return ..()
|
||||
|
||||
/datum/ai_holder/proc/manage_processing(var/desired)
|
||||
if(desired & AI_PROCESSING)
|
||||
START_AIPROCESSING(src)
|
||||
else
|
||||
STOP_AIPROCESSING(src)
|
||||
|
||||
if(desired & AI_FASTPROCESSING)
|
||||
START_AIFASTPROCESSING(src)
|
||||
else
|
||||
STOP_AIFASTPROCESSING(src)
|
||||
|
||||
/datum/ai_holder/proc/holder_stat_change(var/mob, old_stat, new_stat)
|
||||
if(old_stat >= DEAD && new_stat <= DEAD) //Revived
|
||||
manage_processing(AI_PROCESSING)
|
||||
else if(old_stat <= DEAD && new_stat >= DEAD) //Killed
|
||||
manage_processing(AI_NO_PROCESS)
|
||||
|
||||
/datum/ai_holder/proc/update_stance_hud()
|
||||
var/image/stanceimage = holder.grab_hud(LIFE_HUD)
|
||||
stanceimage.icon_state = "ais_[stance]"
|
||||
@@ -78,7 +117,6 @@
|
||||
return
|
||||
forget_everything() // If we ever wake up, its really unlikely that our current memory will be of use.
|
||||
set_stance(STANCE_SLEEP)
|
||||
SSai.processing -= src
|
||||
update_paused_hud()
|
||||
|
||||
// Reverses the above proc.
|
||||
@@ -89,7 +127,6 @@
|
||||
if(!should_wake())
|
||||
return
|
||||
set_stance(STANCE_IDLE)
|
||||
SSai.processing += src
|
||||
update_paused_hud()
|
||||
|
||||
/datum/ai_holder/proc/should_wake()
|
||||
@@ -122,12 +159,23 @@
|
||||
|
||||
// For setting the stance WITHOUT processing it
|
||||
/datum/ai_holder/proc/set_stance(var/new_stance)
|
||||
if(stance == new_stance)
|
||||
ai_log("set_stance() : Ignoring change stance to same stance request.", AI_LOG_INFO)
|
||||
return
|
||||
|
||||
ai_log("set_stance() : Setting stance from [stance] to [new_stance].", AI_LOG_INFO)
|
||||
stance = new_stance
|
||||
if(stance_coloring) // For debugging or really weird mobs.
|
||||
stance_color()
|
||||
update_stance_hud()
|
||||
|
||||
if(new_stance in fastprocess_stances) //Becoming fast
|
||||
manage_processing(AI_PROCESSING|AI_FASTPROCESSING)
|
||||
else if(new_stance in noprocess_stances)
|
||||
manage_processing(AI_NO_PROCESS) //Becoming off
|
||||
else
|
||||
manage_processing(AI_PROCESSING) //Becoming slow
|
||||
|
||||
// This is called every half a second.
|
||||
/datum/ai_holder/proc/handle_stance_tactical()
|
||||
ai_log("========= Fast Process Beginning ==========", AI_LOG_TRACE) // This is to make it easier visually to disinguish between 'blocks' of what a tick did.
|
||||
@@ -167,19 +215,6 @@
|
||||
return
|
||||
|
||||
switch(stance)
|
||||
if(STANCE_IDLE)
|
||||
if(should_go_home())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to go home.", AI_LOG_TRACE)
|
||||
go_home()
|
||||
|
||||
else if(should_follow_leader())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to follow leader.", AI_LOG_TRACE)
|
||||
set_stance(STANCE_FOLLOW)
|
||||
|
||||
else if(should_wander())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to wander randomly.", AI_LOG_TRACE)
|
||||
handle_wander_movement()
|
||||
|
||||
if(STANCE_ALERT)
|
||||
ai_log("handle_stance_tactical() : STANCE_ALERT, going to threaten_target().", AI_LOG_TRACE)
|
||||
threaten_target()
|
||||
@@ -241,9 +276,23 @@
|
||||
if(STANCE_IDLE)
|
||||
if(speak_chance) // In the long loop since otherwise it wont shut up.
|
||||
handle_idle_speaking()
|
||||
|
||||
if(hostile)
|
||||
ai_log("handle_stance_strategical() : STANCE_IDLE, going to find_target().", AI_LOG_TRACE)
|
||||
find_target()
|
||||
|
||||
if(should_go_home())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to go home.", AI_LOG_TRACE)
|
||||
go_home()
|
||||
|
||||
else if(should_follow_leader())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to follow leader.", AI_LOG_TRACE)
|
||||
set_stance(STANCE_FOLLOW)
|
||||
|
||||
else if(should_wander())
|
||||
ai_log("handle_stance_tactical() : STANCE_IDLE, going to wander randomly.", AI_LOG_TRACE)
|
||||
handle_wander_movement()
|
||||
|
||||
if(STANCE_APPROACH)
|
||||
if(target)
|
||||
ai_log("handle_stance_strategical() : STANCE_APPROACH, going to calculate_path([target]).", AI_LOG_TRACE)
|
||||
@@ -291,4 +340,7 @@
|
||||
// 'Taunts' the AI into attacking the taunter.
|
||||
/mob/living/proc/taunt(atom/movable/taunter, force_target_switch = FALSE)
|
||||
if(ai_holder)
|
||||
ai_holder.receive_taunt(taunter, force_target_switch)
|
||||
ai_holder.receive_taunt(taunter, force_target_switch)
|
||||
|
||||
#undef AI_PROCESSING
|
||||
#undef AI_FASTPROCESSING
|
||||
@@ -6,7 +6,7 @@
|
||||
// If our holder is able to do anything.
|
||||
/datum/ai_holder/proc/can_act()
|
||||
if(!holder) // Holder missing.
|
||||
SSai.processing -= src
|
||||
manage_processing(AI_NO_PROCESS)
|
||||
return FALSE
|
||||
if(holder.stat) // Dead or unconscious.
|
||||
ai_log("can_act() : Stat was non-zero ([holder.stat]).", AI_LOG_TRACE)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
ai_log("lose_follow() : Exited.", AI_LOG_DEBUG)
|
||||
|
||||
/datum/ai_holder/proc/should_follow_leader()
|
||||
if(!leader)
|
||||
if(!leader || target)
|
||||
return FALSE
|
||||
if(follow_until_time && world.time > follow_until_time)
|
||||
lose_follow()
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
ai_log("walk_to_destination() : Exiting.",AI_LOG_TRACE)
|
||||
|
||||
/datum/ai_holder/proc/should_go_home()
|
||||
if(stance != STANCE_IDLE)
|
||||
return FALSE
|
||||
if(!returns_home || !home_turf)
|
||||
return FALSE
|
||||
if(get_dist(holder, home_turf) > max_home_distance)
|
||||
@@ -139,7 +141,7 @@
|
||||
return MOVEMENT_ON_COOLDOWN
|
||||
|
||||
/datum/ai_holder/proc/should_wander()
|
||||
return wander && !leader
|
||||
return (stance == STANCE_IDLE) && wander && !leader
|
||||
|
||||
// Wanders randomly in cardinal directions.
|
||||
/datum/ai_holder/proc/handle_wander_movement()
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
// Step 1, find out what we can see.
|
||||
/datum/ai_holder/proc/list_targets()
|
||||
. = hearers(vision_range, holder) - holder // Remove ourselves to prevent suicidal decisions. ~ SRC is the ai_holder.
|
||||
. -= dview_mob // Not the dview mob either, nerd.
|
||||
. = ohearers(vision_range, holder)
|
||||
. -= dview_mob // Not the dview mob!
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/blob))
|
||||
|
||||
@@ -43,13 +43,8 @@
|
||||
if(!has_targets_list)
|
||||
possible_targets = list_targets()
|
||||
for(var/possible_target in possible_targets)
|
||||
var/atom/A = possible_target
|
||||
if(found(A)) // In case people want to override this.
|
||||
. = list(A)
|
||||
break
|
||||
if(can_attack(A)) // Can we attack it?
|
||||
. += A
|
||||
continue
|
||||
if(can_attack(possible_target)) // Can we attack it?
|
||||
. += possible_target
|
||||
|
||||
var/new_target = pick_target(.)
|
||||
give_target(new_target)
|
||||
@@ -57,7 +52,7 @@
|
||||
|
||||
// Step 3, pick among the possible, attackable targets.
|
||||
/datum/ai_holder/proc/pick_target(list/targets)
|
||||
if(target != null) // If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets.
|
||||
if(target) // If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets.
|
||||
targets = target_filter_distance(targets)
|
||||
else
|
||||
targets = target_filter_closest(targets)
|
||||
@@ -88,32 +83,31 @@
|
||||
|
||||
// Filters return one or more 'preferred' targets.
|
||||
|
||||
// This one is for closest targets.
|
||||
// This one is for targets closer than our current one.
|
||||
/datum/ai_holder/proc/target_filter_distance(list/targets)
|
||||
var/target_dist = get_dist(holder, target)
|
||||
var/list/better_targets = list()
|
||||
for(var/possible_target in targets)
|
||||
var/atom/A = possible_target
|
||||
var/target_dist = get_dist(holder, target)
|
||||
var/possible_target_distance = get_dist(holder, A)
|
||||
if(target_dist < possible_target_distance)
|
||||
targets -= A
|
||||
return targets
|
||||
if(possible_target_distance < target_dist)
|
||||
better_targets += A
|
||||
return better_targets
|
||||
|
||||
// Returns the closest target and anything tied with it for distance
|
||||
/datum/ai_holder/proc/target_filter_closest(list/targets)
|
||||
var/lowest_distance = -1
|
||||
var/list/sorted_targets = list()
|
||||
var/lowest_distance = 1e6 //fakely far
|
||||
var/list/closest_targets = list()
|
||||
for(var/possible_target in targets)
|
||||
var/atom/A = possible_target
|
||||
var/current_distance = get_dist(holder, A)
|
||||
if(lowest_distance == -1)
|
||||
if(current_distance < lowest_distance)
|
||||
closest_targets.Cut()
|
||||
lowest_distance = current_distance
|
||||
sorted_targets += A
|
||||
else if(current_distance < lowest_distance)
|
||||
targets.Cut()
|
||||
lowest_distance = current_distance
|
||||
sorted_targets += A
|
||||
closest_targets += A
|
||||
else if(current_distance == lowest_distance)
|
||||
sorted_targets += A
|
||||
return sorted_targets
|
||||
closest_targets += A
|
||||
return closest_targets
|
||||
|
||||
/datum/ai_holder/proc/can_attack(atom/movable/the_target, var/vision_required = TRUE)
|
||||
if(!can_see_target(the_target) && vision_required)
|
||||
@@ -163,11 +157,6 @@
|
||||
return TRUE
|
||||
// return FALSE
|
||||
|
||||
// Override this for special targeting criteria.
|
||||
// If it returns true, the mob will always select it as the target.
|
||||
/datum/ai_holder/proc/found(atom/movable/the_target)
|
||||
return FALSE
|
||||
|
||||
// 'Soft' loss of target. They may still exist, we still have some info about them maybe.
|
||||
/datum/ai_holder/proc/lose_target()
|
||||
ai_log("lose_target() : Entering.", AI_LOG_TRACE)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/ai_holder/can_see_target(atom/movable/the_target, view_range = vision_range)
|
||||
if(the_target && isbelly(the_target.loc))
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
@@ -5,7 +5,7 @@
|
||||
var/list/major_alarms = new()
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
for(var/datum/alarm/A in visible_alarms())
|
||||
if(z && (z && !(A.origin?.z in map_levels)))
|
||||
if(z && !(A.origin?.z in map_levels))
|
||||
continue
|
||||
if(A.max_severity() > 1)
|
||||
major_alarms.Add(A)
|
||||
@@ -15,7 +15,7 @@
|
||||
var/list/minor_alarms = new()
|
||||
var/list/map_levels = using_map.get_map_levels(z)
|
||||
for(var/datum/alarm/A in visible_alarms())
|
||||
if(z && (z && !(A.origin?.z in map_levels)))
|
||||
if(z && !(A.origin?.z in map_levels))
|
||||
continue
|
||||
if(A.max_severity() == 1)
|
||||
minor_alarms.Add(A)
|
||||
|
||||
@@ -84,8 +84,8 @@
|
||||
if(a_right)
|
||||
a_right.on_found(finder)
|
||||
|
||||
/obj/item/device/assembly_holder/Move()
|
||||
..()
|
||||
/obj/item/device/assembly_holder/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(a_left && a_right)
|
||||
a_left.holder_movement()
|
||||
a_right.holder_movement()
|
||||
|
||||
@@ -79,8 +79,11 @@
|
||||
|
||||
/obj/item/device/assembly/infra/Move()
|
||||
var/t = dir
|
||||
..()
|
||||
. = ..()
|
||||
set_dir(t)
|
||||
|
||||
/obj/item/device/assembly/infra/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
QDEL_LIST_NULL(i_beams)
|
||||
|
||||
/obj/item/device/assembly/infra/holder_movement()
|
||||
|
||||
@@ -88,8 +88,8 @@
|
||||
var/obj/item/weapon/grenade/chem_grenade/grenade = holder.loc
|
||||
grenade.primed(scanning)
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/Move()
|
||||
..()
|
||||
/obj/item/device/assembly/prox_sensor/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
sense()
|
||||
|
||||
/obj/item/device/assembly/prox_sensor/interact(mob/user as mob)//TODO: Change this to the wires thingy
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
// Collars
|
||||
|
||||
/datum/gear/choker //A colorable choker
|
||||
display_name = "choker (colorable, tagless)"
|
||||
path = /obj/item/clothing/accessory/choker
|
||||
slot = slot_tie
|
||||
sort_category = "Accessories"
|
||||
|
||||
/datum/gear/choker/New()
|
||||
..()
|
||||
gear_tweaks = list(gear_tweak_free_color_choice)
|
||||
|
||||
/datum/gear/collar
|
||||
display_name = "collar, silver"
|
||||
path = /obj/item/clothing/accessory/collar/silver
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Note for newly added fluff items: Ckeys should not contain any spaces, underscores or capitalizations,
|
||||
// or else the item will not be usable.
|
||||
// Example: Someone whose username is "Master Pred_Man" should be written as "masterpredman" instead
|
||||
// Note: Do not use characters such as # in the display_name. It will cause the item to be unable to be selected.
|
||||
|
||||
/datum/gear/fluff
|
||||
path = /obj/item
|
||||
@@ -804,11 +805,18 @@
|
||||
|
||||
/datum/gear/fluff/nthasd_modkit //Converts a Security suit's sprite
|
||||
path = /obj/item/device/modkit_conversion/hasd
|
||||
display_name = "NT-HASD #556's Modkit"
|
||||
display_name = "NT-HASD 556's Modkit"
|
||||
ckeywhitelist = list("silencedmp5a5")
|
||||
character_name = list("NT-HASD #556")
|
||||
allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective")
|
||||
|
||||
/datum/gear/fluff/serdykov_modkit //Also converts a Security suit's sprite
|
||||
path = /obj/item/device/modkit_conversion/fluff/serdykit
|
||||
display_name = "Serdykov Antoz's Modkit"
|
||||
ckeywhitelist = list("silencedmp5a5")
|
||||
character_name = list("Serdykov Antoz")
|
||||
allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective")
|
||||
|
||||
/datum/gear/fluff/tasy_clownuniform
|
||||
path = /obj/item/clothing/under/sexyclown
|
||||
display_name = "Tasy's Clown Uniform"
|
||||
|
||||
@@ -2,6 +2,29 @@
|
||||
// Collars and such like that
|
||||
//
|
||||
|
||||
/obj/item/clothing/accessory/choker //A colorable, tagless choker
|
||||
name = "plain choker"
|
||||
slot_flags = SLOT_TIE | SLOT_OCLOTHING
|
||||
desc = "A simple, plain choker. Or maybe it's a collar? Use in-hand to customize it."
|
||||
icon = 'icons/obj/clothing/ties_vr.dmi'
|
||||
icon_override = 'icons/mob/ties_vr.dmi'
|
||||
icon_state = "choker_cst"
|
||||
item_state = "choker_cst"
|
||||
overlay_state = "choker_cst"
|
||||
var/customized = 0
|
||||
|
||||
/obj/item/clothing/accessory/choker/attack_self(mob/user as mob)
|
||||
if(!customized)
|
||||
var/design = input(user,"Descriptor?","Pick descriptor","") in list("plain","simple","ornate","elegant","opulent")
|
||||
var/material = input(user,"Material?","Pick material","") in list("leather","velvet","lace","fabric","latex","plastic","metal","chain","silver","gold","platinum","steel","bead","ruby","sapphire","emerald","diamond")
|
||||
var/type = input(user,"Type?","Pick type","") in list("choker","collar","necklace")
|
||||
name = "[design] [material] [type]"
|
||||
desc = "A [type], made of [material]. It's rather [design]."
|
||||
customized = 1
|
||||
to_chat(usr,"<span class='notice'>[src] has now been customized.</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='notice'>[src] has already been customized!</span>")
|
||||
|
||||
/obj/item/clothing/accessory/collar
|
||||
slot_flags = SLOT_TIE | SLOT_OCLOTHING
|
||||
icon = 'icons/obj/clothing/ties_vr.dmi'
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
/obj/machinery/honey_extractor
|
||||
name = "honey extractor"
|
||||
desc = "A machine used to turn honeycombs on the frame into honey and wax."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "centrifuge"
|
||||
|
||||
var/processing = 0
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
new /obj/item/weapon/disk/botany(src)
|
||||
|
||||
/obj/machinery/botany
|
||||
icon = 'icons/obj/hydroponics_machines.dmi'
|
||||
icon = 'icons/obj/hydroponics_machines_vr.dmi' //VOREStation Edit
|
||||
icon_state = "hydrotray3"
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/machinery/portable_atmospherics/hydroponics
|
||||
name = "hydroponics tray"
|
||||
icon = 'icons/obj/hydroponics_machines.dmi'
|
||||
icon = 'icons/obj/hydroponics_machines_vr.dmi' //VOREStation Edit
|
||||
icon_state = "hydrotray3"
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
@@ -65,20 +65,19 @@
|
||||
T.reconsider_lights()
|
||||
return ..()
|
||||
|
||||
/atom/movable/Move()
|
||||
var/turf/old_loc = loc
|
||||
/atom/movable/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(loc != old_loc)
|
||||
for(var/datum/light_source/L in light_sources)
|
||||
L.source_atom.update_light()
|
||||
for(var/datum/light_source/L in light_sources)
|
||||
L.source_atom.update_light()
|
||||
|
||||
var/turf/new_loc = loc
|
||||
if(istype(old_loc) && opacity)
|
||||
old_loc.reconsider_lights()
|
||||
var/turf/new_turf = loc
|
||||
var/turf/old_turf = old_loc
|
||||
if(istype(old_turf) && opacity)
|
||||
old_turf.reconsider_lights()
|
||||
|
||||
if(istype(new_loc) && opacity)
|
||||
new_loc.reconsider_lights()
|
||||
if(istype(new_turf) && opacity)
|
||||
new_turf.reconsider_lights()
|
||||
|
||||
/atom/proc/set_opacity(new_opacity)
|
||||
if(new_opacity == opacity)
|
||||
|
||||
@@ -54,13 +54,14 @@
|
||||
master_area = null
|
||||
|
||||
/obj/machinery/media/Move()
|
||||
..()
|
||||
disconnect_media_source()
|
||||
. = ..()
|
||||
if(anchored)
|
||||
update_music()
|
||||
|
||||
/obj/machinery/media/forceMove(var/atom/destination)
|
||||
disconnect_media_source()
|
||||
..()
|
||||
. = ..()
|
||||
if(anchored)
|
||||
update_music()
|
||||
|
||||
|
||||
@@ -10,37 +10,38 @@
|
||||
icon_vend = "exploration-vend" //VOREStation Add
|
||||
//VOREStation Edit Start - Heavily modified list
|
||||
prize_list = list(
|
||||
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1),
|
||||
new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 1),
|
||||
new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 10),
|
||||
new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 30),
|
||||
new /datum/data/mining_equipment("GPS Device", /obj/item/device/gps/explorer, 10),
|
||||
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10),
|
||||
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 10),
|
||||
new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 10),
|
||||
new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 15),
|
||||
new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 20),
|
||||
new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 90),
|
||||
new /datum/data/mining_equipment("Geiger Counter", /obj/item/device/geiger, 75),
|
||||
new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 30),
|
||||
new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon", /obj/item/fulton_core, 300),
|
||||
new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack", /obj/item/extraction_pack, 125),
|
||||
new /datum/data/mining_equipment("Extraction Equipment - Fulton Beacon",/obj/item/fulton_core, 300),
|
||||
new /datum/data/mining_equipment("Extraction Equipment - Fulton Pack",/obj/item/extraction_pack, 125),
|
||||
new /datum/data/mining_equipment("Umbrella", /obj/item/weapon/melee/umbrella/random, 20),
|
||||
new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50),
|
||||
new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 50),
|
||||
new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card/survey, 50),
|
||||
new /datum/data/mining_equipment("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 25),
|
||||
new /datum/data/mining_equipment("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 25),
|
||||
new /datum/data/mining_equipment("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 25),
|
||||
new /datum/data/mining_equipment("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 25),
|
||||
new /datum/data/mining_equipment("Injector (L) - Glucose",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 50),
|
||||
new /datum/data/mining_equipment("Injector (L) - Panacea",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 50),
|
||||
new /datum/data/mining_equipment("Injector (L) - Trauma",/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 50),
|
||||
new /datum/data/mining_equipment("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose,50),
|
||||
new /datum/data/mining_equipment("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity,50),
|
||||
new /datum/data/mining_equipment("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute,50),
|
||||
new /datum/data/mining_equipment("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 50),
|
||||
new /datum/data/mining_equipment("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 100),
|
||||
new /datum/data/mining_equipment("Nanopaste Tube", /obj/item/stack/nanopaste, 100),
|
||||
new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 120),
|
||||
new /datum/data/mining_equipment("UAV - Recon Skimmer", /obj/item/device/uav, 400),
|
||||
new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c100, 100),
|
||||
new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 250),
|
||||
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 310),
|
||||
new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 300),
|
||||
new /datum/data/mining_equipment("Industrial Equipment - Phoron Bore",/obj/item/weapon/gun/magnetic/matfed, 300),
|
||||
new /datum/data/mining_equipment("Survey Tools - Shovel", /obj/item/weapon/shovel, 40),
|
||||
new /datum/data/mining_equipment("Survey Tools - Mechanical Trap", /obj/item/weapon/beartrap, 50),
|
||||
new /datum/data/mining_equipment("Defense Equipment - Smoke Bomb",/obj/item/weapon/grenade/smokebomb, 10),
|
||||
@@ -50,7 +51,7 @@
|
||||
new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 50),
|
||||
new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 100),
|
||||
new /datum/data/mining_equipment("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 750),
|
||||
new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000)
|
||||
new /datum/data/mining_equipment("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 1000)
|
||||
)
|
||||
//VOREStation Edit End
|
||||
|
||||
|
||||
@@ -377,10 +377,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
following = null
|
||||
return ..()
|
||||
|
||||
/mob/Move()
|
||||
/mob/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
update_following()
|
||||
update_following()
|
||||
|
||||
/mob/Life()
|
||||
// to catch teleports etc which directly set loc
|
||||
|
||||
@@ -6,30 +6,28 @@
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
/mob/living/silicon/var/updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Move()
|
||||
var/oldLoc = src.loc
|
||||
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(provides_camera_vision())
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/AI/Move()
|
||||
var/oldLoc = src.loc
|
||||
/mob/living/silicon/ai/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(provides_camera_vision())
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updateVisibility(oldLoc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
updating = 0
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updateVisibility(old_loc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
updating = 0
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
|
||||
|
||||
@@ -4,18 +4,17 @@
|
||||
|
||||
/mob/living/var/updating_cult_vision = 0
|
||||
|
||||
/mob/living/Move()
|
||||
var/oldLoc = src.loc
|
||||
/mob/living/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(cultnet.provides_vision(src))
|
||||
if(!updating_cult_vision)
|
||||
updating_cult_vision = 1
|
||||
spawn(CULT_UPDATE_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cultnet.updateVisibility(oldLoc, 0)
|
||||
cultnet.updateVisibility(loc, 0)
|
||||
updating_cult_vision = 0
|
||||
if(!cultnet.provides_vision(src))
|
||||
return
|
||||
if(!updating_cult_vision)
|
||||
updating_cult_vision = 1
|
||||
spawn(CULT_UPDATE_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cultnet.updateVisibility(old_loc, 0)
|
||||
cultnet.updateVisibility(loc, 0)
|
||||
updating_cult_vision = 0
|
||||
|
||||
#undef CULT_UPDATE_BUFFER
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
return
|
||||
|
||||
if(sleeping || stat == UNCONSCIOUS)
|
||||
hear_sleep(message)
|
||||
hear_sleep(multilingual_to_message(message_pieces))
|
||||
return FALSE
|
||||
|
||||
if(italics)
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
var/message = combine_message(message_pieces, verb, speaker, always_stars = hard_to_hear, radio = TRUE)
|
||||
if(sleeping || stat == UNCONSCIOUS) //If unconscious or sleeping
|
||||
hear_sleep(message)
|
||||
hear_sleep(multilingual_to_message(message_pieces))
|
||||
return
|
||||
|
||||
var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear)
|
||||
|
||||
@@ -33,20 +33,20 @@
|
||||
touching.clear_reagents()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
/* VOREStation Edit - Duplicated in our code
|
||||
/mob/living/carbon/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
|
||||
// Moving around increases germ_level faster
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
|
||||
// Moving around increases germ_level faster
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
/* VOREStation Removal - Needless duplicate feature
|
||||
/mob/living/carbon/relaymove(var/mob/living/user, direction)
|
||||
if((user in src.stomach_contents) && istype(user))
|
||||
if(user.last_special <= world.time)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
message = "lets out a bark."
|
||||
m_type = 2
|
||||
playsound(loc, 'sound/voice/bark2.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises)
|
||||
if ("his")
|
||||
if ("hiss")
|
||||
message = "lets out a hiss."
|
||||
m_type = 2
|
||||
playsound(loc, 'sound/voice/hiss.ogg', 50, 1, -1, preference = /datum/client_preference/emote_noises)
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
BITSET(hud_updateflag, WANTED_HUD)
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/U = usr
|
||||
U.handle_regular_hud_updates()
|
||||
U.handle_hud_list()
|
||||
if(istype(usr,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/U = usr
|
||||
U.handle_regular_hud_updates()
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
|
||||
..()
|
||||
|
||||
if(life_tick%30==15)
|
||||
hud_updateflag = 1022
|
||||
if(life_tick % 30)
|
||||
hud_updateflag = (1 << TOTAL_HUDS) - 1
|
||||
|
||||
voice = GetVoice()
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
else if(stat == DEAD && !stasis)
|
||||
handle_defib_timer()
|
||||
|
||||
if(!handle_some_updates())
|
||||
if(skip_some_updates())
|
||||
return //We go ahead and process them 5 times for HUD images and other stuff though.
|
||||
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
@@ -99,10 +99,10 @@
|
||||
|
||||
pulse = handle_pulse()
|
||||
|
||||
/mob/living/carbon/human/proc/handle_some_updates()
|
||||
/mob/living/carbon/human/proc/skip_some_updates()
|
||||
if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle
|
||||
return 0
|
||||
return 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/breathe()
|
||||
if(!inStasisNow())
|
||||
@@ -951,7 +951,7 @@
|
||||
|
||||
//DO NOT CALL handle_statuses() from this proc, it's called from living/Life() as long as this returns a true value.
|
||||
/mob/living/carbon/human/handle_regular_status_updates()
|
||||
if(!handle_some_updates())
|
||||
if(skip_some_updates())
|
||||
return 0
|
||||
|
||||
if(status_flags & GODMODE) return 0
|
||||
@@ -1292,8 +1292,11 @@
|
||||
else
|
||||
bodytemp.icon_state = "temp0"
|
||||
|
||||
if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
else clear_fullscreens()
|
||||
if(blinded)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
|
||||
else if(!machine)
|
||||
clear_fullscreens()
|
||||
|
||||
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
|
||||
if(glasses) //to every /obj/item
|
||||
@@ -1395,11 +1398,12 @@
|
||||
|
||||
if(machine)
|
||||
var/viewflags = machine.check_eye(src)
|
||||
machine.apply_visual(src)
|
||||
if(viewflags < 0)
|
||||
reset_view(null, 0)
|
||||
else if(viewflags && !looking_elsewhere)
|
||||
sight |= viewflags
|
||||
else
|
||||
machine.apply_visual(src)
|
||||
else if(eyeobj)
|
||||
if(eyeobj.owner != src)
|
||||
|
||||
|
||||
@@ -58,22 +58,21 @@
|
||||
nif.life()
|
||||
|
||||
//Overriding carbon move proc that forces default hunger factor
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
/mob/living/carbon/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/M = src
|
||||
if(M.stat != 2 && M.nutrition > 0)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/M = src
|
||||
if(M.stat != 2 && M.nutrition > 0)
|
||||
M.nutrition -= M.species.hunger_factor/10
|
||||
if(M.m_intent == "run")
|
||||
M.nutrition -= M.species.hunger_factor/10
|
||||
if(M.m_intent == "run")
|
||||
M.nutrition -= M.species.hunger_factor/10
|
||||
if(M.nutrition < 0)
|
||||
M.nutrition = 0
|
||||
else
|
||||
if(M.nutrition < 0)
|
||||
M.nutrition = 0
|
||||
else
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= DEFAULT_HUNGER_FACTOR/10
|
||||
// Moving around increases germ_level faster
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
// Moving around increases germ_level faster
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
@@ -173,13 +173,11 @@
|
||||
if(ear_damage < 100)
|
||||
adjustEarDamage(-0.05,-1)
|
||||
|
||||
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
||||
/mob/living/handle_regular_hud_updates()
|
||||
if(!client)
|
||||
return 0
|
||||
..()
|
||||
|
||||
handle_vision()
|
||||
handle_darksight()
|
||||
handle_hud_icons()
|
||||
|
||||
|
||||
@@ -33,52 +33,52 @@
|
||||
if (cell_use_power(A.active_usage))
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/Move(a, b, flag)
|
||||
|
||||
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(module)
|
||||
if(module.type == /obj/item/weapon/robot_module/robot/janitor)
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
tile.clean_blood()
|
||||
if (istype(tile, /turf/simulated))
|
||||
var/turf/simulated/S = tile
|
||||
S.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A, /obj/effect))
|
||||
if(istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay))
|
||||
qdel(A)
|
||||
else if(istype(A, /obj/item))
|
||||
var/obj/item/cleaned_item = A
|
||||
cleaned_item.clean_blood()
|
||||
else if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head(0)
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit(0)
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform(0)
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes(0)
|
||||
cleaned_human.clean_blood(1)
|
||||
cleaned_human << "<font color='red'>[src] cleans your face!</font>"
|
||||
if(!module)
|
||||
return
|
||||
|
||||
if((module_state_1 && istype(module_state_1, /obj/item/weapon/storage/bag/ore)) || (module_state_2 && istype(module_state_2, /obj/item/weapon/storage/bag/ore)) || (module_state_3 && istype(module_state_3, /obj/item/weapon/storage/bag/ore))) //Borgs and drones can use their mining bags ~automagically~ if they're deployed in a slot. Only mining bags, as they're optimized for mass use.
|
||||
var/obj/item/weapon/storage/bag/ore/B = null
|
||||
if(istype(module_state_1, /obj/item/weapon/storage/bag/ore)) //First orebag has priority, if they for some reason have multiple.
|
||||
B = module_state_1
|
||||
else if(istype(module_state_2, /obj/item/weapon/storage/bag/ore))
|
||||
B = module_state_2
|
||||
else if(istype(module_state_3, /obj/item/weapon/storage/bag/ore))
|
||||
B = module_state_3
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
B.gather_all(tile, src, 1) //Shhh, unless the bag fills, don't spam the borg's chat with stuff that's going on every time they move!
|
||||
return
|
||||
//Borgs and drones can use their mining bags ~automagically~ if they're deployed in a slot. Only mining bags, as they're optimized for mass use.
|
||||
if(istype(module_state_1, /obj/item/weapon/storage/bag/ore) || istype(module_state_2, /obj/item/weapon/storage/bag/ore) || istype(module_state_3, /obj/item/weapon/storage/bag/ore))
|
||||
var/obj/item/weapon/storage/bag/ore/B = null
|
||||
if(istype(module_state_1, /obj/item/weapon/storage/bag/ore)) //First orebag has priority, if they for some reason have multiple.
|
||||
B = module_state_1
|
||||
else if(istype(module_state_2, /obj/item/weapon/storage/bag/ore))
|
||||
B = module_state_2
|
||||
else if(istype(module_state_3, /obj/item/weapon/storage/bag/ore))
|
||||
B = module_state_3
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
B.gather_all(tile, src, 1) //Shhh, unless the bag fills, don't spam the borg's chat with stuff that's going on every time they move!
|
||||
|
||||
if(istype(module, /obj/item/weapon/robot_module/robot/janitor) && isturf(loc))
|
||||
var/turf/tile = loc
|
||||
tile.clean_blood()
|
||||
if (istype(tile, /turf/simulated))
|
||||
var/turf/simulated/S = tile
|
||||
S.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A, /obj/effect))
|
||||
if(istype(A, /obj/effect/rune) || istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/overlay))
|
||||
qdel(A)
|
||||
else if(istype(A, /obj/item))
|
||||
var/obj/item/cleaned_item = A
|
||||
cleaned_item.clean_blood()
|
||||
else if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head(0)
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit(0)
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform(0)
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes(0)
|
||||
cleaned_human.clean_blood(1)
|
||||
cleaned_human << "<font color='red'>[src] cleans your face!</font>"
|
||||
@@ -109,39 +109,35 @@
|
||||
icon_state = "[module_sprites[icontype]]-wreck"
|
||||
add_overlay("wreck-overlay")
|
||||
|
||||
/mob/living/silicon/robot/Move(a, b, flag)
|
||||
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(scrubbing)
|
||||
var/datum/matter_synth/water = water_res
|
||||
if(water && water.energy >= 1)
|
||||
var/turf/tile = loc
|
||||
if(isturf(tile))
|
||||
water.use_charge(1)
|
||||
tile.clean_blood()
|
||||
if(istype(tile, /turf/simulated))
|
||||
var/turf/simulated/T = tile
|
||||
T.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A,/obj/effect/rune) || istype(A,/obj/effect/decal/cleanable) || istype(A,/obj/effect/overlay))
|
||||
qdel(A)
|
||||
else if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head(0)
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit(0)
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform(0)
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes(0)
|
||||
cleaned_human.clean_blood(1)
|
||||
to_chat(cleaned_human, "<span class='warning'>[src] cleans your face!</span>")
|
||||
return
|
||||
if(scrubbing && isturf(loc) && water_res?.energy >= 1)
|
||||
var/turf/tile = loc
|
||||
water_res.use_charge(1)
|
||||
tile.clean_blood()
|
||||
if(istype(tile, /turf/simulated))
|
||||
var/turf/simulated/T = tile
|
||||
T.dirt = 0
|
||||
for(var/A in tile)
|
||||
if(istype(A,/obj/effect/rune) || istype(A,/obj/effect/decal/cleanable) || istype(A,/obj/effect/overlay))
|
||||
qdel(A)
|
||||
else if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/cleaned_human = A
|
||||
if(cleaned_human.lying)
|
||||
if(cleaned_human.head)
|
||||
cleaned_human.head.clean_blood()
|
||||
cleaned_human.update_inv_head(0)
|
||||
if(cleaned_human.wear_suit)
|
||||
cleaned_human.wear_suit.clean_blood()
|
||||
cleaned_human.update_inv_wear_suit(0)
|
||||
else if(cleaned_human.w_uniform)
|
||||
cleaned_human.w_uniform.clean_blood()
|
||||
cleaned_human.update_inv_w_uniform(0)
|
||||
if(cleaned_human.shoes)
|
||||
cleaned_human.shoes.clean_blood()
|
||||
cleaned_human.update_inv_shoes(0)
|
||||
cleaned_human.clean_blood(1)
|
||||
to_chat(cleaned_human, "<span class='warning'>[src] cleans your face!</span>")
|
||||
|
||||
/mob/living/silicon/robot/proc/vr_sprite_check()
|
||||
if(wideborg == TRUE)
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
var/step = get_step_to(src, food, 0)
|
||||
Move(step)
|
||||
|
||||
/mob/living/simple_mob/animal/goat/Move()
|
||||
..()
|
||||
/mob/living/simple_mob/animal/goat/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!stat)
|
||||
for(var/obj/effect/plant/SV in loc)
|
||||
SV.die_off(1)
|
||||
|
||||
@@ -256,14 +256,10 @@
|
||||
|
||||
for(var/possible_target in possible_targets)
|
||||
var/atom/A = possible_target
|
||||
if(found(A))
|
||||
. = list(A)
|
||||
break
|
||||
if(istype(A, /mob/living) && !can_pick_mobs)
|
||||
continue
|
||||
if(can_attack(A)) // Can we attack it?
|
||||
. += A
|
||||
continue
|
||||
|
||||
for(var/obj/item/I in .)
|
||||
last_search = world.time
|
||||
|
||||
@@ -196,29 +196,15 @@
|
||||
next = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/animal/space/space_worm/Move()
|
||||
var/attachementNextPosition = loc
|
||||
/mob/living/simple_mob/animal/space/space_worm/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(previous)
|
||||
if(previous.z != z)
|
||||
previous.z_transitioning = TRUE
|
||||
else
|
||||
previous.z_transitioning = FALSE
|
||||
previous.forceMove(attachementNextPosition) // None of this 'ripped in half by an airlock' business.
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_mob/animal/space/space_worm/forceMove()
|
||||
var/attachementNextPosition = loc
|
||||
. = ..()
|
||||
if(.)
|
||||
if(previous)
|
||||
if(previous.z != z)
|
||||
previous.z_transitioning = TRUE
|
||||
else
|
||||
previous.z_transitioning = FALSE
|
||||
previous.forceMove(attachementNextPosition) // None of this 'ripped in half by an airlock' business. x 2
|
||||
update_icon()
|
||||
if(previous)
|
||||
if(previous.z != z)
|
||||
previous.z_transitioning = TRUE
|
||||
else
|
||||
previous.z_transitioning = FALSE
|
||||
previous.forceMove(old_loc) // None of this 'ripped in half by an airlock' business.
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_mob/animal/space/space_worm/head/Bump(atom/obstacle)
|
||||
if(open_maw && !stat && obstacle != previous)
|
||||
|
||||
@@ -110,8 +110,8 @@
|
||||
|
||||
|
||||
/client/Move(n, direct)
|
||||
if(!mob)
|
||||
return // Moved here to avoid nullrefs below
|
||||
//if(!mob) // Clients cannot have a null mob, as enforced by byond
|
||||
// return // Moved here to avoid nullrefs below
|
||||
|
||||
if(mob.control_object) Move_object(direct)
|
||||
|
||||
@@ -166,8 +166,11 @@
|
||||
if(!mob.canmove)
|
||||
return
|
||||
|
||||
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
||||
// if(!mob.Process_Spacemove(0)) return 0
|
||||
//Relaymove could handle it
|
||||
if(mob.machine)
|
||||
var/result = mob.machine.relaymove(mob, direct)
|
||||
if(result)
|
||||
return result
|
||||
|
||||
if(!mob.lastarea)
|
||||
mob.lastarea = get_area(mob.loc)
|
||||
@@ -218,10 +221,6 @@
|
||||
return
|
||||
return mob.buckled.relaymove(mob,direct)
|
||||
|
||||
if(istype(mob.machine, /obj/machinery))
|
||||
if(mob.machine.relaymove(mob,direct))
|
||||
return
|
||||
|
||||
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
||||
if(istype(mob.loc, /turf/space))
|
||||
return // No wheelchair driving in space
|
||||
@@ -366,17 +365,7 @@
|
||||
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
mob.forceMove(get_step(mob, direct))
|
||||
mob.dir = direct
|
||||
// Crossed is always a bit iffy
|
||||
for(var/obj/S in mob.loc)
|
||||
if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam))
|
||||
S.Crossed(mob)
|
||||
|
||||
var/area/A = get_area_master(mob)
|
||||
if(A)
|
||||
A.Entered(mob)
|
||||
if(isturf(mob.loc))
|
||||
var/turf/T = mob.loc
|
||||
T.Entered(mob)
|
||||
mob.Post_Incorpmove()
|
||||
return 1
|
||||
|
||||
@@ -468,16 +457,11 @@
|
||||
|
||||
/mob/proc/update_gravity()
|
||||
return
|
||||
/*
|
||||
// The real Move() proc is above, but touching that massive block just to put this in isn't worth it.
|
||||
/mob/Move(var/newloc, var/direct)
|
||||
. = ..(newloc, direct)
|
||||
if(.)
|
||||
post_move(newloc, direct)
|
||||
*/
|
||||
|
||||
// Called when a mob successfully moves.
|
||||
// Would've been an /atom/movable proc but it caused issues.
|
||||
/mob/Moved(atom/oldloc)
|
||||
. = ..()
|
||||
for(var/obj/O in contents)
|
||||
O.on_loc_moved(oldloc)
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@
|
||||
|
||||
var/turf/T = join_props["turf"]
|
||||
var/join_message = join_props["msg"]
|
||||
var/announce_channel = join_props["channel"] || "Common" // VOREStation Add
|
||||
var/announce_channel = join_props["channel"] || "Common"
|
||||
|
||||
if(!T || !join_message)
|
||||
return 0
|
||||
|
||||
@@ -255,6 +255,18 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/modular_computer/apply_visual(var/mob/user)
|
||||
if(active_program)
|
||||
return active_program.apply_visual(user)
|
||||
|
||||
/obj/item/modular_computer/remove_visual(var/mob/user)
|
||||
if(active_program)
|
||||
return active_program.remove_visual(user)
|
||||
|
||||
/obj/item/modular_computer/relaymove(var/mob/user, direction)
|
||||
if(active_program)
|
||||
return active_program.relaymove(user, direction)
|
||||
|
||||
/obj/item/modular_computer/proc/set_autorun(program)
|
||||
if(!hard_drive)
|
||||
return
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
hard_drive.store_file(new/datum/computer_file/program/atmos_control())
|
||||
hard_drive.store_file(new/datum/computer_file/program/rcon_console())
|
||||
hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
|
||||
hard_drive.store_file(new/datum/computer_file/program/shutoff_monitor())
|
||||
|
||||
// Medical
|
||||
/obj/item/modular_computer/console/preset/medical/install_default_programs()
|
||||
|
||||
@@ -203,8 +203,12 @@
|
||||
|
||||
/datum/computer_file/program/apply_visual(mob/M)
|
||||
if(NM)
|
||||
NM.apply_visual(M)
|
||||
return NM.apply_visual(M)
|
||||
|
||||
/datum/computer_file/program/remove_visual(mob/M)
|
||||
if(NM)
|
||||
NM.remove_visual(M)
|
||||
return NM.remove_visual(M)
|
||||
|
||||
/datum/computer_file/program/proc/relaymove(var/mob/M, direction)
|
||||
if(NM)
|
||||
return NM.relaymove(M, direction)
|
||||
@@ -0,0 +1,63 @@
|
||||
/datum/computer_file/program/shutoff_monitor
|
||||
filename = "shutoffmonitor"
|
||||
filedesc = "Shutoff Valve Monitoring"
|
||||
nanomodule_path = /datum/nano_module/shutoff_monitor
|
||||
program_icon_state = "atmos_control"
|
||||
program_key_state = "atmos_key"
|
||||
program_menu_icon = "wrench"
|
||||
extended_desc = "This program allows for remote monitoring and control of emergency shutoff valves."
|
||||
required_access = access_engine
|
||||
requires_ntnet = 1
|
||||
network_destination = "shutoff valve control computer"
|
||||
size = 5
|
||||
var/has_alert = 0
|
||||
|
||||
/datum/nano_module/shutoff_monitor
|
||||
name = "Shutoff Valve Monitoring"
|
||||
|
||||
/datum/nano_module/shutoff_monitor/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_enable"])
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_enable"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
S.close_on_leaks = !S.close_on_leaks
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_open"])
|
||||
var/obj/machinery/atmospherics/valve/shutoff/S = locate(href_list["toggle_open"])
|
||||
if(!istype(S))
|
||||
return 0
|
||||
if(S.open)
|
||||
S.close()
|
||||
else
|
||||
S.open()
|
||||
return 1
|
||||
|
||||
/datum/nano_module/shutoff_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
var/list/valves = list()
|
||||
|
||||
for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
|
||||
valves.Add(list(list(
|
||||
"name" = S.name,
|
||||
"enabled" = S.close_on_leaks,
|
||||
"open" = S.open,
|
||||
"x" = S.x,
|
||||
"y" = S.y,
|
||||
"z" = S.z,
|
||||
"ref" = "\ref[S]"
|
||||
)))
|
||||
|
||||
data["valves"] = valves
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Shutoff Valve Monitoring", 627, 700, state = state)
|
||||
if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -0,0 +1,266 @@
|
||||
/obj/item/modular_computer
|
||||
var/list/paired_uavs //Weakrefs, don't worry about it!
|
||||
|
||||
/datum/computer_file/program/uav
|
||||
filename = "rigger"
|
||||
filedesc = "UAV Control"
|
||||
nanomodule_path = /datum/nano_module/uav
|
||||
program_icon_state = "comm_monitor"
|
||||
program_key_state = "generic_key"
|
||||
program_menu_icon = "link"
|
||||
extended_desc = "This program allows remote control of certain drones, but only when paired with this device."
|
||||
size = 12
|
||||
available_on_ntnet = 1
|
||||
//requires_ntnet = 1
|
||||
|
||||
/datum/nano_module/uav
|
||||
name = "UAV Control program"
|
||||
var/obj/item/device/uav/current_uav = null //The UAV we're watching
|
||||
var/signal_strength = 0 //Our last signal strength report (cached for a few seconds)
|
||||
var/signal_test_counter = 0 //How long until next signal strength check
|
||||
var/list/viewers //Who's viewing a UAV through us
|
||||
var/adhoc_range = 30 //How far we can operate on a UAV without NTnet
|
||||
|
||||
/datum/nano_module/uav/Destroy()
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
. = ..()
|
||||
|
||||
/datum/nano_module/uav/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state)
|
||||
var/list/data = host.initial_data()
|
||||
|
||||
if(current_uav)
|
||||
if(QDELETED(current_uav))
|
||||
set_current(null)
|
||||
else if(signal_test_counter-- <= 0)
|
||||
signal_strength = get_signal_to(current_uav)
|
||||
if(!signal_strength)
|
||||
set_current(null)
|
||||
else // Don't reset counter until we find a UAV that's actually in range we can stay connected to
|
||||
signal_test_counter = 20
|
||||
|
||||
data["current_uav"] = null
|
||||
if(current_uav)
|
||||
data["current_uav"] = list("status" = current_uav.get_status_string(), "power" = current_uav.state == 1 ? 1 : null)
|
||||
data["signal_strength"] = signal_strength ? signal_strength >= 2 ? "High" : "Low" : "None"
|
||||
data["in_use"] = LAZYLEN(viewers)
|
||||
|
||||
var/list/paired_map = list()
|
||||
var/obj/item/modular_computer/mc_host = nano_host()
|
||||
if(istype(mc_host))
|
||||
for(var/puav in mc_host.paired_uavs)
|
||||
var/weakref/wr = puav
|
||||
var/obj/item/device/uav/U = wr.resolve()
|
||||
paired_map[++paired_map.len] = list("name" = "[U ? U.nickname : "!!Missing!!"]", "uavref" = "\ref[U]")
|
||||
|
||||
data["paired_uavs"] = paired_map
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "mod_uav.tmpl", "UAV Control", 600, 500, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/uav/Topic(var/href, var/href_list = list(), var/datum/topic_state/state)
|
||||
if((. = ..()))
|
||||
return
|
||||
state = state || DefaultTopicState() || global.default_state
|
||||
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
|
||||
CouldUseTopic(usr)
|
||||
return OnTopic(usr, href_list, state)
|
||||
CouldNotUseTopic(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/nano_module/uav/proc/OnTopic(var/mob/user, var/list/href_list)
|
||||
if(href_list["switch_uav"])
|
||||
var/obj/item/device/uav/U = locate(href_list["switch_uav"]) //This is a \ref to the UAV itself
|
||||
if(!istype(U))
|
||||
to_chat(usr,"<span class='warning'>Something is blocking the connection to that UAV. In-person investigation is required.</span>")
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if(!get_signal_to(U))
|
||||
to_chat(usr,"<span class='warning'>The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.</span>")
|
||||
return TOPIC_NOACTION
|
||||
|
||||
set_current(U)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["del_uav"])
|
||||
var/refstring = href_list["del_uav"] //This is a \ref to the UAV itself
|
||||
var/obj/item/modular_computer/mc_host = nano_host()
|
||||
//This is so we can really scrape up any weakrefs that can't resolve
|
||||
for(var/weakref/wr in mc_host.paired_uavs)
|
||||
if(wr.ref == refstring)
|
||||
if(current_uav?.weakref == wr)
|
||||
set_current(null)
|
||||
LAZYREMOVE(mc_host.paired_uavs, wr)
|
||||
|
||||
else if(href_list["view_uav"])
|
||||
if(!current_uav)
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if(current_uav.check_eye(user) < 0)
|
||||
to_chat(usr,"<span class='warning'>The screen freezes for a moment, before returning to the UAV selection menu. It's not able to connect to that UAV.</span>")
|
||||
else
|
||||
viewing_uav(user) ? unlook(user) : look(user)
|
||||
return TOPIC_NOACTION
|
||||
|
||||
else if(href_list["power_uav"])
|
||||
if(!current_uav)
|
||||
return TOPIC_NOACTION
|
||||
else if(current_uav.toggle_power())
|
||||
//Clean up viewers faster
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
/datum/nano_module/uav/proc/DefaultTopicState()
|
||||
return global.default_state
|
||||
|
||||
/datum/nano_module/uav/proc/CouldNotUseTopic(mob/user)
|
||||
. = ..()
|
||||
unlook(user)
|
||||
|
||||
/datum/nano_module/uav/proc/CouldUseTopic(mob/user)
|
||||
. = ..()
|
||||
if(viewing_uav(user))
|
||||
look(user)
|
||||
|
||||
/datum/nano_module/uav/proc/set_current(var/obj/item/device/uav/U)
|
||||
if(current_uav == U)
|
||||
return
|
||||
|
||||
signal_strength = 0
|
||||
current_uav = U
|
||||
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
if(current_uav)
|
||||
to_chat(M, "<span class='warning'>You're disconnected from the UAV's camera!</span>")
|
||||
unlook(M)
|
||||
else
|
||||
look(M)
|
||||
|
||||
////
|
||||
//// Finding signal strength between us and the UAV
|
||||
////
|
||||
/datum/nano_module/uav/proc/get_signal_to(var/atom/movable/AM)
|
||||
// Following roughly the ntnet signal levels
|
||||
// 0 is none
|
||||
// 1 is weak
|
||||
// 2 is strong
|
||||
var/obj/item/modular_computer/host = nano_host() //Better not add this to anything other than modular computers.
|
||||
if(!istype(host))
|
||||
return
|
||||
var/our_signal = host.get_ntnet_status() //1 low, 2 good, 3 wired, 0 none
|
||||
var/their_z = get_z(AM)
|
||||
|
||||
//If we have no NTnet connection don't bother getting theirs
|
||||
if(!our_signal)
|
||||
if(get_z(host) == their_z && (get_dist(host, AM) < adhoc_range))
|
||||
return 1 //We can connect (with weak signal) in same z without ntnet, within 30 turfs
|
||||
else
|
||||
return 0
|
||||
|
||||
var/list/zlevels_in_range = using_map.get_map_levels(their_z, FALSE)
|
||||
var/list/zlevels_in_long_range = using_map.get_map_levels(their_z, TRUE) - zlevels_in_range
|
||||
var/their_signal = 0
|
||||
for(var/relay in ntnet_global.relays)
|
||||
var/obj/machinery/ntnet_relay/R = relay
|
||||
if(!R.operable())
|
||||
continue
|
||||
if(R.z == their_z)
|
||||
their_signal = 2
|
||||
break
|
||||
if(R.z in zlevels_in_range)
|
||||
their_signal = 2
|
||||
break
|
||||
if(R.z in zlevels_in_long_range)
|
||||
their_signal = 1
|
||||
break
|
||||
|
||||
if(!their_signal) //They have no NTnet at all
|
||||
if(get_z(host) == their_z && (get_dist(host, AM) < adhoc_range))
|
||||
return 1 //We can connect (with weak signal) in same z without ntnet, within 30 turfs
|
||||
else
|
||||
return 0
|
||||
else
|
||||
return max(our_signal, their_signal)
|
||||
|
||||
////
|
||||
//// UAV viewer handling
|
||||
////
|
||||
/datum/nano_module/uav/proc/viewing_uav(mob/user)
|
||||
return (weakref(user) in viewers)
|
||||
|
||||
/datum/nano_module/uav/proc/look(var/mob/user)
|
||||
if(issilicon(user)) //Too complicated for me to want to mess with at the moment
|
||||
to_chat(user, "<span class='warning'>Regulations prevent you from controlling several corporeal forms at the same time!</span>")
|
||||
return
|
||||
|
||||
if(!current_uav)
|
||||
return
|
||||
|
||||
user.set_machine(nano_host())
|
||||
user.reset_view(current_uav)
|
||||
current_uav.add_master(user)
|
||||
LAZYDISTINCTADD(viewers, weakref(user))
|
||||
|
||||
/datum/nano_module/uav/proc/unlook(var/mob/user)
|
||||
user.unset_machine()
|
||||
user.reset_view()
|
||||
if(current_uav)
|
||||
current_uav.remove_master(user)
|
||||
LAZYREMOVE(viewers, weakref(user))
|
||||
|
||||
/datum/nano_module/uav/check_eye(var/mob/user)
|
||||
if(get_dist(user, nano_host()) > 1 || user.blinded || !current_uav)
|
||||
unlook(user)
|
||||
return -1
|
||||
|
||||
var/viewflag = current_uav.check_eye(user)
|
||||
if (viewflag < 0) //camera doesn't work
|
||||
unlook(user)
|
||||
return -1
|
||||
|
||||
return viewflag
|
||||
|
||||
////
|
||||
//// Relaying movements to the UAV
|
||||
////
|
||||
/datum/nano_module/uav/relaymove(var/mob/user, direction)
|
||||
if(current_uav)
|
||||
return current_uav.relaymove(user, direction, signal_strength)
|
||||
|
||||
////
|
||||
//// The effects when looking through a UAV
|
||||
////
|
||||
/datum/nano_module/uav/apply_visual(var/mob/M)
|
||||
if(!M.client)
|
||||
return
|
||||
if(weakref(M) in viewers)
|
||||
M.overlay_fullscreen("fishbed",/obj/screen/fullscreen/fishbed)
|
||||
M.overlay_fullscreen("scanlines",/obj/screen/fullscreen/scanline)
|
||||
|
||||
if(signal_strength <= 1)
|
||||
M.overlay_fullscreen("whitenoise",/obj/screen/fullscreen/noise)
|
||||
else
|
||||
M.clear_fullscreen("whitenoise", 0)
|
||||
else
|
||||
remove_visual(M)
|
||||
|
||||
/datum/nano_module/uav/remove_visual(mob/M)
|
||||
if(!M.client)
|
||||
return
|
||||
M.clear_fullscreen("fishbed",0)
|
||||
M.clear_fullscreen("scanlines",0)
|
||||
M.clear_fullscreen("whitenoise",0)
|
||||
@@ -46,7 +46,7 @@
|
||||
to_chat(user, "<span class='warning'>The crew monitor doesn't seem like it'll work here.</span>")
|
||||
if(program)
|
||||
program.kill_program()
|
||||
else if(ui)
|
||||
if(ui)
|
||||
ui.close()
|
||||
return
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
nanomodule_path = /datum/nano_module/program/ship/nav
|
||||
program_icon_state = "helm"
|
||||
program_key_state = "generic_key"
|
||||
program_menu_icon = "search"
|
||||
program_menu_icon = "pin-s"
|
||||
extended_desc = "Displays a ship's location in the sector."
|
||||
required_access = null
|
||||
requires_ntnet = 1
|
||||
|
||||
@@ -39,6 +39,27 @@ var/global/ntnet_card_uid = 1
|
||||
icon_state = "netcard_advanced"
|
||||
hardware_size = 1
|
||||
|
||||
/obj/item/weapon/computer_hardware/network_card/quantum
|
||||
name = "quantum NTNet network card"
|
||||
desc = "A network card that can connect to NTnet from anywhere, using quantum entanglement."
|
||||
long_range = 1
|
||||
origin_tech = list(TECH_DATA = 6, TECH_ENGINEERING = 7)
|
||||
power_usage = 200 // Infinite range but higher power usage.
|
||||
icon_state = "netcard_advanced"
|
||||
hardware_size = 1
|
||||
|
||||
/obj/item/weapon/computer_hardware/network_card/quantum/get_signal(var/specific_action = 0)
|
||||
if(!holder2)
|
||||
return 0
|
||||
|
||||
if(!enabled)
|
||||
return 0
|
||||
|
||||
if(!check_functionality() || !ntnet_global || is_banned())
|
||||
return 0
|
||||
|
||||
return 2
|
||||
|
||||
/obj/item/weapon/computer_hardware/network_card/wired
|
||||
name = "wired NTNet network card"
|
||||
desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection."
|
||||
@@ -82,7 +103,8 @@ var/global/ntnet_card_uid = 1
|
||||
var/holderz = get_z(holder2)
|
||||
if(!holderz) //no reception in nullspace
|
||||
return 0
|
||||
var/list/zlevels_in_range = using_map.get_map_levels(holderz, long_range)
|
||||
var/list/zlevels_in_range = using_map.get_map_levels(holderz, FALSE)
|
||||
var/list/zlevels_in_long_range = using_map.get_map_levels(holderz, TRUE) - zlevels_in_range
|
||||
var/best = 0
|
||||
for(var/relay in ntnet_global.relays)
|
||||
var/obj/machinery/ntnet_relay/R = relay
|
||||
@@ -91,11 +113,16 @@ var/global/ntnet_card_uid = 1
|
||||
continue
|
||||
//We're on the same z
|
||||
if(R.z == holderz)
|
||||
best = 2
|
||||
best = 2 //Every network card gets high signal on the same z as the relay
|
||||
break // No point in going further
|
||||
//Not on the same z but within range anyway
|
||||
if(R.z in zlevels_in_range)
|
||||
best = 1
|
||||
best = long_range ? 2 : 1 //High-power network cards get good signal further away
|
||||
break
|
||||
//Only in long range
|
||||
if(long_range && (R.z in zlevels_in_long_range))
|
||||
best = 1 //High-power network cards can get low signal even at long range
|
||||
break
|
||||
return best
|
||||
return 0 // No computer!
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
if(shadow)
|
||||
shadow.sync_icon(src)
|
||||
|
||||
/mob/living/Move()
|
||||
/mob/living/Moved()
|
||||
. = ..()
|
||||
check_shadow()
|
||||
|
||||
|
||||
@@ -62,3 +62,6 @@
|
||||
|
||||
/datum/proc/update_layout()
|
||||
return FALSE
|
||||
|
||||
/datum/nano_module/proc/relaymove(var/mob/user, direction)
|
||||
return FALSE
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
)
|
||||
|
||||
// make a screeching noise to drive people mad
|
||||
/obj/structure/ship_munition/disperser_charge/Move(atom/newloc, direct = 0)
|
||||
if((. = ..()) && prob(50))
|
||||
/obj/structure/ship_munition/disperser_charge/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(prob(50))
|
||||
var/turf/T = get_turf(src)
|
||||
if(!isspace(T) && !istype(T, /turf/simulated/floor/carpet))
|
||||
playsound(T, pick(move_sounds), 50, 1)
|
||||
|
||||
|
||||
/obj/structure/ship_munition/disperser_charge/fire
|
||||
name = "FR1-ENFER charge"
|
||||
color = "#b95a00"
|
||||
|
||||
@@ -19,19 +19,10 @@
|
||||
icon_state = pick(event_icon_states)
|
||||
GLOB.overmap_event_handler.update_hazards(loc)
|
||||
|
||||
/obj/effect/overmap/event/Move()
|
||||
var/turf/old_loc = loc
|
||||
/obj/effect/overmap/event/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
GLOB.overmap_event_handler.update_hazards(old_loc)
|
||||
GLOB.overmap_event_handler.update_hazards(loc)
|
||||
|
||||
/obj/effect/overmap/event/forceMove(atom/destination)
|
||||
var/old_loc = loc
|
||||
. = ..()
|
||||
if(.)
|
||||
GLOB.overmap_event_handler.update_hazards(old_loc)
|
||||
GLOB.overmap_event_handler.update_hazards(loc)
|
||||
GLOB.overmap_event_handler.update_hazards(old_loc)
|
||||
GLOB.overmap_event_handler.update_hazards(loc)
|
||||
|
||||
/obj/effect/overmap/event/Destroy()//takes a look at this one as well, make sure everything is A-OK
|
||||
var/turf/T = loc
|
||||
|
||||
@@ -556,6 +556,11 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
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>")
|
||||
|
||||
@@ -48,7 +48,7 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
return "off"
|
||||
|
||||
// You aren't allowed to move.
|
||||
/obj/machinery/gravity_generator/Move()
|
||||
/obj/machinery/gravity_generator/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
@@ -88,13 +88,14 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
//
|
||||
// Generator which spawns with the station.
|
||||
//
|
||||
/obj/machinery/gravity_generator/main/station
|
||||
use_power = USE_POWER_ACTIVE
|
||||
current_overlay = "activated"
|
||||
|
||||
/obj/machinery/gravity_generator/main/station/Initialize()
|
||||
. = ..()
|
||||
setup_parts()
|
||||
middle.add_overlay("activated")
|
||||
current_overlay = "activated"
|
||||
update_use_power(USE_POWER_ACTIVE)
|
||||
middle.add_overlay("activated")
|
||||
|
||||
//
|
||||
// Generator an admin can spawn
|
||||
@@ -122,7 +123,6 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
var/charge_count = 100
|
||||
var/current_overlay = null
|
||||
var/broken_state = 0
|
||||
var/setting = 1 //Gravity value when on
|
||||
var/list/levels = list()
|
||||
var/list/areas = list()
|
||||
|
||||
@@ -290,19 +290,32 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
else if(breaker)
|
||||
new_state = TRUE
|
||||
|
||||
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
|
||||
// Charging state FSM
|
||||
switch(charging_state)
|
||||
if(POWER_UP)
|
||||
if(!new_state) // Can start spin down during spin up
|
||||
charging_state = POWER_DOWN
|
||||
if(POWER_DOWN)
|
||||
if(new_state) // Can start spin up during spin down
|
||||
charging_state = POWER_UP
|
||||
if(POWER_IDLE)
|
||||
if(!new_state && use_power == USE_POWER_ACTIVE) // Can start spin down during running
|
||||
charging_state = POWER_DOWN
|
||||
else if(new_state && use_power == USE_POWER_IDLE) // Can start spin up during stopped
|
||||
charging_state = POWER_UP
|
||||
|
||||
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", "gravity")
|
||||
update_icon()
|
||||
|
||||
// Set the state of the gravity.
|
||||
/obj/machinery/gravity_generator/main/proc/set_state(new_state)
|
||||
charging_state = POWER_IDLE
|
||||
on = new_state
|
||||
update_use_power(on ? USE_POWER_ACTIVE : USE_POWER_IDLE)
|
||||
update_use_power(new_state ? USE_POWER_ACTIVE : USE_POWER_IDLE)
|
||||
|
||||
// Sound the alert if gravity was just enabled or disabled.
|
||||
var/alert = FALSE
|
||||
if(SSticker.IsRoundInProgress())
|
||||
if(on) // If we turned on and the game is live.
|
||||
if(new_state) // If we turned on and the game is live.
|
||||
if(gravity_in_level() == FALSE)
|
||||
alert = TRUE
|
||||
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
|
||||
@@ -314,9 +327,10 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
message_admins("The gravity generator was brought offline with no backup generator. [ADMIN_JMP(src)]")
|
||||
|
||||
update_list()
|
||||
update_gravity(on)
|
||||
update_gravity(new_state)
|
||||
update_icon()
|
||||
src.updateUsrDialog()
|
||||
|
||||
if(alert)
|
||||
shake_everyone()
|
||||
|
||||
@@ -408,7 +422,7 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
for(var/z in levels)
|
||||
if(!GLOB.gravity_generators["[z]"])
|
||||
GLOB.gravity_generators["[z]"] = list()
|
||||
if(on)
|
||||
if(use_power == USE_POWER_ACTIVE)
|
||||
GLOB.gravity_generators["[z]"] |= src
|
||||
else
|
||||
GLOB.gravity_generators["[z]"] -= src
|
||||
@@ -416,6 +430,8 @@ GLOBAL_LIST_EMPTY(gravity_generators)
|
||||
/obj/machinery/gravity_generator/main/proc/update_areas()
|
||||
areas.Cut()
|
||||
for(var/area/A)
|
||||
if(istype(A, /area/shuttle))
|
||||
continue //Skip shuttle areas
|
||||
if(A.z in levels)
|
||||
areas += A
|
||||
|
||||
|
||||
@@ -135,9 +135,9 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/Move()
|
||||
..()
|
||||
if(master && master.active)
|
||||
/obj/structure/particle_accelerator/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(master?.active)
|
||||
master.toggle_power()
|
||||
log_game("PACCEL([x],[y],[z]) Was moved while active and turned off.")
|
||||
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.","singulo")
|
||||
|
||||
@@ -20,14 +20,6 @@
|
||||
|
||||
icon_state = "ml3m_cmo"
|
||||
|
||||
/obj/item/weapon/gun/projectile/cell_loaded/medical/staff
|
||||
name = "cell-loaded staff"
|
||||
desc = "A modified version of the ML-3 Medigun that takes advantage of internal micro-reactor technology to recharge its cells on the field, allowing for prolonged use without needing to stop and charge or replace the cells."
|
||||
description_fluff = "The 'healrod' allows one to customize their loadout in the field, or before deploying, to allow emergency response personnel to deliver a variety of ranged healing options over an extended period of time, thanks to its internal minireactor."
|
||||
description_antag = ""
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 2, TECH_BIO = 5)
|
||||
allowed_magazines = list(/obj/item/ammo_magazine/cell_mag/medical)
|
||||
icon_state = "healrod"
|
||||
|
||||
|
||||
// The Magazine //
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
icon_override = 'icons/vore/custom_guns_vr.dmi'
|
||||
item_state = null
|
||||
item_icons = null
|
||||
item_icons = list(slot_r_hand_str = 'icons/vore/custom_guns_vr.dmi', slot_l_hand_str = 'icons/vore/custom_guns_vr.dmi')
|
||||
item_state_slots = list(slot_r_hand_str = "gbuster_r", slot_l_hand_str = "gbuster_l")
|
||||
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 4)
|
||||
slot_flags = null
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
fire_sound = 'sound/weapons/gauss_shoot.ogg'
|
||||
fire_sound = 'sound/weapons/mandalorian.ogg'
|
||||
charge_meter = 1
|
||||
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/gunsword
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", charge_cost=240,projectile_type=/obj/item/projectile/beam/stun, modifystate="gbuster", fire_sound='sound/weapons/Taser.ogg'),
|
||||
list(mode_name="lethal", charge_cost=480,projectile_type=/obj/item/projectile/beam, modifystate="gbuster", fire_sound='sound/weapons/gauss_shoot.ogg'),
|
||||
list(mode_name="lethal", charge_cost=480,projectile_type=/obj/item/projectile/beam/imperial, modifystate="gbuster", fire_sound='sound/weapons/gauss_shoot.ogg'),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -338,14 +338,13 @@
|
||||
START_PROCESSING(SSprojectiles, src)
|
||||
pixel_move(1, FALSE) //move it now!
|
||||
|
||||
/obj/item/projectile/Move(atom/newloc, dir = NONE)
|
||||
/obj/item/projectile/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(temporary_unstoppable_movement)
|
||||
temporary_unstoppable_movement = FALSE
|
||||
DISABLE_BITFIELD(movement_type, UNSTOPPABLE)
|
||||
if(fired && can_hit_target(original, permutated, TRUE))
|
||||
Bump(original)
|
||||
if(temporary_unstoppable_movement)
|
||||
temporary_unstoppable_movement = FALSE
|
||||
DISABLE_BITFIELD(movement_type, UNSTOPPABLE)
|
||||
if(fired && can_hit_target(original, permutated, TRUE))
|
||||
Bump(original)
|
||||
|
||||
/obj/item/projectile/proc/after_z_change(atom/olcloc, atom/newloc)
|
||||
|
||||
|
||||
@@ -1030,3 +1030,12 @@
|
||||
req_tech = list(TECH_MATERIAL = 7, TECH_ENGINEERING = 5, TECH_MAGNET = 5, TECH_POWER = 6, TECH_ILLEGAL = 3, TECH_BLUESPACE = 4, TECH_ARCANE = 2, TECH_PRECURSOR = 3)
|
||||
materials = list(MAT_DURASTEEL = 5000, MAT_GRAPHITE = 3000, MAT_MORPHIUM = 1500, MAT_OSMIUM = 1500, MAT_PHORON = 1750, MAT_VERDANTIUM = 3000, MAT_SUPERMATTER = 2000)
|
||||
build_path = /obj/item/rig_module/teleporter
|
||||
|
||||
/datum/design/item/mechfab/uav/basic
|
||||
name = "UAV - Recon Skimmer"
|
||||
id = "recon_skimmer"
|
||||
build_path = /obj/item/device/uav
|
||||
time = 20
|
||||
req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 6000, "silver" = 4000)
|
||||
|
||||
@@ -103,7 +103,7 @@ GLOBAL_DATUM(vchatdb, /database)
|
||||
var/list/messagedef = list(
|
||||
"INSERT INTO messages (ckey,worldtime,message) VALUES (?, ?, ?)",
|
||||
ckey,
|
||||
world.time,
|
||||
world.time || 0,
|
||||
message)
|
||||
|
||||
return vchat_exec_update(messagedef)
|
||||
|
||||
@@ -45,19 +45,18 @@
|
||||
icon_state = "quad_keys"
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/vehicle/train/engine/quadbike/Move(var/turf/destination)
|
||||
var/turf/T = get_turf(src)
|
||||
..() //Move it move it, so we can test it test it.
|
||||
if(T != get_turf(src) && !istype(destination, T.type)) //Did we move at all, and are we changing turf types?
|
||||
if(istype(destination, /turf/simulated/floor/water))
|
||||
/obj/vehicle/train/engine/quadbike/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..() //Move it move it, so we can test it test it.
|
||||
if(!istype(loc, old_loc.type) && !istype(old_loc, loc.type)) //Did we move at all, and are we changing turf types?
|
||||
if(istype(loc, /turf/simulated/floor/water))
|
||||
speed_mod = outdoors_speed_mod * 4 //It kind of floats due to its tires, but it is slow.
|
||||
else if(istype(destination, /turf/simulated/floor/outdoors/rocks))
|
||||
else if(istype(loc, /turf/simulated/floor/outdoors/rocks))
|
||||
speed_mod = initial(speed_mod) //Rocks are good, rocks are solid.
|
||||
else if(istype(destination, /turf/simulated/floor/outdoors/dirt) || istype(destination, /turf/simulated/floor/outdoors/grass))
|
||||
else if(istype(loc, /turf/simulated/floor/outdoors/dirt) || istype(loc, /turf/simulated/floor/outdoors/grass))
|
||||
speed_mod = outdoors_speed_mod //Dirt and grass are the outdoors bench mark.
|
||||
else if(istype(destination, /turf/simulated/floor/outdoors/mud))
|
||||
else if(istype(loc, /turf/simulated/floor/outdoors/mud))
|
||||
speed_mod = outdoors_speed_mod * 1.5 //Gets us roughly 1. Mud may be fun, but it's not the best.
|
||||
else if(istype(destination, /turf/simulated/floor/outdoors/snow))
|
||||
else if(istype(loc, /turf/simulated/floor/outdoors/snow))
|
||||
speed_mod = outdoors_speed_mod * 1.7 //Roughly a 1.25. Snow is coarse and wet and gets everywhere, especially your electric motors.
|
||||
else
|
||||
speed_mod = initial(speed_mod)
|
||||
@@ -193,8 +192,8 @@
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/vehicle/train/trolley/trailer/Move()
|
||||
..()
|
||||
/obj/vehicle/train/trolley/trailer/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(lead)
|
||||
switch(dir) //Due to being a Big Boy sprite, it has to have special pixel shifting to look 'normal'.
|
||||
if(1)
|
||||
|
||||
@@ -29,14 +29,11 @@
|
||||
|
||||
/obj/vehicle/train/Move()
|
||||
var/old_loc = get_turf(src)
|
||||
if(..())
|
||||
if((. = ..()))
|
||||
if(tow)
|
||||
tow.Move(old_loc)
|
||||
return 1
|
||||
else
|
||||
if(lead)
|
||||
unattach()
|
||||
return 0
|
||||
else if(lead)
|
||||
unattach()
|
||||
|
||||
/obj/vehicle/train/Bump(atom/Obstacle)
|
||||
if(!istype(Obstacle, /atom/movable))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/disease2/diseaseanalyser
|
||||
name = "disease analyser"
|
||||
desc = "Analyzes diseases to find out information about them!"
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "analyser"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/computer/centrifuge
|
||||
name = "isolation centrifuge"
|
||||
desc = "Used to separate things with different weight. Spin 'em round, round, right round."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "centrifuge"
|
||||
var/curing
|
||||
var/isolating
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "Encourages the growth of diseases. This model comes with a dispenser system and a small radiation generator."
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "incubator"
|
||||
var/obj/item/weapon/virusdish/dish
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
desc = "Used to isolate and identify diseases, allowing for comparison with a remote database."
|
||||
density = 1
|
||||
anchored = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "isolator"
|
||||
var/isolating = 0
|
||||
var/state = HOME
|
||||
|
||||
@@ -276,6 +276,7 @@
|
||||
name = "Deer dual-color (Taur)"
|
||||
icon_state = "deer_s"
|
||||
extra_overlay = "deer_markings"
|
||||
suit_sprites = 'icons/mob/taursuits_deer_vr.dmi'
|
||||
|
||||
msg_owner_disarm_run = "You quickly push %prey to the ground with your hoof!"
|
||||
msg_prey_disarm_run = "%owner pushes you down to the ground with their hoof!"
|
||||
@@ -387,6 +388,7 @@
|
||||
/datum/sprite_accessory/tail/taur/slug
|
||||
name = "Slug (Taur)"
|
||||
icon_state = "slug_s"
|
||||
suit_sprites = 'icons/mob/taursuits_slug_vr.dmi'
|
||||
|
||||
msg_owner_help_walk = "You carefully slither around %prey."
|
||||
msg_prey_help_walk = "%owner's huge tail slithers past beside you!"
|
||||
@@ -429,6 +431,7 @@
|
||||
name = "Otie (Taur)"
|
||||
icon_state = "otie_s"
|
||||
extra_overlay = "otie_markings"
|
||||
suit_sprites = 'icons/mob/taursuits_otie_vr.dmi'
|
||||
|
||||
/datum/sprite_accessory/tail/taur/alraune/alraune_2c
|
||||
name = "Alraune (dual color)"
|
||||
|
||||
@@ -201,6 +201,17 @@
|
||||
var/taste
|
||||
if(can_taste && (taste = M.get_taste_message(FALSE)))
|
||||
to_chat(owner, "<span class='notice'>[M] tastes of [taste].</span>")
|
||||
//Stop AI processing in bellies
|
||||
if(M.ai_holder)
|
||||
M.ai_holder.go_sleep()
|
||||
|
||||
// Called whenever an atom leaves this belly
|
||||
/obj/belly/Exited(atom/movable/thing, atom/OldLoc)
|
||||
. = ..()
|
||||
if(isliving(thing) && !isbelly(thing.loc))
|
||||
var/mob/living/L = thing
|
||||
if((L.stat != DEAD) && L.ai_holder)
|
||||
L.ai_holder.go_wake()
|
||||
|
||||
// Release all contents of this belly into the owning mob's location.
|
||||
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
|
||||
|
||||
@@ -36,27 +36,27 @@
|
||||
var/from_suit = /obj/item/clothing/suit/space/void
|
||||
var/to_helmet = /obj/item/clothing/head/cardborg
|
||||
var/to_suit = /obj/item/clothing/suit/cardborg
|
||||
|
||||
|
||||
//conversion costs. refunds all parts by default, but can be tweaked per-kit
|
||||
var/from_helmet_cost = 1
|
||||
var/from_suit_cost = 2
|
||||
var/to_helmet_cost = -1
|
||||
var/to_suit_cost = -2
|
||||
|
||||
|
||||
var/owner_ckey = null //ckey of the kit owner as a string
|
||||
var/skip_content_check = FALSE //can we skip the contents check? we generally shouldn't, but this is necessary for rigs/coats with hoods/etc.
|
||||
var/transfer_contents = FALSE //should we transfer the contents across before deleting? we generally shouldn't, esp. in the case of rigs/coats with hoods/etc. note this does nothing if skip is FALSE.
|
||||
var/can_repair = FALSE //can we be used to repair damaged voidsuits when converting them?
|
||||
var/can_revert = TRUE //can we revert items, or is it a one-way trip?
|
||||
var/delete_on_empty = FALSE //do we self-delete when emptied?
|
||||
|
||||
|
||||
//Conversion proc
|
||||
/obj/item/device/modkit_conversion/afterattack(obj/O, mob/user as mob)
|
||||
var/cost
|
||||
var/to_type
|
||||
var/keycheck
|
||||
|
||||
if(isturf(O)) //silently fail if you click on a turf. shouldn't work anyway because turfs aren't objects but if I don't do this it spits runtimes.
|
||||
|
||||
if(isturf(O)) //silently fail if you click on a turf. shouldn't work anyway because turfs aren't objects but if I don't do this it spits runtimes.
|
||||
return
|
||||
if(istype(O,/obj/item/clothing/suit/space/void/) && !can_repair) //check if we're a voidsuit and if we're allowed to repair
|
||||
var/obj/item/clothing/suit/space/void/SS = O
|
||||
@@ -104,13 +104,13 @@
|
||||
playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
var/obj/N = new to_type(O.loc)
|
||||
user.visible_message("<span class='notice'>[user] opens \the [src] and modifies \the [O] into \the [N].</span>","<span class='notice'>You open \the [src] and modify \the [O] into \the [N].</span>")
|
||||
|
||||
|
||||
//crude, but transfer prints and fibers to avoid forensics abuse, same as the bloody/gooey check above
|
||||
N.fingerprints = O.fingerprints
|
||||
N.fingerprintshidden = O.fingerprintshidden
|
||||
N.fingerprintslast = O.fingerprintslast
|
||||
N.suit_fibers = O.suit_fibers
|
||||
|
||||
|
||||
//transfer logic could technically be made more thorough and handle stuff like helmet/boots/tank vars for suits, but in those cases you should be removing the items first anyway
|
||||
if(skip_content_check && transfer_contents)
|
||||
N.contents = O.contents
|
||||
@@ -133,7 +133,7 @@
|
||||
var/obj/item/weapon/gun/energy/NO = N
|
||||
NO.contents = list()
|
||||
NO.cell_type = null
|
||||
|
||||
|
||||
qdel(O)
|
||||
parts -= cost
|
||||
if(!parts && delete_on_empty)
|
||||
@@ -439,8 +439,8 @@
|
||||
|
||||
//SilencedMP5A5:Serdykov Antoz
|
||||
/obj/item/clothing/suit/armor/vest/wolftaur/serdy //SilencedMP5A5's specialty armor suit.
|
||||
name = "KSS-8 security armor"
|
||||
desc = "A set of armor made from pieces of many other armors. There are two orange holobadges on it, one on the chestplate, one on the steel flank plates. The holobadges appear to be russian in origin. 'Kosmicheskaya Stantsiya-8' is printed in faded white letters on one side, along the spine. It smells strongly of dog."
|
||||
name = "custom security cuirass"
|
||||
desc = "An armored vest that protects against some damage. It appears to be created for a wolfhound. The name 'Serdykov L. Antoz' is written on a tag inside one of the haunchplates."
|
||||
species_restricted = null //Species restricted since all it cares about is a taur half
|
||||
icon = 'icons/mob/taursuits_wolf_vr.dmi'
|
||||
icon_state = "serdy_armor"
|
||||
@@ -454,16 +454,27 @@
|
||||
to_chat(H, "<span class='warning'>You need to have a wolf-taur half to wear this.</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/head/helmet/serdy //SilencedMP5A5's specialty helmet. Uncomment if/when they make their custom item app and are accepted.
|
||||
name = "KSS-8 security helmet"
|
||||
desc = "desc = An old production model steel-ceramic lined helmet with a white stripe and a custom orange holographic visor. It has ear holes, and smells of dog. It's been heavily modified, and fitted with a metal mask to protect the jaw."
|
||||
/obj/item/clothing/head/serdyhelmet //SilencedMP5A5's specialty helmet.
|
||||
name = "custom security helmet"
|
||||
desc = "An old production model steel-ceramic lined helmet with a white stripe and a custom orange holographic visor. It has ear holes, and smells of dog."
|
||||
icon = 'icons/vore/custom_clothes_vr.dmi'
|
||||
icon_state = "serdyhelm"
|
||||
|
||||
valid_accessory_slots = (ACCESSORY_SLOT_HELM_C)
|
||||
restricted_accessory_slots = (ACCESSORY_SLOT_HELM_C)
|
||||
flags = THICKMATERIAL
|
||||
armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 10, bio = 0, rad = 0)
|
||||
icon_override = 'icons/vore/custom_clothes_vr.dmi'
|
||||
item_state = "serdyhelm_mob"
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = HELMET_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
siemens_coefficient = 0.7
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
ear_protection = 1
|
||||
drop_sound = 'sound/items/drop/helm.ogg'
|
||||
|
||||
|
||||
/*
|
||||
//SilencedMP5A5:Serdykov Antoz
|
||||
/obj/item/device/modkit_conversion/fluff/serdykit
|
||||
name = "Serdykov's armor modification kit"
|
||||
@@ -474,9 +485,9 @@
|
||||
|
||||
from_helmet = /obj/item/clothing/head/helmet
|
||||
from_suit = /obj/item/clothing/suit/armor/vest/wolftaur
|
||||
to_helmet = /obj/item/clothing/head/helmet/serdy
|
||||
to_helmet = /obj/item/clothing/head/serdyhelmet
|
||||
to_suit = /obj/item/clothing/suit/armor/vest/wolftaur/serdy
|
||||
*/
|
||||
|
||||
|
||||
//Cameron653: Diana Kuznetsova
|
||||
/obj/item/clothing/suit/fluff/purp_robes
|
||||
|
||||
@@ -336,8 +336,8 @@
|
||||
secondary_effect.ToggleActivate(0)
|
||||
return
|
||||
|
||||
/obj/machinery/artifact/Move()
|
||||
..()
|
||||
/obj/machinery/artifact/Moved()
|
||||
. = ..()
|
||||
if(my_effect)
|
||||
my_effect.UpdateMove()
|
||||
if(secondary_effect)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Anomaly Analyser"
|
||||
desc = "Studies the emissions of anomalous materials to discover their uses."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "isolator"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/machinery/artifact_harvester
|
||||
name = "Exotic Particle Harvester"
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "incubator" //incubator_on
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "A specialised, complex scanner for gleaning information on all manner of small things."
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon = 'icons/obj/virology_vr.dmi' //VOREStation Edit
|
||||
icon_state = "analyser"
|
||||
|
||||
use_power = USE_POWER_IDLE
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
/obj/machinery/xenobio/extractor
|
||||
name = "biological product destructive analyzer"
|
||||
icon = 'icons/obj/hydroponics_machines.dmi'
|
||||
icon = 'icons/obj/hydroponics_machines_vr.dmi' //VOREStation Edit
|
||||
icon_state = "traitcopier"
|
||||
circuit = /obj/item/weapon/circuitboard/bioproddestanalyzer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user