Make shield sprites look nicer hopefully

This commit is contained in:
Aronai Sieyes
2020-04-12 17:53:38 -04:00
committed by Leshana
parent 859036b7cd
commit 3a41cf0656
4 changed files with 183 additions and 32 deletions

View File

@@ -15,23 +15,45 @@
var/disabled_for = 0
var/diffused_for = 0
can_atmos_pass = ATMOS_PASS_YES
var/enabled_icon_state
/obj/effect/shield/update_icon()
if(gen && gen.check_flag(MODEFLAG_PHOTONIC) && !disabled_for && !diffused_for)
set_opacity(1)
/obj/effect/shield/proc/update_visuals()
update_iconstate()
update_color()
update_glow()
update_opacity()
/obj/effect/shield/proc/update_iconstate()
if(!enabled_icon_state)
enabled_icon_state = icon_state
if(disabled_for || diffused_for)
icon_state = "shield_broken"
overlays.Cut() //NOT ssoverlays
else
set_opacity(0)
icon_state = enabled_icon_state
flags |= OVERLAY_QUEUED //Trick SSoverlays
SSoverlays.queue += src
if(gen && gen.check_flag(MODEFLAG_OVERCHARGE))
icon_state = "shield_overcharged"
/obj/effect/shield/proc/update_color()
if(disabled_for || diffused_for)
color = "#FFA500"
else if(gen?.check_flag(MODEFLAG_OVERCHARGE))
color = "#FE6666"
else
icon_state = "shield_normal"
color = "#00AAFF"
/obj/effect/shield/proc/update_glow()
if(density)
set_light(3, 3, "#66FFFF")
else
set_light(0)
/obj/effect/shield/proc/update_opacity()
if(gen?.check_flag(MODEFLAG_PHOTONIC) && !disabled_for && !diffused_for)
set_opacity(1)
else
set_opacity(0)
// Prevents singularities and pretty much everything else from moving the field segments away.
// The only thing that is allowed to move us is the Destroy() proc.
@@ -42,7 +64,7 @@
/obj/effect/shield/Destroy()
if(can_atmos_pass != ATMOS_PASS_YES)
update_nearby_tiles()
update_nearby_tiles() //Force ZAS update
. = ..()
if(gen)
if(src in gen.field_segments)
@@ -59,12 +81,11 @@
if(gen)
gen.damaged_segments |= src
disabled_for += duration
set_density(0)
set_invisibility(INVISIBILITY_MAXIMUM)
update_nearby_tiles()
update_icon()
update_explosion_resistance()
set_density(0)
update_visuals()
update_nearby_tiles() //Force ZAS update
update_explosion_resistance()
// Regenerates this shield segment.
/obj/effect/shield/proc/regenerate()
@@ -76,25 +97,23 @@
if(!disabled_for && !diffused_for)
set_density(1)
set_invisibility(0)
update_nearby_tiles()
update_icon()
update_visuals()
update_nearby_tiles() //Force ZAS update
update_explosion_resistance()
gen.damaged_segments -= src
/obj/effect/shield/proc/diffuse(var/duration)
// The shield is trying to counter diffusers. Cause lasting stress on the shield.
if(gen.check_flag(MODEFLAG_BYPASS) && !disabled_for)
if(gen?.check_flag(MODEFLAG_BYPASS) && !disabled_for)
take_damage(duration * rand(8, 12), SHIELD_DAMTYPE_EM)
return
diffused_for = max(duration, 0)
gen.damaged_segments |= src
gen?.damaged_segments |= src
set_density(0)
set_invisibility(INVISIBILITY_MAXIMUM)
update_nearby_tiles()
update_icon()
update_visuals()
update_nearby_tiles() //Force ZAS update
update_explosion_resistance()
/obj/effect/shield/attack_generic(var/source, var/damage, var/emote)
@@ -191,7 +210,7 @@
if(new_value == can_atmos_pass)
return
can_atmos_pass = new_value
update_nearby_tiles()
update_nearby_tiles() //Force ZAS update
// EMP. It may seem weak but keep in mind that multiple shield segments are likely to be affected.
@@ -218,7 +237,7 @@
take_damage(proj.get_structure_damage(), SHIELD_DAMTYPE_HEAT)
else if (proj.damage_type == BRUTE)
take_damage(proj.get_structure_damage(), SHIELD_DAMTYPE_PHYSICAL)
else
else //TODO - This will never happen because of get_structure_damage() only returning values for BRUTE and BURN damage types
take_damage(proj.get_structure_damage(), SHIELD_DAMTYPE_EM)

View File

