Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7043 was 6998, checked in by dafrick, 14 years ago

Merged pickup branch into presentation3 branch.
Seems to be working just fine so not much changes at all. (Except for some representations that had the parameters 'name' instead of 'pickupName' and 'description' instead of 'pickupDescription').

  • Property svn:eol-style set to native
File size: 12.3 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)
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->setCarrierName("Pawn");
86
87        this->setRadarObjectColour(ColourValue::Red);
88        this->setRadarObjectShape(RadarViewable::Dot);
89
90        this->registerVariables();
91
92        this->isHumanShip_ = this->hasLocalController();
93    }
94
95    Pawn::~Pawn()
96    {
97        if (this->isInitialized())
98        {
99            if (this->weaponSystem_)
100                this->weaponSystem_->destroy();
101        }
102    }
103
104    void Pawn::XMLPort(Element& xmlelement, XMLPort::Mode mode)
105    {
106        SUPER(Pawn, XMLPort, xmlelement, mode);
107
108        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
109        XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
110        XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
111
112        XMLPortParam(Pawn, "shieldhealth", setShieldHealth, getShieldHealth, xmlelement, mode).defaultValues(0);
113        XMLPortParam(Pawn, "shieldabsorption", setShieldAbsorption, getShieldAbsorption, xmlelement, mode).defaultValues(0);
114
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
119        XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
120        XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
121        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
122    }
123
124    void Pawn::registerVariables()
125    {
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);
133    }
134
135    void Pawn::tick(float dt)
136    {
137        SUPER(Pawn, tick, dt);
138
139        this->bReload_ = false;
140
141        if (GameMode::isMaster())
142            if (this->health_ <= 0 && bAlive_)
143            {
144                this->fireEvent(); // Event to notify anyone who want's to know about the death.
145                this->death();
146            }
147    }
148
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
165    void Pawn::setHealth(float health)
166    {
167        this->health_ = std::min(health, this->maxHealth_);
168    }
169
170    void Pawn::damage(float damage, Pawn* originator)
171    {
172        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
173        {
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
192            this->lastHitOriginator_ = originator;
193
194            // play damage effect
195        }
196    }
197
198    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
199    {
200        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
201        {
202            this->damage(damage, originator);
203            this->setVelocity(this->getVelocity() + force);
204
205            // play hit effect
206        }
207    }
208
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
222    void Pawn::kill()
223    {
224        this->damage(this->health_);
225        this->death();
226    }
227
228    void Pawn::spawneffect()
229    {
230        // play spawn effect
231        if (!this->spawnparticlesource_.empty())
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        }
240    }
241
242    void Pawn::death()
243    {
244        this->setHealth(1);
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;
249
250            this->setDestroyWhenPlayerLeft(false);
251
252            this->dropItems();
253
254            if (this->getGametype())
255                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
256
257            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
258                this->getPlayer()->stopControl();
259
260            if (GameMode::isMaster())
261            {
262//                this->deathEffect();
263                this->goWithStyle();
264            }
265        }
266    }
267    void Pawn::goWithStyle()
268    {
269        this->bAlive_ = false;
270        this->setDestroyWhenPlayerLeft(false);
271
272        BigExplosion* chunk = new BigExplosion(this->getCreator());
273        chunk->setPosition(this->getPosition());
274
275    }
276    void Pawn::deatheffect()
277    {
278        // play death effect
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        }
308    }
309
310    void Pawn::fired(unsigned int firemode)
311    {
312        if (this->weaponSystem_)
313            this->weaponSystem_->fire(firemode);
314    }
315
316    void Pawn::reload()
317    {
318        this->bReload_ = true;
319    }
320
321    void Pawn::postSpawn()
322    {
323        this->setHealth(this->initialHealth_);
324        if (GameMode::isMaster())
325            this->spawneffect();
326    }
327
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    */
333    void Pawn::addWeaponSlot(WeaponSlot * wSlot)
334    {
335        this->attach(wSlot);
336        if (this->weaponSystem_)
337            this->weaponSystem_->addWeaponSlot(wSlot);
338    }
339
340    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
341    {
342        if (this->weaponSystem_)
343            return this->weaponSystem_->getWeaponSlot(index);
344        else
345            return 0;
346    }
347
348    void Pawn::addWeaponSet(WeaponSet * wSet)
349    {
350        if (this->weaponSystem_)
351            this->weaponSystem_->addWeaponSet(wSet);
352    }
353
354    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
355    {
356        if (this->weaponSystem_)
357            return this->weaponSystem_->getWeaponSet(index);
358        else
359            return 0;
360    }
361
362    void Pawn::addWeaponPack(WeaponPack * wPack)
363    {
364        if (this->weaponSystem_)
365            this->weaponSystem_->addWeaponPack(wPack);
366    }
367
368    void Pawn::addWeaponPackXML(WeaponPack * wPack)
369    {
370        if (this->weaponSystem_)
371            if (!this->weaponSystem_->addWeaponPack(wPack))
372                wPack->destroy();
373    }
374
375    WeaponPack * Pawn::getWeaponPack(unsigned int index) const
376    {
377        if (this->weaponSystem_)
378            return this->weaponSystem_->getWeaponPack(index);
379        else
380            return 0;
381    }
382
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    }
390}
Note: See TracBrowser for help on using the repository browser.