• 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 Buy modified weapon

Sorry but it looks like the .zip is empty. It has a file length of 0 bytes.

Edit:
Okay I have found out something interresting: I tried to run the Fleshpound Chaingunner Mutator (not whitelisted) and the ammo costs 0! Looks like that is a general problem with non whitelisted mutators.

How did you get yours working?
 
Last edited:
Upvote 0
ok...I attached it via the forum iface. Ugh.

A few random things that may/may not be helpful.

The following link has the ENTIRE source code for objects all the way down up the tree for base UT2004. It can be incredibly helpful to look up various things because everything in KF inherits something from these classes.
http://ericdives.com/UT2004-UnCodex/classtree.html

In Weapon classes you MUST HAVE ItemName/Description defined in default properties; Example:
ItemName="bluh"
Description="bluh"
These properties DO NOT INHERIT from parent classes. You have to have them.

In WeaponPickup classes you MUST HAVE the following defined in default properties; Example:
ItemName="bluh"
ItemShortName="bluh"
Description="bluh"
PickupMessage="bluh"
These properties DO NOT INHERIT from parent classes. You have to have them.

Compile process:
ucc make
ucc dumpint <file.u>
ucc exportcache <file.u>

Also, screenshot of the trader UI with custom stuff in there. Notice the ammo cost on the custom Flamethrower I'm holding.
 

Attachments

  • UltraMut.zip
    10.7 KB · Views: 0
  • screenshot-or-it-didnt-happen.jpg
    screenshot-or-it-didnt-happen.jpg
    65.8 KB · Views: 0
Last edited:
Upvote 0
I have some fantastic news! Doing this inside CheckReplacement...

Code:
        if ( Other.IsA('KFHumanPawn') )
    {
        KFHumanPawn(Other).RequiredEquipment[2] = "UltraMut.uFrag";
        return true;
    }

...makes my custom grenades show up in the Trader UI for other people joining my server. Hooray! Maybe there's a way to leverage a similar methodology to get around my current problem with my custom items not showing up for sale in the Trader UI for other people joining my server...
 
Upvote 0
Free ammo bug is because of this:
Code:
function ServerBuyAmmo( Class<Ammunition> AClass, bool bOnlyClip )
{
...
    Price = class<KFWeaponPickup>(KW.PickupClass).default.AmmoCost * KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetAmmoCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), KW.PickupClass); // Clip price.
