Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5992 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

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