Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/orxonox/worldentities/pawns/Pawn.cc @ 7045

Last change on this file since 7045 was 7045, checked in by scheusso, 14 years ago

RadarViewable need a worldentity* when constructing
i really thought i already did this

  • Property svn:eol-style set to native
File size: 12.3 KB
RevLine 
[2072]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "Pawn.h"
30
[3280]31#include <algorithm>
32
[3196]33#include "core/CoreIncludes.h"
[2896]34#include "core/GameMode.h"
[2072]35#include "core/XMLPort.h"
[3196]36#include "network/NetworkFunction.h"
37
[2662]38#include "PawnManager.h"
[5735]39#include "infos/PlayerInfo.h"
[6417]40#include "controllers/Controller.h"
[5735]41#include "gametypes/Gametype.h"
[5737]42#include "graphics/ParticleSpawner.h"
[5735]43#include "worldentities/ExplosionChunk.h"
44#include "worldentities/BigExplosion.h"
45#include "weaponsystem/WeaponSystem.h"
46#include "weaponsystem/WeaponSlot.h"
47#include "weaponsystem/WeaponPack.h"
48#include "weaponsystem/WeaponSet.h"
[2072]49
[3084]50
[2072]51namespace orxonox
52{
53    CreateFactory(Pawn);
54
[6942]55    Pawn::Pawn(BaseObject* creator) 
56        : ControllableEntity(creator)
[7045]57        , RadarViewable(creator, static_cast<WorldEntity*>(this))
[2072]58    {
59        RegisterObject(Pawn);
60
[2662]61        PawnManager::touch();
62        this->bAlive_ = true;
[3053]63        this->bReload_ = false;
[2072]64
65        this->health_ = 0;
66        this->maxHealth_ = 0;
67        this->initialHealth_ = 0;
[6998]68        this->shieldHealth_ = 0;
69        this->shieldAbsorption_ = 0.5;
[2072]70
71        this->lastHitOriginator_ = 0;
72
[2662]73        this->spawnparticleduration_ = 3.0f;
[2098]74
[6417]75        this->aimPosition_ = Vector3::ZERO;
76
[2896]77        if (GameMode::isMaster())
[2662]78        {
79            this->weaponSystem_ = new WeaponSystem(this);
[3053]80            this->weaponSystem_->setPawn(this);
[2662]81        }
82        else
83            this->weaponSystem_ = 0;
[6998]84
[6711]85        this->setCarrierName("Pawn");
[2662]86
87        this->setRadarObjectColour(ColourValue::Red);
88        this->setRadarObjectShape(RadarViewable::Dot);
89
[2072]90        this->registerVariables();
[3089]91
92        this->isHumanShip_ = this->hasLocalController();
[2072]93    }
94
95    Pawn::~Pawn()
96    {
[2662]97        if (this->isInitialized())
98        {
99            if (this->weaponSystem_)
[5929]100                this->weaponSystem_->destroy();
[2662]101        }
[2072]102    }
103
104    void Pawn::XMLPort(Element& xmlelement, XMLPort::Mode mode)
105    {
106        SUPER(Pawn, XMLPort, xmlelement, mode);
107
[2662]108        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
[2072]109        XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
110        XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
[6998]111
112        XMLPortParam(Pawn, "shieldhealth", setShieldHealth, getShieldHealth, xmlelement, mode).defaultValues(0);
113        XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
114
[2662]115        XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
116        XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
117        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(7);
118
[3053]119        XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
120        XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
[6417]121        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
[2072]122    }
123
124    void Pawn::registerVariables()
125    {
[6998]126        registerVariable(this->bAlive_,           VariableDirection::ToClient);
127        registerVariable(this->health_,           VariableDirection::ToClient);
128        registerVariable(this->initialHealth_,    VariableDirection::ToClient);
129        registerVariable(this->shieldHealth_,     VariableDirection::ToClient);
130        registerVariable(this->shieldAbsorption_, VariableDirection::ToClient);
131        registerVariable(this->bReload_,          VariableDirection::ToServer);
132        registerVariable(this->aimPosition_,      Bidirectionality::ServerMaster, 0, true);
[2072]133    }
134
135    void Pawn::tick(float dt)
136    {
[2809]137        SUPER(Pawn, tick, dt);
[2072]138
[3053]139        this->bReload_ = false;
[2662]140
[3084]141        if (GameMode::isMaster())
[3087]142            if (this->health_ <= 0 && bAlive_)
[6864]143            {
144                this->fireEvent(); // Event to notify anyone who want's to know about the death.
[3087]145                this->death();
[6864]146            }
[2072]147    }
148
[2826]149    void Pawn::setPlayer(PlayerInfo* player)
150    {
151        ControllableEntity::setPlayer(player);
152
153        if (this->getGametype())
154            this->getGametype()->playerStartsControllingPawn(player, this);
155    }
156
157    void Pawn::removePlayer()
158    {
159        if (this->getGametype())
160            this->getGametype()->playerStopsControllingPawn(this->getPlayer(), this);
161
162        ControllableEntity::removePlayer();
163    }
164
[2072]165    void Pawn::setHealth(float health)
166    {
[3280]167        this->health_ = std::min(health, this->maxHealth_);
[2072]168    }
169
170    void Pawn::damage(float damage, Pawn* originator)
171    {
[2826]172        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
173        {
[6998]174            //share the dealt damage to the shield and the Pawn.
175            float shielddamage = damage*this->shieldAbsorption_;
176            float healthdamage = damage*(1-this->shieldAbsorption_);
177
178            // In case the shield can not take all the shield damage.
179            if (shielddamage > this->getShieldHealth())
180            {
181                healthdamage += shielddamage-this->getShieldHealth();
182                this->setShieldHealth(0);
183            }
184
185            this->setHealth(this->health_ - healthdamage);
186
187            if (this->getShieldHealth() > 0)
188            {
189                this->setShieldHealth(this->shieldHealth_ - shielddamage);
190            }
191
[2826]192            this->lastHitOriginator_ = originator;
[2072]193
[2826]194            // play damage effect
195        }
[2072]196    }
197
198    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
199    {
[6417]200        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
[2826]201        {
202            this->damage(damage, originator);
203            this->setVelocity(this->getVelocity() + force);
[2072]204
[2826]205            // play hit effect
206        }
[2072]207    }
208
[6417]209    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
210    {
211        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
212        {
213            this->damage(damage, originator);
214
215            if ( this->getController() )
216                this->getController()->hit(originator, contactpoint, damage);
217
218            // play hit effect
219        }
220    }
221
[2072]222    void Pawn::kill()
223    {
224        this->damage(this->health_);
225        this->death();
226    }
227
[2662]228    void Pawn::spawneffect()
[2072]229    {
230        // play spawn effect
[6417]231        if (!this->spawnparticlesource_.empty())
[2662]232        {
233            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
234            effect->setPosition(this->getPosition());
235            effect->setOrientation(this->getOrientation());
236            effect->setDestroyAfterLife(true);
237            effect->setSource(this->spawnparticlesource_);
238            effect->setLifetime(this->spawnparticleduration_);
239        }
[2072]240    }
241
242    void Pawn::death()
243    {
[3033]244        this->setHealth(1);
[2826]245        if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
246        {
247            // Set bAlive_ to false and wait for PawnManager to do the destruction
248            this->bAlive_ = false;
[2662]249
[2826]250            this->setDestroyWhenPlayerLeft(false);
[2662]251
[3073]252            this->dropItems();
253
[2826]254            if (this->getGametype())
255                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
[2662]256
[3038]257            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
258                this->getPlayer()->stopControl();
[2072]259
[2896]260            if (GameMode::isMaster())
[3087]261            {
262//                this->deathEffect();
263                this->goWithStyle();
264            }
[2826]265        }
[2662]266    }
[3087]267    void Pawn::goWithStyle()
268    {
269        this->bAlive_ = false;
270        this->setDestroyWhenPlayerLeft(false);
[2072]271
[3087]272        BigExplosion* chunk = new BigExplosion(this->getCreator());
273        chunk->setPosition(this->getPosition());
274
275    }
[2662]276    void Pawn::deatheffect()
277    {
[2072]278        // play death effect
[2662]279        {
280            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
281            effect->setPosition(this->getPosition());
282            effect->setOrientation(this->getOrientation());
283            effect->setDestroyAfterLife(true);
284            effect->setSource("Orxonox/explosion2b");
285            effect->setLifetime(4.0f);
286        }
287        {
288            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
289            effect->setPosition(this->getPosition());
290            effect->setOrientation(this->getOrientation());
291            effect->setDestroyAfterLife(true);
292            effect->setSource("Orxonox/smoke6");
293            effect->setLifetime(4.0f);
294        }
295        {
296            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
297            effect->setPosition(this->getPosition());
298            effect->setOrientation(this->getOrientation());
299            effect->setDestroyAfterLife(true);
300            effect->setSource("Orxonox/sparks");
301            effect->setLifetime(4.0f);
302        }
303        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
304        {
305            ExplosionChunk* chunk = new ExplosionChunk(this->getCreator());
306            chunk->setPosition(this->getPosition());
307        }
[2072]308    }
309
[6417]310    void Pawn::fired(unsigned int firemode)
[2098]311    {
[6417]312        if (this->weaponSystem_)
313            this->weaponSystem_->fire(firemode);
[2098]314    }
315
[3053]316    void Pawn::reload()
317    {
318        this->bReload_ = true;
319    }
320
[2072]321    void Pawn::postSpawn()
322    {
323        this->setHealth(this->initialHealth_);
[2896]324        if (GameMode::isMaster())
[2662]325            this->spawneffect();
[2072]326    }
[2662]327
[2893]328    /* WeaponSystem:
329    *   functions load Slot, Set, Pack from XML and make sure all parent-pointers are set.
330    *   with setWeaponPack you can not just load a Pack from XML but if a Pack already exists anywhere, you can attach it.
331    *       --> e.g. Pickup-Items
332    */
[3053]333    void Pawn::addWeaponSlot(WeaponSlot * wSlot)
[2662]334    {
335        this->attach(wSlot);
336        if (this->weaponSystem_)
[3053]337            this->weaponSystem_->addWeaponSlot(wSlot);
[2662]338    }
339
340    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
341    {
342        if (this->weaponSystem_)
[3053]343            return this->weaponSystem_->getWeaponSlot(index);
[2662]344        else
345            return 0;
346    }
347
[3053]348    void Pawn::addWeaponSet(WeaponSet * wSet)
[2662]349    {
350        if (this->weaponSystem_)
[3053]351            this->weaponSystem_->addWeaponSet(wSet);
[2662]352    }
353
[3053]354    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
[2662]355    {
356        if (this->weaponSystem_)
[3053]357            return this->weaponSystem_->getWeaponSet(index);
[2662]358        else
359            return 0;
360    }
361
[3053]362    void Pawn::addWeaponPack(WeaponPack * wPack)
[2662]363    {
364        if (this->weaponSystem_)
[3053]365            this->weaponSystem_->addWeaponPack(wPack);
[2662]366    }
367
[6417]368    void Pawn::addWeaponPackXML(WeaponPack * wPack)
369    {
370        if (this->weaponSystem_)
371            if (!this->weaponSystem_->addWeaponPack(wPack))
372                wPack->destroy();
373    }
374
[3053]375    WeaponPack * Pawn::getWeaponPack(unsigned int index) const
[2662]376    {
377        if (this->weaponSystem_)
[3053]378            return this->weaponSystem_->getWeaponPack(index);
[2662]379        else
380            return 0;
381    }
382
[3089]383    //Tell the Map (RadarViewable), if this is a playership
384    void Pawn::startLocalHumanControl()
385    {
386//        SUPER(ControllableEntity, changedPlayer());
387        ControllableEntity::startLocalHumanControl();
388        this->isHumanShip_ = true;
389    }
[2072]390}
Note: See TracBrowser for help on using the repository browser.