mcu8_NPC_Mobster_FallOffDocks (fixed alwaysloaded)

#CustomActor

It makes Hat_NPC_Mobster_FallOffDocks OnInteraction event work even when hitting the mafia guy with a weapon

SariaMode SariaMode SariaMode OnInteraction commands:

OnFallOff PostFallOff (not returning an inflictor, so be careful)

mcu8_NPC_Mobster.uc

[RAW] [Download]

// fuck you, alwaysloaded...
 
class mcu8_NPC_Mobster extends Hat_NPC
    placeable;
 
var Hat_RollingBarrel Barrel;
var bool ToggleBarrel;
var transient Array<AnimSet> DefaultAnimSets;
 
defaultproperties
{
    Begin Object Name=SkeletalMeshComponent0
        PhysicsAsset=PhysicsAsset'HatInTime_Characters.Physics.MafiaGreg_Physics'
        SkeletalMesh=SkeletalMesh'HatInTime_Characters.models.MafiaGreg'
        AnimTreeTemplate=AnimTree'HatInTime_Characters.AnimTree.MafiaGreg_animtree'
        Animations = None;
        AnimSets(0)=AnimSet'HatInTime_Characters.AnimSet.MafiaGreg_Anims'
        AnimSets(1)=AnimSet'HatinTime_Characters_Mafia.AnimSets.MafiaGreg_Anims_Cameron'
        `if(`notdefined(IS_NINTENDO_SWITCH))
        bHasPhysicsAssetInstance = TRUE;
        `endif
 
        BlockActors=false
        BlockZeroExtent=false
        BlockNonZeroExtent=false
        CollideActors=false
        BlockRigidBody=false
        Translation=(Z=-60)
    End Object
 
    Begin Object Class=CylinderComponent Name=CollisionCylinder
        CollisionRadius=40
        CollisionHeight=60
        CanBlockCamera = false
 
        BlockActors=true
        BlockZeroExtent=true
        BlockNonZeroExtent=true
        CollideActors=true
        BlockRigidBody=true
    End Object
    CollisionComponent=CollisionCylinder
    Components.Add(CollisionCylinder)
 
   Begin Object Class=Hat_ExpressionComponent_Mafia Name=hExpression
 
   End Object
   Components.Add(hExpression);
   Expression = hExpression;
}
 
function OnSpawnBarrel(Hat_SeqAct_SpawnBarrel s)
{
    local Hat_RollingBarrel b;
    if (s.InputLinks[0].bHasImpulse)
    {
        ThrowBarrel();
    }
    else if (s.InputLinks[1].bHasImpulse)
    {
        b = Spawn(s.BarrelClass, self, , self.Location + vect(0,0,1)*200);
        b.BounceLimit = 2;
        Barrel = b;
    }
    else if (s.InputLinks[2].bHasImpulse)
    {
        b = Spawn(s.BarrelClass, self, , self.Location + vect(0,0,1)*200);
        b.BounceLimit = 8;
        b.Path2DOnBounce = true;
        b.MoveClockwise = ToggleBarrel;
        //b.Set2D(s.Path2D);
        b.MakeRadial(450, Location);
        Barrel = b;
        b.BounceHeight = 750;
        b.BounceMoveSpeed = 400;
 
        ToggleBarrel = !ToggleBarrel;
    }
    else if (s.InputLinks[3].bHasImpulse)
    {
        b = Spawn(s.BarrelClass, self, , self.Location + vect(0,0,1)*200);
        b.BounceLimit = 10;
        b.Path2DOnBounce = true;
        b.MoveClockwise = ToggleBarrel;
        //b.Set2D(s.Path2D);
        b.MakeRadial(450, Location);
        b.BounceHeight = 750;
        Barrel = b;
 
        ToggleBarrel = !ToggleBarrel;
    }
 
    if (b != None)
    {
        b.StartVelocity.Z =400;
        b.LifeSpan = 20;
        b.SetEnabled(false);
        b.SetBase(self, , SkeletalMeshComponent, 'Barrel');
    }
}
 
function ThrowBarrel()
{
    if (Barrel == None) return;
 
    Barrel.SetBase(None);
    Barrel.SetRotation(Rotation);
    Barrel.SetEnabled(true);
    Barrel = None;
}
 
simulated event bool RestoreAnimSetsToDefault()
{
    SkeletalMeshComponent.AnimSets = DefaultAnimSets;
    return TRUE;
}
 
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
{
    Super.PostInitAnimTree(SkelComp);
 
    // Only refresh anim nodes if our main mesh was updated
    if (SkelComp == SkeletalMeshComponent)
    {
        DefaultAnimSets = SkelComp.AnimSets;
    }
}
mcu8_NPC_Mobster_FallOffDocks.uc

[RAW] [Download]

/**
 *
 * Copyright 2012-2015 Gears for Breakfast ApS. All Rights Reserved.
 */
 
class mcu8_NPC_Mobster_FallOffDocks extends mcu8_NPC_Mobster
    placeable;
 
var() Name KickedOffAnimation;
var() float ForwardVelocity;
var() float UpwardVelocity;
var(Particles) ParticleSystemComponent HitMangaZoomParticle;
var(Particles) ParticleSystem DeathExplosionParticle;
var(Particles) ParticleSystem DeathMangaZoomParticle;
var(Sounds) SoundCue HitSound;
var(Sounds) SoundCue DeathSound;
var(Sounds) SoundCue FallSounds[3];
var transient bool IsKickedOff;
var() bool KnockAllOffAchievement;
 
var() float FallTime;
var() bool FallDeathExplosion;
 
defaultproperties
{
    Begin Object Class=AnimNodeSequence Name=AnimNodeSeq1
        AnimSeqName = "Mafia_sit_dock";
        bLooping = true
        bPlaying = true
    End Object
 
    Begin Object Name=SkeletalMeshComponent0
        AnimSets(0)=AnimSet'HatinTime_Characters_Mafia.AnimSets.MafiaGreg_Anims_Docks'
        Animations=AnimNodeSeq1
    End Object
 
    Begin Object Class=ParticleSystemComponent Name=MangaZoomParticle0 
        Template =  ParticleSystem'HatInTime_PlayerAssets.Particles.mangazoom_damage'
        bAutoActivate = false;
        AbsoluteTranslation=true
    End Object
    Components.Add(MangaZoomParticle0);
    HitMangaZoomParticle = MangaZoomParticle0;
 
    Begin Object Name=CollisionCylinder
        bAlwaysRenderIfSelected=true
    End Object
 
    bBlockActors = false;
 
    KickedOffAnimation = "Mafia_fall_dock";
    ForwardVelocity = 150;
    UpwardVelocity = 600;
    FallTime = 5;
    HitSound = SoundCue'HatInTime_Weapons.SoundCues.PunchHit'
    DeathExplosionParticle = ParticleSystem'HatInTime_PlayerAssets.Particles.CombatEffects.MonsterCloudExplosion_Mesh';
    DeathMangaZoomParticle = ParticleSystem'HatInTime_PlayerAssets.Particles.mangazoom_death';
    DeathSound = SoundCue'HatInTime_PlayerAssets.SoundCues.enemy_explosion';
    FallSounds(0) = SoundCue'HatinTime_SFX_Player3.SoundCues.MafiaTown_MafiaFallDown_Short'
    FallSounds(1) = SoundCue'HatinTime_SFX_Player3.SoundCues.MafiaTown_MafiaFallDown_Medium'
    FallSounds(2) = SoundCue'HatinTime_SFX_Player3.SoundCues.MafiaTown_MafiaFallDown_Long'
}
 
event Touch(Actor Other, PrimitiveComponent OtherComp, Object.Vector HitLocation, Object.Vector HitNormal)
{
    local Hat_WaterVolume v;
    local Vector Loc;
    if (Other.IsA('Pawn') && Pawn(Other).IsPlayerPawn() && !IsKickedOff)
    {
        HitLocation = VLerp(Other.Location, Location, 0.5f);
        KickOffEffects(HitLocation);
        OnKickedOff(Other);
    }
    else if (IsKickedOff && Other.IsA('Hat_WaterVolume'))
    {
        v = Hat_WaterVolume(Other);
        if (v.EntrySoundDive != None)
            PlaySound(v.EntrySoundDive);
        if (v.EntrySound != None)
            PlaySound(v.EntrySound);
        Loc = Location + vect(0,0,-70);
        if (v.EntryParticleDive != None)
            Worldinfo.MyEmitterPool.SpawnEmitter(v.EntryParticleDive, v.EntryParticleDiveParentToActor ? (Loc + vect(0,0,-100)) : Loc);
        if (v.EntryParticleSurface != None)
            Worldinfo.MyEmitterPool.SpawnEmitter(v.EntryParticleSurface, Loc);
    }
    Super.Touch(Other, OtherComp, HitLocation, HitNormal);
}
 
function OnKickedOff(optional Actor Inflictor)
{
    local mcu8_NPC_Mobster_FallOffDocks mfod;
    local bool AnyNotKickedOffYet;
    local Hat_PlayerController PC;
    //SetCollision(false);
    class'Hat_SeqEvent_OnInteraction'.static.CallInteractionEvent(self, Inflictor, "OnFallOff");
 
    SkeletalMeshComponent.PlayAnim(KickedOffAnimation, , false, false);
    SetPhysics(Phys_Falling);
    Velocity = Vector(Rotation)*ForwardVelocity + vect(0,0,1)*UpwardVelocity;
    class'Hat_PawnCombat'.static.ShakeNearbyCameras_Static(200, 1024, 12, 0.4, Location, self);
    IsKickedOff = true;
    PlaySound(FallSounds[(FallTime >= 4) ? 2 : ((FallTime >= 1.4) ? 1 : 0)]);
 
    SetTimer(FallTime, false, NameOf(PostKickedOff));
 
    if (KnockAllOffAchievement)
    {
        AnyNotKickedOffYet = false;
        foreach DynamicActors(class'mcu8_NPC_Mobster_FallOffDocks', mfod)
        {
            if (mfod == self) continue;
            if (!mfod.KnockAllOffAchievement) continue;
            if (mfod.bDeleteMe) continue;
            if (mfod.IsKickedOff) continue;
            AnyNotKickedOffYet = true;
            break;
        }
        if (!AnyNotKickedOffYet && Inflictor != None && Inflictor.IsA('Pawn'))
        {
            PC = Hat_PlayerController(Pawn(Inflictor).Controller);
            if (PC != None)
            {
                PC.UnlockAchievement(26);
            }
        }
    }
 
    `if(`isdefined(WITH_GHOSTPARTY))
    if (Inflictor != None && Inflictor.IsA('Hat_Player'))
        class'Hat_GhostPartyPlayerBase'.static.SendSingleStateLevelObject(Hat_Player(Inflictor).GetPlayerIndex(), self);
    `endif
}
 
