diff --git a/modular_chomp/game/turfs/shuttlewall_types.dm b/modular_chomp/game/turfs/shuttlewall_types.dm new file mode 100644 index 0000000000..df7e3dfb62 --- /dev/null +++ b/modular_chomp/game/turfs/shuttlewall_types.dm @@ -0,0 +1,17 @@ +/turf/simulated/shuttlewalls/white + icon_state = "quartz" + +/turf/simulated/shuttlewalls/white/Initialize(mapload) + . = ..(mapload, "quartz","quartz") + +/turf/simulated/shuttlewalls/void + icon_state = "void" + +/turf/simulated/shuttlewalls/void/Initialize(mapload) + . = ..(mapload, "void opal","void opal") + +/turf/simulated/shuttlewalls/dark + icon_state = "dark" + +/turf/simulated/shuttlewalls/dark/Initialize(mapload) + . = ..(mapload, "painite","painite") \ No newline at end of file diff --git a/modular_chomp/game/turfs/shuttlewalls.dm b/modular_chomp/game/turfs/shuttlewalls.dm new file mode 100644 index 0000000000..cc3fcd7c9c --- /dev/null +++ b/modular_chomp/game/turfs/shuttlewalls.dm @@ -0,0 +1,311 @@ +/turf/simulated/shuttlewalls + name = "wall" + desc = "A huge chunk of metal used to create shuttles." + icon = 'modular_chomp/icons/turf/shuttlewall_masks.dmi' + icon_state = "generic" + opacity = 1 + density = TRUE + blocks_air = 1 + thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall + + var/icon/wall_masks = 'modular_chomp/icons/turf/shuttlewall_masks.dmi' + var/damage = 0 + var/damage_overlay = 0 + var/global/damage_overlays[16] + var/active + var/can_open = 0 + var/datum/material/girder_material + var/datum/material/material + var/datum/material/reinf_material + var/last_state + var/construction_stage + + var/list/wall_connections = list("0", "0", "0", "0") + +/turf/simulated/shuttlewalls/Initialize(mapload, materialtype, rmaterialtype, girdertype) + . = ..() + icon_state = "blank" + if(!materialtype) + materialtype = DEFAULT_WALL_MATERIAL + material = get_material_by_name(materialtype) + if(!girdertype) + girdertype = DEFAULT_WALL_MATERIAL + girder_material = get_material_by_name(girdertype) + if(!isnull(rmaterialtype)) + reinf_material = get_material_by_name(rmaterialtype) + update_material() + START_PROCESSING(SSturfs, src) + +/turf/simulated/shuttlewalls/Destroy() + STOP_PROCESSING(SSturfs, src) + return ..() + +/turf/simulated/shuttlewalls/examine_icon() + return icon(icon=initial(icon), icon_state=initial(icon_state)) + +/turf/simulated/shuttlewalls/process() + // Calling parent will kill processing + if(!radiate()) + return PROCESS_KILL + +/turf/simulated/shuttlewalls/proc/get_material() + return material + +/turf/simulated/shuttlewalls/bullet_act(var/obj/item/projectile/Proj) + if(istype(Proj,/obj/item/projectile/beam)) + burn(2500) + else if(istype(Proj,/obj/item/projectile/ion)) + burn(500) + + var/proj_damage = Proj.get_structure_damage() + + //cap the amount of damage, so that things like emitters can't destroy walls in one hit. + var/damage = min(proj_damage, 100) + + if(Proj.damage_type == BURN && damage > 0) + if(thermite) + thermitemelt() + + if(istype(Proj,/obj/item/projectile/beam)) + if(material && material.reflectivity >= 0.5) // Time to reflect lasers. + var/new_damage = damage * material.reflectivity + var/outgoing_damage = damage - new_damage + damage = new_damage + Proj.damage = outgoing_damage + + visible_message("\The [src] reflects \the [Proj]!") + + // Find a turf near or on the original location to bounce to + var/new_x = Proj.starting.x + pick(0, 0, 0, -1, 1, -2, 2) + var/new_y = Proj.starting.y + pick(0, 0, 0, -1, 1, -2, 2) + //var/turf/curloc = get_turf(src) + var/turf/curloc = get_step(src, get_dir(src, Proj.starting)) + + Proj.penetrating += 1 // Needed for the beam to get out of the wall. + + // redirect the projectile + Proj.redirect(new_x, new_y, curloc, null) + + take_damage(damage) + return + +/turf/simulated/shuttlewalls/hitby(AM as mob|obj, var/speed=THROWFORCE_SPEED_DIVISOR) + ..() + if(ismob(AM)) + return + + var/tforce = AM:throwforce * (speed/THROWFORCE_SPEED_DIVISOR) + if (tforce < 15) + return + + take_damage(tforce) + +/turf/simulated/shuttlewalls/proc/clear_plants() + for(var/obj/effect/overlay/wallrot/WR in src) + qdel(WR) + for(var/obj/effect/plant/plant in range(src, 1)) + if(!plant.floor) //shrooms drop to the floor + plant.floor = 1 + plant.update_icon() + plant.pixel_x = 0 + plant.pixel_y = 0 + plant.update_neighbors() + +/turf/simulated/shuttlewalls/ChangeTurf(var/turf/N, var/tell_universe, var/force_lighting_update, var/preserve_outdoors) + clear_plants() + ..(N, tell_universe, force_lighting_update, preserve_outdoors) + +//Appearance +/turf/simulated/shuttlewalls/examine(mob/user) + . = ..() + + if(!damage) + . += "It looks fully intact." + else + var/dam = damage / material.integrity + if(dam <= 0.3) + . += "It looks slightly damaged." + else if(dam <= 0.6) + . += "It looks moderately damaged." + else + . += "It looks heavily damaged." + + if(locate(/obj/effect/overlay/wallrot) in src) + . += "There is fungus growing on [src]." + +//Damage + +/turf/simulated/shuttlewalls/melt() + + if(!can_melt()) + return + + src.ChangeTurf(/turf/simulated/floor/plating) + + var/turf/simulated/floor/F = src + if(!F) + return + F.burn_tile() + F.icon_state = "wall_thermite" + visible_message("\The [src] spontaneously combusts!.") //!!OH SHIT!! + return + +/turf/simulated/shuttlewalls/take_damage(dam) + if(dam) + damage = max(0, damage + dam) + update_damage() + return + +/turf/simulated/shuttlewalls/proc/update_damage() + var/cap = material.integrity + if(reinf_material) + cap += reinf_material.integrity + + if(locate(/obj/effect/overlay/wallrot) in src) + cap = cap / 10 + + if(damage >= cap) + dismantle_wall() + else + update_icon() + + return + +/turf/simulated/shuttlewalls/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :( + burn(exposed_temperature) + +/turf/simulated/shuttlewalls/adjacent_fire_act(turf/simulated/floor/adj_turf, datum/gas_mixture/adj_air, adj_temp, adj_volume) + burn(adj_temp) + if(adj_temp > material.melting_point) + take_damage(log(RAND_F(0.9, 1.1) * (adj_temp - material.melting_point))) + + return ..() + +/turf/simulated/shuttlewalls/proc/dismantle_wall(var/devastated, var/explode, var/no_product) + + playsound(src, 'sound/items/Welder.ogg', 100, 1) + if(!no_product) + if(reinf_material) + reinf_material.place_dismantled_girder(src, reinf_material, girder_material) + else + material.place_dismantled_girder(src, null, girder_material) + if(!devastated) + material.place_dismantled_product(src) + if (!reinf_material) + material.place_dismantled_product(src) + + for(var/obj/O in src.contents) //Eject contents! + if(istype(O,/obj/structure/sign/poster)) + var/obj/structure/sign/poster/P = O + P.roll_and_drop(src) + else + O.loc = src + + clear_plants() + material = get_material_by_name("placeholder") + reinf_material = null + girder_material = null + update_connections(1) + + ChangeTurf(/turf/simulated/floor/plating) + +/turf/simulated/shuttlewalls/ex_act(severity) + switch(severity) + if(1.0) + if(girder_material.explosion_resistance >= 25 && prob(girder_material.explosion_resistance)) + new /obj/structure/girder/displaced(src, girder_material.name) + src.ChangeTurf(get_base_turf_by_area(src)) + if(2.0) + if(prob(75)) + take_damage(rand(150, 250)) + else + dismantle_wall(1,1) + if(3.0) + take_damage(rand(0, 250)) + else + return + +// Wall-rot effect, a nasty fungus that destroys walls. +/turf/simulated/shuttlewalls/proc/rot() + if(locate(/obj/effect/overlay/wallrot) in src) + return FALSE + + // Wall-rot can't go onto walls that are surrounded in all four cardinal directions. + // Because of spores, or something. It's actually to avoid the pain that is removing wallrot surrounded by + // four r-walls. + var/at_least_one_open_turf = FALSE + for(var/direction in GLOB.cardinal) + var/turf/T = get_step(src, direction) + if(!T.check_density()) + at_least_one_open_turf = TRUE + break + + if(!at_least_one_open_turf) + return FALSE + + var/number_rots = rand(2,3) + for(var/i=0, i= 150 && !girder_material.is_brittle()) //Strong girders will remain in place when a wall is melted. + dismantle_wall(1,1) + else + src.ChangeTurf(/turf/simulated/floor/plating) + + var/turf/simulated/floor/F = src + F.burn_tile() + F.icon_state = "dmg[rand(1,4)]" + to_chat(user, "The thermite starts melting through the wall.") + + spawn(100) + if(O) + qdel(O) +// F.sd_LumReset() //TODO: ~Carn + return + +/turf/simulated/shuttlewalls/proc/radiate() + var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0) + (girder_material ? girder_material.radioactivity / 2 : 0) + if(!total_radiation) + return + + SSradiation.radiate(src, total_radiation) + return total_radiation + +/turf/simulated/shuttlewalls/proc/burn(temperature) + if(material.combustion_effect(src, temperature, 0.7)) + spawn(2) + new /obj/structure/girder(src, girder_material.name) + src.ChangeTurf(/turf/simulated/floor) + for(var/turf/simulated/wall/W in range(3,src)) + W.burn((temperature/4)) + for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) + D.ignite(temperature/4) + +/turf/simulated/shuttlewalls/can_engrave() + return (material && material.hardness >= 10 && material.hardness <= 100) + +/turf/simulated/shuttlewalls/AltClick(mob/user) + if(isliving(user)) + var/mob/living/livingUser = user + if(try_graffiti(livingUser, livingUser.get_active_hand())) + return + . = ..() \ No newline at end of file diff --git a/modular_chomp/game/turfs/shuttlewalls_attacks.dm b/modular_chomp/game/turfs/shuttlewalls_attacks.dm new file mode 100644 index 0000000000..01c30154d2 --- /dev/null +++ b/modular_chomp/game/turfs/shuttlewalls_attacks.dm @@ -0,0 +1,413 @@ +//Interactions +/turf/simulated/shuttlewalls/proc/toggle_open(var/mob/user) + + if(can_open == WALL_OPENING) + return + + SSradiation.resistance_cache.Remove(src) + + if(density) + can_open = WALL_OPENING + //flick("[material.icon_base]fwall_opening", src) + density = FALSE + blocks_air = ZONE_BLOCKED + update_icon() + update_air() + set_light(0) + src.blocks_air = 0 + set_opacity(0) + for(var/turf/simulated/turf in loc) + air_master.mark_for_update(turf) + else + can_open = WALL_OPENING + //flick("[material.icon_base]fwall_closing", src) + density = TRUE + blocks_air = AIR_BLOCKED + update_icon() + update_air() + set_light(1) + src.blocks_air = 1 + set_opacity(1) + for(var/turf/simulated/turf in loc) + air_master.mark_for_update(turf) + + can_open = WALL_CAN_OPEN + update_icon() + +/turf/simulated/shuttlewalls/proc/update_air() + if(!air_master) + return + + for(var/turf/simulated/turf in loc) + update_thermal(turf) + air_master.mark_for_update(turf) + + +/turf/simulated/shuttlewalls/proc/update_thermal(var/turf/simulated/source) + if(istype(source)) + if(density && opacity) + source.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + else + source.thermal_conductivity = initial(source.thermal_conductivity) + +/turf/simulated/shuttlewalls/proc/fail_smash(var/mob/user) + var/damage_lower = 25 + var/damage_upper = 75 + if(isanimal(user)) + var/mob/living/simple_mob/S = user + playsound(src, S.attack_sound, 75, 1) + if(!(S.melee_damage_upper >= STRUCTURE_MIN_DAMAGE_THRESHOLD * 2)) + to_chat(user, "You bounce against the wall.") + return FALSE + damage_lower = S.melee_damage_lower + damage_upper = S.melee_damage_upper + to_chat(user, "You smash against the wall!") + user.do_attack_animation(src) + take_damage(rand(damage_lower,damage_upper)) + +/turf/simulated/shuttlewalls/proc/success_smash(var/mob/user) + to_chat(user, "You smash through the wall!") + user.do_attack_animation(src) + if(isanimal(user)) + var/mob/living/simple_mob/S = user + playsound(src, S.attack_sound, 75, 1) + spawn(1) + dismantle_wall(1) + +/turf/simulated/shuttlewalls/proc/try_touch(var/mob/user, var/rotting) + + if(rotting) + if(reinf_material) + to_chat(user, "\The [reinf_material.display_name] feels porous and crumbly.") + else + to_chat(user, "\The [material.display_name] crumbles under your touch!") + dismantle_wall() + return 1 + + if(!can_open) + if(!material.wall_touch_special(src, user)) + to_chat(user, "You push the wall, but nothing happens.") + playsound(src, 'sound/weapons/Genhit.ogg', 25, 1) + else + toggle_open(user) + return 0 + + +/turf/simulated/shuttlewalls/attack_hand(var/mob/user) + + radiate() + add_fingerprint(user) + user.setClickCooldown(user.get_attack_speed()) + var/rotting = (locate(/obj/effect/overlay/wallrot) in src) + if (HULK in user.mutations) + if (rotting || !prob(material.hardness)) + success_smash(user) + else + fail_smash(user) + return 1 + + try_touch(user, rotting) + +/turf/simulated/shuttlewalls/attack_generic(var/mob/user, var/damage, var/attack_message) + + radiate() + user.setClickCooldown(user.get_attack_speed()) + var/rotting = (locate(/obj/effect/overlay/wallrot) in src) + if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD * 2) + try_touch(user, rotting) + return + + if(rotting) + return success_smash(user) + + if(reinf_material) + if(damage >= max(material.hardness, reinf_material.hardness) ) + return success_smash(user) + else if(damage >= material.hardness) + return success_smash(user) + return fail_smash(user) + +/turf/simulated/shuttlewalls/attackby(var/obj/item/weapon/W, var/mob/user) + + user.setClickCooldown(user.get_attack_speed(W)) + +/* +//As with the floors, only this time it works AND tries pushing the wall after it's done. + if(!construction_stage && user.a_intent == I_HELP) + if(try_graffiti(user,W)) + return +*/ + + if (!user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do this!") + return + + //get the user's location + if(!istype(user.loc, /turf)) + return //can't do this stuff whilst inside objects and such + + if(W) + radiate() + if(is_hot(W)) + burn(is_hot(W)) + + if(istype(W, /obj/item/device/electronic_assembly/wallmount)) + var/obj/item/device/electronic_assembly/wallmount/IC = W + IC.mount_assembly(src, user) + return + + if(istype(W, /obj/item/stack/tile/roofing)) + var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather + var/turf/T = GetAbove(src) + var/obj/item/stack/tile/roofing/R = W + + // Place plating over a wall + if(T) + if(istype(T, /turf/simulated/open) || istype(T, /turf/space)) + if(R.use(1)) // Cost of roofing tiles is 1:1 with cost to place lattice and plating + T.ReplaceWithLattice() + T.ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE) + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] patches a hole in the ceiling.", "You patch a hole in the ceiling.") + expended_tile = TRUE + else + to_chat(user, "There aren't any holes in the ceiling to patch here.") + return + + // Create a ceiling to shield from the weather + if(is_outdoors()) + if(expended_tile || R.use(1)) // Don't need to check adjacent turfs for a wall, we're building on one + make_indoors() + if(!expended_tile) // Would've already played a sound + playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) + user.visible_message("[user] roofs \the [src], shielding it from the elements.", "You roof \the [src] tile, shielding it from the elements.") + return + + + if(locate(/obj/effect/overlay/wallrot) in src) + if(W.has_tool_quality(TOOL_WELDER)) + var/obj/item/weapon/weldingtool/WT = W.get_welder() + if( WT.remove_fuel(0,user) ) + to_chat(user, "You burn away the fungi with \the [WT].") + playsound(src, WT.usesound, 10, 1) + for(var/obj/effect/overlay/wallrot/WR in src) + qdel(WR) + return + else if(!is_sharp(W) && W.force >= 10 || W.force >= 20) + to_chat(user, "\The [src] crumbles away under the force of your [W.name].") + src.dismantle_wall(1) + return + + //THERMITE related stuff. Calls src.thermitemelt() which handles melting simulated walls and the relevant effects + if(thermite) + if(W.has_tool_quality(TOOL_WELDER)) + var/obj/item/weapon/weldingtool/WT = W.get_welder() + if( WT.remove_fuel(0,user) ) + thermitemelt(user) + return + + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + thermitemelt(user) + return + + else if( istype(W, /obj/item/weapon/melee/energy/blade) ) + var/obj/item/weapon/melee/energy/blade/EB = W + + EB.spark_system.start() + to_chat(user, "You slash \the [src] with \the [EB]; the thermite ignites!") + playsound(src, "sparks", 50, 1) + playsound(src, 'sound/weapons/blade1.ogg', 50, 1) + + thermitemelt(user) + return + + var/turf/T = user.loc //get user's location for delay checks + + if(damage && W.has_tool_quality(TOOL_WELDER)) + + var/obj/item/weapon/weldingtool/WT = W.get_welder() + + if(!WT.isOn()) + return + + if(WT.remove_fuel(0,user)) + to_chat(user, "You start repairing the damage to [src].") + playsound(src, WT.usesound, 100, 1) + if(do_after(user, max(5, damage / 5) * WT.toolspeed) && WT && WT.isOn()) + to_chat(user, "You finish repairing the damage to [src].") + take_damage(-damage) + else + to_chat(user, "You need more welding fuel to complete this task.") + return + user.update_examine_panel(src) + return + + // Basic dismantling. + //var/dismantle_toolspeed = 0 + if(isnull(construction_stage) || !reinf_material) + + var/cut_delay = 60 - material.cut_delay + var/dismantle_verb + var/dismantle_sound + + if(W.has_tool_quality(TOOL_WELDER)) + var/obj/item/weapon/weldingtool/WT = W.get_welder() + if(!WT.isOn()) + return + if(!WT.remove_fuel(0,user)) + to_chat(user, "You need more welding fuel to complete this task.") + return + dismantle_verb = "cutting" + dismantle_sound = W.usesound + // cut_delay *= 0.7 // Tools themselves now can shorten the time it takes. + else if(istype(W,/obj/item/weapon/melee/energy/blade)) + dismantle_sound = "sparks" + dismantle_verb = "slicing" + //dismantle_toolspeed = 1 + cut_delay *= 0.5 + else if(istype(W,/obj/item/weapon/pickaxe)) + var/obj/item/weapon/pickaxe/P = W + dismantle_verb = P.drill_verb + dismantle_sound = P.drill_sound + cut_delay -= P.digspeed + + if(dismantle_verb) + + to_chat(user, "You begin [dismantle_verb] through the outer plating.") + if(dismantle_sound) + playsound(src, dismantle_sound, 100, 1) + + if(cut_delay < 0) + cut_delay = 0 + + if(!do_after(user,cut_delay * W.toolspeed)) + return + + to_chat(user, "You remove the outer plating.") + dismantle_wall() + user.visible_message("The wall was torn open by [user]!") + return + + //Reinforced dismantling. + else + switch(construction_stage) + if(6) + if (W.has_tool_quality(TOOL_WIRECUTTER)) + playsound(src, W.usesound, 100, 1) + construction_stage = 5 + user.update_examine_panel(src) + to_chat(user, "You cut through the outer grille.") + update_icon() + return + if(5) + if (W.has_tool_quality(TOOL_SCREWDRIVER)) + to_chat(user, "You begin removing the support lines.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 5) + return + construction_stage = 4 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You unscrew the support lines.") + return + else if (W.has_tool_quality(TOOL_WIRECUTTER)) + construction_stage = 6 + user.update_examine_panel(src) + to_chat(user, "You mend the outer grille.") + playsound(src, W.usesound, 100, 1) + update_icon() + return + if(4) + var/cut_cover + if(W.has_tool_quality(TOOL_WELDER)) + var/obj/item/weapon/weldingtool/WT = W.get_welder() + if(!WT.isOn()) + return + if(WT.remove_fuel(0,user)) + cut_cover=1 + else + to_chat(user, "You need more welding fuel to complete this task.") + return + else if (istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + cut_cover = 1 + if(cut_cover) + to_chat(user, "You begin slicing through the metal cover.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user, 60 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) + return + construction_stage = 3 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You press firmly on the cover, dislodging it.") + return + else if (W.has_tool_quality(TOOL_SCREWDRIVER)) + to_chat(user, "You begin screwing down the support lines.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 4) + return + construction_stage = 5 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You screw down the support lines.") + return + if(3) + if (W.has_tool_quality(TOOL_CROWBAR)) + to_chat(user, "You struggle to pry off the cover.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 3) + return + construction_stage = 2 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You pry off the cover.") + return + if(2) + if (W.has_tool_quality(TOOL_WRENCH)) + to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,40 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 2) + return + construction_stage = 1 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You remove the bolts anchoring the support rods.") + return + if(1) + var/cut_cover + if(W.has_tool_quality(TOOL_WELDER)) + var/obj/item/weapon/weldingtool/WT = W.get_welder() + if( WT.remove_fuel(0,user) ) + cut_cover=1 + else + to_chat(user, "You need more welding fuel to complete this task.") + return + else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + cut_cover = 1 + if(cut_cover) + to_chat(user, "You begin slicing through the support rods.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,70 * W.toolspeed) || !istype(src, /turf/simulated/wall) || construction_stage != 1) + return + construction_stage = 0 + user.update_examine_panel(src) + update_icon() + to_chat(user, "You slice through the support rods.") + return + if(0) + if(W.has_tool_quality(TOOL_CROWBAR)) + to_chat(user, "You struggle to pry off the outer sheath.") + playsound(src, W.usesound, 100, 1) + if(!do_after(user,100 * W.toolspeed) || !istype(src, /turf/simulated/wall) || !user || !W || !T ) + return + if(user.loc == T && user.get_active_hand() == W ) + to_chat(user, "You pry off the outer sheath.") + dismantle_wall() + return + + if(istype(W,/obj/item/frame)) + var/obj/item/frame/F = W + F.try_build(src, user) + return + + else if(!istype(W,/obj/item/weapon/rcd) && !istype(W, /obj/item/weapon/reagent_containers)) + return attack_hand(user) \ No newline at end of file diff --git a/modular_chomp/game/turfs/shuttlewalls_icon.dm b/modular_chomp/game/turfs/shuttlewalls_icon.dm new file mode 100644 index 0000000000..d10a49a0ea --- /dev/null +++ b/modular_chomp/game/turfs/shuttlewalls_icon.dm @@ -0,0 +1,152 @@ +/turf/simulated/shuttlewalls/proc/update_material() + + if(!material) + return + + if(reinf_material) + construction_stage = 6 + else + construction_stage = null + if(!material) + material = get_material_by_name(DEFAULT_WALL_MATERIAL) + if(material) + explosion_resistance = material.explosion_resistance + if(reinf_material && reinf_material.explosion_resistance > explosion_resistance) + explosion_resistance = reinf_material.explosion_resistance + + if(reinf_material) + name = "reinforced [material.display_name] wall" + desc = "It seems to be a section of wall reinforced with [reinf_material.display_name] and plated with [material.display_name]." + else + name = "[material.display_name] wall" + desc = "It seems to be a section of wall plated with [material.display_name]." + + if(material.opacity > 0.5 && !opacity) + set_light(1) + else if(material.opacity < 0.5 && opacity) + set_light(0) + + SSradiation.resistance_cache.Remove(src) + update_connections(1) + update_icon() + + +/turf/simulated/shuttlewalls/proc/set_material(var/datum/material/newmaterial, var/datum/material/newrmaterial, var/datum/material/newgmaterial) + material = newmaterial + reinf_material = newrmaterial + if(!newgmaterial) + girder_material = DEFAULT_WALL_MATERIAL + else + girder_material = newgmaterial + update_material() + +/turf/simulated/wall/update_icon() + if(!material) + return + + if(!damage_overlays[1]) //list hasn't been populated + generate_overlays() + + cut_overlays() + var/image/I + + if(!density) + I = image(wall_masks, "[material.icon_base]fwall_open") + I.color = material.icon_colour + add_overlay(I) + return + + for(var/i = 1 to 4) + I = image(wall_masks, "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1)) + I.color = material.icon_colour + add_overlay(I) + + if(reinf_material) + if(construction_stage != null && construction_stage < 6) + I = image(wall_masks, "reinf_construct-[construction_stage]") + I.color = reinf_material.icon_colour + add_overlay(I) + else + if("[reinf_material.icon_reinf]0" in cached_icon_states(wall_masks)) + // Directional icon + for(var/i = 1 to 4) + I = image(wall_masks, "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) + I.color = reinf_material.icon_colour + add_overlay(I) + else if("[reinf_material.icon_reinf]" in cached_icon_states(wall_masks)) + I = image(wall_masks, reinf_material.icon_reinf) + I.color = reinf_material.icon_colour + add_overlay(I) + var/image/texture = material.get_wall_texture() + if(texture) + add_overlay(texture) + + if(damage != 0) + var/integrity = material.integrity + if(reinf_material) + integrity += reinf_material.integrity + + var/overlay = round(damage / integrity * damage_overlays.len) + 1 + if(overlay > damage_overlays.len) + overlay = damage_overlays.len + + add_overlay(damage_overlays[overlay]) + return + +/turf/simulated/shuttlewalls/proc/generate_overlays() + var/alpha_inc = 256 / damage_overlays.len + + for(var/i = 1; i <= damage_overlays.len; i++) + var/image/img = image(icon = 'modular_chomp/icons/turf/shuttlewall.dmi', icon_state = "overlay_damage") + img.blend_mode = BLEND_MULTIPLY + img.alpha = (i * alpha_inc) - 1 + damage_overlays[i] = img + + +/turf/simulated/shuttlewalls/proc/update_connections(propagate = 0) + if(!material) + return + var/list/dirs = list() + var/inrange = orange(src, 1) + for(var/turf/simulated/wall/W in inrange) + if(!W.material) + continue + if(propagate) + W.update_connections() + W.update_icon() + if(can_join_with_wall(W)) + dirs += get_dir(src, W) + for(var/obj/structure/low_wall/WF in inrange) + if(can_join_with_low_wall(WF)) + dirs += get_dir(src, WF) + + special_wall_connections(dirs, inrange) + wall_connections = dirs_to_corner_states(dirs) + +/turf/simulated/shuttlewalls/proc/special_wall_connections(list/dirs, list/inrange) + if(material.icon_base == "hull") // Could be improved... + var/additional_dirs = 0 + for(var/direction in alldirs) + var/turf/T = get_step(src,direction) + if(T && (locate(/obj/structure/hull_corner) in T)) + dirs += direction + additional_dirs |= direction + if(additional_dirs) + for(var/diag_dir in cornerdirs) + if ((additional_dirs & diag_dir) == diag_dir) + dirs += diag_dir + +/turf/simulated/shuttlewalls/proc/can_join_with_wall(var/turf/simulated/wall/W) + //No blending if no material + if(!material || !W.material) + return 0 + //We can blend if either is the same, or a subtype, of the other one + if(istype(W.material, material.type) || istype(material, W.material.type)) + return 1 + //Also blend if they have the same iconbase + if(material.icon_base == W.material.icon_base) + return 1 + return 0 + +/turf/simulated/shuttlewalls/proc/can_join_with_low_wall(var/obj/structure/low_wall/WF) + return FALSE \ No newline at end of file diff --git a/modular_chomp/icons/turf/shuttlewall.dmi b/modular_chomp/icons/turf/shuttlewall.dmi new file mode 100644 index 0000000000..6fa0e39dfe Binary files /dev/null and b/modular_chomp/icons/turf/shuttlewall.dmi differ diff --git a/modular_chomp/icons/turf/shuttlewall_masks.dmi b/modular_chomp/icons/turf/shuttlewall_masks.dmi new file mode 100644 index 0000000000..ee0f69fedf Binary files /dev/null and b/modular_chomp/icons/turf/shuttlewall_masks.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 64826c3882..35d6e39c05 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4838,6 +4838,10 @@ #include "modular_chomp\game\machinery\buttons.dm" #include "modular_chomp\game\machinery\turrets.dm" #include "modular_chomp\game\objects\effects\spiders.dm" +#include "modular_chomp\game\turfs\shuttlewall_types.dm" +#include "modular_chomp\game\turfs\shuttlewalls.dm" +#include "modular_chomp\game\turfs\shuttlewalls_attacks.dm" +#include "modular_chomp\game\turfs\shuttlewalls_icon.dm" #include "modular_chomp\maps\overmap\aegis_carrier\aegis_objs.dm" #include "modular_chomp\maps\overmap\space_pois\space_areas.dm" #include "modular_chomp\maps\overmap\space_pois\space_pois.dm"