Skip to content

Commit

Permalink
the grind continues
Browse files Browse the repository at this point in the history
  • Loading branch information
MLGTASTICa committed Aug 4, 2024
1 parent 2b3f165 commit c7accad
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 34 deletions.
2 changes: 1 addition & 1 deletion code/ATMOSPHERICS/atmospherics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Pipelines + Other Objects -> Pipe network
var/obj/machinery/atmospherics/node2

/// Pending a full implementation of hitbox for every atom
/obj/structure/atmospherics/bullet_act(obj/item/projectile/P, def_zone, hitboxFlags)
/obj/machinery/atmospherics/bullet_act(obj/item/projectile/P, def_zone, hitboxFlags)
. = ..()
return PROJECTILE_CONTINUE

Expand Down
2 changes: 1 addition & 1 deletion code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
#define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour;
#endif // 1 to use the default behaviour;
// 2 for preloading absolutely everything;
//#define LOWMEMORYMODE 1
#define LOWMEMORYMODE 1

#ifdef LOWMEMORYMODE
#define FORCE_MAP "_maps/runtimestation.json"
Expand Down
32 changes: 23 additions & 9 deletions code/controllers/subsystems/bullets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ SUBSYSTEM_DEF(bullets)
// 1 client tick by default , can be increased by impacts
var/bulletWait = 1
//// x1,y1,x2,y2,z1,z2
var/list/trajectoryData = list(0,0,0,0,0,0)
var/list/trajectoryData = list(0,0,0,0,0,0,0)
var/distanceToTravelForce



Expand Down Expand Up @@ -252,7 +253,9 @@ SUBSYSTEM_DEF(bullets)
/datum/controller/subsystem/bullets/fire(resumed)
if(!resumed)
current_queue = bullet_queue.Copy()
var/turf/leaving
var/global/turf/leaving
var/global/pixelXdist
var/global/pixelYdist
for(var/datum/bullet_data/bullet in current_queue)
current_queue -= bullet
bullet.lastChanges[1] = 0
Expand All @@ -262,13 +265,14 @@ SUBSYSTEM_DEF(bullets)
bullet_queue -= bullet
continue
bulletRatios = bullet.movementRatios
bulletCoords = bullet.currentCoords
projectile = bullet.referencedBullet
pixelsToTravel = bullet.pixelsPerTick
bulletCoords = bullet.currentCoords
/// We have to break up the movement into steps if its too big(since it leads to erronous steps) , this is preety much continous collision
/// but less performant A more performant version would be to use the same algorithm as throwing for determining which turfs to "intersect"
/// Im using this implementation because im getting skill issued trying to implement the same one as throwing(i had to rewrite this 4 times already)
/// and also because it has.. much more information about the general trajectory stored SPCR - 2024
bulletCoords = bullet.currentCoords
trajectoryData[1] = projectile.x * 32 + projectile.pixel_x + 16
trajectoryData[2] = projectile.y * 32 + projectile.pixel_y + 16
trajectoryData[3] = bulletRatios[1] * pixelsToTravel + trajectoryData[1]
Expand All @@ -277,12 +281,16 @@ SUBSYSTEM_DEF(bullets)
/// Yes this is inaccurate for multi-Z transitions somewhat , if someone wants to create a proper equation for pseudo 3D they're welcome to.
trajectoryData[6] = trajectoryData[5] + LERP(bullet.firedLevel, bullet.targetLevel,(bullet.traveled + pixelsToTravel)/bullet.distStartToFinish2D()) - (projectile.z - bullet.firedPos[3] * LEVEL_MAX)
bullet.trajSum += bulletRatios[3] * pixelsToTravel
forceLoop:
while(pixelsToTravel > 0)
pixelsThisStep = pixelsToTravel > MAXPIXELS ? MAXPIXELS : pixelsToTravel
pixelsToTravel -= pixelsThisStep
bullet.traveled += pixelsThisStep
bulletCoords[1] += (bulletRatios[1] * pixelsThisStep)
bulletCoords[2] += (bulletRatios[2] * pixelsThisStep)
pixelXdist = (bulletRatios[1] * pixelsThisStep)
pixelYdist = (bulletRatios[2] * pixelsThisStep)
trajectoryData[7] = (EAST*(pixelXdist>0)) | (WEST*(pixelXdist<0)) | (NORTH*(pixelYdist>0)) | (SOUTH*(pixelYdist<0))
bulletCoords[1] += pixelXdist
bulletCoords[2] += pixelYdist
bulletCoords[3] = LERP(bullet.firedLevel, bullet.targetLevel, bullet.traveled/bullet.distStartToFinish2D()) - (projectile.z - bullet.firedPos[3]) * LEVEL_MAX
//message_admins(bulletCoords[3])
//message_admins("added [(bulletRatios[3] * pixelsThisStep)] , pixels [pixelsThisStep] , curSum [bulletCoords[3]]")
Expand All @@ -291,8 +299,10 @@ SUBSYSTEM_DEF(bullets)
z_change = -(bulletCoords[3] < 0) + (bulletCoords[3] > LEVEL_MAX)
while(x_change || y_change || z_change)
leaving = get_turf(projectile)
if(projectile.scanTurf(leaving, trajectoryData) != PROJECTILE_CONTINUE)
break
if(projectile.scanTurf(leaving, trajectoryData, &distanceToTravelForce) != PROJECTILE_CONTINUE)
pixelsToTravel = DIST_EUCLIDIAN_2D(trajectoryData[1], trajectoryData[2],trajectoryData[3],trajectoryData[4]) - (bullet.pixelsPerTick - pixelsToTravel) - round(distanceToTravelForce)
message_admins("dist set to [pixelsToTravel]")
goto forceLoop
if(QDELETED(projectile))
bullet_queue -= bullet
break
Expand All @@ -314,7 +324,7 @@ SUBSYSTEM_DEF(bullets)
projectile.pixel_x -= PPT * tx_change
projectile.pixel_y -= PPT * ty_change
bullet.updateLevel()
if(projectile.scanTurf(moveTurf, trajectoryData) == PROJECTILE_CONTINUE)
if(projectile.scanTurf(moveTurf, trajectoryData, &distanceToTravelForce) == PROJECTILE_CONTINUE)
//message_admins("[bulletCoords[3]], [trajectoryData[6]]" )
bullet.painted.Add(moveTurf)
//moveTurf.color = COLOR_RED
Expand All @@ -325,6 +335,10 @@ SUBSYSTEM_DEF(bullets)
else
message_admins("reached target with level of [bulletCoords[3]] , pixels : [bullet.traveled], diff : [bullet.distStartToFinish2D() - bullet.traveled] , traj [trajectoryData[6]] , sum [bullet.trajSum]")
*/
else
pixelsToTravel = DIST_EUCLIDIAN_2D(trajectoryData[1], trajectoryData[2],trajectoryData[3],trajectoryData[4]) - (bullet.pixelsPerTick - pixelsToTravel) - round(distanceToTravelForce)
message_admins("dist set to [pixelsToTravel]")
goto forceLoop
moveTurf = null
/*
else
Expand All @@ -342,7 +356,7 @@ SUBSYSTEM_DEF(bullets)
var/animationColor = gradient(list("#ffffff", "#cbcbcb"), levelRatio)
animate(projectile, SSbullets.wait, pixel_x =((abs(bulletCoords[1]))%HPPT * sign(bulletCoords[1]) - 1), pixel_y = ((abs(bulletCoords[2]))%HPPT * sign(bulletCoords[2]) - 1), flags = ANIMATION_END_NOW, color = animationColor)
bullet.currentCoords = bulletCoords
if(bullet.lifetime < 0)
if(bullet.lifetime < 1)
bullet.referencedBullet.finishDeletion()
bullet_queue -= bullet
//for(var/turf/painted in bullet.painted)
Expand Down
7 changes: 7 additions & 0 deletions code/game/objects/structures.dm
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@
var/absorbed = take_damage(target_power)
return absorbed

/obj/structure/bullet_act(obj/item/projectile/P, def_zone, hitboxFlags)
. = ..()
take_damage(P.get_structure_damage())
if(QDELETED(src))
return PROJECTILE_CONTINUE


/obj/structure/New()
..()
if(climbable)
Expand Down
1 change: 1 addition & 0 deletions code/game/turfs/simulated/walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
blocks_air = 1
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
hitbox = /datum/hitboxDatum/atom/wall

var/ricochet_id = 0
var/health = 0
Expand Down
2 changes: 2 additions & 0 deletions code/modules/lighting/lighting_overlay.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

weight = 0

atomFlags = AF_IGNORE_ON_BULLETSCAN

var/needs_update = FALSE

/// More efficient to have the proc return bullet_continue ,avoiding another check for every object on a turf SPCR 2024
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/inventory/slots.dm
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@

/datum/inventory_slot/in_backpack/can_equip(obj/item/I, mob/living/carbon/human/owner, disable_warning)
var/obj/item/storage/back = owner.get_equipped_item(slot_back)
return istype(back) && back.can_be_inserted(src,1)
return istype(back) && back.can_be_inserted(I,1)


/datum/inventory_slot/accessory
Expand Down
74 changes: 56 additions & 18 deletions code/modules/projectiles/hitbox_datums.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,21 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
return false;
}
*/
// Based off the script above.
// Based off the script above. Optimized based off github comments relating to code above.
/datum/hitboxDatum/proc/lineIntersect(list/firstLine , list/secondLine)
var/global/firstRatio
var/global/secondRatio
firstRatio = ((secondLine[3] - secondLine[1]) * (firstLine[2] - secondLine[2]) - (secondLine[4] - secondLine[2]) * (firstLine[1] - secondLine[1]))
firstRatio /= ((secondLine[4] - secondLine[2]) * (firstLine[3] - firstLine[1]) - (secondLine[3] - secondLine[1]) * (firstLine[4] - firstLine[2]))
secondRatio = ((firstLine[3] - firstLine[1]) * (firstLine[2] - secondLine[2]) - (firstLine[4] - firstLine[2]) * (firstLine[1] - secondLine[1]))
secondRatio /= ((secondLine[4] - secondLine[2]) * (firstLine[3] - firstLine[1]) - (secondLine[3] - secondLine[1]) * (firstLine[4] - firstLine[2]))
var/denominator = ((secondLine[4] - secondLine[2]) * (firstLine[3] - firstLine[1]) - (secondLine[3] - secondLine[1]) * (firstLine[4] - firstLine[2]))
if(denominator == 0)
return FALSE
firstRatio = ((secondLine[3] - secondLine[1]) * (firstLine[2] - secondLine[2]) - (secondLine[4] - secondLine[2]) * (firstLine[1] - secondLine[1])) / denominator
secondRatio = ((firstLine[3] - firstLine[1]) * (firstLine[2] - secondLine[2]) - (firstLine[4] - firstLine[2]) * (firstLine[1] - secondLine[1])) / denominator
if(firstRatio >= 0 && firstRatio <= 1 && secondRatio >= 0 && secondRatio <= 1)
/// Distance to intersection of point
return DIST_EUCLIDIAN_2D(firstLine[1],firstLine[2],firstLine[1] + firstRatio * (firstLine[3] - firstLine[1]),firstLine[2] + firstRatio * (firstLine[4] - firstLine[2]) )
//return list(firstLine[1] + firstRatio * (firstLine[3] - firstLine[1]), firstLine[2] + firstRatio * (firstLine[4] - firstLine[2]))
//message_admins("X-collision : [firstLine[1] + firstRatio * (firstLine[3] - firstLine[1])] Y-collision : [firstLine[2] + firstRatio * (firstLine[4] - firstLine[2])]")
//message_admins("Distance between points : [DIST_EUCLIDIAN_2D(firstLine[1],firstLine[2],firstLine[1] + firstRatio * (firstLine[3] - firstLine[1]),firstLine[2] + firstRatio * (firstLine[4] - firstLine[2]) )]")
return TRUE

Check failure on line 76 in code/modules/projectiles/hitbox_datums.dm

View workflow job for this annotation

GitHub Actions / Run Linters

possible unreachable code here
else
return FALSE
Expand Down Expand Up @@ -129,6 +134,7 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
/datum/hitboxDatum/atom/intersects(list/lineData,ownerDirection, turf/incomingFrom, atom/owner, list/arguments)
var/global/worldX
var/global/worldY
var/global/functionReturn
worldX = owner.x
worldY = owner.y
if(owner.atomFlags & AF_HITBOX_OFFSET_BY_ATTACHMENT)
Expand All @@ -144,17 +150,25 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
/// basic AABB but only for the Z-axis.
if(boundingData[5] > max(lineData[5],lineData[6]) || boundingData[6] < min(lineData[6],lineData[5]))
continue
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
return FALSE

Expand Down Expand Up @@ -232,6 +246,7 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
/datum/hitboxDatum/atom/table/intersects(list/lineData,ownerDirection, turf/incomingFrom, obj/structure/table/owner, list/arguments)
var/global/worldX
var/global/worldY
var/global/functionReturn
worldX = owner.x * 32
worldY = owner.y * 32
var/list/boundingList
Expand All @@ -249,17 +264,25 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
continue
if(boundingData[5] < max(lineData[5], lineData[6]) && boundingData[6] < min(lineData[6],lineData[5]))
continue
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
return FALSE

