diff --git a/README.md b/README.md index ba147006b56f0..76a2089db7625 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,6 @@ Sprites added in commit d407e97e26ee5e6bb1daf945a8eb3bd9a6b11976 are CC-BY-NC 3. All sounds added/remixed in the PR https://github.com/tgstation/TerraGov-Marine-Corps/pull/5261 are licensed under CC-BY-NC-SA 3.0 +Sound added in PR https://github.com/tgstation/TerraGov-Marine-Corps/pull/5603 is taken from https://freesound.org/people/nicStage/sounds/127731/ (CC Attribution) + The TGS DMAPI API is licensed as a subproject under the MIT license. diff --git a/code/__HELPERS/movable.dm b/code/__HELPERS/movable.dm deleted file mode 100644 index b8aa5c36f31f1..0000000000000 --- a/code/__HELPERS/movable.dm +++ /dev/null @@ -1,43 +0,0 @@ -/atom/movable/proc/line_of_sight(atom/target, view_dist = WORLD_VIEW_NUM) - if(QDELETED(target)) - return FALSE - - if(z != target.z) //No multi-z. - return FALSE - - var/total_distance = get_dist(src, target) - - if(total_distance > view_dist) - return FALSE - - switch(total_distance) - if(-1) - if(target == src) //We can see ourselves alright. - return TRUE - else //Standard get_dist() error condition. - return FALSE - if(null) //Error, does not compute. - CRASH("get_dist returned null on line_of_sight() with [src] as src and [target] as target") - if(0, 1) //We can see our own tile and the next one regardless. - return TRUE - - var/turf/turf_to_check = get_turf(src) - var/turf/target_turf = get_turf(target) - - for(var/i in 1 to total_distance - 1) - turf_to_check = get_step(turf_to_check, get_dir(turf_to_check, target_turf)) - if(IS_OPAQUE_TURF(turf_to_check)) - return FALSE //First and last turfs' opacity don't matter, but the ones in-between do. - for(var/obj/stuff_in_turf in turf_to_check) - if(!stuff_in_turf.opacity) - continue //Transparent, we can see through it. - if(!CHECK_BITFIELD(stuff_in_turf.flags_atom, ON_BORDER)) - return FALSE //Opaque and not on border. We can't see through this tile, it's over. - if(ISDIAGONALDIR(stuff_in_turf.dir)) - return FALSE //Opaque fulltile window. - if(CHECK_BITFIELD(dir, stuff_in_turf.dir)) - return FALSE //Same direction and opaque, blocks our view. - if(CHECK_BITFIELD(dir, reverse_direction(stuff_in_turf.dir))) - return FALSE //Doesn't block this tile, but it does block the next, and this is not the last pass. - - return TRUE diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 1e5d715777b06..66dce5707f528 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1008,26 +1008,6 @@ GLOBAL_LIST_INIT(common_tools, typecacheof(list( #define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) -/proc/reverse_direction(direction) - switch(direction) - if(NORTH) - return SOUTH - if(NORTHEAST) - return SOUTHWEST - if(EAST) - return WEST - if(SOUTHEAST) - return NORTHWEST - if(SOUTH) - return NORTH - if(SOUTHWEST) - return NORTHEAST - if(WEST) - return EAST - if(NORTHWEST) - return SOUTHEAST - - /proc/reverse_nearby_direction(direction) switch(direction) if(NORTH) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b93066994f797..0fb87b2042874 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -922,3 +922,48 @@ /atom/movable/proc/CanPassThrough(atom/blocker, turf/target, blocker_opinion) SHOULD_CALL_PARENT(TRUE) return blocker_opinion + +///returns FALSE if there isnt line of sight to target within view dist and TRUE if there is +/atom/movable/proc/line_of_sight(atom/target, view_dist = WORLD_VIEW_NUM) + if(QDELETED(target)) + return FALSE + + if(z != target.z) //No multi-z. + return FALSE + + var/total_distance = get_dist(src, target) + + if(total_distance > view_dist) + return FALSE + + switch(total_distance) + if(-1) + if(target == src) //We can see ourselves alright. + return TRUE + else //Standard get_dist() error condition. + return FALSE + if(null) //Error, does not compute. + CRASH("get_dist returned null on line_of_sight() with [src] as src and [target] as target") + if(0, 1) //We can see our own tile and the next one regardless. + return TRUE + + var/turf/turf_to_check = get_turf(src) + var/turf/target_turf = get_turf(target) + + for(var/i in 1 to total_distance - 1) + turf_to_check = get_step(turf_to_check, get_dir(turf_to_check, target_turf)) + if(IS_OPAQUE_TURF(turf_to_check)) + return FALSE //First and last turfs' opacity don't matter, but the ones in-between do. + for(var/obj/stuff_in_turf in turf_to_check) + if(!stuff_in_turf.opacity) + continue //Transparent, we can see through it. + if(!CHECK_BITFIELD(stuff_in_turf.flags_atom, ON_BORDER)) + return FALSE //Opaque and not on border. We can't see through this tile, it's over. + if(ISDIAGONALDIR(stuff_in_turf.dir)) + return FALSE //Opaque fulltile window. + if(CHECK_BITFIELD(dir, stuff_in_turf.dir)) + return FALSE //Same direction and opaque, blocks our view. + if(CHECK_BITFIELD(dir, REVERSE_DIR(stuff_in_turf.dir))) + return FALSE //Doesn't block this tile, but it does block the next, and this is not the last pass. + + return TRUE diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 3d0807bec45f7..c143d224ce29d 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -59,3 +59,23 @@ name = "transfer plasma" icon_state = "transfer_plasma" duration = 0.5 SECONDS + + +/obj/effect/temp_visual/xenomorph/runner_afterimage + name = "runner afterimage" + desc = "It has become speed.." + icon = 'icons/Xeno/2x2_Xenos.dmi' //They are now like, 2x1 or something + icon_state = "Runner Walking" + layer = MOB_LAYER + alpha = 64 //Translucent + duration = 0.5 SECONDS + density = FALSE + opacity = FALSE + anchored = FALSE + animate_movement = SLIDE_STEPS + +/obj/effect/temp_visual/heavyimpact + name = "heavy impact" + icon = 'icons/effects/heavyimpact.dmi' + icon_state = "heavyimpact" + duration = 13 diff --git a/code/game/objects/effects/temporary_visuals/temporary_visual.dm b/code/game/objects/effects/temporary_visuals/temporary_visual.dm index 955a721e50534..9386d87455897 100644 --- a/code/game/objects/effects/temporary_visuals/temporary_visual.dm +++ b/code/game/objects/effects/temporary_visuals/temporary_visual.dm @@ -35,18 +35,6 @@ setDir(set_dir) return ..() -/obj/effect/temp_visual/xenomorph/runner_afterimage - name = "runner afterimage" - desc = "It has become speed.." - icon = 'icons/Xeno/2x2_Xenos.dmi' //They are now like, 2x1 or something - icon_state = "Runner Walking" - layer = MOB_LAYER - alpha = 64 //Translucent - duration = 0.5 SECONDS - density = FALSE - opacity = FALSE - anchored = FALSE - animate_movement = SLIDE_STEPS ///Image that appears at the Xeno Rally target; only Xenos can see it /obj/effect/temp_visual/xenomorph/xeno_tracker_target diff --git a/code/game/objects/machinery/camera/camera_assembly.dm b/code/game/objects/machinery/camera/camera_assembly.dm index 3b1c9e9394515..13cd649e41049 100644 --- a/code/game/objects/machinery/camera/camera_assembly.dm +++ b/code/game/objects/machinery/camera/camera_assembly.dm @@ -35,7 +35,7 @@ user.visible_message("[user] begins attaching [src] to the wall.", "You being attaching [src] to the wall.") playsound(loc, 'sound/machines/click.ogg', 15, 1) - var/constrdir = reverse_direction(user.dir) + var/constrdir = REVERSE_DIR(user.dir) var/constrloc = user.loc if(!do_after(user, 30, TRUE, wall, BUSY_ICON_BUILD)) diff --git a/code/game/objects/structures/dropship_ammo.dm b/code/game/objects/structures/dropship_ammo.dm index 3be7513d46351..dd0da9c6c0ace 100644 --- a/code/game/objects/structures/dropship_ammo.dm +++ b/code/game/objects/structures/dropship_ammo.dm @@ -11,17 +11,20 @@ throwpass = TRUE climbable = TRUE resistance_flags = XENO_DAMAGEABLE - var/travelling_time = 100 //time to impact - var/equipment_type //type of equipment that accept this type of ammo. + ///Time before the ammo impacts + var/travelling_time = 10 SECONDS + ///type of equipment that accept this type of ammo. + var/equipment_type var/ammo_count var/max_ammo_count var/ammo_name = "round" //what to call the ammo in the ammo transfering message var/ammo_id - var/transferable_ammo = FALSE //whether the ammo inside this magazine can be transfered to another magazine. + ///whether the ammo inside this magazine can be transfered to another magazine. + var/transferable_ammo = FALSE var/accuracy_range = 3 //how many tiles the ammo can deviate from the laser target - var/warning_sound = 'sound/machines/hydraulics_2.ogg' //sound played mere seconds before impact + ///sound played mere seconds before impact + var/warning_sound = 'sound/machines/hydraulics_2.ogg' var/ammo_used_per_firing = 1 - var/max_inaccuracy = 6 //what's the max deviation allowed when the ammo is no longer guided by a laser. var/point_cost = 0 //how many points it costs to build this with the fabricator, set to 0 if unbuildable. @@ -52,7 +55,7 @@ to_chat(user, "You grab [PC.loaded] with [PC].") update_icon() return TRUE - . = ..() + return ..() examine(mob/user) @@ -64,7 +67,7 @@ to_chat(user, "It's loaded with \a [src].") return -/obj/structure/ship_ammo/proc/detonate_on(turf/impact) +/obj/structure/ship_ammo/proc/detonate_on(turf/impact, attackdir = NORTH) return @@ -75,53 +78,66 @@ icon_state = "30mm_crate" desc = "A crate full of 30mm bullets used on the dropship heavy guns." equipment_type = /obj/structure/dropship_equipment/weapon/heavygun + accuracy_range = 0 //always hits + travelling_time = 6 SECONDS ammo_count = 200 max_ammo_count = 200 transferable_ammo = TRUE ammo_used_per_firing = 20 point_cost = 50 - var/bullet_spread_range = 4 //how far from the real impact turf can bullets land + ///Radius of the square that the bullets will strafe + var/bullet_spread_range = 2 + ///Width of the square we are attacking, so you can make rectangular attacks later + var/attack_width = 3 - examine(mob/user) - ..() - to_chat(user, "It has [ammo_count] round\s.") - - show_loaded_desc(mob/user) - if(ammo_count) - to_chat(user, "It's loaded with \a [src] containing [ammo_count] round\s.") - else - to_chat(user, "It's loaded with an empty [name].") - - detonate_on(turf/impact) - set waitfor = 0 - var/list/turf_list = list() - for(var/turf/T in range(impact, bullet_spread_range)) - turf_list += T - var/soundplaycooldown = 0 - var/debriscooldown = 0 - for(var/i=1, i<=ammo_used_per_firing, i++) - var/turf/U = pick(turf_list) - turf_list -= U - sleep(1) - U.ex_act(3) - for(var/atom/movable/AM in U) - AM.ex_act(3) - if(!soundplaycooldown) //so we don't play the same sound 20 times very fast. - playsound(U, get_sfx("explosion"), 40, 1, 20, falloff = 3) - soundplaycooldown = 3 - soundplaycooldown-- - if(!debriscooldown) - U.ceiling_debris_check(1) - debriscooldown = 6 - debriscooldown-- - new /obj/effect/particle_effect/expl_particles(U) +/obj/structure/ship_ammo/heavygun/examine(mob/user) + . = ..() + to_chat(user, "It has [ammo_count] round\s.") + +/obj/structure/ship_ammo/heavygun/show_loaded_desc(mob/user) + if(ammo_count) + to_chat(user, "It's loaded with \a [src] containing [ammo_count] round\s.") + else + to_chat(user, "It's loaded with an empty [name].") + +/obj/structure/ship_ammo/heavygun/detonate_on(turf/impact, attackdir = NORTH) + playsound(impact, 'sound/effects/casplane_flyby.ogg', 40) + var/turf/beginning = impact + var/revdir = REVERSE_DIR(attackdir) + for(var/i=0 to bullet_spread_range) + beginning = get_step(beginning, revdir) + var/list/strafelist = list(beginning) + strafelist += get_step(beginning, turn(attackdir, 90)) + strafelist += get_step(beginning, turn(attackdir, -90)) //Build this list 3 turfs at a time for strafe_turfs + for(var/b=0 to bullet_spread_range*2) + beginning = get_step(beginning, attackdir) + strafelist += beginning + strafelist += get_step(beginning, turn(attackdir, 90)) + strafelist += get_step(beginning, turn(attackdir, -90)) + strafe_turfs(strafelist) + +///Takes the top 3 turfs and miniguns them, then repeats until none left +/obj/structure/ship_ammo/heavygun/proc/strafe_turfs(list/strafelist) + var/turf/strafed + playsound(strafelist[1], get_sfx("explosion"), 40, 1, 20, falloff = 3) + for(var/i=1 to attack_width) + strafed = strafelist[1] + strafelist -= strafed + strafed.ex_act(EXPLODE_LIGHT) + new /obj/effect/particle_effect/expl_particles(strafed) + new /obj/effect/temp_visual/heavyimpact(strafed) + for(var/atom/movable/AM as() in strafed) + AM.ex_act(EXPLODE_LIGHT) + + if(length(strafelist)) + addtimer(CALLBACK(src, .proc/strafe_turfs, strafelist), 2) /obj/structure/ship_ammo/heavygun/highvelocity name = "high-velocity 30mm ammo crate" icon_state = "30mm_crate_hv" desc = "A crate full of 30mm high-velocity bullets used on the dropship heavy guns." - travelling_time = 60 + travelling_time = 6 SECONDS ammo_count = 400 max_ammo_count = 400 ammo_used_per_firing = 40 @@ -136,22 +152,23 @@ name = "high-capacity laser battery" icon_state = "laser_battery" desc = "A high-capacity laser battery used to power laser beam weapons." - travelling_time = 10 + travelling_time = 1 SECONDS ammo_count = 100 max_ammo_count = 100 ammo_used_per_firing = 40 equipment_type = /obj/structure/dropship_equipment/weapon/laser_beam_gun ammo_name = "charge" transferable_ammo = TRUE - accuracy_range = 1 + accuracy_range = 0 //its a laser ammo_used_per_firing = 10 - max_inaccuracy = 1 warning_sound = 'sound/effects/nightvision.ogg' point_cost = 150 + ///The length of the beam that will come out of when we fire do both ends xxxoxxx where o is where you click + var/laze_radius = 4 /obj/structure/ship_ammo/laser_battery/examine(mob/user) - ..() + . = ..() to_chat(user, "It's at [round(100*ammo_count/max_ammo_count)]% charge.") @@ -162,28 +179,28 @@ to_chat(user, "It's loaded with an empty [name].") -/obj/structure/ship_ammo/laser_battery/detonate_on(turf/impact) - set waitfor = 0 - var/list/turf_list = list() - for(var/turf/T in range(impact, 3)) - turf_list += T - var/soundplaycooldown = 0 - for(var/i=1 to 20) - var/turf/U = pick(turf_list) - turf_list -= U - sleep(1) - laser_burn(U) - if(!soundplaycooldown) //so we don't play the same sound 20 times very fast. - playsound(U, 'sound/effects/pred_vision.ogg', 20, 1) - soundplaycooldown = 3 - soundplaycooldown-- - - if(!ammo_count && !gc_destroyed) - qdel(src) //deleted after last laser beam is fired and impact the ground. - +/obj/structure/ship_ammo/laser_battery/detonate_on(turf/impact, attackdir = NORTH) + var/turf/beginning = impact + var/turf/end = impact + var/revdir = REVERSE_DIR(attackdir) + for(var/i=0 to laze_radius) + beginning = get_step(beginning, revdir) + end = get_step(end, attackdir) + var/list/turf/lazertargets = getline(beginning, end) + process_lazer(lazertargets) + if(!ammo_count) + QDEL_IN(src, laze_radius+1) //deleted after last laser beam is fired and impact the ground. +///takes the top lazertarget on the stack and fires the lazer at it +/obj/structure/ship_ammo/laser_battery/proc/process_lazer(list/lazertargets) + laser_burn(lazertargets[1]) + lazertargets -= lazertargets[1] + if(length(lazertargets)) + INVOKE_NEXT_TICK(src, .proc/process_lazer, lazertargets) +///Lazer ammo acts on the turf passed in /obj/structure/ship_ammo/laser_battery/proc/laser_burn(turf/T) + playsound(T, 'sound/effects/pred_vision.ogg', 30, 1) for(var/mob/living/L in T) L.adjustFireLoss(120) L.adjust_fire_stacks(20) @@ -204,11 +221,10 @@ ammo_id = "" bound_width = 64 bound_height = 32 - travelling_time = 60 //faster than 30mm rounds - max_inaccuracy = 5 + travelling_time = 6 SECONDS //faster than 30mm rounds point_cost = 0 -/obj/structure/ship_ammo/rocket/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/detonate_on(turf/impact, attackdir = NORTH) qdel(src) @@ -217,11 +233,11 @@ name = "\improper AIM-224 'Widowmaker'" desc = "The AIM-224 is the latest in air to air missile technology. Earning the nickname of 'Widowmaker' from various dropship pilots after improvements to its guidence warhead prevents it from being jammed leading to its high kill rate. Not well suited for ground bombardment, but its high velocity makes it reach its target quickly." icon_state = "single" - travelling_time = 30 //not powerful, but reaches target fast + travelling_time = 4 SECONDS //not powerful, but reaches target fast ammo_id = "" point_cost = 150 -/obj/structure/ship_ammo/rocket/widowmaker/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/widowmaker/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(3) explosion(impact, 2, 4, 6) qdel(src) @@ -233,7 +249,7 @@ ammo_id = "b" point_cost = 175 -/obj/structure/ship_ammo/rocket/banshee/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/banshee/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(3) explosion(impact, 2, 4, 7, 6, flame_range = 7) //more spread out, with flames qdel(src) @@ -245,7 +261,7 @@ ammo_id = "k" point_cost = 300 -/obj/structure/ship_ammo/rocket/keeper/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/keeper/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(3) explosion(impact, 4, 5, 5, 6, small_animation = TRUE) //tighter blast radius, but more devastating near center qdel(src) @@ -256,11 +272,10 @@ desc = "The SM-17 'Fatty' is a cluster-bomb type ordnance that only requires laser-guidance when first launched." icon_state = "fatty" ammo_id = "f" - travelling_time = 70 //slower but deadly accurate, even if laser guidance is stopped mid-travel. - max_inaccuracy = 1 + travelling_time = 7 SECONDS //slower but deadly accurate, even if laser guidance is stopped mid-travel. point_cost = 300 -/obj/structure/ship_ammo/rocket/fatty/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/fatty/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(2) explosion(impact, 2, 3, 4) //first explosion is small to trick xenos into thinking its a minirocket. addtimer(CALLBACK(src, .proc/delayed_detonation, impact), 3 SECONDS) @@ -268,7 +283,7 @@ /obj/structure/ship_ammo/rocket/fatty/proc/delayed_detonation(turf/impact) var/list/impact_coords = list(list(-3,3),list(0,4),list(3,3),list(-4,0),list(4,0),list(-3,-3),list(0,-4), list(3,-3)) - for(var/i in 1 to 8) + for(var/i=1 to 8) var/list/coords = impact_coords[i] var/turf/detonation_target = locate(impact.x+coords[1],impact.y+coords[2],impact.z) detonation_target.ceiling_debris_check(2) @@ -282,10 +297,13 @@ ammo_id = "n" point_cost = 350 -/obj/structure/ship_ammo/rocket/napalm/detonate_on(turf/impact) +/obj/structure/ship_ammo/rocket/napalm/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(3) explosion(impact, 2, 3, 4, 6, small_animation = TRUE) //relatively weak flame_radius(5, impact, 60, 30) //cooking for a long time + var/datum/effect_system/smoke_spread/phosphorus/warcrime = new + warcrime.set_up(6, impact, 7) + warcrime.start() qdel(src) @@ -300,15 +318,14 @@ ammo_count = 6 max_ammo_count = 6 ammo_name = "minirocket" - travelling_time = 80 //faster than 30mm cannon, slower than real rockets + travelling_time = 7 SECONDS //faster than 30mm cannon, slower than real rockets transferable_ammo = TRUE point_cost = 100 -/obj/structure/ship_ammo/minirocket/detonate_on(turf/impact) +/obj/structure/ship_ammo/minirocket/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(2) - explosion(impact, 0, 2, 4, 5, adminlog = FALSE, small_animation = TRUE)//no messaging admin, that'd spam them. - var/datum/effect_system/expl_particles/P = new + var/datum/effect_system/expl_particles/P = new P.set_up(4, 0, impact) P.start() addtimer(CALLBACK(src, .proc/delayed_smoke_spread, impact), 0.5 SECONDS) @@ -335,9 +352,25 @@ icon_state = "minirocket_inc" point_cost = 200 -/obj/structure/ship_ammo/detonate_on(turf/impact) +/obj/structure/ship_ammo/minirocket/incendiary/detonate_on(turf/impact, attackdir = NORTH) . = ..() - impact.ignite() + flame_radius(3, impact) + +/obj/structure/ship_ammo/minirocket/smoke + name = "smoke mini rocket stack" + desc = "A pack of laser guided smoke mini rockets." + icon_state = "minirocket_smoke" + point_cost = 25 + +/obj/structure/ship_ammo/minirocket/smoke/detonate_on(turf/impact, attackdir = NORTH) + impact.ceiling_debris_check(2) + explosion(impact, 0, 0, 2, 2, throw_range = 0)// Smaller explosion + var/datum/effect_system/expl_particles/P = new + P.set_up(4, 0, impact) + P.start() + var/datum/effect_system/smoke_spread/S = new + S.set_up(3, impact) + S.start() /obj/structure/ship_ammo/minirocket/illumination name = "illumination rocket-launched flare stack" @@ -345,7 +378,7 @@ icon_state = "minirocket_ilm" point_cost = 25 // Not a real rocket, so its cheap -/obj/structure/ship_ammo/minirocket/illumination/detonate_on(turf/impact) +/obj/structure/ship_ammo/minirocket/illumination/detonate_on(turf/impact, attackdir = NORTH) impact.ceiling_debris_check(2) var/turf/offset_impact = pick(range(5, impact)) explosion(offset_impact, 0, 0, 2, 2, throw_range = 0)// Smaller explosion to prevent this becoming the PO meta @@ -375,4 +408,4 @@ set_light(light_power) T.visible_message("You see a tiny flash, and then a blindingly bright light from a flare as it lights off in the sky!") playsound(T, 'sound/weapons/guns/fire/flare.ogg', 50, 1, 4) // stolen from the mortar i'm not even sorry - QDEL_IN(src, rand(700, 900)) // About the same burn time as a flare, considering it requires it's own CAS run. + QDEL_IN(src, rand(70 SECONDS, 90 SECONDS)) // About the same burn time as a flare, considering it requires it's own CAS run. diff --git a/code/game/objects/structures/dropship_equipment.dm b/code/game/objects/structures/dropship_equipment.dm index b166ebd8e65b0..5d940956f6add 100644 --- a/code/game/objects/structures/dropship_equipment.dm +++ b/code/game/objects/structures/dropship_equipment.dm @@ -650,13 +650,11 @@ ammo_equipped.ammo_count = max(ammo_equipped.ammo_count-ammo_equipped.ammo_used_per_firing, 0) update_icon() -/obj/structure/dropship_equipment/weapon/proc/open_fire(obj/selected_target) - set waitfor = 0 +/obj/structure/dropship_equipment/weapon/proc/open_fire(obj/selected_target, attackdir) var/turf/target_turf = get_turf(selected_target) if(firing_sound) playsound(loc, firing_sound, 70, 1) var/obj/structure/ship_ammo/SA = ammo_equipped //necessary because we nullify ammo_equipped when firing big rockets - var/ammo_max_inaccuracy = SA.max_inaccuracy var/ammo_accuracy_range = SA.accuracy_range var/ammo_travelling_time = SA.travelling_time //how long the rockets/bullets take to reach the ground target. var/ammo_warn_sound = SA.warning_sound @@ -665,26 +663,17 @@ if(linked_shuttle) for(var/obj/structure/dropship_equipment/electronics/targeting_system/TS in linked_shuttle.equipments) ammo_accuracy_range = max(ammo_accuracy_range-2, 0) //targeting system increase accuracy and reduce travelling time. - ammo_max_inaccuracy = max(ammo_max_inaccuracy -3, 1) - ammo_travelling_time = max(ammo_travelling_time - 20, 10) + ammo_travelling_time = max(ammo_travelling_time - 2 SECONDS, 1 SECONDS) break - if(ammo_travelling_time) - var/total_seconds = max(round(ammo_travelling_time/10),1) - for(var/i = 0 to total_seconds) - sleep(10) - if(!selected_target || !selected_target.loc)//if laser disappeared before we reached the target, - ammo_accuracy_range = min(ammo_accuracy_range + 1, ammo_max_inaccuracy) //accuracy decreases - var/list/possible_turfs = list() - for(var/turf/TU in range(ammo_accuracy_range, target_turf)) + for(var/turf/TU as() in RANGE_TURFS(ammo_accuracy_range, target_turf)) possible_turfs += TU var/turf/impact = pick(possible_turfs) if(ammo_warn_sound) playsound(impact, ammo_warn_sound, 70, 1) new /obj/effect/overlay/temp/blinking_laser (impact) - sleep(10) - SA.detonate_on(impact) + addtimer(CALLBACK(SA, /obj/structure/ship_ammo.proc/detonate_on, impact, attackdir), ammo_travelling_time) /obj/structure/dropship_equipment/weapon/heavygun name = "\improper GAU-21 30mm cannon" diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 01c9e88cdd666..0f4fc334d98c3 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -33,7 +33,7 @@ if (bloodDNA && !locate(/obj/structure) in contents) src.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,H.dir,0,bloodcolor) // Coming - var/turf/from = get_step(H,reverse_direction(H.dir)) + var/turf/from = get_step(H,REVERSE_DIR(H.dir)) if(istype(from) && from) from.AddTracks(/obj/effect/decal/cleanable/blood/tracks/footprints,bloodDNA,0,H.dir,bloodcolor) // Going diff --git a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm index 42b82ab8cddad..f34e7f7f3c36f 100644 --- a/code/modules/mob/living/carbon/xenomorph/facehuggers.dm +++ b/code/modules/mob/living/carbon/xenomorph/facehuggers.dm @@ -354,7 +354,7 @@ if(M.in_throw_mode && M.dir != dir && !M.incapacitated() && !M.get_active_held_item()) var/catch_chance = 50 - if(M.dir == reverse_direction(dir)) + if(M.dir == REVERSE_DIR(dir)) catch_chance += 20 catch_chance -= M.shock_stage * 0.3 if(M.get_inactive_held_item()) diff --git a/code/modules/shuttle/cas_plane.dm b/code/modules/shuttle/cas_plane.dm index 8175969570aa1..2f7f057b8be1c 100644 --- a/code/modules/shuttle/cas_plane.dm +++ b/code/modules/shuttle/cas_plane.dm @@ -149,6 +149,8 @@ ///What state our plane is in, i.e can we launch/do we have to deploy stairs etc var/state = PLANE_STATE_DEACTIVATED + ///Direction we will use for attacks while in combat mode + var/attackdir = NORTH ///List of engine tiles so we can track them for overlays var/list/engines = list() ///Chair that handles all the ui and click stuff @@ -319,7 +321,7 @@ if(!COOLDOWN_CHECK(active_weapon, last_fired)) to_chat(source, "[active_weapon] just fired, wait for it to cool down.") return - active_weapon.open_fire(target) + active_weapon.open_fire(target, attackdir) /obj/structure/caspart/caschair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -342,6 +344,7 @@ .["fuel_left"] = fuel_left .["fuel_max"] = fuel_max .["ship_status"] = getStatusText() + .["attackdir"] = uppertext(dir2text(attackdir)) var/element_nbr = 1 .["all_weapons"] = list() for(var/i in equipments) @@ -411,6 +414,9 @@ owner.turn_on_engines() if(PLANE_STATE_PREPARED) owner.turn_off_engines() + if("cycle_attackdir") + owner.attackdir = turn(owner.attackdir, 90) + . = TRUE diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index bfcb6f64d0bf4..e4f0acfb95258 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -117,7 +117,7 @@ return FALSE if(is_train_head()) - if(direction == reverse_direction(dir) && tow) + if(direction == REVERSE_DIR(dir) && tow) return 0 return ..() diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm index 549f6689a8469..50303db0e6b81 100644 --- a/code/modules/vehicles/train.dm +++ b/code/modules/vehicles/train.dm @@ -146,7 +146,7 @@ if(dir == T_dir) //if car is ahead src.attach_to(T, user, silent) - else if(reverse_direction(dir) == T_dir) //else if car is behind + else if(REVERSE_DIR(dir) == T_dir) //else if car is behind T.attach_to(src, user, silent) //returns true if this is the lead car of the train diff --git a/icons/Marine/mainship_props.dmi b/icons/Marine/mainship_props.dmi index 7aa2c83670d5f..ccec5fe94e9de 100644 Binary files a/icons/Marine/mainship_props.dmi and b/icons/Marine/mainship_props.dmi differ diff --git a/icons/effects/heavyimpact.dmi b/icons/effects/heavyimpact.dmi new file mode 100644 index 0000000000000..dedaca533ac5c Binary files /dev/null and b/icons/effects/heavyimpact.dmi differ diff --git a/sound/effects/casplane_flyby.ogg b/sound/effects/casplane_flyby.ogg new file mode 100644 index 0000000000000..2a0874eb4f973 Binary files /dev/null and b/sound/effects/casplane_flyby.ogg differ diff --git a/tgmc.dme b/tgmc.dme index bf5f046ca0915..d83b324c97484 100644 --- a/tgmc.dme +++ b/tgmc.dme @@ -110,7 +110,6 @@ #include "code\__HELPERS\level_traits.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" -#include "code\__HELPERS\movable.dm" #include "code\__HELPERS\patterns.dm" #include "code\__HELPERS\pencode.dm" #include "code\__HELPERS\pronouns.dm" diff --git a/tgui/packages/tgui/interfaces/MarineCasship.js b/tgui/packages/tgui/interfaces/MarineCasship.js index 9f0b7f7b51eb2..e491a33887f96 100644 --- a/tgui/packages/tgui/interfaces/MarineCasship.js +++ b/tgui/packages/tgui/interfaces/MarineCasship.js @@ -151,6 +151,13 @@ const NormalOperation = (props, context) => { onClick={() => act("deploy")} disabled={data.plane_state !== 3} /> + +