Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hammerhead, ram ahead #2734

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions nsv13/code/__DEFINES/overmap.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion nsv13/code/modules/overmap/fighters/fighters_launcher.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<span class='warning'>You feel a sudden jolt!</span>")
Expand Down
13 changes: 13 additions & 0 deletions nsv13/code/modules/overmap/overmap.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
59 changes: 47 additions & 12 deletions nsv13/code/modules/overmap/physics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)) \
Expand All @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions nsv13/code/modules/overmap/types/nanotrasen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions nsv13/code/modules/overmap/types/syndicate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading