Difference between revisions of "Porting to Left 4 Dead"

From AlliedModders Wiki
Jump to: navigation, search
m
m (IVEngineServer Functions)
 
(5 intermediate revisions by 2 users not shown)
Line 5: Line 5:
  
 
As there is no official SDK yet, we've simply reverse engineered the new header files.  These changes aren't guaranteed to be 100% correct and the SDK isn't complete for building mods -- just most plugins.
 
As there is no official SDK yet, we've simply reverse engineered the new header files.  These changes aren't guaranteed to be 100% correct and the SDK isn't complete for building mods -- just most plugins.
 +
 +
=Changes=
 +
*<tt>IVEngineServer::UserMessageBegin</tt> now takes an additional string parameter containing the message name.
 +
*The low-level datagram type for setting replicated convars on clients has changed from 5 to 6.
 +
*<tt>CreateEntityByName</tt> appears to have a third parameter (SourceMod sets it to true).
  
 
=Removals=
 
=Removals=
 +
==IVEngineServer Functions==
 
The <tt>IVEngineServer</tt> functions <tt>PEntityOfEntIndex</tt> and <tt>IndexOfEdict</tt> have been removed for faster code that can be inlined.  An example of how to re-implement this (as Valve has not released a new SDK yet):
 
The <tt>IVEngineServer</tt> functions <tt>PEntityOfEntIndex</tt> and <tt>IndexOfEdict</tt> have been removed for faster code that can be inlined.  An example of how to re-implement this (as Valve has not released a new SDK yet):
  
Line 12: Line 18:
 
inline int IndexOfEdict(const edict_t *pEdict)
 
inline int IndexOfEdict(const edict_t *pEdict)
 
{
 
{
return (int)(pEdict - gpGlobals->baseEdict);
+
return (int)(pEdict - gpGlobals->pEdicts);
 
}
 
}
 
inline edict_t *PEntityOfEntIndex(int iEntIndex)
 
inline edict_t *PEntityOfEntIndex(int iEntIndex)
Line 18: Line 24:
 
if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities)
 
if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities)
 
{
 
{
return (edict_t *)(gpGlobals->baseEdict + iEntIndex);
+
return (edict_t *)(gpGlobals->pEdicts + iEntIndex);
 
}
 
}
 
return NULL;
 
return NULL;
Line 24: Line 30:
 
</cpp>
 
</cpp>
  
 +
==ICVar functions==
 +
The function <tt>GetCommands</tt> has been removed.  In general, <tt>FindCommand</tt> can be used as a replacement.
 +
 +
However, if iterating across all ConCommandBases is a must, then use <tt>FactoryInternalIterator</tt>.  This returns an <tt>ICvarIteratorInternal</tt> pointer.  An example of how to use these:
 +
 +
<cpp>
 +
ICvarIteratorInternal *iter = icvar->FactoryInternalIterator();
 +
 +
iter->SetFirst();
 +
 +
while (iter->IsValid())
 +
{
 +
ConCommandBase *pCmd = iter->Get();
 +
Msg("ConCommandBase: %s\n", pCmd->GetName());
 +
iter->Next();
 +
}
 +
 +
// ICvarIteratorInternal does not have a virtual destructor.
 +
g_pMemAlloc->Free(iter);
 +
</cpp>
  
 
=Annoyances=
 
=Annoyances=

Latest revision as of 06:01, 29 May 2012

Porting Valve Server Plugins or Metamod:Source plugins to Left 4 Dead is not very difficult. This article explores some of the changes and how to simplify them.

Users of Metamod:Source must upgrade to Metamod:Source 1.7 and use the 1.6+ API (see MM:S API Differences).

As there is no official SDK yet, we've simply reverse engineered the new header files. These changes aren't guaranteed to be 100% correct and the SDK isn't complete for building mods -- just most plugins.

Changes

  • IVEngineServer::UserMessageBegin now takes an additional string parameter containing the message name.
  • The low-level datagram type for setting replicated convars on clients has changed from 5 to 6.
  • CreateEntityByName appears to have a third parameter (SourceMod sets it to true).

Removals

IVEngineServer Functions

The IVEngineServer functions PEntityOfEntIndex and IndexOfEdict have been removed for faster code that can be inlined. An example of how to re-implement this (as Valve has not released a new SDK yet):

inline int IndexOfEdict(const edict_t *pEdict)
{
	return (int)(pEdict - gpGlobals->pEdicts);
}
inline edict_t *PEntityOfEntIndex(int iEntIndex)
{
	if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities)
	{
		return (edict_t *)(gpGlobals->pEdicts + iEntIndex);
	}
	return NULL;
}

ICVar functions

The function GetCommands has been removed. In general, FindCommand can be used as a replacement.

However, if iterating across all ConCommandBases is a must, then use FactoryInternalIterator. This returns an ICvarIteratorInternal pointer. An example of how to use these:

ICvarIteratorInternal *iter = icvar->FactoryInternalIterator();
 
iter->SetFirst();
 
while (iter->IsValid())
{
	ConCommandBase *pCmd = iter->Get();
	Msg("ConCommandBase: %s\n", pCmd->GetName());
	iter->Next();
}
 
// ICvarIteratorInternal does not have a virtual destructor.
g_pMemAlloc->Free(iter);

Annoyances

The console will spew "VPK" warnings unless your file-backed KeyValues operations use relative paths instead of absolute paths.