* FAQ    * Search  * Register * Login 
Active topics
Unanswered topics

All times are UTC-06:00



Post new topic  Reply to topic  [ 18 posts ] 
Author Message
 Post subject: Moving between rooms
PostPosted: Tue Jul 10, 2007 10:46 am 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Now I have another problem: one of the functions of my new gametype is a \"teleport\" function, which just moves the player to a different room by resetting the playerobject position-vector to the center of the destination room, and resetting the playerobject roomnumber.

It works perfectly! The player is suddenly in the destination room, just like I wanted. That is, until some point later (usually when flying normally from room to room) when D3 just locks up. No error message, it just dies.

I have been trying to debug this one for hours. Any ideas?


Top
   
 Post subject:
PostPosted: Tue Jul 10, 2007 12:33 pm 
Offline
DBB Alumni
DBB Alumni
User avatar

Joined: Wed Mar 15, 2000 3:01 am
Posts: 8826
Location: Seattle
struct room has an \"objects\" member, which according to room_external.h is the objnum of the first object in the room. If you change the player's roomnum without checking to make sure that the old room's first object index doesn't still point at the player, the game will probably crash when firing On(Server|Client)PlayerChangeSegment.


Top
   
 Post subject:
PostPosted: Tue Jul 10, 2007 12:52 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Ah... I was looking at it from the perspective of a player-object keeping track of which room it was in; I didn't even think to look at whether the room-object kept track of which objects were in it. That's probably the issue, thank you!


Top
   
 Post subject:
PostPosted: Tue Jul 10, 2007 1:09 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Note:

Which of these do you think would be the likeliest to work?

A. Manually setting the object references in the room structs.

B. Manually calling the OnClientChangeSegment event, and passing it the old and new room references.

I figure B., since I figure it would take care of the changes to the room struct for me... but I'm not sure.

[Edit: this is all on the client side.]


Top
   
 Post subject:
PostPosted: Tue Jul 10, 2007 9:56 pm 
Offline
DBB Alumni
DBB Alumni
User avatar

Joined: Wed Mar 15, 2000 3:01 am
Posts: 8826
Location: Seattle
B will not work because OnClientChangeSegment is a callback, not a mutator. And doing it on the client side only will cause an inconsistency between the client and server and probably lead to an assertion failure when the player next changes rooms.


Top
   
 Post subject: Re:
PostPosted: Tue Jul 10, 2007 11:06 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
DCrazy wrote:
B will not work because OnClientChangeSegment is a callback, not a mutator.


Yeah, I realized that after I got home today.

Thanks for the info, though! I'm still new at this; my coding background is mostly VB and web stuff, so I'm having to pick up the C/C++ as I go along. :roll:


Top
   
 Post subject:
PostPosted: Wed Jul 11, 2007 12:10 am 
Offline
DBB Alumni
DBB Alumni
User avatar

Joined: Wed Mar 15, 2000 3:01 am
Posts: 8826
Location: Seattle
No worries, man. I was still relatively green when I wrote Elimination. Working with DMFC finally gave me the courage to attempt to wrangle with COM.


Top
   
 Post subject:
PostPosted: Fri Jul 20, 2007 10:24 am 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
After about a weeks' vacation, I'm getting back to working on this.

I put in some HUD messages as a primitive debugging tool, to see what the room.objects values (and other values) are at different points. After some testing, I can't seem to find any relationship between the room.objects value and the player objnum, so it doesn't seem to be pointing at any player objects. In fact, most of the time, the room.objects value is -1 (which would make sense when there are no objects in the room). I also tried playing around with the player.oldroom value, but still got the crash.

Anyway, since that doesn't seem to be the issue, any more suggestions on where I might look? I think you're right that it's something about the ChangeSegment event when returning to the room I \"teleported\" from, but I'm not sure where to look anymore.


Top
   
 Post subject:
PostPosted: Fri Jul 20, 2007 10:45 am 
Offline
DBB Benefactor
DBB Benefactor
User avatar

Joined: Sun Jun 03, 2001 2:01 am
Posts: 935
Location: Illinois
Heya Foil!

