• 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/
  • Weve updated the Tripwire Privacy Notice under our Policies to be clearer about our use of customer information to come in line with the EU General Data Protection Regulation (GDPR) rules that come into force today (25th May 2018). The following are highlights of our changes:


    We've incorporated the relevant concepts from the GDPR including joining the EU and Swiss Privacy Shield framework. We've added explanations for why and how Tripwire processes customer data and the types of data that we process, as well as information about your data protection rights.



    For more information about our privacy practices, please review the new Privacy Policy found here: https://tripwireinteractive.com/#/privacy-notice

Extending ROPawn issue

LordGleedo

FNG / Fresh Meat
Jul 18, 2010
800
74
0
Bucks, England
www.theoldgitsarmy.com
Morning,

I have a custom pawn class that extends ROPawn as I want to override a couple of functions, but it's basically just a shell right now with some logging:
Code:
class FTPawn extends ROPawn;

function bool Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
	`Log(">>> DEBUG : Pawn Died", , 'FTPawn');

       super.Died(Killer, damageType, HitLocation);
}

DefaultProperties
{
}
I also have the following set in my main game class default properties to ensure my pawn class gets used:
Code:
AIPawnClass=class'TOGAFT.FTPawn'
DefaultPawnClass=class'TOGAFT.FTPawn'
This is the same way I have my game mode setup in the UDK version I did a while back.

However, my pawn class is not getting used like it does in the UDK. The gameclass is still somehow using ROPawn instead.

All my other custom classes that extend/override are being used correctly, just not my pawn class :confused:

Any thoughts?
 

Mekhazzio

FNG / Fresh Meat
Sep 21, 2011
1,104
641
0
I don't expect that those "default pawn class" settings are ever used for anything. ROPawns are never spawned by the game, and if you're extending something off of those, I doubt they'd work right anyway, because it's two steps up in the hierarchy from the ones the game uses.

The actual character objects spawned by the game are one of the ROGameContent.RO(Allied|Axis)PawnLevel(#)(Role) classes, retrieved from settings in the ROGameInfo. Do the console command "getall ROPawn class" on a live server to see an example.

If you want to change which classes get spawned, the ROGameInfo is the place to start. You might be able to just find the current instance, edit its variables at runtime, and be done with it nice and cleanly.

And yes, that means that overriding pawn behavior requires you to subclass every single one of the existing ones. All 300 of them. Just like I had to do 91 subclasses of the bullets and weapons for Antilag. Be prepared to get very familiar with the UnrealScript preprocessor :)

It's a pain in the butt and it makes your final filesize proportionally larger, so it's worth the while to try to do it in any other way possible. Your Died override is better off done in the mutator PreventDeath hook, for instance.
 

LordGleedo

FNG / Fresh Meat
Jul 18, 2010
800
74
0
Bucks, England
www.theoldgitsarmy.com
It looks like I am going to have to subclass the lot as I need to alter more than a few vars - i need to change TakeDamage amongst other things....

So if that is the case, do I need to put my version of TakeDamage into each subclass that I created?
 

Mekhazzio

FNG / Fresh Meat
Sep 21, 2011
1,104
641
0
Yep. I can post the Antilag source, if you want to see a (less in)convenient way of building the preprocessor skeleton for that, so you can let the make process handle the upkeep for you.

But there's a mutator hook for TakeDamage too: Mutator.NetDamage. It's still live in ROPawn.
 

Mekhazzio

FNG / Fresh Meat
Sep 21, 2011
1,104
641
0
A preprocessor is a system that skims and edits the code files before they're fed to the compiler. All those `ifdef lines you see sprinkled all over the stock code are preprocessor commands.

Of note in this case is that you can use the preprocessor to shortcut the class-building for you. You can leave all your code in one easy-to-maintain file and simply have the preprocessor insert it automatically into a bunch of files that are so small & simple that you can just make them once (ideally with a script or batch file) and then never have to touch them again. In short, you make the skeleton, and let the computer do the work of fleshing it out.

...because keeping up that many classes by hand is insanity.
 

LordGleedo

