/obj/machinery/cruiser/test name = "Experimental BX-1 Cruiser" desc = "An experimental type of syndicate cruiser based on drone technology." interior_type = /area/ship_interior/cruisertest /obj/machinery/cruiser/test2 name = "Experimental BX-2 Cruiser" desc = "An experimental type of syndicate cruiser based on drone technology." interior_type = /area/ship_interior/cruisertest2 /obj/cruiser_shield_visual//This is dumb but required because icons and images don't animate properly as overlays AND their icon_state cannot be changed properly once added (images) name = "" desc = "" icon = 'icons/obj/160x160.dmi' icon_state = "shield" mouse_opacity = 0 bound_width = 160 bound_height = 160 density = 0 anchored = 1 layer = 4 bullet_act(var/obj/projectile/P) return ex_act(var/severity) return /obj/machinery/cruiser icon = 'icons/obj/160x160.dmi' icon_state = "placeholder" name = "Experimental someone-didnt-give-me-a-name cruiser" desc = "Ruh-roh" bound_width = 160 bound_height = 160 density = 1 anchored = 1 dir = 1 var/obj/cruiser_shield_visual/shield_obj var/image/frames var/image/overframes var/image/bar_top var/image/bar_middle var/image/bar_bottom var/facing = 1 var/flying = 0 var/speed = 3 var/stall = 0 var/speed_mod = 0 var/obj/item/shipcomponent/mainweapon/turret_left = null var/obj/item/shipcomponent/mainweapon/turret_right = null var/obj/item/shipcomponent/engine/engine = null var/obj/item/shipcomponent/life_support/life_support = null var/list/powerUse = list() var/power_used = 0 var/power_used_last = 0 var/power_produced_last = 300 var/power_boost = 0 //Additional power per tick. var/power_movement = 100 var/power_defense = 100 var/power_offense = 100 var/shields_regen = 30 //How much per process tick restored. var/shields_timer = 0 //How long since last damage taken. var/shields_delay = 75 //How long in 1/10s of seconds after damage was taken will shields begin to recharge? var/shields_recharge_cost = 20 //Cost per tick to recharge [shields_regen] per tick. var/shields = 600 var/shields_max = 600 var/shields_last = 0 var/shield_regen_always = 0 //If true, shields will continually recharge. Damage wont stop regeneration. var/shield_regen_boost = 0 //Additional shield regen per tick. var/shield_modulation = 0 //If 1, shields will not be weak to energy weapons. //DO NOT MODIFY DIRECTLY var/health = 400 var/health_last = 0 var/health_max = 400 //DO NOT MODIFY DIRECTLY var/weapon_cooldown_mod = 0 //Modifier for weapon cooldown var/firemode = CRUISER_FIREMODE_BOTH var/alt_weapon = 0 var/ramming = 0 //How many ramming hits we have left. var/interior_type //interior area to use for this cruiser var/area/ship_interior/interior_area //Instance of the area assigned to this. var/obj/cruiser_camera_dummy/camera //used to control camera position var/datum/particleSystem/barrelSmoke/smokeParticles var/list/crew = list() var/atmos_fail_count = 5 //counts down when life support is offline. once it his 0, life support fails. var/degradation = 0 //Slowly accumulates and makes new damage more severe. var/warping = 0 proc/internal_sound(var/atom/source, soundin, vol as num, vary, extrarange as num, pitch) playsound(source, soundin, vol, vary, extrarange, pitch) for(var/mob/M in crew) M.playsound_local(M, soundin, vol , vary, extrarange, pitch) return bullet_act(var/obj/projectile/P) if(P.shooter == src) return var/datum/projectile/PD = P.proj_data var/damage = PD.power * PD.ks_ratio damage = round(max(0, damage)) var/ltlpoints = PD.power * (1 - PD.ks_ratio) ltlpoints = round(max(0, ltlpoints)) if(shields) internal_sound(src.loc, 'sound/machines/shieldimpact.ogg', 65, 1, 1) damageShields(damage, PD.damage_type) else internal_sound(src.loc, 'sound/machines/armorimpact.ogg', 65, 1, 1) damageArmor(damage, PD.damage_type) shakeCruiser(3, 1, 0.2) return meteorhit(var/obj/O as obj) if(shields) internal_sound(src.loc, 'sound/machines/shieldimpact.ogg', 65, 1, 1) damageShields(80, D_KINETIC) shakeCruiser(3, 1, 0.2) else internal_sound(src.loc, 'sound/machines/armorimpact.ogg', 65, 1, 1) damageArmor(30, D_KINETIC) shakeCruiser(6, 2, 0.2) ex_act(var/severity) var/dmg_mult = 1 switch(severity) if(1) dmg_mult = 2.5 if(2) dmg_mult = 1.5 if(3) dmg_mult = 1 if(4 to INFINITY) dmg_mult = 0.75 var/damage = round(40 * dmg_mult) if(shields) internal_sound(src.loc, 'sound/machines/shieldimpact.ogg', 65, 1, 1) damageShields(damage, D_KINETIC) shakeCruiser(3, 1, 0.2) else internal_sound(src.loc, 'sound/machines/armorimpact.ogg', 65, 1, 1) damageArmor(damage, D_KINETIC) shakeCruiser(6, 2, 0.2) if(shields <= 0 && prob(75)) var/atom/source = pick(src.interior_area.contents) explosion_new(source, source, max(min(1,4-severity), 5)) return New() if(interior_type) interior_area = locate(interior_type) interior_area.ship = src if(!interior_area) del(src) SubscribeToProcess() shield_obj = new(src.loc) frames = image('icons/obj/160x160.dmi',src,"frames",src.layer+1) overframes = image('icons/obj/160x160.dmi',src,"overframes",src.layer+2) bar_top = image('icons/obj/160x160.dmi',src,"bartop",src.layer+1) bar_middle = image('icons/obj/160x160.dmi',src,"barmiddle",src.layer+1) bar_bottom = image('icons/obj/160x160.dmi',src,"barbottom",src.layer+1) bar_top.color = "#8A1919" bar_middle.color = "#19688A" bar_bottom.color = "#CF9417" camera = new(locate(src.x + 2, src.y + 2, src.z)) camera.name = src.name turret_left = new/obj/item/shipcomponent/mainweapon/light_longrange(src) turret_right = new/obj/item/shipcomponent/mainweapon/light_longrange(src) engine = new/obj/item/shipcomponent/engine(src) life_support = new/obj/item/shipcomponent/life_support(src) Del() del(camera) if(interior_area) interior_area = null return attack_hand(mob/user as mob) return MouseDrop_T(user, user) MouseDrop_T(atom/movable/O as obj, mob/user as mob) enterShip(O, user) return Move(NewLoc,Dir=0,step_x=0,step_y=0) var/preserve_dir = src.dir . = ..(NewLoc,Dir,step_x,step_y) dir = preserve_dir camera.set_loc(locate(src.x + 2, src.y + 2, src.z)) shield_obj.set_loc(src.loc) return process() ..() if(warping) return checkHealth() handlePowerCosts() updateIndicators() handleLifeSupport() return proc/handleLifeSupport() if(src.hasPower() && life_support) atmos_fail_count = min(atmos_fail_count+1, 5) for(var/turf/simulated/T in interior_area) if(T.density) continue if(T.air) T.air.temperature = life_support.tempreg T.oxygen = MOLES_O2STANDARD * 4 T.nitrogen = MOLES_N2STANDARD * 4 else if((atmos_fail_count - 1) == 2) internal_sound(src.loc, 'sound/machines/alarm_a.ogg', 80, 1, -1) if((atmos_fail_count - 1) == 0) internal_sound(src.loc, 'sound/machines/decompress.ogg', 100, 1, -1) atmos_fail_count = max(atmos_fail_count-1, 0) if(!atmos_fail_count) for(var/turf/simulated/T in interior_area) if(T.density) continue if(T.air) T.air.temperature = T0C - 100 T.remove_air(100) proc/switchFireMode() switch(firemode) if(CRUISER_FIREMODE_BOTH) firemode = CRUISER_FIREMODE_ALT boutput(usr, "Fire mode now: Alternate") if(CRUISER_FIREMODE_ALT) firemode = CRUISER_FIREMODE_LEFT boutput(usr, "Fire mode now: Left only") if(CRUISER_FIREMODE_LEFT) firemode = CRUISER_FIREMODE_RIGHT boutput(usr, "Fire mode now: Right only") if(CRUISER_FIREMODE_RIGHT) firemode = CRUISER_FIREMODE_BOTH boutput(usr, "Fire mode now: Simultaneous") return Bump(atom/O) ..(O) if(ramming) ramming-- O.meteorhit(src) if(istype(O, /atom/movable)) if(!O:anchored) step(O,dir) internal_sound(src.loc, 'sound/machines/armorimpact.ogg', 80, 1, -1) if(shields) damageShields(50, D_SPECIAL) else damageArmor(11, D_SPECIAL) shakeCruiser(3, 2, 0.3) if(!ramming) walk(src, 0) src.flying = 0 proc/enableRamming() src.addPowerUse("rammingMode", 90, -1) internal_sound(src.loc, 'sound/machines/boost.ogg', 100, 1, -1) src.speed_mod -= 2 src.ramming += 8 spawn(100) src.speed_mod += 2 src.removePowerUse("rammingMode") src.ramming = max(src.ramming - 8, 0) walk(src, 0) src.flying = 0 return proc/overload_weapons() src.addPowerUse("weaponOverload", 90, -1) internal_sound(src.loc, 'sound/machines/weaponoverload.ogg', 80, 1, -1) src.weapon_cooldown_mod -= 3 spawn(100) src.weapon_cooldown_mod += 3 src.removePowerUse("weaponOverload") return proc/overload_shields() src.addPowerUse("shieldOverload", 90, -1) src.shield_regen_always += 1 src.shield_regen_boost += 10 var/image/I = image('icons/obj/160x160.dmi',shield_obj,"shieldoverload",shield_obj.layer+1) I.alpha = 150 shield_obj.overlays += I internal_sound(src.loc, 'sound/machines/shieldoverload.ogg', 80, 0, -1) spawn(150) src.removePowerUse("shieldOverload") src.shield_regen_always -= 1 src.shield_regen_boost -= 5 shield_obj.overlays.Cut() return proc/toggleShieldModulation() shield_modulation = !shield_modulation internal_sound(src.loc, 'sound/machines/ArtifactAnc1.ogg', 65, 1, -1) if(shield_modulation) src.addPowerUse("shieldModulation", 90, -1) shield_obj.color = "#FF0000" else src.removePowerUse("shieldModulation") shield_obj.color = "#FFFFFF" return proc/addPowerUse(var/key, var/amount, var/rounds = -1) powerUse[key] = "[amount]=[rounds]" return proc/removePowerUse(var/key) if(powerUse[key]) powerUse.Remove(key) return proc/updatePower() if(engine) var/adjustment = 0 adjustment += (1 - (power_movement / 100)) * engine.powergenerated adjustment += (1 - (power_offense / 100)) * engine.powergenerated adjustment += (1 - (power_defense / 100)) * engine.powergenerated power_produced_last = engine.powergenerated + adjustment power_used_last = power_used engine.power_used = power_used power_used = 0 else power_produced_last = 0 updateIndicators() return proc/handlePowerCosts() for(var/U in powerUse) //v FUCK BYOND. FUCK. DOUBLEFUCK. TRIPLEFUCK. var/params = powerUse[U] var/list/L = params2list(params) var/usage = text2num(L[1]) var/rounds = text2num(L[L[1]]) power_used += usage if(rounds > 0) if((--rounds) <= 0) removePowerUse(U) else powerUse[U] = "[usage]=[rounds]" if(src.engine) if(src.flying) addPowerUse("thrusters", 10, 1) if(turret_left) addPowerUse("turretLeft", round(turret_left.power_used / 2), 1) if(turret_right) addPowerUse("turretRight", round(turret_right.power_used / 2), 1) if(life_support) addPowerUse("lifeSupport", life_support.power_used, 1) if(src.hasPower() && src.shields < src.shields_max && ((world.time - src.shields_timer) >= src.shields_delay || src.shield_regen_always)) addPowerUse("shieldRecharge", src.shields_recharge_cost, 1) src.adjustShields(src.shields_regen + shield_regen_boost) power_used = max(power_used, 0) src.updatePower() var/power_area = 1 if(!src.hasPower()) src.adjustShields(-src.shields_max) walk(src, 0) src.flying = 0 power_area = 0 interior_area.power_equip = power_area interior_area.power_light = power_area interior_area.power_environ = power_area interior_area.power_change() return proc/hasPower() if(power_used_last > power_produced_last || health <= 0) return 0 else return 1 return proc/damageArmor(var/amount, var/type = D_SPECIAL, var/use_resistance = 1) if(health <= 0) return //BEEP BOOP if(use_resistance) if(type & D_KINETIC || type & D_PIERCING || type & D_SLASHING) amount += (amount * 0.5) else if(type & D_TOXIC) amount = amount //TODO: Add special else if(type & D_SPECIAL) amount = amount //TODO: Add special shields_timer = world.time amount = round(max(1, amount)) adjustArmor(-amount, type) return proc/damageShields(var/amount, var/type = D_SPECIAL, var/use_resistance = 1) if(use_resistance) if(type & D_ENERGY || type & D_BURNING || type & D_RADIOACTIVE) if(!shield_modulation) amount += (amount * 0.5) else if(type & D_KINETIC || type & D_PIERCING || type & D_SLASHING) amount -= (amount * 0.25) else if(type & D_TOXIC) amount = amount //TODO: Add special else if(type & D_SPECIAL) amount = amount //TODO: Add special var/adjustment = (1 - (power_defense / 100)) * amount amount += adjustment shields_timer = world.time amount = round(max(1, amount)) adjustShields(-amount, type) return proc/adjustShields(var/amount, var/type = D_SPECIAL) shields_last = shields shields += amount shields = max(min(shields, shields_max), 0) var/percent_shields = max(min((shields / shields_max), 1), 0) if(shields_last > 0 && shields <= 0) //Collapse if(shield_obj.icon_state != "shield_collapse") internal_sound(src.loc, 'sound/machines/shielddown.ogg', 100, 1, -1) shield_obj.alpha = 170 shield_obj.icon_state = "shield_collapse" animate(shield_obj, loop = 1, time = 10, alpha = 1) else if(shields_last <= 0 && shields > 0) //Reboot if(shield_obj.icon_state != "shield_reboot") internal_sound(src.loc, 'sound/machines/shieldup.ogg', 100, 1, -1) shield_obj.alpha = 170 shield_obj.icon_state = "shield_reboot" animate(shield_obj, loop = 1, time = 10, alpha = round(170 * percent_shields)) else if(shields > 0) shield_obj.alpha = max(round(170 * percent_shields), 25) updateIndicators() return proc/warp() warping = 1 internal_sound(src.loc, 'sound/machines/cruiser_warp.ogg', 80, 0, 1) var/icon/warpOverlay = icon('icons/obj/160x160.dmi',"warp") overlays.Add(warpOverlay) animate(src, alpha = 0, time = 10) shield_obj.invisibility = 101 //warp sleep(20) animate(src, alpha = 255, time = 10) sleep(15) overlays.Cut() shield_obj.invisibility = 0 warping = 0 return proc/adjustArmor(var/amount, var/type = D_SPECIAL) if(amount < 0) distributeHealthDamage(amount) else distributeHealthRepair(amount) checkHealth() updateIndicators() if(amount < 0 && health <= (health_max - (health_max / 3)) && prob(10+degradation)) var/amount_add = nround((degradation / 2)/10) startFire(1+amount_add) return proc/distributeHealthRepair(var/amount) var/list/components = list() for(var/obj/machinery/cruiser_destroyable/D in interior_area) if(D.ignore || D.health == D.health_max) continue components.Add(D) //Shuffle list??? if(components.len) for(var/obj/machinery/cruiser_destroyable/D in components) if(!amount) break var/missing = D.health_max - D.health if(amount >= missing) D.adjustHealth(missing) amount -= missing else if (missing < amount) D.adjustHealth(amount) amount = 0 break return proc/distributeHealthDamage(var/amount) var/list/components = list() for(var/obj/machinery/cruiser_destroyable/D in interior_area) if(D.ignore || D.health == 0) continue components.Add(D) var/num_split = rand(1,4) var/list/selected = list() for(var/i=0, i 0 && health <= 0) destroy() return proc/startFire(var/amount = 1) if(interior_area) var/list/hotspot_turfs = list() for(var/turf/T in interior_area) if(T.density) continue hotspot_turfs.Add(T) for(var/i=0, iThe exit is blocked.") return proc/enterShip(atom/movable/O as obj, mob/user as mob) if(!interior_area || O == src) return var/entrance = get_turf(locate(/obj/landmark/cruiser_entrance) in interior_area) if(entrance) if(get_dist(O, getExitLoc()) <= 1) O.set_loc(entrance) if(ismob(O)) crew.Add(O) boutput(user, "You put [O] into [src].") else boutput(user, "[O] is too far away from [src]'s airlock.") return proc/shakeCruiser(duration, strength=1, delay=0.2) for(var/mob/M in crew) shake_camera(M, duration, strength, delay) return proc/getExitLoc() switch(src.dir) if(NORTH) return locate(src.x + 2, src.y - 1, src.z) if(EAST) return locate(src.x - 1, src.y + 2, src.z) if(SOUTH) return locate(src.x + 2, src.y + 5, src.z) if(WEST) return locate(src.x + 5, src.y + 2, src.z) /area/ship_interior/cruisertest name = "Cruiser interior" sound_group = "cruiser_1" /area/ship_interior/cruisertest2 name = "Cruiser interior" sound_group = "cruiser_2" /area/ship_interior name = "cruiser interior" icon = 'icons/turf/areas.dmi' icon_state = "eshuttle_transit" var/obj/machinery/cruiser/ship requires_power = 1 /obj/cruiser_camera_dummy name = "" invisibility = 101 anchored = 1 density = 0 /obj/machinery/cruiser_status_panel name = "Status panel" icon = 'icons/obj/ship.dmi' icon_state = "statpanel" density = 0 anchored = 1 var/image/barTop var/image/barMid var/image/barBot New() barTop = image('icons/obj/ship.dmi',src,"statpanel1",src.layer+1) barTop.color = "#8A1919" barMid = image('icons/obj/ship.dmi',src,"statpanel2",src.layer+1) barMid.color = "#19688A" barBot = image('icons/obj/ship.dmi',src,"statpanel3",src.layer+1) barBot.color = "#CF9417" proc/setValues(var/armor, var/shields, var/power) barTop.transform = matrix(armor, 1, MATRIX_SCALE) barTop.pixel_x = -nround( ((24 - (24 * armor)) / 2) ) barMid.transform = matrix(shields, 1, MATRIX_SCALE) barMid.pixel_x = -nround( ((24 - (24 * shields)) / 2) ) barBot.transform = matrix(power, 1, MATRIX_SCALE) barBot.pixel_x = -nround( ((24 - (24 * power)) / 2) ) src.overlays.Cut() src.overlays.Add(barTop) src.overlays.Add(barMid) src.overlays.Add(barBot) return /obj/machinery/cruiser_destroyable/cable_panel name = "Cable panel" icon_state = "wpanel0" icon_working = "wpanel0" icon_broken = "wpanel1" name_working = "Panel" name_broken = "Ruined cable panel" health = 20 health_max = 20 repair_time = 30 /obj/machinery/cruiser_destroyable/cable_floor name = "" desc = "A large hole in the floor." icon_state = "hole1" icon_working = "hole0" icon_broken = "hole1" name_working = "" name_broken = "hole" repair_time = 180 New() icon_broken = pick("hole1", "hole1a", "hole1b", "hole1c", "hole1d") ..() /obj/machinery/cruiser_destroyable name = "Panel" icon = 'icons/obj/ship.dmi' icon_state = "wpanel0" density = 0 anchored = 1 var/ignore = 0 //Wont count towards health / max health and won't break. var/broken = 0 var/health = 50 var/health_last = 0 var/health_max = 50 var/icon_working = "wpanel0" var/icon_broken = "wpanel1" var/name_working = "" var/name_broken = "" var/tool_type = /obj/item/wrench var/repair_time = 150 var/rebooting = 0 meteorhit() return bullet_act(var/obj/projectile/P) return ex_act(var/severity) return attackby(obj/item/W as obj, mob/user as mob) if (rebooting) return if (istype(W, tool_type) && (broken || health < health_max)) playsound(src.loc, "sound/machines/repairing.ogg", 85, 1) var/health_adj = 1 - (health / health_max) //90% = 0,1, 10% = 0,9 var/repair_time_adj = round(repair_time * health_adj) actions.start(new/datum/action/bar/icon/cruiser_repair(src, W, repair_time_adj), user) return 1 return 0 proc/reboot() //Called when the device is rebooted / in override mode. rebooting = 1 spawn(10) rebooting = 0 return "Reboot complete" proc/adjustHealth(var/amount) if(amount < 0 && health == 0) return if(amount > 0 && health == health_max) return health_last = health health += amount health = max(health, 0) health = min(health, health_max) checkHealth() return proc/checkHealth() if(health_last == 0 && health > 0) repair() else if(health_last > 0 && health == 0) destroy() return proc/destroy() if(broken) return broken = 1 setIcon() var/area/ship_interior/I = get_area(src) if(istype(I) && I.ship) I.ship.shakeCruiser(4, 5, 0.4) I.ship.degradation = min(I.ship.degradation + 2, 100) return proc/repair() if(!broken) return broken = 0 setIcon() return proc/setIcon() if(broken) icon_state = icon_broken name = name_broken else icon_state = icon_working name = name_working return /obj/machinery/cruiser_destroyable/cruiser_component_slot name = "Component slot" icon = 'icons/obj/ship.dmi' icon_state = "chute0" var/icon_state_open = "chute1" var/icon_state_closed = "chute0" var/container_type = /obj/item/shipcomponent var/open = 0 var/ready = 1 var/check_blocked = 1 setIcon() if(broken) src.setTexture("damaged", BLEND_MULTIPLY, "damaged") else src.UpdateOverlays(null, "damaged") if(open) icon_state = icon_state_open else icon_state = icon_state_closed attackby(obj/item/W as obj, mob/user as mob) if(!..()) if(open) user.drop_item() W.set_loc(src.loc) else attack_hand(user) return destroy() . = ..() open(null, 1) return . reboot() if(rebooting) return "Device is busy." rebooting = 1 open() sleep(repair_time / 2) if(health == 0) adjustHealth(1) rebooting = 0 close() return "Reboot complete." proc/open(var/mob/user = null, var/ignore_blocked = 0) if(open) return var/blocked = src.loc.density for(var/atom/B in src.loc) if(B.density) blocked = 1 break if(check_blocked && blocked && !ignore_blocked) if(user) boutput(user, "Something is preventing the [src] from opening.") else ready = 0 spawn(10) ready = 1 playsound(src.loc, 'sound/machines/hydraulic.ogg', 50, 0, -1) open = 1 setIcon() uninstall_component() density = 1 return proc/close(var/mob/user = null) if(!open) return if(rebooting) boutput(user, "This device is currently disabled.") return ready = 0 spawn(10) ready = 1 playsound(src.loc, 'sound/machines/weapons-deploy.ogg', 60, 0, -1) open = 0 setIcon() install_component() density = 0 return attack_hand(mob/user as mob) if(!ready) return if(open) if(broken) boutput(user, "[src] is broken. It needs to be repaired.") else close(user) else if(broken) boutput(user, "[src] is broken. It needs to be repaired.") return open(user) proc/install_component() return proc/uninstall_component() return /obj/machinery/cruiser_destroyable/cruiser_component_slot/weapon name = "Weapon slot" container_type = /obj/item/shipcomponent/mainweapon /obj/machinery/cruiser_destroyable/cruiser_component_slot/weapon/left name = "Left turret slot" install_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship) for(var/atom/movable/A in src.loc) if(istype(A, container_type)) A.set_loc(interior.ship) interior.ship.turret_left = A break return uninstall_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship && interior.ship.turret_left) interior.ship.turret_left.set_loc(src.loc) interior.ship.turret_left = null return /obj/machinery/cruiser_destroyable/cruiser_component_slot/weapon/right name = "Right turret slot" install_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship) for(var/atom/movable/A in src.loc) if(istype(A, container_type)) A.set_loc(interior.ship) interior.ship.turret_right = A break return uninstall_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship && interior.ship.turret_right) interior.ship.turret_right.set_loc(src.loc) interior.ship.turret_right = null return /obj/machinery/cruiser_destroyable/cruiser_component_slot/engine name = "Engine core" container_type = /obj/item/shipcomponent/engine health = 75 health_max = 75 install_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship) for(var/atom/movable/A in src.loc) if(istype(A, container_type)) A.set_loc(interior.ship) interior.ship.engine = A break return uninstall_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship && interior.ship.engine) interior.ship.engine.set_loc(src.loc) interior.ship.engine = null return /obj/machinery/cruiser_destroyable/cruiser_component_slot/life_support name = "Life support slot" icon = 'icons/obj/ship.dmi' icon_state = "chuteb1" icon_state_open = "chuteb0" icon_state_closed = "chuteb1" container_type = /obj/item/shipcomponent/life_support check_blocked = 0 install_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship) for(var/atom/movable/A in src.loc) if(istype(A, container_type)) A.set_loc(interior.ship) interior.ship.life_support = A break return uninstall_component() var/area/ship_interior/interior = get_area(src) if(interior && interior.ship && interior.ship.life_support) interior.ship.life_support.set_loc(src.loc) interior.ship.life_support = null return /obj/machinery/cruiser_destroyable/cruiser_exit name = "ship exit" desc = "This airlock leads out of the ship." icon = 'icons/obj/doors/blastdoor.dmi' icon_state = "bdoorsingle1" anchored = 1 density = 1 ignore = 1 bullet_act(var/obj/projectile/P) return ex_act(var/severity) return attack_hand(mob/user as mob) var/area/ship_interior/interior = get_area(src) if(interior.ship) interior.ship.leaveShip(user) /obj/machinery/cruiser_camera_screen name = "camera computer" icon = 'icons/obj/stationobjs.dmi' icon_state = "telescreen" density = 1 anchored = 1 attack_hand(mob/user as mob) if(istype(user.abilityHolder, /datum/abilityHolder/composite)) var/datum/abilityHolder/composite/C = user.abilityHolder C.addHolder(/datum/abilityHolder/cruiser) C.addAbility(/datum/targetable/cruiser/cancel_camera) user.client.view = 11 var/area/ship_interior/I = get_area(src) user.set_eye(I.ship) return /obj/machinery/cruiser_destroyable/cruiser_pod icon = 'icons/obj/64x64.dmi' icon_state = "pod_command_0" var/mob/using = null var/area/ship_interior/interior var/icon_state_full = "pod_command_1" var/icon_state_empty = "pod_command_0" var/datum/abilityHolder/cruiser/AbHolder var/list/abilities = list() bound_width = 32 bound_height = 32 texture_size = 64 density = 1 anchored = 1 health = 85 health_max = 85 remove_air(amount) return src.loc.remove_air(amount) return_air() return src.loc.return_air() bullet_act(var/obj/projectile/P) for(var/atom/A in src) A.bullet_act(P) return ex_act(var/severity) for(var/atom/A in src) A.ex_act(severity) return setIcon() if(broken) src.setTexture("damaged", BLEND_MULTIPLY, "damaged") else src.UpdateOverlays(null, "damaged") if(using) icon_state = icon_state_full else icon_state = icon_state_empty destroy() . = ..() exitPod() return . reboot() if(rebooting) return "Device is busy." rebooting = 1 exitPod() sleep(repair_time / 2) if(health == 0) adjustHealth(1) rebooting = 0 return "Reboot complete." New() interior = get_area(src) icon_state = icon_state_empty AbHolder = new() AbHolder.addAbility(/datum/targetable/cruiser/exit_pod) for(var/T in abilities) AbHolder.addAbility(T) SubscribeToProcess() return attack_hand(mob/user as mob) if(broken) boutput(user, "This pod is broken and must be repaired before it can be used again.") return if(using) boutput(user, "This pod is already being used.") return else enterPod(user) MouseDrop_T(atom/movable/O as obj, mob/user as mob) if(ismob(O) && O:client) attack_hand(O) return proc/enterPod(mob/user as mob) var/obj/machinery/cruiser/C = interior.ship if(rebooting) boutput(user, "This device is currently disabled.") return using = user user.set_loc(src) user.set_eye(C.camera) user.client.view = 11 if(ishuman(user) && istype(user.abilityHolder, /datum/abilityHolder/composite)) var/datum/abilityHolder/composite/H = user.abilityHolder H.addHolderInstance(AbHolder) AbHolder.resumeAllAbilities() if(C) user.client.images += C.frames user.client.images += C.overframes user.client.images += C.bar_top user.client.images += C.bar_middle user.client.images += C.bar_bottom setIcon() return proc/exitPod() var/obj/machinery/cruiser/C = interior.ship if(!using) return using.set_loc(src.loc) using.set_eye(null) using.client.view = world.view if(ishuman(using) && istype(using.abilityHolder, /datum/abilityHolder/composite)) using.targeting_spell = null using.update_cursor() var/datum/abilityHolder/composite/H = using.abilityHolder AbHolder.suspendAllAbilities() H.removeHolder(/datum/abilityHolder/cruiser) if(C) using.client.images -= C.frames using.client.images -= C.overframes using.client.images -= C.bar_top using.client.images -= C.bar_middle using.client.images -= C.bar_bottom using = null setIcon() return process() ..() return /obj/machinery/cruiser_destroyable/cruiser_pod/movement name = "Navigation pod" icon_state_full = "pod_command_1" icon_state_empty = "pod_command_0" abilities = list(/datum/targetable/cruiser/ram) relaymove(mob/user, direction) var/obj/machinery/cruiser/C = interior.ship if (C) C.recieveMovement(direction) return /obj/machinery/cruiser_destroyable/cruiser_pod/security name = "Security pod" icon_state = "pod_security_0" icon_state_full = "pod_security_1" icon_state_empty = "pod_security_0" abilities = list(/datum/targetable/cruiser/fire_weapons, /datum/targetable/cruiser/firemode, /datum/targetable/cruiser/weapon_overload) /obj/machinery/cruiser_destroyable/cruiser_pod/engineering name = "Engineering pod" icon_state = "pod_engineer_0" icon_state_full = "pod_engineer_1" icon_state_empty = "pod_engineer_0" abilities = list(/datum/targetable/cruiser/warp, /datum/targetable/cruiser/shield_overload, /datum/targetable/cruiser/shield_modulation)