class LZRTag::Player::Hardware

Hardware-handling player class. This class extends the base player, adding more hardware-related functionality and interfaces, such as:

etc.

Attributes

battery[R]
beaconTimes[R]

Returns a Hash of the last timestamps when a beacon was detected

brightness[R]

Current brightness of the weapon. @return [Symbol] Symbol describing the current brightness. Possible brightnesses are:

  • :idle (low, slow brightness, white with slight team hue)

  • :teamSelect (team-colored with rainbow overlay)

  • :dead (low brightness, team colored with white overlay)

  • :active (bright, flickering and in team color)

A change will trigger the :playerBrightnessChanged event, with data [player, oldBrightness]

clipAmmo[R]

Current ammo in the clip. Can be set to -1 for infinite shots (no reloading necessary at all), or any other numeric value. Default is a single clip (gun-dependant)

clipSize[R]

Size of the clip of the currently equipped gun. Can not be set!

dead[R]

Whether or not the player is currently dead. Set this to kill the player. Will trigger a :playerKilled or :playerRevived event, although kill_by is preferred to also specify which player killed.

deathChangeTime[R]

Last time the death status changed (killed/revivied). Especially useful to determine when to revive a player

gunNo[R]

Number of the current gun. The application can freely choose which gun profile the set is using, which influences shot speeds, sounds, reloading, etc.

gyroPose[R]

Returns the gyro pose of the set. This is either:

  • :active

  • :laidDown

  • :pointsUp

  • :pointsDown

Changes are triggered by the set itself, if it has a gyro. The :poseChanged event is sent on change with [player, newPose] data

heap[R]
ping[R]
reserveAmmo[R]

Current amount of reserve ammo (i.e. clips the player can reload with) Can be set to -1 to enable infinite reserve ammo (default), or any other value to give the player limited ammo

team[R]

The team (0..7) of this player. Setting it to a number will publish to /DeviceID/CFG/Team, changing the color of the weapon. Interpret it as binary string, with 1 being red, 2 green and 4 blue.

Changes trigger the :playerTeamChanged event, with [player, oldTeam] data

Public Class Methods

getBrightnessKeys() click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 75
def self.getBrightnessKeys()
        return [:idle, :teamSelect, :dead, :active]
end
new(*data) click to toggle source
Calls superclass method LZRTag::Player::Base::new
# File lib/lzrtag/player/hardware_player.rb, line 79
def initialize(*data)
        super(*data);

        @team = 0;
        @brightness = :idle;

        @dead = false;
        @deathChangeTime = Time.now();

        @reserveAmmo = 0;
        @clipAmmo    = 0;
        @clipSize    = 0;

        @gunNo = 0;

        @gyroPose = :unknown;

        @position = {x: 0, y: 0}
        @zoneIDs  = Hash.new();

        @beaconTimes = Hash.new();
        @BeaconTimeout = 3;

        @battery = 0; @ping = 0; @heap = 0;

        @BrightnessMap = self.class.getBrightnessKeys();

        # These values are configured for a DPS ~1, equal to all weapons
        # Including reload timings and other penalties
        @GunDamageMultipliers = [
                0.9138,
                1.85,
                0.6166,
        ];
end

Public Instance Methods

_set_dead(d, player = nil) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 207
def _set_dead(d, player = nil)
        dead = (d ? true : false);
        return false if @dead == dead;
        @dead = dead;

        @deathChangeTime = Time.now();

        _pub_to "CFG/Dead", @dead ? "1" : "0", retain: true;
        @handler.send_event(@dead ? :playerKilled : :playerRevived, self, player);
        return true;
end
brightness=(n) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 192
def brightness=(n)
        raise ArgumentError, "Brightness must be a valid symbol!" unless @BrightnessMap.include? n;

        return if @brightness == n;
        oldB = @brightness;
        @brightness = n;

        n = @BrightnessMap.find_index(n)

        _pub_to "CFG/Brightness", n, retain: true;
        @handler.send_event :playerBrightnessChanged, self, oldB;

        @brightness;
end
check_beacons() click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 274
def check_beacons()
        bIDs = @beaconTimes.keys;
        bIDs.each do |bID|
                if((Time.now() - @beaconTimes[bID]) > @BeaconTimeout)
                        @handler.send_event(:playerLeftBeacon, self, bID);
                        @beaconTimes.delete(bID)
                end
        end
