Merge branch 'master' into nova-ert

This commit is contained in:
Novacat
2020-04-29 14:29:09 -04:00
committed by GitHub
168 changed files with 10709 additions and 8709 deletions
+71 -19
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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()
+3 -1
View File
@@ -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()
+19 -30
View File
@@ -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 ..()
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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()
+4 -1
View File
@@ -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()
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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
+9 -10
View File
@@ -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)
+3 -2
View File
@@ -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
+2 -3
View File
@@ -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
+19 -21
View File
@@ -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
+2 -2
View File
@@ -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)
+11 -11
View File
@@ -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()
+14 -10
View File
@@ -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)
+15 -16
View File
@@ -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++
-2
View File
@@ -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)
+9 -25
View File
@@ -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)
+1 -1
View File
@@ -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!
+1 -1
View File
@@ -61,7 +61,7 @@
if(shadow)
shadow.sync_icon(src)
/mob/living/Move()
/mob/living/Moved()
. = ..()
check_shadow()
+3
View File
@@ -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"
+3 -12
View File
@@ -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
+5
View File
@@ -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>")
+27 -11
View File
@@ -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'),
)
+6 -7
View File
@@ -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)
+9
View File
@@ -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)
+1 -1
View File
@@ -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)
+10 -11
View File
@@ -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)
+3 -6
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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)"
+11
View File
@@ -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.
+28 -17
View File
@@ -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