Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 21, 2012, 3:34:45 PM (12 years ago)
Author:
landauf
Message:

refactored PickupSpawner - it doesn't clone a sample-pickup anymore, it creates new pickups from a template.
removed DroppedPickup because it is not needed anymore, PickupSpawner has now the same functionality.
the representation of the pickup spawner is now destroyed if the pickup is taken and re-created if it spawns again (instead of changing the visibility). makes it easier to change the pickup in a spawner during the game.
adjusted all level files accordingly

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation2012merge/src/modules/pickup/PickupSpawner.cc

    r9318 r9319  
    5555        Pointer to the object which created this item.
    5656    */
    57     PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator), pickup_(NULL)
     57    PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator), pickup_(NULL), representation_(NULL), pickupTemplate_(NULL)
    5858    {
    5959        RegisterObject(PickupSpawner);
    6060
    6161        this->initialize();
    62     }
    63 
    64     /**
    65     @brief
    66         Constructor, Creates a fully functional PickupSpawner.
    67     @param creator
    68         The creator of this PickupSpawner.
    69     @param pickup
    70         The Pickupable to be spawned by this PickupSpawner.
    71     @param triggerDistance
    72         The distance at which the PickupSpawner will trigger.
    73     @param respawnTime
    74         The minimum time between two spawns.
    75     @param maxSpawnedItems
    76         The maximum number of items spawned by this PickupSpawner.
    77     */
    78     PickupSpawner::PickupSpawner(BaseObject* creator, Pickupable* pickup, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator), pickup_(NULL)
    79     {
    80         RegisterObject(PickupSpawner);
    81 
    82         this->initialize();
    83 
    84         this->pickup_ = pickup;
    85 
    86         this->triggerDistance_ = triggerDistance;
    87         this->respawnTime_ = respawnTime;
    88         this->setMaxSpawnedItems(maxSpawnedItems);
    89 
    90         if(this->pickup_ == NULL)
    91         {
    92             orxout(internal_warning, context::pickups) << "A PickupSpawner was created without a valid Pickupable. This won't work." << endl;
    93             this->setActive(false);
    94         }
    95         else
    96         {
    97             PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getRepresentationName());
    98             this->attach(representation->createSpawnerRepresentation(this));
    99             this->setActive(true);
    100         }
    10162    }
    10263
     
    11273        this->spawnsRemaining_ = INF;
    11374        this->selfDestruct_ = false;
     75
     76        this->setPickupable(NULL);
    11477    }
    11578
     
    12285        if(this->isInitialized() && this->selfDestruct_ && this->pickup_ != NULL)
    12386            this->pickup_->destroy();
     87    }
     88
     89    /**
     90    @brief
     91        Factory method, Creates a fully functional PickupSpawner.
     92    @param creator
     93        The creator of this PickupSpawner.
     94    @param pickup
     95        The Pickupable to be spawned by this PickupSpawner.
     96    @param carrier
     97        The PickupCarrier that carried the input pickup before it was dropped.
     98    @param triggerDistance
     99        The distance at which the PickupSpawner will trigger.
     100    */
     101    /*static*/ PickupSpawner* PickupSpawner::createDroppedPickup(BaseObject* creator, Pickupable* pickup, PickupCarrier* carrier, float triggerDistance)
     102    {
     103        PickupSpawner* spawner = new PickupSpawner(creator);
     104
     105        spawner->setPickupable(pickup);
     106        spawner->setTriggerDistance(triggerDistance);
     107        spawner->setMaxSpawnedItems(1);
     108
     109        spawner->setPosition(carrier->getCarrierPosition());
     110        spawner->block(carrier);
     111
     112        return spawner;
    124113    }
    125114
     
    136125        SUPER(PickupSpawner, XMLPort, xmlelement, mode);
    137126
    138         XMLPortObject(PickupSpawner, Pickupable, "pickup", setPickupable, getPickupable, xmlelement, mode);
    139 
     127        XMLPortParam(PickupSpawner, "pickup", setPickupTemplateName, getPickupTemplateName, xmlelement, mode);
    140128        XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
    141129        XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
    142130        XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
    143 
    144         if(this->pickup_ == NULL)
    145         {
    146             orxout(internal_warning, context::pickups) << "A PickupSpawner was created without a valid Pickupable. This won't work." << endl;
    147             this->setActive(false);
    148         }
    149         else
    150         {
    151             PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getRepresentationName());
    152             this->attach(representation->createSpawnerRepresentation(this));
    153             this->setActive(true);
    154         }
    155     }
    156 
    157     /**
    158     @brief
    159         Invoked when the activity has changed. Sets visibility of attached objects.
    160     */
    161     void PickupSpawner::changedActivity()
    162     {
    163         SUPER(PickupSpawner, changedActivity);
    164 
    165         if(GameMode::isMaster())
    166             this->setVisible(this->isActive());
    167131    }
    168132
     
    199163
    200164                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
    201                 PickupCarrier* carrier = orxonox_cast<PickupCarrier*>(*it);
     165                PickupCarrier* carrier = static_cast<PickupCarrier*>(*it);
    202166                // If a PickupCarrier, that fits the target-range of the Pickupable spawned by this PickupSpawner, is in trigger-distance and the carrier is not blocked.
    203167                if(distance.length() < this->triggerDistance_ && carrier != NULL && this->blocked_.find(carrier) == this->blocked_.end())
     
    212176    /**
    213177    @brief
     178        Trigger the PickupSpawner.
     179        Adds the pickup to the Pawn that triggered, sets the timer to re-activate and deactives the PickupSpawner.
     180    @param carrier
     181        Carrier which triggered the PickupSpawner.
     182    */
     183    void PickupSpawner::trigger(PickupCarrier* carrier)
     184    {
     185        orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") triggered and active." << endl;
     186
     187        PickupCarrier* target = carrier->getTarget(this->pickup_);
     188
     189        this->block(carrier);
     190
     191        assert(target);
     192        bool pickedUp = this->pickup_->pickup(target);
     193        assert(pickedUp);
     194        pickedUp = false; // To avoid compiler warning.
     195
     196        this->setPickupable(NULL);
     197        this->decrementSpawnsRemaining();
     198    }
     199
     200    void PickupSpawner::setPickupTemplateName(const std::string& name)
     201    {
     202        Template* temp = Template::getTemplate(name);
     203        if (temp)
     204            this->setPickupTemplate(temp);
     205    }
     206
     207    void PickupSpawner::setPickupTemplate(Template* temp)
     208    {
     209        this->pickupTemplate_ = temp;
     210        this->pickupTemplateName_ = temp->getName();
     211
     212        this->setPickupable(this->createPickup());
     213    }
     214
     215    /**
     216    @brief
    214217        Sets the maximum number of spawned items.
    215218    @param items
     
    233236            this->spawnsRemaining_--;
    234237
     238        this->setActive(false);
     239
    235240        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
    236241        {
    237242            this->startRespawnTimer();
    238 
    239             this->setActive(false);
    240243            this->fireEvent();
    241244        }
     
    243246        {
    244247            orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") empty, selfdestruct initialized." << endl;
    245             this->setActive(false);
    246248            this->destroy();
    247249        }
     
    255257    {
    256258        this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
     259    }
     260
     261    /**
     262    @brief
     263        Invoked by the timer, re-activates the PickupSpawner.
     264    */
     265    void PickupSpawner::respawnTimerCallback()
     266    {
     267        orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") reactivated." << endl;
     268
     269        this->setPickupable(this->createPickup());
     270    }
     271
     272    /**
     273    @brief
     274        Creates a new Pickupable.
     275    @return
     276        The Pickupable created.
     277    */
     278    Pickupable* PickupSpawner::createPickup(void)
     279    {
     280        if(this->spawnsRemaining_ == 0)
     281        {
     282            orxout(internal_error, context::pickups) << "Massive Error: PickupSpawner still alive until having spawned last item." << endl;
     283            return NULL;
     284        }
     285
     286        if (this->pickupTemplate_ != NULL)
     287        {
     288            Identifier* identifier = this->pickupTemplate_->getBaseclassIdentifier();
     289            if (identifier != NULL)
     290            {
     291                Pickupable* pickup = orxonox_cast<Pickupable*>(identifier->fabricate(this));
     292                orxonox_cast<BaseObject*>(pickup)->addTemplate(this->pickupTemplate_);
     293                return pickup;
     294            }
     295            else
     296                orxout(internal_error, context::pickups) << "No base class defined in pickup-template " << this->pickupTemplateName_ << endl;
     297        }
     298
     299        return NULL;
    257300    }
    258301
     
    265308    void PickupSpawner::setPickupable(Pickupable* pickup)
    266309    {
    267         if(this->pickup_ != NULL)
    268         {
    269             orxout(internal_error, context::pickups) << "In PickupSpawner (&" << this << "): setPickupable called, with this->pickup_ already set." << endl;
    270             return;
    271         }
    272         if(pickup == NULL)
    273         {
    274             orxout(internal_error, context::pickups) << "In PickupSpawner (&" << this << "): Argument of setPickupable is NULL." << endl;
    275             return;
     310        if (this->representation_ != NULL)
     311        {
     312            this->representation_->destroy();
     313            this->representation_ = NULL;
     314        }
     315
     316        if (pickup != NULL)
     317        {
     318            if (this->pickup_ != NULL)
     319                this->pickup_->destroy();
     320
     321            PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(pickup->getRepresentationName());
     322            this->representation_ = representation->createSpawnerRepresentation(this);
     323            this->attach(this->representation_);
     324            this->setActive(true);
     325        }
     326        else
     327        {
     328            this->setActive(false);
    276329        }
    277330
    278331        this->pickup_ = pickup;
    279332    }
    280 
    281     /**
    282     @brief
    283         Get the Pickupable that is spawned by this PickupSpawner.
    284     @return
    285         Returns the Pickupable that is spawned by this PickupSpawner.
    286     */
    287     const Pickupable* PickupSpawner::getPickupable(void) const
    288     {
    289         return this->pickup_;
    290     }
    291 
    292     /**
    293     @brief
    294         Trigger the PickupSpawner.
    295         Adds the pickup to the Pawn that triggered, sets the timer to re-activate and deactives the PickupSpawner.
    296     @param pawn
    297         Pawn which triggered the PickupSpawner.
    298     */
    299     void PickupSpawner::trigger(Pawn* pawn)
    300     {
    301         if(this->isActive()) // Checks whether PickupSpawner is active.
    302         {
    303             orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") triggered and active." << endl;
    304 
    305             PickupCarrier* carrier = orxonox_cast<PickupCarrier*>(pawn);
    306             assert(carrier);
    307 
    308             // If the Pawn isn't a target of the Pickupable.
    309             if(!carrier->isTarget(this->pickup_))
    310             {
    311                 orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") triggered but Pawn wasn't a target of the Pickupable." << endl;
    312                 return;
    313             }
    314 
    315             PickupCarrier* target = carrier->getTarget(this->pickup_);
    316             Pickupable* pickup = this->getPickup();
    317 
    318             this->block(carrier);
    319 
    320             assert(pickup);
    321             assert(target);
    322             bool pickedUp = pickup->pickup(target);
    323             assert(pickedUp);
    324             pickedUp = false; // To avoid compiler warning.
    325 
    326             this->decrementSpawnsRemaining();
    327         }
    328     }
    329 
    330     /**
    331     @brief
    332         Creates a new Pickupable.
    333     @return
    334         The Pickupable created.
    335     */
    336     Pickupable* PickupSpawner::getPickup(void)
    337     {
    338         if(this->spawnsRemaining_ == 0)
    339         {
    340             orxout(internal_error, context::pickups) << "Massive Error: PickupSpawner still alive until having spawned last item." << endl;
    341             return NULL;
    342         }
    343 
    344         Pickupable* pickup = this->pickup_->clone();
    345         return pickup;
    346     }
    347 
    348     /**
    349     @brief
    350         Invoked by the timer, re-activates the PickupSpawner.
    351     */
    352     void PickupSpawner::respawnTimerCallback()
    353     {
    354         orxout(verbose, context::pickups) << "PickupSpawner (&" << this << ") reactivated." << endl;
    355 
    356         this->setActive(true);
    357     }
    358333}
Note: See TracChangeset for help on using the changeset viewer.