Given the vehicle class provided in the previous post, it is easy to create a pickup that can change the weapon selection for the vehicle.
To provide the simplest possible example that demonstrates the concept, this example makes the weapon pickup a subclass of Actor. It would be possible to implement the pickup as a subclass of some other base class as well, if those classes had functionality you wanted to keep. The weapon will be picked up when touched by the vehicle, so I’ve placed the pickup code inside of the class’ touch() event.
The crude version looks like this:
class CrudeWeaponChangePickup extends Actor; var class<UTVehicleWeapon> weaponClass; event touch(Actor other, PrimitiveComponent otherComp, vector hitLocation, vector hitNormal) { local WeaponChangeGoliath touchVehicle; touchVehicle = WeaponChangeGoliath(other); if (touchVehicle != none) { touchVehicle.toggleWeapons[touchVehicle.toggleWeaponIndex] = weaponClass; touchVehicle.changeWeapon(0, touchVehicle.toggleWeapons[touchVehicle.toggleWeaponIndex]); destroy(); } } defaultproperties { weaponClass=class'UTVWeap_MantaGun'; Begin Object Class=SkeletalMeshComponent Name=PickupMesh ObjName=PickupMesh Archetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh' SkeletalMesh=SkeletalMesh'WP_RocketLauncher.Mesh.SK_WP_RocketLauncher_3P' ObjectArchetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh' End Object Components.Add(PickupMesh) Begin Object Class=CylinderComponent NAME=CollisionCylinder CollisionRadius=+00030.000000 CollisionHeight=+00020.000000 CollideActors=true End Object CollisionComponent=CollisionCylinder Components.Add(CollisionCylinder) bOnlyDirtyReplication=true NetUpdateFrequency=8 RemoteRole=ROLE_SimulatedProxy bHidden=false NetPriority=+1.4 bCollideActors=true bCollideWorld=true bOrientOnSlope=true bShouldBaseAtStartup=true bIgnoreEncroachers=false bIgnoreRigidBodyPawns=true bUpdateSimulatedPosition=true }
Inside the touch event, it checks if the thing it touched was the WeaponChangeGoliath presented in the earlier post by attempting a typecast. If that is not null, then the thing that was touched was a WeaponChangeGoliath. In that case, the pickup changes the currently-selected weapon in the vehicle’s toggleWeapons array to the weaponClass of this pickup. In order to make the change effective, the pickup also calls the WeaponChangeGoliath’s changeWeapon method, passing the new weapon class. Once the weapon has been changed, the pickup is used up, so it destroys itself.
In Battlezone, weapons are categorized by their type, so a “Gun” type weapon can only replace another “Gun” type weapon. To support this behavior, a modified version of the WeaponChangeGoliath and WeaponChangePickup can be used:
class WeaponChangeGoliath extends UTVehicle_Goliath_Content; var int toggleWeaponIndex; var array< name > toggleWeaponNames; var array< class<UTVehicleWeapon> > toggleWeapons; exec function toggleWeapon() { toggleWeaponIndex++; if (toggleWeaponIndex >= toggleWeapons.length) toggleWeaponIndex -= toggleWeapons.length; changeWeapon(0, toggleWeapons[toggleWeaponIndex]); } simulated function switchWeapon(byte newGroup) { local int newWeaponIndex; newWeaponIndex = newGroup-1; if (newWeaponIndex >= 0 && newWeaponIndex < toggleWeapons.length && newWeaponIndex != toggleWeaponIndex) { toggleWeaponIndex = newWeaponIndex; changeWeapon(0, toggleWeapons[newWeaponIndex]); } } function changeWeapon(int seatNum, class<UTVehicleWeapon> newGunClass) { if (seats[seatNum].gun != none) { // Might be overkill on the "stop firing" stuff here. if (seatNum == 0) stopFiringWeapon(); seats[seatNum].gun.endFire(0); seats[seatNum].gun.endFire(1); seats[seatNum].gun.forceEndFire(); seats[seatNum].gun.destroy(); } seats[seatNum].GunClass = newGunClass; seats[seatNum].Gun = UTVehicleWeapon(InvManager.CreateInventory(seats[seatNum].GunClass)); seats[seatNum].Gun.SetBase(self); if (seats[seatNum].gun != none) { seats[seatNum].gun.SeatIndex = seatNum; seats[seatNum].gun.MyVehicle = self; if (seatNum == 0) { weapon = seats[seatNum].gun; invManager.setCurrentWeapon(seats[0].gun); } } } defaultproperties { toggleWeaponIndex=0 toggleWeapons(0)=class'UTVWeap_GoliathTurret'; toggleWeapons(1)=class'UTVWeap_GoliathMachineGun'; toggleWeaponNames(0)=Cannon toggleWeaponNames(1)=Gun }
The only changes made to the WeaponChangeGoliath were to add the toggleWeaponNames array, which will store the “type” of each weapon.
class WeaponChangePickup extends Actor; var name weaponType; var class<UTVehicleWeapon> weaponClass; event touch(Actor other, PrimitiveComponent otherComp, vector hitLocation, vector hitNormal) { local int i; local WeaponChangeGoliath touchVehicle; touchVehicle = WeaponChangeGoliath(other); if (touchVehicle != none) { for (i=0;i<touchVehicle.toggleWeapons.length && i< touchVehicle.toggleWeaponNames.length;i++) { if (touchVehicle.toggleWeaponNames[i] == weaponType && touchVehicle.toggleWeapons[i] != weaponClass) { touchVehicle.toggleWeapons[i] = weaponClass; if (touchVehicle.toggleWeaponIndex == i) touchVehicle.changeWeapon(0, touchVehicle.toggleWeapons[i]); destroy(); return; } } } } defaultproperties { weaponType=Gun weaponClass=class'UTVWeap_MantaGun' Begin Object Class=SkeletalMeshComponent Name=PickupMesh ObjName=PickupMesh Archetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh' SkeletalMesh=SkeletalMesh'WP_RocketLauncher.Mesh.SK_WP_RocketLauncher_3P' ObjectArchetype=SkeletalMeshComponent'UTGame.Default__UTBeamWeapon:PickupMesh' End Object Components.Add(PickupMesh) Begin Object Class=CylinderComponent NAME=CollisionCylinder CollisionRadius=+00030.000000 CollisionHeight=+00020.000000 CollideActors=true End Object CollisionComponent=CollisionCylinder Components.Add(CollisionCylinder) bOnlyDirtyReplication=true NetUpdateFrequency=8 RemoteRole=ROLE_SimulatedProxy bHidden=false NetPriority=+1.4 bCollideActors=true bCollideWorld=true bOrientOnSlope=true bShouldBaseAtStartup=true bIgnoreEncroachers=false bIgnoreRigidBodyPawns=true bUpdateSimulatedPosition=true }
For the pickup, two changes were made. First, the addition of a weaponType variable allows us to specify what type of weapon this is. Subclasses of the WeaponChangePickup can specify a different weaponType and weaponClass in their defaultproperties block, or they could be set in UnrealEd or through other Unrealscript code.
The second change is to the logic inside of the touch event. In this version, the pickup loops through all of the weapons on the vehicle, and replaces the first one with a matching weaponType that is not already this weapon type.