Physics Shapes (#306)

* Removed BoundingBoxComponent.

* Updated prototypes to use refactored CollidableComponent.

* Renamed ICollidable to IPhysBody.
Moved ICollidable to the Shared/Physics namespace.

* Migrated more yaml files to use PhysShapes.

* Updated YAML to use the new list-of-bodies system.

* Updated the new prototypes.

* Update submodule

* Update submodule again, whoops
This commit is contained in:
Acruid
2019-09-03 13:14:04 -07:00
committed by Pieter-Jan Briers
parent 5aafe89d95
commit 9353a060f2
34 changed files with 148 additions and 90 deletions

View File

@@ -5,6 +5,7 @@ using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.Chat; using Content.Server.Interfaces.Chat;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Server.AI; using Robust.Server.AI;
using Robust.Server.GameObjects;
using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
@@ -12,6 +13,7 @@ using Robust.Shared.Interfaces.Physics;
using Robust.Shared.Interfaces.Timing; using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Server.AI namespace Content.Server.AI
@@ -122,8 +124,8 @@ namespace Content.Server.AI
var entWorldPos = SelfEntity.Transform.WorldPosition; var entWorldPos = SelfEntity.Transform.WorldPosition;
if (SelfEntity.TryGetComponent<BoundingBoxComponent>(out var bounds)) if (SelfEntity.TryGetComponent<CollidableComponent>(out var bounds))
entWorldPos = bounds.WorldAABB.Center; entWorldPos = ((IPhysBody) bounds).WorldAABB.Center;
var rngState = GenSeed(); var rngState = GenSeed();
for (var i = 0; i < 3; i++) // you get 3 chances to find a place to walk for (var i = 0; i < 3; i++) // you get 3 chances to find a place to walk

View File

@@ -5,8 +5,8 @@ using Robust.Server.GameObjects;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components; using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.Physics;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Interfaces.Physics;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Projectiles namespace Content.Server.GameObjects.Components.Projectiles
@@ -54,7 +54,7 @@ namespace Content.Server.GameObjects.Components.Projectiles
/// </summary> /// </summary>
/// <param name="collidedwith"></param> /// <param name="collidedwith"></param>
/// <returns></returns> /// <returns></returns>
bool ICollideSpecial.PreventCollide(ICollidable collidedwith) bool ICollideSpecial.PreventCollide(IPhysBody collidedwith)
{ {
if (IgnoreShooter && collidedwith.Owner.Uid == Shooter) if (IgnoreShooter && collidedwith.Owner.Uid == Shooter)
return true; return true;

View File

@@ -39,9 +39,9 @@ namespace Content.Server.GameObjects.Components
// after impacting the first object. // after impacting the first object.
// For realism this should actually be changed when the velocity of the object is less than a threshold. // For realism this should actually be changed when the velocity of the object is less than a threshold.
// This would allow ricochets off walls, and weird gravity effects from slowing the object. // This would allow ricochets off walls, and weird gravity effects from slowing the object.
if (collidedwith.Count > 0 && Owner.TryGetComponent(out CollidableComponent body)) if (collidedwith.Count > 0 && Owner.TryGetComponent(out CollidableComponent body) && body.PhysicsShapes.Count >= 1)
{ {
body.CollisionMask &= (int)~CollisionGroup.Mob; body.PhysicsShapes[0].CollisionMask &= (int)~CollisionGroup.Mob;
body.IsScrapingFloor = true; body.IsScrapingFloor = true;
// KYS, your job is finished. Trigger ILand as well. // KYS, your job is finished. Trigger ILand as well.

View File

@@ -329,9 +329,9 @@ namespace Content.Server.GameObjects.EntitySystems
} }
// Check if ClickLocation is in object bounds here, if not lets log as warning and see why // Check if ClickLocation is in object bounds here, if not lets log as warning and see why
if (attacked.TryGetComponent(out BoundingBoxComponent boundingBox)) if (attacked.TryGetComponent(out ICollidableComponent collideComp))
{ {
if (!boundingBox.WorldAABB.Contains(coordinates.ToWorld(_mapManager).Position)) if (!collideComp.WorldAABB.Contains(coordinates.ToWorld(_mapManager).Position))
{ {
Logger.WarningS("system.interaction", Logger.WarningS("system.interaction",
$"Player {player.Name} clicked {attacked.Name} outside of its bounding box component somehow"); $"Player {player.Name} clicked {attacked.Name} outside of its bounding box component somehow");

View File

@@ -17,6 +17,7 @@ using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Players; using Robust.Shared.Players;
namespace Content.Server.GameObjects.EntitySystems namespace Content.Server.GameObjects.EntitySystems
@@ -170,7 +171,11 @@ namespace Content.Server.GameObjects.EntitySystems
if (!throwEnt.TryGetComponent(out ThrownItemComponent projComp)) if (!throwEnt.TryGetComponent(out ThrownItemComponent projComp))
{ {
projComp = throwEnt.AddComponent<ThrownItemComponent>(); projComp = throwEnt.AddComponent<ThrownItemComponent>();
colComp.CollisionMask |= (int)CollisionGroup.Mob;
if(colComp.PhysicsShapes.Count == 0)
colComp.PhysicsShapes.Add(new PhysShapeAabb());
colComp.PhysicsShapes[0].CollisionMask |= (int)CollisionGroup.Mob;
colComp.IsScrapingFloor = false; colComp.IsScrapingFloor = false;
} }

View File

@@ -1,17 +1,23 @@
using System; using System;
using JetBrains.Annotations;
namespace Content.Shared.Physics namespace Content.Shared.Physics
{ {
/// <summary> /// <summary>
/// Defined collision groups for the physics system. /// Defined collision groups for the physics system.
/// </summary> /// </summary>
[Flags] [Flags, PublicAPI]
public enum CollisionGroup public enum CollisionGroup
{ {
None = 0, None = 0,
Grid = 1, // Walls Grid = 1 << 0, // Walls
Mob = 2, // Mobs, like the player or NPCs Mob = 1 << 1, // Mobs, like the player or NPCs
Fixture = 4, // wall fixtures, like APC or posters Fixture = 1 << 2, // wall fixtures, like APC or posters
Items = 8 // Items on the ground Items = 1 << 3, // Items on the ground
Furniture = 1 << 4, // Tables, machines
// 32 possible groups
MobMask = Grid | Mob | Furniture,
AllMask = -1,
} }
} }

View File

@@ -25,7 +25,6 @@
- type: Icon - type: Icon
texture: Objects/mopbucket.png texture: Objects/mopbucket.png
- type: Clickable - type: Clickable
- type: BoundingBox
- type: Solution - type: Solution
maxVol: 500 maxVol: 500
caps: 3 caps: 3

View File

@@ -10,16 +10,18 @@
#rotation: -180 #rotation: -180
- type: Icon - type: Icon
texture: Objects/Projectiles/bullet.png texture: Objects/Projectiles/bullet.png
- type: BoundingBox - type: Collidable
aabb: -0.2,-0.2,0.2,0.2 hard: false
shapes:
- !type:PhysShapeAabb
bounds: "-0.2,-0.2,0.2,0.2"
layer: 1
mask: 3
- type: Physics - type: Physics
edgeslide: false edgeslide: false
- type: Projectile - type: Projectile
damages: damages:
Brute: 20 Brute: 20
- type: Collidable
hard: false
mask: 3
- type: entity - type: entity
id: ProjectileBullet id: ProjectileBullet

View File

@@ -20,14 +20,11 @@
sprite: Buildings/airlock_basic.rsi sprite: Buildings/airlock_basic.rsi
state: closed state: closed
- type: BoundingBox
# This AABB isn't the full tile because..
# If it is, airlocks collide with walls and other airlocks causing them to never close.
# yeah...
# TODO: Fix that.
aabb: -0.45, -0.45, 0.45, 0.45
- type: Collidable - type: Collidable
mask: 2 shapes:
- !type:PhysShapeAabb
mask: 2
layer: 16
- type: Door - type: Door
- type: Appearance - type: Appearance
visuals: visuals:

View File

@@ -10,8 +10,10 @@
- type: Icon - type: Icon
sprite: Buildings/Walls/asteroid_rock.rsi sprite: Buildings/Walls/asteroid_rock.rsi
state: 0 state: 0
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
layer: 1
- type: Damageable - type: Damageable
- type: Destructible - type: Destructible
thresholdvalue: 100 thresholdvalue: 100

View File

@@ -3,7 +3,7 @@
name: Catwalk name: Catwalk
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
netsync: false netsync: false
sprite: Buildings/catwalk.rsi sprite: Buildings/catwalk.rsi

View File

@@ -4,7 +4,9 @@
components: components:
- type: Clickable - type: Clickable
- type: Collidable - type: Collidable
- type: BoundingBox shapes:
- !type:PhysShapeAabb
layer: 8
- type: Icon - type: Icon
sprite: Buildings/computer.rsi sprite: Buildings/computer.rsi
state: computer state: computer

View File

@@ -10,10 +10,12 @@
texture: Buildings/weldtank.png texture: Buildings/weldtank.png
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: "-0.5,-0.25,0.5,0.25"
- type: Collidable - type: Collidable
mask: 3 shapes:
- !type:PhysShapeAabb
bounds: "-0.5,-0.25,0.5,0.25"
mask: 19
layer: 16
IsScrapingFloor: true IsScrapingFloor: true
- type: Physics - type: Physics
mass: 15 mass: 15

View File

@@ -3,7 +3,7 @@
id: stool id: stool
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
sprite: Buildings/furniture.rsi sprite: Buildings/furniture.rsi
state: stool_base state: stool_base
@@ -17,7 +17,7 @@
id: chairOfficeLight id: chairOfficeLight
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
sprite: Buildings/furniture.rsi sprite: Buildings/furniture.rsi
state: officechair_white state: officechair_white
@@ -30,7 +30,7 @@
id: chairOfficeDark id: chairOfficeDark
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
sprite: Buildings/furniture.rsi sprite: Buildings/furniture.rsi
state: officechair_dark state: officechair_dark
@@ -43,7 +43,7 @@
id: chair id: chair
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
sprite: Buildings/furniture.rsi sprite: Buildings/furniture.rsi
state: chair state: chair

View File

@@ -8,8 +8,11 @@
- type: Icon - type: Icon
texture: Buildings/wall_girder.png texture: Buildings/wall_girder.png
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
mask: 19
layer: 1
- type: Damageable - type: Damageable
- type: Destructible - type: Destructible
thresholdvalue: 50 thresholdvalue: 50

View File

@@ -9,8 +9,11 @@
- type: Icon - type: Icon
sprite: Buildings/autolathe.rsi sprite: Buildings/autolathe.rsi
state: idle state: idle
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
mask: 19
layer: 16
- type: SnapGrid - type: SnapGrid
offset: Center offset: Center
- type: Lathe - type: Lathe

View File

@@ -3,7 +3,7 @@
name: "Unpowered Light" name: "Unpowered Light"
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sound - type: Sound
- type: Sprite - type: Sprite
sprite: Buildings/light_tube.rsi sprite: Buildings/light_tube.rsi
@@ -29,7 +29,7 @@
parent: wall_light parent: wall_light
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
sprite: Buildings/light_tube.rsi sprite: Buildings/light_tube.rsi
state: off state: off
@@ -53,7 +53,6 @@
parent: wall_light parent: wall_light
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox
- type: Sprite - type: Sprite
sprite: Buildings/light_small.rsi sprite: Buildings/light_small.rsi
state: off state: off

View File

@@ -14,8 +14,10 @@
sprite: Buildings/low_wall.rsi sprite: Buildings/low_wall.rsi
state: metal state: metal
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
layer: 1
- type: Damageable - type: Damageable
- type: Destructible - type: Destructible
thresholdvalue: 100 thresholdvalue: 100

View File

@@ -4,7 +4,7 @@
description: Transfers power, avoid letting things come down it description: Transfers power, avoid letting things come down it
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
netsync: false netsync: false
drawdepth: BelowFloor drawdepth: BelowFloor
@@ -40,9 +40,12 @@
description: A portal to hell which summons power from the nether description: A portal to hell which summons power from the nether
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: -0.5, -0.5, 0.3, 0.5
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5, -0.5, 0.3, 0.5"
mask: 19
layer: 16
- type: Sprite - type: Sprite
texture: Objects/generator.png texture: Objects/generator.png
- type: Icon - type: Icon
@@ -55,7 +58,11 @@
description: Supplies power directly to nearby objects description: Supplies power directly to nearby objects
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
shapes:
- !type:PhysShapeAabb
mask: 19
layer: 4
- type: Sprite - type: Sprite
drawdepth: WallMountedItems drawdepth: WallMountedItems
texture: Objects/provider.png texture: Objects/provider.png
@@ -96,8 +103,10 @@
interfaces: interfaces:
- key: enum.ApcUiKey.Key - key: enum.ApcUiKey.Key
type: ApcBoundUserInterface type: ApcBoundUserInterface
- type: BoundingBox - type: Collidable
aabb: -0.25, -0.25, 0.25, 0.3 shapes:
- !type:PhysShapeAabb
bounds: "-0.25, -0.25, 0.25, 0.3"
- type: Sound - type: Sound
- type: entity - type: entity
@@ -106,9 +115,12 @@
description: Stores power in its super-magnetic cells description: Stores power in its super-magnetic cells
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: -0.5, -0.5, 0.5, 0.5
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5, -0.5, 0.5, 0.5"
mask: 19
layer: 16
- type: Sprite - type: Sprite
netsync: false netsync: false
sprite: Buildings/smes.rsi sprite: Buildings/smes.rsi
@@ -143,9 +155,12 @@
description: A monstrosity that does nothing but suck up power from the nearby wires description: A monstrosity that does nothing but suck up power from the nearby wires
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: -0.5, -0.25, 0.5, 0.25
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5, -0.25, 0.5, 0.25"
mask: 19
layer: 16
- type: Sprite - type: Sprite
texture: Objects/wiredmachine.png texture: Objects/wiredmachine.png
- type: Icon - type: Icon
@@ -161,9 +176,12 @@
description: A terrifying monstrosity that sucks up power from the wireless transmitters, Tesla would be proud description: A terrifying monstrosity that sucks up power from the wireless transmitters, Tesla would be proud
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: -0.5, -0.25, 0.5, 0.25
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5, -0.25, 0.5, 0.25"
mask: 19
layer: 16
- type: Sprite - type: Sprite
texture: Objects/wirelessmachine.png texture: Objects/wirelessmachine.png
- type: Icon - type: Icon

View File

@@ -16,10 +16,12 @@
state: generic_door state: generic_door
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: "-0.5,-0.25,0.5,0.25"
- type: Collidable - type: Collidable
mask: 3 shapes:
- !type:PhysShapeAabb
bounds: "-0.5,-0.25,0.5,0.25"
mask: 19
layer: 16
IsScrapingFloor: true IsScrapingFloor: true
- type: Physics - type: Physics
mass: 25 mass: 25

View File

@@ -16,14 +16,17 @@
state: crate state: crate
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: -0.4, -0.4, 0.4, 0.4
- type: Physics - type: Physics
mass: 25 mass: 25
Anchored: false Anchored: false
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.4, -0.4, 0.4, 0.4"
layer: 16
mask: 19
- type: EntityStorage - type: EntityStorage
Capacity: 60 Capacity: 60
- type: PlaceableSurface - type: PlaceableSurface

View File

@@ -12,8 +12,11 @@
sprite: Buildings/table_solid.rsi sprite: Buildings/table_solid.rsi
state: plain_preview state: plain_preview
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
mask: 19
layer: 16
- type: SnapGrid - type: SnapGrid
offset: Center offset: Center

View File

@@ -3,7 +3,7 @@
name: Turret Base name: Turret Base
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
texture: Buildings/TurrBase.png texture: Buildings/TurrBase.png
@@ -12,7 +12,7 @@
name: Turret (Gun) name: Turret (Gun)
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
drawdepth: WallMountedItems drawdepth: WallMountedItems
texture: Buildings/TurrTop.png texture: Buildings/TurrTop.png
@@ -26,7 +26,7 @@
name: Turret (Light) name: Turret (Light)
components: components:
- type: Clickable - type: Clickable
- type: BoundingBox - type: Collidable
- type: Sprite - type: Sprite
drawdepth: WallMountedItems drawdepth: WallMountedItems
texture: Buildings/TurrLamp.png texture: Buildings/TurrLamp.png

View File

@@ -13,8 +13,10 @@
- type: Icon - type: Icon
sprite: Buildings/VendingMachines/empty.rsi sprite: Buildings/VendingMachines/empty.rsi
state: normal state: normal
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
layer: 8
- type: SnapGrid - type: SnapGrid
offset: Center offset: Center
- type: Damageable - type: Damageable

View File

@@ -8,8 +8,10 @@
drawdepth: Walls drawdepth: Walls
- type: Icon - type: Icon
state: full state: full
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
layer: 1
- type: Damageable - type: Damageable
- type: Destructible - type: Destructible
thresholdvalue: 100 thresholdvalue: 100

View File

@@ -13,8 +13,11 @@
sprite: Buildings/window.rsi sprite: Buildings/window.rsi
state: window0 state: window0
- type: BoundingBox
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.5, -0.5, 0.3, 0.5"
layer: 1
- type: Damageable - type: Damageable
- type: Destructible - type: Destructible
thresholdvalue: 100 thresholdvalue: 100

View File

@@ -5,11 +5,12 @@
- type: Item - type: Item
Size: 5 Size: 5
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: "-0.25,-0.25,0.25,0.25"
- type: Collidable - type: Collidable
mask: 5 shapes:
layer: 8 - !type:PhysShapeAabb
bounds: "-0.25,-0.25,0.25,0.25"
mask: 5
layer: 8
IsScrapingFloor: true IsScrapingFloor: true
- type: Physics - type: Physics
mass: 5 mass: 5

View File

@@ -3,8 +3,10 @@
abstract: true abstract: true
parent: BaseItem parent: BaseItem
components: components:
- type: BoundingBox - type: Collidable
aabb: -0.15,-0.3,0.2,0.3 shapes:
- !type:PhysShapeAabb
bounds: "-0.15,-0.3,0.2,0.3"
- type: PowerCell - type: PowerCell
- type: Appearance - type: Appearance
- type: Sprite - type: Sprite

View File

@@ -50,9 +50,10 @@
description: "Portal to another location" description: "Portal to another location"
components: components:
- type: Collidable - type: Collidable
shapes:
- !type:PhysShapeAabb
mask: 10
- type: Portal - type: Portal
- type: BoundingBox
aabb: "-0.25,-0.25,0.25,0.25"
- type: Sprite - type: Sprite
netsync: false netsync: false
sprite: "Effects/portal.rsi" sprite: "Effects/portal.rsi"

View File

@@ -7,7 +7,7 @@
layers: layers:
- shader: unshaded - shader: unshaded
- type: ConstructionGhost - type: ConstructionGhost
- type: BoundingBox - type: Collidable
- type: Clickable - type: Clickable
baseshader: unshaded baseshader: unshaded
selectionshader: selection_outline_unshaded selectionshader: selection_outline_unshaded
@@ -18,5 +18,5 @@
components: components:
- type: Sprite - type: Sprite
- type: Construction - type: Construction
- type: BoundingBox - type: Collidable
- type: Clickable - type: Clickable

View File

@@ -36,16 +36,15 @@
sprite: Mob/human.rsi sprite: Mob/human.rsi
state: male state: male
- type: BoundingBox
aabb: "-0.35,-0.35,0.35,0.35"
- type: Physics - type: Physics
mass: 85 mass: 85
- type: Collidable - type: Collidable
mask: 3 shapes:
layer: 2 - !type:PhysShapeAabb
DebugColor: "#0000FF" bounds: "-0.5,-0.25,-0.05,0.25"
mask: 19
layer: 2
- type: Input - type: Input
context: "human" context: "human"

View File

@@ -8,8 +8,6 @@
mass: 5 mass: 5
- type: Eye - type: Eye
zoom: 0.5, 0.5 zoom: 0.5, 0.5
- type: BoundingBox
aabb: "-0.5,-0.25,-0.05,0.25"
- type: Input - type: Input
context: "ghost" context: "ghost"
- type: Examiner - type: Examiner

View File

@@ -11,11 +11,11 @@
texture: Buildings/watertank.png texture: Buildings/watertank.png
- type: Clickable - type: Clickable
- type: BoundingBox
aabb: "-0.5,-0.25,0.5,0.25"
- type: Collidable - type: Collidable
mask: 3 mask: 3
layer: 1 layer: 1
shape:
bounds: "-0.5,-0.25,0.5,0.25"
IsScrapingFloor: true IsScrapingFloor: true
- type: Physics - type: Physics
mass: 15 mass: 15