📄 g_spawn.pas
字号:
if lstrcmp(s.name,ent.classname)<>''then //if (!strcmp(s->name, ent->classname))
begin
(* found it*)
s.spawn(ent);
exit;
end;
end;
gi.dprintf('%s doesn'#39't have a spawn function'#13#10'',ent.classname);
end;
(*
=============
ED_NewString
=============
*)
function ED_NewString(string: pchar): pchar;
var
newb: pchar;
new_p: pchar;
i: integer;
l: integer;
begin
l:= lstrlen(string)+1;
newb:= gi.TagMalloc(l,TAG_LEVEL);
new_p:= newb;
for i:=0 to Pred(l) do
begin
if (string[i]=#92) and (i<l-1) then
begin
inc(i);
if string[i]='n' then
begin
new_p^:=#13#10;
inc(new_p);
end
else
begin
new_p^:=#92;
inc(new_p);
end;
end
else
begin
new_p^:=string[i];
inc(new_p);
end;
end;
result:= newb;
end;
(*
===============
ED_ParseField
Takes a key/value pair and sets the binary values
in an edict
===============
*)
procedure ED_ParseField(key: pchar; value: pchar; ent: pedict_t);
var
f: pfield_t;
b: pbyte;
v: float;
vec: vec3_t;
begin
for f:= fields to f.name do //for (f=fields ; f->name ; f++)
begin
if (not (f.flags and FFL_NOSPAWN)) and (not (Q_stricmp(f.name,key)) then
//if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key))
begin
(* found it*)
if f.flags and FFL_SPAWNTEMP then
b:= PByte(@st) //b = (byte *)&st;
else
b:= PByte(ent);//b = (byte *)ent;
case f.type of
F_LSTRING:
begin
PPChar(b+f.ofs)^:=ED_NewString(value); //*(char **)(b+f->ofs)
end;
F_VECTOR:
begin
sscanf(value, '%f %f %f', [@vec[0], @vec[1], @vec[2]]);
PFloat(b+f.ofs)[0]:=vec[0];
PFloat(b+f.ofs)[1]:=vec[1];
PFloat(b+f.ofs)[2]:=vec[2];
end;
F_INT:
begin
PInteger(b+f.ofs):=atoi(value);
end;
F_FLOAT:
begin
PFloat(b+f.ofs):=atof(value);
end;
F_ANGLEHACK:
begin
v:= atof(value);
PFloat(b+f.ofs)[0]:=0;
PFloat(b+f.ofs)[1]:=v;
PFloat(b+f.ofs)[2]:=0;
end;
F_IGNORE: ;
end;{case?}
exit;
end;
end;
gi.dprintf('%s is not a field'#13#10'',key);
end;
(*
====================
ED_ParseEdict
Parses an edict out of the given string, returning the new position
ed should be a properly initialized empty edict.
====================
*)
function ED_ParseEdict(data: pchar; ent: pedict_t): pchar;
var
init: QBoolean;
keyname: array [0..Pred(256)] of Char;
com_token: PChar;
begin
init:= false;
RtlZeroMemory(@st,sizeof(st));
(* go through all the dictionary pairs*)
while True do
begin
(* parse key*)
com_token:= COM_Parse( and data);
if com_token[0]='}' then break;
if data<>nil then gi.error('ED_ParseEntity: EOF without closing brace');
strncpy(keyname,com_token,sizeof(keyname)-1);
com_token:= COM_Parse( and data); (* parse value *)
if data<>nil then gi.error('ED_ParseEntity: EOF without closing brace');
if com_token[0]='}' then gi.error('ED_ParseEntity: closing brace without data');
init:= true;
(* keynames with a leading underscore are used for utility comments,*)
(* and are immediately discarded by quake*)
//if keyname[0]='_' then continue
ED_ParseField(keyname,com_token,ent);
end;
if not init then RtlZeroMemory(ent,sizeof(ent^));
result:= data;
end;
(*
================
G_FindTeams
Chain together all entities with a matching team field.
All but the first will have the FL_TEAMSLAVE flag set.
All but the last will have the teamchain field set to the next one
================
*)
procedure G_FindTeams();
var
e,
e2,
chain: pedict_t;
i,
j,
c,
c2: integer;
begin
c:= 0;
c2:= 0;
i:= 1;
e:= g_edicts+i;
for i:= 1 to globals.num_edicts-1 do
begin
// if not e.inuse then continue;
// if not e.team then continue;
// if e.flags and FL_TEAMSLAVE then continue
chain:= e;
e.teammaster:= e;
inc(c);
inc(c2);
e2:=e+1;
for j:= i+1 to globals.num_edicts-2 do
begin
//if not e2.inuse then continue;
//if not e2.team then continue;
//if e2.flags and FL_TEAMSLAVE then continue;
if not lstrcmp(e.team,e2.team) then
begin
inc(c2);
chain.teamchain:= e2;
e2.teammaster:= e;
chain:= e2;
e2.flags:= e2.flags or (FL_TEAMSLAVE);
end;
inc(e2);
end;
inc(e);
end;
gi.dprintf('%i teams with %i entities'#13#10'',c,c2);
end;
(*
==============
SpawnEntities
Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
==============
*)
procedure SpawnEntities(mapname: pchar; entities: pchar; spawnpoint: pchar);
var
ent: pedict_t;
inhibit: integer;
com_token: pchar;
i: integer;
skill_level: float;
begin
skill_level:= floor(skill.value);
if skill_level<0 then skill_level:= 0;
if skill_level>3 then skill_level:= 3;
if skill.value<>skill_level then gi.cvar_forceset('skill',va('%f',skill_level));
SaveClientData();
gi.FreeTags(TAG_LEVEL);
RtlZeroMemory(@level,sizeof(level));
RtlZeroMemory(g_edicts,game.maxentities*sizeof(g_edicts[0]));
strncpy(level.mapname,mapname,sizeof(level.mapname)-1);
strncpy(game.spawnpoint,spawnpoint,sizeof(game.spawnpoint)-1);
(* set client fields on player ents*)
for i:=0 to Pred(game.maxclients) do
g_edicts[i+1].client:= game.clients+i;
ent:= 0;
inhibit:= 0;
(* parse ents*)
while True do
begin
(* parse the opening brace *)
com_token:= COM_Parse( and entities);
if not entities then break; //if (!entities)
if com_token[0]<>'{' then gi.error('ED_LoadFromFile: found %s when expecting {',com_token);
if not ent then ent:= g_edicts //if (!ent)
else ent:= G_Spawn();
entities:= ED_ParseEdict(entities,ent);
(* yet another map hack*)
if not Q_stricmp(level.mapname,'command')) and (not Q_stricmp(ent.classname,'trigger_once')) and (not Q_stricmp(ent.model,'*27') then
ent.spawnflags:= ent.spawnflags and (not SPAWNFLAG_NOT_HARD);
(* remove things (except the world) from different skill levels or deathmatch*)
if ent<>g_edicts then
begin
if deathmatch.value then //if (deathmatch->value)
begin
if ent.spawnflags and SPAWNFLAG_NOT_DEATHMATCH then
begin
G_FreeEdict(ent);
inc(inhibit);
end;
end;
else
begin
if ((skill.value=0) and (ent.spawnflags and SPAWNFLAG_NOT_EASY)) or
((skill.value=1) and (ent.spawnflags and SPAWNFLAG_NOT_MEDIUM)) or
(((skill.value=2) or (skill.value=3)) and (ent.spawnflags and SPAWNFLAG_NOT_HARD)) then
begin
G_FreeEdict(ent);
inc(inhibit);
end;
end;
ent.spawnflags:= ent.spawnflags and (not(SPAWNFLAG_NOT_EASY or SPAWNFLAG_NOT_MEDIUM or SPAWNFLAG_NOT_HARD or SPAWNFLAG_NOT_COOP or SPAWNFLAG_NOT_DEATHMATCH));
end;
ED_CallSpawn(ent);
end;
gi.dprintf('%i entities inhibited'#13#10'',inhibit);
{$ifdef DEBUG}
i:= 1;
ent:= EDICT_NUM(i);
while i<globals.num_edicts do
begin
if ent.inuse<>0)or(ent.inuse<>1) then
Com_DPrintf('Invalid entity %d'#13#10'',i);
inc(i); ,
inc(ent);
end;
{$endif}
G_FindTeams();
PlayerTrail_Init();
end;
(*===================================================================*)
{$if 0}
(* cursor positioning*)
xl <value>
xr <value>
yb <value>
yt <value>
xv <value>
yv<value>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -