KeyValues class and other

Grab your favourite IDE and tinker with the innards of game engines

KeyValues class and other

Postby Garrador on Tue Sep 25, 2012 9:33 pm

Ok, I myself have just started working on Source. I've gone through all the basics (entities, networking etc.), but I've run into some stuff I can't find any articles on.

So, I'm writing a very basic objective system. Just a test really, so it's not full-fledged. Made to test and learn different systems in source. Here being; keyvalues and networking.

I've created a simple entity that takes a text input in hammer, pointing to a script file that will contain objectives for whatever level you place it in.

I have it set up, and I get the value on the server side, but its not sent or received (or both) properly to the client side.

So, to clarify questions:

#1: Exactly where / when does the client receive? Is there a error here, or just wrongful initialization??
#2: Nothing to do with the below code, but; I want to read objectives from a script file. How exactly does one iterate properly through a script file (by using KeyValues instances).

Here are the server/client entities;

SERVER:
Code: Select all
#include "cbase.h"

#define MAX_OBJECTIVES = 16;

class CTestNetwork : public CBaseEntity
{
   DECLARE_CLASS(CTestNetwork, CBaseEntity);
public:
   DECLARE_SERVERCLASS();
   DECLARE_DATADESC();

   int UpdateTransmitState()   // always send to all clients
   {
      return SetTransmitState( FL_EDICT_ALWAYS );
   }

   CTestNetwork();

   // Inputs
   void InputCompleteObjective(inputdata_t &inputData);

private:
   CNetworkVar( int, m_nObjectiveCount );
   CNetworkString( m_netLookupScriptFile, MAX_PATH );

   string_t m_lookupScriptFile;

   // Outputs
   COutputEvent m_OnObjectiveCompleted;
};

LINK_ENTITY_TO_CLASS(test_network_ent, CTestNetwork);

BEGIN_DATADESC(CTestNetwork)
   DEFINE_KEYFIELD(m_netLookupScriptFile, FIELD_STRING, "scriptfile"),
   DEFINE_KEYFIELD(m_nObjectiveCount, FIELD_INTEGER, "objectivecount"),

   DEFINE_OUTPUT(m_OnObjectiveCompleted, "OnCompleted"),

   DEFINE_INPUTFUNC( FIELD_VOID, "SetCompleted", InputCompleteObjective),
END_DATADESC()

IMPLEMENT_SERVERCLASS_ST(CTestNetwork, DT_TestNetwork)
   SendPropInt( SENDINFO(m_nObjectiveCount), 8, SPROP_UNSIGNED),
   SendPropString( SENDINFO(m_netLookupScriptFile)),
END_SEND_TABLE()


CTestNetwork::CTestNetwork()
{
   m_nObjectiveCount = 0;
   m_netLookupScriptFile.GetForModify()[0] = 0;
   m_lookupScriptFile = NULL_STRING;
}

void CTestNetwork::InputCompleteObjective(inputdata_t &inputData)
{
   Msg("\nInput complete fired in CTestNetwork\n");
   Msg("Script file: %s \n", this->m_netLookupScriptFile);
   Msg("Obj. count: %d\n------------------------\n", this->m_nObjectiveCount);
   this->m_OnObjectiveCompleted.FireOutput(inputData.pActivator, inputData.pCaller);
}



CLIENT
Code: Select all
#include "cbase.h"

class C_TestNetwork : public C_BaseEntity
{
   DECLARE_CLASS(C_TestNetwork, C_BaseEntity);

public:
   DECLARE_CLIENTCLASS();

   C_TestNetwork();
   void ClientThink();
   void Spawn();

private:
   int m_nObjectiveCount;
   char m_netLookupScriptFile[MAX_PATH];
   
};

LINK_ENTITY_TO_CLASS(test_network_ent, C_TestNetwork);

IMPLEMENT_CLIENTCLASS_DT(C_TestNetwork, DT_TestNetwork, CTestNetwork)
   RecvPropInt(   RECVINFO( m_nObjectiveCount ) ),
   RecvPropString( RECVINFO( m_netLookupScriptFile ) ),
END_RECV_TABLE()

C_TestNetwork::C_TestNetwork()
{
   
}

void C_TestNetwork::Spawn()
{
   // These ouput only the initialized values, not any received values (double checked with the objective
   // count, as it outputs '0' in console, when it's set to i.e: 5 in hammer. SO it's correct clientside, but not here.
   // When does it receive? Where?
   char m_szTester[MAX_PATH];
   Q_strcpy(m_szTester, MAKE_STRING(m_netLookupScriptFile));
   Msg("\n--------\nTest message: %s\n--------\n", m_szTester);

   Msg("\n--------\nClient obj. count: %d\n--------\n", m_nObjectiveCount);
}

void C_TestNetwork::ClientThink()
{
}
You click on Build or type
make (or some equivalent), and you are astonished, then mortified, as you realize that the whole world is being
recompiled and relinked!
- Scott Meyers
User avatar
Garrador
Veteran
Veteran
 
Joined: Fri May 12, 2006 10:39 pm
Location: Norway

Re: KeyValues class and other

Postby zombie@computer on Tue Sep 25, 2012 10:08 pm

Just a guess

try setting this in your spawn

AddEFlags( EFL_FORCE_CHECK_TRANSMIT );

as for the client, it should have the correct values onspawn. For dynamic updates use

::OnDataChanged(DataUpdateType_t updateType)
or simply re Think() it all

as for the keyvalues, heres an example i posted a while back

Code: Select all
KeyValues* kv = new KeyValues("");
   kv->UsesEscapeSequences(true);
   kv->LoadFromFile(filesystem, "resource/dialogentries.txt");
   if ( !kv )
   {
      Warning( "Unable to load dialogentries.txt\n" );
      return true;
   }
   //loop all subkeys/dialogs
   for(KeyValues *convo = kv->GetFirstSubKey(); convo; convo = convo->GetNextKey() )
   {
      //loop all subkeys/choicesets
      for ( KeyValues *choiceset = convo->GetFirstSubKey(); choiceset; choiceset = choiceset->GetNextKey() )
      {
         //loop entries in these sets
         for( KeyValues * convoentry = choiceset->GetFirstSubKey(); convoentry; convoentry = convoentry->GetNextKey() )
         {
            dialogEntries.AddToTail( new CDialogEntry(convo->GetName(), choiceset->GetName(), convoentry) );
         }
      }
   }
   kv->deleteThis();
When you are up to your neck in shit, keep your head up high
zombie@computer
Forum Goer Elite™
Forum Goer Elite™
 
Joined: Fri Dec 31, 2004 5:58 pm
Location: Lent, Netherlands

Return to Programming

Who is online

Users browsing this forum: No registered users