news about forums links tools tutorials contact

Making a Relic - author: crack_addict
Relics are mutators that offer various effects through an inventory item which is given to the player when he runs over it. To show how to make a new relic I'll just run through the Blink relic which I made, basically it just toggles the player from being visible/invisible..."blinking" in and out. Simple stuff really.
For a relic there are only 2 classes you need, the relic class itself which handles the spawning of the second class, an inventory pickup. In this case we use RelicBlink and RelicBlinkInventory. Before you make your own relic, its always a good idea to check out the Relic and RelicInventory classes, and a couple of the other relics...just to help you get a good handle on whats going on. Also if you haven't played with mutators yet, you should take a look at them as well, since Relic is just a glorified mutator. :)

    //=====================================================
    // RelicBlink.
    //=====================================================
    class RelicBlink expands Relic;

    defaultproperties
    {
         RelicClass=Class'grelics.RelicBlinkInventory'
    }

Simple, eh? Fortunately the Relic class handles all the spawning and whatnot, so all we have to do is tell it the class we want it to spawn, in this case 'grelics.RelicBlinkInventory'. Now on to the actual meat of a relic...

    //=====================================================
    // RelicBlinkInventory
    //
    // Toggles visibility/invisibility by spawning/destroying
    // invisibility items for the player.
    //=====================================================
    class RelicBlinkInventory expands RelicInventory;

    #exec MESH IMPORT MESH=blink ANIVFILE=MODELS\blink_a.3d DATAFILE=MODELS\blink_d.3d X=0 Y=0 Z=0
    #exec MESH ORIGIN MESH=blink X=0 Y=0 Z=0

    #exec MESH SEQUENCE MESH=blink SEQ=All   STARTFRAME=0 NUMFRAMES=1
    #exec MESH SEQUENCE MESH=blink SEQ=blink STARTFRAME=0 NUMFRAMES=1

    #exec TEXTURE IMPORT NAME=blink_skin FILE=TEXTURES\blink_skin2.pcx GROUP=Skins FLAGS=2

    #exec MESHMAP NEW   MESHMAP=blink MESH=blink
    #exec MESHMAP SCALE MESHMAP=blink X=0.1 Y=0.1 Z=0.2

    #exec MESHMAP SETTEXTURE MESHMAP=blink NUM=0 TEXTURE=blink_skin

    // Is the player invisible?
    var bool bIsInvis;

    // Makeinvis() - creates an invisibility object and gives it to the
    // player (grelics.BlinkItem)
    function MakeInvis()
    {
      local BlinkItem invis;

      // All we do here is spawn an invisiblity item (BlinkItem in this case),
      // set some properties and then give to the player using the GiveTo()
      // function.
      invis = Spawn(class'grelics.BlinkItem');
      invis.Charge = 500;
      invis.bHeldItem = true;
      invis.RespawnTime = 0.0;
      invis.GiveTo(Pawn(Owner));
      invis.Activate();

      // Set invis to true and then use the SetTimer function to be called
      // in 5.0 seconds so that we can make the player visible
      bIsInvis = true;
      SetTimer(5.0, true);
    }

    // MakeVis() - finds the invis item and removes it from the player
    function MakeVis()
    {
      local Inventory invis;

      // This is the exact opposite of MakeInvis().  Here we use the
      // FindInventoryType() function from the Pawn class to see if the
      // player has an invis item.  If they do then we deactivate it
      // and send it off into oblivion...
      invis = Pawn(Owner).FindInventoryType(class'grelics.BlinkItem');
      if (invis != NONE)
      {
        Pickup(invis).UsedUp();
        Pawn(Owner).DeleteInventory(invis);
        invis.Destroy();
      }

      // Then set the timer to be called in a second to make then invis
      // again.
      SetTimer(1.0, true);
      bIsInvis = false;
    }

    // When the relic is picked up, the relic goes into the Activated state,
    // so we put some code here to start the whole vis/invis process, and
    // also here is where we define the Timer function so that we can toggle
    state Activated
    {
      function Timer()
      {
        if (bIsInvis)
          MakeVis();
        else MakeInvis();
      }

    Begin:
      MakeInvis();
      bIsInvis = true;
      SetTimer(5.0, true);
    }

    defaultproperties
    {
      PickupMessage="You picked up the blink relic."
      PickupViewMesh=Mesh'grelics.blink'
      PickupViewScale=0.600000
      Icon=Texture'relics.Icons.RelicIconRedemption'
      Physics=PHYS_Rotating
      Skin=Texture'grelics.Skins.blink_skin'
      CollisionHeight=40.000000
    }

Thats pretty much it, in case you're wondering, BlinkItem is just a subclass of UT_Invisibility that just doesn't send the "Invisibility has worn off..." message. Oh, one last thing, for all mutators (and thus relics), you must have an int file detailing your classes if you want them to show up in UT's menus. Here's the grelics package int file (grelics.int) with the Blink relic statement.

    [Public]
    Object=(Name=grelics.RelicBlink,Class=Class,MetaClass=Engine.Mutator,
    Description="Relic: Blink,A magical relic that causes the owner to blink in and out of visibility.")

Again, pretty simple. Just a quick line describing the relic, with a short description. Just make one for you package (blah.int, sexy.int...etc) and stick it in UT/system with the package and your relic should show up in the mutators menu. If you have more than one relic in a package, just add another line... :)