Files
Paradise/code/game/machinery/shieldgen.dm
T
Tigercat2000 bbca8405ef -tg- Move Refactor
This commit ports /tg/'s move refactor.

The throwing system has been replaced entirely, removing the necessity
of throw_at_fast and resolving multiple outstanding issues, such as
crossbows being unusable.

Spacedrifting has also been upgraded to function with the new throwing
system. It is now it's own process.

Tickcomp has been killed, and the config values have been adjusted to
more or less match live Paradise.

All mobs now share a common Bump() proc. There are only four mobtypes
which do not, including humans and simple animals. With the exception
of mob types that do not ever want to Bump() or be Bumped(), they should
call the parent proc.

Human movement slowdown has been moderately tweaked in how it stacks effects;
It shouldn't be significantly different from a player perspective.

Mobs will now spread fire if they bump into another mob. I don't want to set
the world on fiiiire, I just want start a flame in your heart~

For player facing changes: Input delay has been reduced by roughly ~50ms for
any direction keys, by advantage of a previously unknown flag on byond verbs
which allow them to operate independently from the tick rate of the server.
You may need to clear your interface.dmf file if you have a custom skin for
this change to function.
2017-05-25 06:35:01 -07:00

610 lines
16 KiB
Plaintext

/obj/machinery/shield
name = "Emergency energy shield"
desc = "An energy shield used to contain hull breaches."
icon = 'icons/effects/effects.dmi'
icon_state = "shield-old"
density = 1
opacity = 0
anchored = 1
unacidable = 1
var/const/max_health = 200
var/health = max_health //The shield can only take so much beating (prevents perma-prisons)
/obj/machinery/shield/New()
src.dir = pick(1,2,3,4)
..()
/obj/machinery/shield/initialize()
air_update_turf(1)
..()
/obj/machinery/shield/Destroy()
opacity = 0
density = 0
air_update_turf(1)
return ..()
/obj/machinery/shield/Move()
var/turf/T = loc
..()
move_update_air(T)
/obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height)
if(!height) return 0
else return ..()
/obj/machinery/shield/CanAtmosPass(var/turf/T)
return !density
/obj/machinery/shield/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(!istype(W)) return
//Calculate damage
var/aforce = W.force
if(W.damtype == BRUTE || W.damtype == BURN)
src.health -= aforce
//Play a fitting sound
playsound(src.loc, 'sound/effects/EMPulse.ogg', 75, 1)
if(src.health <= 0)
visible_message("<span class='notice'>The [src] dissipates</span>")
qdel(src)
return
opacity = 1
spawn(20) if(src) opacity = 0
..()
/obj/machinery/shield/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
if(health <=0)
visible_message("<span class='notice'>The [src] dissipates</span>")
qdel(src)
return
opacity = 1
spawn(20) if(src) opacity = 0
/obj/machinery/shield/ex_act(severity)
switch(severity)
if(1.0)
if(prob(75))
qdel(src)
if(2.0)
if(prob(50))
qdel(src)
if(3.0)
if(prob(25))
qdel(src)
return
/obj/machinery/shield/emp_act(severity)
switch(severity)
if(1)
qdel(src)
if(2)
if(prob(50))
qdel(src)
/obj/machinery/shield/blob_act()
qdel(src)
/obj/machinery/shield/hitby(AM as mob|obj)
..()
var/tforce = 0
if(ismob(AM))
tforce = 40
else if(isobj(AM))
var/obj/O = AM
tforce = O.throwforce
health -= tforce
//This seemed to be the best sound for hitting a force field.
playsound(loc, 'sound/effects/EMPulse.ogg', 100, 1)
//Handle the destruction of the shield
if(health <= 0)
visible_message("<span class='notice'>The [src] dissipates</span>")
qdel(src)
return
//The shield becomes dense to absorb the blow.. purely asthetic.
opacity = 1
spawn(20)
if(src)
opacity = 0
/obj/machinery/shieldgen
name = "Emergency shield projector"
desc = "Used to seal minor hull breaches."
icon = 'icons/obj/objects.dmi'
icon_state = "shieldoff"
density = 1
opacity = 0
anchored = 0
pressure_resistance = 2*ONE_ATMOSPHERE
req_access = list(access_engine)
var/const/max_health = 100
var/health = max_health
var/active = 0
var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate
var/list/deployed_shields = list()
var/is_open = 0 //Whether or not the wires are exposed
var/locked = 0
/obj/machinery/shieldgen/Destroy()
QDEL_LIST(deployed_shields)
deployed_shields = null
return ..()
/obj/machinery/shieldgen/proc/shields_up()
if(active) return 0 //If it's already turned on, how did this get called?
src.active = 1
update_icon()
for(var/turf/target_tile in range(2, src))
if(istype(target_tile,/turf/space) && !(locate(/obj/machinery/shield) in target_tile))
if(malfunction && prob(33) || !malfunction)
deployed_shields += new /obj/machinery/shield(target_tile)
/obj/machinery/shieldgen/proc/shields_down()
if(!active) return 0 //If it's already off, how did this get called?
src.active = 0
update_icon()
for(var/obj/machinery/shield/shield_tile in deployed_shields)
qdel(shield_tile)
/obj/machinery/shieldgen/process()
if(malfunction && active)
if(deployed_shields.len && prob(5))
qdel(pick(deployed_shields))
return
/obj/machinery/shieldgen/proc/checkhp()
if(health <= 30)
src.malfunction = 1
if(health <= 0)
qdel(src)
update_icon()
return
/obj/machinery/shieldgen/ex_act(severity)
switch(severity)
if(1.0)
src.health -= 75
src.checkhp()
if(2.0)
src.health -= 30
if(prob(15))
src.malfunction = 1
src.checkhp()
if(3.0)
src.health -= 10
src.checkhp()
return
/obj/machinery/shieldgen/emp_act(severity)
switch(severity)
if(1)
src.health /= 2 //cut health in half
malfunction = 1
locked = pick(0,1)
if(2)
if(prob(50))
src.health *= 0.3 //chop off a third of the health
malfunction = 1
checkhp()
/obj/machinery/shieldgen/attack_hand(mob/user as mob)
if(locked)
to_chat(user, "The machine is locked, you are unable to use it.")
return
if(is_open)
to_chat(user, "The panel must be closed before operating this machine.")
return
if(src.active)
user.visible_message("<span class='notice'>[bicon(src)] [user] deactivated the shield generator.</span>", \
"<span class='notice'>[bicon(src)] You deactivate the shield generator.</span>", \
"You hear heavy droning fade out.")
src.shields_down()
else
if(anchored)
user.visible_message("<span class='notice'>[bicon(src)] [user] activated the shield generator.</span>", \
"<span class='notice'>[bicon(src)] You activate the shield generator.</span>", \
"You hear heavy droning.")
src.shields_up()
else
to_chat(user, "The device must first be secured to the floor.")
return
/obj/machinery/shieldgen/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/card/emag))
malfunction = 1
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
playsound(src.loc, W.usesound, 100, 1)
if(is_open)
to_chat(user, "<span class='notice'>You close the panel.</span>")
is_open = 0
else
to_chat(user, "<span class='notice'>You open the panel and expose the wiring.</span>")
is_open = 1
else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open)
var/obj/item/stack/cable_coil/coil = W
to_chat(user, "<span class='notice'>You begin to replace the wires.</span>")
//if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ), target = src)) //Take longer to repair heavier damage
if(do_after(user, 30 * coil.toolspeed, target = src))
if(!src || !coil) return
coil.use(1)
health = max_health
malfunction = 0
playsound(loc, coil.usesound, 50, 1)
to_chat(user, "<span class='notice'>You repair the [src]!</span>")
update_icon()
else if(istype(W, /obj/item/weapon/wrench))
if(locked)
to_chat(user, "The bolts are covered, unlocking this would retract the covers.")
return
if(anchored)
playsound(src.loc, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>You unsecure the [src] from the floor!</span>")
if(active)
to_chat(user, "<span class='notice'>The [src] shuts off!</span>")
src.shields_down()
anchored = 0
else
if(istype(get_turf(src), /turf/space)) return //No wrenching these in space!
playsound(src.loc, W.usesound, 100, 1)
to_chat(user, "<span class='notice'>You secure the [src] to the floor!</span>")
anchored = 1
else if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
if(src.allowed(user))
src.locked = !src.locked
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
else
to_chat(user, "<span class='warning'>Access denied.</span>")
else
..()
/obj/machinery/shieldgen/update_icon()
if(active)
src.icon_state = malfunction ? "shieldonbr":"shieldon"
else
src.icon_state = malfunction ? "shieldoffbr":"shieldoff"
return
////FIELD GEN START //shameless copypasta from fieldgen, powersink, and grille
#define maxstoredpower 500
/obj/machinery/shieldwallgen
name = "Shield Generator"
desc = "A shield generator."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "Shield_Gen"
anchored = 0
density = 1
req_access = list(access_teleporter)
var/active = 0
var/power = 0
var/state = 0
var/steps = 0
var/last_check = 0
var/check_delay = 10
var/recalc = 0
var/locked = 1
var/destroyed = 0
var/directwired = 1
// var/maxshieldload = 200
var/obj/structure/cable/attached // the attached cable
var/storedpower = 0
flags = CONDUCT
use_power = 0
/obj/machinery/shieldwallgen/proc/power()
if(!anchored)
power = 0
return 0
var/turf/T = src.loc
var/obj/structure/cable/C = T.get_cable_node()
var/datum/powernet/PN
if(C) PN = C.powernet // find the powernet of the connected cable
if(!PN)
power = 0
return 0
var/surplus = max(PN.avail-PN.load, 0)
var/shieldload = min(rand(50,200), surplus)
if(shieldload==0 && !storedpower) // no cable or no power, and no power stored
power = 0
return 0
else
power = 1 // IVE GOT THE POWER!
if(PN) //runtime errors fixer. They were caused by PN.load trying to access missing network in case of working on stored power.
storedpower += shieldload
PN.load += shieldload //uses powernet power.
// message_admins("[PN.load]", 1)
// use_power(250) //uses APC power
/obj/machinery/shieldwallgen/attack_hand(mob/user as mob)
if(state != 1)
to_chat(user, "<span class='warning'>The shield generator needs to be firmly secured to the floor first.</span>")
return 1
if(src.locked && !istype(user, /mob/living/silicon))
to_chat(user, "<span class='warning'>The controls are locked!</span>")
return 1
if(power != 1)
to_chat(user, "<span class='warning'>The shield generator needs to be powered by wire underneath.</span>")
return 1
if(src.active >= 1)
src.active = 0
icon_state = "Shield_Gen"
user.visible_message("[user] turned the shield generator off.", \
"You turn off the shield generator.", \
"You hear heavy droning fade out.")
for(var/dir in list(1,2,4,8)) src.cleanup(dir)
else
src.active = 1
icon_state = "Shield_Gen +a"
user.visible_message("[user] turned the shield generator on.", \
"You turn on the shield generator.", \
"You hear heavy droning.")
src.add_fingerprint(user)
/obj/machinery/shieldwallgen/process()
spawn(100)
power()
if(power)
storedpower -= 50 //this way it can survive longer and survive at all
if(storedpower >= maxstoredpower)
storedpower = maxstoredpower
if(storedpower <= 0)
storedpower = 0
// if(shieldload >= maxshieldload) //there was a loop caused by specifics of process(), so this was needed.
// shieldload = maxshieldload
if(src.active == 1)
if(!src.state == 1)
src.active = 0
return
spawn(1)
setup_field(1)
spawn(2)
setup_field(2)
spawn(3)
setup_field(4)
spawn(4)
setup_field(8)
src.active = 2
if(src.active >= 1)
if(src.power == 0)
src.visible_message("<span class='warning'>The [src.name] shuts down due to lack of power!</span>", \
"You hear heavy droning fade out")
icon_state = "Shield_Gen"
src.active = 0
for(var/dir in list(1,2,4,8)) src.cleanup(dir)
/obj/machinery/shieldwallgen/proc/setup_field(var/NSEW = 0)
var/turf/T = src.loc
var/turf/T2 = src.loc
var/obj/machinery/shieldwallgen/G
var/steps = 0
var/oNSEW = 0
if(!NSEW)//Make sure its ran right
return
if(NSEW == 1)
oNSEW = 2
else if(NSEW == 2)
oNSEW = 1
else if(NSEW == 4)
oNSEW = 8
else if(NSEW == 8)
oNSEW = 4
for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator
T = get_step(T2, NSEW)
T2 = T
steps += 1
if(locate(/obj/machinery/shieldwallgen) in T)
G = (locate(/obj/machinery/shieldwallgen) in T)
steps -= 1
if(!G.active)
return
G.cleanup(oNSEW)
break
if(isnull(G))
return
T2 = src.loc
for(var/dist = 0, dist < steps, dist += 1) // creates each field tile
var/field_dir = get_dir(T2,get_step(T2, NSEW))
T = get_step(T2, NSEW)
T2 = T
var/obj/machinery/shieldwall/CF = new/obj/machinery/shieldwall/(src, G) //(ref to this gen, ref to connected gen)
CF.loc = T
CF.dir = field_dir
/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
if(active)
to_chat(user, "Turn off the field generator first.")
return
else if(state == 0)
state = 1
playsound(src.loc, W.usesound, 75, 1)
to_chat(user, "You secure the external reinforcing bolts to the floor.")
src.anchored = 1
return
else if(state == 1)
state = 0
playsound(src.loc, W.usesound, 75, 1)
to_chat(user, "You undo the external reinforcing bolts.")
src.anchored = 0
return
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if(src.allowed(user))
src.locked = !src.locked
to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]")
else
to_chat(user, "<span class='warning'>Access denied.</span>")
else
add_fingerprint(user)
..()
/obj/machinery/shieldwallgen/proc/cleanup(var/NSEW)
var/obj/machinery/shieldwall/F
var/obj/machinery/shieldwallgen/G
var/turf/T = src.loc
var/turf/T2 = src.loc
for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for fields
T = get_step(T2, NSEW)
T2 = T
if(locate(/obj/machinery/shieldwall) in T)
F = (locate(/obj/machinery/shieldwall) in T)
qdel(F)
if(locate(/obj/machinery/shieldwallgen) in T)
G = (locate(/obj/machinery/shieldwallgen) in T)
if(!G.active)
break
/obj/machinery/shieldwallgen/Destroy()
src.cleanup(1)
src.cleanup(2)
src.cleanup(4)
src.cleanup(8)
return ..()
/obj/machinery/shieldwallgen/bullet_act(var/obj/item/projectile/Proj)
storedpower -= Proj.damage
..()
return
//////////////Containment Field START
/obj/machinery/shieldwall
name = "Shield"
desc = "An energy shield."
icon = 'icons/effects/effects.dmi'
icon_state = "shieldwall"
anchored = 1
density = 1
unacidable = 1
luminosity = 3
var/needs_power = 0
var/active = 1
// var/power = 10
var/delay = 5
var/last_active
var/mob/U
var/obj/machinery/shieldwallgen/gen_primary
var/obj/machinery/shieldwallgen/gen_secondary
/obj/machinery/shieldwall/New(var/obj/machinery/shieldwallgen/A, var/obj/machinery/shieldwallgen/B)
..()
src.gen_primary = A
src.gen_secondary = B
if(A && B)
needs_power = 1
/obj/machinery/shieldwall/attack_hand(mob/user as mob)
return
/obj/machinery/shieldwall/process()
if(needs_power)
if(isnull(gen_primary)||isnull(gen_secondary))
qdel(src)
return
if(!(gen_primary.active)||!(gen_secondary.active))
qdel(src)
return
//
if(prob(50))
gen_primary.storedpower -= 10
else
gen_secondary.storedpower -=10
/obj/machinery/shieldwall/bullet_act(var/obj/item/projectile/Proj)
if(needs_power)
var/obj/machinery/shieldwallgen/G
if(prob(50))
G = gen_primary
else
G = gen_secondary
G.storedpower -= Proj.damage
..()
return
/obj/machinery/shieldwall/ex_act(severity)
if(needs_power)
var/obj/machinery/shieldwallgen/G
switch(severity)
if(1.0) //big boom
if(prob(50))
G = gen_primary
else
G = gen_secondary
G.storedpower -= 200
if(2.0) //medium boom
if(prob(50))
G = gen_primary
else
G = gen_secondary
G.storedpower -= 50
if(3.0) //lil boom
if(prob(50))
G = gen_primary
else
G = gen_secondary
G.storedpower -= 20
return
/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
if(istype(mover) && mover.checkpass(PASSGLASS))
return prob(20)
else
if(istype(mover, /obj/item/projectile))
return prob(10)
else
return !src.density