When I wrote Asteroids, I had to create a teleport function for both the warping of the ship from one side of the level to the other and for the hyperspace jump drive. I didn't use Dallas to write the code, I compiled it as a DLL in MSVS however you might be able to glean some useful information from it.
Code:
// Warp player using Hyper Space Jump Drive
void WarpPlayer(int player_handle)
{
   float mult = 800.0f/RAND_HALF;
   msafe_struct mstruct;

   // Determine if player should be killed
   bool bKill=((float)rand()>(RAND_MAX*0.8f));

   // Play appropriate warp sound
   mstruct.objhandle = player_handle;
   mstruct.state     = 1;
   mstruct.index     = (bKill)?Sound_indexes[4]:Sound_indexes[5];
   mstruct.volume    = 1.0f;
   MSafe_CallFunction(MSAFE_SOUND_2D,&mstruct);

   // Set players new position
   MSafe_GetValue(MSAFE_OBJECT_WORLD_POSITION, &mstruct);
   mstruct.pos.x=2000 + mult*((float)rand()-RAND_HALF);
   mstruct.pos.y=mult * ((float)rand()-RAND_HALF);
   mstruct.pos.z=2000 + mult*((float)rand()-RAND_HALF);
   MSafe_CallFunction(MSAFE_OBJECT_WORLD_POSITION, &mstruct);

   // Deform the player
   mstruct.amount   = 0.2f;
   mstruct.lifetime = (bKill)?2.0f:1.0f;
   MSafe_CallFunction(MSAFE_OBJECT_DEFORM,&mstruct);

   // Kill player if dead or shake viewer if player not dead
   if(bKill)
      Obj_Kill(player_handle,OBJECT_HANDLE_NONE,0.0f,-1,0.0f,0.0f);
   else
   {
      mstruct.amount = 40.0f;
      mstruct.scalar = 10.0f;
      MSafe_CallFunction(MSAFE_OBJECT_SHAKE_AREA,&mstruct);
   }
}

I never did get Multiplayer functioning properly but I do think it's possible.


Top
   
 Post subject:
PostPosted: Fri Jul 20, 2007 12:28 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Looks like the relevant part of what you're doing is essentially what I'm doing, as well.

My function does the following:

- Uses the ComputeRoomCenter function to get the center of the \"destination\" room
- Resets the player.pos to that spot (it currently leaves the orientation and velocity matrices alone)
- Resets the player.roomnum to that room handle (otherwise you get the \"hall of mirrors\" effect)
- Resets the playerobject.oldroom to the \"source\" room (the one the player was in before the move)

It's in a .dll, MSVS 2005, packaged into a .d3m.

The problem is that the functions works perfectly, once!... but when the player flies back to the \"source\" room, D3 crashes.


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 1:12 am 
Offline
DBB Benefactor
DBB Benefactor
User avatar

Joined: Sun Jun 03, 2001 2:01 am
Posts: 935
Location: Illinois
Are you using the same function to set the players position?
Are you initializing the mstruct structure properly?

How about posting a snippet of your code for comparison.

And, this code only transports within the same room so that could be causing the problem. Have you tried teleporting within the same room to see if that crashes as well?


Top
   
 Post subject: Re:
PostPosted: Sat Jul 21, 2007 7:22 am 
Offline
DBB Captain
DBB Captain
User avatar

Joined: Sat Apr 26, 2003 2:01 am
Posts: 561
ICQ: 41102315
Website: http://www.planetdescent.com/asp/profileview.asp?pilotid=77&alpha=F
AOL: Floyddle
Location: Germany
SuperSheep wrote:
I never did get Multiplayer functioning properly but I do think it's possible.

sup Sheep :)
it seems to be worked out in the Duel MOD.

Foil, you could also monitor what D3 changes itself when you fly trough a portal. I'd check both the player and both rooms structs. maybe there's something in room structs that keeps record of which objects are inside, which i'm too lazy to look up now ;)


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 10:02 am 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Here's the function:

Code:
//Will move player to an entry room
void DoClientTeleport(void)
{
   vector vPosition;
   int CurrentRoomNumber;
   int NewRoomNumber;

   CurrentRoomNumber = dObjects[dPlayers[DMFCBase->GetPlayerNum()].objnum].roomnum;

   //Get player team
   int team;
   team = DMFCBase->GetMyTeam();

   //Choose a random entry room from the array
   if(team==RED_TEAM){
      //use red entry rooms
      int randomroomindex = rand() % NumberOfRedEntryRooms; //will be an integer in the range [0,NumberOfRedEntryRooms)
      NewRoomNumber = RedEntryRoomNumber[randomroomindex];
   }
   if(team==BLUE_TEAM){
      //use blue entry rooms
      int randomroomindex = rand() % NumberOfBlueEntryRooms; //will be an integer in the range [0,NumberOfBlueEntryRooms)
      NewRoomNumber = BlueEntryRoomNumber[randomroomindex];
   }

   //Get the coordinates for the center of the room
   DLLComputeRoomCenter(&vPosition,&dRooms[NewRoomNumber]);

   //Set the player's coordinates to that point
   memcpy(&dObjects[dPlayers[DMFCBase->GetPlayerNum()].objnum].pos,&vPosition,sizeof(vector));

   //Set the player's room to that room
   dPlayers[DMFCBase->GetPlayerNum()].oldroom = CurrentRoomNumber;
   dObjects[dPlayers[DMFCBase->GetPlayerNum()].objnum].roomnum = NewRoomNumber;
   
   //Display a HUD message
   DLLAddHUDMessage(TXT_ENTRY);
}


