Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/data_cleanup/src/orxonox/worldentities/pawns/Pawn.cc @ 7559

Last change on this file since 7559 was 7533, checked in by dafrick, 14 years ago

Documenting in pickups module.
Cleaning up in PickupManager.
Removed some obsolete functions in HumanController and ControllableEntity, which were remenants of the old pickups module.
Fixed a bug.

  • Property svn:eol-style set to native
File size: 12.4 KB
Line 
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
31#include <algorithm>
32
33#include "core/CoreIncludes.h"
34#include "core/GameMode.h"
35#include "core/XMLPort.h"
36#include "network/NetworkFunction.h"
37
38#include "PawnManager.h"
39#include "infos/PlayerInfo.h"
40#include "controllers/Controller.h"
41#include "gametypes/Gametype.h"
42#include "graphics/ParticleSpawner.h"
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"
49
50
51namespace orxonox
52{
53    CreateFactory(Pawn);
54
55    Pawn::Pawn(BaseObject* creator)
56        : ControllableEntity(creator)
57        , RadarViewable(creator, static_cast<WorldEntity*>(this))
58    {
59        RegisterObject(Pawn);
60
61        PawnManager::touch();
62        this->bAlive_ = true;
63        this->bReload_ = false;
64
65        this->health_ = 0;
66        this->maxHealth_ = 0;
67        this->initialHealth_ = 0;
68        this->shieldHealth_ = 0;
69        this->shieldAbsorption_ = 0.5;
70
71        this->lastHitOriginator_ = 0;
72
73        this->spawnparticleduration_ = 3.0f;
74
75        this->aimPosition_ = Vector3::ZERO;
76
77        if (GameMode::isMaster())
78        {
79            this->weaponSystem_ = new WeaponSystem(this);
80            this->weaponSystem_->setPawn(this);
81        }
82        else
83            this->weaponSystem_ = 0;
84
85        this->setRadarObjectColour(ColourValue::Red);
86        this->setRadarObjectShape(RadarViewable::Dot);
87
88        this->registerVariables();
89
90        this->isHumanShip_ = this->hasLocalController();
91    }
92
93    Pawn::~Pawn()
94    {
95        if (this->isInitialized())
96        {
97            if (this->weaponSystem_)
98                this->weaponSystem_->destroy();
99        }
100    }
101
102    void Pawn::XMLPort(Element& xmlelement, XMLPort::Mode mode)
103    {
104        SUPER(Pawn, XMLPort, xmlelement, mode);
105
106        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
107        XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
108        XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
109
110        XMLPortParam(Pawn, "shieldhealth", setShieldHealth, getShieldHealth, xmlelement, mode).defaultValues(0);
111        XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
112
113        XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
114        XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
115        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(7);
116
117        XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
118        XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
119        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
120    }
121
122    void Pawn::registerVariables()
123    {
124        registerVariable(this->bAlive_,           VariableDirection::ToClient);
125        registerVariable(this->health_,           VariableDirection::ToClient);
126        registerVariable(this->initialHealth_,    VariableDirection::ToClient);
127        registerVariable(this->shieldHealth_,     VariableDirection::ToClient);
128        registerVariable(this->shieldAbsorption_, VariableDirection::ToClient);
129        registerVariable(this->bReload_,          VariableDirection::ToServer);
130        registerVariable(this->aimPosition_,      VariableDirection::ToServer);  // For the moment this variable gets only transfered to the server
131    }
132
133    void Pawn::tick(float dt)
134    {
135        SUPER(Pawn, tick, dt);
136
137        this->bReload_ = false;
138
139        if (GameMode::isMaster())
140            if (this->health_ <= 0 && bAlive_)
141            {
142                this->fireEvent(); // Event to notify anyone who want's to know about the death.
143                this->death();
144            }
145    }
146
147    void Pawn::setPlayer(PlayerInfo* player)
148    {
149        ControllableEntity::setPlayer(player);
150
151        if (this->getGametype())
152            this->getGametype()->playerStartsControllingPawn(player, this);
153    }
154
155    void Pawn::removePlayer()
156    {
157        if (this->getGametype())
158            this->getGametype()->playerStopsControllingPawn(this->getPlayer(), this);
159
160        ControllableEntity::removePlayer();
161    }
162
163    void Pawn::setHealth(float health)
164    {
165        this->health_ = std::min(health, this->maxHealth_);
166    }
167
168    void Pawn::damage(float damage, Pawn* originator)
169    {
170        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
171        {
172            //share the dealt damage to the shield and the Pawn.
173            float shielddamage = damage*this->shieldAbsorption_;
174            float healthdamage = damage*(1-this->shieldAbsorption_);
175
176            // In case the shield can not take all the shield damage.
177            if (shielddamage > this->getShieldHealth())
178            {
179                healthdamage += shielddamage-this->getShieldHealth();
180                this->setShieldHealth(0);
181            }
182
183            this->setHealth(this->health_ - healthdamage);
184
185            if (this->getShieldHealth() > 0)
186            {
187                this->setShieldHealth(this->shieldHealth_ - shielddamage);
188            }
189
190            this->lastHitOriginator_ = originator;
191
192            // play damage effect
193        }
194    }
195
196    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
197    {
198        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
199        {
200            this->damage(damage, originator);
201            this->setVelocity(this->getVelocity() + force);
202
203            // play hit effect
204        }
205    }
206
207    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
208    {
209        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
210        {
211            this->damage(damage, originator);
212
213            if ( this->getController() )
214                this->getController()->hit(originator, contactpoint, damage);
215
216            // play hit effect
217        }
218    }
219
220    void Pawn::kill()
221    {
222        this->damage(this->health_);
223        this->death();
224    }
225
226    void Pawn::spawneffect()
227    {
228        // play spawn effect
229        if (!this->spawnparticlesource_.empty())
230        {
231            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
232            effect->setPosition(this->getPosition());
233            effect->setOrientation(this->getOrientation());
234            effect->setDestroyAfterLife(true);
235            effect->setSource(this->spawnparticlesource_);
236            effect->setLifetime(this->spawnparticleduration_);
237        }
238    }
239
240    void Pawn::death()
241    {
242        this->setHealth(1);
243        if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
244        {
245            // Set bAlive_ to false and wait for PawnManager to do the destruction
246            this->bAlive_ = false;
247
248            this->setDestroyWhenPlayerLeft(false);
249
250            if (this->getGametype())
251                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
252
253            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
254                this->getPlayer()->stopControl();
255
256            if (GameMode::isMaster())
257            {
258//                this->deathEffect();
259                this->goWithStyle();
260            }
261        }
262    }
263    void Pawn::goWithStyle()
264    {
265        this->bAlive_ = false;
266        this->setDestroyWhenPlayerLeft(false);
267
268        BigExplosion* chunk = new BigExplosion(this->getCreator());
269        chunk->setPosition(this->getPosition());
270
271    }
272    void Pawn::deatheffect()
273    {
274        // play death effect
275        {
276            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
277            effect->setPosition(this->getPosition());
278            effect->setOrientation(this->getOrientation());
279            effect->setDestroyAfterLife(true);
280            effect->setSource("Orxonox/explosion2b");
281            effect->setLifetime(4.0f);
282        }
283        {
284            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
285            effect->setPosition(this->getPosition());
286            effect->setOrientation(this->getOrientation());
287            effect->setDestroyAfterLife(true);
288            effect->setSource("Orxonox/smoke6");
289            effect->setLifetime(4.0f);
290        }
291        {
292            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
293            effect->setPosition(this->getPosition());
294            effect->setOrientation(this->getOrientation());
295            effect->setDestroyAfterLife(true);
296            effect->setSource("Orxonox/sparks");
297            effect->setLifetime(4.0f);
298        }
299        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
300        {
301            ExplosionChunk* chunk = new ExplosionChunk(this->getCreator());
302            chunk->setPosition(this->getPosition());
303        }
304    }
305
306    void Pawn::fired(unsigned int firemode)
307    {
308        if (this->weaponSystem_)
309            this->weaponSystem_->fire(firemode);
310    }
311
312    void Pawn::reload()
313    {
314        this->bReload_ = true;
315    }
316
317    void Pawn::postSpawn()
318    {
319        this->setHealth(this->initialHealth_);
320        if (GameMode::isMaster())
321            this->spawneffect();
322    }
323
324    /* WeaponSystem:
325    *   functions load Slot, Set, Pack from XML and make sure all parent-pointers are set.
326    *   with setWeaponPack you can not just load a Pack from XML but if a Pack already exists anywhere, you can attach it.
327    *       --> e.g. Pickup-Items
328    */
329    void Pawn::addWeaponSlot(WeaponSlot * wSlot)
330    {
331        this->attach(wSlot);
332        if (this->weaponSystem_)
333            this->weaponSystem_->addWeaponSlot(wSlot);
334    }
335
336    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
337    {
338        if (this->weaponSystem_)
339            return this->weaponSystem_->getWeaponSlot(index);
340        else
341            return 0;
342    }
343
344    void Pawn::addWeaponSet(WeaponSet * wSet)
345    {
346        if (this->weaponSystem_)
347            this->weaponSystem_->addWeaponSet(wSet);
348    }
349
350    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
351    {
352        if (this->weaponSystem_)
353            return this->weaponSystem_->getWeaponSet(index);
354        else
355            return 0;
356    }
357
358    void Pawn::addWeaponPack(WeaponPack * wPack)
359    {
360        if (this->weaponSystem_)
361        {
362            this->weaponSystem_->addWeaponPack(wPack);
363            this->addedWeaponPack(wPack);
364        }
365    }
366
367    void Pawn::addWeaponPackXML(WeaponPack * wPack)
368    {
369        if (this->weaponSystem_)
370        {
371            if (!this->weaponSystem_->addWeaponPack(wPack))
372                wPack->destroy();
373            else
374                this->addedWeaponPack(wPack);
375        }
376    }
377
378    WeaponPack * Pawn::getWeaponPack(unsigned int index) const
379    {
380        if (this->weaponSystem_)
381            return this->weaponSystem_->getWeaponPack(index);
382        else
383            return 0;
384    }
385
386    //Tell the Map (RadarViewable), if this is a playership
387    void Pawn::startLocalHumanControl()
388    {
389//        SUPER(ControllableEntity, changedPlayer());
390        ControllableEntity::startLocalHumanControl();
391        this->isHumanShip_ = true;
392    }
393}
Note: See TracBrowser for help on using the repository browser.