/obj/window name = "window" icon = 'icons/obj/window.dmi' icon_state = "window" desc = "A window." density = 1 dir = 5 //full tile flags = FPRINT | USEDELAY | ON_BORDER var/health = 30 var/health_max = 30 var/health_multiplier = 1 var/ini_dir = null var/state = 2 var/hitsound = 'sound/effects/Glasshit.ogg' var/shattersound = "shatter" var/datum/material/reinforcement = null var/blunt_resist = 0 var/cut_resist = 0 var/stab_resist = 0 var/corrode_resist = 0 var/temp_resist = 0 var/default_material = "glass" var/default_reinforcement = null var/reinf = 0 // cant figure out how to remove this without the map crying aaaaa - ISN var/deconstruct_time = 0//20 pressure_resistance = 4*ONE_ATMOSPHERE anchored = 1 New() ..() if (map_setting == "COG2") layer = COG2_WINDOW_LAYER src.ini_dir = src.dir update_nearby_tiles(need_rebuild=1) var/datum/material/M if (default_material) M = getCachedMaterial(default_material) src.setMaterial(M) if (default_reinforcement) src.reinforcement = getCachedMaterial(default_reinforcement) onMaterialChanged() // The health multiplier var wasn't implemented at all, apparently (Convair880)? if (src.health_multiplier != 1 && src.health_multiplier > 0) src.health_max = src.health_max * src.health_multiplier src.health = src.health_max //DEBUG_MESSAGE("[src.name] [log_loc(src)] has [health] health / [health_max] max health ([health_multiplier] multiplier).") return disposing() density = 0 update_nearby_tiles() ..() Move() update_nearby_tiles(need_rebuild=1) ..() src.dir = src.ini_dir update_nearby_tiles(need_rebuild=1) return onMaterialChanged() ..() name = initial(name) if (istype(src.material)) health_max = material.hasProperty(PROP_TOUGHNESS) ? material.getProperty(PROP_TOUGHNESS) : health health = health_max cut_resist = material.hasProperty(PROP_SHEAR) ? material.getProperty(PROP_SHEAR) : cut_resist blunt_resist = material.hasProperty(PROP_COMPRESSIVE) ? material.getProperty(PROP_COMPRESSIVE) : blunt_resist stab_resist = material.hasProperty(PROP_HARDNESS) ? material.getProperty(PROP_HARDNESS) : stab_resist if (blunt_resist != 0) blunt_resist /= 2 corrode_resist = material.hasProperty(PROP_CORROSION) ? material.getProperty(PROP_CORROSION) : corrode_resist temp_resist = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : temp_resist if (material.alpha > 220) opacity = 1 // useless opaque window else opacity = 0 name = "[getQualityName(material.quality)] [material.name] " + name if (istype(reinforcement)) if(reinforcement.hasProperty(PROP_TOUGHNESS)) health_max += reinforcement.hasProperty(PROP_TOUGHNESS) ? round(reinforcement.getProperty(PROP_TOUGHNESS) / 2) : 0 health = health_max else health_max += 30 health = health_max cut_resist += reinforcement.hasProperty(PROP_SHEAR) ? round(reinforcement.getProperty(PROP_SHEAR) / 2) : 0 blunt_resist += reinforcement.hasProperty(PROP_COMPRESSIVE) ? round(reinforcement.getProperty(PROP_COMPRESSIVE) / 2) : 0 stab_resist += reinforcement.hasProperty(PROP_HARDNESS) ? round(reinforcement.getProperty(PROP_HARDNESS) / 2) : 0 corrode_resist += reinforcement.hasProperty(PROP_CORROSION) ? round(reinforcement.getProperty(PROP_CORROSION) / 2) : 0 name = "[reinforcement.name]-reinforced " + name proc/set_reinforcement(var/datum/material/M) if (!M) return reinforcement = M onMaterialChanged() damage_blunt(var/amount) if (!isnum(amount) || amount <= 0) return var/armor = 0 if (src.material) armor = blunt_resist if (src.material.getProperty(PROP_COMPRESSIVE) >= 25) armor += round(src.material.getProperty(PROP_COMPRESSIVE) / 10) else if (src.material.hasProperty(PROP_COMPRESSIVE) && src.material.getProperty(PROP_COMPRESSIVE) < 10) amount += rand(1,3) amount = get_damage_after_percentage_based_armor_reduction(armor,amount) src.health = max(0,min(src.health - amount,src.health_max)) if (src.health == 0) smash() damage_slashing(var/amount) if (!isnum(amount)) return amount = get_damage_after_percentage_based_armor_reduction(cut_resist,amount) if (src.quality < 10) amount += rand(1,3) if (amount <= 0) return src.health = max(0,min(src.health - amount,src.health_max)) if (src.health == 0) smash() damage_piercing(var/amount) if (!isnum(amount)) return amount = get_damage_after_percentage_based_armor_reduction(stab_resist,amount) if (src.quality < 10) amount += rand(1,3) if (amount <= 0) return src.health = max(0,min(src.health - amount,src.health_max)) if (src.health == 0) smash() damage_corrosive(var/amount) if (!isnum(amount) || amount <= 0) return amount = get_damage_after_percentage_based_armor_reduction(corrode_resist,amount) if (amount <= 0) return src.health = max(0,min(src.health - amount,src.health_max)) if (src.health == 0) smash() damage_heat(var/amount) if (!isnum(amount) || amount <= 0) return if (src.material) if (amount * 100000 <= temp_resist) // Not applying enough heat to melt it return if (amount <= 0) return src.health = max(0,min(src.health - amount,src.health_max)) if (src.health == 0) smash() ex_act(severity) switch(severity) if(1) src.damage_blunt(40) src.damage_heat(40) if(2) src.damage_blunt(15) src.damage_heat(15) if(3) src.damage_blunt(7) src.damage_heat(7) meteorhit(var/obj/M) if (istype(M, /obj/newmeteor/massive)) smash() return src.damage_blunt(20) blob_act(var/power) src.damage_blunt(power * 1.25) bullet_act(var/obj/projectile/P) var/damage = 0 if (!P || !istype(P.proj_data,/datum/projectile/)) return damage = round((P.power*P.proj_data.ks_ratio), 1.0) if (damage < 1) return if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter)) for(var/atom/A in src) if(A.material) A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter)) switch(P.proj_data.damage_type) if(D_KINETIC) damage_blunt(damage) if(D_PIERCING) damage_piercing(damage) if(D_ENERGY) damage_heat(damage / 6) return reagent_act(var/reagent_id,var/volume) if (..()) return // windows are good at resisting corrosion and heat switch(reagent_id) if("acid") damage_corrosive(volume / 4) if("pacid") damage_corrosive(volume / 2) if("napalm") damage_heat(volume / 4) if("infernite") damage_heat(volume / 2) if("foof") damage_heat(volume) get_desc() var/the_text = "" switch(src.state) if(0) if (!src.anchored) the_text += "It seems to be completely loose. You could probably slide it around." else the_text += "It seems to have been pried out of the frame." if(1) the_text += "It doesn't seem to be properly fastened down." if (opacity) the_text += " ...you can't see through it at all. What kind of idiot made this?" return the_text CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(istype(mover, /obj/projectile)) var/obj/projectile/P = mover if(P.proj_data.window_pass) return 1 if (src.dir == SOUTHWEST || src.dir == SOUTHEAST || src.dir == NORTHWEST || src.dir == NORTHEAST) return 0 //full tile window, you can't move into it! if(get_dir(loc, target) == dir) return !density else return 1 CheckExit(atom/movable/O as mob|obj, target as turf) if (!src.density) return 1 if(istype(O, /obj/projectile)) var/obj/projectile/P = O if(P.proj_data.window_pass) return 1 if (get_dir(O.loc, target) == src.dir) return 0 return 1 hitby(AM as mob|obj) ..() src.visible_message("[src] was hit by [AM].") playsound(src.loc, src.hitsound , 100, 1) if (ismob(AM)) damage_blunt(15) else var/obj/O = AM damage_blunt(O.throwforce) if (src && src.health <= 2 && !reinforcement) src.anchored = 0 step(src, get_dir(AM, src)) ..() return attack_hand(mob/user as mob) if (user.a_intent == "harm") if (user.bioHolder && user.bioHolder.HasEffect("hulk")) user.visible_message("[user] punches the window.") playsound(src.loc, src.hitsound, 100, 1) src.damage_blunt(10) return else src.visible_message("[user] beats [src] uselessly!") playsound(src.loc, src.hitsound, 100, 1) return else if (istype(usr, /mob/living/carbon/human)) src.visible_message("[usr] knocks on [src].") playsound(src.loc, src.hitsound, 100, 1) sleep(3) playsound(src.loc, src.hitsound, 100, 1) sleep(3) playsound(src.loc, src.hitsound, 100, 1) return attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/screwdriver)) if (state == 10) return else if (state >= 1) playsound(src.loc, "sound/items/Screwdriver.ogg", 75, 1) if (deconstruct_time) user.show_text("You begin to [state == 1 ? "fasten the window to" : "unfasten the window from"] the frame...", "red") if (!do_after(user, deconstruct_time)) boutput(user, "You were interrupted.") return state = 3 - state user.show_text("You have [state == 1 ? "unfastened the window from" : "fastened the window to"] the frame.", "blue") else if (state == 0) playsound(src.loc, "sound/items/Screwdriver.ogg", 75, 1) if (deconstruct_time) user.show_text("You begin to [src.anchored ? "unfasten the frame from" : "fasten the frame to"] the floor...", "red") if (!do_after(user, deconstruct_time)) boutput(user, "You were interrupted.") return src.anchored = !(src.anchored) user.show_text("You have [src.anchored ? "fastened the frame to" : "unfastened the frame from"] the floor.", "blue") return 1 else playsound(src.loc, "sound/items/Screwdriver.ogg", 75, 1) if (deconstruct_time) user.show_text("You begin to [src.anchored ? "unfasten the window from" : "fasten the window to"] the floor...", "red") if (!do_after(user, deconstruct_time)) boutput(user, "You were interrupted.") return src.anchored = !(src.anchored) user.show_text("You have [src.anchored ? "fastened the window to" : "unfastened the window from"] the floor.", "blue") return 1 else if (istype(W, /obj/item/crowbar)) if (state <= 1) playsound(src.loc, "sound/items/Crowbar.ogg", 75, 1) if (deconstruct_time) user.show_text("You begin to [src.state ? "pry the window out of" : "pry the window into"] the frame...", "red") if (!do_after(user, deconstruct_time)) boutput(user, "You were interrupted.") return state = 1 - state user.show_text("You have [src.state ? "pried the window into" : "pried the window out of"] the frame.", "blue") else if (istype(W, /obj/item/grab)) var/obj/item/grab/G = W if (ishuman(G.affecting) && get_dist(G.affecting, src) <= 1) src.visible_message("[user] slams [G.affecting]'s head into [src]!") logTheThing("combat", user, G.affecting, "slams %target%'s head into [src]") playsound(src.loc, src.hitsound , 100, 1) G.affecting:TakeDamage("head", 0, 5) qdel(W) src.damage_blunt(2) else playsound(src.loc, src.hitsound , 75, 1) src.damage_blunt(W.force) if (src.health <= 2) src.anchored = 0 step(src, get_dir(user, src)) ..() return proc/smash() var/atom/A // catastrophic event litter reduction if(limiter.canISpawn(/obj/item/raw_material/shard)) A = new/obj/item/raw_material/shard(src.loc) if(src.material) A.setMaterial(src.material) else var/datum/material/M = getCachedMaterial("glass") A.setMaterial(M) if(reinforcement && limiter.canISpawn(/obj/item/rods)) A = new /obj/item/rods(src.loc) A.setMaterial(reinforcement) playsound(src, src.shattersound, 70, 1) qdel(src) proc/update_nearby_tiles(need_rebuild) if(!air_master) return 0 var/turf/simulated/source = loc var/turf/simulated/target = get_step(source,dir) if(need_rebuild) if(istype(source)) //Rebuild/update nearby group geometry if(source.parent) air_master.queue_update_group(source.parent) else air_master.queue_update_tile(source) if(istype(target)) if(target.parent) air_master.queue_update_group(target.parent) else air_master.queue_update_tile(target) else if(istype(source)) air_master.queue_update_tile(source) if(istype(target)) air_master.queue_update_tile(target) return 1 verb/rotate() set name = "Rotate Window" set src in oview(1) set category = "Local" if (!(src.dir in cardinal)) return if (src.anchored) boutput(usr, "It is fastened to the floor; therefore, you can't rotate it!") return 0 update_nearby_tiles(need_rebuild=1) //Compel updates before var/action = input(usr,"Rotate it which way?","Window Rotation",null) in list("Clockwise ->","Anticlockwise <-","180 Degrees") if (!action) return switch(action) if ("Clockwise ->") src.dir = turn(src.dir, -90) if ("Anticlockwise <-") src.dir = turn(src.dir, 90) if ("180 Degrees") src.dir = turn(src.dir, 180) update_nearby_tiles(need_rebuild=1) src.ini_dir = src.dir return /obj/window/reinforced icon_state = "rwindow" default_reinforcement = "steel" health = 50 health_max = 50 //deconstruct_time = 30 /obj/window/crystal default_material = "plasmaglass" hitsound = 'sound/effects/crystalhit.ogg' shattersound = 'sound/effects/crystalshatter.ogg' health = 80 health_max = 80 //deconstruct_time = 40 /obj/window/crystal/reinforced icon_state = "rwindow" default_reinforcement = "steel" health = 100 health_max = 100 //deconstruct_time = 50 //an unbreakable window /obj/window/bulletproof name = "bulletproof window" desc = "A specially made, heavily reinforced window. Trying to break or shoot through this would be a waste of time." icon_state = "rwindow" default_material = "uqillglass" health_multiplier = 100 //deconstruct_time = 100 /obj/window/supernorn icon = 'icons/Testing/newicons/obj/NEWstructures.dmi' dir = 5 attackby() // TODO: need to be able to smash them, this is a hack rotate() set hidden = 1 New() for (var/turf/simulated/wall/auto/T in orange(1)) T.update_icon() /obj/window/north dir = NORTH /obj/window/east dir = EAST /obj/window/west dir = WEST /obj/window/south dir = SOUTH /obj/window/crystal/north dir = NORTH /obj/window/crystal/east dir = EAST /obj/window/crystal/west dir = WEST /obj/window/crystal/south dir = SOUTH /obj/window/crystal/reinforced/north dir = NORTH /obj/window/crystal/reinforced/east dir = EAST /obj/window/crystal/reinforced/west dir = WEST /obj/window/crystal/reinforced/south dir = SOUTH /obj/window/reinforced/north dir = NORTH /obj/window/reinforced/east dir = EAST /obj/window/reinforced/west dir = WEST /obj/window/reinforced/south dir = SOUTH /obj/window/bulletproof/north dir = NORTH /obj/window/bulletproof/east dir = EAST /obj/window/bulletproof/west dir = WEST /obj/window/bulletproof/south dir = SOUTH /obj/window/auto icon = 'icons/obj/window_pyro.dmi' icon_state = "mapwin" dir = 5 //deconstruct_time = 20 var/mod = null var/list/connects_to = list(/turf/simulated/wall/auto/supernorn, /turf/simulated/wall/auto/reinforced/supernorn, /turf/simulated/shuttle/wall, /turf/simulated/shuttle/wall/escape, /obj/machinery/door, /obj/window) New() ..() src.verbs -= /obj/window/verb/rotate spawn(0) src.update_icon() proc/update_icon() if (!src.anchored) icon_state = "[mod]0" return var/builtdir = 0 for (var/dir in cardinal) var/turf/T = get_step(src, dir) if (T.type in connects_to) builtdir |= dir else if (connects_to) for (var/i=1, i <= connects_to.len, i++) var/atom/A = locate(connects_to[i]) in T if (!isnull(A)) if (istype(A, /atom/movable)) var/atom/movable/M = A if (!M.anchored) continue builtdir |= dir break src.icon_state = "[mod][builtdir]" attackby(obj/item/W as obj, mob/user as mob) if (..(W, user)) src.update_icon() /obj/window/auto/reinforced icon_state = "mapwin_r" mod = "R" default_reinforcement = "steel" health = 50 health_max = 50 //deconstruct_time = 30 /obj/window/auto/crystal default_material = "plasmaglass" hitsound = 'sound/effects/crystalhit.ogg' shattersound = 'sound/effects/crystalshatter.ogg' health = 80 health_max = 80 //deconstruct_time = 40 /obj/window/auto/crystal/reinforced icon_state = "mapwin_r" mod = "R" default_reinforcement = "steel" health = 100 health_max = 100 //deconstruct_time = 50 /obj/window/auto/bulletproof name = "bulletproof window" desc = "A specially made, heavily reinforced window. Trying to break or shoot through this would be a waste of time." icon_state = "mapwin_r" default_material = "uqillglass" health_multiplier = 100 //deconstruct_time = 100 /obj/wingrille_spawn name = "window grille spawner" icon = 'icons/obj/window.dmi' icon_state = "wingrille" density = 1 anchored = 1.0 invisibility = 101 //layer = 99 pressure_resistance = 4*ONE_ATMOSPHERE var/win_path = "/obj/window" var/grille_path = "/obj/grille/steel" var/full_win = 0 // adds a full window as well var/no_dirs = 0 //ignore directional New() spawn(1) src.set_up() spawn(10) qdel(src) proc/set_up() if (!locate(text2path(src.grille_path)) in get_turf(src)) var/obj/grille/new_grille = text2path(src.grille_path) new new_grille(src.loc) if (!no_dirs) for (var/dir in cardinal) var/turf/T = get_step(src, dir) if (!locate(/obj/wingrille_spawn) in T) var/obj/window/new_win = text2path("[src.win_path]/[dir2text(dir)]") new new_win(src.loc) if (src.full_win) if(!no_dirs || !locate(text2path(src.win_path)) in get_turf(src)) // if we have directional windows, there's already a window (or windows) from directional windows // only check if there's no window if we're expecting there to be no window so spawn a full window var/obj/window/new_win = text2path(src.win_path) new new_win(src.loc) full icon_state = "wingrille_f" full_win = 1 reinforced name = "reinforced window grille spawner" icon_state = "r-wingrille" win_path = "/obj/window/reinforced" full icon_state = "r-wingrille_f" full_win = 1 crystal name = "crystal window grille spawner" icon_state = "p-wingrille" win_path = "/obj/window/crystal" full icon_state = "p-wingrille_f" full_win = 1 reinforced_crystal name = "reinforced crystal window grille spawner" icon_state = "pr-wingrille" win_path = "/obj/window/crystal/reinforced" full icon_state = "pr-wingrille_f" full_win = 1 bulletproof name = "bulletproof window grille spawner" icon_state = "br-wingrille" win_path = "/obj/window/bulletproof" full name = "bulletproof window grille spawner" icon_state = "br-wingrille" icon_state = "b-wingrille_f" full_win = 1 auto name = "reinforced autowindow grille spawner" win_path = "/obj/window/auto/reinforced" full_win = 1 no_dirs = 1 icon_state = "r-wingrille_f" crystal name = "crystal autowindow grille spawner" win_path = "/obj/window/auto/crystal/reinforced" icon_state = "p-wingrille_f"