It's called only for clients, when certain conditions are met.

FYI, dPlayers and dObjects are exactly as in the Entropy code, NumberOfRedEntryRooms is the number of possible rooms to teleport to, and RedEntryRooms[] is a 0-based array with room handles - that part works fine, it picks a random \"destination\" room correctly.

In fact, the whole function works correctly the first time.


Floyd, I have done a little experimenting with seeing what the room.objects and player-object.room does when going through a portal... there's nothing useful I've seen so far. Of course, I could be missing something obvious.

(P.S. I know, there are easier ways to handle a couple of those variables... I just want to get this working before I start tweaking it.)


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 11:16 am 
Offline
DBB Benefactor
DBB Benefactor
User avatar

Joined: Sun Jun 03, 2001 2:01 am
Posts: 935
Location: Illinois
Now I see why your function is failing. You can not simply set the room number and position in the players structure as D3 does not know that it has changed. You need to move the player using one of the built in functions.

In gamedll_header.h, you will find a huge number of functions. In particular you want the functions for moving an object.

Code:

typedef void( *ObjSetPosNoMark_fp ) (object *objp,vector *newpos,int roomnum,matrix *orient,bool f_update_attached_children);
DMFCDLLOUT(ObjSetPosNoMark_fp DLLObjSetPosNoMark;)

// ObjSetPos, that automatically sets the OF_MOVED_THIS_FRAME
typedef void (*ObjSetPos_fp)(object *obj,vector *pos,int roomnum,matrix *orient,bool f_update_attached_children);
DMFCDLLOUT(ObjSetPos_fp DLLObjSetPos;)



I would write the code to be more usable for any player as well...

Code:
//Will move player to an entry room
void DoClientTeleport(int pnum)
{
  object* obj     = &dObjects[dPlayers[pnum].objnum];
  matrix* orient  = &obj->orient;
  int     newroom = obj->roomnum;
  vector  newpos  = obj->pos;
  int     team    = DMFCBase->GetPlayerTeam(pnum);

  //Choose a random entry room from the array
  if(team == RED_TEAM)
  {
    //use red entry rooms
    newroom = RedEntryRoomNumber[rand() % NumberOfRedEntryRooms];
    DLLComputeRoomCenter(&newpos, &dRooms[newroom]);
  }
  else if(team==BLUE_TEAM)
  {
    //use blue entry rooms
    newroom = BlueEntryRoomNumber(rand() % NumberOfBlueEntryRooms);
    DLLComputeRoomCenter(&newpos, &dRooms[newroom]);
  }

  // Teleport Player
  DLLObjSetPos(obj, &newpos, newroom, &obj->orient, true);
}


This function sets newroom and newpos to the players current room and current position in case they aren't on red or blue team. Simply to protect the function call to setpos.


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 12:07 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
Ah... thanks, SS!

I figured there had to be something not getting moved/re-set properly, I just didn't know what, or how else to move the player. Heck, I had even tried to implement the DALLAS \"FadeAndMovePlayer\" cinematic. :roll:

How I missed the possibility of using that function, I don't know. It should have been obvious:
typedef void (*ObjSetPos_fp)(object *obj,vector *pos,int roomnum,matrix *orient,bool f_update_attached_children);


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 12:46 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
BTW, that works perfectly. :D

Now to round up a teammate or three, and do some more thorough testing!


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 7:30 pm 
Offline
DBB Benefactor
DBB Benefactor
User avatar

Joined: Sun Jun 03, 2001 2:01 am
Posts: 935
Location: Illinois
Glad to hear it. :P

You know, Anticheat is still looking for coders willing to take over. :D


Top
   
 Post subject:
PostPosted: Sat Jul 21, 2007 8:30 pm 
Offline
DBB Material Defender
DBB Material Defender
User avatar

Joined: Tue Nov 23, 2004 3:31 pm
Posts: 4900
Location: Denver, Colorado, USA
So I've heard. :wink:

Seriously, lemme finish this first. I'm also dabbling in D3Edit now, gotta make some levels for this new mod of mine.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 18 posts ] 

All times are UTC-06:00


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Descent'rs have piloted these pages
 
The layout and contents contained within this site are © DescentBB.net 1997-2006.
Descent, Descent II are © Parallax Software Corporation.
Descent III is Outrage Entertainment.
Descent is a Trademark of Interplay Productions.

Miner Wars™ is trademark of Keen Software House s. r. o.
.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group