Expand Down Expand Up @@ -295,7 +318,13 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
LISTWEST = list(BBOX(10,9,23,25,LEVEL_CHEST-0.1,LEVEL_CHEST+0.2,null))
)


/datum/hitboxDatum/atom/wall
boundingBoxes = list(
LISTNORTH = list(BBOX(0,0,32,32,LEVEL_BELOW ,LEVEL_ABOVE,null)),
LISTSOUTH = list(BBOX(0,0,32,32,LEVEL_BELOW ,LEVEL_ABOVE,null)),
LISTEAST = list(BBOX(0,0,32,32,LEVEL_BELOW ,LEVEL_ABOVE,null)),
LISTWEST = list(BBOX(0,0,32,32,LEVEL_BELOW ,LEVEL_ABOVE,null))
)

/datum/hitboxDatum/mob

Expand Down Expand Up @@ -331,24 +360,33 @@ boolean lineLine(float x1, float y1, float x2, float y2, float x3, float y3, flo
. = ..()
var/global/worldX
var/global/worldY
var/global/functionReturn
worldX = owner.x * 32
worldY = owner.y * 32
var/mob/living/perceivedOwner = owner
for(var/list/boundingData in boundingBoxes["[perceivedOwner.lying]"]["[owner.dir]"])
/// basic AABB but only for the Z-axis.
if(boundingData[5] > max(lineData[5],lineData[6]) || boundingData[6] < min(lineData[6],lineData[5]))
continue
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[1] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[2] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[1] + worldX, boundingData[4] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
if(lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY)))
functionReturn = lineIntersect(lineData, list(boundingData[3] + worldX, boundingData[2] + worldY, boundingData[3] + worldX, boundingData[4] + worldY))
if(functionReturn)
arguments[3] = boundingData[7]
arguments[4] = functionReturn
return TRUE
return FALSE

Expand Down
9 changes: 5 additions & 4 deletions code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ GLOBAL_LIST(projectileDamageConstants)
/// The lower the index , the higher the priority. If you add new paths to the list , make sure to increase the amount of lists in scanTurf below.
#define HittingPrioritiesList list(/mob/living,/obj/structure/multiz/stairs/active,/obj/structure,/atom)

/obj/item/projectile/proc/scanTurf(turf/scanning, list/trajectoryData)
/obj/item/projectile/proc/scanTurf(turf/scanning, list/trajectoryData, dpDistanceToTravel)
if(atomFlags & AF_VISUAL_MOVE)
return PROJECTILE_CONTINUE
var/list/hittingList = new/list(length(HittingPrioritiesList))
Expand All @@ -512,9 +512,9 @@ GLOBAL_LIST(projectileDamageConstants)
for(var/atom/possibleTarget as anything in thing.attached)
if(thing.attached[possibleTarget] & ATFS_IGNORE_HITS)
continue
if(possibleTarget.attached[thing] & ATFA_DIRECTIONAL_HITTABLE && !(dir & reverse_dir[(get_dir(src, thing))]))
if(possibleTarget.attached[thing] & ATFA_DIRECTIONAL_HITTABLE && !(possibleTarget.dir & reverse_dir[trajectoryData[7]]))
continue
if(possibleTarget.attached[thing] & ATFA_DIRECTIONAL_HITTABLE_STRICT && !(dir == reverse_dir[(get_dir(src, thing))]))
if(possibleTarget.attached[thing] & ATFA_DIRECTIONAL_HITTABLE_STRICT && !(possibleTarget.dir == reverse_dir[trajectoryData[7]]))
continue
if(thing.attached[possibleTarget] & ATFS_PRIORITIZE_ATTACHED_FOR_HITS)
hittingList[index][length(hittingList[index])] = possibleTarget
Expand All @@ -527,9 +527,10 @@ GLOBAL_LIST(projectileDamageConstants)
if(target == firer)
continue
/// third slot rezerved for flags passed back by hitbox intersect
var/list/arguments = list(src, def_zone, null)
var/list/arguments = list(src, def_zone, null, null)
if(target.hitbox && !target.hitbox.intersects(trajectoryData, target.dir, 0, target, arguments))
return PROJECTILE_CONTINUE
*dpDistanceToTravel = arguments[4]
if(target.bullet_act(arglist(arguments)) & PROJECTILE_STOP)
onBlockingHit(target)
return PROJECTILE_STOP
Expand Down

0 comments on commit c7accad

Please sign in to comment.