Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/world_entities/spawning_point.cc @ 9537

Last change on this file since 9537 was 9522, checked in by patrick, 18 years ago

new the message handler is checking, if this message is also for the local host. if not the system tries to relay the message

File size: 6.4 KB
Line 
1
2/*
3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12### File Specific:
13   main-programmer: Patrick Boenzli
14   co-programmer:
15*/
16
17#include "spawning_point.h"
18
19#include "util/loading/load_param.h"
20#include "util/loading/factory.h"
21
22#include "world_entity.h"
23
24#include "class_list.h"
25
26#include "compiler.h"
27
28#include "state.h"
29#include "game_rules.h"
30
31#include "shared_network_data.h"
32
33
34/// TODO REMOVE converter.h
35#include "converter.h"
36
37CREATE_FACTORY( SpawningPoint, CL_SPAWNING_POINT );
38
39/**
40 *  constructor
41 */
42SpawningPoint::SpawningPoint( const TiXmlElement * root )
43{
44  this->setAbsCoor( 0, 0, 0 );
45
46  this->init();
47
48  if (root != NULL)
49    this->loadParams(root);
50}
51
52void SpawningPoint::init()
53{
54  this->setClassID(CL_SPAWNING_POINT, "SpawningPoint");
55  PRINTF(0)("Created SpawningPoint\n");
56
57  this->teamId = -1;
58  this->localTimer = 0.0f;
59
60  this->toList( OM_DEAD_TICK );
61
62  MessageManager::getInstance()->registerMessageHandler( MSGID_RESPAWN, respawnMessageHandler, NULL );
63
64  this->setSynchronized( true );
65}
66
67
68/**
69 *  deconstructor
70 */
71SpawningPoint::~SpawningPoint ()
72{}
73
74
75/**
76 * loads the WorldEntity Specific Parameters.
77 * @param root: the XML-Element to load the Data From
78 */
79void SpawningPoint::loadParams(const TiXmlElement* root)
80{
81  /* let the world entity its stuff first */
82  WorldEntity::loadParams(root);
83
84  /* load teamId */
85  LoadParam(root, "teamId", this, SpawningPoint, setTeamId)
86      .describe("sets teamId");
87}
88
89
90
91/**
92 * pushes a world entity to the spawning queue
93 *  @param entity WorldEntity to be added
94 */
95void SpawningPoint::pushEntity(Playable* entity, float delay)
96{
97  QueueEntry qe;
98  qe.entity = entity;
99  qe.respawnTime = this->localTimer + delay;
100
101  queue.push_back( qe );
102}
103
104
105/**
106 *  spawn the entity
107 */
108void SpawningPoint::spawn(Playable* entity)
109{
110  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
111
112  bool found = false;
113
114  if ( !list )
115    return;
116
117  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
118  {
119    if ( *it == entity )
120    {
121      found = true;
122      break;
123    }
124  }
125
126  if ( !found )
127    return;
128
129  PRINTF(0)("Spawningpoint spawns Entity (%s)\n", entity->getClassCName());
130
131
132  entity->setAbsCoor( this->getAbsCoor() );
133  entity->setAbsDir( this->getAbsDir() );
134
135  //TODO set camera (not smooth)
136
137  if ( State::getGameRules() )
138  {
139    (State::getGameRules())->registerSpawn( entity );
140  }
141
142  entity->respawn();
143}
144
145
146/**
147 *  this method is called every frame
148 * @param time: the time in seconds that has passed since the last tick
149 *
150 * Handle all stuff that should update with time inside this method (movement, animation, etc.)
151 */
152void SpawningPoint::tick(float dt)
153{
154  this->localTimer += dt;
155  std::list<QueueEntry>::iterator it = this->queue.begin();
156  for( ; it != this->queue.end(); )
157  {
158    //PRINTF(0)("%f <= %f\n", it->respawnTime, this->localTimer);
159    if( it->respawnTime <= this->localTimer)
160    {
161      //spawn the player
162      this->spawn(it->entity);
163
164      const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
165
166      bool found = false;
167
168      if ( !list )
169        return;
170
171      for ( std::list<BaseObject*>::const_iterator it2 = list->begin(); it2 != list->end(); it2++ )
172      {
173        if ( *it2 == it->entity )
174        {
175          found = true;
176          break;
177        }
178      }
179
180      if ( found && SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
181        this->sendRespawnMessage( it->entity->getUniqueID() );
182
183      std::list<QueueEntry>::iterator delit = it;
184      it++;
185
186      queue.erase( delit );
187
188      continue;
189    }
190
191    it++;
192  }
193
194}
195
196
197/**
198 *  the entity is drawn onto the screen with this function
199 *
200 * This is a central function of an entity: call it to let the entity painted to the screen.
201 * Just override this function with whatever you want to be drawn.
202 */
203void SpawningPoint::draw() const
204{
205}
206
207void SpawningPoint::sendRespawnMessage( int uniqueId )
208{
209#warning this byte array is not being deleted according to valginrd
210  byte * buf = new byte[2*INTSIZE];
211
212  assert( Converter::intToByteArray( this->getUniqueID(), buf, INTSIZE ) == INTSIZE );
213  assert( Converter::intToByteArray( uniqueId, buf + INTSIZE, INTSIZE ) == INTSIZE );
214
215  MessageManager::getInstance()->sendMessage( MSGID_RESPAWN, buf, 2*INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
216}
217
218/**
219 * message handler for respawn message
220 */
221bool SpawningPoint::respawnMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
222{
223  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
224  {
225    PRINTF(2)("server received spawn message!\n");
226    return true;
227  }
228
229  int spUniqueId;
230  int uniqueId;
231
232  if ( dataLength != 2*INTSIZE )
233  {
234    PRINTF(2)("spawn message has wrong size: %d\n", dataLength );
235    return true;
236  }
237
238  assert( Converter::byteArrayToInt( data, &spUniqueId ) == INTSIZE );
239  assert( Converter::byteArrayToInt( data+INTSIZE, &uniqueId ) == INTSIZE );
240
241  PRINTF(0)("SPAWNMESSAGE %d\n", uniqueId);
242
243  SpawningPoint * sp = NULL;
244  Playable      * playable = NULL;
245
246  const std::list<BaseObject*> * list = ClassList::getList( CL_SPAWNING_POINT );
247
248  if ( list )
249  {
250    for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
251    {
252      PRINTF(0)("%d:%d\n", dynamic_cast<SpawningPoint*>(*it)->getUniqueID(), spUniqueId);
253      if ( dynamic_cast<SpawningPoint*>(*it)->getUniqueID() == spUniqueId )
254      {
255        sp = dynamic_cast<SpawningPoint*>(*it);
256        break;
257      }
258    }
259  }
260
261  if ( !sp )
262  {
263    PRINTF(0)("could not find spawning point\n");
264    return false;
265  }
266
267  list = ClassList::getList( CL_PLAYABLE );
268
269  if ( list )
270  {
271    for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
272    {
273      if ( dynamic_cast<Playable*>(*it)->getUniqueID() == uniqueId )
274      {
275        playable = dynamic_cast<Playable*>(*it);
276        break;
277      }
278    }
279  }
280
281  if ( !playable )
282  {
283    PRINTF(0)("could not find playable\n");
284    return false;
285  }
286
287  sp->spawn( playable );
288
289  return true;
290}
291
Note: See TracBrowser for help on using the repository browser.