[Logo]
 
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
AbilityMaxMines  XML
Forum Index -> Druids RPG
Author Message
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

With the help of Szlat, I finished an ability to increase the number of mines that can be deployed.
It works with the deployablefun mod.

Code:
 class AbilityMaxMines extends RPGAbility
 	config(UT2004RPG) 
 	abstract;
 
 var config int RequiredLevel;
 var config int MinesPerLevel;
 var config int MinimumMines;
 
 static simulated function int Cost(RPGPlayerDataObject Data, int CurrentLevel)
 {
 	local int x;
 	local bool ok;
 
 	for (x = 0; x < Data.Abilities.length && !ok; x++)
 		if (Data.Abilities[x] == class'ClassWeaponsMaster')
 			ok = true;
 	if(!ok)
 	{
 		if(CurrentLevel > 0)
 			log("Warning:"@data.Name@"has"@default.class@"Level"@CurrentLevel@"but does not have an associated Class to allow them to purchase it");
 		return 0;
 	}
 	
 	if(Data.Level < (default.RequiredLevel + CurrentLevel))
 		return 0;
 
 	return Super.Cost(Data, CurrentLevel);
 }
 
 static simulated function ModifyWeapon(Weapon W, int AbilityLevel)
 {
     if( !W.GetFireMode(0).IsA('ONSMineThrowFire') )
         return;  // Weapon is not a MineLayer
     
     if (RPGWeapon(W)!=None)
         ONSMineLayer(RPGWeapon(W).ModifiedWeapon).MaxMines = (
             default.MinimumMines + default.MinesPerLevel * AbilityLevel );
     
     // Don't know what would lead to this:
     else
         ONSMineLayer(W).MaxMines = (
             default.MinimumMines + default.MinesPerLevel * AbilityLevel );
     
 }
 
 defaultproperties
 {
      RequiredLevel=50
      MinesPerLevel=1
      MinimumMines=2
      AbilityName="Maximum Mines"
      Description="Increases the number of mines that can be deployed by 1 per level. You must be a Weapons Master to purchase this skill.|You must be level 50 to purchase the first level of this ability.(Max Level: 6)| Cost : 5, 10, 15, 20, 25, 30."
      StartingCost=5
      CostAddPerLevel=5
      MaxLevel=6
 }
 

Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

I think on DC, the max number of mines changes based upon the gametype. So in invasion it is 2, but I think in onslaught it might still be 8.

I am not sure how this happens - perhaps deployablefun only runs on invasion gametypes?

So, on non-invasion games, your ability will reduce the number of mines, rather than increasing?
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

Ok, I can think of a couple of ways to deal with this.
1: Add a test for available gametypes.
2: Base the minimum mines on the map default (I think the mutator changes the map default.)
3: #2 + add a cap to the maximum regardless of level.

I will try and add all of these, and make it configurable so server admins can decide how they want to configure them.
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

greg11 wrote:
2: Base the minimum mines on the map default (I think the mutator changes the map default.) 
Not sure it does. I suspect it will use CheckReplacement to update individual minelayer MaxMines.

greg11 wrote:
1: Add a test for available gametypes. 
If you did that, you could have a minimum set for each gametype, and so set MaxMines accordingly.

greg11 wrote:
I will try and add all of these, and make it configurable so server admins can decide how they want to configure them. 
Still have the problem of how to replicate the MaxMines to the client so it knows how many to draw. Mind you, the deployablefun doesn't do that, so you might be able to get away without.
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

