Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 8891 for code/trunk/src


Ignore:
Timestamp:
Oct 12, 2011, 7:50:43 PM (13 years ago)
Author:
jo
Message:

Ai and tutorial improvements merged back to the trunk. AI features: all weapons are used, the ai-firestrength is configurable, bots are able to collect pickups . I've set the tutorial level as default level.

Location:
code/trunk
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/modules/notifications/NotificationDispatcher.cc

    r8858 r8891  
    5050    CreateUnloadableFactory(NotificationDispatcher);
    5151
     52    registerMemberNetworkFunction(NotificationDispatcher, broadcastHelper);
    5253    registerMemberNetworkFunction(NotificationDispatcher, dispatch);
    5354
     
    6162
    6263        this->sender_ = NotificationListener::NONE;
     64        this->bBroadcast_ = false;
    6365        this->registerVariables();
    6466    }
     
    8183        SUPER(NotificationDispatcher, XMLPort, xmlelement, mode);
    8284
    83         XMLPortParam(NotificationDispatcher, "sender", getSender, setSender, xmlelement, mode);
    84        
    85         XMLPortEventSink(NotificationDispatcher, BaseObject, "trigger", trigger, xmlelement, mode); //TODO: Change BaseObject to MultiTrigger as soon as MultiTrigger is the base of all triggers.
     85        XMLPortParam(NotificationDispatcher, "sender", setSender, getSender, xmlelement, mode);
     86        XMLPortParam(NotificationDispatcher, "broadcast", setBroadcasting, isBroadcasting, xmlelement, mode);
     87
     88        XMLPortEventSink(NotificationDispatcher, BaseObject, "trigger", trigger, xmlelement, mode);
    8689    }
    8790
     
    100103    {
    101104        registerVariable(this->sender_, VariableDirection::ToClient);
     105    }
     106
     107    /**
     108    @brief
     109        Broadcasts a specific Notification.
     110    */
     111    void NotificationDispatcher::broadcast(void)
     112    {
     113        // TODO: Needed?
     114        const std::string message = this->createNotificationMessage();
     115        NotificationListener::sendNotification(message, this->getSender(), notificationMessageType::info, notificationSendMode::local);
     116
     117        // Broadcast
     118        if(!GameMode::isStandalone())
     119        {
     120            callMemberNetworkFunction(NotificationDispatcher, broadcastHelper, this->getObjectID(), NETWORK_PEER_ID_BROADCAST);
     121        }
     122    }
     123
     124    /**
     125    @brief
     126        Helper function for broadcast.
     127    */
     128    void NotificationDispatcher::broadcastHelper(void)
     129    {
     130        this->dispatch(Host::getPlayerID());
    102131    }
    103132
     
    110139    void NotificationDispatcher::dispatch(unsigned int clientId)
    111140    {
    112         if(GameMode::isStandalone() || Host::getPlayerID() == clientId || this->getSyncMode() == 0x0)
     141        // We don't call sendNotification() directly on the server, because if might be necessary that createNotificationMessage() is executed on the client as the message may be client-specific.
     142        if(GameMode::isStandalone() || Host::getPlayerID() == clientId || this->getSyncMode() == ObjectDirection::None)
    113143        {
    114144            const std::string message = this->createNotificationMessage();
     
    139169        orxout(verbose, context::notifications) << "NotificationDispatcher (&" << this << ") triggered." << endl;
    140170
     171        // If the NotificationDispatcher is set to broadcast.
     172        if(this->isBroadcasting())
     173        {
     174            this->broadcast();
     175            return true;
     176        }
     177
    141178        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
    142179        PlayerInfo* player = NULL;
  • code/trunk/src/modules/notifications/NotificationDispatcher.h

    r7552 r8891  
    5050        A NotificationDispatcher is an entity that, upon being triggered, dispatches (or sends) a specified @ref orxonox::Notification "Notification".
    5151
    52         There is one parameter to be set, the @b sender . The sender specifies the part of Orxonox the sent @ref orxonox::Notification "Notification" comes from. The default value is set by the classes implementing NotificationDispatcher.
     52        There are two parameter to be set:
     53        - The @b sender . The sender specifies the part of Orxonox the sent @ref orxonox::Notification "Notification" comes from. The default value is set by the classes implementing NotificationDispatcher.
     54        - The @b broadcast . Specifies whether messages are broadcast (i.e. sent to all clients) or just sent to a specific player.
    5355
    5456        Its standard usage is:
     
    6264        </NotificationDispatcher>
    6365        @endcode
    64         But keep in mind, that NotificationDispatcher is an abstract class and in this example @ref orxonox::PlayerTrigger "PlayerTrigger" stands for any event that is caused by a @ref orxonox::PlayerTrigger "PlayerTrigger", so instead of @ref orxonox::PlayerTrigger "PlayerTrigger", there could be a @ref orxonox::DistanceTrigger "DistanceTrigger", or a @ref orxonox::DistanceMultiTrigger "DistanceMutliTrigger", or even an @ref orxonox::EventListener "EventListener" that waits for an event coming from any kind of @ref orxonox::PlayerTrigger "PlayerTrigger".
     66        But keep in mind, that NotificationDispatcher is an abstract class.
     67        Also in this example @ref orxonox::PlayerTrigger "PlayerTrigger" stands for any event that is caused by a @ref orxonox::PlayerTrigger "PlayerTrigger", so instead of @ref orxonox::PlayerTrigger "PlayerTrigger", there could be a @ref orxonox::DistanceTrigger "DistanceTrigger", or a @ref orxonox::DistanceMultiTrigger "DistanceMutliTrigger", or even an @ref orxonox::EventListener "EventListener" that waits for an event coming from any kind of @ref orxonox::PlayerTrigger "PlayerTrigger".
     68        If the NotificationDispatcher is not set to broadcast only events caused by @ref orxonox::PlayerTrigger "PlayerTriggers" trigger a message since the information obtained by the @ref orxonox::PlayerTrigger "PlayerTrigger" is used to identify the client to which the message should be sent.
    6569
    6670    @author
     
    8488            const std::string& getSender(void) const
    8589                { return this->sender_; }
    86                         /**
     90            /**
    8791            @brief Set the sender of the Notification dispatched by this NotificationDispatcher.
    8892            @param sender The name of the sender.
     
    9195                { this->sender_ = sender; }
    9296
    93             void dispatch(unsigned int clientId); //!< Dispatches a specific Notification.
     97            /**
     98            @brief Check whether the NotificationDispatcher is set to broadcast.
     99            @return Returns true if the NotificationDispatcher is set to broadcast.
     100            */
     101            bool isBroadcasting(void) const
     102                { return this->bBroadcast_; }
     103            /**
     104            @brief Set the NotificationDispatcher to broadcast.
     105            @param broadcast Whether the NotificationDispatcher is set to broadcast or singlecast.
     106            */
     107            void setBroadcasting(bool v)
     108                { this->bBroadcast_ = v; }
     109
     110            void broadcast(void); //!< Broadcasts a specific Notification.
     111            void broadcastHelper(void); //!< Helper function for broadcast.
     112            void dispatch(unsigned int clientId); //!< Dispatches a specific Notification to a given client.
    94113            bool trigger(bool triggered, BaseObject* trigger); //!< Is called when the NotificationDispatcher is triggered.
    95114
    96115        protected:
    97116            std::string sender_; //!< The name of the sender of the Notification dispatched by this NotificationDispatcher.
     117            bool bBroadcast_; //!< Whether the NotificationDispatcher is broadcasting.
    98118
    99119            void registerVariables(void); //!< Register some variables for synchronisation.
     
    105125            */
    106126            virtual const std::string& createNotificationMessage(void)
    107                 { return *(new std::string("")); }
     127                { return BLANKSTRING; }
    108128
    109129    };
  • code/trunk/src/modules/overlays/hud/HUDNavigation.cc

    r8858 r8891  
    6363{
    6464  SetConfigValue(markerLimit_, 3);
     65
    6566}
    6667
     
    7778    setTextSize ( 0.05f );
    7879    setNavMarkerSize ( 0.05f );
     80    setDetectionLimit( 10000.0f );
    7981}
    8082
     
    9597    SUPER ( HUDNavigation, XMLPort, xmlelement, mode );
    9698
    97     XMLPortParam ( HUDNavigation, "font",          setFont,          getFont,          xmlelement, mode );
    98     XMLPortParam ( HUDNavigation, "textSize",      setTextSize,      getTextSize,      xmlelement, mode );
    99     XMLPortParam ( HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlelement, mode );
     99    XMLPortParam ( HUDNavigation, "font",           setFont,           getFont,           xmlelement, mode );
     100    XMLPortParam ( HUDNavigation, "textSize",       setTextSize,       getTextSize,       xmlelement, mode );
     101    XMLPortParam ( HUDNavigation, "navMarkerSize",  setNavMarkerSize,  getNavMarkerSize,  xmlelement, mode );
     102    XMLPortParam ( HUDNavigation, "detectionLimit", setDetectionLimit, getDetectionLimit, xmlelement, mode );
    100103}
    101104
     
    161164
    162165    unsigned int markerCount_ = 0;
    163 
     166    bool closeEnough_ = false; //only display objects that are close enough to be relevant for the player
    164167//         for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
    165168    for ( sortedList::iterator listIt = sortedObjectList_.begin(); listIt != sortedObjectList_.end(); ++markerCount_, ++listIt )
    166169    {
    167170        ObjectMap::iterator it = activeObjectList_.find ( listIt->first );
    168 
    169         if ( markerCount_ < markerLimit_ )
     171        closeEnough_ = listIt->second < detectionLimit_ ;
     172        if ( markerCount_ < markerLimit_ && (closeEnough_ ||  detectionLimit_ < 0) ) // display on HUD if the statement is true
    170173        {
    171174
     
    277280            it->second.text_->show();
    278281        }
    279         else
     282        else // do not display on HUD
    280283        {
    281284            it->second.panel_->hide();
     
    309312void HUDNavigation::addObject ( RadarViewable* object )
    310313{
    311     if( showObject(object)==false )
     314    if( showObject(object) == false )
    312315        return;
    313316
     
    396399        return false;
    397400    assert( rv->getWorldEntity() );
    398     if ( rv->getWorldEntity()->isVisible()==false || rv->getRadarVisibility()==false )
     401    if ( rv->getWorldEntity()->isVisible() == false || rv->getRadarVisibility() == false )
    399402        return false;
    400403    return true;
  • code/trunk/src/modules/overlays/hud/HUDNavigation.h

    r7401 r8891  
    8585    { return navMarkerSize_; }
    8686
     87    void setDetectionLimit( float limit )
     88    { this->detectionLimit_ = limit; }
     89    float getDetectionLimit() const
     90    { return this->detectionLimit_; }
     91
    8792    void setTextSize ( float size );
    8893    float getTextSize() const;
     
    102107    float textSize_;
    103108
    104     unsigned int markerLimit_;; //TODO: is it possible to set this over the console and/or the IG-Setting
    105 
    106 
     109    unsigned int markerLimit_; //TODO: is it possible to set this over the console and/or the IG-Setting
     110    float detectionLimit_; //!< Objects that are more far away than detectionLimit_ are not displayed on the HUD. 10000.0f is the default value.
     111                           //!< In order to bypass this behaviour, set a negative detectionLimit_. Then the detection range is "infinite".
    107112};
    108113}
  • code/trunk/src/modules/overlays/hud/HUDRadar.cc

    r8858 r8891  
    6464        this->shapeMaterials_[RadarViewable::Triangle] = "RadarTriangle.png";
    6565        this->shapeMaterials_[RadarViewable::Square]   = "RadarSquare.png";
    66 
     66        this->setDetectionLimit( 10000.0f );
    6767        this->owner_ = 0;
    6868    }
     
    9393    {
    9494        if (object == dynamic_cast<RadarViewable*>(this->owner_))
     95            return;
     96        if( showObject(object) == false ) //do not show objects that are "invisible" or "radar invisible"
    9597            return;
    9698
     
    123125
    124126    void HUDRadar::objectChanged( RadarViewable* rv )
    125     {
    126         if (rv == dynamic_cast<RadarViewable*>(this->owner_))
    127             return;
    128         assert( this->radarObjects_.find(rv) != this->radarObjects_.end() );
    129         Ogre::PanelOverlayElement* panel = this->radarObjects_[rv];
    130         panel->setMaterialName(TextureGenerator::getMaterialName(
    131             shapeMaterials_[rv->getRadarObjectShape()], rv->getRadarObjectColour()));
     127    {// The new implementation behaves more precisely, since inactive RadarViewables are not displayed anymore.
     128        this->removeObject(rv);
     129        this->addObject(rv);
    132130    }
    133131
     
    174172            coord *= math::pi / 3.5f; // small adjustment to make it fit the texture
    175173            it->second->setPosition((1.0f + coord.x - size) * 0.5f, (1.0f - coord.y - size) * 0.5f);
    176             it->second->show();
     174            if( distance < detectionLimit_ || detectionLimit_ < 0 )
     175                it->second->show();
     176            else
     177                it->second->hide();
    177178
    178179            // if this object is in focus, then set the focus marker
     
    186187    }
    187188
     189    bool HUDRadar::showObject(RadarViewable* rv)
     190    {
     191        if ( rv == dynamic_cast<RadarViewable*> ( this->getOwner() ) )
     192            return false;
     193        assert( rv->getWorldEntity() );
     194        if ( rv->getWorldEntity()->isVisible()==false || rv->getRadarVisibility()==false )
     195            return false;
     196        return true;
     197    }
     198
     199
    188200    void HUDRadar::changedOwner()
    189201    {
  • code/trunk/src/modules/overlays/hud/HUDRadar.h

    r7880 r8891  
    5757        void setHalfDotSizeDistance(float distance) { this->halfDotSizeDistance_ = distance; }
    5858
     59        void setDetectionLimit( float limit )
     60        { this->detectionLimit_ = limit; }
     61        float getDetectionLimit() const
     62        { return this->detectionLimit_; }
     63
    5964        float getMaximumDotSize() const { return this->maximumDotSize_; }
    6065        void setMaximumDotSize(float size) { this->maximumDotSize_ = size; }
     
    6974        virtual void objectChanged( RadarViewable* rv );
    7075        void radarTick(float dt);
     76        bool showObject( RadarViewable* rv ); //!< Do not display an object on radar, if showObject(.) is false.
    7177
    7278        void gatherObjects();
     
    8389
    8490        float sensitivity_;
    85 
     91        float detectionLimit_;
    8692        ControllableEntity* owner_;
    8793    };
  • code/trunk/src/modules/pickup/PickupSpawner.cc

    r8858 r8891  
    181181        if(GameMode::isMaster() && this->isActive())
    182182        {
    183             SmartPtr<PickupSpawner> temp = this; //Create a smart pointer to keep the PickupSpawner alive until we iterated through all Pawns (in case a Pawn takes the last pickup)
     183            WeakPtr<PickupSpawner> spawner = this; // Create a smart pointer to keep the PickupSpawner alive until we iterated through all Pawns (in case a Pawn takes the last pickup)
    184184
    185185            // Remove PickupCarriers from the blocked list if they have exceeded their time.
     
    195195            for(ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
    196196            {
     197                if(spawner == NULL) // Stop if the PickupSpawner has been deleted (e.g. because it has run out of pickups to distribute).
     198                    break;
     199
    197200                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
    198201                PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(*it);
    199                 // If a PickupCarrier, that fits the target-range of the Pickupable spawned by this PickupSpawnder, is in trigger-distance and the carrier is not blocked.
     202                // 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.
    200203                if(distance.length() < this->triggerDistance_ && carrier != NULL && this->blocked_.find(carrier) == this->blocked_.end())
    201204                {
  • code/trunk/src/modules/questsystem/QuestItem.h

    r7552 r8891  
    105105            QuestDescription* description_; //!< The QuestDescription of the QuestItem.
    106106
    107             bool registered_;
     107            bool registered_; //!< Whether the QuestItem is registered with the QuestManager.
    108108
    109109    };
  • code/trunk/src/modules/questsystem/QuestManager.cc

    r8858 r8891  
    3535
    3636#include "util/Exception.h"
     37#include "util/OrxAssert.h"
    3738#include "util/ScopedSingletonManager.h"
    3839#include "core/command/ConsoleCommand.h"
     
    6061    {
    6162        RegisterRootObject(QuestManager);
    62 
    6363        orxout(internal_info, context::quests) << "QuestManager created." << endl;
    6464    }
     
    9595    bool QuestManager::registerQuest(Quest* quest)
    9696    {
    97         assert(quest);
     97        if(quest == NULL)
     98        {
     99            COUT(1) << "Quest pointer is NULL." << endl;
     100            return false;
     101        }
    98102
    99103        std::pair<std::map<std::string, Quest*>::iterator,bool> result;
     
    133137    bool QuestManager::registerHint(QuestHint* hint)
    134138    {
    135         assert(hint);
     139        if(hint == NULL)
     140        {
     141            COUT(1) << "Hint pointer is NULL." << endl;
     142            return false;
     143        }
    136144
    137145        std::pair<std::map<std::string, QuestHint*>::iterator,bool> result;
     
    361369    Quest* QuestManager::getParentQuest(Quest* quest)
    362370    {
     371        OrxAssert(quest, "The input Quest is NULL.");
    363372        return quest->getParentQuest();
    364373    }
     
    374383    QuestDescription* QuestManager::getDescription(Quest* item)
    375384    {
     385        OrxAssert(item, "The input Quest is NULL.");
    376386        return item->getDescription();
    377387    }
     
    387397    QuestDescription* QuestManager::getDescription(QuestHint* item)
    388398    {
     399        OrxAssert(item, "The input QuestHint is NULL.");
    389400        return item->getDescription();
    390401    }
     
    400411    const std::string QuestManager::getId(Quest* item) const
    401412    {
     413        OrxAssert(item, "The input Quest is NULL.");
    402414        return item->getId();
    403415    }
     
    413425    const std::string QuestManager::getId(QuestHint* item) const
    414426    {
     427        OrxAssert(item, "The input QuestHint is NULL.");
    415428        return item->getId();
    416429    }
  • code/trunk/src/modules/weapons/projectiles/Rocket.cc

    r8855 r8891  
    6666        this->localAngularVelocity_ = 0;
    6767        this->lifetime_ = 100.0f;
     68        this->bIsRocket_= true;
    6869
    6970        if (GameMode::isMaster())
     
    134135        if(this->isInitialized())
    135136        {
     137            this->bIsRocket_= false;
    136138            if (GameMode::isMaster())
    137139            {
  • code/trunk/src/orxonox/LevelManager.cc

    r8858 r8891  
    8787    void LevelManager::setConfigValues()
    8888    {
    89         SetConfigValue(defaultLevelName_, "presentationDM.oxw")
     89        SetConfigValue(defaultLevelName_, "missionOne.oxw")
    9090            .description("Sets the pre selection of the level in the main menu.");
    9191    }
     
    158158        if (this->levels_.size() > 0)
    159159        {
    160             // Activate the level that is the first in the list of levels whose activity has been requested. 
     160            // Activate the level that is the first in the list of levels whose activity has been requested.
    161161            this->levels_.front()->setActive(true);
    162162            // Make every player enter the newly activated level.
     
    272272                Loader::unload(&file);
    273273
    274                 if(info == NULL) 
     274                if(info == NULL)
    275275                {
    276276                    // Create a default LevelInfoItem object that merely contains the name
  • code/trunk/src/orxonox/controllers/AIController.cc

    r8729 r8891  
    6565                if (this->freedomCount_ == 1)
    6666                {
    67                 this->state_ = SLAVE;
    68                 this->freedomCount_ = 0;
     67                    this->state_ = SLAVE;
     68                    this->freedomCount_ = 0;
    6969                }
    7070
     
    7676            // search enemy
    7777            random = rnd(maxrand);
    78             if (random < 15 && (!this->target_))
     78            if (random < (15 + botlevel_* 20) && (!this->target_))
    7979                this->searchNewTarget();
    8080
    8181            // forget enemy
    8282            random = rnd(maxrand);
    83             if (random < 5 && (this->target_))
     83            if (random < ((1-botlevel_)*6) && (this->target_))
    8484                this->forgetTarget();
    8585
    8686            // next enemy
    8787            random = rnd(maxrand);
    88             if (random < 10 && (this->target_))
     88            if (random < (botlevel_*20) && (this->target_))
    8989                this->searchNewTarget();
    9090
     
    106106            // shoot
    107107            random = rnd(maxrand);
    108             if (!(this->passive_) && random < 75 && (this->target_ && !this->bShooting_))
     108            if (!(this->passive_) && random < (75 + botlevel_*25) && (this->target_ && !this->bShooting_))
    109109                this->bShooting_ = true;
    110110
    111111            // stop shooting
    112112            random = rnd(maxrand);
    113             if (random < 25 && (this->bShooting_))
     113            if (random < ((1 - botlevel_)*25) && (this->bShooting_))
    114114                this->bShooting_ = false;
     115
     116            // boost
     117            random = rnd(maxrand);
     118            if (random < botlevel_*100 )
     119                this->boostControl();
     120
     121            // update Checkpoints
     122            /*random = rnd(maxrand);
     123            if (this->defaultWaypoint_ && random > (maxrand-10))
     124                this->manageWaypoints();
     125            else //if(random > maxrand-10) //CHECK USABILITY!!*/
     126            if (this->waypoints_.size() == 0 )
     127                this->manageWaypoints();
    115128
    116129        }
     
    159172                // search enemy
    160173                random = rnd(maxrand);
    161                 if (random < 15 && (!this->target_))
     174                if (random < (botlevel_)*25 && (!this->target_))
    162175                    this->searchNewTarget();
    163176
    164177                // forget enemy
    165178                random = rnd(maxrand);
    166                 if (random < 5 && (this->target_))
     179                if (random < (1-botlevel_)*6 && (this->target_))
    167180                    this->forgetTarget();
    168181
     
    185198                // shoot
    186199                random = rnd(maxrand);
    187                 if (!(this->passive_) && random < 9 && (this->target_ && !this->bShooting_))
    188                 {
    189                 this->bShooting_ = true;
    190                 this->forceFreeSlaves();
     200                if (!(this->passive_) && random < 25*(botlevel_)+1 && (this->target_ && !this->bShooting_))
     201                {
     202                    this->bShooting_ = true;
     203                    this->forceFreeSlaves();
    191204                }
    192205
    193206                // stop shooting
    194207                random = rnd(maxrand);
    195                 if (random < 25 && (this->bShooting_))
     208                if (random < ( (1- botlevel_)*25 ) && (this->bShooting_))
    196209                    this->bShooting_ = false;
    197210
     211                // boost
     212                random = rnd(maxrand);
     213                if (random < botlevel_*100 )
     214                    this->boostControl();
     215
     216                // update Checkpoints
     217                /*random = rnd(maxrand);
     218                if (this->defaultWaypoint_ && random > (maxrand-10))
     219                    this->manageWaypoints();
     220                else //if(random > maxrand-10) //CHECK USABILITY!!*/
     221                if (this->waypoints_.size() == 0 )
     222                    this->manageWaypoints();
    198223            }
    199224        }
     
    206231            return;
    207232
    208         if (this->state_ == MASTER)
     233        float random;
     234        float maxrand = 100.0f / ACTION_INTERVAL;
     235        ControllableEntity* controllable = this->getControllableEntity();
     236
     237        if (controllable && this->mode_ == DEFAULT)// bot is ready to move to a target
    209238        {
    210             if (this->specificMasterAction_ ==  NONE)
     239            if (this->waypoints_.size() > 0 ) //Waypoint functionality.
     240            {
     241                WorldEntity* wPoint = this->waypoints_[this->waypoints_.size()-1];
     242                if(wPoint)
     243                {
     244                    this->moveToPosition(wPoint->getWorldPosition()); //BUG ?? sometime wPoint->getWorldPosition() causes crash
     245                    if (wPoint->getWorldPosition().squaredDistance(controllable->getPosition()) <= this->squaredaccuracy_)
     246                        this->waypoints_.pop_back(); // if goal is reached, remove it from the list
     247                }
     248                else
     249                    this->waypoints_.pop_back(); // remove invalid waypoints
     250
     251            }
     252            else if(this->defaultWaypoint_ && ((this->defaultWaypoint_->getPosition()-controllable->getPosition()).length()  > 200.0f))
     253            {
     254                this->moveToPosition(this->defaultWaypoint_->getPosition()); // stay within a certain range of the defaultWaypoint_
     255                random = rnd(maxrand);
     256            }
     257        }
     258        if(this->mode_ == DEFAULT)
     259            {
     260            if (this->state_ == MASTER)
     261            {
     262                if (this->specificMasterAction_ ==  NONE)
     263                {
     264                    if (this->target_)
     265                    {
     266                        if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
     267                            this->forgetTarget();
     268                        else
     269                        {
     270                            this->aimAtTarget();
     271                            random = rnd(maxrand);
     272                            if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
     273                                this->follow();  //If a bot is shooting a player, it shouldn't let him go away easily.
     274                        }
     275                    }
     276
     277                    if (this->bHasTargetPosition_)
     278                        this->moveToTargetPosition();
     279
     280                    this->doFire();
     281                }
     282
     283                if (this->specificMasterAction_  == TURN180)
     284                    this->turn180();
     285
     286                if (this->specificMasterAction_ == SPIN)
     287                    this->spin();
     288                if (this->specificMasterAction_ == FOLLOW)
     289                    this->follow();
     290            }
     291
     292            if (this->state_ == SLAVE)
     293            {
     294                if (this->bHasTargetPosition_)
     295                    this->moveToTargetPosition();
     296            }
     297
     298            if (this->state_ == FREE)
    211299            {
    212300                if (this->target_)
     
    214302                    if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
    215303                        this->forgetTarget();
    216                     else this->aimAtTarget();
     304                    else
     305                    {
     306                        this->aimAtTarget();
     307                        random = rnd(maxrand);
     308
     309                        if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
     310                            this->follow();//If a bot is shooting a player, it shouldn't let him go away easily.
     311                     }
    217312                }
    218313
     
    220315                    this->moveToTargetPosition();
    221316
    222                 if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(math::pi / 20.0f))
    223                     this->getControllableEntity()->fire(0);
    224             }
    225 
    226             if (this->specificMasterAction_  == TURN180)
    227                     this->turn180();
    228 
    229             if (this->specificMasterAction_ == SPIN)
    230                     this->spin();
    231             if (this->specificMasterAction_ == FOLLOW)
     317                this->doFire();
     318            }
     319        }//END_OF DEFAULT MODE
     320        else if (this->mode_ == ROCKET)//Rockets do not belong to a group of bots -> bot states are not relevant.
     321        {   //Vector-implementation: mode_.back() == ROCKET;
     322            if(controllable)
     323            {
     324                if(controllable->getRocket())//Check wether the bot is controlling the rocket and if the timeout is over.
     325                {
    232326                    this->follow();
    233         }
    234 
    235         if (this->state_ == SLAVE)
    236         {
    237 
    238             if (this->bHasTargetPosition_)
    239                 this->moveToTargetPosition();
    240 
    241         }
    242 
    243          if (this->state_ == FREE)
    244         {
    245             if (this->target_)
    246             {
    247                 if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
    248                     this->forgetTarget();
    249                 else this->aimAtTarget();
    250             }
    251 
    252             if (this->bHasTargetPosition_)
    253                 this->moveToTargetPosition();
    254 
    255             if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(math::pi / 20.0f))
    256                 this->getControllableEntity()->fire(0);
    257         }
     327                    this->timeout_ -= dt;
     328                    if((timeout_< 0)||(!target_))//Check if the timeout is over or target died.
     329                    {
     330                       controllable->fire(0);//kill the rocket
     331                       this->setPreviousMode();//get out of rocket mode
     332                    }
     333                }
     334                else
     335                    this->setPreviousMode();//no rocket entity -> get out of rocket mode
     336            }
     337            else
     338                this->setPreviousMode();//If bot dies -> getControllableEntity == NULL -> get out of ROCKET mode
     339        }//END_OF ROCKET MODE
    258340
    259341        SUPER(AIController, tick, dt);
  • code/trunk/src/orxonox/controllers/ArtificialController.cc

    r8858 r8891  
    3939#include "worldentities/pawns/Pawn.h"
    4040#include "worldentities/pawns/TeamBaseMatchBase.h"
     41#include "worldentities/pawns/SpaceShip.h"
    4142#include "gametypes/TeamDeathmatch.h"
    4243#include "gametypes/Dynamicmatch.h"
     
    4445#include "controllers/NewHumanController.h"
    4546#include "controllers/DroneController.h"
     47#include "weaponsystem/WeaponMode.h"
     48#include "weaponsystem/WeaponPack.h"
     49#include "weaponsystem/Weapon.h"
     50#include "weaponsystem/WeaponSlot.h"
     51#include "weaponsystem/WeaponSlot.h"
    4652
    4753namespace orxonox
     
    5258    SetConsoleCommand("ArtificialController", "passivebehaviour", &ArtificialController::passivebehaviour);
    5359    SetConsoleCommand("ArtificialController", "formationsize",    &ArtificialController::formationsize);
     60    SetConsoleCommand("ArtificialController", "setbotlevel",      &ArtificialController::setAllBotLevel);
    5461
    5562    static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7;
     
    8491
    8592        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
     93        this->bSetupWorked = false;
     94        this->botlevel_ = 0.5f;
     95        this->mode_ = DEFAULT;////Vector-implementation: mode_.push_back(DEFAULT);
     96        this->timeout_ = 0;
     97        this->currentWaypoint_ = 0;
     98        this->setAccuracy(5);
     99        this->defaultWaypoint_ = NULL;
    86100    }
    87101
     
    89103    {
    90104        if (this->isInitialized())
    91         {
     105        {//Vector-implementation: mode_.erase(mode_.begin(),mode_.end());
     106            this->waypoints_.clear();
    92107            this->removeFromFormation();
    93 
     108            this->weaponModes_.clear();
    94109            for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it)
    95110            {
     
    305320        if (!this->getControllableEntity())
    306321            this->removeFromFormation();
     322        this->bSetupWorked = false;        // reset weapon information
     323        this->setupWeapons();
    307324    }
    308325
     
    387404        }
    388405    }
     406
     407    void ArtificialController::absoluteMoveToPosition(const Vector3& target)
     408    {
     409        float minDistance = 40.0f;
     410        if (!this->getControllableEntity())
     411            return;
     412
     413        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
     414        float distance = (target - this->getControllableEntity()->getPosition()).length();
     415
     416            if (this->target_ || distance > minDistance)
     417            {
     418                // Multiply with ROTATEFACTOR_FREE to make them a bit slower
     419                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
     420                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
     421                this->getControllableEntity()->moveFrontBack(SPEED_FREE);
     422            }
     423
     424
     425        if (distance < minDistance)
     426        {
     427            this->positionReached();
     428        }
     429    }
     430
    389431
    390432    void ArtificialController::moveToTargetPosition()
     
    915957    bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
    916958    {
     959        if(!entity1 || !entity2)
     960            return true;
    917961        if (entity1 == entity2)
    918962            return true;
     
    10201064        return (team1 == team2 && team1 != -1);
    10211065    }
     1066
     1067    /**
     1068        @brief DoFire is called when a bot should shoot and decides which weapon is used and whether the bot shoots at all.
     1069    */
     1070    void ArtificialController::doFire()
     1071    {
     1072        if(!this->bSetupWorked)//setup: find out which weapons are active ! hard coded: laser is "0", lens flare is "1", ...
     1073        {
     1074            this->setupWeapons();
     1075        }
     1076        else if(this->getControllableEntity() && weaponModes_.size()&&this->bShooting_ && this->isCloseAtTarget((1 + 2*botlevel_)*1000) && this->isLookingAtTarget(math::pi / 20.0f))
     1077        {
     1078            int firemode;
     1079            float random = rnd(1);//
     1080            if (this->isCloseAtTarget(130) && (firemode = getFiremode("LightningGun")) > -1 )
     1081            {//LENSFLARE: short range weapon
     1082                this->getControllableEntity()->fire(firemode); //ai uses lens flare if they're close enough to the target
     1083            }
     1084            else if( this->isCloseAtTarget(400) && (random < this->botlevel_) && (firemode = getFiremode("RocketFire")) > -1 )
     1085            {//ROCKET: mid range weapon
     1086                this->mode_ = ROCKET; //Vector-implementation: mode_.push_back(ROCKET);
     1087                this->getControllableEntity()->fire(firemode); //launch rocket
     1088                if(this->getControllableEntity() && this->target_) //after fire(3) is called, getControllableEntity() refers to the rocket!
     1089                {
     1090                    float speed = this->getControllableEntity()->getVelocity().length() - target_->getVelocity().length();
     1091                    if(!speed) speed = 0.1f;
     1092                    float distance = target_->getPosition().length() - this->getControllableEntity()->getPosition().length();
     1093                    this->timeout_= distance/speed*sgn(speed*distance) + 1.8f; //predicted time of target hit (+ tolerance)
     1094                }
     1095                else
     1096                    this->timeout_ = 4.0f; //TODO: find better default value
     1097            }
     1098            else if ((firemode = getFiremode("HsW01")) > -1 ) //LASER: default weapon
     1099                this->getControllableEntity()->fire(firemode);
     1100        }
     1101    }
     1102
     1103    /**
     1104        @brief Information gathering: Which weapons are ready to use?
     1105    */
     1106    void ArtificialController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions)
     1107    {
     1108        this->bSetupWorked = false;
     1109        if(this->getControllableEntity())
     1110        {
     1111            Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
     1112            if(pawn)
     1113            {
     1114                this->weaponModes_.clear(); // reset previous weapon information
     1115                WeaponSlot* wSlot = 0;
     1116                for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++)
     1117                {
     1118                    WeaponMode* wMode = 0;
     1119                    for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++)
     1120                    {
     1121                        std::string wName = wMode->getIdentifier()->getName();
     1122                        if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new"
     1123                            weaponModes_[wName] = wMode->getMode();
     1124                    }
     1125                }
     1126                if(weaponModes_.size())//at least one weapon detected
     1127                    this->bSetupWorked = true;
     1128            }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user);
     1129        }
     1130    }
     1131
     1132
     1133    void ArtificialController::setBotLevel(float level)
     1134    {
     1135        if (level < 0.0f)
     1136            this->botlevel_ = 0.0f;
     1137        else if (level > 1.0f)
     1138            this->botlevel_ = 1.0f;
     1139        else
     1140            this->botlevel_ = level;
     1141    }
     1142
     1143    void ArtificialController::setAllBotLevel(float level)
     1144    {
     1145        for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it != ObjectList<ArtificialController>::end(); ++it)
     1146            it->setBotLevel(level);
     1147    }
     1148
     1149    void ArtificialController::setPreviousMode()
     1150    {
     1151        this->mode_ = DEFAULT; //Vector-implementation: mode_.pop_back();
     1152    }
     1153
     1154    /**
     1155        @brief Manages boost. Switches between boost usage and boost safe mode.
     1156    */
     1157    void ArtificialController::boostControl()
     1158    {
     1159        SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
     1160        if(ship == NULL) return;
     1161        if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost
     1162            this->getControllableEntity()->boost(true);
     1163        else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
     1164            this->getControllableEntity()->boost(false);
     1165    }
     1166
     1167    int ArtificialController::getFiremode(std::string name)
     1168    {
     1169        for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it)
     1170        {
     1171            if (it->first == name)
     1172                return it->second;
     1173        }
     1174        return -1;
     1175    }
     1176
     1177    void ArtificialController::addWaypoint(WorldEntity* waypoint)
     1178    {
     1179        this->waypoints_.push_back(waypoint);
     1180    }
     1181
     1182    WorldEntity* ArtificialController::getWaypoint(unsigned int index) const
     1183    {
     1184        if (index < this->waypoints_.size())
     1185            return this->waypoints_[index];
     1186        else
     1187            return 0;
     1188    }
     1189
     1190    /**
     1191        @brief Adds first waypoint of type name to the waypoint stack, which is within the searchDistance
     1192        @param name object-name of a point of interest (e.g. "PickupSpawner", "ForceField")
     1193    */
     1194    void ArtificialController::updatePointsOfInterest(std::string name, float searchDistance)
     1195    {
     1196        WorldEntity* waypoint = NULL;
     1197        for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it != ObjectList<WorldEntity>::end(); ++it)
     1198        {
     1199            if((*it)->getIdentifier() == ClassByString(name))
     1200            {
     1201                ControllableEntity* controllable = this->getControllableEntity();
     1202                if(!controllable) continue;
     1203                float actualDistance = ( (*it)->getPosition() - controllable->getPosition() ).length();
     1204                if(actualDistance > searchDistance || actualDistance < 5.0f) continue;
     1205                    // TODO: PickupSpawner: adjust waypoint accuracy to PickupSpawner's triggerdistance
     1206                    // TODO: ForceField: analyze is angle between forcefield boost and own flying direction is acceptable
     1207                else
     1208                {
     1209                    waypoint = *it;
     1210                    break;
     1211                }
     1212            }
     1213        }
     1214        if(waypoint)
     1215            this->waypoints_.push_back(waypoint);
     1216    }
     1217
     1218    /**
     1219        @brief Adds point of interest depending on context. Further Possibilites: "ForceField", "PortalEndPoint", "MovableEntity", "Dock"
     1220    */
     1221    void ArtificialController::manageWaypoints()
     1222    {
     1223        if(!defaultWaypoint_)
     1224            this->updatePointsOfInterest("PickupSpawner", 200.0f); // long search radius if there is no default goal
     1225        else
     1226            this->updatePointsOfInterest("PickupSpawner", 20.0f); // take pickup en passant if there is a default waypoint
     1227    }
     1228
    10221229}
  • code/trunk/src/orxonox/controllers/ArtificialController.h

    r8706 r8891  
    3232#include "OrxonoxPrereqs.h"
    3333
    34 #include <vector>
     34#include <map>
    3535
    3636#include "util/Math.h"
    3737#include "Controller.h"
    3838#include "controllers/NewHumanController.h"
     39#include "weaponsystem/WeaponSystem.h"
    3940
    4041namespace orxonox
     
    7879            static void formationsize(const int size);
    7980
     81            virtual void doFire();
     82            void setBotLevel(float level=1.0f);
     83            inline float getBotLevel() const
     84                { return this->botlevel_; }
     85            static void setAllBotLevel(float level);
     86            //WAYPOINT FUNCTIONS
     87            void addWaypoint(WorldEntity* waypoint);
     88            WorldEntity* getWaypoint(unsigned int index) const;
     89
     90            inline void setAccuracy(float accuracy)
     91                { this->squaredaccuracy_ = accuracy*accuracy; }
     92            inline float getAccuracy() const
     93                { return sqrt(this->squaredaccuracy_); }
     94            void updatePointsOfInterest(std::string name, float distance);
     95            void manageWaypoints();
     96
    8097        protected:
    8198
     
    96113            void moveToPosition(const Vector3& target);
    97114            void moveToTargetPosition();
     115            void absoluteMoveToPosition(const Vector3& target);
    98116
    99117            virtual void positionReached() {}
     
    135153
    136154            static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
     155            void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost.
    137156
    138157            bool bHasTargetPosition_;
     
    141160            bool bShooting_;
    142161
    143         private:
     162            float botlevel_; //<! Makes the level of a bot configurable.
     163            enum Mode {DEFAULT, ROCKET, DEFENCE, MOVING};//TODO; implement DEFENCE, MOVING modes
     164            Mode mode_; //TODO: replace single value with stack-like implementation: std::vector<Mode> mode_;
     165            void setPreviousMode();
     166
     167            //WEAPONSYSTEM DATA
     168            std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode- managed by setupWeapons()
     169            //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons()
     170            float timeout_; //<! Timeout for rocket usage. (If a rocket misses, a bot should stop using it.)
     171            void setupWeapons(); //<! Defines which weapons are available for a bot. Is recalled whenever a bot was killed.
     172            bool bSetupWorked; //<! If false, setupWeapons() is called.
     173            int getFiremode(std::string name);
     174
     175            //WAYPOINT DATA
     176            std::vector<WeakPtr<WorldEntity> > waypoints_;
     177            size_t currentWaypoint_;
     178            float squaredaccuracy_;
     179            WorldEntity* defaultWaypoint_;
    144180    };
    145181}
  • code/trunk/src/orxonox/controllers/DroneController.cc

    r8729 r8891  
    5252        this->drone_ = 0;
    5353        this->isShooting_ = false;
     54        this->setAccuracy(10);
    5455
    5556        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&DroneController::action, this)));
     
    9293        The duration of the tick.
    9394    */
     95    /* PORTALS workaround:
     96    if the owner uses a portal -> distance between owner and drone is huge -> is detected by drone
     97    -> drone searches for portal -> drone adds portal as waypoint -> drone flies towards portal //ignores owner
     98    -> if the drone used a portal, then the distance to the owner is small -> remove waypoint // back to normal mode
     99
     100    */
    94101    void DroneController::tick(float dt)
    95102    {
    96103        if (this->getDrone() && this->getOwner())
    97104        {
    98             if (this->target_)
     105            if (this->waypoints_.size() > 0 ) //Waypoint functionality: Drone should follow it's master through portals
     106            {// Idea: after using the the portal, the master is far away.
     107                WorldEntity* wPoint = this->waypoints_[this->waypoints_.size()-1];
     108                if(wPoint)
     109                {
     110                    float distanceToOwnerSquared = (this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength();
     111                    this->absoluteMoveToPosition(wPoint->getWorldPosition()); //simplified function - needs WORKAROUND
     112                    if (distanceToOwnerSquared <= 90000.0f) //WORKAROUND: if the Drone is again near its owner, the portal has been used correctly.
     113                    {
     114                        this->waypoints_.pop_back(); // if goal is reached, remove it from the list
     115                        this->positionReached(); //needed??
     116                    }
     117
     118                }
     119                else
     120                    this->waypoints_.pop_back(); // remove invalid waypoints
     121            }
     122            else
    99123            {
    100                 float distanceToTargetSquared = (this->getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
    101                 if (distanceToTargetSquared < (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
     124                if (this->target_)
    102125                {
    103                     this->isShooting_ = true;
    104                     this->aimAtTarget();
    105                     this->getDrone()->fire(0);
     126                    float distanceToTargetSquared = (this->getDrone()->getWorldPosition() - this->target_->getWorldPosition()).squaredLength();
     127                    if (distanceToTargetSquared < (this->getDrone()->getMaxShootingRange()*this->getDrone()->getMaxShootingRange()))
     128                    {
     129                       this->isShooting_ = true;
     130                       this->aimAtTarget();
     131                       if(!this->friendlyFire())
     132                           this->getDrone()->fire(0);
     133                    }
     134               }
     135
     136
     137                float maxDistanceSquared = this->getDrone()->getMaxDistanceToOwner()*this->getDrone()->getMaxDistanceToOwner();
     138                float minDistanceSquared = this->getDrone()->getMinDistanceToOwner()*this->getDrone()->getMinDistanceToOwner();
     139                if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > 20.0f*maxDistanceSquared)
     140                {//FIX: if the drone's owner uses portal, the drone searches for the portal & adds it as a waypoint.
     141                    this->updatePointsOfInterest("PortalEndPoint", 500.0f); //possible conflict: speed-pickup
    106142                }
     143                if ((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > maxDistanceSquared)
     144                {
     145                    this->moveToPosition(this->getOwner()->getWorldPosition()); //fly towards owner
     146                }
     147                else if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength() < minDistanceSquared)
     148                {
     149                    this->moveToPosition(-this->getOwner()->getWorldPosition()); //fly away from owner
     150                }
     151                else if (!this->isShooting_)
     152                {
     153                    float random = rnd(2.0f);
     154                    float randomSelection = rnd(6.0f);
     155                    if((int)randomSelection==0) drone_->moveUpDown(random);
     156                    else if((int)randomSelection==1) drone_->moveRightLeft(random);
     157                    else if((int)randomSelection==2) drone_->moveFrontBack(random);
     158                    else if((int)randomSelection==3) drone_->rotateYaw(random);
     159                    else if((int)randomSelection==4) drone_->rotatePitch(random);
     160                    else if((int)randomSelection==5) drone_->rotateRoll(random);
     161                }
     162
     163                this->isShooting_ = false;
    107164            }
    108 
    109             float maxDistanceSquared = this->getDrone()->getMaxDistanceToOwner()*this->getDrone()->getMaxDistanceToOwner();
    110             float minDistanceSquared = this->getDrone()->getMinDistanceToOwner()*this->getDrone()->getMinDistanceToOwner();
    111             if ((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength()  > maxDistanceSquared)
    112             {
    113                 this->moveToPosition(this->getOwner()->getWorldPosition()); //fly towards owner
    114             }
    115             else if((this->getDrone()->getWorldPosition() - this->getOwner()->getWorldPosition()).squaredLength() < minDistanceSquared)
    116             {
    117                 this->moveToPosition(-this->getOwner()->getWorldPosition()); //fly away from owner
    118             }
    119             else if (!this->isShooting_)
    120             {
    121                 float random = rnd(2.0f);
    122                 float randomSelection = rnd(6.0f);
    123                 if((int)randomSelection==0) drone_->moveUpDown(random);
    124                 else if((int)randomSelection==1) drone_->moveRightLeft(random);
    125                 else if((int)randomSelection==2) drone_->moveFrontBack(random);
    126                 else if((int)randomSelection==3) drone_->rotateYaw(random);
    127                 else if((int)randomSelection==4) drone_->rotatePitch(random);
    128                 else if((int)randomSelection==5) drone_->rotateRoll(random);
    129             }
    130 
    131             this->isShooting_ = false;
    132165        }
    133 
    134166        SUPER(AIController, tick, dt);
    135 
    136167    }
    137168
     
    147178            this->destroy();
    148179    }
     180
     181    bool DroneController::friendlyFire()
     182    {   ControllableEntity* droneEntity_ = this->getControllableEntity();
     183        if (!droneEntity_) return false;
     184        if(!owner_) return false;
     185        if(this->bHasTargetPosition_)
     186        {
     187            Vector3 ownerPosition_ = owner_->getPosition();
     188            Vector3 toOwner_ = owner_->getPosition() - droneEntity_->getPosition();
     189            Vector3 toTarget_ = targetPosition_ - droneEntity_->getPosition();
     190            if(toTarget_.length() < toOwner_.length()) return false; //owner is far away = in safty
     191            float angleToOwner = getAngle(droneEntity_->getPosition(), droneEntity_->getOrientation() * WorldEntity::FRONT, ownerPosition_);
     192            float angleToTarget = getAngle(droneEntity_->getPosition(), droneEntity_->getOrientation() * WorldEntity::FRONT, targetPosition_);
     193            float angle = angleToOwner - angleToTarget;//angle between target and owner, observed by the drone
     194            if(std::sin(angle)*toOwner_.length() < 5.0f)//calculate owner's distance to shooting line
     195            return true;
     196        }
     197        return false;//Default return value: Usually there is no friendlyFire
     198    }
    149199}
  • code/trunk/src/orxonox/controllers/DroneController.h

    r8729 r8891  
    6666            virtual void action();
    6767            void ownerDied();
     68            bool friendlyFire(); //<! returns true if the owner_ would be hit.
    6869            bool isShooting_;
    6970
  • code/trunk/src/orxonox/controllers/WaypointController.cc

    r5929 r8891  
    4040    {
    4141        RegisterObject(WaypointController);
    42 
    43         this->currentWaypoint_ = 0;
    4442        this->setAccuracy(100);
    4543    }
     
    4745    WaypointController::~WaypointController()
    4846    {
    49         if (this->isInitialized())
     47        for (size_t i = 0; i < this->waypoints_.size(); ++i)
    5048        {
    51             for (size_t i = 0; i < this->waypoints_.size(); ++i)
     49            if(this->waypoints_[i])
    5250                this->waypoints_[i]->destroy();
    5351        }
     
    5856        SUPER(WaypointController, XMLPort, xmlelement, mode);
    5957
    60         XMLPortParam(WaypointController, "accuracy", setAccuracy, getAccuracy, xmlelement, mode).defaultValues(100.0f);
    61         XMLPortObject(WaypointController, WorldEntity, "waypoints", addWaypoint, getWaypoint,  xmlelement, mode);
     58        XMLPortParam(ArtificialController, "accuracy", setAccuracy, getAccuracy, xmlelement, mode).defaultValues(100.0f);
     59        XMLPortObject(ArtificialController, WorldEntity, "waypoints", addWaypoint, getWaypoint,  xmlelement, mode);
    6260    }
    6361
     
    7674    }
    7775
    78     void WaypointController::addWaypoint(WorldEntity* waypoint)
    79     {
    80         this->waypoints_.push_back(waypoint);
    81     }
    82 
    83     WorldEntity* WaypointController::getWaypoint(unsigned int index) const
    84     {
    85         if (index < this->waypoints_.size())
    86             return this->waypoints_[index];
    87         else
    88             return 0;
    89     }
    9076}
  • code/trunk/src/orxonox/controllers/WaypointController.h

    r5781 r8891  
    4747            virtual void tick(float dt);
    4848
    49             void addWaypoint(WorldEntity* waypoint);
    50             WorldEntity* getWaypoint(unsigned int index) const;
     49        protected:
    5150
    52             inline void setAccuracy(float accuracy)
    53                 { this->squaredaccuracy_ = accuracy*accuracy; }
    54             inline float getAccuracy() const
    55                 { return sqrt(this->squaredaccuracy_); }
    56 
    57         protected:
    58             std::vector<WorldEntity*> waypoints_;
    59             size_t currentWaypoint_;
    60             float squaredaccuracy_;
    6151    };
    6252}
  • code/trunk/src/orxonox/infos/PlayerInfo.cc

    r8706 r8891  
    235235
    236236        this->controllableEntity_->setController(0);
    237         this->controllableEntity_->destroyHud(); // HACK-ish
     237        if(this->isHumanPlayer()) // TODO: Multiplayer?
     238            this->controllableEntity_->destroyHud(); // HACK-ish
    238239       
    239240//        this->controllableEntity_ = this->previousControllableEntity_.back();
     
    248249
    249250         // HACK-ish
    250         if(this->controllableEntity_ != NULL)
     251        if(this->controllableEntity_ != NULL && this->isHumanPlayer())
    251252            this->controllableEntity_->createHud();
    252253
  • code/trunk/src/orxonox/weaponsystem/WeaponSlot.h

    r5781 r8891  
    3535namespace orxonox
    3636{
     37        /**
     38        @brief
     39            The a WeaponSlot defines where a @ref orxonox::Weapon "Weapon" is placed on a pawn. (A WeaponSlot is a StaticEntity)
     40            In a WeaponSlot there can be only one "Weapon", but a Weapon can have several @ref orxonox::WeaponMode "WeaponModes".
     41            A WeaponMode is what one intuitively imagines as weapon. (E.g. RocketFire, LightningGun, LaserFire are weaponmodes)
     42
     43            A WeaponSlot is created in XML (in a weaponsettings file), which can be done in the following fashion:
     44            @code
     45            <weaponslots>
     46              <WeaponSlot position="-15.0,-1.5,0" />
     47              <WeaponSlot position=" 15.0,-1.5,0" />
     48              <WeaponSlot position="    0,   0,0" />
     49            </weaponslots>
     50
     51        @author
     52            Martin Polak
     53
     54        @ingroup Weaponsystem
     55    */
    3756    class _OrxonoxExport WeaponSlot : public StaticEntity
    3857    {
  • code/trunk/src/orxonox/worldentities/ControllableEntity.cc

    r8858 r8891  
    6767        this->camera_ = 0;
    6868        this->xmlcontroller_ = 0;
    69         this->controller_ = 0;
     69        //this->controller_ = 0;
    7070        this->reverseCamera_ = 0;
    7171        this->bDestroyWhenPlayerLeft_ = false;
     
    7474        this->bMouseLook_ = false;
    7575        this->mouseLookSpeed_ = 200;
     76        this->bIsRocket_ = false;
    7677
    7778        this->server_position_         = Vector3::ZERO;
     
    189190        return counter;
    190191    }
    191    
     192
    192193    bool ControllableEntity::setCameraPosition(unsigned int index)
    193194    {
     
    309310    }
    310311
     312    void ControllableEntity::setController(Controller* val)
     313    {
     314        this->controller_ = val;
     315    }
     316
    311317    void ControllableEntity::setTarget( WorldEntity* target )
    312318    {
  • code/trunk/src/orxonox/worldentities/ControllableEntity.h

    r8706 r8891  
    9999            */
    100100            virtual void boost(bool bBoost) {}
    101            
     101
    102102            virtual void greet() {}
    103103            virtual void switchCamera();
     
    155155
    156156            inline Controller* getController() const
    157                 { return this->controller_; }
    158             inline void setController(Controller* val)
    159                 { this->controller_ = val; }
     157                { return this->controller_.get(); }
     158            void setController(Controller* val);
     159
    160160
    161161            virtual void setTarget( WorldEntity* target );
     
    163163                { return this->target_.get(); }
    164164            void setTargetInternal( uint32_t targetID );
     165            inline bool getRocket() const
     166                { return this-> bIsRocket_; }
    165167
    166168        protected:
     
    181183
    182184            Ogre::SceneNode* cameraPositionRootNode_;
     185            bool bIsRocket_; //Workaround to see, if the controllable entity is a Rocket.
    183186
    184187        private:
     
    234237            std::string cameraPositionTemplate_;
    235238            Controller* xmlcontroller_;
    236             Controller* controller_;
     239            WeakPtr<Controller> controller_;
    237240            CameraPosition* reverseCamera_;
    238241            WeakPtr<WorldEntity> target_;
  • code/trunk/src/orxonox/worldentities/pawns/Pawn.cc

    r8855 r8891  
    9393
    9494        this->isHumanShip_ = this->hasLocalController();
    95        
     95
    9696        this->setSyncMode(ObjectDirection::Bidirectional); // needed to synchronise e.g. aimposition
    9797    }
     
    450450        this->isHumanShip_ = true;
    451451    }
     452
     453    void Pawn::changedActivity(void)
     454    {
     455        SUPER(Pawn, changedActivity);
     456
     457        this->setRadarVisibility(this->isActive());
     458    }
     459
     460    void Pawn::changedVisibility(void)
     461    {
     462        SUPER(Pawn, changedVisibility);
     463        //this->setVisible(this->isVisible());
     464        this->setRadarVisibility(this->isVisible());
     465    }
     466
    452467}
  • code/trunk/src/orxonox/worldentities/pawns/Pawn.h

    r8855 r8891  
    170170            virtual const Vector3& getCarrierPosition(void) const
    171171                { return this->getWorldPosition(); };
     172            virtual void changedActivity(void); //!< To enable radarviewability when the activity is changed
     173            virtual void changedVisibility(void); //!< To enable proper radarviewability when the visibility is changed
    172174
    173175        protected:
     
    195197            float maxHealth_;
    196198            float initialHealth_;
    197            
     199
    198200            float shieldHealth_;
    199201            float maxShieldHealth_;
  • code/trunk/src/orxonox/worldentities/pawns/SpaceShip.cc

    r8858 r8891  
    298298    }
    299299
    300         /**
    301     @brief
    302         Add an Engine to the SpaceShip.
    303     @param engine
    304         A pointer to the Engine to be added.
    305     */
    306300    void SpaceShip::addEngine(orxonox::Engine* engine)
    307301    {
     
    504498    void SpaceShip::resetCamera()
    505499    {
    506         Camera *camera = this->getCamera();
    507         if (camera == 0)
    508         {
    509             orxout(internal_warning) << "Failed to reset camera!" << endl;
    510             return;
    511         }
    512 
    513         this->shakeDt_ = 0.0f;
    514         camera->setPosition(this->cameraOriginalPosition_);
    515         camera->setOrientation(this->cameraOriginalOrientation_);
     500        if(this->hasLocalController() && this->hasHumanController())
     501        {
     502            Camera *camera = this->getCamera();
     503            if (camera == 0)
     504            {
     505                orxout(internal_warning) << "Failed to reset camera!" << endl;
     506                return;
     507            }
     508            this->shakeDt_ = 0.0f;
     509            camera->setPosition(this->cameraOriginalPosition_);
     510            camera->setOrientation(this->cameraOriginalOrientation_);
     511        }
    516512    }
    517513
Note: See TracChangeset for help on using the changeset viewer.