Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Created a new MutliTrigger: EventMultiTrigger, which essentially does the same as EventTrigger but for every object that is a target as specified by teh EventMultiTrigger an Event is fired with information as being triggered by the target object.
This allows, e.g. to use the EventMultiTrigger to trigger QuestEffectBeacons.
I've also added a fireEvent() to Pawn such that an Event is fired when the Pawn is destroyed (forcebly). With EventMultiTrigger (but also with EventTrigger) one can now find out whether a Pawn died.
Here a little piece of example XML code to illustrate the usage:
<EventMutliTrigger name="trigger1">

<events>

<trigger>

<Spaceship />

</trigger>

</events>

</EventMultiTrigger>
To be able to implement this another feature was added to MultiTrigger, which is called broadcast. If enabled the MultiTrigger sends all Events triggered by NULL as to have come by all possible triggerers.

Additionally I've fixed a bug:
In DistanceMultiTrigger, an infinite loop occured under some circumstances. Not any more.

And did some niceifying (aka. documenting, renaming and code restructuring).

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