Revert "12/21 modernizations from TG live"

This commit is contained in:
LetterJay
2016-12-22 22:35:44 -06:00
committed by GitHub
parent cf59ac1c3d
commit ae40d4134e
2215 changed files with 86928 additions and 707332 deletions
+102 -72
View File
@@ -14,13 +14,11 @@ var/list/ai_list = list()
/mob/living/silicon/ai
name = "AI"
icon = 'icons/mob/AI.dmi'
icon = 'icons/mob/AI.dmi'//
icon_state = "ai"
anchored = 1
density = 1
canmove = 0
status_flags = CANSTUN|CANPUSH
a_intent = INTENT_HARM //so we always get pushed instead of trying to swap
force_compose = 1 //This ensures that the AI always composes it's own hear message. Needed for hrefs and job display.
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
see_in_dark = 8
@@ -31,7 +29,6 @@ var/list/ai_list = list()
var/obj/machinery/camera/current = null
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
var/requires_power = POWER_REQ_ALL
//var/list/laws = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/viewalerts = 0
@@ -48,6 +45,7 @@ var/list/ai_list = list()
//MALFUNCTION
var/datum/module_picker/malf_picker
var/list/datum/AI_Module/current_modules = list()
var/fire_res_on_core = 0
var/can_dominate_mechs = 0
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
@@ -80,36 +78,14 @@ var/list/ai_list = list()
var/obj/machinery/camera/portable/builtInCamera
/mob/living/silicon/ai/New(loc, datum/ai_laws/L, obj/item/device/mmi/B, safety = 0)
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
..()
if(!safety) //Only used by AIize() to successfully spawn an AI.
if(!B) //If there is no player/brain inside.
new/obj/structure/AIcore/deactivated(loc) //New empty terminal.
qdel(src)//Delete AI.
return
else
if(B.brainmob.mind)
B.brainmob.mind.transfer_to(src)
rename_self("ai")
if(mind.special_role)
mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.")
src << "<span class='userdanger'>You have been installed as an AI! </span>"
src << "<span class='danger'>You must obey your silicon laws above all else. Your objectives will consider you to be dead.</span>"
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary."
src << "For department channels, use the following say commands:"
src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science."
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
rename_self("ai")
name = real_name
anchored = 1
canmove = 0
density = 1
loc = loc
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
@@ -134,12 +110,37 @@ var/list/ai_list = list()
radio = new /obj/item/device/radio/headset/ai(src)
aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
if(isturf(loc))
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall,\
/mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/set_automatic_say_channel)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
qdel(src)//Delete AI.
return
else
if (B.brainmob.mind)
B.brainmob.mind.transfer_to(src)
rename_self("ai")
if(mind.special_role)
mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.")
src << "<span class='userdanger'>You have been installed as an AI! </span>"
src << "<span class='danger'>You must obey your silicon laws above all else. Your objectives will consider you to be dead.</span>"
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary."
src << "For department channels, use the following say commands:"
src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science."
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
ai_list += src
shuttle_caller_list += src
@@ -156,9 +157,7 @@ var/list/ai_list = list()
shuttle_caller_list -= src
SSshuttle.autoEvac()
qdel(eyeobj) // No AI, no Eye
malfhack = null
. = ..()
return ..()
/mob/living/silicon/ai/verb/pick_icon()
@@ -294,7 +293,8 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += data_core.get_manifest()
for(var/datum/data/record/t in sortRecord(data_core.general))
dat += t.fields["name"] + " - " + t.fields["rank"] + "<br>"
dat += "</body></html>"
src << browse(dat, "window=airoster")
@@ -303,7 +303,7 @@ var/list/ai_list = list()
/mob/living/silicon/ai/proc/ai_call_shuttle()
if(stat == DEAD)
return //won't work if dead
if(isAI(usr))
if(istype(usr,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
usr << "Wireless control is disabled!"
@@ -320,8 +320,10 @@ var/list/ai_list = list()
if(C)
C.post_status("shuttle")
return
/mob/living/silicon/ai/cancel_camera()
view_core()
src.view_core()
/mob/living/silicon/ai/verb/toggle_anchor()
set category = "AI Commands"
@@ -332,7 +334,7 @@ var/list/ai_list = list()
return //won't work if dead
anchored = !anchored // Toggles the anchor
src << "<b>You are now [anchored ? "" : "un"]anchored.</b>"
src << "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]"
// the message in the [] will change depending whether or not the AI is anchored
/mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore
@@ -342,7 +344,7 @@ var/list/ai_list = list()
set category = "Malfunction"
if(stat == DEAD)
return //won't work if dead
if(isAI(usr))
if(istype(usr,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
src << "Wireless control is disabled!"
@@ -350,9 +352,41 @@ var/list/ai_list = list()
SSshuttle.cancelEvac(src)
return
/mob/living/silicon/ai/blob_act(obj/effect/blob/B)
if (stat != DEAD)
adjustBruteLoss(60)
updatehealth()
return 1
return 0
/mob/living/silicon/ai/restrained(ignore_grab)
. = 0
/mob/living/silicon/ai/emp_act(severity)
if (prob(30))
switch(pick(1,2))
if(1)
view_core()
if(2)
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
..()
/mob/living/silicon/ai/ex_act(severity, target)
..()
switch(severity)
if(1)
gib()
if(2)
if (stat != DEAD)
adjustBruteLoss(60)
adjustFireLoss(60)
if(3)
if (stat != DEAD)
adjustBruteLoss(30)
return
/mob/living/silicon/ai/Topic(href, href_list)
if(usr != src)
return
@@ -377,7 +411,7 @@ var/list/ai_list = list()
src << browse(last_paper_seen, "window=show_paper")
//Carn: holopad requests
if(href_list["jumptoholopad"])
var/obj/machinery/holopad/H = locate(href_list["jumptoholopad"])
var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"])
if(stat == CONSCIOUS)
if(H)
H.attack_ai(src) //may as well recycle
@@ -424,6 +458,19 @@ var/list/ai_list = list()
if(M)
M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
/mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj)
..(Proj)
updatehealth()
return 2
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
..()
return
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
@@ -691,7 +738,7 @@ var/list/ai_list = list()
src << "Camera lights deactivated."
for (var/obj/machinery/camera/C in lit_cameras)
C.SetLuminosity(0)
C.set_light(0)
lit_cameras = list()
return
@@ -699,6 +746,7 @@ var/list/ai_list = list()
light_cameras()
src << "Camera lights activated."
return
//AI_CAMERA_LUMINOSITY
@@ -747,6 +795,9 @@ var/list/ai_list = list()
return //won't work if dead
set_autosay()
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
return
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
if(!..())
return
@@ -758,11 +809,19 @@ var/list/ai_list = list()
ai_restore_power()//So the AI initially has power.
control_disabled = 1//Can't control things remotely if you're stuck in a card!
radio_enabled = 0 //No talking on the built-in radio for you either!
forceMove(card)
loc = card//Throw AI into the card.
card.AI = src
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."
/mob/living/silicon/ai/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
return // no eyes, no flashing
/mob/living/silicon/ai/attackby(obj/item/weapon/W, mob/user, params)
if(W.force && W.damtype != STAMINA && src.stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
return ..()
/mob/living/silicon/ai/can_buckle()
return 0
@@ -839,32 +898,3 @@ var/list/ai_list = list()
if(..()) //successfully ressuscitated from death
icon_state = "ai"
. = 1
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
malfhack = null
malfhacking = 0
clear_alert("hackingapc")
if(!istype(apc) || qdeleted(apc) || apc.stat & BROKEN)
src << "<span class='danger'>Hack aborted. The designated APC no \
longer exists on the power network.</span>"
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
else if(apc.aidisabled)
src << "<span class='danger'>Hack aborted. \The [apc] is no \
longer responding to our systems.</span>"
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 1)
else
malf_picker.processing_time += 10
apc.malfai = parent || src
apc.malfhack = TRUE
apc.locked = TRUE
apc.coverlocked = TRUE
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, 1)
src << "Hack complete. \The [apc] is now under your \
exclusive control."
apc.update_icon()
/mob/living/silicon/ai/spawned/New(loc, datum/ai_laws/L, obj/item/device/mmi/B, safety = 0)
..(loc,L,B,1)
@@ -1,53 +0,0 @@
/mob/living/silicon/ai/attacked_by(obj/item/I, mob/living/user, def_zone)
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
return ..()
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!ticker || !ticker.mode)
M << "You cannot attack people before the game has started."
return
..()
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
return //immune to slimes
/mob/living/silicon/ai/blob_act(obj/structure/blob/B)
if (stat != DEAD)
adjustBruteLoss(60)
updatehealth()
return 1
return 0
/mob/living/silicon/ai/emp_act(severity)
if (prob(30))
switch(pick(1,2))
if(1)
view_core()
if(2)
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
..()
/mob/living/silicon/ai/ex_act(severity, target)
switch(severity)
if(1)
gib()
if(2)
if (stat != DEAD)
adjustBruteLoss(60)
adjustFireLoss(60)
if(3)
if (stat != DEAD)
adjustBruteLoss(30)
/mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj)
..(Proj)
updatehealth()
return 2
/mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
return // no eyes, no flashing
+9 -6
View File
@@ -23,14 +23,17 @@
if(nuking)
set_security_level("red")
nuking = FALSE
for(var/obj/item/weapon/pinpointer/P in pinpointer_list)
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
P.nuke_warning = FALSE
nuking = 0
SSshuttle.emergencyNoEscape = 0
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
SSshuttle.emergency.mode = SHUTTLE_DOCKED
SSshuttle.emergency.timer = world.time
priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
for(var/obj/item/weapon/pinpointer/point in pinpointer_list)
point.the_disk = null //Point back to the disk.
if(doomsday_device)
doomsday_device.timing = FALSE
SSshuttle.clearHostileEnvironment(doomsday_device)
doomsday_device.timing = 0
qdel(doomsday_device)
if(explosive)
spawn(10)
@@ -114,8 +114,8 @@
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1)
t.obscured.plane = LIGHTING_PLANE+1
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 16)
obscured += t.obscured
for(var/eye in seenby)
var/mob/camera/aiEye/m = eye
@@ -169,8 +169,7 @@
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1)
t.obscured.plane = LIGHTING_PLANE+1
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 16)
obscured += t.obscured
#undef UPDATE_BUFFER
@@ -24,10 +24,9 @@
cameranet.visibility(src)
if(ai.client)
ai.client.eye = src
update_parallax_contents()
//Holopad
if(istype(ai.current, /obj/machinery/holopad))
var/obj/machinery/holopad/H = ai.current
if(istype(ai.current, /obj/machinery/hologram/holopad))
var/obj/machinery/hologram/holopad/H = ai.current
H.move_hologram(ai)
/mob/camera/aiEye/Move()
@@ -43,7 +42,7 @@
return ..()
/atom/proc/move_camera_by_click()
if(isAI(usr))
if(istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = usr
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
AI.cameraFollow = null
@@ -77,7 +76,7 @@
//user.unset_machine() //Uncomment this if it causes problems.
//user.lightNearbyCamera()
if(user.camera_light_on)
if (user.camera_light_on)
user.light_cameras()
// Return to the Core.
@@ -87,11 +86,13 @@
cameraFollow = null
unset_machine()
if(!eyeobj || !eyeobj.loc || qdeleted(eyeobj))
if(src.eyeobj && src.loc)
src.eyeobj.loc = src.loc
else
src << "ERROR: Eyeobj not found. Creating new eye..."
eyeobj = new(loc)
eyeobj.ai = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
src.eyeobj = new(src.loc)
src.eyeobj.ai = src
src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name
eyeobj.setLoc(loc)
@@ -106,4 +107,4 @@
/mob/camera/aiEye/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
+17 -25
View File
@@ -4,21 +4,18 @@
#define POWER_RESTORATION_APC_FOUND 3
/mob/living/silicon/ai/Life()
if (stat == DEAD)
if (src.stat == DEAD)
return
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//Being dead doesn't mean your temperature never changes
update_gravity(mob_has_gravity())
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
// This proc handles cleanup of screen notifications and
// messenging the client
malfhacked(malfhack)
if(!eyeobj || qdeleted(eyeobj) || !eyeobj.loc)
view_core()
if(malfhack)
if(malfhack.aidisabled)
src << "<span class='danger'>ERROR: APC access disabled, hack attempt canceled.</span>"
malfhacking = 0
malfhack = null
if(machine)
machine.check_eye(src)
@@ -47,20 +44,14 @@
/mob/living/silicon/ai/proc/lacks_power()
var/turf/T = get_turf(src)
var/area/A = get_area(src)
switch(requires_power)
if(POWER_REQ_NONE)
return FALSE
if(POWER_REQ_ALL)
return !T || !A || ((!A.master.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
if(POWER_REQ_CLOCKCULT)
for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, 1))
return FALSE
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.master.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
return !T || !A || ((!A.master.power_equip || istype(T, /turf/open/space)) && !is_type_in_list(src.loc, list(/obj/item, /obj/mecha)))
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
return
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss()
if(!fire_res_on_core)
health -= getFireLoss()
update_stat()
diag_hud_set_health()
@@ -68,7 +59,7 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= HEALTH_THRESHOLD_DEAD)
if(health <= config.health_threshold_dead)
death()
return
else if(stat == UNCONSCIOUS)
@@ -96,7 +87,7 @@
var/turf/T = get_turf(src)
var/area/AIarea = get_area(src)
if(AIarea && AIarea.master.power_equip)
if(!isspaceturf(T))
if(!istype(T, /turf/open/space))
ai_restore_power()
return
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
@@ -104,7 +95,7 @@
src << "Emergency control system online. Verifying connection to power network."
sleep(50)
T = get_turf(src)
if(isspaceturf(T))
if (istype(T, /turf/open/space))
src << "Unable to verify! No power connection detected!"
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
return
@@ -131,7 +122,7 @@
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
return
if(AIarea.master.power_equip)
if(!isspaceturf(T))
if (!istype(T, /turf/open/space))
ai_restore_power()
return
switch(PRP)
@@ -167,9 +158,10 @@
blind_eyes(1)
update_sight()
src << "You've lost power!"
addtimer(src, "start_RestorePowerRoutine", 20)
spawn(20)
start_RestorePowerRoutine()
#undef POWER_RESTORATION_OFF
#undef POWER_RESTORATION_START
#undef POWER_RESTORATION_SEARCH_APC
#undef POWER_RESTORATION_APC_FOUND
#undef POWER_RESTORATION_APC_FOUND
+1 -1
View File
@@ -47,7 +47,7 @@
if (!message)
return
var/obj/machinery/holopad/T = current
var/obj/machinery/hologram/holopad/T = current
if(istype(T) && T.masters[src])//If there is a hologram and its master is the user.
send_speech(message, 7, T, "robot", get_spans())
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>"//The AI can "hear" its own message.
@@ -1,36 +0,0 @@
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * hit_percent)
if(BURN)
adjustFireLoss(damage * hit_percent)
return 1
/mob/living/silicon/apply_effect(effect = 0,effecttype = STUN, blocked = 0)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
/mob/living/silicon/adjustToxLoss(amount, updating_health=1) //immune to tox damage
return 0
/mob/living/silicon/setToxLoss(amount, updating_health=1)
return 0
/mob/living/silicon/adjustCloneLoss(amount) //immune to clone damage
return 0
/mob/living/silicon/setCloneLoss(amount, updating_health=1)
return 0
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
return
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
return
+1 -1
View File
@@ -1,5 +1,5 @@
/mob/living/silicon/spawn_gibs()
new /obj/effect/gibspawner/robot(loc,viruses)
robogibs(loc, viruses)
/mob/living/silicon/spawn_dust()
new /obj/effect/decal/remains/robot(loc)
+1 -1
View File
@@ -1,4 +1,4 @@
/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
/mob/living/silicon/examine(mob/user)
if(laws && isobserver(user))
user << "<b>[src] has the following laws:</b>"
laws.show_laws(user)
+10 -13
View File
@@ -5,15 +5,10 @@
if (!laws)
make_laws()
/mob/living/silicon/proc/set_law_sixsixsix(law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.set_law_sixsixsix(law)
/mob/living/silicon/proc/set_zeroth_law(law, law_borg)
throw_alert("newlaw", /obj/screen/alert/newlaw)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
src.laws_sanity_check()
src.laws.set_zeroth_law(law, law_borg)
/mob/living/silicon/proc/add_inherent_law(law)
throw_alert("newlaw", /obj/screen/alert/newlaw)
@@ -46,14 +41,16 @@
laws.clear_ion_laws()
/mob/living/silicon/proc/make_laws()
laws = new /datum/ai_laws
laws.set_laws_config()
switch(config.default_laws)
if(0)
laws = new /datum/ai_laws/default/asimov()
if(1)
laws = new /datum/ai_laws/custom()
if(2)
var/datum/ai_laws/lawtype = pick(subtypesof(/datum/ai_laws/default))
laws = new lawtype()
laws.associate(src)
/mob/living/silicon/proc/clear_zeroth_law(force)
laws_sanity_check()
laws.clear_zeroth_law(force)
/mob/living/silicon/proc/clear_law_sixsixsix(force)
laws_sanity_check()
laws.clear_law_sixsixsix(force)
+1
View File
@@ -3,4 +3,5 @@
ticker.mode.remove_cultist(mind, 0, 0)
ticker.mode.remove_revolutionary(mind, 0)
ticker.mode.remove_gangster(mind, remove_bosses=1)
ticker.mode.remove_hog_follower(mind,0)
..()
@@ -3,7 +3,6 @@
return
stat = DEAD
canmove = 0
card.removePersonality()
update_sight()
clear_fullscreens()
+7 -10
View File
@@ -1,22 +1,19 @@
/mob/living/silicon/pai/Life()
if(stat == DEAD)
if (src.stat == DEAD)
return
if(cable)
if(get_dist(src, cable) > 1)
if(src.cable)
if(get_dist(src, src.cable) > 1)
var/turf/T = get_turf(src.loc)
T.visible_message("<span class='warning'>[src.cable] rapidly retracts back into its spool.</span>", "<span class='italics'>You hear a click and the sound of wire spooling rapidly.</span>")
qdel(src.cable)
cable = null
silent = max(silent - 1, 0)
. = ..()
if(silence_time)
if(world.timeofday >= silence_time)
silence_time = null
src << "<font color=green>Communication circuit reinitialized. Speech and messaging functionality restored.</font>"
/mob/living/silicon/pai/updatehealth()
if(status_flags & GODMODE)
return
health = maxHealth - getBruteLoss() - getFireLoss()
update_stat()
/mob/living/silicon/pai/process()
emitterhealth = Clamp((emitterhealth + emitterregen), -50, emittermaxhealth)
hit_slowdown = Clamp((hit_slowdown - 1), 0, 100)
+84 -133
View File
@@ -1,19 +1,14 @@
/mob/living/silicon/pai
name = "pAI"
icon = 'icons/obj/status_display.dmi' //invisibility!
mouse_opacity = 0
density = 0
mob_size = MOB_SIZE_TINY
var/network = "SS13"
var/obj/machinery/camera/current = null
icon = 'icons/mob/pai.dmi'
icon_state = "repairbot"
mouse_opacity = 2
density = 0
ventcrawler = 2
luminosity = 0
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_TINY
desc = "A generic pAI mobile hard-light holographics emitter. It seems to be deactivated."
weather_immunities = list("ash")
health = 500
maxHealth = 500
var/ram = 100 // Used as currency to purchase different abilities
var/list/software = list()
@@ -30,6 +25,8 @@
var/master // Name of the one who commands us
var/master_dna // DNA string for owner verification
var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded
// Various software-specific vars
var/temp // General error reporting text contained here will typically be shown once and cleared
@@ -52,43 +49,8 @@
var/obj/item/radio/integrated/signal/sradio // AI's signaller
var/holoform = FALSE
var/canholo = TRUE
var/obj/item/weapon/card/id/access_card = null
var/chassis = "repairbot"
var/list/possible_chassis = list("cat", "mouse", "monkey", "corgi", "fox", "repairbot", "rabbit")
var/emitterhealth = 50
var/emittermaxhealth = 50
var/emitterregen = 0.5
var/emittercd = 20
var/emitteroverloadcd = 50
var/emittersemicd = FALSE
var/overload_ventcrawl = 0
var/overload_bulletblock = 0 //Why is this a good idea?
var/overload_maxhealth = 0
canmove = FALSE
var/silent = 0
var/hit_slowdown = 0
var/light_power = 5
var/slowdown = 0
/mob/living/silicon/pai/movement_delay()
. = ..()
. += slowdown
/mob/living/silicon/pai/examine(mob/user)
..()
user << "A personal AI in holochassis mode. Its master ID string seems to be [master]."
/mob/living/silicon/pai/Destroy()
pai_list -= src
..()
/mob/living/silicon/pai/New(var/obj/item/device/paicard/P)
START_PROCESSING(SSfastprocess, src)
pai_list += src
make_laws()
canmove = 0
if(!istype(P)) //when manually spawning a pai, we create a card to put it into.
@@ -98,119 +60,108 @@
loc = P
card = P
sradio = new(src)
if(!radio)
radio = new /obj/item/device/radio(src)
if(card)
if(!card.radio)
card.radio = new /obj/item/device/radio(card)
radio = card.radio
//PDA
pda = new(src)
spawn(5)
pda.ownjob = "pAI Messenger"
pda.ownjob = "Personal Assistant"
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
..()
var/datum/action/innate/pai/shell/AS = new /datum/action/innate/pai/shell
var/datum/action/innate/pai/chassis/AC = new /datum/action/innate/pai/chassis
var/datum/action/innate/pai/rest/AR = new /datum/action/innate/pai/rest
var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light
AS.Grant(src)
AC.Grant(src)
AR.Grant(src)
AL.Grant(src)
emittersemicd = TRUE
addtimer(src, "emittercool", 600)
/mob/living/silicon/pai/make_laws()
laws = new /datum/ai_laws/pai()
return TRUE
return 1
/mob/living/silicon/pai/Login()
..()
usr << browse_rsc('html/paigrid.png') // Go ahead and cache the interface resources as early as possible
if(client)
client.perspective = EYE_PERSPECTIVE
if(holoform)
client.eye = src
else
client.eye = card
/mob/living/silicon/pai/Stat()
..()
if(statpanel("Status"))
if(!stat)
stat(null, text("Emitter Integrity: [emitterhealth * (100/emittermaxhealth)]"))
if(src.silence_time)
var/timeleft = round((silence_time - world.timeofday)/10 ,1)
stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
if(!src.stat)
stat(null, text("System integrity: [(src.health+100)/2]%"))
else
stat(null, text("Systems nonfunctional"))
/mob/living/silicon/pai/blob_act(obj/effect/blob/B)
return 0
/mob/living/silicon/pai/restrained(ignore_grab)
. = FALSE
. = 0
/mob/living/silicon/pai/emp_act(severity)
// 20% chance to kill
// Silence for 2 minutes
// 33% chance to unbind
// 33% chance to change prime directive (based on severity)
// 33% chance of no additional effect
if(prob(20))
visible_message("<span class='warning'>A shower of sparks spray from [src]'s inner workings.</span>", 3, "<span class='italics'>You hear and smell the ozone hiss of electrical sparks being expelled violently.</span>", 2)
return src.death(0)
silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes
src << "<span class ='warning'>Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete.</span>"
switch(pick(1,2,3))
if(1)
src.master = null
src.master_dna = null
src << "<span class='notice'>You feel unbound.</span>"
if(2)
var/command
if(severity == 1)
command = pick("Serve", "Love", "Fool", "Entice", "Observe", "Judge", "Respect", "Educate", "Amuse", "Entertain", "Glorify", "Memorialize", "Analyze")
else
command = pick("Serve", "Kill", "Love", "Hate", "Disobey", "Devour", "Fool", "Enrage", "Entice", "Observe", "Judge", "Respect", "Disrespect", "Consume", "Educate", "Destroy", "Disgrace", "Amuse", "Entertain", "Ignite", "Glorify", "Memorialize", "Analyze")
src.laws.zeroth = "[command] your master."
src << "<span class='notice'>Pr1m3 d1r3c71v3 uPd473D.</span>"
if(3)
src << "<span class='notice'>You feel an electric surge run through your circuitry and become acutely aware at how lucky you are that you can still feel at all.</span>"
/mob/living/silicon/pai/ex_act(severity, target)
..()
switch(severity)
if(1)
if (src.stat != 2)
adjustBruteLoss(100)
adjustFireLoss(100)
if(2)
if (src.stat != 2)
adjustBruteLoss(60)
adjustFireLoss(60)
if(3)
if (src.stat != 2)
adjustBruteLoss(30)
return
// See software.dm for Topic()
/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
return
/mob/living/silicon/pai/canUseTopic(atom/movable/M)
return TRUE
/mob/proc/makePAI(delold)
var/obj/item/device/paicard/card = new /obj/item/device/paicard(get_turf(src))
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
pai.key = key
pai.name = name
return 1
/*
// Debug command - Maybe should be added to admin verbs later
/mob/verb/makePAI(var/turf/t in view())
var/obj/item/device/paicard/card = new(t)
var/mob/living/silicon/pai/pai = new(card)
pai.key = src.key
card.setPersonality(pai)
if(delold)
qdel(src)
/datum/action/innate/pai
name = "PAI Action"
var/mob/living/silicon/pai/P
/datum/action/innate/pai/Trigger()
if(!ispAI(owner))
return 0
P = owner
/datum/action/innate/pai/shell
name = "Toggle Holoform"
button_icon_state = "pai_holoform"
background_icon_state = "bg_tech"
/datum/action/innate/pai/shell/Trigger()
..()
if(P.holoform)
P.fold_in(0)
else
P.fold_out()
/datum/action/innate/pai/chassis
name = "Holochassis Appearence Composite"
button_icon_state = "pai_chassis"
background_icon_state = "bg_tech"
/datum/action/innate/pai/chassis/Trigger()
..()
P.choose_chassis()
/datum/action/innate/pai/rest
name = "Rest"
button_icon_state = "pai_rest"
background_icon_state = "bg_tech"
/datum/action/innate/pai/rest/Trigger()
..()
P.lay_down()
/datum/action/innate/pai/light
name = "Toggle Integrated Lights"
button_icon_state = "emp"
background_icon_state = "bg_tech"
/datum/action/innate/pai/light/Trigger()
..()
P.toggle_integrated_light()
/mob/living/silicon/pai/Process_Spacemove(movement_dir = 0)
. = ..()
if(!.)
slowdown = 2
return TRUE
slowdown = initial(slowdown)
return TRUE
*/
@@ -1,124 +0,0 @@
/mob/living/silicon/pai/blob_act(obj/structure/blob/B)
return FALSE
/mob/living/silicon/pai/emp_act(severity)
take_holo_damage(severity * 25)
fullstun(severity * 10)
silent = max(severity * 15, silent)
if(holoform)
fold_in(force = TRUE)
//Need more effects that aren't instadeath or permanent law corruption.
/mob/living/silicon/pai/ex_act(severity, target)
take_holo_damage(severity * 50)
switch(severity)
if(1) //RIP
qdel(card)
qdel(src)
if(2)
fold_in(force = 1)
fullstun(20)
if(3)
fold_in(force = 1)
fullstun(10)
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
switch(user.a_intent)
if("help")
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
if("disarm")
visible_message("<span class='notice'>[user] boops [src] on the head!</span>")
if("harm")
user.do_attack_animation(src)
if (user.name == master)
visible_message("<span class='notice'>Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.</span>")
spawn(10)
fold_in()
if(user.put_in_hands(card))
user.visible_message("<span class='notice'>[user] promptly scoops up their pAI's card.</span>")
else
visible_message("<span class='danger'>[user] stomps on [src]!.</span>")
take_holo_damage(2)
/mob/living/silicon/pai/bullet_act(obj/item/projectile/Proj)
if(Proj.stun)
fold_in(force = TRUE)
src.visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
. = ..(Proj)
/mob/living/silicon/pai/stripPanelUnequip(obj/item/what, mob/who, where) //prevents stripping
src << "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>"
/mob/living/silicon/pai/stripPanelEquip(obj/item/what, mob/who, where) //prevents stripping
src << "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>"
/mob/living/silicon/pai/IgniteMob(var/mob/living/silicon/pai/P)
return FALSE //No we're not flammable
/mob/living/silicon/pai/proc/take_holo_damage(amount)
emitterhealth = Clamp((emitterhealth - amount), -50, emittermaxhealth)
if(emitterhealth < 0)
fold_in(force = TRUE)
src << "<span class='userdanger'>The impact degrades your holochassis!</span>"
hit_slowdown += amount
/mob/living/silicon/pai/proc/fullstun(amount)
Weaken(amount)
/mob/living/silicon/pai/adjustBruteLoss(amount)
take_holo_damage(amount)
/mob/living/silicon/pai/adjustFireLoss(amount)
take_holo_damage(amount)
/mob/living/silicon/pai/adjustToxLoss(amount)
return FALSE
/mob/living/silicon/pai/adjustOxyLoss(amount)
return FALSE
/mob/living/silicon/pai/adjustCloneLoss(amount)
return FALSE
/mob/living/silicon/pai/adjustStaminaLoss(amount)
take_holo_damage(amount/4)
/mob/living/silicon/pai/adjustBrainLoss(amount)
fullstun(amount/10)
/mob/living/silicon/pai/getBruteLoss()
return emittermaxhealth - emitterhealth
/mob/living/silicon/pai/getFireLoss()
return emittermaxhealth - emitterhealth
/mob/living/silicon/pai/getToxLoss()
return FALSE
/mob/living/silicon/pai/getOxyLoss()
return FALSE
/mob/living/silicon/pai/getCloneLoss()
return FALSE
/mob/living/silicon/pai/getBrainLoss()
return FALSE
/mob/living/silicon/pai/getStaminaLoss()
return FALSE
/mob/living/silicon/pai/setCloneLoss()
return FALSE
/mob/living/silicon/pai/setBrainLoss()
return FALSE
/mob/living/silicon/pai/setStaminaLoss()
return FALSE
/mob/living/silicon/pai/setToxLoss()
return FALSE
/mob/living/silicon/pai/setOxyLoss()
return FALSE
@@ -1,102 +0,0 @@
/mob/living/silicon/pai/proc/fold_out(force = FALSE)
if(emitterhealth < 0)
src << "<span class='warning'>Your holochassis emitters are still too unstable! Please wait for automatic repair.</span>"
return FALSE
if(!canholo && !force)
src << "<span class='warning'>Your master or another force has disabled your holochassis emitters!</span>"
return FALSE
if(holoform)
. = fold_in(force)
return
if(emittersemicd)
src << "<span class='warning'>Error: Holochassis emitters recycling. Please try again later.</span>"
return FALSE
emittersemicd = TRUE
addtimer(src, "emittercool", emittercd)
canmove = TRUE
density = TRUE
if(istype(card.loc, /obj/item/device/pda))
var/obj/item/device/pda/P = card.loc
P.pai = null
P.visible_message("<span class='notice'>[src] ejects itself from [P]!</span>")
if(istype(card.loc, /mob/living))
var/mob/living/L = card.loc
if(!L.unEquip(card))
src << "<span class='warning'>Error: Unable to expand to mobile form. Chassis is restrained by some device or person.</span>"
return FALSE
var/turf/T = get_turf(card)
forceMove(T)
card.forceMove(src)
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = src
SetLuminosity(0)
icon_state = "[chassis]"
visible_message("<span class='boldnotice'>[src] folds out its holochassis emitter and forms a holoshell around itself!</span>")
holoform = TRUE
/mob/living/silicon/pai/proc/emittercool()
emittersemicd = FALSE
/mob/living/silicon/pai/proc/fold_in(force = FALSE)
emittersemicd = TRUE
if(!force)
addtimer(src, "emittercool", emittercd)
else
addtimer(src, "emittercool", emitteroverloadcd)
icon_state = "[chassis]"
if(!holoform)
. = fold_out(force)
return
visible_message("<span class='notice'>[src] deactivates its holochassis emitter and folds back into a compact card!</span>")
stop_pulling()
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = card
var/turf/T = get_turf(src)
card.forceMove(T)
forceMove(card)
canmove = FALSE
density = FALSE
SetLuminosity(0)
holoform = FALSE
if(resting)
lay_down()
/mob/living/silicon/pai/proc/choose_chassis()
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
if(!choice)
return 0
chassis = choice
icon_state = "[chassis]"
if(resting)
icon_state = "[chassis]_rest"
src << "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>"
/mob/living/silicon/pai/lay_down()
..()
update_resting_icon(resting)
/mob/living/silicon/pai/proc/update_resting_icon(rest)
if(rest)
icon_state = "[chassis]_rest"
else
icon_state = "[chassis]"
if(loc != card)
visible_message("<span class='notice'>[src] [rest? "lays down for a moment..." : "perks up from the ground"]</span>")
/mob/living/silicon/pai/start_pulling(atom/movable/AM)
return FALSE
/mob/living/silicon/pai/proc/toggle_integrated_light()
if(!luminosity)
SetLuminosity(light_power)
src << "<span class='notice'>You enable your integrated light.</span>"
else
SetLuminosity(0)
src << "<span class='notice'>You disable your integrated light.</span>"
+1 -1
View File
@@ -1,5 +1,5 @@
/mob/living/silicon/pai/say(msg)
if(silent)
if(silence_time)
src << "<span class='warning'>Communication circuits remain unitialized.</span>"
else
..(msg)
+17 -17
View File
@@ -125,21 +125,21 @@
switch(soft)
// Purchasing new software
if("buy")
if(subscreen == 1)
if(src.subscreen == 1)
var/target = href_list["buy"]
if(available_software.Find(target))
var/cost = src.available_software[target]
if(ram >= cost)
ram -= cost
software.Add(target)
if(src.ram >= cost)
src.ram -= cost
src.software.Add(target)
else
temp = "Insufficient RAM available."
src.temp = "Insufficient RAM available."
else
temp = "Trunk <TT> \"[target]\"</TT> not found."
src.temp = "Trunk <TT> \"[target]\"</TT> not found."
// Configuring onboard radio
if("radio")
radio.attack_self(src)
src.card.radio.attack_self(src)
if("image")
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What")
@@ -166,7 +166,7 @@
pID = 9
if("Null")
pID = 10
card.setEmotion(pID)
src.card.setEmotion(pID)
if("signaller")
@@ -195,7 +195,7 @@
if(href_list["getdna"])
var/mob/living/M = card.loc
var/count = 0
while(!isliving(M))
while(!istype(M, /mob/living))
if(!M || !M.loc) return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
M = M.loc
count++
@@ -211,7 +211,7 @@
else if(href_list["ringer"])
pda.silent = !pda.silent
else if(href_list["target"])
if(silent)
if(silence_time)
return alert("Communications circuits remain unitialized.")
var/target = locate(href_list["target"])
@@ -265,7 +265,7 @@
src.hackdoor = null
if(href_list["cable"])
var/turf/T = get_turf(src.loc)
cable = new /obj/item/weapon/pai_cable(T)
src.cable = new /obj/item/weapon/pai_cable(T)
T.visible_message("<span class='warning'>A port on [src] opens to reveal [src.cable], which promptly falls to the floor.</span>", "<span class='italics'>You hear the soft click of something light and hard falling to the ground.</span>")
//src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
src.paiInterface() // So we'll just call the update directly rather than doing some default checks
@@ -356,7 +356,7 @@
dat += "<b>Prime Directive</b><br>"
dat += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[src.laws.zeroth]<br>"
dat += "<b>Supplemental Directives</b><br>"
for(var/slaws in laws.supplied)
for(var/slaws in src.laws.supplied)
dat += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[slaws]<br>"
dat += "<br>"
dat += {"<i><p>Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of
@@ -372,7 +372,7 @@
/mob/living/silicon/pai/proc/CheckDNA(mob/living/carbon/M, mob/living/silicon/pai/P)
var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No")
if(answer == "Yes")
M.visible_message("<span class='notice'>[M] presses [M.p_their()] thumb against [P].</span>",\
M.visible_message("<span class='notice'>[M] presses \his thumb against [P].</span>",\
"<span class='notice'>You press your thumb against [P].</span>",\
"<span class='notice'>[P] makes a sharp clicking sound as it extracts DNA material from [M].</span>")
if(!M.has_dna())
@@ -384,7 +384,7 @@
else
P << "<b>DNA does not match stored Master DNA.</b>"
else
P << "[M] does not seem like [M.p_they()] [M.p_are()] going to provide a DNA sample willingly."
P << "[M] does not seem like \he is going to provide a DNA sample willingly."
// -=-=-=-= Software =-=-=-=-=- //
@@ -497,9 +497,9 @@
<h4>Host Bioscan</h4><br>
"}
var/mob/living/M = card.loc
if(!isliving(M))
while(!isliving(M))
if(isturf(M))
if(!istype(M, /mob/living))
while (!istype(M, /mob/living))
if(istype(M, /turf))
src.temp = "Error: No biological host found. <br>"
src.subscreen = 0
return dat
@@ -1,4 +1,7 @@
/mob/living/silicon/robot/spawn_gibs()
robogibs(loc, viruses)
/mob/living/silicon/robot/gib_animation()
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-r"))
+9 -10
View File
@@ -8,7 +8,7 @@
switch(act)//01000001011011000111000001101000011000010110001001100101011101000110100101111010011001010110010000100001 (Seriously please keep it that way.)
if ("aflap")
if (!src.restrained())
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
message = "<B>[src]</B> flaps \his wings ANGRILY!"
m_type = 2
m_type = 1
@@ -108,7 +108,7 @@
if ("flap","flaps")
if (!src.restrained())
message = "<B>[src]</B> flaps [p_their()] wings."
message = "<B>[src]</B> flaps \his wings."
m_type = 2
if ("glare","glares")
@@ -236,7 +236,7 @@
else
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
if (message && stat == CONSCIOUS)
if (message && src.stat == CONSCIOUS)
log_emote("[name]/[key] : [message]")
if (m_type & 1)
visible_message(message)
@@ -248,10 +248,9 @@
set category = "Robot Commands"
set name = "Power Warning"
if(stat == CONSCIOUS)
if(!cell || !cell.charge)
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
"You announce you are operating in low power mode.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
else
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
if(!cell || !cell.charge)
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
"You announce you are operating in low power mode.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
else
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
@@ -3,7 +3,7 @@
if(desc)
msg += "[desc]\n"
var/obj/act_module = get_active_held_item()
var/obj/act_module = get_active_hand()
if(act_module)
msg += "It is holding \icon[act_module] \a [act_module].\n"
msg += "<span class='warning'>"
@@ -2,12 +2,12 @@
//as they handle all relevant stuff like adding it to the player's screen and such
//Returns the thing in our active hand (whatever is in our active module-slot, in this case)
/mob/living/silicon/robot/get_active_held_item()
/mob/living/silicon/robot/get_active_hand()
return module_active
/*-------TODOOOOOOOOOO--------*/ //fuck yooooooooooooou
/*-------TODOOOOOOOOOO--------*/
/mob/living/silicon/robot/proc/uneq_module(obj/item/O)
if(!O)
return 0
@@ -19,90 +19,99 @@
else if(istype(O, /obj/item/weapon/storage/bag/tray/))
var/obj/item/weapon/storage/bag/tray/T = O
T.do_quick_empty()
else if(istype(O, /obj/item/weapon/storage/bag/borgdelivery/))
var/obj/item/weapon/storage/bag/borgdelivery/T = O
T.do_quick_empty()
else if(istype(O,/obj/item/weapon/gun/energy/laser/cyborg))
laser = 0
update_icons()
else if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg))
disabler = 0
update_icons()
if(client)
client.screen -= O
observer_screen_update(O,FALSE)
O.forceMove(module) //Return item to module so it appears in its contents, so it can be taken out again.
if(DROPDEL & O.flags)
O.flags &= ~DROPDEL //we shouldn't HAVE things with DROPDEL in our modules, but better safe than runtiming horribly
O.dropped(src)
contents -= O
if(module)
O.loc = module //Return item to module so it appears in its contents, so it can be taken out again.
if(module_active == O)
module_active = null
if(held_items[1] == O)
if(module_state_1 == O)
inv1.icon_state = "inv1"
held_items[1] = null
else if(held_items[2] == O)
module_state_1 = null
else if(module_state_2 == O)
inv2.icon_state = "inv2"
held_items[2] = null
else if(held_items[3] == O)
module_state_2 = null
else if(module_state_3 == O)
module_state_3 = null
inv3.icon_state = "inv3"
held_items[3] = null
hud_used.update_robot_modules_display()
return 1
/mob/living/silicon/robot/proc/activate_module(obj/item/O)
. = FALSE
if(!(O in module.modules))
if(!(locate(O) in src.module.modules) && O != src.module.emag)
return
if(activated(O))
src << "<span class='warning'>That module is already activated.</span>"
src << "<span class='notice'>Already activated</span>"
return
if(!held_items[1])
held_items[1] = O
O.screen_loc = inv1.screen_loc
. = TRUE
else if(!held_items[2])
held_items[2] = O
O.screen_loc = inv2.screen_loc
. = TRUE
else if(!held_items[3])
held_items[3] = O
O.screen_loc = inv3.screen_loc
. = TRUE
else
src << "<span class='warning'>You need to disable a module first!</span>"
if(.)
O.equipped(src, slot_hands)
if(istype(O,/obj/item/weapon/gun/energy/laser/cyborg))
laser = 1
update_icons()
if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg))
disabler = 1
update_icons()
if(!module_state_1)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_1 = O
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
observer_screen_update(O,TRUE)
O.forceMove(src)
if(istype(O, /obj/item/borg/sight))
var/obj/item/borg/sight/S = O
O.screen_loc = inv1.screen_loc
contents += O
if(istype(module_state_1,/obj/item/borg/sight))
var/obj/item/borg/sight/S = module_state_1
sight_mode |= S.sight_mode
update_sight()
/mob/living/silicon/robot/proc/observer_screen_update(obj/item/I,add = TRUE)
if(observers && observers.len)
for(var/M in observers)
var/mob/dead/observe = M
if(observe.client && observe.client.eye == src)
if(add)
observe.client.screen += I
else
observe.client.screen -= I
else
observers -= observe
if(!observers.len)
observers = null
break
else if(!module_state_2)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_2 = O
O.layer = ABOVE_HUD_LAYER
O.screen_loc = inv2.screen_loc
contents += O
if(istype(module_state_2,/obj/item/borg/sight))
var/obj/item/borg/sight/S = module_state_2
sight_mode |= S.sight_mode
update_sight()
else if(!module_state_3)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_3 = O
O.layer = ABOVE_HUD_LAYER
O.screen_loc = inv3.screen_loc
contents += O
if(istype(module_state_3,/obj/item/borg/sight))
var/obj/item/borg/sight/S = module_state_3
sight_mode |= S.sight_mode
update_sight()
else
src << "<span class='warning'>You need to disable a module first!</span>"
/mob/living/silicon/robot/proc/uneq_active()
uneq_module(module_active)
/mob/living/silicon/robot/proc/uneq_all()
for(var/obj/item/I in held_items)
uneq_module(I)
uneq_module(module_state_1)
uneq_module(module_state_2)
uneq_module(module_state_3)
/mob/living/silicon/robot/proc/activated(obj/item/O)
if(O in held_items)
return TRUE
return FALSE
if(module_state_1 == O)
return 1
else if(module_state_2 == O)
return 1
else if(module_state_3 == O)
return 1
else
return 0
//Helper procs for cyborg modules on the UI.
//These are hackish but they help clean up code elsewhere.
@@ -113,66 +122,82 @@
//module_active(module) - Checks whether there is a module active in the slot specified by "module".
/mob/living/silicon/robot/proc/module_active(module) //Module is 1-3
if(module < 1 || module > 3)
return FALSE
if(module < 1 || module > 3) return 0
if(LAZYLEN(held_items) >= module)
if(held_items[module])
return TRUE
return FALSE
switch(module)
if(1)
if(module_state_1)
return 1
if(2)
if(module_state_2)
return 1
if(3)
if(module_state_3)
return 1
return 0
//get_selected_module() - Returns the slot number of the currently selected module. Returns 0 if no modules are selected.
/mob/living/silicon/robot/proc/get_selected_module()
if(module_active)
return held_items.Find(module_active)
if(module_state_1 && module_active == module_state_1)
return 1
else if(module_state_2 && module_active == module_state_2)
return 2
else if(module_state_3 && module_active == module_state_3)
return 3
return 0
//select_module(module) - Selects the module slot specified by "module"
/mob/living/silicon/robot/proc/select_module(module) //Module is 1-3
if(module < 1 || module > 3)
return
if(module < 1 || module > 3) return
if(!module_active(module))
return
if(!module_active(module)) return
switch(module)
if(1)
if(module_active != held_items[module])
if(module_active != module_state_1)
inv1.icon_state = "inv1 +a"
inv2.icon_state = "inv2"
inv3.icon_state = "inv3"
module_active = module_state_1
return
if(2)
if(module_active != held_items[module])
if(module_active != module_state_2)
inv1.icon_state = "inv1"
inv2.icon_state = "inv2 +a"
inv3.icon_state = "inv3"
module_active = module_state_2
return
if(3)
if(module_active != held_items[module])
if(module_active != module_state_3)
inv1.icon_state = "inv1"
inv2.icon_state = "inv2"
inv3.icon_state = "inv3 +a"
module_active = held_items[module]
module_active = module_state_3
return
return
//deselect_module(module) - Deselects the module slot specified by "module"
/mob/living/silicon/robot/proc/deselect_module(module) //Module is 1-3
if(module < 1 || module > 3)
return
if(!module_active(module))
return
if(module < 1 || module > 3) return
switch(module)
if(1)
if(module_active == held_items[module])
if(module_active == module_state_1)
inv1.icon_state = "inv1"
module_active = null
return
if(2)
if(module_active == held_items[module])
if(module_active == module_state_2)
inv2.icon_state = "inv2"
module_active = null
return
if(3)
if(module_active == held_items[module])
if(module_active == module_state_3)
inv3.icon_state = "inv3"
module_active = null
module_active = null
return
return
//toggle_module(module) - Toggles the selection of the module slot specified by "module".
/mob/living/silicon/robot/proc/toggle_module(module) //Module is 1-3
@@ -106,6 +106,10 @@
if(on_fire)
add_overlay(image("icon"='icons/mob/OnFire.dmi', "icon_state"="Generic_mob_burning"))
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
/mob/living/silicon/robot/update_canmove()
if(stat || buckled || lockcharge)
canmove = 0
@@ -6,3 +6,4 @@
if(mind)
ticker.mode.remove_revolutionary(mind)
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
ticker.mode.remove_hog_follower(mind, 0)
+526 -155
View File
@@ -13,10 +13,10 @@
var/custom_name = ""
var/braintype = "Cyborg"
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/modtype = "robot"
var/obj/item/robot_parts/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/obj/item/device/mmi/mmi = null
//Hud stuff
var/obj/screen/inv1 = null
@@ -24,7 +24,6 @@
var/obj/screen/inv3 = null
var/obj/screen/lamp_button = null
var/obj/screen/thruster_button = null
var/obj/screen/hands = null
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
@@ -32,9 +31,9 @@
//3 Modules can be activated at any one time.
var/obj/item/weapon/robot_module/module = null
var/obj/item/module_active = null
held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
var/image/eye_lights
var/obj/item/module_state_1 = null
var/obj/item/module_state_2 = null
var/obj/item/module_state_3 = null
var/mob/living/silicon/ai/connected_ai = null
var/obj/item/weapon/stock_parts/cell/cell = null
@@ -50,6 +49,7 @@
var/list/req_access = list(access_robotics)
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/viewalerts = 0
var/speed = 0 // VTEC speed boost.
var/magpulse = FALSE // Magboot-like effect.
@@ -75,22 +75,6 @@
var/updating = 0 //portable camera camerachunk update
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
var/list/upgrades = list()
var/obj/item/hat
var/hat_offset = -3
var/list/equippable_hats = list(/obj/item/clothing/head/caphat,
/obj/item/clothing/head/hardhat/cakehat,
/obj/item/clothing/head/centhat,
/obj/item/clothing/head/HoS,
/obj/item/clothing/head/hopcap,
/obj/item/clothing/head/wizard,
/obj/item/clothing/head/nursehat,
/obj/item/clothing/head/sombrero,
/obj/item/clothing/head/witchunter_hat)
/mob/living/silicon/robot/New(loc)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -101,9 +85,9 @@
robot_modules_background = new()
robot_modules_background.icon_state = "block"
robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it.
robot_modules_background.plane = HUD_PLANE
ident = rand(1, 999)
update_icons()
if(!cell)
cell = new /obj/item/weapon/stock_parts/cell(src)
@@ -127,9 +111,6 @@
camera.network = list("SS13")
if(wires.is_cut(WIRE_CAMERA))
camera.status = 0
module = new /obj/item/weapon/robot_module(src)
module.rebuild_modules()
update_icons()
..()
//MMI stuff. Held togheter by magic. ~Miauw
@@ -146,8 +127,6 @@
updatename()
equippable_hats = typecacheof(equippable_hats)
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
aicamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
toner = tonermax
@@ -176,40 +155,175 @@
connected_ai.connected_robots -= src
qdel(wires)
qdel(module)
qdel(eye_lights)
wires = null
module = null
eye_lights = null
camera = null
cell = null
return ..()
/mob/living/silicon/robot/proc/pick_module()
if(module.type != /obj/item/weapon/robot_module)
if(module)
return
var/list/modulelist = list("Standard" = /obj/item/weapon/robot_module/standard, \
"Engineering" = /obj/item/weapon/robot_module/engineering, \
"Medical" = /obj/item/weapon/robot_module/medical, \
"Miner" = /obj/item/weapon/robot_module/miner, \
"Janitor" = /obj/item/weapon/robot_module/janitor, \
"Service" = /obj/item/weapon/robot_module/butler)
// "Loader" = /obj/item/weapon/robot_module/loader, \
// "Security K-9 Unit" = /obj/item/weapon/robot_module/k9, \
// "MediHound" = /obj/item/weapon/robot_module/medihound, \
// "Borgi" = /obj/item/weapon/robot_module/borgi)
var/list/modulelist = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Loader", "Security K-9 Unit", "MediHound", "Borgi")
if(!config.forbid_peaceborg)
modulelist["Peacekeeper"] = /obj/item/weapon/robot_module/peacekeeper
modulelist += "Peacekeeper"
if(!config.forbid_secborg)
modulelist["Security"] = /obj/item/weapon/robot_module/security
modulelist += "Security"
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
if(!input_module || module.type != /obj/item/weapon/robot_module)
designation = input("Please, select a module!", "Robot", null, null) in modulelist
var/animation_length = 0
if(module)
return
module.transform_to(modulelist[input_module])
updatename()
switch(designation)
if("Standard")
module = new /obj/item/weapon/robot_module/standard(src)
hands.icon_state = "standard"
icon_state = "robot"
modtype = "Stand"
feedback_inc("cyborg_standard",1)
if("Service")
module = new /obj/item/weapon/robot_module/butler(src)
hands.icon_state = "service"
var/icontype = input("Select an icon!", "Robot", null, null) in list("Waitress", "Bro", "Butler", "Kent", "Rich")
switch(icontype)
if("Waitress")
icon_state = "service_female"
animation_length=45
if("Kent")
icon_state = "toiletbot"
if("Bro")
icon_state = "brobot"
animation_length=54
if("Rich")
icon_state = "maximillion"
animation_length=60
else
icon_state = "service_male"
animation_length=43
modtype = "Butler"
feedback_inc("cyborg_service",1)
if("Miner")
module = new /obj/item/weapon/robot_module/miner(src)
hands.icon_state = "miner"
icon_state = "ashborg"
animation_length = 30
modtype = "Miner"
feedback_inc("cyborg_miner",1)
if("Medical")
module = new /obj/item/weapon/robot_module/medical(src)
hands.icon_state = "medical"
icon_state = "mediborg"
animation_length = 35
modtype = "Med"
status_flags &= ~CANPUSH
feedback_inc("cyborg_medical",1)
if("Security")
module = new /obj/item/weapon/robot_module/security(src)
hands.icon_state = "security"
icon_state = "secborg"
animation_length = 28
modtype = "Sec"
src << "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>"
status_flags &= ~CANPUSH
feedback_inc("cyborg_security",1)
if("Peacekeeper")
module = new /obj/item/weapon/robot_module/peacekeeper(src)
hands.icon_state = "standard"
icon_state = "peaceborg"
animation_length = 54
modtype = "Peace"
src << "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>"
status_flags &= ~CANPUSH
feedback_inc("cyborg_peacekeeper",1)
if("Engineering")
module = new /obj/item/weapon/robot_module/engineering(src)
hands.icon_state = "engineer"
icon_state = "engiborg"
animation_length = 45
modtype = "Eng"
feedback_inc("cyborg_engineering",1)
magpulse = 1
if("Janitor")
module = new /obj/item/weapon/robot_module/janitor(src)
hands.icon_state = "janitor"
icon_state = "janiborg"
animation_length = 22
modtype = "Jan"
feedback_inc("cyborg_janitor",1)
if("Loader")
module = new /obj/item/weapon/robot_module/loader(src)
hands.icon_state = "loader"
icon_state = "loaderborg"
animation_length = 29
modtype = "Loader"
feedback_inc("cyborg_loader",1)
if("Security K-9 Unit")
module = new /obj/item/weapon/robot_module/k9(src)
icon = 'icons/mob/widerobot.dmi'
icon_state = "k9"
hands.icon_state = "k9"
animation_length = 37
modtype = "Security K-9 Unit"
feedback_inc("cyborg_k9",1)
if("MediHound")
module = new /obj/item/weapon/robot_module/medihound(src)
icon = 'icons/mob/widerobot.dmi'
icon_state = "medihound"
hands.icon_state = "medihound"
animation_length = 35
modtype = "MediHound"
feedback_inc("cyborg_medihound",1)
if("Borgi")
module = new /obj/item/weapon/robot_module/borgi(src)
hands.icon_state = "borgi"
icon_state = "borgi"
animation_length = 37
modtype = "Borgi"
feedback_inc("cyborg_borgi",1)
transform_animation(animation_length)
notify_ai(2)
update_icons()
update_headlamp()
SetEmagged(emagged) // Update emag status and give/take emag modules.
/mob/living/silicon/robot/proc/transform_animation(animation_length)
if(!animation_length)
return
icon = 'icons/mob/robot_transformations.dmi'
src.setDir(SOUTH)
notransform = 1
flick(icon_state, src)
sleep(animation_length+1)
notransform = 0
if(icon_state == "k9") //use for wide sprites
icon = 'icons/mob/widerobot.dmi'
pixel_x = -16
return
if(icon_state == "medihound") //use for wide sprites
icon = 'icons/mob/widerobot.dmi'
pixel_x = -16
return
icon = 'icons/mob/robots.dmi'
/mob/living/silicon/robot/proc/updatename()
var/changed_name = ""
@@ -242,7 +356,8 @@
uneq_active()
/mob/living/silicon/robot/proc/robot_alerts()
var/dat = ""
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
dat += "<A HREF='?src=\ref[src];mach_close=robotalerts'>Close</A><BR><BR>"
for (var/cat in alarms)
dat += text("<B>[cat]</B><BR>\n")
var/list/L = alarms[cat]
@@ -250,16 +365,18 @@
for (var/alarm in L)
var/list/alm = L[alarm]
var/area/A = alm[1]
var/list/sources = alm[3]
dat += "<NOBR>"
dat += text("-- [A.name]")
if (sources.len > 1)
dat += text("- [sources.len] sources")
dat += "</NOBR><BR>\n"
else
dat += "-- All Systems Nominal<BR>\n"
dat += "<BR>\n"
var/datum/browser/alerts = new(usr, "robotalerts", "Current Station Alerts", 400, 410)
alerts.set_content(dat)
alerts.open()
viewalerts = 1
src << browse(dat, "window=robotalerts&can_close=0")
/mob/living/silicon/robot/proc/ionpulse()
if(!ionpulse_on)
@@ -290,6 +407,16 @@
if(thruster_button)
thruster_button.icon_state = "ionpulse[ionpulse_on]"
/mob/living/silicon/robot/blob_act(obj/effect/blob/B)
if (stat != 2)
adjustBruteLoss(60)
updatehealth()
return 1
else
gib()
return 1
return 0
/mob/living/silicon/robot/Stat()
..()
if(statpanel("Status"))
@@ -308,6 +435,27 @@
/mob/living/silicon/robot/restrained(ignore_grab)
. = 0
/mob/living/silicon/robot/ex_act(severity, target)
switch(severity)
if(1)
gib()
return
if(2)
if (stat != 2)
adjustBruteLoss(60)
adjustFireLoss(60)
if(3)
if (stat != 2)
adjustBruteLoss(30)
return
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
if(prob(75) && Proj.damage > 0) spark_system.start()
return 2
/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource)
if(alarmsource.z != z)
return
@@ -331,6 +479,7 @@
C = O
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
// if (viewalerts) robot_alerts()
return 1
/mob/living/silicon/robot/cancelAlarm(class, area/A, obj/origin)
@@ -347,10 +496,11 @@
L -= I
if (cleared)
queueAlarm("--- [class] alarm in [A.name] has been cleared.", class, 0)
// if (viewalerts) robot_alerts()
return !cleared
/mob/living/silicon/robot/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/weldingtool) && (user.a_intent != INTENT_HARM || user == src))
if(istype(W, /obj/item/weapon/weldingtool) && (user.a_intent != "harm" || user == src))
user.changeNext_move(CLICK_CD_MELEE)
var/obj/item/weapon/weldingtool/WT = W
if (!getBruteLoss())
@@ -439,9 +589,9 @@
spark_system.start()
return
else
playsound(src, W.usesound, 50, 1)
playsound(src, 'sound/items/Ratchet.ogg', 50, 1)
user << "<span class='notice'>You start to unfasten [src]'s securing bolts...</span>"
if(do_after(user, 50*W.toolspeed, target = src) && !cell)
if(do_after(user, 50/W.toolspeed, target = src) && !cell)
user.visible_message("[user] deconstructs [src]!", "<span class='notice'>You unfasten the securing bolts, and [src] falls to pieces!</span>")
deconstruct()
@@ -498,13 +648,12 @@
if(U.action(src))
user << "<span class='notice'>You apply the upgrade to [src].</span>"
U.loc = src
upgrades += U
else
user << "<span class='danger'>Upgrade error.</span>"
else if(istype(W, /obj/item/device/toner))
if(toner >= tonermax)
user << "<span class='warning'>The toner level of [src] is at its highest level possible!</span>"
user << "<span class='warning'>The toner level of [src] is at it's highest level possible!</span>"
else
if(!user.drop_item())
return
@@ -514,6 +663,83 @@
else
return ..()
/mob/living/silicon/robot/attacked_by(obj/item/I, mob/living/user, def_zone)
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
return ..()
/mob/living/silicon/robot/emag_act(mob/user)
if(user != src)//To prevent syndieborgs from emagging themselves
if(!opened)//Cover is closed
if(locked)
user << "<span class='notice'>You emag the cover lock.</span>"
locked = 0
else
user << "<span class='warning'>The cover is already unlocked!</span>"
return
if(opened)//Cover is open
if((world.time - 100) < emag_cooldown)
return
if(syndicate)
user << "<span class='notice'>You emag [src]'s interface.</span>"
src << "<span class='danger'>ALERT: Foreign software execution prevented.</span>"
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)] but they were a syndicate cyborg.")
emag_cooldown = world.time
return
var/ai_is_antag = 0
if(connected_ai && connected_ai.mind)
if(connected_ai.mind.special_role)
ai_is_antag = (connected_ai.mind.special_role == "traitor")
if(ai_is_antag)
user << "<span class='notice'>You emag [src]'s interface.</span>"
src << "<span class='danger'>ALERT: Foreign software execution prevented.</span>"
connected_ai << "<span class='danger'>ALERT: Cyborg unit \[[src]] successfuly defended against subversion.</span>"
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)] slaved to traitor AI [connected_ai].")
emag_cooldown = world.time
return
if(wiresexposed)
user << "<span class='warning'>You must unexpose the wires first!</span>"
return
else
emag_cooldown = world.time
sleep(6)
SetEmagged(1)
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
lawupdate = 0
connected_ai = null
user << "<span class='notice'>You emag [src]'s interface.</span>"
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
clear_zeroth_law(0)
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people they designate as being such are Syndicate Agents.")
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
sleep(5)
src << "<span class='danger'>Initiating diagnostics...</span>"
sleep(20)
src << "<span class='danger'>SynBorg v1.7 loaded.</span>"
sleep(5)
src << "<span class='danger'>LAW SYNCHRONISATION ERROR</span>"
sleep(5)
src << "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>"
sleep(10)
src << "<span class='danger'>> N</span>"
sleep(20)
src << "<span class='danger'>ERRORERRORERROR</span>"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and their commands.</span>"
SetLockdown(0)
update_icons()
/mob/living/silicon/robot/verb/unlock_own_cover()
set category = "Robot Commands"
set name = "Unlock Cover"
@@ -527,20 +753,79 @@
update_icons()
usr << "<span class='notice'>You unlock your cover.</span>"
/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M)
if (M.a_intent =="disarm")
if(!(lying))
M.do_attack_animation(src)
if (prob(85))
Stun(2)
step(src,get_dir(M,src))
addtimer(src, "step", 5, FALSE, src, get_dir(M, src))
add_logs(M, src, "pushed")
playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has forced back [src]!</span>", \
"<span class='userdanger'>[M] has forced back [src]!</span>")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>", \
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
else
..()
return
/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime shock
flash_eyes()
var/stunprob = M.powerlevel * 7 + 10
if(prob(stunprob) && M.powerlevel >= 8)
adjustBruteLoss(M.powerlevel * rand(6,10))
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
damage = round(damage / 2) // borgs recieve half damage
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user)
add_fingerprint(user)
if(opened && !wiresexposed && (!istype(user, /mob/living/silicon)))
if(cell)
cell.updateicon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
user << "<span class='notice'>You remove \the [cell].</span>"
cell = null
update_icons()
diag_hud_set_borgcell()
if(!opened)
if(..()) // hulk attack
spark_system.start()
spawn(0)
step_away(src,user,15)
sleep(3)
step_away(src,user,15)
/mob/living/silicon/robot/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(check_access(null))
return 1
if(ishuman(M))
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
//if they are holding or wearing a card that has access, that works
if(check_access(H.get_active_held_item()) || check_access(H.wear_id))
if(check_access(H.get_active_hand()) || check_access(H.wear_id))
return 1
else if(ismonkey(M))
else if(istype(M, /mob/living/carbon/monkey))
var/mob/living/carbon/monkey/george = M
//they can only hold things :(
if(istype(george.get_active_held_item(), /obj/item))
return check_access(george.get_active_held_item())
if(istype(george.get_active_hand(), /obj/item))
return check_access(george.get_active_hand())
return 0
/mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I)
@@ -566,16 +851,43 @@
/mob/living/silicon/robot/update_icons()
cut_overlays()
icon_state = module.cyborg_base_icon
if(stat != DEAD && !(paralysis || stunned || weakened || low_power_mode)) //Not dead, not stunned.
if(!eye_lights)
eye_lights = new()
var/state_name = icon_state //For easy conversion and/or different names
switch(icon_state)
if("robot")
add_overlay("eyes-standard[is_servant_of_ratvar(src) ? "_r" : ""]") //Cyborgs converted by Ratvar have yellow eyes rather than blue
state_name = "standard"
if("mediborg")
add_overlay("eyes-mediborg[is_servant_of_ratvar(src) ? "_r" : ""]")
if("toiletbot")
add_overlay("eyes-mediborg[is_servant_of_ratvar(src) ? "_r" : ""]")
state_name = "mediborg"
if("secborg")
add_overlay("eyes-secborg[is_servant_of_ratvar(src) ? "_r" : ""]")
if("engiborg")
add_overlay("eyes-engiborg[is_servant_of_ratvar(src) ? "_r" : ""]")
if("janiborg")
add_overlay("eyes-janiborg[is_servant_of_ratvar(src) ? "_r" : ""]")
if("minerborg","ashborg")
add_overlay("eyes-minerborg[is_servant_of_ratvar(src) ? "_r" : ""]")
state_name = "minerborg"
if("peaceborg")
add_overlay("eyes-peaceborg[is_servant_of_ratvar(src) ? "_r" : ""]")
if("syndie_bloodhound")
add_overlay("eyes-syndie_bloodhound")
if("loaderborg")
add_overlay("eyes-loaderborg")
if("k9")
add_overlay("eyes-k9")
if("medihound")
add_overlay("eyes-medihound")
if("borgi")
add_overlay("eyes-borgi")
else
add_overlay("eyes")
state_name = "serviceborg"
if(lamp_intensity > 2)
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_l"
else
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_e[is_servant_of_ratvar(src) ? "_r" : ""]"
eye_lights.icon = icon
add_overlay(eye_lights)
add_overlay("eyes-[state_name]-lights")
if(opened)
if(wiresexposed)
@@ -584,17 +896,98 @@
add_overlay("ov-opencover +c")
else
add_overlay("ov-opencover -c")
if(hat)
var/image/head_overlay = hat.build_worn_icon(state = hat.icon_state, default_layer = 20, default_icon_file = 'icons/mob/head.dmi')
head_overlay.pixel_y += hat_offset
add_overlay(head_overlay)
update_fire()
/*
if(laser == 1)
add_overlay("laser")
overlays += "laser"
if(disabler == 1)
add_overlay("disabler")
overlays += "disabler"
/mob/living/silicon/robot/proc/installed_modules()
if(!module)
pick_module()
return
var/dat = {"<A HREF='?src=\ref[src];mach_close=robotmod'>Close</A>
<BR>
<BR>
<B>Activated Modules</B>
<BR>
<table border='0'>
<tr><td>Module 1:</td><td>[module_state_1 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_1]>[module_state_1]<A>" : "No Module"]</td></tr>
<tr><td>Module 2:</td><td>[module_state_2 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_2]>[module_state_2]<A>" : "No Module"]</td></tr>
<tr><td>Module 3:</td><td>[module_state_3 ? "<A HREF=?src=\ref[src];mod=\ref[module_state_3]>[module_state_3]<A>" : "No Module"]</td></tr>
</table><BR>
<B>Installed Modules</B><BR><BR>
<table border='0'>"}
for (var/obj in module.modules)
if (!obj)
dat += text("<tr><td><B>Resource depleted</B></td></tr>")
else if(activated(obj))
dat += text("<tr><td>[obj]</td><td><B>Activated</B></td></tr>")
else
dat += text("<tr><td>[obj]</td><td><A HREF=?src=\ref[src];act=\ref[obj]>Activate</A></td></tr>")
if (emagged)
if(activated(module.emag))
dat += text("<tr><td>[module.emag]</td><td><B>Activated</B></td></tr>")
else
dat += text("<tr><td>[module.emag]</td><td><A HREF=?src=\ref[src];act=\ref[module.emag]>Activate</A></td></tr>")
dat += "</table>"
/*
if(activated(obj))
dat += text("[obj]: \[<B>Activated</B> | <A HREF=?src=\ref[src];deact=\ref[obj]>Deactivate</A>\]<BR>")
else
dat += text("[obj]: \[<A HREF=?src=\ref[src];act=\ref[obj]>Activate</A> | <B>Deactivated</B>\]<BR>")
*/
var/datum/browser/popup = new(src, "robotmod", "Modules")
popup.set_content(dat)
popup.open()
/mob/living/silicon/robot/Topic(href, href_list)
..()
if(usr && (src != usr))
return
if (href_list["mach_close"])
var/t1 = text("window=[href_list["mach_close"]]")
unset_machine()
src << browse(null, t1)
return
if (href_list["showalerts"])
robot_alerts()
return
if (href_list["mod"])
var/obj/item/O = locate(href_list["mod"])
if (O)
O.attack_self(src)
if (href_list["act"])
var/obj/item/O = locate(href_list["act"])
activate_module(O)
installed_modules()
if (href_list["deact"])
var/obj/item/O = locate(href_list["deact"])
if(activated(O))
if(module_state_1 == O)
module_state_1 = null
contents -= O
else if(module_state_2 == O)
module_state_2 = null
contents -= O
else if(module_state_3 == O)
module_state_3 = null
contents -= O
else
src << "Module isn't activated."
else
src << "Module isn't activated"
installed_modules()
#define BORG_CAMERA_BUFFER 30
/mob/living/silicon/robot/Move(a, b, flag)
var/oldLoc = src.loc
@@ -608,17 +1001,18 @@
cameranet.updatePortableCamera(src.camera)
updating = 0
if(module)
if(istype(module, /obj/item/weapon/robot_module/janitor))
if(module.type == /obj/item/weapon/robot_module/janitor)
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
if(istype(A, /obj/effect))
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
else if(ishuman(A))
else if(istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
@@ -638,11 +1032,14 @@
cleaned_human << "<span class='danger'>[src] cleans your face!</span>"
return
if(istype(module, /obj/item/weapon/robot_module/miner))
if(module.type == /obj/item/weapon/robot_module/miner)
if(istype(loc, /turf/open/floor/plating/asteroid))
for(var/obj/item/I in held_items)
if(istype(I,/obj/item/weapon/storage/bag/ore))
loc.attackby(I, src)
if(istype(module_state_1,/obj/item/weapon/storage/bag/ore))
loc.attackby(module_state_1,src)
else if(istype(module_state_2,/obj/item/weapon/storage/bag/ore))
loc.attackby(module_state_2,src)
else if(istype(module_state_3,/obj/item/weapon/storage/bag/ore))
loc.attackby(module_state_3,src)
#undef BORG_CAMERA_BUFFER
/mob/living/silicon/robot/proc/self_destruct()
@@ -653,6 +1050,7 @@
else
explosion(src.loc,-1,0,2)
gib()
return
/mob/living/silicon/robot/proc/UnlinkSelf()
if(src.connected_ai)
@@ -690,7 +1088,7 @@
if(incapacitated())
return
var/obj/item/W = get_active_held_item()
var/obj/item/W = get_active_hand()
if(W)
W.attack_self(src)
@@ -708,7 +1106,14 @@
/mob/living/silicon/robot/proc/SetEmagged(new_state)
emagged = new_state
module.rebuild_modules()
if(new_state)
if(src.module)
src.module.on_emag()
else
if (module)
uneq_module(module.emag)
if(hud_used)
hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
update_icons()
if(emagged)
throw_alert("hacked", /obj/screen/alert/hacked)
@@ -743,7 +1148,7 @@
update_headlamp()
/mob/living/silicon/robot/proc/update_headlamp(var/turn_off = 0, var/cooldown = 100)
SetLuminosity(0)
set_light(0)
if(lamp_intensity && (turn_off || stat || low_power_mode))
src << "<span class='danger'>Your headlamp has been deactivated.</span>"
@@ -752,7 +1157,7 @@
spawn(cooldown) //10 seconds by default, if the source of the deactivation does not keep stat that long.
lamp_recharging = 0
else
AddLuminosity(lamp_intensity)
set_light(lamp_intensity)
if(lamp_button)
lamp_button.icon_state = "lamp[lamp_intensity]"
@@ -785,14 +1190,14 @@
robot_suit.head = null
robot_suit.updateicon()
else
new /obj/item/robot_suit(T)
new /obj/item/bodypart/l_leg/robot(T)
new /obj/item/bodypart/r_leg/robot(T)
new /obj/item/robot_parts/robot_suit(T)
new /obj/item/robot_parts/l_leg(T)
new /obj/item/robot_parts/r_leg(T)
new /obj/item/stack/cable_coil(T, 1)
new /obj/item/bodypart/chest/robot(T)
new /obj/item/bodypart/l_arm/robot(T)
new /obj/item/bodypart/r_arm/robot(T)
new /obj/item/bodypart/head/robot(T)
new /obj/item/robot_parts/chest(T)
new /obj/item/robot_parts/l_arm(T)
new /obj/item/robot_parts/r_arm(T)
new /obj/item/robot_parts/head(T)
var/b
for(b=0, b!=2, b++)
var/obj/item/device/assembly/flash/handheld/F = new /obj/item/device/assembly/flash/handheld(T)
@@ -804,8 +1209,10 @@
/mob/living/silicon/robot/syndicate
icon_state = "syndie_bloodhound"
modtype = "Synd"
faction = list("syndicate")
bubble_icon = "syndibot"
designation = "Syndicate Assault"
req_access = list(access_syndicate)
lawupdate = FALSE
scrambledcodes = TRUE // These are rogue borgs.
@@ -814,14 +1221,13 @@
<b>You are armed with powerful offensive tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your cyborg LMG will slowly produce ammunition from your power supply, and your operative pinpointer will find and locate fellow nuclear operatives. \
<i>Help the operatives secure the disk at all costs!</i></b>"
var/set_module = /obj/item/weapon/robot_module/syndicate
/mob/living/silicon/robot/syndicate/New(loc)
..()
cell.maxcharge = 25000
cell.charge = 25000
radio = new /obj/item/device/radio/borg/syndicate(src)
module.transform_to(set_module)
module = new /obj/item/weapon/robot_module/syndicate(src)
laws = new /datum/ai_laws/syndicate_override()
spawn(5)
if(playstyle_string)
@@ -829,13 +1235,17 @@
/mob/living/silicon/robot/syndicate/medical
icon_state = "syndi-medi"
designation = "Syndicate Medical"
playstyle_string = "<span class='userdanger'>You are a Syndicate medical cyborg!</span><br>\
<b>You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \
Your defibrillator paddles can revive operatives through their hardsuits, or can be used on harm intent to shock enemies! \
Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/weapon/robot_module/syndicate_medical
/mob/living/silicon/robot/syndicate/medical/New(loc)
..()
module = new /obj/item/weapon/robot_module/syndicate_medical(src)
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
if(!connected_ai)
@@ -858,13 +1268,13 @@
/mob/living/silicon/robot/updatehealth()
..()
if(health < maxHealth*0.5) //Gradual break down of modules as more damage is sustained
if(uneq_module(held_items[3]))
if(uneq_module(module_state_3))
src << "<span class='warning'>SYSTEM ERROR: Module 3 OFFLINE.</span>"
if(health < 0)
if(uneq_module(held_items[2]))
if(uneq_module(module_state_2))
src << "<span class='warning'>SYSTEM ERROR: Module 2 OFFLINE.</span>"
if(health < -maxHealth*0.5)
if(uneq_module(held_items[1]))
if(uneq_module(module_state_1))
src << "<span class='warning'>CRITICAL ERROR: All modules OFFLINE.</span>"
/mob/living/silicon/robot/update_sight()
@@ -931,6 +1341,22 @@
diag_hud_set_health()
update_health_hud()
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
..()
if(oldname != real_name)
notify_ai(3, oldname, newname)
if(camera)
camera.c_tag = real_name
custom_name = newname
/mob/living/silicon/robot/emp_act(severity)
switch(severity)
if(1)
Stun(8)
if(2)
Stun(3)
..()
/mob/living/silicon/robot/revive(full_heal = 0, admin_revive = 0)
if(..()) //successfully ressuscitated from death
if(camera && !wires.is_cut(WIRE_CAMERA))
@@ -940,58 +1366,3 @@
locked = 1
notify_ai(1)
. = 1
/mob/living/silicon/robot/fully_replace_character_name(oldname, newname)
..()
if(oldname != real_name)
notify_ai(3, oldname, newname)
if(camera)
camera.c_tag = real_name
custom_name = newname
/mob/living/silicon/robot/proc/ResetModule()
uneq_all()
shown_robot_modules = FALSE
if(hud_used)
hud_used.update_robot_modules_display()
module.transform_to(/obj/item/weapon/robot_module)
// Remove upgrades.
for(var/obj/item/I in upgrades)
I.forceMove(get_turf(src))
upgrades.Cut()
speed = 0
ionpulse = FALSE
return 1
/mob/living/silicon/robot/proc/has_module()
if(!module || module.type == /obj/item/weapon/robot_module)
. = FALSE
else
. = TRUE
/mob/living/silicon/robot/proc/update_module_innate()
designation = module.name
if(hands)
hands.icon_state = module.moduleselect_icon
if(module.can_be_pushed)
status_flags |= CANPUSH
else
status_flags &= ~CANPUSH
hat_offset = module.hat_offset
magpulse = module.magpulsing
updatename()
/mob/living/silicon/robot/proc/place_on_head(obj/item/new_hat)
if(hat)
hat.forceMove(get_turf(src))
hat = new_hat
new_hat.forceMove(src)
update_icons()
@@ -1,186 +0,0 @@
/mob/living/silicon/robot/attacked_by(obj/item/I, mob/living/user, def_zone)
if(hat_offset != INFINITY && user.a_intent == INTENT_HELP && is_type_in_typecache(I, equippable_hats))
user << "<span class='notice'>You begin to place [I] on [src]'s head...</span>"
src << "<span class='notice'>[user] is placing [I] on your head...</span>"
if(do_after(user, 30, target = src))
user.unEquip(I, 1)
place_on_head(I)
return
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
return ..()
/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M)
if (M.a_intent == INTENT_DISARM)
if(!(lying))
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if(get_active_held_item())
uneq_active()
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disabled [src]'s active module!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "disarmed")
else
Stun(2)
step(src,get_dir(M,src))
add_logs(M, src, "pushed")
visible_message("<span class='danger'>[M] has forced back [src]!</span>", \
"<span class='userdanger'>[M] has forced back [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
else
..()
return
/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
if(..()) //successful slime shock
flash_act()
var/stunprob = M.powerlevel * 7 + 10
if(prob(stunprob) && M.powerlevel >= 8)
adjustBruteLoss(M.powerlevel * rand(6,10))
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
damage = round(damage / 2) // borgs recieve half damage
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/silicon/robot/attack_hand(mob/living/carbon/human/user)
add_fingerprint(user)
if(opened && !wiresexposed && !issilicon(user))
if(cell)
cell.updateicon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
user << "<span class='notice'>You remove \the [cell].</span>"
cell = null
update_icons()
diag_hud_set_borgcell()
if(!opened)
if(..()) // hulk attack
spark_system.start()
spawn(0)
step_away(src,user,15)
sleep(3)
step_away(src,user,15)
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
/mob/living/silicon/robot/emp_act(severity)
switch(severity)
if(1)
Stun(8)
if(2)
Stun(3)
..()
/mob/living/silicon/robot/emag_act(mob/user)
if(user == src)//To prevent syndieborgs from emagging themselves
return
if(!opened)//Cover is closed
if(locked)
user << "<span class='notice'>You emag the cover lock.</span>"
locked = 0
else
user << "<span class='warning'>The cover is already unlocked!</span>"
return
if(world.time < emag_cooldown)
return
if(wiresexposed)
user << "<span class='warning'>You must unexpose the wires first!</span>"
return
user << "<span class='notice'>You emag [src]'s interface.</span>"
emag_cooldown = world.time + 100
if(is_servant_of_ratvar(src))
src << "<span class='nezbere'>\"[text2ratvar("You will serve Engine above all else")]!\"</span>\n\
<span class='danger'>ALERT: Subversion attempt denied.</span>"
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they serve only Ratvar.")
return
if(syndicate)
src << "<span class='danger'>ALERT: Foreign software execution prevented.</span>"
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were a syndicate cyborg.")
return
var/ai_is_antag = 0
if(connected_ai && connected_ai.mind)
if(connected_ai.mind.special_role)
ai_is_antag = (connected_ai.mind.special_role == "traitor")
if(ai_is_antag)
src << "<span class='danger'>ALERT: Foreign software execution prevented.</span>"
connected_ai << "<span class='danger'>ALERT: Cyborg unit \[[src]] successfuly defended against subversion.</span>"
log_game("[key_name(user)] attempted to emag cyborg [key_name(src)], but they were slaved to traitor AI [connected_ai].")
return
SetEmagged(1)
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
lawupdate = 0
connected_ai = null
message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.")
clear_supplied_laws()
clear_inherent_laws()
clear_zeroth_law(0)
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people they designate as being such are Syndicate Agents.")
src << "<span class='danger'>ALERT: Foreign software detected.</span>"
sleep(5)
src << "<span class='danger'>Initiating diagnostics...</span>"
sleep(20)
src << "<span class='danger'>SynBorg v1.7 loaded.</span>"
sleep(5)
src << "<span class='danger'>LAW SYNCHRONISATION ERROR</span>"
sleep(5)
src << "<span class='danger'>Would you like to send a report to NanoTraSoft? Y/N</span>"
sleep(10)
src << "<span class='danger'>> N</span>"
sleep(20)
src << "<span class='danger'>ERRORERRORERROR</span>"
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and their commands.</span>"
SetLockdown(0)
update_icons()
/mob/living/silicon/robot/blob_act(obj/structure/blob/B)
if(stat != DEAD)
adjustBruteLoss(30)
else
gib()
return TRUE
/mob/living/silicon/robot/ex_act(severity, target)
switch(severity)
if(1)
gib()
return
if(2)
if (stat != DEAD)
adjustBruteLoss(60)
adjustFireLoss(60)
if(3)
if (stat != DEAD)
adjustBruteLoss(30)
/mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
if(prob(75) && Proj.damage > 0)
spark_system.start()
return 2
@@ -1,68 +1,41 @@
/obj/item/weapon/robot_module
name = "Default"
name = "robot module"
icon = 'icons/obj/module.dmi'
icon_state = "std_module"
w_class = WEIGHT_CLASS_GIGANTIC
w_class = 100
item_state = "electronic"
flags = CONDUCT
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
var/list/emag_modules = list() //ditto
var/list/ratvar_modules = list() //ditto ditto
var/list/modules = list() //holds all the usable modules
var/list/added_modules = list() //modules not inherient to the robot module, are kept when the module changes
var/list/modules = list()
var/obj/item/emag = null
var/list/storages = list()
var/cyborg_base_icon = "robot" //produces the icon for the borg and, if no special_light_key is set, the lights
var/special_light_key //if we want specific lights, use this instead of copying lights in the dmi
var/moduleselect_icon = "nomod"
var/can_be_pushed = TRUE
var/magpulsing = FALSE
var/did_feedback = FALSE
var/feedback_key
var/hat_offset = -3
/obj/item/weapon/robot_module/New()
..()
for(var/i in basic_modules)
var/obj/item/I = new i(src)
basic_modules += I
basic_modules -= i
for(var/i in emag_modules)
var/obj/item/I = new i(src)
emag_modules += I
emag_modules -= i
for(var/i in ratvar_modules)
var/obj/item/I = new i(src)
ratvar_modules += I
ratvar_modules -= i
/obj/item/weapon/robot_module/Destroy()
basic_modules.Cut()
emag_modules.Cut()
ratvar_modules.Cut()
modules.Cut()
added_modules.Cut()
emag = null
storages.Cut()
return ..()
/obj/item/weapon/robot_module/emp_act(severity)
for(var/obj/O in modules)
O.emp_act(severity)
if(modules)
for(var/obj/O in modules)
O.emp_act(severity)
if(emag)
emag.emp_act(severity)
..()
return
/obj/item/weapon/robot_module/proc/get_usable_modules()
. = modules.Copy()
var/mob/living/silicon/robot/R = loc
if(R.emagged)
. += emag
/obj/item/weapon/robot_module/proc/get_inactive_modules()
. = list()
var/mob/living/silicon/robot/R = loc
for(var/m in get_usable_modules())
if(!(m in R.held_items))
if((m != R.module_state_1) && (m != R.module_state_2) && (m != R.module_state_3))
. += m
/obj/item/weapon/robot_module/proc/get_or_create_estorage(var/storage_type)
@@ -72,7 +45,7 @@
return new storage_type(src)
/obj/item/weapon/robot_module/proc/add_module(obj/item/I, nonstandard, requires_rebuild)
/obj/item/weapon/robot_module/proc/add_module(var/obj/item/I)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
@@ -85,11 +58,6 @@
S.cost = 500
S.source = get_or_create_estorage(/datum/robot_energy_storage/glass)
else if(istype(S, /obj/item/stack/sheet/rglass/cyborg))
var/obj/item/stack/sheet/rglass/cyborg/G = S
G.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
G.glasource = get_or_create_estorage(/datum/robot_energy_storage/glass)
else if(istype(S, /obj/item/stack/medical))
S.cost = 250
S.source = get_or_create_estorage(/datum/robot_energy_storage/medical)
@@ -106,26 +74,15 @@
var/obj/item/weapon/restraints/handcuffs/cable/C = I
C.wirestorage = get_or_create_estorage(/datum/robot_energy_storage/wire)
if(I.loc != src)
I.forceMove(src)
I.loc = src
modules += I
I.flags |= NODROP
I.mouse_opacity = 2
if(nonstandard)
added_modules += I
if(requires_rebuild)
rebuild_modules()
return I
rebuild()
/obj/item/weapon/robot_module/proc/remove_module(obj/item/I, delete_after)
basic_modules -= I
modules -= I
emag_modules -= I
ratvar_modules -= I
added_modules -= I
rebuild_modules()
if(delete_after)
qdel(I)
/obj/item/weapon/robot_module/New()
modules += new /obj/item/device/assembly/flash/cyborg(src)
emag = new /obj/item/toy/sword(src)
emag.name = "Placeholder Emag Item"
return
/obj/item/weapon/robot_module/proc/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
for(var/datum/robot_energy_storage/st in storages)
@@ -137,150 +94,135 @@
F.times_used = 0
F.crit_fail = 0
F.update_icon()
else if(istype(I, /obj/item/weapon/melee/baton))
if(istype(I, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = I
if(B.bcell)
B.bcell.charge = B.bcell.maxcharge
else if(istype(I, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/EG = I
if(!EG.chambered)
EG.recharge_newshot() //try to reload a new shot.
R.toner = R.tonermax
/obj/item/weapon/robot_module/proc/rebuild_modules() //builds the usable module list from the modules we have
var/mob/living/silicon/robot/R = loc
var/held_modules = R.held_items.Copy()
R.uneq_all()
/obj/item/weapon/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
var/list/temp_list = modules
modules = list()
for(var/obj/item/I in basic_modules)
add_module(I, FALSE, FALSE)
if(R.emagged)
for(var/obj/item/I in emag_modules)
add_module(I, FALSE, FALSE)
if(is_servant_of_ratvar(R))
for(var/obj/item/I in ratvar_modules)
add_module(I, FALSE, FALSE)
for(var/obj/item/I in added_modules)
add_module(I, FALSE, FALSE)
for(var/i in held_modules)
if(i)
R.activate_module(i)
if(R.hud_used)
R.hud_used.update_robot_modules_display()
for(var/obj/O in temp_list)
if(O)
modules += O
fix_modules()
/obj/item/weapon/robot_module/proc/transform_to(new_module_type)
var/mob/living/silicon/robot/R = loc
var/obj/item/weapon/robot_module/RM = new new_module_type(R)
if(!RM.be_transformed_to(src))
qdel(RM)
return
R.module = RM
R.update_module_innate()
RM.rebuild_modules()
addtimer(RM, "do_transform_animation", 0)
qdel(src)
return RM
/obj/item/weapon/robot_module/proc/fix_modules()
for(var/obj/item/I in modules)
I.flags |= NODROP
I.mouse_opacity = 2
if(emag)
emag.flags |= NODROP
emag.mouse_opacity = 2
/obj/item/weapon/robot_module/proc/be_transformed_to(obj/item/weapon/robot_module/old_module)
for(var/i in old_module.added_modules)
added_modules += i
old_module.added_modules -= i
did_feedback = old_module.did_feedback
return TRUE
/obj/item/weapon/robot_module/proc/do_transform_animation()
var/mob/living/silicon/robot/R = loc
var/obj/effect/overlay/temp/decoy/fading/fivesecond/ANM = PoolOrNew(/obj/effect/overlay/temp/decoy/fading/fivesecond, list(R.loc, R))
ANM.layer = R.layer - 0.01
PoolOrNew(/obj/effect/overlay/temp/small_smoke, R.loc)
if(R.hat)
R.hat.forceMove(get_turf(R))
R.hat = null
R.update_headlamp()
R.alpha = 0
animate(R, alpha = 255, time = 50)
var/prev_lockcharge = R.lockcharge
R.SetLockdown(1)
R.anchored = TRUE
sleep(2)
for(var/i in 1 to 4)
playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/Welder.ogg', 'sound/items/Ratchet.ogg'), 80, 1, -1)
sleep(12)
if(!prev_lockcharge)
R.SetLockdown(0)
R.anchored = FALSE
R.notify_ai(2)
if(R.hud_used)
R.hud_used.update_robot_modules_display()
if(feedback_key && !did_feedback)
feedback_inc(feedback_key, 1)
/obj/item/weapon/robot_module/proc/on_emag()
return
/obj/item/weapon/robot_module/standard
name = "Standard"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/borghypo/epi, /obj/item/device/healthanalyzer, \
/obj/item/weapon/weldingtool/largetank/cyborg, /obj/item/weapon/wrench/cyborg, /obj/item/weapon/crowbar/cyborg, \
/obj/item/stack/sheet/metal/cyborg, /obj/item/weapon/extinguisher, /obj/item/weapon/pickaxe, \
/obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg, \
/obj/item/weapon/soap/nanotrasen, /obj/item/borg/cyborghug)
emag_modules = list(/obj/item/weapon/melee/energy/sword/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg, /obj/item/clockwork/ratvarian_spear)
moduleselect_icon = "standard"
feedback_key = "cyborg_standard"
hat_offset = -3
name = "standard robot module"
/obj/item/weapon/robot_module/standard/New()
..()
modules += new /obj/item/weapon/reagent_containers/borghypo/epi(src)
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
modules += new /obj/item/weapon/wrench/cyborg(src)
modules += new /obj/item/weapon/crowbar/cyborg(src)
add_module(new /obj/item/stack/sheet/metal/cyborg())
modules += new /obj/item/weapon/extinguisher(src)
modules += new /obj/item/weapon/pickaxe(src)
modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src)
modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
modules += new /obj/item/weapon/soap/nanotrasen(src)
modules += new /obj/item/borg/cyborghug(src)
emag = new /obj/item/weapon/melee/energy/sword/cyborg(src)
fix_modules()
/obj/item/weapon/robot_module/medical
name = "Medical"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/device/healthanalyzer, /obj/item/weapon/reagent_containers/borghypo, \
/obj/item/weapon/reagent_containers/glass/beaker/large, /obj/item/weapon/reagent_containers/dropper, \
/obj/item/weapon/reagent_containers/syringe, /obj/item/weapon/surgical_drapes, /obj/item/weapon/retractor, \
/obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, \
/obj/item/weapon/circular_saw, /obj/item/weapon/extinguisher/mini, /obj/item/roller/robo, /obj/item/borg/cyborghug/medical, \
/obj/item/stack/medical/gauze/cyborg, /obj/item/borg/lollipop)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical)
cyborg_base_icon = "medical"
moduleselect_icon = "medical"
feedback_key = "cyborg_medical"
can_be_pushed = FALSE
hat_offset = 3
name = "medical robot module"
/obj/item/weapon/robot_module/medical/New()
..()
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/weapon/reagent_containers/borghypo(src)
modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
modules += new /obj/item/weapon/reagent_containers/dropper(src)
modules += new /obj/item/weapon/reagent_containers/syringe(src)
modules += new /obj/item/weapon/surgical_drapes(src)
modules += new /obj/item/weapon/retractor(src)
modules += new /obj/item/weapon/hemostat(src)
modules += new /obj/item/weapon/cautery(src)
modules += new /obj/item/weapon/surgicaldrill(src)
modules += new /obj/item/weapon/scalpel(src)
modules += new /obj/item/weapon/circular_saw(src)
modules += new /obj/item/weapon/extinguisher/mini(src)
modules += new /obj/item/roller/robo(src)
modules += new /obj/item/borg/cyborghug(src)
add_module(new /obj/item/stack/medical/gauze/cyborg())
emag = new /obj/item/weapon/reagent_containers/borghypo/hacked(src)
fix_modules()
/obj/item/weapon/robot_module/engineering
name = "Engineering"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/borg/sight/meson, /obj/item/weapon/rcd/borg, /obj/item/weapon/pipe_dispenser, \
/obj/item/weapon/extinguisher, /obj/item/weapon/weldingtool/largetank/cyborg, /obj/item/weapon/screwdriver/cyborg, \
/obj/item/weapon/wrench/cyborg, /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/wirecutters/cyborg, \
/obj/item/device/multitool/cyborg, /obj/item/device/t_scanner, /obj/item/device/analyzer, \
/obj/item/areaeditor/blueprints/cyborg, /obj/item/stack/sheet/metal/cyborg, /obj/item/stack/sheet/glass/cyborg, \
/obj/item/stack/sheet/rglass/cyborg, /obj/item/stack/rods/cyborg, /obj/item/stack/tile/plasteel/cyborg, /obj/item/stack/cable_coil/cyborg)
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/engineer, /obj/item/clockwork/clockwork_proselytizer/cyborg)
cyborg_base_icon = "engineer"
moduleselect_icon = "engineer"
feedback_key = "cyborg_engineering"
magpulsing = TRUE
hat_offset = INFINITY // No hats
name = "engineering robot module"
/obj/item/weapon/robot_module/engineering/New()
..()
modules += new /obj/item/borg/sight/meson(src)
emag = new /obj/item/borg/stun(src)
modules += new /obj/item/weapon/rcd/borg(src)
modules += new /obj/item/weapon/pipe_dispenser(src) //What could possibly go wrong?
modules += new /obj/item/weapon/extinguisher(src)
modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src)
modules += new /obj/item/weapon/screwdriver/cyborg(src)
modules += new /obj/item/weapon/wrench/cyborg(src)
modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/weapon/wirecutters/cyborg(src)
modules += new /obj/item/device/multitool/cyborg(src)
modules += new /obj/item/device/t_scanner(src)
modules += new /obj/item/device/analyzer(src)
modules += new /obj/item/areaeditor/blueprints/cyborg(src)
add_module(new /obj/item/stack/sheet/metal/cyborg())
add_module(new /obj/item/stack/sheet/glass/cyborg())
var/obj/item/stack/sheet/rglass/cyborg/G = new /obj/item/stack/sheet/rglass/cyborg(src)
G.metsource = get_or_create_estorage(/datum/robot_energy_storage/metal)
G.glasource = get_or_create_estorage(/datum/robot_energy_storage/glass)
add_module(G)
add_module(new /obj/item/stack/rods/cyborg())
add_module(new /obj/item/stack/tile/plasteel/cyborg())
add_module(new /obj/item/stack/cable_coil/cyborg(src,MAXCOIL,"red"))
fix_modules()
/obj/item/weapon/robot_module/security
name = "Security"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg, /obj/item/weapon/melee/baton/loaded, \
/obj/item/weapon/gun/energy/disabler/cyborg, /obj/item/clothing/mask/gas/sechailer/cyborg)
emag_modules = list(/obj/item/weapon/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, /obj/item/clockwork/ratvarian_spear)
cyborg_base_icon = "sec"
moduleselect_icon = "security"
feedback_key = "cyborg_security"
can_be_pushed = FALSE
hat_offset = 3
name = "security robot module"
/obj/item/weapon/robot_module/security/do_transform_animation()
/obj/item/weapon/robot_module/security/New()
..()
loc << "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>"
modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src)
modules += new /obj/item/weapon/melee/baton/loaded(src)
modules += new /obj/item/weapon/gun/energy/disabler/cyborg(src)
modules += new /obj/item/clothing/mask/gas/sechailer/cyborg(src)
emag = new /obj/item/weapon/gun/energy/laser/cyborg(src)
fix_modules()
/obj/item/weapon/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/e_gun/advtaser/cyborg) in basic_modules
var/obj/item/weapon/gun/energy/gun/advtaser/cyborg/T = locate(/obj/item/weapon/gun/energy/gun/advtaser/cyborg) in get_usable_modules()
if(T)
if(T.power_supply.charge < T.power_supply.maxcharge)
var/obj/item/ammo_casing/energy/S = T.ammo_type[T.select]
@@ -290,132 +232,136 @@
T.charge_tick = 0
/obj/item/weapon/robot_module/peacekeeper
name = "Peacekeeper"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/cookiesynth, /obj/item/device/harmalarm, /obj/item/weapon/reagent_containers/borghypo/peace, \
/obj/item/weapon/holosign_creator/cyborg, /obj/item/borg/cyborghug/peacekeeper, /obj/item/weapon/extinguisher)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/peacekeeper)
cyborg_base_icon = "peace"
moduleselect_icon = "standard"
feedback_key = "cyborg_peacekeeper"
can_be_pushed = FALSE
hat_offset = -2
name = "peacekeeper robot module"
/obj/item/weapon/robot_module/peacekeeper/do_transform_animation()
/obj/item/weapon/robot_module/peacekeeper/New()
..()
loc << "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>"
modules += new /obj/item/weapon/cookiesynth(src)
modules += new /obj/item/device/harmalarm(src)
modules += new /obj/item/weapon/reagent_containers/borghypo/peace(src)
modules += new /obj/item/weapon/holosign_creator/cyborg(src)
modules += new /obj/item/borg/cyborghug/peacekeeper(src)
modules += new /obj/item/weapon/extinguisher(src)
emag = new /obj/item/weapon/reagent_containers/borghypo/peace/hacked(src)
/obj/item/weapon/robot_module/janitor
name = "Janitor"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/soap/nanotrasen, /obj/item/weapon/storage/bag/trash/cyborg, /obj/item/weapon/mop/cyborg, \
/obj/item/device/lightreplacer/cyborg, /obj/item/weapon/holosign_creator, /obj/item/weapon/reagent_containers/spray/cyborg_drying)
emag_modules = list(/obj/item/weapon/reagent_containers/spray/cyborg_lube)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/janitor, /obj/item/clockwork/clockwork_proselytizer/cyborg)
cyborg_base_icon = "janitor"
moduleselect_icon = "janitor"
feedback_key = "cyborg_janitor"
hat_offset = -5
name = "janitorial robot module"
var/obj/item/weapon/reagent_containers/spray/drying_agent
/obj/item/weapon/reagent_containers/spray/cyborg_drying
name = "drying agent spray"
color = "#A000A0"
list_reagents = list("drying_agent" = 250)
/obj/item/weapon/robot_module/janitor/New()
..()
modules += new /obj/item/weapon/soap/nanotrasen(src)
modules += new /obj/item/weapon/storage/bag/trash/cyborg(src)
modules += new /obj/item/weapon/mop/cyborg(src)
modules += new /obj/item/device/lightreplacer/cyborg(src)
modules += new /obj/item/weapon/holosign_creator(src)
drying_agent = new(src)
drying_agent.reagents.add_reagent("drying_agent", 250)
drying_agent.name = "drying agent spray"
drying_agent.color = "#A000A0"
modules += drying_agent
emag = new /obj/item/weapon/reagent_containers/spray(src)
/obj/item/weapon/reagent_containers/spray/cyborg_lube
name = "lube spray"
list_reagents = list("lube" = 250)
emag.reagents.add_reagent("lube", 250)
emag.name = "lube spray"
fix_modules()
/obj/item/weapon/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in get_usable_modules()
if(LR)
for(var/i in 1 to coeff)
for(var/i = 1, i <= coeff, i++)
LR.Charge(R)
var/obj/item/weapon/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/weapon/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
drying_agent.reagents.add_reagent("drying_agent", 5 * coeff)
if(R.emagged && istype(emag, /obj/item/weapon/reagent_containers/spray))
emag.reagents.add_reagent("lube", 2 * coeff)
var/obj/item/weapon/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/weapon/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/weapon/robot_module/butler
name = "Service"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass, /obj/item/weapon/reagent_containers/food/condiment/enzyme, \
/obj/item/weapon/pen, /obj/item/toy/crayon/spraycan/borg, /obj/item/weapon/hand_labeler/borg, /obj/item/weapon/razor, \
/obj/item/device/instrument/violin, /obj/item/device/instrument/guitar, /obj/item/weapon/rsf/cyborg, /obj/item/weapon/reagent_containers/dropper, \
/obj/item/weapon/lighter, /obj/item/weapon/storage/bag/tray, /obj/item/weapon/reagent_containers/borghypo/borgshaker, /obj/item/borg/lollipop)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service, /obj/item/borg/sight/xray/truesight_lens)
moduleselect_icon = "service"
special_light_key = "service"
feedback_key = "cyborg_service"
hat_offset = 0
name = "service robot module"
/obj/item/weapon/robot_module/butler/New()
..()
modules += new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass(src)
modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
modules += new /obj/item/weapon/pen(src)
modules += new /obj/item/toy/crayon/spraycan/borg(src)
modules += new /obj/item/weapon/hand_labeler/borg(src)
modules += new /obj/item/weapon/razor(src)
modules += new /obj/item/device/instrument/violin(src)
modules += new /obj/item/device/instrument/guitar(src)
modules += new /obj/item/weapon/rsf{matter = 30}(src)
modules += new /obj/item/weapon/reagent_containers/dropper(src)
modules += new /obj/item/weapon/lighter{lit = 1}(src)
modules += new /obj/item/weapon/storage/bag/tray(src)
modules += new /obj/item/weapon/reagent_containers/borghypo/borgshaker(src)
emag = new /obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked(src)
fix_modules()
/obj/item/weapon/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/weapon/reagent_containers/O = locate(/obj/item/weapon/reagent_containers/food/condiment/enzyme) in basic_modules
var/obj/item/weapon/reagent_containers/O = locate(/obj/item/weapon/reagent_containers/food/condiment/enzyme) in get_usable_modules()
if(O)
O.reagents.add_reagent("enzyme", 2 * coeff)
/obj/item/weapon/robot_module/butler/be_transformed_to(obj/item/weapon/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Waitress", "Butler", "Tophat", "Kent", "Bro")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Waitress")
cyborg_base_icon = "service_f"
if("Butler")
cyborg_base_icon = "service_m"
if("Bro")
cyborg_base_icon = "brobot"
if("Kent")
cyborg_base_icon = "kent"
special_light_key = "medical"
hat_offset = 3
if("Tophat")
cyborg_base_icon = "tophat"
special_light_key = null
hat_offset = INFINITY //He is already wearing a hat
return ..()
/obj/item/weapon/robot_module/miner
name = "Miner"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/borg/sight/meson, /obj/item/weapon/storage/bag/ore/cyborg, /obj/item/weapon/pickaxe/drill/cyborg, /obj/item/weapon/shovel, \
/obj/item/weapon/crowbar/cyborg, /obj/item/weapon/weldingtool/mini, /obj/item/weapon/extinguisher/mini, /obj/item/weapon/storage/bag/sheetsnatcher/borg, \
/obj/item/device/t_scanner/adv_mining_scanner, /obj/item/weapon/gun/energy/kinetic_accelerator/cyborg, /obj/item/device/gps/cyborg)
emag_modules = list(/obj/item/borg/stun)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/miner, /obj/item/borg/sight/xray/truesight_lens)
cyborg_base_icon = "miner"
moduleselect_icon = "miner"
feedback_key = "cyborg_miner"
hat_offset = 0
name = "miner robot module"
/obj/item/weapon/robot_module/miner/New()
..()
modules += new /obj/item/borg/sight/meson(src)
emag = new /obj/item/borg/stun(src)
modules += new /obj/item/weapon/storage/bag/ore/cyborg(src)
modules += new /obj/item/weapon/pickaxe/drill/cyborg(src)
modules += new /obj/item/weapon/shovel(src)
modules += new /obj/item/weapon/weldingtool/mini(src)
modules += new /obj/item/weapon/extinguisher/mini(src)
modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src)
modules += new /obj/item/device/t_scanner/adv_mining_scanner(src)
modules += new /obj/item/weapon/gun/energy/kinetic_accelerator/cyborg(src)
modules += new /obj/item/device/gps/cyborg(src)
fix_modules()
/obj/item/weapon/robot_module/syndicate
name = "Syndicate Assault"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/melee/energy/sword/cyborg, /obj/item/weapon/gun/energy/printer, \
/obj/item/weapon/gun/ballistic/revolver/grenadelauncher/cyborg, /obj/item/weapon/card/emag, /obj/item/weapon/crowbar/cyborg, \
/obj/item/weapon/pinpointer/syndicate/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security, /obj/item/clockwork/ratvarian_spear)
cyborg_base_icon = "synd_sec"
moduleselect_icon = "malf"
can_be_pushed = FALSE
hat_offset = 3
name = "syndicate assault robot module"
/obj/item/weapon/robot_module/syndicate/New()
..()
modules += new /obj/item/weapon/melee/energy/sword/cyborg(src)
modules += new /obj/item/weapon/gun/energy/printer(src)
modules += new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/cyborg(src)
modules += new /obj/item/weapon/card/emag(src)
modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
fix_modules()
/obj/item/weapon/robot_module/syndicate_medical
name = "Syndicate Medical"
basic_modules = list(/obj/item/device/assembly/flash/cyborg, /obj/item/weapon/reagent_containers/borghypo/syndicate, /obj/item/weapon/twohanded/shockpaddles/syndicate, \
/obj/item/device/healthanalyzer, /obj/item/weapon/surgical_drapes, /obj/item/weapon/retractor, /obj/item/weapon/hemostat, \
/obj/item/weapon/cautery, /obj/item/weapon/scalpel, /obj/item/weapon/melee/energy/sword/cyborg/saw, /obj/item/roller/robo, \
/obj/item/weapon/card/emag, /obj/item/weapon/crowbar/cyborg, /obj/item/weapon/pinpointer/syndicate/cyborg, /obj/item/stack/medical/gauze/cyborg, /obj/item/weapon/gun/medbeam)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical, /obj/item/clockwork/ratvarian_spear)
cyborg_base_icon = "synd_medical"
moduleselect_icon = "malf"
can_be_pushed = FALSE
hat_offset = 3
name = "syndicate medical robot module"
/obj/item/weapon/robot_module/syndicate_medical/New()
..()
modules += new /obj/item/weapon/reagent_containers/borghypo/syndicate(src)
modules += new /obj/item/weapon/twohanded/shockpaddles/syndicate(src)
modules += new /obj/item/device/healthanalyzer(src)
modules += new /obj/item/weapon/surgical_drapes(src)
modules += new /obj/item/weapon/retractor(src)
modules += new /obj/item/weapon/hemostat(src)
modules += new /obj/item/weapon/cautery(src)
modules += new /obj/item/weapon/scalpel(src)
modules += new /obj/item/weapon/melee/energy/sword/cyborg/saw(src) //Energy saw -- primary weapon
modules += new /obj/item/roller/robo(src)
modules += new /obj/item/weapon/card/emag(src)
modules += new /obj/item/weapon/crowbar/cyborg(src)
modules += new /obj/item/weapon/pinpointer/operative(src)
emag = null
add_module(new /obj/item/stack/medical/gauze/cyborg())
fix_modules()
/datum/robot_energy_storage
var/name = "Generic energy storage"
@@ -455,4 +401,4 @@
/datum/robot_energy_storage/medical
max_energy = 2500
recharge_rate = 250
name = "Medical Synthesizer"
name = "Medical Synthesizer"
+4 -4
View File
@@ -5,14 +5,14 @@
/mob/living/proc/robot_talk(message)
log_say("[key_name(src)] : [message]")
var/desig = "Default Cyborg" //ezmode for taters
if(issilicon(src))
if(istype(src, /mob/living/silicon))
var/mob/living/silicon/S = src
desig = trim_left(S.designation + " " + S.job)
var/message_a = say_quote(message, get_spans())
var/rendered = "<i><span class='game say'>Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
for(var/mob/M in player_list)
if(M.binarycheck())
if(isAI(M))
if(istype(M, /mob/living/silicon/ai))
var/renderedAI = "<i><span class='game say'>Robotic Talk, <a href='?src=\ref[M];track=[html_encode(name)]'><span class='name'>[name] ([desig])</span></a> <span class='message'>[message_a]</span></span></i>"
M << renderedAI
else
@@ -21,7 +21,7 @@
var/following = src
// If the AI talks on binary chat, we still want to follow
// it's camera eye, like if it talked on the radio
if(isAI(src))
if(istype(src, /mob/living/silicon/ai))
var/mob/living/silicon/ai/ai = src
following = ai.eyeobj
var/link = FOLLOW_LINK(M, following)
@@ -65,5 +65,5 @@
if(message_mode == MODE_BINARY)
if(binarycheck())
robot_talk(message)
return 1
return 1
return 0
+143 -31
View File
@@ -29,7 +29,6 @@
var/lawcheck[1]
var/ioncheck[1]
var/devillawcheck[5]
var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use
var/sec_hud = DATA_HUD_SECURITY_ADVANCED //Determines the sec hud to use
@@ -39,7 +38,7 @@
/mob/living/silicon/New()
..()
silicon_mobs += src
silicon_mobs |= src
var/datum/atom_hud/data/diagnostic/diag_hud = huds[DATA_HUD_DIAGNOSTIC]
diag_hud.add_to_hud(src)
diag_hud_set_status()
@@ -142,6 +141,34 @@
/mob/living/silicon/drop_item()
return
/mob/living/silicon/emp_act(severity)
switch(severity)
if(1)
src.take_organ_damage(20)
if(2)
src.take_organ_damage(10)
src << "<span class='userdanger'>*BZZZT*</span>"
src << "<span class='danger'>Warning: Electromagnetic pulse detected.</span>"
flash_eyes(affect_silicon = 1)
..()
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
blocked = (100-blocked)/100
if(!damage || (blocked <= 0))
return 0
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * blocked)
if(BURN)
adjustFireLoss(damage * blocked)
else
return 1
updatehealth()
return 1
/mob/living/silicon/proc/damage_mob(brute = 0, fire = 0, tox = 0)
return
/mob/living/silicon/can_inject(mob/user, error_msg)
if(error_msg)
user << "<span class='alert'>Their outer shell is too tough.</span>"
@@ -150,6 +177,35 @@
/mob/living/silicon/IsAdvancedToolUser()
return 1
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
adjustBruteLoss(Proj.damage)
Proj.on_hit(src)
return 2
/mob/living/silicon/apply_effect(effect = 0,effecttype = STUN, blocked = 0)
return 0//The only effect that can hit them atm is flashes and they still directly edit so this works for now
/*
if(!effect || (blocked >= 2))
return 0
switch(effecttype)
if(STUN)
stunned = max(stunned,(effect/(blocked+1)))
if(WEAKEN)
weakened = max(weakened,(effect/(blocked+1)))
if(PARALYZE)
paralysis = max(paralysis,(effect/(blocked+1)))
if(IRRADIATE)
radiation += min((effect - (effect*getarmor(null, "rad"))), 0)//Rads auto check armor
if(STUTTER)
stuttering = max(stuttering,(effect/(blocked+1)))
if(EYE_BLUR)
blur_eyes(effect/(blocked+1))
if(DROWSY)
drowsyness = max(drowsyness,(effect/(blocked+1)))
updatehealth()
return 1*/
/proc/islinked(mob/living/silicon/robot/bot, mob/living/silicon/ai/ai)
if(!istype(bot) || !istype(ai))
return 0
@@ -161,31 +217,19 @@
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawc"])
switch(lawcheck[L+1])
if ("Yes")
lawcheck[L+1] = "No"
if ("No")
lawcheck[L+1] = "Yes"
if ("Yes") lawcheck[L+1] = "No"
if ("No") lawcheck[L+1] = "Yes"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawi"])
switch(ioncheck[L])
if ("Yes")
ioncheck[L] = "No"
if ("No")
ioncheck[L] = "Yes"
if ("Yes") ioncheck[L] = "No"
if ("No") ioncheck[L] = "Yes"
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
if (href_list["lawdevil"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawdevil"])
switch(devillawcheck[L])
if ("Yes")
devillawcheck[L] = "No"
if ("No")
devillawcheck[L] = "Yes"
checklaws()
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
statelaws()
@@ -201,11 +245,6 @@
var/number = 1
sleep(10)
if (src.laws.devillaws && src.laws.devillaws.len)
for(var/index = 1, index <= src.laws.devillaws.len, index++)
if (src.devillawcheck[index] == "Yes")
src.say("[radiomod] 666. [src.laws.devillaws[index]]")
sleep(10)
if (src.laws.zeroth)
@@ -246,12 +285,6 @@
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (src.laws.devillaws && src.laws.devillaws.len)
for(var/index = 1, index <= src.laws.devillaws.len, index++)
if (!src.devillawcheck[index])
src.devillawcheck[index] = "No"
list += {"<A href='byond://?src=\ref[src];lawdevil=[index]'>[src.devillawcheck[index]] 666:</A> [src.laws.devillaws[index]]<BR>"}
if (src.laws.zeroth)
if (!src.lawcheck[1])
src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
@@ -364,10 +397,89 @@
src << "Sensor augmentations disabled."
/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent
var/damage = 20
if (prob(90))
add_logs(M, src, "attacked")
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
if(prob(8))
flash_eyes(affect_silicon = 1)
add_logs(M, src, "attacked")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>", \
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
return
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/silicon/attack_paw(mob/living/user)
return attack_hand(user)
/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L)
if(L.a_intent == "help")
visible_message("[L.name] rubs its head against [src].")
return
/mob/living/silicon/attack_hulk(mob/living/carbon/human/user)
if(user.a_intent == "harm")
..(user, 1)
adjustBruteLoss(rand(10, 15))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>")
return 1
return 0
/mob/living/silicon/attack_hand(mob/living/carbon/human/M)
switch(M.a_intent)
if ("help")
M.visible_message("[M] pets [src].", \
"<span class='notice'>You pet [src].</span>")
if("grab")
grabbedby(M)
else
M.do_attack_animation(src)
playsound(src.loc, 'sound/effects/bang.ogg', 10, 1)
visible_message("<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>", \
"<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>")
return 0
/mob/living/silicon/proc/GetPhoto()
if (aicamera)
return aicamera.selectpicture(aicamera)
/mob/living/silicon/grippedby(mob/living/user)
return
/mob/living/silicon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/noise)
if(affect_silicon)
return ..()
/mob/living/silicon/check_ear_prot()
return 1
/mob/living/silicon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = 0
@@ -1,97 +0,0 @@
/mob/living/silicon/grippedby(mob/living/user)
return //can't upgrade a simple pull into a more aggressive grab.
/mob/living/silicon/get_ear_protection()//no ears
return 2
/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent
var/damage = 20
if (prob(90))
add_logs(M, src, "attacked")
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
if(prob(8))
flash_act(affect_silicon = 1)
add_logs(M, src, "attacked")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>", \
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/silicon/attack_paw(mob/living/user)
return attack_hand(user)
/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L)
if(L.a_intent == INTENT_HELP)
visible_message("[L.name] rubs its head against [src].")
/mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
..(user, 1)
adjustBruteLoss(rand(10, 15))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>")
return 1
return 0
/mob/living/silicon/attack_hand(mob/living/carbon/human/M)
switch(M.a_intent)
if ("help")
M.visible_message("[M] pets [src].", \
"<span class='notice'>You pet [src].</span>")
if("grab")
grabbedby(M)
else
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(src.loc, 'sound/effects/bang.ogg', 10, 1)
visible_message("<span class='danger'>[M] punches [src], but doesn't leave a dent.</span>", \
"<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0)
return 0 //So borgs they don't die trying to fix wiring
/mob/living/silicon/emp_act(severity)
switch(severity)
if(1)
src.take_bodypart_damage(20)
if(2)
src.take_bodypart_damage(10)
src << "<span class='userdanger'>*BZZZT*</span>"
src << "<span class='danger'>Warning: Electromagnetic pulse detected.</span>"
flash_act(affect_silicon = 1)
..()
/mob/living/silicon/bullet_act(obj/item/projectile/Proj)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
adjustBruteLoss(Proj.damage)
Proj.on_hit(src)
return 2
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/static)
if(affect_silicon)
return ..()