Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

Mutator that adds custom weapon to existing UT3 maps

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mutator that adds custom weapon to existing UT3 maps

    Hi

    Can anyone help me here, I am stuck? I want to create a mutator that adds my custom weapon pickup factory to existing UT3 maps like Arsenal or Biohazard. This is what I want to do.

    Change this mutator file code below UTMutator_Ripper to add the Ripper weapon instead of replace with other weapon pickup factory:

    Code:
    class UTMutator_Ripper extends UTMutator;
    
    struct ReplacementInfo
    {
    	/** class name of the weapon we want to get rid of */
    	var name OldClassName;
    	/** fully qualified path of the class to replace it with */
    	var string NewClassPath;
    };
    
    var array<ReplacementInfo> WeaponsToReplace;
    var array<ReplacementInfo> AmmoToReplace;
    
    function PostBeginPlay()
    {
    	local UTGame Game;
    	local int i, Index;
    
    	Super.PostBeginPlay();
    
    	// replace default weapons
    	Game = UTGame(WorldInfo.Game);
    	if (Game != None)
    	{
    		for (i = 0; i < Game.DefaultInventory.length; i++)
    		{
    			if (Game.DefaultInventory[i] != None)
    			{
    				Index = WeaponsToReplace.Find('OldClassName', Game.DefaultInventory[i].Name);
    				if (Index != INDEX_NONE)
    				{
    					if (WeaponsToReplace[Index].NewClassPath == "")
    					{
    						// replace with nothing
    						Game.DefaultInventory.Remove(i, 1);
    						i--;
    					}
    					Game.DefaultInventory[i] = class<UTWeapon>(DynamicLoadObject(WeaponsToReplace[Index].NewClassPath, class'Class'));
    				}
    			}
    		}
    
    		if (Game.TranslocatorClass != None)
    		{
    			Index = WeaponsToReplace.Find('OldClassName', Game.TranslocatorClass.Name);
    			if (Index != INDEX_NONE)
    			{
    				if (WeaponsToReplace[Index].NewClassPath == "")
    				{
    					// replace with nothing
    					Game.TranslocatorClass = None;
    				}
    				else
    				{
    					Game.TranslocatorClass = class<UTWeapon>(DynamicLoadObject(WeaponsToReplace[Index].NewClassPath, class'Class'));
    				}
    			}
    		}
    	}
    }
    
    function bool CheckReplacement(Actor Other)
    {
    	local UTWeaponPickupFactory WeaponPickup;
    	local UTWeaponLocker Locker;
    	local UTAmmoPickupFactory AmmoPickup, NewAmmo;
    	local int i, Index;
    	local class<UTAmmoPickupFactory> NewAmmoClass;
    
    	WeaponPickup = UTWeaponPickupFactory(Other);
    	if (WeaponPickup != None)
    	{
    		if (WeaponPickup.WeaponPickupClass != None)
    		{
    			Index = WeaponsToReplace.Find('OldClassName', WeaponPickup.WeaponPickupClass.Name);
    			if (Index != INDEX_NONE)
    			{
    				if (WeaponsToReplace[Index].NewClassPath == "")
    				{
    					// replace with nothing
    					return false;
    				}
    				WeaponPickup.WeaponPickupClass = class<UTWeapon>(DynamicLoadObject(WeaponsToReplace[Index].NewClassPath, class'Class'));
    				WeaponPickup.InitializePickup();
    			}
    		}
    	}
    	else
    	{
    		Locker = UTWeaponLocker(Other);
    		if (Locker != None)
    		{
    			for (i = 0; i < Locker.Weapons.length; i++)
    			{
    				if (Locker.Weapons[i].WeaponClass != None)
    				{
    					Index = WeaponsToReplace.Find('OldClassName', Locker.Weapons[i].WeaponClass.Name);
    					if (Index != INDEX_NONE)
    					{
    						if (WeaponsToReplace[Index].NewClassPath == "")
    						{
    							// replace with nothing
    							Locker.ReplaceWeapon(i, None);
    						}
    						else
    						{
    							Locker.ReplaceWeapon(i, class<UTWeapon>(DynamicLoadObject(WeaponsToReplace[Index].NewClassPath, class'Class')));
    						}
    					}
    				}
    			}
    		}
    		else
    		{
    			AmmoPickup = UTAmmoPickupFactory(Other);
    			if (AmmoPickup != None)
    			{
    				Index = AmmoToReplace.Find('OldClassName', AmmoPickup.Class.Name);
    				if (Index != INDEX_NONE)
    				{
    					if (AmmoToReplace[Index].NewClassPath == "")
    					{
    						// replace with nothing
    						return false;
    					}
    					NewAmmoClass = class<UTAmmoPickupFactory>(DynamicLoadObject(AmmoToReplace[Index].NewClassPath, class'Class'));
    					if (NewAmmoClass == None)
    					{
    						// replace with nothing
    						return false;
    					}
    					else if (NewAmmoClass.default.bStatic || NewAmmoClass.default.bNoDelete)
    					{
    						// transform the current ammo into the desired class
    						AmmoPickup.TransformAmmoType(NewAmmoClass);
    						return true;
    					}
    					else
    					{
    						// spawn the new ammo, link it to the old, then disable the old one
    						NewAmmo = AmmoPickup.Spawn(NewAmmoClass);
    						NewAmmo.OriginalFactory = AmmoPickup;
    						AmmoPickup.ReplacementFactory = NewAmmo;
    						return false;
    					}
    				}
    			}
    		}
    	}
    
    	return true;
    }
    
    defaultproperties
    {
       WeaponsToReplace(0)=(OldClassName="UTWeap_FlakCannon",NewClassPath="Ripper.UTWeap_Ripper")
       AmmoToReplace(0)=(OldClassName="UTAmmo_FlakCannon",NewClassPath="Ripper.UTAmmo_Ripper")
       GroupNames(0)="RIPPERMOD"
       Components(0)=Sprite
       Name="Default__UTMutator_Ripper"
       ObjectArchetype=UTMutator'UTGame.Default__UTMutator'
    }

  • replied
    Originally posted by RattleSN4K3 View Post

    The intention of this thread was to implement a mutator to add ammo, right? Instead of copying the files, also rename these. "XAmmoAddLocationInfo.uc" to something like "MyMutatorAmmoLocationInfo.exe" etc. Search and replace the classes in the source code.
    Correct! And add a weapon as well. Okay I think I get what you mean. I wasn't going to change or rename anything anyway. Can I give it to my friends as is for them to use when playing?

    Leave a comment:


  • replied
    Originally posted by UTCollector88 View Post
    I also forgot to mention that there is a problem with the XMutatorAmmoAdd Loader button function in the editor. It comes up with an error failed to load or retrieve materials when I use that button to call the stored ammo location in the same map. Don't know if you already know this.
    It happened on my side. But I don't think it is related to this mutator. The basic mutator references the Pickups packages which then gets loaded. Probably related to that.

    Originally posted by UTCollector88 View Post
    Should I uninstall /remove the previous ammo mutator example you did?
    Remove/overwrite yes.

    Originally posted by UTCollector88 View Post
    Not sure what you mean by renaming classes?
    The intention of this thread was to implement a mutator to add ammo, right? Instead of copying the files, also rename these. "XAmmoAddLocationInfo.uc" to something like "MyMutatorAmmoLocationInfo.exe" etc. Search and replace the classes in the source code.

    Leave a comment:


  • replied
    Originally posted by RattleSN4K3 View Post
    The shipped mutator XMutatorAmmoAdd_REV2_PC.zip works out of the box now. It can be seen with opening a Instant action game, select DM-Deck and add the mutator "Test Ammo-Add-Mutator". A ShockRifle and Flak ammo pickup should be created on the bridge in Deck (near Stinger).

    Only at the end, I polished the code and removed a passed parameter in the restore function (which is used in the weapon code). With that change, I missed using the right class to spawn custom pickups . Therefore the engine tries to spawn an abstract class (and non-spawnable one) which isn't working. I made some changes, which now fully works in edito, in-game, local and network sessions.
    Okay, I will try the Test Ammo Add Mutator. Should I uninstall /remove the previous ammo mutator example you did?



    Originally posted by RattleSN4K3 View Post
    Do not create a mutator package with the same name... also preferably, renaming classes.
    Not sure what you mean by renaming classes?

    Leave a comment:


  • replied
    Originally posted by RattleSN4K3 View Post
    What 2nd method?

    Looks like it is not loading. Strange. Gonna check it real quick and fix it.

    Second method is using the UI not the play in editor. I also forgot to mention that there is a problem with the XMutatorAmmoAdd Loader button function in the editor. It comes up with an error failed to load or retrieve materials when I use that button to call the stored ammo location in the same map. Don't know if you already know this.

    Leave a comment:


  • replied
    The shipped mutator XMutatorAmmoAdd_REV2_PC.zip works out of the box now. It can be seen with opening a Instant action game, select DM-Deck and add the mutator "Test Ammo-Add-Mutator". A ShockRifle and Flak ammo pickup should be created on the bridge in Deck (near Stinger).

    Only at the end, I polished the code and removed a passed parameter in the restore function (which is used in the weapon code). With that change, I missed using the right class to spawn custom pickups . Therefore the engine tries to spawn an abstract class (and non-spawnable one) which isn't working. I made some changes, which now fully works in edito, in-game, local and network sessions.


    Keep in mind: This mutator should be an example mutator. Do not create a mutator package with the same name... also preferably, renaming classes.

    Leave a comment:


  • replied
    What 2nd method?

    Looks like it is not loading. Strange. Gonna check it real quick and fix it.

    Leave a comment:


  • replied
    I tested it using the second method and it doesn't seem to work in game.

    Leave a comment:


  • replied
    Thanks RattleSN4K3

    Sorry for the late reply. I have downloaded the source code. Will have a look at it later and test it. Cheers!

    Leave a comment:


  • replied
    thanks you

    Leave a comment:


  • replied
    Late reply. But here we go. i just uploaded the working code for storing and restoring ammo pickups. It works similar to weapon factories. You create the factories in the level editor and select an ammo type. Save the profile with the toolbar button (in case of the editor script is installed) or the PIE mutator. Check the source code here:
    https://github.com/RattleSN4K3/UT3-S...r-Ammos-AddNew

    Leave a comment:


  • replied
    Yep. And also, as I wrote down my initial idea, I ran into problems regarding "transforming ammo factories". Which is working but the native transforming code somehow manipulates the original ammo factorty in a way that it won't work after the item is picked up once. This is strange but I already found the origin of that problem, a material gets applied which seems like is not working for these non-static factories. I ran several tests to notice that (with debugging).

    Leave a comment:


  • replied
    Oh, I think I see what you mean. That is why in the editor all the ammo pickups are under the UTAmmoPickupFactory class and the UTAmmoPickupFactory must transform into the ammo you select to place into the map. Which is totally different to how the UTWeaponPickupFactory works. Should of though of that earlier.

    Leave a comment:


  • replied
    Looking good so far. But that's the easiest part of it . The important part would be how to store and restore ammo classes. A weapon factory has set the Weapon to spawn in its properties. A ammo factory doesn't have such property. A ammo factor is a single class for each specific ammo item. It wouldn't work the same way. The ammo mutator is actually more complex than this. Not sure if you will get that far; let me have a look on how to implement that mutator (I actually had it in mind previously, it's just a matter of writing it down and testing, testing and testing ).

    Leave a comment:


  • replied
    This is what I have done so far.

    Created file XAmmoAddFactory.uc with content below:

    Code:
    /** 
     * Basic ammo factory to spawn in the level on runtime
     */
     
     class XAmmoAddFactory extends UTAmmoPickupFactory;
     
     DefaultProperties
    {
    	// allow dynamic spawn
        bStatic=false
        bNoDelete=false
    
    	// allow basing on moveable actors (such as lifts)
    	bMovable=true
    
        AmmoPickupClass=class'UTAmmo_ShockRifle'
    
    	// replicate initial rotation
    	bNetInitialRotation=true
    	bNeverReplicateRotation=false // just set is for safety
    
    	// replicate all other props (not only the 'hidden' flag)
    	bOnlyReplicateHidden=false
    }
    Created file XAmmoAddMutator.uc with content below:

    Code:
    /**
     * Mutator to initialize the map profile containing the locations 
     * for the new ammo factories
     */
     
     class XAmmoAddMutator extends UTMutator;
     
    var class<PickupFactory> AmmoFactoryClass;
    
    function PostBeginPlay()
    {
        super.PostBeginPlay();
    	LoadAmmo();
    }
    
    function LoadAmmo(optional string ProfileName = "")
    {
    	local XAmmoAddLocationInfo LocInfo;
    	if (class'XAmmoAddLocationInfo'.static.Exists(LocInfo, ProfileName))
    	{
    		LocInfo.RestoreFactories(AmmoFactoryClass);
    	}
    }
    
    Defaultproperties
    {
    	AmmoFactoryClass=class'XAmmoAddFactory'
    }

    How am I going so far?

    Leave a comment:

Working...
X