Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/worldentities/pawns/Pawn.cc @ 8664

Last change on this file since 8664 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 12.6 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 "infos/PlayerInfo.h"
39#include "controllers/Controller.h"
40#include "gametypes/Gametype.h"
41#include "graphics/ParticleSpawner.h"
42#include "worldentities/ExplosionChunk.h"
43#include "worldentities/BigExplosion.h"
44#include "weaponsystem/WeaponSystem.h"
45#include "weaponsystem/WeaponSlot.h"
46#include "weaponsystem/WeaponPack.h"
47#include "weaponsystem/WeaponSet.h"
48
49
50namespace orxonox
51{
52    CreateFactory(Pawn);
53
54    Pawn::Pawn(BaseObject* creator)
55        : ControllableEntity(creator)
56        , RadarViewable(creator, static_cast<WorldEntity*>(this))
57    {
58        RegisterObject(Pawn);
59
60        this->bAlive_ = true;
61        this->bReload_ = false;
62
63        this->health_ = 0;
64        this->maxHealth_ = 0;
65        this->initialHealth_ = 0;
66        this->shieldHealth_ = 0;
67        this->shieldAbsorption_ = 0.5;
68
69        this->lastHitOriginator_ = 0;
70
71        this->spawnparticleduration_ = 3.0f;
72
73        this->aimPosition_ = Vector3::ZERO;
74
75        if (GameMode::isMaster())
76        {
77            this->weaponSystem_ = new WeaponSystem(this);
78            this->weaponSystem_->setPawn(this);
79        }
80        else
81            this->weaponSystem_ = 0;
82
83        this->setRadarObjectColour(ColourValue::Red);
84        this->setRadarObjectShape(RadarViewable::Dot);
85
86        this->registerVariables();
87
88        this->isHumanShip_ = this->hasLocalController();
89       
90        this->setSyncMode(ObjectDirection::Bidirectional); // needed to synchronise e.g. aimposition
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::preDestroy()
148    {
149        // yay, multiple inheritance!
150        this->ControllableEntity::preDestroy();
151        this->PickupCarrier::preDestroy();
152    }
153
154    void Pawn::setPlayer(PlayerInfo* player)
155    {
156        ControllableEntity::setPlayer(player);
157
158        if (this->getGametype())
159            this->getGametype()->playerStartsControllingPawn(player, this);
160    }
161
162    void Pawn::removePlayer()
163    {
164        if (this->getGametype())
165            this->getGametype()->playerStopsControllingPawn(this->getPlayer(), this);
166
167        ControllableEntity::removePlayer();
168    }
169
170    void Pawn::setHealth(float health)
171    {
172        this->health_ = std::min(health, this->maxHealth_);
173    }
174
175    void Pawn::damage(float damage, Pawn* originator)
176    {
177        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
178        {
179            //share the dealt damage to the shield and the Pawn.
180            float shielddamage = damage*this->shieldAbsorption_;
181            float healthdamage = damage*(1-this->shieldAbsorption_);
182
183            // In case the shield can not take all the shield damage.
184            if (shielddamage > this->getShieldHealth())
185            {
186                healthdamage += shielddamage-this->getShieldHealth();
187                this->setShieldHealth(0);
188            }
189
190            this->setHealth(this->health_ - healthdamage);
191
192            if (this->getShieldHealth() > 0)
193            {
194                this->setShieldHealth(this->shieldHealth_ - shielddamage);
195            }
196
197            this->lastHitOriginator_ = originator;
198
199            // play damage effect
200        }
201    }
202
203    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
204    {
205        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
206        {
207            this->damage(damage, originator);
208            this->setVelocity(this->getVelocity() + force);
209
210            // play hit effect
211        }
212    }
213
214    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
215    {
216        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
217        {
218            this->damage(damage, originator);
219
220            if ( this->getController() )
221                this->getController()->hit(originator, contactpoint, damage);
222
223            // play hit effect
224        }
225    }
226
227    void Pawn::kill()
228    {
229        this->damage(this->health_);
230        this->death();
231    }
232
233    void Pawn::spawneffect()
234    {
235        // play spawn effect
236        if (!this->spawnparticlesource_.empty())
237        {
238            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
239            effect->setPosition(this->getPosition());
240            effect->setOrientation(this->getOrientation());
241            effect->setDestroyAfterLife(true);
242            effect->setSource(this->spawnparticlesource_);
243            effect->setLifetime(this->spawnparticleduration_);
244        }
245    }
246
247    void Pawn::death()
248    {
249        this->setHealth(1);
250        if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
251        {
252            // Set bAlive_ to false and wait for PawnManager to do the destruction
253            this->bAlive_ = false;
254
255            this->setDestroyWhenPlayerLeft(false);
256
257            if (this->getGametype())
258                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
259
260            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
261                this->getPlayer()->stopControl();
262
263            if (GameMode::isMaster())
264            {
265//                this->deathEffect();
266                this->goWithStyle();
267            }
268        }
269    }
270    void Pawn::goWithStyle()
271    {
272        this->bAlive_ = false;
273        this->setDestroyWhenPlayerLeft(false);
274
275        BigExplosion* chunk = new BigExplosion(this->getCreator());
276        chunk->setPosition(this->getPosition());
277
278    }
279    void Pawn::deatheffect()
280    {
281        // play death effect
282        {
283            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
284            effect->setPosition(this->getPosition());
285            effect->setOrientation(this->getOrientation());
286            effect->setDestroyAfterLife(true);
287            effect->setSource("Orxonox/explosion2b");
288            effect->setLifetime(4.0f);
289        }
290        {
291            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
292            effect->setPosition(this->getPosition());
293            effect->setOrientation(this->getOrientation());
294            effect->setDestroyAfterLife(true);
295            effect->setSource("Orxonox/smoke6");
296            effect->setLifetime(4.0f);
297        }
298        {
299            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
300            effect->setPosition(this->getPosition());
301            effect->setOrientation(this->getOrientation());
302            effect->setDestroyAfterLife(true);
303            effect->setSource("Orxonox/sparks");
304            effect->setLifetime(4.0f);
305        }
306        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
307        {
308            ExplosionChunk* chunk = new ExplosionChunk(this->getCreator());
309            chunk->setPosition(this->getPosition());
310        }
311    }
312
313    void Pawn::fired(unsigned int firemode)
314    {
315        if (this->weaponSystem_)
316            this->weaponSystem_->fire(firemode);
317    }
318
319    void Pawn::reload()
320    {
321        this->bReload_ = true;
322    }
323
324    void Pawn::postSpawn()
325    {
326        this->setHealth(this->initialHealth_);
327        if (GameMode::isMaster())
328            this->spawneffect();
329    }
330
331    /* WeaponSystem:
332    *   functions load Slot, Set, Pack from XML and make sure all parent-pointers are set.
333    *   with setWeaponPack you can not just load a Pack from XML but if a Pack already exists anywhere, you can attach it.
334    *       --> e.g. Pickup-Items
335    */
336    void Pawn::addWeaponSlot(WeaponSlot * wSlot)
337    {
338        this->attach(wSlot);
339        if (this->weaponSystem_)
340            this->weaponSystem_->addWeaponSlot(wSlot);
341    }
342
343    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
344    {
345        if (this->weaponSystem_)
346            return this->weaponSystem_->getWeaponSlot(index);
347        else
348            return 0;
349    }
350
351    void Pawn::addWeaponSet(WeaponSet * wSet)
352    {
353        if (this->weaponSystem_)
354            this->weaponSystem_->addWeaponSet(wSet);
355    }
356
357    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
358    {
359        if (this->weaponSystem_)
360            return this->weaponSystem_->getWeaponSet(index);
361        else
362            return 0;
363    }
364
365    void Pawn::addWeaponPack(WeaponPack * wPack)
366    {
367        if (this->weaponSystem_)
368        {
369            this->weaponSystem_->addWeaponPack(wPack);
370            this->addedWeaponPack(wPack);
371        }
372    }
373
374    void Pawn::addWeaponPackXML(WeaponPack * wPack)
375    {
376        if (this->weaponSystem_)
377        {
378            if (!this->weaponSystem_->addWeaponPack(wPack))
379                wPack->destroy();
380            else
381                this->addedWeaponPack(wPack);
382        }
383    }
384
385    WeaponPack * Pawn::getWeaponPack(unsigned int index) const
386    {
387        if (this->weaponSystem_)
388            return this->weaponSystem_->getWeaponPack(index);
389        else
390            return 0;
391    }
392
393    //Tell the Map (RadarViewable), if this is a playership
394    void Pawn::startLocalHumanControl()
395    {
396//        SUPER(ControllableEntity, changedPlayer());
397        ControllableEntity::startLocalHumanControl();
398        this->isHumanShip_ = true;
399    }
400}
Note: See TracBrowser for help on using the repository browser.