return 0;
}
+// MUST match effectnameindex_t in client.h
+static const char *standardeffectnames[EFFECT_TOTAL] =
+{
+ "",
+ "TE_GUNSHOT",
+ "TE_GUNSHOTQUAD",
+ "TE_SPIKE",
+ "TE_SPIKEQUAD",
+ "TE_SUPERSPIKE",
+ "TE_SUPERSPIKEQUAD",
+ "TE_WIZSPIKE",
+ "TE_KNIGHTSPIKE",
+ "TE_EXPLOSION",
+ "TE_EXPLOSIONQUAD",
+ "TE_TAREXPLOSION",
+ "TE_TELEPORT",
+ "TE_LAVASPLASH",
+ "TE_SMALLFLASH",
+ "TE_FLAMEJET",
+ "EF_FLAME",
+ "TE_BLOOD",
+ "TE_SPARK",
+ "TE_PLASMABURN",
+ "TE_TEI_G3",
+ "TE_TEI_SMOKE",
+ "TE_TEI_BIGEXPLOSION",
+ "TE_TEI_PLASMAHIT",
+ "EF_STARDUST",
+ "TR_ROCKET",
+ "TR_GRENADE",
+ "TR_BLOOD",
+ "TR_WIZSPIKE",
+ "TR_SLIGHTBLOOD",
+ "TR_KNIGHTSPIKE",
+ "TR_VORESPIKE",
+ "TR_NEHAHRASMOKE",
+ "TR_NEXUIZPLASMA",
+ "TR_GLOWTRAIL",
+ "SVC_PARTICLE"
+};
+
+/*
+================
+SV_ParticleEffectIndex
+
+================
+*/
+int SV_ParticleEffectIndex(const char *name)
+{
+ int i, argc, linenumber, effectnameindex;
+ fs_offset_t filesize;
+ unsigned char *filedata;
+ const char *text, *textstart, *textend;
+ char argv[16][1024];
+ if (!sv.particleeffectnamesloaded)
+ {
+ sv.particleeffectnamesloaded = true;
+ memset(sv.particleeffectname, 0, sizeof(sv.particleeffectname));
+ for (i = 0;i < EFFECT_TOTAL;i++)
+ strlcpy(sv.particleeffectname[i], standardeffectnames[i], sizeof(sv.particleeffectname[i]));
+ filedata = FS_LoadFile("effectinfo.txt", tempmempool, true, &filesize);
+ if (filedata)
+ {
+ textstart = (const char *)filedata;
+ textend = (const char *)filedata + filesize;
+ text = textstart;
+ for (linenumber = 1;;linenumber++)
+ {
+ argc = 0;
+ for (;;)
+ {
+ if (!COM_ParseToken(&text, true) || !strcmp(com_token, "\n"))
+ break;
+ if (argc < 16)
+ {
+ strlcpy(argv[argc], com_token, sizeof(argv[argc]));
+ argc++;
+ }
+ }
+ if (com_token[0] == 0)
+ break; // if the loop exited and it's not a \n, it's EOF
+ if (argc < 1)
+ continue;
+ if (!strcmp(argv[0], "effect"))
+ {
+ if (argc == 2)
+ {
+ for (effectnameindex = 1;effectnameindex < SV_MAX_PARTICLEEFFECTNAME;effectnameindex++)
+ {
+ if (sv.particleeffectname[effectnameindex][0])
+ {
+ if (!strcmp(sv.particleeffectname[effectnameindex], argv[1]))
+ break;
+ }
+ else
+ {
+ strlcpy(sv.particleeffectname[effectnameindex], argv[1], sizeof(sv.particleeffectname[effectnameindex]));
+ break;
+ }
+ }
+ // if we run out of names, abort
+ if (effectnameindex == SV_MAX_PARTICLEEFFECTNAME)
+ {
+ Con_Printf("effectinfo.txt:%i: too many effects!\n", linenumber);
+ break;
+ }
+ }
+ }
+ }
+ Mem_Free(filedata);
+ }
+ }
+ // search for the name
+ for (effectnameindex = 1;effectnameindex < SV_MAX_PARTICLEEFFECTNAME && sv.particleeffectname[effectnameindex][0];effectnameindex++)
+ if (!strcmp(sv.particleeffectname[effectnameindex], name))
+ return effectnameindex;
+ // return 0 if we couldn't find it
+ return 0;
+}
+
/*
================
SV_CreateBaseline
// TODO: add a requiredfuncs list (ask LH if this is necessary at all)
PRVM_LoadProgs( sv_progs.string, 0, NULL, REQFIELDS, reqfields, 0, NULL );
+ // some mods compiled with scrambling compilers lack certain critical
+ // global names and field names such as "self" and "time" and "nextthink"
+ // so we have to set these offsets manually, matching the entvars_t
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, angles);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, chain);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, classname);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, frame);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, groundentity);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, ideal_yaw);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, nextthink);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, think);
+ PRVM_ED_FindFieldOffset_FromStruct(entvars_t, yaw_speed);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, self);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, time);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, v_forward);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, v_right);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, v_up);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_allsolid);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_startsolid);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_fraction);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_inwater);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_inopen);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_endpos);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_plane_normal);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_plane_dist);
+ PRVM_ED_FindGlobalOffset_FromStruct(globalvars_t, trace_ent);
+ // OP_STATE is always supported on server (due to entvars_t)
+ prog->flag |= PRVM_OP_STATE;
+
VM_AutoSentStats_Clear();//[515]: csqc
EntityFrameCSQC_ClearVersions();//[515]: csqc