MultiMessageComponentModifier

local MultiMessageComponentModifier = require('encompass').MultiMessageComponentModifier

A MultiMessageComponentModifier is a special kind of ComponentModifier. It conveniently aggregates multiple ComponentMessages that are intended to modify the same component.

It is fundamentally the same as a ComponentModifier, with a slightly different modify callback.

Function Reference

MultiMessageComponentModifier:modify(component, frozen_fields, messages, dt)
Arguments:
  • component (Component) – A reference to an instantiated component referenced by the tracked Message.
  • frozen_fields (table) – A copied table of fields on the referenced component, so that the Modifier can read component data without it being affected by other Modifiers.
  • messages (table) – An array-style table containing references to multiple messages that have been tracked by the ComponentModifier and all reference the same component.
  • dt – The delta time given by the World’s current frame update.

This callback is triggered when one or more ComponentMessages of the specified prototype are produced. The programmer must override this callback or an error will be thrown.

Example

local Vector = require('hump.vector')
local forward_identity_vector = Vector(0, 1)

local MotionMessage = require('game.messages.motion')
local TimeDilationStateMessage = require('game.messages.state.time_dilation')

local MultiMessageComponentModifier = require('compass').MultiMessageComponentModifier
local MotionModifier = MultiMessageComponentModifier.define(
    'MotionModifier',
    MotionMessage,
    { TimeDilationStateMessage }
)

function MotionModifier:modify(transform_component, frozen_fields, messages, dt)
    local new_x = frozen_fields.position.x
    local new_y = frozen_fields.position.y
    local new_r = frozen_fields.rotation

    local time_dilation_state_message = self:get_state_message(TimeDilationStateMessage)
    dt = dt * (time_dilation_state_message ~= nil and time_dilation_state_message.factor or 1)

    for _, message in pairs(messages) do
        local instant_linear_or_dt = message.instant_linear and 1 or dt
        local instant_angular_or_dt = message.instant_angular and 1 or dt
        new_x = new_x + message.x_velocity * instant_linear_or_dt
        new_y = new_y + message.y_velocity * instant_linear_or_dt
        new_r = new_r + message.angular_velocity * instant_angular_or_dt
    end

    if frozen_fields.screen_wrap then
        new_x = new_x % love.graphics.getWidth()
        new_y = new_y % love.graphics.getHeight()
    end

    transform_component.position.x = new_x
    transform_component.position.y = new_y
    transform_component.rotation = new_r
    transform_component.forward = forward_identity_vector:rotated(new_r)
end

return MotionModifier