• Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

Code Linking a Pickup to a Spawn

EvilHobo

Grizzled Veteran
Dec 22, 2005
2,613
192
Germany, NRW
Alright, so Panzerfaust spawns linked to SpawnAreas is something I have been trying to accomplish for Kriegstadt for quite a long time, but have never quite gotten it to work out. What you are going to see is a mish-mash of code from a lot of stuff...ROVehicleFactory, ROTeamGame, ROPanzerFaustPickup, all that good stuff.

So if any coding gurus can lend a hand, it would be much appreciated...

Code:
class ROPanzerFaustPickupEH extends ROPlaceableAmmoPickup;

var        Ammo          LastSpawnedPickup;
var     bool            bActive;        
var()   bool                bDestroyPickupWhenInactive;
var()   class<Inventory>    WeaponType;
var()   int                 PickupRespawnLimit;
var     int                 TotalSpawnedPickups;
var        array<ROPanzerFaustPickupEH>            FaustPickups;
var        array<ROSpawnArea>            SpawnAreas;
var        ROSpawnArea                    CurrentSpawnArea[2];        // Stores the current spawn areas being used
var        array<ROSpawnArea>            TankCrewSpawnAreas;
var        ROSpawnArea                    CurrentTankCrewSpawnArea[2];// Stores the current tank crew spawn areas being used

var()    bool            bUsesSpawnAreas;

static function StaticPrecache(LevelInfo L)
{
    L.AddPrecacheStaticMesh(StaticMesh'WeaponPickupSM.Weapons.Panzerfaust');
    L.AddPrecacheStaticMesh(StaticMesh'WeaponPickupSM.Ammo.Warhead3rd');
    L.AddPrecacheStaticMesh(StaticMesh'WeaponPickupSM.Ammo.Warhead1st');
    L.AddPrecacheMaterial(Material'Weapons3rd_tex.German.Panzerfaust_world');
    L.AddPrecacheMaterial(Material'Weapons1st_tex.Grenades.Panzerfaust_S');
}

function PostBeginPlay()
{
    Super.PostBeginPlay();

    if( !bUsesSpawnAreas )
        Activate();
}

//Yanked from ROTeamGame
function CheckFaustPickups()
{
    local int i;

    for( i = 0; i < FaustPickups.Length; i++)
    {
        if( FaustPickups[i] == none )
            continue;

         if( FaustPickups[i].bUsesSpawnAreas )
         {
             if( ((CurrentTankCrewSpawnArea[AXIS_TEAM_INDEX] != none &&
                CurrentTankCrewSpawnArea[AXIS_TEAM_INDEX].Tag == FaustPickups[i].Tag) ||
                 CurrentSpawnArea[AXIS_TEAM_INDEX].Tag == FaustPickups[i].Tag) ||
                ( (CurrentTankCrewSpawnArea[ALLIES_TEAM_INDEX] != none &&
                 CurrentTankCrewSpawnArea[ALLIES_TEAM_INDEX].Tag == FaustPickups[i].Tag) ||
                 CurrentSpawnArea[ALLIES_TEAM_INDEX].Tag == FaustPickups[i].Tag) )
            {
                 FaustPickups[i].Activate();
            }
            else
            {

                FaustPickups[i].Deactivate();
            }
         }
         else
         {
             FaustPickups[i].Activate();
         }
    }
}

function Activate()
{
    bActive = True;
}

function Deactivate()
{
    bActive = False;

    //This part is sketchy; not sure how to word it properly
    //if (bDestroyPickupWhenInactive && ROVehicle(LastSpawnedVehicle) != None )
    //{
    //   ROVehicle(LastSpawnedVehicle).ResetTime = Level.TimeSeconds + 1;
    //}
}


auto state Pickup
{
    function bool ReadyToPickup(float MaxWait)
    {
        return true;
    }

    /* ValidTouch()
     Validate touch (if valid return true to let other pick me up and trigger event).
    */
    function bool ValidTouch( actor Other )
    {
        // make sure its a live player
        if ( (Pawn(Other) == None) || !Pawn(Other).bCanPickupInventory || (Pawn(Other).Health <= 0) || (Pawn(Other).DrivenVehicle == None && Pawn(Other).Controller == None))
            return false;

        if( ROPawn(Other) != none && ROPawn(Other).AutoTraceActor != none && ROPawn(Other).AutoTraceActor == self )
        {
            // do nothing
        }
        // make sure not touching through wall
        else if ( !FastTrace(Other.Location, Location) )
            return false;

        // make sure game will let player pick me up
        if( Level.Game.PickupQuery(Pawn(Other), self) )
        {
            TriggerEvent(Event, self, Pawn(Other));
            return true;
        }
        return false;
    }

    // When touched by an actor.
    function Touch( actor Other )
    {
    }

    function CheckTouching()
    {
    }

    function UsedBy( Pawn user )
    {
        local Inventory Copy;
        local inventory Inv;
        local bool bHasWeapon;

        if( user == none )
            return;

           // check if Other has a primary weapon
        if( user != none && user.Inventory != none )
        {
            for ( Inv=user.Inventory; Inv!=None; Inv=Inv.Inventory )
            {
                if ( Inv != none && Weapon(Inv) != None )
                {
                    if( Inv.class == WeaponType)
                    {
                        if( Weapon(Inv).AmmoMaxed(0) )
                            return;
                        else
                            bHasWeapon = true;
                    }
                }
            }
        }

        // valid touch will pickup the object
        if( ValidTouch( user ) )
        {
            if( bHasWeapon )
                Copy = SpawnCopy(user);
            else
                Copy = SpawnWeaponCopy(user);

            AnnouncePickup(user);
            if ( Copy != None )
                Copy.PickupFunction(user);

            //if (bActive)
            //SetRespawn();
        }
    }

    function Timer()
    {
        if (bDropped)
        {
            GotoState('FadeOut');
            //SetRespawn();
        }
    }

    function BeginState()
    {
        UntriggerEvent(Event, self, None);
        if ( bDropped )
        {
            AddToNavigation();
            SetTimer(DropLifeTime, false);
        }
    }

    function EndState()
    {
        if ( bDropped )
            RemoveFromNavigation();
    }

Begin:
    CheckTouching();
}

