]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
-CVS: ----------------------------------------------------------------------
authorblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 27 May 2005 15:43:48 +0000 (15:43 +0000)
committerblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 27 May 2005 15:43:48 +0000 (15:43 +0000)
-Merged the old VM into the new one. The pr_* files are mess right now and
 will be removed as soon as they are not needed as semi-reference (to trace
 bugs)
-There is a certain risk that the server could crash now and then since some
 parts of the code can only be debugged (- checking them by looking at the code
 would be quite tedious to put it nicely)
-Changed all references to the old VM to point to the new VM (also hopefully
 all todo items)
-Im working on a cleanup for the SV_VM_Begin/End mess.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5344 d7cf8633-e32d-0410-b094-e92efae38249

29 files changed:
cl_collision.c
gl_rmain.c
host.c
host_cmd.c
makefile.inc
menu.c
mvm_cmds.c
netconn.c
pr_cmds.c
pr_edict.c
pr_exec.c
pr_execprogram.h
progs.h
progsvm.h
protocol.c
prvm_cmds.c
prvm_cmds.h
prvm_edict.c
prvm_exec.c
prvm_execprogram.h
quakedef.h
server.h
sv_main.c
sv_move.c
sv_phys.c
sv_user.c
svvm_cmds.c [new file with mode: 0644]
world.c
world.h

index 8920a5edbf6b1263d3aa053b1a81e2635e82a3e6..c97f0a3f4dbff6efc60ee914815f812d35606bc3 100644 (file)
@@ -6,7 +6,7 @@
 // not yet used
 typedef struct physentity_s
 {
-       // this may be a entity_t, or a edict_t, or whatever
+       // this may be a entity_t, or a prvm_edict_t, or whatever
        void *realentity;
 
        // can be NULL if it is a bbox object
index d7ab02c30a9750e7c59cbaec53664d39010f3896..760e60ce4ce36ac7bb596411f14688498a734423 100644 (file)
@@ -606,7 +606,7 @@ void GL_Init (void)
        VID_CheckExtensions();
 
        // LordHavoc: report supported extensions
-       Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS);
+       Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions );
 
        // clear to black (loading plaque will be seen over this)
        qglClearColor(0,0,0,1);
diff --git a/host.c b/host.c
index 9eaa3ba4d18a55c3bf7cc041c9e5235f610bfe6c..41272a7739614ae8b8a64f1716dc03d276c3a137 100644 (file)
--- a/host.c
+++ b/host.c
@@ -127,7 +127,7 @@ void Host_Error (const char *error, ...)
 
        CL_Parse_DumpPacket();
 
-       PR_Crash();
+       //PR_Crash();
 
        //PRVM_Crash(); // crash current prog
 
@@ -394,7 +394,7 @@ void SV_DropClient(qboolean crash)
        Con_Printf("Client \"%s\" dropped\n", host_client->name);
 
        // make sure edict is not corrupt (from a level change for example)
-       host_client->edict = EDICT_NUM(host_client - svs.clients + 1);
+       host_client->edict = PRVM_EDICT_NUM(host_client - svs.clients + 1);
 
        if (host_client->netconnection)
        {
@@ -419,18 +419,18 @@ void SV_DropClient(qboolean crash)
        {
                // call the prog function for removing a client
                // this will set the body to a dead frame, among other things
-               int saveSelf = pr_global_struct->self;
+               int saveSelf = prog->globals.server->self;
                host_client->clientconnectcalled = false;
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-               PR_ExecuteProgram(pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
-               pr_global_struct->self = saveSelf;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+               PRVM_ExecuteProgram(prog->globals.server->ClientDisconnect, "QC function ClientDisconnect is missing");
+               prog->globals.server->self = saveSelf;
        }
 
        // remove leaving player from scoreboard
-       //host_client->edict->v->netname = PR_SetEngineString(host_client->name);
-       //if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
+       //host_client->edict->fields.server->netname = PRVM_SetEngineString(host_client->name);
+       //if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
        //      val->_float = 0;
-       //host_client->edict->v->frags = 0;
+       //host_client->edict->fields.server->frags = 0;
        host_client->name[0] = 0;
        host_client->colors = 0;
        host_client->frags = 0;
@@ -458,7 +458,7 @@ void SV_DropClient(qboolean crash)
        if (sv.active)
        {
                // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
-               ED_ClearEdict(host_client->edict);
+               PRVM_ED_ClearEdict(host_client->edict);
        }
 
        // clear the client struct (this sets active to false)
@@ -487,8 +487,9 @@ void Host_ShutdownServer(qboolean crash)
        if (!sv.active)
                return;
 
+       SV_VM_Begin();
        // print out where the crash happened, if it was caused by QC
-       PR_Crash();
+       //PRVM_Crash();
 
        NetConn_Heartbeat(2);
        NetConn_Heartbeat(2);
@@ -503,18 +504,20 @@ void Host_ShutdownServer(qboolean crash)
                Con_Printf("Host_ShutdownServer: NetConn_SendToAll failed for %u clients\n", count);
 
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
-               if (host_client->active)
+               if (host_client->active) {
                        SV_DropClient(crash); // server shutdown
+               }
 
        NetConn_CloseServerPorts();
 
        sv.active = false;
-
 //
 // clear structures
 //
        memset(&sv, 0, sizeof(sv));
        memset(svs.clients, 0, svs.maxclients*sizeof(client_t));
+
+       SV_VM_End();
 }
 
 
@@ -670,10 +673,15 @@ void Host_ServerFrame (void)
                return;
        }
        sv.timer += host_realframetime;
+
+    
        // run the world state
        // don't allow simulation to run too fast or too slow or logic glitches can occur
        for (framecount = 0;framecount < framelimit && sv.timer > 0;framecount++)
        {
+               // setup the VM frame
+               SV_VM_Begin();
+
                if (cl.islocalgame)
                        advancetime = min(sv.timer, sys_ticrate.value);
                else
@@ -704,7 +712,12 @@ void Host_ServerFrame (void)
 
                // send an heartbeat if enough time has passed since the last one
                NetConn_Heartbeat(0);
+
+               // end the server VM frame
+               SV_VM_End();
        }
+
+
        // if we fell behind too many frames just don't worry about it
        if (sv.timer > 0)
                sv.timer = 0;
@@ -958,8 +971,8 @@ void Host_Init (void)
        Mathlib_Init();
 
        NetConn_Init();
-       PR_Init();
-       PR_Cmd_Init();
+       //PR_Init();
+       //PR_Cmd_Init();
        PRVM_Init();
        Mod_Init();
        SV_Init();
@@ -1082,7 +1095,7 @@ void Host_Shutdown(void)
        CDAudio_Shutdown ();
        S_Terminate ();
        NetConn_Shutdown ();
-       PR_Shutdown ();
+       //PR_Shutdown ();
 
        if (cls.state != ca_dedicated)
        {
index f28ac1763e31543a433d6a4e4c18b72ae3235565..ac6d821fb6900c6b0f7c76fbebfe076d92d242fc 100644 (file)
@@ -24,8 +24,6 @@ int current_skill;
 cvar_t sv_cheats = {0, "sv_cheats", "0"};
 qboolean allowcheats = false;
 
-mfunction_t *ED_FindFunction (char *name);
-
 /*
 ==================
 Host_Quit_f
@@ -84,7 +82,7 @@ void Host_Status_f (void)
                }
                else
                        hours = 0;
-               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->v->frags, hours, minutes, seconds);
+               print ("#%-2u %-16.16s  %3i  %2i:%02i:%02i\n", j+1, client->name, (int)client->edict->fields.server->frags, hours, minutes, seconds);
                print ("   %s\n", client->netconnection ? client->netconnection->address : "botclient");
        }
 }
@@ -111,8 +109,8 @@ void Host_God_f (void)
                return;
        }
 
-       host_client->edict->v->flags = (int)host_client->edict->v->flags ^ FL_GODMODE;
-       if (!((int)host_client->edict->v->flags & FL_GODMODE) )
+       host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags ^ FL_GODMODE;
+       if (!((int)host_client->edict->fields.server->flags & FL_GODMODE) )
                SV_ClientPrint("godmode OFF\n");
        else
                SV_ClientPrint("godmode ON\n");
@@ -132,8 +130,8 @@ void Host_Notarget_f (void)
                return;
        }
 
-       host_client->edict->v->flags = (int)host_client->edict->v->flags ^ FL_NOTARGET;
-       if (!((int)host_client->edict->v->flags & FL_NOTARGET) )
+       host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags ^ FL_NOTARGET;
+       if (!((int)host_client->edict->fields.server->flags & FL_NOTARGET) )
                SV_ClientPrint("notarget OFF\n");
        else
                SV_ClientPrint("notarget ON\n");
@@ -155,16 +153,16 @@ void Host_Noclip_f (void)
                return;
        }
 
-       if (host_client->edict->v->movetype != MOVETYPE_NOCLIP)
+       if (host_client->edict->fields.server->movetype != MOVETYPE_NOCLIP)
        {
                noclip_anglehack = true;
-               host_client->edict->v->movetype = MOVETYPE_NOCLIP;
+               host_client->edict->fields.server->movetype = MOVETYPE_NOCLIP;
                SV_ClientPrint("noclip ON\n");
        }
        else
        {
                noclip_anglehack = false;
-               host_client->edict->v->movetype = MOVETYPE_WALK;
+               host_client->edict->fields.server->movetype = MOVETYPE_WALK;
                SV_ClientPrint("noclip OFF\n");
        }
 }
@@ -190,14 +188,14 @@ void Host_Fly_f (void)
                return;
        }
 
-       if (host_client->edict->v->movetype != MOVETYPE_FLY)
+       if (host_client->edict->fields.server->movetype != MOVETYPE_FLY)
        {
-               host_client->edict->v->movetype = MOVETYPE_FLY;
+               host_client->edict->fields.server->movetype = MOVETYPE_FLY;
                SV_ClientPrint("flymode ON\n");
        }
        else
        {
-               host_client->edict->v->movetype = MOVETYPE_WALK;
+               host_client->edict->fields.server->movetype = MOVETYPE_WALK;
                SV_ClientPrint("flymode OFF\n");
        }
 }
@@ -278,7 +276,11 @@ void Host_Map_f (void)
        strcpy(level, Cmd_Argv(1));
        SV_SpawnServer(level);
        if (sv.active && cls.state == ca_disconnected)
+       {
+               SV_VM_Begin();
                CL_EstablishConnection("local:1");
+               SV_VM_End();
+       }
 }
 
 /*
@@ -309,12 +311,18 @@ void Host_Changelevel_f (void)
        key_dest = key_game;
        key_consoleactive = 0;
 
+       SV_VM_Begin();
        SV_SaveSpawnparms ();
+       SV_VM_End();
        allowcheats = sv_cheats.integer != 0;
        strcpy(level, Cmd_Argv(1));
        SV_SpawnServer(level);
        if (sv.active && cls.state == ca_disconnected)
+       {
+               SV_VM_Begin();
                CL_EstablishConnection("local:1");
+               SV_VM_End();
+       }
 }
 
 /*
@@ -348,8 +356,12 @@ void Host_Restart_f (void)
        allowcheats = sv_cheats.integer != 0;
        strcpy(mapname, sv.name);
        SV_SpawnServer(mapname);
-       if (sv.active && cls.state == ca_disconnected)
+       if (sv.active && cls.state == ca_disconnected) 
+       {
+               SV_VM_Begin();
                CL_EstablishConnection("local:1");
+               SV_VM_End();
+       }
 }
 
 /*
@@ -389,7 +401,9 @@ void Host_Connect_f (void)
                Con_Print("connect <serveraddress> : connect to a multiplayer game\n");
                return;
        }
-       CL_EstablishConnection(Cmd_Argv(1));
+       SV_VM_Begin();
+       CL_EstablishConnection("local:1");
+       SV_VM_End();
 }
 
 
@@ -464,7 +478,7 @@ void Host_Savegame_f (void)
                                Con_Print("Can't save multiplayer games.\n");
                                return;
                        }
-                       if (svs.clients[i].edict->v->deadflag)
+                       if (svs.clients[i].edict->fields.server->deadflag)
                        {
                                Con_Print("Can't savegame with a dead player\n");
                                return;
@@ -513,9 +527,14 @@ void Host_Savegame_f (void)
                        FS_Print(f,"m\n");
        }
 
-       ED_WriteGlobals (f);
-       for (i=0 ; i<sv.num_edicts ; i++)
-               ED_Write (f, EDICT_NUM(i));
+       SV_VM_Begin();
+
+       PRVM_ED_WriteGlobals (f);
+       for (i=0 ; i<prog->num_edicts ; i++)
+               PRVM_ED_Write (f, PRVM_EDICT_NUM(i));
+
+       SV_VM_End();
+
        FS_Close (f);
        Con_Print("done.\n");
 }
@@ -534,7 +553,7 @@ void Host_Loadgame_f (void)
        const char *start;
        const char *t;
        char *text;
-       edict_t *ent;
+       prvm_edict_t *ent;
        int i;
        int entnum;
        int version;
@@ -619,6 +638,7 @@ void Host_Loadgame_f (void)
        }
 
 // load the edicts out of the savegame file
+       SV_VM_Begin();
        // -1 is the globals
        entnum = -1;
        for (;;)
@@ -641,7 +661,7 @@ void Host_Loadgame_f (void)
                if (entnum == -1)
                {
                        // parse the global vars
-                       ED_ParseGlobals (start);
+                       PRVM_ED_ParseGlobals (start);
                }
                else
                {
@@ -651,22 +671,23 @@ void Host_Loadgame_f (void)
                                Mem_Free(text);
                                Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)\n", MAX_EDICTS);
                        }
-                       while (entnum >= sv.max_edicts)
-                               SV_IncreaseEdicts();
-                       ent = EDICT_NUM(entnum);
-                       memset (ent->v, 0, progs->entityfields * 4);
-                       ent->e->free = false;
-                       ED_ParseEdict (start, ent);
+                       while (entnum >= prog->max_edicts)
+                               //SV_IncreaseEdicts();
+                               PRVM_MEM_IncreaseEdicts();
+                       ent = PRVM_EDICT_NUM(entnum);
+                       memset (ent->fields.server, 0, prog->progs->entityfields * 4);
+                       ent->priv.server->free = false;
+                       PRVM_ED_ParseEdict (start, ent);
 
                        // link it into the bsp tree
-                       if (!ent->e->free)
+                       if (!ent->priv.server->free)
                                SV_LinkEdict (ent, false);
                }
 
                entnum++;
        }
 
-       sv.num_edicts = entnum;
+       prog->num_edicts = entnum;
        sv.time = time;
 
        for (i = 0;i < NUM_SPAWN_PARMS;i++)
@@ -675,6 +696,8 @@ void Host_Loadgame_f (void)
        // make sure we're connected to loopback
        if (cls.state == ca_disconnected || !(cls.state == ca_connected && cls.netcon != NULL && LHNETADDRESS_GetAddressType(&cls.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP))
                CL_EstablishConnection("local:1");
+
+       SV_VM_End();
 }
 
 //============================================================================
@@ -724,7 +747,7 @@ void Host_Name_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->name, newName, sizeof (host_client->name));
-       host_client->edict->v->netname = PR_SetEngineString(host_client->name);
+       host_client->edict->fields.server->netname = PRVM_SetEngineString(host_client->name);
        if (strcmp(host_client->old_name, host_client->name))
        {
                if (host_client->spawned)
@@ -786,11 +809,11 @@ void Host_Playermodel_f (void)
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
        if( eval_playermodel )
-               GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetEngineString(host_client->playermodel);
+               PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
        if (strcmp(host_client->old_model, host_client->playermodel))
        {
                if (host_client->spawned)
-                       SV_BroadcastPrintf("%s changed model to %s\n", host_client->old_model, host_client->playermodel);
+                       SV_BroadcastPrintf("%s changed model to %s\n", host_client->name, host_client->playermodel);
                strcpy(host_client->old_model, host_client->playermodel);
                /*// send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatepmodel);
@@ -847,11 +870,11 @@ void Host_Playerskin_f (void)
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
        if( eval_playerskin )
-               GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetEngineString(host_client->playerskin);
+               PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
        if (strcmp(host_client->old_skin, host_client->playerskin))
        {
                if (host_client->spawned)
-                       SV_BroadcastPrintf("%s changed skin to %s\n", host_client->old_skin, host_client->playerskin);
+                       SV_BroadcastPrintf("%s changed skin to %s\n", host_client->name, host_client->playerskin);
                strcpy(host_client->old_skin, host_client->playerskin);
                /*// send notification to all clients
                MSG_WriteByte (&sv.reliable_datagram, svc_updatepskin);
@@ -920,7 +943,7 @@ void Host_Say(qboolean teamonly)
        // note: save is not a valid edict if fromServer is true
        save = host_client;
        for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
-               if (host_client->spawned && (!teamonly || host_client->edict->v->team == save->edict->v->team))
+               if (host_client->spawned && (!teamonly || host_client->edict->fields.server->team == save->edict->fields.server->team))
                        SV_ClientPrint(text);
        host_client = save;
 
@@ -1050,22 +1073,22 @@ void Host_Color_f(void)
                return;
        }
 
-       if (host_client->edict && (f = ED_FindFunction ("SV_ChangeTeam")) && (SV_ChangeTeam = (func_t)(f - pr_functions)))
+       if (host_client->edict && (f = PRVM_ED_FindFunction ("SV_ChangeTeam")) && (SV_ChangeTeam = (func_t)(f - prog->functions)))
        {
                Con_DPrint("Calling SV_ChangeTeam\n");
-               pr_global_struct->time = sv.time;
-               pr_globals[OFS_PARM0] = playercolor;
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-               PR_ExecuteProgram (SV_ChangeTeam, "QC function SV_ChangeTeam is missing");
+               prog->globals.server->time = sv.time;
+               prog->globals.generic[OFS_PARM0] = playercolor;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+               PRVM_ExecuteProgram (SV_ChangeTeam, "QC function SV_ChangeTeam is missing");
        }
        else
        {
-               eval_t *val;
+               prvm_eval_t *val;
                if (host_client->edict)
                {
-                       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
+                       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
                                val->_float = playercolor;
-                       host_client->edict->v->team = bottom + 1;
+                       host_client->edict->fields.server->team = bottom + 1;
                }
                host_client->colors = playercolor;
                if (host_client->old_colors != host_client->colors)
@@ -1117,15 +1140,15 @@ void Host_Kill_f (void)
                return;
        }
 
-       if (host_client->edict->v->health <= 0)
+       if (host_client->edict->fields.server->health <= 0)
        {
                SV_ClientPrint("Can't suicide -- already dead!\n");
                return;
        }
 
-       pr_global_struct->time = sv.time;
-       pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-       PR_ExecuteProgram (pr_global_struct->ClientKill, "QC function ClientKill is missing");
+       prog->globals.server->time = sv.time;
+       prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+       PRVM_ExecuteProgram (prog->globals.server->ClientKill, "QC function ClientKill is missing");
 }
 
 
@@ -1164,7 +1187,7 @@ cvar_t cl_pmodel = {CVAR_SAVE, "_cl_pmodel", "0"};
 static void Host_PModel_f (void)
 {
        int i;
-       eval_t *val;
+       prvm_eval_t *val;
 
        if (Cmd_Argc () == 1)
        {
@@ -1183,7 +1206,7 @@ static void Host_PModel_f (void)
                return;
        }
 
-       if (host_client->edict && (val = GETEDICTFIELDVALUE(host_client->edict, eval_pmodel)))
+       if (host_client->edict && (val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_pmodel)))
                val->_float = i;
 }
 
@@ -1258,36 +1281,36 @@ void Host_Spawn_f (void)
                // if this is the last client to be connected, unpause
                sv.paused = false;
 
-               if ((f = ED_FindFunction ("RestoreGame")))
-               if ((RestoreGame = (func_t)(f - pr_functions)))
+               if ((f = PRVM_ED_FindFunction ("RestoreGame")))
+               if ((RestoreGame = (func_t)(f - prog->functions)))
                {
                        Con_DPrint("Calling RestoreGame\n");
-                       pr_global_struct->time = sv.time;
-                       pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-                       PR_ExecuteProgram (RestoreGame, "QC function RestoreGame is missing");
+                       prog->globals.server->time = sv.time;
+                       prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+                       PRVM_ExecuteProgram (RestoreGame, "QC function RestoreGame is missing");
                }
        }
        else
        {
                // set up the edict
-               ED_ClearEdict(host_client->edict);
+               PRVM_ED_ClearEdict(host_client->edict);
 
-               //Con_Printf("Host_Spawn_f: host_client->edict->netname = %s, host_client->edict->netname = %s, host_client->name = %s\n", PR_GetString(host_client->edict->v->netname), PR_GetString(host_client->edict->v->netname), host_client->name);
+               //Con_Printf("Host_Spawn_f: host_client->edict->netname = %s, host_client->edict->netname = %s, host_client->name = %s\n", PRVM_GetString(host_client->edict->fields.server->netname), PRVM_GetString(host_client->edict->fields.server->netname), host_client->name);
 
                // copy spawn parms out of the client_t
                for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
-                       (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
+                       (&prog->globals.server->parm1)[i] = host_client->spawn_parms[i];
 
                // call the spawn function
                host_client->clientconnectcalled = true;
-               pr_global_struct->time = sv.time;
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-               PR_ExecuteProgram (pr_global_struct->ClientConnect, "QC function ClientConnect is missing");
+               prog->globals.server->time = sv.time;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+               PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
 
                if ((Sys_DoubleTime() - host_client->connecttime) <= sv.time)
                        Con_Printf("%s entered the game\n", host_client->name);
 
-               PR_ExecuteProgram (pr_global_struct->PutClientInServer, "QC function PutClientInServer is missing");
+               PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
        }
 
 
@@ -1321,19 +1344,19 @@ void Host_Spawn_f (void)
        // send some stats
        MSG_WriteByte (&host_client->message, svc_updatestat);
        MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS);
-       MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets);
+       MSG_WriteLong (&host_client->message, prog->globals.server->total_secrets);
 
        MSG_WriteByte (&host_client->message, svc_updatestat);
        MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS);
-       MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters);
+       MSG_WriteLong (&host_client->message, prog->globals.server->total_monsters);
 
        MSG_WriteByte (&host_client->message, svc_updatestat);
        MSG_WriteByte (&host_client->message, STAT_SECRETS);
-       MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets);
+       MSG_WriteLong (&host_client->message, prog->globals.server->found_secrets);
 
        MSG_WriteByte (&host_client->message, svc_updatestat);
        MSG_WriteByte (&host_client->message, STAT_MONSTERS);
-       MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters);
+       MSG_WriteLong (&host_client->message, prog->globals.server->killed_monsters);
 
        // send a fixangle
        // Never send a roll angle, because savegames can catch the server
@@ -1341,8 +1364,8 @@ void Host_Spawn_f (void)
        // and it won't happen if the game was just loaded, so you wind up
        // with a permanent head tilt
        MSG_WriteByte (&host_client->message, svc_setangle);
-       MSG_WriteAngle (&host_client->message, host_client->edict->v->angles[0], sv.protocol);
-       MSG_WriteAngle (&host_client->message, host_client->edict->v->angles[1], sv.protocol);
+       MSG_WriteAngle (&host_client->message, host_client->edict->fields.server->angles[0], sv.protocol);
+       MSG_WriteAngle (&host_client->message, host_client->edict->fields.server->angles[1], sv.protocol);
        MSG_WriteAngle (&host_client->message, 0, sv.protocol);
 
        SV_WriteClientdataToMessage (host_client, host_client->edict, &host_client->message, stats);
@@ -1466,7 +1489,7 @@ void Host_Give_f (void)
 {
        const char *t;
        int v;
-       eval_t *val;
+       prvm_eval_t *val;
 
        if (cmd_source == src_command)
        {
@@ -1501,128 +1524,128 @@ void Host_Give_f (void)
                        if (t[0] == '6')
                        {
                                if (t[1] == 'a')
-                                       host_client->edict->v->items = (int)host_client->edict->v->items | HIT_PROXIMITY_GUN;
+                                       host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_PROXIMITY_GUN;
                                else
-                                       host_client->edict->v->items = (int)host_client->edict->v->items | IT_GRENADE_LAUNCHER;
+                                       host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | IT_GRENADE_LAUNCHER;
                        }
                        else if (t[0] == '9')
-                               host_client->edict->v->items = (int)host_client->edict->v->items | HIT_LASER_CANNON;
+                               host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_LASER_CANNON;
                        else if (t[0] == '0')
-                               host_client->edict->v->items = (int)host_client->edict->v->items | HIT_MJOLNIR;
+                               host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | HIT_MJOLNIR;
                        else if (t[0] >= '2')
-                               host_client->edict->v->items = (int)host_client->edict->v->items | (IT_SHOTGUN << (t[0] - '2'));
+                               host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | (IT_SHOTGUN << (t[0] - '2'));
                }
                else
                {
                        if (t[0] >= '2')
-                               host_client->edict->v->items = (int)host_client->edict->v->items | (IT_SHOTGUN << (t[0] - '2'));
+                               host_client->edict->fields.server->items = (int)host_client->edict->fields.server->items | (IT_SHOTGUN << (t[0] - '2'));
                }
                break;
 
        case 's':
-               if (gamemode == GAME_ROGUE && (val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_shells1)))
+               if (gamemode == GAME_ROGUE && (val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_shells1)))
                        val->_float = v;
 
-               host_client->edict->v->ammo_shells = v;
+               host_client->edict->fields.server->ammo_shells = v;
                break;
        case 'n':
                if (gamemode == GAME_ROGUE)
                {
-                       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_nails1)))
+                       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_nails1)))
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon <= IT_LIGHTNING)
-                                       host_client->edict->v->ammo_nails = v;
+                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_nails = v;
                        }
                }
                else
                {
-                       host_client->edict->v->ammo_nails = v;
+                       host_client->edict->fields.server->ammo_nails = v;
                }
                break;
        case 'l':
                if (gamemode == GAME_ROGUE)
                {
-                       val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_lava_nails);
+                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_lava_nails);
                        if (val)
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon > IT_LIGHTNING)
-                                       host_client->edict->v->ammo_nails = v;
+                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_nails = v;
                        }
                }
                break;
        case 'r':
                if (gamemode == GAME_ROGUE)
                {
-                       val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_rockets1);
+                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_rockets1);
                        if (val)
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon <= IT_LIGHTNING)
-                                       host_client->edict->v->ammo_rockets = v;
+                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_rockets = v;
                        }
                }
                else
                {
-                       host_client->edict->v->ammo_rockets = v;
+                       host_client->edict->fields.server->ammo_rockets = v;
                }
                break;
        case 'm':
                if (gamemode == GAME_ROGUE)
                {
-                       val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_multi_rockets);
+                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_multi_rockets);
                        if (val)
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon > IT_LIGHTNING)
-                                       host_client->edict->v->ammo_rockets = v;
+                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_rockets = v;
                        }
                }
                break;
        case 'h':
-               host_client->edict->v->health = v;
+               host_client->edict->fields.server->health = v;
                break;
        case 'c':
                if (gamemode == GAME_ROGUE)
                {
-                       val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_cells1);
+                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_cells1);
                        if (val)
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon <= IT_LIGHTNING)
-                                       host_client->edict->v->ammo_cells = v;
+                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_cells = v;
                        }
                }
                else
                {
-                       host_client->edict->v->ammo_cells = v;
+                       host_client->edict->fields.server->ammo_cells = v;
                }
                break;
        case 'p':
                if (gamemode == GAME_ROGUE)
                {
-                       val = GETEDICTFIELDVALUE(host_client->edict, eval_ammo_plasma);
+                       val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ammo_plasma);
                        if (val)
                        {
                                val->_float = v;
-                               if (host_client->edict->v->weapon > IT_LIGHTNING)
-                                       host_client->edict->v->ammo_cells = v;
+                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                                       host_client->edict->fields.server->ammo_cells = v;
                        }
                }
                break;
        }
 }
 
-edict_t        *FindViewthing (void)
+prvm_edict_t   *FindViewthing (void)
 {
        int             i;
-       edict_t *e;
+       prvm_edict_t    *e;
 
-       for (i=0 ; i<sv.num_edicts ; i++)
+       for (i=0 ; i<prog->num_edicts ; i++)
        {
-               e = EDICT_NUM(i);
-               if (!strcmp (PR_GetString(e->v->classname), "viewthing"))
+               e = PRVM_EDICT_NUM(i);
+               if (!strcmp (PRVM_GetString(e->fields.server->classname), "viewthing"))
                        return e;
        }
        Con_Print("No viewthing on map\n");
@@ -1636,7 +1659,7 @@ Host_Viewmodel_f
 */
 void Host_Viewmodel_f (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        model_t *m;
 
        e = FindViewthing ();
@@ -1650,8 +1673,8 @@ void Host_Viewmodel_f (void)
                return;
        }
 
-       e->v->frame = 0;
-       cl.model_precache[(int)e->v->modelindex] = m;
+       e->fields.server->frame = 0;
+       cl.model_precache[(int)e->fields.server->modelindex] = m;
 }
 
 /*
@@ -1661,20 +1684,20 @@ Host_Viewframe_f
 */
 void Host_Viewframe_f (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        int             f;
        model_t *m;
 
        e = FindViewthing ();
        if (!e)
                return;
-       m = cl.model_precache[(int)e->v->modelindex];
+       m = cl.model_precache[(int)e->fields.server->modelindex];
 
        f = atoi(Cmd_Argv(1));
        if (f >= m->numframes)
                f = m->numframes-1;
 
-       e->v->frame = f;
+       e->fields.server->frame = f;
 }
 
 
@@ -1693,19 +1716,19 @@ Host_Viewnext_f
 */
 void Host_Viewnext_f (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        model_t *m;
 
        e = FindViewthing ();
        if (!e)
                return;
-       m = cl.model_precache[(int)e->v->modelindex];
+       m = cl.model_precache[(int)e->fields.server->modelindex];
 
-       e->v->frame = e->v->frame + 1;
-       if (e->v->frame >= m->numframes)
-               e->v->frame = m->numframes - 1;
+       e->fields.server->frame = e->fields.server->frame + 1;
+       if (e->fields.server->frame >= m->numframes)
+               e->fields.server->frame = m->numframes - 1;
 
-       PrintFrameName (m, e->v->frame);
+       PrintFrameName (m, e->fields.server->frame);
 }
 
 /*
@@ -1715,20 +1738,20 @@ Host_Viewprev_f
 */
 void Host_Viewprev_f (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        model_t *m;
 
        e = FindViewthing ();
        if (!e)
                return;
 
-       m = cl.model_precache[(int)e->v->modelindex];
+       m = cl.model_precache[(int)e->fields.server->modelindex];
 
-       e->v->frame = e->v->frame - 1;
-       if (e->v->frame < 0)
-               e->v->frame = 0;
+       e->fields.server->frame = e->fields.server->frame - 1;
+       if (e->fields.server->frame < 0)
+               e->fields.server->frame = 0;
 
-       PrintFrameName (m, e->v->frame);
+       PrintFrameName (m, e->fields.server->frame);
 }
 
 /*
index a512ef804e0370e98c3cd772d38d9a960325ebaa..a143524d59df385551d57e8dde1a7a7e0c9012f6 100644 (file)
@@ -75,11 +75,12 @@ OBJ_COMMON= \
        palette.o \
        polygon.o \
        portals.o \
-       pr_cmds.o \
-       pr_edict.o \
-       pr_exec.o \
+#      pr_cmds.o \
+#      pr_edict.o \
+#      pr_exec.o \
        protocol.o \
        mvm_cmds.o \
+       svvm_cmds.o \
        prvm_cmds.o \
        prvm_edict.o \
        prvm_exec.o \
diff --git a/menu.c b/menu.c
index 130d5bdf1e5f72961f70fc6fca8bdc604b4e787b..466e9f1f070dc840d578d5b863fa0519fdc8132b 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -4629,8 +4629,8 @@ void MP_Keydown (int key, char ascii)
        *prog->time = realtime;
 
        // pass key
-       prog->globals[OFS_PARM0] = (float) key;
-       prog->globals[OFS_PARM1] = (float) ascii;
+       prog->globals.generic[OFS_PARM0] = (float) key;
+       prog->globals.generic[OFS_PARM1] = (float) ascii;
        PRVM_ExecuteProgram(m_keydown, M_F_KEYDOWN"(float key, float ascii) required\n");
 
        PRVM_End;
@@ -4694,9 +4694,10 @@ void MP_Init (void)
        PRVM_Begin;
        PRVM_InitProg(PRVM_MENUPROG);
 
-       prog->crc = M_PROGHEADER_CRC;
+       prog->headercrc = M_PROGHEADER_CRC;
        prog->edictprivate_size = 0; // no private struct used
        prog->name = M_NAME;
+       prog->num_edicts = 1;
        prog->limit_edicts = M_MAX_EDICTS;
        prog->extensionstring = vm_m_extensions;
        prog->builtins = vm_m_builtins;
@@ -4708,7 +4709,7 @@ void MP_Init (void)
        // allocate the mempools
        prog->progs_mempool = Mem_AllocPool(M_PROG_FILENAME, 0, NULL);
 
-       PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func);
+       PRVM_LoadProgs(M_PROG_FILENAME, m_numrequiredfunc, m_required_func, 0, NULL);
 
        // set m_draw and m_keydown
        m_draw = (func_t) (PRVM_ED_FindFunction(M_F_DRAW) - prog->functions);
index 5636ad0086fda8d6408907840d5e28ec7570b331..401b33d6065ba223f176c95df8809cc0e10f59b1 100644 (file)
@@ -6,6 +6,54 @@
 char *vm_m_extensions =
 "DP_CINEMATIC_DPV";
 
+/*
+=========
+VM_M_precache_file
+
+string precache_file(string)
+=========
+*/
+void VM_M_precache_file (void)
+{      // precache_file is only used to copy files with qcc, it does nothing
+       VM_SAFEPARMCOUNT(1,VM_precache_file);
+
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
+/*
+=========
+VM_M_preache_error
+
+used instead of the other VM_precache_* functions in the builtin list
+=========
+*/
+
+void VM_M_precache_error (void)
+{
+       PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
+}
+
+/*
+=========
+VM_M_precache_sound
+
+string precache_sound (string sample)
+=========
+*/
+void VM_M_precache_sound (void)
+{
+       const char      *s;
+
+       VM_SAFEPARMCOUNT(1, VM_precache_sound);
+
+       s = PRVM_G_STRING(OFS_PARM0);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+       VM_CheckEmptyString (s);
+
+       if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
+               Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
+}
+
 /*
 =========
 VM_M_setmousetarget
@@ -75,7 +123,7 @@ void VM_M_setkeydest(void)
                // key_dest = key_message
                // break;
        default:
-               PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals[OFS_PARM0]);
+               PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals.generic[OFS_PARM0]);
        }
 }
 
@@ -672,6 +720,98 @@ void VM_M_addwantedserverlistkey( void )
        VM_SAFEPARMCOUNT( 1, VM_M_addwantedserverlistkey );
 }
 
+/*
+===============================================================================
+MESSAGE WRITING
+
+used only for client and menu
+severs uses VM_SV_...
+
+Write*(* data, float type, float to)
+
+===============================================================================
+*/
+
+#define        MSG_BROADCAST   0               // unreliable to all
+#define        MSG_ONE                 1               // reliable to one (msg_entity)
+#define        MSG_ALL                 2               // reliable to all
+#define        MSG_INIT                3               // write to the init string
+
+sizebuf_t *VM_WriteDest (void)
+{
+       int             dest;
+       int             destclient;
+
+       if(!sv.active)
+               PRVM_ERROR("VM_WriteDest: game is not server (%s)\n", PRVM_NAME);
+
+       dest = PRVM_G_FLOAT(OFS_PARM1);
+       switch (dest)
+       {
+       case MSG_BROADCAST:
+               return &sv.datagram;
+
+       case MSG_ONE:
+               destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
+               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
+                       PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
+
+               return &svs.clients[destclient].message;
+
+       case MSG_ALL:
+               return &sv.reliable_datagram;
+
+       case MSG_INIT:
+               return &sv.signon;
+
+       default:
+               PRVM_ERROR ("WriteDest: bad destination");
+               break;
+       }
+
+       return NULL;
+}
+
+void VM_M_WriteByte (void)
+{
+       MSG_WriteByte (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_M_WriteChar (void)
+{
+       MSG_WriteChar (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_M_WriteShort (void)
+{
+       MSG_WriteShort (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_M_WriteLong (void)
+{
+       MSG_WriteLong (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_M_WriteAngle (void)
+{
+       MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+}
+
+void VM_M_WriteCoord (void)
+{
+       MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
+}
+
+void VM_M_WriteString (void)
+{
+       MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
+}
+
+void VM_M_WriteEntity (void)
+{
+       MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
+}
+
 prvm_builtin_t vm_m_builtins[] = {
        0, // to be consistent with the old vm
        // common builtings (mostly)
@@ -702,8 +842,8 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_findfloat,
        VM_findchain,
        VM_findchainfloat,
-       VM_precache_file,
-       VM_precache_sound,
+       VM_M_precache_file,
+       VM_M_precache_sound,
        VM_coredump,    // 30
        VM_traceon,
        VM_traceoff,
@@ -767,14 +907,14 @@ prvm_builtin_t vm_m_builtins[] = {
        e100,                   // 300
        e100,                   // 400
        // msg functions
-       VM_WriteByte,
-       VM_WriteChar,
-       VM_WriteShort,
-       VM_WriteLong,
-       VM_WriteAngle,
-       VM_WriteCoord,
-       VM_WriteString,
-       VM_WriteEntity, // 408
+       VM_M_WriteByte,
+       VM_M_WriteChar,
+       VM_M_WriteShort,
+       VM_M_WriteLong,
+       VM_M_WriteAngle,
+       VM_M_WriteCoord,
+       VM_M_WriteString,
+       VM_M_WriteEntity,       // 408
        0,
        0,                              // 410
        e10,                    // 420
index e5fe3d8845ae52498c022300d1a04fdf9bbc0b6d..ba94089475c699826a5b22663817c02cdec248bb 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -1583,7 +1583,7 @@ int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length,
                                                        MSG_WriteByte(&net_message, playerNumber);
                                                        MSG_WriteString(&net_message, client->name);
                                                        MSG_WriteLong(&net_message, client->colors);
-                                                       MSG_WriteLong(&net_message, (int)client->edict->v->frags);
+                                                       MSG_WriteLong(&net_message, (int)client->edict->fields.server->frags);
                                                        MSG_WriteLong(&net_message, (int)(realtime - client->connecttime));
                                                        MSG_WriteString(&net_message, client->netconnection ? client->netconnection->address : "botclient");
                                                        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
index 52555c95db1f72bb89725ad99d3cd730a06944b7..1fe17e146c9b3d0beec1fe33f11fbbbfb627f2f0 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -37,7 +37,7 @@ static char *PR_GetTempString(void)
        return s;
 }
 
-#define        RETURN_EDICT(e) (G_INT(OFS_RETURN) = EDICT_TO_PROG(e))
+#define        RETURN_EDICT(e) (PRVM_G_INT(OFS_RETURN) = PRVM_EDICT_TO_PROG(e))
 #define PF_WARNING(s) do{Con_Printf(s);PR_PrintState();return;}while(0)
 #define PF_ERROR(s) do{Host_Error(s);return;}while(0)
 
@@ -60,7 +60,7 @@ void PF_VarString(int first, char *out, int outlength)
        outend = out + outlength - 1;
        for (i = first;i < pr_argc && out < outend;i++)
        {
-               s = G_STRING((OFS_PARM0+i*3));
+               s = PRVM_G_STRING((OFS_PARM0+i*3));
                while (out < outend && *s)
                        *out++ = *s++;
        }
@@ -207,7 +207,7 @@ checkextension(extensionname)
 */
 void PF_checkextension (void)
 {
-       G_FLOAT(OFS_RETURN) = checkextension(G_STRING(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = checkextension(PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
@@ -222,12 +222,12 @@ error(value)
 */
 void PF_error (void)
 {
-       edict_t *ed;
+       prvm_edict_t    *ed;
        char string[STRINGTEMP_LENGTH];
 
        PF_VarString(0, string, sizeof(string));
-       Con_Printf("======SERVER ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string);
-       ed = PROG_TO_EDICT(pr_global_struct->self);
+       Con_Printf("======SERVER ERROR in %s:\n%s\n", PRVM_GetString(pr_xfunction->s_name), string);
+       ed = PRVM_PROG_TO_EDICT(prog->globals.server->self);
        ED_Print(ed);
 
        PF_ERROR("Program error");
@@ -245,12 +245,12 @@ objerror(value)
 */
 void PF_objerror (void)
 {
-       edict_t *ed;
+       prvm_edict_t    *ed;
        char string[STRINGTEMP_LENGTH];
 
        PF_VarString(0, string, sizeof(string));
-       Con_Printf("======OBJECT ERROR in %s:\n%s\n", PR_GetString(pr_xfunction->s_name), string);
-       ed = PROG_TO_EDICT(pr_global_struct->self);
+       Con_Printf("======OBJECT ERROR in %s:\n%s\n", PRVM_GetString(pr_xfunction->s_name), string);
+       ed = PRVM_PROG_TO_EDICT(prog->globals.server->self);
        ED_Print(ed);
        ED_Free (ed);
 }
@@ -266,7 +266,7 @@ makevectors(vector)
 */
 void PF_makevectors (void)
 {
-       AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
+       AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
 }
 
 /*
@@ -279,8 +279,8 @@ vectorvectors(vector, vector)
 */
 void PF_vectorvectors (void)
 {
-       VectorNormalize2(G_VECTOR(OFS_PARM0), pr_global_struct->v_forward);
-       VectorVectors(pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up);
+       VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward);
+       VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
 }
 
 /*
@@ -294,21 +294,21 @@ setorigin (entity, origin)
 */
 void PF_setorigin (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        float   *org;
 
-       e = G_EDICT(OFS_PARM0);
-       if (e == sv.edicts)
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
                PF_WARNING("setorigin: can not modify world entity\n");
-       if (e->e->free)
+       if (e->priv.server->free)
                PF_WARNING("setorigin: can not modify free entity\n");
-       org = G_VECTOR(OFS_PARM1);
-       VectorCopy (org, e->v->origin);
+       org = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy (org, e->fields.server->origin);
        SV_LinkEdict (e, false);
 }
 
 
-void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
+void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
 {
        int             i;
 
@@ -317,9 +317,9 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
                        PF_ERROR("SetMinMaxSize: backwards mins/maxs\n");
 
 // set derived values
-       VectorCopy (min, e->v->mins);
-       VectorCopy (max, e->v->maxs);
-       VectorSubtract (max, min, e->v->size);
+       VectorCopy (min, e->fields.server->mins);
+       VectorCopy (max, e->fields.server->maxs);
+       VectorSubtract (max, min, e->fields.server->size);
 
        SV_LinkEdict (e, false);
 }
@@ -336,16 +336,16 @@ setsize (entity, minvector, maxvector)
 */
 void PF_setsize (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        float   *min, *max;
 
-       e = G_EDICT(OFS_PARM0);
-       if (e == sv.edicts)
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
                PF_WARNING("setsize: can not modify world entity\n");
-       if (e->e->free)
+       if (e->priv.server->free)
                PF_WARNING("setsize: can not modify free entity\n");
-       min = G_VECTOR(OFS_PARM1);
-       max = G_VECTOR(OFS_PARM2);
+       min = PRVM_G_VECTOR(OFS_PARM1);
+       max = PRVM_G_VECTOR(OFS_PARM2);
        SetMinMaxSize (e, min, max, false);
 }
 
@@ -360,18 +360,18 @@ setmodel(entity, model)
 static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
 void PF_setmodel (void)
 {
-       edict_t *e;
+       prvm_edict_t    *e;
        model_t *mod;
        int             i;
 
-       e = G_EDICT(OFS_PARM0);
-       if (e == sv.edicts)
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
                PF_WARNING("setmodel: can not modify world entity\n");
-       if (e->e->free)
+       if (e->priv.server->free)
                PF_WARNING("setmodel: can not modify free entity\n");
-       i = SV_ModelIndex(G_STRING(OFS_PARM1), 1);
-       e->v->model = PR_SetEngineString(sv.model_precache[i]);
-       e->v->modelindex = i;
+       i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
+       e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
+       e->fields.server->modelindex = i;
 
        mod = sv.models[i];
 
@@ -417,7 +417,7 @@ void PF_sprint (void)
        int                     entnum;
        char string[STRINGTEMP_LENGTH];
 
-       entnum = G_EDICTNUM(OFS_PARM0);
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
@@ -447,7 +447,7 @@ void PF_centerprint (void)
        int                     entnum;
        char string[STRINGTEMP_LENGTH];
 
-       entnum = G_EDICTNUM(OFS_PARM0);
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
@@ -475,7 +475,7 @@ void PF_normalize (void)
        vec3_t  newvalue;
        float   new;
 
-       value1 = G_VECTOR(OFS_PARM0);
+       value1 = PRVM_G_VECTOR(OFS_PARM0);
 
        new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
        new = sqrt(new);
@@ -490,7 +490,7 @@ void PF_normalize (void)
                newvalue[2] = value1[2] * new;
        }
 
-       VectorCopy (newvalue, G_VECTOR(OFS_RETURN));
+       VectorCopy (newvalue, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 /*
@@ -505,12 +505,12 @@ void PF_vlen (void)
        float   *value1;
        float   new;
 
-       value1 = G_VECTOR(OFS_PARM0);
+       value1 = PRVM_G_VECTOR(OFS_PARM0);
 
        new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
        new = sqrt(new);
 
-       G_FLOAT(OFS_RETURN) = new;
+       PRVM_G_FLOAT(OFS_RETURN) = new;
 }
 
 /*
@@ -525,7 +525,7 @@ void PF_vectoyaw (void)
        float   *value1;
        float   yaw;
 
-       value1 = G_VECTOR(OFS_PARM0);
+       value1 = PRVM_G_VECTOR(OFS_PARM0);
 
        if (value1[1] == 0 && value1[0] == 0)
                yaw = 0;
@@ -536,7 +536,7 @@ void PF_vectoyaw (void)
                        yaw += 360;
        }
 
-       G_FLOAT(OFS_RETURN) = yaw;
+       PRVM_G_FLOAT(OFS_RETURN) = yaw;
 }
 
 
@@ -551,7 +551,7 @@ void PF_vectoangles (void)
 {
        double value1[3], forward, yaw, pitch;
 
-       VectorCopy(G_VECTOR(OFS_PARM0), value1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), value1);
 
        if (value1[1] == 0 && value1[0] == 0)
        {
@@ -581,7 +581,7 @@ void PF_vectoangles (void)
                        pitch += 360;
        }
 
-       VectorSet(G_VECTOR(OFS_RETURN), pitch, yaw, 0);
+       VectorSet(PRVM_G_VECTOR(OFS_RETURN), pitch, yaw, 0);
 }
 
 /*
@@ -595,7 +595,7 @@ random()
 */
 void PF_random (void)
 {
-       G_FLOAT(OFS_RETURN) = lhrandom(0, 1);
+       PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1);
 }
 
 /*
@@ -611,10 +611,10 @@ void PF_particle (void)
        float           color;
        float           count;
 
-       org = G_VECTOR(OFS_PARM0);
-       dir = G_VECTOR(OFS_PARM1);
-       color = G_FLOAT(OFS_PARM2);
-       count = G_FLOAT(OFS_PARM3);
+       org = PRVM_G_VECTOR(OFS_PARM0);
+       dir = PRVM_G_VECTOR(OFS_PARM1);
+       color = PRVM_G_FLOAT(OFS_PARM2);
+       count = PRVM_G_FLOAT(OFS_PARM3);
        SV_StartParticle (org, dir, color, count);
 }
 
@@ -632,10 +632,10 @@ void PF_ambientsound (void)
        float           vol, attenuation;
        int                     soundnum, large;
 
-       pos = G_VECTOR (OFS_PARM0);
-       samp = G_STRING(OFS_PARM1);
-       vol = G_FLOAT(OFS_PARM2);
-       attenuation = G_FLOAT(OFS_PARM3);
+       pos = PRVM_G_VECTOR (OFS_PARM0);
+       samp = PRVM_G_STRING(OFS_PARM1);
+       vol = PRVM_G_FLOAT(OFS_PARM2);
+       attenuation = PRVM_G_FLOAT(OFS_PARM3);
 
 // check to see if samp was properly precached
        soundnum = SV_SoundIndex(samp, 1);
@@ -684,15 +684,15 @@ void PF_sound (void)
 {
        const char      *sample;
        int                     channel;
-       edict_t         *entity;
+       prvm_edict_t            *entity;
        int             volume;
        float attenuation;
 
-       entity = G_EDICT(OFS_PARM0);
-       channel = G_FLOAT(OFS_PARM1);
-       sample = G_STRING(OFS_PARM2);
-       volume = G_FLOAT(OFS_PARM3) * 255;
-       attenuation = G_FLOAT(OFS_PARM4);
+       entity = PRVM_G_EDICT(OFS_PARM0);
+       channel = PRVM_G_FLOAT(OFS_PARM1);
+       sample = PRVM_G_STRING(OFS_PARM2);
+       volume = PRVM_G_FLOAT(OFS_PARM3) * 255;
+       attenuation = PRVM_G_FLOAT(OFS_PARM4);
 
        if (volume < 0 || volume > 255)
                PF_WARNING("SV_StartSound: volume must be in range 0-1\n");
@@ -734,29 +734,29 @@ void PF_traceline (void)
        float   *v1, *v2;
        trace_t trace;
        int             move;
-       edict_t *ent;
+       prvm_edict_t    *ent;
 
        pr_xfunction->builtinsprofile += 30;
 
-       v1 = G_VECTOR(OFS_PARM0);
-       v2 = G_VECTOR(OFS_PARM1);
-       move = G_FLOAT(OFS_PARM2);
-       ent = G_EDICT(OFS_PARM3);
+       v1 = PRVM_G_VECTOR(OFS_PARM0);
+       v2 = PRVM_G_VECTOR(OFS_PARM1);
+       move = PRVM_G_FLOAT(OFS_PARM2);
+       ent = PRVM_G_EDICT(OFS_PARM3);
 
        trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent);
 
-       pr_global_struct->trace_allsolid = trace.allsolid;
-       pr_global_struct->trace_startsolid = trace.startsolid;
-       pr_global_struct->trace_fraction = trace.fraction;
-       pr_global_struct->trace_inwater = trace.inwater;
-       pr_global_struct->trace_inopen = trace.inopen;
-       VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
-       VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
-       pr_global_struct->trace_plane_dist =  trace.plane.dist;
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
        if (trace.ent)
-               pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
-               pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
        // FIXME: add trace_endcontents
 }
 
@@ -778,61 +778,61 @@ void PF_tracebox (void)
        float   *v1, *v2, *m1, *m2;
        trace_t trace;
        int             move;
-       edict_t *ent;
+       prvm_edict_t    *ent;
 
        pr_xfunction->builtinsprofile += 30;
 
-       v1 = G_VECTOR(OFS_PARM0);
-       m1 = G_VECTOR(OFS_PARM1);
-       m2 = G_VECTOR(OFS_PARM2);
-       v2 = G_VECTOR(OFS_PARM3);
-       move = G_FLOAT(OFS_PARM4);
-       ent = G_EDICT(OFS_PARM5);
+       v1 = PRVM_G_VECTOR(OFS_PARM0);
+       m1 = PRVM_G_VECTOR(OFS_PARM1);
+       m2 = PRVM_G_VECTOR(OFS_PARM2);
+       v2 = PRVM_G_VECTOR(OFS_PARM3);
+       move = PRVM_G_FLOAT(OFS_PARM4);
+       ent = PRVM_G_EDICT(OFS_PARM5);
 
        trace = SV_Move (v1, m1, m2, v2, move, ent);
 
-       pr_global_struct->trace_allsolid = trace.allsolid;
-       pr_global_struct->trace_startsolid = trace.startsolid;
-       pr_global_struct->trace_fraction = trace.fraction;
-       pr_global_struct->trace_inwater = trace.inwater;
-       pr_global_struct->trace_inopen = trace.inopen;
-       VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
-       VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
-       pr_global_struct->trace_plane_dist =  trace.plane.dist;
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
        if (trace.ent)
-               pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
-               pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
 }
 
-extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
-void PF_TraceToss (void)
+extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore);
+void PF_tracetoss (void)
 {
        trace_t trace;
-       edict_t *ent;
-       edict_t *ignore;
+       prvm_edict_t    *ent;
+       prvm_edict_t    *ignore;
 
        pr_xfunction->builtinsprofile += 600;
 
-       ent = G_EDICT(OFS_PARM0);
-       if (ent == sv.edicts)
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
                PF_WARNING("tracetoss: can not use world entity\n");
-       ignore = G_EDICT(OFS_PARM1);
+       ignore = PRVM_G_EDICT(OFS_PARM1);
 
        trace = SV_Trace_Toss (ent, ignore);
 
-       pr_global_struct->trace_allsolid = trace.allsolid;
-       pr_global_struct->trace_startsolid = trace.startsolid;
-       pr_global_struct->trace_fraction = trace.fraction;
-       pr_global_struct->trace_inwater = trace.inwater;
-       pr_global_struct->trace_inopen = trace.inopen;
-       VectorCopy (trace.endpos, pr_global_struct->trace_endpos);
-       VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal);
-       pr_global_struct->trace_plane_dist =  trace.plane.dist;
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
        if (trace.ent)
-               pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
-               pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts);
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
 }
 
 
@@ -858,7 +858,7 @@ qbyte checkpvs[MAX_MAP_LEAFS/8];
 int PF_newcheckclient (int check)
 {
        int             i;
-       edict_t *ent;
+       prvm_edict_t    *ent;
        vec3_t  org;
 
 // cycle to the next one
@@ -877,16 +877,16 @@ int PF_newcheckclient (int check)
                if (i == svs.maxclients+1)
                        i = 1;
                // look up the client's edict
-               ent = EDICT_NUM(i);
+               ent = PRVM_EDICT_NUM(i);
                // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
-               if (i != check && (ent->e->free || ent->v->health <= 0 || ((int)ent->v->flags & FL_NOTARGET)))
+               if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
                        continue;
                // found a valid client (possibly the same one again)
                break;
        }
 
 // get the PVS for the entity
-       VectorAdd(ent->v->origin, ent->v->view_ofs, org);
+       VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
        checkpvsbytes = 0;
        if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
                checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
@@ -912,7 +912,7 @@ name checkclient ()
 int c_invis, c_notvis;
 void PF_checkclient (void)
 {
-       edict_t *ent, *self;
+       prvm_edict_t    *ent, *self;
        vec3_t  view;
 
        // find a new check if on a new frame
@@ -923,20 +923,20 @@ void PF_checkclient (void)
        }
 
        // return check if it might be visible
-       ent = EDICT_NUM(sv.lastcheck);
-       if (ent->e->free || ent->v->health <= 0)
+       ent = PRVM_EDICT_NUM(sv.lastcheck);
+       if (ent->priv.server->free || ent->fields.server->health <= 0)
        {
-               RETURN_EDICT(sv.edicts);
+               RETURN_EDICT(prog->edicts);
                return;
        }
 
        // if current entity can't possibly see the check entity, return 0
-       self = PROG_TO_EDICT(pr_global_struct->self);
-       VectorAdd(self->v->origin, self->v->view_ofs, view);
+       self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
        if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
        {
                c_notvis++;
-               RETURN_EDICT(sv.edicts);
+               RETURN_EDICT(prog->edicts);
                return;
        }
 
@@ -963,13 +963,13 @@ void PF_stuffcmd (void)
        const char      *str;
        client_t        *old;
 
-       entnum = G_EDICTNUM(OFS_PARM0);
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
                Con_Print("Can't stuffcmd to a non-client\n");
                return;
        }
-       str = G_STRING(OFS_PARM1);
+       str = PRVM_G_STRING(OFS_PARM1);
 
        old = host_client;
        host_client = svs.clients + entnum-1;
@@ -988,7 +988,7 @@ localcmd (string)
 */
 void PF_localcmd (void)
 {
-       Cbuf_AddText(G_STRING(OFS_PARM0));
+       Cbuf_AddText(PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
@@ -1000,7 +1000,7 @@ float cvar (string)
 */
 void PF_cvar (void)
 {
-       G_FLOAT(OFS_RETURN) = Cvar_VariableValue(G_STRING(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
@@ -1012,7 +1012,7 @@ float cvar (string)
 */
 void PF_cvar_set (void)
 {
-       Cvar_Set(G_STRING(OFS_PARM0), G_STRING(OFS_PARM1));
+       Cvar_Set(PRVM_G_STRING(OFS_PARM0), PRVM_G_STRING(OFS_PARM1));
 }
 
 /*
@@ -1026,17 +1026,17 @@ findradius (origin, radius)
 */
 void PF_findradius (void)
 {
-       edict_t *ent, *chain;
+       prvm_edict_t *ent, *chain;
        vec_t radius, radius2;
        vec3_t org, eorg, mins, maxs;
        int i;
        int numtouchedicts;
-       edict_t *touchedicts[MAX_EDICTS];
+       prvm_edict_t *touchedicts[MAX_EDICTS];
 
-       chain = (edict_t *)sv.edicts;
+       chain = (prvm_edict_t *)prog->edicts;
 
-       VectorCopy(G_VECTOR(OFS_PARM0), org);
-       radius = G_FLOAT(OFS_PARM1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       radius = PRVM_G_FLOAT(OFS_PARM1);
        radius2 = radius * radius;
 
        mins[0] = org[0] - (radius + 1);
@@ -1058,23 +1058,23 @@ void PF_findradius (void)
                pr_xfunction->builtinsprofile++;
                // Quake did not return non-solid entities but darkplaces does
                // (note: this is the reason you can't blow up fallen zombies)
-               if (ent->v->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
+               if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
                        continue;
                // LordHavoc: compare against bounding box rather than center so it
                // doesn't miss large objects, and use DotProduct instead of Length
                // for a major speedup
-               VectorSubtract(org, ent->v->origin, eorg);
+               VectorSubtract(org, ent->fields.server->origin, eorg);
                if (sv_gameplayfix_findradiusdistancetobox.integer)
                {
-                       eorg[0] -= bound(ent->v->mins[0], eorg[0], ent->v->maxs[0]);
-                       eorg[1] -= bound(ent->v->mins[1], eorg[1], ent->v->maxs[1]);
-                       eorg[2] -= bound(ent->v->mins[2], eorg[2], ent->v->maxs[2]);
+                       eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
+                       eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
+                       eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
                }
                else
-                       VectorMAMAM(1, eorg, 0.5f, ent->v->mins, 0.5f, ent->v->maxs, eorg);
+                       VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
                if (DotProduct(eorg, eorg) < radius2)
                {
-                       ent->v->chain = EDICT_TO_PROG(chain);
+                       ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
                        chain = ent;
                }
        }
@@ -1102,42 +1102,42 @@ void PF_ftos (void)
 {
        float v;
        char *s;
-       v = G_FLOAT(OFS_PARM0);
+       v = PRVM_G_FLOAT(OFS_PARM0);
 
        s = PR_GetTempString();
        if ((float)((int)v) == v)
                sprintf(s, "%i", (int)v);
        else
                sprintf(s, "%f", v);
-       G_INT(OFS_RETURN) = PR_SetEngineString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 void PF_fabs (void)
 {
        float   v;
-       v = G_FLOAT(OFS_PARM0);
-       G_FLOAT(OFS_RETURN) = fabs(v);
+       v = PRVM_G_FLOAT(OFS_PARM0);
+       PRVM_G_FLOAT(OFS_RETURN) = fabs(v);
 }
 
 void PF_vtos (void)
 {
        char *s;
        s = PR_GetTempString();
-       sprintf (s, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
-       G_INT(OFS_RETURN) = PR_SetEngineString(s);
+       sprintf (s, "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 void PF_etos (void)
 {
        char *s;
        s = PR_GetTempString();
-       sprintf (s, "entity %i", G_EDICTNUM(OFS_PARM0));
-       G_INT(OFS_RETURN) = PR_SetEngineString(s);
+       sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 void PF_Spawn (void)
 {
-       edict_t *ed;
+       prvm_edict_t    *ed;
        pr_xfunction->builtinsprofile += 20;
        ed = ED_Alloc();
        RETURN_EDICT(ed);
@@ -1145,16 +1145,16 @@ void PF_Spawn (void)
 
 void PF_Remove (void)
 {
-       edict_t *ed;
+       prvm_edict_t    *ed;
        pr_xfunction->builtinsprofile += 20;
 
-       ed = G_EDICT(OFS_PARM0);
-       if (ed == sv.edicts)
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       if (ed == prog->edicts)
                PF_WARNING("remove: tried to remove world\n");
-       if (NUM_FOR_EDICT(ed) <= svs.maxclients)
+       if (PRVM_NUM_FOR_EDICT(ed) <= svs.maxclients)
                PF_WARNING("remove: tried to remove a client\n");
        // LordHavoc: not an error because id1 progs did this in some cases (killtarget removes entities, even if they are already removed in some cases...)
-       if (ed->e->free && developer.integer)
+       if (ed->priv.server->free && developer.integer)
                PF_WARNING("remove: tried to remove an entity that was already removed\n");
        ED_Free (ed);
 }
@@ -1166,22 +1166,22 @@ void PF_Find (void)
        int             e;
        int             f;
        const char      *s, *t;
-       edict_t *ed;
+       prvm_edict_t    *ed;
 
-       e = G_EDICTNUM(OFS_PARM0);
-       f = G_INT(OFS_PARM1);
-       s = G_STRING(OFS_PARM2);
+       e = PRVM_G_EDICTNUM(OFS_PARM0);
+       f = PRVM_G_INT(OFS_PARM1);
+       s = PRVM_G_STRING(OFS_PARM2);
        if (!s || !s[0])
        {
-               RETURN_EDICT(sv.edicts);
+               RETURN_EDICT(prog->edicts);
                return;
        }
 
-       for (e++ ; e < sv.num_edicts ; e++)
+       for (e++ ; e < prog->num_edicts ; e++)
        {
                pr_xfunction->builtinsprofile++;
-               ed = EDICT_NUM(e);
-               if (ed->e->free)
+               ed = PRVM_EDICT_NUM(e);
+               if (ed->priv.server->free)
                        continue;
                t = E_STRING(ed,f);
                if (!t)
@@ -1193,7 +1193,7 @@ void PF_Find (void)
                }
        }
 
-       RETURN_EDICT(sv.edicts);
+       RETURN_EDICT(prog->edicts);
 }
 
 // LordHavoc: added this for searching float, int, and entity reference fields
@@ -1202,17 +1202,17 @@ void PF_FindFloat (void)
        int             e;
        int             f;
        float   s;
-       edict_t *ed;
+       prvm_edict_t    *ed;
 
-       e = G_EDICTNUM(OFS_PARM0);
-       f = G_INT(OFS_PARM1);
-       s = G_FLOAT(OFS_PARM2);
+       e = PRVM_G_EDICTNUM(OFS_PARM0);
+       f = PRVM_G_INT(OFS_PARM1);
+       s = PRVM_G_FLOAT(OFS_PARM2);
 
-       for (e++ ; e < sv.num_edicts ; e++)
+       for (e++ ; e < prog->num_edicts ; e++)
        {
                pr_xfunction->builtinsprofile++;
-               ed = EDICT_NUM(e);
-               if (ed->e->free)
+               ed = PRVM_EDICT_NUM(e);
+               if (ed->priv.server->free)
                        continue;
                if (E_FLOAT(ed,f) == s)
                {
@@ -1221,7 +1221,7 @@ void PF_FindFloat (void)
                }
        }
 
-       RETURN_EDICT(sv.edicts);
+       RETURN_EDICT(prog->edicts);
 }
 
 // chained search for strings in entity fields
@@ -1231,23 +1231,23 @@ void PF_findchain (void)
        int             i;
        int             f;
        const char      *s, *t;
-       edict_t *ent, *chain;
+       prvm_edict_t    *ent, *chain;
 
-       chain = (edict_t *)sv.edicts;
+       chain = (prvm_edict_t *)prog->edicts;
 
-       f = G_INT(OFS_PARM0);
-       s = G_STRING(OFS_PARM1);
+       f = PRVM_G_INT(OFS_PARM0);
+       s = PRVM_G_STRING(OFS_PARM1);
        if (!s || !s[0])
        {
-               RETURN_EDICT(sv.edicts);
+               RETURN_EDICT(prog->edicts);
                return;
        }
 
-       ent = NEXT_EDICT(sv.edicts);
-       for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
+       ent = PRVM_NEXT_EDICT(prog->edicts);
+       for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        continue;
                t = E_STRING(ent,f);
                if (!t)
@@ -1255,7 +1255,7 @@ void PF_findchain (void)
                if (strcmp(t,s))
                        continue;
 
-               ent->v->chain = EDICT_TO_PROG(chain);
+               ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
@@ -1269,23 +1269,23 @@ void PF_findchainfloat (void)
        int             i;
        int             f;
        float   s;
-       edict_t *ent, *chain;
+       prvm_edict_t    *ent, *chain;
 
-       chain = (edict_t *)sv.edicts;
+       chain = (prvm_edict_t *)prog->edicts;
 
-       f = G_INT(OFS_PARM0);
-       s = G_FLOAT(OFS_PARM1);
+       f = PRVM_G_INT(OFS_PARM0);
+       s = PRVM_G_FLOAT(OFS_PARM1);
 
-       ent = NEXT_EDICT(sv.edicts);
-       for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
+       ent = PRVM_NEXT_EDICT(prog->edicts);
+       for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        continue;
                if (E_FLOAT(ent,f) != s)
                        continue;
 
-               ent->v->chain = EDICT_TO_PROG(chain);
+               ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
@@ -1298,17 +1298,17 @@ void PF_findflags (void)
        int             e;
        int             f;
        int             s;
-       edict_t *ed;
+       prvm_edict_t    *ed;
 
-       e = G_EDICTNUM(OFS_PARM0);
-       f = G_INT(OFS_PARM1);
-       s = (int)G_FLOAT(OFS_PARM2);
+       e = PRVM_G_EDICTNUM(OFS_PARM0);
+       f = PRVM_G_INT(OFS_PARM1);
+       s = (int)PRVM_G_FLOAT(OFS_PARM2);
 
-       for (e++ ; e < sv.num_edicts ; e++)
+       for (e++ ; e < prog->num_edicts ; e++)
        {
                pr_xfunction->builtinsprofile++;
-               ed = EDICT_NUM(e);
-               if (ed->e->free)
+               ed = PRVM_EDICT_NUM(e);
+               if (ed->priv.server->free)
                        continue;
                if ((int)E_FLOAT(ed,f) & s)
                {
@@ -1317,7 +1317,7 @@ void PF_findflags (void)
                }
        }
 
-       RETURN_EDICT(sv.edicts);
+       RETURN_EDICT(prog->edicts);
 }
 
 // LordHavoc: chained search for flags in float fields
@@ -1326,23 +1326,23 @@ void PF_findchainflags (void)
        int             i;
        int             f;
        int             s;
-       edict_t *ent, *chain;
+       prvm_edict_t    *ent, *chain;
 
-       chain = (edict_t *)sv.edicts;
+       chain = (prvm_edict_t *)prog->edicts;
 
-       f = G_INT(OFS_PARM0);
-       s = (int)G_FLOAT(OFS_PARM1);
+       f = PRVM_G_INT(OFS_PARM0);
+       s = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       ent = NEXT_EDICT(sv.edicts);
-       for (i = 1;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
+       ent = PRVM_NEXT_EDICT(prog->edicts);
+       for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                pr_xfunction->builtinsprofile++;
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        continue;
                if (!((int)E_FLOAT(ent,f) & s))
                        continue;
 
-               ent->v->chain = EDICT_TO_PROG(chain);
+               ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
@@ -1351,20 +1351,20 @@ void PF_findchainflags (void)
 
 void PF_precache_file (void)
 {      // precache_file is only used to copy files with qcc, it does nothing
-       G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
 }
 
 
 void PF_precache_sound (void)
 {
-       SV_SoundIndex(G_STRING(OFS_PARM0), 2);
-       G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
+       SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
 }
 
 void PF_precache_model (void)
 {
-       SV_ModelIndex(G_STRING(OFS_PARM0), 2);
-       G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
+       SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
 }
 
 
@@ -1385,7 +1385,7 @@ void PF_traceoff (void)
 
 void PF_eprint (void)
 {
-       ED_PrintNum (G_EDICTNUM(OFS_PARM0));
+       ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0));
 }
 
 /*
@@ -1397,24 +1397,24 @@ float(float yaw, float dist) walkmove
 */
 void PF_walkmove (void)
 {
-       edict_t *ent;
+       prvm_edict_t    *ent;
        float   yaw, dist;
        vec3_t  move;
        mfunction_t     *oldf;
        int     oldself;
 
        // assume failure if it returns early
-       G_FLOAT(OFS_RETURN) = 0;
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
 
-       ent = PROG_TO_EDICT(pr_global_struct->self);
-       if (ent == sv.edicts)
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
                PF_WARNING("walkmove: can not modify world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("walkmove: can not modify free entity\n");
-       yaw = G_FLOAT(OFS_PARM0);
-       dist = G_FLOAT(OFS_PARM1);
+       yaw = PRVM_G_FLOAT(OFS_PARM0);
+       dist = PRVM_G_FLOAT(OFS_PARM1);
 
-       if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
+       if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
                return;
 
        yaw = yaw*M_PI*2 / 360;
@@ -1425,14 +1425,14 @@ void PF_walkmove (void)
 
 // save program state, because SV_movestep may call other progs
        oldf = pr_xfunction;
-       oldself = pr_global_struct->self;
+       oldself = prog->globals.server->self;
 
-       G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
+       PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
 
 
 // restore program state
        pr_xfunction = oldf;
-       pr_global_struct->self = oldself;
+       prog->globals.server->self = oldself;
 }
 
 /*
@@ -1444,33 +1444,33 @@ void() droptofloor
 */
 void PF_droptofloor (void)
 {
-       edict_t         *ent;
+       prvm_edict_t            *ent;
        vec3_t          end;
        trace_t         trace;
 
        // assume failure if it returns early
-       G_FLOAT(OFS_RETURN) = 0;
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
 
-       ent = PROG_TO_EDICT(pr_global_struct->self);
-       if (ent == sv.edicts)
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
                PF_WARNING("droptofloor: can not modify world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("droptofloor: can not modify free entity\n");
 
-       VectorCopy (ent->v->origin, end);
+       VectorCopy (ent->fields.server->origin, end);
        end[2] -= 256;
 
-       trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+       trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
 
        if (trace.fraction != 1)
        {
-               VectorCopy (trace.endpos, ent->v->origin);
+               VectorCopy (trace.endpos, ent->fields.server->origin);
                SV_LinkEdict (ent, false);
-               ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-               ent->v->groundentity = EDICT_TO_PROG(trace.ent);
-               G_FLOAT(OFS_RETURN) = 1;
+               ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+               ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+               PRVM_G_FLOAT(OFS_RETURN) = 1;
                // if support is destroyed, keep suspended (gross hack for floating items in various maps)
-               ent->e->suspendedinairflag = true;
+               ent->priv.server->suspendedinairflag = true;
        }
 }
 
@@ -1488,8 +1488,8 @@ void PF_lightstyle (void)
        client_t        *client;
        int                     j;
 
-       style = G_FLOAT(OFS_PARM0);
-       val = G_STRING(OFS_PARM1);
+       style = PRVM_G_FLOAT(OFS_PARM0);
+       val = PRVM_G_STRING(OFS_PARM1);
 
 // change the string in sv
        strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
@@ -1512,19 +1512,19 @@ void PF_lightstyle (void)
 void PF_rint (void)
 {
        float   f;
-       f = G_FLOAT(OFS_PARM0);
+       f = PRVM_G_FLOAT(OFS_PARM0);
        if (f > 0)
-               G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
+               PRVM_G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
        else
-               G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
+               PRVM_G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
 }
 void PF_floor (void)
 {
-       G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = floor(PRVM_G_FLOAT(OFS_PARM0));
 }
 void PF_ceil (void)
 {
-       G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = ceil(PRVM_G_FLOAT(OFS_PARM0));
 }
 
 
@@ -1535,7 +1535,7 @@ PF_checkbottom
 */
 void PF_checkbottom (void)
 {
-       G_FLOAT(OFS_RETURN) = SV_CheckBottom (G_EDICT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
 }
 
 /*
@@ -1545,7 +1545,7 @@ PF_pointcontents
 */
 void PF_pointcontents (void)
 {
-       G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(G_VECTOR(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(PRVM_G_VECTOR(OFS_PARM0));
 }
 
 /*
@@ -1558,20 +1558,20 @@ entity nextent(entity)
 void PF_nextent (void)
 {
        int             i;
-       edict_t *ent;
+       prvm_edict_t    *ent;
 
-       i = G_EDICTNUM(OFS_PARM0);
+       i = PRVM_G_EDICTNUM(OFS_PARM0);
        while (1)
        {
                pr_xfunction->builtinsprofile++;
                i++;
-               if (i == sv.num_edicts)
+               if (i == prog->num_edicts)
                {
-                       RETURN_EDICT(sv.edicts);
+                       RETURN_EDICT(prog->edicts);
                        return;
                }
-               ent = EDICT_NUM(i);
-               if (!ent->e->free)
+               ent = PRVM_EDICT_NUM(i);
+               if (!ent->priv.server->free)
                {
                        RETURN_EDICT(ent);
                        return;
@@ -1589,7 +1589,7 @@ vector aim(entity, missilespeed)
 */
 void PF_aim (void)
 {
-       edict_t *ent, *check, *bestent;
+       prvm_edict_t    *ent, *check, *bestent;
        vec3_t  start, dir, end, bestdir;
        int             i, j;
        trace_t tr;
@@ -1597,29 +1597,29 @@ void PF_aim (void)
        float   speed;
 
        // assume failure if it returns early
-       VectorCopy(pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
+       VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
        // if sv_aim is so high it can't possibly accept anything, skip out early
        if (sv_aim.value >= 1)
                return;
 
-       ent = G_EDICT(OFS_PARM0);
-       if (ent == sv.edicts)
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
                PF_WARNING("aim: can not use world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("aim: can not use free entity\n");
-       speed = G_FLOAT(OFS_PARM1);
+       speed = PRVM_G_FLOAT(OFS_PARM1);
 
-       VectorCopy (ent->v->origin, start);
+       VectorCopy (ent->fields.server->origin, start);
        start[2] += 20;
 
 // try sending a trace straight
-       VectorCopy (pr_global_struct->v_forward, dir);
+       VectorCopy (prog->globals.server->v_forward, dir);
        VectorMA (start, 2048, dir, end);
        tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
-       if (tr.ent && ((edict_t *)tr.ent)->v->takedamage == DAMAGE_AIM
-       && (!teamplay.integer || ent->v->team <=0 || ent->v->team != ((edict_t *)tr.ent)->v->team) )
+       if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
+       && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
        {
-               VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
+               VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
                return;
        }
 
@@ -1629,22 +1629,22 @@ void PF_aim (void)
        bestdist = sv_aim.value;
        bestent = NULL;
 
-       check = NEXT_EDICT(sv.edicts);
-       for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
+       check = PRVM_NEXT_EDICT(prog->edicts);
+       for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
        {
                pr_xfunction->builtinsprofile++;
-               if (check->v->takedamage != DAMAGE_AIM)
+               if (check->fields.server->takedamage != DAMAGE_AIM)
                        continue;
                if (check == ent)
                        continue;
-               if (teamplay.integer && ent->v->team > 0 && ent->v->team == check->v->team)
+               if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
                        continue;       // don't aim at teammate
                for (j=0 ; j<3 ; j++)
-                       end[j] = check->v->origin[j]
-                       + 0.5*(check->v->mins[j] + check->v->maxs[j]);
+                       end[j] = check->fields.server->origin[j]
+                       + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
                VectorSubtract (end, start, dir);
                VectorNormalize (dir);
-               dist = DotProduct (dir, pr_global_struct->v_forward);
+               dist = DotProduct (dir, prog->globals.server->v_forward);
                if (dist < bestdist)
                        continue;       // to far to turn
                tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
@@ -1657,16 +1657,16 @@ void PF_aim (void)
 
        if (bestent)
        {
-               VectorSubtract (bestent->v->origin, ent->v->origin, dir);
-               dist = DotProduct (dir, pr_global_struct->v_forward);
-               VectorScale (pr_global_struct->v_forward, dist, end);
+               VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
+               dist = DotProduct (dir, prog->globals.server->v_forward);
+               VectorScale (prog->globals.server->v_forward, dist, end);
                end[2] = dir[2];
                VectorNormalize (end);
-               VectorCopy (end, G_VECTOR(OFS_RETURN));
+               VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
        }
        else
        {
-               VectorCopy (bestdir, G_VECTOR(OFS_RETURN));
+               VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
        }
 }
 
@@ -1679,17 +1679,17 @@ This was a major timewaster in progs, so it was converted to C
 */
 void PF_changeyaw (void)
 {
-       edict_t         *ent;
+       prvm_edict_t            *ent;
        float           ideal, current, move, speed;
 
-       ent = PROG_TO_EDICT(pr_global_struct->self);
-       if (ent == sv.edicts)
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
                PF_WARNING("changeyaw: can not modify world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("changeyaw: can not modify free entity\n");
-       current = ANGLEMOD(ent->v->angles[1]);
-       ideal = ent->v->ideal_yaw;
-       speed = ent->v->yaw_speed;
+       current = ANGLEMOD(ent->fields.server->angles[1]);
+       ideal = ent->fields.server->ideal_yaw;
+       speed = ent->fields.server->yaw_speed;
 
        if (current == ideal)
                return;
@@ -1715,7 +1715,7 @@ void PF_changeyaw (void)
                        move = -speed;
        }
 
-       ent->v->angles[1] = ANGLEMOD (current + move);
+       ent->fields.server->angles[1] = ANGLEMOD (current + move);
 }
 
 /*
@@ -1725,24 +1725,24 @@ PF_changepitch
 */
 void PF_changepitch (void)
 {
-       edict_t         *ent;
+       prvm_edict_t            *ent;
        float           ideal, current, move, speed;
-       eval_t          *val;
+       prvm_eval_t             *val;
 
-       ent = G_EDICT(OFS_PARM0);
-       if (ent == sv.edicts)
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
                PF_WARNING("changepitch: can not modify world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("changepitch: can not modify free entity\n");
-       current = ANGLEMOD( ent->v->angles[0] );
-       if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
+       current = ANGLEMOD( ent->fields.server->angles[0] );
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_idealpitch)))
                ideal = val->_float;
        else
        {
                PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
                return;
        }
-       if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
                speed = val->_float;
        else
        {
@@ -1774,7 +1774,7 @@ void PF_changepitch (void)
                        move = -speed;
        }
 
-       ent->v->angles[0] = ANGLEMOD (current + move);
+       ent->fields.server->angles[0] = ANGLEMOD (current + move);
 }
 
 /*
@@ -1794,17 +1794,17 @@ sizebuf_t *WriteDest (void)
 {
        int             entnum;
        int             dest;
-       edict_t *ent;
+       prvm_edict_t    *ent;
 
-       dest = G_FLOAT(OFS_PARM0);
+       dest = PRVM_G_FLOAT(OFS_PARM0);
        switch (dest)
        {
        case MSG_BROADCAST:
                return &sv.datagram;
 
        case MSG_ONE:
-               ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
-               entnum = NUM_FOR_EDICT(ent);
+               ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
+               entnum = PRVM_NUM_FOR_EDICT(ent);
                if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
                        Host_Error("WriteDest: tried to write to non-client\n");
                return &svs.clients[entnum-1].message;
@@ -1825,81 +1825,81 @@ sizebuf_t *WriteDest (void)
 
 void PF_WriteByte (void)
 {
-       MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1));
+       MSG_WriteByte (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
 }
 
 void PF_WriteChar (void)
 {
-       MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1));
+       MSG_WriteChar (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
 }
 
 void PF_WriteShort (void)
 {
-       MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1));
+       MSG_WriteShort (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
 }
 
 void PF_WriteLong (void)
 {
-       MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1));
+       MSG_WriteLong (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
 }
 
 void PF_WriteAngle (void)
 {
-       MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocol);
+       MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
 }
 
 void PF_WriteCoord (void)
 {
-       MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1), sv.protocol);
+       MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
 }
 
 void PF_WriteString (void)
 {
-       MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1));
+       MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
 }
 
 
 void PF_WriteEntity (void)
 {
-       MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1));
+       MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
 }
 
 //=============================================================================
 
 void PF_makestatic (void)
 {
-       edict_t *ent;
+       prvm_edict_t *ent;
        int i, large;
 
-       ent = G_EDICT(OFS_PARM0);
-       if (ent == sv.edicts)
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
                PF_WARNING("makestatic: can not modify world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("makestatic: can not modify free entity\n");
 
        large = false;
-       if (ent->v->modelindex >= 256 || ent->v->frame >= 256)
+       if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
                large = true;
 
        if (large)
        {
                MSG_WriteByte (&sv.signon,svc_spawnstatic2);
-               MSG_WriteShort (&sv.signon, ent->v->modelindex);
-               MSG_WriteShort (&sv.signon, ent->v->frame);
+               MSG_WriteShort (&sv.signon, ent->fields.server->modelindex);
+               MSG_WriteShort (&sv.signon, ent->fields.server->frame);
        }
        else
        {
                MSG_WriteByte (&sv.signon,svc_spawnstatic);
-               MSG_WriteByte (&sv.signon, ent->v->modelindex);
-               MSG_WriteByte (&sv.signon, ent->v->frame);
+               MSG_WriteByte (&sv.signon, ent->fields.server->modelindex);
+               MSG_WriteByte (&sv.signon, ent->fields.server->frame);
        }
 
-       MSG_WriteByte (&sv.signon, ent->v->colormap);
-       MSG_WriteByte (&sv.signon, ent->v->skin);
+       MSG_WriteByte (&sv.signon, ent->fields.server->colormap);
+       MSG_WriteByte (&sv.signon, ent->fields.server->skin);
        for (i=0 ; i<3 ; i++)
        {
-               MSG_WriteCoord(&sv.signon, ent->v->origin[i], sv.protocol);
-               MSG_WriteAngle(&sv.signon, ent->v->angles[i], sv.protocol);
+               MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
+               MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
        }
 
 // throw the entity away now
@@ -1915,12 +1915,12 @@ PF_setspawnparms
 */
 void PF_setspawnparms (void)
 {
-       edict_t *ent;
+       prvm_edict_t    *ent;
        int             i;
        client_t        *client;
 
-       ent = G_EDICT(OFS_PARM0);
-       i = NUM_FOR_EDICT(ent);
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       i = PRVM_NUM_FOR_EDICT(ent);
        if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
        {
                Con_Print("tried to setspawnparms on a non-client\n");
@@ -1930,7 +1930,7 @@ void PF_setspawnparms (void)
        // copy spawn parms out of the client_t
        client = svs.clients + i-1;
        for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
-               (&pr_global_struct->parm1)[i] = client->spawn_parms[i];
+               (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
 }
 
 /*
@@ -1947,23 +1947,23 @@ void PF_changelevel (void)
                return;
        svs.changelevel_issued = true;
 
-       s = G_STRING(OFS_PARM0);
+       s = PRVM_G_STRING(OFS_PARM0);
        Cbuf_AddText (va("changelevel %s\n",s));
 }
 
 void PF_sin (void)
 {
-       G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = sin(PRVM_G_FLOAT(OFS_PARM0));
 }
 
 void PF_cos (void)
 {
-       G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = cos(PRVM_G_FLOAT(OFS_PARM0));
 }
 
 void PF_sqrt (void)
 {
-       G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0));
+       PRVM_G_FLOAT(OFS_RETURN) = sqrt(PRVM_G_FLOAT(OFS_PARM0));
 }
 
 /*
@@ -1985,7 +1985,7 @@ void PF_randomvec (void)
                temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
        }
        while (DotProduct(temp, temp) >= 1);
-       VectorCopy (temp, G_VECTOR(OFS_RETURN));
+       VectorCopy (temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 /*
@@ -2004,21 +2004,21 @@ void PF_GetLight (void)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
        vec_t *p;
-       p = G_VECTOR(OFS_PARM0);
+       p = PRVM_G_VECTOR(OFS_PARM0);
        VectorClear(ambientcolor);
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
        if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
                sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
-       VectorMA(ambientcolor, 0.5, diffusecolor, G_VECTOR(OFS_RETURN));
+       VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 void PF_registercvar (void)
 {
        const char *name, *value;
-       name = G_STRING(OFS_PARM0);
-       value = G_STRING(OFS_PARM1);
-       G_FLOAT(OFS_RETURN) = 0;
+       name = PRVM_G_STRING(OFS_PARM0);
+       value = PRVM_G_STRING(OFS_PARM1);
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
 
 // first check to see if it has already been defined
        if (Cvar_FindVar (name))
@@ -2033,7 +2033,7 @@ void PF_registercvar (void)
 
        Cvar_Get(name, value, 0);
 
-       G_FLOAT(OFS_RETURN) = 1; // success
+       PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }
 
 /*
@@ -2049,19 +2049,19 @@ void PF_min (void)
 {
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
        if (pr_argc == 2)
-               G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
+               PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
        else if (pr_argc >= 3)
        {
                int i;
-               float f = G_FLOAT(OFS_PARM0);
+               float f = PRVM_G_FLOAT(OFS_PARM0);
                for (i = 1;i < pr_argc;i++)
-                       if (G_FLOAT((OFS_PARM0+i*3)) < f)
-                               f = G_FLOAT((OFS_PARM0+i*3));
-               G_FLOAT(OFS_RETURN) = f;
+                       if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f)
+                               f = PRVM_G_FLOAT((OFS_PARM0+i*3));
+               PRVM_G_FLOAT(OFS_RETURN) = f;
        }
        else
        {
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
                PF_WARNING("min: must supply at least 2 floats\n");
        }
 }
@@ -2079,19 +2079,19 @@ void PF_max (void)
 {
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
        if (pr_argc == 2)
-               G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
+               PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
        else if (pr_argc >= 3)
        {
                int i;
-               float f = G_FLOAT(OFS_PARM0);
+               float f = PRVM_G_FLOAT(OFS_PARM0);
                for (i = 1;i < pr_argc;i++)
-                       if (G_FLOAT((OFS_PARM0+i*3)) > f)
-                               f = G_FLOAT((OFS_PARM0+i*3));
-               G_FLOAT(OFS_RETURN) = f;
+                       if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
+                               f = PRVM_G_FLOAT((OFS_PARM0+i*3));
+               PRVM_G_FLOAT(OFS_RETURN) = f;
        }
        else
        {
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
                PF_WARNING("max: must supply at least 2 floats\n");
        }
 }
@@ -2107,7 +2107,7 @@ min(min, value, max)
 */
 void PF_bound (void)
 {
-       G_FLOAT(OFS_RETURN) = bound(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
+       PRVM_G_FLOAT(OFS_RETURN) = bound(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1), PRVM_G_FLOAT(OFS_PARM2));
 }
 
 /*
@@ -2121,7 +2121,7 @@ pow(a, b)
 */
 void PF_pow (void)
 {
-       G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
+       PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
 }
 
 /*
@@ -2135,16 +2135,16 @@ copyentity(src, dst)
 */
 void PF_copyentity (void)
 {
-       edict_t *in, *out;
-       in = G_EDICT(OFS_PARM0);
-       if (in == sv.edicts)
+       prvm_edict_t *in, *out;
+       in = PRVM_G_EDICT(OFS_PARM0);
+       if (in == prog->edicts)
                PF_WARNING("copyentity: can not read world entity\n");
-       if (in->e->free)
+       if (in->priv.server->free)
                PF_WARNING("copyentity: can not read free entity\n");
-       out = G_EDICT(OFS_PARM1);
-       if (out == sv.edicts)
+       out = PRVM_G_EDICT(OFS_PARM1);
+       if (out == prog->edicts)
                PF_WARNING("copyentity: can not modify world entity\n");
-       if (out->e->free)
+       if (out->priv.server->free)
                PF_WARNING("copyentity: can not modify free entity\n");
        memcpy(out->v, in->v, progs->entityfields * 4);
 }
@@ -2162,10 +2162,10 @@ void PF_setcolor (void)
 {
        client_t *client;
        int entnum, i;
-       eval_t *val;
+       prvm_eval_t *val;
 
-       entnum = G_EDICTNUM(OFS_PARM0);
-       i = G_FLOAT(OFS_PARM1);
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+       i = PRVM_G_FLOAT(OFS_PARM1);
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
@@ -2176,9 +2176,9 @@ void PF_setcolor (void)
        client = svs.clients + entnum-1;
        if (client->edict)
        {
-               if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
+               if ((val = PRVM_GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
                        val->_float = i;
-               client->edict->v->team = (i & 15) + 1;
+               client->edict->fields.server->team = (i & 15) + 1;
        }
        client->colors = i;
        if (client->old_colors != client->colors)
@@ -2202,52 +2202,52 @@ void PF_effect (void)
 {
        int i;
        const char *s;
-       s = G_STRING(OFS_PARM1);
+       s = PRVM_G_STRING(OFS_PARM1);
        if (!s || !s[0])
                PF_WARNING("effect: no model specified\n");
 
        i = SV_ModelIndex(s, 1);
        if (!i)
                PF_WARNING("effect: model not precached\n");
-       SV_StartEffect(G_VECTOR(OFS_PARM0), i, G_FLOAT(OFS_PARM2), G_FLOAT(OFS_PARM3), G_FLOAT(OFS_PARM4));
+       SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
 }
 
 void PF_te_blood (void)
 {
-       if (G_FLOAT(OFS_PARM2) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM2) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_BLOOD);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // velocity
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
        // count
-       MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
 }
 
 void PF_te_bloodshower (void)
 {
-       if (G_FLOAT(OFS_PARM3) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
        // min
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // max
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // speed
-       MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM2), sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
        // count
-       MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
 }
 
 void PF_te_explosionrgb (void)
@@ -2255,107 +2255,107 @@ void PF_te_explosionrgb (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // color
-       MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[0] * 255), 255));
-       MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[1] * 255), 255));
-       MSG_WriteByte(&sv.datagram, bound(0, (int) (G_VECTOR(OFS_PARM1)[2] * 255), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
 }
 
 void PF_te_particlecube (void)
 {
-       if (G_FLOAT(OFS_PARM3) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
        // min
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // max
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // velocity
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
        // count
-       MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
        // color
-       MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
        // gravity true/false
-       MSG_WriteByte(&sv.datagram, ((int) G_FLOAT(OFS_PARM5)) != 0);
+       MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
        // randomvel
-       MSG_WriteCoord(&sv.datagram, G_FLOAT(OFS_PARM6), sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
 }
 
 void PF_te_particlerain (void)
 {
-       if (G_FLOAT(OFS_PARM3) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
        // min
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // max
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // velocity
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
        // count
-       MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
        // color
-       MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
 }
 
 void PF_te_particlesnow (void)
 {
-       if (G_FLOAT(OFS_PARM3) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
        // min
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // max
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // velocity
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
        // count
-       MSG_WriteShort(&sv.datagram, bound(0, G_FLOAT(OFS_PARM3), 65535));
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
        // color
-       MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM4));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
 }
 
 void PF_te_spark (void)
 {
-       if (G_FLOAT(OFS_PARM2) < 1)
+       if (PRVM_G_FLOAT(OFS_PARM2) < 1)
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SPARK);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // velocity
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[0], 127));
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[1], 127));
-       MSG_WriteByte(&sv.datagram, bound(-128, (int) G_VECTOR(OFS_PARM1)[2], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
        // count
-       MSG_WriteByte(&sv.datagram, bound(0, (int) G_FLOAT(OFS_PARM2), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
 }
 
 void PF_te_gunshotquad (void)
@@ -2363,9 +2363,9 @@ void PF_te_gunshotquad (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_spikequad (void)
@@ -2373,9 +2373,9 @@ void PF_te_spikequad (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_superspikequad (void)
@@ -2383,9 +2383,9 @@ void PF_te_superspikequad (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_explosionquad (void)
@@ -2393,9 +2393,9 @@ void PF_te_explosionquad (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_smallflash (void)
@@ -2403,29 +2403,29 @@ void PF_te_smallflash (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_customflash (void)
 {
-       if (G_FLOAT(OFS_PARM1) < 8 || G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
+       if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
                return;
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // radius
-       MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM1) / 8 - 1, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
        // lifetime
-       MSG_WriteByte(&sv.datagram, bound(0, G_FLOAT(OFS_PARM2) * 256 - 1, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
        // color
-       MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[0] * 255, 255));
-       MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[1] * 255, 255));
-       MSG_WriteByte(&sv.datagram, bound(0, G_VECTOR(OFS_PARM3)[2] * 255, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
 }
 
 void PF_te_gunshot (void)
@@ -2433,9 +2433,9 @@ void PF_te_gunshot (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_spike (void)
@@ -2443,9 +2443,9 @@ void PF_te_spike (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SPIKE);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_superspike (void)
@@ -2453,9 +2453,9 @@ void PF_te_superspike (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_explosion (void)
@@ -2463,9 +2463,9 @@ void PF_te_explosion (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_tarexplosion (void)
@@ -2473,9 +2473,9 @@ void PF_te_tarexplosion (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_wizspike (void)
@@ -2483,9 +2483,9 @@ void PF_te_wizspike (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_knightspike (void)
@@ -2493,9 +2493,9 @@ void PF_te_knightspike (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_lavasplash (void)
@@ -2503,9 +2503,9 @@ void PF_te_lavasplash (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_teleport (void)
@@ -2513,9 +2513,9 @@ void PF_te_teleport (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_TELEPORT);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 void PF_te_explosion2 (void)
@@ -2523,12 +2523,12 @@ void PF_te_explosion2 (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
        // origin
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
        // color
-       MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM1));
-       MSG_WriteByte(&sv.datagram, G_FLOAT(OFS_PARM2));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2));
 }
 
 void PF_te_lightning1 (void)
@@ -2536,15 +2536,15 @@ void PF_te_lightning1 (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
        // owner entity
-       MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        // start
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // end
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
 }
 
 void PF_te_lightning2 (void)
@@ -2552,15 +2552,15 @@ void PF_te_lightning2 (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
        // owner entity
-       MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        // start
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // end
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
 }
 
 void PF_te_lightning3 (void)
@@ -2568,15 +2568,15 @@ void PF_te_lightning3 (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
        // owner entity
-       MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        // start
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // end
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
 }
 
 void PF_te_beam (void)
@@ -2584,24 +2584,24 @@ void PF_te_beam (void)
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_BEAM);
        // owner entity
-       MSG_WriteShort(&sv.datagram, G_EDICTNUM(OFS_PARM0));
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        // start
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
        // end
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
 }
 
 void PF_te_plasmaburn (void)
 {
        MSG_WriteByte(&sv.datagram, svc_temp_entity);
        MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[0], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[1], sv.protocol);
-       MSG_WriteCoord(&sv.datagram, G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
 }
 
 static void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out)
@@ -2640,13 +2640,13 @@ static void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out)
        }
 }
 
-static msurface_t *getsurface(edict_t *ed, int surfacenum)
+static msurface_t *getsurface(prvm_edict_t *ed, int surfacenum)
 {
        int modelindex;
        model_t *model;
-       if (!ed || ed->e->free)
+       if (!ed || ed->priv.server->free)
                return NULL;
-       modelindex = ed->v->modelindex;
+       modelindex = ed->fields.server->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return NULL;
        model = sv.models[modelindex];
@@ -2661,41 +2661,41 @@ void PF_getsurfacenumpoints(void)
 {
        msurface_t *surface;
        // return 0 if no such surface
-       if (!(surface = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
        {
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
                return;
        }
 
        // note: this (incorrectly) assumes it is a simple polygon
-       G_FLOAT(OFS_RETURN) = surface->num_vertices;
+       PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
 }
 //PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
 void PF_getsurfacepoint(void)
 {
-       edict_t *ed;
+       prvm_edict_t *ed;
        msurface_t *surface;
        int pointnum;
-       VectorClear(G_VECTOR(OFS_RETURN));
-       ed = G_EDICT(OFS_PARM0);
-       if (!ed || ed->e->free)
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       if (!ed || ed->priv.server->free)
                return;
-       if (!(surface = getsurface(ed, G_FLOAT(OFS_PARM1))))
+       if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1))))
                return;
        // note: this (incorrectly) assumes it is a simple polygon
-       pointnum = G_FLOAT(OFS_PARM2);
+       pointnum = PRVM_G_FLOAT(OFS_PARM2);
        if (pointnum < 0 || pointnum >= surface->num_vertices)
                return;
        // FIXME: implement rotation/scaling
-       VectorAdd(&(surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->v->origin, G_VECTOR(OFS_RETURN));
+       VectorAdd(&(surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
 }
 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
 void PF_getsurfacenormal(void)
 {
        msurface_t *surface;
        vec3_t normal;
-       VectorClear(G_VECTOR(OFS_RETURN));
-       if (!(surface = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
                return;
        // FIXME: implement rotation/scaling
        // note: this (incorrectly) assumes it is a simple polygon
@@ -2703,16 +2703,16 @@ void PF_getsurfacenormal(void)
        // well for curved surfaces or arbitrary meshes
        TriangleNormal((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 3, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
        VectorNormalize(normal);
-       VectorCopy(normal, G_VECTOR(OFS_RETURN));
+       VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
 }
 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
 void PF_getsurfacetexture(void)
 {
        msurface_t *surface;
-       G_INT(OFS_RETURN) = 0;
-       if (!(surface = getsurface(G_EDICT(OFS_PARM0), G_FLOAT(OFS_PARM1))))
+       PRVM_G_INT(OFS_RETURN) = 0;
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
                return;
-       G_INT(OFS_RETURN) = PR_SetEngineString(surface->texture->name);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name);
 }
 //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
 void PF_getsurfacenearpoint(void)
@@ -2720,17 +2720,17 @@ void PF_getsurfacenearpoint(void)
        int surfacenum, best, modelindex;
        vec3_t clipped, p;
        vec_t dist, bestdist;
-       edict_t *ed;
+       prvm_edict_t *ed;
        model_t *model;
        msurface_t *surface;
        vec_t *point;
-       G_FLOAT(OFS_RETURN) = -1;
-       ed = G_EDICT(OFS_PARM0);
-       point = G_VECTOR(OFS_PARM1);
+       PRVM_G_FLOAT(OFS_RETURN) = -1;
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       point = PRVM_G_VECTOR(OFS_PARM1);
 
-       if (!ed || ed->e->free)
+       if (!ed || ed->priv.server->free)
                return;
-       modelindex = ed->v->modelindex;
+       modelindex = ed->fields.server->modelindex;
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return;
        model = sv.models[modelindex];
@@ -2738,7 +2738,7 @@ void PF_getsurfacenearpoint(void)
                return;
 
        // FIXME: implement rotation/scaling
-       VectorSubtract(point, ed->v->origin, p);
+       VectorSubtract(point, ed->fields.server->origin, p);
        best = -1;
        bestdist = 1000000000;
        for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
@@ -2763,25 +2763,25 @@ void PF_getsurfacenearpoint(void)
                        }
                }
        }
-       G_FLOAT(OFS_RETURN) = best;
+       PRVM_G_FLOAT(OFS_RETURN) = best;
 }
 //PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
 void PF_getsurfaceclippedpoint(void)
 {
-       edict_t *ed;
+       prvm_edict_t *ed;
        msurface_t *surface;
        vec3_t p, out;
-       VectorClear(G_VECTOR(OFS_RETURN));
-       ed = G_EDICT(OFS_PARM0);
-       if (!ed || ed->e->free)
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       if (!ed || ed->priv.server->free)
                return;
-       if (!(surface = getsurface(ed, G_FLOAT(OFS_PARM1))))
+       if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1))))
                return;
        // FIXME: implement rotation/scaling
-       VectorSubtract(G_VECTOR(OFS_PARM2), ed->v->origin, p);
+       VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
        clippointtosurface(surface, p, out);
        // FIXME: implement rotation/scaling
-       VectorAdd(out, ed->v->origin, G_VECTOR(OFS_RETURN));
+       VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 #define MAX_PRFILES 256
@@ -2809,7 +2809,7 @@ void PF_stof(void)
 {
        char string[STRINGTEMP_LENGTH];
        PF_VarString(0, string, sizeof(string));
-       G_FLOAT(OFS_RETURN) = atof(string);
+       PRVM_G_FLOAT(OFS_RETURN) = atof(string);
 }
 
 //float(string filename, float mode) fopen = #110; // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE), returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
@@ -2823,10 +2823,10 @@ void PF_fopen(void)
        if (filenum >= MAX_PRFILES)
        {
                Con_Printf("PF_fopen: ran out of file handles (%i)\n", MAX_PRFILES);
-               G_FLOAT(OFS_RETURN) = -2;
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
                return;
        }
-       mode = G_FLOAT(OFS_PARM1);
+       mode = PRVM_G_FLOAT(OFS_PARM1);
        switch(mode)
        {
        case 0: // FILE_READ
@@ -2840,10 +2840,10 @@ void PF_fopen(void)
                break;
        default:
                Con_Printf("PF_fopen: no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", mode);
-               G_FLOAT(OFS_RETURN) = -3;
+               PRVM_G_FLOAT(OFS_RETURN) = -3;
                return;
        }
-       filename = G_STRING(OFS_PARM0);
+       filename = PRVM_G_STRING(OFS_PARM0);
        // -4 failure (dangerous/non-portable filename) removed, FS_Open checks
        pr_files[filenum] = FS_Open(va("data/%s", filename), modestring, false, false);
 
@@ -2851,15 +2851,15 @@ void PF_fopen(void)
                pr_files[filenum] = FS_Open(filename, modestring, false, false);
 
        if (pr_files[filenum] == NULL)
-               G_FLOAT(OFS_RETURN) = -1;
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
-               G_FLOAT(OFS_RETURN) = filenum;
+               PRVM_G_FLOAT(OFS_RETURN) = filenum;
 }
 
 //void(float fhandle) fclose = #111; // closes a file
 void PF_fclose(void)
 {
-       int filenum = G_FLOAT(OFS_PARM0);
+       int filenum = PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= MAX_PRFILES)
        {
                Con_Printf("PF_fclose: invalid file handle %i\n", filenum);
@@ -2879,7 +2879,7 @@ void PF_fgets(void)
 {
        int c, end;
        static char string[STRINGTEMP_LENGTH];
-       int filenum = G_FLOAT(OFS_PARM0);
+       int filenum = PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= MAX_PRFILES)
        {
                Con_Printf("PF_fgets: invalid file handle %i\n", filenum);
@@ -2910,9 +2910,9 @@ void PF_fgets(void)
        if (developer.integer)
                Con_Printf("fgets: %s\n", string);
        if (c >= 0 || end)
-               G_INT(OFS_RETURN) = PR_SetEngineString(string);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string);
        else
-               G_INT(OFS_RETURN) = 0;
+               PRVM_G_INT(OFS_RETURN) = 0;
 }
 
 //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file
@@ -2920,7 +2920,7 @@ void PF_fputs(void)
 {
        int stringlength;
        char string[STRINGTEMP_LENGTH];
-       int filenum = G_FLOAT(OFS_PARM0);
+       int filenum = PRVM_G_FLOAT(OFS_PARM0);
        if (filenum < 0 || filenum >= MAX_PRFILES)
        {
                Con_Printf("PF_fputs: invalid file handle %i\n", filenum);
@@ -2942,11 +2942,11 @@ void PF_fputs(void)
 void PF_strlen(void)
 {
        const char *s;
-       s = G_STRING(OFS_PARM0);
+       s = PRVM_G_STRING(OFS_PARM0);
        if (s)
-               G_FLOAT(OFS_RETURN) = strlen(s);
+               PRVM_G_FLOAT(OFS_RETURN) = strlen(s);
        else
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
 }
 
 //string(string s1, string s2) strcat = #115; // concatenates two strings (for example "abc", "def" would return "abcdef") and returns as a tempstring
@@ -2954,7 +2954,7 @@ void PF_strcat(void)
 {
        char *s = PR_GetTempString();
        PF_VarString(0, s, STRINGTEMP_LENGTH);
-       G_INT(OFS_RETURN) = PR_SetEngineString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 //string(string s, float start, float length) substring = #116; // returns a section of a string as a tempstring
@@ -2963,16 +2963,16 @@ void PF_substring(void)
        int i, start, length;
        const char *s;
        char *string = PR_GetTempString();
-       s = G_STRING(OFS_PARM0);
-       start = G_FLOAT(OFS_PARM1);
-       length = G_FLOAT(OFS_PARM2);
+       s = PRVM_G_STRING(OFS_PARM0);
+       start = PRVM_G_FLOAT(OFS_PARM1);
+       length = PRVM_G_FLOAT(OFS_PARM2);
        if (!s)
                s = "";
        for (i = 0;i < start && *s;i++, s++);
        for (i = 0;i < STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
                string[i] = *s;
        string[i] = 0;
-       G_INT(OFS_RETURN) = PR_SetEngineString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string);
 }
 
 //vector(string s) stov = #117; // returns vector value from a string
@@ -2980,7 +2980,7 @@ void PF_stov(void)
 {
        char string[STRINGTEMP_LENGTH];
        PF_VarString(0, string, sizeof(string));
-       Math_atov(string, G_VECTOR(OFS_RETURN));
+       Math_atov(string, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //string(string s) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often)
@@ -2988,16 +2988,16 @@ void PF_strzone(void)
 {
        const char *in;
        char *out;
-       in = G_STRING(OFS_PARM0);
+       in = PRVM_G_STRING(OFS_PARM0);
        out = PR_AllocString(strlen(in) + 1);
        strcpy(out, in);
-       G_INT(OFS_RETURN) = PR_SetQCString(out);
+       PRVM_G_INT(OFS_RETURN) = PR_SetQCString(out);
 }
 
 //void(string s) strunzone = #119; // removes a copy of a string from the string zone (you can not use that string again or it may crash!!!)
 void PF_strunzone(void)
 {
-       PR_FreeString((char *)G_STRING(OFS_PARM0));
+       PR_FreeString((char *)PRVM_G_STRING(OFS_PARM0));
 }
 
 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
@@ -3008,7 +3008,7 @@ void PF_clientcommand (void)
        int i;
 
        //find client for this entity
-       i = (NUM_FOR_EDICT(G_EDICT(OFS_PARM0)) - 1);
+       i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
        if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
        {
                Con_Print("PF_clientcommand: entity is not a client\n");
@@ -3017,7 +3017,7 @@ void PF_clientcommand (void)
 
        temp_client = host_client;
        host_client = svs.clients + i;
-       Cmd_ExecuteString (G_STRING(OFS_PARM1), src_client);
+       Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
        host_client = temp_client;
 }
 
@@ -3030,7 +3030,7 @@ void PF_tokenize (void)
 {
        int pos;
        const char *p;
-       p = G_STRING(OFS_PARM0);
+       p = PRVM_G_STRING(OFS_PARM0);
 
        num_tokens = 0;
        pos = 0;
@@ -3045,73 +3045,73 @@ void PF_tokenize (void)
                pos += strlen(com_token) + 1;
        }
 
-       G_FLOAT(OFS_RETURN) = num_tokens;
+       PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
 }
 
 //string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index)
 //this function originally written by KrimZon, made shorter by LordHavoc
 void PF_argv (void)
 {
-       int token_num = G_FLOAT(OFS_PARM0);
+       int token_num = PRVM_G_FLOAT(OFS_PARM0);
        if (token_num >= 0 && token_num < num_tokens)
-               G_INT(OFS_RETURN) = PR_SetEngineString(tokens[token_num]);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tokens[token_num]);
        else
-               G_INT(OFS_RETURN) = PR_SetEngineString(NULL);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL);
 }
 
 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
 void PF_setattachment (void)
 {
-       edict_t *e = G_EDICT(OFS_PARM0);
-       edict_t *tagentity = G_EDICT(OFS_PARM1);
-       const char *tagname = G_STRING(OFS_PARM2);
-       eval_t *v;
+       prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
+       prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
+       const char *tagname = PRVM_G_STRING(OFS_PARM2);
+       prvm_eval_t *v;
        int modelindex;
        model_t *model;
 
-       if (e == sv.edicts)
+       if (e == prog->edicts)
                PF_WARNING("setattachment: can not modify world entity\n");
-       if (e->e->free)
+       if (e->priv.server->free)
                PF_WARNING("setattachment: can not modify free entity\n");
 
        if (tagentity == NULL)
-               tagentity = sv.edicts;
+               tagentity = prog->edicts;
 
-       v = GETEDICTFIELDVALUE(e, eval_tag_entity);
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_entity);
        if (v)
-               v->edict = EDICT_TO_PROG(tagentity);
+               fields.server->edict = PRVM_EDICT_TO_PROG(tagentity);
 
-       v = GETEDICTFIELDVALUE(e, eval_tag_index);
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_index);
        if (v)
-               v->_float = 0;
-       if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0])
+               fields.server->_float = 0;
+       if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
        {
-               modelindex = (int)tagentity->v->modelindex;
+               modelindex = (int)tagentity->fields.server->modelindex;
                if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
                {
-                       v->_float = Mod_Alias_GetTagIndexForName(model, tagentity->v->skin, tagname);
-                       if (v->_float == 0)
-                               Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name);
+                       fields.server->_float = Mod_Alias_GetTagIndexForName(model, tagentity->fields.server->skin, tagname);
+                       if (fields.server->_float == 0)
+                               Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
                }
                else
-                       Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity));
+                       Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
        }
 }
 
 /////////////////////////////////////////
 // DP_MD3_TAGINFO extension coded by VorteX
 
-int SV_GetTagIndex (edict_t *e, const char *tagname)
+int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
 {
        int i;
        model_t *model;
 
-       i = e->v->modelindex;
+       i = e->fields.server->modelindex;
        if (i < 1 || i >= MAX_MODELS)
                return -1;
        model = sv.models[i];
 
-       return Mod_Alias_GetTagIndexForName(model, e->v->skin, tagname);
+       return Mod_Alias_GetTagIndexForName(model, e->fields.server->skin, tagname);
 };
 
 // Warnings/errors code:
@@ -3124,29 +3124,29 @@ int SV_GetTagIndex (edict_t *e, const char *tagname)
 extern cvar_t cl_bob;
 extern cvar_t cl_bobcycle;
 extern cvar_t cl_bobup;
-int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
+int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
-       eval_t *val;
+       prvm_eval_t *val;
        int modelindex, reqframe, attachloop;
        matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
-       edict_t *attachent;
+       prvm_edict_t *attachent;
        model_t *model;
 
        Matrix4x4_CreateIdentity(out); // warnings and errors return identical matrix
 
-       if (ent == sv.edicts)
+       if (ent == prog->edicts)
                return 1;
-       if (ent->e->free)
+       if (ent->priv.server->free)
                return 2;
 
-       modelindex = (int)ent->v->modelindex;
+       modelindex = (int)ent->fields.server->modelindex;
        if (modelindex <= 0 || modelindex > MAX_MODELS)
                return 3;
 
        model = sv.models[modelindex];
 
-       if (ent->v->frame >= 0 && ent->v->frame < model->numframes && model->animscenes)
-               reqframe = model->animscenes[(int)ent->v->frame].firstframe;
+       if (ent->fields.server->frame >= 0 && ent->fields.server->frame < model->numframes && model->animscenes)
+               reqframe = model->animscenes[(int)ent->fields.server->frame].firstframe;
        else
                reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame
 
@@ -3160,23 +3160,23 @@ int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
        else
                Matrix4x4_CreateIdentity(&tagmatrix);
 
-       if ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
        { // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
                attachloop = 0;
                do
                {
-                       attachent = EDICT_NUM(val->edict); // to this it entity our entity is attached
-                       val = GETEDICTFIELDVALUE(ent, eval_tag_index);
-                       if (val->_float >= 1 && attachent->v->modelindex >= 1 && attachent->v->modelindex < MAX_MODELS && (model = sv.models[(int)attachent->v->modelindex]) && model->animscenes && attachent->v->frame >= 0 && attachent->v->frame < model->numframes)
-                               Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->v->frame].firstframe, val->_float - 1, &attachmatrix);
+                       attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
+                       val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index);
+                       if (val->_float >= 1 && attachent->fields.server->modelindex >= 1 && attachent->fields.server->modelindex < MAX_MODELS && (model = sv.models[(int)attachent->fields.server->modelindex]) && model->animscenes && attachent->fields.server->frame >= 0 && attachent->fields.server->frame < model->numframes)
+                               Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.server->frame].firstframe, val->_float - 1, &attachmatrix);
                        else
                                Matrix4x4_CreateIdentity(&attachmatrix);
 
                        // apply transformation by child entity matrix
-                       val = GETEDICTFIELDVALUE(ent, eval_scale);
+                       val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
                        if (val->_float == 0)
                                val->_float = 1;
-                       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], -ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], val->_float);
+                       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float);
                        Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                        out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
                        out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
@@ -3195,30 +3195,30 @@ int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
                        if (attachloop > 255) // prevent runaway looping
                                return 5;
                }
-               while ((val = GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict);
+               while ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict);
        }
 
        // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
-       val = GETEDICTFIELDVALUE(ent, eval_scale);
+       val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
        if (val->_float == 0)
                val->_float = 1;
        // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
-       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], -ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], val->_float);
+       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float);
        Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
        out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
        out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
        out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
 
-       if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
        {// RENDER_VIEWMODEL magic
                Matrix4x4_Copy(&tagmatrix, out);
-               ent = EDICT_NUM(val->edict);
+               ent = PRVM_EDICT_NUM(val->edict);
 
-               val = GETEDICTFIELDVALUE(ent, eval_scale);
+               val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
                if (val->_float == 0)
                        val->_float = 1;
 
-               Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2] + ent->v->view_ofs[2], ent->v->v_angle[0], ent->v->v_angle[1], ent->v->v_angle[2], val->_float);
+               Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], val->_float);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
                out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
@@ -3226,7 +3226,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
 
                /*
                // Cl_bob, ported from rendering code
-               if (ent->v->health > 0 && cl_bob.value && cl_bobcycle.value)
+               if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
                {
                        double bob, cycle;
                        // LordHavoc: this code is *weird*, but not replacable (I think it
@@ -3241,7 +3241,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
                                cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
                        // bob is proportional to velocity in the xy plane
                        // (don't count Z, or jumping messes it up)
-                       bob = sqrt(ent->v->velocity[0]*ent->v->velocity[0] + ent->v->velocity[1]*ent->v->velocity[1])*cl_bob.value;
+                       bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value;
                        bob = bob*0.3 + bob*0.7*cycle;
                        out->m[2][3] += bound(-7, bob, 4);
                }
@@ -3254,38 +3254,38 @@ int SV_GetTagMatrix (matrix4x4_t *out, edict_t *ent, int tagindex)
 
 void PF_gettagindex (void)
 {
-       edict_t *ent = G_EDICT(OFS_PARM0);
-       const char *tag_name = G_STRING(OFS_PARM1);
+       prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
+       const char *tag_name = PRVM_G_STRING(OFS_PARM1);
        int modelindex, tag_index;
 
-       if (ent == sv.edicts)
+       if (ent == prog->edicts)
                PF_WARNING("gettagindex: can't affect world entity\n");
-       if (ent->e->free)
+       if (ent->priv.server->free)
                PF_WARNING("gettagindex: can't affect free entity\n");
 
-       modelindex = (int)ent->v->modelindex;
+       modelindex = (int)ent->fields.server->modelindex;
        tag_index = 0;
        if (modelindex <= 0 || modelindex > MAX_MODELS)
-               Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", NUM_FOR_EDICT(ent));
+               Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
        else
        {
                tag_index = SV_GetTagIndex(ent, tag_name);
                if (tag_index == 0)
-                       Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", NUM_FOR_EDICT(ent), tag_name);
+                       Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
        }
-       G_FLOAT(OFS_RETURN) = tag_index;
+       PRVM_G_FLOAT(OFS_RETURN) = tag_index;
 };
 
 //vector(entity ent, float tagindex) gettaginfo;
 void PF_gettaginfo (void)
 {
-       edict_t *e = G_EDICT(OFS_PARM0);
-       int tagindex = (int)G_FLOAT(OFS_PARM1);
+       prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
+       int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
        matrix4x4_t tag_matrix;
        int returncode;
 
        returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
-       Matrix4x4_ToVectors(&tag_matrix, pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up, G_VECTOR(OFS_RETURN));
+       Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
 
        switch(returncode)
        {
@@ -3296,13 +3296,13 @@ void PF_gettaginfo (void)
                        PF_WARNING("gettagindex: can't affect free entity\n");
                        break;
                case 3:
-                       Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", NUM_FOR_EDICT(e));
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
                        break;
                case 4:
-                       Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", NUM_FOR_EDICT(e), tagindex);
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
                        break;
                case 5:
-                       Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", NUM_FOR_EDICT(e));
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
                        break;
        }
 }
@@ -3344,12 +3344,12 @@ void PF_search_begin(void)
        const char *pattern;
        int caseinsens, quiet;
 
-       pattern = G_STRING(OFS_PARM0);
+       pattern = PRVM_G_STRING(OFS_PARM0);
        if (!pattern || pattern[0] <= ' ')
                PF_ERROR("PF_search_begin: Bad string");
 
-       caseinsens = G_FLOAT(OFS_PARM1);
-       quiet = G_FLOAT(OFS_PARM2);
+       caseinsens = PRVM_G_FLOAT(OFS_PARM1);
+       quiet = PRVM_G_FLOAT(OFS_PARM2);
 
        for(handle = 0; handle < MAX_SEARCHES; handle++)
                if(!pr_fssearchlist[handle])
@@ -3358,14 +3358,14 @@ void PF_search_begin(void)
        if(handle >= MAX_SEARCHES)
        {
                Con_Printf("PR_search_begin: ran out of search handles (%i)\n", MAX_SEARCHES);
-               G_FLOAT(OFS_RETURN) = -2;
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
                return;
        }
 
        if(!(pr_fssearchlist[handle] = FS_Search(pattern,caseinsens, quiet)))
-               G_FLOAT(OFS_RETURN) = -1;
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
-               G_FLOAT(OFS_RETURN) = handle;
+               PRVM_G_FLOAT(OFS_RETURN) = handle;
 }
 
 /*
@@ -3379,7 +3379,7 @@ void PF_search_end(void)
 {
        int handle;
 
-       handle = G_FLOAT(OFS_PARM0);
+       handle = PRVM_G_FLOAT(OFS_PARM0);
 
        if(handle < 0 || handle >= MAX_SEARCHES)
        {
@@ -3407,7 +3407,7 @@ void PF_search_getsize(void)
 {
        int handle;
 
-       handle = G_FLOAT(OFS_PARM0);
+       handle = PRVM_G_FLOAT(OFS_PARM0);
 
        if(handle < 0 || handle >= MAX_SEARCHES)
        {
@@ -3420,7 +3420,7 @@ void PF_search_getsize(void)
                return;
        }
 
-       G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames;
+       PRVM_G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames;
 }
 
 /*
@@ -3435,8 +3435,8 @@ void PF_search_getfilename(void)
        int handle, filenum;
        char *tmp;
 
-       handle = G_FLOAT(OFS_PARM0);
-       filenum = G_FLOAT(OFS_PARM1);
+       handle = PRVM_G_FLOAT(OFS_PARM0);
+       filenum = PRVM_G_FLOAT(OFS_PARM1);
 
        if(handle < 0 || handle >= MAX_SEARCHES)
        {
@@ -3457,7 +3457,7 @@ void PF_search_getfilename(void)
        tmp = PR_GetTempString();
        strcpy(tmp, pr_fssearchlist[handle]->filenames[filenum]);
 
-       G_INT(OFS_RETURN) = PR_SetEngineString(tmp);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp);
 }
 
 void PF_cvar_string (void)
@@ -3466,7 +3466,7 @@ void PF_cvar_string (void)
        cvar_t *var;
        char *tmp;
 
-       str = G_STRING(OFS_PARM0);
+       str = PRVM_G_STRING(OFS_PARM0);
        var = Cvar_FindVar (str);
        if (var)
        {
@@ -3475,7 +3475,7 @@ void PF_cvar_string (void)
        }
        else
                tmp = NULL;
-       G_INT(OFS_RETURN) = PR_SetEngineString(tmp);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tmp);
 }
 
 //void(entity clent) dropclient (DP_SV_DROPCLIENT)
@@ -3483,7 +3483,7 @@ void PF_dropclient (void)
 {
        int clientnum;
        client_t *oldhostclient;
-       clientnum = G_EDICTNUM(OFS_PARM0) - 1;
+       clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
        if (clientnum < 0 || clientnum >= svs.maxclients)
                PF_WARNING("dropclient: not a client\n");
        if (!svs.clients[clientnum].active)
@@ -3498,16 +3498,16 @@ void PF_dropclient (void)
 void PF_spawnclient (void)
 {
        int i;
-       edict_t *ed;
+       prvm_edict_t    *ed;
        pr_xfunction->builtinsprofile += 2;
-       ed = sv.edicts;
+       ed = prog->edicts;
        for (i = 0;i < svs.maxclients;i++)
        {
                if (!svs.clients[i].active)
                {
                        pr_xfunction->builtinsprofile += 100;
                        SV_ConnectClient (i, NULL);
-                       ed = EDICT_NUM(i + 1);
+                       ed = PRVM_EDICT_NUM(i + 1);
                        break;
                }
        }
@@ -3518,15 +3518,15 @@ void PF_spawnclient (void)
 void PF_clienttype (void)
 {
        int clientnum;
-       clientnum = G_EDICTNUM(OFS_PARM0) - 1;
+       clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
        if (clientnum < 0 || clientnum >= svs.maxclients)
-               G_FLOAT(OFS_RETURN) = 3;
+               PRVM_G_FLOAT(OFS_RETURN) = 3;
        else if (!svs.clients[clientnum].active)
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
        else if (svs.clients[clientnum].netconnection)
-               G_FLOAT(OFS_RETURN) = 1;
+               PRVM_G_FLOAT(OFS_RETURN) = 1;
        else
-               G_FLOAT(OFS_RETURN) = 2;
+               PRVM_G_FLOAT(OFS_RETURN) = 2;
 }
 
 builtin_t pr_builtin[] =
index 15db72d412eee376d79e899d4e5a3630ad7deba3..8d7841938dcb12ceee625232949feca695946d2c 100644 (file)
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "quakedef.h"
 
 dprograms_t            *progs;
-mfunction_t            *pr_functions;
+mfunction_t            *prog->functions;
 char                   *pr_strings;
 int                            pr_stringssize;
 ddef_t                 *pr_fielddefs;
@@ -30,7 +30,7 @@ ddef_t                        *pr_globaldefs;
 dstatement_t   *pr_statements;
 globalvars_t   *pr_global_struct;
 float                  *pr_globals;                    // same as pr_global_struct
-int                            pr_edict_size;                  // in bytes
+int                            prog->edict_size;                       // in bytes
 int                            pr_edictareasize;               // LordHavoc: in bytes
 
 int                            pr_maxknownstrings;
@@ -44,7 +44,7 @@ mempool_t             *serverprogs_mempool;
 int            type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
 
 ddef_t *ED_FieldAtOfs(int ofs);
-qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s);
+qboolean ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s);
 
 cvar_t pr_checkextension = {CVAR_READONLY, "pr_checkextension", "1"};
 cvar_t nomonsters = {0, "nomonsters", "0"};
@@ -86,7 +86,7 @@ typedef struct {
 static gefv_cache      gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
 
 ddef_t *ED_FindField (const char *name);
-mfunction_t *ED_FindFunction (const char *name);
+mfunction_t *PRVM_ED_FindFunction (const char *name);
 
 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  these are defined as externs in progs.h
 int eval_gravity;
@@ -210,11 +210,11 @@ void FindEdictFieldOffsets(void)
        eval_playerskin = FindFieldOffset("playerskin");
 
        // LordHavoc: allowing QuakeC to override the player movement code
-       SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
+       SV_PlayerPhysicsQC = PRVM_ED_FindFunction ("SV_PlayerPhysics");
        // LordHavoc: support for endframe
-       EndFrameQC = ED_FindFunction ("EndFrame");
+       EndFrameQC = PRVM_ED_FindFunction ("EndFrame");
        //KrimZon - SERVER COMMANDS IN QUAKEC
-       SV_ParseClientCommandQC = ED_FindFunction ("SV_ParseClientCommand");
+       SV_ParseClientCommandQC = PRVM_ED_FindFunction ("SV_ParseClientCommand");
 }
 
 /*
@@ -224,30 +224,30 @@ ED_ClearEdict
 Sets everything to NULL
 =================
 */
-void ED_ClearEdict (edict_t *e)
+void ED_ClearEdict (prvm_edict_t *e)
 {
        int num;
        memset (e->v, 0, progs->entityfields * 4);
-       e->e->free = false;
+       e->priv.server->free = false;
        // LordHavoc: for consistency set these here
-       num = NUM_FOR_EDICT(e) - 1;
+       num = PRVM_NUM_FOR_EDICT(e) - 1;
        if (num >= 0 && num < svs.maxclients)
        {
-               eval_t *val;
+               prvm_eval_t *val;
                // set colormap and team on newly created player entity
-               e->v->colormap = num + 1;
-               e->v->team = (svs.clients[num].colors & 15) + 1;
+               e->fields.server->colormap = num + 1;
+               e->fields.server->team = (svs.clients[num].colors & 15) + 1;
                // set netname/clientcolors back to client values so that
                // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
                // reset them
-               e->v->netname = PR_SetEngineString(svs.clients[num].name);
-               if ((val = GETEDICTFIELDVALUE(e, eval_clientcolors)))
+               e->fields.server->netname = PRVM_SetEngineString(svs.clients[num].name);
+               if ((val = PRVM_GETEDICTFIELDVALUE(e, eval_clientcolors)))
                        val->_float = svs.clients[num].colors;
                // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
                if( eval_playermodel )
-                       GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetEngineString(svs.clients[num].playermodel);
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PRVM_SetEngineString(svs.clients[num].playermodel);
                if( eval_playerskin )
-                       GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetEngineString(svs.clients[num].playerskin);
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PRVM_SetEngineString(svs.clients[num].playerskin);
        }
 }
 
@@ -262,17 +262,17 @@ instead of being removed and recreated, which can cause interpolated
 angles and bad trails.
 =================
 */
-edict_t *ED_Alloc (void)
+prvm_edict_t *ED_Alloc (void)
 {
        int                     i;
-       edict_t         *e;
+       prvm_edict_t            *e;
 
-       for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
+       for (i = svs.maxclients + 1;i < prog->num_edicts;i++)
        {
-               e = EDICT_NUM(i);
+               e = PRVM_EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
                // freeing and allocating, so relax the replacement policy
-               if (e->e->free && ( e->e->freetime < 2 || sv.time - e->e->freetime > 0.5 ) )
+               if (e->priv.server->free && ( e->priv.server->freetime < 2 || sv.time - e->priv.server->freetime > 0.5 ) )
                {
                        ED_ClearEdict (e);
                        return e;
@@ -282,10 +282,10 @@ edict_t *ED_Alloc (void)
        if (i == MAX_EDICTS)
                Host_Error ("ED_Alloc: no free edicts");
 
-       sv.num_edicts++;
-       if (sv.num_edicts >= sv.max_edicts)
+       prog->num_edicts++;
+       if (prog->num_edicts >= prog->max_edicts)
                SV_IncreaseEdicts();
-       e = EDICT_NUM(i);
+       e = PRVM_EDICT_NUM(i);
        ED_ClearEdict (e);
 
        return e;
@@ -299,23 +299,23 @@ Marks the edict as free
 FIXME: walk all entities and NULL out references to this entity
 =================
 */
-void ED_Free (edict_t *ed)
+void ED_Free (prvm_edict_t *ed)
 {
        SV_UnlinkEdict (ed);            // unlink from world bsp
 
-       ed->e->free = true;
-       ed->v->model = 0;
-       ed->v->takedamage = 0;
-       ed->v->modelindex = 0;
-       ed->v->colormap = 0;
-       ed->v->skin = 0;
-       ed->v->frame = 0;
-       VectorClear(ed->v->origin);
-       VectorClear(ed->v->angles);
-       ed->v->nextthink = -1;
-       ed->v->solid = 0;
-
-       ed->e->freetime = sv.time;
+       ed->priv.server->free = true;
+       ed->fields.server->model = 0;
+       ed->fields.server->takedamage = 0;
+       ed->fields.server->modelindex = 0;
+       ed->fields.server->colormap = 0;
+       ed->fields.server->skin = 0;
+       ed->fields.server->frame = 0;
+       VectorClear(ed->fields.server->origin);
+       VectorClear(ed->fields.server->angles);
+       ed->fields.server->nextthink = -1;
+       ed->fields.server->solid = 0;
+
+       ed->priv.server->freetime = sv.time;
 }
 
 //===========================================================================
@@ -371,7 +371,7 @@ ddef_t *ED_FindField (const char *name)
        for (i=0 ; i<progs->numfielddefs ; i++)
        {
                def = &pr_fielddefs[i];
-               if (!strcmp(PR_GetString(def->s_name), name))
+               if (!strcmp(PRVM_GetString(def->s_name), name))
                        return def;
        }
        return NULL;
@@ -390,7 +390,7 @@ ddef_t *ED_FindGlobal (const char *name)
        for (i=0 ; i<progs->numglobaldefs ; i++)
        {
                def = &pr_globaldefs[i];
-               if (!strcmp(PR_GetString(def->s_name), name))
+               if (!strcmp(PRVM_GetString(def->s_name), name))
                        return def;
        }
        return NULL;
@@ -399,18 +399,18 @@ ddef_t *ED_FindGlobal (const char *name)
 
 /*
 ============
-ED_FindFunction
+PRVM_ED_FindFunction
 ============
 */
-mfunction_t *ED_FindFunction (const char *name)
+mfunction_t *PRVM_ED_FindFunction (const char *name)
 {
        mfunction_t             *func;
        int                             i;
 
        for (i=0 ; i<progs->numfunctions ; i++)
        {
-               func = &pr_functions[i];
-               if (!strcmp(PR_GetString(func->s_name), name))
+               func = &prog->functions[i];
+               if (!strcmp(PRVM_GetString(func->s_name), name))
                        return func;
        }
        return NULL;
@@ -424,8 +424,8 @@ PR_ValueString
 Returns a string describing *data in a type specific manner
 =============
 */
-//int NoCrash_NUM_FOR_EDICT(edict_t *e);
-char *PR_ValueString (etype_t type, eval_t *val)
+//int NoCrash_NUM_FOR_EDICT(prvm_edict_t *e);
+char *PR_ValueString (etype_t type, prvm_eval_t *val)
 {
        static char line[1024]; // LordHavoc: enlarged a bit (was 256)
        ddef_t *def;
@@ -437,10 +437,10 @@ char *PR_ValueString (etype_t type, eval_t *val)
        switch (type)
        {
        case ev_string:
-               strlcpy (line, PR_GetString (val->string), sizeof (line));
+               strlcpy (line, PRVM_GetString (val->string), sizeof (line));
                break;
        case ev_entity:
-               //n = NoCrash_NUM_FOR_EDICT(PROG_TO_EDICT(val->edict));
+               //n = NoCrash_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict));
                n = val->edict;
                if (n < 0 || n >= MAX_EDICTS)
                        dpsnprintf (line, sizeof (line), "entity %i (invalid!)", n);
@@ -448,12 +448,12 @@ char *PR_ValueString (etype_t type, eval_t *val)
                        dpsnprintf (line, sizeof (line), "entity %i", n);
                break;
        case ev_function:
-               f = pr_functions + val->function;
-               dpsnprintf (line, sizeof (line), "%s()", PR_GetString(f->s_name));
+               f = prog->functions + val->function;
+               dpsnprintf (line, sizeof (line), "%s()", PRVM_GetString(f->s_name));
                break;
        case ev_field:
                def = ED_FieldAtOfs ( val->_int );
-               dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
+               dpsnprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name));
                break;
        case ev_void:
                dpsnprintf (line, sizeof (line), "void");
@@ -485,7 +485,7 @@ Returns a string describing *data in a type specific manner
 Easier to parse than PR_ValueString
 =============
 */
-char *PR_UglyValueString (etype_t type, eval_t *val)
+char *PR_UglyValueString (etype_t type, prvm_eval_t *val)
 {
        static char line[4096];
        int i;
@@ -501,7 +501,7 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
                // Parse the string a bit to turn special characters
                // (like newline, specifically) into escape codes,
                // this fixes saving games from various mods
-               s = PR_GetString (val->string);
+               s = PRVM_GetString (val->string);
                for (i = 0;i < (int)sizeof(line) - 2 && *s;)
                {
                        if (*s == '\n')
@@ -521,15 +521,15 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
                line[i] = '\0';
                break;
        case ev_entity:
-               dpsnprintf (line, sizeof (line), "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
+               dpsnprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
                break;
        case ev_function:
-               f = pr_functions + val->function;
-               strlcpy (line, PR_GetString (f->s_name), sizeof (line));
+               f = prog->functions + val->function;
+               strlcpy (line, PRVM_GetString (f->s_name), sizeof (line));
                break;
        case ev_field:
                def = ED_FieldAtOfs ( val->_int );
-               dpsnprintf (line, sizeof (line), ".%s", PR_GetString(def->s_name));
+               dpsnprintf (line, sizeof (line), ".%s", PRVM_GetString(def->s_name));
                break;
        case ev_void:
                dpsnprintf (line, sizeof (line), "void");
@@ -571,7 +571,7 @@ char *PR_GlobalString (int ofs)
        else
        {
                s = PR_ValueString (def->type, val);
-               dpsnprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
+               dpsnprintf (line, sizeof (line), "%i(%s)%s", ofs, PRVM_GetString(def->s_name), s);
        }
 
        i = strlen(line);
@@ -592,7 +592,7 @@ char *PR_GlobalStringNoContents (int ofs)
        if (!def)
                dpsnprintf (line, sizeof (line), "%i(?)", ofs);
        else
-               dpsnprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
+               dpsnprintf (line, sizeof (line), "%i(%s)", ofs, PRVM_GetString(def->s_name));
 
        i = strlen(line);
        for ( ; i<20 ; i++)
@@ -612,7 +612,7 @@ For debugging
 */
 // LordHavoc: optimized this to print out much more quickly (tempstring)
 // LordHavoc: changed to print out every 4096 characters (incase there are a lot of fields to print)
-void ED_Print(edict_t *ed)
+void ED_Print(prvm_edict_t *ed)
 {
        int             l;
        ddef_t  *d;
@@ -622,18 +622,18 @@ void ED_Print(edict_t *ed)
        int             type;
        char    tempstring[8192], tempstring2[260]; // temporary string buffers
 
-       if (ed->e->free)
+       if (ed->priv.server->free)
        {
                Con_Print("FREE\n");
                return;
        }
 
        tempstring[0] = 0;
-       dpsnprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", NUM_FOR_EDICT(ed));
+       dpsnprintf (tempstring, sizeof (tempstring), "\nEDICT %i:\n", PRVM_NUM_FOR_EDICT(ed));
        for (i=1 ; i<progs->numfielddefs ; i++)
        {
                d = &pr_fielddefs[i];
-               name = PR_GetString(d->s_name);
+               name = PRVM_GetString(d->s_name);
                if (name[strlen(name)-2] == '_')
                        continue;       // skip _x, _y, _z vars
 
@@ -660,7 +660,7 @@ void ED_Print(edict_t *ed)
                        strcat(tempstring, " ");
                strcat(tempstring, " ");
 
-               name = PR_ValueString(d->type, (eval_t *)v);
+               name = PR_ValueString(d->type, (prvm_eval_t *)v);
                if (strlen(name) > 256)
                {
                        memcpy(tempstring2, name, 256);
@@ -687,7 +687,7 @@ ED_Write
 For savegames
 =============
 */
-void ED_Write (qfile_t *f, edict_t *ed)
+void ED_Write (qfile_t *f, prvm_edict_t *ed)
 {
        ddef_t  *d;
        int             *v;
@@ -697,7 +697,7 @@ void ED_Write (qfile_t *f, edict_t *ed)
 
        FS_Print(f, "{\n");
 
-       if (ed->e->free)
+       if (ed->priv.server->free)
        {
                FS_Print(f, "}\n");
                return;
@@ -706,7 +706,7 @@ void ED_Write (qfile_t *f, edict_t *ed)
        for (i=1 ; i<progs->numfielddefs ; i++)
        {
                d = &pr_fielddefs[i];
-               name = PR_GetString(d->s_name);
+               name = PRVM_GetString(d->s_name);
                if (name[strlen(name)-2] == '_')
                        continue;       // skip _x, _y, _z vars
 
@@ -721,7 +721,7 @@ void ED_Write (qfile_t *f, edict_t *ed)
                        continue;
 
                FS_Printf(f,"\"%s\" ",name);
-               FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
+               FS_Printf(f,"\"%s\"\n", PR_UglyValueString(d->type, (prvm_eval_t *)v));
        }
 
        FS_Print(f, "}\n");
@@ -729,7 +729,7 @@ void ED_Write (qfile_t *f, edict_t *ed)
 
 void ED_PrintNum (int ent)
 {
-       ED_Print(EDICT_NUM(ent));
+       ED_Print(PRVM_EDICT_NUM(ent));
 }
 
 /*
@@ -743,8 +743,8 @@ void ED_PrintEdicts (void)
 {
        int             i;
 
-       Con_Printf("%i entities\n", sv.num_edicts);
-       for (i=0 ; i<sv.num_edicts ; i++)
+       Con_Printf("%i entities\n", prog->num_edicts);
+       for (i=0 ; i<prog->num_edicts ; i++)
                ED_PrintNum (i);
 }
 
@@ -760,7 +760,7 @@ void ED_PrintEdict_f (void)
        int             i;
 
        i = atoi (Cmd_Argv(1));
-       if (i < 0 || i >= sv.num_edicts)
+       if (i < 0 || i >= prog->num_edicts)
        {
                Con_Print("Bad edict number\n");
                return;
@@ -778,25 +778,25 @@ For debugging
 void ED_Count (void)
 {
        int             i;
-       edict_t *ent;
+       prvm_edict_t    *ent;
        int             active, models, solid, step;
 
        active = models = solid = step = 0;
-       for (i=0 ; i<sv.num_edicts ; i++)
+       for (i=0 ; i<prog->num_edicts ; i++)
        {
-               ent = EDICT_NUM(i);
-               if (ent->e->free)
+               ent = PRVM_EDICT_NUM(i);
+               if (ent->priv.server->free)
                        continue;
                active++;
-               if (ent->v->solid)
+               if (ent->fields.server->solid)
                        solid++;
-               if (ent->v->model)
+               if (ent->fields.server->model)
                        models++;
-               if (ent->v->movetype == MOVETYPE_STEP)
+               if (ent->fields.server->movetype == MOVETYPE_STEP)
                        step++;
        }
 
-       Con_Printf("num_edicts:%3i\n", sv.num_edicts);
+       Con_Printf("num_edicts:%3i\n", prog->num_edicts);
        Con_Printf("active    :%3i\n", active);
        Con_Printf("view      :%3i\n", models);
        Con_Printf("touch     :%3i\n", solid);
@@ -837,9 +837,9 @@ void ED_WriteGlobals (qfile_t *f)
                if (type != ev_string && type != ev_float && type != ev_entity)
                        continue;
 
-               name = PR_GetString(def->s_name);
+               name = PRVM_GetString(def->s_name);
                FS_Printf(f,"\"%s\" ", name);
-               FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
+               FS_Printf(f,"\"%s\"\n", PR_UglyValueString(type, (prvm_eval_t *)&pr_globals[def->ofs]));
        }
        FS_Print(f,"}\n");
 }
@@ -853,7 +853,7 @@ Console command to set a field of a specified edict
 */
 void ED_EdictSet_f(void)
 {
-       edict_t *ed;
+       prvm_edict_t *ed;
        ddef_t *key;
 
        if(Cmd_Argc() != 4)
@@ -861,7 +861,7 @@ void ED_EdictSet_f(void)
                Con_Print("edictset <edict number> <field> <value>\n");
                return;
        }
-       ed = EDICT_NUM(atoi(Cmd_Argv(1)));
+       ed = PRVM_EDICT_NUM(atoi(Cmd_Argv(1)));
 
        if((key = ED_FindField(Cmd_Argv(2))) == 0)
        {
@@ -922,18 +922,18 @@ Can parse either fields or globals
 returns false if error
 =============
 */
-qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
+qboolean ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
 {
        int i, l;
        char *new_p;
        ddef_t *def;
-       eval_t *val;
+       prvm_eval_t *val;
        mfunction_t *func;
 
        if (ent)
-               val = (eval_t *)((int *)ent->v + key->ofs);
+               val = (prvm_eval_t *)((int *)ent->v + key->ofs);
        else
-               val = (eval_t *)((int *)pr_globals + key->ofs);
+               val = (prvm_eval_t *)((int *)pr_globals + key->ofs);
        switch (key->type & ~DEF_SAVEGLOBAL)
        {
        case ev_string:
@@ -983,12 +983,12 @@ qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
                i = atoi(s);
                if (i < 0 || i >= MAX_EDICTS)
                        Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
-               while (i >= sv.max_edicts)
+               while (i >= prog->max_edicts)
                        SV_IncreaseEdicts();
                // if SV_IncreaseEdicts was called the base pointer needs to be updated
                if (ent)
-                       val = (eval_t *)((int *)ent->v + key->ofs);
-               val->edict = EDICT_TO_PROG(EDICT_NUM(i));
+                       val = (prvm_eval_t *)((int *)ent->v + key->ofs);
+               val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(i));
                break;
 
        case ev_field:
@@ -998,22 +998,22 @@ qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
                        Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
                        return false;
                }
-               //val->_int = G_INT(def->ofs); // AK Please check this - seems to be an org. quake bug
+               //val->_int = PRVM_G_INT(def->ofs); // AK Please check this - seems to be an org. quake bug
                val->_int = def->ofs;
                break;
 
        case ev_function:
-               func = ED_FindFunction(s);
+               func = PRVM_ED_FindFunction(s);
                if (!func)
                {
                        Con_Printf("ED_ParseEpair: Can't find function %s\n", s);
                        return false;
                }
-               val->function = func - pr_functions;
+               val->function = func - prog->functions;
                break;
 
        default:
-               Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
+               Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PRVM_GetString(key->s_name));
                return false;
        }
        return true;
@@ -1028,7 +1028,7 @@ ed should be a properly initialized empty edict.
 Used for initial level load and for savegames.
 ====================
 */
-const char *ED_ParseEdict (const char *data, edict_t *ent)
+const char *ED_ParseEdict (const char *data, prvm_edict_t *ent)
 {
        ddef_t *key;
        qboolean anglehack;
@@ -1039,7 +1039,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
        init = false;
 
 // clear it
-       if (ent != sv.edicts)   // hack
+       if (ent != prog->edicts)        // hack
                memset (ent->v, 0, progs->entityfields * 4);
 
 // go through all the dictionary pairs
@@ -1104,7 +1104,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
        }
 
        if (!init)
-               ent->e->free = true;
+               ent->priv.server->free = true;
 
        return data;
 }
@@ -1127,7 +1127,7 @@ to call ED_CallSpawnFunctions () to let the objects initialize themselves.
 */
 void ED_LoadFromFile (const char *data)
 {
-       edict_t *ent;
+       prvm_edict_t *ent;
        int parsed, inhibited, spawned, died;
        mfunction_t *func;
 
@@ -1136,7 +1136,7 @@ void ED_LoadFromFile (const char *data)
        inhibited = 0;
        spawned = 0;
        died = 0;
-       pr_global_struct->time = sv.time;
+       prog->globals.server->time = sv.time;
 
 // parse ents
        while (1)
@@ -1148,7 +1148,7 @@ void ED_LoadFromFile (const char *data)
                        Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
 
                if (!ent)
-                       ent = EDICT_NUM(0);
+                       ent = PRVM_EDICT_NUM(0);
                else
                        ent = ED_Alloc ();
                data = ED_ParseEdict (data, ent);
@@ -1159,16 +1159,16 @@ void ED_LoadFromFile (const char *data)
                {
                        if (deathmatch.integer)
                        {
-                               if (((int)ent->v->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
+                               if (((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
                                {
                                        ED_Free (ent);
                                        inhibited++;
                                        continue;
                                }
                        }
-                       else if ((current_skill <= 0 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_EASY  ))
-                               || (current_skill == 1 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_MEDIUM))
-                               || (current_skill >= 2 && ((int)ent->v->spawnflags & SPAWNFLAG_NOT_HARD  )))
+                       else if ((current_skill <= 0 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_EASY  ))
+                               || (current_skill == 1 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_MEDIUM))
+                               || (current_skill >= 2 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_HARD  )))
                        {
                                ED_Free (ent);
                                inhibited++;
@@ -1178,7 +1178,7 @@ void ED_LoadFromFile (const char *data)
 //
 // immediately call spawn function
 //
-               if (!ent->v->classname)
+               if (!ent->fields.server->classname)
                {
                        Con_Print("No classname for:\n");
                        ED_Print(ent);
@@ -1187,7 +1187,7 @@ void ED_LoadFromFile (const char *data)
                }
 
        // look for the spawn function
-               func = ED_FindFunction (PR_GetString(ent->v->classname));
+               func = PRVM_ED_FindFunction (PRVM_GetString(ent->fields.server->classname));
 
                if (!func)
                {
@@ -1200,10 +1200,10 @@ void ED_LoadFromFile (const char *data)
                        continue;
                }
 
-               pr_global_struct->self = EDICT_TO_PROG(ent);
-               PR_ExecuteProgram (func - pr_functions, "QC function spawn is missing");
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+               PRVM_ExecuteProgram (func - prog->functions, "QC function spawn is missing");
                spawned++;
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        died++;
        }
 
@@ -1314,7 +1314,7 @@ void PR_LoadProgs (const char *progsname)
        if (progs->crc != PROGHEADER_CRC && progs->crc != 32401) // tenebrae crc also allowed
                Host_Error ("progs.dat system vars have been modified, progdefs.h is out of date");
 
-       //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
+       //prog->functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
        dfunctions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
 
        pr_strings = (char *)progs + progs->ofs_strings;
@@ -1335,7 +1335,7 @@ void PR_LoadProgs (const char *progsname)
        // so allocate a new place for it
        infielddefs = (ddef_t *)((qbyte *)progs + progs->ofs_fielddefs);
        pr_fielddefs = PR_Alloc((progs->numfielddefs + DPFIELDS) * sizeof(ddef_t));
-       pr_functions = PR_Alloc(sizeof(mfunction_t) * progs->numfunctions);
+       prog->functions = PR_Alloc(sizeof(mfunction_t) * progs->numfunctions);
 
        pr_statements = (dstatement_t *)((qbyte *)progs + progs->ofs_statements);
 
@@ -1355,13 +1355,13 @@ void PR_LoadProgs (const char *progsname)
 
        for (i = 0;i < progs->numfunctions;i++)
        {
-               pr_functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
-               pr_functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
-               pr_functions[i].s_name = LittleLong (dfunctions[i].s_name);
-               pr_functions[i].s_file = LittleLong (dfunctions[i].s_file);
-               pr_functions[i].numparms = LittleLong (dfunctions[i].numparms);
-               pr_functions[i].locals = LittleLong (dfunctions[i].locals);
-               memcpy(pr_functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
+               prog->functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
+               prog->functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
+               prog->functions[i].s_name = LittleLong (dfunctions[i].s_name);
+               prog->functions[i].s_file = LittleLong (dfunctions[i].s_file);
+               prog->functions[i].numparms = LittleLong (dfunctions[i].numparms);
+               prog->functions[i].locals = LittleLong (dfunctions[i].locals);
+               memcpy(prog->functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
        }
 
        for (i=0 ; i<progs->numglobaldefs ; i++)
@@ -1386,7 +1386,7 @@ void PR_LoadProgs (const char *progsname)
        {
                pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
                pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
-               pr_fielddefs[progs->numfielddefs].s_name = PR_SetEngineString(dpfields[i].string);
+               pr_fielddefs[progs->numfielddefs].s_name = PRVM_SetEngineString(dpfields[i].string);
                if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
                        progs->entityfields += 3;
                else
@@ -1398,9 +1398,9 @@ void PR_LoadProgs (const char *progsname)
                ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
 
        // moved edict_size calculation down here, below field adding code
-       // LordHavoc: this no longer includes the edict_t header
-       pr_edict_size = progs->entityfields * 4;
-       pr_edictareasize = pr_edict_size * MAX_EDICTS;
+       // LordHavoc: this no longer includes the prvm_edict_t header
+       prog->edict_size = progs->entityfields * 4;
+       pr_edictareasize = prog->edict_size * MAX_EDICTS;
 
        // LordHavoc: bounds check anything static
        for (i = 0,st = pr_statements;i < progs->numstatements;i++,st++)
@@ -1513,7 +1513,7 @@ void PR_Fields_f (void)
        int *counts;
        const char *name;
        char tempstring[5000], tempstring2[260];
-       edict_t *ed;
+       prvm_edict_t *ed;
        ddef_t *d;
        int *v;
        if (!sv.active)
@@ -1522,15 +1522,15 @@ void PR_Fields_f (void)
                return;
        }
        counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
-       for (ednum = 0;ednum < sv.max_edicts;ednum++)
+       for (ednum = 0;ednum < prog->max_edicts;ednum++)
        {
-               ed = EDICT_NUM(ednum);
-               if (ed->e->free)
+               ed = PRVM_EDICT_NUM(ednum);
+               if (ed->priv.server->free)
                        continue;
                for (i = 1;i < progs->numfielddefs;i++)
                {
                        d = &pr_fielddefs[i];
-                       name = PR_GetString(d->s_name);
+                       name = PRVM_GetString(d->s_name);
                        if (name[strlen(name)-2] == '_')
                                continue;       // skip _x, _y, _z vars
                        v = (int *)((char *)ed->v + d->ofs*4);
@@ -1551,7 +1551,7 @@ void PR_Fields_f (void)
        for (i = 0;i < progs->numfielddefs;i++)
        {
                d = &pr_fielddefs[i];
-               name = PR_GetString(d->s_name);
+               name = PRVM_GetString(d->s_name);
                if (name[strlen(name)-2] == '_')
                        continue;       // skip _x, _y, _z vars
                switch(d->type & ~DEF_SAVEGLOBAL)
@@ -1610,7 +1610,7 @@ void PR_Fields_f (void)
                }
        }
        Mem_Free(counts);
-       Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, sv.max_edicts, progs->entityfields * 4 * sv.max_edicts, usedamount * 4 * sv.max_edicts);
+       Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, prog->max_edicts, progs->entityfields * 4 * prog->max_edicts, usedamount * 4 * prog->max_edicts);
 }
 
 void PR_Globals_f (void)
@@ -1622,7 +1622,7 @@ void PR_Globals_f (void)
                return;
        }
        for (i = 0;i < progs->numglobaldefs;i++)
-               Con_Printf("%s\n", PR_GetString(pr_globaldefs[i].s_name));
+               Con_Printf("%s\n", PRVM_GetString(pr_globaldefs[i].s_name));
        Con_Printf("%i global variables, totalling %i bytes\n", progs->numglobals, progs->numglobals * 4);
 }
 
@@ -1706,59 +1706,59 @@ void _PR_FreeAll(const char *filename, int fileline)
 {
        progs = NULL;
        pr_fielddefs = NULL;
-       pr_functions = NULL;
+       prog->functions = NULL;
        _Mem_EmptyPool(serverprogs_mempool, filename, fileline);
 }
 
-// LordHavoc: turned EDICT_NUM into a #define for speed reasons
-edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
+// LordHavoc: turned PRVM_EDICT_NUM into a #define for speed reasons
+prvm_edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline)
 {
-       Host_Error ("EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
+       Host_Error ("PRVM_EDICT_NUM: bad number %i (called at %s:%i)", n, filename, fileline);
        return NULL;
 }
 
 /*
-int NUM_FOR_EDICT_ERROR(edict_t *e)
+int NUM_FOR_EDICT_ERROR(prvm_edict_t *e)
 {
-       Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
+       Host_Error ("PRVM_NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, prog->edicts, e - prog->edicts);
        return 0;
 }
 
-int NUM_FOR_EDICT(edict_t *e)
+int PRVM_NUM_FOR_EDICT(prvm_edict_t *e)
 {
        int n;
-       n = e - sv.edicts;
+       n = e - prog->edicts;
        if ((unsigned int)n >= MAX_EDICTS)
-               Host_Error ("NUM_FOR_EDICT: bad pointer");
+               Host_Error ("PRVM_NUM_FOR_EDICT: bad pointer");
        return n;
 }
 
-//int NoCrash_NUM_FOR_EDICT(edict_t *e)
+//int NoCrash_NUM_FOR_EDICT(prvm_edict_t *e)
 //{
-//     return e - sv.edicts;
+//     return e - prog->edicts;
 //}
 
-//#define      EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
-//#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
-int EDICT_TO_PROG(edict_t *e)
+//#define      PRVM_EDICT_TO_PROG(e) ((qbyte *)(((prvm_edict_t *)e)->v) - (qbyte *)(prog->edictsfields))
+//#define PRVM_PROG_TO_EDICT(e) (prog->edicts + ((e) / (progs->entityfields * 4)))
+int PRVM_EDICT_TO_PROG(prvm_edict_t *e)
 {
        int n;
-       n = e - sv.edicts;
-       if ((unsigned int)n >= (unsigned int)sv.max_edicts)
-               Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
+       n = e - prog->edicts;
+       if ((unsigned int)n >= (unsigned int)prog->max_edicts)
+               Host_Error("PRVM_EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, prog->edicts);
        return n;// EXPERIMENTAL
-       //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
+       //return (qbyte *)e->v - (qbyte *)prog->edictsfields;
 }
-edict_t *PROG_TO_EDICT(int n)
+prvm_edict_t *PRVM_PROG_TO_EDICT(int n)
 {
-       if ((unsigned int)n >= (unsigned int)sv.max_edicts)
-               Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
-       return sv.edicts + n; // EXPERIMENTAL
-       //return sv.edicts + ((n) / (progs->entityfields * 4));
+       if ((unsigned int)n >= (unsigned int)prog->max_edicts)
+               Host_Error("PRVM_PROG_TO_EDICT: invalid edict number %i\n", n);
+       return prog->edicts + n; // EXPERIMENTAL
+       //return prog->edicts + ((n) / (progs->entityfields * 4));
 }
 */
 
-const char *PR_GetString(int num)
+const char *PRVM_GetString(int num)
 {
        if (num >= 0 && num < pr_stringssize)
                return pr_strings + num;
@@ -1766,12 +1766,12 @@ const char *PR_GetString(int num)
        {
                num = -1 - num;
                if (!pr_knownstrings[num])
-                       Host_Error("PR_GetString: attempt to get string that is already freed\n");
+                       Host_Error("PRVM_GetString: attempt to get string that is already freed\n");
                return pr_knownstrings[num];
        }
        else
        {
-               Host_Error("PR_GetString: invalid string offset %i\n", num);
+               Host_Error("PRVM_GetString: invalid string offset %i\n", num);
                return "";
        }
 }
@@ -1790,13 +1790,13 @@ int PR_SetQCString(const char *s)
        return -1 - i;
 }
 
-int PR_SetEngineString(const char *s)
+int PRVM_SetEngineString(const char *s)
 {
        int i;
        if (!s)
                return 0;
        if (s >= pr_strings && s <= pr_strings + pr_stringssize)
-               Host_Error("PR_SetEngineString: s in pr_strings area\n");
+               Host_Error("PRVM_SetEngineString: s in pr_strings area\n");
        for (i = 0;i < pr_numknownstrings;i++)
                if (pr_knownstrings[i] == s)
                        return -1 - i;
index 2393ed1dd4d127d0939f31cee067f20e589cd555..a63f04df2147c6cd3200c6526beb2c7a2b7d3ea3 100644 (file)
--- a/pr_exec.c
+++ b/pr_exec.c
@@ -199,7 +199,7 @@ void PR_StackTrace (void)
                if (!f)
                        Con_Print("<NULL FUNCTION>\n");
                else
-                       Con_Printf("%12s : %s : statement %i\n", PR_GetString(f->s_file), PR_GetString(f->s_name), pr_stack[i].s - f->first_statement);
+                       Con_Printf("%12s : %s : statement %i\n", PRVM_GetString(f->s_file), PRVM_GetString(f->s_name), pr_stack[i].s - f->first_statement);
        }
 }
 
@@ -233,7 +233,7 @@ void PR_Profile_f (void)
                best = NULL;
                for (i=0 ; i<progs->numfunctions ; i++)
                {
-                       f = &pr_functions[i];
+                       f = &prog->functions[i];
                        if (f->profile > max)
                        {
                                max = f->profile;
@@ -243,7 +243,7 @@ void PR_Profile_f (void)
                if (best)
                {
                        //if (num < howmany)
-                               Con_Printf("%7i %7i %7i %s\n", best->profile, best->builtinsprofile, best->callcount, PR_GetString(best->s_name));
+                               Con_Printf("%7i %7i %7i %s\n", best->profile, best->builtinsprofile, best->callcount, PRVM_GetString(best->s_name));
                        num++;
                        best->profile = 0;
                        best->builtinsprofile = 0;
@@ -280,7 +280,7 @@ void PR_Crash(void)
 
 /*
 ============================================================================
-PR_ExecuteProgram
+PRVM_ExecuteProgram
 
 The interpretation main loop
 ============================================================================
@@ -309,7 +309,7 @@ int PR_EnterFunction (mfunction_t *f)
 // save off any locals that the new function steps on
        c = f->locals;
        if (localstack_used + c > LOCALSTACK_SIZE)
-               Host_Error ("PR_ExecuteProgram: locals stack overflow\n");
+               Host_Error ("PRVM_ExecuteProgram: locals stack overflow\n");
 
        for (i=0 ; i < c ; i++)
                localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
@@ -348,7 +348,7 @@ int PR_LeaveFunction (void)
        c = pr_xfunction->locals;
        localstack_used -= c;
        if (localstack_used < 0)
-               Host_Error ("PR_ExecuteProgram: locals stack underflow\n");
+               Host_Error ("PRVM_ExecuteProgram: locals stack underflow\n");
 
        for (i=0 ; i < c ; i++)
                ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
@@ -371,31 +371,31 @@ void PR_Execute_ProgsLoaded(void)
 
 /*
 ====================
-PR_ExecuteProgram
+PRVM_ExecuteProgram
 ====================
 */
 // LordHavoc: optimized
-#define OPA ((eval_t *)&pr_globals[(unsigned short) st->a])
-#define OPB ((eval_t *)&pr_globals[(unsigned short) st->b])
-#define OPC ((eval_t *)&pr_globals[(unsigned short) st->c])
+#define OPA ((prvm_eval_t *)&pr_globals[(unsigned short) st->a])
+#define OPB ((prvm_eval_t *)&pr_globals[(unsigned short) st->b])
+#define OPC ((prvm_eval_t *)&pr_globals[(unsigned short) st->c])
 extern cvar_t pr_boundscheck;
 extern cvar_t pr_traceqc;
-void PR_ExecuteProgram (func_t fnum, const char *errormessage)
+void PRVM_ExecuteProgram (func_t fnum, const char *errormessage)
 {
        dstatement_t    *st;
        mfunction_t     *f, *newf;
-       edict_t *ed;
-       eval_t  *ptr;
+       prvm_edict_t    *ed;
+       prvm_eval_t     *ptr;
        int             profile, startprofile, cachedpr_trace, exitdepth;
 
        if (!fnum || fnum >= (unsigned) progs->numfunctions)
        {
-               if (pr_global_struct->self)
-                       ED_Print(PROG_TO_EDICT(pr_global_struct->self));
-               Host_Error ("PR_ExecuteProgram: %s", errormessage);
+               if (prog->globals.server->self)
+                       ED_Print(PRVM_PROG_TO_EDICT(prog->globals.server->self));
+               Host_Error ("PRVM_ExecuteProgram: %s", errormessage);
        }
 
-       f = &pr_functions[fnum];
+       f = &prog->functions[fnum];
 
        pr_trace = pr_traceqc.integer;
 
index 3ea2241ebb880f7016fdf149158d8ace205570b9..f70f100ebeefad3cacc61e0b5fc7771765d19658 100644 (file)
@@ -90,7 +90,7 @@
                                OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
                                break;
                        case OP_NOT_S:
-                               OPC->_float = !OPA->string || !*PR_GetString(OPA->string);
+                               OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string);
                                break;
                        case OP_NOT_FNC:
                                OPC->_float = !OPA->function;
                                OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
                                break;
                        case OP_EQ_S:
-                               OPC->_float = !strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string));
+                               OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
                                break;
                        case OP_EQ_E:
                                OPC->_float = OPA->_int == OPB->_int;
                                OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
                                break;
                        case OP_NE_S:
-                               OPC->_float = strcmp(PR_GetString(OPA->string),PR_GetString(OPB->string));
+                               OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
                                break;
                        case OP_NE_E:
                                OPC->_float = OPA->_int != OPB->_int;
                                        return;
                                }
 #endif
-                               ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
+                               ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
                                ptr->_int = OPA->_int;
                                break;
                        case OP_STOREP_V:
                                        return;
                                }
 #endif
-                               ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
+                               ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
                                ptr->vector[0] = OPA->vector[0];
                                ptr->vector[1] = OPA->vector[1];
                                ptr->vector[2] = OPA->vector[2];
                                        Host_Error("assignment to world entity");
                                        return;
                                }
-                               ed = PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = (qbyte *)((int *)ed->v + OPB->_int) - (qbyte *)sv.edictsfields;
+                               ed = PRVM_PROG_TO_EDICT(OPA->edict);
+                               OPC->_int = (qbyte *)((int *)ed->v + OPB->_int) - (qbyte *)prog->edictsfields;
                                break;
 
                        case OP_LOAD_F:
                                        return;
                                }
 #endif
-                               ed = PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
+                               ed = PRVM_PROG_TO_EDICT(OPA->edict);
+                               OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
                                break;
 
                        case OP_LOAD_V:
                                        return;
                                }
 #endif
-                               ed = PROG_TO_EDICT(OPA->edict);
-                               OPC->vector[0] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[0];
-                               OPC->vector[1] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[1];
-                               OPC->vector[2] = ((eval_t *)((int *)ed->v + OPB->_int))->vector[2];
+                               ed = PRVM_PROG_TO_EDICT(OPA->edict);
+                               OPC->vector[0] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[0];
+                               OPC->vector[1] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[1];
+                               OPC->vector[2] = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->vector[2];
                                break;
 
                //==================
                                else if (OPA->function > (unsigned) progs->numfunctions)
                                        Host_Error("Bad function number");
 
-                               newf = &pr_functions[OPA->function];
+                               newf = &prog->functions[OPA->function];
                                newf->callcount++;
 
                                if (newf->first_statement < 0)
                                pr_xfunction->profile += profile - startprofile;
                                startprofile = profile;
                                pr_xstatement = st - pr_statements;
-                               ed = PROG_TO_EDICT(pr_global_struct->self);
-                               ed->v->nextthink = pr_global_struct->time + 0.1;
-                               ed->v->frame = OPA->_float;
-                               ed->v->think = OPB->function;
+                               ed = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+                               ed->fields.server->nextthink = prog->globals.server->time + 0.1;
+                               ed->fields.server->frame = OPA->_float;
+                               ed->fields.server->think = OPB->function;
                                break;
 
 // LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
                                        return;
                                }
 #endif
-                               ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
+                               ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
                                ptr->_int = OPA->_int;
                                break;
                        case OP_LOAD_I:
                                        return;
                                }
 #endif
-                               ed = PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
+                               ed = PRVM_PROG_TO_EDICT(OPA->edict);
+                               OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
                                break;
 
                        case OP_GSTOREP_I:
diff --git a/progs.h b/progs.h
index 2a2605c9054ace87a78874033361dfd3e26e18bc..c4bd745a45da36e88914ccdfc31465e563e6b428 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -18,8 +18,112 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
 
-#ifndef PROGS_H
+#ifndef PROGS_H 
 #define PROGS_H
+#include "pr_comp.h"                   // defs shared with qcc
+
+typedef struct link_s
+{
+       int entitynumber;
+       struct link_s   *prev, *next;
+} link_t;
+
+#define ENTITYGRIDAREAS 16
+
+typedef struct edict_engineprivate_s
+{
+       // true if this edict is unused
+       qboolean free;
+       // sv.time when the object was freed (to prevent early reuse which could
+       // mess up client interpolation or obscure severe QuakeC bugs)
+       float freetime;
+
+       // physics grid areas this edict is linked into
+       link_t areagrid[ENTITYGRIDAREAS];
+       // since the areagrid can have multiple references to one entity,
+       // we should avoid extensive checking on entities already encountered
+       int areagridmarknumber;
+
+       // PROTOCOL_QUAKE, PROTOCOL_QUAKEDP, PROTOCOL_NEHAHRAMOVIE
+       // baseline values
+       entity_state_t baseline;
+
+       // LordHavoc: gross hack to make floating items still work
+       int suspendedinairflag;
+       // used by PushMove to keep track of where objects were before they were
+       // moved, in case they need to be moved back
+       vec3_t moved_from;
+       vec3_t moved_fromangles;
+}
+edict_engineprivate_t;
+
+// LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  see pr_edict.c for the functions which use these.
+extern int eval_gravity;
+extern int eval_button3;
+extern int eval_button4;
+extern int eval_button5;
+extern int eval_button6;
+extern int eval_button7;
+extern int eval_button8;
+extern int eval_buttonuse;
+extern int eval_buttonchat;
+extern int eval_glow_size;
+extern int eval_glow_trail;
+extern int eval_glow_color;
+extern int eval_items2;
+extern int eval_scale;
+extern int eval_alpha;
+extern int eval_renderamt; // HalfLife support
+extern int eval_rendermode; // HalfLife support
+extern int eval_fullbright;
+extern int eval_ammo_shells1;
+extern int eval_ammo_nails1;
+extern int eval_ammo_lava_nails;
+extern int eval_ammo_rockets1;
+extern int eval_ammo_multi_rockets;
+extern int eval_ammo_cells1;
+extern int eval_ammo_plasma;
+extern int eval_idealpitch;
+extern int eval_pitch_speed;
+extern int eval_viewmodelforclient;
+extern int eval_nodrawtoclient;
+extern int eval_exteriormodeltoclient;
+extern int eval_drawonlytoclient;
+extern int eval_ping;
+extern int eval_movement;
+extern int eval_pmodel;
+extern int eval_punchvector;
+extern int eval_viewzoom;
+extern int eval_clientcolors;
+extern int eval_tag_entity;
+extern int eval_tag_index;
+extern int eval_light_lev;
+extern int eval_color;
+extern int eval_style;
+extern int eval_pflags;
+extern int eval_cursor_active;
+extern int eval_cursor_screen;
+extern int eval_cursor_trace_start;
+extern int eval_cursor_trace_endpos;
+extern int eval_cursor_trace_ent;
+extern int eval_colormod;
+extern int eval_playermodel;
+extern int eval_playerskin;
+
+extern mfunction_t *SV_PlayerPhysicsQC;
+extern mfunction_t *EndFrameQC;
+//KrimZon - SERVER COMMANDS IN QUAKEC
+extern mfunction_t *SV_ParseClientCommandQC;
+
+#endif
+
+
+
+
+
+
+//////////////////////////////////
+#if 0
 
 #include "pr_comp.h"                   // defs shared with qcc
 #include "progdefs.h"                  // generated by program cdefs
@@ -33,7 +137,7 @@ typedef union eval_s
        int                             ivector[3];
        int                             _int;
        int                             edict;
-} eval_t;
+} prvm_eval_t;
 
 typedef struct link_s
 {
@@ -79,7 +183,7 @@ typedef struct edict_s
        // QuakeC fields (stored in dynamically resized array)
        entvars_t *v;
 }
-edict_t;
+prvm_edict_t;
 
 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  see pr_edict.c for the functions which use these.
 extern int eval_gravity;
@@ -134,7 +238,7 @@ extern int eval_colormod;
 extern int eval_playermodel;
 extern int eval_playerskin;
 
-#define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((qbyte *)ed->v + fieldoffset) : NULL)
+#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((qbyte *)ed->v + fieldoffset) : NULL)
 
 
 extern mfunction_t *SV_PlayerPhysicsQC;
@@ -145,7 +249,7 @@ extern mfunction_t *SV_ParseClientCommandQC;
 //============================================================================
 
 extern dprograms_t             *progs;
-extern mfunction_t             *pr_functions;
+extern mfunction_t             *prog->functions;
 extern char                    *pr_strings;
 extern int                             pr_stringssize;
 extern ddef_t                  *pr_globaldefs;
@@ -154,7 +258,7 @@ extern      dstatement_t    *pr_statements;
 extern globalvars_t    *pr_global_struct;
 extern float                   *pr_globals;                    // same as pr_global_struct
 
-extern int                             pr_edict_size;  // in bytes
+extern int                             prog->edict_size;       // in bytes
 extern int                             pr_edictareasize; // LordHavoc: for bounds checking
 
 extern int                             pr_maxknownstrings;
@@ -166,7 +270,7 @@ extern      const char              **pr_knownstrings;
 void PR_Init (void);
 void PR_Shutdown (void);
 
-void PR_ExecuteProgram (func_t fnum, const char *errormessage);
+void PRVM_ExecuteProgram (func_t fnum, const char *errormessage);
 void PR_LoadProgs (const char *progsname);
 
 #define PR_Alloc(buffersize) _PR_Alloc(buffersize, __FILE__, __LINE__)
@@ -183,49 +287,49 @@ void PR_Crash (void);
 
 void SV_IncreaseEdicts(void);
 
-edict_t *ED_Alloc (void);
-void ED_Free (edict_t *ed);
-void ED_ClearEdict (edict_t *e);
+prvm_edict_t *ED_Alloc (void);
+void ED_Free (prvm_edict_t *ed);
+void ED_ClearEdict (prvm_edict_t *e);
 
-void ED_Print(edict_t *ed);
-void ED_Write (qfile_t *f, edict_t *ed);
-const char *ED_ParseEdict (const char *data, edict_t *ent);
+void ED_Print(prvm_edict_t *ed);
+void ED_Write (qfile_t *f, prvm_edict_t *ed);
+const char *ED_ParseEdict (const char *data, prvm_edict_t *ent);
 
 void ED_WriteGlobals (qfile_t *f);
 void ED_ParseGlobals (const char *data);
 
 void ED_LoadFromFile (const char *data);
 
-edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline);
-#define EDICT_NUM(n) (((n) >= 0 && (n) < sv.max_edicts) ? sv.edicts + (n) : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
-#define EDICT_NUM_UNSIGNED(n) (((n) < sv.max_edicts) ? sv.edicts + (n) : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
+prvm_edict_t *EDICT_NUM_ERROR(int n, char *filename, int fileline);
+#define PRVM_EDICT_NUM(n) (((n) >= 0 && (n) < prog->max_edicts) ? prog->edicts + (n) : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
+#define EDICT_NUM_UNSIGNED(n) (((n) < prog->max_edicts) ? prog->edicts + (n) : EDICT_NUM_ERROR(n, __FILE__, __LINE__))
 
-//int NUM_FOR_EDICT_ERROR(edict_t *e);
-#define NUM_FOR_EDICT(e) ((int)((edict_t *)(e) - sv.edicts))
-//int NUM_FOR_EDICT(edict_t *e);
+//int NUM_FOR_EDICT_ERROR(prvm_edict_t *e);
+#define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts))
+//int PRVM_NUM_FOR_EDICT(prvm_edict_t *e);
 
-#define        NEXT_EDICT(e) ((e) + 1)
+#define        PRVM_NEXT_EDICT(e) ((e) + 1)
 
-#define EDICT_TO_PROG(e) (NUM_FOR_EDICT(e))
-//int EDICT_TO_PROG(edict_t *e);
-#define PROG_TO_EDICT(n) (EDICT_NUM(n))
-//edict_t *PROG_TO_EDICT(int n);
+#define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e))
+//int PRVM_EDICT_TO_PROG(prvm_edict_t *e);
+#define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n))
+//prvm_edict_t *PRVM_PROG_TO_EDICT(int n);
 
 //============================================================================
 
-#define        G_FLOAT(o) (pr_globals[o])
-#define        G_INT(o) (*(int *)&pr_globals[o])
-#define        G_EDICT(o) (PROG_TO_EDICT(*(int *)&pr_globals[o]))
-#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
-#define        G_VECTOR(o) (&pr_globals[o])
-#define        G_STRING(o) (PR_GetString(*(string_t *)&pr_globals[o]))
+#define        PRVM_G_FLOAT(o) (pr_globals[o])
+#define        PRVM_G_INT(o) (*(int *)&pr_globals[o])
+#define        PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&pr_globals[o]))
+#define PRVM_G_EDICTNUM(o) PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(o))
+#define        PRVM_G_VECTOR(o) (&pr_globals[o])
+#define        PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&pr_globals[o]))
 //#define      G_FUNCTION(o) (*(func_t *)&pr_globals[o])
 
 // FIXME: make these go away?
 #define        E_FLOAT(e,o) (((float*)e->v)[o])
 //#define      E_INT(e,o) (((int*)e->v)[o])
 //#define      E_VECTOR(e,o) (&((float*)e->v)[o])
-#define        E_STRING(e,o) (PR_GetString(*(string_t *)&((float*)e->v)[o]))
+#define        E_STRING(e,o) (PRVM_GetString(*(string_t *)&((float*)e->v)[o]))
 
 extern int             type_size[8];
 
@@ -246,9 +350,9 @@ void PR_Execute_ProgsLoaded(void);
 void ED_PrintEdicts (void);
 void ED_PrintNum (int ent);
 
-const char *PR_GetString(int num);
+const char *PRVM_GetString(int num);
 int PR_SetQCString(const char *s);
-int PR_SetEngineString(const char *s);
+int PRVM_SetEngineString(const char *s);
 char *PR_AllocString(int bufferlength);
 void PR_FreeString(char *s);
 
index d702a7dc2de1519ca47fd25d8df48cca91b43715..c40fd82597ca4c91765bb241edf7f8ed68da514b 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -30,7 +30,7 @@ The code uses void pointers instead.
 #define PROGSVM_H
 
 #include "pr_comp.h"                   // defs shared with qcc
-//#include "progdefs.h"                        // generated by program cdefs
+#include "progdefs.h"                  // generated by program cdefs
 
 /*
 typedef union vm_eval_s
@@ -152,6 +152,13 @@ typedef union prvm_eval_s
        int                             edict;
 } prvm_eval_t;
 
+typedef struct prvm_required_field_s 
+{
+       int type;
+       const char *name;
+} prvm_required_field_t;
+
+
 /*typedef struct prvm_link_s
 {
        int entitynumber;
@@ -173,7 +180,8 @@ typedef struct prvm_edict_s
        union
        {
                prvm_edict_private_t *required;
-               void                             *vp;
+               void *vp;
+               edict_engineprivate_t *server;
                // add other private structs as you desire
                // new structs have to start with the elements of prvm_edit_private_t
                // e.g. a new struct has to either look like this:
@@ -192,14 +200,14 @@ typedef struct prvm_edict_s
                // However, the first one should be preferred.
        } priv;
        // QuakeC fields (stored in dynamically resized array)
-       //entvars_t *v;
        union 
        {
                void *vp;
+               entvars_t *server;
        } fields;
 } prvm_edict_t;
 
-#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((qbyte *)ed->v + fieldoffset) : NULL)
+#define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((qbyte *)ed->fields.vp + fieldoffset) : NULL)
 
 /*// this struct is the basic requirement for a qc prog
 typedef struct prvm_pr_globalvars_s
@@ -250,11 +258,14 @@ typedef struct prvm_prog_s
        ddef_t                          *fielddefs;
        ddef_t                          *globaldefs;
        dstatement_t            *statements;
-       //prvm_pr_globalvars_t*pr_global_struct;
-       float                           *globals;                       // same as pr_global_struct
        int                                     edict_size;                     // in bytes
        int                                     edictareasize;          // LordHavoc: in bytes (for bound checking)
 
+       union {
+               float *generic;
+               globalvars_t *server;
+       } globals;
+
        int                                     maxknownstrings;
        int                                     numknownstrings;
        const char                      **knownstrings;
@@ -279,14 +290,23 @@ typedef struct prvm_prog_s
        int                                     localstack[PRVM_LOCALSTACK_SIZE];
        int                                     localstack_used;
 
-       unsigned short          crc; // [INIT]
+       unsigned short          headercrc; // [INIT]
+
+       unsigned short          filecrc;
 
        //============================================================================
        // until this point everything also exists (with the pr_ prefix) in the old vm
 
        // copies of some vars that were former read from sv
        int                                     num_edicts;
-       int                                     max_edicts;
+       // number of edicts for which space has been (should be) allocated
+       int                                     max_edicts; // [INIT]
+       // used instead of the constant MAX_EDICTS
+       int                                     limit_edicts; // [INIT]
+
+       // number of reserved edicts (allocated from 1)
+       int                                     reserved_edicts; // [INIT]
+
 
        prvm_edict_t            *edicts;
        void                            *edictsfields;
@@ -309,12 +329,11 @@ typedef struct prvm_prog_s
 
        char                            *extensionstring; // [INIT]
 
+       qboolean                        loadintoworld; // [INIT]
+
        // used to indicate whether a prog is loaded
        qboolean                        loaded;
 
-       // used instead of the constant MAX_EDICTS
-       int                                     limit_edicts; // [INIT]
-
 //     prvm_builtin_mem_t  *mem_list;
 
 // now passes as parameter of PRVM_LoadProgs
@@ -331,7 +350,7 @@ typedef struct prvm_prog_s
        void                            (*begin_increase_edicts)(void); // [INIT] used by PRVM_MEM_Increase_Edicts
        void                            (*end_increase_edicts)(void); // [INIT]
 
-       void                            (*init_edict)(int num); // [INIT] used by PRVM_ED_ClearEdict
+       void                            (*init_edict)(prvm_edict_t *edict); // [INIT] used by PRVM_ED_ClearEdict
        void                            (*free_edict)(prvm_edict_t *ed); // [INIT] used by PRVM_ED_Free
 
        void                            (*count_edicts)(void); // [INIT] used by PRVM_ED_Count_f
@@ -345,7 +364,6 @@ typedef struct prvm_prog_s
 
 } prvm_prog_t;
 
-
 extern prvm_prog_t * prog;
 
 #define PRVM_MAXPROGS 3
@@ -400,6 +418,12 @@ void PRVM_PrintState(void);
 void PRVM_CrashAll (void);
 void PRVM_Crash (void);
 
+int PRVM_ED_FindFieldOffset(const char *field);
+ddef_t *PRVM_ED_FindField (const char *name);
+mfunction_t *PRVM_ED_FindFunction (const char *name);
+
+void PRVM_MEM_IncreaseEdicts(void);
+
 prvm_edict_t *PRVM_ED_Alloc (void);
 void PRVM_ED_Free (prvm_edict_t *ed);
 void PRVM_ED_ClearEdict (prvm_edict_t *e);
@@ -415,27 +439,28 @@ void PRVM_ED_LoadFromFile (const char *data);
 
 prvm_edict_t *PRVM_EDICT_NUM_ERROR(int n, char *filename, int fileline);
 #define        PRVM_EDICT_NUM(n) (((n) >= 0 && (n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__))
+#define        PRVM_EDICT_NUM_UNSIGNED(n) (((n) < prog->max_edicts) ? prog->edicts + (n) : PRVM_EDICT_NUM_ERROR(n, __FILE__, __LINE__))
 
-//int NUM_FOR_EDICT_ERROR(edict_t *e);
+//int NUM_FOR_EDICT_ERROR(prvm_edict_t *e);
 #define PRVM_NUM_FOR_EDICT(e) ((int)((prvm_edict_t *)(e) - prog->edicts))
-//int NUM_FOR_EDICT(edict_t *e);
+//int PRVM_NUM_FOR_EDICT(prvm_edict_t *e);
 
 #define        PRVM_NEXT_EDICT(e) ((e) + 1)
 
 #define PRVM_EDICT_TO_PROG(e) (PRVM_NUM_FOR_EDICT(e))
-//int PRVM_EDICT_TO_PROG(edict_t *e);
+//int PRVM_EDICT_TO_PROG(prvm_edict_t *e);
 #define PRVM_PROG_TO_EDICT(n) (PRVM_EDICT_NUM(n))
-//edict_t *PRVM_PROG_TO_EDICT(int n);
+//prvm_edict_t *PRVM_PROG_TO_EDICT(int n);
 
 //============================================================================
 
-#define        PRVM_G_FLOAT(o) (prog->globals[o])
-#define        PRVM_G_INT(o) (*(int *)&prog->globals[o])
-#define        PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals[o]))
+#define        PRVM_G_FLOAT(o) (prog->globals.generic[o])
+#define        PRVM_G_INT(o) (*(int *)&prog->globals.generic[o])
+#define        PRVM_G_EDICT(o) (PRVM_PROG_TO_EDICT(*(int *)&prog->globals.generic[o]))
 #define PRVM_G_EDICTNUM(o) PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(o))
-#define        PRVM_G_VECTOR(o) (&prog->globals[o])
-#define        PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals[o]))
-//#define      PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals[o])
+#define        PRVM_G_VECTOR(o) (&prog->globals.generic[o])
+#define        PRVM_G_STRING(o) (PRVM_GetString(*(string_t *)&prog->globals.generic[o]))
+//#define      PRVM_G_FUNCTION(o) (*(func_t *)&prog->globals.generic[o])
 
 // FIXME: make these go away?
 #define        PRVM_E_FLOAT(e,o) (((float*)e->fields.vp)[o])
@@ -460,10 +485,10 @@ void PRVM_FreeString(char *s);
 //============================================================================
 
 // used as replacement for a prog stack
-//#define PRVM_DEBUGPRSTACK
+#define PRVM_DEBUGPRSTACK
 
 #ifdef PRVM_DEBUGPRSTACK
-#define PRVM_Begin  if(prog != 0) Con_Printf("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
+#define PRVM_Begin  if(prog != 0) Host_Error("prog not 0(prog = %i) in file: %s line: %i!\n", PRVM_GetProgNr(), __FILE__, __LINE__)
 #define PRVM_End       prog = 0
 #else
 #define PRVM_Begin
@@ -495,7 +520,7 @@ Load a program with LoadProgs
 */
 void PRVM_InitProg(int prognr);
 // LoadProgs expects to be called right after InitProg
-void PRVM_LoadProgs (const char *filename, int numrequiredfunc, char **required_func);
+void PRVM_LoadProgs (const char *filename, int numrequiredfunc, char **required_func, int numrequiredfields, prvm_required_field_t *required_field);
 void PRVM_ResetProg(void);
 
 qboolean PRVM_ProgLoaded(int prognr);
index f92041421c139760b9f02a38980fee74447193f7..7577d69008f69fd066b14d3ca5f79e882b4937db 100644 (file)
@@ -270,7 +270,7 @@ void EntityFrameQuake_WriteFrame(sizebuf_t *msg, int numstates, const entity_sta
                        bits |= U_EXTERIORMODEL;
 
                // LordHavoc: old stuff, but rewritten to have more exact tolerances
-               baseline = sv.edicts[s->number].e->baseline;
+               baseline = prog->edicts[s->number].priv.server->baseline;
                if (baseline.origin[0] != s->origin[0])
                        bits |= U_ORIGIN1;
                if (baseline.origin[1] != s->origin[1])
@@ -1381,15 +1381,15 @@ void EntityFrame4_WriteFrame(sizebuf_t *msg, entityframe4_database_t *d, int num
                                Con_Printf(" %i", d->commit[i].framenum);
                Con_Print(")\n");
        }
-       if (d->currententitynumber >= sv.max_edicts)
+       if (d->currententitynumber >= prog->max_edicts)
                startnumber = 1;
        else
-               startnumber = bound(1, d->currententitynumber, sv.max_edicts - 1);
+               startnumber = bound(1, d->currententitynumber, prog->max_edicts - 1);
        MSG_WriteShort(msg, startnumber);
        // reset currententitynumber so if the loop does not break it we will
        // start at beginning next frame (if it does break, it will set it)
        d->currententitynumber = 1;
-       for (i = 0, n = startnumber;n < sv.max_edicts;n++)
+       for (i = 0, n = startnumber;n < prog->max_edicts;n++)
        {
                // find the old state to delta from
                e = EntityFrame4_GetReferenceEntity(d, n);
@@ -2025,8 +2025,8 @@ void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int num
        qbyte data[128];
        entityframe5_packetlog_t *packetlog;
 
-       if (sv.max_edicts > d->maxedicts)
-               EntityFrame5_ExpandEdicts(d, (sv.max_edicts + 255) & ~255);
+       if (prog->max_edicts > d->maxedicts)
+               EntityFrame5_ExpandEdicts(d, (prog->max_edicts + 255) & ~255);
 
        framenum = d->latestframenum + 1;
        d->viewentnum = viewentnum;
@@ -2090,8 +2090,8 @@ void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int num
                num++;
        }
        // all remaining entities are dead
-       // note: this must use sv.max_edicts, not sv.num_edicts, because sv.num_edicts can both increase and decrease, where as sv.max_edicts only increases (if sv.num_edicts is used, sometimes some entities are missed when the sv.num_edicts count goes back down after firing some shots)
-       for (;num < sv.max_edicts;num++)
+       // note: this must use prog->max_edicts, not prog->num_edicts, because prog->num_edicts can both increase and decrease, where as prog->max_edicts only increases (if prog->num_edicts is used, sometimes some entities are missed when the prog->num_edicts count goes back down after firing some shots)
+       for (;num < prog->max_edicts;num++)
        {
                if (CHECKPVSBIT(d->visiblebits, num))
                {
@@ -2111,7 +2111,7 @@ void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int num
        // build lists of entities by priority level
        memset(entityframe5_prioritychaincounts, 0, sizeof(entityframe5_prioritychaincounts));
        l = 0;
-       for (num = 0;num < sv.num_edicts;num++)
+       for (num = 0;num < prog->num_edicts;num++)
        {
                if (d->priorities[num])
                {
index 55a7584edcca90fe4e367452140eb9e342de47ab..7d8354a941cf8e15e207291d350ccc2d62000b05 100644 (file)
@@ -11,8 +11,6 @@
 
 // temp string handling
 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
-#define VM_STRINGTEMP_BUFFERS 16
-#define VM_STRINGTEMP_LENGTH 4096
 static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH];
 static int vm_string_tempindex = 0;
 
@@ -370,7 +368,7 @@ void VM_vectoangles (void)
                        yaw = 270;
 
                forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
-               pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
+               pitch = (atan2(value1[2], forward) * 180 / M_PI);
                if (pitch < 0)
                        pitch += 360;
        }
@@ -416,15 +414,15 @@ void PF_sound (void)
 {
        char            *sample;
        int                     channel;
-       edict_t         *entity;
+       prvm_edict_t            *entity;
        int             volume;
        float attenuation;
 
-       entity = G_EDICT(OFS_PARM0);
-       channel = G_FLOAT(OFS_PARM1);
-       sample = G_STRING(OFS_PARM2);
-       volume = G_FLOAT(OFS_PARM3) * 255;
-       attenuation = G_FLOAT(OFS_PARM4);
+       entity = PRVM_G_EDICT(OFS_PARM0);
+       channel = PRVM_G_FLOAT(OFS_PARM1);
+       sample = PRVM_G_STRING(OFS_PARM2);
+       volume = PRVM_G_FLOAT(OFS_PARM3) * 255;
+       attenuation = PRVM_G_FLOAT(OFS_PARM4);
 
        if (volume < 0 || volume > 255)
                Host_Error ("SV_StartSound: volume = %i", volume);
@@ -729,11 +727,17 @@ void VM_remove (void)
        VM_SAFEPARMCOUNT(1, VM_remove);
 
        ed = PRVM_G_EDICT(OFS_PARM0);
+       if( PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts ) {
+               Con_DPrint( "VM_remove: tried to remove the null entity or a reserved entity!\n" );
+       } else if( ed->priv.required->free ) {
+               Con_DPrint( "VM_remove: tried to remove an already freed entity!\n" );
+       } else {
+               PRVM_ED_Free (ed);
+       }
 //     if (ed == prog->edicts)
 //             PRVM_ERROR ("remove: tried to remove world\n");
 //     if (PRVM_NUM_FOR_EDICT(ed) <= sv.maxclients)
 //             Host_Error("remove: tried to remove a client\n");
-       PRVM_ED_Free (ed);
 }
 
 /*
@@ -922,54 +926,6 @@ void VM_findchainfloat (void)
        VM_RETURN_EDICT(chain);
 }
 
-/*
-=========
-VM_precache_file
-
-string precache_file(string)
-=========
-*/
-void VM_precache_file (void)
-{      // precache_file is only used to copy files with qcc, it does nothing
-       VM_SAFEPARMCOUNT(1,VM_precache_file);
-
-       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-}
-
-/*
-=========
-VM_preache_error
-
-used instead of the other VM_precache_* functions in the builtin list
-=========
-*/
-
-void VM_precache_error (void)
-{
-       PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
-}
-
-/*
-=========
-VM_precache_sound
-
-string precache_sound (string sample)
-=========
-*/
-void VM_precache_sound (void)
-{
-       const char      *s;
-
-       VM_SAFEPARMCOUNT(1, VM_precache_sound);
-
-       s = PRVM_G_STRING(OFS_PARM0);
-       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-       VM_CheckEmptyString (s);
-
-       if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
-               Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
-}
-
 /*
 =========
 VM_coredump
@@ -1138,98 +1094,6 @@ void VM_nextent (void)
        }
 }
 
-/*
-===============================================================================
-MESSAGE WRITING
-
-used only for client and menu
-severs uses VM_SV_...
-
-Write*(* data, float type, float to)
-
-===============================================================================
-*/
-
-#define        MSG_BROADCAST   0               // unreliable to all
-#define        MSG_ONE                 1               // reliable to one (msg_entity)
-#define        MSG_ALL                 2               // reliable to all
-#define        MSG_INIT                3               // write to the init string
-
-sizebuf_t *VM_WriteDest (void)
-{
-       int             dest;
-       int             destclient;
-
-       if(!sv.active)
-               PRVM_ERROR("VM_WriteDest: game is not server (%s)\n", PRVM_NAME);
-
-       dest = G_FLOAT(OFS_PARM1);
-       switch (dest)
-       {
-       case MSG_BROADCAST:
-               return &sv.datagram;
-
-       case MSG_ONE:
-               destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
-               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
-                       PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
-
-               return &svs.clients[destclient].message;
-
-       case MSG_ALL:
-               return &sv.reliable_datagram;
-
-       case MSG_INIT:
-               return &sv.signon;
-
-       default:
-               PRVM_ERROR ("WriteDest: bad destination");
-               break;
-       }
-
-       return NULL;
-}
-
-void VM_WriteByte (void)
-{
-       MSG_WriteByte (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
-}
-
-void VM_WriteChar (void)
-{
-       MSG_WriteChar (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
-}
-
-void VM_WriteShort (void)
-{
-       MSG_WriteShort (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
-}
-
-void VM_WriteLong (void)
-{
-       MSG_WriteLong (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
-}
-
-void VM_WriteAngle (void)
-{
-       MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
-}
-
-void VM_WriteCoord (void)
-{
-       MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
-}
-
-void VM_WriteString (void)
-{
-       MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
-}
-
-void VM_WriteEntity (void)
-{
-       MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
-}
-
 //=============================================================================
 
 /*
@@ -1490,10 +1354,10 @@ setcolor(clientent, value)
 {
        client_t *client;
        int entnum, i;
-       eval_t *val;
+       prvm_eval_t *val;
 
-       entnum = G_EDICTNUM(OFS_PARM0);
-       i = G_FLOAT(OFS_PARM1);
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+       i = PRVM_G_FLOAT(OFS_PARM1);
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
@@ -1502,11 +1366,11 @@ setcolor(clientent, value)
        }
 
        client = svs.clients + entnum-1;
-       if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
+       if ((val = PRVM_GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
                val->_float = i;
        client->colors = i;
        client->old_colors = i;
-       client->edict->v->team = (i & 15) + 1;
+       client->edict->fields.server->team = (i & 15) + 1;
 
        MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
        MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
@@ -1589,16 +1453,7 @@ void VM_fopen(void)
                return;
        }
        filename = PRVM_G_STRING(OFS_PARM0);
-       // .. is parent directory on many platforms
-       // / is parent directory on Amiga
-       // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
-       // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
-       if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
-       {
-               Con_Printf("VM_fopen: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
-               PRVM_G_FLOAT(OFS_RETURN) = -4;
-               return;
-       }
+
        VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false, false);
        if (VM_FILES[filenum] == NULL && mode == 0)
                VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false, false);
@@ -1887,50 +1742,38 @@ VM_tokenize
 float tokenize(string s)
 =========
 */
-//float(string s) tokenize = #441;
-// takes apart a string into individal words (access them with argv), returns how many
-// this function originally written by KrimZon, made shorter by LordHavoc
-static char **tokens = NULL;
-static int    max_tokens, num_tokens = 0;
+//float(string s) tokenize = #441; // takes apart a string into individal words (access them with argv), returns how many
+//this function originally written by KrimZon, made shorter by LordHavoc
+//20040203: rewritten by LordHavoc (no longer uses allocations)
+int num_tokens = 0;
+char *tokens[256], tokenbuf[4096];
 void VM_tokenize (void)
 {
-       const char *p, *str;
+       int pos;
+       const char *p;
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
-       str = PRVM_G_STRING(OFS_PARM0);
-
-       if (tokens != NULL)
-       {
-               int i;
-               for (i=0;i<num_tokens;i++)
-                       Z_Free(tokens[i]);
-               Z_Free(tokens);
-               num_tokens = 0;
-       }
-
-       tokens = Z_Malloc(strlen(str) * sizeof(char *));
-       max_tokens = strlen(str);
+       p = PRVM_G_STRING(OFS_PARM0);
 
-       for (p = str;COM_ParseToken(&p, false) && num_tokens < max_tokens;num_tokens++)
+       num_tokens = 0;
+       pos = 0;
+       while(COM_ParseToken(&p, false))
        {
-               tokens[num_tokens] = Z_Malloc(strlen(com_token) + 1);
-               strcpy(tokens[num_tokens], com_token);
+               if (num_tokens >= (int)(sizeof(tokens)/sizeof(tokens[0])))
+                       break;
+               if (pos + strlen(com_token) + 1 > sizeof(tokenbuf))
+                       break;
+               tokens[num_tokens++] = tokenbuf + pos;
+               strcpy(tokenbuf + pos, com_token);
+               pos += strlen(com_token) + 1;
        }
 
        PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
 }
 
-/*
-=========
-VM_argv
-
-string argv(float n)
-=========
-*/
-//string(float n) argv = #442;
-// returns a word from the tokenized string (returns nothing for an invalid index)
-// this function originally written by KrimZon, made shorter by LordHavoc
+//string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index)
+//this function originally written by KrimZon, made shorter by LordHavoc
 void VM_argv (void)
 {
        int token_num;
@@ -1938,6 +1781,7 @@ void VM_argv (void)
        VM_SAFEPARMCOUNT(1,VM_argv);
 
        token_num = PRVM_G_FLOAT(OFS_PARM0);
+
        if (token_num >= 0 && token_num < num_tokens)
                PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tokens[token_num]);
        else
@@ -1948,43 +1792,43 @@ void VM_argv (void)
 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
 void PF_setattachment (void)
 {
-       edict_t *e = G_EDICT(OFS_PARM0);
-       edict_t *tagentity = G_EDICT(OFS_PARM1);
-       char *tagname = G_STRING(OFS_PARM2);
-       eval_t *v;
+       prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
+       prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
+       char *tagname = PRVM_G_STRING(OFS_PARM2);
+       prvm_eval_t *v;
        int i, modelindex;
        model_t *model;
 
        if (tagentity == NULL)
-               tagentity = sv.edicts;
+               tagentity = prog->edicts;
 
-       v = GETEDICTFIELDVALUE(e, eval_tag_entity);
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_entity);
        if (v)
-               v->edict = EDICT_TO_PROG(tagentity);
+               fields.server->edict = PRVM_EDICT_TO_PROG(tagentity);
 
-       v = GETEDICTFIELDVALUE(e, eval_tag_index);
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_index);
        if (v)
-               v->_float = 0;
-       if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0])
+               fields.server->_float = 0;
+       if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
        {
-               modelindex = (int)tagentity->v->modelindex;
+               modelindex = (int)tagentity->fields.server->modelindex;
                if (modelindex >= 0 && modelindex < MAX_MODELS)
                {
                        model = sv.models[modelindex];
-                       if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames)
-                               for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
-                                       if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
-                                               v->_float = i + 1;
+                       if (model->data_overridetagnamesforskin && (unsigned int)tagentity->fields.server->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->fields.server->skin].num_overridetagnames)
+                               for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->fields.server->skin].num_overridetagnames;i++)
+                                       if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->fields.server->skin].data_overridetagnames[i].name))
+                                               fields.server->_float = i + 1;
                        // FIXME: use a model function to get tag info (need to handle skeletal)
-                       if (v->_float == 0 && model->num_tags)
+                       if (fields.server->_float == 0 && model->num_tags)
                                for (i = 0;i < model->num_tags;i++)
                                        if (!strcmp(tagname, model->data_tags[i].name))
-                                               v->_float = i + 1;
-                       if (v->_float == 0)
-                               Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name);
+                                               fields.server->_float = i + 1;
+                       if (fields.server->_float == 0)
+                               Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
                }
                else
-                       Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity));
+                       Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
        }
 }*/
 
index be993f425c71c5a1f439caf7b1c5159b12c87a55..ef95c4f25c7f1aeb68a3e86722bcc266057e37a2 100644 (file)
@@ -187,12 +187,15 @@ float     getserverlistindexforkey(string key)
 #define VM_SAFEPARMCOUNT(p,f)
 #endif
 
-#define        VM_RETURN_EDICT(e)              (((int *)prog->globals)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
+#define        VM_RETURN_EDICT(e)              (((int *)prog->globals.generic)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
 
-#define e10 0,0,0,0,0,0,0,0,0,0
+#define e10 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
 #define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
 #define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
 
+#define VM_STRINGTEMP_BUFFERS 16
+#define VM_STRINGTEMP_LENGTH 4096
+
 // builtins and other general functions
 
 char *VM_GetTempString(void);
index 53f7e5d23e3d29b4c05634b3f95e0f934a0c61bc..ea7c7f3991dc442386a0c72d02d52e4d02cb55e3 100644 (file)
@@ -36,9 +36,6 @@ cvar_t        prvm_boundscheck = {0, "prvm_boundscheck", "1"};
 // LordHavoc: prints every opcode as it executes - warning: this is significant spew
 cvar_t prvm_traceqc = {0, "prvm_traceqc", "0"};
 
-ddef_t *PRVM_ED_FindField (const char *name);
-mfunction_t *PRVM_ED_FindFunction (const char *name);
-
 //============================================================================
 // mempool handling
 
@@ -47,14 +44,14 @@ mfunction_t *PRVM_ED_FindFunction (const char *name);
 PRVM_MEM_Alloc
 ===============
 */
-void PRVM_MEM_Alloc()
+void PRVM_MEM_Alloc(void)
 {
        int i;
 
        // reserve space for the null entity aka world
        // check bound of max_edicts
-       prog->max_edicts = bound(1, prog->max_edicts, prog->limit_edicts);
-       prog->num_edicts = bound(1, prog->num_edicts, prog->max_edicts);
+       prog->max_edicts = bound(1 + prog->reserved_edicts, prog->max_edicts, prog->limit_edicts);
+       prog->num_edicts = bound(1 + prog->reserved_edicts, prog->num_edicts, prog->max_edicts);
 
        // edictprivate_size has to be min as big prvm_edict_private_t
        prog->edictprivate_size = max(prog->edictprivate_size,(int)sizeof(prvm_edict_private_t));
@@ -81,7 +78,7 @@ void PRVM_MEM_Alloc()
 PRVM_MEM_IncreaseEdicts
 ===============
 */
-void PRVM_MEM_IncreaseEdicts()
+void PRVM_MEM_IncreaseEdicts(void)
 {
        int             i;
        int             oldmaxedicts = prog->max_edicts;
@@ -170,12 +167,12 @@ PRVM_SetProg
 */
 void PRVM_SetProg(int prognr)
 {
-       if(prognr && prognr < PRVM_MAXPROGS)
+       if(0 <= prognr && prognr < PRVM_MAXPROGS)
        {
                if(prog_list[prognr].loaded)
                        prog = &prog_list[prognr];
                else
-                       PRVM_ERROR("%i(%s) not loaded !\n", prognr, PRVM_NAME);
+                       PRVM_ERROR("%i not loaded !\n", prognr);
                return;
        }
        PRVM_ERROR("Invalid program number %i\n", prognr);
@@ -193,11 +190,9 @@ void PRVM_ED_ClearEdict (prvm_edict_t *e)
        int num;
        memset (e->fields.vp, 0, prog->progs->entityfields * 4);
        e->priv.required->free = false;
-       // LordHavoc: for consistency set these here
-       num = PRVM_NUM_FOR_EDICT(e) - 1;
 
        // AK: Let the init_edict function determine if something needs to be initialized
-       PRVM_GCALL(init_edict)(num);
+       PRVM_GCALL(init_edict)(e);
 }
 
 /*
@@ -221,7 +216,7 @@ prvm_edict_t *PRVM_ED_Alloc (void)
        // AK:  changed i=svs.maxclients+1
        // AK:  changed so the edict 0 wont spawn -> used as reserved/world entity
        //              although the menu/client has no world
-       for (i = 1;i < prog->num_edicts;i++)
+       for (i = prog->reserved_edicts + 1;i < prog->num_edicts;i++)
        {
                e = PRVM_EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
@@ -233,7 +228,7 @@ prvm_edict_t *PRVM_ED_Alloc (void)
                }
        }
 
-       if (i == MAX_EDICTS)
+       if (i == prog->limit_edicts)
                PRVM_ERROR ("%s: PRVM_ED_Alloc: no free edicts",PRVM_NAME);
 
        prog->num_edicts++;
@@ -256,8 +251,8 @@ FIXME: walk all entities and NULL out references to this entity
 */
 void PRVM_ED_Free (prvm_edict_t *ed)
 {
-       // dont delete the null entity (world)
-       if(PRVM_NUM_FOR_EDICT(ed) == 0)
+       // dont delete the null entity (world) or reserved edicts
+       if(PRVM_NUM_FOR_EDICT(ed) <= prog->reserved_edicts )
                return;
 
        PRVM_GCALL(free_edict)(ed);
@@ -388,7 +383,7 @@ char *PRVM_ValueString (etype_t type, prvm_eval_t *val)
                break;
        case ev_entity:
                n = val->edict;
-               if (n < 0 || n >= MAX_EDICTS)
+               if (n < 0 || n >= prog->limit_edicts)
                        sprintf (line, "entity %i (invalid!)", n);
                else
                        sprintf (line, "entity %i", n);
@@ -470,7 +465,7 @@ char *PRVM_UglyValueString (etype_t type, prvm_eval_t *val)
                dpsnprintf (line, sizeof (line), "%i", PRVM_NUM_FOR_EDICT(PRVM_PROG_TO_EDICT(val->edict)));
                break;
        case ev_function:
-               f = pr_functions + val->function;
+               f = prog->functions + val->function;
                strlcpy (line, PRVM_GetString (f->s_name), sizeof (line));
                break;
        case ev_field:
@@ -510,7 +505,7 @@ char *PRVM_GlobalString (int ofs)
        void    *val;
        static char     line[128];
 
-       val = (void *)&prog->globals[ofs];
+       val = (void *)&prog->globals.generic[ofs];
        def = PRVM_ED_GlobalAtOfs(ofs);
        if (!def)
                sprintf (line,"%i(?)", ofs);
@@ -819,7 +814,7 @@ void PRVM_ED_WriteGlobals (qfile_t *f)
 
                name = PRVM_GetString(def->s_name);
                FS_Printf(f,"\"%s\" ", name);
-               FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals[def->ofs]));
+               FS_Printf(f,"\"%s\"\n", PRVM_UglyValueString(type, (prvm_eval_t *)&prog->globals.generic[def->ofs]));
        }
        FS_Print(f,"}\n");
 }
@@ -885,7 +880,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
        if (ent)
                val = (prvm_eval_t *)((int *)ent->fields.vp + key->ofs);
        else
-               val = (prvm_eval_t *)((int *)prog->globals + key->ofs);
+               val = (prvm_eval_t *)((int *)prog->globals.generic + key->ofs);
        switch (key->type & ~DEF_SAVEGLOBAL)
        {
        case ev_string:
@@ -934,7 +929,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
                while (*s && *s <= ' ')
                        s++;
                i = atoi(s);
-               if (i < 0 || i >= MAX_EDICTS)
+               if (i < 0 || i >= prog->limit_edicts)
                        Con_Printf("PRVM_ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i) on %s\n", i, MAX_EDICTS, PRVM_NAME);
                while (i >= prog->max_edicts)
                        PRVM_MEM_IncreaseEdicts();
@@ -942,7 +937,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
                // if SV_IncreaseEdicts was called the base pointer needs to be updated
                if (ent)
                        val = (prvm_eval_t *)((int *)ent->fields.vp + key->ofs);
-               val->edict = PRVM_EDICT_TO_PROG(EDICT_NUM(i));
+               val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(i));
                break;
 
        case ev_field:
@@ -966,7 +961,7 @@ qboolean PRVM_ED_ParseEpair(prvm_edict_t *ent, ddef_t *key, const char *s)
                break;
 
        default:
-               Con_Printf("PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PR_GetString(key->s_name), PRVM_NAME);
+               Con_Printf("PRVM_ED_ParseEpair: Unknown key->type %i for key \"%s\" on %s\n", key->type, PRVM_GetString(key->s_name), PRVM_NAME);
                return false;
        }
        return true;
@@ -1134,9 +1129,12 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (com_token[0] != '{')
                        PRVM_ERROR ("PRVM_ED_LoadFromFile: %s: found %s when expecting {", PRVM_NAME, com_token);
 
-               // CHANGED: this is not conform to ED_LoadFromFile
-               if(!prog->num_edicts)
+               // CHANGED: this is not conform to PR_LoadFromFile
+               if(prog->loadintoworld)
+               {
+                       prog->loadintoworld = false;
                        ent = PRVM_EDICT_NUM(0);
+               }
                else
                        ent = PRVM_ED_Alloc();
 
@@ -1160,7 +1158,7 @@ void PRVM_ED_LoadFromFile (const char *data)
 //
                if(prog->self && prog->flag & PRVM_FE_CLASSNAME)
                {
-                       string_t handle =  *(string_t*)&((float*)ent->fields.vp)[PRVM_ED_FindFieldOffset("classname")];
+                       string_t handle =  *(string_t*)&((qbyte*)ent->fields.vp)[PRVM_ED_FindFieldOffset("classname")];
                        if (!handle)
                        {
                                Con_Print("No classname for:\n");
@@ -1230,7 +1228,7 @@ void PRVM_ResetProg()
 PRVM_LoadProgs
 ===============
 */
-void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required_func)
+void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required_func, int numrequiredfields, prvm_required_field_t *required_field)
 {
        int i;
        dstatement_t *st;
@@ -1243,7 +1241,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
 
        Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, fs_filesize/1024);
 
-       pr_crc = CRC_Block((qbyte *)prog->progs, fs_filesize);
+       prog->filecrc = CRC_Block((qbyte *)prog->progs, fs_filesize);
 
 // byte swap the header
        for (i = 0;i < (int) sizeof(*prog->progs) / 4;i++)
@@ -1251,10 +1249,10 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
 
        if (prog->progs->version != PROG_VERSION)
                PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs->version, PROG_VERSION);
-       if (prog->progs->crc != prog->crc)
+       if (prog->progs->crc != prog->headercrc)
                PRVM_ERROR ("%s: %s system vars have been modified, progdefs.h is out of date", PRVM_NAME, filename);
 
-       //pr_functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
+       //prog->functions = (dfunction_t *)((qbyte *)progs + progs->ofs_functions);
        dfunctions = (dfunction_t *)((qbyte *)prog->progs + prog->progs->ofs_functions);
 
        prog->strings = (char *)prog->progs + prog->progs->ofs_strings;
@@ -1275,14 +1273,14 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
        // so allocate a new place for it
        infielddefs = (ddef_t *)((qbyte *)prog->progs + prog->progs->ofs_fielddefs);
        //                                                                                              ( + DPFIELDS                       )
-       prog->fielddefs = Mem_Alloc(prog->progs_mempool, prog->progs->numfielddefs * sizeof(ddef_t));
+       prog->fielddefs = Mem_Alloc(prog->progs_mempool, (prog->progs->numfielddefs + numrequiredfields) * sizeof(ddef_t));
 
        prog->statements = (dstatement_t *)((qbyte *)prog->progs + prog->progs->ofs_statements);
 
        // moved edict_size calculation down below field adding code
 
        //pr_global_struct = (globalvars_t *)((qbyte *)progs + progs->ofs_globals);
-       prog->globals = (float *)((qbyte *)prog->progs + prog->progs->ofs_globals);
+       prog->globals.generic = (float *)((qbyte *)prog->progs + prog->progs->ofs_globals);
 
 // byte swap the lumps
        for (i=0 ; i<prog->progs->numstatements ; i++)
@@ -1322,18 +1320,18 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                prog->fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
        }
 
-/*     // append the darkplaces fields
-       for (i = 0;i < (int) DPFIELDS;i++)
+       // append the required fields
+       for (i = 0;i < (int) numrequiredfields;i++)
        {
-               pr_fielddefs[progs->numfielddefs].type = dpfields[i].type;
-               pr_fielddefs[progs->numfielddefs].ofs = progs->entityfields;
-               pr_fielddefs[progs->numfielddefs].s_name = PR_SetEngineString(dpfields[i].string);
-               if (pr_fielddefs[progs->numfielddefs].type == ev_vector)
-                       progs->entityfields += 3;
+               prog->fielddefs[prog->progs->numfielddefs].type = required_field[i].type;
+               prog->fielddefs[prog->progs->numfielddefs].ofs = prog->progs->entityfields;
+               prog->fielddefs[prog->progs->numfielddefs].s_name = PRVM_SetEngineString(required_field[i].name);
+               if (prog->fielddefs[prog->progs->numfielddefs].type == ev_vector)
+                       prog->progs->entityfields += 3;
                else
-                       progs->entityfields++;
-               progs->numfielddefs++;
-       }*/
+                       prog->progs->entityfields++;
+               prog->progs->numfielddefs++;
+       }
 
        // check required functions
        for(i=0 ; i < numrequiredfunc ; i++)
@@ -1341,12 +1339,12 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, char **required
                        PRVM_ERROR("%s: %s not found in %s\n",PRVM_NAME, required_func[i], filename);
 
        for (i=0 ; i<prog->progs->numglobals ; i++)
-               ((int *)prog->globals)[i] = LittleLong (((int *)prog->globals)[i]);
+               ((int *)prog->globals.generic)[i] = LittleLong (((int *)prog->globals.generic)[i]);
 
        // moved edict_size calculation down here, below field adding code
-       // LordHavoc: this no longer includes the edict_t header
+       // LordHavoc: this no longer includes the prvm_edict_t header
        prog->edict_size = prog->progs->entityfields * 4;
-       prog->edictareasize = prog->edict_size * MAX_EDICTS;
+       prog->edictareasize = prog->edict_size * prog->limit_edicts;
 
        // LordHavoc: bounds check anything static
        for (i = 0,st = prog->statements;i < prog->progs->numstatements;i++,st++)
@@ -1649,7 +1647,7 @@ void PRVM_Global_f(void)
        if( !global )
                Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
        else
-               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( global->type, (prvm_eval_t *) &prog->globals[ global->ofs ] ) );
+               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( global->type, (prvm_eval_t *) &prog->globals.generic[ global->ofs ] ) );
        PRVM_End;
 }
 
@@ -1758,43 +1756,43 @@ void PRVM_ProcessError(void)
 }
 
 /*
-int NUM_FOR_EDICT_ERROR(edict_t *e)
+int NUM_FOR_EDICT_ERROR(prvm_edict_t *e)
 {
-       Host_Error ("NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, sv.edicts, e - sv.edicts);
+       Host_Error ("PRVM_NUM_FOR_EDICT: bad pointer %p (world is %p, entity number would be %i)", e, prog->edicts, e - prog->edicts);
        return 0;
 }
 
-int NUM_FOR_EDICT(edict_t *e)
+int PRVM_NUM_FOR_EDICT(prvm_edict_t *e)
 {
        int n;
-       n = e - sv.edicts;
-       if ((unsigned int)n >= MAX_EDICTS)
-               Host_Error ("NUM_FOR_EDICT: bad pointer");
+       n = e - prog->edicts;
+       if ((unsigned int)n >= prog->limit_edicts)
+               Host_Error ("PRVM_NUM_FOR_EDICT: bad pointer");
        return n;
 }
 
-//int NoCrash_NUM_FOR_EDICT(edict_t *e)
+//int NoCrash_NUM_FOR_EDICT(prvm_edict_t *e)
 //{
-//     return e - sv.edicts;
+//     return e - prog->edicts;
 //}
 
-//#define      EDICT_TO_PROG(e) ((qbyte *)(((edict_t *)e)->v) - (qbyte *)(sv.edictsfields))
-//#define PROG_TO_EDICT(e) (sv.edicts + ((e) / (progs->entityfields * 4)))
-int EDICT_TO_PROG(edict_t *e)
+//#define      PRVM_EDICT_TO_PROG(e) ((qbyte *)(((prvm_edict_t *)e)->v) - (qbyte *)(prog->edictsfields))
+//#define PRVM_PROG_TO_EDICT(e) (prog->edicts + ((e) / (progs->entityfields * 4)))
+int PRVM_EDICT_TO_PROG(prvm_edict_t *e)
 {
        int n;
-       n = e - sv.edicts;
-       if ((unsigned int)n >= (unsigned int)sv.max_edicts)
-               Host_Error("EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, sv.edicts);
+       n = e - prog->edicts;
+       if ((unsigned int)n >= (unsigned int)prog->max_edicts)
+               Host_Error("PRVM_EDICT_TO_PROG: invalid edict %8p (number %i compared to world at %8p)\n", e, n, prog->edicts);
        return n;// EXPERIMENTAL
-       //return (qbyte *)e->v - (qbyte *)sv.edictsfields;
+       //return (qbyte *)e->v - (qbyte *)prog->edictsfields;
 }
-edict_t *PROG_TO_EDICT(int n)
+prvm_edict_t *PRVM_PROG_TO_EDICT(int n)
 {
-       if ((unsigned int)n >= (unsigned int)sv.max_edicts)
-               Host_Error("PROG_TO_EDICT: invalid edict number %i\n", n);
-       return sv.edicts + n; // EXPERIMENTAL
-       //return sv.edicts + ((n) / (progs->entityfields * 4));
+       if ((unsigned int)n >= (unsigned int)prog->max_edicts)
+               Host_Error("PRVM_PROG_TO_EDICT: invalid edict number %i\n", n);
+       return prog->edicts + n; // EXPERIMENTAL
+       //return prog->edicts + ((n) / (progs->entityfields * 4));
 }
 */
 
index 428a1586af58e269fa2e7725aaa1db12c7f8786f..4314b1fa951cec7c18454aabcc1d90dcf467e7e1 100644 (file)
@@ -265,6 +265,8 @@ void PRVM_PrintState(void)
 
 void PRVM_Crash()
 {
+
+       //TODO: make this more compilant with PR_Crash
        if (prog->depth < 1)
        {
                // kill the stack just to be sure
@@ -316,7 +318,7 @@ int PRVM_EnterFunction (mfunction_t *f)
                PRVM_ERROR ("PRVM_ExecuteProgram: locals stack overflow in %s\n", PRVM_NAME);
 
        for (i=0 ; i < c ; i++)
-               prog->localstack[prog->localstack_used+i] = ((int *)prog->globals)[f->parm_start + i];
+               prog->localstack[prog->localstack_used+i] = ((int *)prog->globals.generic)[f->parm_start + i];
        prog->localstack_used += c;
 
 // copy parameters
@@ -325,7 +327,7 @@ int PRVM_EnterFunction (mfunction_t *f)
        {
                for (j=0 ; j<f->parm_size[i] ; j++)
                {
-                       ((int *)prog->globals)[o] = ((int *)prog->globals)[OFS_PARM0+i*3+j];
+                       ((int *)prog->globals.generic)[o] = ((int *)prog->globals.generic)[OFS_PARM0+i*3+j];
                        o++;
                }
        }
@@ -355,7 +357,7 @@ int PRVM_LeaveFunction (void)
                PRVM_ERROR ("PRVM_ExecuteProgram: locals stack underflow in %s\n", PRVM_NAME);
 
        for (i=0 ; i < c ; i++)
-               ((int *)prog->globals)[prog->xfunction->parm_start + i] = prog->localstack[prog->localstack_used+i];
+               ((int *)prog->globals.generic)[prog->xfunction->parm_start + i] = prog->localstack[prog->localstack_used+i];
 
 // up stack
        prog->depth--;
@@ -378,9 +380,9 @@ PRVM_ExecuteProgram
 ====================
 */
 // LordHavoc: optimized
-#define OPA ((prvm_eval_t *)&prog->globals[(unsigned short) st->a])
-#define OPB ((prvm_eval_t *)&prog->globals[(unsigned short) st->b])
-#define OPC ((prvm_eval_t *)&prog->globals[(unsigned short) st->c])
+#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a])
+#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b])
+#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c])
 extern cvar_t prvm_boundscheck;
 extern cvar_t prvm_traceqc;
 extern int             PRVM_ED_FindFieldOffset (const char *field);
@@ -397,7 +399,7 @@ void PRVM_ExecuteProgram (func_t fnum, const char *errormessage)
        {
                if (prog->self && PRVM_G_INT(prog->self->ofs))
                        PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs)));
-               PRVM_ERROR ("PR_ExecuteProgram: %s", errormessage);
+               PRVM_ERROR ("PRVM_ExecuteProgram: %s", errormessage);
        }
 
        f = &prog->functions[fnum];
index d1474939fa926a2efe593bd3df2c7dcb51ae2908..07ca7a16b5de532ab2de95355ef743b053e7a434 100644 (file)
                                startprofile = profile;
                                prog->xstatement = st - prog->statements;
 
-                               prog->globals[OFS_RETURN] = prog->globals[(unsigned short) st->a];
-                               prog->globals[OFS_RETURN+1] = prog->globals[(unsigned short) st->a+1];
-                               prog->globals[OFS_RETURN+2] = prog->globals[(unsigned short) st->a+2];
+                               prog->globals.generic[OFS_RETURN] = prog->globals.generic[(unsigned short) st->a];
+                               prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(unsigned short) st->a+1];
+                               prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(unsigned short) st->a+2];
 
                                st = prog->statements + PRVM_LeaveFunction();
                                if (prog->depth <= exitdepth)
                                        startprofile = profile;
                                        prog->xstatement = st - prog->statements;
                                        ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs));
-                                       PRVM_E_FLOAT(ed,PRVM_ED_FindFieldOffset ("nextthink")) = *prog->time + 0.1;
-                                       PRVM_E_FLOAT(ed,PRVM_ED_FindFieldOffset ("frame")) = OPA->_float;
-                                       *(func_t *)((qbyte*)ed->fields.vp + PRVM_ED_FindFieldOffset ("think")) = OPB->function;
+                                       PRVM_E_FLOAT(ed,PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1;
+                                       PRVM_E_FLOAT(ed,PRVM_ED_FindField ("frame")->ofs) = OPA->_float;
+                                       *(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function;
                                }
                                else
                                        PRVM_ERROR("OP_STATE not supported by %s\n", PRVM_NAME);
                                        return;
                                }
 #endif
-                               ptr = (eval_t *)((qbyte *)sv.edictsfields + OPB->_int);
+                               ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
                                ptr->_int = OPA->_int;
                                break;
                        case OP_LOAD_I:
                                        return;
                                }
 #endif
-                               ed = PROG_TO_EDICT(OPA->edict);
-                               OPC->_int = ((eval_t *)((int *)ed->v + OPB->_int))->_int;
+                               ed = PRVM_PROG_TO_EDICT(OPA->edict);
+                               OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
                                break;
 
                        case OP_GSTOREP_I:
index 0417274c9002b9d850184820c2ca644c4ad7f55d..041280dbe7642d62d62a887210388ae482f1b0f0 100644 (file)
@@ -205,6 +205,7 @@ extern char *buildstring;
 #include "client.h"
 #include "render.h"
 #include "progs.h"
+#include "progsvm.h"
 #include "server.h"
 
 #include "input.h"
index 51e5d6b2a4991ff7a43792d41e18a1708406b8d1..ca02186f59510cf8d2ccf807a552b298a9ddb002 100644 (file)
--- a/server.h
+++ b/server.h
@@ -76,20 +76,9 @@ typedef struct
        // updated by SV_SoundIndex
        char sound_precache[MAX_SOUNDS][MAX_QPATH];
        char lightstyles[MAX_LIGHTSTYLES][64];
-       int num_edicts;
-       int max_edicts;
-       // small edict_t structures which just contain pointers
-       // (allocated at server startup only)
-       edict_t *edicts;
-       // engine private edict information
-       // (dynamically resized - always access through edict_t!)
-       edict_engineprivate_t *edictsengineprivate;
-       // QuakeC fields array
-       // (dynamically resized - always access through edict_t!)
-       void *edictsfields;
        // PushMove sometimes has to move entities back from a failed move
        // (dynamically resized)
-       edict_t **moved_edicts;
+       prvm_edict_t **moved_edicts;
        // some actions are only valid during load
        server_state_t state;
 
@@ -143,8 +132,8 @@ typedef struct client_s
        // can be added to at any time, copied and clear once per frame
        sizebuf_t message;
        qbyte msgbuf[NET_MAXMESSAGE];
-       // EDICT_NUM(clientnum+1)
-       edict_t *edict;
+       // PRVM_EDICT_NUM(clientnum+1)
+       prvm_edict_t *edict;
 
        float ping_times[NUM_PING_TIMES];
        // ping_times[num_pings%NUM_PING_TIMES]
@@ -296,7 +285,7 @@ void SV_Init (void);
 
 void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
 void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate);
-void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, float attenuation);
+void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation);
 
 void SV_ConnectClient (int clientnum, netconn_t *netconnection);
 void SV_DropClient (qboolean crash);
@@ -326,11 +315,11 @@ void SV_BroadcastPrintf(const char *fmt, ...);
 
 void SV_Physics (void);
 
-qboolean SV_PlayerCheckGround (edict_t *ent);
-qboolean SV_CheckBottom (edict_t *ent);
-qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
+qboolean SV_PlayerCheckGround (prvm_edict_t *ent);
+qboolean SV_CheckBottom (prvm_edict_t *ent);
+qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink);
 
-void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg, int *stats);
+void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
 
 void SV_MoveToGoal (void);
 
@@ -338,7 +327,12 @@ void SV_ApplyClientMove (void);
 void SV_SaveSpawnparms (void);
 void SV_SpawnServer (const char *server);
 
-void SV_CheckVelocity (edict_t *ent);
+void SV_CheckVelocity (prvm_edict_t *ent);
+
+void SV_SetupVM(void);
+
+void SV_VM_Begin(void);
+void SV_VM_End(void);
 
 #endif
 
index 88c7acaff8a8ff1b0fe53f3a932fa88d02a3f052..ff2bfe56b94952eaad508740efb91192f0b06d52 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -21,6 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
+void SV_VM_Init();
+void SV_VM_Setup();
+
 // select which protocol to host, this is fed to Protocol_EnumForName
 cvar_t sv_protocolname = {0, "sv_protocolname", "DP6"};
 cvar_t sv_ratelimitlocalplayer = {0, "sv_ratelimitlocalplayer", "0"};
@@ -91,6 +94,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_maxrate);
        Cvar_RegisterVariable (&sv_progs);
 
+       SV_VM_Init();
        SV_Phys_Init();
        SV_World_Init();
 
@@ -200,7 +204,7 @@ Larger attenuations will drop off.  (max 4 attenuation)
 
 ==================
 */
-void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, float attenuation)
+void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation)
 {
        int sound_num, field_mask, i, ent;
 
@@ -221,7 +225,7 @@ void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume
        if (!sound_num)
                return;
 
-       ent = NUM_FOR_EDICT(entity);
+       ent = PRVM_NUM_FOR_EDICT(entity);
 
        field_mask = 0;
        if (volume != DEFAULT_SOUND_PACKET_VOLUME)
@@ -252,7 +256,7 @@ void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume
        else
                MSG_WriteByte (&sv.datagram, sound_num);
        for (i = 0;i < 3;i++)
-               MSG_WriteCoord (&sv.datagram, entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]), sv.protocol);
+               MSG_WriteCoord (&sv.datagram, entity->fields.server->origin[i]+0.5*(entity->fields.server->mins[i]+entity->fields.server->maxs[i]), sv.protocol);
 }
 
 /*
@@ -277,25 +281,25 @@ void SV_SendServerinfo (client_t *client)
        char message[128];
 
        // edicts get reallocated on level changes, so we need to update it here
-       client->edict = EDICT_NUM((client - svs.clients) + 1);
+       client->edict = PRVM_EDICT_NUM((client - svs.clients) + 1);
 
        // if client is a botclient coming from a level change, we need to set up
        // client info that normally requires networking
        if (!client->netconnection)
        {
                // set up the edict
-               ED_ClearEdict(client->edict);
+                PRVM_ED_ClearEdict(client->edict);
 
                // copy spawn parms out of the client_t
                for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
-                       (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
+                       (&prog->globals.server->parm1)[i] = host_client->spawn_parms[i];
 
                // call the spawn function
                host_client->clientconnectcalled = true;
-               pr_global_struct->time = sv.time;
-               pr_global_struct->self = EDICT_TO_PROG(client->edict);
-               PR_ExecuteProgram (pr_global_struct->ClientConnect, "QC function ClientConnect is missing");
-               PR_ExecuteProgram (pr_global_struct->PutClientInServer, "QC function PutClientInServer is missing");
+               prog->globals.server->time = sv.time;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(client->edict);
+               PRVM_ExecuteProgram (prog->globals.server->ClientConnect, "QC function ClientConnect is missing");
+               PRVM_ExecuteProgram (prog->globals.server->PutClientInServer, "QC function PutClientInServer is missing");
                host_client->spawned = true;
                return;
        }
@@ -322,7 +326,7 @@ void SV_SendServerinfo (client_t *client)
 
        SZ_Clear (&client->message);
        MSG_WriteByte (&client->message, svc_print);
-       dpsnprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, pr_crc);
+       dpsnprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, prog->filecrc);
        MSG_WriteString (&client->message,message);
 
        MSG_WriteByte (&client->message, svc_serverinfo);
@@ -334,7 +338,7 @@ void SV_SendServerinfo (client_t *client)
        else
                MSG_WriteByte (&client->message, GAME_COOP);
 
-       MSG_WriteString (&client->message,PR_GetString(sv.edicts->v->message));
+       MSG_WriteString (&client->message,PRVM_GetString(prog->edicts->fields.server->message));
 
        for (i = 1;i < MAX_MODELS && sv.model_precache[i][0];i++)
                MSG_WriteString (&client->message, sv.model_precache[i]);
@@ -346,12 +350,12 @@ void SV_SendServerinfo (client_t *client)
 
 // send music
        MSG_WriteByte (&client->message, svc_cdtrack);
-       MSG_WriteByte (&client->message, sv.edicts->v->sounds);
-       MSG_WriteByte (&client->message, sv.edicts->v->sounds);
+       MSG_WriteByte (&client->message, prog->edicts->fields.server->sounds);
+       MSG_WriteByte (&client->message, prog->edicts->fields.server->sounds);
 
 // set view
        MSG_WriteByte (&client->message, svc_setview);
-       MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
+       MSG_WriteShort (&client->message, PRVM_NUM_FOR_EDICT(client->edict));
 
        MSG_WriteByte (&client->message, svc_signonnum);
        MSG_WriteByte (&client->message, 1);
@@ -388,7 +392,7 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
        strcpy(client->name, "unconnected");
        strcpy(client->old_name, "unconnected");
        client->spawned = false;
-       client->edict = EDICT_NUM(clientnum+1);
+       client->edict = PRVM_EDICT_NUM(clientnum+1);
        client->message.data = client->msgbuf;
        client->message.maxsize = sizeof(client->msgbuf);
        client->message.allowoverflow = true;           // we can catch it
@@ -404,9 +408,9 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
        else
        {
                // call the progs to get default spawn parms for the new client
-               PR_ExecuteProgram (pr_global_struct->SetNewParms, "QC function SetNewParms is missing");
+               PRVM_ExecuteProgram (prog->globals.server->SetNewParms, "QC function SetNewParms is missing");
                for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
-                       client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
+                       client->spawn_parms[i] = (&prog->globals.server->parm1)[i];
        }
 
        // don't call SendServerinfo for a fresh botclient because its fields have
@@ -459,42 +463,42 @@ void SV_PrepareEntitiesForSending(void)
 {
        int e, i;
        float f;
-       edict_t *ent;
-       eval_t *val;
+       prvm_edict_t *ent;
+       prvm_eval_t *val;
        entity_state_t cs;
        // send all entities that touch the pvs
        numsendentities = 0;
        sendentitiesindex[0] = NULL;
-       for (e = 1, ent = NEXT_EDICT(sv.edicts);e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
+       for (e = 1, ent = PRVM_NEXT_EDICT(prog->edicts);e < prog->num_edicts;e++, ent = PRVM_NEXT_EDICT(ent))
        {
                sendentitiesindex[e] = NULL;
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        continue;
 
                cs = defaultstate;
                cs.active = true;
                cs.number = e;
-               VectorCopy(ent->v->origin, cs.origin);
-               VectorCopy(ent->v->angles, cs.angles);
+               VectorCopy(ent->fields.server->origin, cs.origin);
+               VectorCopy(ent->fields.server->angles, cs.angles);
                cs.flags = 0;
-               cs.effects = (unsigned)ent->v->effects;
-               cs.colormap = (unsigned)ent->v->colormap;
-               cs.skin = (unsigned)ent->v->skin;
-               cs.frame = (unsigned)ent->v->frame;
-               cs.viewmodelforclient = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)->edict;
-               cs.exteriormodelforclient = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)->edict;
-               cs.nodrawtoclient = GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)->edict;
-               cs.drawonlytoclient = GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)->edict;
-               cs.tagentity = GETEDICTFIELDVALUE(ent, eval_tag_entity)->edict;
-               cs.tagindex = (qbyte)GETEDICTFIELDVALUE(ent, eval_tag_index)->_float;
-               i = (int)(GETEDICTFIELDVALUE(ent, eval_glow_size)->_float * 0.25f);
+               cs.effects = (unsigned)ent->fields.server->effects;
+               cs.colormap = (unsigned)ent->fields.server->colormap;
+               cs.skin = (unsigned)ent->fields.server->skin;
+               cs.frame = (unsigned)ent->fields.server->frame;
+               cs.viewmodelforclient = PRVM_GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)->edict;
+               cs.exteriormodelforclient = PRVM_GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)->edict;
+               cs.nodrawtoclient = PRVM_GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)->edict;
+               cs.drawonlytoclient = PRVM_GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)->edict;
+               cs.tagentity = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)->edict;
+               cs.tagindex = (qbyte)PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index)->_float;
+               i = (int)(PRVM_GETEDICTFIELDVALUE(ent, eval_glow_size)->_float * 0.25f);
                cs.glowsize = (qbyte)bound(0, i, 255);
-               if (GETEDICTFIELDVALUE(ent, eval_glow_trail)->_float)
+               if (PRVM_GETEDICTFIELDVALUE(ent, eval_glow_trail)->_float)
                        cs.flags |= RENDER_GLOWTRAIL;
 
                // don't need to init cs.colormod because the defaultstate did that for us
                //cs.colormod[0] = cs.colormod[1] = cs.colormod[2] = 32;
-               val = GETEDICTFIELDVALUE(ent, eval_colormod);
+               val = PRVM_GETEDICTFIELDVALUE(ent, eval_colormod);
                if (val->vector[0] || val->vector[1] || val->vector[2])
                {
                        i = val->vector[0] * 32.0f;cs.colormod[0] = bound(0, i, 255);
@@ -503,19 +507,19 @@ void SV_PrepareEntitiesForSending(void)
                }
 
                cs.modelindex = 0;
-               i = (int)ent->v->modelindex;
-               if (i >= 1 && i < MAX_MODELS && *PR_GetString(ent->v->model))
+               i = (int)ent->fields.server->modelindex;
+               if (i >= 1 && i < MAX_MODELS && *PRVM_GetString(ent->fields.server->model))
                        cs.modelindex = i;
 
                cs.alpha = 255;
-               f = (GETEDICTFIELDVALUE(ent, eval_alpha)->_float * 255.0f);
+               f = (PRVM_GETEDICTFIELDVALUE(ent, eval_alpha)->_float * 255.0f);
                if (f)
                {
                        i = (int)f;
                        cs.alpha = (qbyte)bound(0, i, 255);
                }
                // halflife
-               f = (GETEDICTFIELDVALUE(ent, eval_renderamt)->_float);
+               f = (PRVM_GETEDICTFIELDVALUE(ent, eval_renderamt)->_float);
                if (f)
                {
                        i = (int)f;
@@ -523,7 +527,7 @@ void SV_PrepareEntitiesForSending(void)
                }
 
                cs.scale = 16;
-               f = (GETEDICTFIELDVALUE(ent, eval_scale)->_float * 16.0f);
+               f = (PRVM_GETEDICTFIELDVALUE(ent, eval_scale)->_float * 16.0f);
                if (f)
                {
                        i = (int)f;
@@ -531,32 +535,32 @@ void SV_PrepareEntitiesForSending(void)
                }
 
                cs.glowcolor = 254;
-               f = (GETEDICTFIELDVALUE(ent, eval_glow_color)->_float);
+               f = (PRVM_GETEDICTFIELDVALUE(ent, eval_glow_color)->_float);
                if (f)
                        cs.glowcolor = (int)f;
 
-               if (GETEDICTFIELDVALUE(ent, eval_fullbright)->_float)
+               if (PRVM_GETEDICTFIELDVALUE(ent, eval_fullbright)->_float)
                        cs.effects |= EF_FULLBRIGHT;
 
-               if (ent->v->movetype == MOVETYPE_STEP)
+               if (ent->fields.server->movetype == MOVETYPE_STEP)
                        cs.flags |= RENDER_STEP;
                if ((cs.effects & EF_LOWPRECISION) && cs.origin[0] >= -32768 && cs.origin[1] >= -32768 && cs.origin[2] >= -32768 && cs.origin[0] <= 32767 && cs.origin[1] <= 32767 && cs.origin[2] <= 32767)
                        cs.flags |= RENDER_LOWPRECISION;
-               if (ent->v->colormap >= 1024)
+               if (ent->fields.server->colormap >= 1024)
                        cs.flags |= RENDER_COLORMAPPED;
                if (cs.viewmodelforclient)
                        cs.flags |= RENDER_VIEWMODEL; // show relative to the view
 
-               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[0]*256;
+               f = PRVM_GETEDICTFIELDVALUE(ent, eval_color)->vector[0]*256;
                cs.light[0] = (unsigned short)bound(0, f, 65535);
-               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[1]*256;
+               f = PRVM_GETEDICTFIELDVALUE(ent, eval_color)->vector[1]*256;
                cs.light[1] = (unsigned short)bound(0, f, 65535);
-               f = GETEDICTFIELDVALUE(ent, eval_color)->vector[2]*256;
+               f = PRVM_GETEDICTFIELDVALUE(ent, eval_color)->vector[2]*256;
                cs.light[2] = (unsigned short)bound(0, f, 65535);
-               f = GETEDICTFIELDVALUE(ent, eval_light_lev)->_float;
+               f = PRVM_GETEDICTFIELDVALUE(ent, eval_light_lev)->_float;
                cs.light[3] = (unsigned short)bound(0, f, 65535);
-               cs.lightstyle = (qbyte)GETEDICTFIELDVALUE(ent, eval_style)->_float;
-               cs.lightpflags = (qbyte)GETEDICTFIELDVALUE(ent, eval_pflags)->_float;
+               cs.lightstyle = (qbyte)PRVM_GETEDICTFIELDVALUE(ent, eval_style)->_float;
+               cs.lightpflags = (qbyte)PRVM_GETEDICTFIELDVALUE(ent, eval_pflags)->_float;
 
                if (gamemode == GAME_TENEBRAE)
                {
@@ -766,7 +770,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
 
 entity_state_t sendstates[MAX_EDICTS];
 
-void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg, int *stats)
+void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int *stats)
 {
        int i, numsendstates;
        entity_state_t *s;
@@ -786,12 +790,12 @@ void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg,
 
 // find the client's PVS
        // the real place being tested from
-       VectorAdd(clent->v->origin, clent->v->view_ofs, sv_writeentitiestoclient_testeye);
+       VectorAdd(clent->fields.server->origin, clent->fields.server->view_ofs, sv_writeentitiestoclient_testeye);
        sv_writeentitiestoclient_pvsbytes = 0;
        if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
                sv_writeentitiestoclient_pvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, sv_writeentitiestoclient_testeye, 8, sv_writeentitiestoclient_pvs, sizeof(sv_writeentitiestoclient_pvs));
 
-       sv_writeentitiestoclient_clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
+       sv_writeentitiestoclient_clentnum = PRVM_EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
 
        sententitiesmark++;
 
@@ -832,11 +836,11 @@ SV_CleanupEnts
 void SV_CleanupEnts (void)
 {
        int             e;
-       edict_t *ent;
+       prvm_edict_t    *ent;
 
-       ent = NEXT_EDICT(sv.edicts);
-       for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
-               ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
+       ent = PRVM_NEXT_EDICT(prog->edicts);
+       for (e=1 ; e<prog->num_edicts ; e++, ent = PRVM_NEXT_EDICT(ent))
+               ent->fields.server->effects = (int)ent->fields.server->effects & ~EF_MUZZLEFLASH;
 }
 
 /*
@@ -845,13 +849,13 @@ SV_WriteClientdataToMessage
 
 ==================
 */
-void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg, int *stats)
+void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
 {
        int             bits;
        int             i;
-       edict_t *other;
+       prvm_edict_t    *other;
        int             items;
-       eval_t  *val;
+       prvm_eval_t     *val;
        vec3_t  punchvector;
        qbyte   viewzoom;
        int             weaponmodelindex;
@@ -859,17 +863,17 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg
 //
 // send a damage message
 //
-       if (ent->v->dmg_take || ent->v->dmg_save)
+       if (ent->fields.server->dmg_take || ent->fields.server->dmg_save)
        {
-               other = PROG_TO_EDICT(ent->v->dmg_inflictor);
+               other = PRVM_PROG_TO_EDICT(ent->fields.server->dmg_inflictor);
                MSG_WriteByte (msg, svc_damage);
-               MSG_WriteByte (msg, ent->v->dmg_save);
-               MSG_WriteByte (msg, ent->v->dmg_take);
+               MSG_WriteByte (msg, ent->fields.server->dmg_save);
+               MSG_WriteByte (msg, ent->fields.server->dmg_take);
                for (i=0 ; i<3 ; i++)
-                       MSG_WriteCoord (msg, other->v->origin[i] + 0.5*(other->v->mins[i] + other->v->maxs[i]), sv.protocol);
+                       MSG_WriteCoord (msg, other->fields.server->origin[i] + 0.5*(other->fields.server->mins[i] + other->fields.server->maxs[i]), sv.protocol);
 
-               ent->v->dmg_take = 0;
-               ent->v->dmg_save = 0;
+               ent->fields.server->dmg_take = 0;
+               ent->fields.server->dmg_save = 0;
        }
 
 //
@@ -878,74 +882,74 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg
        SV_SetIdealPitch ();            // how much to look up / down ideally
 
 // a fixangle might get lost in a dropped packet.  Oh well.
-       if ( ent->v->fixangle )
+       if ( ent->fields.server->fixangle )
        {
                MSG_WriteByte (msg, svc_setangle);
                for (i=0 ; i < 3 ; i++)
-                       MSG_WriteAngle (msg, ent->v->angles[i], sv.protocol);
-               ent->v->fixangle = 0;
+                       MSG_WriteAngle (msg, ent->fields.server->angles[i], sv.protocol);
+               ent->fields.server->fixangle = 0;
        }
 
        // stuff the sigil bits into the high bits of items for sbar, or else
        // mix in items2
-       val = GETEDICTFIELDVALUE(ent, eval_items2);
+       val = PRVM_GETEDICTFIELDVALUE(ent, eval_items2);
        if (val)
-               items = (int)ent->v->items | ((int)val->_float << 23);
+               items = (int)ent->fields.server->items | ((int)val->_float << 23);
        else
-               items = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
+               items = (int)ent->fields.server->items | ((int)prog->globals.server->serverflags << 28);
 
        VectorClear(punchvector);
-       if ((val = GETEDICTFIELDVALUE(ent, eval_punchvector)))
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_punchvector)))
                VectorCopy(val->vector, punchvector);
 
-       weaponmodelindex = SV_ModelIndex(PR_GetString(ent->v->weaponmodel), 1);
+       weaponmodelindex = SV_ModelIndex(PRVM_GetString(ent->fields.server->weaponmodel), 1);
 
        viewzoom = 255;
-       if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom)))
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewzoom)))
                viewzoom = val->_float * 255.0f;
        if (viewzoom == 0)
                viewzoom = 255;
 
        bits = 0;
 
-       if ((int)ent->v->flags & FL_ONGROUND)
+       if ((int)ent->fields.server->flags & FL_ONGROUND)
                bits |= SU_ONGROUND;
-       if (ent->v->waterlevel >= 2)
+       if (ent->fields.server->waterlevel >= 2)
                bits |= SU_INWATER;
-       if (ent->v->idealpitch)
+       if (ent->fields.server->idealpitch)
                bits |= SU_IDEALPITCH;
 
        for (i=0 ; i<3 ; i++)
        {
-               if (ent->v->punchangle[i])
+               if (ent->fields.server->punchangle[i])
                        bits |= (SU_PUNCH1<<i);
                if (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE)
                        if (punchvector[i])
                                bits |= (SU_PUNCHVEC1<<i);
-               if (ent->v->velocity[i])
+               if (ent->fields.server->velocity[i])
                        bits |= (SU_VELOCITY1<<i);
        }
 
        memset(stats, 0, sizeof(int[MAX_CL_STATS]));
-       stats[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
+       stats[STAT_VIEWHEIGHT] = ent->fields.server->view_ofs[2];
        stats[STAT_ITEMS] = items;
-       stats[STAT_WEAPONFRAME] = ent->v->weaponframe;
-       stats[STAT_ARMOR] = ent->v->armorvalue;
+       stats[STAT_WEAPONFRAME] = ent->fields.server->weaponframe;
+       stats[STAT_ARMOR] = ent->fields.server->armorvalue;
        stats[STAT_WEAPON] = weaponmodelindex;
-       stats[STAT_HEALTH] = ent->v->health;
-       stats[STAT_AMMO] = ent->v->currentammo;
-       stats[STAT_SHELLS] = ent->v->ammo_shells;
-       stats[STAT_NAILS] = ent->v->ammo_nails;
-       stats[STAT_ROCKETS] = ent->v->ammo_rockets;
-       stats[STAT_CELLS] = ent->v->ammo_cells;
-       stats[STAT_ACTIVEWEAPON] = ent->v->weapon;
+       stats[STAT_HEALTH] = ent->fields.server->health;
+       stats[STAT_AMMO] = ent->fields.server->currentammo;
+       stats[STAT_SHELLS] = ent->fields.server->ammo_shells;
+       stats[STAT_NAILS] = ent->fields.server->ammo_nails;
+       stats[STAT_ROCKETS] = ent->fields.server->ammo_rockets;
+       stats[STAT_CELLS] = ent->fields.server->ammo_cells;
+       stats[STAT_ACTIVEWEAPON] = ent->fields.server->weapon;
        stats[STAT_VIEWZOOM] = viewzoom;
        // the QC bumps these itself by sending svc_'s, so we have to keep them
        // zero or they'll be corrected by the engine
-       //stats[STAT_TOTALSECRETS] = pr_global_struct->total_secrets;
-       //stats[STAT_TOTALMONSTERS] = pr_global_struct->total_monsters;
-       //stats[STAT_SECRETS] = pr_global_struct->found_secrets;
-       //stats[STAT_MONSTERS] = pr_global_struct->killed_monsters;
+       //stats[STAT_TOTALSECRETS] = prog->globals.server->total_secrets;
+       //stats[STAT_TOTALMONSTERS] = prog->globals.server->total_monsters;
+       //stats[STAT_SECRETS] = prog->globals.server->found_secrets;
+       //stats[STAT_MONSTERS] = prog->globals.server->killed_monsters;
 
        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)
        {
@@ -977,16 +981,16 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg
                MSG_WriteChar (msg, stats[STAT_VIEWHEIGHT]);
 
        if (bits & SU_IDEALPITCH)
-               MSG_WriteChar (msg, ent->v->idealpitch);
+               MSG_WriteChar (msg, ent->fields.server->idealpitch);
 
        for (i=0 ; i<3 ; i++)
        {
                if (bits & (SU_PUNCH1<<i))
                {
                        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE)
-                               MSG_WriteChar(msg, ent->v->punchangle[i]);
+                               MSG_WriteChar(msg, ent->fields.server->punchangle[i]);
                        else
-                               MSG_WriteAngle16i(msg, ent->v->punchangle[i]);
+                               MSG_WriteAngle16i(msg, ent->fields.server->punchangle[i]);
                }
                if (bits & (SU_PUNCHVEC1<<i))
                {
@@ -998,9 +1002,9 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg
                if (bits & (SU_VELOCITY1<<i))
                {
                        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
-                               MSG_WriteChar(msg, ent->v->velocity[i] * (1.0f / 16.0f));
+                               MSG_WriteChar(msg, ent->fields.server->velocity[i] * (1.0f / 16.0f));
                        else
-                               MSG_WriteCoord32f(msg, ent->v->velocity[i]);
+                               MSG_WriteCoord32f(msg, ent->fields.server->velocity[i]);
                }
        }
 
@@ -1136,7 +1140,7 @@ void SV_UpdateToReliableMessages (void)
 {
        int i, j;
        client_t *client;
-       eval_t *val;
+       prvm_eval_t *val;
        const char *name;
        const char *model;
        const char *skin;
@@ -1145,15 +1149,15 @@ void SV_UpdateToReliableMessages (void)
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
                // update the host_client fields we care about according to the entity fields
-               host_client->edict = EDICT_NUM(i+1);
+               host_client->edict = PRVM_EDICT_NUM(i+1);
 
                // DP_SV_CLIENTNAME
-               name = PR_GetString(host_client->edict->v->netname);
+               name = PRVM_GetString(host_client->edict->fields.server->netname);
                if (name == NULL)
                        name = "";
                // always point the string back at host_client->name to keep it safe
                strlcpy (host_client->name, name, sizeof (host_client->name));
-               host_client->edict->v->netname = PR_SetEngineString(host_client->name);
+               host_client->edict->fields.server->netname = PRVM_SetEngineString(host_client->name);
                if (strcmp(host_client->old_name, host_client->name))
                {
                        if (host_client->spawned)
@@ -1167,7 +1171,7 @@ void SV_UpdateToReliableMessages (void)
 
                // DP_SV_CLIENTCOLORS
                // this is always found (since it's added by the progs loader)
-               if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
+               if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
                        host_client->colors = (int)val->_float;
                if (host_client->old_colors != host_client->colors)
                {
@@ -1180,26 +1184,26 @@ void SV_UpdateToReliableMessages (void)
 
                // NEXUIZ_PLAYERMODEL
                if( eval_playermodel ) {
-                       model = PR_GetString(GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string);
+                       model = PRVM_GetString(PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string);
                        if (model == NULL)
                                model = "";
                        // always point the string back at host_client->name to keep it safe
                        strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel));
-                       GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetEngineString(host_client->playermodel);
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
                }
 
                // NEXUIZ_PLAYERSKIN
                if( eval_playerskin ) {
-                       skin = PR_GetString(GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string);
+                       skin = PRVM_GetString(PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string);
                        if (skin == NULL)
                                skin = "";
                        // always point the string back at host_client->name to keep it safe
                        strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin));
-                       GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetEngineString(host_client->playerskin);
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
                }
 
                // frags
-               host_client->frags = (int)host_client->edict->v->frags;
+               host_client->frags = (int)host_client->edict->fields.server->frags;
                if (host_client->old_frags != host_client->frags)
                {
                        host_client->old_frags = host_client->frags;
@@ -1434,40 +1438,40 @@ SV_CreateBaseline
 void SV_CreateBaseline (void)
 {
        int i, entnum, large;
-       edict_t *svent;
+       prvm_edict_t *svent;
 
        // LordHavoc: clear *all* states (note just active ones)
-       for (entnum = 0;entnum < sv.max_edicts;entnum++)
+       for (entnum = 0;entnum < prog->max_edicts;entnum++)
        {
                // get the current server version
-               svent = EDICT_NUM(entnum);
+               svent = PRVM_EDICT_NUM(entnum);
 
                // LordHavoc: always clear state values, whether the entity is in use or not
-               svent->e->baseline = defaultstate;
+               svent->priv.server->baseline = defaultstate;
 
-               if (svent->e->free)
+               if (svent->priv.server->free)
                        continue;
-               if (entnum > svs.maxclients && !svent->v->modelindex)
+               if (entnum > svs.maxclients && !svent->fields.server->modelindex)
                        continue;
 
                // create entity baseline
-               VectorCopy (svent->v->origin, svent->e->baseline.origin);
-               VectorCopy (svent->v->angles, svent->e->baseline.angles);
-               svent->e->baseline.frame = svent->v->frame;
-               svent->e->baseline.skin = svent->v->skin;
+               VectorCopy (svent->fields.server->origin, svent->priv.server->baseline.origin);
+               VectorCopy (svent->fields.server->angles, svent->priv.server->baseline.angles);
+               svent->priv.server->baseline.frame = svent->fields.server->frame;
+               svent->priv.server->baseline.skin = svent->fields.server->skin;
                if (entnum > 0 && entnum <= svs.maxclients)
                {
-                       svent->e->baseline.colormap = entnum;
-                       svent->e->baseline.modelindex = SV_ModelIndex("progs/player.mdl", 1);
+                       svent->priv.server->baseline.colormap = entnum;
+                       svent->priv.server->baseline.modelindex = SV_ModelIndex("progs/player.mdl", 1);
                }
                else
                {
-                       svent->e->baseline.colormap = 0;
-                       svent->e->baseline.modelindex = svent->v->modelindex;
+                       svent->priv.server->baseline.colormap = 0;
+                       svent->priv.server->baseline.modelindex = svent->fields.server->modelindex;
                }
 
                large = false;
-               if (svent->e->baseline.modelindex & 0xFF00 || svent->e->baseline.frame & 0xFF00)
+               if (svent->priv.server->baseline.modelindex & 0xFF00 || svent->priv.server->baseline.frame & 0xFF00)
                        large = true;
 
                // add to the message
@@ -1479,20 +1483,20 @@ void SV_CreateBaseline (void)
 
                if (large)
                {
-                       MSG_WriteShort (&sv.signon, svent->e->baseline.modelindex);
-                       MSG_WriteShort (&sv.signon, svent->e->baseline.frame);
+                       MSG_WriteShort (&sv.signon, svent->priv.server->baseline.modelindex);
+                       MSG_WriteShort (&sv.signon, svent->priv.server->baseline.frame);
                }
                else
                {
-                       MSG_WriteByte (&sv.signon, svent->e->baseline.modelindex);
-                       MSG_WriteByte (&sv.signon, svent->e->baseline.frame);
+                       MSG_WriteByte (&sv.signon, svent->priv.server->baseline.modelindex);
+                       MSG_WriteByte (&sv.signon, svent->priv.server->baseline.frame);
                }
-               MSG_WriteByte (&sv.signon, svent->e->baseline.colormap);
-               MSG_WriteByte (&sv.signon, svent->e->baseline.skin);
+               MSG_WriteByte (&sv.signon, svent->priv.server->baseline.colormap);
+               MSG_WriteByte (&sv.signon, svent->priv.server->baseline.skin);
                for (i=0 ; i<3 ; i++)
                {
-                       MSG_WriteCoord(&sv.signon, svent->e->baseline.origin[i], sv.protocol);
-                       MSG_WriteAngle(&sv.signon, svent->e->baseline.angles[i], sv.protocol);
+                       MSG_WriteCoord(&sv.signon, svent->priv.server->baseline.origin[i], sv.protocol);
+                       MSG_WriteAngle(&sv.signon, svent->priv.server->baseline.angles[i], sv.protocol);
                }
        }
 }
@@ -1535,7 +1539,7 @@ void SV_SaveSpawnparms (void)
 {
        int             i, j;
 
-       svs.serverflags = pr_global_struct->serverflags;
+       svs.serverflags = prog->globals.server->serverflags;
 
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
@@ -1543,55 +1547,55 @@ void SV_SaveSpawnparms (void)
                        continue;
 
        // call the progs to get default spawn parms for the new client
-               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-               PR_ExecuteProgram (pr_global_struct->SetChangeParms, "QC function SetChangeParms is missing");
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+               PRVM_ExecuteProgram (prog->globals.server->SetChangeParms, "QC function SetChangeParms is missing");
                for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
-                       host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
+                       host_client->spawn_parms[j] = (&prog->globals.server->parm1)[j];
        }
 }
-
+/*
 void SV_IncreaseEdicts(void)
 {
        int i;
-       edict_t *ent;
-       int oldmax_edicts = sv.max_edicts;
-       void *oldedictsengineprivate = sv.edictsengineprivate;
-       void *oldedictsfields = sv.edictsfields;
+       prvm_edict_t *ent;
+       int oldmax_edicts = prog->max_edicts;
+       void *oldedictsengineprivate = prog->edictprivate;
+       void *oldedictsfields = prog->edictsfields;
        void *oldmoved_edicts = sv.moved_edicts;
 
-       if (sv.max_edicts >= MAX_EDICTS)
+       if (prog->max_edicts >= MAX_EDICTS)
                return;
 
        // links don't survive the transition, so unlink everything
-       for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
+       for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
        {
-               if (!ent->e->free)
-                       SV_UnlinkEdict(sv.edicts + i);
-               memset(&ent->e->areagrid, 0, sizeof(ent->e->areagrid));
+               if (!ent->priv.server->free)
+                       SV_UnlinkEdict(prog->edicts + i);
+               memset(&ent->priv.server->areagrid, 0, sizeof(ent->priv.server->areagrid));
        }
        SV_ClearWorld();
 
-       sv.max_edicts   = min(sv.max_edicts + 256, MAX_EDICTS);
-       sv.edictsengineprivate = PR_Alloc(sv.max_edicts * sizeof(edict_engineprivate_t));
-       sv.edictsfields = PR_Alloc(sv.max_edicts * pr_edict_size);
-       sv.moved_edicts = PR_Alloc(sv.max_edicts * sizeof(edict_t *));
+       prog->max_edicts   = min(prog->max_edicts + 256, MAX_EDICTS);
+       prog->edictprivate = PR_Alloc(prog->max_edicts * sizeof(edict_engineprivate_t));
+       prog->edictsfields = PR_Alloc(prog->max_edicts * prog->edict_size);
+       sv.moved_edicts = PR_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
 
-       memcpy(sv.edictsengineprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t));
-       memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size);
+       memcpy(prog->edictprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t));
+       memcpy(prog->edictsfields, oldedictsfields, oldmax_edicts * prog->edict_size);
 
-       for (i = 0, ent = sv.edicts;i < sv.max_edicts;i++, ent++)
+       for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
        {
-               ent->e = sv.edictsengineprivate + i;
-               ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
+               ent->priv.vp = (qbyte*) prog->edictprivate + i * prog->edictprivate_size;
+               ent->fields.server = (void *)((qbyte *)prog->edictsfields + i * prog->edict_size);
                // link every entity except world
-               if (!ent->e->free)
+               if (!ent->priv.server->free)
                        SV_LinkEdict(ent, false);
        }
 
        PR_Free(oldedictsengineprivate);
        PR_Free(oldedictsfields);
        PR_Free(oldmoved_edicts);
-}
+}*/
 
 /*
 ================
@@ -1604,7 +1608,7 @@ extern float              scr_centertime_off;
 
 void SV_SpawnServer (const char *server)
 {
-       edict_t *ent;
+       prvm_edict_t *ent;
        int i;
        qbyte *entities;
        model_t *worldmodel;
@@ -1633,8 +1637,12 @@ void SV_SpawnServer (const char *server)
 //
 // tell all connected clients that we are going to a new level
 //
-       if (sv.active)
+       if (sv.active) 
+       {
+               SV_VM_Begin();
                SV_SendReconnect();
+               SV_VM_End();
+       }
        else
        {
                // make sure cvars have been checked before opening the ports
@@ -1670,32 +1678,36 @@ void SV_SpawnServer (const char *server)
                sv.protocol = PROTOCOL_QUAKE;
        }
 
+       SV_VM_Setup();
+
+       SV_VM_Begin();
+
 // load progs to get entity field count
-       PR_LoadProgs ( sv_progs.string );
+       //PR_LoadProgs ( sv_progs.string );
 
-// allocate server memory
-       // start out with just enough room for clients and a reasonable estimate of entities
-       sv.max_edicts = max(svs.maxclients + 1, 512);
-       sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
+       // allocate server memory
+       /*// start out with just enough room for clients and a reasonable estimate of entities
+       prog->max_edicts = max(svs.maxclients + 1, 512);
+       prog->max_edicts = min(prog->max_edicts, MAX_EDICTS);
 
-       // edict_t structures (hidden from progs)
-       sv.edicts = PR_Alloc(MAX_EDICTS * sizeof(edict_t));
+       // prvm_edict_t structures (hidden from progs)
+       prog->edicts = PR_Alloc(MAX_EDICTS * sizeof(prvm_edict_t));
        // engine private structures (hidden from progs)
-       sv.edictsengineprivate = PR_Alloc(sv.max_edicts * sizeof(edict_engineprivate_t));
+       prog->edictprivate = PR_Alloc(prog->max_edicts * sizeof(edict_engineprivate_t));
        // progs fields, often accessed by server
-       sv.edictsfields = PR_Alloc(sv.max_edicts * pr_edict_size);
+       prog->edictsfields = PR_Alloc(prog->max_edicts * prog->edict_size);*/
        // used by PushMove to move back pushed entities
-       sv.moved_edicts = PR_Alloc(sv.max_edicts * sizeof(edict_t *));
-       for (i = 0;i < sv.max_edicts;i++)
+       sv.moved_edicts = PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
+       /*for (i = 0;i < prog->max_edicts;i++)
        {
-               ent = sv.edicts + i;
-               ent->e = sv.edictsengineprivate + i;
-               ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
-       }
+               ent = prog->edicts + i;
+               ent->priv.vp = (qbyte*) prog->edictprivate + i * prog->edictprivate_size;
+               ent->fields.server = (void *)((qbyte *)prog->edictsfields + i * prog->edict_size);
+       }*/
 
        // fix up client->edict pointers for returning clients right away...
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
-               host_client->edict = EDICT_NUM(i + 1);
+               host_client->edict = PRVM_EDICT_NUM(i + 1);
 
        sv.datagram.maxsize = sizeof(sv.datagram_buf);
        sv.datagram.cursize = 0;
@@ -1710,12 +1722,12 @@ void SV_SpawnServer (const char *server)
        sv.signon.data = sv.signon_buf;
 
 // leave slots at start for clients only
-       sv.num_edicts = svs.maxclients+1;
+       //prog->num_edicts = svs.maxclients+1;
 
        sv.state = ss_loading;
        sv.paused = false;
 
-       sv.time = 1.0;
+       *prog->time = sv.time = 1.0;
 
        Mod_ClearUsed();
        worldmodel->used = true;
@@ -1743,23 +1755,24 @@ void SV_SpawnServer (const char *server)
 //
 // load the rest of the entities
 //
-       ent = EDICT_NUM(0);
-       memset (ent->v, 0, progs->entityfields * 4);
-       ent->e->free = false;
-       ent->v->model = PR_SetEngineString(sv.modelname);
-       ent->v->modelindex = 1;         // world model
-       ent->v->solid = SOLID_BSP;
-       ent->v->movetype = MOVETYPE_PUSH;
+       // AK possible hack since num_edicts is still 0 
+       ent = PRVM_EDICT_NUM(0);
+       memset (ent->fields.server, 0, prog->progs->entityfields * 4);
+       ent->priv.server->free = false;
+       ent->fields.server->model = PRVM_SetEngineString(sv.modelname);
+       ent->fields.server->modelindex = 1;             // world model
+       ent->fields.server->solid = SOLID_BSP;
+       ent->fields.server->movetype = MOVETYPE_PUSH;
 
        if (coop.value)
-               pr_global_struct->coop = coop.integer;
+               prog->globals.server->coop = coop.integer;
        else
-               pr_global_struct->deathmatch = deathmatch.integer;
+               prog->globals.server->deathmatch = deathmatch.integer;
 
-       pr_global_struct->mapname = PR_SetEngineString(sv.name);
+       prog->globals.server->mapname = PRVM_SetEngineString(sv.name);
 
 // serverflags are for cross level information (sigils)
-       pr_global_struct->serverflags = svs.serverflags;
+       prog->globals.server->serverflags = svs.serverflags;
 
        // load replacement entity file if found
        entities = NULL;
@@ -1768,15 +1781,15 @@ void SV_SpawnServer (const char *server)
        if (entities)
        {
                Con_Printf("Loaded maps/%s.ent\n", sv.name);
-               ED_LoadFromFile (entities);
+               PRVM_ED_LoadFromFile (entities);
                Mem_Free(entities);
        }
        else
-               ED_LoadFromFile (sv.worldmodel->brush.entities);
+               PRVM_ED_LoadFromFile (sv.worldmodel->brush.entities);
 
 
        // LordHavoc: clear world angles (to fix e3m3.bsp)
-       VectorClear(sv.edicts->v->angles);
+       VectorClear(prog->edicts->fields.server->angles);
 
        sv.active = true;
 
@@ -1804,5 +1817,412 @@ void SV_SpawnServer (const char *server)
 
        Con_DPrint("Server spawned.\n");
        NetConn_Heartbeat (2);
+
+       SV_VM_End();
+}
+
+/////////////////////////////////////////////////////
+// SV VM stuff
+
+void SV_VM_CB_BeginIncreaseEdicts(void)
+{
+       int i;
+       prvm_edict_t *ent;
+
+       PRVM_Free( sv.moved_edicts );
+       sv.moved_edicts = PRVM_Alloc(prog->max_edicts * sizeof(prvm_edict_t *));
+
+       // links don't survive the transition, so unlink everything
+       for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
+       {
+               if (!ent->priv.server->free)
+                       SV_UnlinkEdict(prog->edicts + i);
+               memset(&ent->priv.server->areagrid, 0, sizeof(ent->priv.server->areagrid));
+       }
+       SV_ClearWorld();
+}
+
+void SV_VM_CB_EndIncreaseEdicts(void)
+{
+       int i;
+       prvm_edict_t *ent;
+
+       for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
+       {
+               // link every entity except world
+               if (!ent->priv.server->free)
+                       SV_LinkEdict(ent, false);
+       }
+}
+
+void SV_VM_CB_InitEdict(prvm_edict_t *e)
+{
+       // LordHavoc: for consistency set these here
+       int num = PRVM_NUM_FOR_EDICT(e) - 1;
+
+       if (num >= 0 && num < svs.maxclients)
+       {
+               prvm_eval_t *val;
+               // set colormap and team on newly created player entity
+               e->fields.server->colormap = num + 1;
+               e->fields.server->team = (svs.clients[num].colors & 15) + 1;
+               // set netname/clientcolors back to client values so that
+               // DP_SV_CLIENTNAME and DPV_SV_CLIENTCOLORS will not immediately
+               // reset them
+               e->fields.server->netname = PRVM_SetEngineString(svs.clients[num].name);
+               if ((val = PRVM_GETEDICTFIELDVALUE(e, eval_clientcolors)))
+                       val->_float = svs.clients[num].colors;
+               // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
+               if( eval_playermodel )
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PRVM_SetEngineString(svs.clients[num].playermodel);
+               if( eval_playerskin )
+                       PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PRVM_SetEngineString(svs.clients[num].playerskin);
+       }
+}
+
+void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
+{
+       SV_UnlinkEdict (ed);            // unlink from world bsp
+
+       ed->fields.server->model = 0;
+       ed->fields.server->takedamage = 0;
+       ed->fields.server->modelindex = 0;
+       ed->fields.server->colormap = 0;
+       ed->fields.server->skin = 0;
+       ed->fields.server->frame = 0;
+       VectorClear(ed->fields.server->origin);
+       VectorClear(ed->fields.server->angles);
+       ed->fields.server->nextthink = -1;
+       ed->fields.server->solid = 0;
 }
 
+void SV_VM_CB_CountEdicts(void)
+{
+       int             i;
+       prvm_edict_t    *ent;
+       int             active, models, solid, step;
+
+       active = models = solid = step = 0;
+       for (i=0 ; i<prog->num_edicts ; i++)
+       {
+               ent = PRVM_EDICT_NUM(i);
+               if (ent->priv.server->free)
+                       continue;
+               active++;
+               if (ent->fields.server->solid)
+                       solid++;
+               if (ent->fields.server->model)
+                       models++;
+               if (ent->fields.server->movetype == MOVETYPE_STEP)
+                       step++;
+       }
+
+       Con_Printf("num_edicts:%3i\n", prog->num_edicts);
+       Con_Printf("active    :%3i\n", active);
+       Con_Printf("view      :%3i\n", models);
+       Con_Printf("touch     :%3i\n", solid);
+       Con_Printf("step      :%3i\n", step);
+}
+
+qboolean SV_VM_CB_LoadEdict(prvm_edict_t *ent) 
+{
+       // remove things from different skill levels or deathmatch
+       if (gamemode != GAME_TRANSFUSION) //Transfusion does this in QC
+       {
+               if (deathmatch.integer)
+               {
+                       if (((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
+                       {
+                               return false;
+                       }
+               }
+               else if ((current_skill <= 0 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_EASY  ))
+                       || (current_skill == 1 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_MEDIUM))
+                       || (current_skill >= 2 && ((int)ent->fields.server->spawnflags & SPAWNFLAG_NOT_HARD  )))
+               {
+                       return false;
+               }
+       }
+       return true;
+}
+
+cvar_t nomonsters = {0, "nomonsters", "0"};
+cvar_t gamecfg = {0, "gamecfg", "0"};
+cvar_t scratch1 = {0, "scratch1", "0"};
+cvar_t scratch2 = {0,"scratch2", "0"};
+cvar_t scratch3 = {0, "scratch3", "0"};
+cvar_t scratch4 = {0, "scratch4", "0"};
+cvar_t savedgamecfg = {CVAR_SAVE, "savedgamecfg", "0"};
+cvar_t saved1 = {CVAR_SAVE, "saved1", "0"};
+cvar_t saved2 = {CVAR_SAVE, "saved2", "0"};
+cvar_t saved3 = {CVAR_SAVE, "saved3", "0"};
+cvar_t saved4 = {CVAR_SAVE, "saved4", "0"};
+cvar_t decors = {0, "decors", "0"};
+cvar_t nehx00 = {0, "nehx00", "0"};cvar_t      nehx01 = {0, "nehx01", "0"};
+cvar_t nehx02 = {0, "nehx02", "0"};cvar_t      nehx03 = {0, "nehx03", "0"};
+cvar_t nehx04 = {0, "nehx04", "0"};cvar_t      nehx05 = {0, "nehx05", "0"};
+cvar_t nehx06 = {0, "nehx06", "0"};cvar_t      nehx07 = {0, "nehx07", "0"};
+cvar_t nehx08 = {0, "nehx08", "0"};cvar_t      nehx09 = {0, "nehx09", "0"};
+cvar_t nehx10 = {0, "nehx10", "0"};cvar_t      nehx11 = {0, "nehx11", "0"};
+cvar_t nehx12 = {0, "nehx12", "0"};cvar_t      nehx13 = {0, "nehx13", "0"};
+cvar_t nehx14 = {0, "nehx14", "0"};cvar_t      nehx15 = {0, "nehx15", "0"};
+cvar_t nehx16 = {0, "nehx16", "0"};cvar_t      nehx17 = {0, "nehx17", "0"};
+cvar_t nehx18 = {0, "nehx18", "0"};cvar_t      nehx19 = {0, "nehx19", "0"};
+cvar_t cutscene = {0, "cutscene", "1"};
+
+void SV_VM_Init(void)
+{
+       Cvar_RegisterVariable (&nomonsters);
+       Cvar_RegisterVariable (&gamecfg);
+       Cvar_RegisterVariable (&scratch1);
+       Cvar_RegisterVariable (&scratch2);
+       Cvar_RegisterVariable (&scratch3);
+       Cvar_RegisterVariable (&scratch4);
+       Cvar_RegisterVariable (&savedgamecfg);
+       Cvar_RegisterVariable (&saved1);
+       Cvar_RegisterVariable (&saved2);
+       Cvar_RegisterVariable (&saved3);
+       Cvar_RegisterVariable (&saved4);
+       // LordHavoc: for DarkPlaces, this overrides the number of decors (shell casings, gibs, etc)
+       Cvar_RegisterVariable (&decors);
+       // LordHavoc: Nehahra uses these to pass data around cutscene demos
+       if (gamemode == GAME_NEHAHRA)
+       {
+               Cvar_RegisterVariable (&nehx00);Cvar_RegisterVariable (&nehx01);
+               Cvar_RegisterVariable (&nehx02);Cvar_RegisterVariable (&nehx03);
+               Cvar_RegisterVariable (&nehx04);Cvar_RegisterVariable (&nehx05);
+               Cvar_RegisterVariable (&nehx06);Cvar_RegisterVariable (&nehx07);
+               Cvar_RegisterVariable (&nehx08);Cvar_RegisterVariable (&nehx09);
+               Cvar_RegisterVariable (&nehx10);Cvar_RegisterVariable (&nehx11);
+               Cvar_RegisterVariable (&nehx12);Cvar_RegisterVariable (&nehx13);
+               Cvar_RegisterVariable (&nehx14);Cvar_RegisterVariable (&nehx15);
+               Cvar_RegisterVariable (&nehx16);Cvar_RegisterVariable (&nehx17);
+               Cvar_RegisterVariable (&nehx18);Cvar_RegisterVariable (&nehx19);
+       }
+       Cvar_RegisterVariable (&cutscene); // for Nehahra but useful to other mods as well
+}
+
+// LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  these are defined as externs in progs.h
+int eval_gravity;
+int eval_button3;
+int eval_button4;
+int eval_button5;
+int eval_button6;
+int eval_button7;
+int eval_button8;
+int eval_buttonuse;
+int eval_buttonchat;
+int eval_glow_size;
+int eval_glow_trail;
+int eval_glow_color;
+int eval_items2;
+int eval_scale;
+int eval_alpha;
+int eval_renderamt; // HalfLife support
+int eval_rendermode; // HalfLife support
+int eval_fullbright;
+int eval_ammo_shells1;
+int eval_ammo_nails1;
+int eval_ammo_lava_nails;
+int eval_ammo_rockets1;
+int eval_ammo_multi_rockets;
+int eval_ammo_cells1;
+int eval_ammo_plasma;
+int eval_idealpitch;
+int eval_pitch_speed;
+int eval_viewmodelforclient;
+int eval_nodrawtoclient;
+int eval_exteriormodeltoclient;
+int eval_drawonlytoclient;
+int eval_ping;
+int eval_movement;
+int eval_pmodel;
+int eval_punchvector;
+int eval_viewzoom;
+int eval_clientcolors;
+int eval_tag_entity;
+int eval_tag_index;
+int eval_light_lev;
+int eval_color;
+int eval_style;
+int eval_pflags;
+int eval_cursor_active;
+int eval_cursor_screen;
+int eval_cursor_trace_start;
+int eval_cursor_trace_endpos;
+int eval_cursor_trace_ent;
+int eval_colormod;
+int eval_playermodel;
+int eval_playerskin;
+
+mfunction_t *SV_PlayerPhysicsQC;
+mfunction_t *EndFrameQC;
+//KrimZon - SERVER COMMANDS IN QUAKEC
+mfunction_t *SV_ParseClientCommandQC;
+
+void SV_VM_FindEdictFieldOffsets(void)
+{
+       eval_gravity = PRVM_ED_FindFieldOffset("gravity");
+       eval_button3 = PRVM_ED_FindFieldOffset("button3");
+       eval_button4 = PRVM_ED_FindFieldOffset("button4");
+       eval_button5 = PRVM_ED_FindFieldOffset("button5");
+       eval_button6 = PRVM_ED_FindFieldOffset("button6");
+       eval_button7 = PRVM_ED_FindFieldOffset("button7");
+       eval_button8 = PRVM_ED_FindFieldOffset("button8");
+       eval_buttonuse = PRVM_ED_FindFieldOffset("buttonuse");
+       eval_buttonchat = PRVM_ED_FindFieldOffset("buttonchat");
+       eval_glow_size = PRVM_ED_FindFieldOffset("glow_size");
+       eval_glow_trail = PRVM_ED_FindFieldOffset("glow_trail");
+       eval_glow_color = PRVM_ED_FindFieldOffset("glow_color");
+       eval_items2 = PRVM_ED_FindFieldOffset("items2");
+       eval_scale = PRVM_ED_FindFieldOffset("scale");
+       eval_alpha = PRVM_ED_FindFieldOffset("alpha");
+       eval_renderamt = PRVM_ED_FindFieldOffset("renderamt"); // HalfLife support
+       eval_rendermode = PRVM_ED_FindFieldOffset("rendermode"); // HalfLife support
+       eval_fullbright = PRVM_ED_FindFieldOffset("fullbright");
+       eval_ammo_shells1 = PRVM_ED_FindFieldOffset("ammo_shells1");
+       eval_ammo_nails1 = PRVM_ED_FindFieldOffset("ammo_nails1");
+       eval_ammo_lava_nails = PRVM_ED_FindFieldOffset("ammo_lava_nails");
+       eval_ammo_rockets1 = PRVM_ED_FindFieldOffset("ammo_rockets1");
+       eval_ammo_multi_rockets = PRVM_ED_FindFieldOffset("ammo_multi_rockets");
+       eval_ammo_cells1 = PRVM_ED_FindFieldOffset("ammo_cells1");
+       eval_ammo_plasma = PRVM_ED_FindFieldOffset("ammo_plasma");
+       eval_idealpitch = PRVM_ED_FindFieldOffset("idealpitch");
+       eval_pitch_speed = PRVM_ED_FindFieldOffset("pitch_speed");
+       eval_viewmodelforclient = PRVM_ED_FindFieldOffset("viewmodelforclient");
+       eval_nodrawtoclient = PRVM_ED_FindFieldOffset("nodrawtoclient");
+       eval_exteriormodeltoclient = PRVM_ED_FindFieldOffset("exteriormodeltoclient");
+       eval_drawonlytoclient = PRVM_ED_FindFieldOffset("drawonlytoclient");
+       eval_ping = PRVM_ED_FindFieldOffset("ping");
+       eval_movement = PRVM_ED_FindFieldOffset("movement");
+       eval_pmodel = PRVM_ED_FindFieldOffset("pmodel");
+       eval_punchvector = PRVM_ED_FindFieldOffset("punchvector");
+       eval_viewzoom = PRVM_ED_FindFieldOffset("viewzoom");
+       eval_clientcolors = PRVM_ED_FindFieldOffset("clientcolors");
+       eval_tag_entity = PRVM_ED_FindFieldOffset("tag_entity");
+       eval_tag_index = PRVM_ED_FindFieldOffset("tag_index");
+       eval_light_lev = PRVM_ED_FindFieldOffset("light_lev");
+       eval_color = PRVM_ED_FindFieldOffset("color");
+       eval_style = PRVM_ED_FindFieldOffset("style");
+       eval_pflags = PRVM_ED_FindFieldOffset("pflags");
+       eval_cursor_active = PRVM_ED_FindFieldOffset("cursor_active");
+       eval_cursor_screen = PRVM_ED_FindFieldOffset("cursor_screen");
+       eval_cursor_trace_start = PRVM_ED_FindFieldOffset("cursor_trace_start");
+       eval_cursor_trace_endpos = PRVM_ED_FindFieldOffset("cursor_trace_endpos");
+       eval_cursor_trace_ent = PRVM_ED_FindFieldOffset("cursor_trace_ent");
+       eval_colormod = PRVM_ED_FindFieldOffset("colormod");
+       eval_playermodel = PRVM_ED_FindFieldOffset("playermodel");
+       eval_playerskin = PRVM_ED_FindFieldOffset("playerskin");
+
+       // LordHavoc: allowing QuakeC to override the player movement code
+       SV_PlayerPhysicsQC = PRVM_ED_FindFunction ("SV_PlayerPhysics");
+       // LordHavoc: support for endframe
+       EndFrameQC = PRVM_ED_FindFunction ("EndFrame");
+       //KrimZon - SERVER COMMANDS IN QUAKEC
+       SV_ParseClientCommandQC = PRVM_ED_FindFunction ("SV_ParseClientCommand");
+}
+
+#define REQFIELDS (sizeof(reqfields) / sizeof(prvm_required_field_t))
+
+prvm_required_field_t reqfields[] =
+{
+       {ev_entity, "cursor_trace_ent"},
+       {ev_entity, "drawonlytoclient"},
+       {ev_entity, "exteriormodeltoclient"},
+       {ev_entity, "nodrawtoclient"},
+       {ev_entity, "tag_entity"},
+       {ev_entity, "viewmodelforclient"},
+       {ev_float, "alpha"},
+       {ev_float, "ammo_cells1"},
+       {ev_float, "ammo_lava_nails"},
+       {ev_float, "ammo_multi_rockets"},
+       {ev_float, "ammo_nails1"},
+       {ev_float, "ammo_plasma"},
+       {ev_float, "ammo_rockets1"},
+       {ev_float, "ammo_shells1"},
+       {ev_float, "button3"},
+       {ev_float, "button4"},
+       {ev_float, "button5"},
+       {ev_float, "button6"},
+       {ev_float, "button7"},
+       {ev_float, "button8"},
+       {ev_float, "buttonchat"},
+       {ev_float, "buttonuse"},
+       {ev_float, "clientcolors"},
+       {ev_float, "cursor_active"},
+       {ev_float, "fullbright"},
+       {ev_float, "glow_color"},
+       {ev_float, "glow_size"},
+       {ev_float, "glow_trail"},
+       {ev_float, "gravity"},
+       {ev_float, "idealpitch"},
+       {ev_float, "items2"},
+       {ev_float, "light_lev"},
+       {ev_float, "pflags"},
+       {ev_float, "ping"},
+       {ev_float, "pitch_speed"},
+       {ev_float, "pmodel"},
+       {ev_float, "renderamt"}, // HalfLife support
+       {ev_float, "rendermode"}, // HalfLife support
+       {ev_float, "scale"},
+       {ev_float, "style"},
+       {ev_float, "tag_index"},
+       {ev_float, "viewzoom"},
+       {ev_vector, "color"},
+       {ev_vector, "colormod"},
+       {ev_vector, "cursor_screen"},
+       {ev_vector, "cursor_trace_endpos"},
+       {ev_vector, "cursor_trace_start"},
+       {ev_vector, "movement"},
+       {ev_vector, "punchvector"},
+       {ev_string, "playermodel"},
+       {ev_string, "playerskin"}
+};
+
+void SV_VM_Setup(void)
+{
+       PRVM_Begin;
+       PRVM_InitProg( PRVM_SERVERPROG );
+
+       // allocate the mempools
+       prog->progs_mempool = Mem_AllocPool("Server Progs", 0, NULL);
+       prog->builtins = vm_sv_builtins;
+       prog->numbuiltins = vm_sv_numbuiltins;
+       prog->headercrc = PROGHEADER_CRC;
+       prog->max_edicts = 512;
+       prog->limit_edicts = MAX_EDICTS;
+       prog->reserved_edicts = svs.maxclients;
+       prog->edictprivate_size = sizeof(edict_engineprivate_t);
+       prog->name = "server";
+       prog->extensionstring = vm_sv_extensions;
+       prog->loadintoworld = true;
+
+       prog->begin_increase_edicts = SV_VM_CB_BeginIncreaseEdicts;
+       prog->end_increase_edicts = SV_VM_CB_EndIncreaseEdicts;
+       prog->init_edict = SV_VM_CB_InitEdict;
+       prog->free_edict = SV_VM_CB_FreeEdict;
+       prog->count_edicts = SV_VM_CB_CountEdicts;
+       prog->load_edict = SV_VM_CB_LoadEdict;
+       prog->init_cmd = VM_SV_Cmd_Init;
+       prog->reset_cmd = VM_SV_Cmd_Reset;
+       prog->error_cmd = NULL; // change this 
+
+       // TODO: add a requiredfuncs list (ask LH if this is necessary at all)
+       PRVM_LoadProgs( sv_progs.string, 0, NULL, REQFIELDS, reqfields );
+       SV_VM_FindEdictFieldOffsets();
+
+       PRVM_End;
+}
+
+void SV_VM_Begin(void)
+{
+       PRVM_Begin;
+       PRVM_SetProg( PRVM_SERVERPROG );
+
+       *prog->time = (float) sv.time;
+}
+
+void SV_VM_End(void)
+{
+       PRVM_End;
+}
\ No newline at end of file
index 9fc5b31d3d05545266eadc5fa3f26aa7fa450cff..8c8f9b866aaaf3f7ec5abd0431829398ecef5c6a 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -32,15 +32,15 @@ is not a staircase.
 */
 int c_yes, c_no;
 
-qboolean SV_CheckBottom (edict_t *ent)
+qboolean SV_CheckBottom (prvm_edict_t *ent)
 {
        vec3_t  mins, maxs, start, stop;
        trace_t trace;
        int             x, y;
        float   mid, bottom;
 
-       VectorAdd (ent->v->origin, ent->v->mins, mins);
-       VectorAdd (ent->v->origin, ent->v->maxs, maxs);
+       VectorAdd (ent->fields.server->origin, ent->fields.server->mins, mins);
+       VectorAdd (ent->fields.server->origin, ent->fields.server->maxs, maxs);
 
 // if all of the points under the corners are solid world, don't bother
 // with the tougher checks
@@ -102,52 +102,52 @@ SV_movestep
 Called by monster program code.
 The move will be adjusted for slopes and stairs, but if the move isn't
 possible, no move is done, false is returned, and
-pr_global_struct->trace_normal is set to the normal of the blocking wall
+prog->globals.server->trace_normal is set to the normal of the blocking wall
 =============
 */
-qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
+qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
 {
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
        trace_t         trace;
        int                     i;
-       edict_t         *enemy;
+       prvm_edict_t            *enemy;
 
 // try the move
-       VectorCopy (ent->v->origin, oldorg);
-       VectorAdd (ent->v->origin, move, neworg);
+       VectorCopy (ent->fields.server->origin, oldorg);
+       VectorAdd (ent->fields.server->origin, move, neworg);
 
 // flying monsters don't step up
-       if ( (int)ent->v->flags & (FL_SWIM | FL_FLY) )
+       if ( (int)ent->fields.server->flags & (FL_SWIM | FL_FLY) )
        {
        // try one move with vertical motion, then one without
                for (i=0 ; i<2 ; i++)
                {
-                       VectorAdd (ent->v->origin, move, neworg);
-                       enemy = PROG_TO_EDICT(ent->v->enemy);
-                       if (i == 0 && enemy != sv.edicts)
+                       VectorAdd (ent->fields.server->origin, move, neworg);
+                       enemy = PRVM_PROG_TO_EDICT(ent->fields.server->enemy);
+                       if (i == 0 && enemy != prog->edicts)
                        {
-                               dz = ent->v->origin[2] - PROG_TO_EDICT(ent->v->enemy)->v->origin[2];
+                               dz = ent->fields.server->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.server->enemy)->fields.server->origin[2];
                                if (dz > 40)
                                        neworg[2] -= 8;
                                if (dz < 30)
                                        neworg[2] += 8;
                        }
-                       trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, neworg, MOVE_NORMAL, ent);
+                       trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, neworg, MOVE_NORMAL, ent);
 
                        if (trace.fraction == 1)
                        {
                                VectorCopy(trace.endpos, traceendpos);
-                               if (((int)ent->v->flags & FL_SWIM) && !(SV_PointSuperContents(traceendpos) & SUPERCONTENTS_LIQUIDSMASK))
+                               if (((int)ent->fields.server->flags & FL_SWIM) && !(SV_PointSuperContents(traceendpos) & SUPERCONTENTS_LIQUIDSMASK))
                                        return false;   // swim monster left water
 
-                               VectorCopy (traceendpos, ent->v->origin);
+                               VectorCopy (traceendpos, ent->fields.server->origin);
                                if (relink)
                                        SV_LinkEdict (ent, true);
                                return true;
                        }
 
-                       if (enemy == sv.edicts)
+                       if (enemy == prog->edicts)
                                break;
                }
 
@@ -159,24 +159,24 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
-       trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+       trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
-               trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+               trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
                if (trace.startsolid)
                        return false;
        }
        if (trace.fraction == 1)
        {
        // if monster had the ground pulled out, go ahead and fall
-               if ( (int)ent->v->flags & FL_PARTIALGROUND )
+               if ( (int)ent->fields.server->flags & FL_PARTIALGROUND )
                {
-                       VectorAdd (ent->v->origin, move, ent->v->origin);
+                       VectorAdd (ent->fields.server->origin, move, ent->fields.server->origin);
                        if (relink)
                                SV_LinkEdict (ent, true);
-                       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        return true;
                }
 
@@ -184,25 +184,25 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
        }
 
 // check point traces down for dangling corners
-       VectorCopy (trace.endpos, ent->v->origin);
+       VectorCopy (trace.endpos, ent->fields.server->origin);
 
        if (!SV_CheckBottom (ent))
        {
-               if ( (int)ent->v->flags & FL_PARTIALGROUND )
+               if ( (int)ent->fields.server->flags & FL_PARTIALGROUND )
                {       // entity had floor mostly pulled out from underneath it
                        // and is trying to correct
                        if (relink)
                                SV_LinkEdict (ent, true);
                        return true;
                }
-               VectorCopy (oldorg, ent->v->origin);
+               VectorCopy (oldorg, ent->fields.server->origin);
                return false;
        }
 
-       if ( (int)ent->v->flags & FL_PARTIALGROUND )
-               ent->v->flags = (int)ent->v->flags & ~FL_PARTIALGROUND;
+       if ( (int)ent->fields.server->flags & FL_PARTIALGROUND )
+               ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_PARTIALGROUND;
 
-       ent->v->groundentity = EDICT_TO_PROG(trace.ent);
+       ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
 
 // the move is ok
        if (relink)
@@ -223,12 +223,12 @@ facing it.
 ======================
 */
 void PF_changeyaw (void);
-qboolean SV_StepDirection (edict_t *ent, float yaw, float dist)
+qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
 {
        vec3_t          move, oldorigin;
        float           delta;
 
-       ent->v->ideal_yaw = yaw;
+       ent->fields.server->ideal_yaw = yaw;
        PF_changeyaw();
 
        yaw = yaw*M_PI*2 / 360;
@@ -236,13 +236,13 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist)
        move[1] = sin(yaw)*dist;
        move[2] = 0;
 
-       VectorCopy (ent->v->origin, oldorigin);
+       VectorCopy (ent->fields.server->origin, oldorigin);
        if (SV_movestep (ent, move, false))
        {
-               delta = ent->v->angles[YAW] - ent->v->ideal_yaw;
+               delta = ent->fields.server->angles[YAW] - ent->fields.server->ideal_yaw;
                if (delta > 45 && delta < 315)
                {               // not turned far enough, so don't take the step
-                       VectorCopy (oldorigin, ent->v->origin);
+                       VectorCopy (oldorigin, ent->fields.server->origin);
                }
                SV_LinkEdict (ent, true);
                return true;
@@ -258,9 +258,9 @@ SV_FixCheckBottom
 
 ======================
 */
-void SV_FixCheckBottom (edict_t *ent)
+void SV_FixCheckBottom (prvm_edict_t *ent)
 {
-       ent->v->flags = (int)ent->v->flags | FL_PARTIALGROUND;
+       ent->fields.server->flags = (int)ent->fields.server->flags | FL_PARTIALGROUND;
 }
 
 
@@ -272,17 +272,17 @@ SV_NewChaseDir
 ================
 */
 #define        DI_NODIR        -1
-void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
+void SV_NewChaseDir (prvm_edict_t *actor, prvm_edict_t *enemy, float dist)
 {
        float           deltax,deltay;
        float                   d[3];
        float           tdir, olddir, turnaround;
 
-       olddir = ANGLEMOD((int)(actor->v->ideal_yaw/45)*45);
+       olddir = ANGLEMOD((int)(actor->fields.server->ideal_yaw/45)*45);
        turnaround = ANGLEMOD(olddir - 180);
 
-       deltax = enemy->v->origin[0] - actor->v->origin[0];
-       deltay = enemy->v->origin[1] - actor->v->origin[1];
+       deltax = enemy->fields.server->origin[0] - actor->fields.server->origin[0];
+       deltay = enemy->fields.server->origin[1] - actor->fields.server->origin[1];
        if (deltax>10)
                d[1]= 0;
        else if (deltax<-10)
@@ -345,7 +345,7 @@ void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
        if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) )
                        return;
 
-       actor->v->ideal_yaw = olddir;           // can't move
+       actor->fields.server->ideal_yaw = olddir;               // can't move
 
 // if a bridge was pulled out from underneath a monster, it may not have
 // a valid standing position at all
@@ -361,15 +361,15 @@ SV_CloseEnough
 
 ======================
 */
-qboolean SV_CloseEnough (edict_t *ent, edict_t *goal, float dist)
+qboolean SV_CloseEnough (prvm_edict_t *ent, prvm_edict_t *goal, float dist)
 {
        int             i;
 
        for (i=0 ; i<3 ; i++)
        {
-               if (goal->v->absmin[i] > ent->v->absmax[i] + dist)
+               if (goal->fields.server->absmin[i] > ent->fields.server->absmax[i] + dist)
                        return false;
-               if (goal->v->absmax[i] < ent->v->absmin[i] - dist)
+               if (goal->fields.server->absmax[i] < ent->fields.server->absmin[i] - dist)
                        return false;
        }
        return true;
@@ -383,26 +383,26 @@ SV_MoveToGoal
 */
 void SV_MoveToGoal (void)
 {
-       edict_t         *ent, *goal;
+       prvm_edict_t            *ent, *goal;
        float           dist;
 
-       ent = PROG_TO_EDICT(pr_global_struct->self);
-       goal = PROG_TO_EDICT(ent->v->goalentity);
-       dist = G_FLOAT(OFS_PARM0);
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       goal = PRVM_PROG_TO_EDICT(ent->fields.server->goalentity);
+       dist = PRVM_G_FLOAT(OFS_PARM0);
 
-       if ( !( (int)ent->v->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
+       if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
        {
-               G_FLOAT(OFS_RETURN) = 0;
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
                return;
        }
 
 // if the next step hits the enemy, return immediately
-       if ( PROG_TO_EDICT(ent->v->enemy) != sv.edicts &&  SV_CloseEnough (ent, goal, dist) )
+       if ( PRVM_PROG_TO_EDICT(ent->fields.server->enemy) != prog->edicts &&  SV_CloseEnough (ent, goal, dist) )
                return;
 
 // bump around...
        if ( (rand()&3)==1 ||
-       !SV_StepDirection (ent, ent->v->ideal_yaw, dist))
+       !SV_StepDirection (ent, ent->fields.server->ideal_yaw, dist))
        {
                SV_NewChaseDir (ent, goal, dist);
        }
index f02cf84a21235ac348204140638585c3566385f8..a44bfa4a55645b44591626099df4c5222426c6df 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -52,7 +52,7 @@ cvar_t sv_freezenonclients = {CVAR_NOTIFY, "sv_freezenonclients", "0"};
 
 #define        MOVE_EPSILON    0.01
 
-void SV_Physics_Toss (edict_t *ent);
+void SV_Physics_Toss (prvm_edict_t *ent);
 
 void SV_Phys_Init (void)
 {
@@ -71,18 +71,18 @@ SV_CheckAllEnts
 void SV_CheckAllEnts (void)
 {
        int e;
-       edict_t *check;
+       prvm_edict_t *check;
 
        // see if any solid entities are inside the final position
-       check = NEXT_EDICT(sv.edicts);
-       for (e = 1;e < sv.num_edicts;e++, check = NEXT_EDICT(check))
+       check = PRVM_NEXT_EDICT(prog->edicts);
+       for (e = 1;e < prog->num_edicts;e++, check = PRVM_NEXT_EDICT(check))
        {
-               if (check->e->free)
+               if (check->priv.server->free)
                        continue;
-               if (check->v->movetype == MOVETYPE_PUSH
-                || check->v->movetype == MOVETYPE_NONE
-                || check->v->movetype == MOVETYPE_FOLLOW
-                || check->v->movetype == MOVETYPE_NOCLIP)
+               if (check->fields.server->movetype == MOVETYPE_PUSH
+                || check->fields.server->movetype == MOVETYPE_NONE
+                || check->fields.server->movetype == MOVETYPE_FOLLOW
+                || check->fields.server->movetype == MOVETYPE_NOCLIP)
                        continue;
 
                if (SV_TestEntityPosition (check))
@@ -95,7 +95,7 @@ void SV_CheckAllEnts (void)
 SV_CheckVelocity
 ================
 */
-void SV_CheckVelocity (edict_t *ent)
+void SV_CheckVelocity (prvm_edict_t *ent)
 {
        int i;
        float wishspeed;
@@ -105,26 +105,26 @@ void SV_CheckVelocity (edict_t *ent)
 //
        for (i=0 ; i<3 ; i++)
        {
-               if (IS_NAN(ent->v->velocity[i]))
+               if (IS_NAN(ent->fields.server->velocity[i]))
                {
-                       Con_Printf("Got a NaN velocity on %s\n", PR_GetString(ent->v->classname));
-                       ent->v->velocity[i] = 0;
+                       Con_Printf("Got a NaN velocity on %s\n", PRVM_GetString(ent->fields.server->classname));
+                       ent->fields.server->velocity[i] = 0;
                }
-               if (IS_NAN(ent->v->origin[i]))
+               if (IS_NAN(ent->fields.server->origin[i]))
                {
-                       Con_Printf("Got a NaN origin on %s\n", PR_GetString(ent->v->classname));
-                       ent->v->origin[i] = 0;
+                       Con_Printf("Got a NaN origin on %s\n", PRVM_GetString(ent->fields.server->classname));
+                       ent->fields.server->origin[i] = 0;
                }
        }
 
        // LordHavoc: max velocity fix, inspired by Maddes's source fixes, but this is faster
-       wishspeed = DotProduct(ent->v->velocity, ent->v->velocity);
+       wishspeed = DotProduct(ent->fields.server->velocity, ent->fields.server->velocity);
        if (wishspeed > sv_maxvelocity.value * sv_maxvelocity.value)
        {
                wishspeed = sv_maxvelocity.value / sqrt(wishspeed);
-               ent->v->velocity[0] *= wishspeed;
-               ent->v->velocity[1] *= wishspeed;
-               ent->v->velocity[2] *= wishspeed;
+               ent->fields.server->velocity[0] *= wishspeed;
+               ent->fields.server->velocity[1] *= wishspeed;
+               ent->fields.server->velocity[2] *= wishspeed;
        }
 }
 
@@ -138,11 +138,11 @@ in a frame.  Not used for pushmove objects, because they must be exact.
 Returns false if the entity removed itself.
 =============
 */
-qboolean SV_RunThink (edict_t *ent)
+qboolean SV_RunThink (prvm_edict_t *ent)
 {
        float thinktime;
 
-       thinktime = ent->v->nextthink;
+       thinktime = ent->fields.server->nextthink;
        if (thinktime <= 0 || thinktime > sv.time + sv.frametime)
                return true;
 
@@ -151,12 +151,12 @@ qboolean SV_RunThink (edict_t *ent)
        if (thinktime < sv.time)
                thinktime = sv.time;
 
-       ent->v->nextthink = 0;
-       pr_global_struct->time = thinktime;
-       pr_global_struct->self = EDICT_TO_PROG(ent);
-       pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
-       PR_ExecuteProgram (ent->v->think, "QC function self.think is missing");
-       return !ent->e->free;
+       ent->fields.server->nextthink = 0;
+       prog->globals.server->time = thinktime;
+       prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+       prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
+       PRVM_ExecuteProgram (ent->fields.server->think, "QC function self.think is missing");
+       return !ent->priv.server->free;
 }
 
 /*
@@ -166,30 +166,30 @@ SV_Impact
 Two entities have touched, so run their touch functions
 ==================
 */
-void SV_Impact (edict_t *e1, edict_t *e2)
+void SV_Impact (prvm_edict_t *e1, prvm_edict_t *e2)
 {
        int old_self, old_other;
 
-       old_self = pr_global_struct->self;
-       old_other = pr_global_struct->other;
+       old_self = prog->globals.server->self;
+       old_other = prog->globals.server->other;
 
-       pr_global_struct->time = sv.time;
-       if (e1->v->touch && e1->v->solid != SOLID_NOT)
+       prog->globals.server->time = sv.time;
+       if (e1->fields.server->touch && e1->fields.server->solid != SOLID_NOT)
        {
-               pr_global_struct->self = EDICT_TO_PROG(e1);
-               pr_global_struct->other = EDICT_TO_PROG(e2);
-               PR_ExecuteProgram (e1->v->touch, "QC function self.touch is missing");
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(e1);
+               prog->globals.server->other = PRVM_EDICT_TO_PROG(e2);
+               PRVM_ExecuteProgram (e1->fields.server->touch, "QC function self.touch is missing");
        }
 
-       if (e2->v->touch && e2->v->solid != SOLID_NOT)
+       if (e2->fields.server->touch && e2->fields.server->solid != SOLID_NOT)
        {
-               pr_global_struct->self = EDICT_TO_PROG(e2);
-               pr_global_struct->other = EDICT_TO_PROG(e1);
-               PR_ExecuteProgram (e2->v->touch, "QC function self.touch is missing");
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(e2);
+               prog->globals.server->other = PRVM_EDICT_TO_PROG(e1);
+               PRVM_ExecuteProgram (e2->fields.server->touch, "QC function self.touch is missing");
        }
 
-       pr_global_struct->self = old_self;
-       pr_global_struct->other = old_other;
+       prog->globals.server->self = old_self;
+       prog->globals.server->other = old_other;
 }
 
 
@@ -230,7 +230,7 @@ If stepnormal is not NULL, the plane normal of any vertical wall hit will be sto
 */
 // LordHavoc: increased from 5 to 32
 #define MAX_CLIP_PLANES 32
-int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
+int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
 {
        int blocked, bumpcount;
        int i, j, impact, numplanes;
@@ -238,29 +238,29 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
        vec3_t dir, end, planes[MAX_CLIP_PLANES], primal_velocity, original_velocity, new_velocity;
        trace_t trace;
        blocked = 0;
-       VectorCopy(ent->v->velocity, original_velocity);
-       VectorCopy(ent->v->velocity, primal_velocity);
+       VectorCopy(ent->fields.server->velocity, original_velocity);
+       VectorCopy(ent->fields.server->velocity, primal_velocity);
        numplanes = 0;
        time_left = time;
        for (bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
        {
-               if (!ent->v->velocity[0] && !ent->v->velocity[1] && !ent->v->velocity[2])
+               if (!ent->fields.server->velocity[0] && !ent->fields.server->velocity[1] && !ent->fields.server->velocity[2])
                        break;
 
-               VectorMA(ent->v->origin, time_left, ent->v->velocity, end);
-               trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+               VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
+               trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
 #if 0
                //if (trace.fraction < 0.002)
                {
 #if 1
                        vec3_t start;
                        trace_t testtrace;
-                       VectorCopy(ent->v->origin, start);
+                       VectorCopy(ent->fields.server->origin, start);
                        start[2] += 3;//0.03125;
-                       VectorMA(ent->v->origin, time_left, ent->v->velocity, end);
+                       VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
                        end[2] += 3;//0.03125;
-                       testtrace = SV_Move(start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
-                       if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->v->velocity) < DotProduct(testtrace.plane.normal, ent->v->velocity)))
+                       testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+                       if (trace.fraction < testtrace.fraction && !testtrace.startsolid && (testtrace.fraction == 1 || DotProduct(trace.plane.normal, ent->fields.server->velocity) < DotProduct(testtrace.plane.normal, ent->fields.server->velocity)))
                        {
                                Con_Printf("got further (new %f > old %f)\n", testtrace.fraction, trace.fraction);
                                trace = testtrace;
@@ -270,26 +270,26 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                        //j = -1;
                        for (i = 0;i < numplanes;i++)
                        {
-                               VectorCopy(ent->v->origin, start);
-                               VectorMA(ent->v->origin, time_left, ent->v->velocity, end);
+                               VectorCopy(ent->fields.server->origin, start);
+                               VectorMA(ent->fields.server->origin, time_left, ent->fields.server->velocity, end);
                                VectorMA(start, 3, planes[i], start);
                                VectorMA(end, 3, planes[i], end);
-                               testtrace = SV_Move(start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+                               testtrace = SV_Move(start, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
                                if (trace.fraction < testtrace.fraction)
                                {
                                        trace = testtrace;
-                                       VectorCopy(start, ent->v->origin);
+                                       VectorCopy(start, ent->fields.server->origin);
                                        //j = i;
                                }
                        }
                        //if (j >= 0)
-                       //      VectorAdd(ent->v->origin, planes[j], start);
+                       //      VectorAdd(ent->fields.server->origin, planes[j], start);
 #endif
                }
 #endif
 
 #if 0
-               Con_Printf("entity %i bump %i: velocity %f %f %f trace %f", ent - sv.edicts, bumpcount, ent->v->velocity[0], ent->v->velocity[1], ent->v->velocity[2], trace.fraction);
+               Con_Printf("entity %i bump %i: velocity %f %f %f trace %f", ent - prog->edicts, bumpcount, ent->fields.server->velocity[0], ent->fields.server->velocity[1], ent->fields.server->velocity[2], trace.fraction);
                if (trace.fraction < 1)
                        Con_Printf(" : %f %f %f", trace.plane.normal[0], trace.plane.normal[1], trace.plane.normal[2]);
                Con_Print("\n");
@@ -300,7 +300,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                {
                        // LordHavoc: note: this code is what makes entities stick in place if embedded in another object (which can be the world)
                        // entity is trapped in another solid
-                       VectorClear(ent->v->velocity);
+                       VectorClear(ent->fields.server->velocity);
                        return 3;
                }
                */
@@ -308,18 +308,18 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                // break if it moved the entire distance
                if (trace.fraction == 1)
                {
-                       VectorCopy(trace.endpos, ent->v->origin);
+                       VectorCopy(trace.endpos, ent->fields.server->origin);
                        break;
                }
 
                if (!trace.ent)
                        Host_Error("SV_FlyMove: !trace.ent");
 
-               if (((int) ent->v->flags & FL_ONGROUND) && ent->v->groundentity == EDICT_TO_PROG(trace.ent))
+               if (((int) ent->fields.server->flags & FL_ONGROUND) && ent->fields.server->groundentity == PRVM_EDICT_TO_PROG(trace.ent))
                        impact = false;
                else
                {
-                       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        impact = true;
                }
 
@@ -329,8 +329,8 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                        {
                                // floor
                                blocked |= 1;
-                               ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-                               ent->v->groundentity = EDICT_TO_PROG(trace.ent);
+                               ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+                               ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
                        }
                }
                else
@@ -345,8 +345,8 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                if (trace.fraction >= 0.001)
                {
                        // actually covered some distance
-                       VectorCopy(trace.endpos, ent->v->origin);
-                       VectorCopy(ent->v->velocity, original_velocity);
+                       VectorCopy(trace.endpos, ent->fields.server->origin);
+                       VectorCopy(ent->fields.server->velocity, original_velocity);
                        numplanes = 0;
                }
 
@@ -356,7 +356,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                        SV_Impact(ent, trace.ent);
 
                        // break if removed by the impact function
-                       if (ent->e->free)
+                       if (ent->priv.server->free)
                                break;
                }
 
@@ -366,7 +366,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                if (numplanes >= MAX_CLIP_PLANES)
                {
                        // this shouldn't really happen
-                       VectorClear(ent->v->velocity);
+                       VectorClear(ent->fields.server->velocity);
                        blocked = 3;
                        break;
                }
@@ -377,7 +377,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                                break;
                if (i < numplanes)
                {
-                       VectorAdd(ent->v->velocity, trace.plane.normal, ent->v->velocity);
+                       VectorAdd(ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity);
                        continue;
                }
                */
@@ -386,7 +386,7 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                numplanes++;
 
                if (sv_newflymove.integer)
-                       ClipVelocity(ent->v->velocity, trace.plane.normal, ent->v->velocity, 1);
+                       ClipVelocity(ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1);
                else
                {
                        // modify original_velocity so it parallels all of the clip planes
@@ -409,59 +409,59 @@ int SV_FlyMove (edict_t *ent, float time, float *stepnormal)
                        if (i != numplanes)
                        {
                                // go along this plane
-                               VectorCopy(new_velocity, ent->v->velocity);
+                               VectorCopy(new_velocity, ent->fields.server->velocity);
                        }
                        else
                        {
                                // go along the crease
                                if (numplanes != 2)
                                {
-                                       VectorClear(ent->v->velocity);
+                                       VectorClear(ent->fields.server->velocity);
                                        blocked = 7;
                                        break;
                                }
                                CrossProduct(planes[0], planes[1], dir);
                                // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
                                VectorNormalize(dir);
-                               d = DotProduct(dir, ent->v->velocity);
-                               VectorScale(dir, d, ent->v->velocity);
+                               d = DotProduct(dir, ent->fields.server->velocity);
+                               VectorScale(dir, d, ent->fields.server->velocity);
                        }
                }
 
                // if current velocity is against the original velocity,
                // stop dead to avoid tiny occilations in sloping corners
-               if (DotProduct(ent->v->velocity, primal_velocity) <= 0)
+               if (DotProduct(ent->fields.server->velocity, primal_velocity) <= 0)
                {
-                       VectorClear(ent->v->velocity);
+                       VectorClear(ent->fields.server->velocity);
                        break;
                }
        }
 
-       //Con_Printf("entity %i final: blocked %i velocity %f %f %f\n", ent - sv.edicts, blocked, ent->v->velocity[0], ent->v->velocity[1], ent->v->velocity[2]);
+       //Con_Printf("entity %i final: blocked %i velocity %f %f %f\n", ent - prog->edicts, blocked, ent->fields.server->velocity[0], ent->fields.server->velocity[1], ent->fields.server->velocity[2]);
 
        /*
        if ((blocked & 1) == 0 && bumpcount > 1)
        {
                // LordHavoc: fix the 'fall to your death in a wedge corner' glitch
                // flag ONGROUND if there's ground under it
-               trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+               trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
        }
        */
        return blocked;
 }
 
-int SV_SetOnGround (edict_t *ent)
+int SV_SetOnGround (prvm_edict_t *ent)
 {
        vec3_t end;
        trace_t trace;
-       if ((int)ent->v->flags & FL_ONGROUND)
+       if ((int)ent->fields.server->flags & FL_ONGROUND)
                return 1;
-       VectorSet(end, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2] - 1);
-       trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent);
+       VectorSet(end, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] - 1);
+       trace = SV_Move(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
        if (trace.fraction < 1 && trace.plane.normal[2] >= 0.7)
        {
-               ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-               ent->v->groundentity = EDICT_TO_PROG(trace.ent);
+               ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+               ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
                return 1;
        }
        return 0;
@@ -473,17 +473,17 @@ SV_AddGravity
 
 ============
 */
-void SV_AddGravity (edict_t *ent)
+void SV_AddGravity (prvm_edict_t *ent)
 {
        float ent_gravity;
-       eval_t *val;
+       prvm_eval_t *val;
 
-       val = GETEDICTFIELDVALUE(ent, eval_gravity);
+       val = PRVM_GETEDICTFIELDVALUE(ent, eval_gravity);
        if (val!=0 && val->_float)
                ent_gravity = val->_float;
        else
                ent_gravity = 1.0;
-       ent->v->velocity[2] -= ent_gravity * sv_gravity.value * sv.frametime;
+       ent->fields.server->velocity[2] -= ent_gravity * sv_gravity.value * sv.frametime;
 }
 
 
@@ -502,27 +502,27 @@ SV_PushEntity
 Does not change the entities velocity at all
 ============
 */
-trace_t SV_PushEntity (edict_t *ent, vec3_t push)
+trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push)
 {
        int type;
        trace_t trace;
        vec3_t end;
 
-       VectorAdd (ent->v->origin, push, end);
+       VectorAdd (ent->fields.server->origin, push, end);
 
-       if (ent->v->movetype == MOVETYPE_FLYMISSILE)
+       if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
                type = MOVE_MISSILE;
-       else if (ent->v->solid == SOLID_TRIGGER || ent->v->solid == SOLID_NOT)
+       else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
                type = MOVE_NOMONSTERS; // only clip against bmodels
        else
                type = MOVE_NORMAL;
 
-       trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, type, ent);
+       trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent);
 
-       VectorCopy (trace.endpos, ent->v->origin);
+       VectorCopy (trace.endpos, ent->fields.server->origin);
        SV_LinkEdict (ent, true);
 
-       if (trace.ent && (!((int)ent->v->flags & FL_ONGROUND) || ent->v->groundentity != EDICT_TO_PROG(trace.ent)))
+       if (trace.ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace.ent)))
                SV_Impact (ent, trace.ent);
        return trace;
 }
@@ -534,26 +534,26 @@ SV_PushMove
 
 ============
 */
-trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
-void SV_PushMove (edict_t *pusher, float movetime)
+trace_t SV_ClipMoveToEntity (prvm_edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
+void SV_PushMove (prvm_edict_t *pusher, float movetime)
 {
        int i, e, index;
-       edict_t *check, *ed;
+       prvm_edict_t *check, *ed;
        float savesolid, movetime2, pushltime;
        vec3_t mins, maxs, move, move1, moveangle, pushorig, pushang, a, forward, left, up, org, org2;
        int num_moved;
        int numcheckentities;
-       static edict_t *checkentities[MAX_EDICTS];
+       static prvm_edict_t *checkentities[MAX_EDICTS];
        model_t *pushermodel;
        trace_t trace;
 
-       if (!pusher->v->velocity[0] && !pusher->v->velocity[1] && !pusher->v->velocity[2] && !pusher->v->avelocity[0] && !pusher->v->avelocity[1] && !pusher->v->avelocity[2])
+       if (!pusher->fields.server->velocity[0] && !pusher->fields.server->velocity[1] && !pusher->fields.server->velocity[2] && !pusher->fields.server->avelocity[0] && !pusher->fields.server->avelocity[1] && !pusher->fields.server->avelocity[2])
        {
-               pusher->v->ltime += movetime;
+               pusher->fields.server->ltime += movetime;
                return;
        }
 
-       switch ((int) pusher->v->solid)
+       switch ((int) pusher->fields.server->solid)
        {
        // LordHavoc: valid pusher types
        case SOLID_BSP:
@@ -564,42 +564,42 @@ void SV_PushMove (edict_t *pusher, float movetime)
        // LordHavoc: no collisions
        case SOLID_NOT:
        case SOLID_TRIGGER:
-               VectorMA (pusher->v->origin, movetime, pusher->v->velocity, pusher->v->origin);
-               VectorMA (pusher->v->angles, movetime, pusher->v->avelocity, pusher->v->angles);
-               pusher->v->angles[0] -= 360.0 * floor(pusher->v->angles[0] * (1.0 / 360.0));
-               pusher->v->angles[1] -= 360.0 * floor(pusher->v->angles[1] * (1.0 / 360.0));
-               pusher->v->angles[2] -= 360.0 * floor(pusher->v->angles[2] * (1.0 / 360.0));
-               pusher->v->ltime += movetime;
+               VectorMA (pusher->fields.server->origin, movetime, pusher->fields.server->velocity, pusher->fields.server->origin);
+               VectorMA (pusher->fields.server->angles, movetime, pusher->fields.server->avelocity, pusher->fields.server->angles);
+               pusher->fields.server->angles[0] -= 360.0 * floor(pusher->fields.server->angles[0] * (1.0 / 360.0));
+               pusher->fields.server->angles[1] -= 360.0 * floor(pusher->fields.server->angles[1] * (1.0 / 360.0));
+               pusher->fields.server->angles[2] -= 360.0 * floor(pusher->fields.server->angles[2] * (1.0 / 360.0));
+               pusher->fields.server->ltime += movetime;
                SV_LinkEdict (pusher, false);
                return;
        default:
-               Con_Printf("SV_PushMove: unrecognized solid type %f\n", pusher->v->solid);
+               Con_Printf("SV_PushMove: unrecognized solid type %f\n", pusher->fields.server->solid);
                return;
        }
-       index = (int) pusher->v->modelindex;
+       index = (int) pusher->fields.server->modelindex;
        if (index < 1 || index >= MAX_MODELS)
        {
-               Con_Printf("SV_PushMove: invalid modelindex %f\n", pusher->v->modelindex);
+               Con_Printf("SV_PushMove: invalid modelindex %f\n", pusher->fields.server->modelindex);
                return;
        }
        pushermodel = sv.models[index];
 
        movetime2 = movetime;
-       VectorScale(pusher->v->velocity, movetime2, move1);
-       VectorScale(pusher->v->avelocity, movetime2, moveangle);
+       VectorScale(pusher->fields.server->velocity, movetime2, move1);
+       VectorScale(pusher->fields.server->avelocity, movetime2, moveangle);
        if (moveangle[0] || moveangle[2])
        {
                for (i = 0;i < 3;i++)
                {
                        if (move1[i] > 0)
                        {
-                               mins[i] = pushermodel->rotatedmins[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->rotatedmaxs[i] + move1[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->rotatedmins[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->rotatedmaxs[i] + move1[i] + pusher->fields.server->origin[i] + 1;
                        }
                        else
                        {
-                               mins[i] = pushermodel->rotatedmins[i] + move1[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->rotatedmaxs[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->rotatedmins[i] + move1[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->rotatedmaxs[i] + pusher->fields.server->origin[i] + 1;
                        }
                }
        }
@@ -609,13 +609,13 @@ void SV_PushMove (edict_t *pusher, float movetime)
                {
                        if (move1[i] > 0)
                        {
-                               mins[i] = pushermodel->yawmins[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->yawmaxs[i] + move1[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->yawmins[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->yawmaxs[i] + move1[i] + pusher->fields.server->origin[i] + 1;
                        }
                        else
                        {
-                               mins[i] = pushermodel->yawmins[i] + move1[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->yawmaxs[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->yawmins[i] + move1[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->yawmaxs[i] + pusher->fields.server->origin[i] + 1;
                        }
                }
        }
@@ -625,13 +625,13 @@ void SV_PushMove (edict_t *pusher, float movetime)
                {
                        if (move1[i] > 0)
                        {
-                               mins[i] = pushermodel->normalmins[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->normalmaxs[i] + move1[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->normalmins[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->normalmaxs[i] + move1[i] + pusher->fields.server->origin[i] + 1;
                        }
                        else
                        {
-                               mins[i] = pushermodel->normalmins[i] + move1[i] + pusher->v->origin[i] - 1;
-                               maxs[i] = pushermodel->normalmaxs[i] + pusher->v->origin[i] + 1;
+                               mins[i] = pushermodel->normalmins[i] + move1[i] + pusher->fields.server->origin[i] - 1;
+                               maxs[i] = pushermodel->normalmaxs[i] + pusher->fields.server->origin[i] + 1;
                        }
                }
        }
@@ -639,18 +639,18 @@ void SV_PushMove (edict_t *pusher, float movetime)
        VectorNegate (moveangle, a);
        AngleVectorsFLU (a, forward, left, up);
 
-       VectorCopy (pusher->v->origin, pushorig);
-       VectorCopy (pusher->v->angles, pushang);
-       pushltime = pusher->v->ltime;
+       VectorCopy (pusher->fields.server->origin, pushorig);
+       VectorCopy (pusher->fields.server->angles, pushang);
+       pushltime = pusher->fields.server->ltime;
 
 // move the pusher to it's final position
 
-       VectorMA (pusher->v->origin, movetime, pusher->v->velocity, pusher->v->origin);
-       VectorMA (pusher->v->angles, movetime, pusher->v->avelocity, pusher->v->angles);
-       pusher->v->ltime += movetime;
+       VectorMA (pusher->fields.server->origin, movetime, pusher->fields.server->velocity, pusher->fields.server->origin);
+       VectorMA (pusher->fields.server->angles, movetime, pusher->fields.server->avelocity, pusher->fields.server->angles);
+       pusher->fields.server->ltime += movetime;
        SV_LinkEdict (pusher, false);
 
-       savesolid = pusher->v->solid;
+       savesolid = pusher->fields.server->solid;
 
 // see if any solid entities are inside the final position
        num_moved = 0;
@@ -659,21 +659,21 @@ void SV_PushMove (edict_t *pusher, float movetime)
        for (e = 0;e < numcheckentities;e++)
        {
                check = checkentities[e];
-               if (check->v->movetype == MOVETYPE_PUSH
-                || check->v->movetype == MOVETYPE_NONE
-                || check->v->movetype == MOVETYPE_FOLLOW
-                || check->v->movetype == MOVETYPE_NOCLIP
-                || check->v->movetype == MOVETYPE_FAKEPUSH)
+               if (check->fields.server->movetype == MOVETYPE_PUSH
+                || check->fields.server->movetype == MOVETYPE_NONE
+                || check->fields.server->movetype == MOVETYPE_FOLLOW
+                || check->fields.server->movetype == MOVETYPE_NOCLIP
+                || check->fields.server->movetype == MOVETYPE_FAKEPUSH)
                        continue;
 
                // if the entity is standing on the pusher, it will definitely be moved
-               if (!(((int)check->v->flags & FL_ONGROUND) && PROG_TO_EDICT(check->v->groundentity) == pusher))
-                       if (!SV_ClipMoveToEntity(pusher, check->v->origin, check->v->mins, check->v->maxs, check->v->origin).startsolid)
+               if (!(((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher))
+                       if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin).startsolid)
                                continue;
 
                if (forward[0] != 1 || left[1] != 1) // quick way to check if any rotation is used
                {
-                       VectorSubtract (check->v->origin, pusher->v->origin, org);
+                       VectorSubtract (check->fields.server->origin, pusher->fields.server->origin, org);
                        org2[0] = DotProduct (org, forward);
                        org2[1] = DotProduct (org, left);
                        org2[2] = DotProduct (org, up);
@@ -684,71 +684,71 @@ void SV_PushMove (edict_t *pusher, float movetime)
                        VectorCopy (move1, move);
 
                // remove the onground flag for non-players
-               if (check->v->movetype != MOVETYPE_WALK)
-                       check->v->flags = (int)check->v->flags & ~FL_ONGROUND;
+               if (check->fields.server->movetype != MOVETYPE_WALK)
+                       check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND;
 
-               VectorCopy (check->v->origin, check->e->moved_from);
-               VectorCopy (check->v->angles, check->e->moved_fromangles);
+               VectorCopy (check->fields.server->origin, check->priv.server->moved_from);
+               VectorCopy (check->fields.server->angles, check->priv.server->moved_fromangles);
                sv.moved_edicts[num_moved++] = check;
 
                // try moving the contacted entity
-               pusher->v->solid = SOLID_NOT;
+               pusher->fields.server->solid = SOLID_NOT;
                trace = SV_PushEntity (check, move);
                // FIXME: turn players specially
-               check->v->angles[1] += trace.fraction * moveangle[1];
-               pusher->v->solid = savesolid; // was SOLID_BSP
+               check->fields.server->angles[1] += trace.fraction * moveangle[1];
+               pusher->fields.server->solid = savesolid; // was SOLID_BSP
 
                // if it is still inside the pusher, block
-               if (SV_ClipMoveToEntity(pusher, check->v->origin, check->v->mins, check->v->maxs, check->v->origin).startsolid)
+               if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin).startsolid)
                {
                        // try moving the contacted entity a tiny bit further to account for precision errors
-                       pusher->v->solid = SOLID_NOT;
+                       pusher->fields.server->solid = SOLID_NOT;
                        VectorScale(move, 0.1, move);
                        SV_PushEntity (check, move);
-                       pusher->v->solid = savesolid;
-                       if (SV_ClipMoveToEntity(pusher, check->v->origin, check->v->mins, check->v->maxs, check->v->origin).startsolid)
+                       pusher->fields.server->solid = savesolid;
+                       if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin).startsolid)
                        {
                                // still inside pusher, so it's really blocked
 
                                // fail the move
-                               if (check->v->mins[0] == check->v->maxs[0])
+                               if (check->fields.server->mins[0] == check->fields.server->maxs[0])
                                        continue;
-                               if (check->v->solid == SOLID_NOT || check->v->solid == SOLID_TRIGGER)
+                               if (check->fields.server->solid == SOLID_NOT || check->fields.server->solid == SOLID_TRIGGER)
                                {
                                        // corpse
-                                       check->v->mins[0] = check->v->mins[1] = 0;
-                                       VectorCopy (check->v->mins, check->v->maxs);
+                                       check->fields.server->mins[0] = check->fields.server->mins[1] = 0;
+                                       VectorCopy (check->fields.server->mins, check->fields.server->maxs);
                                        continue;
                                }
 
-                               VectorCopy (pushorig, pusher->v->origin);
-                               VectorCopy (pushang, pusher->v->angles);
-                               pusher->v->ltime = pushltime;
+                               VectorCopy (pushorig, pusher->fields.server->origin);
+                               VectorCopy (pushang, pusher->fields.server->angles);
+                               pusher->fields.server->ltime = pushltime;
                                SV_LinkEdict (pusher, false);
 
                                // move back any entities we already moved
                                for (i = 0;i < num_moved;i++)
                                {
                                        ed = sv.moved_edicts[i];
-                                       VectorCopy (ed->e->moved_from, ed->v->origin);
-                                       VectorCopy (ed->e->moved_fromangles, ed->v->angles);
+                                       VectorCopy (ed->priv.server->moved_from, ed->fields.server->origin);
+                                       VectorCopy (ed->priv.server->moved_fromangles, ed->fields.server->angles);
                                        SV_LinkEdict (ed, false);
                                }
 
                                // if the pusher has a "blocked" function, call it, otherwise just stay in place until the obstacle is gone
-                               if (pusher->v->blocked)
+                               if (pusher->fields.server->blocked)
                                {
-                                       pr_global_struct->self = EDICT_TO_PROG(pusher);
-                                       pr_global_struct->other = EDICT_TO_PROG(check);
-                                       PR_ExecuteProgram (pusher->v->blocked, "QC function self.blocked is missing");
+                                       prog->globals.server->self = PRVM_EDICT_TO_PROG(pusher);
+                                       prog->globals.server->other = PRVM_EDICT_TO_PROG(check);
+                                       PRVM_ExecuteProgram (pusher->fields.server->blocked, "QC function self.blocked is missing");
                                }
                                break;
                        }
                }
        }
-       pusher->v->angles[0] -= 360.0 * floor(pusher->v->angles[0] * (1.0 / 360.0));
-       pusher->v->angles[1] -= 360.0 * floor(pusher->v->angles[1] * (1.0 / 360.0));
-       pusher->v->angles[2] -= 360.0 * floor(pusher->v->angles[2] * (1.0 / 360.0));
+       pusher->fields.server->angles[0] -= 360.0 * floor(pusher->fields.server->angles[0] * (1.0 / 360.0));
+       pusher->fields.server->angles[1] -= 360.0 * floor(pusher->fields.server->angles[1] * (1.0 / 360.0));
+       pusher->fields.server->angles[2] -= 360.0 * floor(pusher->fields.server->angles[2] * (1.0 / 360.0));
 }
 
 /*
@@ -757,16 +757,16 @@ SV_Physics_Pusher
 
 ================
 */
-void SV_Physics_Pusher (edict_t *ent)
+void SV_Physics_Pusher (prvm_edict_t *ent)
 {
        float thinktime, oldltime, movetime;
 
-       oldltime = ent->v->ltime;
+       oldltime = ent->fields.server->ltime;
 
-       thinktime = ent->v->nextthink;
-       if (thinktime < ent->v->ltime + sv.frametime)
+       thinktime = ent->fields.server->nextthink;
+       if (thinktime < ent->fields.server->ltime + sv.frametime)
        {
-               movetime = thinktime - ent->v->ltime;
+               movetime = thinktime - ent->fields.server->ltime;
                if (movetime < 0)
                        movetime = 0;
        }
@@ -774,16 +774,16 @@ void SV_Physics_Pusher (edict_t *ent)
                movetime = sv.frametime;
 
        if (movetime)
-               // advances ent->v->ltime if not blocked
+               // advances ent->fields.server->ltime if not blocked
                SV_PushMove (ent, movetime);
 
-       if (thinktime > oldltime && thinktime <= ent->v->ltime)
+       if (thinktime > oldltime && thinktime <= ent->fields.server->ltime)
        {
-               ent->v->nextthink = 0;
-               pr_global_struct->time = sv.time;
-               pr_global_struct->self = EDICT_TO_PROG(ent);
-               pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
-               PR_ExecuteProgram (ent->v->think, "QC function self.think is missing");
+               ent->fields.server->nextthink = 0;
+               prog->globals.server->time = sv.time;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+               prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
+               PRVM_ExecuteProgram (ent->fields.server->think, "QC function self.think is missing");
        }
 }
 
@@ -804,19 +804,19 @@ This is a big hack to try and fix the rare case of getting stuck in the world
 clipping hull.
 =============
 */
-void SV_CheckStuck (edict_t *ent)
+void SV_CheckStuck (prvm_edict_t *ent)
 {
        int i, j, z;
        vec3_t org;
 
        if (!SV_TestEntityPosition(ent))
        {
-               VectorCopy (ent->v->origin, ent->v->oldorigin);
+               VectorCopy (ent->fields.server->origin, ent->fields.server->oldorigin);
                return;
        }
 
-       VectorCopy (ent->v->origin, org);
-       VectorCopy (ent->v->oldorigin, ent->v->origin);
+       VectorCopy (ent->fields.server->origin, org);
+       VectorCopy (ent->fields.server->oldorigin, ent->fields.server->origin);
        if (!SV_TestEntityPosition(ent))
        {
                Con_DPrint("Unstuck.\n");
@@ -828,9 +828,9 @@ void SV_CheckStuck (edict_t *ent)
                for (i=-1 ; i <= 1 ; i++)
                        for (j=-1 ; j <= 1 ; j++)
                        {
-                               ent->v->origin[0] = org[0] + i;
-                               ent->v->origin[1] = org[1] + j;
-                               ent->v->origin[2] = org[2] + z;
+                               ent->fields.server->origin[0] = org[0] + i;
+                               ent->fields.server->origin[1] = org[1] + j;
+                               ent->fields.server->origin[2] = org[2] + z;
                                if (!SV_TestEntityPosition(ent))
                                {
                                        Con_DPrint("Unstuck.\n");
@@ -839,7 +839,7 @@ void SV_CheckStuck (edict_t *ent)
                                }
                        }
 
-       VectorCopy (org, ent->v->origin);
+       VectorCopy (org, ent->fields.server->origin);
        Con_DPrint("player is stuck.\n");
 }
 
@@ -849,33 +849,33 @@ void SV_CheckStuck (edict_t *ent)
 SV_CheckWater
 =============
 */
-qboolean SV_CheckWater (edict_t *ent)
+qboolean SV_CheckWater (prvm_edict_t *ent)
 {
        int cont;
        vec3_t point;
 
-       point[0] = ent->v->origin[0];
-       point[1] = ent->v->origin[1];
-       point[2] = ent->v->origin[2] + ent->v->mins[2] + 1;
+       point[0] = ent->fields.server->origin[0];
+       point[1] = ent->fields.server->origin[1];
+       point[2] = ent->fields.server->origin[2] + ent->fields.server->mins[2] + 1;
 
-       ent->v->waterlevel = 0;
-       ent->v->watertype = CONTENTS_EMPTY;
+       ent->fields.server->waterlevel = 0;
+       ent->fields.server->watertype = CONTENTS_EMPTY;
        cont = SV_PointSuperContents(point);
        if (cont & (SUPERCONTENTS_LIQUIDSMASK))
        {
-               ent->v->watertype = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cont);
-               ent->v->waterlevel = 1;
-               point[2] = ent->v->origin[2] + (ent->v->mins[2] + ent->v->maxs[2])*0.5;
+               ent->fields.server->watertype = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cont);
+               ent->fields.server->waterlevel = 1;
+               point[2] = ent->fields.server->origin[2] + (ent->fields.server->mins[2] + ent->fields.server->maxs[2])*0.5;
                if (SV_PointSuperContents(point) & (SUPERCONTENTS_LIQUIDSMASK))
                {
-                       ent->v->waterlevel = 2;
-                       point[2] = ent->v->origin[2] + ent->v->view_ofs[2];
+                       ent->fields.server->waterlevel = 2;
+                       point[2] = ent->fields.server->origin[2] + ent->fields.server->view_ofs[2];
                        if (SV_PointSuperContents(point) & (SUPERCONTENTS_LIQUIDSMASK))
-                               ent->v->waterlevel = 3;
+                               ent->fields.server->waterlevel = 3;
                }
        }
 
-       return ent->v->waterlevel > 1;
+       return ent->fields.server->waterlevel > 1;
 }
 
 /*
@@ -884,20 +884,20 @@ SV_WallFriction
 
 ============
 */
-void SV_WallFriction (edict_t *ent, float *stepnormal)
+void SV_WallFriction (prvm_edict_t *ent, float *stepnormal)
 {
        float d, i;
        vec3_t forward, into, side;
 
-       AngleVectors (ent->v->v_angle, forward, NULL, NULL);
+       AngleVectors (ent->fields.server->v_angle, forward, NULL, NULL);
        if ((d = DotProduct (stepnormal, forward) + 0.5) < 0)
        {
                // cut the tangential velocity
-               i = DotProduct (stepnormal, ent->v->velocity);
+               i = DotProduct (stepnormal, ent->fields.server->velocity);
                VectorScale (stepnormal, i, into);
-               VectorSubtract (ent->v->velocity, into, side);
-               ent->v->velocity[0] = side[0] * (1 + d);
-               ent->v->velocity[1] = side[1] * (1 + d);
+               VectorSubtract (ent->fields.server->velocity, into, side);
+               ent->fields.server->velocity[0] = side[0] * (1 + d);
+               ent->fields.server->velocity[1] = side[1] * (1 + d);
        }
 }
 
@@ -913,12 +913,12 @@ Try fixing by pushing one pixel in each direction.
 This is a hack, but in the interest of good gameplay...
 ======================
 */
-int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
+int SV_TryUnstick (prvm_edict_t *ent, vec3_t oldvel)
 {
        int i, clip;
        vec3_t oldorg, dir;
 
-       VectorCopy (ent->v->origin, oldorg);
+       VectorCopy (ent->fields.server->origin, oldorg);
        VectorClear (dir);
 
        for (i=0 ; i<8 ; i++)
@@ -939,24 +939,24 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
                SV_PushEntity (ent, dir);
 
                // retry the original move
-               ent->v->velocity[0] = oldvel[0];
-               ent->v->velocity[1] = oldvel[1];
-               ent->v->velocity[2] = 0;
+               ent->fields.server->velocity[0] = oldvel[0];
+               ent->fields.server->velocity[1] = oldvel[1];
+               ent->fields.server->velocity[2] = 0;
                clip = SV_FlyMove (ent, 0.1, NULL);
 
-               if (fabs(oldorg[1] - ent->v->origin[1]) > 4
-                || fabs(oldorg[0] - ent->v->origin[0]) > 4)
+               if (fabs(oldorg[1] - ent->fields.server->origin[1]) > 4
+                || fabs(oldorg[0] - ent->fields.server->origin[0]) > 4)
                {
                        Con_DPrint("TryUnstick - success.\n");
                        return clip;
                }
 
                // go back to the original pos and try again
-               VectorCopy (oldorg, ent->v->origin);
+               VectorCopy (oldorg, ent->fields.server->origin);
        }
 
        // still not moving
-       VectorClear (ent->v->velocity);
+       VectorClear (ent->fields.server->velocity);
        Con_DPrint("TryUnstick - failure.\n");
        return 7;
 }
@@ -968,7 +968,7 @@ SV_WalkMove
 Only used by players
 ======================
 */
-void SV_WalkMove (edict_t *ent)
+void SV_WalkMove (prvm_edict_t *ent)
 {
        int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity;
        vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity;
@@ -977,24 +977,24 @@ void SV_WalkMove (edict_t *ent)
        SV_CheckVelocity(ent);
 
        // do a regular slide move unless it looks like you ran into a step
-       oldonground = (int)ent->v->flags & FL_ONGROUND;
-       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+       oldonground = (int)ent->fields.server->flags & FL_ONGROUND;
+       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
 
-       VectorCopy (ent->v->origin, start_origin);
-       VectorCopy (ent->v->velocity, start_velocity);
+       VectorCopy (ent->fields.server->origin, start_origin);
+       VectorCopy (ent->fields.server->velocity, start_velocity);
 
        clip = SV_FlyMove (ent, sv.frametime, NULL);
 
        SV_SetOnGround (ent);
        SV_CheckVelocity(ent);
 
-       VectorCopy(ent->v->origin, originalmove_origin);
-       VectorCopy(ent->v->velocity, originalmove_velocity);
+       VectorCopy(ent->fields.server->origin, originalmove_origin);
+       VectorCopy(ent->fields.server->velocity, originalmove_velocity);
        originalmove_clip = clip;
-       originalmove_flags = (int)ent->v->flags;
-       originalmove_groundentity = ent->v->groundentity;
+       originalmove_flags = (int)ent->fields.server->flags;
+       originalmove_groundentity = ent->fields.server->groundentity;
 
-       if ((int)ent->v->flags & FL_WATERJUMP)
+       if ((int)ent->fields.server->flags & FL_WATERJUMP)
                return;
 
        if (sv_nostep.integer)
@@ -1007,22 +1007,22 @@ void SV_WalkMove (edict_t *ent)
                if (fabs(start_velocity[0]) < 0.03125 && fabs(start_velocity[1]) < 0.03125)
                        return;
 
-               if (ent->v->movetype != MOVETYPE_FLY)
+               if (ent->fields.server->movetype != MOVETYPE_FLY)
                {
                        // return if gibbed by a trigger
-                       if (ent->v->movetype != MOVETYPE_WALK)
+                       if (ent->fields.server->movetype != MOVETYPE_WALK)
                                return;
 
                        // only step up while jumping if that is enabled
                        if (!(sv_jumpstep.integer && sv_gameplayfix_stepwhilejumping.integer))
-                               if (!oldonground && ent->v->waterlevel == 0)
+                               if (!oldonground && ent->fields.server->waterlevel == 0)
                                        return;
                }
 
                // try moving up and forward to go up a step
                // back to start pos
-               VectorCopy (start_origin, ent->v->origin);
-               VectorCopy (start_velocity, ent->v->velocity);
+               VectorCopy (start_origin, ent->fields.server->origin);
+               VectorCopy (start_velocity, ent->fields.server->velocity);
 
                // move up
                VectorClear (upmove);
@@ -1031,25 +1031,25 @@ void SV_WalkMove (edict_t *ent)
                SV_PushEntity(ent, upmove);
 
                // move forward
-               ent->v->velocity[2] = 0;
+               ent->fields.server->velocity[2] = 0;
                clip = SV_FlyMove (ent, sv.frametime, stepnormal);
-               ent->v->velocity[2] += start_velocity[2];
+               ent->fields.server->velocity[2] += start_velocity[2];
 
                SV_CheckVelocity(ent);
 
                // check for stuckness, possibly due to the limited precision of floats
                // in the clipping hulls
                if (clip
-                && fabs(originalmove_origin[1] - ent->v->origin[1]) < 0.03125
-                && fabs(originalmove_origin[0] - ent->v->origin[0]) < 0.03125)
+                && fabs(originalmove_origin[1] - ent->fields.server->origin[1]) < 0.03125
+                && fabs(originalmove_origin[0] - ent->fields.server->origin[0]) < 0.03125)
                {
                        //Con_Printf("wall\n");
                        // stepping up didn't make any progress, revert to original move
-                       VectorCopy(originalmove_origin, ent->v->origin);
-                       VectorCopy(originalmove_velocity, ent->v->velocity);
+                       VectorCopy(originalmove_origin, ent->fields.server->origin);
+                       VectorCopy(originalmove_velocity, ent->fields.server->velocity);
                        //clip = originalmove_clip;
-                       ent->v->flags = originalmove_flags;
-                       ent->v->groundentity = originalmove_groundentity;
+                       ent->fields.server->flags = originalmove_flags;
+                       ent->fields.server->groundentity = originalmove_groundentity;
                        // now try to unstick if needed
                        //clip = SV_TryUnstick (ent, oldvel);
                        return;
@@ -1062,7 +1062,7 @@ void SV_WalkMove (edict_t *ent)
                        SV_WallFriction (ent, stepnormal);
        }
        // skip out if stepdown is enabled, moving downward, not in water, and the move started onground and ended offground
-       else if (!(sv_gameplayfix_stepdown.integer && ent->v->waterlevel < 2 && start_velocity[2] < (1.0 / 32.0) && oldonground && !((int)ent->v->flags & FL_ONGROUND)))
+       else if (!(sv_gameplayfix_stepdown.integer && ent->fields.server->waterlevel < 2 && start_velocity[2] < (1.0 / 32.0) && oldonground && !((int)ent->fields.server->flags & FL_ONGROUND)))
                return;
 
        // move down
@@ -1074,11 +1074,11 @@ void SV_WalkMove (edict_t *ent)
        if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7)
        {
                // LordHavoc: disabled this check so you can walk on monsters/players
-               //if (ent->v->solid == SOLID_BSP)
+               //if (ent->fields.server->solid == SOLID_BSP)
                {
                        //Con_Printf("onground\n");
-                       ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-                       ent->v->groundentity = EDICT_TO_PROG(downtrace.ent);
+                       ent->fields.server->flags =     (int)ent->fields.server->flags | FL_ONGROUND;
+                       ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(downtrace.ent);
                }
        }
        else
@@ -1087,11 +1087,11 @@ void SV_WalkMove (edict_t *ent)
                // if the push down didn't end up on good ground, use the move without
                // the step up.  This happens near wall / slope combinations, and can
                // cause the player to hop up higher on a slope too steep to climb
-               VectorCopy(originalmove_origin, ent->v->origin);
-               VectorCopy(originalmove_velocity, ent->v->velocity);
+               VectorCopy(originalmove_origin, ent->fields.server->origin);
+               VectorCopy(originalmove_velocity, ent->fields.server->velocity);
                //clip = originalmove_clip;
-               ent->v->flags = originalmove_flags;
-               ent->v->groundentity = originalmove_groundentity;
+               ent->fields.server->flags = originalmove_flags;
+               ent->fields.server->groundentity = originalmove_groundentity;
        }
 
        SV_SetOnGround (ent);
@@ -1107,40 +1107,40 @@ SV_Physics_Follow
 Entities that are "stuck" to another entity
 =============
 */
-void SV_Physics_Follow (edict_t *ent)
+void SV_Physics_Follow (prvm_edict_t *ent)
 {
        vec3_t vf, vr, vu, angles, v;
-       edict_t *e;
+       prvm_edict_t *e;
 
        // regular thinking
        if (!SV_RunThink (ent))
                return;
 
        // LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
-       e = PROG_TO_EDICT(ent->v->aiment);
-       if (e->v->angles[0] == ent->v->punchangle[0] && e->v->angles[1] == ent->v->punchangle[1] && e->v->angles[2] == ent->v->punchangle[2])
+       e = PRVM_PROG_TO_EDICT(ent->fields.server->aiment);
+       if (e->fields.server->angles[0] == ent->fields.server->punchangle[0] && e->fields.server->angles[1] == ent->fields.server->punchangle[1] && e->fields.server->angles[2] == ent->fields.server->punchangle[2])
        {
                // quick case for no rotation
-               VectorAdd(e->v->origin, ent->v->view_ofs, ent->v->origin);
+               VectorAdd(e->fields.server->origin, ent->fields.server->view_ofs, ent->fields.server->origin);
        }
        else
        {
-               angles[0] = -ent->v->punchangle[0];
-               angles[1] =  ent->v->punchangle[1];
-               angles[2] =  ent->v->punchangle[2];
+               angles[0] = -ent->fields.server->punchangle[0];
+               angles[1] =  ent->fields.server->punchangle[1];
+               angles[2] =  ent->fields.server->punchangle[2];
                AngleVectors (angles, vf, vr, vu);
-               v[0] = ent->v->view_ofs[0] * vf[0] + ent->v->view_ofs[1] * vr[0] + ent->v->view_ofs[2] * vu[0];
-               v[1] = ent->v->view_ofs[0] * vf[1] + ent->v->view_ofs[1] * vr[1] + ent->v->view_ofs[2] * vu[1];
-               v[2] = ent->v->view_ofs[0] * vf[2] + ent->v->view_ofs[1] * vr[2] + ent->v->view_ofs[2] * vu[2];
-               angles[0] = -e->v->angles[0];
-               angles[1] =  e->v->angles[1];
-               angles[2] =  e->v->angles[2];
+               v[0] = ent->fields.server->view_ofs[0] * vf[0] + ent->fields.server->view_ofs[1] * vr[0] + ent->fields.server->view_ofs[2] * vu[0];
+               v[1] = ent->fields.server->view_ofs[0] * vf[1] + ent->fields.server->view_ofs[1] * vr[1] + ent->fields.server->view_ofs[2] * vu[1];
+               v[2] = ent->fields.server->view_ofs[0] * vf[2] + ent->fields.server->view_ofs[1] * vr[2] + ent->fields.server->view_ofs[2] * vu[2];
+               angles[0] = -e->fields.server->angles[0];
+               angles[1] =  e->fields.server->angles[1];
+               angles[2] =  e->fields.server->angles[2];
                AngleVectors (angles, vf, vr, vu);
-               ent->v->origin[0] = v[0] * vf[0] + v[1] * vf[1] + v[2] * vf[2] + e->v->origin[0];
-               ent->v->origin[1] = v[0] * vr[0] + v[1] * vr[1] + v[2] * vr[2] + e->v->origin[1];
-               ent->v->origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->v->origin[2];
+               ent->fields.server->origin[0] = v[0] * vf[0] + v[1] * vf[1] + v[2] * vf[2] + e->fields.server->origin[0];
+               ent->fields.server->origin[1] = v[0] * vr[0] + v[1] * vr[1] + v[2] * vr[2] + e->fields.server->origin[1];
+               ent->fields.server->origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->fields.server->origin[2];
        }
-       VectorAdd (e->v->angles, ent->v->v_angle, ent->v->angles);
+       VectorAdd (e->fields.server->angles, ent->fields.server->v_angle, ent->fields.server->angles);
        SV_LinkEdict (ent, true);
 }
 
@@ -1158,31 +1158,31 @@ SV_CheckWaterTransition
 
 =============
 */
-void SV_CheckWaterTransition (edict_t *ent)
+void SV_CheckWaterTransition (prvm_edict_t *ent)
 {
        int cont;
-       cont = SV_PointQ1Contents(ent->v->origin);
-       if (!ent->v->watertype)
+       cont = SV_PointQ1Contents(ent->fields.server->origin);
+       if (!ent->fields.server->watertype)
        {
                // just spawned here
-               ent->v->watertype = cont;
-               ent->v->waterlevel = 1;
+               ent->fields.server->watertype = cont;
+               ent->fields.server->waterlevel = 1;
                return;
        }
 
        // check if the entity crossed into or out of water
-       if ((ent->v->watertype == CONTENTS_WATER || ent->v->watertype == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME))
+       if ((ent->fields.server->watertype == CONTENTS_WATER || ent->fields.server->watertype == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME))
                SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
 
        if (cont <= CONTENTS_WATER)
        {
-               ent->v->watertype = cont;
-               ent->v->waterlevel = 1;
+               ent->fields.server->watertype = cont;
+               ent->fields.server->waterlevel = 1;
        }
        else
        {
-               ent->v->watertype = CONTENTS_EMPTY;
-               ent->v->waterlevel = 0;
+               ent->fields.server->watertype = CONTENTS_EMPTY;
+               ent->fields.server->waterlevel = 0;
        }
 }
 
@@ -1193,98 +1193,98 @@ SV_Physics_Toss
 Toss, bounce, and fly movement.  When onground, do nothing.
 =============
 */
-void SV_Physics_Toss (edict_t *ent)
+void SV_Physics_Toss (prvm_edict_t *ent)
 {
        trace_t trace;
        vec3_t move;
 
        // don't stick to ground if onground and moving upward
-       if (ent->v->velocity[2] >= (1.0 / 32.0) && ((int)ent->v->flags & FL_ONGROUND))
-               ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+       if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && ((int)ent->fields.server->flags & FL_ONGROUND))
+               ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
 
 // if onground, return without moving
-       if ((int)ent->v->flags & FL_ONGROUND)
+       if ((int)ent->fields.server->flags & FL_ONGROUND)
        {
-               if (ent->v->groundentity == 0 || sv_gameplayfix_noairborncorpse.integer)
+               if (ent->fields.server->groundentity == 0 || sv_gameplayfix_noairborncorpse.integer)
                        return;
                // if ent was supported by a brush model on previous frame,
                // and groundentity is now freed, set groundentity to 0 (floating)
-               if (ent->e->suspendedinairflag && PROG_TO_EDICT(ent->v->groundentity)->e->free)
+               if (ent->priv.server->suspendedinairflag && PRVM_PROG_TO_EDICT(ent->fields.server->groundentity)->priv.server->free)
                {
                        // leave it suspended in the air
-                       ent->v->groundentity = 0;
+                       ent->fields.server->groundentity = 0;
                        return;
                }
        }
-       ent->e->suspendedinairflag = false;
+       ent->priv.server->suspendedinairflag = false;
 
        SV_CheckVelocity (ent);
 
 // add gravity
-       if (ent->v->movetype == MOVETYPE_TOSS || ent->v->movetype == MOVETYPE_BOUNCE)
+       if (ent->fields.server->movetype == MOVETYPE_TOSS || ent->fields.server->movetype == MOVETYPE_BOUNCE)
                SV_AddGravity (ent);
 
 // move angles
-       VectorMA (ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
+       VectorMA (ent->fields.server->angles, sv.frametime, ent->fields.server->avelocity, ent->fields.server->angles);
 
 // move origin
-       VectorScale (ent->v->velocity, sv.frametime, move);
+       VectorScale (ent->fields.server->velocity, sv.frametime, move);
        trace = SV_PushEntity (ent, move);
-       if (ent->e->free)
+       if (ent->priv.server->free)
                return;
 
        if (trace.fraction < 1)
        {
-               if (ent->v->movetype == MOVETYPE_BOUNCEMISSILE)
+               if (ent->fields.server->movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, 2.0);
-                       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                       ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 2.0);
+                       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                }
-               else if (ent->v->movetype == MOVETYPE_BOUNCE)
+               else if (ent->fields.server->movetype == MOVETYPE_BOUNCE)
                {
                        float d;
-                       ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, 1.5);
+                       ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1.5);
                        // LordHavoc: fixed grenades not bouncing when fired down a slope
                        if (sv_gameplayfix_grenadebouncedownslopes.integer)
                        {
-                               d = DotProduct(trace.plane.normal, ent->v->velocity);
+                               d = DotProduct(trace.plane.normal, ent->fields.server->velocity);
                                if (trace.plane.normal[2] > 0.7 && fabs(d) < 60)
                                {
-                                       ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-                                       ent->v->groundentity = EDICT_TO_PROG(trace.ent);
-                                       VectorClear (ent->v->velocity);
-                                       VectorClear (ent->v->avelocity);
+                                       ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+                                       ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+                                       VectorClear (ent->fields.server->velocity);
+                                       VectorClear (ent->fields.server->avelocity);
                                }
                                else
-                                       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                                       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        }
                        else
                        {
-                               if (trace.plane.normal[2] > 0.7 && ent->v->velocity[2] < 60)
+                               if (trace.plane.normal[2] > 0.7 && ent->fields.server->velocity[2] < 60)
                                {
-                                       ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-                                       ent->v->groundentity = EDICT_TO_PROG(trace.ent);
-                                       VectorClear (ent->v->velocity);
-                                       VectorClear (ent->v->avelocity);
+                                       ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+                                       ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+                                       VectorClear (ent->fields.server->velocity);
+                                       VectorClear (ent->fields.server->avelocity);
                                }
                                else
-                                       ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                                       ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        }
                }
                else
                {
-                       ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, 1.0);
+                       ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1.0);
                        if (trace.plane.normal[2] > 0.7)
                        {
-                               ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
-                               ent->v->groundentity = EDICT_TO_PROG(trace.ent);
-                               if (((edict_t *)trace.ent)->v->solid == SOLID_BSP)
-                                       ent->e->suspendedinairflag = true;
-                               VectorClear (ent->v->velocity);
-                               VectorClear (ent->v->avelocity);
+                               ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+                               ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+                               if (((prvm_edict_t *)trace.ent)->fields.server->solid == SOLID_BSP)
+                                       ent->priv.server->suspendedinairflag = true;
+                               VectorClear (ent->fields.server->velocity);
+                               VectorClear (ent->fields.server->avelocity);
                        }
                        else
-                               ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+                               ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                }
        }
 
@@ -1311,16 +1311,16 @@ This is also used for objects that have become still on the ground, but
 will fall if the floor is pulled out from under them.
 =============
 */
-void SV_Physics_Step (edict_t *ent)
+void SV_Physics_Step (prvm_edict_t *ent)
 {
        // don't stick to ground if onground and moving upward
-       if (ent->v->velocity[2] >= (1.0 / 32.0) && ((int)ent->v->flags & FL_ONGROUND))
-               ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND;
+       if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && ((int)ent->fields.server->flags & FL_ONGROUND))
+               ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
 
        // freefall if not onground/fly/swim
-       if (!((int)ent->v->flags & (FL_ONGROUND | FL_FLY | FL_SWIM)))
+       if (!((int)ent->fields.server->flags & (FL_ONGROUND | FL_FLY | FL_SWIM)))
        {
-               int hitsound = ent->v->velocity[2] < sv_gravity.value * -0.1;
+               int hitsound = ent->fields.server->velocity[2] < sv_gravity.value * -0.1;
 
                SV_AddGravity(ent);
                SV_CheckVelocity(ent);
@@ -1328,7 +1328,7 @@ void SV_Physics_Step (edict_t *ent)
                SV_LinkEdict(ent, true);
 
                // just hit ground
-               if (hitsound && (int)ent->v->flags & FL_ONGROUND && gamemode != GAME_NEXUIZ)
+               if (hitsound && (int)ent->fields.server->flags & FL_ONGROUND && gamemode != GAME_NEXUIZ)
                        SV_StartSound(ent, 0, "demon/dland2.wav", 255, 1);
        }
 
@@ -1340,9 +1340,9 @@ void SV_Physics_Step (edict_t *ent)
 
 //============================================================================
 
-void SV_Physics_Entity (edict_t *ent, qboolean runmove)
+void SV_Physics_Entity (prvm_edict_t *ent, qboolean runmove)
 {
-       int i = ent - sv.edicts;
+       int i = ent - prog->edicts;
        if (i >= 1 && i <= svs.maxclients)
        {
                // apply the latest accepted move to the entity fields
@@ -1352,9 +1352,9 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
                // LordHavoc: QuakeC replacement for SV_ClientThink (player movement)
                if (SV_PlayerPhysicsQC)
                {
-                       pr_global_struct->time = sv.time;
-                       pr_global_struct->self = EDICT_TO_PROG(ent);
-                       PR_ExecuteProgram ((func_t)(SV_PlayerPhysicsQC - pr_functions), "QC function SV_PlayerPhysics is missing");
+                       prog->globals.server->time = sv.time;
+                       prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+                       PRVM_ExecuteProgram ((func_t)(SV_PlayerPhysicsQC - prog->functions), "QC function SV_PlayerPhysics is missing");
                }
                else
                        SV_ClientThink ();
@@ -1364,17 +1364,17 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
                // player_run/player_stand1 does not horribly malfunction if the
                // velocity becomes a number that is both == 0 and != 0
                // (sounds to me like NaN but to be absolutely safe...)
-               if (DotProduct(ent->v->velocity, ent->v->velocity) < 0.0001)
-                       VectorClear(ent->v->velocity);
+               if (DotProduct(ent->fields.server->velocity, ent->fields.server->velocity) < 0.0001)
+                       VectorClear(ent->fields.server->velocity);
                // call standard client pre-think
-               pr_global_struct->time = sv.time;
-               pr_global_struct->self = EDICT_TO_PROG(ent);
-               PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing");
+               prog->globals.server->time = sv.time;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+               PRVM_ExecuteProgram (prog->globals.server->PlayerPreThink, "QC function PlayerPreThink is missing");
                SV_CheckVelocity (ent);
        }
 
        // LordHavoc: merged client and normal entity physics
-       switch ((int) ent->v->movetype)
+       switch ((int) ent->fields.server->movetype)
        {
        case MOVETYPE_PUSH:
        case MOVETYPE_FAKEPUSH:
@@ -1382,7 +1382,7 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
                break;
        case MOVETYPE_NONE:
                // LordHavoc: manually inlined the thinktime check here because MOVETYPE_NONE is used on so many objects
-               if (ent->v->nextthink > 0 && ent->v->nextthink <= sv.time + sv.frametime)
+               if (ent->fields.server->nextthink > 0 && ent->fields.server->nextthink <= sv.time + sv.frametime)
                        SV_RunThink (ent);
                break;
        case MOVETYPE_FOLLOW:
@@ -1392,8 +1392,8 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
                if (SV_RunThink(ent))
                {
                        SV_CheckWater(ent);
-                       VectorMA(ent->v->origin, sv.frametime, ent->v->velocity, ent->v->origin);
-                       VectorMA(ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
+                       VectorMA(ent->fields.server->origin, sv.frametime, ent->fields.server->velocity, ent->fields.server->origin);
+                       VectorMA(ent->fields.server->angles, sv.frametime, ent->fields.server->avelocity, ent->fields.server->angles);
                }
                // relink normal entities here, players always get relinked so don't relink twice
                if (!(i > 0 && i <= svs.maxclients))
@@ -1405,7 +1405,7 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
        case MOVETYPE_WALK:
                if (SV_RunThink (ent))
                {
-                       if (!SV_CheckWater (ent) && ! ((int)ent->v->flags & FL_WATERJUMP) )
+                       if (!SV_CheckWater (ent) && ! ((int)ent->fields.server->flags & FL_WATERJUMP) )
                                SV_AddGravity (ent);
                        SV_CheckStuck (ent);
                        SV_WalkMove (ent);
@@ -1435,7 +1435,7 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
                }
                break;
        default:
-               Host_Error ("SV_Physics: bad movetype %i", (int)ent->v->movetype);
+               Host_Error ("SV_Physics: bad movetype %i", (int)ent->fields.server->movetype);
                break;
        }
 
@@ -1448,9 +1448,9 @@ void SV_Physics_Entity (edict_t *ent, qboolean runmove)
 
                SV_CheckVelocity (ent);
 
-               pr_global_struct->time = sv.time;
-               pr_global_struct->self = EDICT_TO_PROG(ent);
-               PR_ExecuteProgram (pr_global_struct->PlayerPostThink, "QC function PlayerPostThink is missing");
+               prog->globals.server->time = sv.time;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+               PRVM_ExecuteProgram (prog->globals.server->PlayerPostThink, "QC function PlayerPostThink is missing");
        }
 }
 
@@ -1464,32 +1464,32 @@ SV_Physics
 void SV_Physics (void)
 {
        int i, newnum_edicts;
-       edict_t *ent;
+       prvm_edict_t *ent;
        qbyte runmove[MAX_EDICTS];
 
 // let the progs know that a new frame has started
-       pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
-       pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
-       pr_global_struct->time = sv.time;
-       pr_global_struct->frametime = sv.frametime;
-       PR_ExecuteProgram (pr_global_struct->StartFrame, "QC function StartFrame is missing");
+       prog->globals.server->self = PRVM_EDICT_TO_PROG(prog->edicts);
+       prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
+       prog->globals.server->time = sv.time;
+       prog->globals.server->frametime = sv.frametime;
+       PRVM_ExecuteProgram (prog->globals.server->StartFrame, "QC function StartFrame is missing");
 
        newnum_edicts = 0;
-       for (i = 0, ent = sv.edicts;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
-               if ((runmove[i] = !ent->e->free))
+       for (i = 0, ent = prog->edicts;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
+               if ((runmove[i] = !ent->priv.server->free))
                        newnum_edicts = i + 1;
-       sv.num_edicts = max(svs.maxclients + 1, newnum_edicts);
+       prog->num_edicts = max(svs.maxclients + 1, newnum_edicts);
 
 //
 // treat each object in turn
 //
 
-       for (i = 0, ent = sv.edicts;i < sv.num_edicts;i++, ent = NEXT_EDICT(ent))
+       for (i = 0, ent = prog->edicts;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
-               if (ent->e->free)
+               if (ent->priv.server->free)
                        continue;
 
-               if (pr_global_struct->force_retouch)
+               if (prog->globals.server->force_retouch)
                        SV_LinkEdict (ent, true);       // force retouch even for stationary
 
                if (i >= 1 && i <= svs.maxclients)
@@ -1511,16 +1511,16 @@ void SV_Physics (void)
                SV_Physics_Entity(ent, runmove[i]);
        }
 
-       if (pr_global_struct->force_retouch > 0)
-               pr_global_struct->force_retouch = max(0, pr_global_struct->force_retouch - 1);
+       if (prog->globals.server->force_retouch > 0)
+               prog->globals.server->force_retouch = max(0, prog->globals.server->force_retouch - 1);
 
        // LordHavoc: endframe support
        if (EndFrameQC)
        {
-               pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
-               pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
-               pr_global_struct->time = sv.time;
-               PR_ExecuteProgram ((func_t)(EndFrameQC - pr_functions), "QC function EndFrame is missing");
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(prog->edicts);
+               prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
+               prog->globals.server->time = sv.time;
+               PRVM_ExecuteProgram ((func_t)(EndFrameQC - prog->functions), "QC function EndFrame is missing");
        }
 
        if (!sv_freezenonclients.integer)
@@ -1528,27 +1528,27 @@ void SV_Physics (void)
 }
 
 
-trace_t SV_Trace_Toss (edict_t *tossent, edict_t *ignore)
+trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
 {
        int i;
        float gravity, savesolid;
        vec3_t move, end;
-       edict_t tempent, *tent;
+       prvm_edict_t tempent, *tent;
        entvars_t vars;
-       eval_t *val;
+       prvm_eval_t *val;
        trace_t trace;
 
        // copy the vars over
-       memcpy(&vars, tossent->v, sizeof(entvars_t));
+       memcpy(&vars, tossent->fields.server, sizeof(entvars_t));
        // set up the temp entity to point to the copied vars
        tent = &tempent;
-       tent->v = &vars;
+       tent->fields.server = &vars;
 
-       savesolid = tossent->v->solid;
-       tossent->v->solid = SOLID_NOT;
+       savesolid = tossent->fields.server->solid;
+       tossent->fields.server->solid = SOLID_NOT;
 
        // this has to fetch the field from the original edict, since our copy is truncated
-       val = GETEDICTFIELDVALUE(tossent, eval_gravity);
+       val = PRVM_GETEDICTFIELDVALUE(tossent, eval_gravity);
        if (val != NULL && val->_float != 0)
                gravity = val->_float;
        else
@@ -1558,17 +1558,17 @@ trace_t SV_Trace_Toss (edict_t *tossent, edict_t *ignore)
        for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
        {
                SV_CheckVelocity (tent);
-               tent->v->velocity[2] -= gravity;
-               VectorMA (tent->v->angles, 0.05, tent->v->avelocity, tent->v->angles);
-               VectorScale (tent->v->velocity, 0.05, move);
-               VectorAdd (tent->v->origin, move, end);
-               trace = SV_Move (tent->v->origin, tent->v->mins, tent->v->maxs, end, MOVE_NORMAL, tent);
-               VectorCopy (trace.endpos, tent->v->origin);
+               tent->fields.server->velocity[2] -= gravity;
+               VectorMA (tent->fields.server->angles, 0.05, tent->fields.server->avelocity, tent->fields.server->angles);
+               VectorScale (tent->fields.server->velocity, 0.05, move);
+               VectorAdd (tent->fields.server->origin, move, end);
+               trace = SV_Move (tent->fields.server->origin, tent->fields.server->mins, tent->fields.server->maxs, end, MOVE_NORMAL, tent);
+               VectorCopy (trace.endpos, tent->fields.server->origin);
 
                if (trace.fraction < 1 && trace.ent && trace.ent != ignore)
                        break;
        }
-       tossent->v->solid = savesolid;
+       tossent->fields.server->solid = savesolid;
        trace.fraction = 0; // not relevant
        return trace;
 }
index b9d44e9b962471ada3ffc4516e247a5387c5e0f4..ef51038a78dc5b1306245d75e5ee824edd00cd05 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -45,18 +45,18 @@ void SV_SetIdealPitch (void)
        int             i, j;
        int             step, dir, steps;
 
-       if (!((int)host_client->edict->v->flags & FL_ONGROUND))
+       if (!((int)host_client->edict->fields.server->flags & FL_ONGROUND))
                return;
 
-       angleval = host_client->edict->v->angles[YAW] * M_PI*2 / 360;
+       angleval = host_client->edict->fields.server->angles[YAW] * M_PI*2 / 360;
        sinval = sin(angleval);
        cosval = cos(angleval);
 
        for (i=0 ; i<MAX_FORWARD ; i++)
        {
-               top[0] = host_client->edict->v->origin[0] + cosval*(i+3)*12;
-               top[1] = host_client->edict->v->origin[1] + sinval*(i+3)*12;
-               top[2] = host_client->edict->v->origin[2] + host_client->edict->v->view_ofs[2];
+               top[0] = host_client->edict->fields.server->origin[0] + cosval*(i+3)*12;
+               top[1] = host_client->edict->fields.server->origin[1] + sinval*(i+3)*12;
+               top[2] = host_client->edict->fields.server->origin[2] + host_client->edict->fields.server->view_ofs[2];
 
                bottom[0] = top[0];
                bottom[1] = top[1];
@@ -92,13 +92,13 @@ void SV_SetIdealPitch (void)
 
        if (!dir)
        {
-               host_client->edict->v->idealpitch = 0;
+               host_client->edict->fields.server->idealpitch = 0;
                return;
        }
 
        if (steps < 2)
                return;
-       host_client->edict->v->idealpitch = -dir * sv_idealpitchscale.value;
+       host_client->edict->fields.server->idealpitch = -dir * sv_idealpitchscale.value;
 }
 
 #if 1
@@ -119,14 +119,14 @@ void SV_UserFriction (void)
        vec3_t start, stop;
        trace_t trace;
 
-       speed = sqrt(host_client->edict->v->velocity[0]*host_client->edict->v->velocity[0]+host_client->edict->v->velocity[1]*host_client->edict->v->velocity[1]);
+       speed = sqrt(host_client->edict->fields.server->velocity[0]*host_client->edict->fields.server->velocity[0]+host_client->edict->fields.server->velocity[1]*host_client->edict->fields.server->velocity[1]);
        if (!speed)
                return;
 
        // if the leading edge is over a dropoff, increase friction
-       start[0] = stop[0] = host_client->edict->v->origin[0] + host_client->edict->v->velocity[0]/speed*16;
-       start[1] = stop[1] = host_client->edict->v->origin[1] + host_client->edict->v->velocity[1]/speed*16;
-       start[2] = host_client->edict->v->origin[2] + host_client->edict->v->mins[2];
+       start[0] = stop[0] = host_client->edict->fields.server->origin[0] + host_client->edict->fields.server->velocity[0]/speed*16;
+       start[1] = stop[1] = host_client->edict->fields.server->origin[1] + host_client->edict->fields.server->velocity[1]/speed*16;
+       start[2] = host_client->edict->fields.server->origin[2] + host_client->edict->fields.server->mins[2];
        stop[2] = start[2] - 34;
 
        trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, host_client->edict);
@@ -145,7 +145,7 @@ void SV_UserFriction (void)
        else
                newspeed /= speed;
 
-       VectorScale(host_client->edict->v->velocity, newspeed, host_client->edict->v->velocity);
+       VectorScale(host_client->edict->fields.server->velocity, newspeed, host_client->edict->fields.server->velocity);
 }
 
 /*
@@ -158,7 +158,7 @@ void SV_Accelerate (void)
        int i;
        float addspeed, accelspeed, currentspeed;
 
-       currentspeed = DotProduct (host_client->edict->v->velocity, wishdir);
+       currentspeed = DotProduct (host_client->edict->fields.server->velocity, wishdir);
        addspeed = wishspeed - currentspeed;
        if (addspeed <= 0)
                return;
@@ -167,7 +167,7 @@ void SV_Accelerate (void)
                accelspeed = addspeed;
 
        for (i=0 ; i<3 ; i++)
-               host_client->edict->v->velocity[i] += accelspeed*wishdir[i];
+               host_client->edict->fields.server->velocity[i] += accelspeed*wishdir[i];
 }
 
 void SV_AirAccelerate (vec3_t wishveloc)
@@ -178,7 +178,7 @@ void SV_AirAccelerate (vec3_t wishveloc)
        wishspd = VectorNormalizeLength (wishveloc);
        if (wishspd > 30)
                wishspd = 30;
-       currentspeed = DotProduct (host_client->edict->v->velocity, wishveloc);
+       currentspeed = DotProduct (host_client->edict->fields.server->velocity, wishveloc);
        addspeed = wishspd - currentspeed;
        if (addspeed <= 0)
                return;
@@ -187,23 +187,23 @@ void SV_AirAccelerate (vec3_t wishveloc)
                accelspeed = addspeed;
 
        for (i=0 ; i<3 ; i++)
-               host_client->edict->v->velocity[i] += accelspeed*wishveloc[i];
+               host_client->edict->fields.server->velocity[i] += accelspeed*wishveloc[i];
 }
 
 
 void DropPunchAngle (void)
 {
        float len;
-       eval_t *val;
+       prvm_eval_t *val;
 
-       len = VectorNormalizeLength (host_client->edict->v->punchangle);
+       len = VectorNormalizeLength (host_client->edict->fields.server->punchangle);
 
        len -= 10*sv.frametime;
        if (len < 0)
                len = 0;
-       VectorScale (host_client->edict->v->punchangle, len, host_client->edict->v->punchangle);
+       VectorScale (host_client->edict->fields.server->punchangle, len, host_client->edict->fields.server->punchangle);
 
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_punchvector)))
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_punchvector)))
        {
                len = VectorNormalizeLength (val->vector);
 
@@ -224,16 +224,16 @@ void SV_FreeMove (void)
        int i;
        float wishspeed;
 
-       AngleVectors (host_client->edict->v->v_angle, forward, right, up);
+       AngleVectors (host_client->edict->fields.server->v_angle, forward, right, up);
 
        for (i = 0; i < 3; i++)
-               host_client->edict->v->velocity[i] = forward[i] * cmd.forwardmove + right[i] * cmd.sidemove;
+               host_client->edict->fields.server->velocity[i] = forward[i] * cmd.forwardmove + right[i] * cmd.sidemove;
 
-       host_client->edict->v->velocity[2] += cmd.upmove;
+       host_client->edict->fields.server->velocity[2] += cmd.upmove;
 
-       wishspeed = VectorLength(host_client->edict->v->velocity);
+       wishspeed = VectorLength(host_client->edict->fields.server->velocity);
        if (wishspeed > sv_maxspeed.value)
-               VectorScale(host_client->edict->v->velocity, sv_maxspeed.value / wishspeed, host_client->edict->v->velocity);
+               VectorScale(host_client->edict->fields.server->velocity, sv_maxspeed.value / wishspeed, host_client->edict->fields.server->velocity);
 }
 
 /*
@@ -249,7 +249,7 @@ void SV_WaterMove (void)
        float speed, newspeed, wishspeed, addspeed, accelspeed, temp;
 
        // user intentions
-       AngleVectors (host_client->edict->v->v_angle, forward, right, up);
+       AngleVectors (host_client->edict->fields.server->v_angle, forward, right, up);
 
        for (i=0 ; i<3 ; i++)
                wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
@@ -269,14 +269,14 @@ void SV_WaterMove (void)
        wishspeed *= 0.7;
 
        // water friction
-       speed = VectorLength(host_client->edict->v->velocity);
+       speed = VectorLength(host_client->edict->fields.server->velocity);
        if (speed)
        {
                newspeed = speed - sv.frametime * speed * sv_friction.value;
                if (newspeed < 0)
                        newspeed = 0;
                temp = newspeed/speed;
-               VectorScale(host_client->edict->v->velocity, temp, host_client->edict->v->velocity);
+               VectorScale(host_client->edict->fields.server->velocity, temp, host_client->edict->fields.server->velocity);
        }
        else
                newspeed = 0;
@@ -295,18 +295,18 @@ void SV_WaterMove (void)
                accelspeed = addspeed;
 
        for (i=0 ; i<3 ; i++)
-               host_client->edict->v->velocity[i] += accelspeed * wishvel[i];
+               host_client->edict->fields.server->velocity[i] += accelspeed * wishvel[i];
 }
 
 void SV_WaterJump (void)
 {
-       if (sv.time > host_client->edict->v->teleport_time || !host_client->edict->v->waterlevel)
+       if (sv.time > host_client->edict->fields.server->teleport_time || !host_client->edict->fields.server->waterlevel)
        {
-               host_client->edict->v->flags = (int)host_client->edict->v->flags & ~FL_WATERJUMP;
-               host_client->edict->v->teleport_time = 0;
+               host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags & ~FL_WATERJUMP;
+               host_client->edict->fields.server->teleport_time = 0;
        }
-       host_client->edict->v->velocity[0] = host_client->edict->v->movedir[0];
-       host_client->edict->v->velocity[1] = host_client->edict->v->movedir[1];
+       host_client->edict->fields.server->velocity[0] = host_client->edict->fields.server->movedir[0];
+       host_client->edict->fields.server->velocity[1] = host_client->edict->fields.server->movedir[1];
 }
 
 
@@ -324,20 +324,20 @@ void SV_AirMove (void)
 
        // LordHavoc: correct quake movement speed bug when looking up/down
        wishvel[0] = wishvel[2] = 0;
-       wishvel[1] = host_client->edict->v->angles[1];
+       wishvel[1] = host_client->edict->fields.server->angles[1];
        AngleVectors (wishvel, forward, right, up);
 
        fmove = cmd.forwardmove;
        smove = cmd.sidemove;
 
 // hack to not let you back into teleporter
-       if (sv.time < host_client->edict->v->teleport_time && fmove < 0)
+       if (sv.time < host_client->edict->fields.server->teleport_time && fmove < 0)
                fmove = 0;
 
        for (i=0 ; i<3 ; i++)
                wishvel[i] = forward[i]*fmove + right[i]*smove;
 
-       if ((int)host_client->edict->v->movetype != MOVETYPE_WALK)
+       if ((int)host_client->edict->fields.server->movetype != MOVETYPE_WALK)
                wishvel[2] += cmd.upmove;
 
        VectorCopy (wishvel, wishdir);
@@ -349,10 +349,10 @@ void SV_AirMove (void)
                wishspeed = sv_maxspeed.value;
        }
 
-       if (host_client->edict->v->movetype == MOVETYPE_NOCLIP)
+       if (host_client->edict->fields.server->movetype == MOVETYPE_NOCLIP)
        {
                // noclip
-               VectorCopy (wishvel, host_client->edict->v->velocity);
+               VectorCopy (wishvel, host_client->edict->fields.server->velocity);
        }
        else if ( onground )
        {
@@ -378,30 +378,30 @@ void SV_ClientThink (void)
 {
        vec3_t v_angle;
 
-       if (host_client->edict->v->movetype == MOVETYPE_NONE)
+       if (host_client->edict->fields.server->movetype == MOVETYPE_NONE)
                return;
 
-       onground = (int)host_client->edict->v->flags & FL_ONGROUND;
+       onground = (int)host_client->edict->fields.server->flags & FL_ONGROUND;
 
        DropPunchAngle ();
 
        // if dead, behave differently
-       if (host_client->edict->v->health <= 0)
+       if (host_client->edict->fields.server->health <= 0)
                return;
 
        cmd = host_client->cmd;
 
        // angles
        // show 1/3 the pitch angle and all the roll angle
-       VectorAdd (host_client->edict->v->v_angle, host_client->edict->v->punchangle, v_angle);
-       host_client->edict->v->angles[ROLL] = V_CalcRoll (host_client->edict->v->angles, host_client->edict->v->velocity)*4;
-       if (!host_client->edict->v->fixangle)
+       VectorAdd (host_client->edict->fields.server->v_angle, host_client->edict->fields.server->punchangle, v_angle);
+       host_client->edict->fields.server->angles[ROLL] = V_CalcRoll (host_client->edict->fields.server->angles, host_client->edict->fields.server->velocity)*4;
+       if (!host_client->edict->fields.server->fixangle)
        {
-               host_client->edict->v->angles[PITCH] = -v_angle[PITCH]/3;
-               host_client->edict->v->angles[YAW] = v_angle[YAW];
+               host_client->edict->fields.server->angles[PITCH] = -v_angle[PITCH]/3;
+               host_client->edict->fields.server->angles[YAW] = v_angle[YAW];
        }
 
-       if ( (int)host_client->edict->v->flags & FL_WATERJUMP )
+       if ( (int)host_client->edict->fields.server->flags & FL_WATERJUMP )
        {
                SV_WaterJump ();
                return;
@@ -409,8 +409,8 @@ void SV_ClientThink (void)
 
        /*
        // Player is (somehow) outside of the map, or flying, or noclipping
-       if (host_client->edict->v->movetype != MOVETYPE_NOCLIP && (host_client->edict->v->movetype == MOVETYPE_FLY || SV_TestEntityPosition (host_client->edict)))
-       //if (host_client->edict->v->movetype == MOVETYPE_NOCLIP || host_client->edict->v->movetype == MOVETYPE_FLY || SV_TestEntityPosition (host_client->edict))
+       if (host_client->edict->fields.server->movetype != MOVETYPE_NOCLIP && (host_client->edict->fields.server->movetype == MOVETYPE_FLY || SV_TestEntityPosition (host_client->edict)))
+       //if (host_client->edict->fields.server->movetype == MOVETYPE_NOCLIP || host_client->edict->fields.server->movetype == MOVETYPE_FLY || SV_TestEntityPosition (host_client->edict))
        {
                SV_FreeMove ();
                return;
@@ -418,7 +418,7 @@ void SV_ClientThink (void)
        */
 
        // walk
-       if ((host_client->edict->v->waterlevel >= 2) && (host_client->edict->v->movetype != MOVETYPE_NOCLIP))
+       if ((host_client->edict->fields.server->waterlevel >= 2) && (host_client->edict->fields.server->movetype != MOVETYPE_NOCLIP))
        {
                SV_WaterMove ();
                return;
@@ -438,48 +438,48 @@ void SV_ClientThink(void)
        float wishspeed, f, limit;
        trace_t trace;
 
-       if (host_client->edict->v->movetype == MOVETYPE_NONE)
+       if (host_client->edict->fields.server->movetype == MOVETYPE_NONE)
                return;
 
-       f = DotProduct(host_client->edict->v->punchangle, host_client->edict->v->punchangle);
+       f = DotProduct(host_client->edict->fields.server->punchangle, host_client->edict->fields.server->punchangle);
        if (f)
        {
                limit = sqrt(f);
                f = (limit - 10 * sv.frametime);
                f /= limit;
                f = max(0, f);
-               VectorScale(host_client->edict->v->punchangle, f, host_client->edict->v->punchangle);
+               VectorScale(host_client->edict->fields.server->punchangle, f, host_client->edict->fields.server->punchangle);
        }
 
        // if dead, behave differently
-       if (host_client->edict->v->health <= 0)
+       if (host_client->edict->fields.server->health <= 0)
                return;
 
-       AngleVectors(host_client->edict->v->v_angle, v_forward, v_right, v_up);
+       AngleVectors(host_client->edict->fields.server->v_angle, v_forward, v_right, v_up);
        // show 1/3 the pitch angle and all the roll angle
-       f = DotProduct(host_client->edict->v->velocity, v_right) * (1.0 / cl_rollspeed.value);
-       host_client->edict->v->angles[2] = bound(-1, f, 1) * cl_rollangle.value * 4;
-       if (!host_client->edict->v->fixangle)
+       f = DotProduct(host_client->edict->fields.server->velocity, v_right) * (1.0 / cl_rollspeed.value);
+       host_client->edict->fields.server->angles[2] = bound(-1, f, 1) * cl_rollangle.value * 4;
+       if (!host_client->edict->fields.server->fixangle)
        {
-               host_client->edict->v->angles[0] = (host_client->edict->v->v_angle[0] + host_client->edict->v->punchangle[0]) * -0.333;
-               host_client->edict->v->angles[1] = host_client->edict->v->v_angle[1] + host_client->edict->v->punchangle[1];
+               host_client->edict->fields.server->angles[0] = (host_client->edict->fields.server->v_angle[0] + host_client->edict->fields.server->punchangle[0]) * -0.333;
+               host_client->edict->fields.server->angles[1] = host_client->edict->fields.server->v_angle[1] + host_client->edict->fields.server->punchangle[1];
        }
 
-       if ((int)host_client->edict->v->flags & FL_WATERJUMP)
+       if ((int)host_client->edict->fields.server->flags & FL_WATERJUMP)
        {
-               host_client->edict->v->velocity[0] = host_client->edict->v->movedir[0];
-               host_client->edict->v->velocity[1] = host_client->edict->v->movedir[1];
-               if (sv.time > host_client->edict->v->teleport_time || host_client->edict->v->waterlevel == 0)
+               host_client->edict->fields.server->velocity[0] = host_client->edict->fields.server->movedir[0];
+               host_client->edict->fields.server->velocity[1] = host_client->edict->fields.server->movedir[1];
+               if (sv.time > host_client->edict->fields.server->teleport_time || host_client->edict->fields.server->waterlevel == 0)
                {
-                       host_client->edict->v->flags = (int)host_client->edict->v->flags - ((int)host_client->edict->v->flags & FL_WATERJUMP);
-                       host_client->edict->v->teleport_time = 0;
+                       host_client->edict->fields.server->flags = (int)host_client->edict->fields.server->flags - ((int)host_client->edict->fields.server->flags & FL_WATERJUMP);
+                       host_client->edict->fields.server->teleport_time = 0;
                }
                return;
        }
 
        // swim
-       if (host_client->edict->v->waterlevel >= 2)
-       if (host_client->edict->v->movetype != MOVETYPE_NOCLIP)
+       if (host_client->edict->fields.server->waterlevel >= 2)
+       if (host_client->edict->fields.server->movetype != MOVETYPE_NOCLIP)
        {
                if (host_client->cmd.forwardmove == 0 && host_client->cmd.sidemove == 0 && host_client->cmd.upmove == 0)
                {
@@ -499,12 +499,12 @@ void SV_ClientThink(void)
                wishspeed = min(wishspeed, sv_maxspeed.value) * 0.7;
 
                // water friction
-               f = VectorLength(host_client->edict->v->velocity) * (1 - sv.frametime * sv_friction.value);
+               f = VectorLength(host_client->edict->fields.server->velocity) * (1 - sv.frametime * sv_friction.value);
                if (f > 0)
-                       f /= VectorLength(host_client->edict->v->velocity);
+                       f /= VectorLength(host_client->edict->fields.server->velocity);
                else
                        f = 0;
-               VectorScale(host_client->edict->v->velocity, f, host_client->edict->v->velocity);
+               VectorScale(host_client->edict->fields.server->velocity, f, host_client->edict->fields.server->velocity);
 
                // water acceleration
                if (wishspeed <= f)
@@ -517,23 +517,23 @@ void SV_ClientThink(void)
                limit = VectorLength(wishvel);
                if (limit)
                        f /= limit;
-               VectorMA(host_client->edict->v->velocity, f, wishvel, host_client->edict->v->velocity);
+               VectorMA(host_client->edict->fields.server->velocity, f, wishvel, host_client->edict->fields.server->velocity);
                return;
        }
 
        // if not flying, move horizontally only
-       if (host_client->edict->v->movetype != MOVETYPE_FLY)
+       if (host_client->edict->fields.server->movetype != MOVETYPE_FLY)
        {
                VectorClear(wishvel);
-               wishvel[1] = host_client->edict->v->v_angle[1];
+               wishvel[1] = host_client->edict->fields.server->v_angle[1];
                AngleVectors(wishvel, v_forward, v_right, v_up);
        }
 
        // hack to not let you back into teleporter
        VectorScale(v_right, host_client->cmd.sidemove, wishvel);
-       if (sv.time >= host_client->edict->v->teleport_time || host_client->cmd.forwardmove > 0)
+       if (sv.time >= host_client->edict->fields.server->teleport_time || host_client->cmd.forwardmove > 0)
                VectorMA(wishvel, host_client->cmd.forwardmove, v_forward, wishvel);
-       if (host_client->edict->v->movetype != MOVETYPE_WALK)
+       if (host_client->edict->fields.server->movetype != MOVETYPE_WALK)
                wishvel[2] += cmd.upmove;
 
        VectorCopy(wishvel, wishdir);
@@ -542,26 +542,26 @@ void SV_ClientThink(void)
        if (wishspeed > sv_maxspeed.value)
                wishspeed = sv_maxspeed.value;
 
-       if (host_client->edict->v->movetype == MOVETYPE_NOCLIP || host_client->edict->v->movetype == MOVETYPE_FLY)
+       if (host_client->edict->fields.server->movetype == MOVETYPE_NOCLIP || host_client->edict->fields.server->movetype == MOVETYPE_FLY)
        {
-               VectorScale(wishdir, wishspeed, host_client->edict->v->velocity);
+               VectorScale(wishdir, wishspeed, host_client->edict->fields.server->velocity);
                return;
        }
 
-       if ((int)host_client->edict->v->flags & FL_ONGROUND) // walking
+       if ((int)host_client->edict->fields.server->flags & FL_ONGROUND) // walking
        {
                // friction
-               f = host_client->edict->v->velocity[0] * host_client->edict->v->velocity[0] + host_client->edict->v->velocity[1] * host_client->edict->v->velocity[1];
+               f = host_client->edict->fields.server->velocity[0] * host_client->edict->fields.server->velocity[0] + host_client->edict->fields.server->velocity[1] * host_client->edict->fields.server->velocity[1];
                if (f)
                {
                        f = sqrt(f);
-                       VectorCopy(host_client->edict->v->velocity, v);
+                       VectorCopy(host_client->edict->fields.server->velocity, v);
                        v[2] = 0;
 
                        // if the leading edge is over a dropoff, increase friction
                        limit = 16.0f / f;
-                       VectorMA(host_client->edict->v->origin, limit, v, v);
-                       v[2] += host_client->edict->v->mins[2];
+                       VectorMA(host_client->edict->fields.server->origin, limit, v, v);
+                       v[2] += host_client->edict->fields.server->mins[2];
 
                        VectorCopy(v, start);
                        VectorCopy(v, stop);
@@ -579,20 +579,20 @@ void SV_ClientThink(void)
 
                        if (f < 0)
                                f = 0;
-                       VectorScale(host_client->edict->v->velocity, f, host_client->edict->v->velocity);
+                       VectorScale(host_client->edict->fields.server->velocity, f, host_client->edict->fields.server->velocity);
                }
        }
        else // airborn
                wishspeed = min(wishspeed, 30);
 
        // ground or air acceleration
-       f = wishspeed - DotProduct(host_client->edict->v->velocity, wishdir);
+       f = wishspeed - DotProduct(host_client->edict->fields.server->velocity, wishdir);
        if (f > 0)
        {
                limit = sv_accelerate.value * sv.frametime * wishspeed;
                if (f > limit)
                        f = limit;
-               VectorMA(host_client->edict->v->velocity, f, wishdir, host_client->edict->v->velocity);
+               VectorMA(host_client->edict->fields.server->velocity, f, wishdir, host_client->edict->fields.server->velocity);
        }
 }
 #endif
@@ -602,7 +602,7 @@ void SV_ClientThink(void)
 SV_ReadClientMove
 ===================
 */
-extern void SV_Physics_Entity (edict_t *ent, qboolean runmove);
+extern void SV_Physics_Entity (prvm_edict_t *ent, qboolean runmove);
 void SV_ReadClientMove (void)
 {
        int i;
@@ -667,14 +667,14 @@ void SV_ReadClientMove (void)
                move->cursor_impact[1] = MSG_ReadFloat();
                move->cursor_impact[2] = MSG_ReadFloat();
                move->cursor_entitynumber = (unsigned short)MSG_ReadShort();
-               if (move->cursor_entitynumber >= sv.max_edicts)
+               if (move->cursor_entitynumber >= prog->max_edicts)
                {
                        Con_DPrintf("SV_ReadClientMessage: client send bad cursor_entitynumber\n");
                        move->cursor_entitynumber = 0;
                }
                // as requested by FrikaC, cursor_trace_ent is reset to world if the
                // entity is free at time of receipt
-               if (EDICT_NUM(move->cursor_entitynumber)->e->free)
+               if (PRVM_EDICT_NUM(move->cursor_entitynumber)->priv.server->free)
                        move->cursor_entitynumber = 0;
                if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
        }
@@ -687,12 +687,12 @@ void SV_ReadClientMove (void)
                if (host_client->movesequence)
                {
                        double frametime = move->time - oldmovetime;
-                       double oldframetime = pr_global_struct->frametime;
+                       double oldframetime = prog->globals.server->frametime;
                        if (frametime > 0.1)
                                frametime = 0.1;
-                       pr_global_struct->frametime = frametime;
+                       prog->globals.server->frametime = frametime;
                        SV_Physics_Entity(host_client->edict, true);
-                       pr_global_struct->frametime = oldframetime;
+                       prog->globals.server->frametime = oldframetime;
                }
        }
 }
@@ -700,7 +700,7 @@ void SV_ReadClientMove (void)
 void SV_ApplyClientMove (void)
 {
        int i;
-       eval_t *val;
+       prvm_eval_t *val;
        float total;
        usercmd_t *move = &host_client->cmd;
 
@@ -712,25 +712,25 @@ void SV_ApplyClientMove (void)
        host_client->ping = total / NUM_PING_TIMES;
 
        // set the edict fields
-       host_client->edict->v->button0 = move->buttons & 1;
-       host_client->edict->v->button2 = (move->buttons & 2)>>1;
-       host_client->edict->v->impulse = move->impulse;
-       VectorCopy(move->viewangles, host_client->edict->v->v_angle);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button3))) val->_float = ((move->buttons >> 2) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button4))) val->_float = ((move->buttons >> 3) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button5))) val->_float = ((move->buttons >> 4) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((move->buttons >> 5) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((move->buttons >> 6) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((move->buttons >> 7) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((move->buttons >> 8) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((move->buttons >> 9) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((move->buttons >> 10) & 1);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_movement))) VectorSet(val->vector, move->forwardmove, move->sidemove, move->upmove);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_screen))) VectorCopy(move->cursor_screen, val->vector);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_start))) VectorCopy(move->cursor_start, val->vector);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = EDICT_TO_PROG(EDICT_NUM(move->cursor_entitynumber));
-       if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_ping))) val->_float = host_client->ping * 1000.0;
+       host_client->edict->fields.server->button0 = move->buttons & 1;
+       host_client->edict->fields.server->button2 = (move->buttons & 2)>>1;
+       host_client->edict->fields.server->impulse = move->impulse;
+       VectorCopy(move->viewangles, host_client->edict->fields.server->v_angle);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button3))) val->_float = ((move->buttons >> 2) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button4))) val->_float = ((move->buttons >> 3) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button5))) val->_float = ((move->buttons >> 4) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button6))) val->_float = ((move->buttons >> 5) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button7))) val->_float = ((move->buttons >> 6) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_button8))) val->_float = ((move->buttons >> 7) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_buttonuse))) val->_float = ((move->buttons >> 8) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_buttonchat))) val->_float = ((move->buttons >> 9) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_active))) val->_float = ((move->buttons >> 10) & 1);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_movement))) VectorSet(val->vector, move->forwardmove, move->sidemove, move->upmove);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_screen))) VectorCopy(move->cursor_screen, val->vector);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_start))) VectorCopy(move->cursor_start, val->vector);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber));
+       if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ping))) val->_float = host_client->ping * 1000.0;
 }
 
 void SV_FrameLost(int framenum)
@@ -803,9 +803,9 @@ void SV_ReadClientMessage(void)
                                Cmd_ExecuteString (s, src_client);
                        else if (SV_ParseClientCommandQC)
                        {
-                               G_INT(OFS_PARM0) = PR_SetEngineString(s);
-                               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-                               PR_ExecuteProgram ((func_t)(SV_ParseClientCommandQC - pr_functions), "QC function SV_ParseClientCommand is missing");
+                               PRVM_G_INT(OFS_PARM0) = PRVM_SetEngineString(s);
+                               prog->globals.server->self = PRVM_EDICT_TO_PROG(host_client->edict);
+                               PRVM_ExecuteProgram ((func_t)(SV_ParseClientCommandQC - prog->functions), "QC function SV_ParseClientCommand is missing");
                        }
                        else if (strncasecmp(s, "status", 6) == 0
                         || strncasecmp(s, "name", 4) == 0
diff --git a/svvm_cmds.c b/svvm_cmds.c
new file mode 100644 (file)
index 0000000..21d7150
--- /dev/null
@@ -0,0 +1,2538 @@
+#include "prvm_cmds.h"
+
+//============================================================================
+// Server
+
+#define PF_WARNING(s) do{Con_Printf(s);PRVM_PrintState();return;}while(0)
+cvar_t sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled autoaim by default
+
+
+char *vm_sv_extensions =
+"DP_BUTTONCHAT "
+"DP_BUTTONUSE "
+"DP_CL_LOADSKY "
+"DP_CON_SET "
+"DP_CON_SETA "
+"DP_CON_STARTMAP "
+"DP_EF_ADDITIVE "
+"DP_EF_BLUE "
+"DP_EF_FLAME "
+"DP_EF_FULLBRIGHT "
+"DP_EF_NODEPTHTEST "
+"DP_EF_NODRAW "
+"DP_EF_NOSHADOW "
+"DP_EF_RED "
+"DP_EF_STARDUST "
+"DP_ENT_ALPHA "
+"DP_ENT_CUSTOMCOLORMAP "
+"DP_ENT_EXTERIORMODELTOCLIENT "
+"DP_ENT_GLOW "
+"DP_ENT_LOWPRECISION "
+"DP_ENT_SCALE "
+"DP_ENT_VIEWMODEL "
+"DP_GFX_EXTERNALTEXTURES "
+"DP_GFX_FOG "
+"DP_GFX_QUAKE3MODELTAGS "
+"DP_GFX_SKINFILES "
+"DP_GFX_SKYBOX "
+"DP_HALFLIFE_MAP "
+"DP_HALFLIFE_MAP_CVAR "
+"DP_HALFLIFE_SPRITE "
+"DP_INPUTBUTTONS "
+"DP_LITSPRITES "
+"DP_LITSUPPORT "
+"DP_MONSTERWALK "
+"DP_MOVETYPEBOUNCEMISSILE "
+"DP_MOVETYPEFOLLOW "
+"DP_QC_CHANGEPITCH "
+"DP_QC_COPYENTITY "
+"DP_QC_CVAR_STRING "
+"DP_QC_ETOS "
+"DP_QC_FINDCHAIN "
+"DP_QC_FINDCHAINFLAGS "
+"DP_QC_FINDCHAINFLOAT "
+"DP_QC_FINDFLAGS "
+"DP_QC_FINDFLOAT "
+"DP_QC_FS_SEARCH " // Black: same as in the menu qc
+"DP_QC_GETLIGHT "
+"DP_QC_GETSURFACE "
+"DP_QC_GETTAGINFO "
+"DP_QC_MINMAXBOUND "
+"DP_QC_MULTIPLETEMPSTRINGS "
+"DP_QC_RANDOMVEC "
+"DP_QC_SINCOSSQRTPOW "
+"DP_QC_TRACEBOX "
+"DP_QC_TRACETOSS "
+"DP_QC_TRACE_MOVETYPE_HITMODEL "
+"DP_QC_TRACE_MOVETYPE_WORLDONLY "
+"DP_QC_VECTORVECTORS "
+"DP_QUAKE2_MODEL "
+"DP_QUAKE2_SPRITE "
+"DP_QUAKE3_MODEL "
+"DP_REGISTERCVAR "
+"DP_SND_DIRECTIONLESSATTNNONE "
+"DP_SND_FAKETRACKS "
+"DP_SND_OGGVORBIS "
+"DP_SND_STEREOWAV "
+"DP_SOLIDCORPSE "
+"DP_SPRITE32 "
+"DP_SV_BOTCLIENT "
+"DP_SV_CLIENTCOLORS "
+"DP_SV_CLIENTNAME "
+"DP_SV_DRAWONLYTOCLIENT "
+"DP_SV_DROPCLIENT "
+"DP_SV_EFFECT "
+"DP_SV_NODRAWTOCLIENT "
+"DP_SV_PING "
+"DP_SV_PLAYERPHYSICS "
+"DP_SV_PUNCHVECTOR "
+"DP_SV_ROTATINGBMODEL "
+"DP_SV_SETCOLOR "
+"DP_SV_SLOWMO "
+"DP_TE_BLOOD "
+"DP_TE_BLOODSHOWER "
+"DP_TE_CUSTOMFLASH "
+"DP_TE_EXPLOSIONRGB "
+"DP_TE_FLAMEJET "
+"DP_TE_PARTICLECUBE "
+"DP_TE_PARTICLERAIN "
+"DP_TE_PARTICLESNOW "
+"DP_TE_PLASMABURN "
+"DP_TE_QUADEFFECTS1 "
+"DP_TE_SMALLFLASH "
+"DP_TE_SPARK "
+"DP_TE_STANDARDEFFECTBUILTINS "
+"DP_VIEWZOOM "
+"FRIK_FILE "
+"KRIMZON_SV_PARSECLIENTCOMMAND "
+"NEH_CMD_PLAY2 "
+"NEH_RESTOREGAME "
+"NXQ_GFX_LETTERBOX "
+"PRYDON_CLIENTCURSOR "
+"TENEBRAE_GFX_DLIGHTS "
+"TW_SV_STEPCONTROL "
+"NEXUIZ_PLAYERMODEL "
+"NEXUIZ_PLAYERSKIN "
+;
+
+/*
+==============
+PF_makevectors
+
+Writes new values for v_forward, v_up, and v_right based on angles
+makevectors(vector)
+==============
+*/
+void PF_makevectors (void)
+{
+       AngleVectors (PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
+}
+
+/*
+==============
+PF_vectorvectors
+
+Writes new values for v_forward, v_up, and v_right based on the given forward vector
+vectorvectors(vector, vector)
+==============
+*/
+void PF_vectorvectors (void)
+{
+       VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), prog->globals.server->v_forward);
+       VectorVectors(prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up);
+}
+
+/*
+=================
+PF_setorigin
+
+This is the only valid way to move an object without using the physics of the world (setting velocity and waiting).  Directly changing origin will not set internal links correctly, so clipping would be messed up.  This should be called when an object is spawned, and then only if it is teleported.
+
+setorigin (entity, origin)
+=================
+*/
+void PF_setorigin (void)
+{
+       prvm_edict_t    *e;
+       float   *org;
+
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
+               PF_WARNING("setorigin: can not modify world entity\n");
+       if (e->priv.server->free)
+               PF_WARNING("setorigin: can not modify free entity\n");
+       org = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy (org, e->fields.server->origin);
+       SV_LinkEdict (e, false);
+}
+
+
+void SetMinMaxSize (prvm_edict_t *e, float *min, float *max, qboolean rotate)
+{
+       int             i;
+
+       for (i=0 ; i<3 ; i++)
+               if (min[i] > max[i])
+                       PRVM_ERROR("SetMinMaxSize: backwards mins/maxs\n");
+
+// set derived values
+       VectorCopy (min, e->fields.server->mins);
+       VectorCopy (max, e->fields.server->maxs);
+       VectorSubtract (max, min, e->fields.server->size);
+
+       SV_LinkEdict (e, false);
+}
+
+/*
+=================
+PF_setsize
+
+the size box is rotated by the current angle
+LordHavoc: no it isn't...
+
+setsize (entity, minvector, maxvector)
+=================
+*/
+void PF_setsize (void)
+{
+       prvm_edict_t    *e;
+       float   *min, *max;
+
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
+               PF_WARNING("setsize: can not modify world entity\n");
+       if (e->priv.server->free)
+               PF_WARNING("setsize: can not modify free entity\n");
+       min = PRVM_G_VECTOR(OFS_PARM1);
+       max = PRVM_G_VECTOR(OFS_PARM2);
+       SetMinMaxSize (e, min, max, false);
+}
+
+
+/*
+=================
+PF_setmodel
+
+setmodel(entity, model)
+=================
+*/
+static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
+void PF_setmodel (void)
+{
+       prvm_edict_t    *e;
+       model_t *mod;
+       int             i;
+
+       e = PRVM_G_EDICT(OFS_PARM0);
+       if (e == prog->edicts)
+               PF_WARNING("setmodel: can not modify world entity\n");
+       if (e->priv.server->free)
+               PF_WARNING("setmodel: can not modify free entity\n");
+       i = SV_ModelIndex(PRVM_G_STRING(OFS_PARM1), 1);
+       e->fields.server->model = PRVM_SetEngineString(sv.model_precache[i]);
+       e->fields.server->modelindex = i;
+
+       mod = sv.models[i];
+
+       if (mod)
+       {
+               if (mod->type != mod_alias || sv_gameplayfix_setmodelrealbox.integer)
+                       SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
+               else
+                       SetMinMaxSize (e, quakemins, quakemaxs, true);
+       }
+       else
+               SetMinMaxSize (e, vec3_origin, vec3_origin, true);
+}
+
+/*
+=================
+PF_sprint
+
+single print to a specific client
+
+sprint(clientent, value)
+=================
+*/
+void PF_sprint (void)
+{
+       client_t        *client;
+       int                     entnum;
+       char string[VM_STRINGTEMP_LENGTH];
+
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+       {
+               Con_Print("tried to sprint to a non-client\n");
+               return;
+       }
+
+       client = svs.clients + entnum-1;
+       VM_VarString(1, string, sizeof(string));
+       MSG_WriteChar(&client->message,svc_print);
+       MSG_WriteString(&client->message, string);
+}
+
+
+/*
+=================
+PF_centerprint
+
+single print to a specific client
+
+centerprint(clientent, value)
+=================
+*/
+void PF_centerprint (void)
+{
+       client_t        *client;
+       int                     entnum;
+       char string[VM_STRINGTEMP_LENGTH];
+
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+       {
+               Con_Print("tried to sprint to a non-client\n");
+               return;
+       }
+
+       client = svs.clients + entnum-1;
+       VM_VarString(1, string, sizeof(string));
+       MSG_WriteChar(&client->message,svc_centerprint);
+       MSG_WriteString(&client->message, string);
+}
+
+/*
+=================
+PF_particle
+
+particle(origin, color, count)
+=================
+*/
+void PF_particle (void)
+{
+       float           *org, *dir;
+       float           color;
+       float           count;
+
+       org = PRVM_G_VECTOR(OFS_PARM0);
+       dir = PRVM_G_VECTOR(OFS_PARM1);
+       color = PRVM_G_FLOAT(OFS_PARM2);
+       count = PRVM_G_FLOAT(OFS_PARM3);
+       SV_StartParticle (org, dir, color, count);
+}
+
+
+/*
+=================
+PF_ambientsound
+
+=================
+*/
+void PF_ambientsound (void)
+{
+       const char      *samp;
+       float           *pos;
+       float           vol, attenuation;
+       int                     soundnum, large;
+
+       pos = PRVM_G_VECTOR (OFS_PARM0);
+       samp = PRVM_G_STRING(OFS_PARM1);
+       vol = PRVM_G_FLOAT(OFS_PARM2);
+       attenuation = PRVM_G_FLOAT(OFS_PARM3);
+
+// check to see if samp was properly precached
+       soundnum = SV_SoundIndex(samp, 1);
+       if (!soundnum)
+               return;
+
+       large = false;
+       if (soundnum >= 256)
+               large = true;
+
+       // add an svc_spawnambient command to the level signon packet
+
+       if (large)
+               MSG_WriteByte (&sv.signon, svc_spawnstaticsound2);
+       else
+               MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
+
+       MSG_WriteVector(&sv.signon, pos, sv.protocol);
+
+       if (large)
+               MSG_WriteShort (&sv.signon, soundnum);
+       else
+               MSG_WriteByte (&sv.signon, soundnum);
+
+       MSG_WriteByte (&sv.signon, vol*255);
+       MSG_WriteByte (&sv.signon, attenuation*64);
+
+}
+
+/*
+=================
+PF_sound
+
+Each entity can have eight independant sound sources, like voice,
+weapon, feet, etc.
+
+Channel 0 is an auto-allocate channel, the others override anything
+already running on that entity/channel pair.
+
+An attenuation of 0 will play full volume everywhere in the level.
+Larger attenuations will drop off.
+
+=================
+*/
+void PF_sound (void)
+{
+       const char      *sample;
+       int                     channel;
+       prvm_edict_t            *entity;
+       int             volume;
+       float attenuation;
+
+       entity = PRVM_G_EDICT(OFS_PARM0);
+       channel = PRVM_G_FLOAT(OFS_PARM1);
+       sample = PRVM_G_STRING(OFS_PARM2);
+       volume = PRVM_G_FLOAT(OFS_PARM3) * 255;
+       attenuation = PRVM_G_FLOAT(OFS_PARM4);
+
+       if (volume < 0 || volume > 255)
+               PF_WARNING("SV_StartSound: volume must be in range 0-1\n");
+
+       if (attenuation < 0 || attenuation > 4)
+               PF_WARNING("SV_StartSound: attenuation must be in range 0-4\n");
+
+       if (channel < 0 || channel > 7)
+               PF_WARNING("SV_StartSound: channel must be in range 0-7\n");
+
+       SV_StartSound (entity, channel, sample, volume, attenuation);
+}
+
+/*
+=================
+PF_traceline
+
+Used for use tracing and shot targeting
+Traces are blocked by bbox and exact bsp entityes, and also slide box entities
+if the tryents flag is set.
+
+traceline (vector1, vector2, tryents)
+=================
+*/
+void PF_traceline (void)
+{
+       float   *v1, *v2;
+       trace_t trace;
+       int             move;
+       prvm_edict_t    *ent;
+
+       prog->xfunction->builtinsprofile += 30;
+
+       v1 = PRVM_G_VECTOR(OFS_PARM0);
+       v2 = PRVM_G_VECTOR(OFS_PARM1);
+       move = PRVM_G_FLOAT(OFS_PARM2);
+       ent = PRVM_G_EDICT(OFS_PARM3);
+
+       trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent);
+
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
+       if (trace.ent)
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
+       else
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+       // FIXME: add trace_endcontents
+}
+
+
+/*
+=================
+PF_tracebox
+
+Used for use tracing and shot targeting
+Traces are blocked by bbox and exact bsp entityes, and also slide box entities
+if the tryents flag is set.
+
+tracebox (vector1, vector mins, vector maxs, vector2, tryents)
+=================
+*/
+// LordHavoc: added this for my own use, VERY useful, similar to traceline
+void PF_tracebox (void)
+{
+       float   *v1, *v2, *m1, *m2;
+       trace_t trace;
+       int             move;
+       prvm_edict_t    *ent;
+
+       prog->xfunction->builtinsprofile += 30;
+
+       v1 = PRVM_G_VECTOR(OFS_PARM0);
+       m1 = PRVM_G_VECTOR(OFS_PARM1);
+       m2 = PRVM_G_VECTOR(OFS_PARM2);
+       v2 = PRVM_G_VECTOR(OFS_PARM3);
+       move = PRVM_G_FLOAT(OFS_PARM4);
+       ent = PRVM_G_EDICT(OFS_PARM5);
+
+       trace = SV_Move (v1, m1, m2, v2, move, ent);
+
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
+       if (trace.ent)
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
+       else
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+}
+
+extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore);
+void PF_tracetoss (void)
+{
+       trace_t trace;
+       prvm_edict_t    *ent;
+       prvm_edict_t    *ignore;
+
+       prog->xfunction->builtinsprofile += 600;
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
+               PF_WARNING("tracetoss: can not use world entity\n");
+       ignore = PRVM_G_EDICT(OFS_PARM1);
+
+       trace = SV_Trace_Toss (ent, ignore);
+
+       prog->globals.server->trace_allsolid = trace.allsolid;
+       prog->globals.server->trace_startsolid = trace.startsolid;
+       prog->globals.server->trace_fraction = trace.fraction;
+       prog->globals.server->trace_inwater = trace.inwater;
+       prog->globals.server->trace_inopen = trace.inopen;
+       VectorCopy (trace.endpos, prog->globals.server->trace_endpos);
+       VectorCopy (trace.plane.normal, prog->globals.server->trace_plane_normal);
+       prog->globals.server->trace_plane_dist =  trace.plane.dist;
+       if (trace.ent)
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
+       else
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+}
+
+
+/*
+=================
+PF_checkpos
+
+Returns true if the given entity can move to the given position from it's
+current position by walking or rolling.
+FIXME: make work...
+scalar checkpos (entity, vector)
+=================
+*/
+void PF_checkpos (void)
+{
+}
+
+//============================================================================
+
+int checkpvsbytes;
+qbyte checkpvs[MAX_MAP_LEAFS/8];
+
+int PF_newcheckclient (int check)
+{
+       int             i;
+       prvm_edict_t    *ent;
+       vec3_t  org;
+
+// cycle to the next one
+
+       check = bound(1, check, svs.maxclients);
+       if (check == svs.maxclients)
+               i = 1;
+       else
+               i = check + 1;
+
+       for ( ;  ; i++)
+       {
+               // count the cost
+               prog->xfunction->builtinsprofile++;
+               // wrap around
+               if (i == svs.maxclients+1)
+                       i = 1;
+               // look up the client's edict
+               ent = PRVM_EDICT_NUM(i);
+               // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
+               if (i != check && (ent->priv.server->free || ent->fields.server->health <= 0 || ((int)ent->fields.server->flags & FL_NOTARGET)))
+                       continue;
+               // found a valid client (possibly the same one again)
+               break;
+       }
+
+// get the PVS for the entity
+       VectorAdd(ent->fields.server->origin, ent->fields.server->view_ofs, org);
+       checkpvsbytes = 0;
+       if (sv.worldmodel && sv.worldmodel->brush.FatPVS)
+               checkpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, org, 0, checkpvs, sizeof(checkpvs));
+
+       return i;
+}
+
+/*
+=================
+PF_checkclient
+
+Returns a client (or object that has a client enemy) that would be a
+valid target.
+
+If there is more than one valid option, they are cycled each frame
+
+If (self.origin + self.viewofs) is not in the PVS of the current target,
+it is not returned at all.
+
+name checkclient ()
+=================
+*/
+int c_invis, c_notvis;
+void PF_checkclient (void)
+{
+       prvm_edict_t    *ent, *self;
+       vec3_t  view;
+
+       // find a new check if on a new frame
+       if (sv.time - sv.lastchecktime >= 0.1)
+       {
+               sv.lastcheck = PF_newcheckclient (sv.lastcheck);
+               sv.lastchecktime = sv.time;
+       }
+
+       // return check if it might be visible
+       ent = PRVM_EDICT_NUM(sv.lastcheck);
+       if (ent->priv.server->free || ent->fields.server->health <= 0)
+       {
+               VM_RETURN_EDICT(prog->edicts);
+               return;
+       }
+
+       // if current entity can't possibly see the check entity, return 0
+       self = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       VectorAdd(self->fields.server->origin, self->fields.server->view_ofs, view);
+       if (sv.worldmodel && checkpvsbytes && !sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, checkpvs, view, view))
+       {
+               c_notvis++;
+               VM_RETURN_EDICT(prog->edicts);
+               return;
+       }
+
+       // might be able to see it
+       c_invis++;
+       VM_RETURN_EDICT(ent);
+}
+
+//============================================================================
+
+
+/*
+=================
+PF_stuffcmd
+
+Sends text over to the client's execution buffer
+
+stuffcmd (clientent, value)
+=================
+*/
+void PF_stuffcmd (void)
+{
+       int             entnum;
+       const char      *str;
+       client_t        *old;
+
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+       {
+               Con_Print("Can't stuffcmd to a non-client\n");
+               return;
+       }
+       str = PRVM_G_STRING(OFS_PARM1);
+
+       old = host_client;
+       host_client = svs.clients + entnum-1;
+       Host_ClientCommands ("%s", str);
+       host_client = old;
+}
+
+/*
+=================
+PF_findradius
+
+Returns a chain of entities that have origins within a spherical area
+
+findradius (origin, radius)
+=================
+*/
+void PF_findradius (void)
+{
+       prvm_edict_t *ent, *chain;
+       vec_t radius, radius2;
+       vec3_t org, eorg, mins, maxs;
+       int i;
+       int numtouchedicts;
+       prvm_edict_t *touchedicts[MAX_EDICTS];
+
+       chain = (prvm_edict_t *)prog->edicts;
+
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       radius = PRVM_G_FLOAT(OFS_PARM1);
+       radius2 = radius * radius;
+
+       mins[0] = org[0] - (radius + 1);
+       mins[1] = org[1] - (radius + 1);
+       mins[2] = org[2] - (radius + 1);
+       maxs[0] = org[0] + (radius + 1);
+       maxs[1] = org[1] + (radius + 1);
+       maxs[2] = org[2] + (radius + 1);
+       numtouchedicts = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, touchedicts);
+       if (numtouchedicts > MAX_EDICTS)
+       {
+               // this never happens
+               Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+               numtouchedicts = MAX_EDICTS;
+       }
+       for (i = 0;i < numtouchedicts;i++)
+       {
+               ent = touchedicts[i];
+               prog->xfunction->builtinsprofile++;
+               // Quake did not return non-solid entities but darkplaces does
+               // (note: this is the reason you can't blow up fallen zombies)
+               if (ent->fields.server->solid == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
+                       continue;
+               // LordHavoc: compare against bounding box rather than center so it
+               // doesn't miss large objects, and use DotProduct instead of Length
+               // for a major speedup
+               VectorSubtract(org, ent->fields.server->origin, eorg);
+               if (sv_gameplayfix_findradiusdistancetobox.integer)
+               {
+                       eorg[0] -= bound(ent->fields.server->mins[0], eorg[0], ent->fields.server->maxs[0]);
+                       eorg[1] -= bound(ent->fields.server->mins[1], eorg[1], ent->fields.server->maxs[1]);
+                       eorg[2] -= bound(ent->fields.server->mins[2], eorg[2], ent->fields.server->maxs[2]);
+               }
+               else
+                       VectorMAMAM(1, eorg, 0.5f, ent->fields.server->mins, 0.5f, ent->fields.server->maxs, eorg);
+               if (DotProduct(eorg, eorg) < radius2)
+               {
+                       ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
+                       chain = ent;
+               }
+       }
+
+       VM_RETURN_EDICT(chain);
+}
+
+// LordHavoc: search for flags in float fields
+void PF_findflags (void)
+{
+       int             e;
+       int             f;
+       int             s;
+       prvm_edict_t    *ed;
+
+       e = PRVM_G_EDICTNUM(OFS_PARM0);
+       f = PRVM_G_INT(OFS_PARM1);
+       s = (int)PRVM_G_FLOAT(OFS_PARM2);
+
+       for (e++ ; e < prog->num_edicts ; e++)
+       {
+               prog->xfunction->builtinsprofile++;
+               ed = PRVM_EDICT_NUM(e);
+               if (ed->priv.server->free)
+                       continue;
+               if ((int)PRVM_E_FLOAT(ed,f) & s)
+               {
+                       VM_RETURN_EDICT(ed);
+                       return;
+               }
+       }
+
+       VM_RETURN_EDICT(prog->edicts);
+}
+
+// LordHavoc: chained search for flags in float fields
+void PF_findchainflags (void)
+{
+       int             i;
+       int             f;
+       int             s;
+       prvm_edict_t    *ent, *chain;
+
+       chain = (prvm_edict_t *)prog->edicts;
+
+       f = PRVM_G_INT(OFS_PARM0);
+       s = (int)PRVM_G_FLOAT(OFS_PARM1);
+
+       ent = PRVM_NEXT_EDICT(prog->edicts);
+       for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
+       {
+               prog->xfunction->builtinsprofile++;
+               if (ent->priv.server->free)
+                       continue;
+               if (!((int)PRVM_E_FLOAT(ent,f) & s))
+                       continue;
+
+               ent->fields.server->chain = PRVM_EDICT_TO_PROG(chain);
+               chain = ent;
+       }
+
+       VM_RETURN_EDICT(chain);
+}
+
+void PF_precache_file (void)
+{      // precache_file is only used to copy files with qcc, it does nothing
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
+
+void PF_precache_sound (void)
+{
+       SV_SoundIndex(PRVM_G_STRING(OFS_PARM0), 2);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
+void PF_precache_model (void)
+{
+       SV_ModelIndex(PRVM_G_STRING(OFS_PARM0), 2);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
+/*
+===============
+PF_walkmove
+
+float(float yaw, float dist) walkmove
+===============
+*/
+void PF_walkmove (void)
+{
+       prvm_edict_t    *ent;
+       float   yaw, dist;
+       vec3_t  move;
+       mfunction_t     *oldf;
+       int     oldself;
+
+       // assume failure if it returns early
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
+
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
+               PF_WARNING("walkmove: can not modify world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("walkmove: can not modify free entity\n");
+       yaw = PRVM_G_FLOAT(OFS_PARM0);
+       dist = PRVM_G_FLOAT(OFS_PARM1);
+
+       if ( !( (int)ent->fields.server->flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
+               return;
+
+       yaw = yaw*M_PI*2 / 360;
+
+       move[0] = cos(yaw)*dist;
+       move[1] = sin(yaw)*dist;
+       move[2] = 0;
+
+// save program state, because SV_movestep may call other progs
+       oldf = prog->xfunction;
+       oldself = prog->globals.server->self;
+
+       PRVM_G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true);
+
+
+// restore program state
+       prog->xfunction = oldf;
+       prog->globals.server->self = oldself;
+}
+
+/*
+===============
+PF_droptofloor
+
+void() droptofloor
+===============
+*/
+void PF_droptofloor (void)
+{
+       prvm_edict_t            *ent;
+       vec3_t          end;
+       trace_t         trace;
+
+       // assume failure if it returns early
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
+
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
+               PF_WARNING("droptofloor: can not modify world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("droptofloor: can not modify free entity\n");
+
+       VectorCopy (ent->fields.server->origin, end);
+       end[2] -= 256;
+
+       trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+
+       if (trace.fraction != 1)
+       {
+               VectorCopy (trace.endpos, ent->fields.server->origin);
+               SV_LinkEdict (ent, false);
+               ent->fields.server->flags = (int)ent->fields.server->flags | FL_ONGROUND;
+               ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
+               PRVM_G_FLOAT(OFS_RETURN) = 1;
+               // if support is destroyed, keep suspended (gross hack for floating items in various maps)
+               ent->priv.server->suspendedinairflag = true;
+       }
+}
+
+/*
+===============
+PF_lightstyle
+
+void(float style, string value) lightstyle
+===============
+*/
+void PF_lightstyle (void)
+{
+       int             style;
+       const char      *val;
+       client_t        *client;
+       int                     j;
+
+       style = PRVM_G_FLOAT(OFS_PARM0);
+       val = PRVM_G_STRING(OFS_PARM1);
+
+// change the string in sv
+       strlcpy(sv.lightstyles[style], val, sizeof(sv.lightstyles[style]));
+
+// send message to all clients on this server
+       if (sv.state != ss_active)
+               return;
+
+       for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
+       {
+               if (client->active)
+               {
+                       MSG_WriteChar (&client->message, svc_lightstyle);
+                       MSG_WriteChar (&client->message,style);
+                       MSG_WriteString (&client->message, val);
+               }
+       }
+}
+
+/*
+=============
+PF_checkbottom
+=============
+*/
+void PF_checkbottom (void)
+{
+       PRVM_G_FLOAT(OFS_RETURN) = SV_CheckBottom (PRVM_G_EDICT(OFS_PARM0));
+}
+
+/*
+=============
+PF_pointcontents
+=============
+*/
+void PF_pointcontents (void)
+{
+       PRVM_G_FLOAT(OFS_RETURN) = SV_PointQ1Contents(PRVM_G_VECTOR(OFS_PARM0));
+}
+
+/*
+=============
+PF_aim
+
+Pick a vector for the player to shoot along
+vector aim(entity, missilespeed)
+=============
+*/
+void PF_aim (void)
+{
+       prvm_edict_t    *ent, *check, *bestent;
+       vec3_t  start, dir, end, bestdir;
+       int             i, j;
+       trace_t tr;
+       float   dist, bestdist;
+       float   speed;
+
+       // assume failure if it returns early
+       VectorCopy(prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
+       // if sv_aim is so high it can't possibly accept anything, skip out early
+       if (sv_aim.value >= 1)
+               return;
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
+               PF_WARNING("aim: can not use world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("aim: can not use free entity\n");
+       speed = PRVM_G_FLOAT(OFS_PARM1);
+
+       VectorCopy (ent->fields.server->origin, start);
+       start[2] += 20;
+
+// try sending a trace straight
+       VectorCopy (prog->globals.server->v_forward, dir);
+       VectorMA (start, 2048, dir, end);
+       tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
+       if (tr.ent && ((prvm_edict_t *)tr.ent)->fields.server->takedamage == DAMAGE_AIM
+       && (!teamplay.integer || ent->fields.server->team <=0 || ent->fields.server->team != ((prvm_edict_t *)tr.ent)->fields.server->team) )
+       {
+               VectorCopy (prog->globals.server->v_forward, PRVM_G_VECTOR(OFS_RETURN));
+               return;
+       }
+
+
+// try all possible entities
+       VectorCopy (dir, bestdir);
+       bestdist = sv_aim.value;
+       bestent = NULL;
+
+       check = PRVM_NEXT_EDICT(prog->edicts);
+       for (i=1 ; i<prog->num_edicts ; i++, check = PRVM_NEXT_EDICT(check) )
+       {
+               prog->xfunction->builtinsprofile++;
+               if (check->fields.server->takedamage != DAMAGE_AIM)
+                       continue;
+               if (check == ent)
+                       continue;
+               if (teamplay.integer && ent->fields.server->team > 0 && ent->fields.server->team == check->fields.server->team)
+                       continue;       // don't aim at teammate
+               for (j=0 ; j<3 ; j++)
+                       end[j] = check->fields.server->origin[j]
+                       + 0.5*(check->fields.server->mins[j] + check->fields.server->maxs[j]);
+               VectorSubtract (end, start, dir);
+               VectorNormalize (dir);
+               dist = DotProduct (dir, prog->globals.server->v_forward);
+               if (dist < bestdist)
+                       continue;       // to far to turn
+               tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
+               if (tr.ent == check)
+               {       // can shoot at this one
+                       bestdist = dist;
+                       bestent = check;
+               }
+       }
+
+       if (bestent)
+       {
+               VectorSubtract (bestent->fields.server->origin, ent->fields.server->origin, dir);
+               dist = DotProduct (dir, prog->globals.server->v_forward);
+               VectorScale (prog->globals.server->v_forward, dist, end);
+               end[2] = dir[2];
+               VectorNormalize (end);
+               VectorCopy (end, PRVM_G_VECTOR(OFS_RETURN));
+       }
+       else
+       {
+               VectorCopy (bestdir, PRVM_G_VECTOR(OFS_RETURN));
+       }
+}
+
+/*
+==============
+PF_changeyaw
+
+This was a major timewaster in progs, so it was converted to C
+==============
+*/
+void PF_changeyaw (void)
+{
+       prvm_edict_t            *ent;
+       float           ideal, current, move, speed;
+
+       ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
+       if (ent == prog->edicts)
+               PF_WARNING("changeyaw: can not modify world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("changeyaw: can not modify free entity\n");
+       current = ANGLEMOD(ent->fields.server->angles[1]);
+       ideal = ent->fields.server->ideal_yaw;
+       speed = ent->fields.server->yaw_speed;
+
+       if (current == ideal)
+               return;
+       move = ideal - current;
+       if (ideal > current)
+       {
+               if (move >= 180)
+                       move = move - 360;
+       }
+       else
+       {
+               if (move <= -180)
+                       move = move + 360;
+       }
+       if (move > 0)
+       {
+               if (move > speed)
+                       move = speed;
+       }
+       else
+       {
+               if (move < -speed)
+                       move = -speed;
+       }
+
+       ent->fields.server->angles[1] = ANGLEMOD (current + move);
+}
+
+/*
+==============
+PF_changepitch
+==============
+*/
+void PF_changepitch (void)
+{
+       prvm_edict_t            *ent;
+       float           ideal, current, move, speed;
+       prvm_eval_t             *val;
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
+               PF_WARNING("changepitch: can not modify world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("changepitch: can not modify free entity\n");
+       current = ANGLEMOD( ent->fields.server->angles[0] );
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_idealpitch)))
+               ideal = val->_float;
+       else
+       {
+               PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
+               return;
+       }
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_pitch_speed)))
+               speed = val->_float;
+       else
+       {
+               PF_WARNING("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch\n");
+               return;
+       }
+
+       if (current == ideal)
+               return;
+       move = ideal - current;
+       if (ideal > current)
+       {
+               if (move >= 180)
+                       move = move - 360;
+       }
+       else
+       {
+               if (move <= -180)
+                       move = move + 360;
+       }
+       if (move > 0)
+       {
+               if (move > speed)
+                       move = speed;
+       }
+       else
+       {
+               if (move < -speed)
+                       move = -speed;
+       }
+
+       ent->fields.server->angles[0] = ANGLEMOD (current + move);
+}
+
+/*
+===============================================================================
+
+MESSAGE WRITING
+
+===============================================================================
+*/
+
+#define        MSG_BROADCAST   0               // unreliable to all
+#define        MSG_ONE                 1               // reliable to one (msg_entity)
+#define        MSG_ALL                 2               // reliable to all
+#define        MSG_INIT                3               // write to the init string
+
+sizebuf_t *WriteDest (void)
+{
+       int             entnum;
+       int             dest;
+       prvm_edict_t    *ent;
+
+       dest = PRVM_G_FLOAT(OFS_PARM0);
+       switch (dest)
+       {
+       case MSG_BROADCAST:
+               return &sv.datagram;
+
+       case MSG_ONE:
+               ent = PRVM_PROG_TO_EDICT(prog->globals.server->msg_entity);
+               entnum = PRVM_NUM_FOR_EDICT(ent);
+               if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+                       Host_Error("WriteDest: tried to write to non-client\n");
+               return &svs.clients[entnum-1].message;
+
+       case MSG_ALL:
+               return &sv.reliable_datagram;
+
+       case MSG_INIT:
+               return &sv.signon;
+
+       default:
+               Host_Error("WriteDest: bad destination");
+               break;
+       }
+
+       return NULL;
+}
+
+void PF_WriteByte (void)
+{
+       MSG_WriteByte (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
+}
+
+void PF_WriteChar (void)
+{
+       MSG_WriteChar (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
+}
+
+void PF_WriteShort (void)
+{
+       MSG_WriteShort (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
+}
+
+void PF_WriteLong (void)
+{
+       MSG_WriteLong (WriteDest(), PRVM_G_FLOAT(OFS_PARM1));
+}
+
+void PF_WriteAngle (void)
+{
+       MSG_WriteAngle (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+}
+
+void PF_WriteCoord (void)
+{
+       MSG_WriteCoord (WriteDest(), PRVM_G_FLOAT(OFS_PARM1), sv.protocol);
+}
+
+void PF_WriteString (void)
+{
+       MSG_WriteString (WriteDest(), PRVM_G_STRING(OFS_PARM1));
+}
+
+
+void PF_WriteEntity (void)
+{
+       MSG_WriteShort (WriteDest(), PRVM_G_EDICTNUM(OFS_PARM1));
+}
+
+//////////////////////////////////////////////////////////
+
+void PF_makestatic (void)
+{
+       prvm_edict_t *ent;
+       int i, large;
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent == prog->edicts)
+               PF_WARNING("makestatic: can not modify world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("makestatic: can not modify free entity\n");
+
+       large = false;
+       if (ent->fields.server->modelindex >= 256 || ent->fields.server->frame >= 256)
+               large = true;
+
+       if (large)
+       {
+               MSG_WriteByte (&sv.signon,svc_spawnstatic2);
+               MSG_WriteShort (&sv.signon, ent->fields.server->modelindex);
+               MSG_WriteShort (&sv.signon, ent->fields.server->frame);
+       }
+       else
+       {
+               MSG_WriteByte (&sv.signon,svc_spawnstatic);
+               MSG_WriteByte (&sv.signon, ent->fields.server->modelindex);
+               MSG_WriteByte (&sv.signon, ent->fields.server->frame);
+       }
+
+       MSG_WriteByte (&sv.signon, ent->fields.server->colormap);
+       MSG_WriteByte (&sv.signon, ent->fields.server->skin);
+       for (i=0 ; i<3 ; i++)
+       {
+               MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol);
+               MSG_WriteAngle(&sv.signon, ent->fields.server->angles[i], sv.protocol);
+       }
+
+// throw the entity away now
+       PRVM_ED_Free (ent);
+}
+
+//=============================================================================
+
+/*
+==============
+PF_setspawnparms
+==============
+*/
+void PF_setspawnparms (void)
+{
+       prvm_edict_t    *ent;
+       int             i;
+       client_t        *client;
+
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       i = PRVM_NUM_FOR_EDICT(ent);
+       if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
+       {
+               Con_Print("tried to setspawnparms on a non-client\n");
+               return;
+       }
+
+       // copy spawn parms out of the client_t
+       client = svs.clients + i-1;
+       for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
+               (&prog->globals.server->parm1)[i] = client->spawn_parms[i];
+}
+
+/*
+=================
+PF_getlight
+
+Returns a color vector indicating the lighting at the requested point.
+
+(Internal Operation note: actually measures the light beneath the point, just like
+                          the model lighting on the client)
+
+getlight(vector)
+=================
+*/
+void PF_getlight (void)
+{
+       vec3_t ambientcolor, diffusecolor, diffusenormal;
+       vec_t *p;
+       p = PRVM_G_VECTOR(OFS_PARM0);
+       VectorClear(ambientcolor);
+       VectorClear(diffusecolor);
+       VectorClear(diffusenormal);
+       if (sv.worldmodel && sv.worldmodel->brush.LightPoint)
+               sv.worldmodel->brush.LightPoint(sv.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
+       VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
+}
+
+void PF_registercvar (void)
+{
+       const char *name, *value;
+       name = PRVM_G_STRING(OFS_PARM0);
+       value = PRVM_G_STRING(OFS_PARM1);
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
+
+// first check to see if it has already been defined
+       if (Cvar_FindVar (name))
+               return;
+
+// check for overlap with a command
+       if (Cmd_Exists (name))
+       {
+               Con_Printf("PF_registercvar: %s is a command\n", name);
+               return;
+       }
+
+       Cvar_Get(name, value, 0);
+
+       PRVM_G_FLOAT(OFS_RETURN) = 1; // success
+}
+
+/*
+=================
+PF_copyentity
+
+copies data from one entity to another
+
+copyentity(src, dst)
+=================
+*/
+void PF_copyentity (void)
+{
+       prvm_edict_t *in, *out;
+       in = PRVM_G_EDICT(OFS_PARM0);
+       if (in == prog->edicts)
+               PF_WARNING("copyentity: can not read world entity\n");
+       if (in->priv.server->free)
+               PF_WARNING("copyentity: can not read free entity\n");
+       out = PRVM_G_EDICT(OFS_PARM1);
+       if (out == prog->edicts)
+               PF_WARNING("copyentity: can not modify world entity\n");
+       if (out->priv.server->free)
+               PF_WARNING("copyentity: can not modify free entity\n");
+       memcpy(out->fields.server, in->fields.server, prog->progs->entityfields * 4);
+}
+
+
+/*
+=================
+PF_setcolor
+
+sets the color of a client and broadcasts the update to all connected clients
+
+setcolor(clientent, value)
+=================
+*/
+void PF_setcolor (void)
+{
+       client_t *client;
+       int entnum, i;
+       prvm_eval_t *val;
+
+       entnum = PRVM_G_EDICTNUM(OFS_PARM0);
+       i = PRVM_G_FLOAT(OFS_PARM1);
+
+       if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+       {
+               Con_Print("tried to setcolor a non-client\n");
+               return;
+       }
+
+       client = svs.clients + entnum-1;
+       if (client->edict)
+       {
+               if ((val = PRVM_GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
+                       val->_float = i;
+               client->edict->fields.server->team = (i & 15) + 1;
+       }
+       client->colors = i;
+       if (client->old_colors != client->colors)
+       {
+               client->old_colors = client->colors;
+               // send notification to all clients
+               MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
+               MSG_WriteByte (&sv.reliable_datagram, client - svs.clients);
+               MSG_WriteByte (&sv.reliable_datagram, client->colors);
+       }
+}
+
+/*
+=================
+PF_effect
+
+effect(origin, modelname, startframe, framecount, framerate)
+=================
+*/
+void PF_effect (void)
+{
+       int i;
+       const char *s;
+       s = PRVM_G_STRING(OFS_PARM1);
+       if (!s || !s[0])
+               PF_WARNING("effect: no model specified\n");
+
+       i = SV_ModelIndex(s, 1);
+       if (!i)
+               PF_WARNING("effect: model not precached\n");
+       SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
+}
+
+void PF_te_blood (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM2) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_BLOOD);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // velocity
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
+       // count
+       MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
+}
+
+void PF_te_bloodshower (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_BLOODSHOWER);
+       // min
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // max
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // speed
+       MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol);
+       // count
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
+}
+
+void PF_te_explosionrgb (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_EXPLOSIONRGB);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // color
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[0] * 255), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[1] * 255), 255));
+       MSG_WriteByte(&sv.datagram, bound(0, (int) (PRVM_G_VECTOR(OFS_PARM1)[2] * 255), 255));
+}
+
+void PF_te_particlecube (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_PARTICLECUBE);
+       // min
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // max
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // velocity
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       // count
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
+       // color
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
+       // gravity true/false
+       MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0);
+       // randomvel
+       MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM6), sv.protocol);
+}
+
+void PF_te_particlerain (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_PARTICLERAIN);
+       // min
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // max
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // velocity
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       // count
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
+       // color
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
+}
+
+void PF_te_particlesnow (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM3) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_PARTICLESNOW);
+       // min
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // max
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // velocity
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+       // count
+       MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535));
+       // color
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4));
+}
+
+void PF_te_spark (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM2) < 1)
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SPARK);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // velocity
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[0], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[1], 127));
+       MSG_WriteByte(&sv.datagram, bound(-128, (int) PRVM_G_VECTOR(OFS_PARM1)[2], 127));
+       // count
+       MSG_WriteByte(&sv.datagram, bound(0, (int) PRVM_G_FLOAT(OFS_PARM2), 255));
+}
+
+void PF_te_gunshotquad (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_GUNSHOTQUAD);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_spikequad (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SPIKEQUAD);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_superspikequad (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SUPERSPIKEQUAD);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_explosionquad (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_EXPLOSIONQUAD);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_smallflash (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SMALLFLASH);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_customflash (void)
+{
+       if (PRVM_G_FLOAT(OFS_PARM1) < 8 || PRVM_G_FLOAT(OFS_PARM2) < (1.0 / 256.0))
+               return;
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_CUSTOMFLASH);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // radius
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255));
+       // lifetime
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255));
+       // color
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255));
+       MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255));
+}
+
+void PF_te_gunshot (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_GUNSHOT);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_spike (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SPIKE);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_superspike (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_SUPERSPIKE);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_explosion (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_EXPLOSION);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_tarexplosion (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_TAREXPLOSION);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_wizspike (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_WIZSPIKE);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_knightspike (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_KNIGHTSPIKE);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_lavasplash (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_LAVASPLASH);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_teleport (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_TELEPORT);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+void PF_te_explosion2 (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_EXPLOSION2);
+       // origin
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+       // color
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM1));
+       MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2));
+}
+
+void PF_te_lightning1 (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_LIGHTNING1);
+       // owner entity
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
+       // start
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // end
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+}
+
+void PF_te_lightning2 (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_LIGHTNING2);
+       // owner entity
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
+       // start
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // end
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+}
+
+void PF_te_lightning3 (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_LIGHTNING3);
+       // owner entity
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
+       // start
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // end
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+}
+
+void PF_te_beam (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_BEAM);
+       // owner entity
+       MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
+       // start
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol);
+       // end
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol);
+}
+
+void PF_te_plasmaburn (void)
+{
+       MSG_WriteByte(&sv.datagram, svc_temp_entity);
+       MSG_WriteByte(&sv.datagram, TE_PLASMABURN);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[0], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol);
+       MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol);
+}
+
+static void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out)
+{
+       int i, j, k;
+       float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
+       const int *e;
+       bestdist = 1000000000;
+       VectorCopy(p, out);
+       for (i = 0, e = (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3)
+       {
+               // clip original point to each triangle of the surface and find the
+               // triangle that is closest
+               v[0] = surface->groupmesh->data_vertex3f + e[0] * 3;
+               v[1] = surface->groupmesh->data_vertex3f + e[1] * 3;
+               v[2] = surface->groupmesh->data_vertex3f + e[2] * 3;
+               TriangleNormal(v[0], v[1], v[2], facenormal);
+               VectorNormalize(facenormal);
+               offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
+               VectorMA(p, offsetdist, facenormal, temp);
+               for (j = 0, k = 2;j < 3;k = j, j++)
+               {
+                       VectorSubtract(v[k], v[j], edgenormal);
+                       CrossProduct(edgenormal, facenormal, sidenormal);
+                       VectorNormalize(sidenormal);
+                       offsetdist = DotProduct(v[k], sidenormal) - DotProduct(temp, sidenormal);
+                       if (offsetdist < 0)
+                               VectorMA(temp, offsetdist, sidenormal, temp);
+               }
+               dist = VectorDistance2(temp, p);
+               if (bestdist > dist)
+               {
+                       bestdist = dist;
+                       VectorCopy(temp, out);
+               }
+       }
+}
+
+static msurface_t *getsurface(prvm_edict_t *ed, int surfacenum)
+{
+       int modelindex;
+       model_t *model;
+       if (!ed || ed->priv.server->free)
+               return NULL;
+       modelindex = ed->fields.server->modelindex;
+       if (modelindex < 1 || modelindex >= MAX_MODELS)
+               return NULL;
+       model = sv.models[modelindex];
+       if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
+               return NULL;
+       return model->data_surfaces + surfacenum + model->firstmodelsurface;
+}
+
+
+//PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
+void PF_getsurfacenumpoints(void)
+{
+       msurface_t *surface;
+       // return 0 if no such surface
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
+       {
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+               return;
+       }
+
+       // note: this (incorrectly) assumes it is a simple polygon
+       PRVM_G_FLOAT(OFS_RETURN) = surface->num_vertices;
+}
+//PF_getsurfacepoint,     // #435 vector(entity e, float s, float n) getsurfacepoint = #435;
+void PF_getsurfacepoint(void)
+{
+       prvm_edict_t *ed;
+       msurface_t *surface;
+       int pointnum;
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       if (!ed || ed->priv.server->free)
+               return;
+       if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1))))
+               return;
+       // note: this (incorrectly) assumes it is a simple polygon
+       pointnum = PRVM_G_FLOAT(OFS_PARM2);
+       if (pointnum < 0 || pointnum >= surface->num_vertices)
+               return;
+       // FIXME: implement rotation/scaling
+       VectorAdd(&(surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
+}
+//PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
+void PF_getsurfacenormal(void)
+{
+       msurface_t *surface;
+       vec3_t normal;
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
+               return;
+       // FIXME: implement rotation/scaling
+       // note: this (incorrectly) assumes it is a simple polygon
+       // note: this only returns the first triangle, so it doesn't work very
+       // well for curved surfaces or arbitrary meshes
+       TriangleNormal((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 3, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
+       VectorNormalize(normal);
+       VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN));
+}
+//PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
+void PF_getsurfacetexture(void)
+{
+       msurface_t *surface;
+       PRVM_G_INT(OFS_RETURN) = 0;
+       if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1))))
+               return;
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name);
+}
+//PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438;
+void PF_getsurfacenearpoint(void)
+{
+       int surfacenum, best, modelindex;
+       vec3_t clipped, p;
+       vec_t dist, bestdist;
+       prvm_edict_t *ed;
+       model_t *model;
+       msurface_t *surface;
+       vec_t *point;
+       PRVM_G_FLOAT(OFS_RETURN) = -1;
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       point = PRVM_G_VECTOR(OFS_PARM1);
+
+       if (!ed || ed->priv.server->free)
+               return;
+       modelindex = ed->fields.server->modelindex;
+       if (modelindex < 1 || modelindex >= MAX_MODELS)
+               return;
+       model = sv.models[modelindex];
+       if (!model->num_surfaces)
+               return;
+
+       // FIXME: implement rotation/scaling
+       VectorSubtract(point, ed->fields.server->origin, p);
+       best = -1;
+       bestdist = 1000000000;
+       for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
+       {
+               surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
+               // first see if the nearest point on the surface's box is closer than the previous match
+               clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
+               clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
+               clipped[2] = bound(surface->mins[2], p[2], surface->maxs[2]) - p[2];
+               dist = VectorLength2(clipped);
+               if (dist < bestdist)
+               {
+                       // it is, check the nearest point on the actual geometry
+                       clippointtosurface(surface, p, clipped);
+                       VectorSubtract(clipped, p, clipped);
+                       dist += VectorLength2(clipped);
+                       if (dist < bestdist)
+                       {
+                               // that's closer too, store it as the best match
+                               best = surfacenum;
+                               bestdist = dist;
+                       }
+               }
+       }
+       PRVM_G_FLOAT(OFS_RETURN) = best;
+}
+//PF_getsurfaceclippedpoint, // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint = #439;
+void PF_getsurfaceclippedpoint(void)
+{
+       prvm_edict_t *ed;
+       msurface_t *surface;
+       vec3_t p, out;
+       VectorClear(PRVM_G_VECTOR(OFS_RETURN));
+       ed = PRVM_G_EDICT(OFS_PARM0);
+       if (!ed || ed->priv.server->free)
+               return;
+       if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1))))
+               return;
+       // FIXME: implement rotation/scaling
+       VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p);
+       clippointtosurface(surface, p, out);
+       // FIXME: implement rotation/scaling
+       VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
+}
+
+//void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
+//this function originally written by KrimZon, made shorter by LordHavoc
+void PF_clientcommand (void)
+{
+       client_t *temp_client;
+       int i;
+
+       //find client for this entity
+       i = (PRVM_NUM_FOR_EDICT(PRVM_G_EDICT(OFS_PARM0)) - 1);
+       if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
+       {
+               Con_Print("PF_clientcommand: entity is not a client\n");
+               return;
+       }
+
+       temp_client = host_client;
+       host_client = svs.clients + i;
+       Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
+       host_client = temp_client;
+}
+
+//void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
+void PF_setattachment (void)
+{
+       prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
+       prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
+       const char *tagname = PRVM_G_STRING(OFS_PARM2);
+       prvm_eval_t *v;
+       int modelindex;
+       model_t *model;
+
+       if (e == prog->edicts)
+               PF_WARNING("setattachment: can not modify world entity\n");
+       if (e->priv.server->free)
+               PF_WARNING("setattachment: can not modify free entity\n");
+
+       if (tagentity == NULL)
+               tagentity = prog->edicts;
+
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_entity);
+       if (v)
+               v->edict = PRVM_EDICT_TO_PROG(tagentity);
+
+       v = PRVM_GETEDICTFIELDVALUE(e, eval_tag_index);
+       if (v)
+               v->_float = 0;
+       if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
+       {
+               modelindex = (int)tagentity->fields.server->modelindex;
+               if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex]))
+               {
+                       v->_float = Mod_Alias_GetTagIndexForName(model, tagentity->fields.server->skin, tagname);
+                       if (v->_float == 0)
+                               Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
+               }
+               else
+                       Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
+       }
+}
+
+/////////////////////////////////////////
+// DP_MD3_TAGINFO extension coded by VorteX
+
+int SV_GetTagIndex (prvm_edict_t *e, const char *tagname)
+{
+       int i;
+       model_t *model;
+
+       i = e->fields.server->modelindex;
+       if (i < 1 || i >= MAX_MODELS)
+               return -1;
+       model = sv.models[i];
+
+       return Mod_Alias_GetTagIndexForName(model, e->fields.server->skin, tagname);
+};
+
+// Warnings/errors code:
+// 0 - normal (everything all-right)
+// 1 - world entity
+// 2 - free entity
+// 3 - null or non-precached model
+// 4 - no tags with requested index
+// 5 - runaway loop at attachment chain
+extern cvar_t cl_bob;
+extern cvar_t cl_bobcycle;
+extern cvar_t cl_bobup;
+int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
+{
+       prvm_eval_t *val;
+       int modelindex, reqframe, attachloop;
+       matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
+       prvm_edict_t *attachent;
+       model_t *model;
+
+       Matrix4x4_CreateIdentity(out); // warnings and errors return identical matrix
+
+       if (ent == prog->edicts)
+               return 1;
+       if (ent->priv.server->free)
+               return 2;
+
+       modelindex = (int)ent->fields.server->modelindex;
+       if (modelindex <= 0 || modelindex > MAX_MODELS)
+               return 3;
+
+       model = sv.models[modelindex];
+
+       if (ent->fields.server->frame >= 0 && ent->fields.server->frame < model->numframes && model->animscenes)
+               reqframe = model->animscenes[(int)ent->fields.server->frame].firstframe;
+       else
+               reqframe = 0; // if model has wrong frame, engine automatically switches to model first frame
+
+       // get initial tag matrix
+       if (tagindex)
+       {
+               int ret = Mod_Alias_GetTagMatrix(model, reqframe, tagindex - 1, &tagmatrix);
+               if (ret)
+                       return ret;
+       }
+       else
+               Matrix4x4_CreateIdentity(&tagmatrix);
+
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict)
+       { // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity
+               attachloop = 0;
+               do
+               {
+                       attachent = PRVM_EDICT_NUM(val->edict); // to this it entity our entity is attached
+                       val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index);
+                       if (val->_float >= 1 && attachent->fields.server->modelindex >= 1 && attachent->fields.server->modelindex < MAX_MODELS && (model = sv.models[(int)attachent->fields.server->modelindex]) && model->animscenes && attachent->fields.server->frame >= 0 && attachent->fields.server->frame < model->numframes)
+                               Mod_Alias_GetTagMatrix(model, model->animscenes[(int)attachent->fields.server->frame].firstframe, val->_float - 1, &attachmatrix);
+                       else
+                               Matrix4x4_CreateIdentity(&attachmatrix);
+
+                       // apply transformation by child entity matrix
+                       val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
+                       if (val->_float == 0)
+                               val->_float = 1;
+                       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float);
+                       Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
+                       out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
+                       out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
+                       out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+                       Matrix4x4_Copy(&tagmatrix, out);
+
+                       // finally transformate by matrix of tag on parent entity
+                       Matrix4x4_Concat(out, &attachmatrix, &tagmatrix);
+                       out->m[0][3] = attachmatrix.m[0][3] + attachmatrix.m[0][0]*tagmatrix.m[0][3] + attachmatrix.m[0][1]*tagmatrix.m[1][3] + attachmatrix.m[0][2]*tagmatrix.m[2][3];
+                       out->m[1][3] = attachmatrix.m[1][3] + attachmatrix.m[1][0]*tagmatrix.m[0][3] + attachmatrix.m[1][1]*tagmatrix.m[1][3] + attachmatrix.m[1][2]*tagmatrix.m[2][3];
+                       out->m[2][3] = attachmatrix.m[2][3] + attachmatrix.m[2][0]*tagmatrix.m[0][3] + attachmatrix.m[2][1]*tagmatrix.m[1][3] + attachmatrix.m[2][2]*tagmatrix.m[2][3];
+                       Matrix4x4_Copy(&tagmatrix, out);
+
+                       ent = attachent;
+                       attachloop += 1;
+                       if (attachloop > 255) // prevent runaway looping
+                               return 5;
+               }
+               while ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict);
+       }
+
+       // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
+       val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
+       if (val->_float == 0)
+               val->_float = 1;
+       // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
+       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], -ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], val->_float);
+       Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
+       out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
+       out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
+       out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+
+       if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
+       {// RENDER_VIEWMODEL magic
+               Matrix4x4_Copy(&tagmatrix, out);
+               ent = PRVM_EDICT_NUM(val->edict);
+
+               val = PRVM_GETEDICTFIELDVALUE(ent, eval_scale);
+               if (val->_float == 0)
+                       val->_float = 1;
+
+               Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], val->_float);
+               Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
+               out->m[0][3] = entitymatrix.m[0][3] + val->_float*(entitymatrix.m[0][0]*tagmatrix.m[0][3] + entitymatrix.m[0][1]*tagmatrix.m[1][3] + entitymatrix.m[0][2]*tagmatrix.m[2][3]);
+               out->m[1][3] = entitymatrix.m[1][3] + val->_float*(entitymatrix.m[1][0]*tagmatrix.m[0][3] + entitymatrix.m[1][1]*tagmatrix.m[1][3] + entitymatrix.m[1][2]*tagmatrix.m[2][3]);
+               out->m[2][3] = entitymatrix.m[2][3] + val->_float*(entitymatrix.m[2][0]*tagmatrix.m[0][3] + entitymatrix.m[2][1]*tagmatrix.m[1][3] + entitymatrix.m[2][2]*tagmatrix.m[2][3]);
+
+               /*
+               // Cl_bob, ported from rendering code
+               if (ent->fields.server->health > 0 && cl_bob.value && cl_bobcycle.value)
+               {
+                       double bob, cycle;
+                       // LordHavoc: this code is *weird*, but not replacable (I think it
+                       // should be done in QC on the server, but oh well, quake is quake)
+                       // LordHavoc: figured out bobup: the time at which the sin is at 180
+                       // degrees (which allows lengthening or squishing the peak or valley)
+                       cycle = sv.time/cl_bobcycle.value;
+                       cycle -= (int)cycle;
+                       if (cycle < cl_bobup.value)
+                               cycle = sin(M_PI * cycle / cl_bobup.value);
+                       else
+                               cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
+                       // bob is proportional to velocity in the xy plane
+                       // (don't count Z, or jumping messes it up)
+                       bob = sqrt(ent->fields.server->velocity[0]*ent->fields.server->velocity[0] + ent->fields.server->velocity[1]*ent->fields.server->velocity[1])*cl_bob.value;
+                       bob = bob*0.3 + bob*0.7*cycle;
+                       out->m[2][3] += bound(-7, bob, 4);
+               }
+               */
+       }
+       return 0;
+}
+
+//float(entity ent, string tagname) gettagindex;
+
+void PF_gettagindex (void)
+{
+       prvm_edict_t *ent = PRVM_G_EDICT(OFS_PARM0);
+       const char *tag_name = PRVM_G_STRING(OFS_PARM1);
+       int modelindex, tag_index;
+
+       if (ent == prog->edicts)
+               PF_WARNING("gettagindex: can't affect world entity\n");
+       if (ent->priv.server->free)
+               PF_WARNING("gettagindex: can't affect free entity\n");
+
+       modelindex = (int)ent->fields.server->modelindex;
+       tag_index = 0;
+       if (modelindex <= 0 || modelindex > MAX_MODELS)
+               Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
+       else
+       {
+               tag_index = SV_GetTagIndex(ent, tag_name);
+               if (tag_index == 0)
+                       Con_DPrintf("gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
+       }
+       PRVM_G_FLOAT(OFS_RETURN) = tag_index;
+};
+
+//vector(entity ent, float tagindex) gettaginfo;
+void PF_gettaginfo (void)
+{
+       prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
+       int tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
+       matrix4x4_t tag_matrix;
+       int returncode;
+
+       returncode = SV_GetTagMatrix(&tag_matrix, e, tagindex);
+       Matrix4x4_ToVectors(&tag_matrix, prog->globals.server->v_forward, prog->globals.server->v_right, prog->globals.server->v_up, PRVM_G_VECTOR(OFS_RETURN));
+
+       switch(returncode)
+       {
+               case 1:
+                       PF_WARNING("gettagindex: can't affect world entity\n");
+                       break;
+               case 2:
+                       PF_WARNING("gettagindex: can't affect free entity\n");
+                       break;
+               case 3:
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(e));
+                       break;
+               case 4:
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): model has no tag with requested index %i\n", PRVM_NUM_FOR_EDICT(e), tagindex);
+                       break;
+               case 5:
+                       Con_DPrintf("SV_GetTagMatrix(entity #%i): runaway loop at attachment chain\n", PRVM_NUM_FOR_EDICT(e));
+                       break;
+       }
+}
+
+//void(entity clent) dropclient (DP_SV_DROPCLIENT)
+void PF_dropclient (void)
+{
+       int clientnum;
+       client_t *oldhostclient;
+       clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
+       if (clientnum < 0 || clientnum >= svs.maxclients)
+               PF_WARNING("dropclient: not a client\n");
+       if (!svs.clients[clientnum].active)
+               PF_WARNING("dropclient: that client slot is not connected\n");
+       oldhostclient = host_client;
+       host_client = svs.clients + clientnum;
+       SV_DropClient(false);
+       host_client = oldhostclient;
+}
+
+//entity() spawnclient (DP_SV_BOTCLIENT)
+void PF_spawnclient (void)
+{
+       int i;
+       prvm_edict_t    *ed;
+       prog->xfunction->builtinsprofile += 2;
+       ed = prog->edicts;
+       for (i = 0;i < svs.maxclients;i++)
+       {
+               if (!svs.clients[i].active)
+               {
+                       prog->xfunction->builtinsprofile += 100;
+                       SV_ConnectClient (i, NULL);
+                       ed = PRVM_EDICT_NUM(i + 1);
+                       break;
+               }
+       }
+       VM_RETURN_EDICT(ed);
+}
+
+//float(entity clent) clienttype (DP_SV_BOTCLIENT)
+void PF_clienttype (void)
+{
+       int clientnum;
+       clientnum = PRVM_G_EDICTNUM(OFS_PARM0) - 1;
+       if (clientnum < 0 || clientnum >= svs.maxclients)
+               PRVM_G_FLOAT(OFS_RETURN) = 3;
+       else if (!svs.clients[clientnum].active)
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+       else if (svs.clients[clientnum].netconnection)
+               PRVM_G_FLOAT(OFS_RETURN) = 1;
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = 2;
+}
+
+prvm_builtin_t vm_sv_builtins[] = {
+NULL,                                          // #0
+PF_makevectors,                                // #1 void(entity e) makevectors
+PF_setorigin,                          // #2 void(entity e, vector o) setorigin
+PF_setmodel,                           // #3 void(entity e, string m) setmodel
+PF_setsize,                                    // #4 void(entity e, vector min, vector max) setsize
+NULL,                                          // #5 void(entity e, vector min, vector max) setabssize
+VM_break,                                      // #6 void() break
+VM_random,                                     // #7 float() random
+PF_sound,                                      // #8 void(entity e, float chan, string samp) sound
+VM_normalize,                          // #9 vector(vector v) normalize
+VM_error,                                      // #10 void(string e) error
+VM_objerror,                           // #11 void(string e) objerror
+VM_vlen,                                       // #12 float(vector v) vlen
+VM_vectoyaw,                           // #13 float(vector v) vectoyaw
+VM_spawn,                                      // #14 entity() spawn
+VM_remove,                                     // #15 void(entity e) remove
+PF_traceline,                          // #16 float(vector v1, vector v2, float tryents) traceline
+PF_checkclient,                                // #17 entity() clientlist
+VM_find,                                       // #18 entity(entity start, .string fld, string match) find
+PF_precache_sound,                     // #19 void(string s) precache_sound
+PF_precache_model,                     // #20 void(string s) precache_model
+PF_stuffcmd,                           // #21 void(entity client, string s)stuffcmd
+PF_findradius,                         // #22 entity(vector org, float rad) findradius
+VM_bprint,                                     // #23 void(string s) bprint
+PF_sprint,                                     // #24 void(entity client, string s) sprint
+VM_dprint,                                     // #25 void(string s) dprint
+VM_ftos,                                       // #26 void(string s) ftos
+VM_vtos,                                       // #27 void(string s) vtos
+VM_coredump,                           // #28 void() coredump
+VM_traceon,                                    // #29 void() traceon
+VM_traceoff,                           // #30 void() traceoff
+VM_eprint,                                     // #31 void(entity e) eprint
+PF_walkmove,                           // #32 float(float yaw, float dist) walkmove
+NULL,                                          // #33
+PF_droptofloor,                                // #34 float() droptofloor
+PF_lightstyle,                         // #35 void(float style, string value) lightstyle
+VM_rint,                                       // #36 float(float v) rint
+VM_floor,                                      // #37 float(float v) floor
+VM_ceil,                                       // #38 float(float v) ceil
+NULL,                                          // #39
+PF_checkbottom,                                // #40 float(entity e) checkbottom
+PF_pointcontents,                      // #41 float(vector v) pointcontents
+NULL,                                          // #42
+VM_fabs,                                       // #43 float(float f) fabs
+PF_aim,                                                // #44 vector(entity e, float speed) aim
+VM_cvar,                                       // #45 float(string s) cvar
+VM_localcmd,                           // #46 void(string s) localcmd
+VM_nextent,                                    // #47 entity(entity e) nextent
+PF_particle,                           // #48 void(vector o, vector d, float color, float count) particle
+PF_changeyaw,                          // #49 void() ChangeYaw
+NULL,                                          // #50
+VM_vectoangles,                                // #51 vector(vector v) vectoangles
+PF_WriteByte,                          // #52 void(float to, float f) WriteByte
+PF_WriteChar,                          // #53 void(float to, float f) WriteChar
+PF_WriteShort,                         // #54 void(float to, float f) WriteShort
+PF_WriteLong,                          // #55 void(float to, float f) WriteLong
+PF_WriteCoord,                         // #56 void(float to, float f) WriteCoord
+PF_WriteAngle,                         // #57 void(float to, float f) WriteAngle
+PF_WriteString,                                // #58 void(float to, string s) WriteString
+PF_WriteEntity,                                // #59 void(float to, entity e) WriteEntity
+VM_sin,                                                // #60 float(float f) sin (DP_QC_SINCOSSQRTPOW)
+VM_cos,                                                // #61 float(float f) cos (DP_QC_SINCOSSQRTPOW)
+VM_sqrt,                                       // #62 float(float f) sqrt (DP_QC_SINCOSSQRTPOW)
+PF_changepitch,                                // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
+PF_tracetoss,                          // #64 void(entity e, entity ignore) tracetoss (DP_QC_TRACETOSS)
+VM_etos,                                       // #65 string(entity ent) etos (DP_QC_ETOS)
+NULL,                                          // #66
+SV_MoveToGoal,                         // #67 void(float step) movetogoal
+PF_precache_file,                      // #68 string(string s) precache_file
+PF_makestatic,                         // #69 void(entity e) makestatic
+VM_changelevel,                                // #70 void(string s) changelevel
+NULL,                                          // #71
+VM_cvar_set,                           // #72 void(string var, string val) cvar_set
+PF_centerprint,                                // #73 void(entity client, strings) centerprint
+PF_ambientsound,                       // #74 void(vector pos, string samp, float vol, float atten) ambientsound
+PF_precache_model,                     // #75 string(string s) precache_model2
+PF_precache_sound,                     // #76 string(string s) precache_sound2
+PF_precache_file,                      // #77 string(string s) precache_file2
+PF_setspawnparms,                      // #78 void(entity e) setspawnparms
+NULL,                                          // #79
+NULL,                                          // #80
+VM_stof,                                       // #81 float(string s) stof (FRIK_FILE)
+NULL,                                          // #82
+NULL,                                          // #83
+NULL,                                          // #84
+NULL,                                          // #85
+NULL,                                          // #86
+NULL,                                          // #87
+NULL,                                          // #88
+NULL,                                          // #89
+PF_tracebox,                           // #90 void(vector v1, vector min, vector max, vector v2, float nomonsters, entity forent) tracebox (DP_QC_TRACEBOX)
+VM_randomvec,                          // #91 vector() randomvec (DP_QC_RANDOMVEC)
+PF_getlight,                           // #92 vector(vector org) getlight (DP_QC_GETLIGHT)
+PF_registercvar,                       // #93 float(string name, string value) registercvar (DP_REGISTERCVAR)
+VM_min,                                                // #94 float(float a, floats) min (DP_QC_MINMAXBOUND)
+VM_max,                                                // #95 float(float a, floats) max (DP_QC_MINMAXBOUND)
+VM_bound,                                      // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND)
+VM_pow,                                                // #97 float(float f, float f) pow (DP_QC_SINCOSSQRTPOW)
+VM_findfloat,                          // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
+VM_checkextension,                     // #99 float(string s) checkextension (the basis of the extension system)
+NULL,                                          // #100
+NULL,                                          // #101
+NULL,                                          // #102
+NULL,                                          // #103
+NULL,                                          // #104
+NULL,                                          // #105
+NULL,                                          // #106
+NULL,                                          // #107
+NULL,                                          // #108
+NULL,                                          // #109
+VM_fopen,                                      // #110 float(string filename, float mode) fopen (FRIK_FILE)
+VM_fclose,                                     // #111 void(float fhandle) fclose (FRIK_FILE)
+VM_fgets,                                      // #112 string(float fhandle) fgets (FRIK_FILE)
+VM_fputs,                                      // #113 void(float fhandle, string s) fputs (FRIK_FILE)
+VM_strlen,                                     // #114 float(string s) strlen (FRIK_FILE)
+VM_strcat,                                     // #115 string(string s1, string s2) strcat (FRIK_FILE)
+VM_substring,                          // #116 string(string s, float start, float length) substring (FRIK_FILE)
+VM_stov,                                       // #117 vector(string) stov (FRIK_FILE)
+VM_strzone,                                    // #118 string(string s) strzone (FRIK_FILE)
+VM_strunzone,                          // #119 void(string s) strunzone (FRIK_FILE)
+e10, e10, e10, e10, e10, e10, e10, e10,                // #120-199
+e10, e10, e10, e10, e10, e10, e10, e10, e10, e10,      // #200-299
+e10, e10, e10, e10, e10, e10, e10, e10, e10, e10,      // #300-399
+VM_copyentity,                         // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
+PF_setcolor,                           // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
+VM_findchain,                          // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
+VM_findchainfloat,                     // #403 entity(.float fld, float match) findchainfloat (DP_QC_FINDCHAINFLOAT)
+PF_effect,                                     // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
+PF_te_blood,                           // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
+PF_te_bloodshower,                     // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
+PF_te_explosionrgb,                    // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
+PF_te_particlecube,                    // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
+PF_te_particlerain,                    // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
+PF_te_particlesnow,                    // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
+PF_te_spark,                           // #411 void(vector org, vector vel, float howmany) te_spark (DP_TE_SPARK)
+PF_te_gunshotquad,                     // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
+PF_te_spikequad,                       // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
+PF_te_superspikequad,          // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
+PF_te_explosionquad,           // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
+PF_te_smallflash,                      // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
+PF_te_customflash,                     // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
+PF_te_gunshot,                         // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_spike,                           // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_superspike,                      // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_explosion,                       // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_tarexplosion,                    // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_wizspike,                                // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_knightspike,                     // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_lavasplash,                      // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_teleport,                                // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_explosion2,                      // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_lightning1,                      // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_lightning2,                      // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_lightning3,                      // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
+PF_te_beam,                                    // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
+PF_vectorvectors,                      // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
+PF_te_plasmaburn,                      // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
+PF_getsurfacenumpoints,                // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
+PF_getsurfacepoint,                    // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
+PF_getsurfacenormal,           // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
+PF_getsurfacetexture,          // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
+PF_getsurfacenearpoint,                // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
+PF_getsurfaceclippedpoint,     // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)
+PF_clientcommand,                      // #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_tokenize,                           // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
+VM_argv,                                       // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND)
+PF_setattachment,                      // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
+VM_search_begin,                       // #444 float(string pattern, float caseinsensitive, float quiet) search_begin (DP_FS_SEARCH)
+VM_search_end,                         // #445 void(float handle) search_end (DP_FS_SEARCH)
+VM_search_getsize,                     // #446 float(float handle) search_getsize (DP_FS_SEARCH)
+VM_search_getfilename,         // #447 string(float handle, float num) search_getfilename (DP_FS_SEARCH)
+VM_cvar_string,                                // #448 string(string s) cvar_string (DP_QC_CVAR_STRING)
+PF_findflags,                          // #449 entity(entity start, .float fld, float match) findflags (DP_QC_FINDFLAGS)
+PF_findchainflags,                     // #450 entity(.float fld, float match) findchainflags (DP_QC_FINDCHAINFLAGS)
+PF_gettagindex,                                // #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
+PF_gettaginfo,                         // #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
+PF_dropclient,                         // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT)
+PF_spawnclient,                                // #454 entity() spawnclient (DP_SV_BOTCLIENT)
+PF_clienttype,                         // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
+NULL,                                          // #456
+NULL,                                          // #457
+NULL,                                          // #458
+NULL,                                          // #459
+e10, e10, e10, e10                     // #460-499 (LordHavoc)
+};
+
+const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
+
+void VM_SV_Cmd_Init(void)
+{
+       VM_Cmd_Init();
+}
+
+void VM_SV_Cmd_Reset(void)
+{
+       VM_Cmd_Reset();
+}
+
diff --git a/world.c b/world.c
index 6665620eb9110a94bd17f869e7ee7545400f1832..cad831b37059250ed66e4513488a4e60f01ad890 100644 (file)
--- a/world.c
+++ b/world.c
@@ -146,25 +146,25 @@ SV_UnlinkEdict
 
 ===============
 */
-void SV_UnlinkEdict (edict_t *ent)
+void SV_UnlinkEdict (prvm_edict_t *ent)
 {
        int i;
        for (i = 0;i < ENTITYGRIDAREAS;i++)
        {
-               if (ent->e->areagrid[i].prev)
+               if (ent->priv.server->areagrid[i].prev)
                {
-                       RemoveLink (&ent->e->areagrid[i]);
-                       ent->e->areagrid[i].prev = ent->e->areagrid[i].next = NULL;
+                       RemoveLink (&ent->priv.server->areagrid[i]);
+                       ent->priv.server->areagrid[i].prev = ent->priv.server->areagrid[i].next = NULL;
                }
        }
 }
 
-int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list)
+int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
 {
        int numlist;
        areagrid_t *grid;
        link_t *l;
-       edict_t *ent;
+       prvm_edict_t *ent;
        int igrid[3], igridmins[3], igridmaxs[3];
 
        sv_areagrid_stats_calls++;
@@ -189,11 +189,11 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list)
        {
                for (l = sv_areagrid_outside.edicts.next;l != &sv_areagrid_outside.edicts;l = l->next)
                {
-                       ent = EDICT_NUM_UNSIGNED(l->entitynumber);
-                       if (ent->e->areagridmarknumber != sv_areagrid_marknumber)
+                       ent = PRVM_EDICT_NUM_UNSIGNED(l->entitynumber);
+                       if (ent->priv.server->areagridmarknumber != sv_areagrid_marknumber)
                        {
-                               ent->e->areagridmarknumber = sv_areagrid_marknumber;
-                               if (!ent->e->free && BoxesOverlap(mins, maxs, ent->v->absmin, ent->v->absmax))
+                               ent->priv.server->areagridmarknumber = sv_areagrid_marknumber;
+                               if (!ent->priv.server->free && BoxesOverlap(mins, maxs, ent->fields.server->absmin, ent->fields.server->absmax))
                                {
                                        if (numlist < maxlist)
                                                list[numlist] = ent;
@@ -213,11 +213,11 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list)
                        {
                                for (l = grid->edicts.next;l != &grid->edicts;l = l->next)
                                {
-                                       ent = EDICT_NUM_UNSIGNED(l->entitynumber);
-                                       if (ent->e->areagridmarknumber != sv_areagrid_marknumber)
+                                       ent = PRVM_EDICT_NUM_UNSIGNED(l->entitynumber);
+                                       if (ent->priv.server->areagridmarknumber != sv_areagrid_marknumber)
                                        {
-                                               ent->e->areagridmarknumber = sv_areagrid_marknumber;
-                                               if (!ent->e->free && BoxesOverlap(mins, maxs, ent->v->absmin, ent->v->absmax))
+                                               ent->priv.server->areagridmarknumber = sv_areagrid_marknumber;
+                                               if (!ent->priv.server->free && BoxesOverlap(mins, maxs, ent->fields.server->absmin, ent->fields.server->absmax))
                                                {
                                                        if (numlist < maxlist)
                                                                list[numlist] = ent;
@@ -232,14 +232,14 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list)
        return numlist;
 }
 
-void SV_TouchAreaGrid(edict_t *ent)
+void SV_TouchAreaGrid(prvm_edict_t *ent)
 {
        int i, numtouchedicts, old_self, old_other;
-       edict_t *touch, *touchedicts[MAX_EDICTS];
+       prvm_edict_t *touch, *touchedicts[MAX_EDICTS];
 
        // build a list of edicts to touch, because the link loop can be corrupted
        // by SV_IncreaseEdicts called during touch functions
-       numtouchedicts = SV_EntitiesInBox(ent->v->absmin, ent->v->absmax, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(ent->fields.server->absmin, ent->fields.server->absmax, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -247,41 +247,41 @@ void SV_TouchAreaGrid(edict_t *ent)
                numtouchedicts = MAX_EDICTS;
        }
 
-       old_self = pr_global_struct->self;
-       old_other = pr_global_struct->other;
+       old_self = prog->globals.server->self;
+       old_other = prog->globals.server->other;
        for (i = 0;i < numtouchedicts;i++)
        {
                touch = touchedicts[i];
-               if (touch != ent && (int)touch->v->solid == SOLID_TRIGGER && touch->v->touch)
+               if (touch != ent && (int)touch->fields.server->solid == SOLID_TRIGGER && touch->fields.server->touch)
                {
-                       pr_global_struct->self = EDICT_TO_PROG(touch);
-                       pr_global_struct->other = EDICT_TO_PROG(ent);
-                       pr_global_struct->time = sv.time;
-                       PR_ExecuteProgram (touch->v->touch, "QC function self.touch is missing");
+                       prog->globals.server->self = PRVM_EDICT_TO_PROG(touch);
+                       prog->globals.server->other = PRVM_EDICT_TO_PROG(ent);
+                       prog->globals.server->time = sv.time;
+                       PRVM_ExecuteProgram (touch->fields.server->touch, "QC function self.touch is missing");
                }
        }
-       pr_global_struct->self = old_self;
-       pr_global_struct->other = old_other;
+       prog->globals.server->self = old_self;
+       prog->globals.server->other = old_other;
 }
 
-void SV_LinkEdict_AreaGrid(edict_t *ent)
+void SV_LinkEdict_AreaGrid(prvm_edict_t *ent)
 {
        areagrid_t *grid;
-       int igrid[3], igridmins[3], igridmaxs[3], gridnum, entitynumber = NUM_FOR_EDICT(ent);
+       int igrid[3], igridmins[3], igridmaxs[3], gridnum, entitynumber = PRVM_NUM_FOR_EDICT(ent);
 
-       if (entitynumber <= 0 || entitynumber >= sv.max_edicts || EDICT_NUM(entitynumber) != ent)
-               Host_Error("SV_LinkEdict_AreaGrid: invalid edict %p (sv.edicts is %p, edict compared to sv.edicts is %i)\n", ent, sv.edicts, entitynumber);
+       if (entitynumber <= 0 || entitynumber >= prog->max_edicts || PRVM_EDICT_NUM(entitynumber) != ent)
+               Host_Error("SV_LinkEdict_AreaGrid: invalid edict %p (edicts is %p, edict compared to prog->edicts is %i)\n", ent, prog->edicts, entitynumber);
 
-       igridmins[0] = (int) ((ent->v->absmin[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]);
-       igridmins[1] = (int) ((ent->v->absmin[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]);
-       //igridmins[2] = (int) ((ent->v->absmin[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]);
-       igridmaxs[0] = (int) ((ent->v->absmax[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1;
-       igridmaxs[1] = (int) ((ent->v->absmax[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1;
-       //igridmaxs[2] = (int) ((ent->v->absmax[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]) + 1;
+       igridmins[0] = (int) ((ent->fields.server->absmin[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]);
+       igridmins[1] = (int) ((ent->fields.server->absmin[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]);
+       //igridmins[2] = (int) ((ent->fields.server->absmin[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]);
+       igridmaxs[0] = (int) ((ent->fields.server->absmax[0] + sv_areagrid_bias[0]) * sv_areagrid_scale[0]) + 1;
+       igridmaxs[1] = (int) ((ent->fields.server->absmax[1] + sv_areagrid_bias[1]) * sv_areagrid_scale[1]) + 1;
+       //igridmaxs[2] = (int) ((ent->fields.server->absmax[2] + sv_areagrid_bias[2]) * sv_areagrid_scale[2]) + 1;
        if (igridmins[0] < 0 || igridmaxs[0] > AREA_GRID || igridmins[1] < 0 || igridmaxs[1] > AREA_GRID || ((igridmaxs[0] - igridmins[0]) * (igridmaxs[1] - igridmins[1])) > ENTITYGRIDAREAS)
        {
                // wow, something outside the grid, store it as such
-               InsertLinkBefore (&ent->e->areagrid[0], &sv_areagrid_outside.edicts, entitynumber);
+               InsertLinkBefore (&ent->priv.server->areagrid[0], &sv_areagrid_outside.edicts, entitynumber);
                return;
        }
 
@@ -290,7 +290,7 @@ void SV_LinkEdict_AreaGrid(edict_t *ent)
        {
                grid = sv_areagrid + igrid[1] * AREA_GRID + igridmins[0];
                for (igrid[0] = igridmins[0];igrid[0] < igridmaxs[0];igrid[0]++, grid++, gridnum++)
-                       InsertLinkBefore (&ent->e->areagrid[gridnum], &grid->edicts, entitynumber);
+                       InsertLinkBefore (&ent->priv.server->areagrid[gridnum], &grid->edicts, entitynumber);
        }
 }
 
@@ -300,27 +300,27 @@ SV_LinkEdict
 
 ===============
 */
-void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
+void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers)
 {
        model_t *model;
 
-       if (ent->e->areagrid[0].prev)
+       if (ent->priv.server->areagrid[0].prev)
                SV_UnlinkEdict (ent);   // unlink from old position
 
-       if (ent == sv.edicts)
+       if (ent == prog->edicts)
                return;         // don't add the world
 
-       if (ent->e->free)
+       if (ent->priv.server->free)
                return;
 
 // set the abs box
 
-       if (ent->v->solid == SOLID_BSP)
+       if (ent->fields.server->solid == SOLID_BSP)
        {
-               int modelindex = ent->v->modelindex;
+               int modelindex = ent->fields.server->modelindex;
                if (modelindex < 0 || modelindex > MAX_MODELS)
                {
-                       Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", NUM_FOR_EDICT(ent));
+                       Con_Printf("edict %i: SOLID_BSP with invalid modelindex!\n", PRVM_NUM_FOR_EDICT(ent));
                        modelindex = 0;
                }
                model = sv.models[modelindex];
@@ -328,63 +328,63 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                {
                        Mod_CheckLoaded(model);
                        if (!model->TraceBox)
-                               Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", NUM_FOR_EDICT(ent));
+                               Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
 
-                       if (ent->v->angles[0] || ent->v->angles[2] || ent->v->avelocity[0] || ent->v->avelocity[2])
+                       if (ent->fields.server->angles[0] || ent->fields.server->angles[2] || ent->fields.server->avelocity[0] || ent->fields.server->avelocity[2])
                        {
-                               VectorAdd(ent->v->origin, model->rotatedmins, ent->v->absmin);
-                               VectorAdd(ent->v->origin, model->rotatedmaxs, ent->v->absmax);
+                               VectorAdd(ent->fields.server->origin, model->rotatedmins, ent->fields.server->absmin);
+                               VectorAdd(ent->fields.server->origin, model->rotatedmaxs, ent->fields.server->absmax);
                        }
-                       else if (ent->v->angles[1] || ent->v->avelocity[1])
+                       else if (ent->fields.server->angles[1] || ent->fields.server->avelocity[1])
                        {
-                               VectorAdd(ent->v->origin, model->yawmins, ent->v->absmin);
-                               VectorAdd(ent->v->origin, model->yawmaxs, ent->v->absmax);
+                               VectorAdd(ent->fields.server->origin, model->yawmins, ent->fields.server->absmin);
+                               VectorAdd(ent->fields.server->origin, model->yawmaxs, ent->fields.server->absmax);
                        }
                        else
                        {
-                               VectorAdd(ent->v->origin, model->normalmins, ent->v->absmin);
-                               VectorAdd(ent->v->origin, model->normalmaxs, ent->v->absmax);
+                               VectorAdd(ent->fields.server->origin, model->normalmins, ent->fields.server->absmin);
+                               VectorAdd(ent->fields.server->origin, model->normalmaxs, ent->fields.server->absmax);
                        }
                }
                else
                {
                        // SOLID_BSP with no model is valid, mainly because some QC setup code does so temporarily
-                       VectorAdd(ent->v->origin, ent->v->mins, ent->v->absmin);
-                       VectorAdd(ent->v->origin, ent->v->maxs, ent->v->absmax);
+                       VectorAdd(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->absmin);
+                       VectorAdd(ent->fields.server->origin, ent->fields.server->maxs, ent->fields.server->absmax);
                }
        }
        else
        {
-               VectorAdd(ent->v->origin, ent->v->mins, ent->v->absmin);
-               VectorAdd(ent->v->origin, ent->v->maxs, ent->v->absmax);
+               VectorAdd(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->absmin);
+               VectorAdd(ent->fields.server->origin, ent->fields.server->maxs, ent->fields.server->absmax);
        }
 
 //
 // to make items easier to pick up and allow them to be grabbed off
 // of shelves, the abs sizes are expanded
 //
-       if ((int)ent->v->flags & FL_ITEM)
+       if ((int)ent->fields.server->flags & FL_ITEM)
        {
-               ent->v->absmin[0] -= 15;
-               ent->v->absmin[1] -= 15;
-               ent->v->absmin[2] -= 1;
-               ent->v->absmax[0] += 15;
-               ent->v->absmax[1] += 15;
-               ent->v->absmax[2] += 1;
+               ent->fields.server->absmin[0] -= 15;
+               ent->fields.server->absmin[1] -= 15;
+               ent->fields.server->absmin[2] -= 1;
+               ent->fields.server->absmax[0] += 15;
+               ent->fields.server->absmax[1] += 15;
+               ent->fields.server->absmax[2] += 1;
        }
        else
        {
                // because movement is clipped an epsilon away from an actual edge,
                // we must fully check even when bounding boxes don't quite touch
-               ent->v->absmin[0] -= 1;
-               ent->v->absmin[1] -= 1;
-               ent->v->absmin[2] -= 1;
-               ent->v->absmax[0] += 1;
-               ent->v->absmax[1] += 1;
-               ent->v->absmax[2] += 1;
+               ent->fields.server->absmin[0] -= 1;
+               ent->fields.server->absmin[1] -= 1;
+               ent->fields.server->absmin[2] -= 1;
+               ent->fields.server->absmax[0] += 1;
+               ent->fields.server->absmax[1] += 1;
+               ent->fields.server->absmax[2] += 1;
        }
 
-       if (ent->v->solid == SOLID_NOT)
+       if (ent->fields.server->solid == SOLID_NOT)
                return;
 
        SV_LinkEdict_AreaGrid(ent);
@@ -411,9 +411,9 @@ SV_TestEntityPosition
 This could be a lot more efficient...
 ============
 */
-int SV_TestEntityPosition (edict_t *ent)
+int SV_TestEntityPosition (prvm_edict_t *ent)
 {
-       return SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, ent->v->origin, MOVE_NORMAL, ent).startsolid;
+       return SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, MOVE_NORMAL, ent).startsolid;
 }
 
 
@@ -433,7 +433,7 @@ Handles selection or creation of a clipping hull, and offseting (and
 eventually rotation) of the end points
 ==================
 */
-trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents)
+trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int movetype, int hitsupercontents)
 {
        trace_t trace;
        model_t *model = NULL;
@@ -445,45 +445,45 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
        trace.fraction = trace.realfraction = 1;
        VectorCopy(end, trace.endpos);
 
-       if ((int) ent->v->solid == SOLID_BSP || movetype == MOVE_HITMODEL)
+       if ((int) ent->fields.server->solid == SOLID_BSP || movetype == MOVE_HITMODEL)
        {
-               unsigned int modelindex = ent->v->modelindex;
+               unsigned int modelindex = ent->fields.server->modelindex;
                // if the modelindex is 0, it shouldn't be SOLID_BSP!
                if (modelindex == 0)
                {
-                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with no model\n", NUM_FOR_EDICT(ent));
+                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with no model\n", PRVM_NUM_FOR_EDICT(ent));
                        return trace;
                }
                if (modelindex >= MAX_MODELS)
                {
-                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with invalid modelindex\n", NUM_FOR_EDICT(ent));
+                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with invalid modelindex\n", PRVM_NUM_FOR_EDICT(ent));
                        return trace;
                }
                model = sv.models[modelindex];
                if (modelindex != 0 && model == NULL)
                {
-                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with invalid modelindex\n", NUM_FOR_EDICT(ent));
+                       Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with invalid modelindex\n", PRVM_NUM_FOR_EDICT(ent));
                        return trace;
                }
 
                Mod_CheckLoaded(model);
-               if ((int) ent->v->solid == SOLID_BSP)
+               if ((int) ent->fields.server->solid == SOLID_BSP)
                {
                        if (!model->TraceBox)
                        {
-                               Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with a non-collidable model\n", NUM_FOR_EDICT(ent));
+                               Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP with a non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
                                return trace;
                        }
-                       //if (ent->v->movetype != MOVETYPE_PUSH)
+                       //if (ent->fields.server->movetype != MOVETYPE_PUSH)
                        //{
-                       //      Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP without MOVETYPE_PUSH\n", NUM_FOR_EDICT(ent));
+                       //      Con_Printf("SV_ClipMoveToEntity: edict %i: SOLID_BSP without MOVETYPE_PUSH\n", PRVM_NUM_FOR_EDICT(ent));
                        //      return trace;
                        //}
                }
-               Matrix4x4_CreateFromQuakeEntity(&matrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2], ent->v->angles[0], ent->v->angles[1], ent->v->angles[2], 1);
+               Matrix4x4_CreateFromQuakeEntity(&matrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2], ent->fields.server->angles[0], ent->fields.server->angles[1], ent->fields.server->angles[2], 1);
        }
        else
-               Matrix4x4_CreateTranslate(&matrix, ent->v->origin[0], ent->v->origin[1], ent->v->origin[2]);
+               Matrix4x4_CreateTranslate(&matrix, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2]);
 
        Matrix4x4_Invert_Simple(&imatrix, &matrix);
        Matrix4x4_Transform(&imatrix, start, starttransformed);
@@ -495,7 +495,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
        if (model && model->TraceBox)
        {
                int frame;
-               frame = (int)ent->v->frame;
+               frame = (int)ent->fields.server->frame;
                frame = bound(0, frame, (model->numframes - 1));
                VectorAdd(starttransformed, maxs, starttransformedmaxs);
                VectorAdd(endtransformed, maxs, endtransformedmaxs);
@@ -504,7 +504,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
                model->TraceBox(model, frame, &trace, starttransformedmins, starttransformedmaxs, endtransformedmins, endtransformedmaxs, hitsupercontents);
        }
        else
-               Collision_ClipTrace_Box(&trace, ent->v->mins, ent->v->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, SUPERCONTENTS_SOLID);
+               Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, SUPERCONTENTS_SOLID);
        trace.fraction = bound(0, trace.fraction, 1);
        trace.realfraction = bound(0, trace.realfraction, 1);
 
@@ -529,9 +529,9 @@ SV_Move
 ==================
 */
 #if COLLISIONPARANOID >= 1
-trace_t SV_Move_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, edict_t *passedict)
+trace_t SV_Move_(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
 #else
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, edict_t *passedict)
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
 #endif
 {
        vec3_t hullmins, hullmaxs;
@@ -539,7 +539,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        int hitsupercontentsmask;
        int passedictprog;
        qboolean pointtrace;
-       edict_t *traceowner, *touch;
+       prvm_edict_t *traceowner, *touch;
        trace_t trace;
        // bounding box of entire move area
        vec3_t clipboxmins, clipboxmaxs;
@@ -552,7 +552,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        // trace results
        trace_t cliptrace;
        int numtouchedicts;
-       edict_t *touchedicts[MAX_EDICTS];
+       prvm_edict_t *touchedicts[MAX_EDICTS];
 
        VectorCopy(start, clipstart);
        VectorCopy(end, clipend);
@@ -567,16 +567,16 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        hitsupercontentsmask = SUPERCONTENTS_SOLID;
        if (passedict)
        {
-               if (passedict->v->solid == SOLID_SLIDEBOX)
+               if (passedict->fields.server->solid == SOLID_SLIDEBOX)
                        hitsupercontentsmask |= SUPERCONTENTS_PLAYERCLIP;
-               if ((int)passedict->v->flags & FL_MONSTER)
+               if ((int)passedict->fields.server->flags & FL_MONSTER)
                        hitsupercontentsmask |= SUPERCONTENTS_MONSTERCLIP;
        }
 
        // clip to world
-       cliptrace = SV_ClipMoveToEntity(sv.edicts, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
+       cliptrace = SV_ClipMoveToEntity(prog->edicts, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
        if (cliptrace.startsolid || cliptrace.fraction < 1)
-               cliptrace.ent = sv.edicts;
+               cliptrace.ent = prog->edicts;
        if (type == MOVE_WORLDONLY)
                return cliptrace;
 
@@ -614,14 +614,14 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        }
 
        // if the passedict is world, make it NULL (to avoid two checks each time)
-       if (passedict == sv.edicts)
+       if (passedict == prog->edicts)
                passedict = NULL;
        // precalculate prog value for passedict for comparisons
-       passedictprog = EDICT_TO_PROG(passedict);
+       passedictprog = PRVM_EDICT_TO_PROG(passedict);
        // figure out whether this is a point trace for comparisons
        pointtrace = VectorCompare(clipmins, clipmaxs);
        // precalculate passedict's owner edict pointer for comparisons
-       traceowner = passedict ? PROG_TO_EDICT(passedict->v->owner) : 0;
+       traceowner = passedict ? PRVM_PROG_TO_EDICT(passedict->fields.server->owner) : 0;
 
        // clip to enttiies
        numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
@@ -635,9 +635,9 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        {
                touch = touchedicts[i];
 
-               if (touch->v->solid < SOLID_BBOX)
+               if (touch->fields.server->solid < SOLID_BBOX)
                        continue;
-               if (type == MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP)
+               if (type == MOVE_NOMONSTERS && touch->fields.server->solid != SOLID_BSP)
                        continue;
 
                if (passedict)
@@ -649,21 +649,21 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                        if (traceowner == touch)
                                continue;
                        // don't clip owner against owned entities
-                       if (passedictprog == touch->v->owner)
+                       if (passedictprog == touch->fields.server->owner)
                                continue;
                        // don't clip points against points (they can't collide)
-                       if (pointtrace && VectorCompare(touch->v->mins, touch->v->maxs) && (type != MOVE_MISSILE || !((int)touch->v->flags & FL_MONSTER)))
+                       if (pointtrace && VectorCompare(touch->fields.server->mins, touch->fields.server->maxs) && (type != MOVE_MISSILE || !((int)touch->fields.server->flags & FL_MONSTER)))
                                continue;
                        // don't clip corpse against character
-                       if (passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
+                       if (passedict->fields.server->solid == SOLID_CORPSE && (touch->fields.server->solid == SOLID_SLIDEBOX || touch->fields.server->solid == SOLID_CORPSE))
                                continue;
                        // don't clip character against corpse
-                       if (passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
+                       if (passedict->fields.server->solid == SOLID_SLIDEBOX && touch->fields.server->solid == SOLID_CORPSE)
                                continue;
                }
 
                // might interact, so do an exact clip
-               if ((int)touch->v->flags & FL_MONSTER)
+               if ((int)touch->fields.server->flags & FL_MONSTER)
                        trace = SV_ClipMoveToEntity(touch, clipstart, clipmins2, clipmaxs2, clipend, type, hitsupercontentsmask);
                else
                        trace = SV_ClipMoveToEntity(touch, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
@@ -698,7 +698,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
 }
 
 #if COLLISIONPARANOID >= 1
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, edict_t *passedict)
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict)
 {
        int endstuck;
        trace_t trace;
@@ -711,7 +711,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
 #if COLLISIONPARANOID < 3
                if (trace.startsolid || endstuck)
 #endif
-                       Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", passedict ? passedict - sv.edicts : -1, passedict->v->origin[0], passedict->v->origin[1], passedict->v->origin[2], end[0] - passedict->v->origin[0], end[1] - passedict->v->origin[1], end[2] - passedict->v->origin[2], trace.fraction, trace.endpos[0] - passedict->v->origin[0], trace.endpos[1] - passedict->v->origin[1], trace.endpos[2] - passedict->v->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
+                       Con_Printf("%s{e%i:%f %f %f:%f %f %f:%f:%f %f %f%s%s}\n", (trace.startsolid || endstuck) ? "\002" : "", passedict ? passedict - prog->edicts : -1, passedict->fields.server->origin[0], passedict->fields.server->origin[1], passedict->fields.server->origin[2], end[0] - passedict->fields.server->origin[0], end[1] - passedict->fields.server->origin[1], end[2] - passedict->fields.server->origin[2], trace.fraction, trace.endpos[0] - passedict->fields.server->origin[0], trace.endpos[1] - passedict->fields.server->origin[1], trace.endpos[2] - passedict->fields.server->origin[2], trace.startsolid ? " startstuck" : "", endstuck ? " endstuck" : "");
        }
        return trace;
 }
diff --git a/world.h b/world.h
index 91742334e801432bcc0dc834d66c950e02d13766..898926e864d915436ad781b25f16950c0ffd9174 100644 (file)
--- a/world.h
+++ b/world.h
@@ -36,18 +36,18 @@ void SV_ClearWorld (void);
 
 // call before removing an entity, and before trying to move one,
 // so it doesn't clip against itself
-void SV_UnlinkEdict (edict_t *ent);
+void SV_UnlinkEdict (prvm_edict_t *ent);
 
 // Needs to be called any time an entity changes origin, mins, maxs, or solid
 // sets ent->v.absmin and ent->v.absmax
 // if touchtriggers, calls prog functions for the intersected triggers
-void SV_LinkEdict (edict_t *ent, qboolean touch_triggers);
+void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers);
 
 // returns true if the entity is in solid currently
-int SV_TestEntityPosition (edict_t *ent);
+int SV_TestEntityPosition (prvm_edict_t *ent);
 
 // returns list of entities touching a box
-int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list);
+int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list);
 
 // mins and maxs are relative
 // if the entire move stays in a solid volume, trace.allsolid will be set
@@ -59,7 +59,7 @@ int SV_EntitiesInBox(vec3_t mins, vec3_t maxs, int maxlist, edict_t **list);
 // shouldn't be considered solid objects
 
 // passedict is explicitly excluded from clipping checks (normally NULL)
-trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, edict_t *passedict);
+trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict);
 
 int SV_PointQ1Contents(const vec3_t point);
 int SV_PointSuperContents(const vec3_t point);