Rider slots cannot be occupied if the first rider slot is already occupied

Issue #1 resolved
Colin Basnett created an issue

Steps to Reproduce

  1. Player 1 enters a vehicle and occupies the first rider slot (eg. Sherman M4A3).
  2. Player 2, a rifleman, attempts to enter the vehicle.

Results

Player 2 is unable to occupy a rider slot.

Expected Results

Player 2 occupies the first available rider slot.

Comments (9)

  1. Andrew Theel

    Yea with access to DH vehicle base classes, this will be easier to fix. Also, I wanted to speak with you in TS about the vehicle class hierarchy.

  2. Matt Hands

    I have a fix for this and use it on modified vehicles on the GG server. Problem is in vehicle class's FindEntryVehicle function and fix would be implemented in DHROTreadCraft. Will post when I've familiarised myself with this site & scripting standards.

    There is a much more minor bug where riders cannot switch positions from the 1st slot on a vehicle that has not been entered by a tanker. I have a fix in use and will post. Problem is in passenger class's TryToDrive function and fix would be implemented in DHROPassengerPawn.

  3. Matt Hands
    • changed status to open

    I don't think the original (& more serious) big has been fixed. I only see the TryToDrive fix committed in DH_ROPassengerPawn, which was a very minor issue. The original issue problem is fixed in the FindEntryVehicle function and would have to be added to DH_ROTreadCraft.

  4. Matt Hands

    This goes in DH_ROTreadCraft:

    // Matt: modified to fix RO bug where players can't get into a rider position on a driven tank if 1st rider position is already occupied
    // Original often returned MG as ClosestWeaponPawn, which infantry cannot use, so we now check player can use weapon pawn & it's available)
    function Vehicle FindEntryVehicle(Pawn P)
    {
        // Matt: changed all distances to distance squared, so we can compare to VSizeSquared (faster than VSize)
        local  float              DistSquared, ClosestDistSquared, BackupDistSquared;
        local  int                x;
        local  VehicleWeaponPawn  ClosestWeaponPawn, BackupWeaponPawn;
        local  Bot                B;
        local  Vehicle            VehicleGoal;
        local  bool               bPlayerIsTanker;
    
        // Bots know what they want
        B = Bot(P.Controller);
    
        if (B != none)
        {
            // Matt: this is what's added in ROTreadCraft, worked into main function from ROVehicle ("code to get the bots using tanks better")
            if (WeaponPawns.length != 0 && IsVehicleEmpty())
            {
                for (x = WeaponPawns.length -1; x >= 0; x--)
                {
                    if (WeaponPawns[x].Driver == none)
                    {
                        return WeaponPawns[x];
                    }
                }
            }
    
            VehicleGoal = Vehicle(B.RouteGoal);
    
            if (VehicleGoal == none)
            {
                return none;
            }
    
            if (VehicleGoal == self)
            {
                if (Driver == none)
                {
                    return self;
                }
    
                return none;
            }
    
            for (x = 0; x < WeaponPawns.length; x++)
            {
                if (VehicleGoal == WeaponPawns[x])
                {
                    if (WeaponPawns[x].Driver == none)
                    {
                        return WeaponPawns[x];
                    }
    
                    if (Driver == none)
                    {
                        return self;
                    }
    
                    return none;
                }
            }
    
            return none;
        }
    
        // Always go with driver's seat if no driver (Matt: even if player isn't tank crew, TryToDrive puts them in any available rider slot)
        if (Driver == none)
        {
            DistSquared = VSizeSquared(P.Location - (Location + (EntryPosition >> Rotation)));
    
            if (DistSquared < Square(EntryRadius))
            {
                return self;
            }
    
            for (x = 0; x < WeaponPawns.length; x++)
            {
                DistSquared = VSizeSquared(P.Location - (WeaponPawns[x].Location + (WeaponPawns[x].EntryPosition >> Rotation)));
    
                if (DistSquared < Square(WeaponPawns[x].EntryRadius))
                {
                    return self;
                }
            }
    
            return none;
        }
    
        // Matt: added to flag whether the player can be tank crew
        bPlayerIsTanker = P.IsHumanControlled() && ROPlayerReplicationInfo(P.Controller.PlayerReplicationInfo) != none && 
            ROPlayerReplicationInfo(P.Controller.PlayerReplicationInfo).RoleInfo != none && ROPlayerReplicationInfo(P.Controller.PlayerReplicationInfo).RoleInfo.bCanBeTankCrew;
    
        // Check WeaponPawns to see if we are in radius
        ClosestDistSquared = 1000000.0; // Matt: increased to 1 million as is now distance squared (equivalent to distance of 1,000 units or 16.5m)
        BackupDistSquared = 1000000.0;  // Matt: added so we can check the closest weapon pawn player could occupy, even though it may be out of range
    
        for (x = 0; x < WeaponPawns.length; x++)
        {
            // Matt: added to ignore weapon pawn if it's already occupied by another player
            if (WeaponPawns[x] == none || (WeaponPawns[x].Driver != none && WeaponPawns[x].Driver.IsHumanControlled()))
            {
                continue;
            }
    
            // Matt: added so non-tanker doesn't try to use cannon or MG, which would be unsuccessful & stop them reaching a valid rider slot
            if (!bPlayerIsTanker && WeaponPawns[x].IsA('ROVehicleWeaponPawn') && ROVehicleWeaponPawn(WeaponPawns[x]).bMustBeTankCrew)
            {
                continue;
            }
    
            DistSquared = VSizeSquared(P.Location - (WeaponPawns[x].Location + (WeaponPawns[x].EntryPosition >> Rotation)));
    
            // Matt: this weapon pawn is currently the closest one within range that the player can use
            if (DistSquared < ClosestDistSquared && DistSquared < Square(WeaponPawns[x].EntryRadius))
            {
                ClosestDistSquared = DistSquared;
                ClosestWeaponPawn = WeaponPawns[x];
            }    
            // Matt: added to record if this is closest 'backup' weapon pawn player could occupy (used below if tank in range but no weapon pawn in range)
            else if (ClosestWeaponPawn == none && DistSquared < BackupDistSquared)
            {
                BackupDistSquared = DistSquared;
                BackupWeaponPawn = WeaponPawns[x];            
            }
        }
    
        // Matt: added to replace original code below, as now we've already ensured above this is a valid weapon pawn slot
        if (ClosestWeaponPawn != none)
        {
            return ClosestWeaponPawn;
        }
    
        // Matt: added to replace original 'for' loop below, as now we've already recorded the closest 'backup' weapon pawn
        if (BackupWeaponPawn != none && VSizeSquared(P.Location - (Location + (EntryPosition >> Rotation))) < Square(EntryRadius))
        {
            return BackupWeaponPawn;
        }
    /*    
        if (ClosestWeaponPawn != none || VSizeSquared(P.Location - (Location + (EntryPosition >> Rotation))) < Square(EntryRadius))
        {
            if (ClosestWeaponPawn != none && ClosestWeaponPawn.Driver == none)
            {
                return ClosestWeaponPawn; // if closest WeaponPawn slot is open we try it
            }
            else // otherwise we try to find another open WeaponPawn slot
            {
                for (x = 0; x < WeaponPawns.length; x++)
                {
                    if (WeaponPawns[x].Driver == none)
                        return WeaponPawns[x];
                }
            }
        }
    */
        // No valid slots in range
        return none;
    }
    
  5. Log in to comment