//
// Set up respawn waiting if desired.
//
function SetRespawn()
{
    //if (bActive)
    StartSleeping();

}

function inventory SpawnWeaponCopy( pawn Other )
{
    local inventory Copy;

    if ( Inventory != None )
    {
        Copy = Inventory;
        Inventory = None;
    }
    else
        Copy = Other.spawn(WeaponType,Other,,,rot(0,0,0));

    Copy.GiveTo( Other, self );

    return Copy;
}

function Reset()
{
    if( !bUsesSpawnAreas )
        Activate();
}

event Trigger( Actor Other, Pawn EventInstigator )
{
}



defaultproperties
{
    InventoryType=class'PanzerFaustAmmoEH'//class'PanzerFaustWeapon'
    WeaponType=class'PanzerFaustWeaponEH'

    PickupMessage="You got the Panzerfaust."
    TouchMessage="Pick Up: Panzerfaust"
    PickupSound=Sound'Inf_Weapons_Foley.WeaponPickup'
    PickupForce="AssaultRiflePickup"  // jdf

    bAmmoPickupIsWeapon=true

    MaxDesireability=+0.78

    StaticMesh=StaticMesh'WeaponPickupSM.Weapons.Panzerfaust'
    RespawnTime=3.000000
    AmmoAmount = 1
    DrawType=DT_StaticMesh
    DrawScale=1.0
    AmbientGlow=10
    bDestroyPickupWhenInactive=True
    TeamNum=NEUTRAL
    PickupRespawnLimit=255

    CollisionRadius=25.0
    CollisionHeight=3.0
    PrePivot=(X=0.0,Y=0.0,Z=3.0)

}
 
just thinking aloud;

aren't AmmoVolumes linked to spawns as well?

hrm.

-------

The work around of course would be to put the pickup someplace inaccessible (say a hollow ammo crate), stick a mover on top of it that is activated when teh objective you desire is capped. .. of course that only works one way I suppose. (so you can't cover up a Faust pickup in the axis units fall back to a spawn or something..) or maybe you could.. hrm.. ..
 
Upvote 0
I wonder if I could potentially create a monster by extending the pickup from a resupply volume but somehow override all of the volume code in the child class while replacing it with pickup stuff? Could I be mad?

Yes.

The 'i used to program for a living' person in me wants to pimp slap you :]

I was just pointing another thing in your direction that may or may not help out.
 
Upvote 0
Yeah, sorry it was late and I was delirious.
So delirious.

I should have deleted that response when I came to the realization that it wouldn't work, so as to hide my shame. Oh well.

In any case, I wish to keep the Panzerfausts as Panzerfaust pickups as opposed to volumes. On the other hand, a thought that just jumped in to my head would be to have a mix of singular Panzerfaust spawns and Panzerfaust caches with long reload times (the issue here is if a bunch of players come up to it they would all get Panzerfausts, and hence it could become problematic).

jsah;hkjfahj
 
Upvote 0
Alright alright, so how about this:

I make an EHPanzerfaustResupplyVolume that would extend from the existing ROAmmoResupplyVolume (so as to be included in the Activate/Deactivate check done by ROTeamGame). However, modifications to this volume would include that:

To be resupplied one must be inside of the volume and press their Use key: this will tell the volume that the player is requesting a Panzerfaust. However, the volume will only resupply one Panzerfaust at a time to a player as opposed to all ammunition (which would in this case be two Panzerfausts). Following the resupply of one Panzerfaust, the timer kicks in. Furthermore, one can probably make the said volumes team specific in their usage, denying them to Russian players. And of course, once a cache is lost, players are left to scavenge for the singular spawns of Panzerfausts.

Does that sound like a reasonable solution?
 
Upvote 0
Alright alright, so how about this:

I make an EHPanzerfaustResupplyVolume that would extend from the existing ROAmmoResupplyVolume (so as to be included in the Activate/Deactivate check done by ROTeamGame). However, modifications to this volume would include that:

To be resupplied one must be inside of the volume and press their Use key: this will tell the volume that the player is requesting a Panzerfaust. However, the volume will only resupply one Panzerfaust at a time to a player as opposed to all ammunition (which would in this case be two Panzerfausts). Following the resupply of one Panzerfaust, the timer kicks in. Furthermore, one can probably make the said volumes team specific in their usage, denying them to Russian players. And of course, once a cache is lost, players are left to scavenge for the singular spawns of Panzerfausts.

Does that sound like a reasonable solution?

Actually that does sound like a pretty reasonable/feasible idea.

As for team specific/spawn linking, the ROAmmo Volumes, iirc, can already do all of that.

I think you're hardest issue now is how to indicate to the player that there is, or is not, a panzer faust available for pickup..
 
Upvote 0