The 515 MegaPR early downport (#7783)

Co-authored-by: Selis <selis@xynolabs.com>
Co-authored-by: Selis <sirlionfur@hotmail.de>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
Co-authored-by: SatinIsle <thesatinisle@gmail.com>
Co-authored-by: Heroman <alesha3000@list.ru>
Co-authored-by: Casey <a.roaming.shadow@gmail.com>
Co-authored-by: Raeschen <rycoop29@gmail.com>
This commit is contained in:
Cadyn
2024-02-27 11:17:32 -08:00
committed by GitHub
parent 96a43a09c1
commit b90f7ec922
254 changed files with 2135 additions and 1576 deletions

View File

@@ -542,7 +542,7 @@
return 2
//just assume we can shoot through glass and stuff. No big deal, the player can just choose to not target someone
//on the other side of a window if it makes a difference. Or if they run behind a window, too bad.
if(check_trajectory(target, user))
if(target in check_trajectory(target, user))
return 1 // Magic numbers are fun.
//called if there was no projectile to shoot

View File

@@ -41,6 +41,7 @@
var/ricochets_max = 2
var/ricochet_chance = 30
var/can_miss = TRUE
var/bump_targets = TRUE //Should we bump and/or attack objects we hit? Used only for 'raytraces' e.g. subtype /test
//Hitscan
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
@@ -145,6 +146,14 @@
var/hud_state = "unknown" // What HUD state we use when we have ammunition.
var/hud_state_empty = "unknown" // The empty state. DON'T USE _FLASH IN THE NAME OF THE EMPTY STATE STRING, THAT IS ADDED BY THE CODE.
var/obj/item/ammo_casing/my_case = null
/obj/item/projectile/New()
if(istype(loc, /obj/item/ammo_casing))
my_case = loc
. = ..()
/obj/item/projectile/proc/Range()
range--
if(range <= 0 && loc)
@@ -231,7 +240,7 @@
after_move()
if(can_hit_target(original, permutated))
Bump(original)
if(!hitscanning && !forcemoved)
if(!hitscanning && !forcemoved && trajectory)
pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move
pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move
animate(src, pixel_x = trajectory.return_px(), pixel_y = trajectory.return_py(), time = 1, flags = ANIMATION_END_NOW)
@@ -320,7 +329,8 @@
/obj/item/projectile/proc/fire(angle, atom/direct_target)
//If no angle needs to resolve it from xo/yo!
if(direct_target)
direct_target.bullet_act(src, def_zone)
if(bump_targets)
direct_target.bullet_act(src, def_zone)
qdel(src)
return
if(isnum(angle))
@@ -459,7 +469,16 @@
impacted_mobs.Cut()
impacted_mobs = null
qdel(trajectory)
trajectory = null
beam_index = null
beam_components = null
if(my_case)
if(my_case.BB == src)
my_case.BB = null
my_case = null
return ..()
/obj/item/projectile/proc/cleanup_beam_segments()
@@ -565,25 +584,31 @@
var/shield_chance = min(80, (30 * (M.mob_size / 10))) //Small mobs have a harder time keeping a dead body as a shield than a human-sized one. Unathi would have an easier job, if they are made to be SIZE_LARGE in the future. -Mech
if(prob(shield_chance))
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
if(Bump(G.affecting))
return
if(bump_targets)
if(Bump(G.affecting))
return
else
visible_message("<span class='danger'>\The [M] tries to use [G.affecting] as a shield, but fails!</span>")
else
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
if(Bump(G.affecting))
return //If Bump() returns 0 (keep going) then we continue on to attack M.
if(bump_targets)
if(Bump(G.affecting))
return //If Bump() returns 0 (keep going) then we continue on to attack M.
passthrough = !attack_mob(M, distance)
if(bump_targets)
passthrough = !attack_mob(M, distance)
else
passthrough = 1 //Projectiles that don't bump (raytraces) always pass through
else
passthrough = 1 //so ghosts don't stop bullets
else
passthrough = (A.bullet_act(src, def_zone) == PROJECTILE_CONTINUE) //backwards compatibility
if(isturf(A))
for(var/obj/O in A)
O.bullet_act(src)
for(var/mob/living/M in A)
attack_mob(M, distance)
if(bump_targets) // only attack/act a turf's contents if our projectile is not a raytrace
if(isturf(A))
for(var/obj/O in A)
O.bullet_act(src)
for(var/mob/living/M in A)
attack_mob(M, distance)
//penetrating projectiles can pass through things that otherwise would not let them
if(!passthrough && penetrating > 0)
@@ -606,7 +631,7 @@
trajectory_ignore_forcemove = FALSE
return FALSE
if(A)
if(A && bump_targets)
on_impact(A)
qdel(src)
return TRUE
@@ -649,7 +674,9 @@
return 1
/obj/item/projectile/proc/check_fire(atom/target as mob, mob/living/user as mob) //Checks if you can hit them or not.
check_trajectory(target, user, pass_flags, flags)
if(target in check_trajectory(target, user, pass_flags, flags))
return TRUE
return FALSE
/obj/item/projectile/CanPass()
return TRUE

View File

@@ -14,7 +14,9 @@
return trace.launch_projectile(target) //Test it!
/obj/item/projectile/proc/_check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
check_trajectory(target, user, pass_flags, flags)
if(target in check_trajectory(target, user, pass_flags, flags))
return TRUE
return FALSE
//"Tracing" projectile
/obj/item/projectile/test //Used to see if you can hit them.
@@ -22,6 +24,7 @@
hitscan = TRUE
nodamage = TRUE
damage = 0
bump_targets = FALSE
var/list/hit = list()
/obj/item/projectile/test/process_hitscan()
@@ -33,7 +36,24 @@
/obj/item/projectile/test/Bump(atom/A)
if(A != src)
hit |= A
if(isturf(A))
for(var/obj/O in A)
hit |= A
for(var/mob/living/M in A)
hit |= A
return ..()
/obj/item/projectile/test/fire(angle, atom/direct_target)
. = ..()
if(direct_target)
if(direct_target != src)
hit |= direct_target
. = hit
/obj/item/projectile/test/attack_mob()
return
//Don't generate tracers - they are generated on Destroy()
/obj/item/projectile/test/finalize_hitscan_and_generate_tracers()
return