• 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 Is subclassing required to change alt-fire behavior?

Woden

Member
May 23, 2009
8
0
I'm trying to change the alt-fire behavior on the 9mm and dualies. Since both weapons use SingleALTFire as their alt-fire class, it seems like the most practical course would be to simply replace SingleALTFire (and thus not touch the weapons at all) rather than subclassing the weapons themselves to make them point to my new alt-fire class.

So my question is, is it possible to do a replacement like that, or do I just need to buckle down and subclass?
 
Replacing SingleALTFire and recompiling would mean you will no longer be able to play online, since your "base" game would be different than any other server's version (besides your own, if you have one).

I think your best bet is to subclass. Well, extend SingleAltFire, Single, SinglePickup, Dualies, and DualDeaglePickup. One to make the changes to the firing behavior, the "gun names" to reference the new fire mode, and the Pickups to reference the new "gun names" so you can grab your modified guns in game. I think the rest of the code can remain the same, since you'd be extending.

Then, you'd have to modify or create a map where your new gun is either lying around on the ground as a pickup or is somehow given to the players instead of the standard 9mm / purchaseable at the store.

It's a doozy. I'm willing to bet someone wiser than me knows of a way to alter the alt-fire through a mutator where you wouldn't have to bother with all of this, though.

Edit: http://wiki.beyondunreal.com/Legacy:Weapon_Mutator_Tutorial is almost exactly what you (and, coincidentally, I) I need.
 
Last edited:
Upvote 0
Thanks for the link, but I'd already found that one. I'm virtually certain that subclassing everything is what I'm supposed to do, but given that I could do this by overriding just one class instead of five (or more), it seems offensively wasteful.

Not to mention that if there is a way to override rather than subclass, it would mean that my mutator would be compatible with some types of other pistol-affecting mutators, which would be nice.
 
Upvote 0
Well, you might be able to write a mutator that "only" replaces SingleAltFire with a .uc of your choosing. I don't see why that wouldn't work... Since it seems like the weapon mutator in that tutorial just performs a find/replace on classes?

Edit: Not as simple as I thought. You can't directly replace a "Fire" class with the CheckReplacement function in Mutator because Fire classes are extensions of Object, not Actor. I guess you have to do it the hard way.

Edit 2: It's certainly doable, though. Took about 15 minutes to make a mutator that replaces the Deagles bullet with one doing three times as much damage and making a shotgun sound effect. I still had to modify the Pickup, Weapon, and Fire classes, though. I'm going to do a little more digging and see if there's a workaround for only modifying the Fire code.

Edit 3: Nope, can't find a way around having to make a new gun. Heck, I can't find a way to make my character spawn with the one's I've made versus havning to place it on the map... seems like GetInventoryClassOverride isn't doing its job.
 
Last edited:
Upvote 0
Well, I'm confused.

It's "easy" to get a modified fire mode in game crudely. You create a "new" gun, pickup, and fire mode. You then place the pickup on a map somewhere, and voila. This applies if you are extending a previously existing weapon only, but on the other hand the gun / pickup extensions are one line of code each (one to say "pickup my modified gun", the other to say "use this new fire mode").

However, getting a player to SPAWN with a different weapon is driving me bonkers. Here's what I've tried:

1) Having CheckReplacement check both for "Weapon" and "WeaponPickup" Actors. If it sees a Single or SinglePickup, replace with my gun / pickup. This does not work: Player still spawns with a regular Single.

2) Using GetInventoryClassOverride to check for either Single or SinglePickup and replace them with my gun (can't do both at once, but I've recompiled trying both). This does not work, either.

I see in KFHumanPawn or something similar that there are "RequiredWeapon(1)=KFMod.Single" lines for each of the "always have" weapons, but I assume(d) that a Mutator would get around this?
 
Upvote 0
What is the CheckReplacement syntax you're using, Duckie? The example looks like this:

Code:
if ( string( xWeaponBase(Other).WeaponType ) ~= "XWeapons.Minigun" )

But the XWeapons class appears to have been removed from UT 2004. Instead, Single (for example) inherits from KFWeapon, which inherits from BaseKFWeapon, which inherits from Weapon, and nowhere in that family tree is the method WeaponType, so I have no idea how to determine what type of weapon the code is looking at.
 
