Forum

[SOLVED]Why sending entity with FTE is so hard?

Discuss CSQC related programming.

Moderator: InsideQC Admins

Re: Why sending entity with FTE is so hard?

Postby toneddu2000 » Wed Sep 24, 2014 11:15 pm

Hi ceriux,
ssqc:
Code: Select all
#pragma PROGS_DAT "../progs.dat"
#define SSQC
#include "../common/fteextensions.qc"
#include "../common/commondefs.qc"
#include "../common/quakedefs.qc"

//needed functions, placeholders just for now
void main(){}
void SetNewParms(){}
void SetChangeParms(){}
void Precache(){}
void worldspawn(){}
void StartFrame(){}
void ClientConnect(){}
void ClientDisconnect(){}

entity Player_FindStartPoint()
{
   local entity spot;
   
   spot = find(world,classname,"info_player_start");
   if(!spot){
      error ("PutClientInServer: no starting point on level");
   }
   return spot;
}

float playersend()
{
   WriteCoord(MSG_ENTITY, self.origin_x);
   WriteCoord(MSG_ENTITY, self.origin_y);
   WriteCoord(MSG_ENTITY, self.origin_z);
   return TRUE;
}

void PlayerPreThink(){}

void PlayerPostThink()
{
   self.SendFlags = FULLSEND;
}

void PutClientInServer()
{
   local            entity   playerspwn;
   
   playerspwn =       Player_FindStartPoint();
   self.origin = playerspwn.origin;
   self.health = 100;
   self.movetype = MOVETYPE_WALK;
   precache_model(PLAYER_MODEL);
   setmodel (self, PLAYER_MODEL);
   setsize (self, '-16 -16 -24', '16 16 32');
   self.SendEntity = playersend;
   self.SendFlags = FULLSEND;
}

void info_player_start()
{
}

csqc:
Code: Select all
#pragma PROGS_DAT "../csprogs.dat"
#define CSQC
#include "../common/fteextensions.qc"
#include "../common/commondefs.qc"

//needed functions, placeholders just for now
void CSQC_Init(float apilevel, string enginename, float engineversion){}
void CSQC_Shutdown(void){}
float CSQC_ConsoleCommand(string strMessage){return 0;}
float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent ={return FALSE;};

void CSQC_Ent_Update(float isnew)
{
   self.origin_x = readcoord();
   self.origin_y = readcoord();
   self.origin_z = readcoord();
   somerandomplayer = self;
}

void CSQC_UpdateView(float vwidth, float vheight, float notmenu)
{
   clearscene();
   setviewprop(VF_ORIGIN, somerandomplayer.origin);
   setviewprop(VF_ANGLES, view_angles);
   addentities(1|2);
   renderscene();
}

in NetRadiant I just create 6 walls and a info_player_start entity. On DP works flawless, on FTE it does not.

I don't understood what do you mean for "spawning your player at the proper entities", but if I made an error
1) it shouldn't work on DP
2) it shouldn't work on FTE if I delete csprogs.dat, instead it DOES work if I delete that file.
MYSTERY :)

EDIT: I tried even with sock's wonderful Focal Point map but same story
toneddu2000
 
Posts: 1329
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Why sending entity with FTE is so hard?

Postby toneddu2000 » Thu Sep 25, 2014 12:06 am

ok, I did something I should have done at least 1 week ago. Download another FTE version! The latest experimental one it works like a charm! :shock:
I feel like a stupid but I was 100% sure that FTE versions couldn't differ too much from one to another... well I was definitely wrong! :lol:
old version (FTE SVN 4728) completely ignored my csqc code, this current one (FTE SVN 4754) instead does its job perfectly (but it ignores .fmf file for game settings :? )
Sorry guys to have created an useless post!
toneddu2000
 
Posts: 1329
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Why sending entity with FTE is so hard?

Postby frag.machine » Thu Sep 25, 2014 1:06 am

