Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changes between Version 12 and Version 13 of code/doc/Pickups


Ignore:
Timestamp:
Aug 23, 2010, 11:16:05 PM (14 years ago)
Author:
dafrick
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • code/doc/Pickups

    v12 v13  
    3131}}}
    3232
    33 There is another file called pickups.oxi which creates all representations needed for the pickups supplied by the pickup_representation_templates.oxt file. You will have to include it as well. It has to be some where after the opening Scene-tag and your first use of a pickup.
     33There is another file called pickups.oxi which creates all representations needed for the pickups supplied by the pickup_representation_templates.oxt file. You will have to include it as well. It has to be somewhere after the opening Scene-tag and your first use of a pickup.
    3434
    3535{{{
     
    6666==== Using non-predefined pickups ====
    6767
    68 Now let's assume you're not satisfied with the pickups that are provided by the two before mentioned file, but you're not much of a coder as well. Luckily there is a way for you. Pickups were created with a broad range of use in mind, which means that the pickups provided by the files are not all there is.
     68Now let's assume you're not satisfied with the pickups that are provided by the two before mentioned file, but you're not much of a coder either. Luckily there is a way for you. Pickups were created with a broad range of use in mind, which means that the pickups provided by the files are not all there is.
    6969
    7070There is no minimum requirement to use pickups in your level files, as long as they have been coded in C++. e.g.
     
    9292    description = "This is an awesome new health pickup."
    9393    spawnerTemplate = "newhealthpickupRepresentation"
     94    inventoryRepresentation = "MediumHealth"
    9495>
    9596    <pickup>
     
    126127}}}
    127128
    128 Your done. Now you have a new pickup type with an appropriate representation for your use. If you feel that it is useful in general please don't hesitate create a template for the pickup and add your pickup to the pickup_representation_templates.oxt file and the pickups.oxi file, so that anyone who wants to use kit can do so quite easily.
    129 
    130 Let's assume you're still not satisfied. I mean, come on, we just used a pickup that already existed and created a new type by changing some parameter values and adding a representation, that's not really anything new now, is it?
     129Also there is a parameter defining how the pickup is displayed in the Pickup Inventory (a menu to browse your currently equipped pickups).
     130
     131{{{
     132    inventoryRepresentation = "MediumHealth"
     133}}}
     134
     135This is the name of an image defined in the PickupInventory imageset, which can be found in data_extern/gui/imagesets.
     136
     137Your done. Now you have a new pickup type with an appropriate representation for your use. If you feel that it is useful in general, please don't hesitate to create a template for the pickup and add your pickup to the pickup_representation_templates.oxt file and the pickups.oxi file, so that anyone who wants to use it can do so quite easily.
     138
     139Now let's assume you're still not satisfied. I mean, come on, we just used a pickup that already existed and created a new type by changing some parameter values and adding a representation, that's not really anything new now, is it?
    131140
    132141Well I've got something for you. It's called a PickupCollection (in the following just referred to as collection). A collection is comprised of many different types of pickups and behaves just as if it were one pickup itself. This is how you create one:
     
    135144<PickupCollection>
    136145    <pickupables>
    137         -- some pickups you want th have in your collection, e.g. --
     146        -- some pickups you want to have in your collection, e.g. --
    138147        <HealthPickup template=smallhealthpickup />
    139148        <HealthPickup health=50 healthRate=5 durationType=continuous activationType=immediate healthType=limited />
     
    142151}}}
    143152
     153Which pickups make up your collection is entirely up to you, they can be mixed freely.[[BR]]
    144154That's it, there's nothing more to it. However if you have questions regarding any of the above please feel free to contact [wiki:DamianFrick me].
    145155
    146156=== Creating a new pickup ===
    147157
    148 Now it get's a little trickier. Therefore I'm just going to supply you with a recipe, or a set of steps you have to take, without which your pickup won't work.
     158Now it gets a little trickier. Therefore I'm just going to supply you with a recipe, or a set of steps you have to take, without which your pickup won't work and point out some common pitfalls.
    149159
    150160==== Creating the class ====
    151 For a new pickup you need to create a new class in modules/pickup/items. Your class needs to be derived from another pickup class, normally this would either be Pickupable or Pickup. Pickupable is (as mentioned earlier) the base class of all things that can be picked up, thus of all pickups. However you are brobably going to want to derive your class form Pickup, because it provides some useful methods. So have a look at Pickup.
     161For a new pickup you need to create a new class in modules/pickup/items. Your class needs to be derived from another pickup class, normally this would either be Pickupable, CollectiblePickup or Pickup. Pickupable is (as mentioned earlier) the base class of all things that can be picked up, thus of all pickups. CollectiblePickup is a (directly) derived class of Pickupable and provides the additional functionality of enabling your pickup to be used in a collection. However you are probably going to want to derive your class form Pickup, because it is a CollectiblePickup and provides some useful methods. So have a look at Pickup.
    152162
    153163Once you have created your new pickup class you have to insert it in the PickupPrereqs.h file in the modules/pickup folder and in the CMakeList.txt file in the modules/pickup/items folder. Also have a look at other pickups to make sure you include all the necessary files in your class.
     
    167177==== Coosing the carriers ====
    168178You also have to choose the carriers that are allowed to pick your pickup up. After you have chosen the entity that carries your pickup you need to do the following.
    169  * The enity that carries your pickup needs to be derived from the PickupCarrier interface. And you need to implement the PickupCarriers virtual functions getCarrierChildren() and getCarrierParent(). Now let me explain, very briefly, why these functions are needed. All pickups are initially picked up by a pawn and the "propagated", or handed down to the entity that carries them. With the above mentioned two function just that is done. A hierarchical structure is established with one parent and a set of children, where the Pawn is the root node of this hierarchical structure, the only entity with no parent.
    170  * Once you have done that you will also want to specify in your pickup by which carriers it can be picked up, this is done via the addTarget() function. So you have to make sure the target is added whenever one of your pickups is created (so, most conveniently somewhere in the constructor), with the following command.
     179 * The enity that carries your pickup needs to be derived from the PickupCarrier interface. And you need to implement the PickupCarriers virtual functions getCarrierChildren() and getCarrierParent(). Now let me explain, very briefly, why these functions are needed. All pickups are initially picked up by a pawn and then handed down to the entity that effectively carries them. With the above mentioned two function just that is done. A hierarchical structure is established with one parent and a set of children, where the Pawn is the root node of this hierarchical structure, the only entity with no parent.
     180 * Once you have done that you will also want to specify in your pickup which carriers can pick it up, this is done via the addTarget() function. So you have to make sure the target is added whenever one of your pickups is created (so, most conveniently somewhere in the constructor), with the following command.
    171181{{{
    172182this->addTarget(ClassIdentifier<MyCarrierClass>::getIdentifier());
     
    174184
    175185==== Creating the inner workings of your pickup ====
    176 Now that we have the skeleton of a pickup and we have defined which carriers are allowed to pick our pickup up we are going to take a look at all the methods we can (or sometimes have to) overload from Pickupable, for our pickup to work properly. Bu firstly I will introduce some more concepts to make the need for these methods more obvious.
    177  * Since one pickup class can itself be many pickup types we need a way to find out whether a particular instance of a pickup is of the same type as another instance of a pickup. To that end the PickupIdentifier (in the following just called identifier) was created. The PickupIdentifier accounts for the type of class your pickup is of and also for the parameters (and their values) that distinguish different types of pickups of the same class. Much of the functionality of the pickup module relies on this identifier being correct, thus it is very important to initialize it correctly. (We will see, how that is done in a short while.)
     186Now that we have the skeleton of a pickup and we have defined which carriers are allowed to pick our pickup up we are going to take a look at all the methods we can (or sometimes have to) overload from Pickupable, for our pickup to work properly. But first I will introduce some more concepts to make the need for these methods more obvious.
     187 * Since one pickup class can by itself be many pickup types we need a way to find out whether a particular instance of a pickup is of the same type as another instance of a pickup. To that end the PickupIdentifier (in the following just called identifier) was created. The PickupIdentifier accounts for the type of class your pickup is of and also for the parameters (and their values) that distinguish different types of pickups of the same class. Much of the functionality of the pickup module relies on this identifier being correct, thus it is very important to initialize it correctly. (We will see, how that is done in a short while.)
    178188 * Every pickup has at least two states which are very important. The first is, whether the pickup is currently in use or not and the second is whether the pickup is currently picked up or not.
    179189
     
    184194
    185195Please be aware, that these three methods are methods registered with Super, meaning, that whenever overloading them, don't forget to call SUPER(MyClass, myMethod);
     196[[BR]]Also when implementing the above methods you should think of what should happen in unexpected situations, e.g. when your pickup is unused and set to used again. 
    186197
    187198 * clone() The clone() method creates a new pickup of the same type as the pickup it is cloned from. So the cloned pickup is not exactly the same, as it doesn't necessarily completely reflect the status of the pickup it is cloned from, but all the parameters and their values, that distinguish different types of this pickup class. It needs to be implemented by every pickup class. And it is best if this is done in a very specific way. Below is shown how:
     
    195206       
    196207    MyPickup* pickup = dynamic_cast<MyPickup*>(item);
    197     // Here you should set all the important parameters (that destinguis the different types of this pickup), e.g.
     208    // Here you should set all the important parameters (that distinguish the different types of this pickup), e.g.
    198209    pickup->setSomeParameter(this->getSomeParameter());
    199210       
    200     // You must also initialize the identifier of the new pickup, conveniently this is normally done in a member function called initializeIdentifier() and so just this method is called here.
     211    // You must also initialize the identifier of the new pickup, this is normally done in a member function called initializeIdentifier() and so just this method is called here.
    201212    pickup->initializeIdentifier();
    202213}
    203214}}}
    204  * initializeIdentifier() The initializeIdentifier() method initializes (or more simply put, creates) the PickupIdentifier of the instance of your pickup. Since the important values of the parameters are not yet available in the constructor of your pickup this initializeIdentifier() method must be called as soon as they are available, which normally is in the XMLPort() method, and the clone() method, as seen above. In the initializeIdentifier method you need to register each parameter that is important for the type of your pickup to its identifier, this is normally done as follows:
     215 * initializeIdentifier() The initializeIdentifier() method initializes (or more simply put, creates) the PickupIdentifier of the instance of your pickup. Since the important values of the parameters are not yet available in the constructor of your pickup this initializeIdentifier() method must be called as soon as they are available, which normally is in the XMLPort() method, and the clone() method, as seen above. In the initializeIdentifier() method you need to register each parameter that is important for the type of your pickup to its identifier, this is normally done as follows:
    205216{{{
    206217void Pickup::initializeIdentifier(void)
     
    219230}
    220231}}}
    221 Be aware, this only works for parameters that are simple enough, meaning with pointers for example it will, naturally, not work.
    222 
    223  * createSpawner() The createSpawner() method needs to be implemented by any pickup directly inheriting from Pickupable (so if you inherit from Pickup, you don't need to implement this). It is used to create a spawner when the pickup is dropped. A standard implementation would look like this.
     232Be aware, this only works for parameters that are simple enough, meaning with pointers for example it will, naturally, not work, and other ways must be found (this is for example done in PickupCollection with a derived class of the PickupIdentifier, the PickupCollectionIdentifier).
     233
     234 * createSpawner() The createSpawner() method needs to be implemented by any pickup directly inheriting from Pickupable (or directly from CollectiblePickup), so if you inherit from Pickup, you don't need to implement this. It is used to create a spawner when the pickup is dropped. A standard implementation would look like this.
    224235{{{
    225236bool MyPickup::createSpawner(void)
     
    230241}}}
    231242
    232 === Making your object pickupable ===
    233 
    234 work in progress..
    235 
    236243== Detailed description ==
    237244