Modules / Physics & movement

hitscan3dplugin

A shot along a line through a 3D world, answered with the first thing it meets.

Putting it in a scene

The scene's sim lists the hitscan3d kind from #plugins/hitscan3d/hitscan3d.sim.ts. A scene that aims shots back at what a seat saw also has one { "is": "hitscan3d" } actor, whose row is described under The row. A scene that only shoots from the server's present needs no row. A child scene inherits world.hitscan3d from the manager scene. What a line meets is asked of other plugins through mods, each optional.

"world": {
  "hitscan3d": {
    "mods": { "ground": "terrain3d", "solids": "scatter3d", "bodies": "walker" },
    "kinds": {
      "xbot": { "tall": "height", "off": "dead" }
    },
    "rewind": 12
  }
},
"prefabs": {
  "hitscan3d": {}
}

Properties

Read from world.hitscan3d.

.mods : { ground?, solids?, bodies? }

The plugins whose mods say what a line meets (see Mods).

.kinds : { [kind]: { tall?, off? } }

The kinds of body a shot can hit, and no other. A body is the shapes its bodies mod hands, each named by its part: upright cylinders and capsules.

KeyMeaning
tallOptional: the name of a row field. When the row carries it as a number, the body's cylinders reach that high over their foot, as with a crouch. A capsule stays where the body's pose puts it.
offOptional: the name of a row field. A row whose field is truthy, a body lying dead, is not hit.

.rewind : number

Steps: how far back a shot may be aimed.

The row

A seat sees the other bodies where the last packet it took put them, some steps behind the server by the time its shot arrives, so a shot is checked against the bodies as that packet held them. That needs a hitscan3d row, made by one actor entry. Its after counts the steps in its field n, and keeps every body's feet and shapes at the end of each of the last rewind steps, under the n the step's packet carries. A page reads n off the row in the packet it draws and hands it to the shot with seen on the browser half. shoot's seen then puts each body back where it stood then.

A seen older than rewind steps is taken as the oldest kept, and a seen newer than the last step, or one given in a scene with no hitscan3d row, is taken as now. A body is only put back, never brought back: one that has ended since is not there, and whether it is off is read off its row now. What is kept is sent to no seat, and a truth rebuilt by replaying its steps keeps it again.

Methods

Acts

Defined by every kind a shot, a round or a burst can hurt, and called on its row as a rule's, seat −1.

hit( struck )

The one act that hurts a row, whoever hurts it. struck is { ...hurt, damage, by, part, point, dir, what }: damage the harm as a number, by the row that struck, part the shape met, point where it was met or struck from, and dir the unit way the harm travels. what is "body" for a shot, "splash" for a volley3d round's splash and "blast" for a rule's burst, the last two with part null. Whatever else the weapon's hurt carries, a knock or an impulse, comes with it.

Rules

From #plugins/hitscan3d/hitscan3d.sim.ts. t is metres along dir from from. dir can be any length, since it is normalised, but not zero. far is the most metres a line is asked along.

shoot( w, from, dir, far, opts? ) : Hit | undefined

The first thing the line from from along dir meets within far, or undefined when it meets nothing. A Hit is { t, point, normal, what, id?, kind?, part? }. what is "ground", "solid" or "body", and normal is the surface's, of unit length. A body also gives its id, kind and the part of the shape met. A line that starts inside a shape meets it where it leaves it, and a line that starts inside a skipped body passes it by.

OptionMeaning
skipIds of bodies the line passes through, such as the shooter.
seenThe step the shot was aimed at (see The row).
bodiesfalse passes through every body, for a line that only the ground and the solids stop, such as a camera kept out of a hill.
growMetres every shape is taken wider by, and a cylinder longer by at both ends, 0 when left out. It is for a round with a size of its own.
hurt{ damage, by, … }: what the shot does to a body it meets. damage is a number, or { [part]: number }, the harm by the part met, which must name that part. by is the row that shot. With a hurt, the body met is hurt: its row's hit act is called with what: "body", the part met, the point met and the line's way. Without one, the shot only answers.

strike( w, row, struck )

Hurts a row: calls its hit act, as a rule's, with struck. A rule's burst hurts each row it reaches with it.

hittable( w ) : Body[]

Every body a shot can hit now, { id, kind, pos, shapes }: of a kind kinds lists, none lying off, each cylinder as tall as its row's tall field when it carries one.

sees( w, from, to ) : boolean

Whether nothing of the ground or the solids stands between two points. Bodies do not block a sight.

cylinder( origin, dir, far, centre, radius, y0, y1 ) : { t, normal } | undefined

Where a line from origin along the unit dir first meets an upright cylinder about centre's x and z, from y0 up to y1 (Infinity for one without end), within far. From inside, it gives where the line leaves.

capsule( origin, dir, far, a, b, radius ) : { t, normal } | undefined

Where a line from origin along the unit dir first meets every point within radius of the segment from a to b, within far, one sphere when they are one point. From inside, it gives where the line leaves.

On the page

Through plugins.hitscan3d.

seen( ) : number | undefined

The n of the hitscan3d row in the packet this page draws the bodies from, which a game's player actor sends with each shot. Undefined in a scene with no hitscan3d row, or before the first packet has brought it.

Mods

Name them in world.hitscan3d.mods. Each is optional, and each takes one plugin.

  • terrain3d
    ground: (w, from, dir, far) → { t, normal } | undefined, the first point of the ground along the line.
  • scatter3d
    solids: (w, from, dir, far) → { x, z, radius, base, tall? }[], every solid standing on the ground, a trunk or a boulder, whose circle the line's path over the ground crosses within far. Each is an upright cylinder about (x, z) from base up tall, or without end when it has none.
  • walker
    bodies: (w) → { id, kind, pos, shapes }[]. Every row of a kind world.walker.kinds lists is one upright cylinder from its feet at pos, of its kind's radius and height, its part named as its kind.
  • ragdoll3d
    bodies: a standing body's bones. Every row of a kind world.anim.kinds lists, whose rig carries the bake's ends for its model and that anim has played a clip on, is one capsule a bone, each part named as its bone, as it stands this step of its clip. Every other body comes from the bodies mod named in world.ragdoll3d.mods, none when it names none, and a body that mod hands with the id of one of these is this one, never both.
  • dismember3d
    bodies: the joints of every body that comes apart. Every row of a kind world.dismember3d.kinds lists is a sphere for each joint it still has, its part named as its segment, as it stands this step of its clip, and none before anim has played it a clip. Every other body comes from the bodies mod named in world.dismember3d.mods, as with ragdoll3d's.

hitscan3d gives two mods.

  • volley3d
    shoot and bodies: name them in world.volley3d.mods as { shoot: "hitscan3d", bodies: "hitscan3d" }, so launched rounds meet, and hurt, what a shot meets. shoot is asked of the step as it is now, since a round flies in the server's present and no step is rewound to, and it hurts the body met by the round's hurt. bodies is hittable.
  • box3dvehicle
    bodies and strike: name them in world.box3dvehicle.mods as { bodies: "hitscan3d", strike: "hitscan3d" }, so a car hits the bodies a shot hits. bodies is hittable, and strike is strike.

In the guide