`if(`isdefined(WITH_GHOSTPARTY))
event OnGhostPartyStateChange(Actor Sender, int NewState)
{
    local Vector HitLocation;
    if (IsKickedOff) return;
    HitLocation = VLerp(Sender.Location, Location, 0.5f);
    KickOffEffects(HitLocation);
    OnKickedOff(Sender);
}
`endif
 
function KickOffEffects(Vector HitLocation)
{
    local ParticleSystemComponent p;
    Spawn(class'Hat_ExplosionLight_EnemyImpact',,, HitLocation);
    Spawn(class'Hat_DynamicRadialBlurActor_EnemyImpact',,, HitLocation);
    if (HitSound != None) PlaySound(HitSound);
    if (Worldinfo.MyEmitterPool != None)
    {
        p = Worldinfo.MyEmitterPool.SpawnEmitter(class'Hat_DamageType'.default.ImpactParticle, HitLocation);
        if (p != None)
            p.SetDepthPriorityGroup(SDPG_Foreground);
    }
    HitMangaZoomParticle.SetTranslation(Location);
    HitMangaZoomParticle.SetActive(true);
}
 
simulated event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
    if (IsKickedOff) return;
    KickOffEffects(HitLocation);
    OnKickedOff(InstigatedBy != None ? InstigatedBy.Pawn : None);
}
 
function PostKickedOff()
{
    class'Hat_SeqEvent_OnInteraction'.static.CallInteractionEvent(self, None, "PostFallOff");
 
    if (FallDeathExplosion)
    {
        Spawn(class'Hat_ExplosionLight_EnemyDeath',,, Location);
        Spawn(class'Hat_DynamicRadialBlurActor_EnemyDeath',,, Location);
        if (DeathExplosionParticle != None)
            Worldinfo.MyEmitterPool.SpawnEmitter(DeathExplosionParticle, Location);
        if (DeathMangaZoomParticle != None && !WorldInfo.IsConsoleBuild())
            Worldinfo.MyEmitterPool.SpawnEmitter(DeathMangaZoomParticle, Location);
        if (DeathSound != None)
            PlaySound(DeathSound);
        class'Hat_PawnCombat'.static.ShakeNearbyCameras_Static(200, 1024, 60, 0.4, Location, self);
    }
 
    Destroy();
}
 
simulated function bool CanBeInteractedWith(Actor hOther)
{
    return false;
}