mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-23 22:06:47 +01:00
cf585ef505
Makes ship combat significantly more destructive (and a bit deadlier), especially with non-explosive projectiles. **Additions:** - A shell that penetrates a solid (dense) structure will cause spalling. This spall does 2-30 damage, depending on range and has a high embed chance. These embedded chunks are large enough to be ripped out by hand. (But you probably shouldn't). The pilot's suit has 30 ballistic armor, so a prepared bridge crew can survive a lot of spall. - Adds a gun that shoots any ship weapon that admins can spawn. Useful for testing, or for adminbus where they don't want to have to spawn a whole overmap ship. - Made several structures destructible, vending machines, computer frames, grilles (these were just bugged) and watertanks (and their children). These structures could just block infinite shots and were common enough to serve as effective armor for the horizon. These now spawn shrapnel (of their material if it's set), in addition to sheets of steel when destroyed. - Added support for negative maim chance. This allows chosen projectiles to be prevented from decapitating. No more accidentally gibbing the bridge crew's heads. (Unless they get hit with something really really big). **Balance:** - All non-explosive anti ship rounds got significant buffs. Typically 2-3x Anti-Material numbers. - Armour piercing anti-ship rounds got massively increased penetration stats. Typically 4-8 from 1-2. - Doors now get destroyed in less hits, if they are hit by anti-material projectiles. Hits to destroy -= Antimaterial / 2 - Francisca frag shells now shoot less fragments but deal more damage. 394 projectiles for every shot was a bit laggy, now it's only 280. **Shields:** Shields now take more power. 13-14 megawatts for a 10 strength shield. Just inside the ship's generation capacity with both the INDRA and Supermatter running. Instead of deleting any projectile they are hit by, shields now have different failure modes. - Firstly, a piercing projectile has it's penetration reduced by the shield strength. Eg A shot that would go through 10 walls, only penetrates 4 after going through a 6 strength shield. - Secondly, a projectile has it's damage multiplied by 1 - shield strength / 10, then has shield strength subtracted from it's damage. Eg. A damage 100 projectile, hitting a 5 strength shield, has it's damaged reduced to 50, (100 * 0.5), then to 45. (50-5) - Thirdly, an explosive projectile (that does not penetrate per the first step) does not explode, but instead deals it's full damage to the shield. Hits to the shield now also damage the field itself, not just the shield tile. As such, a very big hit on the shield can bring the whole thing down, requiring an engineer to reset it. Shields can now be upgraded with research components. Additionally, shield generators can now support more than one capacitor. The roundstart capacitor on the Horizon is only good enough to support a 6 strength shield. The upgrades increase efficiency, strength loss over time and charge speed. **Overmap Targetting** Previously, shells would spawn within 20 tiles of their target and aim directly forwards. This was bugged for shots with burst, which would instead all aim inwards and mostly miss. This is the reason the Grauwolf (in addition to the explosion bug below) and Fransisca felt so useless, only one of every shell in a burst would hit. Shots now spawn at the map edge, based on the orientation of the projectile and ship. Diagonals are now accounted for. Shots are then aimed directly at the target selected on the console, with 3 degrees of dispersion. **Bugfixes:** - Fixes lots of explosions that didn't pass a turf to the explosions subsystem. This caused the explosion not to happen if the thing hit got qdeled before the subsystem could get the turf to spawn the explosion on. - Embedded shrapnel no longer gets the initial projectile name, this prevents it getting named shrapnelshrapnel. - Fixes a bunch of projectile piercing bugs, mostly with grilles and windows. Shots now go past window frames without hitting them. - Fixes shields not having a click delay when attacked. --------- Signed-off-by: FenodyreeAv <fenodyree.av@gmail.com> Co-authored-by: Matt Atlas <mattiathebest2000@hotmail.it>
815 lines
25 KiB
Plaintext
815 lines
25 KiB
Plaintext
/obj/structure/window
|
|
name = "glass pane"
|
|
desc = "A glass pane."
|
|
icon = 'icons/obj/structure/window/window_panes.dmi'
|
|
icon_state = "window"
|
|
alpha = 196
|
|
density = TRUE
|
|
pass_flags_self = PASSWINDOW
|
|
w_class = WEIGHT_CLASS_NORMAL
|
|
layer = OBJ_LAYER
|
|
anchored = TRUE
|
|
atom_flags = ATOM_FLAG_CHECKS_BORDER
|
|
obj_flags = OBJ_FLAG_ROTATABLE|OBJ_FLAG_MOVES_UNSUPPORTED
|
|
maxhealth = OBJECT_HEALTH_FRAGILE
|
|
hitsound = 'sound/effects/glass_hit.ogg'
|
|
|
|
var/maximal_heat = T0C + 100 // Maximal heat before this window begins taking damage from fire
|
|
var/damage_per_fire_tick = 2 // Amount of damage per fire tick. Regular windows are not fireproof so they might as well break quickly.
|
|
var/ini_dir = null
|
|
var/state = 2
|
|
var/reinf = FALSE
|
|
var/basestate
|
|
var/shardtype = /obj/item/material/shard
|
|
var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass.
|
|
var/silicate = 0 // number of units of silicate
|
|
var/base_frame = null
|
|
var/full = FALSE
|
|
|
|
atmos_canpass = CANPASS_PROC
|
|
|
|
/obj/structure/window/get_damage_condition_hints(mob/user, distance, is_adjacent)
|
|
if(health == maxhealth)
|
|
. = SPAN_NOTICE("It looks fully intact.")
|
|
else
|
|
var/perc = health / maxhealth
|
|
if(perc > 0.75)
|
|
. = SPAN_NOTICE("It has a few cracks.")
|
|
else if(perc > 0.5)
|
|
. = SPAN_WARNING("It looks slightly damaged.")
|
|
else if(perc > 0.25)
|
|
. = SPAN_WARNING("It looks moderately damaged.")
|
|
else
|
|
. = SPAN_DANGER("It looks heavily damaged.")
|
|
if(silicate)
|
|
if (silicate < 30)
|
|
. = SPAN_NOTICE("It has a thin layer of silicate.")
|
|
else if (silicate < 70)
|
|
. = SPAN_NOTICE("It is covered in silicate.")
|
|
else
|
|
. = SPAN_NOTICE("There is a thick layer of silicate covering it.")
|
|
|
|
/obj/structure/window/proc/update_nearby_icons()
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
/obj/structure/window/update_icon()
|
|
if(!full)
|
|
if(dir == SOUTH)
|
|
layer = ABOVE_HUMAN_LAYER
|
|
QUEUE_SMOOTH(src)
|
|
|
|
/obj/structure/window/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon, message)
|
|
shatter(message)
|
|
|
|
/obj/structure/window/proc/apply_silicate(var/amount)
|
|
if(health < maxhealth) // Mend the damage.
|
|
add_health(amount * 3)
|
|
if(health == maxhealth)
|
|
visible_message(SPAN_NOTICE("The silicate fully mends the damage on \the [src]."))
|
|
else // Reinforce.
|
|
silicate = min(silicate + amount, 100)
|
|
updateSilicate()
|
|
|
|
/obj/structure/window/proc/updateSilicate()
|
|
ClearOverlays()
|
|
|
|
var/image/img = image(icon, icon_state)
|
|
img.color = "#ffffff"
|
|
img.alpha = silicate * 255 / 100
|
|
AddOverlays(img)
|
|
|
|
/obj/structure/window/proc/shatter(var/display_message = 1)
|
|
playsound(src, SFX_BREAK_GLASS, 70, 1)
|
|
if(display_message)
|
|
visible_message(SPAN_WARNING("\The [src] shatters!"))
|
|
if(dir == SOUTHWEST)
|
|
var/index = null
|
|
index = 0
|
|
while(index < 2)
|
|
new shardtype(loc)
|
|
if(reinf)
|
|
new /obj/item/stack/rods(loc)
|
|
index++
|
|
else
|
|
new shardtype(loc)
|
|
if(reinf)
|
|
new /obj/item/stack/rods(loc)
|
|
|
|
if(base_frame)
|
|
if(prob(50))
|
|
var/obj/F = new base_frame(loc)
|
|
F.anchored = anchored
|
|
else
|
|
new /obj/item/material/shard/shrapnel(loc)
|
|
|
|
qdel(src)
|
|
return
|
|
|
|
/obj/structure/window/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
|
var/proj_damage = hitting_projectile.get_structure_damage()
|
|
if(!proj_damage)
|
|
return BULLET_ACT_BLOCK
|
|
|
|
. = ..()
|
|
if(. != BULLET_ACT_HIT)
|
|
return .
|
|
|
|
add_damage(proj_damage, hitting_projectile.damage_flags(), hitting_projectile.damage_type, hitting_projectile.armor_penetration, hitting_projectile)
|
|
|
|
/obj/structure/window/ex_act(severity)
|
|
switch(severity)
|
|
if(1)
|
|
qdel(src)
|
|
if(2)
|
|
shatter(0)
|
|
if(3)
|
|
if(prob(50))
|
|
shatter(0)
|
|
else
|
|
add_damage(rand(10,30), TRUE, FALSE)
|
|
|
|
// This and relevant verbs/procs can probably be removed since full windows are a thing now. -Gem
|
|
/obj/structure/window/proc/is_full_window()
|
|
return (dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST)
|
|
|
|
/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
|
if(mover?.movement_type & PHASING)
|
|
return TRUE
|
|
if(istype(mover) && mover.pass_flags & PASSGLASS)
|
|
return TRUE
|
|
if(is_full_window())
|
|
return !density //full tile window, you can't move into it if it's solid!
|
|
var/movingdir = get_dir(loc,target)
|
|
if(movingdir == 0)
|
|
movingdir = get_dir(loc,mover)
|
|
if(movingdir & dir)
|
|
return !density
|
|
else
|
|
return TRUE
|
|
|
|
/obj/structure/window/CheckExit(atom/movable/O, turf/target)
|
|
if(istype(O) && O.pass_flags & PASSGLASS)
|
|
return 1
|
|
if(get_dir(O.loc, target) == dir)
|
|
return 0
|
|
return 1
|
|
|
|
/obj/structure/window/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
|
..()
|
|
var/tforce = 0
|
|
if(ismob(hitting_atom))
|
|
if(isliving(hitting_atom))
|
|
var/mob/living/M = hitting_atom
|
|
M.turf_collision(src, throwingdatum.speed, SFX_GLASS_CRACK)
|
|
return
|
|
else
|
|
visible_message(SPAN_DANGER("\The [src] was hit by \the [hitting_atom]."))
|
|
tforce = 40
|
|
else if(isobj(hitting_atom))
|
|
visible_message(SPAN_DANGER("\The [src] was hit by \the [hitting_atom]."))
|
|
var/obj/item/I = hitting_atom
|
|
tforce = I.throwforce
|
|
if(reinf)
|
|
tforce *= 0.25
|
|
add_damage(tforce)
|
|
|
|
/obj/structure/window/attack_hand(var/mob/living/user)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
if((user.mutations & HULK) && !(user.isSynthetic()) && !(isvaurca(user)))
|
|
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
|
|
user.visible_message(SPAN_DANGER("[user] smashes through [src]!"))
|
|
user.do_attack_animation(src)
|
|
shatter()
|
|
|
|
else if (user.a_intent == I_HURT)
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
if(H.species.can_shred(H) || (H.is_berserk()))
|
|
attack_generic(H,25)
|
|
return
|
|
|
|
playsound(src.loc, 'sound/effects/glass_knock.ogg', 90, 1)
|
|
user.do_attack_animation(src)
|
|
user.visible_message(SPAN_DANGER("\The [user] bangs against \the [src]!"),
|
|
SPAN_DANGER("You bang against \the [src]!"),
|
|
"You hear a banging sound.")
|
|
else
|
|
playsound(src.loc, 'sound/effects/glass_knock.ogg', 60, 1)
|
|
user.visible_message("<b>[user]</b> knocks on \the [src.name].",
|
|
"You knock on \the [src.name].",
|
|
"You hear a knocking sound.")
|
|
return
|
|
|
|
/obj/structure/window/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
if(damage >= 10)
|
|
visible_message(SPAN_DANGER("[user] smashes into [src]!"))
|
|
add_damage(damage)
|
|
else
|
|
visible_message(SPAN_NOTICE("\The [user] bonks \the [src] harmlessly."))
|
|
playsound(src.loc, 'sound/effects/glass_hit.ogg', 10, 1, -2)
|
|
user.do_attack_animation(src)
|
|
return 1
|
|
|
|
/obj/structure/window/do_simple_ranged_interaction(var/mob/user)
|
|
visible_message(SPAN_NOTICE("Something knocks on \the [src]."))
|
|
playsound(loc, 'sound/effects/glass_hit.ogg', 50, 1)
|
|
return TRUE
|
|
|
|
/obj/structure/window/attackby(obj/item/attacking_item, mob/user)
|
|
if(!istype(attacking_item) || istype(attacking_item, /obj/item/flag))
|
|
return
|
|
|
|
// Slamming someone against the window interaction
|
|
if(istype(attacking_item, /obj/item/grab) && get_dist(src,user)<2)
|
|
var/obj/item/grab/G = attacking_item
|
|
if(istype(G.affecting, /mob/living))
|
|
grab_smash_attack(G, DAMAGE_BRUTE)
|
|
return
|
|
|
|
if(attacking_item.item_flags & ITEM_FLAG_NO_BLUDGEON)
|
|
return
|
|
|
|
if(handle_construction(attacking_item, user))
|
|
return
|
|
|
|
. = ..()
|
|
|
|
/obj/structure/window/proc/handle_construction(obj/item/attacking_item, mob/user)
|
|
// Screwdriver
|
|
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != I_HURT)
|
|
if(reinf && state >= 1)
|
|
state = 3 - state
|
|
update_nearby_icons()
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
to_chat(user, (state == 1 ? SPAN_NOTICE("You have unfastened the window from the frame.") : SPAN_NOTICE("You have fastened the window to the frame.")))
|
|
|
|
else if(reinf && state == 0)
|
|
anchored = !anchored
|
|
update_icon()
|
|
update_nearby_icons()
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the frame to the floor.") : SPAN_NOTICE("You have unfastened the frame from the floor.")))
|
|
|
|
else
|
|
anchored = !anchored
|
|
update_nearby_icons()
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the window to the floor.") : SPAN_NOTICE("You have unfastened the window.")))
|
|
update_icon()
|
|
update_nearby_icons()
|
|
|
|
return TRUE
|
|
|
|
// Crowbar
|
|
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && reinf && state <= 1 && user.a_intent != I_HURT)
|
|
state = 1 - state
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
to_chat(user, (state ? SPAN_NOTICE("You have pried the window into the frame.") : SPAN_NOTICE("You have pried the window out of the frame.")))
|
|
return TRUE
|
|
|
|
// Wrench
|
|
else if(attacking_item.tool_behaviour == TOOL_WRENCH && !anchored && (!state || !reinf) && user.a_intent != I_HURT)
|
|
if(!glasstype)
|
|
to_chat(user, SPAN_NOTICE("You're not sure how to dismantle \the [src] properly."))
|
|
else
|
|
visible_message(SPAN_NOTICE("[user] dismantles \the [src]."))
|
|
dismantle_window()
|
|
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/obj/structure/window/proc/grab_smash_attack(obj/item/grab/G, var/damtype = DAMAGE_BRUTE)
|
|
var/mob/living/M = G.affecting
|
|
var/mob/living/user = G.assailant
|
|
|
|
var/state = G.state
|
|
qdel(G) //gotta delete it here because if window breaks, it won't get deleted
|
|
|
|
var/def_zone = ran_zone(BP_HEAD, 20)
|
|
switch (state)
|
|
if(1)
|
|
M.visible_message(SPAN_WARNING("[user] slams [M] against \the [src]!"))
|
|
M.apply_damage(7, damtype, def_zone, used_weapon = src)
|
|
hit(10)
|
|
if(2)
|
|
M.visible_message(SPAN_DANGER("[user] bashes [M] against \the [src]!"))
|
|
if (prob(50))
|
|
M.Weaken(1)
|
|
M.apply_damage(10, damtype, def_zone, used_weapon = src)
|
|
hit(25)
|
|
if(3)
|
|
M.visible_message(SPAN_DANGER("<big>[user] crushes [M] against \the [src]!</big>"))
|
|
M.Weaken(5)
|
|
M.apply_damage(20, damtype, def_zone, used_weapon = src)
|
|
hit(50)
|
|
|
|
/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1)
|
|
if(reinf)
|
|
damage *= 0.5
|
|
add_damage(damage)
|
|
|
|
/obj/structure/window/proc/dismantle_window()
|
|
if(dir == SOUTHWEST)
|
|
var/obj/item/stack/material/mats = new glasstype(loc)
|
|
mats.amount = is_fulltile() ? 4 : 2
|
|
else
|
|
new glasstype(loc)
|
|
qdel(src)
|
|
|
|
/obj/structure/window/Initialize(mapload, start_dir = null, constructed = 0)
|
|
. = ..()
|
|
if(!full && constructed)
|
|
anchored = FALSE
|
|
|
|
if (!mapload && constructed)
|
|
state = 0
|
|
|
|
if (start_dir)
|
|
set_dir(start_dir)
|
|
|
|
ini_dir = dir
|
|
|
|
update_nearby_tiles(need_rebuild=1)
|
|
update_nearby_icons()
|
|
update_icon()
|
|
|
|
/obj/structure/window/Destroy()
|
|
density = 0
|
|
update_nearby_tiles()
|
|
var/turf/location = loc
|
|
loc = null
|
|
|
|
for(var/obj/structure/window/W in orange(location, 1))
|
|
W.update_icon()
|
|
|
|
for(var/obj/structure/table/T in view(location, 1))
|
|
T.update_connections()
|
|
T.update_icon()
|
|
|
|
loc = location
|
|
|
|
return ..()
|
|
|
|
/obj/structure/window/Move()
|
|
var/ini_dir = dir
|
|
var/oldloc = loc
|
|
|
|
update_nearby_tiles(need_rebuild=1)
|
|
|
|
. = ..()
|
|
|
|
set_dir(ini_dir)
|
|
update_nearby_tiles(need_rebuild=1)
|
|
|
|
if(loc != oldloc)
|
|
for(var/obj/structure/table/T in view(oldloc, 1) | view(loc, 1))
|
|
T.update_connections()
|
|
T.update_icon()
|
|
|
|
/obj/structure/window/proc/is_fulltile() // Checks if this window is a full-tile one.
|
|
if(dir & (dir - 1))
|
|
return 1
|
|
return 0
|
|
|
|
/obj/structure/window/fire_act(exposed_temperature, exposed_volume)
|
|
if(exposed_temperature > maximal_heat)
|
|
hit(damage_per_fire_tick, 0)
|
|
..()
|
|
|
|
/********** Glass and Glass Panes **********/
|
|
/obj/structure/window/basic
|
|
name = "glass pane"
|
|
desc = "It looks thin and flimsy. A few hits with anything will shatter it."
|
|
icon_state = "window"
|
|
basestate = "window"
|
|
glasstype = /obj/item/stack/material/glass
|
|
maximal_heat = T0C + 100
|
|
damage_per_fire_tick = 2
|
|
maxhealth = OBJECT_HEALTH_FRAGILE
|
|
|
|
/obj/structure/window/basic/full
|
|
name = "glass"
|
|
icon_state = "window"
|
|
dir = 5
|
|
|
|
/obj/structure/window/reinforced
|
|
name = "reinforced glass pane"
|
|
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
|
icon_state = "rwindow"
|
|
basestate = "rwindow"
|
|
maxhealth = OBJECT_HEALTH_LOW
|
|
reinf = TRUE
|
|
maximal_heat = T0C + 750
|
|
damage_per_fire_tick = 2
|
|
glasstype = /obj/item/stack/material/glass/reinforced
|
|
|
|
/obj/structure/window/reinforced/full
|
|
name = "reinforced glass"
|
|
icon_state = "rwindow"
|
|
dir = 5
|
|
|
|
/obj/structure/window/reinforced/tinted
|
|
name = "reinforced tinted glass pane"
|
|
desc = "It looks rather strong and opaque. Might take a few good hits to shatter it."
|
|
icon_state = "twindow"
|
|
basestate = "twindow"
|
|
opacity = 1
|
|
|
|
/obj/structure/window/reinforced/tinted/frosted
|
|
name = "reinforced frosted glass pane"
|
|
desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window."
|
|
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
|
|
|
|
/obj/structure/window/reinforced/polarized
|
|
name = "reinforced electrochromic glass pane"
|
|
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
|
var/id
|
|
|
|
/obj/structure/window/reinforced/polarized/proc/toggle()
|
|
if(opacity)
|
|
animate(src, color="#FFFFFF", time=5)
|
|
set_opacity(0)
|
|
else
|
|
animate(src, color="#222222", time=5)
|
|
set_opacity(1)
|
|
|
|
/obj/structure/window/reinforced/crescent/attack_hand()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/attackby()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/ex_act(var/severity = 2)
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/shatter()
|
|
return
|
|
|
|
/obj/structure/machinery/button/switch/windowtint
|
|
name = "window tint control"
|
|
desc = "A remote control switch for polarized windows."
|
|
var/range = 16
|
|
|
|
/obj/structure/machinery/button/switch/windowtint/update_icon()
|
|
icon_state = "light[active]"
|
|
|
|
/obj/structure/machinery/button/switch/windowtint/attack_hand(mob/user as mob)
|
|
if(..())
|
|
return TRUE
|
|
|
|
toggle_tint()
|
|
|
|
/obj/structure/machinery/button/switch/windowtint/proc/toggle_tint()
|
|
use_power_oneoff(5)
|
|
|
|
active = !active
|
|
update_icon()
|
|
|
|
for(var/obj/structure/window/reinforced/polarized/W in range(src, range))
|
|
if(W.id == src.id || !W.id)
|
|
W.toggle()
|
|
|
|
for(var/obj/structure/window/full/reinforced/polarized/W in range(src, range))
|
|
if(W.id == src.id || !W.id)
|
|
W.toggle()
|
|
|
|
/obj/structure/machinery/button/switch/windowtint/power_change()
|
|
..()
|
|
if(active && !powered(power_channel))
|
|
toggle_tint()
|
|
|
|
/obj/structure/window/borosilicate
|
|
name = "borosilicate glass pane"
|
|
desc = "A borosilicate alloy window. It seems to be quite strong."
|
|
color = GLASS_COLOR_PHORON
|
|
shardtype = /obj/item/material/shard/phoron
|
|
glasstype = /obj/item/stack/material/glass/phoronglass
|
|
maximal_heat = T0C + 2000
|
|
damage_per_fire_tick = 1 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while.
|
|
maxhealth = OBJECT_HEALTH_VERY_LOW
|
|
/// Phoron-infused silicate
|
|
rad_resistance_modifier = 4
|
|
|
|
/obj/structure/window/borosilicate/reinforced
|
|
name = "reinforced borosilicate glass pane"
|
|
desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong."
|
|
color = GLASS_COLOR_PHORON_R
|
|
glasstype = /obj/item/stack/material/glass/phoronrglass
|
|
reinf = TRUE
|
|
maximal_heat = T0C + 4000
|
|
maxhealth = OBJECT_HEALTH_LOW
|
|
|
|
/obj/structure/window/borosilicate/reinforced/skrell
|
|
name = "advanced borosilicate alloy window"
|
|
desc = "A window made out of a higly advanced borosilicate alloy. It seems to be extremely strong."
|
|
color = GLASS_COLOR_PHORON
|
|
maxhealth = OBJECT_HEALTH_HIGH
|
|
|
|
/********** Shuttle Windows **********/
|
|
/obj/structure/window/shuttle
|
|
name = "reinforced shuttle window"
|
|
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
|
icon = 'icons/obj/smooth/shuttle_window.dmi'
|
|
icon_state = "shuttle_window"
|
|
basestate = "w"
|
|
atom_flags = 0
|
|
obj_flags = null
|
|
maxhealth = OBJECT_HEALTH_VERY_LOW
|
|
reinf = TRUE
|
|
dir = 5
|
|
smoothing_flags = SMOOTH_TRUE
|
|
can_be_unanchored = TRUE
|
|
layer = FULL_WINDOW_LAYER
|
|
rad_resistance_modifier = 4
|
|
|
|
/obj/structure/window/shuttle/mouse_drop_receive(atom/dropping, mob/user, params)
|
|
//Adds the component only once. We do it here & not in Initialize() because there are tons of walls & we don't want to add to their init times
|
|
LoadComponent(/datum/component/leanable, dropping)
|
|
|
|
/obj/structure/window/shuttle/legion
|
|
name = "reinforced cockpit window"
|
|
icon = 'icons/obj/smooth/shuttle_window_legion.dmi'
|
|
maxhealth = OBJECT_HEALTH_HIGH
|
|
|
|
/obj/structure/window/shuttle/palepurple
|
|
icon = 'icons/obj/smooth/shuttle_window_palepurple.dmi'
|
|
|
|
/obj/structure/window/shuttle/skrell
|
|
name = "advanced borosilicate alloy window"
|
|
desc = "It looks extremely strong. Might take many good hits to crack it."
|
|
icon = 'icons/obj/smooth/skrell_window_purple.dmi'
|
|
maxhealth = OBJECT_HEALTH_VERY_HIGH
|
|
smoothing_flags = SMOOTH_MORE | SMOOTH_DIAGONAL
|
|
canSmoothWith = list(
|
|
/turf/simulated/wall/shuttle/skrell,
|
|
/obj/structure/window/shuttle/skrell
|
|
)
|
|
|
|
/obj/structure/window/shuttle/scc_space_ship
|
|
name = "advanced borosilicate alloy window"
|
|
desc = "It looks extremely strong. Might take many good hits to crack it."
|
|
icon = 'icons/turf/smooth/scc_ship/scc_ship_windows.dmi'
|
|
icon_state = "map_window"
|
|
maxhealth = OBJECT_HEALTH_VERY_HIGH
|
|
alpha = 255
|
|
smoothing_flags = SMOOTH_MORE
|
|
canSmoothWith = list(
|
|
/obj/structure/window/shuttle/scc_space_ship,
|
|
/turf/simulated/wall/shuttle/scc_space_ship,
|
|
/turf/unsimulated/wall/shuttle/scc_space_ship
|
|
)
|
|
blend_overlay = "-wall"
|
|
attach_overlay = "attach"
|
|
can_blend_with = list(
|
|
/turf/simulated/wall/shuttle/scc_space_ship,
|
|
/turf/unsimulated/wall/shuttle/scc_space_ship,
|
|
/obj/structure/window/shuttle/scc_space_ship
|
|
)
|
|
|
|
|
|
/obj/structure/window/shuttle/scc_space_ship/cardinal
|
|
smoothing_flags = SMOOTH_MORE
|
|
|
|
/obj/structure/window/shuttle/scc_space_ship/cardinal_smooth(adjacencies, var/list/dir_mods)
|
|
dir_mods = handle_blending(adjacencies, dir_mods)
|
|
return ..(adjacencies, dir_mods)
|
|
|
|
/obj/structure/window/shuttle/scc
|
|
icon = 'icons/obj/smooth/scc_shuttle_window.dmi'
|
|
maxhealth = OBJECT_HEALTH_HIGH
|
|
|
|
/obj/structure/window/shuttle/crescent
|
|
desc = "It looks rather strong."
|
|
|
|
//
|
|
// Full Windows
|
|
//
|
|
/obj/structure/window/full
|
|
name = "window"
|
|
desc = "You aren't supposed to see this."
|
|
atom_flags = 0
|
|
obj_flags = null
|
|
dir = 5
|
|
maxhealth = OBJECT_HEALTH_EXTREMELY_LOW
|
|
glasstype = /obj/item/stack/material/glass
|
|
shardtype = /obj/item/material/shard
|
|
full = TRUE
|
|
layer = FULL_WINDOW_LAYER
|
|
base_frame = /obj/structure/window_frame
|
|
smoothing_flags = SMOOTH_MORE
|
|
canSmoothWith = list(
|
|
/turf/simulated/wall,
|
|
/turf/simulated/wall/r_wall,
|
|
/turf/unsimulated/wall/steel,
|
|
/turf/unsimulated/wall/darkshuttlewall,
|
|
/turf/unsimulated/wall/riveted,
|
|
/turf/unsimulated/wall/fakepdoor,
|
|
/obj/structure/window_frame,
|
|
/obj/structure/window_frame/unanchored,
|
|
/obj/structure/window_frame/empty,
|
|
/obj/structure/window/full/reinforced,
|
|
/obj/structure/window/full/reinforced/indestructible,
|
|
/obj/structure/window/full/reinforced/polarized,
|
|
/obj/structure/window/full/reinforced/polarized/indestructible,
|
|
/obj/structure/window/full/phoron/reinforced,
|
|
/obj/structure/window/shuttle/scc_space_ship,
|
|
/turf/simulated/wall/shuttle/scc_space_ship,
|
|
/obj/structure/machinery/door
|
|
)
|
|
blend_overlay = "wall"
|
|
attach_overlay = "attach"
|
|
can_blend_with = list(
|
|
/turf/simulated/wall,
|
|
/obj/structure/machinery/door,
|
|
/obj/structure/window_frame
|
|
)
|
|
|
|
/obj/structure/window/full/Destroy()
|
|
var/obj/structure/window_frame/WF = locate(/obj/structure/window_frame) in get_turf(src)
|
|
if(WF)
|
|
WF.has_glass_installed = FALSE
|
|
return ..()
|
|
|
|
/obj/structure/window/full/handle_construction(obj/item/attacking_item, mob/user)
|
|
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != I_HURT)
|
|
if(state == 2)
|
|
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
|
|
to_chat(user, SPAN_NOTICE("You have unfastened the glass from the window frame."))
|
|
state--
|
|
update_nearby_icons()
|
|
return TRUE
|
|
|
|
else if(state == 1)
|
|
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
|
|
to_chat(user, SPAN_NOTICE("You have fastened the glass to the window frame."))
|
|
state++
|
|
update_nearby_icons()
|
|
return TRUE
|
|
|
|
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && user.a_intent != I_HURT)
|
|
if(state == 1)
|
|
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
|
|
to_chat(user, SPAN_NOTICE("You pry the glass out of the window frame."))
|
|
state--
|
|
update_nearby_icons()
|
|
return TRUE
|
|
|
|
else if(state == 0)
|
|
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
|
|
to_chat(user, SPAN_NOTICE("You pry the glass into the window frame."))
|
|
state++
|
|
update_nearby_icons()
|
|
return TRUE
|
|
|
|
else if(attacking_item.tool_behaviour == TOOL_WRENCH && user.a_intent != I_HURT)
|
|
if(state == 0)
|
|
user.visible_message(SPAN_DANGER("\The [user] is dismantling \the [src]!"))
|
|
if(attacking_item.use_tool(src, user, 2 SECONDS, volume = 50))
|
|
to_chat(user, SPAN_NOTICE("You undo the safety bolts and remove the glass from \the [src]."))
|
|
dismantle_window()
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/obj/structure/window/full/shatter(var/display_message = 1)
|
|
playsound(src, SFX_BREAK_GLASS, 70, 1)
|
|
if(display_message)
|
|
visible_message(SPAN_WARNING("\The [src] shatters!"))
|
|
if(reinf)
|
|
new /obj/item/stack/rods(loc, 4)
|
|
for(var/i = 1 to 4)
|
|
new shardtype(loc)
|
|
|
|
qdel(src)
|
|
return
|
|
|
|
/obj/structure/window/full/dismantle_window()
|
|
var/obj/item/stack/material/mats = new glasstype(loc)
|
|
mats.amount = 4
|
|
var/obj/structure/window_frame/WF = locate(/obj/structure/window_frame) in get_turf(src)
|
|
if(istype(WF))
|
|
WF.has_glass_installed = FALSE
|
|
WF.desc = "An empty steel window frame."
|
|
qdel(src)
|
|
update_nearby_icons()
|
|
|
|
/obj/structure/window/full/mouse_drop_receive(atom/dropping, mob/user, params)
|
|
//Adds the component only once. We do it here & not in Initialize() because there are tons of walls & we don't want to add to their init times
|
|
LoadComponent(/datum/component/leanable, dropping)
|
|
|
|
/********** Full Windows **********/
|
|
// Reinforced Window
|
|
/obj/structure/window/full/reinforced
|
|
name = "reinforced window"
|
|
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
|
icon = 'icons/obj/smooth/window/full_window.dmi'
|
|
icon_state = "window_glass"
|
|
basestate = "window_glass"
|
|
maxhealth = OBJECT_HEALTH_LOW
|
|
reinf = TRUE
|
|
maximal_heat = T0C + 750
|
|
glasstype = /obj/item/stack/material/glass/reinforced
|
|
layer = FULL_WINDOW_LAYER
|
|
base_frame = /obj/structure/window_frame
|
|
smoothing_flags = SMOOTH_MORE
|
|
|
|
/obj/structure/window/full/cardinal_smooth(adjacencies, var/list/dir_mods)
|
|
dir_mods = handle_blending(adjacencies, dir_mods)
|
|
return ..(adjacencies, dir_mods)
|
|
|
|
/obj/structure/window_frame/proc/update_nearby_icons()
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
/obj/structure/window_frame/update_icon()
|
|
QUEUE_SMOOTH(src)
|
|
|
|
// Indestructible Reinforced Window
|
|
/obj/structure/window/full/reinforced/indestructible/attack_hand()
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/indestructible/attackby()
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/indestructible/ex_act(var/severity = 2)
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/indestructible/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/indestructible/shatter()
|
|
return
|
|
|
|
// Reinforced Polarized Window
|
|
/obj/structure/window/full/reinforced/polarized
|
|
name = "reinforced electrochromic window"
|
|
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
|
var/id
|
|
|
|
/obj/structure/window/full/reinforced/polarized/proc/toggle()
|
|
if(opacity)
|
|
animate(src, color="#FFFFFF", time = 1 SECOND)
|
|
set_opacity(FALSE)
|
|
else
|
|
animate(src, color="#606060", time = 1 SECOND)
|
|
set_opacity(TRUE)
|
|
|
|
// Indestructible Reinforced Polarized Window
|
|
/obj/structure/window/full/reinforced/polarized/indestructible/attack_hand()
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/polarized/indestructible/attackby()
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/polarized/indestructible/ex_act(var/severity = 2)
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/polarized/indestructible/hitby(atom/movable/hitting_atom, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
|
return
|
|
|
|
/obj/structure/window/full/reinforced/polarized/indestructible/shatter()
|
|
return
|
|
|
|
//Shuttle exterior window
|
|
/obj/structure/window/full/reinforced/shuttle
|
|
icon = 'icons/obj/smooth/window/shuttle_window_dark.dmi'
|
|
color = "#006eff"
|
|
icon_state = "window_glass"
|
|
basestate = "window_glass"
|
|
|
|
/obj/structure/window/full/reinforced/shuttle/red
|
|
color = "#ff0000"
|
|
|
|
/obj/structure/window/full/reinforced/shuttle/green
|
|
color = "#00ff40"
|
|
|
|
/obj/structure/window/full/reinforced/shuttle/black
|
|
color = "#150b41"
|
|
|
|
// Borosilicate Window (I.e. Phoron Window)
|
|
/obj/structure/window/full/phoron
|
|
name = "borosilicate window"
|
|
desc = "You aren't supposed to see this."
|
|
icon = 'icons/obj/smooth/window/full_window_phoron.dmi'
|
|
icon_state = "window_glass"
|
|
basestate = "window_glass"
|
|
glasstype = /obj/item/stack/material/glass/phoronglass
|
|
shardtype = /obj/item/material/shard/phoron
|
|
maxhealth = OBJECT_HEALTH_LOW
|
|
maximal_heat = T0C + 2000
|
|
damage_per_fire_tick = 1
|
|
|
|
// Reinforced Borosilicate Window (I.e. Reinforced Phoron Window)
|
|
/obj/structure/window/full/phoron/reinforced
|
|
name = "reinforced borosilicate window"
|
|
desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong."
|
|
glasstype = /obj/item/stack/material/glass/phoronrglass
|
|
maxhealth = OBJECT_HEALTH_MEDIUM
|
|
reinf = TRUE
|
|
maximal_heat = T0C + 4000
|
|
rad_resistance_modifier = 4
|