Adds AI control beacons for exosuits (Winter Thaw 2017) (#23320)

* Adds AI control beacons for exosuits

* Diagnostic HUD entry + Design Fix

- Adds Diagnostic HUD entries for mecha beacons. (Green for normal, Blue
for AI)
- Fixes AI beacon research designs to havep roper requirements

* Sanity checks for mech hijacking
This commit is contained in:
Xhuis
2017-01-28 18:10:08 +01:00
committed by AnturK
parent 65aa7782f4
commit bdb383ae40
10 changed files with 95 additions and 20 deletions
+2 -1
View File
@@ -14,8 +14,9 @@
#define DIAG_BATT_HUD "10"// Borg/Mech power meter
#define DIAG_MECH_HUD "11"// Mech health bar
#define DIAG_BOT_HUD "12"// Bot HUDs
#define DIAG_TRACK_HUD "13"// Mech tracking beacon
//for antag huds. these are used at the /mob level
#define ANTAG_HUD "13"
#define ANTAG_HUD "14"
//data HUD (medhud, sechud) defines
//Don't forget to update human/New() if you change these!
+14 -1
View File
@@ -45,7 +45,7 @@
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
/datum/atom_hud/data/diagnostic
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD)
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD)
/* MED/SEC/DIAG HUD HOOKS */
@@ -326,6 +326,19 @@
if(internal_damage)
holder.icon_state = "hudwarn"
/obj/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech
var/image/holder = hud_list[DIAG_TRACK_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
var/new_icon_state //This var exists so that the holder's icon state is set only once in the event of multiple mech beacons.
for(var/obj/item/mecha_parts/mecha_tracking/T in trackers)
if(T.ai_beacon) //Beacon with AI uplink
new_icon_state = "hudtrackingai"
break //Immediately terminate upon finding an AI beacon to ensure it is always shown over the normal one, as mechs can have several trackers.
else
new_icon_state = "hudtracking"
holder.icon_state = new_icon_state
/*~~~~~~~~~
Bots!
~~~~~~~~~~*/
+46 -15
View File
@@ -49,7 +49,6 @@
var/lights_power = 6
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it.
//inner atmos
var/use_internal_tank = 0
@@ -117,7 +116,7 @@
var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision)
hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD)
hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD)
/obj/mecha/New()
@@ -142,6 +141,7 @@
diag_hud_set_mechhealth()
diag_hud_set_mechcell()
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
/obj/mecha/Destroy()
@@ -373,6 +373,7 @@
diag_hud_set_mechhealth()
diag_hud_set_mechcell()
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
@@ -627,6 +628,21 @@
break
//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>"
else
examine(user)
if(occupant)
user << "<span class='warning'>This exosuit has a pilot and cannot be controlled.</span>"
return
var/can_control_mech = 0
for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers)
can_control_mech = 1
user << "<span class='notice'>\icon[src] Status of [name]:</span>\n\
[A.get_mecha_info()]"
break
if(!can_control_mech)
user << "<span class='warning'>You cannot control exosuits without AI control beacons installed.</span>"
return
user << "<a href='?src=\ref[user];ai_take_control=\ref[src]'><span class='boldnotice'>Take control of exosuit?</span></a><br>"
/obj/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
if(!..())
@@ -654,12 +670,13 @@
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!
if(AI_MECH_HACK) //Called by AIs on the mech
AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc)
if(AI.can_dominate_mechs)
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.
@@ -693,10 +710,10 @@
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 loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" \
AI << "[AI.can_dominate_mechs ? "<span class='announce'>Takeover of [name] complete! You are now 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='reallybig boldnotice'>Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.</span>"
GrantActions(AI)
GrantActions(AI, !AI.can_dominate_mechs)
//An actual AI (simple_animal mecha pilot) entering the mech
@@ -916,11 +933,25 @@
var/mob/living/brain/brain = occupant
RemoveActions(brain)
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.
RemoveActions(occupant)
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 if(isAI(occupant))
var/mob/living/silicon/ai/AI = occupant
if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf.
RemoveActions(occupant)
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
if(!AI.linked_core)
AI << "<span class='userdanger'>Inactive core destroyed. Unable to return.</span>"
AI.linked_core = null
return
AI << "<span class='notice'>Returning to core...</span>"
AI.controlled_mech = null
AI.remote_control = null
RemoveActions(occupant, 1)
mob_container = AI
newloc = get_turf(AI.linked_core)
qdel(AI.linked_core)
else
return
var/mob/living/L = occupant
+1 -1
View File
@@ -37,7 +37,7 @@
button_icon_state = "mech_eject"
/datum/action/innate/mecha/mech_eject/Activate()
if(!owner || !iscarbon(owner))
if(!owner)
return
if(!chassis || chassis.occupant != owner)
return
+8
View File
@@ -68,6 +68,7 @@
icon_state = "motion2"
w_class = WEIGHT_CLASS_SMALL
origin_tech = "programming=2;magnets=2"
var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
if(!in_mecha())
@@ -115,6 +116,13 @@
return M.get_log_html()
/obj/item/mecha_parts/mecha_tracking/ai_control
name = "exosuit AI control beacon"
desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
origin_tech = "programming=3;magnets=2;engineering=2"
ai_beacon = TRUE
/obj/item/weapon/storage/box/mechabeacons
name = "exosuit tracking beacons"
+1
View File
@@ -264,6 +264,7 @@
W.forceMove(src)
trackers += W
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
diag_hud_set_mechtracking()
return
else
return ..()
+1 -1
View File
@@ -900,7 +900,7 @@
//Mobs on Fire end
// used by secbot and monkeys Crossed
/mob/living/proc/knockOver(var/mob/living/carbon/C)
/mob/living/proc/knockOver(var/mob/living/carbon/C)
C.visible_message("<span class='warning'>[pick( \
"[C] dives out of [src]'s way!", \
"[C] stumbles over [src]!", \
+12 -1
View File
@@ -82,6 +82,8 @@ var/list/ai_list = list()
var/obj/machinery/camera/portable/builtInCamera
var/obj/structure/AIcore/deactivated/linked_core //For exosuit control
/mob/living/silicon/ai/New(loc, datum/ai_laws/L, mob/target_ai)
..()
if(!target_ai) //If there is no player/brain inside.
@@ -419,7 +421,16 @@ var/list/ai_list = list()
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!"
src << "<span class='warning'>You are already loaded into an onboard computer!</span>"
return
if(!cameranet.checkCameraVis(M))
src << "<span class='warning'>Exosuit is no longer near active cameras.</span>"
return
if(lacks_power())
src << "<span class='warning'>You're depowered!</span>"
return
if(!isturf(loc))
src << "<span class='warning'>You aren't in your core!</span>"
return
if(M)
M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
@@ -728,6 +728,16 @@
construction_time = 50
category = list("Misc")
/datum/design/mecha_tracking_ai_control
name = "AI Control Beacon"
id = "mecha_tracking_ai_control"
build_type = MECHFAB
build_path = /obj/item/mecha_parts/mecha_tracking/ai_control
materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_SILVER = 200)
req_tech = list("programming" = 3, "magnets" = 2, "engineering" = 2)
construction_time = 50
category = list("Misc")
/datum/design/drone_shell
name = "Drone Shell"
desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs."
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB