Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/world_entities/npcs/npc.cc @ 10720

Last change on this file since 10720 was 10710, checked in by rennerc, 18 years ago

player cannot shoot throu walls
per default worldentities cannot be killed
weapon correct again

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(); //FIXME / REMOVE: is not used
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 :)
442/*void 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.