[SOLVED]Why sending entity with FTE is so hard?
Posted: Sun Sep 14, 2014 9:22 pm
Ola guys!
I'm here to bother you again, CSQC mentors!
CASE:
simple mixture of SSQC + CSQC to spawn a player on a map. Nothing else. Let's start simple.
DP
on the client I create the SendEntity function
On CSQC I read these values in the CSQC_Ent_Update() function and launch the "check player" func if player is new
DONE.
I can see my shiny Quake3 map and that's it
FTE
...now here come the troubles!!
If you do something similar above, the map won't load: black screen, no errors, no warnings (and that's a bit annoying, I must say)
I want to clarify that I completely replaced CSQC DP defs with the command "pr_dumpplatform -FFTE -TCS -O csplat".
Then I replaced the CSQC part with cleancsqc.
This time map loads but only if I comment the SSQC and CSQC part of read/write values.
I studied A LOT csqctest and it uses a pretty obscure (at least for me) construction to send values from SSQC to SSQC.
Both SSQC AND CSQC share a classes.qc file
Interested line is #define eclasses eclass(CLASS_ROCKET, ParseRocketClass) eclass(CLASS_GIB, ParseGibbing) eclass(CLASS_PLAYER, ParsePlayer) eclass(CLASS_EXPLOSION, ParseExplosion) eclass(CLASS_NAIL, ParseNailClass)
Now, my mind completely refuses to understand the #DEFINE directives, ok, but... what's the difference with the code I used?
CLASS_PLAYER is used in SSQC/client.qc
and ParsePlayer in CSQC/player.qc
First, I can't understand where ParsePlayer is called (not in CSQC_Ent_Update for sure), second: again.. what's the difference with the code I used?
Last funny thing: If I compile csqctest on svn FTE, quake(1)maps work great, instead my custom Quake 3 maps are not visible again!!
Here a little test I made with DP and FTE. Very basic pack: a map, an exe(only Win version, sorry), simple code and a bunch of silly assets!
In the FTE zip you find two code folders, one similar to DP's one (code_simple), with the only difference in FTE functions names and defs files, the other (code_cleancsqc) with the csqc part completely taken from cleancsqc
Please let me know if someone had same problems with FTE!
Thanks in advance
I'm here to bother you again, CSQC mentors!
CASE:
simple mixture of SSQC + CSQC to spawn a player on a map. Nothing else. Let's start simple.
DP
on the client I create the SendEntity function
Code: Select all
float Player_SendEntityToCSQC()
{
WriteByte(MSG_ENTITY, ENT_CSPLAYER);
WriteByte(MSG_ENTITY, player.frame); //FIXME NEED COMPRESSION
WriteByte(MSG_ENTITY, player.modelindex);
WriteByte(MSG_ENTITY, player.PersID);
WriteShort(MSG_ENTITY, player.angles_x);
WriteShort(MSG_ENTITY, player.angles_y);
WriteShort(MSG_ENTITY, player.angles_z);
WriteCoord(MSG_ENTITY, player.origin_x);
WriteCoord(MSG_ENTITY, player.origin_y);
WriteCoord(MSG_ENTITY, player.origin_z);
WriteShort(MSG_ENTITY, player.velocity_x);
WriteShort(MSG_ENTITY, player.velocity_y);
WriteShort(MSG_ENTITY, player.velocity_z);
return TRUE;
}
void PutClientInServer()
{
local entity playerspwn;
playerspwn = Player_FindStartPoint();
player = self; //now use player as global player entity
player.classname = "player";
player.health = 100;
player.takedamage = DAMAGE_AIM;
player.solid = SOLID_SLIDEBOX;
player.movetype = MOVETYPE_WALK;
player.origin = playerspwn.origin;
player.angles = playerspwn.angles;
player.fixangle = TRUE; // turn this way immediately
precache_model(PLAYER_MODEL);
setmodel (player, PLAYER_MODEL);
setsize (player, VEC_HULL_MIN, VEC_HULL_MAX);
player.flags = FL_CLIENT;
player.SendEntity = Player_SendEntityToCSQC;//VITAL!
self.Version = self.Version + 1;//Is this needed?
}
Code: Select all
void Player_Startup(float newent)
{
if (newent)
{
player.classname = "player";
setmodelindex(self, player.modelindex);
self.drawmask = MASK_NORMAL; // makes the entity visible
}
}
void CSQC_Ent_Update (float isnew)
{
self.enttype = ReadByte();
switch(self.enttype)
{
//receiving Player
case ENT_CSPLAYER:
player = self;
//read here all send values from client.c in ssqc
player.animation = ReadByte();
player.modelindex = ReadByte();
player.PersID = ReadByte();
player.angles_x = ReadShort();
player.angles_y = ReadShort();
player.angles_z = ReadShort();
player.origin_x = ReadCoord();
player.origin_y = ReadCoord();
player.origin_z = ReadCoord();
player.velocity_x = ReadShort();
player.velocity_y = ReadShort();
player.velocity_z = ReadShort();
Player_Startup(isnew); // IT WILL HAPPEN JUST ONCE - in cs/player/startup.c
break;
}
}
I can see my shiny Quake3 map and that's it
FTE
...now here come the troubles!!
If you do something similar above, the map won't load: black screen, no errors, no warnings (and that's a bit annoying, I must say)
I want to clarify that I completely replaced CSQC DP defs with the command "pr_dumpplatform -FFTE -TCS -O csplat".
Then I replaced the CSQC part with cleancsqc.
This time map loads but only if I comment the SSQC and CSQC part of read/write values.
I studied A LOT csqctest and it uses a pretty obscure (at least for me) construction to send values from SSQC to SSQC.
Both SSQC AND CSQC share a classes.qc file
Code: Select all
#ifndef _CLASSES_QC_
#define _CLASSES_QC_
#define eclasses eclass(CLASS_ROCKET, ParseRocketClass) eclass(CLASS_GIB, ParseGibbing) eclass(CLASS_PLAYER, ParsePlayer) eclass(CLASS_EXPLOSION, ParseExplosion) eclass(CLASS_NAIL, ParseNailClass)
#ifdef CSQC
#define eclass(eid,func) void(float isnew) func;
eclasses
#undef eclass
#endif
enum {
#define eclass(eid,func) eid,
eclasses CLASS_MAX
#undef eclass
};
enum {
GIB_BAD,
GIB_PLAYER,
GIB_SOLDIER,
GIB_ZOMBIE,
GIB_DEMON,
GIB_OGRE,
GIB_DOG,
GIB_WIZARD,
GIB_SHAMBLER,
GIB_KNIGHT,
GIB_HELLKNIGHT,
GIB_FISH,
GIB_ENFORCER,
GIB_SHALRATH,
GIB_MAX
};
#else
#ifdef CSQC
nonstatic var void(float isnew) ParseEntityClass[ ] = {
#define eclass(eid,func) func ,
eclasses
#undef eclass
__NULL__
};
#endif
#endif
Now, my mind completely refuses to understand the #DEFINE directives, ok, but... what's the difference with the code I used?
CLASS_PLAYER is used in SSQC/client.qc
Code: Select all
WriteByte(MSG_ENTITY, CLASS_PLAYER);
Code: Select all
/*
this file handles the local player, and marshalling between the different sorts of player models.
RefreshPlayer: Called from the engine each time a player (ent with player.mdl) is about to be drawn
ParsePlayer: Called from CSQC_Ent_Parse for csqc protocol ents
*/
nonstatic void(float isnew) ParsePlayer =
{
local float f;
f = readbyte();
if (f != self.frame || isnew)
{
self.frame2 = self.frame;
self.lerptime = time;
self.frame = f;
}
self.angles_x = readbyte()*(360/256);
self.angles_y = readbyte()*(360/256);
self.origin_x = readcoord();
self.origin_y = readcoord();
self.origin_z = readcoord();
self.velocity_x = readshort();
self.velocity_y = readshort();
self.velocity_z = readshort();
self.colormap = self.entnum;
self.sveffects = readbyte();
RefreshPlayer(isnew);
};
Last funny thing: If I compile csqctest on svn FTE, quake(1)maps work great, instead my custom Quake 3 maps are not visible again!!
Here a little test I made with DP and FTE. Very basic pack: a map, an exe(only Win version, sorry), simple code and a bunch of silly assets!
In the FTE zip you find two code folders, one similar to DP's one (code_simple), with the only difference in FTE functions names and defs files, the other (code_cleancsqc) with the csqc part completely taken from cleancsqc
Please let me know if someone had same problems with FTE!
Thanks in advance