Files
CHOMPStation2/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_manipulation.dm
CHOMPStation2 ab154b48b2 [MIRROR] refactors most spans (#9139)
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com>
Co-authored-by: Kashargul <KashL@t-online.de>
2024-10-04 15:00:17 +02:00

209 lines
8.3 KiB
Plaintext

// MANIPULATION TREE
//
// Abilities in this tree allow the AI to physically manipulate systems around the station.
// T1 - Electrical Pulse - Sends out pulse that breaks some lights and sometimes even APCs. This can actually break the AI's APC so be careful!
// T2 - Hack Camera - Allows the AI to hack a camera. Deactivated areas may be reactivated, and functional cameras can be upgraded.
// T3 - Emergency Forcefield - Allows the AI to project 1 tile forcefield that blocks movement and air flow. Forcefield dissipates over time. It is also very susceptible to energetic weaponry.
// T4 - Machine Overload - Detonates machine of choice in a minor explosion. Two of these are usually enough to kill or K/O someone.
// BEGIN RESEARCH DATUMS
/datum/malf_research_ability/manipulation/electrical_pulse
ability = new/datum/game_mode/malfunction/verb/electrical_pulse()
price = 50
next = new/datum/malf_research_ability/manipulation/hack_camera()
name = "Electrical Pulse"
/datum/malf_research_ability/manipulation/hack_camera
ability = new/datum/game_mode/malfunction/verb/hack_camera()
price = 1200
next = new/datum/malf_research_ability/manipulation/emergency_forcefield()
name = "Hack Camera"
/datum/malf_research_ability/manipulation/emergency_forcefield
ability = new/datum/game_mode/malfunction/verb/emergency_forcefield()
price = 3000
next = new/datum/malf_research_ability/manipulation/machine_overload()
name = "Emergency Forcefield"
/datum/malf_research_ability/manipulation/machine_overload
ability = new/datum/game_mode/malfunction/verb/machine_overload()
price = 7500
name = "Machine Overload"
// END RESEARCH DATUMS
// BEGIN ABILITY VERBS
/datum/game_mode/malfunction/verb/electrical_pulse()
set name = "Electrical Pulse"
set desc = "15 CPU - Sends feedback pulse through station's power grid, overloading some sensitive systems, such as lights."
set category = "Software"
var/price = 15
var/mob/living/silicon/ai/user = usr
if(!ability_prechecks(user, price) || !ability_pay(user,price))
return
to_chat(user, "Sending feedback pulse...")
for(var/obj/machinery/power/apc/AP in GLOB.apcs)
if(prob(5))
AP.overload_lighting()
if(prob(1) && prob(1)) // Very very small chance to actually destroy the APC.
AP.set_broken()
/datum/game_mode/malfunction/verb/hack_camera(var/obj/machinery/camera/target in cameranet.cameras)
set name = "Hack Camera"
set desc = "100 CPU - Hacks existing camera, allowing you to add upgrade of your choice to it. Alternatively it lets you reactivate broken camera."
set category = "Software"
var/price = 100
var/mob/living/silicon/ai/user = usr
if(target && !istype(target))
to_chat(user, "This is not a camera.")
return
if(!target)
return
if(!ability_prechecks(user, price))
return
var/action = tgui_input_list(user, "Select required action:", "Hack Camera", list("Reset", "Add X-Ray", "Add Motion Sensor", "Add EMP Shielding"))
if(!action || !target)
return
switch(action)
if("Reset")
if(target.wires)
if(!ability_pay(user, price))
return
target.reset_wires()
to_chat(user, "Camera reactivated.")
if("Add X-Ray")
if(target.isXRay())
to_chat(user, "Camera already has X-Ray function.")
return
else if(ability_pay(user, price))
target.upgradeXRay()
target.reset_wires()
to_chat(user, "X-Ray camera module enabled.")
return
if("Add Motion Sensor")
if(target.isMotion())
to_chat(user, "Camera already has Motion Sensor function.")
return
else if(ability_pay(user, price))
target.upgradeMotion()
target.reset_wires()
to_chat(user, "Motion Sensor camera module enabled.")
return
if("Add EMP Shielding")
if(target.isEmpProof())
to_chat(user, "Camera already has EMP Shielding function.")
return
else if(ability_pay(user, price))
target.upgradeEmpProof()
target.reset_wires()
to_chat(user, "EMP Shielding camera module enabled.")
return
/datum/game_mode/malfunction/verb/emergency_forcefield(var/turf/T as turf in world)
set name = "Emergency Forcefield"
set desc = "275 CPU - Uses station's emergency shielding system to create temporary barrier which lasts for few minutes, but won't resist gunfire."
set category = "Software"
var/price = 275
var/mob/living/silicon/ai/user = usr
if(!T || !istype(T))
return
if(!ability_prechecks(user, price) || !ability_pay(user, price))
return
to_chat(user, "Emergency forcefield projection completed.")
new/obj/machinery/shield/malfai(T)
user.hacking = 1
spawn(20)
user.hacking = 0
/datum/game_mode/malfunction/verb/machine_overload(obj/machinery/M in machines)
set name = "Machine Overload"
set desc = "400 CPU - Causes cyclic short-circuit in machine, resulting in weak explosion after some time."
set category = "Software"
var/price = 400
var/mob/living/silicon/ai/user = usr
if(!ability_prechecks(user, price))
return
var/obj/machinery/power/N = M
var/explosion_intensity = 2
// Verify if we can overload the target, if yes, calculate explosion strength. Some things have higher explosion strength than others, depending on charge(APCs, SMESs)
if(N && istype(N)) // /obj/machinery/power first, these create bigger explosions due to direct powernet connection
if(!istype(N, /obj/machinery/power/apc) && !istype(N, /obj/machinery/power/smes/buildable) && (!N.powernet || !N.powernet.avail)) // Directly connected machine which is not an APC or SMES. Either it has no powernet connection or it's powernet does not have enough power to overload
to_chat(user, span_notice("ERROR: Low network voltage. Unable to overload. Increase network power level and try again."))
return
else if (istype(N, /obj/machinery/power/apc)) // APC. Explosion is increased by available cell power.
var/obj/machinery/power/apc/A = N
if(A.cell && A.cell.charge)
explosion_intensity = 4 + round(A.cell.charge / 2000) // Explosion is increased by 1 for every 2k charge in cell
else
to_chat(user, span_notice("ERROR: APC Malfunction - Cell depleted or removed. Unable to overload."))
return
else if (istype(N, /obj/machinery/power/smes/buildable)) // SMES. These explode in a very very very big boom. Similar to magnetic containment failure when messing with coils.
var/obj/machinery/power/smes/buildable/S = N
if(S.charge && S.RCon)
explosion_intensity = 4 + round(S.charge / 1000000)
else
// Different error texts
if(!S.charge)
to_chat(user, span_notice("ERROR: SMES Depleted. Unable to overload. Please charge SMES unit and try again."))
else
to_chat(user, span_notice("ERROR: SMES RCon error - Unable to reach destination. Please verify wire connection."))
return
else if(M && istype(M)) // Not power machinery, so it's a regular machine instead. These have weak explosions.
if(!M.use_power) // Not using power at all
to_chat(user, span_notice("ERROR: No power grid connection. Unable to overload."))
return
if(M.inoperable()) // Not functional
to_chat(user, span_notice("ERROR: Unknown error. Machine is probably damaged or power supply is nonfunctional."))
return
else // Not a machine at all (what the hell is this doing in Machines list anyway??)
to_chat(user, span_notice("ERROR: Unable to overload - target is not a machine."))
return
explosion_intensity = min(explosion_intensity, 12) // 3, 6, 12 explosion cap
M.use_power(2000000) // Major power spike, few of these will completely burn APC's cell - equivalent of 2GJ of power.
// Trigger a powernet alarm. Careful engineers will probably notice something is going on.
var/area/temp_area = get_area(M)
if(temp_area)
var/obj/machinery/power/apc/temp_apc = temp_area.get_apc()
if(temp_apc && temp_apc.terminal && temp_apc.terminal.powernet)
temp_apc.terminal.powernet.trigger_warning(50) // Long alarm
if(temp_apc)
temp_apc.emp_act(3) // Such power surges are not good for APC electronics
if(temp_apc.cell)
temp_apc.cell.maxcharge -= between(0, (temp_apc.cell.maxcharge/2) + 500, temp_apc.cell.maxcharge)
if(temp_apc.cell.maxcharge < 100) // That's it, you busted the APC cell completely. Break the APC and completely destroy the cell.
qdel(temp_apc.cell)
temp_apc.set_broken()
if(!ability_pay(user,price))
return
M.visible_message(span_notice("BZZZZZZZT"))
spawn(50)
explosion(get_turf(M), round(explosion_intensity/4),round(explosion_intensity/2),round(explosion_intensity),round(explosion_intensity * 2))
if(M)
qdel(M)
// END ABILITY VERBS