Upvote 0
Code:
function bool CheckReplacement(Actor Other, out byte bSuperRelevant )
{    
    if( WeaponPickup(Other) != None )
    {       
        if (string(Other.Class) ~= "KFMod.BullpupPickup")
        {
            ReplaceWith(Other, "TDMods.BOOMPickup");          
            return false;
        }
    }
return true;
}
There's one example. This is exactly how "MutMachinePistols" handles purportedly replacing all Pickups of one gun with another. I added a BullpupPickup to one of the maps right outside spawn so I could be CERTAIN a BullpupPickup, uh, spawned. It's still giving Bullpups. Even trying a "pure KF" replacement, changing "TDMods.BOOMPickup" to, say, "KFMod.ChainsawPickup" doesn't produce any results.

Alternatively,

Code:
if( KFWeapon(Other) != None )   
{     
    if (string(Other.Class) ~= "KFMod.Single")
    {
        ReplaceWith(Other, "TDMods.BOOMPistol");          
        return false;
    }
}
Trying to directly replace any example of the weapon in this manner fails. Changing KFWeapon to Weapon, or TDMods.BOOMPistol to some original KF weapon fails as well.

Either CheckReplacement is borked by something KF does, or I'm severely misunderstanding its use. I'm guessing the latter.

Edit: Oh, and I also tried replacing KFHumanPawn with a custom version that had one of my guns as "RequiredEquipment(1)". Still didn't spawn with it. I also tried goofing around with the return statements, commenting them out / changing them / etc. with no results.
 
Last edited:
Upvote 0
Hrm. Two things that might have potential (I'm not yet at the "working code" phase, so I can't test these):

DefaultWeapon sets what the starting weapon for a newly-spawned player will be. Set it in the defaultproperties of your mutator.

The class method IsA could be useful in wrangling the CheckReplacement method. The prototype is as follows:
Code:
bool IsA( name ClassName );
For example, the following might work(?):

Code:
if( WeaponPickup(Other) != None )
    {       
        if (Other.IsA('BullpupPickup'))
        {
            ReplaceWith(Other, "TDMods.BOOMPickup");          
            return false;
        }
 
Upvote 0
Things are getting stranger and stranger.

I remembered seeing a "SAS Throwing Knives" mod in the General section, so I grabbed it to see how that person got things working. They did so through ModifyPlayer(), simply gifting the player the new weapon when they spawn.

I tried adding this code to my mutator code. Surprisingly, it failed to work. Needless to say, I was pissed. So, in the spirit of troubleshooting, I've been going step-by-step and working towards my original intent. Here's what I've discovered:

1) ModifyPlayer works. If I completely toss out all of the CheckRelevance and InventoryOverride code and only try to give the player my gun, it works. Peachy. You can even give two guns at once, or a KF official weapon and my own. Works perfectly for what it is.

2) CheckReplacement appears to be "trying" to work but fails to do so and, in the process, completely invalidates the mutator. I've learned this by adding a small CheckReplacement back into my code, as follows:

Code:
function bool CheckReplacement(Actor Other, out byte bSuperRelevant )
{
    if( Weapon(Other) != None )
    {       
        if (string(Other.Class) ~= "TDMods.BOOMPistol")
        {
            ReplaceWith(Other, "KFMod.Chainsaw");
            return false;
        }
    }  
    return true;
}
The most important line here is "return false". Since I know for certain that the player is being given the BOOMPistol (through ModifyPlayer), it stands to reason that CheckReplacement should function. But wait! If I have return false in the code, my character spawns with stock equipment. If I comment it out, i.e. allowing the return true to occur, my character will spawn with the BOOMPistol as if CheckReplacement never ran.

It's quite perplexing. I can only thing of two things that could be happening. Either A)return false is the "jobs done!" state and ReplaceWith is somehow failing to replace the BOOMPistol, hence removing it entirely from my inventory and leaving me with what appears to be absolutely stock weaponry, or B)return true is "jobs done!" and ReplaceWith just isn't doing its job.

I'm going to test A) right now by giving the player another weapon that CheckReplacement doesn't touch at all. Results momentarily.

Results: return false is definitely a "jobs done!" switch. The problem is in ReplaceWith, not CheckReplacement. I know this because the Machete I gave myself in ModifyPlayer remained in my inventory while the BOOMPistol simply vanished. So, the mutator code is absolutely correct but ReplaceWith isn't replacing the weapon as intended. Hmph.
 
Last edited:
Upvote 0