...
}
Ammo price is multiplied by perk ammo price scaling even when you have no perk selected. This results the game multiply ammo price by zero (which obviously outputs in
 
Upvote 0
Marco you are right, I have looked into this method and I know which variable is None. Maybe I am able to fix it by giving the player a VereranSkillLevel in CheckReplacement.

BEEEEEES I can see on your screenshot Berserker 6. How did you do that? I can only be nothing.

EDIT: Okay prices are correct with this code: (I removed the 6 Log lines)
Code:
if (KFPlayerReplicationInfo(Other) != None)
    {
        if (KFPlayerReplicationInfo(Other).ClientVeteranSkill == None)
        {
            KFPlayerReplicationInfo(Other).ClientVeteranSkill = Class'KFVeterancyTypes';
        }
        return true;
    }
But things I buy aren't put into the inventory... time to track down that bug...

EDIT: It works! I had to replace weapons too, not only the Pickups. Do not ask my why... Maybe I find the reason in the log file.

EDIT: STRANGE... really strange, since I worked on the mutator I suffer the "Can not connect bug" described here: http://forums.tripwireinteractive.com/showthread.php?t=38803 That really sucks!

EDIT: Okay some bugs
* There are always two pickups on the same place (random weapon pickups on maps)
* Looks like the pickups are never destroyed
* Sometimes buying does not work? (that will be a long night; hello dear replication)
* Players can sell my 9mm replacement. (Urgh)
I think this is very suboptimal:
Code:
    // I need this to replace Pickups that are on the ground
    // and to make buying modified weapons working (why??).
    for (i = 0; i < MAX_REPLACE; ++i)
    {
        if (Other.Class == From[i])
        {
            Log("XXXX: Replacing [[" $ String(Other) $
                "]] which matched [[" $ String(From[i]) $
                "]] with [[" $ String(To[i]) $ "]]");
            ReplaceWith(Other, String(To[i]));
            return false;
        }
    }
 
Last edited:
Upvote 0
Check my post here for your "can't connect" bug:

http://forums.tripwireinteractive.com/showthread.php?p=559523#post559523

Ammo Cost: Yes it has to do with the veterancy info; I got around it by running this mutator with the PerkReplacement Mutator. That's the only reason I had an ammo cost and a perk in the screenshot. Save yourself the massive headache and just use non-whitelisted stuff you need to do things like this with the PerkReplacement Mutator as it takes care of the veterancy info problem without any coding required.

Update:

I'm pretty sure I now know why ReplaceWith() inside CheckReplace() is breaking some things.

KF generally adds item (from the shop for example) to player inventory in a 2-step process.

  1. The item to be added is Spawn()'d
  2. The item given to the player's pawn with GiveTo()
ReplaceWith() inside CheckReplace() can break this process because CheckReplace() is called during Step 1, before Step 2 occurs. For example:

  • An item to be added to Player pawn's inventory is Spawn()'d.
  • CheckReplace() is called to evaluate the item that just Spawn()'d in Step 1. If the item is ReplaceWith()'d, it messes up variables that GiveTo() is going to try to use in Step 2.
  • Step 2 rolls around, and GiveTo() breaks: You click the buy button in the trader UI, but nothing seems to happen.
It isn't a Replication issue, it's a logic problem- at least for this very specific process. I don't think we should be trying to replace Weapon classes in CheckReplace() at all.

Edit: I have a working solution!

Do something similar to this in your mutator:
Code:
function Timer()
{
    local KFPlayerController PC;
    local KFHumanPawn PWN;
    local Inventory ITM;

    ForEach DynamicActors(class'KFHumanPawn', PWN)
    {
        PC = KFPlayerController(PWN.Controller);
        if (PC == None)
            continue;

        //at this point, we have a valid player-controlled KFHumanPawn
        //let's check their inventory for equipment that needs to be replaced by
        //my custom equipment
        for(ITM=PWN.Inventory; ITM!=None;ITM=ITM.Inventory)
        {
            Log("########## Found an item: " $ String(ITM.Class));
            if(ITM.Class == Class'KFMod.MP7MMedicGun')
            {
                PWN.DeleteInventory(ITM);
                PWN.CreateInventory("UltraMut.uMP7MMedicGun");
            }
        }

    }
}
This was just a framework to prove that it actually did work; When Timer() fires, it scans each Player-controlled KFHumanPawn's Inventory. I intend to put an array-based comparison instead of what is there now, but that is going to be pretty easy now that I know this works.
 
Last edited:
Upvote 0
Here's my complete current code for reference. The actual Mutator class is attached outside the .zip for easy reference, but everything is inside the .zip if you want to reference something else.

This version is a million times cleaner that previous ones, and it works quite nicely; getting some actual sleep did wonders for my productivity ;)

Still haven't figured out how to replace the trader list (for network clients), but I may not want to since it is going to break perk price discounts.

This code works quite dandy with the [Perk Selector 1011 (Replacement)] Mutator for easy access to perks, which takes care of ammo prices 'n so on being free or displaying as 0.

I have learned an a**load about replication since I started on this.
 

Attachments

  • ultraMut.uc.txt
    6.7 KB · Views: 0
  • UltraMut.zip
    11.7 KB · Views: 0
Last edited:
Upvote 0
The way I did for my doom mutator:

Mutator:
Code:
function PostBeginPlay()
{
    SetTimer(0.1,False);
}
function Timer()
{
    local KFGameType KF;

    KF = KFGameType(Level.Game);
    if ( KF!=None )
    {
        if( KF.KFLRules!=None )
            KF.KFLRules.Destroy();
        KF.KFLRules = Spawn(Class'KFDoomLevelRules');
    }
}
KFDoomLevelRules:
Code:
class KFDoomLevelRules extends KFLevelRules;

defaultproperties
{
    ItemForSale(0)=Class'DoomPistolPickup'
    ItemForSale(1)=Class'DoomShotgunPickup'
    ItemForSale(2)=Class'DoomSShotgunPickup'
    ItemForSale(3)=Class'DoomChaingunPickup'
    ItemForSale(4)=Class'DoomChainsawPickup'
    ItemForSale(5)=Class'DoomRLPickup'
    ItemForSale(6)=Class'DoomPlasmaPickup'
    ItemForSale(7)=Class'DoomBFGPickup'
    ItemForSale(8)=Class'KFMod.Vest'
    ItemForSale(9)=None
    ItemForSale(10)=None
    ItemForSale(11)=None
    ItemForSale(12)=None
    ItemForSale(13)=None
    ItemForSale(14)=None
    ItemForSale(15)=None
    ItemForSale(16)=None
    ItemForSale(17)=None
    ItemForSale(18)=None
    ItemForSale(19)=None
    ItemForSale(20)=None
    ItemForSale(21)=None
    ItemForSale(22)=None
    ItemForSale(23)=None
}

This works offline/online.
 
Upvote 0