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

Discuss CSQC related programming.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Why sending entity with FTE is so hard?

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: Why sending entity with FTE is so hard?

Post by toneddu2000 »

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!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
frag.machine
Posts: 2121
Joined: Sat Nov 25, 2006 1:49 pm

Re: Why sending entity with FTE is so hard?

Post by frag.machine »

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)
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

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

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Post Reply