Merge pull request #1031 from Citadel-Station-13/upstream-merge-27234

[MIRROR] [READY]Peacekeeper cyborg projectile dampening fields, attempt three
This commit is contained in:
LetterJay
2017-05-18 23:39:25 -04:00
committed by GitHub
11 changed files with 657 additions and 22 deletions
@@ -504,6 +504,113 @@
S.change_head_color(color2)
dropped = TRUE
//Peacekeeper Cyborg Projectile Dampenening Field
/obj/item/borg/projectile_dampen
name = "Hyperkinetic Dampening projector"
desc = "A device that projects a dampening field that weakens kinetic energy above a certain threshold. <span class='boldnotice'>Projects a field that drains power per second \
while active, that will weaken and slow damaging projectiles inside its field.</span> Still being a prototype, it tends to induce a charge on ungrounded metallic surfaces."
icon = 'icons/obj/device.dmi'
icon_state = "shield"
var/maxenergy = 1500
var/energy = 1500
var/energy_recharge = 7.5
var/energy_recharge_cyborg_drain_coefficient = 0.4
var/cyborg_cell_critical_percentage = 0.05
var/mob/living/silicon/robot/host = null
var/datum/proximity_monitor/advanced/dampening_field
var/projectile_damage_coefficient = 0.5
var/projectile_damage_tick_ecost_coefficient = 2 //Lasers get half their damage chopped off, drains 50 power/tick. Note that fields are processed 5 times per second.
var/projectile_speed_coefficient = 1.5 //Higher the coefficient slower the projectile.
var/projectile_tick_speed_ecost = 15
var/current_damage_dampening = 0
var/list/obj/item/projectile/tracked
var/image/projectile_effect
var/field_radius = 3
/obj/item/borg/projectile_dampen/debug
maxenergy = 50000
energy = 50000
energy_recharge = 5000
/obj/item/borg/projectile_dampen/Initialize()
. = ..()
projectile_effect = image('icons/effects/fields.dmi', "projectile_dampen_effect")
tracked = list()
icon_state = "shield0"
START_PROCESSING(SSfastprocess, src)
/obj/item/borg/projectile_dampen/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/item/borg/projectile_dampen/attack_self(mob/user)
var/active = FALSE
if(!istype(dampening_field))
activate_field()
active = TRUE
else
deactivate_field()
active = FALSE
to_chat(user, "<span class='boldnotice'>You [active? "activate":"deactivate"] the [src].</span>")
icon_state = "[initial(icon_state)][active]"
/obj/item/borg/projectile_dampen/proc/activate_field()
if(!istype(dampening_field))
dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
/obj/item/borg/projectile_dampen/proc/deactivate_field()
QDEL_NULL(dampening_field)
visible_message("<span class='warning'>The [src] shuts off!</span>")
for(var/obj/item/projectile/P in tracked)
restore_projectile(P)
/obj/item/borg/projectile_dampen/process()
process_recharge()
process_usage()
update_location()
/obj/item/borg/projectile_dampen/proc/update_location()
if(dampening_field)
dampening_field.HandleMove()
/obj/item/borg/projectile_dampen/proc/process_usage()
var/usage = 0
for(var/I in tracked)
if(!tracked[I]) //No damage
continue
usage += projectile_tick_speed_ecost
usage += (current_damage_dampening * projectile_damage_tick_ecost_coefficient)
energy = Clamp(energy - usage, 0, maxenergy)
if(energy <= 0)
deactivate_field()
visible_message("<span class='warning'>The [src] blinks \"ENERGY DEPLETED\"</span>")
/obj/item/borg/projectile_dampen/proc/process_recharge()
if(!istype(host))
energy = Clamp(energy + energy_recharge, 0, maxenergy)
return
if((host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy))
host.cell.use(energy_recharge*energy_recharge_cyborg_drain_coefficient)
energy += energy_recharge
/obj/item/borg/projectile_dampen/proc/dampen_projectile(obj/item/projectile/P, track_projectile = TRUE)
if(tracked[P])
return
if(track_projectile)
tracked[P] = P.damage
current_damage_dampening += P.damage
P.damage *= projectile_damage_coefficient
P.speed *= projectile_speed_coefficient
P.add_overlay(projectile_effect)
/obj/item/borg/projectile_dampen/proc/restore_projectile(obj/item/projectile/P)
tracked -= P
P.damage *= (1/projectile_damage_coefficient)
P.speed *= (1/projectile_speed_coefficient)
P.cut_overlay(projectile_effect)
current_damage_dampening -= P.damage
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
+3 -3
View File
@@ -42,7 +42,7 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/open/space/attack_ghost(mob/dead/observer/user)
@@ -177,7 +177,7 @@
ChangeTurf(/turf/open/floor/plating)
return TRUE
return FALSE
/turf/open/space/ReplaceWithLattice()
var/dest_x = destination_x
var/dest_y = destination_y
@@ -186,4 +186,4 @@
destination_x = dest_x
destination_y = dest_y
destination_z = dest_z
+19 -18
View File
@@ -92,39 +92,39 @@
LC.attackby(C,user)
return
coil.place_turf(src, user)
return 1
return TRUE
return 0
return FALSE
/turf/CanPass(atom/movable/mover, turf/target, height=1.5)
if(!target) return 0
if(!target) return FALSE
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
return !density
else // Now, doing more detailed checks for air movement and air group formation
if(target.blocks_air||blocks_air)
return 0
return FALSE
for(var/obj/obstacle in src)
if(!obstacle.CanPass(mover, target, height))
return 0
return FALSE
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height))
return 0
return FALSE
return 1
return TRUE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
if (!mover)
return 1
return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
mover.Bump(obstacle, 1)
return 0
return FALSE
var/list/large_dense = list()
//Next, check objects to block entry that are on the border
@@ -132,14 +132,14 @@
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
return 0
return FALSE
else
large_dense += border_obstacle
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Bump(src, 1)
return 0
return FALSE
//Finally, check objects/mobs to block entry that are not on the border
var/atom/movable/tompost_bump
@@ -151,8 +151,9 @@
top_layer = obstacle.layer
if(tompost_bump)
mover.Bump(tompost_bump,1)
return 0
return 1 //Nothing found to block so return success!
return FALSE
return TRUE //Nothing found to block so return success!
/turf/Entered(atom/movable/AM)
if(explosion_level && AM.ex_check(explosion_id))
@@ -185,7 +186,7 @@
O.make_unfrozen()
/turf/proc/is_plasteel_floor()
return 0
return FALSE
/turf/proc/levelupdate()
for(var/obj/O in src)
@@ -303,7 +304,7 @@
if(src_object.contents.len)
to_chat(usr, "<span class='notice'>You start dumping out the contents...</span>")
if(!do_after(usr,20,target=src_object))
return 0
return FALSE
var/list/things = src_object.contents.Copy()
var/datum/progressbar/progress = new(user, things.len, src)
@@ -311,7 +312,7 @@
sleep(1)
qdel(progress)
return 1
return TRUE
//////////////////////////////
//Distance procs
@@ -325,7 +326,7 @@
// possible. It results in more efficient (CPU-wise) pathing
// for bots and anything else that only moves in cardinal dirs.
/turf/proc/Distance_cardinal(turf/T)
if(!src || !T) return 0
if(!src || !T) return FALSE
return abs(x - T.x) + abs(y - T.y)
////////////////////////////////////////////////////
@@ -341,7 +342,7 @@
return(2)
/turf/proc/can_have_cabling()
return 1
return TRUE
/turf/proc/can_lay_cable()
return can_have_cabling() & !intact