Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 6, 2008, 5:31:58 PM (16 years ago)
Author:
landauf
Message:

several improvements:

  • AI works properly now - add enemies with 'createEnemy x' where x is the number of enemies to add, default is 1. You can remove AI ships with 'killEnemies'.
  • Added new explosion (with smoke)
  • Added new projectile (with trail)
  • Added new thruster emitter
  • AI ships are destroyable - they start with 100 hp, each hit makes 15 hp damage, this value is configurable in the config-file: [Projectile] damage_
  • Added AI ship spawn and explosion effects
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/objects/SpaceShipAI.cc

    r1505 r1552  
    3232#include <OgreMath.h>
    3333#include "Projectile.h"
     34#include "ParticleSpawner.h"
    3435#include "core/CoreIncludes.h"
    3536#include "core/Iterator.h"
     
    3738#include "core/ConsoleCommand.h"
    3839#include "core/XMLPort.h"
     40#include "particle/ParticleInterface.h"
    3941
    4042#define ACTION_INTERVAL 1.0f
     
    5153        RegisterObject(SpaceShipAI);
    5254
    53         this->alive_ = true;
    54         this->setPosition(Vector3(rnd(-1000, 1000), rnd(-1000, 1000), rnd(-1000, 0000)));
    5555        this->target_ = 0;
    5656        this->bShooting_ = 0;
     
    7070    }
    7171
     72    SpaceShipAI::~SpaceShipAI()
     73    {
     74        for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; ++it)
     75            it->shipDied(this);
     76    }
     77
    7278    void SpaceShipAI::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    7379    {
    7480        SpaceShip::XMLPort(xmlelement, mode);
    75         myShip_=true;
    76 
     81
     82        this->myShip_=true;
    7783        this->actionTimer_.setTimer(ACTION_INTERVAL, true, this, createExecutor(createFunctor(&SpaceShipAI::action)));
    7884    }
     
    8591            newenemy->setMesh("assff.mesh");
    8692//            newenemy->setPosition(0, 0, 0);
     93            newenemy->setPosition(Vector3(rnd(-3000, 3000), rnd(-3000, 3000), rnd(-3000, 3000)));
    8794            newenemy->setScale(10);
    8895            newenemy->setMaxSpeed(500);
     
    95102            Element xmlelement;
    96103            newenemy->XMLPort(xmlelement, XMLPort::LoadObject);
     104
     105            ParticleSpawner* spawneffect = new ParticleSpawner("Orxonox/fairytwirl", 2.0, 0.0, newenemy->getOrth());
     106            spawneffect->setPosition(newenemy->getPosition() - newenemy->getOrth() * 50);
     107            spawneffect->create();
    97108        }
    98109    }
     
    103114        for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; )
    104115        {
    105             delete *(it++);
    106             ++i;
     116            (it++)->kill();
    107117            if (num && i >= num)
    108118                break;
     
    122132        // search enemy
    123133        random = rnd(maxrand);
    124 //std::cout << "search enemy: " << random << std::endl;
    125134        if (random < 20 && (!this->target_))
    126         {
    127135            this->searchNewTarget();
    128         }
    129136
    130137        // forget enemy
    131138        random = rnd(maxrand);
    132 //std::cout << "forget enemy: " << random << std::endl;
    133139        if (random < 5 && (this->target_))
    134         {
    135140            this->forgetTarget();
    136         }
    137141
    138142        // next enemy
    139143        random = rnd(maxrand);
    140 //std::cout << "next enemy: " << random << std::endl;
    141144        if (random < 10 && (this->target_))
    142         {
    143145            this->searchNewTarget();
    144         }
    145146
    146147        // fly somewhere
    147148        random = rnd(maxrand);
    148 //std::cout << "fly somewhere: " << random << std::endl;
    149149        if (random < 40 && (!this->bHasTargetPosition_ && !this->target_))
    150         {
    151150            this->searchNewTargetPosition();
    152         }
    153151
    154152        // stop flying
    155153        random = rnd(maxrand);
    156 //std::cout << "stop flying: " << random << std::endl;
    157154        if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
    158         {
    159155            this->bHasTargetPosition_ = false;
    160         }
    161156
    162157        // fly somewhere else
    163158        random = rnd(maxrand);
    164 //std::cout << "fly somewhere else: " << random << std::endl;
    165159        if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
    166         {
    167160            this->searchNewTargetPosition();
    168         }
    169161
    170162        // shoot
    171163        random = rnd(maxrand);
    172 //std::cout << "shoot: " << random << std::endl;
    173164        if (random < 75 && (this->target_ && !this->bShooting_))
    174         {
    175165            this->bShooting_ = true;
    176         }
    177166
    178167        // stop shooting
    179168        random = rnd(maxrand);
    180 //std::cout << "stop shooting: " << random << std::endl;
    181169        if (random < 25 && (this->bShooting_))
    182         {
    183170            this->bShooting_ = false;
    184         }
     171    }
     172
     173    void SpaceShipAI::damage(float damage)
     174    {
     175        this->health_ -= damage;
     176        if (this->health_ <= 0)
     177        {
     178            this->kill();
     179            SpaceShipAI::createEnemy(1);
     180        }
     181    }
     182
     183    void SpaceShipAI::kill()
     184    {
     185        ParticleSpawner* explosion = new ParticleSpawner("Orxonox/BigExplosion1part1", 3.0);
     186        explosion->setPosition(this->getPosition());
     187        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
     188        explosion->setScale(4);
     189        explosion->create();
     190
     191        explosion = new ParticleSpawner("Orxonox/BigExplosion1part2", 3.0);
     192        explosion->setPosition(this->getPosition());
     193        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
     194        explosion->setScale(4);
     195        explosion->create();
     196
     197        Vector3 ringdirection = Vector3(rnd(), rnd(), rnd());
     198        ringdirection.normalise();
     199        explosion = new ParticleSpawner("Orxonox/BigExplosion1part3", 3.0, 0.5, ringdirection);
     200        explosion->setPosition(this->getPosition());
     201        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
     202        explosion->setScale(4);
     203        explosion->create();
     204
     205        delete this;
    185206    }
    186207
     
    193214            this->moveToTargetPosition(dt);
    194215
    195         if (this->bShooting_ && this->isCloseAtTarget(2000) && this->isLookingAtTarget(Ogre::Math::PI / 10.0f))
     216        if (this->bShooting_ && this->isCloseAtTarget(2500) && this->isLookingAtTarget(Ogre::Math::PI / 10))
    196217            this->doFire();
    197218
     
    201222    void SpaceShipAI::moveToTargetPosition(float dt)
    202223    {
    203         static Radian RadianZERO(0);
    204 
    205 //        float dotprod = (this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(this->targetPosition_ - this->getPosition());
    206         Quaternion rotation = (this->getOrientation() * Ogre::Vector3::UNIT_X).getRotationTo(this->targetPosition_ - this->getPosition());
    207 /*
    208 std::cout << "scalprod: " << dotprod << std::endl;
    209 std::cout << "dist: " << this->targetPosition_ - this->getPosition() << std::endl;
    210 std::cout << "yaw: " << rotation.getYaw().valueRadians() << std::endl;
    211 std::cout << "pitch: " << rotation.getPitch().valueRadians() << std::endl;
    212 std::cout << "roll: " << rotation.getRoll().valueRadians() << std::endl;
    213 */
    214         this->setMoveYaw(-rotation.getRoll().valueRadians());
    215         this->setMovePitch(rotation.getYaw().valueRadians());
    216 
    217         if ((this->targetPosition_ - this->getPosition()).length() > 100)
    218         {
     224        Vector3 proj = Ogre::Plane(this->getDir(), this->getPosition()).projectVector(this->targetPosition_ - this->getPosition());
     225        float angle = acos((this->getOrth().dotProduct(proj)) / (this->getOrth().length()*proj.length()));
     226
     227        if ((this->getDir().crossProduct(this->getOrth())).dotProduct(this->targetPosition_ - this->getPosition()) > 0)
     228            this->setMoveYaw(sgn(sin(angle)));
     229        else
     230            this->setMoveYaw(-sgn(sin(angle)));
     231        this->setMovePitch(sgn(cos(angle)));
     232
     233        if ((this->targetPosition_ - this->getPosition()).length() > 300)
    219234            this->setMoveLongitudinal(1);
    220         }
    221 
     235
     236        if (this->isCloseAtTarget(300) && this->target_)
     237        {
     238            if (this->getVelocity().length() > this->target_->getVelocity().length())
     239                this->setMoveLongitudinal(-1);
     240        }
    222241    }
    223242
     
    241260                Vector3 distanceNew = it->getPosition() - this->getPosition();
    242261                if (!this->target_ || it->getPosition().squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI))
    243                         < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)))
     262                        < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250))
    244263                {
    245264                    this->target_ = (*it);
     
    248267            }
    249268        }
    250    }
     269    }
    251270
    252271    void SpaceShipAI::forgetTarget()
     
    260279        if (!this->target_)
    261280            return;
    262 /*
     281
    263282        Vector3 enemymovement = this->target_->getVelocity();
    264283        Vector3 distance_normalised = this->target_->getPosition() - this->getPosition();
     
    267286        float scalarprod = enemymovement.dotProduct(distance_normalised);
    268287        float aimoffset = scalarprod*scalarprod + Projectile::getSpeed() * Projectile::getSpeed() - this->target_->getVelocity().squaredLength();
     288
    269289        if (aimoffset < 0)
    270290        {
     
    273293        }
    274294        aimoffset = -scalarprod + sqrt(aimoffset);
    275         this->targetPosition_ = enemymovement + distance_normalised * aimoffset;
     295        this->targetPosition_ = this->getPosition() + enemymovement + distance_normalised * aimoffset;
    276296        this->bHasTargetPosition_ = true;
    277 
    278         std::cout << "targetpos: " << this->targetPosition_ << std::endl;
    279 */
    280         this->targetPosition_ = this->target_->getPosition();
    281         this->bHasTargetPosition_ = true;
    282297    }
    283298
    284299    bool SpaceShipAI::isCloseAtTarget(float distance)
    285300    {
    286         return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
     301        if (!this->target_)
     302            return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
     303        else
     304            return (this->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
    287305    }
    288306
    289307    bool SpaceShipAI::isLookingAtTarget(float angle)
    290308    {
    291         return (this->getOrientation() * Ogre::Vector3::UNIT_X).directionEquals(this->targetPosition_ - this->getPosition(), Radian(angle));
     309        Vector3 dist = this->targetPosition_ - this->getPosition();
     310        return (acos((this->getDir().dotProduct(dist)) / (dist.length() * this->getDir().length())) < angle);
     311    }
     312
     313    void SpaceShipAI::shipDied(SpaceShipAI* ship)
     314    {
     315        this->forgetTarget();
     316        this->searchNewTargetPosition();
    292317    }
    293318}
Note: See TracChangeset for help on using the changeset viewer.