Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/cleanup/src/world_entities/npcs/npc.cc

Last change on this file was 10618, checked in by bknecht, 18 years ago

merged cleanup into trunk (only improvements)

File size: 12.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer:
16*/
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
18
19
20#include "movement_module.h"
21#include "ai_module.h"
22#include "ai_team.h"
23#include "ai_swarm.h"
24#include "ai_engine.h"
25
26#include "player.h"
27#include "playable.h"
28
29#include "weapons/test_gun.h"
30#include "weapons/turret.h"
31#include "weapons/cannon.h"
32
33#include "loading/factory.h"
34#include "debug.h"
35#include "loading/load_param.h"
36#include "util/loading/load_param_xml.h"
37#include "track/track.h"
38
39#include "particles/dot_emitter.h"
40#include "particles/emitter_node.h"
41#include "particles/sprite_particles.h"
42
43#include "weapons/test_gun.h"
44#include "weapons/light_blaster.h"
45#include "weapons/medium_blaster.h"
46#include "weapons/heavy_blaster.h"
47#include "weapons/swarm_launcher.h"
48#include "weapons/spike_thrower.h"
49#include "weapons/acid_launcher.h"
50#include "weapons/boomerang_gun.h"
51#include "weapons/turret.h"
52#include "weapons/cannon.h"
53
54#include "tools/mount_point.h"
55#include "weapons/weapon_slot.h"
56
57#include "npc.h"
58
59ObjectListDefinition(NPC);
60CREATE_FACTORY(NPC);
61
62
63#include "script_class.h"
64CREATE_SCRIPTABLE_CLASS(NPC,
65                        addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
66                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
67                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
68                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
69                        ->addMethod("setAbsDir", Executor4<PNode, lua_State*,float,float,float,float>(&PNode::setAbsDir))
70                        ->addMethod("fire", Executor0<NPC, lua_State*>(&NPC::fire))
71                        ->addMethod("pause", Executor1<WorldEntity, lua_State*, bool>(&WorldEntity::pauseTrack))
72                        ->addMethod("setAI", Executor1<NPC, lua_State*, bool>(&NPC::setAI))
73                        ->addMethod("setVisibility", Executor1<WorldEntity, lua_State*, bool>(&WorldEntity::setVisibility))
74                        ->addMethod("destroy", Executor0<NPC, lua_State*/*, WorldEntity**/>(&NPC::destroyThis))
75                       );
76
77NPC::NPC(const TiXmlElement* root)
78  : weaponMan(this)
79{
80  this->registerObject(this, NPC::_objectList);
81
82  this->toList(OM_GROUP_00);
83  this->bAIEnabled = false;
84
85
86
87   // create the weapons and their manager
88  Weapon* wpRight1 = new LightBlaster ();
89  wpRight1->setName( "LightBlaster");
90  Weapon* wpLeft1 = new LightBlaster ();
91  wpLeft1->setName( "LightBlaster");
92
93  Weapon* wpRight2 = new MediumBlaster ();
94  wpRight2->setName( "MediumBlaster");
95  Weapon* wpLeft2 = new MediumBlaster ();
96  wpLeft2->setName( "MediumBlaster");
97
98  Weapon* wpRight3 = new HeavyBlaster (1);
99  wpRight3->setName( "HeavyBlaster");
100  Weapon* wpLeft3 = new HeavyBlaster (0);
101  wpLeft3->setName( "HeavyBlaster");
102
103  Weapon* cannon = new SwarmLauncher();
104  cannon->setName( "SwarmLauncher");
105
106  Weapon* spike = new SpikeThrower();
107  spike->setName( "SpikeThrower" );
108
109
110  Weapon* acid0 = new AcidLauncher();
111  acid0->setName( "AcidSplasher" );
112
113  Weapon* acid1 = new AcidLauncher();
114  acid1->setName( "AcidSplasher" );
115
116
117  this->weaponMan.addWeapon( wpLeft1, 0, 0);
118  this->weaponMan.addWeapon( wpRight1, 0, 1);
119
120  this->weaponMan.addWeapon( wpLeft2, 1, 2);
121  this->weaponMan.addWeapon( wpRight2, 1, 3);
122
123  this->weaponMan.addWeapon( wpLeft3, 2, 4);
124  this->weaponMan.addWeapon( wpRight3, 2, 5);
125/*
126  this->weaponMan.addWeapon( wpLeft1, 3, 0);
127  this->weaponMan.addWeapon( wpRight1, 3, 1);
128
129  this->weaponMan.addWeapon( wpLeft2, 3, 2);
130  this->weaponMan.addWeapon( wpRight2, 3, 3);
131
132  this->weaponMan.addWeapon( wpLeft3, 3, 4);
133  this->weaponMan.addWeapon( wpRight3, 3, 5);
134*/
135
136  this->weaponMan.addWeapon( acid0, 3, 0);
137  this->weaponMan.addWeapon( acid1, 3, 1);
138
139
140  if( root != NULL)
141    this->loadParams(root);
142
143  if( this->bAIEnabled && ! this->entityTrack)
144  {
145    std::cout << "Team Number: " << teamNumber << "\n";
146    std::cout << "Swarm Number:" << swarmNumber << "\n";
147
148    AIEngine::getInstance()->addAI(teamNumber,swarmNumber,(WorldEntity*)this,maxSpeed,attackDistance);
149  }
150
151  this->bFire = false;
152  if( this->entityTrack)
153  {
154      this->setParent(this->entityTrack->getTrackNode());
155      this->setRelCoor(0,0,0);
156  }
157
158
159
160
161//   this->secWeaponMan.addWeapon( acid0, 2, 2);
162//   this->secWeaponMan.addWeapon( acid1, 2, 3);
163
164
165//   this->weaponMan.changeWeaponConfig(3);
166
167//   this->getWeaponManager().changeWeaponConfig(1);
168
169  this->setHealthMax(100);
170  this->setHealth(80);
171
172  this->getWeaponManager().setSlotCount(7);
173
174  this->getWeaponManager().setSlotPosition(0, Vector(-2.6, .1, -3.0));
175  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
176
177  this->getWeaponManager().setSlotPosition(1, Vector(-2.6, .1, 3.0));
178  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
179
180  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
181  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
182
183  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
184  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
185
186  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
187  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
188
189  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
190  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
191
192  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
193  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
194
195
196
197  this->getWeaponManager().getFixedTarget()->setParent(this);
198  this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0);
199  this->bInit = false;
200}
201
202
203NPC::~NPC ()
204{
205 if(! this->entityTrack)
206  AIEngine::getInstance()->removeAI(teamNumber,swarmNumber,(WorldEntity*)this);
207}
208
209
210
211/**
212 * loads the xml tags
213 * @param root: root xml tag for this element
214 */
215void NPC::loadParams(const TiXmlElement* root)
216{
217   WorldEntity::loadParams(root);
218
219  LoadParam(root, "enableAI", this, NPC, enableAI)
220      .describe("enables the AI algorithms");
221
222  LoadParam(root, "team", this, NPC, setTeamNumber)
223  .describe("this sets the team number")
224  .defaultValues(0);
225
226  LoadParam(root, "swarm", this, NPC, setSwarmNumber)
227  .describe("this sets the swarm number")
228  .defaultValues(0);
229
230  LoadParam(root, "maxSpeed", this, NPC, setMaxSpeed)
231  .describe("this sets the NPC max Speed")
232  .defaultValues(0);
233
234  LoadParam(root, "attackDistance", this, NPC, setAttackDistance)
235  .describe("this sets the NPC distance to target")
236  .defaultValues(0);
237
238  LoadParam(root, "weapon-config", this, NPC, setWeaponConfig);
239
240//   LoadParamXML(root, "Weapons", this, NPC, addWeapons)
241//   .describe("creates and adds weapons");
242}
243
244void NPC::setAI(bool activate)
245{
246     if(activate) AIEngine::getInstance()->addAI(teamNumber,swarmNumber,(WorldEntity*)this,maxSpeed,attackDistance);
247     else AIEngine::getInstance()->removeAI(teamNumber,swarmNumber,(WorldEntity*)this);
248}
249
250void NPC::destroy( WorldEntity* killer )
251{
252
253  PRINTF(5)("NPC destroy\n");
254
255  EmitterNode* node  = NULL;
256  DotEmitter* emitter = NULL;
257  SpriteParticles*  explosionParticles  = NULL;
258
259  explosionParticles = new SpriteParticles(200);
260  explosionParticles->setName("SpaceShipExplosionParticles");
261  explosionParticles->setLifeSpan(.2, .3);
262  explosionParticles->setRadius(0.0, 10.0);
263  explosionParticles->setRadius(.5, 6.0);
264  explosionParticles->setRadius(1.0, 3.0);
265  explosionParticles->setColor(0.0, 1,1,1,.9);
266  explosionParticles->setColor(0.1,  1,1,0,.9);
267  explosionParticles->setColor(0.5, .8,.4,0,.5);
268  explosionParticles->setColor(1.0, .2,.2,.2,.5);
269
270
271  emitter = new DotEmitter( 2000, 70, 360);
272  //emitter->setSpread( 0, M_2_PI);
273  emitter->setEmissionRate( 200.0);
274  //emitter->setEmissionVelocity( 200.0);
275  //emitter->setSystem( explosionParticles);
276  //emitter->setAbsCoor( this->getAbsCoor());
277
278  node  = new EmitterNode( .1f);
279  node->setupParticle( emitter, explosionParticles);
280  node->setAbsDir( this->getAbsDir());
281  node->setVelocity( this->getVelocity() * .9f);
282  node->setAbsCoor( this->getAbsCoor());
283  if( !node->start())
284    PRINTF(0)("Explosion node not correctly started!");
285/*
286  PNode* node          = new PNode();
287  node->setAbsCoor(this->getAbsCoor());
288  Explosion* explosion = new Explosion();
289  explosion->explode( node, Vector(5,5,5));
290*/
291/*
292  if( this->hasPlayer())
293  {
294        this->setAbsCoor(Vector(-10000,10000,10000));
295        this->hide();
296  }
297  else
298  {*/
299    //this->setAbsCoor( this->getAbsCoor() + Vector(100,0,0) + Vector(1,0,0) * VECTOR_RAND(150).dot(Vector(1,0,0)));
300  //}
301
302  this->toList(OM_NULL);
303  this->setAI( false);
304  this->setAbsCoor(-10000,-10000,-10000);
305
306
307}
308
309void NPC::setWeaponConfig(int i)
310{
311  this->weaponMan.changeWeaponConfig(i);
312}
313
314void NPC::addWeapons(const TiXmlElement* root)
315{
316  if( root == NULL)
317    return;
318
319//   LOAD_PARAM_START_CYCLE(root, element);
320//   {
321// //     PRINTF(0)("got weapon: %s\n", element->Value());
322//     BaseObject* obj = Factory::fabricate(element);
323//     if( obj != NULL && obj->isA( Weapon::staticClassID()))
324//     {
325//       Weapon* w = dynamic_cast<Weapon*>(obj);
326// //       PRINTF(0)("created a weapon\n");
327//       int preferedSlot = w->getPreferedSlot();
328//       int preferedSide = w->getPreferedSide();
329//
330//       this->addWeapon( w, preferedSide, preferedSlot);
331//     }
332//   }
333//   LOAD_PARAM_END_CYCLE(element);
334}
335
336
337/**
338 * @brief adds a Weapon to the NPC.
339 * @param weapon the Weapon to add.
340 * @param configID the Configuration ID to add this weapon to.
341 * @param slotID the slotID to add the Weapon to.
342 */
343bool NPC::addWeapon(Weapon* weapon, int configID, int slotID)
344{
345  weapon->setOwner(this->getOwner());
346
347
348  if(this->weaponMan.addWeapon(weapon, configID, slotID))
349  {
350    return true;
351  }
352  else
353  {
354    if (weapon != NULL)
355      PRINTF(1)("Unable to add Weapon (%s::%s) to %s::%s\n",
356                weapon->getClassCName(), weapon->getCName(), this->getClassCName(), this->getCName());
357    else
358      PRINTF(1)("No weapon defined\n");
359    return false;
360
361  }
362}
363
364/**
365 * @brief removes a Weapon.
366 * @param weapon the Weapon to remove.
367 */
368void NPC::removeWeapon(Weapon* weapon)
369{
370  this->weaponMan.removeWeapon(weapon);
371
372}
373
374/**
375 * @brief jumps to the next WeaponConfiguration
376 */
377void NPC::nextWeaponConfig()
378{
379  this->weaponMan.nextWeaponConfig();
380}
381
382/**
383 * @brief moves to the last WeaponConfiguration
384 */
385void NPC::previousWeaponConfig()
386{
387  this->weaponMan.previousWeaponConfig();
388}
389
390
391
392
393/**
394 * ticking
395 * @param dt  time since last tick
396 */
397void NPC::tick(float dt)
398{
399  if( !this->bInit)
400  {
401    // now get slots from the mount points
402    std::map<int, MountPoint*>::iterator it = this->mountPointMap.begin();
403    for( ;it != this->mountPointMap.end(); it++)
404    {
405      WeaponSlot* ws = dynamic_cast<WeaponSlot*>((*it).second->getMount());
406      if( ws != NULL && ws->isA(WeaponSlot::staticClassID()))
407      {
408        int slot = ws->getWeaponSlot();
409        int side = ws->getWeaponSide();
410        this->getWeaponManager().setSlotPosition(slot, (*it).second->getCenter());
411        this->getWeaponManager().setSlotDirection(slot, ws->getRelDir());
412//         PRINTF(0)("setting slot %i\n", slot);
413//         (*it).second->getCenter().debug();
414      }
415    }
416  this->bInit = true;
417  }
418
419
420
421  this->weaponMan.tick(dt);
422  if (this->bFire)
423  {
424    weaponMan.fire();
425  }
426  this->bFire = false;
427
428 if(this->entityTrack)
429    this->entityTrack->tick(dt);
430
431}
432
433void NPC::draw() const
434{
435 if( this->entityTrack != NULL && this->isDrawTrack())
436  this->entityTrack->drawGraph();
437
438 WorldEntity::draw();
439}
440
441// HACK just to make sure they explode as nice as possible :)
442void NPC::hit( float damage, WorldEntity* killer)
443{
444  this->destroy( killer);
445  this->setDamage(killer->getDamage());
446}
Note: See TracBrowser for help on using the repository browser.