diff --git a/PSBT.lua b/PSBT.lua
index 1236b22..8a2a56e 100644
--- a/PSBT.lua
+++ b/PSBT.lua
@@ -128,17 +128,19 @@ function PSBT:NewEvent( scrollArea, sticky, icon, text )
local area = self._areas[ scrollArea ]
- local height = area:GetHeight()
- local duration = 1
+ local height = area:GetHeight()
+ local duration = 1
local relativePoint = nil
if ( scrollArea == PSBT_AREAS.NOTIFICATION ) then
relativePoint = TOP
duration = height * 20
elseif ( scrollArea == PSBT_AREAS.INCOMING ) then
relativePoint = BOTTOM
+ duration = height * 10
height = height * -1
elseif ( scrollArea == PSBT_AREAS.OUTGOING ) then
relativePoint = TOP
+ duration = height * 10
elseif ( scrollArea == PSBT_AREAS.STATIC ) then
relativePoint = BOTTOM
duration = height * 50
diff --git a/PSBT.xml b/PSBT.xml
index 094010f..b312e86 100644
--- a/PSBT.xml
+++ b/PSBT.xml
@@ -1,11 +1,11 @@
<GuiXml>
<Controls>
<Control name="PSBT_Label" virtual="true">
- <Dimensions x="202" y="44" />
+ <Dimensions x="300" y="24" />
<Controls>
<Texture name="$(parent)_Icon" layer="OVERLAY">
- <Dimensions x="40" />
+ <Dimensions x="24" />
<Anchor point="TOPLEFT" relativeTo="$(parent)" relativePoint="TOPLEFT" />
<Anchor point="BOTTOMLEFT" relativeTo="$(parent)" relativePoint="BOTTOMLEFT" />
</Texture>
@@ -39,14 +39,14 @@
<Control name="$(parent)_Incoming">
<Dimensions x="300" y="450" />
- <Anchor point="RIGHT" relativeTo="$(parent)" relativePoint="CENTER" offsetX="-300" offsetY="0" />
+ <Anchor point="RIGHT" relativeTo="$(parent)" relativePoint="CENTER" offsetX="-300" offsetY="150" />
<Controls>
</Controls>
</Control>
<Control name="$(parent)_Outgoing">
<Dimensions x="300" y="450" />
- <Anchor point="LEFT" relativeTo="$(parent)" relativePoint="CENTER" offsetX="300" offsetY="0" />
+ <Anchor point="LEFT" relativeTo="$(parent)" relativePoint="CENTER" offsetX="300" offsetY="150" />
<Controls>
</Controls>
</Control>
diff --git a/PSBT_Combat.lua b/PSBT_Combat.lua
index d4c203e..e0e5cfe 100644
--- a/PSBT_Combat.lua
+++ b/PSBT_Combat.lua
@@ -2,35 +2,339 @@ local PSBT_Combat = PSBT_Module:Subclass()
PSBT_Combat._iconRegistry = setmetatable( {}, { __mode = 'kv' } )
local CBM = CALLBACK_MANAGER
+local MAX_EVENTS = 15
+
+local PlayerName = GetUnitName( 'player' )
+local PlayerNameRaw = GetRawUnitName( 'player' )
+
+local function IsPlayerType( targetType )
+ return targetType == COMBAT_UNIT_TYPE_PLAYER or
+ targetType == COMBAT_UNIT_TYPE_PLAYER_PET
+end
+
+local function IsPlayer( targetType, targetName )
+ if ( IsPlayerType( targetType ) ) then
+ return true
+ end
+
+ if ( targetType == COMBAT_UNIT_TYPE_NONE ) then
+ return targetName == PlayerName or targetName == PlayerNameRaw
+ end
+
+ return false
+end
+
+
+local combat_events =
+{
+ [ ACTION_RESULT_ABSORBED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Absorbed <<1>>', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_BLADETURN ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Blocked <<1>>', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_BLOCKED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Blocked <<1>>', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_BLOCKED_DAMAGE ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Blocked <<1>>', hitValue ), area, false
+ end,
+ [ ACTION_RESULT_CANT_SEE_TARGET ] = function( ... )
+ return 'Can\'t See Target!', PSBT_AREAS.STATIC, false
+ end,
+ [ ACTION_RESULT_CRITICAL_DAMAGE ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>>!', hitValue ), area, true
+ end,
+ [ ACTION_RESULT_CRITICAL_HEAL ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ local name = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ name = sourceName
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ name = targetName
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>> [<<2>>]!', hitValue, name ), area, true
+ end,
+ [ ACTION_RESULT_DAMAGE ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( "<<1>>", hitValue ), area, false
+ end,
+ [ ACTION_RESULT_DAMAGE_SHIELDED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Shielded <<1>>', hitValue ), area, false
+ end,
+ [ ACTION_RESULT_DEFENDED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Defended <<1>>', hitValue ), area, false
+ end,
+ [ ACTION_RESULT_DOT_TICK ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>>', hitValue ), area, false
+ end,
+ [ ACTION_RESULT_DOT_TICK_CRITICAL ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue, damageType )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>>!', hitValue ), area, true
+ end,
+ [ ACTION_RESULT_HEAL ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ local name = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ name = sourceName
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ name = targetName
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>> [<<2>>]' , hitValue, name ), area, false
+ end,
+ [ ACTION_RESULT_HOT_TICK ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ local name = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ name = sourceName
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ name = targetName
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>> [<<2>>]', hitValue, name ), area, false
+ end,
+ [ ACTION_RESULT_HOT_TICK_CRITICAL ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ local name = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ name = sourceName
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ name = targetName
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( '<<1>> [<<2>>]!', hitValue, name ), area, true
+ end,
+ [ ACTION_RESULT_DODGED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Dodged <<1>>', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_MISS ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return 'Miss!', area, false
+ end,
+ [ ACTION_RESULT_PARRIED ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Parried <<1>>', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_RESIST ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Resisted <<1>>!', abilityName ), area, false
+ end,
+ [ ACTION_RESULT_PARTIAL_RESIST ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ area = PSBT_AREAS.OUTGOING
+ end
+
+ return zo_strformat( 'Partially Resisted <<1>>!', abilityName ), nil, false
+ end,
+ [ ACTION_RESULT_FALL_DAMAGE ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local area = nil
+ if ( IsPlayer( targetType, targetName ) ) then
+ area = PSBT_AREAS.INCOMING
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ return nil, nil, false
+ end
+
+ return zo_strformat( '<<1>> falling', hitValue ), area, false
+ end,
+ [ ACTION_RESULT_KILLING_BLOW ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType )
+ if ( IsPlayer( targetType, targetName ) ) then
+ return zo_strformat( '<<1>> Kill You.', sourceName ), PSBT_AREAS.STATIC, true
+ elseif ( IsPlayer( sourceType, sourceName ) ) then
+ return zo_strformat( 'Killing Blow <<1>>!', targetName ), PSBT_AREAS.STATIC, true
+ end
+
+ return nil, nil, false
+ end,
+ [ EVENT_ALLIANCE_POINT_UPDATE ] = function(value, sound, diff)
+ return zo_strformat( '<<1>> AP', diff ), PSBT_AREAS.STATIC, false
+ end,
+ [ EVENT_RANK_POINT_UPDATE ] = function( tag , value, diff )
+ if (tag == "player") then
+ return zo_strformat( '<<1>> RP', diff ), PSBT_AREAS.STATIC, false
+ end
+ end,
+ [ EVENT_BATTLE_TOKEN_UPDATE ] = function( value, sound, diff )
+ return zo_strformat( '<<1>> BT', diff ), PSBT_AREAS.STATIC, false
+ end,
+ [ EVENT_EXPERIENCE_GAIN ] = function( value )
+ return zo_strformat( '<<1>> XP', value ), PSBT_AREAS.STATIC, false
+ end,
+ [ EVENT_EXPERIENCE_GAIN_DISCOVERY ] = function( areaName, value )
+ return zo_strformat( '<<1>> XP', value ), PSBT_AREAS.STATIC, false
+ end,
+
+ [ ACTION_RESULT_POWER_DRAIN ] = function( abilityName, abilityGraphic, abilityActionSlotType, sourceName, sourceType, targetName, targetType, hitValue, mechanicValue )
+ local mechanicName = GetString( 'SI_COMBATMECHANICTYPE', mechanicValue )
+ return zo_strformat( '-<<1>> (<<2>>)', hitValue, mechanicName ), PSBT_AREAS.OUTGOING, false
+ end,
+ ---------------------------------------------
+ --[[[ ACTION_RESULT_POWER_ENERGIZE ] = nil,
+ [ ACTION_RESULT_EFFECT_GAINED_DURATION ] = nil,
+ [ ACTION_RESULT_EFFECT_GAINED ] = nil,
+ [ ACTION_RESULT_EFFECT_FADED ] = nil,
+ [ ACTION_RESULT_DEBUFF ] = nil,
+ [ ACTION_RESULT_CASTER_DEAD ] = nil,
+ [ ACTION_RESULT_COMPLETE ] = nil,
+ [ ACTION_RESULT_BUFF ] = nil,
+ [ ACTION_RESULT_BUSY ] = nil,
+ [ ACTION_RESULT_CANNOT_USE ] = nil,
+ [ ACTION_RESULT_BEGIN_CHANNEL ] = nil,
+ [ ACTION_RESULT_BAD_TARGET ] = nil,
+ [ ACTION_RESULT_ABILITY_ON_COOLDOWN ] = nil,
+ [ ACTION_RESULT_BEGIN ] = nil,
+ [ ACTION_RESULT_POWER_DRAIN ] = nil,
+ [ ACTION_RESULT_RESURRECT ] = nil,
+ [ ACTION_RESULT_DIED ] = nil,
+ [ ACTION_RESULT_DIED_XP ] = nil,]]
+}
-local MAX_EVENTS = 25
function PSBT_Combat:Initialize( ... )
PSBT_Module.Initialize( self, ... )
- self._playernameRaw = GetRawUnitName( 'player' )
- self._playernameClean = GetUnitName( 'player' )
self._buffer = ZO_CircularBuffer:New( DEFAULT_MAX_BUFFERED_EVENTS )
self._index = 1
+ self._free = nil
for i=1,GetNumAbilities() do
local name, icon = GetAbilityInfoByIndex( i )
self._iconRegistry[ name ] = icon
end
- self:RegisterForEvent( EVENT_COMBAT_EVENT, function( eventCode, ... ) self:OnCombatEvent( ... ) end )
+ self:RegisterForEvent( EVENT_COMBAT_EVENT, function( event, ... ) self:OnCombatEvent( ... ) end )
end
function PSBT_Combat:OnCombatEvent( ... )
- local sourceType = select( 7, ... )
- local targetType = select( 9, ... )
+ local result = select( 1, ... )
+ if ( not combat_events[ result ] ) then
+ return
+ end
+
+ -- did we get hit or do something?
+ if ( IsPlayer( select( 7, ... ), select( 6, ... ) ) or IsPlayer( select( 9, ... ), select( 8, ... ) ) ) then
- if ( sourceType == COMBAT_UNIT_TYPE_PLAYER
- or sourceType == COMBAT_UNIT_TYPE_PLAYER_PET
- or targetType == COMBAT_UNIT_TYPE_PLAYER
- or targetType == COMBAT_UNIT_TYPE_PLAYER_PET ) then
+ if ( self._free ) then
+ local argCount = select( "#", ... )
+ for i = 1,argCount do
+ self._free[ i ] = select( i, ... )
+ end
+
+ --clear any additional arguments
+ for i=#self._free,argCount+1,-1 do
+ self._free[ i ] = nil
+ end
+
+ self._free = self._buffer:Add( self._free )
+ else
+ self._free = self._buffer:Add( { ... } )
+ end
- self._buffer:Add( { ... } )
self._index = self._index - 1
end
end
@@ -54,29 +358,14 @@ function PSBT_Combat:OnUpdate( frameTime )
end
end
-function PSBT_Combat:DispatchEvent( ... )
- local sourceType = select( 7, ... )
- local targetType = select( 9, ... )
- local ability = select( 3, ... )
- local value = select( 10, ... )
-
- d( GetString("SI_DAMAGETYPE", select( 11, ... ) ) )
- d( GetString("SI_COMBATMECHANICTYPE", select( 11, ... ) ) )
+--integer result, bool isError, string abilityName, integer abilityGraphic, integer abilityActionSlotType, string sourceName, integer sourceType, string targetName, integer targetType, integer hitValue, integer powerType, integer damageType, bool log
+function PSBT_Combat:DispatchEvent( result, _, ... )
+ local func = combat_events[ result ]
+ local text, area, crit = func( ... )
- local icon = self._iconRegistry[ ability ]
- if ( not icon ) then
- icon = [[/esoui/art/icons/icon_missing.dds]]
- end
-
- local area = nil
- if ( targetType == COMBAT_UNIT_TYPE_PLAYER or
- targetType == COMBAT_UNIT_TYPE_PLAYER_PET ) then
- area = PSBT_AREAS.INCOMING
- else
- area = PSBT_AREAS.OUTGOING
- end
+ local icon = self._iconRegistry[ select( 1, ... ) ]
- self:NewEvent( area, false, icon, value )
+ self:NewEvent( area, crit, icon, text )
end
CBM:RegisterCallback( PSBT_EVENTS.LOADED,
diff --git a/PSBT_Label.lua b/PSBT_Label.lua
index d8f2ba0..2c943d3 100644
--- a/PSBT_Label.lua
+++ b/PSBT_Label.lua
@@ -28,9 +28,10 @@ end
function PSBT_Label:SetTexture( texture )
if ( type( texture ) == 'string' ) then
+ self.icon:SetWidth( self.control:GetHeight() )
self.icon:SetTexture( texture )
else
- print( 'SetTexture( %d )', texture )
+ self.icon:SetWidth( 0 )
end
end
@@ -39,12 +40,19 @@ function PSBT_Label:IsVisible()
end
function PSBT_Label:Play( height, duration )
- self.control:SetAlpha( 1.0 )
self.control:SetHidden( false )
+ self.control:SetAlpha( 0.01 )
- local animation = LibAnim:New( self.control )
- animation:AlphaTo( 0.0, duration )
- animation:TranslateTo( 0, height, duration )
+ local enter = LibAnim:New( self.control )
+ enter:AlphaTo( 1.0, 500, nil, nil, ZO_LinearEase )
+ enter:InsertCallback( function() self:OnEnterComplete( height, duration ) end, 500 )
+ enter:Play()
+end
+
+function PSBT_Label:OnEnterComplete( height, duration )
+ local leave = LibAnim:New( self.control )
+ leave:AlphaTo( 0.0, duration, nil, nil, ZO_EaseOutCubic )
+ leave:TranslateTo( 0, height, duration, nil, nil, ZO_EaseOutCubic )
- animation:Play()
+ leave:Play()
end
\ No newline at end of file