@@ -104,14 +104,8 @@
// Generates the field objects. Deletes existing field, if applicable.
/obj/machinery/power/shield_generator/proc/regenerate_field()
if(field_segments.len)
for(var/obj/effect/shield/S in field_segments)
qdel(S)
// The generator is not turned on, so don't generate any new tiles.
if(!running)
return
for(var/obj/effect/shield/S in field_segments)
qdel(S)
var/list/shielded_turfs
if(check_flag(MODEFLAG_HULL))
@@ -124,8 +118,145 @@
S.gen = src
S.flags_updated()
field_segments |= S
//Hull shield chaos icon generation
if(check_flag(MODEFLAG_HULL))
var/list/midsections = list()
var/list/startends = list()
var/list/corners = list()
var/list/horror = list()
for(var/obj/effect/shield/SE in field_segments)
var/adjacent_fields = 0
for(var/direction in cardinal)
var/turf/T = get_step(SE, direction)
var/obj/effect/shield/S = locate() in T
if(S)
adjacent_fields |= direction
//What?
if(!adjacent_fields)
horror += SE
testing("Solo shield turf at [SE.x], [SE.y], [SE.z]")
continue
//Middle section or corner (multiple bits set)
if((adjacent_fields & (adjacent_fields - 1)) != 0)
//'Impossible' directions
if(adjacent_fields == (NORTH|SOUTH) || adjacent_fields == (EAST|WEST))
midsections[SE] = adjacent_fields
//It's a simple corner
else //if (adjacent_fields in cornerdirs)
corners[SE] = adjacent_fields
//Not 0, not multiple bits, it's a start or an end
else
startends[SE] = adjacent_fields
//Midsections go first
for(var/obj/effect/shield/SE in midsections)
var/adjacent = midsections[SE]
var/turf/L = get_step(SE, ~adjacent & (SOUTH|WEST))
var/turf/R = get_step(SE, ~adjacent & (NORTH|EAST))
if(!isspace(L) && !isspace(R)) // Squished in a single tile gap of space!
switch(adjacent)
if(NORTH|SOUTH) //Middle vertical section
if(SE.x < src.x) //Left of generator goes north
SE.set_dir(NORTH)
else
SE.set_dir(SOUTH)
if(EAST|WEST) //Middle horizontal section
if(SE.y < src.y) //South of generator goes left
SE.set_dir(WEST)
else
SE.set_dir(EAST)
else if(isspace(L))
SE.set_dir(turn(~adjacent & (SOUTH|WEST), -90))
else
SE.set_dir(turn(~adjacent & (NORTH|EAST), -90))
midsections -= SE
//Corners
for(var/obj/effect/shield/S in corners)
var/adjacent = corners[S]
if(adjacent in cornerdirs)
do_corner_shield(S, adjacent) //Dir is adjacent fields direction
else
// Okay first a quick hack. If only one nonshield...
var/nonshield = adjacent ^ (NORTH|SOUTH|EAST|WEST)
if((nonshield & (nonshield - 1)) == 0)
if(!isspace(get_step(S, nonshield)))
S.set_dir(turn(nonshield, 90)) // We're basically a normal midsection just with another touching. Ignore it.
//What's this mysterious 3rd shield touching us?
var/dir_to_them = turn(nonshield, 180)
var/turf/T = get_step(S, dir_to_them)
var/obj/effect/shield/SO = locate() in T
//They are a corner
if((SO.dir & (SO.dir - 1)) != 0)
continue
else if(dir_to_them & SO.dir) //They're facing away from us, so we're their start
add_overlay(image(icon, icon_state = "shield_start" , dir = SO.dir))
else if(SO.dir & nonshield) //They're facing us (and the wall)
add_overlay(image(icon, icon_state = "shield_end" , dir = SO.dir))
else
var/list/touchnonshield = list()
for(var/direction in cornerdirs)
var/turf/T = get_step(S, direction)
if(!isspace(T))
touchnonshield += T
if(touchnonshield.len == 1)
do_corner_shield(S, get_dir(S, touchnonshield[1]))
else
S.icon_state = "capacitor"
else
// Not actually a corner... It has MULTIPLE!
S.icon_state = "arrow" //Error state/unhandled
for(var/obj/effect/shield/SE in midsections)
SE.icon_state = "arrow" //Error state/unhandled
for(var/obj/effect/shield/SE in field_segments)
SE.update_visuals()
//Phew, update our own icon
update_icon()
/obj/machinery/power/shield_generator/proc/do_corner_shield(var/obj/effect/shield/S, var/new_dir)
S.icon_state = "blank"
S.set_dir(new_dir)
var/inside = isspace(get_step(S, new_dir))
// TODO - Obviously this can be more elegant
if(inside)
switch(new_dir)
if(NORTHEAST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = SOUTH))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = EAST))
if(NORTHWEST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = EAST))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = NORTH))
if(SOUTHEAST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = WEST))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = SOUTH))
if(SOUTHWEST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = NORTH))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = WEST))
else
switch(new_dir)
if(NORTHEAST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = WEST))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = NORTH))
if(NORTHWEST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = SOUTH))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = WEST))
if(SOUTHEAST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = NORTH))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = EAST))
if(SOUTHWEST)
S.add_overlay(image(S.icon, icon_state = "shield_end", dir = EAST))
S.add_overlay(image(S.icon, icon_state = "shield_start", dir = SOUTH))
// Recalculates and updates the upkeep multiplier
/obj/machinery/power/shield_generator/proc/update_upkeep_multiplier()