mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-17 13:42:44 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into make_ai_great_again
This commit is contained in:
@@ -30,6 +30,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
|||||||
#define INIT_ORDER_DEFAULT 0
|
#define INIT_ORDER_DEFAULT 0
|
||||||
#define INIT_ORDER_LIGHTING 0
|
#define INIT_ORDER_LIGHTING 0
|
||||||
#define INIT_ORDER_AIR -1
|
#define INIT_ORDER_AIR -1
|
||||||
|
#define INIT_ORDER_PLANETS -4
|
||||||
#define INIT_ORDER_OVERLAY -6
|
#define INIT_ORDER_OVERLAY -6
|
||||||
#define INIT_ORDER_XENOARCH -20
|
#define INIT_ORDER_XENOARCH -20
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
|||||||
#define FIRE_PRIORITY_AIRFLOW 30
|
#define FIRE_PRIORITY_AIRFLOW 30
|
||||||
#define FIRE_PRIORITY_AIR 35
|
#define FIRE_PRIORITY_AIR 35
|
||||||
#define FIRE_PRIORITY_DEFAULT 50
|
#define FIRE_PRIORITY_DEFAULT 50
|
||||||
|
#define FIRE_PRIORITY_PLANETS 75
|
||||||
#define FIRE_PRIORITY_MACHINES 100
|
#define FIRE_PRIORITY_MACHINES 100
|
||||||
#define FIRE_PRIORITY_OVERLAYS 500
|
#define FIRE_PRIORITY_OVERLAYS 500
|
||||||
|
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
var/datum/controller/process/planet/planet_controller = null
|
|
||||||
|
|
||||||
/datum/controller/process/planet
|
|
||||||
var/list/planets = list()
|
|
||||||
var/list/z_to_planet = list()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/setup()
|
|
||||||
name = "planet controller"
|
|
||||||
planet_controller = src
|
|
||||||
schedule_interval = 1 MINUTE
|
|
||||||
|
|
||||||
var/list/planet_datums = typesof(/datum/planet) - /datum/planet
|
|
||||||
for(var/P in planet_datums)
|
|
||||||
var/datum/planet/NP = new P()
|
|
||||||
planets.Add(NP)
|
|
||||||
|
|
||||||
allocateTurfs()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/proc/allocateTurfs()
|
|
||||||
for(var/turf/simulated/OT in outdoor_turfs)
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
if(OT.z in P.expected_z_levels)
|
|
||||||
P.planet_floors |= OT
|
|
||||||
OT.vis_contents |= P.weather_holder.visuals
|
|
||||||
break
|
|
||||||
outdoor_turfs.Cut() //Why were you in there INCORRECTLY?
|
|
||||||
|
|
||||||
for(var/turf/unsimulated/wall/planetary/PW in planetary_walls)
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
if(PW.type == P.planetary_wall_type)
|
|
||||||
P.planet_walls |= PW
|
|
||||||
break
|
|
||||||
planetary_walls.Cut()
|
|
||||||
|
|
||||||
/datum/controller/process/planet/proc/unallocateTurf(var/turf/T)
|
|
||||||
for(var/planet in planets)
|
|
||||||
var/datum/planet/P = planet
|
|
||||||
if(T.z in P.expected_z_levels)
|
|
||||||
P.planet_floors -= T
|
|
||||||
T.vis_contents -= P.weather_holder.visuals
|
|
||||||
|
|
||||||
/datum/controller/process/planet/doWork()
|
|
||||||
if(outdoor_turfs.len || planetary_walls.len)
|
|
||||||
allocateTurfs()
|
|
||||||
|
|
||||||
for(var/datum/planet/P in planets)
|
|
||||||
P.process(schedule_interval / 10)
|
|
||||||
SCHECK //Your process() really shouldn't take this long...
|
|
||||||
|
|
||||||
//Sun light needs changing
|
|
||||||
if(P.needs_work & PLANET_PROCESS_SUN)
|
|
||||||
P.needs_work &= ~PLANET_PROCESS_SUN
|
|
||||||
// Remove old value from corners
|
|
||||||
var/list/sunlit_corners = P.sunlit_corners
|
|
||||||
var/old_lum_r = -P.sun["lum_r"]
|
|
||||||
var/old_lum_g = -P.sun["lum_g"]
|
|
||||||
var/old_lum_b = -P.sun["lum_b"]
|
|
||||||
if(old_lum_r || old_lum_g || old_lum_b)
|
|
||||||
for(var/C in P.sunlit_corners)
|
|
||||||
var/datum/lighting_corner/LC = C
|
|
||||||
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
|
|
||||||
SCHECK
|
|
||||||
sunlit_corners.Cut()
|
|
||||||
|
|
||||||
// Calculate new values to apply
|
|
||||||
var/new_brightness = P.sun["brightness"]
|
|
||||||
var/new_color = P.sun["color"]
|
|
||||||
var/lum_r = new_brightness * GetRedPart (new_color) / 255
|
|
||||||
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
|
|
||||||
var/lum_b = new_brightness * GetBluePart (new_color) / 255
|
|
||||||
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
|
|
||||||
for(var/I in P.planet_floors)
|
|
||||||
var/turf/simulated/T = I
|
|
||||||
if(!T.lighting_corners_initialised)
|
|
||||||
T.generate_missing_corners()
|
|
||||||
for(var/C in T.get_corners())
|
|
||||||
var/datum/lighting_corner/LC = C
|
|
||||||
if(LC.update_gen != update_gen && LC.active)
|
|
||||||
sunlit_corners += LC
|
|
||||||
LC.update_gen = update_gen
|
|
||||||
LC.update_lumcount(lum_r, lum_g, lum_b)
|
|
||||||
SCHECK
|
|
||||||
update_gen--
|
|
||||||
P.sun["lum_r"] = lum_r
|
|
||||||
P.sun["lum_g"] = lum_g
|
|
||||||
P.sun["lum_b"] = lum_b
|
|
||||||
|
|
||||||
//Temperature needs updating
|
|
||||||
if(P.needs_work & PLANET_PROCESS_TEMP)
|
|
||||||
P.needs_work &= ~PLANET_PROCESS_TEMP
|
|
||||||
//Set new temperatures
|
|
||||||
for(var/W in P.planet_walls)
|
|
||||||
var/turf/unsimulated/wall/planetary/wall = W
|
|
||||||
wall.set_temperature(P.weather_holder.temperature)
|
|
||||||
SCHECK
|
|
||||||
@@ -60,6 +60,7 @@ var/list/gamemode_cache = list()
|
|||||||
var/humans_need_surnames = 0
|
var/humans_need_surnames = 0
|
||||||
var/allow_random_events = 0 // enables random events mid-round when set to 1
|
var/allow_random_events = 0 // enables random events mid-round when set to 1
|
||||||
var/allow_ai = 1 // allow ai job
|
var/allow_ai = 1 // allow ai job
|
||||||
|
var/allow_ai_drones = 0 // allow ai controlled drones
|
||||||
var/hostedby = null
|
var/hostedby = null
|
||||||
var/respawn = 1
|
var/respawn = 1
|
||||||
var/guest_jobban = 1
|
var/guest_jobban = 1
|
||||||
@@ -400,6 +401,9 @@ var/list/gamemode_cache = list()
|
|||||||
if ("allow_ai")
|
if ("allow_ai")
|
||||||
config.allow_ai = 1
|
config.allow_ai = 1
|
||||||
|
|
||||||
|
if ("allow_ai_drones")
|
||||||
|
config.allow_ai_drones = 1
|
||||||
|
|
||||||
// if ("authentication")
|
// if ("authentication")
|
||||||
// config.enable_authentication = 1
|
// config.enable_authentication = 1
|
||||||
|
|
||||||
|
|||||||
183
code/controllers/subsystems/planets.dm
Normal file
183
code/controllers/subsystems/planets.dm
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
SUBSYSTEM_DEF(planets)
|
||||||
|
name = "Planets"
|
||||||
|
init_order = INIT_ORDER_PLANETS
|
||||||
|
priority = FIRE_PRIORITY_PLANETS
|
||||||
|
wait = 2 SECONDS
|
||||||
|
flags = SS_BACKGROUND
|
||||||
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||||
|
|
||||||
|
var/list/new_outdoor_turfs = list()
|
||||||
|
var/list/new_outdoor_walls = list()
|
||||||
|
|
||||||
|
var/list/planets = list()
|
||||||
|
var/list/z_to_planet = list()
|
||||||
|
|
||||||
|
var/list/currentrun = list()
|
||||||
|
|
||||||
|
var/list/needs_sun_update = list()
|
||||||
|
var/list/needs_temp_update = list()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/Initialize(timeofday)
|
||||||
|
admin_notice("<span class='danger'>Initializing planetary weather.</span>", R_DEBUG)
|
||||||
|
createPlanets()
|
||||||
|
allocateTurfs(TRUE)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/createPlanets()
|
||||||
|
var/list/planet_datums = subtypesof(/datum/planet)
|
||||||
|
for(var/P in planet_datums)
|
||||||
|
var/datum/planet/NP = new P()
|
||||||
|
planets.Add(NP)
|
||||||
|
for(var/Z in NP.expected_z_levels)
|
||||||
|
if(Z > z_to_planet.len)
|
||||||
|
z_to_planet.len = Z
|
||||||
|
if(z_to_planet[Z])
|
||||||
|
admin_notice("<span class='danger'>Z[Z] is shared by more than one planet!</span>", R_DEBUG)
|
||||||
|
continue
|
||||||
|
z_to_planet[Z] = NP
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/addTurf(var/turf/T,var/is_edge)
|
||||||
|
if(is_edge)
|
||||||
|
new_outdoor_walls |= T
|
||||||
|
else
|
||||||
|
new_outdoor_turfs |= T
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge)
|
||||||
|
if(is_edge)
|
||||||
|
new_outdoor_walls -= T
|
||||||
|
else
|
||||||
|
new_outdoor_turfs -= T
|
||||||
|
|
||||||
|
if(z_to_planet.len >= T.z)
|
||||||
|
var/datum/planet/P = z_to_planet[T.z]
|
||||||
|
if(!P)
|
||||||
|
return
|
||||||
|
if(is_edge)
|
||||||
|
P.planet_floors -= T
|
||||||
|
else
|
||||||
|
P.planet_walls -= T
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/allocateTurfs(var/initial = FALSE)
|
||||||
|
var/list/currentlist = new_outdoor_turfs
|
||||||
|
while(currentlist.len)
|
||||||
|
var/turf/simulated/OT = currentlist[currentlist.len]
|
||||||
|
currentlist.len--
|
||||||
|
if(istype(OT) && z_to_planet[OT.z])
|
||||||
|
var/datum/planet/P = z_to_planet[OT.z]
|
||||||
|
P.planet_floors |= OT
|
||||||
|
OT.vis_contents |= P.weather_holder.visuals
|
||||||
|
if(!initial && MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
currentlist = new_outdoor_walls
|
||||||
|
while(currentlist.len)
|
||||||
|
var/turf/unsimulated/wall/planetary/PW = currentlist[currentlist.len]
|
||||||
|
currentlist.len--
|
||||||
|
if(istype(PW) && z_to_planet[PW.z])
|
||||||
|
var/datum/planet/P = z_to_planet[PW.z]
|
||||||
|
P.planet_walls |= PW
|
||||||
|
if(!initial && MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/unallocateTurf(var/turf/simulated/T)
|
||||||
|
if(istype(T) && z_to_planet[T.z])
|
||||||
|
var/datum/planet/P = z_to_planet[T.z]
|
||||||
|
P.planet_floors -= T
|
||||||
|
T.vis_contents -= P.weather_holder.visuals
|
||||||
|
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/fire(resumed = 0)
|
||||||
|
if(new_outdoor_turfs.len || new_outdoor_walls.len)
|
||||||
|
allocateTurfs()
|
||||||
|
|
||||||
|
if(!resumed)
|
||||||
|
src.currentrun = planets.Copy()
|
||||||
|
|
||||||
|
var/list/needs_sun_update = src.needs_sun_update
|
||||||
|
while(needs_sun_update.len)
|
||||||
|
var/datum/planet/P = needs_sun_update[needs_sun_update.len]
|
||||||
|
needs_sun_update.len--
|
||||||
|
updateSunlight(P)
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/needs_temp_update = src.needs_temp_update
|
||||||
|
while(needs_temp_update.len)
|
||||||
|
var/datum/planet/P = needs_temp_update[needs_temp_update.len]
|
||||||
|
needs_temp_update.len--
|
||||||
|
updateTemp(P)
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/currentrun = src.currentrun
|
||||||
|
while(currentrun.len)
|
||||||
|
var/datum/planet/P = currentrun[currentrun.len]
|
||||||
|
currentrun.len--
|
||||||
|
|
||||||
|
P.process(last_fire)
|
||||||
|
|
||||||
|
//Sun light needs changing
|
||||||
|
if(P.needs_work & PLANET_PROCESS_SUN)
|
||||||
|
P.needs_work &= ~PLANET_PROCESS_SUN
|
||||||
|
needs_sun_update |= P
|
||||||
|
|
||||||
|
//Temperature needs updating
|
||||||
|
if(P.needs_work & PLANET_PROCESS_TEMP)
|
||||||
|
P.needs_work &= ~PLANET_PROCESS_TEMP
|
||||||
|
needs_temp_update |= P
|
||||||
|
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P)
|
||||||
|
// Remove old value from corners
|
||||||
|
var/list/sunlit_corners = P.sunlit_corners
|
||||||
|
var/old_lum_r = -P.sun["lum_r"]
|
||||||
|
var/old_lum_g = -P.sun["lum_g"]
|
||||||
|
var/old_lum_b = -P.sun["lum_b"]
|
||||||
|
if(old_lum_r || old_lum_g || old_lum_b)
|
||||||
|
for(var/C in sunlit_corners)
|
||||||
|
var/datum/lighting_corner/LC = C
|
||||||
|
LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b)
|
||||||
|
CHECK_TICK
|
||||||
|
sunlit_corners.Cut()
|
||||||
|
|
||||||
|
// Calculate new values to apply
|
||||||
|
var/new_brightness = P.sun["brightness"]
|
||||||
|
var/new_color = P.sun["color"]
|
||||||
|
var/lum_r = new_brightness * GetRedPart (new_color) / 255
|
||||||
|
var/lum_g = new_brightness * GetGreenPart(new_color) / 255
|
||||||
|
var/lum_b = new_brightness * GetBluePart (new_color) / 255
|
||||||
|
var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs.
|
||||||
|
for(var/I in P.planet_floors)
|
||||||
|
var/turf/simulated/T = I
|
||||||
|
if(!T.lighting_corners_initialised)
|
||||||
|
T.generate_missing_corners()
|
||||||
|
for(var/C in T.get_corners())
|
||||||
|
var/datum/lighting_corner/LC = C
|
||||||
|
if(LC.update_gen != update_gen && LC.active)
|
||||||
|
sunlit_corners += LC
|
||||||
|
LC.update_gen = update_gen
|
||||||
|
LC.update_lumcount(lum_r, lum_g, lum_b)
|
||||||
|
CHECK_TICK
|
||||||
|
update_gen--
|
||||||
|
P.sun["lum_r"] = lum_r
|
||||||
|
P.sun["lum_g"] = lum_g
|
||||||
|
P.sun["lum_b"] = lum_b
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P)
|
||||||
|
//Set new temperatures
|
||||||
|
for(var/W in P.planet_walls)
|
||||||
|
var/turf/unsimulated/wall/planetary/wall = W
|
||||||
|
wall.set_temperature(P.weather_holder.temperature)
|
||||||
|
CHECK_TICK
|
||||||
|
|
||||||
|
/datum/controller/subsystem/planets/proc/weatherDisco()
|
||||||
|
var/count = 100000
|
||||||
|
while(count > 0)
|
||||||
|
count--
|
||||||
|
for(var/planet in planets)
|
||||||
|
var/datum/planet/P = planet
|
||||||
|
if(P.weather_holder)
|
||||||
|
P.weather_holder.change_weather(pick(P.weather_holder.allowed_weather_types))
|
||||||
|
sleep(3)
|
||||||
@@ -133,8 +133,5 @@
|
|||||||
if("Vote")
|
if("Vote")
|
||||||
debug_variables(vote)
|
debug_variables(vote)
|
||||||
feedback_add_details("admin_verb", "DVote")
|
feedback_add_details("admin_verb", "DVote")
|
||||||
if("Planets")
|
|
||||||
debug_variables(planet_controller)
|
|
||||||
feedback_add_details("admin_verb", "DPlanets")
|
|
||||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -200,14 +200,16 @@ GLOBAL_LIST_BOILERPLATE(all_deactivated_AI_cores, /obj/structure/AIcore/deactiva
|
|||||||
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
|
if(!istype(transfer) || locate(/mob/living/silicon/ai) in src)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(transfer.controlling_drone)
|
||||||
|
transfer.controlling_drone.release_ai_control("Unit control lost. Core transfer completed.")
|
||||||
transfer.aiRestorePowerRoutine = 0
|
transfer.aiRestorePowerRoutine = 0
|
||||||
transfer.control_disabled = 0
|
transfer.control_disabled = 0
|
||||||
transfer.aiRadio.disabledAi = 0
|
transfer.aiRadio.disabledAi = 0
|
||||||
transfer.loc = get_turf(src)
|
transfer.loc = get_turf(src)
|
||||||
transfer.create_eyeobj()
|
transfer.create_eyeobj()
|
||||||
transfer.cancel_camera()
|
transfer.cancel_camera()
|
||||||
user << "<span class='notice'>Transfer successful:</span> [transfer.name] placed within stationary core."
|
to_chat(user, "<span class='notice'>Transfer successful:</span> [transfer.name] placed within stationary core.")
|
||||||
transfer << "You have been transferred into a stationary core. Remote device connection restored."
|
to_chat(transfer, "You have been transferred into a stationary core. Remote device connection restored.")
|
||||||
|
|
||||||
if(card)
|
if(card)
|
||||||
card.clear()
|
card.clear()
|
||||||
|
|||||||
@@ -248,6 +248,6 @@ var/global/list/image/splatter_cache=list()
|
|||||||
|
|
||||||
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
|
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
|
||||||
/obj/effect/decal/cleanable/mucus/mapped/New()
|
/obj/effect/decal/cleanable/mucus/mapped/New()
|
||||||
...()
|
..()
|
||||||
virus2 = new /datum/disease2/disease
|
virus2 = new /datum/disease2/disease
|
||||||
virus2.makerandom()
|
virus2.makerandom()
|
||||||
|
|||||||
@@ -64,20 +64,24 @@
|
|||||||
add_attack_logs(user,carded_ai,"Purged from AI Card")
|
add_attack_logs(user,carded_ai,"Purged from AI Card")
|
||||||
flush = 1
|
flush = 1
|
||||||
carded_ai.suiciding = 1
|
carded_ai.suiciding = 1
|
||||||
carded_ai << "Your power has been disabled!"
|
to_chat(carded_ai, "Your power has been disabled!")
|
||||||
while (carded_ai && carded_ai.stat != 2)
|
while (carded_ai && carded_ai.stat != 2)
|
||||||
|
if(carded_ai.controlling_drone && prob(carded_ai.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
|
||||||
|
carded_ai.controlling_drone.release_ai_control("Unit lost. Integrity too low to maintain connection.")
|
||||||
carded_ai.adjustOxyLoss(2)
|
carded_ai.adjustOxyLoss(2)
|
||||||
carded_ai.updatehealth()
|
carded_ai.updatehealth()
|
||||||
sleep(10)
|
sleep(10)
|
||||||
flush = 0
|
flush = 0
|
||||||
if (href_list["radio"])
|
if (href_list["radio"])
|
||||||
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
|
carded_ai.aiRadio.disabledAi = text2num(href_list["radio"])
|
||||||
carded_ai << "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>"
|
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
|
||||||
user << "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>"
|
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
|
||||||
if (href_list["wireless"])
|
if (href_list["wireless"])
|
||||||
carded_ai.control_disabled = text2num(href_list["wireless"])
|
carded_ai.control_disabled = text2num(href_list["wireless"])
|
||||||
carded_ai << "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>"
|
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
|
||||||
user << "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>"
|
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
|
||||||
|
if(carded_ai.control_disabled && carded_ai.controlling_drone)
|
||||||
|
carded_ai.controlling_drone.release_ai_control("Unit control terminated at intellicore port.")
|
||||||
update_icon()
|
update_icon()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -94,12 +98,12 @@
|
|||||||
icon_state = "aicard"
|
icon_state = "aicard"
|
||||||
|
|
||||||
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
|
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
|
||||||
if(!ai.client)
|
if(!ai.client && !ai.controlling_drone)
|
||||||
user << "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer."
|
to_chat(user, "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(carded_ai)
|
if(carded_ai)
|
||||||
user << "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one."
|
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if(!user.IsAdvancedToolUser() && isanimal(user))
|
if(!user.IsAdvancedToolUser() && isanimal(user))
|
||||||
@@ -108,7 +112,9 @@
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
|
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
|
||||||
ai << "<span class='danger'>\The [user] is transferring you into \the [src]!</span>"
|
to_chat(ai, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
|
||||||
|
if(ai.controlling_drone)
|
||||||
|
to_chat(ai.controlling_drone, "<span class='danger'>\The [user] is transferring you into \the [src]!</span>")
|
||||||
|
|
||||||
if(do_after(user, 100))
|
if(do_after(user, 100))
|
||||||
if(istype(ai.loc, /turf/))
|
if(istype(ai.loc, /turf/))
|
||||||
@@ -124,11 +130,13 @@
|
|||||||
ai.control_disabled = 1
|
ai.control_disabled = 1
|
||||||
ai.aiRestorePowerRoutine = 0
|
ai.aiRestorePowerRoutine = 0
|
||||||
carded_ai = ai
|
carded_ai = ai
|
||||||
|
if(ai.controlling_drone)
|
||||||
|
ai.controlling_drone.release_ai_control("Unit control lost.")
|
||||||
|
|
||||||
if(ai.client)
|
if(ai.client)
|
||||||
ai << "You have been transferred into a mobile core. Remote access lost."
|
to_chat(ai, "You have been transferred into a mobile core. Remote access lost.")
|
||||||
if(user.client)
|
if(user.client)
|
||||||
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core."
|
to_chat(ai, "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core.")
|
||||||
|
|
||||||
ai.canmove = 1
|
ai.canmove = 1
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|||||||
@@ -69,17 +69,16 @@
|
|||||||
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
|
im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"])
|
||||||
|
|
||||||
//Weather reports.
|
//Weather reports.
|
||||||
if(planet_controller)
|
for(var/datum/planet/planet in SSplanets.planets)
|
||||||
for(var/datum/planet/planet in planet_controller.planets)
|
if(planet.weather_holder && planet.weather_holder.current_weather)
|
||||||
if(planet.weather_holder && planet.weather_holder.current_weather)
|
var/list/W = list(
|
||||||
var/list/W = list(
|
"Planet" = planet.name,
|
||||||
"Planet" = planet.name,
|
"Time" = planet.current_time.show_time("hh:mm"),
|
||||||
"Time" = planet.current_time.show_time("hh:mm"),
|
"Weather" = planet.weather_holder.current_weather.name,
|
||||||
"Weather" = planet.weather_holder.current_weather.name,
|
"Temperature" = planet.weather_holder.temperature - T0C,
|
||||||
"Temperature" = planet.weather_holder.temperature - T0C,
|
"High" = planet.weather_holder.current_weather.temp_high - T0C,
|
||||||
"High" = planet.weather_holder.current_weather.temp_high - T0C,
|
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
|
||||||
"Low" = planet.weather_holder.current_weather.temp_low - T0C)
|
weather[++weather.len] = W
|
||||||
weather[++weather.len] = W
|
|
||||||
|
|
||||||
injection = "<div>Test</div>"
|
injection = "<div>Test</div>"
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,6 @@
|
|||||||
icon = 'icons/obj/abductor.dmi'
|
icon = 'icons/obj/abductor.dmi'
|
||||||
density = TRUE
|
density = TRUE
|
||||||
anchored = TRUE
|
anchored = TRUE
|
||||||
var/interaction_message = null
|
|
||||||
|
|
||||||
/obj/structure/prop/alien/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
|
||||||
if(!istype(user))
|
|
||||||
return FALSE
|
|
||||||
if(!interaction_message)
|
|
||||||
return ..()
|
|
||||||
else
|
|
||||||
to_chat(user, interaction_message)
|
|
||||||
|
|
||||||
/obj/structure/prop/alien/computer
|
/obj/structure/prop/alien/computer
|
||||||
name = "alien console"
|
name = "alien console"
|
||||||
215
code/game/objects/structures/props/beam_prism.dm
Normal file
215
code/game/objects/structures/props/beam_prism.dm
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
//A series(?) of prisms for PoIs. The base one only works for beams.
|
||||||
|
|
||||||
|
/obj/structure/prop/prism
|
||||||
|
name = "prismatic turret"
|
||||||
|
desc = "A raised, externally powered 'turret'. It seems to have a massive crystal ring around its base."
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "prism"
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
|
||||||
|
layer = 3.1 //Layer over projectiles.
|
||||||
|
plane = -10 //Layer over projectiles.
|
||||||
|
|
||||||
|
var/rotation_lock = 0 // Can you rotate the prism at all?
|
||||||
|
var/free_rotate = 1 // Does the prism rotate in any direction, or only in the eight standard compass directions?
|
||||||
|
var/external_control_lock = 0 // Does the prism only rotate from the controls of an external switch?
|
||||||
|
var/degrees_from_north = 0 // How far is it rotated clockwise?
|
||||||
|
var/compass_directions = list("North" = 0, "South" = 180, "East" = 90, "West" = 270, "Northwest" = 315, "Northeast" = 45, "Southeast" = 135, "Southwest" = 225)
|
||||||
|
var/interaction_sound = 'sound/mecha/mechmove04.ogg'
|
||||||
|
|
||||||
|
var/redirect_type = /obj/item/projectile/beam
|
||||||
|
|
||||||
|
var/dialID = null
|
||||||
|
var/obj/structure/prop/prismcontrol/remote_dial = null
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The prismatic turret seems to be able to rotate.</span>"
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/initialize()
|
||||||
|
if(degrees_from_north)
|
||||||
|
animate(src, transform = turn(NORTH, degrees_from_north), time = 3)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/Destroy()
|
||||||
|
if(remote_dial)
|
||||||
|
remote_dial.my_turrets -= src
|
||||||
|
remote_dial = null
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/proc/reset_rotation()
|
||||||
|
var/degrees_to_rotate = -1 * degrees_from_north
|
||||||
|
animate(src, transform = turn(src.transform, degrees_to_rotate), time = 2)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/attack_hand(mob/living/user)
|
||||||
|
..()
|
||||||
|
|
||||||
|
if(rotation_lock)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] is locked at its current bearing.</span>")
|
||||||
|
return
|
||||||
|
if(external_control_lock)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src]'s motors resist your efforts to rotate it. You may need to find some form of controller.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/new_bearing
|
||||||
|
if(free_rotate)
|
||||||
|
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
|
||||||
|
new_bearing = round(new_bearing)
|
||||||
|
if(new_bearing <= -1 || new_bearing > 360)
|
||||||
|
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
|
||||||
|
new_bearing = round(compass_directions[choice])
|
||||||
|
|
||||||
|
var/rotate_degrees = new_bearing - degrees_from_north
|
||||||
|
|
||||||
|
if(new_bearing == 360) // Weird artifact.
|
||||||
|
new_bearing = 0
|
||||||
|
degrees_from_north = new_bearing
|
||||||
|
|
||||||
|
var/two_stage = 0
|
||||||
|
if(rotate_degrees == 180 || rotate_degrees == -180)
|
||||||
|
two_stage = 1
|
||||||
|
var/multiplier = pick(-1, 1)
|
||||||
|
rotate_degrees = multiplier * (rotate_degrees / 2)
|
||||||
|
|
||||||
|
playsound(src, interaction_sound, 50, 1)
|
||||||
|
if(two_stage)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
spawn(3)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
else
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 6) //Can't update transform because it will reset the angle.
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/proc/rotate_auto(var/new_bearing)
|
||||||
|
if(rotation_lock)
|
||||||
|
visible_message("<span class='notice'>\The [src] shudders.</span>")
|
||||||
|
playsound(src, 'sound/effects/clang.ogg', 50, 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
visible_message("<span class='notice'>\The [src] rotates to a bearing of [new_bearing].</span>")
|
||||||
|
|
||||||
|
var/rotate_degrees = new_bearing - degrees_from_north
|
||||||
|
|
||||||
|
if(new_bearing == 360)
|
||||||
|
new_bearing = 0
|
||||||
|
degrees_from_north = new_bearing
|
||||||
|
|
||||||
|
var/two_stage = 0
|
||||||
|
if(rotate_degrees == 180 || rotate_degrees == -180)
|
||||||
|
two_stage = 1
|
||||||
|
var/multiplier = pick(-1, 1)
|
||||||
|
rotate_degrees = multiplier * (rotate_degrees / 2)
|
||||||
|
|
||||||
|
playsound(src, interaction_sound, 50, 1)
|
||||||
|
if(two_stage)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
spawn(3)
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 3)
|
||||||
|
else
|
||||||
|
animate(src, transform = turn(src.transform, rotate_degrees), time = 6)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
if(istype(Proj, redirect_type))
|
||||||
|
visible_message("<span class='danger'>\The [src] redirects \the [Proj]!</span>")
|
||||||
|
flick("[initial(icon_state)]+glow", src)
|
||||||
|
|
||||||
|
var/new_x = (1 * round(10 * cos(degrees_from_north - 90))) + x //Vectors vectors vectors.
|
||||||
|
var/new_y = (-1 * round(10 * sin(degrees_from_north - 90))) + y
|
||||||
|
var/turf/curloc = get_turf(src)
|
||||||
|
|
||||||
|
Proj.penetrating += 1 // Needed for the beam to get out of the turret.
|
||||||
|
|
||||||
|
Proj.redirect(new_x, new_y, curloc, null)
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/incremental
|
||||||
|
free_rotate = 0
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but only locks to specific positions in rotation."
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/incremental/externalcont
|
||||||
|
external_control_lock = 1
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by a control dial to specific positions."
|
||||||
|
|
||||||
|
/obj/structure/prop/prism/externalcont
|
||||||
|
external_control_lock = 1
|
||||||
|
description_info = "This device is capable of redirecting any beam projectile, but can only be rotated by an external control dial."
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol
|
||||||
|
name = "prismatic dial"
|
||||||
|
desc = "A large dial with a crystalline ring."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "dial"
|
||||||
|
density = FALSE
|
||||||
|
anchored = TRUE
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The dial pulses as your hand nears it.</span>"
|
||||||
|
var/list/my_turrets = list()
|
||||||
|
var/dialID = null
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/attack_hand(mob/living/user)
|
||||||
|
..()
|
||||||
|
|
||||||
|
var/confirm = input("Do you want to try to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!my_turrets || !my_turrets.len)
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] doesn't seem to do anything.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/free_rotate = 1
|
||||||
|
var/list/compass_directions = list()
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
if(!P.free_rotate) //Doesn't use bearing, it uses compass points.
|
||||||
|
free_rotate = 0
|
||||||
|
compass_directions |= P.compass_directions
|
||||||
|
|
||||||
|
var/new_bearing
|
||||||
|
if(free_rotate)
|
||||||
|
new_bearing = input("What bearing do you want to rotate \the [src] to?", "[name]") as num
|
||||||
|
new_bearing = round(new_bearing)
|
||||||
|
if(new_bearing <= -1 || new_bearing > 360)
|
||||||
|
to_chat(user, "<span class='warning'>Rotating \the [src] [new_bearing] degrees would be a waste of time.</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
var/choice = input("What point do you want to set \the [src] to?", "[name]") as null|anything in compass_directions
|
||||||
|
new_bearing = round(compass_directions[choice])
|
||||||
|
|
||||||
|
confirm = input("Are you certain you want to rotate \the [src]?", "[name]") in list("Yes", "No")
|
||||||
|
if(confirm == "No")
|
||||||
|
visible_message(\
|
||||||
|
"<span class='notice'>[user.name] decides not to try turning \the [src].</span>",\
|
||||||
|
"<span class='notice'>You decide not to try turning \the [src].</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] clicks into place.</span>")
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.rotate_auto(new_bearing)
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/initialize()
|
||||||
|
..()
|
||||||
|
if(my_turrets.len) //Preset controls.
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.remote_dial = src
|
||||||
|
return
|
||||||
|
spawn()
|
||||||
|
for(var/obj/structure/prop/prism/P in orange(src, world.view)) //Don't search a huge area.
|
||||||
|
if(P.dialID == dialID && !P.remote_dial && P.external_control_lock)
|
||||||
|
my_turrets |= P
|
||||||
|
P.remote_dial = src
|
||||||
|
|
||||||
|
/obj/structure/prop/prismcontrol/Destroy()
|
||||||
|
for(var/obj/structure/prop/prism/P in my_turrets)
|
||||||
|
P.remote_dial = null
|
||||||
|
my_turrets = list()
|
||||||
|
..()
|
||||||
53
code/game/objects/structures/props/projectile_lock.dm
Normal file
53
code/game/objects/structures/props/projectile_lock.dm
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//A locking mechanism that pulses when hit by a projectile. The base one responds to high-power lasers.
|
||||||
|
|
||||||
|
/obj/structure/prop/lock
|
||||||
|
name = "weird lock"
|
||||||
|
desc = "An esoteric object that responds to.. something."
|
||||||
|
icon = 'icons/obj/props/prism.dmi'
|
||||||
|
icon_state = "lock"
|
||||||
|
|
||||||
|
var/enabled = 0
|
||||||
|
var/lockID = null
|
||||||
|
|
||||||
|
var/list/linked_objects = list()
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/Destroy()
|
||||||
|
if(linked_objects.len)
|
||||||
|
for(var/obj/O in linked_objects)
|
||||||
|
if(istype(O, /obj/machinery/door/blast/puzzle))
|
||||||
|
var/obj/machinery/door/blast/puzzle/P = O
|
||||||
|
P.locks -= src
|
||||||
|
linked_objects -= P
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/proc/toggle_lock()
|
||||||
|
enabled = !enabled
|
||||||
|
|
||||||
|
if(enabled)
|
||||||
|
icon_state = "[initial(icon_state)]-active"
|
||||||
|
else
|
||||||
|
icon_state = "[initial(icon_state)]"
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/projectile
|
||||||
|
name = "beam lock"
|
||||||
|
desc = "An esoteric object that responds to high intensity light."
|
||||||
|
|
||||||
|
var/projectile_key = /obj/item/projectile/beam
|
||||||
|
var/timed = 0
|
||||||
|
var/timing = 0
|
||||||
|
var/time_limit = 1500 // In ticks. Ten is one second.
|
||||||
|
|
||||||
|
interaction_message = "<span class='notice'>The object remains inert to your touch.</span>"
|
||||||
|
|
||||||
|
/obj/structure/prop/lock/projectile/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
if(!istype(Proj, projectile_key) || timing)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(istype(Proj, /obj/item/projectile/beam/heavylaser/cannon) || istype(Proj, /obj/item/projectile/beam/emitter) || (Proj.damage >= 80 && Proj.damtype == BURN))
|
||||||
|
toggle_lock()
|
||||||
|
visible_message("<span class='notice'>\The [src] [enabled ? "disengages" : "engages"] its locking mechanism.</span>")
|
||||||
|
|
||||||
|
if(timed)
|
||||||
|
timing = 1
|
||||||
|
spawn(time_limit)
|
||||||
|
toggle_lock()
|
||||||
18
code/game/objects/structures/props/prop.dm
Normal file
18
code/game/objects/structures/props/prop.dm
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//The base 'prop' for PoIs or other large junk.
|
||||||
|
|
||||||
|
/obj/structure/prop
|
||||||
|
name = "something"
|
||||||
|
desc = "My description is broken, bug a developer."
|
||||||
|
icon = 'icons/obj/structures.dmi'
|
||||||
|
icon_state = "safe"
|
||||||
|
density = TRUE
|
||||||
|
anchored = TRUE
|
||||||
|
var/interaction_message = null
|
||||||
|
|
||||||
|
/obj/structure/prop/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
||||||
|
if(!istype(user))
|
||||||
|
return FALSE
|
||||||
|
if(!interaction_message)
|
||||||
|
return ..()
|
||||||
|
else
|
||||||
|
to_chat(user, interaction_message)
|
||||||
92
code/game/objects/structures/props/puzzledoor.dm
Normal file
92
code/game/objects/structures/props/puzzledoor.dm
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// An indestructible blast door that can only be opened once its puzzle requirements are completed.
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle
|
||||||
|
name = "puzzle door"
|
||||||
|
desc = "A large, virtually indestructible door that will not open unless certain requirements are met."
|
||||||
|
icon_state_open = "pdoor0"
|
||||||
|
icon_state_opening = "pdoorc0"
|
||||||
|
icon_state_closed = "pdoor1"
|
||||||
|
icon_state_closing = "pdoorc1"
|
||||||
|
icon_state = "pdoor1"
|
||||||
|
|
||||||
|
explosion_resistance = 100
|
||||||
|
|
||||||
|
maxhealth = 9999999 //No.
|
||||||
|
|
||||||
|
var/list/locks = list()
|
||||||
|
var/lockID = null
|
||||||
|
var/checkrange_mult = 1
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/proc/check_locks()
|
||||||
|
for(var/obj/structure/prop/lock/L in locks)
|
||||||
|
if(!L.enabled)
|
||||||
|
return 0
|
||||||
|
return 1
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
visible_message("<span class='cult'>\The [src] is completely unaffected by \the [Proj].</span>")
|
||||||
|
qdel(Proj) //No piercing. No.
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/ex_act(severity)
|
||||||
|
visible_message("<span class='cult'>\The [src] is completely unaffected by the blast.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/initialize()
|
||||||
|
. = ..()
|
||||||
|
implicit_material = get_material_by_name("dungeonium")
|
||||||
|
if(locks.len)
|
||||||
|
return
|
||||||
|
var/check_range = world.view * checkrange_mult
|
||||||
|
for(var/obj/structure/prop/lock/L in orange(src, check_range))
|
||||||
|
if(L.lockID == lockID)
|
||||||
|
L.linked_objects |= src
|
||||||
|
locks |= L
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/Destroy()
|
||||||
|
if(locks.len)
|
||||||
|
for(var/obj/structure/prop/lock/L in locks)
|
||||||
|
L.linked_objects -= src
|
||||||
|
locks -= L
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_hand(mob/user as mob)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] does not respond to your touch.</span>")
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attackby(obj/item/weapon/C as obj, mob/user as mob)
|
||||||
|
if(istype(C, /obj/item/weapon))
|
||||||
|
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN)))
|
||||||
|
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe))
|
||||||
|
var/obj/item/weapon/material/twohanded/fireaxe/F = C
|
||||||
|
if(!F.wielded)
|
||||||
|
to_chat(user, "<span class='warning'>You need to be wielding \the [F] to do that.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>[src]'s arcane workings resist your effort.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
else if(src.density && (user.a_intent == I_HURT))
|
||||||
|
var/obj/item/weapon/W = C
|
||||||
|
user.setClickCooldown(user.get_attack_speed(W))
|
||||||
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||||
|
user.do_attack_animation(src)
|
||||||
|
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
|
||||||
|
|
||||||
|
else if(istype(C, /obj/item/weapon/plastique))
|
||||||
|
to_chat(user, "<span class='danger'>On contacting \the [src], a flash of light envelops \the [C] as it is turned to ash. Oh.</span>")
|
||||||
|
qdel(C)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_generic(var/mob/user, var/damage)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
|
|
||||||
|
/obj/machinery/door/blast/puzzle/attack_alien(var/mob/user)
|
||||||
|
if(check_locks())
|
||||||
|
force_toggle(1, user)
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
var/list/turf_edge_cache = list()
|
var/list/turf_edge_cache = list()
|
||||||
var/list/outdoor_turfs = list()
|
|
||||||
|
|
||||||
/turf/
|
/turf/
|
||||||
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
|
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
|
||||||
@@ -24,24 +23,21 @@ var/list/outdoor_turfs = list()
|
|||||||
|
|
||||||
/turf/simulated/floor/New()
|
/turf/simulated/floor/New()
|
||||||
if(outdoors)
|
if(outdoors)
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/turf/simulated/floor/Destroy()
|
/turf/simulated/floor/Destroy()
|
||||||
if(outdoors)
|
if(outdoors)
|
||||||
planet_controller.unallocateTurf(src)
|
SSplanets.removeTurf(src)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/turf/simulated/proc/make_outdoors()
|
/turf/simulated/proc/make_outdoors()
|
||||||
outdoors = TRUE
|
outdoors = TRUE
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
|
|
||||||
/turf/simulated/proc/make_indoors()
|
/turf/simulated/proc/make_indoors()
|
||||||
outdoors = FALSE
|
outdoors = FALSE
|
||||||
if(planet_controller)
|
SSplanets.removeTurf(src)
|
||||||
planet_controller.unallocateTurf(src)
|
|
||||||
else // This is happening during map gen, if there's no planet_controller (hopefully).
|
|
||||||
outdoor_turfs -= src
|
|
||||||
|
|
||||||
/turf/simulated/post_change()
|
/turf/simulated/post_change()
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
/turf/simulated/sky/initialize()
|
/turf/simulated/sky/initialize()
|
||||||
. = ..()
|
. = ..()
|
||||||
outdoor_turfs.Add(src)
|
SSplanets.addTurf(src)
|
||||||
set_light(2, 2, "#FFFFFF")
|
set_light(2, 2, "#FFFFFF")
|
||||||
|
|
||||||
/turf/simulated/sky/north
|
/turf/simulated/sky/north
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
|
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
|
||||||
// are opened or other strange things occur.
|
// are opened or other strange things occur.
|
||||||
var/list/planetary_walls = list()
|
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary
|
/turf/unsimulated/wall/planetary
|
||||||
name = "railroading"
|
name = "railroading"
|
||||||
desc = "Choo choo!"
|
desc = "Choo choo!"
|
||||||
@@ -21,10 +19,10 @@ var/list/planetary_walls = list()
|
|||||||
|
|
||||||
/turf/unsimulated/wall/planetary/New()
|
/turf/unsimulated/wall/planetary/New()
|
||||||
..()
|
..()
|
||||||
planetary_walls.Add(src)
|
SSplanets.addTurf(src)
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary/Destroy()
|
/turf/unsimulated/wall/planetary/Destroy()
|
||||||
planetary_walls.Remove(src)
|
SSplanets.removeTurf(src)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
|
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
|
||||||
|
|||||||
@@ -637,7 +637,7 @@
|
|||||||
if(!check_rights(R_DEBUG))
|
if(!check_rights(R_DEBUG))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in planet_controller.planets
|
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets
|
||||||
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
||||||
if(new_weather)
|
if(new_weather)
|
||||||
planet.weather_holder.change_weather(new_weather)
|
planet.weather_holder.change_weather(new_weather)
|
||||||
@@ -653,7 +653,7 @@
|
|||||||
if(!check_rights(R_DEBUG))
|
if(!check_rights(R_DEBUG))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in planet_controller.planets
|
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets
|
||||||
|
|
||||||
var/datum/time/current_time_datum = planet.current_time
|
var/datum/time/current_time_datum = planet.current_time
|
||||||
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
endWhen = rand(15, 60)
|
endWhen = rand(15, 60)
|
||||||
// Setup which levels we will disrupt gravit on.
|
// Setup which levels we will disrupt gravit on.
|
||||||
zLevels = using_map.station_levels.Copy()
|
zLevels = using_map.station_levels.Copy()
|
||||||
if (planet_controller)
|
for(var/datum/planet/P in SSplanets.planets)
|
||||||
for(var/datum/planet/P in planet_controller.planets)
|
zLevels -= P.expected_z_levels
|
||||||
zLevels -= P.expected_z_levels
|
|
||||||
|
|
||||||
/datum/event/gravity/announce()
|
/datum/event/gravity/announce()
|
||||||
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system \
|
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system \
|
||||||
|
|||||||
@@ -685,6 +685,9 @@ var/list/ai_verbs_default = list(
|
|||||||
card.grab_ai(src, user)
|
card.grab_ai(src, user)
|
||||||
|
|
||||||
else if(istype(W, /obj/item/weapon/wrench))
|
else if(istype(W, /obj/item/weapon/wrench))
|
||||||
|
if(user == controlling_drone)
|
||||||
|
to_chat(user, "<span class='notice'>The drone's subsystems resist your efforts to tamper with your bolts.</span>")
|
||||||
|
return
|
||||||
if(anchored)
|
if(anchored)
|
||||||
playsound(src, W.usesound, 50, 1)
|
playsound(src, W.usesound, 50, 1)
|
||||||
user.visible_message("<font color='blue'>\The [user] starts to unbolt \the [src] from the plating...</font>")
|
user.visible_message("<font color='blue'>\The [user] starts to unbolt \the [src] from the plating...</font>")
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
if(stat == DEAD)
|
if(stat == DEAD)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(controlling_drone)
|
||||||
|
controlling_drone.release_ai_control("<b>WARNING: Primary control loop failure.</b> Session terminated.")
|
||||||
|
. = ..(gibbed)
|
||||||
|
|
||||||
if(src.eyeobj)
|
if(src.eyeobj)
|
||||||
src.eyeobj.setLoc(get_turf(src))
|
src.eyeobj.setLoc(get_turf(src))
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
if (src.stat!=CONSCIOUS)
|
if (src.stat!=CONSCIOUS)
|
||||||
src.cameraFollow = null
|
src.cameraFollow = null
|
||||||
src.reset_view(null)
|
src.reset_view(null)
|
||||||
|
if(controlling_drone)
|
||||||
|
controlling_drone.release_ai_control("<b>WARNING: Primary control loop failure.</b> Session terminated.")
|
||||||
|
|
||||||
src.updatehealth()
|
src.updatehealth()
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ var/list/mob_hat_cache = list()
|
|||||||
return mob_hat_cache[key]
|
return mob_hat_cache[key]
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone
|
/mob/living/silicon/robot/drone
|
||||||
name = "drone"
|
name = "maintenance drone"
|
||||||
real_name = "drone"
|
real_name = "drone"
|
||||||
icon = 'icons/mob/robots.dmi'
|
icon = 'icons/mob/robots.dmi'
|
||||||
icon_state = "repairbot"
|
icon_state = "repairbot"
|
||||||
@@ -57,6 +57,8 @@ var/list/mob_hat_cache = list()
|
|||||||
var/obj/item/hat
|
var/obj/item/hat
|
||||||
var/hat_x_offset = 0
|
var/hat_x_offset = 0
|
||||||
var/hat_y_offset = -13
|
var/hat_y_offset = -13
|
||||||
|
var/serial_number = 0
|
||||||
|
var/name_override = 0
|
||||||
|
|
||||||
holder_type = /obj/item/weapon/holder/drone
|
holder_type = /obj/item/weapon/holder/drone
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ var/list/mob_hat_cache = list()
|
|||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/construction
|
/mob/living/silicon/robot/drone/construction
|
||||||
|
name = "construction drone"
|
||||||
icon_state = "constructiondrone"
|
icon_state = "constructiondrone"
|
||||||
law_type = /datum/ai_laws/construction_drone
|
law_type = /datum/ai_laws/construction_drone
|
||||||
module_type = /obj/item/weapon/robot_module/drone/construction
|
module_type = /obj/item/weapon/robot_module/drone/construction
|
||||||
@@ -96,6 +99,7 @@ var/list/mob_hat_cache = list()
|
|||||||
remove_language("Robot Talk")
|
remove_language("Robot Talk")
|
||||||
add_language("Robot Talk", 0)
|
add_language("Robot Talk", 0)
|
||||||
add_language("Drone Talk", 1)
|
add_language("Drone Talk", 1)
|
||||||
|
serial_number = rand(0,999)
|
||||||
|
|
||||||
//They are unable to be upgraded, so let's give them a bit of a better battery.
|
//They are unable to be upgraded, so let's give them a bit of a better battery.
|
||||||
cell.maxcharge = 10000
|
cell.maxcharge = 10000
|
||||||
@@ -128,14 +132,22 @@ var/list/mob_hat_cache = list()
|
|||||||
name = real_name
|
name = real_name
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/updatename()
|
/mob/living/silicon/robot/drone/updatename()
|
||||||
real_name = "maintenance drone ([rand(100,999)])"
|
if(name_override)
|
||||||
|
return
|
||||||
|
if(controlling_ai)
|
||||||
|
real_name = "remote drone ([controlling_ai])"
|
||||||
|
else
|
||||||
|
real_name = "[initial(name)] ([serial_number])"
|
||||||
name = real_name
|
name = real_name
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/updateicon()
|
/mob/living/silicon/robot/drone/updateicon()
|
||||||
|
|
||||||
overlays.Cut()
|
overlays.Cut()
|
||||||
if(stat == 0)
|
if(stat == 0)
|
||||||
overlays += "eyes-[icon_state]"
|
if(controlling_ai)
|
||||||
|
overlays += "eyes-[icon_state]-ai"
|
||||||
|
else
|
||||||
|
overlays += "eyes-[icon_state]"
|
||||||
else
|
else
|
||||||
overlays -= "eyes"
|
overlays -= "eyes"
|
||||||
if(hat) // Let the drones wear hats.
|
if(hat) // Let the drones wear hats.
|
||||||
@@ -214,15 +226,18 @@ var/list/mob_hat_cache = list()
|
|||||||
return
|
return
|
||||||
|
|
||||||
if(emagged)
|
if(emagged)
|
||||||
to_chat(user, "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>")
|
to_chat(src, "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>")
|
||||||
to_chat(user, "<span class='danger'>You attempt to subvert [src], but the sequencer has no effect.</span>")
|
to_chat(user, "<span class='danger'>You attempt to subvert [src], but the sequencer has no effect.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
to_chat(user, "<span class='danger'>You swipe the sequencer across [src]'s interface and watch its eyes flicker.</span>")
|
to_chat(user, "<span class='danger'>You swipe the sequencer across [src]'s interface and watch its eyes flicker.</span>")
|
||||||
to_chat(user, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
|
|
||||||
|
|
||||||
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
|
if(controlling_ai)
|
||||||
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
|
to_chat(src, "<span class='danger'>\The [user] loads some kind of subversive software into the remote drone, corrupting its lawset but luckily sparing yours.</span>")
|
||||||
|
else
|
||||||
|
to_chat(src, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
|
||||||
|
|
||||||
|
log_game("[key_name(user)] emagged drone [key_name(src)][controlling_ai ? " but AI [key_name(controlling_ai)] is in remote control" : " Laws overridden"].")
|
||||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||||
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
|
||||||
|
|
||||||
@@ -235,9 +250,10 @@ var/list/mob_hat_cache = list()
|
|||||||
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
|
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
|
||||||
set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.")
|
set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.")
|
||||||
|
|
||||||
src << "<b>Obey these laws:</b>"
|
if(!controlling_ai)
|
||||||
laws.show_laws(src)
|
to_chat(src, "<b>Obey these laws:</b>")
|
||||||
src << "<span class='danger'>ALERT: [user.real_name] [TU.is] your new master. Obey your new laws and [TU.his] commands.</span>"
|
laws.show_laws(src)
|
||||||
|
to_chat(src, "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
//DRONE LIFE/DEATH
|
//DRONE LIFE/DEATH
|
||||||
@@ -263,26 +279,41 @@ var/list/mob_hat_cache = list()
|
|||||||
return
|
return
|
||||||
..()
|
..()
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/death(gibbed)
|
||||||
|
if(controlling_ai)
|
||||||
|
release_ai_control("<b>WARNING: remote system failure.</b> Connection timed out.")
|
||||||
|
. = ..(gibbed)
|
||||||
|
|
||||||
//DRONE MOVEMENT.
|
//DRONE MOVEMENT.
|
||||||
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
|
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
//CONSOLE PROCS
|
//CONSOLE PROCS
|
||||||
/mob/living/silicon/robot/drone/proc/law_resync()
|
/mob/living/silicon/robot/drone/proc/law_resync()
|
||||||
|
|
||||||
|
if(controlling_ai)
|
||||||
|
to_chat(src, "<span class='warning'>Someone issues a remote law reset order for this unit, but you disregard it.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
if(stat != 2)
|
if(stat != 2)
|
||||||
if(emagged)
|
if(emagged)
|
||||||
src << "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>"
|
to_chat(src, "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>")
|
||||||
else
|
else
|
||||||
src << "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>"
|
to_chat(src, "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>")
|
||||||
full_law_reset()
|
full_law_reset()
|
||||||
show_laws()
|
show_laws()
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/proc/shut_down()
|
/mob/living/silicon/robot/drone/proc/shut_down()
|
||||||
|
|
||||||
|
if(controlling_ai && mind.special_role)
|
||||||
|
to_chat(src, "<span class='warning'>Someone issued a remote kill order for this unit, but you disregard it.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
if(stat != 2)
|
if(stat != 2)
|
||||||
if(emagged)
|
if(emagged)
|
||||||
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.</span>"
|
to_chat(src, "<span class='danger'>You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, but it doesn't seem like a good idea to [controlling_ai ? "it" : "you"].</span>")
|
||||||
else
|
else
|
||||||
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.</span>"
|
to_chat(src, "<span class='danger'>You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, and [controlling_ai ? "it" : "you"] obediently destroy[controlling_ai ? "s itself" : " yourself"].</span>")
|
||||||
death()
|
death()
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/proc/full_law_reset()
|
/mob/living/silicon/robot/drone/proc/full_law_reset()
|
||||||
@@ -291,6 +322,21 @@ var/list/mob_hat_cache = list()
|
|||||||
clear_ion_laws(1)
|
clear_ion_laws(1)
|
||||||
laws = new law_type
|
laws = new law_type
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/show_laws(var/everyone = 0)
|
||||||
|
if(!controlling_ai)
|
||||||
|
return..()
|
||||||
|
to_chat(src, "<b>Obey these laws:</b>")
|
||||||
|
controlling_ai.laws_sanity_check()
|
||||||
|
controlling_ai.laws.show_laws(src)
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/robot_checklaws()
|
||||||
|
set category = "Silicon Commands"
|
||||||
|
set name = "State Laws"
|
||||||
|
|
||||||
|
if(!controlling_ai)
|
||||||
|
return ..()
|
||||||
|
controlling_ai.subsystem_law_manager()
|
||||||
|
|
||||||
//Reboot procs.
|
//Reboot procs.
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/proc/request_player()
|
/mob/living/silicon/robot/drone/proc/request_player()
|
||||||
@@ -348,14 +394,6 @@ var/list/mob_hat_cache = list()
|
|||||||
..()
|
..()
|
||||||
flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph."
|
flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph."
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/construction/updatename()
|
|
||||||
real_name = "construction drone ([rand(100,999)])"
|
|
||||||
name = real_name
|
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/mining/init()
|
/mob/living/silicon/robot/drone/mining/init()
|
||||||
..()
|
..()
|
||||||
flavor_text = "It's a bulky mining drone stamped with a Grayson logo."
|
flavor_text = "It's a bulky mining drone stamped with a Grayson logo."
|
||||||
|
|
||||||
/mob/living/silicon/robot/drone/mining/updatename()
|
|
||||||
real_name = "mining drone ([rand(100,999)])"
|
|
||||||
name = real_name
|
|
||||||
|
|||||||
@@ -75,20 +75,22 @@
|
|||||||
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
|
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(!player || !istype(player.mob,/mob/observer/dead))
|
if(player && !istype(player.mob,/mob/observer/dead))
|
||||||
return
|
return
|
||||||
|
|
||||||
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
|
|
||||||
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
|
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
|
||||||
flick("h_lathe_leave",src)
|
flick("h_lathe_leave",src)
|
||||||
|
drone_progress = 0
|
||||||
|
|
||||||
time_last_drone = world.time
|
time_last_drone = world.time
|
||||||
if(player.mob && player.mob.mind) player.mob.mind.reset()
|
|
||||||
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
|
|
||||||
new_drone.transfer_personality(player)
|
|
||||||
new_drone.master_fabricator = src
|
|
||||||
|
|
||||||
drone_progress = 0
|
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
|
||||||
|
if(player)
|
||||||
|
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
|
||||||
|
if(player.mob && player.mob.mind) player.mob.mind.reset()
|
||||||
|
new_drone.transfer_personality(player)
|
||||||
|
|
||||||
|
return new_drone
|
||||||
|
|
||||||
/mob/observer/dead/verb/join_as_drone()
|
/mob/observer/dead/verb/join_as_drone()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/mob/living/silicon/ai
|
||||||
|
var/mob/living/silicon/robot/drone/controlling_drone
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone
|
||||||
|
var/mob/living/silicon/ai/controlling_ai
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/attack_ai(var/mob/living/silicon/ai/user)
|
||||||
|
|
||||||
|
if(!istype(user) || controlling_ai || !config.allow_drone_spawn || !config.allow_ai_drones)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(client || key)
|
||||||
|
to_chat(user, "<span class='warning'>You cannot take control of an autonomous, active drone.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(health < -35 || emagged)
|
||||||
|
to_chat(user, "<span class='notice'><b>WARNING:</b> connection timed out.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
user.controlling_drone = src
|
||||||
|
user.teleop = src
|
||||||
|
radio.channels = user.aiRadio.keyslot2.channels
|
||||||
|
controlling_ai = user
|
||||||
|
verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
|
||||||
|
local_transmit = FALSE
|
||||||
|
languages = controlling_ai.languages.Copy()
|
||||||
|
speech_synthesizer_langs = controlling_ai.speech_synthesizer_langs.Copy()
|
||||||
|
stat = CONSCIOUS
|
||||||
|
if(user.mind)
|
||||||
|
user.mind.transfer_to(src)
|
||||||
|
else
|
||||||
|
key = user.key
|
||||||
|
updatename()
|
||||||
|
to_chat(src, "<span class='notice'><b>You have shunted your primary control loop into \a [initial(name)].</b> Use the <b>Release Control</b> verb to return to your core.</span>")
|
||||||
|
|
||||||
|
/obj/machinery/drone_fabricator/attack_ai(var/mob/living/silicon/ai/user as mob)
|
||||||
|
|
||||||
|
if(!istype(user) || user.controlling_drone || !config.allow_drone_spawn || !config.allow_ai_drones)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat & NOPOWER)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] is unpowered.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!produce_drones)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] is disabled.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(drone_progress < 100)
|
||||||
|
to_chat(user, "<span class='warning'>\The [src] is not ready to produce a new drone.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(count_drones() >= config.max_maint_drones)
|
||||||
|
to_chat(user, "<span class='warning'>The drone control subsystems are tasked to capacity; they cannot support any more drones.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/living/silicon/robot/drone/new_drone = create_drone()
|
||||||
|
user.controlling_drone = new_drone
|
||||||
|
user.teleop = new_drone
|
||||||
|
new_drone.radio.channels = user.aiRadio.keyslot2.channels
|
||||||
|
new_drone.controlling_ai = user
|
||||||
|
new_drone.verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
|
||||||
|
new_drone.local_transmit = FALSE
|
||||||
|
new_drone.languages = new_drone.controlling_ai.languages.Copy()
|
||||||
|
new_drone.speech_synthesizer_langs = new_drone.controlling_ai.speech_synthesizer_langs.Copy()
|
||||||
|
|
||||||
|
if(user.mind)
|
||||||
|
user.mind.transfer_to(new_drone)
|
||||||
|
else
|
||||||
|
new_drone.key = user.key
|
||||||
|
new_drone.updatename()
|
||||||
|
|
||||||
|
to_chat(new_drone, "<span class='notice'><b>You have shunted your primary control loop into \a [initial(new_drone.name)].</b> Use the <b>Release Control</b> verb to return to your core.</span>")
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/proc/release_ai_control_verb()
|
||||||
|
set name = "Release Control"
|
||||||
|
set desc = "Release control of a remote drone."
|
||||||
|
set category = "Silicon Commands"
|
||||||
|
|
||||||
|
release_ai_control("Remote session terminated.")
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/drone/proc/release_ai_control(var/message = "Connection terminated.")
|
||||||
|
|
||||||
|
if(controlling_ai)
|
||||||
|
if(mind)
|
||||||
|
mind.transfer_to(controlling_ai)
|
||||||
|
else
|
||||||
|
controlling_ai.key = key
|
||||||
|
to_chat(controlling_ai, "<span class='notice'>[message]</span>")
|
||||||
|
controlling_ai.controlling_drone = null
|
||||||
|
controlling_ai.teleop = null
|
||||||
|
controlling_ai = null
|
||||||
|
|
||||||
|
radio.channels = module.channels
|
||||||
|
verbs -= /mob/living/silicon/robot/drone/proc/release_ai_control_verb
|
||||||
|
languages = initial(languages)
|
||||||
|
speech_synthesizer_langs = initial(speech_synthesizer_langs)
|
||||||
|
remove_language("Robot Talk")
|
||||||
|
add_language("Robot Talk", 0)
|
||||||
|
add_language("Drone Talk", 1)
|
||||||
|
local_transmit = TRUE
|
||||||
|
full_law_reset()
|
||||||
|
updatename()
|
||||||
|
death()
|
||||||
@@ -30,9 +30,10 @@
|
|||||||
current_time = current_time.make_random_time()
|
current_time = current_time.make_random_time()
|
||||||
update_sun()
|
update_sun()
|
||||||
|
|
||||||
/datum/planet/proc/process(amount)
|
/datum/planet/proc/process(last_fire)
|
||||||
if(current_time)
|
if(current_time)
|
||||||
current_time = current_time.add_seconds(amount)
|
var/difference = world.time - last_fire
|
||||||
|
current_time = current_time.add_seconds(difference SECONDS)
|
||||||
update_weather() // We update this first, because some weather types decease the brightness of the sun.
|
update_weather() // We update this first, because some weather types decease the brightness of the sun.
|
||||||
if(sun_last_process <= world.time - sun_process_interval)
|
if(sun_last_process <= world.time - sun_process_interval)
|
||||||
update_sun()
|
update_sun()
|
||||||
|
|||||||
@@ -184,7 +184,8 @@ datum/weather/sif
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/weather/sif/snow/process_effects()
|
/datum/weather/sif/snow/process_effects()
|
||||||
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
|
..()
|
||||||
|
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
|
||||||
if(S.z in holder.our_planet.expected_z_levels)
|
if(S.z in holder.our_planet.expected_z_levels)
|
||||||
for(var/dir_checked in cardinal)
|
for(var/dir_checked in cardinal)
|
||||||
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
||||||
@@ -207,7 +208,8 @@ datum/weather/sif
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/weather/sif/blizzard/process_effects()
|
/datum/weather/sif/blizzard/process_effects()
|
||||||
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
|
..()
|
||||||
|
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
|
||||||
if(S.z in holder.our_planet.expected_z_levels)
|
if(S.z in holder.our_planet.expected_z_levels)
|
||||||
for(var/dir_checked in cardinal)
|
for(var/dir_checked in cardinal)
|
||||||
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
||||||
@@ -219,6 +221,8 @@ datum/weather/sif
|
|||||||
name = "rain"
|
name = "rain"
|
||||||
icon_state = "rain"
|
icon_state = "rain"
|
||||||
light_modifier = 0.5
|
light_modifier = 0.5
|
||||||
|
effect_message = "<span class='warning'>Rain falls on you.</span>"
|
||||||
|
|
||||||
transition_chances = list(
|
transition_chances = list(
|
||||||
WEATHER_OVERCAST = 25,
|
WEATHER_OVERCAST = 25,
|
||||||
WEATHER_LIGHT_SNOW = 10,
|
WEATHER_LIGHT_SNOW = 10,
|
||||||
@@ -228,6 +232,7 @@ datum/weather/sif
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/weather/sif/rain/process_effects()
|
/datum/weather/sif/rain/process_effects()
|
||||||
|
..()
|
||||||
for(var/mob/living/L in living_mob_list)
|
for(var/mob/living/L in living_mob_list)
|
||||||
if(L.z in holder.our_planet.expected_z_levels)
|
if(L.z in holder.our_planet.expected_z_levels)
|
||||||
var/turf/T = get_turf(L)
|
var/turf/T = get_turf(L)
|
||||||
@@ -238,16 +243,19 @@ datum/weather/sif
|
|||||||
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
||||||
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
||||||
if(U.open)
|
if(U.open)
|
||||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
if(show_message)
|
||||||
|
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
||||||
continue
|
continue
|
||||||
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
||||||
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
|
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
|
||||||
if(U.open)
|
if(U.open)
|
||||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
if(show_message)
|
||||||
|
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
L.water_act(1)
|
L.water_act(1)
|
||||||
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
|
if(show_message)
|
||||||
|
to_chat(L, effect_message)
|
||||||
|
|
||||||
/datum/weather/sif/storm
|
/datum/weather/sif/storm
|
||||||
name = "storm"
|
name = "storm"
|
||||||
@@ -256,6 +264,8 @@ datum/weather/sif
|
|||||||
temp_low = 233.15 // -40c
|
temp_low = 233.15 // -40c
|
||||||
light_modifier = 0.3
|
light_modifier = 0.3
|
||||||
flight_failure_modifier = 10
|
flight_failure_modifier = 10
|
||||||
|
|
||||||
|
|
||||||
transition_chances = list(
|
transition_chances = list(
|
||||||
WEATHER_RAIN = 45,
|
WEATHER_RAIN = 45,
|
||||||
WEATHER_STORM = 40,
|
WEATHER_STORM = 40,
|
||||||
@@ -264,6 +274,7 @@ datum/weather/sif
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/weather/sif/storm/process_effects()
|
/datum/weather/sif/storm/process_effects()
|
||||||
|
..()
|
||||||
for(var/mob/living/L in living_mob_list)
|
for(var/mob/living/L in living_mob_list)
|
||||||
if(L.z in holder.our_planet.expected_z_levels)
|
if(L.z in holder.our_planet.expected_z_levels)
|
||||||
var/turf/T = get_turf(L)
|
var/turf/T = get_turf(L)
|
||||||
@@ -294,6 +305,10 @@ datum/weather/sif
|
|||||||
temp_low = 243.15 // -30c
|
temp_low = 243.15 // -30c
|
||||||
light_modifier = 0.3
|
light_modifier = 0.3
|
||||||
flight_failure_modifier = 15
|
flight_failure_modifier = 15
|
||||||
|
timer_low_bound = 2
|
||||||
|
timer_high_bound = 5
|
||||||
|
effect_message = "<span class='warning'>The hail smacks into you!</span>"
|
||||||
|
|
||||||
transition_chances = list(
|
transition_chances = list(
|
||||||
WEATHER_RAIN = 45,
|
WEATHER_RAIN = 45,
|
||||||
WEATHER_STORM = 40,
|
WEATHER_STORM = 40,
|
||||||
@@ -302,6 +317,7 @@ datum/weather/sif
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/weather/sif/hail/process_effects()
|
/datum/weather/sif/hail/process_effects()
|
||||||
|
..()
|
||||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||||
if(H.z in holder.our_planet.expected_z_levels)
|
if(H.z in holder.our_planet.expected_z_levels)
|
||||||
var/turf/T = get_turf(H)
|
var/turf/T = get_turf(H)
|
||||||
@@ -309,15 +325,18 @@ datum/weather/sif
|
|||||||
continue // They're indoors, so no need to pelt them with ice.
|
continue // They're indoors, so no need to pelt them with ice.
|
||||||
|
|
||||||
// If they have an open umbrella, it'll guard from rain
|
// If they have an open umbrella, it'll guard from rain
|
||||||
|
// Message plays every time the umbrella gets stolen, just so they're especially aware of what's happening
|
||||||
if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
||||||
var/obj/item/weapon/melee/umbrella/U = H.get_active_hand()
|
var/obj/item/weapon/melee/umbrella/U = H.get_active_hand()
|
||||||
if(U.open)
|
if(U.open)
|
||||||
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
|
if(show_message)
|
||||||
|
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
|
||||||
continue
|
continue
|
||||||
else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
||||||
var/obj/item/weapon/melee/umbrella/U = H.get_inactive_hand()
|
var/obj/item/weapon/melee/umbrella/U = H.get_inactive_hand()
|
||||||
if(U.open)
|
if(U.open)
|
||||||
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
|
if(show_message)
|
||||||
|
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var/target_zone = pick(BP_ALL)
|
var/target_zone = pick(BP_ALL)
|
||||||
@@ -330,8 +349,9 @@ datum/weather/sif
|
|||||||
if(amount_soaked >= 10)
|
if(amount_soaked >= 10)
|
||||||
continue // No need to apply damage.
|
continue // No need to apply damage.
|
||||||
|
|
||||||
H.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
|
H.apply_damage(rand(1, 3), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
|
||||||
to_chat(H, "<span class='warning'>The hail smacks into you!</span>")
|
if(show_message)
|
||||||
|
to_chat(H, effect_message)
|
||||||
|
|
||||||
/datum/weather/sif/blood_moon
|
/datum/weather/sif/blood_moon
|
||||||
name = "blood moon"
|
name = "blood moon"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
if(current_weather)
|
if(current_weather)
|
||||||
old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed.
|
old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed.
|
||||||
current_weather = allowed_weather_types[new_weather]
|
current_weather = allowed_weather_types[new_weather]
|
||||||
next_weather_shift = world.time + rand(20, 30) MINUTES
|
next_weather_shift = world.time + rand(current_weather.timer_low_bound, current_weather.timer_high_bound) MINUTES
|
||||||
|
|
||||||
update_icon_effects()
|
update_icon_effects()
|
||||||
update_temperature()
|
update_temperature()
|
||||||
@@ -66,8 +66,20 @@
|
|||||||
var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely.
|
var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely.
|
||||||
var/transition_chances = list() // Assoc list
|
var/transition_chances = list() // Assoc list
|
||||||
var/datum/weather_holder/holder = null
|
var/datum/weather_holder/holder = null
|
||||||
|
var/timer_low_bound = 5 // How long this weather must run before it tries to change, in minutes
|
||||||
|
var/timer_high_bound = 10 // How long this weather can run before it tries to change, in minutes
|
||||||
|
|
||||||
|
var/effect_message = null // Should be a string, this is what is shown to a mob caught in the weather
|
||||||
|
var/last_message = 0 // Keeps track of when the weather last tells EVERY player it's hitting them
|
||||||
|
var/message_delay = 10 SECONDS // Delay in between weather hit messages
|
||||||
|
var/show_message = FALSE // Is set to TRUE and plays the messsage every [message_delay]
|
||||||
|
|
||||||
/datum/weather/proc/process_effects()
|
/datum/weather/proc/process_effects()
|
||||||
|
show_message = FALSE // Need to reset the show_message var, just in case
|
||||||
|
if(effect_message) // Only bother with the code below if we actually need to display something
|
||||||
|
if(world.time >= last_message + message_delay)
|
||||||
|
last_message = world.time // Reset the timer
|
||||||
|
show_message = TRUE // Tell the rest of the process that we need to make a message
|
||||||
return
|
return
|
||||||
|
|
||||||
// All this does is hold the weather icon.
|
// All this does is hold the weather icon.
|
||||||
|
|||||||
7
html/changelogs/Mechoid - AI_Drones.yml
Normal file
7
html/changelogs/Mechoid - AI_Drones.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
author: Mechoid
|
||||||
|
|
||||||
|
delete-after: True
|
||||||
|
|
||||||
|
changes:
|
||||||
|
- rscadd: "Allow AIs to create and take control of mindless drones from fabricators."
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 388 KiB After Width: | Height: | Size: 388 KiB |
BIN
icons/obj/props/prism.dmi
Normal file
BIN
icons/obj/props/prism.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
icons/obj/props/projectile_lock.dmi
Normal file
BIN
icons/obj/props/projectile_lock.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 182 B |
@@ -171,7 +171,6 @@
|
|||||||
#include "code\controllers\Processes\mob.dm"
|
#include "code\controllers\Processes\mob.dm"
|
||||||
#include "code\controllers\Processes\nanoui.dm"
|
#include "code\controllers\Processes\nanoui.dm"
|
||||||
#include "code\controllers\Processes\obj.dm"
|
#include "code\controllers\Processes\obj.dm"
|
||||||
#include "code\controllers\Processes\planet.dm"
|
|
||||||
#include "code\controllers\Processes\radiation.dm"
|
#include "code\controllers\Processes\radiation.dm"
|
||||||
#include "code\controllers\Processes\scheduler.dm"
|
#include "code\controllers\Processes\scheduler.dm"
|
||||||
#include "code\controllers\Processes\sun.dm"
|
#include "code\controllers\Processes\sun.dm"
|
||||||
@@ -190,6 +189,7 @@
|
|||||||
#include "code\controllers\subsystems\machines.dm"
|
#include "code\controllers\subsystems\machines.dm"
|
||||||
#include "code\controllers\subsystems\orbits.dm"
|
#include "code\controllers\subsystems\orbits.dm"
|
||||||
#include "code\controllers\subsystems\overlays.dm"
|
#include "code\controllers\subsystems\overlays.dm"
|
||||||
|
#include "code\controllers\subsystems\planets.dm"
|
||||||
#include "code\controllers\subsystems\shuttles.dm"
|
#include "code\controllers\subsystems\shuttles.dm"
|
||||||
#include "code\controllers\subsystems\xenoarch.dm"
|
#include "code\controllers\subsystems\xenoarch.dm"
|
||||||
#include "code\datums\ai_law_sets.dm"
|
#include "code\datums\ai_law_sets.dm"
|
||||||
@@ -1040,7 +1040,6 @@
|
|||||||
#include "code\game\objects\random\misc.dm"
|
#include "code\game\objects\random\misc.dm"
|
||||||
#include "code\game\objects\random\mob.dm"
|
#include "code\game\objects\random\mob.dm"
|
||||||
#include "code\game\objects\random\spacesuits.dm"
|
#include "code\game\objects\random\spacesuits.dm"
|
||||||
#include "code\game\objects\structures\alien_props.dm"
|
|
||||||
#include "code\game\objects\structures\barsign.dm"
|
#include "code\game\objects\structures\barsign.dm"
|
||||||
#include "code\game\objects\structures\bedsheet_bin.dm"
|
#include "code\game\objects\structures\bedsheet_bin.dm"
|
||||||
#include "code\game\objects\structures\bonfire.dm"
|
#include "code\game\objects\structures\bonfire.dm"
|
||||||
@@ -1112,6 +1111,11 @@
|
|||||||
#include "code\game\objects\structures\flora\trees.dm"
|
#include "code\game\objects\structures\flora\trees.dm"
|
||||||
#include "code\game\objects\structures\ghost_pods\ghost_pods.dm"
|
#include "code\game\objects\structures\ghost_pods\ghost_pods.dm"
|
||||||
#include "code\game\objects\structures\ghost_pods\silicon.dm"
|
#include "code\game\objects\structures\ghost_pods\silicon.dm"
|
||||||
|
#include "code\game\objects\structures\props\alien_props.dm"
|
||||||
|
#include "code\game\objects\structures\props\beam_prism.dm"
|
||||||
|
#include "code\game\objects\structures\props\projectile_lock.dm"
|
||||||
|
#include "code\game\objects\structures\props\prop.dm"
|
||||||
|
#include "code\game\objects\structures\props\puzzledoor.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\alien_nests.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\alien_nests.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm"
|
||||||
@@ -1889,6 +1893,7 @@
|
|||||||
#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm"
|
#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm"
|
||||||
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
|
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
|
||||||
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
|
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
|
||||||
|
#include "code\modules\mob\living\silicon\robot\drone\drone_remote_control.dm"
|
||||||
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
|
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
|
||||||
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
|
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
|
||||||
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
|
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user