35 currentRegionX = currentRegionY = INT_MIN;
37 playerTimer =
new cMessage(
"playerTimeout");
42 cancelAndDelete(playerTimer);
47 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
50 globalStatistics->addStdDev(
"SimMUD: Lost or too long delayed MoveLists/s",
51 lostMovementLists / time);
52 globalStatistics->addStdDev(
"SimMUD: Received valid MoveLists/s",
53 receivedMovementLists / time);
58 if( stage != (numInitStages()-1)) {
63 fieldSize = par(
"areaDimension");
64 numSubspaces = par(
"numSubspaces");
65 regionSize = fieldSize / numSubspaces;
66 playerTimeout = par(
"playerTimeout");
68 receivedMovementLists = 0;
69 lostMovementLists = 0;
71 maxMoveDelay = par(
"maxMoveDelay");
72 AOIWidth = par(
"AOIWidth");
74 WATCH(currentRegionX);
75 WATCH(currentRegionY);
76 WATCH(currentRegionID);
89 cPolymorphic* context,
90 int rpcId, simtime_t rtt )
98 if( msg == playerTimer ) {
100 map<NodeHandle, PlayerInfo>::iterator it;
101 list<NodeHandle> erasePlayers;
102 for( it = playerMap.begin(); it != playerMap.end(); ++it ) {
103 if( it->second.update ==
false ) {
104 erasePlayers.push_back( it->first );
106 it->second.update =
false;
108 for( list<NodeHandle>::iterator it = erasePlayers.begin(); it != erasePlayers.end(); ++it) {
114 send(scMsg,
"to_upperTier");
116 playerMap.erase( *it );
118 erasePlayers.clear();
120 scheduleAt( simTime() + playerTimeout, msg );
127 dynamic_cast<ALMMulticastMessage*>(msg) ){
129 cMessage* innerMsg = mcastMsg->decapsulate();
135 handleOtherPlayerMove( moveMsg );
145 if( getThisCompType() - msg->
getComp() == 1 ){
148 msg->
setComp(getThisCompType());
149 send(msg,
"to_upperTier");
154 send(gameMsg,
"to_upperTier");
156 if( playerTimeout > 0 ) {
157 cancelEvent( playerTimer );
158 scheduleAt( simTime() + playerTimeout, playerTimer );
169 dynamic_cast<GameAPIPositionMessage*>(msg) ) {
170 handleMove( moveMsg );
177 if( (
int) (msg->
getPosition().
x/regionSize) != currentRegionX ||
178 (
int) (msg->
getPosition().
y/regionSize) != currentRegionY ) {
182 currentRegionX = (int) (msg->
getPosition().
x/regionSize);
183 currentRegionY = (int) (msg->
getPosition().
y/regionSize);
184 std::stringstream regionstr;
185 regionstr << currentRegionX <<
":" << currentRegionY;
187 currentRegionID = region;
190 set<OverlayKey> expectedRegions;
191 set<OverlayKey> allowedRegions;
192 int minX = (int) ((msg->
getPosition().
x - AOIWidth)/regionSize);
193 if( minX < 0 ) minX = 0;
194 int maxX = (int) ((msg->
getPosition().
x + AOIWidth)/regionSize);
195 if( maxX >= numSubspaces ) maxX = numSubspaces -1;
196 int minY = (int) ((msg->
getPosition().
y - AOIWidth)/regionSize);
197 if( minY < 0 ) minY = 0;
198 int maxY = (int) ((msg->
getPosition().
y + AOIWidth)/regionSize);
199 if( maxY >= numSubspaces ) maxY = numSubspaces -1;
202 int minUnsubX = (int) ((msg->
getPosition().
x - 1.5*AOIWidth)/regionSize);
203 if( minUnsubX < 0 ) minUnsubX = 0;
204 int maxUnsubX = (int) ((msg->
getPosition().
x + 1.5*AOIWidth)/regionSize);
205 if( maxUnsubX >= numSubspaces ) maxUnsubX = numSubspaces -1;
206 int minUnsubY = (int) ((msg->
getPosition().
y - 1.5*AOIWidth)/regionSize);
207 if( minUnsubY < 0 ) minUnsubY = 0;
208 int maxUnsubY = (int) ((msg->
getPosition().
y + 1.5+AOIWidth)/regionSize);
209 if( maxUnsubY >= numSubspaces ) maxUnsubY = numSubspaces -1;
211 for(
int x = minUnsubX; x <= maxUnsubX; ++x ){
212 for(
int y = minUnsubY; y <= maxUnsubY; ++y ){
213 std::stringstream regionstr;
214 regionstr << x <<
":" << y;
215 if( x >= minX && x <=maxX && y >= minY && y <= maxY ){
222 set<OverlayKey>::iterator subIt = subscribedRegions.begin();
223 while( subIt != subscribedRegions.end() ){
225 expectedRegions.erase( *subIt );
228 if( allowedRegions.find( *subIt ) == allowedRegions.end() ){
231 moveMsg->
setSrc( overlay->getThisNode() );
238 mcastMsg->encapsulate( moveMsg );
240 send(mcastMsg,
"to_lowerTier");
245 send(leaveMsg,
"to_lowerTier");
249 subscribedRegions.erase( subIt++ );
256 for( set<OverlayKey>::iterator regionIt = expectedRegions.begin(); regionIt != expectedRegions.end(); ++regionIt ){
260 send( subMsg,
"to_lowerTier" );
262 subscribedRegions.insert( *regionIt );
268 moveMsg->
setSrc( overlay->getThisNode() );
275 mcastMsg->encapsulate( moveMsg );
277 send(mcastMsg,
"to_lowerTier");
289 globalStatistics->addStdDev(
"SimMUD: LOST MOVE Delay",
292 ++receivedMovementLists;
295 if( src != overlay->getThisNode() ){
296 globalStatistics->addStdDev(
"SimMUD: MOVE Delay",
305 playerMap.erase( src );
313 playerMap.insert( make_pair(src, player) );
328 send(scMsg,
"to_upperTier");