mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 20:47:10 +01:00
Merge remote-tracking branch 'ParadiseSS13/master' into GoOnYourFeet
This commit is contained in:
@@ -1337,7 +1337,7 @@
|
||||
"azK" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/fitness)
|
||||
"azL" = (/turf/simulated/wall,/area/mimeoffice)
|
||||
"azM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/spray/waterflower,/turf/simulated/floor/wood,/area/mimeoffice)
|
||||
"azN" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/item/weapon/paper_bin,/obj/item/toy/crayon/mime,/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/wood,/area/mimeoffice)
|
||||
"azN" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/item/weapon/paper_bin,/obj/item/toy/crayon/mime,/turf/simulated/floor/wood,/area/mimeoffice)
|
||||
"azO" = (/obj/machinery/camera{c_tag = "Magistrate's Office"; dir = 4; network = list("SS13")},/turf/simulated/floor/carpet,/area/magistrateoffice)
|
||||
"azP" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/carpet,/area/magistrateoffice)
|
||||
"azQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet,/area/magistrateoffice)
|
||||
|
||||
@@ -134,6 +134,11 @@
|
||||
|
||||
#define RESIZE_DEFAULT_SIZE 1
|
||||
|
||||
//transfer_ai() defines. Main proc in ai_core.dm
|
||||
#define AI_TRANS_TO_CARD 1 //Downloading AI to InteliCard.
|
||||
#define AI_TRANS_FROM_CARD 2 //Uploading AI from InteliCard
|
||||
#define AI_MECH_HACK 3 //Malfunctioning AI hijacking mecha
|
||||
|
||||
//singularity defines
|
||||
#define STAGE_ONE 1
|
||||
#define STAGE_TWO 3
|
||||
|
||||
@@ -17,6 +17,6 @@ var/global/list/table_recipes = list() //list of all table craft recipes
|
||||
|
||||
var/global/list/all_areas = list()
|
||||
var/global/list/machines = list()
|
||||
var/global/list/processing_power_items = list()
|
||||
//items that ask to be called every cycle
|
||||
var/global/list/processing_power_items = list() //items that ask to be called every cycle
|
||||
var/global/list/rcd_list = list() //list of Rapid Construction Devices.
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
return
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden.
|
||||
controlled_mech.click_action(A, src) //Override AI normal click behavior.
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
|
||||
@@ -279,7 +279,7 @@ var/global/datum/shuttle_controller/shuttle_controller
|
||||
)
|
||||
|
||||
WS.announcer = "NSV Icarus"
|
||||
WS.arrival_message = "Attention, [station_name()], we just tracked a large medical vessel approaching the station from the telecommunications satellite. Can't fire on them without hitting the station - prepare for visitors."
|
||||
WS.arrival_message = "Attention, [station_name()], we just tracked a large medical vessel approaching the station from the telecommunications satellite. Might have wounded on board, can't destroy it - prepare for visitors."
|
||||
WS.departure_message = "Your guests are pulling away, [station_name()] - moving too fast for us to draw a bead on them. Looks like they're heading back to the telecommunications satellite."
|
||||
WS.interim = locate(/area/shuttle/derelict/ship/transit)
|
||||
|
||||
|
||||
+20
-22
@@ -141,7 +141,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/jobspecific/syndidonk
|
||||
name = "Syndicate Donk Pockets"
|
||||
desc = "A box of highly specialized donk pockets with a number of regenerative and stimulating chemicals inside of them; the box comes equipped with a self-heating mechanism."
|
||||
desc = "A box of highly specialized Donk pockets with a number of regenerative and stimulating chemicals inside of them; the box comes equipped with a self-heating mechanism."
|
||||
reference = "SDP"
|
||||
item = /obj/item/weapon/storage/box/syndidonkpockets
|
||||
cost = 2
|
||||
@@ -162,7 +162,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/jobspecific/rad_laser
|
||||
name = "Radiation Laser"
|
||||
desc = "A radiation laser concealed inside of a Health Analyser, After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!"
|
||||
desc = "A radiation laser concealed inside of a Health Analyser. After a moderate delay, causes temporary collapse and radiation. Has adjustable controls, but will not function as a regular health analyser, only appears like one. May not function correctly on radiation resistant humanoids!"
|
||||
reference = "RL"
|
||||
item = /obj/item/device/rad_laser
|
||||
cost = 6
|
||||
@@ -270,7 +270,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/car
|
||||
name = "C-90gl Compact Assault Rifle"
|
||||
desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a togglable underslung 40mm grenade launcher."
|
||||
desc = "A fully-loaded Zashchita Industriya toploading bullpup assault rifle that uses 30-round 5.45x39mm magazines with a toggleable underslung 40mm grenade launcher."
|
||||
reference = "AR"
|
||||
item = /obj/item/weapon/gun/projectile/automatic/c90gl
|
||||
cost = 18
|
||||
@@ -297,7 +297,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/flamethrower
|
||||
name = "Flamethrower"
|
||||
desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen stations. Make a statement by roasting the filth in their own greed. Use with caution."
|
||||
desc = "A flamethrower, fuelled by a portion of highly flammable bio-toxins stolen previously from Nanotrasen stations. Make a statement by roasting the filth in their own greed. Use with caution."
|
||||
reference = "FT"
|
||||
item = /obj/item/weapon/flamethrower/full/tank
|
||||
cost = 11
|
||||
@@ -306,7 +306,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/sword
|
||||
name = "Energy Sword"
|
||||
desc = "The esword is an edged weapon with a blade of pure energy. The sword is small enough to be pocketed when inactive. Activating it produces a loud, distinctive noise."
|
||||
desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be pocketed when inactive. Activating it produces a loud, distinctive noise."
|
||||
reference = "ES"
|
||||
item = /obj/item/weapon/melee/energy/sword
|
||||
cost = 8
|
||||
@@ -329,7 +329,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/tabungrenades
|
||||
name = "Tabun Gas Grenades"
|
||||
desc = "A box of four (4) grenades filled with tabun, a deadly neurotoxin. Use extreme caution when handling and be sure to vacate the premise after using; ensure communication is maintaind with team to avoid accidental gassings."
|
||||
desc = "A box of four (4) grenades filled with Tabun, a deadly neurotoxin. Use extreme caution when handling and be sure to vacate the premise after using; ensure communication is maintained with team to avoid accidental gassings."
|
||||
reference = "TGG"
|
||||
item = /obj/item/weapon/storage/box/syndie_kit/tabun
|
||||
cost = 15
|
||||
@@ -345,7 +345,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/syndicate_minibomb
|
||||
name = "Syndicate Minibomb"
|
||||
desc = "The Minibomb is a grenade with a five-second fuse."
|
||||
desc = "The minibomb is a grenade with a five-second fuse."
|
||||
reference = "SMB"
|
||||
item = /obj/item/weapon/grenade/syndieminibomb
|
||||
cost = 6
|
||||
@@ -362,7 +362,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/dangerous/mauler
|
||||
name = "Mauler Exosuit"
|
||||
desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targetting, thrust vectoring, and deployable smoke."
|
||||
desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targeting, thrust vectoring, and deployable smoke."
|
||||
reference = "ME"
|
||||
item = /obj/mecha/combat/marauder/mauler/loaded
|
||||
cost = 140
|
||||
@@ -453,8 +453,8 @@ var/list/uplink_items = list()
|
||||
gamemodes = list("nuclear emergency")
|
||||
|
||||
/datum/uplink_item/ammo/machinegun
|
||||
name = "Box Magazine - 7.62×51mm"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machinegun. By the time you need to use this, you'll already be on a pile of corpses."
|
||||
name = "Box Magazine - 7.62x51mm"
|
||||
desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses."
|
||||
reference = "762"
|
||||
item = /obj/item/ammo_box/magazine/m762
|
||||
cost = 12
|
||||
@@ -489,8 +489,6 @@ var/list/uplink_items = list()
|
||||
item = /obj/item/weapon/cartridge/syndicate
|
||||
cost = 6
|
||||
|
||||
// Commented out until a fix can be found, currently doesn't work with the PDA NanoUI and people keep wasting Telecrystals on it. -- Dave
|
||||
|
||||
/datum/uplink_item/stealthy_weapons/silencer
|
||||
name = "Universal Suppressor"
|
||||
desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the shots of the weapon for increased stealth and superior ambushing capability."
|
||||
@@ -528,7 +526,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon_stamp
|
||||
name = "Chameleon Stamp"
|
||||
desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp™. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \
|
||||
desc = "A stamp that can be activated to imitate an official Nanotrasen Stamp. The disguised stamp will work exactly like the real stamp and will allow you to forge false documents to gain access or equipment; \
|
||||
it can also be used in a washing machine to forge clothing."
|
||||
reference = "CHST"
|
||||
item = /obj/item/weapon/stamp/chameleon
|
||||
@@ -551,14 +549,14 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/stealthy_tools/voice_changer
|
||||
name = "Voice Changer"
|
||||
desc = "A conspicuous gas mask that mimics the voice named on your identification card. When no identification is worn, the mask will render your voice unrecognizable."
|
||||
desc = "A conspicuous gas mask that mimics the voice named on your identification card. When no identification is worn, the mask will render your voice unrecognisable."
|
||||
reference = "VC"
|
||||
item = /obj/item/clothing/mask/gas/voice
|
||||
cost = 5
|
||||
|
||||
/datum/uplink_item/stealthy_tools/chameleon_proj
|
||||
name = "Chameleon-Projector"
|
||||
desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and rojectiles pass over them."
|
||||
desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't move the projector from their hand. The disguised user cannot run and projectiles pass over them."
|
||||
reference = "CP"
|
||||
item = /obj/item/device/chameleon
|
||||
cost = 7
|
||||
@@ -594,7 +592,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/device_tools/emag
|
||||
name = "Cryptographic Sequencer"
|
||||
desc = "The emag is a small card that unlocks hidden functions in electronic devices, subverts intended functions and characteristically breaks security mechanisms."
|
||||
desc = "The cryptographic sequencer, also known as an emag, is a small card that unlocks hidden functions in electronic devices, subverts intended functions and characteristically breaks security mechanisms."
|
||||
reference = "EMAG"
|
||||
item = /obj/item/weapon/card/emag
|
||||
cost = 6
|
||||
@@ -609,7 +607,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/device_tools/medkit
|
||||
name = "Syndicate Combat Medic Kit"
|
||||
desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \
|
||||
desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical HUD for quick identification of injured comrades, \
|
||||
and other medical supplies helpful for a medical field operative."
|
||||
reference = "SCMK"
|
||||
item = /obj/item/weapon/storage/firstaid/tactical
|
||||
@@ -632,8 +630,8 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/device_tools/hardsuit
|
||||
name = "Blood-red Hardsuit"
|
||||
desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring. When the helmet is deployed your identity will be protected. Toggling the suit into combat mode \
|
||||
will allow you all the mobility of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \
|
||||
desc = "The feared suit of a syndicate nuclear agent. Features slightly better armor. When the helmet is deployed your identity will be protected. Toggling the suit into combat mode \
|
||||
will allow you all the mobility of a loose fitting uniform without sacrificing armor. Additionally the suit is collapsible, small enough to fit within a backpack. \
|
||||
Nanotrasen crewmembers are trained to report red space suit sightings, these suits in particular are known to drive employees into a panic."
|
||||
reference = "BRHS"
|
||||
item = /obj/item/weapon/storage/box/syndie_kit/hardsuit
|
||||
@@ -641,7 +639,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/device_tools/thermal
|
||||
name = "Thermal Imaging Glasses"
|
||||
desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
|
||||
desc = "These glasses are thermals disguised as engineers' optical meson scanners. They allow you to see organisms through walls by capturing the upper portion of the infra-red light spectrum, emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks."
|
||||
reference = "THIG"
|
||||
item = /obj/item/clothing/glasses/thermal/syndi
|
||||
cost = 6
|
||||
@@ -680,7 +678,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/device_tools/plastic_explosives
|
||||
name = "Composition C-4"
|
||||
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaler to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds."
|
||||
desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls or connect a signaller to its wiring to make it remotely detonable. It has a modifiable timer with a minimum setting of 10 seconds."
|
||||
reference = "C4"
|
||||
item = /obj/item/weapon/c4
|
||||
cost = 1
|
||||
@@ -762,7 +760,7 @@ var/list/uplink_items = list()
|
||||
|
||||
/datum/uplink_item/implants/uplink
|
||||
name = "Uplink Implant"
|
||||
desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their posessions have been stripped from them makes this implant excellent for escaping confinement."
|
||||
desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their possessions have been stripped from them makes this implant excellent for escaping confinement."
|
||||
reference = "UI"
|
||||
item = /obj/item/weapon/implanter/uplink
|
||||
cost = 14
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/datum/wires/nuclearbomb
|
||||
holder_type = /obj/machinery/nuclearbomb
|
||||
random = 1
|
||||
wire_count = 7
|
||||
|
||||
var/const/NUCLEARBOMB_WIRE_LIGHT = 1
|
||||
var/const/NUCLEARBOMB_WIRE_TIMING = 2
|
||||
var/const/NUCLEARBOMB_WIRE_SAFETY = 4
|
||||
|
||||
/datum/wires/nuclearbomb/CanUse(var/mob/living/L)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
if(N.panel_open)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/wires/nuclearbomb/GetInteractWindow()
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
. += ..()
|
||||
. += "<BR>The device is [N.timing ? "shaking!" : "still."]<BR>"
|
||||
. += "The device is is [N.safety ? "quiet" : "whirring"].<BR>"
|
||||
. += "The lights are [N.lighthack ? "static" : "functional"].<BR>"
|
||||
|
||||
/datum/wires/nuclearbomb/UpdatePulsed(var/index)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
spawn(100)
|
||||
N.lighthack = !N.lighthack
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
if(N.timing)
|
||||
spawn
|
||||
message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
N.safety = !N.safety
|
||||
spawn(100)
|
||||
N.safety = !N.safety
|
||||
if(N.safety == 1)
|
||||
if(!N.is_syndicate)
|
||||
set_security_level(N.previous_level)
|
||||
N.visible_message("\blue The [N] quiets down.")
|
||||
if(!N.lighthack)
|
||||
if (N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
else
|
||||
N.visible_message("\blue The [N] emits a quiet whirling noise!")
|
||||
|
||||
/datum/wires/nuclearbomb/UpdateCut(var/index, var/mended)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(index)
|
||||
if(NUCLEARBOMB_WIRE_SAFETY)
|
||||
if(N.timing)
|
||||
spawn
|
||||
message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
if(NUCLEARBOMB_WIRE_TIMING)
|
||||
if(!N.lighthack)
|
||||
if (N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
N.timing = 0
|
||||
bomb_set = 0
|
||||
if(NUCLEARBOMB_WIRE_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
@@ -1,3 +1,4 @@
|
||||
/var/datum/announcement/minor/minor_announcement = new()
|
||||
/var/datum/announcement/priority/priority_announcement = new(do_log = 0)
|
||||
/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1)
|
||||
|
||||
@@ -15,6 +16,11 @@
|
||||
sound = new_sound
|
||||
log = do_log
|
||||
newscast = do_newscast
|
||||
|
||||
/datum/announcement/minor/New(var/do_log = 0, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
|
||||
..(do_log, new_sound, do_newscast)
|
||||
title = "Attention"
|
||||
announcement_type = "Minor Announcement"
|
||||
|
||||
/datum/announcement/priority/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
|
||||
..(do_log, new_sound, do_newscast)
|
||||
@@ -55,8 +61,9 @@ datum/announcement/proc/Message(message as text, message_title as text)
|
||||
if (announcer)
|
||||
M << "<span class='alert'> -[html_encode(announcer)]</span>"
|
||||
|
||||
datum/announcement/minor/Message(message as text, message_title as text)
|
||||
world << "<b>[message]</b>"
|
||||
/datum/announcement/minor/Message(message as text, message_title as text)
|
||||
world << "<b><font size=3><font color=red>[message_title]</font color></font></b>"
|
||||
world << "<b><font size=3>[message]</font size></font></b>"
|
||||
|
||||
datum/announcement/priority/Message(message as text, message_title as text)
|
||||
world << "<h1 class='alert'>[message_title]</h1>"
|
||||
|
||||
@@ -224,7 +224,7 @@ Obviously, requires DNA2.
|
||||
var/list/validtargets = new /list()
|
||||
for(var/mob/M in living_mob_list)
|
||||
if(M && M.mind)
|
||||
if(isAntag(M))
|
||||
if(M.z != user.z || isNonCrewAntag(M))
|
||||
continue
|
||||
|
||||
validtargets += M
|
||||
@@ -277,17 +277,22 @@ Obviously, requires DNA2.
|
||||
|
||||
action_icon_state = "genetic_view"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr)
|
||||
/obj/effect/proc_holder/spell/targeted/remoteview/choose_targets(mob/user = usr)
|
||||
var/list/targets = living_mob_list
|
||||
var/list/remoteviewers = new /list()
|
||||
var/list/validtargets = new /list()
|
||||
for(var/mob/M in targets)
|
||||
if(REMOTE_VIEW in M.mutations)
|
||||
remoteviewers += M
|
||||
if(!remoteviewers.len || remoteviewers.len == 1)
|
||||
if(M && M.mind)
|
||||
if(M.z != user.z || isNonCrewAntag(M))
|
||||
continue
|
||||
|
||||
validtargets += M
|
||||
|
||||
if(!validtargets.len || validtargets.len == 1)
|
||||
usr << "<span class='warning'>No valid targets with remote view were found!</span>"
|
||||
start_recharge()
|
||||
return
|
||||
targets += input("Choose the target to spy on.", "Targeting") as mob in remoteviewers
|
||||
|
||||
targets += input("Choose the target to spy on.", "Targeting") as mob in validtargets
|
||||
|
||||
perform(targets)
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
var/list/suspects = list()
|
||||
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind)
|
||||
// NT relation option
|
||||
if(isAntag(man))
|
||||
if(isNonCrewAntag(man))
|
||||
continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew.
|
||||
if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \
|
||||
man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20))
|
||||
@@ -246,6 +246,7 @@
|
||||
// Antags
|
||||
else if(special_role == "traitor" && prob(40) || \
|
||||
special_role == "Changeling" && prob(50) || \
|
||||
special_role == "Vampire" && prob(40) || \
|
||||
special_role == "Cultist" && prob(30) || \
|
||||
special_role == "Head Revolutionary" && prob(30) || \
|
||||
special_role == "Shadowling" && prob(15))
|
||||
|
||||
@@ -34,7 +34,7 @@ rcd light flash thingy on matter drain
|
||||
|
||||
|
||||
/datum/AI_Module/large/fireproof_core
|
||||
module_name = "Core upgrade"
|
||||
module_name = "Core Upgrade"
|
||||
mod_pick_name = "coreup"
|
||||
description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
|
||||
cost = 50
|
||||
@@ -51,9 +51,9 @@ rcd light flash thingy on matter drain
|
||||
src << "<span class='notice'>Core fireproofed.</span>"
|
||||
|
||||
/datum/AI_Module/large/upgrade_turrets
|
||||
module_name = "AI Turret upgrade"
|
||||
module_name = "AI Turret Upgrade"
|
||||
mod_pick_name = "turret"
|
||||
description = "Improves the firing speed and health of all AI turrets. This effect is permanent."
|
||||
description = "Improves the firing power and health of all AI turrets. This effect is permanent."
|
||||
cost = 50
|
||||
one_time = 1
|
||||
|
||||
@@ -62,26 +62,25 @@ rcd light flash thingy on matter drain
|
||||
/mob/living/silicon/ai/proc/upgrade_turrets()
|
||||
set category = "Malfunction"
|
||||
set name = "Upgrade Turrets"
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
src.verbs -= /mob/living/silicon/ai/proc/upgrade_turrets
|
||||
for(var/obj/machinery/turret/turret in machines)
|
||||
var/turf/T = get_turf(turret)
|
||||
if(T.z in config.station_levels)
|
||||
turret.health += 30
|
||||
turret.shot_delay = 20
|
||||
for(var/obj/machinery/porta_turret/turret in machines)
|
||||
var/turf/T = get_turf(turret)
|
||||
if(T.z in config.station_levels)
|
||||
// Increase health by 37.5% of original max, decrease delays between shots to 66%
|
||||
turret.health += initial(turret.health) * 3 / 8
|
||||
turret.shot_delay = initial(turret.shot_delay) * 2 / 3
|
||||
turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR.
|
||||
turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
src << "<span class='notice'>Turrets upgraded.</span>"
|
||||
|
||||
/datum/AI_Module/large/lockdown
|
||||
module_name = "Hostile Station Lockdown"
|
||||
mod_pick_name = "lockdown"
|
||||
description = "Take control of the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks."
|
||||
description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 120 seconds."
|
||||
cost = 20
|
||||
one_time = 1
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/lockdown
|
||||
|
||||
@@ -89,12 +88,43 @@ rcd light flash thingy on matter drain
|
||||
set category = "Malfunction"
|
||||
set name = "Initiate Hostile Lockdown"
|
||||
|
||||
if(src.stat == 2)
|
||||
src <<"You cannot begin a lockdown because you are dead!"
|
||||
if(stat)
|
||||
return
|
||||
|
||||
for(var/datum/AI_Module/large/lockdown/lockdown in current_modules)
|
||||
if(lockdown.uses > 0)
|
||||
lockdown.uses --
|
||||
|
||||
var/obj/machinery/door/airlock/AL
|
||||
for(var/obj/machinery/door/D in airlocks)
|
||||
if(!(D.z in config.contact_levels))
|
||||
continue
|
||||
spawn()
|
||||
if(istype(D, /obj/machinery/door/airlock))
|
||||
AL = D
|
||||
if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire.
|
||||
AL.locked = 0 //For airlocks that were bolted open.
|
||||
AL.safe = 0 //DOOR CRUSH
|
||||
AL.close()
|
||||
AL.lock()
|
||||
AL.electrified_until = -1 //Shock it!
|
||||
else if(!D.stat) //So that only powered doors are closed.
|
||||
D.close() //Close ALL the doors!
|
||||
|
||||
if(malf_cooldown)
|
||||
return
|
||||
var/obj/machinery/computer/communications/C = locate() in machines
|
||||
if(C)
|
||||
C.post_status("alert", "lockdown")
|
||||
|
||||
minor_announcement.Announce("Hostile runtime detected in door controllers. Isolation lockdown protocols are now in effect. Please remain calm.","Network Alert")
|
||||
src << "<span class='danger'>Lockdown initiated. Network reset in two minutes.</span>"
|
||||
spawn(1200) //120 Seconds.
|
||||
disablelockdown() //Reset the lockdown after 120 seconds.
|
||||
else
|
||||
src << "<span class='warning'>Out of uses.</span>"
|
||||
|
||||
/mob/living/silicon/ai/proc/disablelockdown()
|
||||
set category = "Malfunction"
|
||||
set name = "Disable Lockdown"
|
||||
|
||||
var/obj/machinery/door/airlock/AL
|
||||
for(var/obj/machinery/door/D in airlocks)
|
||||
@@ -104,77 +134,73 @@ rcd light flash thingy on matter drain
|
||||
if(istype(D, /obj/machinery/door/airlock))
|
||||
AL = D
|
||||
if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire.
|
||||
AL.locked = 0 //For airlocks that were bolted open.
|
||||
AL.safe = 0 //DOOR CRUSH
|
||||
AL.close()
|
||||
AL.locked = 1 //Bolt it!
|
||||
AL.lights = 0 //Stealth bolt for a classic AI door trap.
|
||||
AL.electrified_until = -1 //Shock it!
|
||||
else if(!D.stat) //So that only powered doors are closed.
|
||||
D.close() //Close ALL the doors!
|
||||
|
||||
var/obj/machinery/computer/communications/C = locate() in machines
|
||||
if(C)
|
||||
C.post_status("alert", "lockdown")
|
||||
|
||||
src.verbs += /mob/living/silicon/ai/proc/disablelockdown
|
||||
src << "<span class = 'warning'>Lockdown Initiated.</span>"
|
||||
malf_cooldown = 1
|
||||
spawn(30)
|
||||
malf_cooldown = 0
|
||||
|
||||
/mob/living/silicon/ai/proc/disablelockdown()
|
||||
set category = "Malfunction"
|
||||
set name = "Disable Lockdown"
|
||||
|
||||
if(src.stat == 2)
|
||||
src <<"You cannot disable lockdown because you are dead!"
|
||||
return
|
||||
if(malf_cooldown)
|
||||
return
|
||||
|
||||
var/obj/machinery/door/airlock/AL
|
||||
for(var/obj/machinery/door/D in airlocks)
|
||||
spawn()
|
||||
if(istype(D, /obj/machinery/door/airlock))
|
||||
AL = D
|
||||
if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire.
|
||||
AL.locked = 0
|
||||
AL.unlock()
|
||||
AL.electrified_until = 0
|
||||
AL.open()
|
||||
AL.safe = 1
|
||||
AL.lights = 1 //Essentially reset the airlock to normal.
|
||||
else if(!D.stat) //Opens only powered doors.
|
||||
D.open() //Open everything!
|
||||
D.open() //Open everything!
|
||||
|
||||
var/obj/machinery/computer/communications/C = locate() in machines
|
||||
if(C)
|
||||
C.post_status("alert", "default")
|
||||
|
||||
minor_announcement.Announce("Automatic system reboot complete. Have a secure day.","Network Reset")
|
||||
|
||||
src << "<span class = 'notice'>Lockdown Lifted.</span>"
|
||||
malf_cooldown = 1
|
||||
spawn(30)
|
||||
malf_cooldown = 0
|
||||
|
||||
/datum/AI_Module/large/disable_rcd
|
||||
module_name = "RCD disable"
|
||||
/datum/AI_Module/large/destroy_rcd
|
||||
module_name = "Destroy RCDs"
|
||||
mod_pick_name = "rcd"
|
||||
description = "Send a specialised pulse to break all RCD devices on the station."
|
||||
cost = 50
|
||||
description = "Send a specialised pulse to detonate all hand-held and exosuit Rapid Cconstruction Devices on the station."
|
||||
cost = 25
|
||||
one_time = 1
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/disable_rcd
|
||||
|
||||
/mob/living/silicon/ai/proc/disable_rcd()
|
||||
set category = "Malfunction"
|
||||
set name = "Disable RCDs"
|
||||
for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules)
|
||||
if(rcdmod.uses > 0)
|
||||
rcdmod.uses --
|
||||
for(var/obj/item/weapon/rcd/rcd in world)
|
||||
rcd.disabled = 1
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
|
||||
rcd.disabled = 1
|
||||
src << "<span class='warning>RCD-disabling pulse emitted.</span>"
|
||||
else src << "<span class='notice'>Out of uses.</span>"
|
||||
set name = "Destroy RCDs"
|
||||
set desc = "Detonate all RCDs on the station, while sparing onboard cyborg RCDs."
|
||||
|
||||
if(stat || malf_cooldown)
|
||||
return
|
||||
|
||||
for(var/obj/item/RCD in rcd_list)
|
||||
if(!istype(RCD, /obj/item/weapon/rcd/borg)) //Ensures that cyborg RCDs are spared.
|
||||
RCD.audible_message("<span class='danger'><b>[RCD] begins to vibrate and buzz loudly!</b></span>","<span class='danger'><b>[RCD] begins vibrating violently!</b></span>")
|
||||
spawn(50) //5 seconds to get rid of it!
|
||||
if(RCD) //Make sure it still exists (In case of chain-reaction)
|
||||
explosion(RCD, 0, 0, 3, 1, flame_range = 1)
|
||||
qdel(RCD)
|
||||
|
||||
src << "<span class='danger'>RCD detonation pulse emitted.</span>"
|
||||
malf_cooldown = 1
|
||||
spawn(100)
|
||||
malf_cooldown = 0
|
||||
|
||||
/datum/AI_Module/large/mecha_domination
|
||||
module_name = "Viral Mech Domination"
|
||||
mod_pick_name = "mechjack"
|
||||
description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\
|
||||
Do not allow the mech to leave the station's vicinity or allow it to be destroyed."
|
||||
cost = 30
|
||||
one_time = 1
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/mech_takeover
|
||||
|
||||
/mob/living/silicon/ai/proc/mech_takeover()
|
||||
set name = "Compile Mecha Virus"
|
||||
set category = "Malfunction"
|
||||
set desc = "Target a mech by clicking it. Click the appropriate command when ready."
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
can_dominate_mechs = 1 //Yep. This is all it does. Honk!
|
||||
src << "Virus package compiled. Select a target mech at any time. <b>You must remain on the station at all times. Loss of signal will result in total system lockout.</b>"
|
||||
verbs -= /mob/living/silicon/ai/proc/mech_takeover
|
||||
|
||||
/datum/AI_Module/small/overload_machine
|
||||
module_name = "Machine overload"
|
||||
module_name = "Machine Overload"
|
||||
mod_pick_name = "overload"
|
||||
description = "Overloads an electrical machine, causing a small explosion. 2 uses."
|
||||
uses = 2
|
||||
@@ -185,6 +211,10 @@ rcd light flash thingy on matter drain
|
||||
/mob/living/silicon/ai/proc/overload_machine(obj/machinery/M as obj in world)
|
||||
set name = "Overload Machine"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if (istype(M, /obj/machinery))
|
||||
if(istype(M,/obj/machinery/field_generator))
|
||||
src << "This machine can not be overloaded due to a firewall."
|
||||
@@ -197,11 +227,11 @@ rcd light flash thingy on matter drain
|
||||
spawn(50)
|
||||
explosion(get_turf(M), 0,1,1,0)
|
||||
qdel(M)
|
||||
else src << "<span class='notice'>Out of uses.</span>"
|
||||
else src << "<span class='warning'>Out of uses.</span>"
|
||||
else src << "<span class='notice'>That's not a machine.</span>"
|
||||
|
||||
/datum/AI_Module/small/override_machine
|
||||
module_name = "Machine override"
|
||||
module_name = "Machine Override"
|
||||
mod_pick_name = "override"
|
||||
description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses."
|
||||
uses = 4
|
||||
@@ -213,6 +243,10 @@ rcd light flash thingy on matter drain
|
||||
/mob/living/silicon/ai/proc/override_machine(obj/machinery/M as obj in world)
|
||||
set name = "Override Machine"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if (istype(M, /obj/machinery))
|
||||
if(istype(M,/obj/machinery/field_generator))
|
||||
src << "This machine can not be overloaded due to a firewall."
|
||||
@@ -226,7 +260,7 @@ rcd light flash thingy on matter drain
|
||||
spawn(50)
|
||||
if(M)
|
||||
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(M), M, src, 1)
|
||||
else src << "<span class='notice'>Out of uses.</span>"
|
||||
else src << "<span class='warning'>Out of uses.</span>"
|
||||
else src << "<span class='notice'>That's not a machine.</span>"
|
||||
|
||||
/datum/AI_Module/large/place_cyborg_transformer
|
||||
@@ -246,8 +280,10 @@ rcd light flash thingy on matter drain
|
||||
/mob/living/silicon/ai/proc/place_transformer()
|
||||
set name = "Place Robotic Factory"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(!canPlaceTransformer())
|
||||
return
|
||||
|
||||
var/sure = alert(src, "Are you sure you want to place the machine here?", "Are you sure?", "Yes", "No")
|
||||
if(sure == "Yes")
|
||||
if(!canPlaceTransformer())
|
||||
@@ -312,6 +348,10 @@ rcd light flash thingy on matter drain
|
||||
/mob/living/silicon/ai/proc/blackout()
|
||||
set category = "Malfunction"
|
||||
set name = "Blackout"
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
for(var/datum/AI_Module/small/blackout/blackout in current_modules)
|
||||
if(blackout.uses > 0)
|
||||
blackout.uses --
|
||||
@@ -320,72 +360,88 @@ rcd light flash thingy on matter drain
|
||||
apc.overload_lighting()
|
||||
else apc.overload++
|
||||
src << "<span class='notice'>Overcurrent applied to the powernet.</span>"
|
||||
else src << "<span class='notice'>Out of uses.</span>"
|
||||
else src << "<span class='warning'>Out of uses.</span>"
|
||||
|
||||
/datum/AI_Module/small/reactivate_camera
|
||||
module_name = "Reactivate camera"
|
||||
/datum/AI_Module/small/reactivate_cameras
|
||||
module_name = "Reactivate Camera Network"
|
||||
mod_pick_name = "recam"
|
||||
description = "Reactivates a currently disabled camera. 5 uses."
|
||||
uses = 5
|
||||
cost = 5
|
||||
description = "Runs a network-wide diagnostic on the camera network, resetting focus and re-routing power to failed cameras. Can be used to repair up to 30 cameras."
|
||||
uses = 30
|
||||
cost = 10
|
||||
one_time = 1
|
||||
|
||||
power_type = /client/proc/reactivate_camera
|
||||
power_type = /mob/living/silicon/ai/proc/reactivate_cameras
|
||||
|
||||
/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
set name = "Reactivate Camera"
|
||||
/mob/living/silicon/ai/proc/reactivate_cameras()
|
||||
set name = "Reactivate Cameranet"
|
||||
set category = "Malfunction"
|
||||
if (istype (C, /obj/machinery/camera))
|
||||
for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules)
|
||||
|
||||
if(stat || malf_cooldown)
|
||||
return
|
||||
var/fixedcams = 0 //Tells the AI how many cams it fixed. Stats are fun.
|
||||
|
||||
for(var/datum/AI_Module/small/reactivate_cameras/camera in current_modules)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
var/initial_range = initial(C.view_range) //To prevent calling the proc twice
|
||||
if(camera.uses > 0)
|
||||
if(!C.status)
|
||||
C.deactivate(src)
|
||||
camera.uses --
|
||||
src << "<span class='notice'>Camera reactivated.</span>"
|
||||
else
|
||||
src << "<span class='notice'>This camera is either active, or not repairable.</span>"
|
||||
else src << "<span class='notice'>Out of uses.</span>"
|
||||
else src << "<span class='notice'>That's not a camera.</span>"
|
||||
|
||||
/datum/AI_Module/small/upgrade_camera
|
||||
module_name = "Upgrade Camera"
|
||||
mod_pick_name = "upgradecam"
|
||||
description = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 5 uses."
|
||||
uses = 5
|
||||
cost = 5
|
||||
|
||||
power_type = /client/proc/upgrade_camera
|
||||
|
||||
/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
|
||||
set name = "Upgrade Camera"
|
||||
set category = "Malfunction"
|
||||
if(istype(C))
|
||||
var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
|
||||
if(UC)
|
||||
if(UC.uses > 0)
|
||||
if(C.assembly)
|
||||
var/upgraded = 0
|
||||
|
||||
if(!C.isXRay())
|
||||
C.upgradeXRay()
|
||||
upgraded = 1
|
||||
|
||||
if(!C.isEmpProof())
|
||||
C.upgradeEmpProof()
|
||||
upgraded = 1
|
||||
|
||||
if(!C.isMotion())
|
||||
C.upgradeMotion()
|
||||
upgraded = 1
|
||||
|
||||
if(upgraded)
|
||||
UC.uses --
|
||||
C.visible_message("<span class='notice'>\icon[C] *beep*</span>")
|
||||
src << "<span class='notice'>Camera successully upgraded!</span>"
|
||||
else
|
||||
src << "<span class='notice'>This camera is already upgraded!</span>"
|
||||
C.deactivate(src, 1) //Reactivates the camera based on status. Badly named proc.
|
||||
fixedcams++
|
||||
camera.uses--
|
||||
if(C.view_range != initial_range)
|
||||
C.view_range = initial_range //Fixes cameras with bad focus.
|
||||
camera.uses--
|
||||
fixedcams++
|
||||
//If a camera is both deactivated and has bad focus, it will cost two uses to fully fix!
|
||||
else
|
||||
src << "<span class='notice'>Out of uses.</span>"
|
||||
src << "<span class='warning'>Out of uses.</span>"
|
||||
verbs -= /mob/living/silicon/ai/proc/reactivate_cameras //It is useless now, clean it up.
|
||||
break
|
||||
src << "<span class='notice'>Diagnostic complete! Operations completed: [fixedcams].</span>"
|
||||
|
||||
malf_cooldown = 1
|
||||
spawn(30) //Lag protection
|
||||
malf_cooldown = 0
|
||||
|
||||
/datum/AI_Module/small/upgrade_cameras
|
||||
module_name = "Upgrade Camera Network"
|
||||
mod_pick_name = "upgradecam"
|
||||
description = "Install broad-spectrum scanning and electrical redundancy firmware to the camera network, enabling EMP-Proofing and light-amplified X-ray vision." //I <3 pointless technobabble
|
||||
//This used to have motion sensing as well, but testing quickly revealed that giving it to the whole cameranet is PURE HORROR.
|
||||
one_time = 1
|
||||
cost = 35 //Decent price for omniscience!
|
||||
|
||||
power_type = /mob/living/silicon/ai/proc/upgrade_cameras
|
||||
|
||||
/mob/living/silicon/ai/proc/upgrade_cameras()
|
||||
set name = "Upgrade Cameranet"
|
||||
set category = "Malfunction"
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
var/upgradedcams = 0
|
||||
see_override = SEE_INVISIBLE_MINIMUM //Night-vision, without which X-ray would be very limited in power.
|
||||
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(C.assembly)
|
||||
var/upgraded = 0
|
||||
|
||||
if(!C.isXRay())
|
||||
C.upgradeXRay()
|
||||
//Update what it can see.
|
||||
cameranet.updateVisibility(C, 0)
|
||||
upgraded = 1
|
||||
|
||||
if(!C.isEmpProof())
|
||||
C.upgradeEmpProof()
|
||||
upgraded = 1
|
||||
|
||||
if(upgraded)
|
||||
upgradedcams++
|
||||
|
||||
src << "<span class='notice'>OTA firmware distribution complete! Cameras upgraded: [upgradedcams]. Light amplification system online.</span>"
|
||||
verbs -= /mob/living/silicon/ai/proc/upgrade_cameras
|
||||
|
||||
/datum/module_picker
|
||||
var/temp = null
|
||||
@@ -411,9 +467,9 @@ rcd light flash thingy on matter drain
|
||||
<B>Install Module:</B><BR>
|
||||
<I>The number afterwards is the amount of processing time it consumes.</I><BR>"}
|
||||
for(var/datum/AI_Module/large/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> ([module.cost])<BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=\ref[src];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
for(var/datum/AI_Module/small/module in src.possible_modules)
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A> ([module.cost])<BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];[module.mod_pick_name]=1'>[module.module_name]</A><A href='byond://?src=\ref[src];showdesc=[module.mod_pick_name]'>\[?\]</A> ([module.cost])<BR>"
|
||||
dat += "<HR>"
|
||||
if (src.temp)
|
||||
dat += "[src.temp]"
|
||||
@@ -455,5 +511,9 @@ rcd light flash thingy on matter drain
|
||||
temp = AM.description
|
||||
src.processing_time -= AM.cost
|
||||
|
||||
if(href_list["showdesc"])
|
||||
if(AM.mod_pick_name == href_list["showdesc"])
|
||||
temp = AM.description
|
||||
|
||||
src.use(usr)
|
||||
return
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
|
||||
|
||||
/datum/game_mode/malfunction/proc/capture_the_station()
|
||||
world << "<FONT size = 3><B>The AI has won!</B></FONT>"
|
||||
world << "<FONT size = 3><B>The AI has accessed the station's core files!</B></FONT>"
|
||||
world << "<B>It has fully taken control of all of [station_name()]'s systems.</B>"
|
||||
|
||||
to_nuke_or_not_to_nuke = 1
|
||||
@@ -328,7 +328,8 @@
|
||||
/datum/game_mode/proc/auto_declare_completion_malfunction()
|
||||
if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) )
|
||||
var/text = "<FONT size = 2><B>The malfunctioning AI were:</B></FONT>"
|
||||
|
||||
var/module_text_temp = "<br><b>Purchased modules:</b><br>" //Added at the end
|
||||
|
||||
for(var/datum/mind/malf in malf_ai)
|
||||
|
||||
text += "<br>[malf.key] was [malf.name] ("
|
||||
@@ -339,9 +340,13 @@
|
||||
text += "operational"
|
||||
if(malf.current.real_name != malf.name)
|
||||
text += " as [malf.current.real_name]"
|
||||
var/mob/living/silicon/ai/AI = malf.current
|
||||
for(var/datum/AI_Module/mod in AI.current_modules)
|
||||
module_text_temp += mod.module_name + "<br>"
|
||||
else
|
||||
text += "hardware destroyed"
|
||||
text += ")"
|
||||
|
||||
text += module_text_temp
|
||||
|
||||
world << text
|
||||
return 1
|
||||
@@ -6,26 +6,23 @@ var/bomb_set
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nuclearbomb0"
|
||||
density = 1
|
||||
var/deployable = 0.0
|
||||
var/extended = 0.0
|
||||
var/deployable = 0
|
||||
var/extended = 0
|
||||
var/lighthack = 0
|
||||
var/opened = 0.0
|
||||
var/timeleft = 120.0
|
||||
var/timing = 0.0
|
||||
var/timeleft = 120
|
||||
var/timing = 0
|
||||
var/r_code = "ADMIN"
|
||||
var/code = ""
|
||||
var/yes_code = 0.0
|
||||
var/safety = 1.0
|
||||
var/yes_code = 0
|
||||
var/safety = 1
|
||||
var/obj/item/weapon/disk/nuclear/auth = null
|
||||
var/list/wires = list()
|
||||
var/light_wire
|
||||
var/safety_wire
|
||||
var/timing_wire
|
||||
var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
|
||||
var/lastentered
|
||||
var/is_syndicate = 0
|
||||
use_power = 0
|
||||
unacidable = 1
|
||||
var/previous_level = ""
|
||||
var/datum/wires/nuclearbomb/wires = null
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate
|
||||
is_syndicate = 1
|
||||
@@ -33,23 +30,15 @@ var/bomb_set
|
||||
/obj/machinery/nuclearbomb/New()
|
||||
..()
|
||||
r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
|
||||
src.wires["Red"] = 0
|
||||
src.wires["Blue"] = 0
|
||||
src.wires["Green"] = 0
|
||||
src.wires["Marigold"] = 0
|
||||
src.wires["Fuschia"] = 0
|
||||
src.wires["Black"] = 0
|
||||
src.wires["Pearl"] = 0
|
||||
var/list/w = list("Red","Blue","Green","Marigold","Black","Fuschia","Pearl")
|
||||
src.light_wire = pick(w)
|
||||
w -= src.light_wire
|
||||
src.timing_wire = pick(w)
|
||||
w -= src.timing_wire
|
||||
src.safety_wire = pick(w)
|
||||
w -= src.safety_wire
|
||||
|
||||
wires = new/datum/wires/nuclearbomb(src)
|
||||
previous_level = get_security_level()
|
||||
|
||||
/obj/machinery/nuclearbomb/Destroy()
|
||||
qdel(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/process()
|
||||
if (src.timing)
|
||||
if (timing)
|
||||
bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
|
||||
timeleft = max(timeleft - 2, 0) // 2 seconds per process()
|
||||
if (timeleft <= 0)
|
||||
@@ -60,40 +49,41 @@ var/bomb_set
|
||||
|
||||
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob, params)
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
src.add_fingerprint(user)
|
||||
if (src.auth)
|
||||
if (src.opened == 0)
|
||||
src.opened = 1
|
||||
add_fingerprint(user)
|
||||
if (auth)
|
||||
if (panel_open == 0)
|
||||
panel_open = 1
|
||||
overlays += image(icon, "npanel_open")
|
||||
user << "You unscrew the control panel of [src]."
|
||||
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
else
|
||||
src.opened = 0
|
||||
panel_open = 0
|
||||
overlays -= image(icon, "npanel_open")
|
||||
user << "You screw the control panel of [src] back on."
|
||||
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
else
|
||||
if (src.opened == 0)
|
||||
if (panel_open == 0)
|
||||
user << "[src] emits a buzzing noise, the panel staying locked in."
|
||||
if (src.opened == 1)
|
||||
src.opened = 0
|
||||
if (panel_open == 1)
|
||||
panel_open = 0
|
||||
overlays -= image(icon, "npanel_open")
|
||||
user << "You screw the control panel of [src] back on."
|
||||
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
flick("nuclearbombc", src)
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
if (istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters))
|
||||
ui_interact(user)
|
||||
if (panel_open && (istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters)))
|
||||
return attack_hand(user)
|
||||
|
||||
if (src.extended)
|
||||
if (extended)
|
||||
if (istype(O, /obj/item/weapon/disk/nuclear))
|
||||
usr.drop_item()
|
||||
O.loc = src
|
||||
src.auth = O
|
||||
src.add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
return
|
||||
auth = O
|
||||
add_fingerprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
if (src.anchored)
|
||||
if (anchored)
|
||||
switch(removal_stage)
|
||||
if(0)
|
||||
if(istype(O,/obj/item/weapon/weldingtool))
|
||||
@@ -163,73 +153,56 @@ var/bomb_set
|
||||
..()
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
|
||||
ui_interact(user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
|
||||
if (src.extended)
|
||||
if (src.opened)
|
||||
if (extended)
|
||||
if (panel_open)
|
||||
wires.Interact(user)
|
||||
else
|
||||
ui_interact(user)
|
||||
else if (src.deployable)
|
||||
else if (deployable)
|
||||
if(removal_stage < 5)
|
||||
src.anchored = 1
|
||||
anchored = 1
|
||||
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
|
||||
else
|
||||
visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
|
||||
if(!src.lighthack)
|
||||
if(!lighthack)
|
||||
flick("nuclearbombc", src)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.extended = 1
|
||||
icon_state = "nuclearbomb1"
|
||||
extended = 1
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
var/uiwidth
|
||||
var/uiheight
|
||||
var/uititle
|
||||
data["is_syndicate"] = is_syndicate
|
||||
if(!src.opened)
|
||||
data["hacking"] = 0
|
||||
data["auth"] = is_auth(user)
|
||||
if (is_auth(user))
|
||||
if (src.yes_code)
|
||||
data["authstatus"] = src.timing ? "Functional/Set" : "Functional"
|
||||
else
|
||||
data["authstatus"] = "Auth. S2"
|
||||
data["hacking"] = 0
|
||||
data["auth"] = is_auth(user)
|
||||
if (is_auth(user))
|
||||
if (yes_code)
|
||||
data["authstatus"] = timing ? "Functional/Set" : "Functional"
|
||||
else
|
||||
if (src.timing)
|
||||
data["authstatus"] = "Set"
|
||||
else
|
||||
data["authstatus"] = "Auth. S1"
|
||||
data["safe"] = src.safety ? "Safe" : "Engaged"
|
||||
data["time"] = src.timeleft
|
||||
data["timer"] = src.timing
|
||||
data["safety"] = src.safety
|
||||
data["anchored"] = src.anchored
|
||||
data["yescode"] = src.yes_code
|
||||
data["message"] = "AUTH"
|
||||
if (is_auth(user))
|
||||
data["message"] = src.code
|
||||
if (src.yes_code)
|
||||
data["message"] = "*****"
|
||||
uiwidth = 300
|
||||
uiheight = 510
|
||||
uititle = "Nuke Control Panel"
|
||||
data["authstatus"] = "Auth. S2"
|
||||
else
|
||||
data["hacking"] = 1
|
||||
var/list/tempwires[0]
|
||||
for(var/wire in src.wires)
|
||||
tempwires.Add(list(list("name" = wire, "cut" = src.wires[wire])))
|
||||
data["wires"] = tempwires
|
||||
data["timing"] = src.timing
|
||||
data["safety"] = src.safety
|
||||
data["lighthack"] = src.lighthack
|
||||
uiwidth = 420
|
||||
uiheight = 440
|
||||
uititle = "Nuclear Bomb Defusion"
|
||||
if (timing)
|
||||
data["authstatus"] = "Set"
|
||||
else
|
||||
data["authstatus"] = "Auth. S1"
|
||||
data["safe"] = safety ? "Safe" : "Engaged"
|
||||
data["time"] = timeleft
|
||||
data["timer"] = timing
|
||||
data["safety"] = safety
|
||||
data["anchored"] = anchored
|
||||
data["yescode"] = yes_code
|
||||
data["message"] = "AUTH"
|
||||
if (is_auth(user))
|
||||
data["message"] = code
|
||||
if (yes_code)
|
||||
data["message"] = "*****"
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "nuclear_bomb.tmpl", uititle, uiwidth, uiheight)
|
||||
ui = new(user, src, ui_key, "nuclear_bomb.tmpl", "Nuke Control Panel", 300, 510)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -242,12 +215,12 @@ var/bomb_set
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
return
|
||||
|
||||
if (src.deployable)
|
||||
if (deployable)
|
||||
usr << "\red You close several panels to make [src] undeployable."
|
||||
src.deployable = 0
|
||||
deployable = 0
|
||||
else
|
||||
usr << "\red You adjust some panels to make [src] deployable."
|
||||
src.deployable = 1
|
||||
deployable = 1
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/is_auth(user as mob)
|
||||
@@ -262,73 +235,29 @@ var/bomb_set
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["act"])
|
||||
var/temp_wire = href_list["wire"]
|
||||
if(href_list["act"] == "pulse")
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
else
|
||||
if(src.wires[temp_wire])
|
||||
usr << "You can't pulse a cut wire."
|
||||
else
|
||||
if(src.light_wire == temp_wire)
|
||||
src.lighthack = !src.lighthack
|
||||
spawn(100) src.lighthack = !src.lighthack
|
||||
if(src.timing_wire == temp_wire)
|
||||
if(src.timing)
|
||||
spawn
|
||||
explode()
|
||||
if(src.safety_wire == temp_wire)
|
||||
src.safety = !src.safety
|
||||
spawn(100) src.safety = !src.safety
|
||||
if(src.safety == 1)
|
||||
visible_message("\blue The [src] quiets down.")
|
||||
if(!src.lighthack)
|
||||
if (src.icon_state == "nuclearbomb2")
|
||||
src.icon_state = "nuclearbomb1"
|
||||
else
|
||||
visible_message("\blue The [src] emits a quiet whirling noise!")
|
||||
if(href_list["act"] == "wire")
|
||||
if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
|
||||
usr << "You need wirecutters!"
|
||||
else
|
||||
wires[temp_wire] = !wires[temp_wire]
|
||||
if(src.safety_wire == temp_wire)
|
||||
if(src.timing)
|
||||
spawn
|
||||
explode()
|
||||
if(src.timing_wire == temp_wire)
|
||||
if(!src.lighthack)
|
||||
if (src.icon_state == "nuclearbomb2")
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.timing = 0
|
||||
bomb_set = 0
|
||||
if(src.light_wire == temp_wire)
|
||||
src.lighthack = !src.lighthack
|
||||
|
||||
if (href_list["auth"])
|
||||
if (src.auth)
|
||||
src.auth.loc = src.loc
|
||||
src.yes_code = 0
|
||||
src.auth = null
|
||||
if (auth)
|
||||
auth.loc = loc
|
||||
yes_code = 0
|
||||
auth = null
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/disk/nuclear))
|
||||
usr.drop_item()
|
||||
I.loc = src
|
||||
src.auth = I
|
||||
auth = I
|
||||
if (is_auth(usr))
|
||||
if (href_list["type"])
|
||||
if (href_list["type"] == "E")
|
||||
if (src.code == src.r_code)
|
||||
src.yes_code = 1
|
||||
src.code = null
|
||||
if (code == r_code)
|
||||
yes_code = 1
|
||||
code = null
|
||||
else
|
||||
src.code = "ERROR"
|
||||
code = "ERROR"
|
||||
else
|
||||
if (href_list["type"] == "R")
|
||||
src.yes_code = 0
|
||||
src.code = null
|
||||
yes_code = 0
|
||||
code = null
|
||||
else
|
||||
lastentered = text("[]", href_list["type"])
|
||||
if (text2num(lastentered) == null)
|
||||
@@ -336,51 +265,61 @@ var/bomb_set
|
||||
message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: <a href='?_src_=vars;Vars=\ref[src]'>[lastentered]</a>! ([LOC ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[LOC.x];Y=[LOC.y];Z=[LOC.z]'>JMP</a>" : "null"])", 0)
|
||||
log_admin("EXPLOIT: [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered]!")
|
||||
else
|
||||
src.code += lastentered
|
||||
if (length(src.code) > 5)
|
||||
src.code = "ERROR"
|
||||
if (src.yes_code)
|
||||
code += lastentered
|
||||
if (length(code) > 5)
|
||||
code = "ERROR"
|
||||
if (yes_code)
|
||||
if (href_list["time"])
|
||||
var/time = text2num(href_list["time"])
|
||||
src.timeleft += time
|
||||
src.timeleft = min(max(round(src.timeleft), 120), 600)
|
||||
timeleft += time
|
||||
timeleft = min(max(round(src.timeleft), 120), 600)
|
||||
if (href_list["timer"])
|
||||
if (src.timing == -1.0)
|
||||
if (timing == -1.0)
|
||||
nanomanager.update_uis(src)
|
||||
return
|
||||
if (src.safety)
|
||||
if (safety)
|
||||
usr << "\red The safety is still on."
|
||||
nanomanager.update_uis(src)
|
||||
return
|
||||
src.timing = !( src.timing )
|
||||
if (src.timing)
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb2"
|
||||
if(!src.safety)
|
||||
bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N
|
||||
timing = !(timing)
|
||||
if (timing)
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb2"
|
||||
if(!safety)
|
||||
message_admins("[key_name_admin(usr)] engaged a nuclear bomb (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
if(!is_syndicate)
|
||||
set_security_level("delta")
|
||||
bomb_set = 1 //There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke/N
|
||||
else
|
||||
bomb_set = 0
|
||||
else
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
bomb_set = 0
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb1"
|
||||
if (href_list["safety"])
|
||||
src.safety = !( src.safety )
|
||||
safety = !(safety)
|
||||
if(safety)
|
||||
src.timing = 0
|
||||
if(!is_syndicate)
|
||||
set_security_level(previous_level)
|
||||
timing = 0
|
||||
bomb_set = 0
|
||||
if (href_list["anchor"])
|
||||
if(removal_stage == 5)
|
||||
src.anchored = 0
|
||||
anchored = 0
|
||||
visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
|
||||
nanomanager.update_uis(src)
|
||||
return
|
||||
|
||||
src.anchored = !( src.anchored )
|
||||
if(src.anchored)
|
||||
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
|
||||
|
||||
if(!isinspace())
|
||||
anchored = !(anchored)
|
||||
if(anchored)
|
||||
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
|
||||
else
|
||||
visible_message("\red The anchoring bolts slide back into the depths of [src].")
|
||||
else
|
||||
visible_message("\red The anchoring bolts slide back into the depths of [src].")
|
||||
usr << "<span class='warning'>There is nothing to anchor to!</span>"
|
||||
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
@@ -388,7 +327,7 @@ var/bomb_set
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/blob_act()
|
||||
if (src.timing == -1.0)
|
||||
if (timing == -1.0)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
@@ -396,14 +335,14 @@ var/bomb_set
|
||||
|
||||
#define NUKERANGE 80
|
||||
/obj/machinery/nuclearbomb/proc/explode()
|
||||
if (src.safety)
|
||||
src.timing = 0
|
||||
if (safety)
|
||||
timing = 0
|
||||
return
|
||||
src.timing = -1.0
|
||||
src.yes_code = 0
|
||||
src.safety = 1
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb3"
|
||||
timing = -1.0
|
||||
yes_code = 0
|
||||
safety = 1
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb3"
|
||||
playsound(src,'sound/machines/Alarm.ogg',100,0,5)
|
||||
if (ticker && ticker.mode)
|
||||
ticker.mode.explosion_in_progress = 1
|
||||
|
||||
@@ -152,9 +152,9 @@ Made by Xhuis
|
||||
update_shadow_icons_added(new_thrall_mind)
|
||||
new_thrall_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Became a thrall</span>"
|
||||
new_thrall_mind.current.add_language("Shadowling Hivemind")
|
||||
new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare)
|
||||
new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk)
|
||||
//new_thrall_mind.current.AddSpell(new /obj/effect/proc_holder/spell/targeted/thrall_vision) //Uncomment when vision code is unfucked.
|
||||
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare)
|
||||
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk)
|
||||
//new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/thrall_vision) //Uncomment when vision code is unfucked.
|
||||
new_thrall_mind.current << "<span class='shadowling'><b>You see the truth. Reality has been torn away and you realize what a fool you've been.</b></span>"
|
||||
new_thrall_mind.current << "<span class='shadowling'><b>The shadowlings are your masters.</b> Serve them above all else and ensure they complete their goals.</span>"
|
||||
new_thrall_mind.current << "<span class='shadowling'>You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls.</span>"
|
||||
|
||||
@@ -91,11 +91,11 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
|
||||
sleep(10)
|
||||
H << "<span class='shadowling'><b><i>Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies.</b></i></span>"
|
||||
H.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/shadowling_hatch)
|
||||
H.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare)
|
||||
H.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil)
|
||||
H.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk)
|
||||
H.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze)
|
||||
H.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze)
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shadowling_ascend
|
||||
name = "Ascend"
|
||||
@@ -156,11 +156,11 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
|
||||
H.mind.transfer_to(A)
|
||||
A.name = H.real_name
|
||||
A.languages = H.languages
|
||||
A.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate)
|
||||
A.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis)
|
||||
A.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift)
|
||||
A.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm)
|
||||
A.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit)
|
||||
A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate)
|
||||
A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis)
|
||||
A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift)
|
||||
A.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm)
|
||||
A.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit)
|
||||
if(A.real_name)
|
||||
A.real_name = H.real_name
|
||||
H.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly
|
||||
|
||||
@@ -233,201 +233,28 @@ This is a good place for AI-related object verbs so I'm sticking it here.
|
||||
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
|
||||
That prevents a few funky behaviors.
|
||||
*/
|
||||
//What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc.
|
||||
/obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob)
|
||||
if(!src:flush)
|
||||
switch(choice)
|
||||
if("AICORE")//AI mob.
|
||||
var/mob/living/silicon/ai/T = target
|
||||
switch(interaction)
|
||||
if("AICARD")
|
||||
var/obj/item/device/aicard/C = src
|
||||
if(C.contents.len)//If there is an AI on card.
|
||||
U << "\red <b>Transfer failed</b>: \black Existing AI found on this terminal. Remove existing AI to install a new one."
|
||||
else
|
||||
if (ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
for (var/datum/mind/malfai in malf.malf_ai)
|
||||
if (T.mind == malfai)
|
||||
U << "\red <b>ERROR</b>: \black Remote transfer interface disabled."//Do ho ho ho~
|
||||
return
|
||||
new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location.
|
||||
T.aiRestorePowerRoutine = 0//So the AI initially has power.
|
||||
T.control_disabled = 1//Can't control things remotely if you're stuck in a card!
|
||||
T.loc = C//Throw AI into the card.
|
||||
C.name = "inteliCard - [T.name]"
|
||||
if (T.stat == 2)
|
||||
C.icon_state = "aicard-404"
|
||||
else
|
||||
C.icon_state = "aicard-full"
|
||||
T.cancel_camera()
|
||||
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
/*if("NINJASUIT")
|
||||
var/obj/item/clothing/suit/space/space_ninja/C = src
|
||||
if(C.AI)//If there is an AI on card.
|
||||
U << "\red <b>Transfer failed</b>: \black Existing AI found on this terminal. Remove existing AI to install a new one."
|
||||
else
|
||||
if (ticker.mode.name == "AI malfunction")
|
||||
var/datum/game_mode/malfunction/malf = ticker.mode
|
||||
for (var/datum/mind/malfai in malf.malf_ai)
|
||||
if (T.mind == malfai)
|
||||
U << "\red <b>ERROR</b>: \black Remote transfer interface disabled."
|
||||
return
|
||||
if(T.stat)//If the ai is dead/dying.
|
||||
U << "\red <b>ERROR</b>: \black [T.name] data core is corrupted. Unable to install."
|
||||
else
|
||||
new /obj/structure/AIcore/deactivated(T.loc)
|
||||
T.aiRestorePowerRoutine = 0
|
||||
T.control_disabled = 1
|
||||
T.loc = C
|
||||
C.AI = T
|
||||
T.cancel_camera()
|
||||
T << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."*/
|
||||
//The type of interaction, the player performing the operation, the AI itself, and the card object, if any.
|
||||
|
||||
if("INACTIVE")//Inactive AI object.
|
||||
var/obj/structure/AIcore/deactivated/T = target
|
||||
switch(interaction)
|
||||
if("AICARD")
|
||||
var/obj/item/device/aicard/C = src
|
||||
var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever.
|
||||
if(A)//If AI exists on the card. Else nothing since both are empty.
|
||||
A.control_disabled = 0
|
||||
A.loc = T.loc//To replace the terminal.
|
||||
C.icon_state = "aicard"
|
||||
C.name = "inteliCard"
|
||||
C.overlays.Cut()
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
qdel(T)
|
||||
/*if("NINJASUIT")
|
||||
var/obj/item/clothing/suit/space/space_ninja/C = src
|
||||
var/mob/living/silicon/ai/A = C.AI
|
||||
if(A)
|
||||
A.control_disabled = 0
|
||||
C.AI = null
|
||||
A.loc = T.loc
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
U << "\blue <b>Transfer succesful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
del(T)*/
|
||||
if("AIFIXER")//AI Fixer terminal.
|
||||
var/obj/machinery/computer/aifixer/T = target
|
||||
switch(interaction)
|
||||
if("AICARD")
|
||||
var/obj/item/device/aicard/C = src
|
||||
if(!T.contents.len)
|
||||
if (!C.contents.len)
|
||||
U << "No AI to copy over!"//Well duh
|
||||
else for(var/mob/living/silicon/ai/A in C)
|
||||
C.icon_state = "aicard"
|
||||
C.name = "inteliCard"
|
||||
C.overlays.Cut()
|
||||
A.loc = T
|
||||
T.occupant = A
|
||||
A.control_disabled = 1
|
||||
if (A.stat == 2)
|
||||
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
|
||||
else
|
||||
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
else
|
||||
if(!C.contents.len && T.occupant && !T.active)
|
||||
C.name = "inteliCard - [T.occupant.name]"
|
||||
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
if (T.occupant.stat == 2)
|
||||
C.icon_state = "aicard-404"
|
||||
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
|
||||
else
|
||||
C.icon_state = "aicard-full"
|
||||
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
|
||||
U << "\blue <b>Transfer succesful</b>: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
T.occupant.loc = C
|
||||
T.occupant.cancel_camera()
|
||||
T.occupant = null
|
||||
else if (C.contents.len)
|
||||
U << "\red <b>ERROR</b>: \black Artificial intelligence detected on terminal."
|
||||
else if (T.active)
|
||||
U << "\red <b>ERROR</b>: \black Reconstruction in progress."
|
||||
else if (!T.occupant)
|
||||
U << "\red <b>ERROR</b>: \black Unable to locate artificial intelligence."
|
||||
/*if("NINJASUIT")
|
||||
var/obj/item/clothing/suit/space/space_ninja/C = src
|
||||
if(!T.contents.len)
|
||||
if (!C.AI)
|
||||
U << "No AI to copy over!"
|
||||
else
|
||||
var/mob/living/silicon/ai/A = C.AI
|
||||
A.loc = T
|
||||
T.occupant = A
|
||||
C.AI = null
|
||||
A.control_disabled = 1
|
||||
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
U << "\blue <b>Transfer successful</b>: \black [A.name] ([rand(1000,9999)].exe) installed and executed succesfully. Local copy has been removed."
|
||||
else
|
||||
if(!C.AI && T.occupant && !T.active)
|
||||
if (T.occupant.stat)
|
||||
U << "\red <b>ERROR</b>: \black [T.occupant.name] data core is corrupted. Unable to install."
|
||||
else
|
||||
T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
T.occupant << "You have been downloaded to a mobile storage device. Still no remote access."
|
||||
U << "\blue <b>Transfer successful</b>: \black [T.occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
T.occupant.loc = C
|
||||
T.occupant.cancel_camera()
|
||||
T.occupant = null
|
||||
else if (C.AI)
|
||||
U << "\red <b>ERROR</b>: \black Artificial intelligence detected on terminal."
|
||||
else if (T.active)
|
||||
U << "\red <b>ERROR</b>: \black Reconstruction in progress."
|
||||
else if (!T.occupant)
|
||||
U << "\red <b>ERROR</b>: \black Unable to locate artificial intelligence."*/
|
||||
/*if("NINJASUIT")//Ninjasuit
|
||||
var/obj/item/clothing/suit/space/space_ninja/T = target
|
||||
switch(interaction)
|
||||
if("AICARD")
|
||||
var/obj/item/device/aicard/C = src
|
||||
if(T.s_initialized&&U==T.affecting)//If the suit is initialized and the actor is the user.
|
||||
|
||||
var/mob/living/silicon/ai/A_T = locate() in C//Determine if there is an AI on target card. Saves time when checking later.
|
||||
var/mob/living/silicon/ai/A = T.AI//Deterine if there is an AI in suit.
|
||||
atom/proc/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
|
||||
if(istype(card))
|
||||
if(card.flush)
|
||||
user << "<span class='boldannounce'>ERROR</span>: AI flush is in progress, cannot execute transfer protocol."
|
||||
return 0
|
||||
return 1
|
||||
|
||||
if(A)//If the host AI card is not empty.
|
||||
if(A_T)//If there is an AI on the target card.
|
||||
U << "\red <b>ERROR</b>: \black [A_T.name] already installed. Remove [A_T.name] to install a new one."
|
||||
else
|
||||
A.loc = C//Throw them into the target card. Since they are already on a card, transfer is easy.
|
||||
C.name = "inteliCard - [A.name]"
|
||||
C.icon_state = "aicard-full"
|
||||
T.AI = null
|
||||
A.cancel_camera()
|
||||
A << "You have been uploaded to a mobile storage device."
|
||||
U << "\blue <b>SUCCESS</b>: \black [A.name] ([rand(1000,9999)].exe) removed from host and stored within local memory."
|
||||
else//If host AI is empty.
|
||||
if(C.flush)//If the other card is flushing.
|
||||
U << "\red <b>ERROR</b>: \black AI flush is in progress, cannot execute transfer protocol."
|
||||
else
|
||||
if(A_T&&!A_T.stat)//If there is an AI on the target card and it's not inactive.
|
||||
A_T.loc = T//Throw them into suit.
|
||||
C.icon_state = "aicard"
|
||||
C.name = "inteliCard"
|
||||
C.overlays.Cut()
|
||||
T.AI = A_T
|
||||
A_T.cancel_camera()
|
||||
A_T << "You have been uploaded to a mobile storage device."
|
||||
U << "\blue <b>SUCCESS</b>: \black [A_T.name] ([rand(1000,9999)].exe) removed from local memory and installed to host."
|
||||
else if(A_T)//If the target AI is dead. Else just go to return since nothing would happen if both are empty.
|
||||
U << "\red <b>ERROR</b>: \black [A_T.name] data core is corrupted. Unable to install."*/
|
||||
|
||||
else
|
||||
U << "\red <b>ERROR</b>: \black AI flush is in progress, cannot execute transfer protocol."
|
||||
return
|
||||
/obj/structure/AIcore/deactivated/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
//Transferring a carded AI to a core.
|
||||
if(interaction == AI_TRANS_FROM_CARD)
|
||||
AI.control_disabled = 0
|
||||
AI.aiRadio.disabledAi = 0
|
||||
AI.loc = loc//To replace the terminal.
|
||||
AI << "You have been uploaded to a stationary terminal. Remote device connection restored."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
|
||||
qdel(src)
|
||||
else //If for some reason you use an empty card on an empty AI terminal.
|
||||
user << "There is no AI loaded on this terminal!"
|
||||
|
||||
@@ -10,77 +10,64 @@
|
||||
|
||||
light_color = LIGHT_COLOR_PURPLE
|
||||
|
||||
/obj/machinery/computer/aifixer/New()
|
||||
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
|
||||
|
||||
/obj/machinery/computer/aifixer/attackby(I as obj, user as mob, params)
|
||||
if(istype(I, /obj/item/device/aicard))
|
||||
if(occupant && istype(I, /obj/item/weapon/screwdriver))
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
user << "This terminal isn't functioning right now, get it working!"
|
||||
return
|
||||
I:transfer_ai("AIFIXER","AICARD",src,user)
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
user << "<span class='warning'>The screws on [name]'s screen won't budge.</span>"
|
||||
else
|
||||
user << "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob)
|
||||
return attack_hand(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = "<h3>AI System Integrity Restorer</h3><br><br>"
|
||||
|
||||
if (src.occupant)
|
||||
var/laws
|
||||
dat += "Stored AI: [src.occupant.name]<br>System integrity: [(src.occupant.health+100)/2]%<br>"
|
||||
|
||||
if (src.occupant.laws.zeroth)
|
||||
laws += "0: [src.occupant.laws.zeroth]<BR>"
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
if(occupant)
|
||||
data["occupant"] = occupant.name
|
||||
data["reference"] = "\ref[occupant]"
|
||||
data["integrity"] = (occupant.health+100)/2
|
||||
data["stat"] = occupant.stat
|
||||
data["active"] = active
|
||||
data["wireless"] = occupant.control_disabled
|
||||
data["radio"] = occupant.aiRadio.disabledAi
|
||||
data["zeroth"] = occupant.laws.zeroth
|
||||
|
||||
var/laws[0]
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= src.occupant.laws.inherent.len, index++)
|
||||
var/law = src.occupant.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
for (var/index = 1, index <= occupant.laws.inherent.len, index++)
|
||||
var/law = occupant.laws.inherent[index]
|
||||
if(length(law) > 0)
|
||||
laws.Add(list(list("law" = law, "number" = number)))
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= src.occupant.laws.supplied.len, index++)
|
||||
var/law = src.occupant.laws.supplied[index]
|
||||
for (var/index = 1, index <= occupant.laws.supplied.len, index++)
|
||||
var/law = occupant.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
laws += "<b>[number]:</b> [law]<BR>"
|
||||
number++
|
||||
|
||||
data["laws"] = laws
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
dat += "Laws:<br>[laws]<br>"
|
||||
|
||||
if (src.occupant.stat == 2)
|
||||
dat += "<b>AI nonfunctional</b>"
|
||||
else
|
||||
dat += "<b>AI functional</b>"
|
||||
if (!src.active)
|
||||
dat += {"<br><br><A href='byond://?src=\ref[src];fix=1'>Begin Reconstruction</A>"}
|
||||
else
|
||||
dat += "<br><br>Reconstruction in process, please wait.<br>"
|
||||
dat += {" <A href='?src=\ref[user];mach_close=computer'>Close</A>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/aifixer/process()
|
||||
if(..())
|
||||
src.updateDialog()
|
||||
return
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "ai_fixer.tmpl", "AI System Integrity Restorer", 550, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/aifixer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if (href_list["fix"])
|
||||
|
||||
if(href_list["fix"])
|
||||
src.active = 1
|
||||
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on")
|
||||
while (src.occupant.health < 100)
|
||||
src.occupant.adjustOxyLoss(-1)
|
||||
src.occupant.adjustFireLoss(-1)
|
||||
@@ -92,32 +79,66 @@
|
||||
src.occupant.lying = 0
|
||||
dead_mob_list -= src.occupant
|
||||
living_mob_list += src.occupant
|
||||
src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
|
||||
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
src.updateUsrDialog()
|
||||
sleep(10)
|
||||
src.active = 0
|
||||
src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-on")
|
||||
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["wireless"])
|
||||
var/wireless = text2num(href_list["wireless"])
|
||||
if(wireless == 0 || wireless == 1)
|
||||
occupant.control_disabled = wireless
|
||||
|
||||
if(href_list["radio"])
|
||||
var/radio = text2num(href_list["radio"])
|
||||
if(radio == 0 || radio == 1)
|
||||
occupant.aiRadio.disabledAi = radio
|
||||
|
||||
nanomanager.update_uis(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/aifixer/update_icon()
|
||||
..()
|
||||
// Broken / Unpowered
|
||||
if((stat & BROKEN) || (stat & NOPOWER))
|
||||
overlays.Cut()
|
||||
|
||||
// Working / Powered
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
else
|
||||
var/overlay_layer = LIGHTING_LAYER+0.2 // +0.1 from the default computer overlays
|
||||
if(active)
|
||||
overlays += image(icon,"ai-fixer-on",overlay_layer)
|
||||
if (occupant)
|
||||
switch (occupant.stat)
|
||||
if (0)
|
||||
overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
|
||||
overlays += image(icon,"ai-fixer-full",overlay_layer)
|
||||
if (2)
|
||||
overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
|
||||
overlays += image(icon,"ai-fixer-404",overlay_layer)
|
||||
else
|
||||
overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
|
||||
overlays += image(icon,"ai-fixer-empty",overlay_layer)
|
||||
|
||||
/obj/machinery/computer/aifixer/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
//Downloading AI from card to terminal.
|
||||
if(interaction == AI_TRANS_FROM_CARD)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
user << "[src] is offline and cannot take an AI at this time!"
|
||||
return
|
||||
AI.loc = src
|
||||
occupant = AI
|
||||
AI.control_disabled = 1
|
||||
AI.aiRadio.disabledAi = 1
|
||||
AI << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
|
||||
update_icon()
|
||||
|
||||
else //Uploading AI from terminal to card
|
||||
if(occupant && !active)
|
||||
occupant << "You have been downloaded to a mobile storage device. Still no remote access."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [occupant.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
occupant.loc = card
|
||||
occupant = null
|
||||
update_icon()
|
||||
else if (active)
|
||||
user << "<span class='boldannounce'>ERROR</span>: Reconstruction in progress."
|
||||
else if (!occupant)
|
||||
user << "<span class='boldannounce'>ERROR</span>: Unable to locate artificial intelligence."
|
||||
|
||||
@@ -5,39 +5,43 @@
|
||||
icon_screen = "rdcomp"
|
||||
light_color = LIGHT_COLOR_PURPLE
|
||||
req_access = list(access_robotics)
|
||||
circuit = "/obj/item/weapon/circuitboard/pod_locater"
|
||||
circuit = /obj/item/weapon/circuitboard/pod_locater
|
||||
|
||||
/obj/machinery/computer/podtracker/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/podtracker/attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
|
||||
dat += "<h3>Pod beacons data</h3>"
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/podtracker/attack_hand(user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/podtracker/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
var/list/pods[0]
|
||||
for(var/obj/item/device/spacepod_equipment/misc/tracker/TR in world)
|
||||
var/obj/spacepod/myPod = TR.my_atom
|
||||
var/enabled = TR.enabled
|
||||
if(myPod && enabled)
|
||||
dat += {"<hr>[capitalize(myPod.name)]</br>
|
||||
<b> Pod SPS X:</b> [myPod.x]</br>
|
||||
<b> Pod SPS Y:</b> [myPod.y]</br>
|
||||
<b> Pod SPS Z:</b> [myPod.z]</br>"}
|
||||
var/podname = capitalize(sanitize(myPod.name))
|
||||
var/occupant = "None"
|
||||
var/occupant2 = "None"
|
||||
if(myPod.occupant)
|
||||
dat += {"<b> Pod Pilot:</b> [myPod.occupant.name]</br>"}
|
||||
occupant = myPod.occupant.name
|
||||
if(myPod.occupant2)
|
||||
dat += {"<b> Pod Passenger:</b> [myPod.occupant2.name]</br>"}
|
||||
occupant2 = myPod.occupant2.name
|
||||
pods.Add(list(list("pod" = "\ref[myPod]", "name" = podname, "occupant" = occupant, "occupant2" = occupant2, "x" = myPod.x, "y" = myPod.y, "z" = myPod.z)))
|
||||
|
||||
data["pods"] = pods
|
||||
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
|
||||
dat += "</body></html>"
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "pod_tracking.tmpl", "Pod Tracking Console", 400, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/podtracker/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
return 1
|
||||
|
||||
if(href_list["refresh"])
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
@@ -374,11 +374,11 @@
|
||||
new /obj/effect/decal/cleanable/blood/gibs(src)
|
||||
|
||||
if(!UserOverride)
|
||||
src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by <b>[user]/[user.ckey]</b>" //One shall not simply gib a mob unnoticed!
|
||||
user.attack_log += "\[[time_stamp()]\] Gibbed <b>[src.occupant]/[src.occupant.ckey]</b>"
|
||||
src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [key_name(user)]" //One shall not simply gib a mob unnoticed!
|
||||
user.attack_log += "\[[time_stamp()]\] Gibbed [key_name(occupant)]"
|
||||
|
||||
if(src.occupant.ckey)
|
||||
msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] gibbed [src.occupant] ([src.occupant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
msg_admin_attack("[key_name_admin(user)] gibbed [key_name_admin(occupant)]")
|
||||
|
||||
if(!iscarbon(user))
|
||||
src.occupant.LAssailant = null
|
||||
|
||||
@@ -282,17 +282,22 @@
|
||||
construction_time = 1200
|
||||
construction_cost = list("metal"=30000,"plasma"=25000,"silver"=20000,"gold"=20000)
|
||||
var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock.
|
||||
var/disabled = 0 //malf
|
||||
var/canRwall = 0
|
||||
|
||||
New()
|
||||
rcd_list += src
|
||||
..()
|
||||
|
||||
Destroy()
|
||||
rcd_list -= src
|
||||
..()
|
||||
|
||||
action(atom/target)
|
||||
if(istype(target,/area/shuttle)||istype(target, /turf/space/transit))//>implying these are ever made -Sieve
|
||||
disabled = 1
|
||||
else
|
||||
disabled = 0
|
||||
if(istype(target, /turf/space/transit))//>implying these are ever made -Sieve
|
||||
return
|
||||
if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock))
|
||||
target = get_turf(target)
|
||||
if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3) return
|
||||
playsound(chassis, 'sound/machines/click.ogg', 50, 1)
|
||||
//meh
|
||||
switch(mode)
|
||||
@@ -303,7 +308,6 @@
|
||||
occupant_message("Deconstructing [target]...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
target:ChangeTurf(/turf/simulated/floor/plating)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
@@ -312,7 +316,6 @@
|
||||
occupant_message("Deconstructing [target]...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
target:ChangeTurf(/turf/space)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
@@ -321,7 +324,6 @@
|
||||
occupant_message("Deconstructing [target]...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
qdel(target)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
@@ -331,7 +333,6 @@
|
||||
occupant_message("Building Floor...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
target:ChangeTurf(/turf/simulated/floor/plating)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
@@ -340,7 +341,6 @@
|
||||
occupant_message("Building Wall...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
target:ChangeTurf(/turf/simulated/wall)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
@@ -350,7 +350,6 @@
|
||||
occupant_message("Building Airlock...")
|
||||
set_ready_state(0)
|
||||
if(do_after_cooldown(target))
|
||||
if(disabled) return
|
||||
chassis.spark_system.start()
|
||||
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
|
||||
T.autoclose = 1
|
||||
|
||||
+153
-111
@@ -96,11 +96,6 @@
|
||||
mechas_list += src //global mech list
|
||||
return
|
||||
|
||||
/obj/mecha/Destroy()
|
||||
src.go_out()
|
||||
mechas_list -= src //global mech list
|
||||
return ..()
|
||||
|
||||
////////////////////////
|
||||
////// Helpers /////////
|
||||
////////////////////////
|
||||
@@ -615,50 +610,65 @@
|
||||
return
|
||||
|
||||
/obj/mecha/proc/destroy()
|
||||
spawn()
|
||||
go_out()
|
||||
var/turf/T = get_turf(src)
|
||||
tag = "\ref[src]" //better safe then sorry
|
||||
if(loc)
|
||||
loc.Exited(src)
|
||||
loc = null
|
||||
if(T)
|
||||
if(istype(src, /obj/mecha/working/ripley/))
|
||||
var/obj/mecha/working/ripley/R = src
|
||||
if(R.cargo)
|
||||
for(var/obj/O in R.cargo) //Dump contents of stored cargo
|
||||
O.loc = T
|
||||
R.cargo -= O
|
||||
T.Entered(O)
|
||||
go_out()
|
||||
for(var/mob/M in src) //Let's just be ultra sure
|
||||
if(isAI(M))
|
||||
M.gib() //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. Forever.
|
||||
else
|
||||
M.Move(loc)
|
||||
|
||||
if(prob(30))
|
||||
explosion(get_turf(loc), 0, 0, 1, 3)
|
||||
|
||||
if(istype(src, /obj/mecha/working/ripley/))
|
||||
var/obj/mecha/working/ripley/R = src
|
||||
if(R.cargo)
|
||||
for(var/obj/O in R.cargo) //Dump contents of stored cargo
|
||||
O.loc = loc
|
||||
R.cargo -= O
|
||||
loc.Entered(O)
|
||||
|
||||
if(prob(30))
|
||||
explosion(get_turf(loc), 0, 0, 1, 3)
|
||||
spawn(0)
|
||||
if(wreckage)
|
||||
var/obj/effect/decal/mecha_wreckage/WR = new wreckage(T)
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
|
||||
if(E.salvageable && prob(30))
|
||||
WR.crowbar_salvage += E
|
||||
E.forceMove(WR)
|
||||
E.equip_ready = 1
|
||||
E.reliability = round(rand(E.reliability/3,E.reliability))
|
||||
else
|
||||
E.forceMove(T)
|
||||
E.destroy()
|
||||
if(cell)
|
||||
WR.crowbar_salvage += cell
|
||||
cell.forceMove(WR)
|
||||
cell.charge = rand(0, cell.charge)
|
||||
if(internal_tank)
|
||||
WR.crowbar_salvage += internal_tank
|
||||
internal_tank.forceMove(WR)
|
||||
else
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
|
||||
E.forceMove(T)
|
||||
E.destroy()
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
return
|
||||
if(wreckage)
|
||||
var/obj/effect/decal/mecha_wreckage/WR = new wreckage(loc)
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
|
||||
if(E.salvageable && prob(30))
|
||||
WR.crowbar_salvage += E
|
||||
E.forceMove(WR)
|
||||
E.equip_ready = 1
|
||||
E.reliability = round(rand(E.reliability/3,E.reliability))
|
||||
else
|
||||
E.forceMove(loc)
|
||||
E.destroy()
|
||||
if(cell)
|
||||
WR.crowbar_salvage += cell
|
||||
cell.forceMove(WR)
|
||||
cell.charge = rand(0, cell.charge)
|
||||
if(internal_tank)
|
||||
WR.crowbar_salvage += internal_tank
|
||||
internal_tank.forceMove(WR)
|
||||
else
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
|
||||
E.forceMove(loc)
|
||||
E.destroy()
|
||||
if(cell)
|
||||
qdel(cell)
|
||||
if(internal_tank)
|
||||
qdel(internal_tank)
|
||||
equipment.Cut()
|
||||
cell = null
|
||||
internal_tank = null
|
||||
|
||||
qdel(pr_int_temp_processor)
|
||||
qdel(pr_give_air)
|
||||
qdel(pr_internal_damage)
|
||||
qdel(spark_system)
|
||||
pr_int_temp_processor = null
|
||||
pr_give_air = null
|
||||
pr_internal_damage = null
|
||||
spark_system = null
|
||||
|
||||
mechas_list -= src //global mech list
|
||||
return ..()
|
||||
|
||||
/obj/mecha/ex_act(severity)
|
||||
src.log_message("Affected by explosion of severity: [severity].",1)
|
||||
@@ -916,16 +926,92 @@
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
/////////////////////////////////////
|
||||
//////////// AI piloting ////////////
|
||||
/////////////////////////////////////
|
||||
|
||||
/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob)
|
||||
if(!istype(user, /mob/living/silicon/ai))
|
||||
if(!isAI(user))
|
||||
return
|
||||
var/output = {"<b>Assume direct control over [src]?</b>
|
||||
<a href='?src=\ref[src];ai_take_control=\ref[user];duration=3000'>Yes</a><br>
|
||||
"}
|
||||
user << browse(output, "window=mecha_attack_ai")
|
||||
return
|
||||
*/
|
||||
//Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot.
|
||||
if(user.can_dominate_mechs)
|
||||
examine(user) //Get diagnostic information!
|
||||
var/obj/item/mecha_parts/mecha_tracking/B = locate(/obj/item/mecha_parts/mecha_tracking) in src
|
||||
if(B) //Beacons give the AI more detailed mech information.
|
||||
user << "<span class='danger'>Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:"
|
||||
user << "[B.get_mecha_info()]"
|
||||
//Nothing like a big, red link to make the player feel powerful!
|
||||
user << "<a href='?src=\ref[user];ai_take_control=\ref[src]'><span class='userdanger'>ASSUME DIRECT CONTROL?</span></a><br>"
|
||||
|
||||
/obj/mecha/transfer_ai(var/interaction, mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
|
||||
//Transfer from core or card to mech. Proc is called by mech.
|
||||
switch(interaction)
|
||||
if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card.
|
||||
if(!maint_access) //Mech must be in maint mode to allow carding.
|
||||
user << "<span class='warning'>[name] must have maintenance protocols active in order to allow a transfer.</span>"
|
||||
return
|
||||
AI = occupant
|
||||
if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot
|
||||
user << "<span class='warning'>No AI detected in the [name] onboard computer.</span>"
|
||||
return
|
||||
if (AI.mind.special_role == "malfunction") //Malf AIs cannot leave mechs. Except through death.
|
||||
user << "<span class='boldannounce'>ACCESS DENIED.</span>"
|
||||
return
|
||||
AI.aiRestorePowerRoutine = 0//So the AI initially has power.
|
||||
AI.control_disabled = 1
|
||||
AI.aiRadio.disabledAi = 1
|
||||
AI.loc = card
|
||||
occupant = null
|
||||
AI.controlled_mech = null
|
||||
AI.remote_control = null
|
||||
icon_state = initial(icon_state)+"-open"
|
||||
AI << "You have been downloaded to a mobile storage device. Wireless connection offline."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory."
|
||||
|
||||
if(AI_MECH_HACK) //Called by Malf AI mob on the mech.
|
||||
new /obj/structure/AIcore/deactivated(AI.loc)
|
||||
if(occupant) //Oh, I am sorry, were you using that?
|
||||
AI << "<span class='warning'>Pilot detected! Forced ejection initiated!"
|
||||
occupant << "<span class='danger'>You have been forcibly ejected!</span>"
|
||||
go_out(1) //IT IS MINE, NOW. SUCK IT, RD!
|
||||
ai_enter_mech(AI, interaction)
|
||||
|
||||
if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech.
|
||||
AI = locate(/mob/living/silicon/ai) in card
|
||||
if(!AI)
|
||||
user << "<span class='warning'>There is no AI currently installed on this device.</span>"
|
||||
return
|
||||
else if(AI.stat || !AI.client)
|
||||
user << "<span class='warning'>[AI.name] is currently unresponsive, and cannot be uploaded.</span>"
|
||||
return
|
||||
else if(occupant || dna) //Normal AIs cannot steal mechs!
|
||||
user << "<span class='warning'>Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"]."
|
||||
return
|
||||
AI.control_disabled = 0
|
||||
AI.aiRadio.disabledAi = 0
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
|
||||
ai_enter_mech(AI, interaction)
|
||||
|
||||
//Hack and From Card interactions share some code, so leave that here for both to use.
|
||||
/obj/mecha/proc/ai_enter_mech(var/mob/living/silicon/ai/AI, var/interaction)
|
||||
AI.aiRestorePowerRoutine = 0
|
||||
AI.loc = src
|
||||
occupant = AI
|
||||
icon_state = initial(icon_state)
|
||||
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
|
||||
if(!hasInternalDamage())
|
||||
occupant << sound('sound/mecha/nominal.ogg',volume=50)
|
||||
AI.cancel_camera()
|
||||
AI.controlled_mech = src
|
||||
AI.remote_control = src
|
||||
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
|
||||
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
|
||||
AI << "[interaction == AI_MECH_HACK ? "<span class='announce'>Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" \
|
||||
: "<span class='notice'>You have been uploaded to a mech's onboard computer."]"
|
||||
AI << "<span class='boldnotice'>Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.</span>"
|
||||
|
||||
/////////////////////////////////////
|
||||
//////// Atmospheric stuff ////////
|
||||
@@ -1228,7 +1314,7 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/proc/go_out()
|
||||
/obj/mecha/proc/go_out(var/forced)
|
||||
if(!src.occupant) return
|
||||
var/atom/movable/mob_container
|
||||
if(ishuman(occupant))
|
||||
@@ -1236,6 +1322,10 @@
|
||||
else if(istype(occupant, /mob/living/carbon/brain))
|
||||
var/mob/living/carbon/brain/brain = occupant
|
||||
mob_container = brain.container
|
||||
else if(isAI(occupant) && forced) //This should only happen if there are multiple AIs in a round, and at least one is Malf.
|
||||
occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced.
|
||||
occupant = null
|
||||
return
|
||||
else
|
||||
return
|
||||
if(mob_container.forceMove(src.loc))//ejecting mob container
|
||||
@@ -1677,13 +1767,13 @@
|
||||
user << browse(null,"window=exosuit_add_access")
|
||||
return
|
||||
if(href_list["dna_lock"])
|
||||
if(usr != src.occupant) return
|
||||
if(istype(occupant, /mob/living/carbon/brain))
|
||||
occupant_message("You are a brain. No.")
|
||||
if(usr != src.occupant)
|
||||
return
|
||||
if(src.occupant)
|
||||
src.dna = src.occupant.dna.unique_enzymes
|
||||
src.occupant_message("You feel a prick as the needle takes your DNA sample.")
|
||||
if(src.occupant && !iscarbon(src.occupant))
|
||||
src.occupant << "<span class='danger'>You do not have any DNA!</span>"
|
||||
return
|
||||
src.dna = src.occupant.dna.unique_enzymes
|
||||
src.occupant_message("You feel a prick as the needle takes your DNA sample.")
|
||||
return
|
||||
if(href_list["reset_dna"])
|
||||
if(usr != src.occupant) return
|
||||
@@ -1712,54 +1802,6 @@
|
||||
return
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
if (href_list["ai_take_control"])
|
||||
var/mob/living/silicon/ai/AI = locate(href_list["ai_take_control"])
|
||||
var/duration = text2num(href_list["duration"])
|
||||
var/mob/living/silicon/ai/O = new /mob/living/silicon/ai(src)
|
||||
var/cur_occupant = src.occupant
|
||||
O.invisibility = 0
|
||||
O.canmove = 1
|
||||
O.name = AI.name
|
||||
O.real_name = AI.real_name
|
||||
O.anchored = 1
|
||||
O.aiRestorePowerRoutine = 0
|
||||
O.control_disabled = 1 // Can't control things remotely if you're stuck in a card!
|
||||
O.laws = AI.laws
|
||||
O.stat = AI.stat
|
||||
O.oxyloss = AI.getOxyLoss()
|
||||
O.fireloss = AI.getFireLoss()
|
||||
O.bruteloss = AI.getBruteLoss()
|
||||
O.toxloss = AI.toxloss
|
||||
O.updatehealth()
|
||||
src.occupant = O
|
||||
if(AI.mind)
|
||||
AI.mind.transfer_to(O)
|
||||
AI.name = "Inactive AI"
|
||||
AI.real_name = "Inactive AI"
|
||||
AI.icon_state = "ai-empty"
|
||||
spawn(duration)
|
||||
AI.name = O.name
|
||||
AI.real_name = O.real_name
|
||||
if(O.mind)
|
||||
O.mind.transfer_to(AI)
|
||||
AI.control_disabled = 0
|
||||
AI.laws = O.laws
|
||||
AI.oxyloss = O.getOxyLoss()
|
||||
AI.fireloss = O.getFireLoss()
|
||||
AI.bruteloss = O.getBruteLoss()
|
||||
AI.toxloss = O.toxloss
|
||||
AI.updatehealth()
|
||||
del(O)
|
||||
if (!AI.stat)
|
||||
AI.icon_state = "ai"
|
||||
else
|
||||
AI.icon_state = "ai-crash"
|
||||
src.occupant = cur_occupant
|
||||
*/
|
||||
return
|
||||
|
||||
///////////////////////
|
||||
|
||||
@@ -5,64 +5,66 @@
|
||||
icon_screen = "mecha"
|
||||
light_color = LIGHT_COLOR_FADEDPURPLE
|
||||
req_access = list(access_robotics)
|
||||
circuit = "/obj/item/weapon/circuitboard/mecha_control"
|
||||
circuit = /obj/item/weapon/circuitboard/mecha_control
|
||||
var/list/located = list()
|
||||
var/screen = 0
|
||||
var/stored_data
|
||||
|
||||
attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
/obj/machinery/computer/mecha/attack_ai(var/mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
|
||||
if(screen == 0)
|
||||
dat += "<h3>Tracking beacons data</h3>"
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
|
||||
var/answer = TR.get_mecha_info()
|
||||
if(answer)
|
||||
dat += {"<hr>[answer]<br/>
|
||||
<a href='?src=\ref[src];send_message=\ref[TR]'>Send message</a><br/>
|
||||
<a href='?src=\ref[src];get_log=\ref[TR]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=\ref[src];shock=\ref[TR]'>(EMP pulse)</a><br>"}
|
||||
/obj/machinery/computer/mecha/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
data["screen"] = screen
|
||||
if(screen == 0)
|
||||
var/list/mechas[0]
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
|
||||
var/answer = TR.get_mecha_info()
|
||||
if(answer)
|
||||
mechas[++mechas.len] = answer
|
||||
data["mechas"] = mechas
|
||||
if(screen == 1)
|
||||
data["log"] = stored_data
|
||||
|
||||
if(screen==1)
|
||||
dat += "<h3>Log contents</h3>"
|
||||
dat += "<a href='?src=\ref[src];return=1'>Return</a><hr>"
|
||||
dat += "[stored_data]"
|
||||
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
|
||||
dat += "</body></html>"
|
||||
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
if(href_list["send_message"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
|
||||
var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text)
|
||||
var/obj/mecha/M = MT.in_mecha()
|
||||
if(trim(message) && M)
|
||||
M.occupant_message(message)
|
||||
return
|
||||
if(href_list["shock"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
|
||||
MT.shock()
|
||||
if(href_list["get_log"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
|
||||
stored_data = MT.get_mecha_log()
|
||||
screen = 1
|
||||
if(href_list["return"])
|
||||
screen = 0
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "exosuit_control.tmpl", "Exosuit Control Console", 420, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/mecha/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
if(href_list["send_message"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
|
||||
var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text)
|
||||
if(!trim(message) || ..())
|
||||
return 1
|
||||
var/obj/mecha/M = MT.in_mecha()
|
||||
if(M)
|
||||
M.occupant_message(message)
|
||||
|
||||
if(href_list["shock"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
|
||||
MT.shock()
|
||||
|
||||
if(href_list["get_log"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
|
||||
stored_data = MT.get_mecha_log()
|
||||
screen = 1
|
||||
|
||||
if(href_list["return"])
|
||||
screen = 0
|
||||
|
||||
nanomanager.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking
|
||||
name = "Exosuit tracking beacon"
|
||||
@@ -73,49 +75,57 @@
|
||||
construction_time = 50
|
||||
construction_cost = list("metal"=500)
|
||||
|
||||
proc/get_mecha_info()
|
||||
if(!in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
var/cell_charge = M.get_charge()
|
||||
var/answer = {"<b>Name:</b> [M.name]<br>
|
||||
<b>Integrity:</b> [M.health/initial(M.health)*100]%<br>
|
||||
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]<br>
|
||||
<b>Airtank:</b> [M.return_pressure()]kPa<br>
|
||||
<b>Pilot:</b> [M.occupant||"None"]<br>
|
||||
<b>Location:</b> [get_area(M)||"Unknown"]<br>
|
||||
<b>Active equipment:</b> [M.selected||"None"]"}
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
|
||||
|
||||
return answer
|
||||
|
||||
emp_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
ex_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
proc/in_mecha()
|
||||
if(istype(src.loc, /obj/mecha))
|
||||
return src.loc
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
|
||||
if(!in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
var/list/answer[0]
|
||||
answer["reference"] = "\ref[src]"
|
||||
answer["name"] = sanitize(replacetext(M.name,"\"","'")) // Double apostrophes break JSON
|
||||
if(M.cell)
|
||||
answer["cell"] = 1
|
||||
answer["cell_capacity"] = M.cell.maxcharge
|
||||
answer["cell_current"] = M.get_charge()
|
||||
answer["cell_percentage"] = round(M.cell.percent())
|
||||
else
|
||||
answer["cell"] = 0
|
||||
answer["integrity"] = M.health/initial(M.health)*100
|
||||
answer["airtank"] = M.return_pressure()
|
||||
answer["pilot"] = "[M.occupant||"None"]"
|
||||
var/area/area = get_area(M)
|
||||
answer["location"] = "[sanitize(area.name)||"Unknown"]"
|
||||
answer["equipment"] = "[M.selected||"None"]"
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
answer["hascargo"] = 1
|
||||
answer["cargo"] = RM.cargo.len/RM.cargo_capacity*100
|
||||
|
||||
return answer
|
||||
|
||||
proc/shock()
|
||||
var/obj/mecha/M = in_mecha()
|
||||
if(M)
|
||||
M.emp_act(2)
|
||||
qdel(src)
|
||||
/obj/item/mecha_parts/mecha_tracking/emp_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
proc/get_mecha_log()
|
||||
if(!src.in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
return M.get_log_html()
|
||||
/obj/item/mecha_parts/mecha_tracking/ex_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
|
||||
if(istype(src.loc, /obj/mecha))
|
||||
return src.loc
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/shock()
|
||||
var/obj/mecha/M = in_mecha()
|
||||
if(M)
|
||||
M.emp_act(2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
|
||||
if(!src.in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
return M.get_log_html()
|
||||
|
||||
/obj/item/weapon/storage/box/mechabeacons
|
||||
name = "Exosuit Tracking Beacons"
|
||||
|
||||
@@ -5,129 +5,138 @@
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_BELT
|
||||
flags = NOBLUDGEON
|
||||
var/flush = null
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
|
||||
attack(mob/living/silicon/ai/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/silicon/ai))//If target is not an AI.
|
||||
return ..()
|
||||
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been carded with [src.name] by [key_name(user)]</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to card [key_name(M)]</font>")
|
||||
msg_admin_attack("[key_name_admin(user)] used the [src.name] to card [M.name] ([M.ckey])")
|
||||
|
||||
transfer_ai("AICORE", "AICARD", M, user)
|
||||
/obj/item/device/aicard/afterattack(atom/target, mob/user, proximity)
|
||||
..()
|
||||
if(!proximity || !target)
|
||||
return
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src
|
||||
if(AI) //AI is on the card, implies user wants to upload it.
|
||||
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
|
||||
add_logs(AI,user, "carded", object="[name]")
|
||||
else //No AI on the card, therefore the user wants to download one.
|
||||
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
|
||||
update_state() //Whatever happened, update the card's state (icon, name) to match.
|
||||
|
||||
attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
|
||||
if (!istype (M, /mob/living/silicon/decoy))
|
||||
return ..()
|
||||
/obj/item/device/aicard/proc/update_state()
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside.
|
||||
if(AI)
|
||||
name = "intelliCard - [AI.name]"
|
||||
if (AI.stat == DEAD)
|
||||
icon_state = "aicard-404"
|
||||
else
|
||||
M.death()
|
||||
user << "<b>ERROR ERROR ERROR</b>"
|
||||
icon_state = "aicard-full"
|
||||
AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded.
|
||||
else
|
||||
icon_state = "aicard"
|
||||
name = "intelliCard"
|
||||
overlays.Cut()
|
||||
|
||||
/obj/item/device/aicard/attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Intelicard</B><BR>"
|
||||
var/laws
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
dat += "Stored AI: [A.name]<br>System integrity: [(A.health+100)/2]%<br>"
|
||||
|
||||
attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Intelicard</B><BR>"
|
||||
var/laws
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
dat += "Stored AI: [A.name]<br>System integrity: [(A.health+100)/2]%<br>"
|
||||
for (var/index = 1, index <= A.laws.ion.len, index++)
|
||||
var/law = A.laws.ion[index]
|
||||
if (length(law) > 0)
|
||||
var/num = ionnum()
|
||||
laws += "[num]. [law]"
|
||||
|
||||
for (var/index = 1, index <= A.laws.ion.len, index++)
|
||||
var/law = A.laws.ion[index]
|
||||
if (length(law) > 0)
|
||||
var/num = ionnum()
|
||||
laws += "[num]. [law]"
|
||||
if (A.laws.zeroth)
|
||||
laws += "0: [A.laws.zeroth]<BR>"
|
||||
|
||||
if (A.laws.zeroth)
|
||||
laws += "0: [A.laws.zeroth]<BR>"
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= A.laws.inherent.len, index++)
|
||||
var/law = A.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
|
||||
var/number = 1
|
||||
for (var/index = 1, index <= A.laws.inherent.len, index++)
|
||||
var/law = A.laws.inherent[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
for (var/index = 1, index <= A.laws.supplied.len, index++)
|
||||
var/law = A.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
|
||||
for (var/index = 1, index <= A.laws.supplied.len, index++)
|
||||
var/law = A.laws.supplied[index]
|
||||
if (length(law) > 0)
|
||||
laws += "[number]: [law]<BR>"
|
||||
number++
|
||||
dat += "Laws:<br>[laws]<br>"
|
||||
|
||||
dat += "Laws:<br>[laws]<br>"
|
||||
|
||||
if (A.stat == 2)
|
||||
dat += "<b>AI nonfunctional</b>"
|
||||
if (A.stat == 2)
|
||||
dat += "<b>AI nonfunctional</b>"
|
||||
else
|
||||
if (!src.flush)
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Wipe'>Wipe AI</A>"}
|
||||
else
|
||||
if (!src.flush)
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Wipe'>Wipe AI</A>"}
|
||||
else
|
||||
dat += "<b>Wipe in progress</b>"
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Wireless'>[A.control_disabled ? "Enable" : "Disable"] Wireless Activity</a>"}
|
||||
dat += "<br>"
|
||||
dat += "Subspace Transceiver is: [A.aiRadio.disabledAi ? "Disabled" : "Enabled"]"
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Radio'>[A.aiRadio.disabledAi ? "Enable" : "Disable"] Subspace Transceiver</a>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
dat += "<b>Wipe in progress</b>"
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Wireless'>[A.control_disabled ? "Enable" : "Disable"] Wireless Activity</a>"}
|
||||
dat += "<br>"
|
||||
dat += "Subspace Transceiver is: [A.aiRadio.disabledAi ? "Disabled" : "Enabled"]"
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Radio'>[A.aiRadio.disabledAi ? "Enable" : "Disable"] Subspace Transceiver</a>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
return
|
||||
|
||||
/obj/item/device/aicard/Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else).
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)//If they are not in range of 1 or less or their machine is not the card (ie, clicked on something else).
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
if ("Wipe")
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
if(isnull(src)||!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
else
|
||||
flush = 1
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.suiciding = 1
|
||||
A << "Your core files are being wiped!"
|
||||
while (A.stat != 2)
|
||||
A.adjustOxyLoss(2)
|
||||
A.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
if ("Radio")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.aiRadio.disabledAi = !A.aiRadio.disabledAi
|
||||
A << "Your Subspace Transceiver has been: [A.aiRadio.disabledAi ? "disabled" : "enabled"]"
|
||||
U << "You [A.aiRadio.disabledAi ? "Disable" : "Enable"] the AI's Subspace Transceiver"
|
||||
|
||||
if ("Wipe")
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
if(isnull(src)||!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
else
|
||||
flush = 1
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.suiciding = 1
|
||||
A << "Your core files are being wiped!"
|
||||
while (A.stat != 2)
|
||||
A.adjustOxyLoss(2)
|
||||
A.updatehealth()
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
if ("Radio")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.aiRadio.disabledAi = !A.aiRadio.disabledAi
|
||||
A << "Your Subspace Transceiver has been: [A.aiRadio.disabledAi ? "disabled" : "enabled"]"
|
||||
U << "You [A.aiRadio.disabledAi ? "Disable" : "Enable"] the AI's Subspace Transceiver"
|
||||
|
||||
if ("Wireless")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.control_disabled = !A.control_disabled
|
||||
A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!"
|
||||
if (A.control_disabled)
|
||||
overlays -= image('icons/obj/aicards.dmi', "aicard-on")
|
||||
else
|
||||
overlays += image('icons/obj/aicards.dmi', "aicard-on")
|
||||
attack_self(U)
|
||||
if ("Wireless")
|
||||
for(var/mob/living/silicon/ai/A in src)
|
||||
A.control_disabled = !A.control_disabled
|
||||
A << "The intelicard's wireless port has been [A.control_disabled ? "disabled" : "enabled"]!"
|
||||
if (A.control_disabled)
|
||||
overlays -= image('icons/obj/aicards.dmi', "aicard-on")
|
||||
else
|
||||
overlays += image('icons/obj/aicards.dmi', "aicard-on")
|
||||
attack_self(U)
|
||||
|
||||
/obj/item/device/aicard/ex_act(severity)
|
||||
switch(severity)
|
||||
|
||||
@@ -50,10 +50,10 @@ var/list/world_uplinks = list()
|
||||
job = user.mind.assigned_role
|
||||
|
||||
var/dat = "<B>[src.welcome]</B><BR>"
|
||||
dat += "Tele-Crystals left: [src.uses]<BR>"
|
||||
dat += "Telecrystals left: [src.uses]<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Request item:</B><BR>"
|
||||
dat += "<I>Each item costs a number of tele-crystals as indicated by the number following their name.</I><br>"
|
||||
dat += "<I>Each item costs a number of telecrystals as indicated by the number following their name.</I><br>"
|
||||
|
||||
var/category_items = 1
|
||||
for(var/category in ItemsCategory)
|
||||
@@ -262,10 +262,6 @@ var/list/world_uplinks = list()
|
||||
for(var/datum/data/record/L in data_core.general)
|
||||
if(L.fields["id"] == id)
|
||||
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
|
||||
// We trade off being able to automatically add shit for more control over what gets passed to json
|
||||
// and if it's sanitized for html.
|
||||
nanoui_data["exploit"]["nanoui_exploit_record"] = html_encode(L.fields["exploit_record"]) // Change stuff into html
|
||||
nanoui_data["exploit"]["nanoui_exploit_record"] = replacetext(nanoui_data["exploit"]["nanoui_exploit_record"], "\n", "<br>") // change line breaks into <br>
|
||||
nanoui_data["exploit"]["name"] = html_encode(L.fields["name"])
|
||||
nanoui_data["exploit"]["sex"] = html_encode(L.fields["sex"])
|
||||
nanoui_data["exploit"]["age"] = html_encode(L.fields["age"])
|
||||
|
||||
@@ -26,16 +26,20 @@ RCD
|
||||
var/working = 0
|
||||
var/mode = 1
|
||||
var/canRwall = 0
|
||||
var/disabled = 0
|
||||
|
||||
|
||||
New()
|
||||
desc = "A RCD. It currently holds [matter]/[max_matter] matter-units."
|
||||
src.spark_system = new /datum/effect/effect/system/spark_spread
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
rcd_list += src
|
||||
return
|
||||
|
||||
|
||||
Destroy()
|
||||
qdel(spark_system)
|
||||
spark_system = null
|
||||
rcd_list -= src
|
||||
return ..()
|
||||
|
||||
attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
@@ -82,8 +86,6 @@ RCD
|
||||
|
||||
afterattack(atom/A, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(disabled && !isrobot(user))
|
||||
return 0
|
||||
if(istype(A,/area/shuttle)||istype(A,/turf/space/transit))
|
||||
return 0
|
||||
if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock)))
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
return
|
||||
else if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && src.welding)
|
||||
msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] triggered a fueltank explosion.")
|
||||
msg_admin_attack("[key_name_admin(user)] triggered a fueltank explosion.")
|
||||
log_game("[key_name(user)] triggered a fueltank explosion.")
|
||||
user << "\red That was stupid of you."
|
||||
var/obj/structure/reagent_dispensers/fueltank/tank = O
|
||||
|
||||
@@ -251,7 +251,7 @@ var/send_emergency_team
|
||||
if("Engineer")
|
||||
engineer_slots -= 1
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/engineer(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full/multitool(M), slot_belt)
|
||||
@@ -275,7 +275,7 @@ var/send_emergency_team
|
||||
if("Security")
|
||||
security_slots -= 1
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/security(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
|
||||
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/response_team(M), slot_belt)
|
||||
@@ -299,7 +299,7 @@ var/send_emergency_team
|
||||
if("Medic")
|
||||
medical_slots -= 1
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/medical(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
|
||||
|
||||
var/obj/item/weapon/card/id/W = new(src)
|
||||
@@ -321,7 +321,7 @@ var/send_emergency_team
|
||||
if("Commander")
|
||||
command_slots = 0
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/commander(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/responseteam(M), slot_in_backpack)
|
||||
|
||||
var/obj/item/weapon/card/id/W = new(src)
|
||||
|
||||
@@ -676,11 +676,10 @@ var/list/mechtoys = list(
|
||||
supply_controller.points -= P.cost
|
||||
supply_controller.shoppinglist += O
|
||||
temp = "Thanks for your order.<BR>"
|
||||
temp += "<BR><A href='?src=\ref[src];viewrequests=1'>Back</A> <A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
|
||||
else
|
||||
temp = "Not enough supply points.<BR>"
|
||||
temp += "<BR><A href='?src=\ref[src];viewrequests=1'>Back</A> <A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
|
||||
break
|
||||
temp += "<BR><A href='?src=\ref[src];viewrequests=1'>Back</A> <A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
|
||||
|
||||
else if (href_list["vieworders"])
|
||||
temp = "Current approved orders: <BR><BR>"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
item_state = "electronic"
|
||||
flags = CONDUCT | NOBLUDGEON
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=4;biotech=2"
|
||||
var/scanning = 0
|
||||
var/list/log = list()
|
||||
|
||||
|
||||
@@ -922,7 +922,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert(M), slot_back)
|
||||
|
||||
var/obj/item/weapon/card/id/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card (Emergency Response Team - Member)"
|
||||
@@ -944,7 +944,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert/alt(M), slot_l_ear)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt)
|
||||
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
|
||||
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/ert/commander(M), slot_back)
|
||||
|
||||
var/obj/item/weapon/card/id/W = new(M)
|
||||
W.name = "[M.real_name]'s ID Card (Emergency Response Team - Leader)"
|
||||
|
||||
@@ -44,12 +44,12 @@
|
||||
if((istype(W, /obj/item/weapon/weldingtool) && W:welding))
|
||||
if(!status)
|
||||
status = 1
|
||||
bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
|
||||
msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
|
||||
bombers += "[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]"
|
||||
msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]")
|
||||
user << "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>"
|
||||
else
|
||||
status = 0
|
||||
bombers += "[key_name(user)] unwelded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
|
||||
bombers += "[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]"
|
||||
user << "<span class='notice'>The hole has been closed.</span>"
|
||||
add_fingerprint(user)
|
||||
..()
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
if(!(C.species.flags & IS_SYNTHETIC))
|
||||
C.hallucination += rand(50, 100)
|
||||
/datum/event/mass_hallucination/announce()
|
||||
command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage")
|
||||
command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucinations, but no further damage")
|
||||
|
||||
@@ -302,9 +302,9 @@
|
||||
|
||||
user.lastattacked = M
|
||||
M.lastattacker = user
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
|
||||
msg_admin_attack("[user.name] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" )
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [key_name(user)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
|
||||
msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" )
|
||||
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
@@ -63,7 +63,7 @@ var/list/karma_spenders = list()
|
||||
|
||||
var/list/karma_list = list("Cancel")
|
||||
for(var/mob/M in player_list) if(M.client && M.mind)
|
||||
if(isAntag(M)) // Don't include special roles, because players use it to meta
|
||||
if(isNonCrewAntag(M)) // Don't include special roles, because players use it to meta
|
||||
continue
|
||||
karma_list += M
|
||||
|
||||
|
||||
@@ -1225,6 +1225,9 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
|
||||
else if(!seer)
|
||||
see_in_dark = species.darksight
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if(see_override) //Override all
|
||||
see_invisible = see_override
|
||||
|
||||
if(ticker && ticker.mode.name == "nations")
|
||||
process_nations()
|
||||
|
||||
@@ -55,6 +55,7 @@ var/list/ai_verbs_default = list(
|
||||
var/ioncheck[1]
|
||||
var/lawchannel = "Common" // Default channel on which to state laws
|
||||
var/icon/holo_icon//Default is assigned when AI is created.
|
||||
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
|
||||
var/obj/item/device/pda/ai/aiPDA = null
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
var/custom_sprite = 0 //For our custom sprites
|
||||
@@ -66,7 +67,7 @@ var/list/ai_verbs_default = list(
|
||||
var/processing_time = 100
|
||||
var/list/datum/AI_Module/current_modules = list()
|
||||
var/fire_res_on_core = 0
|
||||
|
||||
var/can_dominate_mechs = 0
|
||||
var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE
|
||||
var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
|
||||
var/malf_cooldown = 0 //Cooldown var for malf modules
|
||||
@@ -536,6 +537,14 @@ var/list/ai_verbs_default = list(
|
||||
botcall()
|
||||
return
|
||||
|
||||
if (href_list["ai_take_control"]) //Mech domination
|
||||
var/obj/mecha/M = locate(href_list["ai_take_control"])
|
||||
if(controlled_mech)
|
||||
src << "You are already loaded into an onboard computer!"
|
||||
return
|
||||
if(M)
|
||||
M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
|
||||
|
||||
else if (href_list["faketrack"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
@@ -981,6 +990,24 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/is_in_chassis()
|
||||
return istype(loc, /turf)
|
||||
|
||||
/mob/living/silicon/ai/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
|
||||
if(!mind)
|
||||
user << "<span class='warning'>No intelligence patterns detected.</span>" //No more magical carding of empty cores, AI RETURN TO BODY!!!11
|
||||
return
|
||||
if (mind.special_role == "malfunction") //AI MALF!!
|
||||
user << "<span class='boldannounce'>ERROR</span>: Remote transfer interface disabled."//Do ho ho ho~
|
||||
return
|
||||
new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
|
||||
aiRestorePowerRoutine = 0//So the AI initially has power.
|
||||
control_disabled = 1//Can't control things remotely if you're stuck in a card!
|
||||
aiRadio.disabledAi = 1 //No talking on the built-in radio for you either!
|
||||
loc = card//Throw AI into the card.
|
||||
src << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
|
||||
#undef AI_CHECK_WIRELESS
|
||||
#undef AI_CHECK_RADIO
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
loc = T.loc
|
||||
if (istype(loc, /area))
|
||||
//stage = 4
|
||||
if (!loc.power_equip && !istype(src.loc,/obj/item))
|
||||
if (!loc.power_equip && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha)))
|
||||
//stage = 5
|
||||
blind = 1
|
||||
|
||||
@@ -56,7 +56,8 @@
|
||||
src.sight |= SEE_OBJS
|
||||
src.see_in_dark = 8
|
||||
src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
|
||||
//Congratulations! You've found a way for AI's to run without using power!
|
||||
//Todo: Without snowflaking up master_controller procs find a way to make AI use_power but only when APC's clear the area usage the tick prior
|
||||
@@ -97,7 +98,7 @@
|
||||
src.see_in_dark = 0
|
||||
src.see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if (((!loc.power_equip) || istype(T, /turf/space)) && !istype(src.loc,/obj/item))
|
||||
if (((!loc.power_equip) || istype(T, /turf/space)) && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha)))
|
||||
if (src:aiRestorePowerRoutine==0)
|
||||
src:aiRestorePowerRoutine = 1
|
||||
|
||||
|
||||
@@ -174,6 +174,18 @@ proc/isAntag(A)
|
||||
if(C.mind && C.mind.special_role)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/isNonCrewAntag(A)
|
||||
if(!isAntag(A))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/C = A
|
||||
var/special_role = C.mind.special_role
|
||||
var/list/crew_roles = list("traitor", "Changeling", "Vampire", "Cultist", "Head Revolutionary", "Revolutionary", "malfunctioning AI", "Shadowling", "loyalist", "mutineer", "Response Team")
|
||||
if((special_role in crew_roles))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
proc/isnewplayer(A)
|
||||
if(istype(A, /mob/new_player))
|
||||
@@ -480,7 +492,7 @@ var/list/intents = list("help","disarm","grab","harm")
|
||||
name = realname
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || check_rights(R_MOD,0)) && (M.client.prefs.toggles & CHAT_DEAD))
|
||||
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || check_rights(R_MOD,0,M)) && (M.client.prefs.toggles & CHAT_DEAD))
|
||||
var/follow
|
||||
var/lname
|
||||
if(subject)
|
||||
@@ -491,7 +503,7 @@ var/list/intents = list("help","disarm","grab","harm")
|
||||
var/mob/dead/observer/DM
|
||||
if(istype(subject, /mob/dead/observer))
|
||||
DM = subject
|
||||
if(check_rights(R_MOD,0)) // What admins see
|
||||
if(check_rights(R_MOD,0,M)) // What admins see
|
||||
lname = "[keyname][(DM && DM.anonsay) ? "*" : (DM ? "" : "^")] ([name])"
|
||||
else
|
||||
if(DM && DM.anonsay) // If the person is actually observer they have the option to be anonymous
|
||||
|
||||
@@ -191,8 +191,6 @@
|
||||
|
||||
if(world.time < move_delay) return
|
||||
|
||||
if(isAI(mob)) return AIMove(n,direct,mob)
|
||||
|
||||
if(!isliving(mob)) return mob.Move(n,direct)
|
||||
|
||||
if(moving) return 0
|
||||
@@ -211,10 +209,6 @@
|
||||
var/mob/spirit/currentSpirit = mob
|
||||
return currentSpirit.Spirit_Move(direct)
|
||||
|
||||
// handle possible AI movement
|
||||
if(isAI(mob))
|
||||
return AIMove(n,direct,mob)
|
||||
|
||||
if(mob.notransform) return//This is sota the goto stop mobs from moving var
|
||||
|
||||
if(isliving(mob))
|
||||
@@ -235,6 +229,9 @@
|
||||
if(mob.remote_control) //we're controlling something, our movement is relayed to it
|
||||
return mob.remote_control.relaymove(mob, direct)
|
||||
|
||||
if(isAI(mob))
|
||||
return AIMove(n,direct,mob)
|
||||
|
||||
if(!mob.canmove)
|
||||
return
|
||||
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
|
||||
var/obj/item/device/assembly_holder/H = W
|
||||
if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter))
|
||||
msg_admin_attack("[key_name_admin(user)][isAntag(user) ? "(ANTAG)" : ""] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.")
|
||||
log_game("[key_name(user)] rigged fueltank at ([loc.x],[loc.y],[loc.z]) for explosion.")
|
||||
msg_admin_attack("[key_name_admin(user)] rigged a fueltank for explosion (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_game("[key_name(user)] rigged fueltank a fueltank for explosion at [loc.x], [loc.y], [loc.z]")
|
||||
|
||||
rig = W
|
||||
user.drop_item()
|
||||
|
||||
@@ -169,10 +169,10 @@
|
||||
msg = "[user.name] stuffs [target.name] into the [src]!"
|
||||
user << "You stuff [target.name] into the [src]!"
|
||||
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has placed [target.name] ([target.ckey]) in disposals.</font>")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been placed in disposals by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has placed [key_name(target)] in disposals.</font>")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been placed in disposals by [key_name(user)]</font>")
|
||||
if(target.ckey)
|
||||
msg_admin_attack("[user] ([user.ckey])[isAntag(user) ? "(ANTAG)" : ""] placed [target] ([target.ckey]) in a disposals unit. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
msg_admin_attack("[key_name_admin(user)] placed [key_name_admin(target)] in a disposals unit")
|
||||
else
|
||||
return
|
||||
if (target.client)
|
||||
|
||||
@@ -99,4 +99,15 @@
|
||||
build_type = PROTOLATHE
|
||||
materials = list("$metal" = 4000, "$glass" = 1000)
|
||||
build_path = /obj/item/clothing/mask/gas/welding
|
||||
category = list("Equipment")
|
||||
|
||||
/datum/design/detective_scanner
|
||||
name = "Forensic Scanner"
|
||||
desc = "A high tech scanner designed for forensic evidence collection, DNA recovery, and fiber analysis."
|
||||
id = "detectivescanner"
|
||||
req_tech = list("biotech" = 2, "magnets" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list("$metal" = 6000, "$glass" = 2000)
|
||||
build_path = /obj/item/device/detective_scanner
|
||||
locked = 1 //no validhunting scientists.
|
||||
category = list("Equipment")
|
||||
@@ -210,6 +210,6 @@
|
||||
M.lastattacker = user
|
||||
|
||||
if(inserted_battery.battery_effect)
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Tapped [M.name] ([M.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Tapped by [user.name] ([user.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
|
||||
msg_admin_attack("[key_name(user)][isAntag(user) ? "(ANTAG)" : ""] tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" )
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Tapped by [key_name(user)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
|
||||
msg_admin_attack("[key_name_admin(user)] tapped [key_name_admin(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" )
|
||||
|
||||
@@ -174,8 +174,7 @@ var/global/maint_all_access = 0
|
||||
for(var/obj/machinery/door/airlock/D in A)
|
||||
D.emergency = 1
|
||||
D.update_icon(0)
|
||||
world << "<font size=4 color='red'>Attention!</font>"
|
||||
world << "<font color='red'>The maintenance access requirement has been revoked on all airlocks.</font>"
|
||||
minor_announcement.Announce("The maintenance access requirement has been revoked on all airlocks.")
|
||||
maint_all_access = 1
|
||||
|
||||
/proc/revoke_maint_all_access()
|
||||
@@ -183,6 +182,5 @@ var/global/maint_all_access = 0
|
||||
for(var/obj/machinery/door/airlock/D in A)
|
||||
D.emergency = 0
|
||||
D.update_icon(0)
|
||||
world << "<font size=4 color='red'>Attention!</font>"
|
||||
world << "<font color='red'>The maintenance access requirement has been readded on all maintenance airlocks.</font>"
|
||||
minor_announcement.Announce("The maintenance access requirement has been readded on all maintenance airlocks.")
|
||||
maint_all_access = 0
|
||||
@@ -144,7 +144,7 @@
|
||||
|
||||
/obj/vehicle/train/cargo/trolley/RunOver(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)]</font>")
|
||||
|
||||
/obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
@@ -153,10 +153,10 @@
|
||||
var/mob/living/carbon/human/D = load
|
||||
D << "\red \b You ran over [H]!"
|
||||
visible_message("<B>\red \The [src] ran over [H]!</B>")
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])</font>")
|
||||
msg_admin_attack("[D.name] ([D.ckey])[isAntag(D) ? "(ANTAG)" : ""] ran over [H.name] ([H.ckey]). (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)], driven by [key_name(D)]</font>")
|
||||
msg_admin_attack("[key_name_admin(D)] ran over [key_name_admin(H)]")
|
||||
else
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
|
||||
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [key_name(H)]</font>")
|
||||
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 75 KiB |
@@ -0,0 +1,63 @@
|
||||
<!--
|
||||
Title: AI System Integrity Restorer
|
||||
Used In File(s): \code\game\machinery\computer\aifixer.dm
|
||||
-->
|
||||
{{if data.occupant}}
|
||||
<div class="item">
|
||||
<h2>Stored AI: {{:data.occupant}}</h2>
|
||||
<h3>Information</h3>
|
||||
<div class="itemLabel">
|
||||
Integrity
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class="{{if data.integrity >= 75}}good{{else data.integrity >= 25}}average{{else}}bad{{/if}}">{{:data.integrity}}%</span>
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Status
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.stat == 2}}
|
||||
<span class="bad">Non-functional</span>
|
||||
{{else}}
|
||||
<span class="good">Functional</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Wireless Activity
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Enabled','check',{'wireless' : 0},data.wireless == 0 ? 'selected' : '')}}
|
||||
{{:helper.link('Disabled','close',{'wireless' : 1},data.wireless == 1 ? 'selected' : '')}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Subspace Transceiver
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Enabled','check',{'radio' : 0},data.radio == 0 ? 'selected' : '')}}
|
||||
{{:helper.link('Disabled','close',{'radio' : 1},data.radio == 1 ? 'selected' : '')}}
|
||||
</div>
|
||||
<h3>Laws</h3>
|
||||
{{if data.zeroth}}
|
||||
0: {{:data.zeroth}}<br />
|
||||
{{/if}}
|
||||
{{for data.laws}}
|
||||
{{:value.number}}: {{:value.law}}<br />
|
||||
{{empty}}
|
||||
{{if !data.zeroth}}
|
||||
<span class='bad'>No laws detected!</span>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
|
||||
<h3>Actions</h3>
|
||||
{{if data.active}}
|
||||
<b>Reconstruction in progress, please wait.</b>
|
||||
{{:helper.displayBar(data.integrity, 0, 100, (data.integrity >= 75) ? 'good' : (data.integrity >= 25) ? 'average' : 'bad')}}
|
||||
<span class="statusValue">{{:data.integrity}}%</span>
|
||||
{{/if}}
|
||||
<div class="item">
|
||||
{{:helper.link('Reconstruct', 'wrench', {'fix' : 1}, data.active || data.integrity >= 100 ? 'disabled' : '')}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<h3>No artificial intelligence detected.</h3>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,81 @@
|
||||
<!--
|
||||
Title: Exosuit Control Console
|
||||
Used In File(s): \code\game\mecha\mecha_control_console.dm
|
||||
-->
|
||||
{{if data.screen == 0}}
|
||||
{{for data.mechas}}
|
||||
<hr>
|
||||
<div class='item'>
|
||||
<h2>{{:value.name}}</h2>
|
||||
<h3>Information</h3>
|
||||
<div class="itemLabel">
|
||||
Pilot:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.pilot}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Integrity:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class="{{if value.integrity >= 75}}good{{else value.integrity >= 25}}average{{else}}bad{{/if}}">{{:value.integrity}}%</span>
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Location:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.location}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Airtank:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.airtank}}kPa
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Active Equipment:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.equipment}}
|
||||
</div>
|
||||
{{if value.hascargo}}
|
||||
<div class="itemLabel">
|
||||
Cargo Used:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.cargo}}%
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<h3>Power Cell</h3>
|
||||
{{if value.cell}}
|
||||
<span class="itemLabel">
|
||||
Rating:
|
||||
</span>
|
||||
<span class="itemContent">
|
||||
{{:value.cell_capacity}}
|
||||
</span>
|
||||
{{:helper.displayBar(value.cell_percentage, 0, 100, (value.cell_percentage >= 50) ? 'good' : (value.cell_percentage >= 25) ? 'average' : 'bad')}}
|
||||
<b> {{:value.cell_percentage}}%</b>
|
||||
{{else}}
|
||||
<b><i>Not Installed</i></b>
|
||||
{{:helper.displayBar(100, 0, 100, 'bad')}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
<h3>Actions</h3>
|
||||
{{:helper.link('Send Message', 'mail-closed', {'send_message' : value.reference})}}
|
||||
{{:helper.link('Exosuit Log', 'search', {'get_log' : value.reference})}}
|
||||
{{:helper.link('EMP Pulse', 'alert', {'shock' : value.reference}, null, 'redButton')}}
|
||||
</div>
|
||||
{{empty}}
|
||||
<div class='item'>
|
||||
<h3>No mecha trackers were found.</h3>
|
||||
</div>
|
||||
{{/for}}
|
||||
{{else}}
|
||||
<div style="margin-bottom: 10px;" class="item">
|
||||
{{:helper.link('Return', 'close', {'return' : 1})}}
|
||||
</div>
|
||||
{{:data.log}}
|
||||
{{/if}}
|
||||
@@ -5,84 +5,67 @@ Used In File(s): \code\game\gamemodes\nuclear\nuclearbomb.dm
|
||||
{{if data.is_syndicate}}
|
||||
{{:helper.syndicateMode()}}
|
||||
{{/if}}
|
||||
{{if !data.hacking}}
|
||||
<div class="item">
|
||||
<b>Authorization Disk:</b> {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}}
|
||||
</div>
|
||||
<hr>
|
||||
<div class="item">
|
||||
<div><b>Status:</b> {{:data.authstatus}} - {{:data.safe}}</div>
|
||||
<div><b>Timer:</b> {{:data.time}}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item">
|
||||
<b>Authorization Disk:</b> {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}}
|
||||
</div>
|
||||
{{if data.auth && data.yescode}}
|
||||
<div class="item">
|
||||
<b>Timer:</b> {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Time:</b> {{:helper.link('--', '', {'time' : -10}, data.time <= 120 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 120 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="item">
|
||||
<b>Timer:</b> {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Time:</b> {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{if data.auth && data.yescode}}
|
||||
<div class="item">
|
||||
<b>Safety:</b> {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'selected')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Anchor:</b> {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="item">
|
||||
<b>Safety:</b> {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Anchor:</b> {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item">
|
||||
<div><b>Status:</b> {{:data.authstatus}} - {{:data.safe}}</div>
|
||||
<div><b>Timer:</b> {{:data.time}}</div>
|
||||
>{{if data.message}} {{:data.message}}{{/if}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item">
|
||||
{{if data.auth && data.yescode}}
|
||||
<div class="item">
|
||||
<b>Timer:</b> {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'selected' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Time:</b> {{:helper.link('--', '', {'time' : -10}, data.time <= 60 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 60 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="item">
|
||||
<b>Timer:</b> {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Time:</b> {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{if data.auth && data.yescode}}
|
||||
<div class="item">
|
||||
<b>Safety:</b> {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'selected')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Anchor:</b> {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="item">
|
||||
<b>Safety:</b> {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<b>Anchor:</b> {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item">
|
||||
>{{if data.message}} {{:data.message}}{{/if}}
|
||||
{{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item">
|
||||
{{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}}
|
||||
</div>
|
||||
{{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="block">
|
||||
<h3>Exposed Wires</h3>
|
||||
{{for data.wires}}
|
||||
<div class="item">
|
||||
<div class="{{:value.name}} itemLabel">{{:value.name}}</div>
|
||||
<div class="itemContent">{{:helper.link(value.cut ? 'Mend' : 'Cut', '', {'wire' : value.name, 'act' : 'wire'})}} {{:helper.link('Pulse', '', {'wire' : value.name, 'act' : 'pulse'})}}</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div class="item">
|
||||
The device is {{if data.timing}}shaking!{{else}}still.{{/if}}<br />
|
||||
The device is {{if data.safety}}quiet.{{else}}whirring.{{/if}}<br />
|
||||
The lights are {{if data.lighthack}}static.{{else}}functional.{{/if}}<br />
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -0,0 +1,33 @@
|
||||
<!--
|
||||
Title: Pod Tracking Console
|
||||
Used In File(s): \code\game\machinery\computer\pod_tracking_console.dm
|
||||
-->
|
||||
<style>
|
||||
h3 {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.refresh {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 50px;
|
||||
}
|
||||
</style>
|
||||
<div class="refresh">{{:helper.link('Refresh', 'refresh', {'refresh' : 1})}}</div>
|
||||
<h2>Pods</h2>
|
||||
{{for data.pods}}
|
||||
<hr>
|
||||
<div class="item">
|
||||
<h3>{{:value.name}}</h3>
|
||||
<div class="itemLabel">Pilot</div>
|
||||
<div class="itemContent">{{:value.occupant}}</div>
|
||||
<div class="itemLabel">Passenger</div>
|
||||
<div class="itemContent">{{:value.occupant2}}</div>
|
||||
<div class="itemLabel">Coordinates</div>
|
||||
<div class="itemContent">{{:value.x}}, {{:value.y}}, {{:value.z}}</div>
|
||||
</div>
|
||||
{{empty}}
|
||||
<div class='item'>
|
||||
<h3>No pod trackers were found.</h3>
|
||||
</div>
|
||||
{{/for}}
|
||||
@@ -64,11 +64,10 @@
|
||||
{{:value.cell_capacity}}
|
||||
</span>
|
||||
{{:helper.displayBar(value.cell_percentage, 0, 100, (value.cell_percentage >= 50) ? 'good' : (value.cell_percentage >= 25) ? 'average' : 'bad')}}
|
||||
<b> {{:value.cell_percentage}} %</b>
|
||||
<b> {{:value.cell_percentage}}%</b>
|
||||
{{else}}
|
||||
<b><i>Not Installed</i></b>
|
||||
{{:helper.displayBar(100, 0, 100, 'bad')}}
|
||||
<b> N/A %</b>
|
||||
{{/if}}
|
||||
<h3>Actions</h3>
|
||||
{{if value.status == "Operational"}}
|
||||
|
||||
@@ -12,7 +12,7 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link(data.descriptions ? 'Hide Descriptions' : 'Show Descriptions', 'gear', {'descriptions' : 1}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link(data.descriptions ? 'Hide Descriptions' : 'Show Descriptions', 'gear', {'descriptions' : 1}, data.menu == 0 ? '' : 'disabled', 'fixedLeftWider')}}
|
||||
{{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}}
|
||||
{{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
|
||||
@@ -80,9 +80,6 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
|
||||
<span class="good">Age: </span> <span class="average">{{:data.exploit.age}} </span><br>
|
||||
<span class="good">Rank: </span> <span class="average">{{:data.exploit.rank}} </span><br>
|
||||
<span class="good">Fingerprint: </span> <span class="average">{{:data.exploit.fingerprint}} </span><br>
|
||||
|
||||
<br>Acquired Information:<br>
|
||||
<span class="good">Notes:<br> </span> <span class="average">{{:data.exploit.nanoui_exploit_record}}</span><br><br>
|
||||
{{else}}
|
||||
<span class="bad">
|
||||
No exploitative information acquired!
|
||||
|
||||
@@ -225,6 +225,7 @@
|
||||
#include "code\datums\wires\camera.dm"
|
||||
#include "code\datums\wires\explosive.dm"
|
||||
#include "code\datums\wires\mulebot.dm"
|
||||
#include "code\datums\wires\nuclearbomb.dm"
|
||||
#include "code\datums\wires\particle_accelerator.dm"
|
||||
#include "code\datums\wires\radio.dm"
|
||||
#include "code\datums\wires\robot.dm"
|
||||
|
||||
Reference in New Issue
Block a user