end
clear_all_topics() click to toggle source
Calls superclass method LZRTag::Player::Base#clear_all_topics
# File lib/lzrtag/player/hardware_player.rb, line 284
def clear_all_topics()
        super();

        [   "CFG/Dead", "CFG/GunNo", "CFG/Brightness", "CFG/Team"].each do |t|
                _pub_to(t, "", retain: true);
        end
end
clipAmmo=(n) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 237
def clipAmmo=(n)
        unless (n.is_a?(Integer))
                raise ArgumentError, "Ammo amount needs to be a number!"
        end

        _pub_to("Stats/Ammo/SetClip", n);
end
dead=(d) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 218
def dead=(d)
        _set_dead(d);
end
gunDamage(number = nil) click to toggle source

Return the averaged damage the player's gun should do. This function is very useful to calculate the damage a player did per shot. The returned number tries to average damage to “1 DPS” for all weapons regardless of speed etc., which the application can multiply for a given total damage, creating a more balanced game.

# File lib/lzrtag/player/hardware_player.rb, line 264
def gunDamage(number = nil)
        number ||= @gunNo

        return @GunDamageMultipliers[number-1] || 1;
end
gunNo=(n) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 245
def gunNo=(n)
        unless (n.is_a?(Integer) and (n >= 0))
                raise ArgumentError, "Gun ID needs to be a positive integer!"
        end

        return if(@gunNo == n)

        oldGun = @gunNo;
        @gunNo = n;
        @handler.send_event(:playerGunChanged, self, n, oldGun);

        _pub_to("CFG/GunNo", n, retain: true);
end
kill_by(player) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 221
def kill_by(player)
        return if @dead;
        _set_dead(true, player);
end
on_mqtt_data(data, topic) click to toggle source

@private This function processes incoming MQTT data. The user must not call this, since it is handled by the LZRTag base handler

Calls superclass method LZRTag::Player::Base#on_mqtt_data
# File lib/lzrtag/player/hardware_player.rb, line 119
def on_mqtt_data(data, topic)
        case topic[1..topic.length].join("/")
        when "HW/Ping"
                if(data.size == 3*4)
                        parsedData = data.unpack("L<*");

                        @battery = parsedData[0].to_f/1000;
                        @ping     = parsedData[2].to_f;
                end
        when "CFG/Dead"
                dead = (data == "1")
                return if @dead == dead;
                @dead = dead;

                @deathChangeTime = Time.now();

                @handler.send_event(@dead ? :playerKilled : :playerRevived, self);
        when "Stats/Ammo"
                return if(data.size != 12)

                outData = data.unpack("L<*");
                @clipAmmo = outData[0];
                @clipSize = outData[1];
                @reserveAmmo = outData[2];
        when "Position"
                begin
                        @position = JSON.parse(data, symbolize_names: true);
                rescue
                end
        when "HW/NSwitch"
                @handler.send_event(:navSwitchPressed, self, data.to_i)
        when "HW/Gyro"
                @gyroPose = data.to_sym
                @handler.send_event(:poseChanged, self, @gyroPose);
        when "HW/BeaconDetect"
                beaconID = data.to_i;
                unless(@beaconTimes[beaconID])
                        @handler.send_event(:playerEnteredBeacon, self, beaconID);
                end
                @beaconTimes[beaconID] = Time.now();
                @handler.send_event(:playerInBeacon, self, beaconID);
        when "ZoneUpdate"
                begin
                        data = JSON.parse(data, symbolize_names: true);
                rescue JSON::ParserError
                        return;
                end

                @zoneIDs = data[:data];
                if(data[:entered])
                        @handler.send_event(:playerEnteredZone, self, data[:entered])
                end
                if(data[:exited])
                        @handler.send_event(:playerExitedZone, self, data[:exited])
                end
        else
                super(data, topic);
        end
end
reload() click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 270
def reload()
        _pub_to("CFG/Reload", "1");
end
reserveAmmo=(n) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 230
def reserveAmmo=(n)
        unless (n.is_a?(Integer))
                raise ArgumentError, "Ammo amount needs to be a number!"
        end

        _pub_to("Stats/Ammo/SetReserve", n);
end
revive_by(player) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 225
def revive_by(player)
        return unless @dead
        _set_dead(false, player)
end
team=(n) click to toggle source
# File lib/lzrtag/player/hardware_player.rb, line 179
def team=(n)
        n = n.to_i;
        raise ArgumentError, "Team out of range (must be between 0 and 7)" unless n <= 7 and n >= 0;

        return if @team == n;
        oldT = @team;
        @team = n;

        _pub_to "CFG/Team", @team, retain: true;
        @handler.send_event :playerTeamChanged, self, oldT;

        @team;
end