mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Force LF line endings with gitattributes and convert repo (#52266)
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
This commit is contained in:
co-authored by
Aleksej Komarov
parent
39e8bd721f
commit
62676e72a8
@@ -1,207 +1,207 @@
|
||||
// stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
|
||||
#define RAD_COLLECTOR_COEFFICIENT 100
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
|
||||
#define RAD_COLLECTOR_OUTPUT min(stored_energy, (stored_energy*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
|
||||
/obj/machinery/power/rad_collector
|
||||
name = "Radiation Collector Array"
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "ca"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
max_integrity = 350
|
||||
integrity_failure = 0.2
|
||||
circuit = /obj/item/circuitboard/machine/rad_collector
|
||||
rad_insulation = RAD_EXTREME_INSULATION
|
||||
var/obj/item/tank/internals/plasma/loaded_tank = null
|
||||
var/stored_energy = 0
|
||||
var/active = 0
|
||||
var/locked = FALSE
|
||||
var/drainratio = 1
|
||||
var/powerproduction_drain = 0.001
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored/delta //Deltastation's engine is shared by engineers and atmos techs
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power. This model allows access by Atmospheric Technicians."
|
||||
req_access = list(ACCESS_ENGINE_EQUIP, ACCESS_ATMOSPHERICS)
|
||||
|
||||
/obj/machinery/power/rad_collector/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/should_have_node()
|
||||
return anchored
|
||||
|
||||
/obj/machinery/power/rad_collector/process()
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES])
|
||||
loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= gasdrained
|
||||
loaded_tank.air_contents.assert_gas(/datum/gas/tritium)
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += gasdrained
|
||||
loaded_tank.air_contents.garbage_collect()
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_energy-=power_produced
|
||||
|
||||
/obj/machinery/power/rad_collector/interact(mob/user)
|
||||
if(anchored)
|
||||
if(!src.locked)
|
||||
toggle_power()
|
||||
user.visible_message("<span class='notice'>[user.name] turns the [src.name] [active? "on":"off"].</span>", \
|
||||
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
|
||||
var/fuel
|
||||
if(loaded_tank)
|
||||
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
|
||||
fuel = fuel ? fuel[MOLES] : 0
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(loaded_tank)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank/internals/plasma))
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first!</span>")
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>There's already a plasma tank loaded!</span>")
|
||||
return TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first!</span>")
|
||||
return TRUE
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
loaded_tank = W
|
||||
update_icon()
|
||||
else if(W.GetID())
|
||||
if(allowed(user))
|
||||
if(active)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the controls.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when \the [src] is active!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/wrench_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
else
|
||||
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return TRUE
|
||||
eject()
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>There isn't a tank loaded!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/return_analyzable_air()
|
||||
if(loaded_tank)
|
||||
return loaded_tank.return_analyzable_air()
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/power/rad_collector/examine(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
// stored_energy is converted directly to watts every SSmachines.wait * 0.1 seconds.
|
||||
// Therefore, its units are joules per SSmachines.wait * 0.1 seconds.
|
||||
// So joules = stored_energy * SSmachines.wait * 0.1
|
||||
var/joules = stored_energy * SSmachines.wait * 0.1
|
||||
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayJoules(joules)]</b>, and is processing <b>[DisplayPower(RAD_COLLECTOR_OUTPUT)]</b>.</span>"
|
||||
else
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>.\"</span>"
|
||||
|
||||
/obj/machinery/power/rad_collector/obj_break(damage_flag)
|
||||
. = ..()
|
||||
if(.)
|
||||
eject()
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/eject()
|
||||
locked = FALSE
|
||||
var/obj/item/tank/internals/plasma/Z = src.loaded_tank
|
||||
if (!Z)
|
||||
return
|
||||
Z.forceMove(drop_location())
|
||||
Z.layer = initial(Z.layer)
|
||||
Z.plane = initial(Z.plane)
|
||||
src.loaded_tank = null
|
||||
if(active)
|
||||
toggle_power()
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/rad_collector/rad_act(pulse_strength)
|
||||
. = ..()
|
||||
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
|
||||
stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
|
||||
/obj/machinery/power/rad_collector/update_overlays()
|
||||
. = ..()
|
||||
if(loaded_tank)
|
||||
. += "ptank"
|
||||
if(machine_stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
. += "on"
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/toggle_power()
|
||||
active = !active
|
||||
if(active)
|
||||
icon_state = "ca_on"
|
||||
flick("ca_active", src)
|
||||
else
|
||||
icon_state = "ca"
|
||||
flick("ca_deactive", src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
#undef RAD_COLLECTOR_EFFICIENCY
|
||||
#undef RAD_COLLECTOR_COEFFICIENT
|
||||
#undef RAD_COLLECTOR_STORED_OUT
|
||||
#undef RAD_COLLECTOR_MINING_CONVERSION_RATE
|
||||
#undef RAD_COLLECTOR_OUTPUT
|
||||
// stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
|
||||
#define RAD_COLLECTOR_COEFFICIENT 100
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
|
||||
#define RAD_COLLECTOR_OUTPUT min(stored_energy, (stored_energy*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
|
||||
/obj/machinery/power/rad_collector
|
||||
name = "Radiation Collector Array"
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "ca"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
max_integrity = 350
|
||||
integrity_failure = 0.2
|
||||
circuit = /obj/item/circuitboard/machine/rad_collector
|
||||
rad_insulation = RAD_EXTREME_INSULATION
|
||||
var/obj/item/tank/internals/plasma/loaded_tank = null
|
||||
var/stored_energy = 0
|
||||
var/active = 0
|
||||
var/locked = FALSE
|
||||
var/drainratio = 1
|
||||
var/powerproduction_drain = 0.001
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/anchored/delta //Deltastation's engine is shared by engineers and atmos techs
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power. This model allows access by Atmospheric Technicians."
|
||||
req_access = list(ACCESS_ENGINE_EQUIP, ACCESS_ATMOSPHERICS)
|
||||
|
||||
/obj/machinery/power/rad_collector/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/should_have_node()
|
||||
return anchored
|
||||
|
||||
/obj/machinery/power/rad_collector/process()
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
|
||||
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES])
|
||||
loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= gasdrained
|
||||
loaded_tank.air_contents.assert_gas(/datum/gas/tritium)
|
||||
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += gasdrained
|
||||
loaded_tank.air_contents.garbage_collect()
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_energy-=power_produced
|
||||
|
||||
/obj/machinery/power/rad_collector/interact(mob/user)
|
||||
if(anchored)
|
||||
if(!src.locked)
|
||||
toggle_power()
|
||||
user.visible_message("<span class='notice'>[user.name] turns the [src.name] [active? "on":"off"].</span>", \
|
||||
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
|
||||
var/fuel
|
||||
if(loaded_tank)
|
||||
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
|
||||
fuel = fuel ? fuel[MOLES] : 0
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/power/rad_collector/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(loaded_tank)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/default_unfasten_wrench(mob/user, obj/item/I, time = 20)
|
||||
. = ..()
|
||||
if(. == SUCCESSFUL_UNFASTEN)
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank/internals/plasma))
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first!</span>")
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>There's already a plasma tank loaded!</span>")
|
||||
return TRUE
|
||||
if(panel_open)
|
||||
to_chat(user, "<span class='warning'>Close the maintenance panel first!</span>")
|
||||
return TRUE
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
loaded_tank = W
|
||||
update_icon()
|
||||
else if(W.GetID())
|
||||
if(allowed(user))
|
||||
if(active)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the controls.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when \the [src] is active!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/wrench_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>Remove the plasma tank first!</span>")
|
||||
else
|
||||
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(loaded_tank)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return TRUE
|
||||
eject()
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>There isn't a tank loaded!</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/rad_collector/return_analyzable_air()
|
||||
if(loaded_tank)
|
||||
return loaded_tank.return_analyzable_air()
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/power/rad_collector/examine(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
// stored_energy is converted directly to watts every SSmachines.wait * 0.1 seconds.
|
||||
// Therefore, its units are joules per SSmachines.wait * 0.1 seconds.
|
||||
// So joules = stored_energy * SSmachines.wait * 0.1
|
||||
var/joules = stored_energy * SSmachines.wait * 0.1
|
||||
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayJoules(joules)]</b>, and is processing <b>[DisplayPower(RAD_COLLECTOR_OUTPUT)]</b>.</span>"
|
||||
else
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>.\"</span>"
|
||||
|
||||
/obj/machinery/power/rad_collector/obj_break(damage_flag)
|
||||
. = ..()
|
||||
if(.)
|
||||
eject()
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/eject()
|
||||
locked = FALSE
|
||||
var/obj/item/tank/internals/plasma/Z = src.loaded_tank
|
||||
if (!Z)
|
||||
return
|
||||
Z.forceMove(drop_location())
|
||||
Z.layer = initial(Z.layer)
|
||||
Z.plane = initial(Z.plane)
|
||||
src.loaded_tank = null
|
||||
if(active)
|
||||
toggle_power()
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/rad_collector/rad_act(pulse_strength)
|
||||
. = ..()
|
||||
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
|
||||
stored_energy += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
|
||||
/obj/machinery/power/rad_collector/update_overlays()
|
||||
. = ..()
|
||||
if(loaded_tank)
|
||||
. += "ptank"
|
||||
if(machine_stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
. += "on"
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/toggle_power()
|
||||
active = !active
|
||||
if(active)
|
||||
icon_state = "ca_on"
|
||||
flick("ca_active", src)
|
||||
else
|
||||
icon_state = "ca"
|
||||
flick("ca_deactive", src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
#undef RAD_COLLECTOR_EFFICIENCY
|
||||
#undef RAD_COLLECTOR_COEFFICIENT
|
||||
#undef RAD_COLLECTOR_STORED_OUT
|
||||
#undef RAD_COLLECTOR_MINING_CONVERSION_RATE
|
||||
#undef RAD_COLLECTOR_OUTPUT
|
||||
|
||||
@@ -1,143 +1,143 @@
|
||||
|
||||
|
||||
/obj/machinery/field/containment
|
||||
name = "containment field"
|
||||
desc = "An energy field."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "Contain_F"
|
||||
density = FALSE
|
||||
move_resist = INFINITY
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
use_power = NO_POWER_USE
|
||||
interaction_flags_atom = NONE
|
||||
interaction_flags_machine = NONE
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
light_range = 4
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
var/obj/machinery/field/generator/FG1 = null
|
||||
var/obj/machinery/field/generator/FG2 = null
|
||||
|
||||
/obj/machinery/field/containment/Initialize()
|
||||
. = ..()
|
||||
air_update_turf(TRUE)
|
||||
|
||||
/obj/machinery/field/containment/Destroy()
|
||||
FG1.fields -= src
|
||||
FG2.fields -= src
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/machinery/field/containment/attack_hand(mob/user)
|
||||
if(get_dist(src, user) > 1)
|
||||
return FALSE
|
||||
else
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/attackby(obj/item/W, mob/user, params)
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, TRUE)
|
||||
if(BRUTE)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, TRUE)
|
||||
|
||||
/obj/machinery/field/containment/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/attack_animal(mob/living/simple_animal/M)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
M.visible_message("<span class='warning'>[M] glows fiercely as the containment field flickers out!</span>")
|
||||
FG1.calc_power(INFINITY) //rip that 'containment' field
|
||||
M.adjustHealth(-M.obj_damage)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/containment/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
shock(AM)
|
||||
|
||||
if(ismachinery(AM) || isstructure(AM) || ismecha(AM))
|
||||
bump_field(AM)
|
||||
|
||||
/obj/machinery/field/containment/proc/set_master(master1,master2)
|
||||
if(!master1 || !master2)
|
||||
return FALSE
|
||||
FG1 = master1
|
||||
FG2 = master2
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/shock(mob/living/user)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Move()
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
|
||||
// Abstract Field Class
|
||||
// Used for overriding certain procs
|
||||
|
||||
/obj/machinery/field
|
||||
var/hasShocked = FALSE //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
|
||||
|
||||
/obj/machinery/field/Bumped(atom/movable/mover)
|
||||
if(hasShocked)
|
||||
return
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
return
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/field/CanAllowThrough(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/proc/shock(mob/living/user)
|
||||
var/shock_damage = min(rand(30,40),rand(30,40))
|
||||
|
||||
if(iscarbon(user))
|
||||
user.Paralyze(300)
|
||||
user.electrocute_act(shock_damage, src, 1)
|
||||
|
||||
else if(issilicon(user))
|
||||
if(prob(20))
|
||||
user.Stun(40)
|
||||
user.take_overall_damage(0, shock_damage)
|
||||
user.visible_message("<span class='danger'>[user.name] is shocked by the [src.name]!</span>", \
|
||||
"<span class='userdanger'>Energy pulse detected, system damaged!</span>", \
|
||||
"<span class='hear'>You hear an electrical crack.</span>")
|
||||
|
||||
user.updatehealth()
|
||||
bump_field(user)
|
||||
|
||||
/obj/machinery/field/proc/clear_shock()
|
||||
hasShocked = FALSE
|
||||
|
||||
/obj/machinery/field/proc/bump_field(atom/movable/AM as mob|obj)
|
||||
if(hasShocked)
|
||||
return FALSE
|
||||
hasShocked = TRUE
|
||||
do_sparks(5, TRUE, AM.loc)
|
||||
var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src)))
|
||||
AM.throw_at(target, 200, 4)
|
||||
addtimer(CALLBACK(src, .proc/clear_shock), 5)
|
||||
|
||||
|
||||
/obj/machinery/field/containment
|
||||
name = "containment field"
|
||||
desc = "An energy field."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "Contain_F"
|
||||
density = FALSE
|
||||
move_resist = INFINITY
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
use_power = NO_POWER_USE
|
||||
interaction_flags_atom = NONE
|
||||
interaction_flags_machine = NONE
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
light_range = 4
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
var/obj/machinery/field/generator/FG1 = null
|
||||
var/obj/machinery/field/generator/FG2 = null
|
||||
|
||||
/obj/machinery/field/containment/Initialize()
|
||||
. = ..()
|
||||
air_update_turf(TRUE)
|
||||
|
||||
/obj/machinery/field/containment/Destroy()
|
||||
FG1.fields -= src
|
||||
FG2.fields -= src
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/machinery/field/containment/attack_hand(mob/user)
|
||||
if(get_dist(src, user) > 1)
|
||||
return FALSE
|
||||
else
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/attackby(obj/item/W, mob/user, params)
|
||||
shock(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, TRUE)
|
||||
if(BRUTE)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 75, TRUE)
|
||||
|
||||
/obj/machinery/field/containment/blob_act(obj/structure/blob/B)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/ex_act(severity, target)
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/containment/attack_animal(mob/living/simple_animal/M)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return
|
||||
if(ismegafauna(M))
|
||||
M.visible_message("<span class='warning'>[M] glows fiercely as the containment field flickers out!</span>")
|
||||
FG1.calc_power(INFINITY) //rip that 'containment' field
|
||||
M.adjustHealth(-M.obj_damage)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/containment/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
shock(AM)
|
||||
|
||||
if(ismachinery(AM) || isstructure(AM) || ismecha(AM))
|
||||
bump_field(AM)
|
||||
|
||||
/obj/machinery/field/containment/proc/set_master(master1,master2)
|
||||
if(!master1 || !master2)
|
||||
return FALSE
|
||||
FG1 = master1
|
||||
FG2 = master2
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/containment/shock(mob/living/user)
|
||||
if(!FG1 || !FG2)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Move()
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
|
||||
// Abstract Field Class
|
||||
// Used for overriding certain procs
|
||||
|
||||
/obj/machinery/field
|
||||
var/hasShocked = FALSE //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
|
||||
|
||||
/obj/machinery/field/Bumped(atom/movable/mover)
|
||||
if(hasShocked)
|
||||
return
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
return
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/field/CanAllowThrough(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(hasShocked || isliving(mover) || ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/field/proc/shock(mob/living/user)
|
||||
var/shock_damage = min(rand(30,40),rand(30,40))
|
||||
|
||||
if(iscarbon(user))
|
||||
user.Paralyze(300)
|
||||
user.electrocute_act(shock_damage, src, 1)
|
||||
|
||||
else if(issilicon(user))
|
||||
if(prob(20))
|
||||
user.Stun(40)
|
||||
user.take_overall_damage(0, shock_damage)
|
||||
user.visible_message("<span class='danger'>[user.name] is shocked by the [src.name]!</span>", \
|
||||
"<span class='userdanger'>Energy pulse detected, system damaged!</span>", \
|
||||
"<span class='hear'>You hear an electrical crack.</span>")
|
||||
|
||||
user.updatehealth()
|
||||
bump_field(user)
|
||||
|
||||
/obj/machinery/field/proc/clear_shock()
|
||||
hasShocked = FALSE
|
||||
|
||||
/obj/machinery/field/proc/bump_field(atom/movable/AM as mob|obj)
|
||||
if(hasShocked)
|
||||
return FALSE
|
||||
hasShocked = TRUE
|
||||
do_sparks(5, TRUE, AM.loc)
|
||||
var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src)))
|
||||
AM.throw_at(target, 200, 4)
|
||||
addtimer(CALLBACK(src, .proc/clear_shock), 5)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,414 +1,414 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
field_generator power level display
|
||||
The icon used for the field_generator need to have 6 icon states
|
||||
named 'Field_Gen +p[num]' where 'num' ranges from 1 to 6
|
||||
|
||||
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
|
||||
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
|
||||
no power level overlay is currently in the overlays list.
|
||||
-Aygar
|
||||
*/
|
||||
|
||||
#define field_generator_max_power 250
|
||||
|
||||
#define FG_OFFLINE 0
|
||||
#define FG_CHARGING 1
|
||||
#define FG_ONLINE 2
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
/obj/machinery/field/generator
|
||||
name = "field generator"
|
||||
desc = "A large thermal battery that projects a high amount of energy when powered."
|
||||
icon = 'icons/obj/machines/field_generator.dmi'
|
||||
icon_state = "Field_Gen"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
max_integrity = 500
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
//100% immune to lasers and energy projectiles since it absorbs their energy.
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
var/power_level = 0
|
||||
var/active = FG_OFFLINE
|
||||
var/power = 20 // Current amount of power
|
||||
var/state = FG_UNSECURED
|
||||
var/warming_up = 0
|
||||
var/list/obj/machinery/field/containment/fields
|
||||
var/list/obj/machinery/field/generator/connected_gens
|
||||
var/clean_up = 0
|
||||
|
||||
/obj/machinery/field/generator/update_overlays()
|
||||
. = ..()
|
||||
if(warming_up)
|
||||
. += "+a[warming_up]"
|
||||
if(LAZYLEN(fields))
|
||||
. += "+on"
|
||||
if(power_level)
|
||||
. += "+p[power_level]"
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Initialize()
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
|
||||
/obj/machinery/field/generator/anchored/Initialize()
|
||||
. = ..()
|
||||
setAnchored(TRUE)
|
||||
|
||||
/obj/machinery/field/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/field/generator/process()
|
||||
if(active == FG_ONLINE)
|
||||
calc_power()
|
||||
|
||||
/obj/machinery/field/generator/interact(mob/user)
|
||||
if(state == FG_WELDED)
|
||||
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
|
||||
if(active >= FG_CHARGING)
|
||||
to_chat(user, "<span class='warning'>You are unable to turn off [src] once it is online!</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] turns on [src].</span>", \
|
||||
"<span class='notice'>You turn on [src].</span>", \
|
||||
"<span class='hear'>You hear heavy droning.</span>")
|
||||
turn_on()
|
||||
investigate_log("<font color='green'>activated</font> by [key_name(user)].", INVESTIGATE_SINGULO)
|
||||
|
||||
add_fingerprint(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be firmly secured to the floor first!</span>")
|
||||
|
||||
/obj/machinery/field/generator/setAnchored(anchorvalue)
|
||||
. = ..()
|
||||
if(active)
|
||||
turn_off()
|
||||
state = anchorvalue ? FG_SECURED : FG_UNSECURED
|
||||
|
||||
/obj/machinery/field/generator/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Turn \the [src] off first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
else if(state == FG_WELDED)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[src] is welded to the floor!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/generator/welder_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be off!</span>")
|
||||
return TRUE
|
||||
|
||||
switch(state)
|
||||
if(FG_UNSECURED)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be wrenched to the floor!</span>")
|
||||
|
||||
if(FG_SECURED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] starts to weld [src] to the floor.</span>", \
|
||||
"<span class='notice'>You start to weld \the [src] to the floor...</span>", \
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_SECURED)
|
||||
state = FG_WELDED
|
||||
to_chat(user, "<span class='notice'>You weld the field generator to the floor.</span>")
|
||||
|
||||
if(FG_WELDED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] starts to cut [src] free from the floor.</span>", \
|
||||
"<span class='notice'>You start to cut \the [src] free from the floor...</span>", \
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_WELDED)
|
||||
state = FG_SECURED
|
||||
to_chat(user, "<span class='notice'>You cut \the [src] free from the floor.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/attack_animal(mob/living/simple_animal/M)
|
||||
if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS && active == FG_OFFLINE && state != FG_UNSECURED)
|
||||
setAnchored(FALSE)
|
||||
M.visible_message("<span class='warning'>[M] rips [src] free from its moorings!</span>")
|
||||
else
|
||||
..()
|
||||
if(!anchored)
|
||||
step(src, get_dir(M, src))
|
||||
|
||||
/obj/machinery/field/generator/blob_act(obj/structure/blob/B)
|
||||
if(active)
|
||||
return 0
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bullet_act(obj/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power = min(power + Proj.damage, field_generator_max_power)
|
||||
check_power_level()
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Destroy()
|
||||
cleanup()
|
||||
return ..()
|
||||
|
||||
/*
|
||||
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
|
||||
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
|
||||
no power level overlay is currently in the overlays list.
|
||||
*/
|
||||
|
||||
/obj/machinery/field/generator/proc/check_power_level()
|
||||
var/new_level = round(6 * power / field_generator_max_power)
|
||||
if(new_level != power_level)
|
||||
power_level = new_level
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_off()
|
||||
active = FG_OFFLINE
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
INVOKE_ASYNC(src, .proc/cleanup)
|
||||
addtimer(CALLBACK(src, .proc/cool_down), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/cool_down()
|
||||
if(active || warming_up <= 0)
|
||||
return
|
||||
warming_up--
|
||||
update_icon()
|
||||
if(warming_up > 0)
|
||||
addtimer(CALLBACK(src, .proc/cool_down), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_on()
|
||||
active = FG_CHARGING
|
||||
addtimer(CALLBACK(src, .proc/warm_up), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/warm_up()
|
||||
if(!active)
|
||||
return
|
||||
warming_up++
|
||||
update_icon()
|
||||
if(warming_up >= 3)
|
||||
start_fields()
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/warm_up), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/calc_power(set_power_draw)
|
||||
var/power_draw = 2 + fields.len
|
||||
if(set_power_draw)
|
||||
power_draw = set_power_draw
|
||||
|
||||
if(draw_power(round(power_draw/2,1)))
|
||||
check_power_level()
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>The [name] shuts down!</span>", "<span class='hear'>You hear something shutting down.</span>")
|
||||
turn_off()
|
||||
investigate_log("ran out of power and <font color='red'>deactivated</font>", INVESTIGATE_SINGULO)
|
||||
power = 0
|
||||
check_power_level()
|
||||
return 0
|
||||
|
||||
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
|
||||
/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = FALSE, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
|
||||
if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
|
||||
return 0
|
||||
else
|
||||
failsafe++
|
||||
|
||||
if(power >= draw)//We have enough power
|
||||
power -= draw
|
||||
return 1
|
||||
|
||||
else//Need more power
|
||||
draw -= power
|
||||
power = 0
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
if(FG == last)//We just asked you
|
||||
continue
|
||||
if(G)//Another gen is askin for power and we dont have it
|
||||
if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else//We are askin another for power
|
||||
if(FG.draw_power(draw,failsafe,src,src))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/start_fields()
|
||||
if(state != FG_WELDED || !anchored)
|
||||
turn_off()
|
||||
return
|
||||
move_resist = INFINITY
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
air_update_turf(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 1), 1)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 2), 2)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 4), 3)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 8), 4)
|
||||
addtimer(VARSET_CALLBACK(src, active, FG_ONLINE), 5)
|
||||
|
||||
/obj/machinery/field/generator/proc/setup_field(NSEW)
|
||||
var/turf/T = loc
|
||||
if(!istype(T))
|
||||
return 0
|
||||
|
||||
var/obj/machinery/field/generator/G = null
|
||||
var/steps = 0
|
||||
if(!NSEW)//Make sure its ran right
|
||||
return 0
|
||||
for(var/dist in 0 to 7) // checks out to 8 tiles away for another generator
|
||||
T = get_step(T, NSEW)
|
||||
if(T.density)//We cant shoot a field though this
|
||||
return 0
|
||||
|
||||
G = locate(/obj/machinery/field/generator) in T
|
||||
if(G)
|
||||
steps -= 1
|
||||
if(!G.active)
|
||||
return 0
|
||||
break
|
||||
|
||||
for(var/TC in T.contents)
|
||||
var/atom/A = TC
|
||||
if(ismob(A))
|
||||
continue
|
||||
if(A.density)
|
||||
return 0
|
||||
|
||||
steps++
|
||||
|
||||
if(!G)
|
||||
return 0
|
||||
|
||||
T = loc
|
||||
for(var/dist in 0 to steps) // creates each field tile
|
||||
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
|
||||
T = get_step(T, NSEW)
|
||||
if(!locate(/obj/machinery/field/containment) in T)
|
||||
var/obj/machinery/field/containment/CF = new(T)
|
||||
CF.set_master(src,G)
|
||||
CF.setDir(field_dir)
|
||||
fields += CF
|
||||
G.fields += CF
|
||||
for(var/mob/living/L in T)
|
||||
CF.Crossed(L)
|
||||
|
||||
connected_gens |= G
|
||||
G.connected_gens |= src
|
||||
shield_floor(TRUE)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/cleanup()
|
||||
clean_up = 1
|
||||
for (var/F in fields)
|
||||
qdel(F)
|
||||
|
||||
shield_floor(FALSE)
|
||||
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
FG.connected_gens -= src
|
||||
if(!FG.clean_up)//Makes the other gens clean up as well
|
||||
FG.cleanup()
|
||||
connected_gens -= FG
|
||||
clean_up = 0
|
||||
update_icon()
|
||||
|
||||
//This is here to help fight the "hurr durr, release singulo cos nobody will notice before the
|
||||
//singulo eats the evidence". It's not fool-proof but better than nothing.
|
||||
//I want to avoid using global variables.
|
||||
INVOKE_ASYNC(src, .proc/notify_admins)
|
||||
|
||||
move_resist = initial(move_resist)
|
||||
|
||||
/obj/machinery/field/generator/proc/shield_floor(create)
|
||||
if(connected_gens.len < 2)
|
||||
return
|
||||
var/CGcounter
|
||||
for(CGcounter = 1; CGcounter < connected_gens.len, CGcounter++)
|
||||
|
||||
var/list/CGList = ((connected_gens[CGcounter].connected_gens & connected_gens[CGcounter+1].connected_gens)^src)
|
||||
if(!CGList.len)
|
||||
return
|
||||
var/obj/machinery/field/generator/CG = CGList[1]
|
||||
|
||||
var/x_step
|
||||
var/y_step
|
||||
if(CG.x > x && CG.y > y)
|
||||
for(x_step=x; x_step <= CG.x; x_step++)
|
||||
for(y_step=y; y_step <= CG.y; y_step++)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else if(CG.x > x && CG.y < y)
|
||||
for(x_step=x; x_step <= CG.x; x_step++)
|
||||
for(y_step=y; y_step >= CG.y; y_step--)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else if(CG.x < x && CG.y > y)
|
||||
for(x_step=x; x_step >= CG.x; x_step--)
|
||||
for(y_step=y; y_step <= CG.y; y_step++)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else
|
||||
for(x_step=x; x_step >= CG.x; x_step--)
|
||||
for(y_step=y; y_step >= CG.y; y_step--)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/place_floor(Location,create)
|
||||
if(create && !locate(/obj/effect/shield) in Location)
|
||||
new/obj/effect/shield(Location)
|
||||
else if(!create)
|
||||
var/obj/effect/shield/S=locate(/obj/effect/shield) in Location
|
||||
if(S)
|
||||
qdel(S)
|
||||
|
||||
/obj/machinery/field/generator/proc/notify_admins()
|
||||
var/temp = TRUE //stops spam
|
||||
for(var/obj/singularity/O in GLOB.singularities)
|
||||
if(O.last_warning && temp)
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
notify_ghosts("IT'S LOOSE", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, ghost_sound = 'sound/machines/warning-buzzer.ogg', header = "IT'S LOOSE", notify_volume = 75)
|
||||
O.last_warning = world.time
|
||||
|
||||
/obj/machinery/field/generator/shock(mob/living/user)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bump_field(atom/movable/AM as mob|obj)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
#undef FG_UNSECURED
|
||||
#undef FG_SECURED
|
||||
#undef FG_WELDED
|
||||
|
||||
#undef FG_OFFLINE
|
||||
#undef FG_CHARGING
|
||||
#undef FG_ONLINE
|
||||
|
||||
|
||||
|
||||
/*
|
||||
field_generator power level display
|
||||
The icon used for the field_generator need to have 6 icon states
|
||||
named 'Field_Gen +p[num]' where 'num' ranges from 1 to 6
|
||||
|
||||
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
|
||||
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
|
||||
no power level overlay is currently in the overlays list.
|
||||
-Aygar
|
||||
*/
|
||||
|
||||
#define field_generator_max_power 250
|
||||
|
||||
#define FG_OFFLINE 0
|
||||
#define FG_CHARGING 1
|
||||
#define FG_ONLINE 2
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
/obj/machinery/field/generator
|
||||
name = "field generator"
|
||||
desc = "A large thermal battery that projects a high amount of energy when powered."
|
||||
icon = 'icons/obj/machines/field_generator.dmi'
|
||||
icon_state = "Field_Gen"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
max_integrity = 500
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
//100% immune to lasers and energy projectiles since it absorbs their energy.
|
||||
armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
var/power_level = 0
|
||||
var/active = FG_OFFLINE
|
||||
var/power = 20 // Current amount of power
|
||||
var/state = FG_UNSECURED
|
||||
var/warming_up = 0
|
||||
var/list/obj/machinery/field/containment/fields
|
||||
var/list/obj/machinery/field/generator/connected_gens
|
||||
var/clean_up = 0
|
||||
|
||||
/obj/machinery/field/generator/update_overlays()
|
||||
. = ..()
|
||||
if(warming_up)
|
||||
. += "+a[warming_up]"
|
||||
if(LAZYLEN(fields))
|
||||
. += "+on"
|
||||
if(power_level)
|
||||
. += "+p[power_level]"
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Initialize()
|
||||
. = ..()
|
||||
fields = list()
|
||||
connected_gens = list()
|
||||
|
||||
/obj/machinery/field/generator/anchored/Initialize()
|
||||
. = ..()
|
||||
setAnchored(TRUE)
|
||||
|
||||
/obj/machinery/field/generator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/field/generator/process()
|
||||
if(active == FG_ONLINE)
|
||||
calc_power()
|
||||
|
||||
/obj/machinery/field/generator/interact(mob/user)
|
||||
if(state == FG_WELDED)
|
||||
if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on
|
||||
if(active >= FG_CHARGING)
|
||||
to_chat(user, "<span class='warning'>You are unable to turn off [src] once it is online!</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] turns on [src].</span>", \
|
||||
"<span class='notice'>You turn on [src].</span>", \
|
||||
"<span class='hear'>You hear heavy droning.</span>")
|
||||
turn_on()
|
||||
investigate_log("<font color='green'>activated</font> by [key_name(user)].", INVESTIGATE_SINGULO)
|
||||
|
||||
add_fingerprint(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be firmly secured to the floor first!</span>")
|
||||
|
||||
/obj/machinery/field/generator/setAnchored(anchorvalue)
|
||||
. = ..()
|
||||
if(active)
|
||||
turn_off()
|
||||
state = anchorvalue ? FG_SECURED : FG_UNSECURED
|
||||
|
||||
/obj/machinery/field/generator/can_be_unfasten_wrench(mob/user, silent)
|
||||
if(active)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>Turn \the [src] off first!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
else if(state == FG_WELDED)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>[src] is welded to the floor!</span>")
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/field/generator/wrench_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
default_unfasten_wrench(user, I)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/field/generator/welder_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(active)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be off!</span>")
|
||||
return TRUE
|
||||
|
||||
switch(state)
|
||||
if(FG_UNSECURED)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be wrenched to the floor!</span>")
|
||||
|
||||
if(FG_SECURED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] starts to weld [src] to the floor.</span>", \
|
||||
"<span class='notice'>You start to weld \the [src] to the floor...</span>", \
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_SECURED)
|
||||
state = FG_WELDED
|
||||
to_chat(user, "<span class='notice'>You weld the field generator to the floor.</span>")
|
||||
|
||||
if(FG_WELDED)
|
||||
if(!I.tool_start_check(user, amount=0))
|
||||
return TRUE
|
||||
user.visible_message("<span class='notice'>[user] starts to cut [src] free from the floor.</span>", \
|
||||
"<span class='notice'>You start to cut \the [src] free from the floor...</span>", \
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
if(I.use_tool(src, user, 20, volume=50) && state == FG_WELDED)
|
||||
state = FG_SECURED
|
||||
to_chat(user, "<span class='notice'>You cut \the [src] free from the floor.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/field/generator/attack_animal(mob/living/simple_animal/M)
|
||||
if(M.environment_smash & ENVIRONMENT_SMASH_RWALLS && active == FG_OFFLINE && state != FG_UNSECURED)
|
||||
setAnchored(FALSE)
|
||||
M.visible_message("<span class='warning'>[M] rips [src] free from its moorings!</span>")
|
||||
else
|
||||
..()
|
||||
if(!anchored)
|
||||
step(src, get_dir(M, src))
|
||||
|
||||
/obj/machinery/field/generator/blob_act(obj/structure/blob/B)
|
||||
if(active)
|
||||
return 0
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bullet_act(obj/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power = min(power + Proj.damage, field_generator_max_power)
|
||||
check_power_level()
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/Destroy()
|
||||
cleanup()
|
||||
return ..()
|
||||
|
||||
/*
|
||||
The power level is displayed using overlays. The current displayed power level is stored in 'powerlevel'.
|
||||
The overlay in use and the powerlevel variable must be kept in sync. A powerlevel equal to 0 means that
|
||||
no power level overlay is currently in the overlays list.
|
||||
*/
|
||||
|
||||
/obj/machinery/field/generator/proc/check_power_level()
|
||||
var/new_level = round(6 * power / field_generator_max_power)
|
||||
if(new_level != power_level)
|
||||
power_level = new_level
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_off()
|
||||
active = FG_OFFLINE
|
||||
CanAtmosPass = ATMOS_PASS_YES
|
||||
air_update_turf(TRUE)
|
||||
INVOKE_ASYNC(src, .proc/cleanup)
|
||||
addtimer(CALLBACK(src, .proc/cool_down), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/cool_down()
|
||||
if(active || warming_up <= 0)
|
||||
return
|
||||
warming_up--
|
||||
update_icon()
|
||||
if(warming_up > 0)
|
||||
addtimer(CALLBACK(src, .proc/cool_down), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/turn_on()
|
||||
active = FG_CHARGING
|
||||
addtimer(CALLBACK(src, .proc/warm_up), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/warm_up()
|
||||
if(!active)
|
||||
return
|
||||
warming_up++
|
||||
update_icon()
|
||||
if(warming_up >= 3)
|
||||
start_fields()
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/warm_up), 50)
|
||||
|
||||
/obj/machinery/field/generator/proc/calc_power(set_power_draw)
|
||||
var/power_draw = 2 + fields.len
|
||||
if(set_power_draw)
|
||||
power_draw = set_power_draw
|
||||
|
||||
if(draw_power(round(power_draw/2,1)))
|
||||
check_power_level()
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>The [name] shuts down!</span>", "<span class='hear'>You hear something shutting down.</span>")
|
||||
turn_off()
|
||||
investigate_log("ran out of power and <font color='red'>deactivated</font>", INVESTIGATE_SINGULO)
|
||||
power = 0
|
||||
check_power_level()
|
||||
return 0
|
||||
|
||||
//This could likely be better, it tends to start loopin if you have a complex generator loop setup. Still works well enough to run the engine fields will likely recode the field gens and fields sometime -Mport
|
||||
/obj/machinery/field/generator/proc/draw_power(draw = 0, failsafe = FALSE, obj/machinery/field/generator/G = null, obj/machinery/field/generator/last = null)
|
||||
if((G && (G == src)) || (failsafe >= 8))//Loopin, set fail
|
||||
return 0
|
||||
else
|
||||
failsafe++
|
||||
|
||||
if(power >= draw)//We have enough power
|
||||
power -= draw
|
||||
return 1
|
||||
|
||||
else//Need more power
|
||||
draw -= power
|
||||
power = 0
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
if(FG == last)//We just asked you
|
||||
continue
|
||||
if(G)//Another gen is askin for power and we dont have it
|
||||
if(FG.draw_power(draw,failsafe,G,src))//Can you take the load
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else//We are askin another for power
|
||||
if(FG.draw_power(draw,failsafe,src,src))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/start_fields()
|
||||
if(state != FG_WELDED || !anchored)
|
||||
turn_off()
|
||||
return
|
||||
move_resist = INFINITY
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
air_update_turf(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 1), 1)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 2), 2)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 4), 3)
|
||||
addtimer(CALLBACK(src, .proc/setup_field, 8), 4)
|
||||
addtimer(VARSET_CALLBACK(src, active, FG_ONLINE), 5)
|
||||
|
||||
/obj/machinery/field/generator/proc/setup_field(NSEW)
|
||||
var/turf/T = loc
|
||||
if(!istype(T))
|
||||
return 0
|
||||
|
||||
var/obj/machinery/field/generator/G = null
|
||||
var/steps = 0
|
||||
if(!NSEW)//Make sure its ran right
|
||||
return 0
|
||||
for(var/dist in 0 to 7) // checks out to 8 tiles away for another generator
|
||||
T = get_step(T, NSEW)
|
||||
if(T.density)//We cant shoot a field though this
|
||||
return 0
|
||||
|
||||
G = locate(/obj/machinery/field/generator) in T
|
||||
if(G)
|
||||
steps -= 1
|
||||
if(!G.active)
|
||||
return 0
|
||||
break
|
||||
|
||||
for(var/TC in T.contents)
|
||||
var/atom/A = TC
|
||||
if(ismob(A))
|
||||
continue
|
||||
if(A.density)
|
||||
return 0
|
||||
|
||||
steps++
|
||||
|
||||
if(!G)
|
||||
return 0
|
||||
|
||||
T = loc
|
||||
for(var/dist in 0 to steps) // creates each field tile
|
||||
var/field_dir = get_dir(T,get_step(G.loc, NSEW))
|
||||
T = get_step(T, NSEW)
|
||||
if(!locate(/obj/machinery/field/containment) in T)
|
||||
var/obj/machinery/field/containment/CF = new(T)
|
||||
CF.set_master(src,G)
|
||||
CF.setDir(field_dir)
|
||||
fields += CF
|
||||
G.fields += CF
|
||||
for(var/mob/living/L in T)
|
||||
CF.Crossed(L)
|
||||
|
||||
connected_gens |= G
|
||||
G.connected_gens |= src
|
||||
shield_floor(TRUE)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/cleanup()
|
||||
clean_up = 1
|
||||
for (var/F in fields)
|
||||
qdel(F)
|
||||
|
||||
shield_floor(FALSE)
|
||||
|
||||
for(var/CG in connected_gens)
|
||||
var/obj/machinery/field/generator/FG = CG
|
||||
FG.connected_gens -= src
|
||||
if(!FG.clean_up)//Makes the other gens clean up as well
|
||||
FG.cleanup()
|
||||
connected_gens -= FG
|
||||
clean_up = 0
|
||||
update_icon()
|
||||
|
||||
//This is here to help fight the "hurr durr, release singulo cos nobody will notice before the
|
||||
//singulo eats the evidence". It's not fool-proof but better than nothing.
|
||||
//I want to avoid using global variables.
|
||||
INVOKE_ASYNC(src, .proc/notify_admins)
|
||||
|
||||
move_resist = initial(move_resist)
|
||||
|
||||
/obj/machinery/field/generator/proc/shield_floor(create)
|
||||
if(connected_gens.len < 2)
|
||||
return
|
||||
var/CGcounter
|
||||
for(CGcounter = 1; CGcounter < connected_gens.len, CGcounter++)
|
||||
|
||||
var/list/CGList = ((connected_gens[CGcounter].connected_gens & connected_gens[CGcounter+1].connected_gens)^src)
|
||||
if(!CGList.len)
|
||||
return
|
||||
var/obj/machinery/field/generator/CG = CGList[1]
|
||||
|
||||
var/x_step
|
||||
var/y_step
|
||||
if(CG.x > x && CG.y > y)
|
||||
for(x_step=x; x_step <= CG.x; x_step++)
|
||||
for(y_step=y; y_step <= CG.y; y_step++)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else if(CG.x > x && CG.y < y)
|
||||
for(x_step=x; x_step <= CG.x; x_step++)
|
||||
for(y_step=y; y_step >= CG.y; y_step--)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else if(CG.x < x && CG.y > y)
|
||||
for(x_step=x; x_step >= CG.x; x_step--)
|
||||
for(y_step=y; y_step <= CG.y; y_step++)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
else
|
||||
for(x_step=x; x_step >= CG.x; x_step--)
|
||||
for(y_step=y; y_step >= CG.y; y_step--)
|
||||
place_floor(locate(x_step,y_step,z),create)
|
||||
|
||||
|
||||
/obj/machinery/field/generator/proc/place_floor(Location,create)
|
||||
if(create && !locate(/obj/effect/shield) in Location)
|
||||
new/obj/effect/shield(Location)
|
||||
else if(!create)
|
||||
var/obj/effect/shield/S=locate(/obj/effect/shield) in Location
|
||||
if(S)
|
||||
qdel(S)
|
||||
|
||||
/obj/machinery/field/generator/proc/notify_admins()
|
||||
var/temp = TRUE //stops spam
|
||||
for(var/obj/singularity/O in GLOB.singularities)
|
||||
if(O.last_warning && temp)
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
|
||||
notify_ghosts("IT'S LOOSE", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, ghost_sound = 'sound/machines/warning-buzzer.ogg', header = "IT'S LOOSE", notify_volume = 75)
|
||||
O.last_warning = world.time
|
||||
|
||||
/obj/machinery/field/generator/shock(mob/living/user)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
/obj/machinery/field/generator/bump_field(atom/movable/AM as mob|obj)
|
||||
if(fields.len)
|
||||
..()
|
||||
|
||||
#undef FG_UNSECURED
|
||||
#undef FG_SECURED
|
||||
#undef FG_WELDED
|
||||
|
||||
#undef FG_OFFLINE
|
||||
#undef FG_CHARGING
|
||||
#undef FG_ONLINE
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/////SINGULARITY SPAWNER
|
||||
/obj/machinery/the_singularitygen
|
||||
name = "Gravitational Singularity Generator"
|
||||
desc = "An odd device which produces a Gravitational Singularity when set up."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "TheSingGen"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
// You can buckle someone to the singularity generator, then start the engine. Fun!
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
buckle_requires_restraints = TRUE
|
||||
|
||||
var/energy = 0
|
||||
var/creation_type = /obj/singularity
|
||||
|
||||
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
default_unfasten_wrench(user, W, 0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/the_singularitygen/process()
|
||||
if(energy > 0)
|
||||
if(energy >= 200)
|
||||
var/turf/T = get_turf(src)
|
||||
SSblackbox.record_feedback("tally", "engine_started", 1, type)
|
||||
var/obj/singularity/S = new creation_type(T, 50)
|
||||
transfer_fingerprints_to(S)
|
||||
qdel(src)
|
||||
else
|
||||
energy -= 1
|
||||
/////SINGULARITY SPAWNER
|
||||
/obj/machinery/the_singularitygen
|
||||
name = "Gravitational Singularity Generator"
|
||||
desc = "An odd device which produces a Gravitational Singularity when set up."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "TheSingGen"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
// You can buckle someone to the singularity generator, then start the engine. Fun!
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
buckle_requires_restraints = TRUE
|
||||
|
||||
var/energy = 0
|
||||
var/creation_type = /obj/singularity
|
||||
|
||||
/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
default_unfasten_wrench(user, W, 0)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/the_singularitygen/process()
|
||||
if(energy > 0)
|
||||
if(energy >= 200)
|
||||
var/turf/T = get_turf(src)
|
||||
SSblackbox.record_feedback("tally", "engine_started", 1, type)
|
||||
var/obj/singularity/S = new creation_type(T, 50)
|
||||
transfer_fingerprints_to(S)
|
||||
qdel(src)
|
||||
else
|
||||
energy -= 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/area/engine/engineering/poweralert(state, source)
|
||||
if (state != poweralm)
|
||||
investigate_log("has a power alarm!", INVESTIGATE_SINGULO)
|
||||
..()
|
||||
/area/engine/engineering/poweralert(state, source)
|
||||
if (state != poweralm)
|
||||
investigate_log("has a power alarm!", INVESTIGATE_SINGULO)
|
||||
..()
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
/obj/effect/accelerated_particle
|
||||
name = "Accelerated Particles"
|
||||
desc = "Small things moving very fast."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "particle"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/movement_range = 10
|
||||
var/energy = 10
|
||||
var/speed = 1
|
||||
|
||||
/obj/effect/accelerated_particle/weak
|
||||
movement_range = 8
|
||||
energy = 5
|
||||
|
||||
/obj/effect/accelerated_particle/strong
|
||||
movement_range = 15
|
||||
energy = 15
|
||||
|
||||
/obj/effect/accelerated_particle/powerful
|
||||
movement_range = 20
|
||||
energy = 50
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/New(loc)
|
||||
..()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/move), 1)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bump(atom/A)
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/singularity))
|
||||
var/obj/singularity/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/structure/blob))
|
||||
var/obj/structure/blob/B = A
|
||||
B.take_damage(energy*0.6)
|
||||
movement_range = 0
|
||||
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
. = ..()
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/ex_act(severity, target)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/accelerated_particle/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
|
||||
M.rad_act(energy*6)
|
||||
|
||||
/obj/effect/accelerated_particle/proc/move()
|
||||
if(!step(src,dir))
|
||||
forceMove(get_step(src,dir))
|
||||
movement_range--
|
||||
if(movement_range == 0)
|
||||
qdel(src)
|
||||
else
|
||||
sleep(speed)
|
||||
move()
|
||||
/obj/effect/accelerated_particle
|
||||
name = "Accelerated Particles"
|
||||
desc = "Small things moving very fast."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "particle"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
var/movement_range = 10
|
||||
var/energy = 10
|
||||
var/speed = 1
|
||||
|
||||
/obj/effect/accelerated_particle/weak
|
||||
movement_range = 8
|
||||
energy = 5
|
||||
|
||||
/obj/effect/accelerated_particle/strong
|
||||
movement_range = 15
|
||||
energy = 15
|
||||
|
||||
/obj/effect/accelerated_particle/powerful
|
||||
movement_range = 20
|
||||
energy = 50
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/New(loc)
|
||||
..()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/move), 1)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/Bump(atom/A)
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/singularity))
|
||||
var/obj/singularity/S = A
|
||||
S.energy += energy
|
||||
else if(istype(A, /obj/structure/blob))
|
||||
var/obj/structure/blob/B = A
|
||||
B.take_damage(energy*0.6)
|
||||
movement_range = 0
|
||||
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
. = ..()
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
/obj/effect/accelerated_particle/ex_act(severity, target)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/accelerated_particle/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/accelerated_particle/proc/toxmob(mob/living/M)
|
||||
M.rad_act(energy*6)
|
||||
|
||||
/obj/effect/accelerated_particle/proc/move()
|
||||
if(!step(src,dir))
|
||||
forceMove(get_step(src,dir))
|
||||
movement_range--
|
||||
if(movement_range == 0)
|
||||
qdel(src)
|
||||
else
|
||||
sleep(speed)
|
||||
move()
|
||||
|
||||
@@ -1,173 +1,173 @@
|
||||
/*Composed of 7 parts :
|
||||
|
||||
3 Particle Emitters
|
||||
1 Power Box
|
||||
1 Fuel Chamber
|
||||
1 End Cap
|
||||
1 Control computer
|
||||
|
||||
Setup map
|
||||
|
||||
|EC|
|
||||
CC|FC|
|
||||
|PB|
|
||||
PE|PE|PE
|
||||
|
||||
*/
|
||||
#define PA_CONSTRUCTION_UNSECURED 0
|
||||
#define PA_CONSTRUCTION_UNWIRED 1
|
||||
#define PA_CONSTRUCTION_PANEL_OPEN 2
|
||||
#define PA_CONSTRUCTION_COMPLETE 3
|
||||
|
||||
/obj/structure/particle_accelerator
|
||||
name = "Particle Accelerator"
|
||||
desc = "Part of a Particle Accelerator."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
max_integrity = 500
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80)
|
||||
|
||||
var/obj/machinery/particle_accelerator/control_box/master = null
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/reference = null
|
||||
var/powered = 0
|
||||
var/strength = null
|
||||
|
||||
/obj/structure/particle_accelerator/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/structure/particle_accelerator/Destroy()
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
if(master)
|
||||
master.connected_parts -= src
|
||||
master.assembled = 0
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/particle_accelerator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("<span class='notice'>[user.name] secures the [name] to the floor.</span>", \
|
||||
"<span class='notice'>You secure the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("<span class='notice'>[user.name] detaches the [name] from the floor.</span>", \
|
||||
"<span class='notice'>You remove the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("<span class='notice'>[user.name] adds wires to the [name].</span>", \
|
||||
"<span class='notice'>You add some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)//TODO:Shock user if its on?
|
||||
user.visible_message("<span class='notice'>[user.name] removes some wires from the [name].</span>", \
|
||||
"<span class='notice'>You remove some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] closes the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You close the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] opens the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You open the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
new /obj/item/stack/sheet/metal (loc, 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/particle_accelerator/Move()
|
||||
. = ..()
|
||||
if(master && master.active)
|
||||
master.toggle_power()
|
||||
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/update_icon_state()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED,PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state="[reference]"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state="[reference]w"
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(powered)
|
||||
icon_state="[reference]p[strength]"
|
||||
else
|
||||
icon_state="[reference]c"
|
||||
|
||||
/obj/structure/particle_accelerator/proc/update_state()
|
||||
if(master)
|
||||
master.update_state()
|
||||
|
||||
/obj/structure/particle_accelerator/proc/connect_master(obj/O)
|
||||
if(O.dir == dir)
|
||||
master = O
|
||||
return 1
|
||||
return 0
|
||||
|
||||
///////////
|
||||
// PARTS //
|
||||
///////////
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/end_cap
|
||||
name = "Alpha Particle Generation Array"
|
||||
desc = "This is where Alpha particles are generated from \[REDACTED\]."
|
||||
icon_state = "end_cap"
|
||||
reference = "end_cap"
|
||||
|
||||
/obj/structure/particle_accelerator/power_box
|
||||
name = "Particle Focusing EM Lens"
|
||||
desc = "This uses electromagnetic waves to focus the Alpha particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "power_box"
|
||||
reference = "power_box"
|
||||
|
||||
/obj/structure/particle_accelerator/fuel_chamber
|
||||
name = "EM Acceleration Chamber"
|
||||
desc = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "fuel_chamber"
|
||||
reference = "fuel_chamber"
|
||||
/*Composed of 7 parts :
|
||||
|
||||
3 Particle Emitters
|
||||
1 Power Box
|
||||
1 Fuel Chamber
|
||||
1 End Cap
|
||||
1 Control computer
|
||||
|
||||
Setup map
|
||||
|
||||
|EC|
|
||||
CC|FC|
|
||||
|PB|
|
||||
PE|PE|PE
|
||||
|
||||
*/
|
||||
#define PA_CONSTRUCTION_UNSECURED 0
|
||||
#define PA_CONSTRUCTION_UNWIRED 1
|
||||
#define PA_CONSTRUCTION_PANEL_OPEN 2
|
||||
#define PA_CONSTRUCTION_COMPLETE 3
|
||||
|
||||
/obj/structure/particle_accelerator
|
||||
name = "Particle Accelerator"
|
||||
desc = "Part of a Particle Accelerator."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
max_integrity = 500
|
||||
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80)
|
||||
|
||||
var/obj/machinery/particle_accelerator/control_box/master = null
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/reference = null
|
||||
var/powered = 0
|
||||
var/strength = null
|
||||
|
||||
/obj/structure/particle_accelerator/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/structure/particle_accelerator/Destroy()
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
if(master)
|
||||
master.connected_parts -= src
|
||||
master.assembled = 0
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/particle_accelerator/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("<span class='notice'>[user.name] secures the [name] to the floor.</span>", \
|
||||
"<span class='notice'>You secure the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("<span class='notice'>[user.name] detaches the [name] from the floor.</span>", \
|
||||
"<span class='notice'>You remove the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("<span class='notice'>[user.name] adds wires to the [name].</span>", \
|
||||
"<span class='notice'>You add some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)//TODO:Shock user if its on?
|
||||
user.visible_message("<span class='notice'>[user.name] removes some wires from the [name].</span>", \
|
||||
"<span class='notice'>You remove some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] closes the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You close the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] opens the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You open the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
new /obj/item/stack/sheet/metal (loc, 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/particle_accelerator/Move()
|
||||
. = ..()
|
||||
if(master && master.active)
|
||||
master.toggle_power()
|
||||
investigate_log("was moved whilst active; it <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/update_icon_state()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED,PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state="[reference]"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state="[reference]w"
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(powered)
|
||||
icon_state="[reference]p[strength]"
|
||||
else
|
||||
icon_state="[reference]c"
|
||||
|
||||
/obj/structure/particle_accelerator/proc/update_state()
|
||||
if(master)
|
||||
master.update_state()
|
||||
|
||||
/obj/structure/particle_accelerator/proc/connect_master(obj/O)
|
||||
if(O.dir == dir)
|
||||
master = O
|
||||
return 1
|
||||
return 0
|
||||
|
||||
///////////
|
||||
// PARTS //
|
||||
///////////
|
||||
|
||||
|
||||
/obj/structure/particle_accelerator/end_cap
|
||||
name = "Alpha Particle Generation Array"
|
||||
desc = "This is where Alpha particles are generated from \[REDACTED\]."
|
||||
icon_state = "end_cap"
|
||||
reference = "end_cap"
|
||||
|
||||
/obj/structure/particle_accelerator/power_box
|
||||
name = "Particle Focusing EM Lens"
|
||||
desc = "This uses electromagnetic waves to focus the Alpha particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "power_box"
|
||||
reference = "power_box"
|
||||
|
||||
/obj/structure/particle_accelerator/fuel_chamber
|
||||
name = "EM Acceleration Chamber"
|
||||
desc = "This is where the Alpha particles are accelerated to <b><i>radical speeds</i></b>."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "fuel_chamber"
|
||||
reference = "fuel_chamber"
|
||||
|
||||
@@ -1,323 +1,323 @@
|
||||
/obj/machinery/particle_accelerator/control_box
|
||||
name = "Particle Accelerator Control Console"
|
||||
desc = "This controls the density of the particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_box"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 500
|
||||
active_power_usage = 10000
|
||||
dir = NORTH
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ui_x = 350
|
||||
ui_y = 185
|
||||
var/strength_upper_limit = 2
|
||||
var/interface_control = TRUE
|
||||
var/list/obj/structure/particle_accelerator/connected_parts
|
||||
var/assembled = FALSE
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/active = FALSE
|
||||
var/strength = 0
|
||||
var/powered = FALSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/particle_accelerator/control_box(src)
|
||||
connected_parts = list()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Destroy()
|
||||
if(active)
|
||||
toggle_power()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.master = null
|
||||
connected_parts.Cut()
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/multitool_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/update_state()
|
||||
if(construction_state < PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = NO_POWER_USE
|
||||
assembled = FALSE
|
||||
active = FALSE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = FALSE
|
||||
part.update_icon()
|
||||
connected_parts.Cut()
|
||||
return
|
||||
if(!part_scan())
|
||||
use_power = IDLE_POWER_USE
|
||||
active = FALSE
|
||||
connected_parts.Cut()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/update_icon_state()
|
||||
if(active)
|
||||
icon_state = "control_boxp1"
|
||||
else
|
||||
if(use_power)
|
||||
if(assembled)
|
||||
icon_state = "control_boxp"
|
||||
else
|
||||
icon_state = "ucontrol_boxp"
|
||||
else
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state = "control_box"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state = "control_boxw"
|
||||
else
|
||||
icon_state = "control_boxc"
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/add_strength(s)
|
||||
if(assembled && (strength < strength_upper_limit))
|
||||
strength++
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("increased to <font color='red'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s)
|
||||
if(assembled && (strength > 0))
|
||||
strength--
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("decreased to <font color='green'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/power_change()
|
||||
. = ..()
|
||||
if(machine_stat & NOPOWER)
|
||||
active = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
else if(!machine_stat && construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/process()
|
||||
if(active)
|
||||
//a part is missing!
|
||||
if(connected_parts.len < 6)
|
||||
investigate_log("lost a connected part; It <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
toggle_power()
|
||||
update_icon()
|
||||
return
|
||||
//emit some particles
|
||||
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
|
||||
PE.emit_particle(strength)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
|
||||
var/ldir = turn(dir,-90)
|
||||
var/rdir = turn(dir,90)
|
||||
var/odir = turn(dir,180)
|
||||
var/turf/T = loc
|
||||
|
||||
assembled = FALSE
|
||||
critical_machine = FALSE
|
||||
|
||||
var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src)
|
||||
if(!F)
|
||||
return FALSE
|
||||
|
||||
setDir(F.dir)
|
||||
connected_parts.Cut()
|
||||
|
||||
T = get_step(T,rdir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/fuel_chamber))
|
||||
return FALSE
|
||||
T = get_step(T,odir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/end_cap))
|
||||
return FALSE
|
||||
T = get_step(T,dir)
|
||||
T = get_step(T,dir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/power_box))
|
||||
return FALSE
|
||||
T = get_step(T,dir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/center))
|
||||
return FALSE
|
||||
T = get_step(T,ldir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/left))
|
||||
return FALSE
|
||||
T = get_step(T,rdir)
|
||||
T = get_step(T,rdir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/right))
|
||||
return FALSE
|
||||
|
||||
assembled = TRUE
|
||||
critical_machine = TRUE //Only counts if the PA is actually assembled.
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type)
|
||||
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
|
||||
if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE))
|
||||
if(PA.connect_master(src))
|
||||
connected_parts.Add(PA)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
|
||||
active = !active
|
||||
investigate_log("turned [active?"<font color='green'>ON</font>":"<font color='red'>OFF</font>"] by [usr ? key_name(usr) : "outside forces"] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? ADMIN_LOOKUPFLW(usr) : "outside forces"] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] at [AREACOORD(src)]")
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.powered = TRUE
|
||||
part.update_icon()
|
||||
else
|
||||
use_power = IDLE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = FALSE
|
||||
part.update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("<span class='notice'>[user.name] secures the [name] to the floor.</span>", \
|
||||
"<span class='notice'>You secure the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("<span class='notice'>[user.name] detaches the [name] from the floor.</span>", \
|
||||
"<span class='notice'>You remove the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("<span class='notice'>[user.name] adds wires to the [name].</span>", \
|
||||
"<span class='notice'>You add some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)//TODO:Shock user if its on?
|
||||
user.visible_message("<span class='notice'>[user.name] removes some wires from the [name].</span>", \
|
||||
"<span class='notice'>You remove some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] closes the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You close the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] opens the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You open the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/interact(mob/user)
|
||||
if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
|
||||
if(!interface_control)
|
||||
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
|
||||
return FALSE
|
||||
if(construction_state != PA_CONSTRUCTION_COMPLETE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_status(mob/user)
|
||||
if(is_interactive(user))
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ParticleAccelerator", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["assembled"] = assembled
|
||||
data["power"] = active
|
||||
data["strength"] = strength
|
||||
return data
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
if(wires.is_cut(WIRE_POWER))
|
||||
return
|
||||
toggle_power()
|
||||
. = TRUE
|
||||
if("scan")
|
||||
part_scan()
|
||||
. = TRUE
|
||||
if("add_strength")
|
||||
if(wires.is_cut(WIRE_STRENGTH))
|
||||
return
|
||||
add_strength()
|
||||
. = TRUE
|
||||
if("remove_strength")
|
||||
if(wires.is_cut(WIRE_STRENGTH))
|
||||
return
|
||||
remove_strength()
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
#undef PA_CONSTRUCTION_UNSECURED
|
||||
#undef PA_CONSTRUCTION_UNWIRED
|
||||
#undef PA_CONSTRUCTION_PANEL_OPEN
|
||||
#undef PA_CONSTRUCTION_COMPLETE
|
||||
/obj/machinery/particle_accelerator/control_box
|
||||
name = "Particle Accelerator Control Console"
|
||||
desc = "This controls the density of the particles."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_box"
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
use_power = NO_POWER_USE
|
||||
idle_power_usage = 500
|
||||
active_power_usage = 10000
|
||||
dir = NORTH
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
ui_x = 350
|
||||
ui_y = 185
|
||||
var/strength_upper_limit = 2
|
||||
var/interface_control = TRUE
|
||||
var/list/obj/structure/particle_accelerator/connected_parts
|
||||
var/assembled = FALSE
|
||||
var/construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
var/active = FALSE
|
||||
var/strength = 0
|
||||
var/powered = FALSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/particle_accelerator/control_box(src)
|
||||
connected_parts = list()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/Destroy()
|
||||
if(active)
|
||||
toggle_power()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.master = null
|
||||
connected_parts.Cut()
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/multitool_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/update_state()
|
||||
if(construction_state < PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = NO_POWER_USE
|
||||
assembled = FALSE
|
||||
active = FALSE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = FALSE
|
||||
part.update_icon()
|
||||
connected_parts.Cut()
|
||||
return
|
||||
if(!part_scan())
|
||||
use_power = IDLE_POWER_USE
|
||||
active = FALSE
|
||||
connected_parts.Cut()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/update_icon_state()
|
||||
if(active)
|
||||
icon_state = "control_boxp1"
|
||||
else
|
||||
if(use_power)
|
||||
if(assembled)
|
||||
icon_state = "control_boxp"
|
||||
else
|
||||
icon_state = "ucontrol_boxp"
|
||||
else
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED)
|
||||
icon_state = "control_box"
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
icon_state = "control_boxw"
|
||||
else
|
||||
icon_state = "control_boxc"
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/strength_change()
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/add_strength(s)
|
||||
if(assembled && (strength < strength_upper_limit))
|
||||
strength++
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("increased to <font color='red'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s)
|
||||
if(assembled && (strength > 0))
|
||||
strength--
|
||||
strength_change()
|
||||
|
||||
message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [AREACOORD(src)]")
|
||||
investigate_log("decreased to <font color='green'>[strength]</font> by [key_name(usr)] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/power_change()
|
||||
. = ..()
|
||||
if(machine_stat & NOPOWER)
|
||||
active = FALSE
|
||||
use_power = NO_POWER_USE
|
||||
else if(!machine_stat && construction_state == PA_CONSTRUCTION_COMPLETE)
|
||||
use_power = IDLE_POWER_USE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/process()
|
||||
if(active)
|
||||
//a part is missing!
|
||||
if(connected_parts.len < 6)
|
||||
investigate_log("lost a connected part; It <font color='red'>powered down</font>.", INVESTIGATE_SINGULO)
|
||||
toggle_power()
|
||||
update_icon()
|
||||
return
|
||||
//emit some particles
|
||||
for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts)
|
||||
PE.emit_particle(strength)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/part_scan()
|
||||
var/ldir = turn(dir,-90)
|
||||
var/rdir = turn(dir,90)
|
||||
var/odir = turn(dir,180)
|
||||
var/turf/T = loc
|
||||
|
||||
assembled = FALSE
|
||||
critical_machine = FALSE
|
||||
|
||||
var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src)
|
||||
if(!F)
|
||||
return FALSE
|
||||
|
||||
setDir(F.dir)
|
||||
connected_parts.Cut()
|
||||
|
||||
T = get_step(T,rdir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/fuel_chamber))
|
||||
return FALSE
|
||||
T = get_step(T,odir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/end_cap))
|
||||
return FALSE
|
||||
T = get_step(T,dir)
|
||||
T = get_step(T,dir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/power_box))
|
||||
return FALSE
|
||||
T = get_step(T,dir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/center))
|
||||
return FALSE
|
||||
T = get_step(T,ldir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/left))
|
||||
return FALSE
|
||||
T = get_step(T,rdir)
|
||||
T = get_step(T,rdir)
|
||||
if(!check_part(T, /obj/structure/particle_accelerator/particle_emitter/right))
|
||||
return FALSE
|
||||
|
||||
assembled = TRUE
|
||||
critical_machine = TRUE //Only counts if the PA is actually assembled.
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type)
|
||||
var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T
|
||||
if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE))
|
||||
if(PA.connect_master(src))
|
||||
connected_parts.Add(PA)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
|
||||
active = !active
|
||||
investigate_log("turned [active?"<font color='green'>ON</font>":"<font color='red'>OFF</font>"] by [usr ? key_name(usr) : "outside forces"] at [AREACOORD(src)]", INVESTIGATE_SINGULO)
|
||||
message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? ADMIN_LOOKUPFLW(usr) : "outside forces"] in [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] at [AREACOORD(src)]")
|
||||
if(active)
|
||||
use_power = ACTIVE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = strength
|
||||
part.powered = TRUE
|
||||
part.update_icon()
|
||||
else
|
||||
use_power = IDLE_POWER_USE
|
||||
for(var/CP in connected_parts)
|
||||
var/obj/structure/particle_accelerator/part = CP
|
||||
part.strength = null
|
||||
part.powered = FALSE
|
||||
part.update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/examine(mob/user)
|
||||
. = ..()
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
. += "Looks like it's not attached to the flooring."
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
. += "It is missing some cables."
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
. += "The panel is open."
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params)
|
||||
var/did_something = FALSE
|
||||
|
||||
switch(construction_state)
|
||||
if(PA_CONSTRUCTION_UNSECURED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH && !isinspace())
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = TRUE
|
||||
user.visible_message("<span class='notice'>[user.name] secures the [name] to the floor.</span>", \
|
||||
"<span class='notice'>You secure the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_UNWIRED)
|
||||
if(W.tool_behaviour == TOOL_WRENCH)
|
||||
W.play_tool_sound(src, 75)
|
||||
anchored = FALSE
|
||||
user.visible_message("<span class='notice'>[user.name] detaches the [name] from the floor.</span>", \
|
||||
"<span class='notice'>You remove the external bolts.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNSECURED
|
||||
did_something = TRUE
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(1))
|
||||
user.visible_message("<span class='notice'>[user.name] adds wires to the [name].</span>", \
|
||||
"<span class='notice'>You add some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_PANEL_OPEN)
|
||||
if(W.tool_behaviour == TOOL_WIRECUTTER)//TODO:Shock user if its on?
|
||||
user.visible_message("<span class='notice'>[user.name] removes some wires from the [name].</span>", \
|
||||
"<span class='notice'>You remove some wires.</span>")
|
||||
construction_state = PA_CONSTRUCTION_UNWIRED
|
||||
did_something = TRUE
|
||||
else if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] closes the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You close the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_COMPLETE
|
||||
did_something = TRUE
|
||||
if(PA_CONSTRUCTION_COMPLETE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
user.visible_message("<span class='notice'>[user.name] opens the [name]'s access panel.</span>", \
|
||||
"<span class='notice'>You open the access panel.</span>")
|
||||
construction_state = PA_CONSTRUCTION_PANEL_OPEN
|
||||
did_something = TRUE
|
||||
|
||||
if(did_something)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
update_state()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B)
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/interact(mob/user)
|
||||
if(construction_state == PA_CONSTRUCTION_PANEL_OPEN)
|
||||
wires.interact(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/proc/is_interactive(mob/user)
|
||||
if(!interface_control)
|
||||
to_chat(user, "<span class='alert'>ERROR: Request timed out. Check wire contacts.</span>")
|
||||
return FALSE
|
||||
if(construction_state != PA_CONSTRUCTION_COMPLETE)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_status(mob/user)
|
||||
if(is_interactive(user))
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ParticleAccelerator", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["assembled"] = assembled
|
||||
data["power"] = active
|
||||
data["strength"] = strength
|
||||
return data
|
||||
|
||||
/obj/machinery/particle_accelerator/control_box/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("power")
|
||||
if(wires.is_cut(WIRE_POWER))
|
||||
return
|
||||
toggle_power()
|
||||
. = TRUE
|
||||
if("scan")
|
||||
part_scan()
|
||||
. = TRUE
|
||||
if("add_strength")
|
||||
if(wires.is_cut(WIRE_STRENGTH))
|
||||
return
|
||||
add_strength()
|
||||
. = TRUE
|
||||
if("remove_strength")
|
||||
if(wires.is_cut(WIRE_STRENGTH))
|
||||
return
|
||||
remove_strength()
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
#undef PA_CONSTRUCTION_UNSECURED
|
||||
#undef PA_CONSTRUCTION_UNWIRED
|
||||
#undef PA_CONSTRUCTION_PANEL_OPEN
|
||||
#undef PA_CONSTRUCTION_COMPLETE
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
/obj/structure/particle_accelerator/particle_emitter
|
||||
name = "EM Containment Grid"
|
||||
desc = "This launches the Alpha particles, might not want to stand near this end."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
var/fire_delay = 50
|
||||
var/last_shot = 0
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/center
|
||||
icon_state = "emitter_center"
|
||||
reference = "emitter_center"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/left
|
||||
icon_state = "emitter_left"
|
||||
reference = "emitter_left"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/right
|
||||
icon_state = "emitter_right"
|
||||
reference = "emitter_right"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/set_delay(delay)
|
||||
if(delay >= 0)
|
||||
fire_delay = delay
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(strength = 0)
|
||||
if((last_shot + fire_delay) <= world.time)
|
||||
last_shot = world.time
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/effect/accelerated_particle/P
|
||||
switch(strength)
|
||||
if(0)
|
||||
P = new/obj/effect/accelerated_particle/weak(T)
|
||||
if(1)
|
||||
P = new/obj/effect/accelerated_particle(T)
|
||||
if(2)
|
||||
P = new/obj/effect/accelerated_particle/strong(T)
|
||||
if(3)
|
||||
P = new/obj/effect/accelerated_particle/powerful(T)
|
||||
P.setDir(dir)
|
||||
return 1
|
||||
return 0
|
||||
/obj/structure/particle_accelerator/particle_emitter
|
||||
name = "EM Containment Grid"
|
||||
desc = "This launches the Alpha particles, might not want to stand near this end."
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "none"
|
||||
var/fire_delay = 50
|
||||
var/last_shot = 0
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/center
|
||||
icon_state = "emitter_center"
|
||||
reference = "emitter_center"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/left
|
||||
icon_state = "emitter_left"
|
||||
reference = "emitter_left"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/right
|
||||
icon_state = "emitter_right"
|
||||
reference = "emitter_right"
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/set_delay(delay)
|
||||
if(delay >= 0)
|
||||
fire_delay = delay
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(strength = 0)
|
||||
if((last_shot + fire_delay) <= world.time)
|
||||
last_shot = world.time
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/effect/accelerated_particle/P
|
||||
switch(strength)
|
||||
if(0)
|
||||
P = new/obj/effect/accelerated_particle/weak(T)
|
||||
if(1)
|
||||
P = new/obj/effect/accelerated_particle(T)
|
||||
if(2)
|
||||
P = new/obj/effect/accelerated_particle/strong(T)
|
||||
if(3)
|
||||
P = new/obj/effect/accelerated_particle/powerful(T)
|
||||
P.setDir(dir)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user