Update:
Code:
class AbilityMaxMines extends RPGAbility
 	config(UT2004RPG) 
 	abstract;
 
 var config int RequiredLevel;
 var config int MinesPerLevel;
 var config int MinimumMines;
 var config bool bReqDeployableFun;
 
 static function int Cost(RPGPlayerDataObject Data, int CurrentLevel)
 {
 	local int x;
 	local bool ok;
 
 	for (x = 0; x < Data.Abilities.length && !ok; x++)
 		if (Data.Abilities[x] == class'ClassWeaponsMaster')
 			ok = true;
 	if(!ok)
 	{
 		if(CurrentLevel > 0)
 			log("Warning:"@data.Name@"has"@default.class@"Level"@CurrentLevel@"but does not have an associated Class to allow them to purchase it");
 		return 0;
 	}
 	
 	if(Data.Level < (default.RequiredLevel + CurrentLevel))
 		return 0;
 
 	return Super.Cost(Data, CurrentLevel);
 }
 
 static simulated function ModifyWeapon(Weapon W, int AbilityLevel)
 {
 	local Mutator m;
     local int MaxMines;
     local bool bDepFunFound;
     
     if( !W.GetFireMode(0).IsA('ONSMineThrowFire') )
         return;  // Weapon is not a MineLayer
 
     /*
     if( W.Level.getgameclass() != class'SkaarjPack.Invasion')
         return;
     */
     
     bDepFunFound=False;
             
 // Determine if deployable fun is loaded
     if (W.level.Game != None)   //TODO: W.level.Game doesn't exist on client
         {
         for ( m = W.Level.Game.BaseMutator; m != None; m = m.NextMutator )
             if (m.IsA('DeployableFun'))
                 {
                     bDepFunFound=True;
                     break;
                 }
         }
 
     if ( bDepFunFound )
         MaxMines = default.MinimumMines + default.MinesPerLevel * AbilityLevel;
     else
     {
         // If deployable fun is required, exit
         if( default.bReqDeployableFun )
             return;
 
         // Since deployablefun is not loaded, use hardcoded default maxmines
         MaxMines = 8 + default.MinesPerLevel * AbilityLevel;
     }
  
  // set new maxmines
     if ( RPGWeapon(W)!=None )
         ONSMineLayer(RPGWeapon(W).ModifiedWeapon).MaxMines = MaxMines;
     
     // Don't know what would lead to this:
     /*
     else
         if (ONSMineLayer(W)!=None)
             ONSMineLayer(W).MaxMines = (
                 default.MinimumMines + default.MinesPerLevel * AbilityLevel );
     */
 }
 
 defaultproperties
 {
      RequiredLevel=50
      MinesPerLevel=1
      MinimumMines=2
      AbilityName="Maximum Mines"
      Description="Increases the number of mines that can be deployed by 1 per level. You must be a Weapons Master to purchase this skill.|You must be level 50 to purchase the first level of this ability.(Max Level: 6)| Cost : 5, 10, 15, 20, 25, 30."
      StartingCost=5
      CostAddPerLevel=5
      MaxLevel=6
      bReqDeployableFun=True
 }
 


Added a check for deployablefun mutator.


Szlat wrote:
Still have the problem of how to replicate the MaxMines to the client so it knows how many to draw. Mind you, the deployablefun doesn't do that, so you might be able to get away without. 

The replication was working for me until this change. I found out that W.Level.Game doesn't exist on the client, so the client figures that deployablefun is not loaded, and will draw the wrong number of undeployed mines (the transparent ones), but this doesn't seem to affect the gameplay.

The issue with object.Level.Game exists in DruidLoaded.ModifyPawn also:
Code:
 for (m = Other.Level.Game.BaseMutator; m != None; m = m.NextMutator)
 		if (MutUT2004RPG(m) != None)
 		{
 			RPGMut = MutUT2004RPG(m);
 			break;
 		}
 

This resulted in a bunch of accessed none warnings on the client
Code:
 Warning: DruidLoaded None (Function DruidsRPG200.DruidLoaded.ModifyPawn:001E) Accessed None 'Game'
 Warning: DruidLoaded None (Function DruidsRPG200.DruidLoaded.GiveWeapon:0043) Accessed None 'Game'
 Warning: DruidLoaded None (Function DruidsRPG200.DruidLoaded.GiveWeapon:004B) Accessed None
 Warning: Failed to load 'NULL': Can't resolve package name
 Warning: Failed to load 'Class None.': Can't resolve package name
 

Also I noticed that the functions in DruidLoaded are not simulated, but RPGAbility prototypes them as simulated, so it looks like they are still called on the client.
Assuming that the client doesn't need to run this function, it looks like you need to add:
Code:
 if (Other.level.Game != None)
  return;
 


EDIT: Nevermind, I see this was already addressed in 2.21

I still need to find a way for the client to determine what mutators are active though.
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

Yeh, the DruidLoaded.ModifyPawn has changed a bit over time.

The ModifyPawn is called both client and server side because it is a static function. These execute within the context of a class, and have no replication context as such. It depends on the object that called the static function as to where it is executed.

Nothing is ever as simple as you would like it to be, and replicating values between the server and the client is one of the trickiest bits.
Since the deployable fun doesn't worry about reducing the clientside number of mines, and people on DC are used to seeing 8 transparent mines even though it might only be possible to use 2, I would ignore the clientside aspects of it for now. Just stick with updating the mines serverside.

Mutators are by default not replicated to the clientside. It requires quite a bit of code, which I expect the deployablefun mutator not to include. So I doubt very much if you can detect it, without generating your own list of mutators serverside and passing to the client.

I don't particularly like magic numbers like 8. What would
class'ONSMineLayer'.default.MaxMines
give?

I am not sure what you can use the bReqDeployableFun variable for. For DC it is required for invasion, but not for other gametypes - which value would you set it to? With the values set as in the code, on games without Deployablefun, the ability would do nothing.
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

Szlat wrote:

I don't particularly like magic numbers like 8. What would
class'ONSMineLayer'.default.MaxMines
give?
 

That works, I will use that instead of hardcoding.


