diff --git a/nsv13/code/__DEFINES/overmap.dm b/nsv13/code/__DEFINES/overmap.dm index b76e8577e0f..3495343ba18 100644 --- a/nsv13/code/__DEFINES/overmap.dm +++ b/nsv13/code/__DEFINES/overmap.dm @@ -114,6 +114,11 @@ GLOBAL_LIST_INIT(overmap_impact_sounds, list('nsv13/sound/effects/ship/freespace #define MASS_TITAN 150 //40+ Players - Large Capital Ships #define MASS_IMMOBILE 200 //Things that should not be moving. See: stations +//Collision stuff +#define OVERMAP_COLLISION_COOLDOWN 1 SECONDS //! Cooldown between collisions. +#define OVERMAP_COLLISION_MAGNIFIER 4 //! All collision damage big enough to go into the damage calculation itself is multiplied by this. +#define HAMMERHEAD_COLLISION_GUARD_ANGLE 55 //! Angle that determines maximum variance of collision angle to ship angle to count as "head" impact. + //Fun tools #define SHIELD_NOEFFECT 0 //!Shield failed to absorb hit. #define SHIELD_ABSORB 1 //!Shield absorbed hit. diff --git a/nsv13/code/modules/overmap/fighters/fighters_launcher.dm b/nsv13/code/modules/overmap/fighters/fighters_launcher.dm index 47dffe75ee1..2ee6e4ecbd7 100644 --- a/nsv13/code/modules/overmap/fighters/fighters_launcher.dm +++ b/nsv13/code/modules/overmap/fighters/fighters_launcher.dm @@ -157,7 +157,7 @@ linkup() /obj/structure/fighter_launcher/proc/shake_people(var/obj/structure/overmap/OM) - if(OM?.operators.len) + if(OM && length(OM.operators)) for(var/mob/M in OM.operators) shake_with_inertia(M, 10, 1) to_chat(M, "You feel a sudden jolt!") diff --git a/nsv13/code/modules/overmap/overmap.dm b/nsv13/code/modules/overmap/overmap.dm index 2c5eba460a9..45a6c8dc1df 100644 --- a/nsv13/code/modules/overmap/overmap.dm +++ b/nsv13/code/modules/overmap/overmap.dm @@ -31,6 +31,8 @@ var/sprite_size = 64 //Pixels. This represents 64x64 and allows for the bullets that you fire to align properly. var/area_type = null //Set the type of the desired area you want a ship to link to, assuming it's not the main player ship. var/impact_sound_cooldown = FALSE //Avoids infinite spamming of the ship taking damage. + ///Handles cooldown between collisions to avoid certain very bad times :) + var/next_collision = 0 var/datum/star_system/current_system //What star_system are we currently in? Used for parallax. var/resize = 0 //Factor by which we should shrink a ship down. 0 means don't shrink it. var/list/docking_points = list() //Where we can land on this ship. Usually right at the edge of a z-level. @@ -1005,3 +1007,14 @@ Proc to spool up a new Z-level for a player ship and assign it a treadmill. if(ftl_drive) return TRUE return FALSE + +/** + * Handles special modifications or effects an overmap has for collisions. + * * other_ship = the ship this collides with. + * * impact_powers = the strength of the impact for (this ship, other ship). Done this way because list pointer allows inplace var access. + * * impact_angle = The angle of the impact. + * + * This does NOT return the modified impact powers, as it is not neccessary due to inplace handling! + */ +/obj/structure/overmap/proc/spec_collision_handling(obj/structure/overmap/other_ship, list/impact_powers, impact_angle) + return diff --git a/nsv13/code/modules/overmap/physics.dm b/nsv13/code/modules/overmap/physics.dm index 99665fffe79..49656303f2c 100644 --- a/nsv13/code/modules/overmap/physics.dm +++ b/nsv13/code/modules/overmap/physics.dm @@ -438,6 +438,15 @@ This proc is to be used when someone gets stuck in an overmap ship, gauss, WHATE return return ..() +/** + * Handles collision between two overmap objects. + * * other = the object collided with. + * * c_response = ???? + * * collision_velocity = UNUSED + * + * * BEAR IN MIND col_angle and velocity angles go COUNTERCLOCKWISE starting EAST while (overmap) angle itself goes CLOCKWISE starting NORTH!!!!! + * * ^ ^ ^ ^ THIS IS REALLY IMPORTANT + */ /obj/structure/overmap/proc/collide(obj/structure/overmap/other, datum/collision_response/c_response, collision_velocity) //No colliders. But we still get a lot of info anyways! if(!c_response) @@ -452,7 +461,7 @@ This proc is to be used when someone gets stuck in an overmap ship, gauss, WHATE if(((cos(src.velocity.angle() - col_angle) * src_vel_mag) - (cos(other.velocity.angle() - col_angle) * other_vel_mag)) < 0) return - // Elastic collision equations + // Elastic collision equations - I don't feel like rewriting these so I'll just change the damage calculation unrelated to the new velocities :) ~Delta var/new_src_vel_x = (( \ (src_vel_mag * cos(src.velocity.angle() - col_angle) * (src.mass - other.mass)) + \ (2 * other.mass * other_vel_mag * cos(other.velocity.angle() - col_angle)) \ @@ -473,20 +482,46 @@ This proc is to be used when someone gets stuck in an overmap ship, gauss, WHATE (2 * src.mass * src_vel_mag * cos(src.velocity.angle() - col_angle)) \ ) / (other.mass + src.mass)) * sin(col_angle) + (other_vel_mag * sin(other.velocity.angle() - col_angle) * sin(col_angle + 90)) - src.velocity._set(new_src_vel_x, new_src_vel_y) - other.velocity._set(new_other_vel_x, new_other_vel_y) + //New calculations, go! + + //Calculate vector forces when angled towards collision angle. - var/bonk = src_vel_mag//How much we got bonked - var/bonk2 = other_vel_mag //Vs how much they got bonked - //Prevent ultra spam. - if(!impact_sound_cooldown && (bonk > 2 || bonk2 > 2)) - bonk *= 5 //The rammer gets an innate penalty, to discourage ramming metas. - bonk2 *= 5 - take_quadrant_hit(bonk, quadrant_impact(other)) //This looks horrible, but trust me, it isn't! Probably!. Armour_quadrant.dm for more info - other.take_quadrant_hit(bonk2, quadrant_impact(src)) //This looks horrible, but trust me, it isn't! Probably!. Armour_quadrant.dm for more info + var/self_vector_angle_diff = ((col_angle - velocity.angle()) + 360) % 360 //Byond modulo allows negative values as outcome apparently. :) + var/self_ramvec = src_vel_mag * cos(self_vector_angle_diff) - log_game("[key_name(pilot)] has impacted an overmap ship into [other] with velocity [bonk]") + var/other_vector_angle_diff = ((col_angle + 180 - other.velocity.angle()) + 360) % 360 + var/other_ramvec = other_vel_mag * cos(other_vector_angle_diff) + var/total_force = (self_ramvec + other_ramvec) //Forces combined + + if(world.time >= next_collision && total_force >= 2) //Magic! + total_force *= OVERMAP_COLLISION_MAGNIFIER //Arbitrary amplifier to collisions (used to be x5, for now x4 because of new math) + //Impact forces applied to each ship. + var/own_impact_power = CLAMP(other.mass / mass, 0.2, 10) * (total_force * 0.5) //I'm kind of scared of how the masses of big chonkers are going to interact so I'm capping this for now :) + var/other_impact_power = CLAMP(mass / other.mass, 0.2, 10) * (total_force * 0.5) + if(self_ramvec > other_ramvec) + own_impact_power *= 2 //The one having more impact force towards the ramming vector takes more damage. + else + other_impact_power *= 2 + var/list/impact_powers = list(own_impact_power, other_impact_power) //List for inplace adjustments + var/modulated_col_angle = (col_angle + 360) % 360 + spec_collision_handling(other, impact_powers, modulated_col_angle) + impact_powers = reverseList(impact_powers) + other.spec_collision_handling(src, impact_powers, ((modulated_col_angle + 180) % 360)) + own_impact_power = impact_powers[2] //Remember, we turned this around! + other_impact_power = impact_powers[1] + if(own_impact_power > 0) + take_quadrant_hit(own_impact_power, quadrant_impact(other)) + if(other_impact_power > 0) + other.take_quadrant_hit(other_impact_power, other.quadrant_impact(src)) + + next_collision = world.time + OVERMAP_COLLISION_COOLDOWN + log_game("[key_name(pilot)] has impacted an overmap ship into [other] \[Total collision force:[total_force]\]") + //Uncomment for debug :) + //message_admins("COLLISION DEBUG: own mag / ramvec: \[[src_vel_mag]|[self_ramvec]\]; other mag / remvec: \[[other_vel_mag]|[other_ramvec]\]; total force / own force / other force: \[[total_force]|[own_impact_power]|[other_impact_power]\]; Angles - collision angle / vector angle / angle diff / other vector angle / other angle diff: \[CA[col_angle]|VA[velocity.angle()]|AD[self_vector_angle_diff]|OVA[other.velocity.angle()]|OAD[other_vector_angle_diff]\]") + + src.velocity._set(new_src_vel_x, new_src_vel_y) + other.velocity._set(new_other_vel_x, new_other_vel_y) return TRUE //Update the colliders before we do any kind of calc. diff --git a/nsv13/code/modules/overmap/types/nanotrasen.dm b/nsv13/code/modules/overmap/types/nanotrasen.dm index 9d3ca87896c..f59fe833260 100644 --- a/nsv13/code/modules/overmap/types/nanotrasen.dm +++ b/nsv13/code/modules/overmap/types/nanotrasen.dm @@ -202,6 +202,14 @@ overmap_deletion_traits = DAMAGE_STARTS_COUNTDOWN broadside = TRUE +/obj/structure/overmap/nanotrasen/heavy_cruiser/starter/spec_collision_handling(obj/structure/overmap/other_ship, list/impact_powers, impact_angle) + var/modified_angle = 360 - ((angle + 630) % 360) + var/angle_diff = impact_angle - modified_angle + if(abs(angle_diff) > HAMMERHEAD_COLLISION_GUARD_ANGLE) + return + impact_powers[1] *= 0.5 // x 0.5 self damage + impact_powers[2] *= 2.5 // x 2.5 other damage + /obj/structure/overmap/nanotrasen/heavy_cruiser/starter/apply_weapons() weapon_types[FIRE_MODE_AMS] = new /datum/ship_weapon/vls(src) weapon_types[FIRE_MODE_GAUSS] = new /datum/ship_weapon/gauss(src) diff --git a/nsv13/code/modules/overmap/types/syndicate.dm b/nsv13/code/modules/overmap/types/syndicate.dm index 29427a2ebf7..307d530d530 100644 --- a/nsv13/code/modules/overmap/types/syndicate.dm +++ b/nsv13/code/modules/overmap/types/syndicate.dm @@ -180,6 +180,14 @@ combat_dice_type = /datum/combat_dice/destroyer possible_interior_maps = list(/datum/map_template/boarding/destroyer) +/obj/structure/overmap/syndicate/ai/destroyer/spec_collision_handling(obj/structure/overmap/other_ship, list/impact_powers, impact_angle) + var/modified_angle = 360 - ((angle + 630) % 360) + var/angle_diff = impact_angle - modified_angle + if(abs(angle_diff) > HAMMERHEAD_COLLISION_GUARD_ANGLE) + return + impact_powers[1] *= 0.5 // x 0.5 self damage + impact_powers[2] *= 2.5 // x 2.5 other damage + /obj/structure/overmap/syndicate/ai/destroyer/elite name = "Special Ops Torpedo Destroyer" icon_state = "hammerhead_elite"