initial commit
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
|
||||
modifier_ogreseal_flop = class({})
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local OGRE_MINIMUM_HEIGHT_ABOVE_LOWEST = 150
|
||||
local OGRE_MINIMUM_HEIGHT_ABOVE_HIGHEST = 33
|
||||
local OGRE_ACCELERATION_Z = 1250
|
||||
local OGRE_MAX_HORIZONTAL_ACCELERATION = 800
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:IsStunDebuff()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:IsHidden()
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:IsPurgable()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:RemoveOnDeath()
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:OnCreated( kv )
|
||||
if IsServer() then
|
||||
if self.nHopCount == nil then
|
||||
self.nHopCount = 1
|
||||
self.flop_distances = { 200, 400, 400 }
|
||||
|
||||
local nFXIndex = ParticleManager:CreateParticle( "particles/creatures/ogre_seal/ogre_seal_warcry.vpcf", PATTACH_ABSORIGIN_FOLLOW, self:GetParent() )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 1, self:GetParent(), PATTACH_POINT_FOLLOW, "attach_hitloc", self:GetParent():GetOrigin(), true )
|
||||
if self:GetCaster():IsRealHero() == false then
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 2, self:GetParent(), PATTACH_POINT_FOLLOW, "mouth", self:GetParent():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 6, self:GetParent(), PATTACH_POINT_FOLLOW, "eye_L", self:GetParent():GetOrigin(), true )
|
||||
ParticleManager:SetParticleControlEnt( nFXIndex, 7, self:GetParent(), PATTACH_POINT_FOLLOW, "eye_R", self:GetParent():GetOrigin(), true )
|
||||
end
|
||||
|
||||
self:AddParticle( nFXIndex, false, false, -1, false, false )
|
||||
end
|
||||
|
||||
if self:GetCaster():IsRealHero() then
|
||||
self:GetCaster():StartGesture( ACT_DOTA_FLAIL )
|
||||
end
|
||||
|
||||
self.bHorizontalMotionInterrupted = false
|
||||
self.bDamageApplied = false
|
||||
self.bTargetTeleported = false
|
||||
|
||||
if self:ApplyHorizontalMotionController() == false or self:ApplyVerticalMotionController() == false then
|
||||
self:Destroy()
|
||||
return
|
||||
end
|
||||
|
||||
self.flTimer = 0.0
|
||||
self.vStartPosition = GetGroundPosition( self:GetParent():GetOrigin(), self:GetParent() )
|
||||
self.flCurrentTimeHoriz = 0.0
|
||||
self.flCurrentTimeVert = 0.0
|
||||
|
||||
self.vLoc = Vector( kv.vLocX, kv.vLocY, kv.vLocZ )
|
||||
self.vLastKnownTargetPos = self.vLoc
|
||||
|
||||
local duration = self:GetAbility():GetSpecialValueFor( "duration" )
|
||||
local flDesiredHeight = OGRE_MINIMUM_HEIGHT_ABOVE_LOWEST * self.nHopCount * duration * duration
|
||||
local flLowZ = math.min( self.vLastKnownTargetPos.z, self.vStartPosition.z )
|
||||
local flHighZ = math.max( self.vLastKnownTargetPos.z, self.vStartPosition.z )
|
||||
local flArcTopZ = math.max( flLowZ + flDesiredHeight, flHighZ + OGRE_MINIMUM_HEIGHT_ABOVE_HIGHEST * self.nHopCount )
|
||||
|
||||
local flArcDeltaZ = flArcTopZ - self.vStartPosition.z
|
||||
self.flInitialVelocityZ = math.sqrt( 2.0 * flArcDeltaZ * OGRE_ACCELERATION_Z * self.nHopCount )
|
||||
|
||||
local flDeltaZ = self.vLastKnownTargetPos.z - self.vStartPosition.z
|
||||
local flSqrtDet = math.sqrt( math.max( 0, ( self.flInitialVelocityZ * self.flInitialVelocityZ ) - 2.0 * OGRE_ACCELERATION_Z * self.nHopCount * flDeltaZ ) )
|
||||
self.flPredictedTotalTime = math.max( ( self.flInitialVelocityZ + flSqrtDet) / ( OGRE_ACCELERATION_Z * self.nHopCount ), ( self.flInitialVelocityZ - flSqrtDet) / ( OGRE_ACCELERATION_Z * self.nHopCount ) )
|
||||
|
||||
self.vHorizontalVelocity = ( self.vLastKnownTargetPos - self.vStartPosition ) / self.flPredictedTotalTime
|
||||
self.vHorizontalVelocity.z = 0.0
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:OnDestroy()
|
||||
if IsServer() then
|
||||
self:GetParent():RemoveHorizontalMotionController( self )
|
||||
self:GetParent():RemoveVerticalMotionController( self )
|
||||
|
||||
if self:GetCaster():IsRealHero() then
|
||||
self:GetCaster():RemoveGesture( ACT_DOTA_FLAIL )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:DeclareFunctions()
|
||||
local funcs =
|
||||
{
|
||||
-- MODIFIER_PROPERTY_OVERRIDE_ANIMATION,
|
||||
}
|
||||
|
||||
return funcs
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:CheckState()
|
||||
local state =
|
||||
{
|
||||
[MODIFIER_STATE_STUNNED] = true,
|
||||
}
|
||||
|
||||
return state
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:UpdateHorizontalMotion( me, dt )
|
||||
if IsServer() then
|
||||
self.flTimer = self.flTimer + dt
|
||||
self.flCurrentTimeHoriz = math.min( self.flCurrentTimeHoriz + dt, self.flPredictedTotalTime )
|
||||
local t = self.flCurrentTimeHoriz / self.flPredictedTotalTime
|
||||
local vStartToTarget = self.vLastKnownTargetPos - self.vStartPosition
|
||||
local vDesiredPos = self.vStartPosition + t * vStartToTarget
|
||||
|
||||
GridNav:DestroyTreesAroundPoint( me:GetAbsOrigin(), 75, false )
|
||||
|
||||
--[[
|
||||
-- Prevent players from hopping through obstructions (players can cast ogre seal flop with the Ogre Seal Totem item)
|
||||
if me:IsRealHero() then
|
||||
if ( not GridNav:CanFindPath( me:GetOrigin(), vDesiredPos ) ) then
|
||||
self:Destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
local vOldPos = me:GetOrigin()
|
||||
local vToDesired = vDesiredPos - vOldPos
|
||||
vToDesired.z = 0.0
|
||||
local vDesiredVel = vToDesired / dt
|
||||
local vVelDif = vDesiredVel - self.vHorizontalVelocity
|
||||
local flVelDif = vVelDif:Length2D()
|
||||
vVelDif = vVelDif:Normalized()
|
||||
local flVelDelta = math.min( flVelDif, OGRE_MAX_HORIZONTAL_ACCELERATION * self.nHopCount )
|
||||
|
||||
self.vHorizontalVelocity = self.vHorizontalVelocity + vVelDif * flVelDelta * dt
|
||||
local vNewPos = vOldPos + self.vHorizontalVelocity * dt
|
||||
me:SetOrigin( vNewPos )
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:UpdateVerticalMotion( me, dt )
|
||||
if IsServer() then
|
||||
self.flCurrentTimeVert = self.flCurrentTimeVert + dt
|
||||
local bGoingDown = ( -OGRE_ACCELERATION_Z * self.nHopCount * self.flCurrentTimeVert + self.flInitialVelocityZ ) < 0
|
||||
|
||||
local vNewPos = me:GetOrigin()
|
||||
vNewPos.z = self.vStartPosition.z + ( -0.5 * OGRE_ACCELERATION_Z * self.nHopCount * ( self.flCurrentTimeVert * self.flCurrentTimeVert ) + self.flInitialVelocityZ * self.flCurrentTimeVert )
|
||||
|
||||
local flGroundHeight = GetGroundHeight( vNewPos, self:GetParent() )
|
||||
local bLanded = false
|
||||
if ( vNewPos.z < flGroundHeight and bGoingDown == true ) then
|
||||
vNewPos.z = flGroundHeight
|
||||
bLanded = true
|
||||
end
|
||||
|
||||
me:SetOrigin( vNewPos )
|
||||
if bLanded == true then
|
||||
|
||||
local bDoneHopping = self.nHopCount == 3
|
||||
|
||||
if self.bHorizontalMotionInterrupted == false then
|
||||
if self.nHopCount > 1 then
|
||||
|
||||
self:GetAbility():TryToDamage()
|
||||
self.flTimer = 0.0
|
||||
end
|
||||
else
|
||||
bDoneHopping = true
|
||||
end
|
||||
|
||||
if bDoneHopping then
|
||||
self:Destroy()
|
||||
|
||||
else
|
||||
self.nHopCount = self.nHopCount + 1
|
||||
self.vLoc = self.vLoc + self:GetCaster():GetForwardVector() * self.flop_distances[ self.nHopCount ]
|
||||
local kv =
|
||||
{
|
||||
vLocX = self.vLoc.x,
|
||||
vLocY = self.vLoc.y,
|
||||
vLocZ = self.vLoc.z,
|
||||
}
|
||||
self:OnCreated( kv )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:OnHorizontalMotionInterrupted()
|
||||
if IsServer() then
|
||||
self.bHorizontalMotionInterrupted = true
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:OnVerticalMotionInterrupted()
|
||||
if IsServer() then
|
||||
self:Destroy()
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function modifier_ogreseal_flop:GetOverrideAnimation( params )
|
||||
return ACT_DOTA_OVERRIDE_ABILITY_2
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user