toneddu2000 wrote:ok, I did something I should have done at least 1 week ago. Download another FTE version! The latest experimental one it works like a charm! :shock:
I feel like a stupid but I was 100% sure that FTE versions couldn't differ too much from one to another... well I was definitely wrong! :lol:
old version (FTE SVN 4728) completely ignored my csqc code, this current one (FTE SVN 4754) instead does its job perfectly (but it ignores .fmf file for game settings :? )
Sorry guys to have created an useless post!


Well, I don't think it's useless at all. Specially because turns out the problem wasn't in your code after all.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2081
Joined: Sat Nov 25, 2006 1:49 pm

Re: [SOLVED]Why sending entity with FTE is so hard?

Postby toneddu2000 » Sun Dec 21, 2014 7:44 pm

don't know if it could be of help for anyone but...
I figured out how to avoid that devil mechanism of #defines that Spike created in common/classes.qc in csqctest

If anyone has trouble to understand how to use ParsePlayer, ParseNail, ParseExplosion, etc. you can use a different approach.

For example, for
Code: Select all
#define eclasses   eclass(CLASS_PLAYER, ParsePlayer)

You can comment every comparison of common/classes.qc in both ssqc.src and csprogs.src and:

1)add in common defs
Code: Select all
float CLASS_PLAYER = 1;
This will be sent from ssqc to csqc only for player
and add with a sequential number everything you need to parse
Code: Select all
float CLASS_NAIL = 2;
float CLASS_ROCKET = 3;//and so on...

2) add in CSQC_Ent_Update
Code: Select all
void CSQC_Ent_Update(float isnew)
{
   local float classtype,f;
   
   classtype = readbyte();//this reads CLASS_...
   if (classtype == CLASS_PLAYER){
      //reads first argument (frame in this case)
      if (f != self.frame || isnew){
         self.frame2 = self.frame;
         self.lerptime = time;
         self.frame = f;
      }
      //angles
      self.angles_x = readbyte()*(360/256);
      self.angles_y = readbyte()*(360/256);
      //origin
      self.origin_x = readcoord();
      self.origin_y = readcoord();
      self.origin_z = readcoord();
      //velocity
      self.velocity_x = readshort();
      self.velocity_y = readshort();
      self.velocity_z = readshort();
      //effects
      self.colormap = self.entnum;
      self.sveffects = readbyte();
      RefreshPlayer(isnew);
   }
}


3)the ssqc part is untouched (except for the inclusion of the common defs at step 1)
Code: Select all
float(entity to) SendPlayer =
{
   float ef;
   float f;

//encode the current weapon in the lower 4 bits.
   for (f = 1, ef = 0; ef < 16; ef=ef+1,f*=2)
   {
      if (self.weapon == f)
         break;
   }
//and put effects in the upper 3
   if (self.items & IT_INVISIBILITY)
      ef |= 128;
   if (self.items & IT_INVULNERABILITY || self.flags & FL_GODMODE)
      ef |= 64;
   if (self.items & IT_QUAD)
      ef |= 32;
//and the final bit takes an indication to switch of prediction.
   if (self.movetype != MOVETYPE_WALK)
      ef |= 16;   //tells the csqc to stop trying to predict (I can't be bothered to send the real movetype)


   WriteByte(MSG_ENTITY, CLASS_PLAYER);
   WriteByte(MSG_ENTITY, self.frame);   //for clientside animation selection, in a way compatable with not having csqc.
   WriteByte(MSG_ENTITY, self.angles_x*(256/360));
   WriteByte(MSG_ENTITY, self.angles_y*(256/360));
   WriteCoord(MSG_ENTITY, self.origin_x);
   WriteCoord(MSG_ENTITY, self.origin_y);
   WriteCoord(MSG_ENTITY, self.origin_z);
   WriteShort(MSG_ENTITY, self.velocity_x);
   WriteShort(MSG_ENTITY, self.velocity_y);
   WriteShort(MSG_ENTITY, self.velocity_z);
   WriteByte(MSG_ENTITY, ef);
   return TRUE;
};


You can replicate steps 1,2 and 3 for every ParseXXXX command
toneddu2000
 
Posts: 1329
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Previous

Return to CSQC Programming

Who is online

Users browsing this forum: No registered users and 1 guest