diff --git a/code/datums/riding.dm b/code/datums/riding.dm index 746cc6dcf7..4f9513397a 100644 --- a/code/datums/riding.dm +++ b/code/datums/riding.dm @@ -101,7 +101,7 @@ if(keycheck(user)) if(!Process_Spacemove(direction) || !isturf(ridden.loc)) return - step(ridden, direction) + ridden.Move(get_step(ridden, direction)) handle_vehicle_layer() handle_vehicle_offsets() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index c17adfd9c2..a320f6340c 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -66,40 +66,51 @@ if(!newloc.Enter(src, src.loc)) return + + if(!check_multi_tile_move_density_dir(direct, locs)) // We're big, and we can't move that way. + return + // Past this is the point of no return - var/atom/oldloc = loc - var/area/oldarea = get_area(oldloc) - var/area/newarea = get_area(newloc) - loc = newloc - . = TRUE - oldloc.Exited(src, newloc) - if(oldarea != newarea) - oldarea.Exited(src, newloc) + if(!locs || locs.len <= 1) // We're not a multi-tile object. + var/atom/oldloc = loc + var/area/oldarea = get_area(oldloc) + var/area/newarea = get_area(newloc) + loc = newloc + . = TRUE + oldloc.Exited(src, newloc) + if(oldarea != newarea) + oldarea.Exited(src, newloc) - for(var/i in oldloc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Uncrossed(src) + for(var/i in oldloc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Uncrossed(src) - newloc.Entered(src, oldloc) - if(oldarea != newarea) - newarea.Entered(src, oldloc) + newloc.Entered(src, oldloc) + if(oldarea != newarea) + newarea.Entered(src, oldloc) + + for(var/i in loc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Crossed(src) + + else if(newloc) // We're a multi-tile object. + . = doMove(newloc) - for(var/i in loc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Crossed(src) // //////////////////////////////////////// -/atom/movable/Move(atom/newloc, direct) +/atom/movable/Move(atom/newloc, direct = 0) if(!loc || !newloc) return FALSE var/atom/oldloc = loc if(loc != newloc) + if(!direct) + direct = get_dir(oldloc, newloc) if (!(direct & (direct - 1))) //Cardinal move . = ..() else //Diagonal move, split it into cardinal moves @@ -190,6 +201,13 @@ . = TRUE return CanPass(AM, loc) +/atom/movable/CanPass(atom/movable/mover, turf/target) + . = ..() + if(locs && locs.len >= 2) // If something is standing on top of us, let them pass. + if(mover.loc in locs) + . = TRUE + return . + //oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! /atom/movable/Crossed(atom/movable/AM, oldloc) return diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 7652e98571..35ee1cd7b6 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -205,13 +205,11 @@ set_ready_state(1) return - /obj/item/mecha_parts/mecha_equipment/Topic(href,href_list) if(href_list["detach"]) src.detach() return - /obj/item/mecha_parts/mecha_equipment/proc/set_ready_state(state) equip_ready = state if(chassis) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 3ea93b6f77..5df2c54d10 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -34,11 +34,18 @@ var/turf/aimloc = targloc if(deviation) aimloc = locate(targloc.x+GaussRandRound(deviation,1),targloc.y+GaussRandRound(deviation,1),targloc.z) - if(!aimloc || aimloc == curloc) + if(!aimloc || aimloc == curloc || (locs && aimloc in locs)) break playsound(chassis, fire_sound, fire_volume, 1) projectiles-- - var/P = new projectile(curloc) + var/turf/projectile_turf + if(chassis.locs && chassis.locs.len) // Multi tile. + for(var/turf/Tloc in chassis.locs) + if(get_dist(Tloc, aimloc) < get_dist(loc, aimloc)) + projectile_turf = get_turf(Tloc) + if(!projectile_turf) + projectile_turf = get_turf(curloc) + var/P = new projectile(projectile_turf) Fire(P, target, params) if(i == 1) set_ready_state(0) @@ -61,11 +68,14 @@ return /obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, params) - var/obj/item/projectile/P = A - P.dispersion = deviation - process_accuracy(P, chassis.occupant, target) - P.preparePixelProjectile(target, chassis.occupant, params) - P.fire() + if(istype(A, /obj/item/projectile)) // Sanity. + var/obj/item/projectile/P = A + P.dispersion = deviation + process_accuracy(P, chassis.occupant, target) + P.launch_projectile_from_turf(target, chassis.occupant.zone_sel.selecting, chassis.occupant, params) + else if(istype(A, /atom/movable)) + var/atom/movable/AM = A + AM.throw_at(target, 7, 1, chassis) /obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target) var/obj/item/projectile/P = projectile @@ -416,6 +426,7 @@ var/heavy_blast = 1 var/light_blast = 2 var/flash_blast = 4 + does_spin = FALSE // No fun corkscrew missiles. /obj/item/missile/proc/warhead_special(var/target) explosion(target, devastation, heavy_blast, light_blast, flash_blast) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 9b17cb8613..b556286292 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -49,6 +49,8 @@ var/mech_faction = null var/firstactivation = 0 //It's simple. If it's 0, no one entered it yet. Otherwise someone entered it at least once. + var/stomp_sound = 'sound/mecha/mechstep.ogg' + var/swivel_sound = 'sound/mecha/mechturn.ogg' //inner atmos var/use_internal_tank = 0 @@ -441,21 +443,24 @@ /obj/mecha/proc/mechturn(direction) set_dir(direction) - playsound(src,'sound/mecha/mechturn.ogg',40,1) + if(swivel_sound) + playsound(src,swivel_sound,40,1) return 1 /obj/mecha/proc/mechstep(direction) - var/result = step(src,direction) - if(result) - playsound(src,"mechstep",40,1) + var/result = get_step(src,direction) + if(result && Move(result)) + if(stomp_sound) + playsound(src,stomp_sound,40,1) handle_equipment_movement() return result /obj/mecha/proc/mechsteprand() - var/result = step_rand(src) - if(result) - playsound(src,"mechstep",40,1) + var/result = get_step_rand(src) + if(result && Move(result)) + if(stomp_sound) + playsound(src,stomp_sound,40,1) handle_equipment_movement() return result @@ -473,9 +478,10 @@ else //I have no idea why I disabled this obstacle.Bumped(src) else if(istype(obstacle, /mob)) - step(obstacle,src.dir) + var/mob/M = obstacle + M.Move(get_step(obstacle,src.dir)) else - obstacle.Bumped(src) + . = ..(obstacle) return /////////////////////////////////// diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 3e1b0aafc8..9894784e15 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -221,3 +221,11 @@ name = "Janus wreckage" icon_state = "janus-broken" description_info = "Due to the incredibly intricate design of this exosuit, it is impossible to salvage components from it." + +/obj/effect/decal/mecha_wreckage/shuttlecraft + name = "Shuttlecraft wreckage" + desc = "Remains of some unfortunate shuttlecraft. Completely unrepairable." + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "shuttle_standard-broken" + bound_width = 64 + bound_height = 64 diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index 90ab62681a..6e9dee5047 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -5,6 +5,8 @@ max_universal_equip = 1 max_special_equip = 1 + stomp_sound = 'sound/mecha/mechmove01.ogg' + cargo_capacity = 1 /obj/mecha/medical/Initialize() @@ -13,7 +15,7 @@ if(isPlayerLevel(T.z)) new /obj/item/mecha_parts/mecha_tracking(src) - +/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech /obj/mecha/medical/mechturn(direction) set_dir(direction) playsound(src,'sound/mecha/mechmove01.ogg',40,1) @@ -29,4 +31,5 @@ var/result = step_rand(src) if(result) playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result \ No newline at end of file + return result +*/ diff --git a/code/game/mecha/working/hoverpod.dm b/code/game/mecha/space/hoverpod.dm similarity index 91% rename from code/game/mecha/working/hoverpod.dm rename to code/game/mecha/space/hoverpod.dm index 8c19c2b004..85fc59d564 100644 --- a/code/game/mecha/working/hoverpod.dm +++ b/code/game/mecha/space/hoverpod.dm @@ -17,6 +17,9 @@ var/datum/effect/effect/system/ion_trail_follow/ion_trail var/stabilization_enabled = 1 + stomp_sound = 'sound/machines/hiss.ogg' + swivel_sound = null + max_hull_equip = 2 max_weapon_equip = 0 max_utility_equip = 2 @@ -49,7 +52,7 @@ output += ..() return output -//No space drifting +// No space drifting /obj/mecha/working/hoverpod/check_for_support() //does the hoverpod have enough charge left to stabilize itself? if (!has_charge(step_energy_drain)) @@ -62,6 +65,11 @@ return ..() +// No falling if we've got our boosters on +/obj/mecha/working/hoverpod/can_fall() + return (stabilization_enabled && has_charge(step_energy_drain)) + +/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech //these three procs overriden to play different sounds /obj/mecha/working/hoverpod/mechturn(direction) set_dir(direction) @@ -80,7 +88,7 @@ if(result) playsound(src,'sound/machines/hiss.ogg',40,1) return result - +*/ //Hoverpod variants /obj/mecha/working/hoverpod/combatpod diff --git a/code/game/mecha/space/shuttle.dm b/code/game/mecha/space/shuttle.dm new file mode 100644 index 0000000000..7e361ece0c --- /dev/null +++ b/code/game/mecha/space/shuttle.dm @@ -0,0 +1,99 @@ +/obj/mecha/working/hoverpod/shuttlecraft + desc = "A more advanced variant of the hoverpod." + name = "Shuttle" + catalogue_data = list(/datum/category_item/catalogue/technology/hoverpod) + icon = 'icons/mecha/mecha64x64.dmi' + icon_state = "shuttle_standard" + initial_icon = "shuttle_standard" + internal_damage_threshold = 60 + step_in = 2 + step_energy_drain = 5 + max_temperature = 20000 + health = 300 + maxhealth = 300 + infra_luminosity = 6 + wreckage = /obj/effect/decal/mecha_wreckage/shuttlecraft + cargo_capacity = 3 + max_equip = 3 + + opacity = FALSE + + stomp_sound = 'sound/machines/generator/generator_end.ogg' + swivel_sound = 'sound/machines/hiss.ogg' + + // Paint colors! Null if not set. + var/base_paint + var/engine_paint + var/central_paint + var/front_paint + + var/image/base_paint_mask + var/image/engine_paint_mask + var/image/central_paint_mask + var/image/front_paint_mask + + bound_height = 64 + bound_width = 64 + + max_hull_equip = 2 + max_weapon_equip = 1 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + +/obj/mecha/working/hoverpod/Initialize() + ..() + ion_trail.stop() + +/obj/mecha/working/hoverpod/shuttlecraft/moved_inside(var/mob/living/carbon/human/H as mob) + . = ..(H) + if(.) + ion_trail.start() + +/obj/mecha/working/hoverpod/shuttlecraft/go_out() + . = ..() + if(!occupant) + ion_trail.stop() + +/obj/mecha/working/hoverpod/shuttlecraft/update_icon() + overlays.Cut() + ..() + + if(base_paint) + if(!base_paint_mask) + base_paint_mask = image(icon, "[initial_icon]-mask+base", src.layer + 1) + base_paint_mask.color = base_paint + overlays |= base_paint_mask + if(front_paint) + if(!front_paint_mask) + front_paint_mask = image(icon, "[initial_icon]-mask+front", src.layer + 1) + front_paint_mask.color = front_paint + overlays |= front_paint_mask + if(engine_paint) + if(!engine_paint_mask) + engine_paint_mask = image(icon, "[initial_icon]-mask+engine", src.layer + 1) + engine_paint_mask.color = engine_paint + overlays |= engine_paint_mask + if(central_paint) + if(!engine_paint_mask) + central_paint_mask = image(icon, "[initial_icon]-mask+central", src.layer + 2) + central_paint_mask.color = central_paint + overlays |= central_paint_mask + +/obj/mecha/working/hoverpod/shuttlecraft/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/device/multitool) && state == 1) + var/new_paint_location = input("Please select a target zone.", "Paint Zone", null) as null|anything in list("Central", "Engine", "Base", "Front", "CANCEL") + if(new_paint_location && new_paint_location != "CANCEL") + var/new_paint_color = input("Please select a paint color.", "Paint Color", null) as color|null + if(new_paint_color) + switch(new_paint_location) + if("Central") + central_paint = new_paint_color + if("Engine") + engine_paint = new_paint_color + if("Front") + front_paint = new_paint_color + if("Base") + base_paint = new_paint_color + update_icon() + else ..() diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index f21d6443fb..551449a8fb 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -408,6 +408,10 @@ steam.start() -- spawns the effect src.processing = 0 spawn(0) var/turf/T = get_turf(src.holder) + if(istype(holder, /atom/movable)) + var/atom/movable/AM = holder + if(AM.locs && AM.locs.len) + T = pick(AM.locs) if(T != src.oldposition) if(isturf(T)) var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition) diff --git a/code/modules/multi-tile/multi-tile.dm b/code/modules/multi-tile/multi-tile.dm new file mode 100644 index 0000000000..b8dd9ef512 --- /dev/null +++ b/code/modules/multi-tile/multi-tile.dm @@ -0,0 +1,28 @@ +/* + * This is the home of multi-tile movement checks, and thus here be dragons. You are warned. + */ + +/atom/movable/proc/check_multi_tile_move_density_dir(var/stepdir) + if(!locs || !locs.len) + return TRUE + + if(bound_height > 32 || bound_width > 32) + var/safe_move = TRUE + var/list/checked_turfs = list() + for(var/turf/T in locs) + var/turf/Tcheck = get_step(T, stepdir) + if(Tcheck in checked_turfs) + continue + if(Tcheck in locs) + checked_turfs |= Tcheck + continue + if(!(Tcheck in locs)) + if(!T.Exit(src, Tcheck)) + safe_move = FALSE + if(!Tcheck.Enter(src, T)) + safe_move = FALSE + checked_turfs |= Tcheck + if(!safe_move) + break + return safe_move + return TRUE diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e180ac271c..d74bfb9caf 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -346,10 +346,18 @@ /obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0) var/turf/curloc = get_turf(source) var/turf/targloc = get_turf(target) + + if(istype(source, /atom/movable)) + var/atom/movable/MT = source + if(MT.locs && MT.locs.len) // Multi tile! + for(var/turf/T in MT.locs) + if(get_dist(T, target) < get_turf(curloc)) + curloc = get_turf(T) + trajectory_ignore_forcemove = TRUE forceMove(get_turf(source)) trajectory_ignore_forcemove = FALSE - starting = get_turf(source) + starting = curloc original = target if(targloc || !params) yo = targloc.y - curloc.y @@ -651,3 +659,14 @@ silenced = launcher.silenced return launch_projectile(target, target_zone, user, params, angle_override, forced_spread) + +/obj/item/projectile/proc/launch_projectile_from_turf(atom/target, target_zone, mob/user, params, angle_override, forced_spread = 0) + original = target + def_zone = check_zone(target_zone) + firer = user + var/direct_target + if(get_turf(target) == get_turf(src)) + direct_target = target + + preparePixelProjectile(target, get_turf(src), params, forced_spread) + return fire(angle_override, direct_target) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 15d2b21449..7f884698fd 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -81,7 +81,6 @@ if(riding_datum) riding_datum.handle_ride(user, direction) - /obj/vehicle/Moved() . = ..() if(riding_datum) diff --git a/icons/mecha/mecha64x64.dmi b/icons/mecha/mecha64x64.dmi index 37c60a6286..141724e4ad 100644 Binary files a/icons/mecha/mecha64x64.dmi and b/icons/mecha/mecha64x64.dmi differ diff --git a/icons/obj/vehicles_64x64.dmi b/icons/obj/vehicles_64x64.dmi index 98ed024d68..2558d66eed 100644 Binary files a/icons/obj/vehicles_64x64.dmi and b/icons/obj/vehicles_64x64.dmi differ diff --git a/polaris.dme b/polaris.dme index 8b32d9cd83..d6fe78402a 100644 --- a/polaris.dme +++ b/polaris.dme @@ -784,7 +784,8 @@ #include "code\game\mecha\equipment\weapons\weapons.dm" #include "code\game\mecha\medical\medical.dm" #include "code\game\mecha\medical\odysseus.dm" -#include "code\game\mecha\working\hoverpod.dm" +#include "code\game\mecha\space\hoverpod.dm" +#include "code\game\mecha\space\shuttle.dm" #include "code\game\mecha\working\ripley.dm" #include "code\game\mecha\working\working.dm" #include "code\game\objects\banners.dm" @@ -2206,6 +2207,7 @@ #include "code\modules\modular_computers\NTNet\emails\email_account.dm" #include "code\modules\modular_computers\NTNet\emails\email_message.dm" #include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" +#include "code\modules\multi-tile\multi-tile.dm" #include "code\modules\multiz\_stubs.dm" #include "code\modules\multiz\basic.dm" #include "code\modules\multiz\hoist.dm"