FNG / Fresh Meat
Jul 18, 2010
800
74
0
Bucks, England
www.theoldgitsarmy.com
Ah gotcha. So I could in theory just use `include in all my sub classes to point to my file that has the common code in?

Code:
class FTAxisPawnLevel6Assault extends ROAxisPawnLevel6Assault;

`include(FTCommonPawn.uci)

DefaultProperties
{
}
Something like that ^
 

Mekhazzio

FNG / Fresh Meat
Sep 21, 2011
1,104
641
0
That's the gist of it, yep. You could also use preprocessor macros to make sure that any variables or function calls get tailored to the file as well, or to make sure that some sections show up only in some files. It's a simple preprocessor, compared to some full-blown languages out there, but it's still capable of powerful things that can save you a lot of time and hassle.
 
Last edited:

Le0

FNG / Fresh Meat
Sep 20, 2011
638
119
0
Neuchatel, Switzerland
Yep. I can post the Antilag source, if you want to see a (less in)convenient way of building the preprocessor skeleton for that, so you can let the make process handle the upkeep for you.

But there's a mutator hook for TakeDamage too: Mutator.NetDamage. It's still live in ROPawn.
Would you mind posting your source? I'd be also interested to see how you did it.
 

LordGleedo

FNG / Fresh Meat
Jul 18, 2010
800
74
0
Bucks, England
www.theoldgitsarmy.com
Right, thought id post back in this thread as it's relevant to my current issue...

As mentioned above, I have created a bunch of classes that extend each of the games player class (AxisPawnLevel1Eng, AxisPawnLevel2Eng etc), each of which has an include so they all run some common code which works fine.

Now when in-game, when I aim down my sights and press my use key, If I am looking at a team mate that is in a certain state, I need to set a variable on that players custom pawn class (which ever one it may be).

I have done the trace code and it writes some debug info to screen:
Code:
ClientMessage("Hit: "$HitActor$"  class: "$HitActor.class.outer.name$"."$HitActor.class);
Would write out something like:
Code:
Hit: FTAxisPawnLevel1Engineer etc
How can I set a variable if the class could be one of several possible classes?

If this were c# I would have created an interface which each of my custom class inherits so I could call it with confidence...

I could of course have a rather large case statement doing IsA('FTblah...') and then just cast it, but i'm hoping there is a more quick way.

Any thoughts appreciated :)
 

LordGleedo

FNG / Fresh Meat
Jul 18, 2010
800
74
0
Bucks, England
www.theoldgitsarmy.com
Think I must be being thick here...

I have created an interface called FTPawnIntf and defined a function inside it and then added that to all my custom pawn classes.

Code:
interface FTPawnIntf;

function TestInterface();
and

Code:
class FTAxisPawnLevel6SquadLeaderW extends ROAxisPawnLevel6SquadLeaderW implements(FTPawnIntf);
If I try a compile without adding the function defined in my interface to the custom pawn class, I get the expect errors, so I know that works.

So I implement my Interface function inside the custom pawn class and it compiles without error :)

Next in my player controller class I need to test for the interface which I try and do like so:
Code:
if ( FTPawnIntf(HitActor) != none)
{
     // do stuff here....
}
and according to this tutorial, this should work:
Code:
local FTPawnIntf myIntf;

myIntf = FTPawnIntf(HitActor);

if ( myIntf != none)
{
     // do stuff here....
}
Upon compiling I get the following error:
Code:
Error, Missing opening '(' in Implements list
According to the documentation, the above should work:
http://udn.epicgames.com/Three/UnrealScriptInterfaces.html

My eyes have glazed over lol :D
 
Last edited:

Ducky

Super Moderator
May 22, 2011
6,359
237
0
Netherlands
In case of interfaces, then you need to make a reference to your interface. You will get something like:

Code:
class FTAxisPawnLevel6SquadLeaderW extends ROAxisPawnLevel6SquadLeaderW implements(FTPawnIntf);

var FTPawnIntf  [COLOR=Yellow]IntRef[/COLOR];

function BlaBlaBla(Actor HitActor)
{
    if ([COLOR=Yellow]IntRef[/COLOR](HitActor) != none)
    {
        // do stuff here....
    }
}
This line if (IntRef(HitActor) != none) is not a typo ;)
 
Last edited: