Predicted Projectile Bilebomb


Changed files:
// ======= Copyright (c) 2003-2011, Unknown Worlds Entertainment, Inc. All rights reserved. =======
//
// lua\Weapons\Alien\BileBomb.lua
//
// Created by: Charlie Cleveland (charlie@unknownworlds.com)
//
// ========= For more information, visit us at http://www.unknownworlds.com =====================
Script.Load("lua/Weapons/Alien/Ability.lua")
Script.Load("lua/Weapons/Alien/Bomb.lua")
Script.Load("lua/Weapons/Alien/HealSprayMixin.lua")
class 'BileBomb' (Ability)
BileBomb.kMapName = "bilebomb"
// part of the players velocity is use for the bomb
local kPlayerVelocityFraction = 1
local kBombVelocity = 18
local kAnimationGraph = PrecacheAsset("models/alien/gorge/gorge_view.animation_graph")
local kBbombViewEffect = PrecacheAsset("cinematics/alien/gorge/bbomb_1p.cinematic")
local networkVars =
{
firingPrimary = "boolean"
}
AddMixinNetworkVars(HealSprayMixin, networkVars)
function BileBomb:OnCreate()
Ability.OnCreate(self)
self.firingPrimary = false
self.timeLastBileBomb = 0
InitMixin(self, HealSprayMixin)
end
function BileBomb:GetAnimationGraphName()
return kAnimationGraph
end
function BileBomb:GetEnergyCost(player)
return kBileBombEnergyCost
end
function BileBomb:GetHUDSlot()
return 2
end
function BileBomb:GetSecondaryTechId()
return kTechId.Spray
end
function BileBomb:OnTag(tagName)
PROFILE("BileBomb:OnTag")
if self.firingPrimary and tagName == "shoot" then
local player = self:GetParent()
if player then
self:FireBombProjectile(player)
player:DeductAbilityEnergy(self:GetEnergyCost())
self.timeLastBileBomb = Shared.GetTime()
self:TriggerEffects("bilebomb_attack")
if Client then
local cinematic = Client.CreateCinematic(RenderScene.Zone_ViewModel)
cinematic:SetCinematic(kBbombViewEffect)
end
TEST_EVENT("BileBomb shot")
end
end
end
function BileBomb:OnPrimaryAttack(player)
if player:GetEnergy() >= self:GetEnergyCost() then
self.firingPrimary = true
else
self.firingPrimary = false
end
end
function BileBomb:OnPrimaryAttackEnd(player)
Ability.OnPrimaryAttackEnd(self, player)
self.firingPrimary = false
end
function BileBomb:GetTimeLastBomb()
return self.timeLastBileBomb
end
function BileBomb:FireBombProjectile(player)
PROFILE("BileBomb:FireBombProjectile")
if Server or (Client and Client.GetIsControllingPlayer()) then
local viewAngles = player:GetViewAngles()
local velocity = player:GetVelocity()
local viewCoords = viewAngles:GetCoords()
local startPoint = player:GetEyePos() + viewCoords.zAxis * 1
local startVelocity = viewCoords.zAxis * kBombVelocity
local bomb = player:CreatePredictedProjectile("Bomb", startPoint, startVelocity, 0, 0, 5)
end
end
function BileBomb:OnUpdateAnimationInput(modelMixin)
PROFILE("BileBomb:OnUpdateAnimationInput")
modelMixin:SetAnimationInput("ability", "bomb")
local activityString = "none"
if self.firingPrimary then
activityString = "primary"
end
modelMixin:SetAnimationInput("activity", activityString)
end
Shared.LinkClassToMap("BileBomb", BileBomb.kMapName, networkVars)
Script.Load("lua/Weapons/Projectile.lua")
Script.Load("lua/TeamMixin.lua")
Script.Load("lua/Weapons/DotMarker.lua")
Script.Load("lua/Weapons/PredictedProjectile.lua")
PrecacheAsset("cinematics/vfx_materials/decals/bilebomb_decal.surface_shader")
class 'Bomb' (PredictedProjectile)
Bomb.kMapName = "bomb"
Bomb.kModelName = PrecacheAsset("models/alien/gorge/bilebomb.model")
Bomb.kClearOnImpact = false
Bomb.kClearOnEnemyImpact = true
Bomb.kradius = 0.2
local kBombLifetime = 1.5
local kBileBombDotIntervall = 0.4
local networkVars = { }
AddMixinNetworkVars(BaseModelMixin, networkVars)
AddMixinNetworkVars(ModelMixin, networkVars)
AddMixinNetworkVars(TeamMixin, networkVars)
local function UpdateLifetime(self)
if not self.endOfLife then
self.endOfLife = Shared.GetTime() + kBombLifetime
end
if self.endOfLife <= Shared.GetTime() then
self:Detonate(nil, nil, true)
return false
end
return true
end
function Bomb:OnCreate()
PredictedProjectile.OnCreate(self)
InitMixin(self, BaseModelMixin)
InitMixin(self, ModelMixin)
InitMixin(self, TeamMixin)
if Server then
self:AddTimedCallback(UpdateLifetime, 0.1)
self.endOfLife = nil
end
end
function Bomb:GetProjectileModel()
return Bomb.kModelName
end
function Bomb:GetDeathIconIndex()
return
end
function Bomb:GetDamageType()
return kBileBombDamageType
end
function Bomb:ProcessHit(targetHit, surface, endPoint)
if Server and self:GetOwner() ~= targetHit and GetAreEnemies(self, targetHit) then
self:Detonate(targetHit, surface)
else
return true
end
end
function Bomb:ProcessNearMiss( targetHit, endPoint )
if targetHit and GetAreEnemies(self, targetHit) then
if Server then
self:Detonate( targetHit )
end
return true
end
end
if Server then
function Bomb:Detonate(targetHit, surface, force)
if not self:GetIsDestroyed() then
if targetHit or force then
local dotMarker = CreateEntity(DotMarker.kMapName, self:GetOrigin(), self:GetTeamNumber())
dotMarker:SetDamageType(kBileBombDamageType)
dotMarker:SetLifeTime(kBileBombDuration)
dotMarker:SetDamage(kBileBombDamage)
dotMarker:SetRadius(kBileBombSplashRadius)
dotMarker:SetDamageIntervall(kBileBombDotIntervall)
dotMarker:SetDotMarkerType(DotMarker.kType.Static)
dotMarker:SetTargetEffectName("bilebomb_onstructure")
dotMarker:SetDeathIconIndex(kDeathMessageIcon.BileBomb)
dotMarker:SetOwner(self:GetOwner())
dotMarker:SetFallOffFunc(SineFalloff)
dotMarker:TriggerEffects("bilebomb_hit")
DestroyEntity(self)
CreateExplosionDecals(self, "bilebomb_decal")
end
end
end
end
Shared.LinkClassToMap("Bomb", Bomb.kMapName, networkVars)
Edit: Did put large code blocks into spoilers to make post easier to read ~Ghoul

Comments
Also everything which is inside the "Fixes to be tested" list has been merged into the beta build.
Beside that bile bombs should not bounce, but I'll ignore that for now.
So far your code come close to the remi's solution (without the bouncing feature). But be aware that in your version BileBomb:FireBombProjectile() gets also executed by the Predicted VM, which could cause some issues.
For the future:
If you want to to provide patches for the vanilla build please provide them as diffs or patch files!