Skip to main content

ShapeClass

A script class that is instanced for every "scripted" Interactable Shape in the game.

An interactable part is a Shape that is usually built by the player and can be interacted with, for example a button or an engine.

The class can receive events sent with sm.event.sendToInteractable.

The fields below are accessed using self.fieldName in the ShapeClass script:

Fields:
TypeNameDescription
InteractableinteractableThe Interactable game object belonging to this class instance. The same as shape.interactable.
ShapeshapeThe Shape game object that the Interactable is attached to. (The same as interactable.shape)
NetworknetworkA Network object that can be used to send data between client and server.
StoragestorageA server-side Storage object that can be used to save and load data to/from the world database.
anydataData from the data entry in the shape's JSON file entry.
anyparamsParameter set with Interactable:setParams when created from a script.
Constants:

colorHighlight
colorNormal
connectionInput
connectionOutput
maxChildCount
maxParentCount
poseWeightCount

Callbacks:

Server + Client

onProjectile

function ShapeClass.server_onProjectile( self, position, airTime, velocity, projectileName, shooter, damage, customData, normal, uuid )
end
function ShapeClass.client_onProjectile( self, position, airTime, velocity, projectileName, shooter, damage, customData, normal, uuid )
end

Called when the Shape is hit by a projectile.

note

If the shooter is destroyed before the projectile hits, the shooter value will be nil.

Arguments:
  • self [ table ]: The class instance.
  • position [ Vec3 ]: The position in world space where the projectile hit the Shape.
  • airTime [ number ]: The time, in seconds, that the projectile spent flying before the hit.
  • velocity [ Vec3 ]: The velocity of the projectile at impact.
  • projectileName [ string ]: The name of the projectile. (Legacy, use uuid instead)
  • shooter [ Player / Unit / Shape / Harvestable / nil ]: The shooter. Can be a Player, Unit, Shape, Harvestable or nil if unknown.
  • damage [ int ]: The damage value of the projectile.
  • customData [ any ]: A Lua object that can be defined at shoot time using sm.projectile.customProjectileAttack or any other custom version.
  • normal [ Vec3 ]: The normal at the point of impact.
  • uuid [ Uuid ]: The uuid of the projectile.

onMelee

function ShapeClass.server_onMelee( self, position, attacker, damage, power, direction, normal )
end
function ShapeClass.client_onMelee( self, position, attacker, damage, power, direction, normal )
end

Called when the Shape is hit by a melee attack.

note

If the attacker is destroyed before the hit lands, the attacker value will be nil.

Arguments:
  • self [ table ]: The class instance.
  • position [ Vec3 ]: The position in world space where the Shape was hit.
  • attacker [ Player / nil ]: The attacker. Can be a Player or nil if unknown. Attacks made by a Unit will be nil on the client.
  • damage [ int ]: The damage value of the melee hit.
  • power [ number ]: The physical impact of the hit.
  • direction [ Vec3 ]: The direction of the melee attack.
  • normal [ Vec3 ]: The normal at the point of impact.

onCollision

function ShapeClass.server_onCollision( self, other, position, selfPointVelocity, otherPointVelocity, normal )
end
function ShapeClass.client_onCollision( self, other, position, selfPointVelocity, otherPointVelocity, normal )
end

Called when the Shape collides with another object.

Arguments:
  • self [ table ]: The class instance.
  • other [ Shape / Character / Harvestable / Lift / nil ]: The other object. Nil if terrain.
  • position [ Player / nil ]: The position in world space where the collision occurred.
  • selfPointVelocity [ int ]: The velocity that that the Shape had at the point of collision.
  • otherPointVelocity [ number ]: The velocity that that the other object had at the point of collision.
  • normal [ Vec3 ]: The collision normal between the Shape and the other object.

canErase

function ShapeClass.server_canErase( self )
return true --true or false, default true
end
function ShapeClass.client_canErase( self )
return true --true or false, default true
end

Called to check whether the Shape can be erased at this moment.

note

This can be used to override restrictions. (See Shape.erasable)

Arguments:
  • self [ table ]: The class instance.
Returns:
  • [ bool ]: A boolean indicating whether the Shape can be erased or not. (Defaults to true)

Server-only

onUnload

function ShapeClass.server_onUnload( self )
end

Called when the Interactable is unloaded from the game because no Player's Character is close enough to it.
Also called when exiting the game.

note

The creation, consisting of one or more bodies, consisting of one or more shapes joined together with joints are always unloaded at the same time.

Arguments:
  • self [ table ]: The class instance.

onExplosion

function ShapeClass.server_onExplosion( self, center, destructionLevel )
end

Called when the Shape is hit by an explosion.

For more information about explosions, see sm.physics.explode.

Arguments:
  • self [ table ]: The class instance.
  • center [ Vec3 ]: The center of the explosion.
  • destructionLevel [ int ]: The level of destruction done by this explosion. Corresponds to the durability rating of a Shape.

onSledgehammer

function ShapeClass.server_onSledgehammer( self )
end
deprecated

Use onMelee instead.


Client-only

onInteract

function ShapeClass.client_onInteract( self, character, state )
end

Called when a Player is interacting with the Interactable by pressing the Use key (default E)
or pressing 0-9 if the Interactable is connected to a seat (See: Interactable:pressSeatInteractable).

note

If this method is defined, the player will see the interaction text E Use when looking at the Shape.

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is interacting with the Interactable.
  • state [ bool ]: The interaction state (true if pressed, false if released).
Example Usage
-- Example of interaction
function MySwitch.client_onInteract( self, character, state )
if state then
self.network:sendToServer( 'sv_n_toggle' )
end
end

