"Long reply about how to make a NV mutator"
I'm surprised!! Somebody remembers me! Thank you OICW!
So here is it again:
NV Goggles tutorial
by Kn'Thrak (knthrak@planetunreal.com)
Coder of Urban Empires (www.planetunreal.com/urbanempires)
Introduction
First, let me tell what this tutorial (and probably all of my follwing tutorials) is and what it's not. I assume that you already know about general programming and about UScript specifically. If you don't know anything about UScript stop here and read some other tutorials first, have a look at unreal.epicgames.com or
www.planetunreal.com/chimeric. I also won't just put the whole code down here and comment on every line, as I don't think that'd be really useful for anyone. I'll only put down the stuff that helped me learning more about the actor replication in Unreal, and I hope it'll help you in the same way.
First Attempt
So, what I wanted was Nightvision goggles, in game programming terms that'd mean spawning a temporary light. What I knew by that time was that the lights in Unreal are actors just as all other objects in the game, and that all actors have a variable called bOnlyOwnerSee, which make should them invisible to all players except the owner. So I thought it's gonna be quite easy, spawn an actor that does nothing except emitting light, set it's owner to the player who has the NV and set bOnlyOwnerSee to true, and you're set. It failed. Theoretically it should've worked, but it doesn't because of the way the engine handles bOnlyOwnerSee: it only hides the model or sprite that belongs to the actor, not any light it emits. So I had to spawn the light client-sided so the other clients wouldn't ever get to know it.
How it works
By now you should take a break from this tutorial and read the Unreal Networking Architecture document (unreal.epicgames.com/Network.htm) if you don't know it yet. Read it entirely and carefully, even if it's not really necessary for understanding the tutorial, but it'll help you understanding the replication system used in the Unreal engine. Also download the mutator pack by Digital Extremes (www.digitalextremes.com) and have a look at the Team Beacon mutator code, you'll notice that my NV code is very similar to it, as it does nearly the same (the TB mutator spawns client-sided sprites that marks your team mates).
So let's get started. First we'll need the actual light actor that we'll spawn:
class NVGogglesLight expands Effects;
defaultproperties
{
LightEffect=LE_NonIncidence
LightBrightness=1000
LightRadius=100
LightSaturation=1000
LightType=LT_Steady
bHidden=true
}
The Light... variables should be clear to everyone, they make the actor emit the light. bHidden is set to true to hide the ugly 'bird-head-sprite' that actors have as standard, and it won't hide the light as we know by now. It also serves another purpose that you'll get to know later.
Note: If you have a look at the code of the released NV Goggles mutator you'll also find RemoteRole set to ROLE_SimulatedProxy. After reading the Networking Architecture document once again I think it's not really necessary as it's main purpose seems to be that 'simulated' functions of the actor are called, but this actor doesn't execute any code anyway. But as I don't have tested it without this setting yet don't rely on this, try to put it back in when it's not working.
Now we need a pickup for the player to pick up, I won't describe that in detail. I mainly copied the code of the invisibility pickup and removed the stuff that makes the models invisible, but kept the charging code so it'll wear off after about 45 seconds.
Note that the pickup itself doesn't spawn the light. I believe that it could possibly, but I've done it another way like it's done in the Team Beacon mutator. The light is called in the HUD mutator's PostRender function. It's a simulated function, so it's only executed on the client, and it's called every frame so we can also put code for the movement of the light in here.
var NVGogglesLight NVLight;
var PlayerPawn PlayerOwner;
var inventory inv;
simulated function PostRender(Canvas C)
{
PlayerOwner = PlayerPawn(Owner.Owner);
if (PlayerOwner == None)
return;
inv=PlayerOwner.FindInventoryType(class'NVGogglesInventory');
if (inv != none && inv.bActive)
{
if (NVLight==none)
NVLight=Spawn(class'NVGogglesLight', self,, Location);
else
NVLight.SetLocation(PlayerOwner.Location);
}
else if (NVLight != none)
{
NVLight.Destroy();
NVLight=none;
}
if ( NextMutator != None )
NextMutator.PostRender(C);
}
The code should be pretty self explanatory. It first checks if the player has the NV Goggles pickup and if it's activated, if so it creates the light actor if it doesn't exist yet or moves it to the current player position. When the player doesn't have the pickup and the light still exists it's destroyed.
That's basically all the code needed for the NV Goggles, if you don't know how to put it together properly have a look at the released code.
Last thing I want to tell you about is the second purpose of setting bHidden=true that I mentioned. Try commenting this line out, compile it and start a network game with a non-dedicated server. It'll work greatly as long as one of the clients picks up the NV, but when the server does the light will get replicated over the network and seen by the clients. That's because the light is still in the "Relevant Set of Actors" according to the Network Architecture document, setting bHidden=true will prevent this.
I hope you liked that tutorial and that it was of any help for you. Send feedback or questions to knthrak@planetunreal.com or contact me via ICQ 48124716
Live and let die!
BTW, I also read the roadmap!!
Credits to Snakeye