* Content side new physics structure * BroadPhase outline done * But we need to fix WorldAABB * Fix static pvs AABB * Fix import * Rando fixes * B is for balloon * Change human mob hitbox to circle * Decent movement * Start adding friction to player controller I think it's the best way to go about it to keep other objects somewhat consistent for physics. * This baby can fit so many physics bugs in it. * Slight mob mover optimisations. * Player mover kinda works okay. * Beginnings of testbed * More testbed * Circlestack bed * Namespaces * BB fixes * Pull WorldAABB * Joint pulling * Semi-decent movement I guess. * Pulling better * Bullet controller + old movement * im too dumb for this shit * Use kinematic mob controller again It's probably for the best TBH * Stashed shitcode * Remove SlipController * In which movement code is entirely refactored * Singularity fix * Fix ApplyLinearImpulse * MoveRelay fix * Fix door collisions * Disable subfloor collisions Saves on broadphase a fair bit * Re-implement ClimbController * Zumzum's pressure * Laggy item throwing * Minor atmos change * Some caching * Optimise controllers * Optimise CollideWith to hell and back * Re-do throwing and tile friction * Landing too * Optimise controllers * Move CCVars and other stuff swept is beautiful * Cleanup a bunch of controllers * Fix shooting and high pressure movement controller * Flashing improvements * Stuff and things * Combat collisions * Combat mode collisions * Pulling distance joint again * Cleanup physics interfaces * More like scuffedularity * Shit's fucked * Haha tests go green * Bigmoneycrab Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
107 lines
4.3 KiB
C#
107 lines
4.3 KiB
C#
#nullable enable
|
|
using Content.Server.GameObjects.Components.Observer;
|
|
using Content.Server.GameObjects.Components.Singularity;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Physics;
|
|
using Robust.Shared.Physics.Broadphase;
|
|
using Robust.Shared.Physics.Controllers;
|
|
using Robust.Shared.Random;
|
|
|
|
namespace Content.Server.Physics.Controllers
|
|
{
|
|
internal sealed class SingularityController : VirtualController
|
|
{
|
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
|
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
|
|
|
private float _pullAccumulator;
|
|
private float _moveAccumulator;
|
|
|
|
public override void UpdateBeforeSolve(bool prediction, float frameTime)
|
|
{
|
|
base.UpdateBeforeSolve(prediction, frameTime);
|
|
|
|
_moveAccumulator += frameTime;
|
|
_pullAccumulator += frameTime;
|
|
|
|
while (_pullAccumulator > 0.5f)
|
|
{
|
|
_pullAccumulator -= 0.5f;
|
|
|
|
foreach (var singularity in ComponentManager.EntityQuery<SingularityComponent>())
|
|
{
|
|
// TODO: Use colliders instead probably yada yada
|
|
PullEntities(singularity);
|
|
// Yeah look the collision with station wasn't working and I'm 15k lines in and not debugging this shit
|
|
DestroyTiles(singularity);
|
|
}
|
|
}
|
|
|
|
while (_moveAccumulator > 1.0f)
|
|
{
|
|
_moveAccumulator -= 1.0f;
|
|
|
|
foreach (var (singularity, physics) in ComponentManager.EntityQuery<SingularityComponent, PhysicsComponent>())
|
|
{
|
|
if (singularity.Owner.HasComponent<BasicActorComponent>()) continue;
|
|
|
|
// TODO: Need to essentially use a push vector in a random direction for us PLUS
|
|
// Any entity colliding with our larger circlebox needs to have an impulse applied to itself.
|
|
physics.BodyStatus = BodyStatus.InAir;
|
|
MoveSingulo(singularity, physics);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MoveSingulo(SingularityComponent singularity, PhysicsComponent physics)
|
|
{
|
|
if (singularity.Level <= 1) return;
|
|
// TODO: Could try gradual changes instead but for now just try to replicate
|
|
|
|
var pushVector = new Vector2(_robustRandom.Next(-10, 10), _robustRandom.Next(-10, 10));
|
|
|
|
if (pushVector == Vector2.Zero) return;
|
|
|
|
physics.LinearVelocity = Vector2.Zero;
|
|
physics.LinearVelocity = pushVector.Normalized * 2;
|
|
}
|
|
|
|
private void PullEntities(SingularityComponent component)
|
|
{
|
|
var singularityCoords = component.Owner.Transform.Coordinates;
|
|
// TODO: Maybe if we have named fixtures needs to pull out the outer circle collider (inner will be for deleting).
|
|
var entitiesToPull = EntityManager.GetEntitiesInRange(singularityCoords, component.Level * 10);
|
|
foreach (var entity in entitiesToPull)
|
|
{
|
|
if (!entity.TryGetComponent<PhysicsComponent>(out var collidableComponent) || collidableComponent.BodyType == BodyType.Static) continue;
|
|
if (entity.HasComponent<GhostComponent>()) continue;
|
|
if (singularityCoords.EntityId != entity.Transform.Coordinates.EntityId) continue;
|
|
var vec = (singularityCoords - entity.Transform.Coordinates).Position;
|
|
if (vec == Vector2.Zero) continue;
|
|
|
|
var speed = 10 / vec.Length * component.Level;
|
|
|
|
collidableComponent.ApplyLinearImpulse(vec.Normalized * speed);
|
|
}
|
|
}
|
|
|
|
private void DestroyTiles(SingularityComponent component)
|
|
{
|
|
if (!component.Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) return;
|
|
var worldBox = physicsComponent.GetWorldAABB();
|
|
|
|
foreach (var grid in _mapManager.FindGridsIntersecting(component.Owner.Transform.MapID, worldBox))
|
|
{
|
|
foreach (var tile in grid.GetTilesIntersecting(worldBox))
|
|
{
|
|
grid.SetTile(tile.GridIndices, Tile.Empty);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|