function MySwitch.sv_n_toggle( self )
-- Toggle on and off
self.interactable.active = not self.interactable.active
end

canInteract

function ShapeClass.client_canInteract( self, character )
return true --true or false, default true if onInteract is implemented
end

Called to check whether the Interactable can be interacted with at this moment.

note

This callback can also be used to change the interaction text shown to the player using sm.gui.setInteractionText (Defaults to E Use).

This can be used to override restrictions (See Shape.usable).

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is looking at the Shape.
Returns:
  • [ bool ]: A boolean indicating whether the interactable can be interacted with or not (Defaults to true if client_onInteract is implemented, otherwise false).

onTinker

function ShapeClass.client_onTinker( self, character, state )
end

Called when a Player is interacting with the Interactable by pressing the Tinker key (default U).

note

Tinkering usually means opening the upgrade menu for seats.

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is tinkering with the Interactable.
  • state [ bool ]: The interaction state (true if pressed, false if released).

canTinker

function ShapeClass.client_canTinker( self, character )
return true --true or false, default true if onTinker is implemented
end

Called to check whether the Interactable can be tinkered with at this moment.

note

Tinkering usually means opening the upgrade menu for seats.

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is looking at the Shape.
Returns:
  • [ bool ]: A boolean indicating whether the interactable can be tinkered with or not (Defaults to true if client_onTinker is implemented, otherwise false).

onInteractThroughJoint

function ShapeClass.client_onInteractThroughJoint( self, character, state, joint )
end

Called when a Player is interacting with the Interactable through a connected Joint.

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is interacting with the Interactable.
  • state [ bool ]: The interaction state. Always true. client_onInteractThroughJoint only receives the key down event.
  • joint [ Joint ]: The Joint that the Player interacted through.

canInteractThroughJoint

function ShapeClass.client_canInteractThroughJoint( self, character )
return true --true or false, default true if onInteractThroughJoint is implemented
end

Called to check whether the Interactable can be interacted with through a child Joint at this moment.

note

This callback can also be used to change the interaction text shown to the player using sm.gui.setInteractionText (Defaults to E Use)

Arguments:
  • self [ table ]: The class instance.
  • character [ Character ]: The Character of the Player that is looking at the Joint.
Returns:
  • [ bool ]: A boolean indicating whether the interactable can be interacted with or not (Defaults to true if client_onInteractThroughJoint is implemented, otherwise false).

onAction

function ShapeClass.client_onAction( self, action, state )
end

Called when the interactable receives input from a Player with the Character locked to the Interactable.

When a Character is seated in an Interactable Shape with a seat component, the Character is also considered locked to the Interactable.

Details about the action value are in sm.interactable.actions.

Arguments:
  • self [ table ]: The class instance.
  • action [ int ]: The action as an integer value.
  • state [ bool ]: True on begin action, false on end action.

canCarry

function ShapeClass.client_canCarry( self )
return true --true or false, default false
end

Called to check if the shape must be carried instead of put in the inventory.

note

Shapes with the carryItem attribute are always carried.

Arguments:
  • self [ table ]: The class instance.
Returns:
  • [ bool ]: A boolean indicating whether the interacable must be carried or not. (Defaults to false)

getAvailableParentConnectionCount

function ShapeClass.client_getAvailableParentConnectionCount( self, connectionType )
return int --The number of available connections.
end

Called to check how many more parent (input) connections with the given connectionType the Interactable will accept.
Return 1 or more to allow a connection of this type.

See sm.interactable.connectionType for details about the connection type.

note

The maxParentCount constant must be 1 or more for this callback to be called.

Arguments:
  • self [ table ]: The class instance.
  • connectionType [ int ]: The connection type(s).
Returns:
  • [ int ]: The number of available connections.
Example Usage
-- Example of implementation where logic and power shares the same slot but electricity counts as separate
MyInteractable.maxParentCount = 2
MyInteractable.connectionInput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power + sm.interactable.connectionType.electricity

function MyInteractable.client_getAvailableParentConnectionCount( self, connectionType )
if bit.band( connectionType, bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) ) ~= 0 then
return 1 - self:getParents( bit.bor( sm.interactable.connectionType.logic, sm.interactable.connectionType.power ) )
end
if bit.band( connectionType, sm.interactable.connectionType.electricity ) ~= 0 then
return 1 - self:getParents( sm.interactable.connectionType.electricity )
end
return 0
end

getAvailableChildConnectionCount

function ShapeClass.client_getAvailableChildConnectionCount( self, connectionType )
return int --The number of available connections.
end

Called to check how many more child (output) connections with the given connectionType the Interactable will accept.
Return 1 or more to allow a connection of this type.

See sm.interactable.connectionType for details about the connection type.

note

The maxChildCount constant must be 1 or more for this callback to be called.

Arguments:
  • self [ table ]: The class instance.
  • connectionType [ int ]: The connection type(s).
Returns:
  • [ int ]: The number of available connections.
Example Usage
-- Example of implementation that accepts 10 logic connections and 1 power connection
MyInteractable.maxChildCount = 11
MyInteractable.connectionOutput = sm.interactable.connectionType.logic + sm.interactable.connectionType.power

function MyIteractable.client_getAvailableChildConnectionCount( self, connectionType )
if bit.band( connectionType, sm.interactable.connectionType.logic ) ~= 0 then
return 10 - self:getParents( sm.interactable.connectionType.logic )
end
if bit.band( connectionType, sm.interactable.connectionType.power ) ~= 0 then
return 1 - self:getParents( sm.interactable.connectionType.power )
end
return 0
end