I am not sure what you can use the bReqDeployableFun variable for. For DC it is required for invasion, but not for other gametypes - which value would you set it to? With the values set as in the code, on games without Deployablefun, the ability would do nothing. 


It only makes a difference if DeployableFun is not loaded.
if bReqDeployableFun is set to true, and DeployableFun is not loaded, then the ability does not add anymore mines. The maximum mines will always be 8 regardless of level.

if it is false and DeployableFun isn't loaded, then the ability still adds mines. So a player with this skill maxed out could have 14 mines.

the W.Level.getgameclass() does work on both the server and the client. I could just use an allowablegametypes array instead of checking for the mutator. This should fix the replication, and offer more flexibility in case deployablefun is replaced.
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

greg11 wrote:

Szlat wrote:
I am not sure what you can use the bReqDeployableFun variable for. For DC it is required for invasion, but not for other gametypes - which value would you set it to? With the values set as in the code, on games without Deployablefun, the ability would do nothing. 
It only makes a difference if DeployableFun is not loaded.
if bReqDeployableFun is set to true, and DeployableFun is not loaded, then the ability does not add anymore mines. The maximum mines will always be 8 regardless of level. 
On a site, bReqDeployableFun can only have one value.
If on DC it is set to True, (DC tries to run with defaults) then the amount of mines will be
2+level if the deployablefun mutator is present (invasion)
8 if the mutator isnt present. (other games)
So, the ability will do nothing on non-invasion gametypes. Is that what you want?
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

I removed the check for deployablefun, and did a test for the gametype instead. This allows the mines to be drawn on the client end.
What is the class name for vehicle invasion?

The bReqDeployableFun was more for flexibility.
I would imagine that Dru would want to limit the mines to 8 on other gametypes, but I can see other servers wanting to permit this.

I think I can get the client to determine if deployablefun is loaded. If so, which would be the more appropriate way to go about this? Doing a gametype check or checking for deployablefun?

Even if Dru doesn't use this, it has been an interesting exercise for me.
 Filename AbilityMaxMines.zip [Disk] Download
 Description AbilityMaxMines source (modified 3Dec09)
 Filesize 1 Kbytes
 Downloaded:  219 time(s)

Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

greg11 wrote:
What is the class name for vehicle invasion? 
I think it is 'VehicleInvasion-116.VehicleInvasion' but I might be wrong.

greg11 wrote:
I would imagine that Dru would want to limit the mines to 8 on other gametypes, but I can see other servers wanting to permit this. 
Agreed.

greg11 wrote:
I think I can get the client to determine if deployablefun is loaded. If so, which would be the more appropriate way to go about this? Doing a gametype check or checking for deployablefun? 
One thing to remember is the list of gametypes AllowedGameType is configured serverside, and is not replicated to the client. So your client will not know which gametypes it is to work with. But I am not sure you can detect the deployablefun clientside either, but I may be wrong.

greg11 wrote:
Even if Dru doesn't use this, it has been an interesting exercise for me. 
It's amazing how difficult even a simple idea can get
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

Szlat wrote:
I think it is 'VehicleInvasion-116.VehicleInvasion' but I might be wrong. 


I could set it up to just look for Invasion and VehicleInvasion.

Szlat wrote:
One thing to remember is the list of gametypes AllowedGameType is configured serverside, and is not replicated to the client. So your client will not know which gametypes it is to work with. But I am not sure you can detect the deployablefun clientside either, but I may be wrong.
 

I have found some info about testing for mutators clientside on epic's forums. The clients get a list of mutators enabled on the serverinfo page. The question is will I be able to access that list from the modifyweapon function.

Currently I am running a dedicated server from the same machine as the client. I guess the client is getting a the info from the local config file.
I will try and get a dedicated server running on a remote machine later.
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

greg11 wrote:
Currently I am running a dedicated server from the same machine as the client. I guess the client is getting a the info from the local config file.
I will try and get a dedicated server running on a remote machine later. 
Yeh, its a right pain trying to sort the replication stuff. But basically, if it is a config variable it comes from the local ini file.
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

Greg11, is this now finished? Or are you still investigating client side issues?
greg11

Wicked Sick!

Joined: 02/10/2008 20:00:40
Messages: 526
Location: Hood River, OR
Offline

It can wait till the next version, go ahead and submit your stuff.
I am still working on installing a test server on a different machine so I can make sure the replication will work the same on the dc server.

Also, I have a question. What will happen if I toss a minelayer to another player? Will they get the added mines? It is tough to test this with bots.
If so, would this be a bug or a feature?
Szlat

Wicked Sick!

Joined: 05/18/2005 18:32:41
Messages: 2124
Location: UK
Offline

greg11 wrote:
Also, I have a question. What will happen if I toss a minelayer to another player? Will they get the added mines? It is tough to test this with bots.
If so, would this be a bug or a feature? 
Bug.
 
Forum Index -> Druids RPG
Go to: