ParticleSystem::ParticleSystem( int iEntIndex, char *szFilename ) { int iParticles = 100; // default m_iEntIndex = iEntIndex; m_pNextSystem = NULL; m_pFirstType = NULL; if ( !c_bCosTableInit ) { for ( int i = 0; i < 360 + 90; i++ ) { c_fCosTable[i] = cos( i * M_PI / 180.0 ); } c_bCosTableInit = true; } const char *memFile; const char *szFile = (char *)LOAD_FILE( szFilename, NULL ); char *szToken; if( !szFile ) { ALERT( at_error, "particle %s not found.\n", szFilename ); return; } else { memFile = szFile; szToken = COM_ParseToken( &szFile ); while ( szToken ) { if ( !stricmp( szToken, "particles" ) ) { szToken = COM_ParseToken( &szFile ); iParticles = atof(szToken); } else if ( !stricmp( szToken, "maintype" ) ) { szToken = COM_ParseToken( &szFile ); m_pMainType = AddPlaceholderType(szToken); } else if ( !stricmp( szToken, "attachment" ) ) { szToken = COM_ParseToken( &szFile ); m_iEntAttachment = atof(szToken); } else if ( !stricmp( szToken, "killcondition" ) ) { szToken = COM_ParseToken( &szFile ); if ( !stricmp( szToken, "empty" ) ) { m_iKillCondition = CONTENTS_EMPTY; } else if ( !stricmp( szToken, "water" ) ) { m_iKillCondition = CONTENTS_WATER; } else if ( !stricmp( szToken, "solid" ) ) { m_iKillCondition = CONTENTS_SOLID; } } else if ( !stricmp( szToken, "{" ) ) { // parse new type this->ParseType( &szFile ); // parses the type, moves the file pointer } szToken = COM_ParseToken( &szFile ); } } FREE_FILE( (void *)memFile ); AllocateParticles( iParticles ); }
// creates a new particletype from the given file // NB: this changes the value of szFile. ParticleType *ParticleSystem::ParseType( const char **szFile ) { ParticleType *pType = new ParticleType(); // parse the .aur file char *szToken; szToken = COM_ParseToken( szFile ); while ( stricmp( szToken, "}" ) ) { if (!szFile) break; if ( !stricmp( szToken, "name" ) ) { szToken = COM_ParseToken( szFile ); strncpy(pType->m_szName, szToken, sizeof(pType->m_szName) ); ParticleType *pTemp = GetType(szToken); if (pTemp) { // there's already a type with this name if (pTemp->m_bIsDefined) ALERT( at_warning, "Particle type %s is defined more than once!\n", szToken); // copy all our data into the existing type, throw away the type we were making *pTemp = *pType; delete pType; pType = pTemp; pType->m_bIsDefined = true; // record the fact that it's defined, so we won't need to add it to the list } } else if ( !stricmp( szToken, "gravity" ) ) { szToken = COM_ParseToken( szFile ); pType->m_Gravity = RandomRange( szToken ); } else if ( !stricmp( szToken, "windyaw" ) ) { szToken = COM_ParseToken( szFile ); pType->m_WindYaw = RandomRange( szToken ); } else if ( !stricmp( szToken, "windstrength" ) ) { szToken = COM_ParseToken( szFile ); pType->m_WindStrength = RandomRange( szToken ); } else if ( !stricmp( szToken, "sprite" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SpriteIndex = g_engfuncs.pEventAPI->EV_FindModelIndex( szToken ); } else if ( !stricmp( szToken, "startalpha" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartAlpha = RandomRange( szToken ); } else if ( !stricmp( szToken, "endalpha" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndAlpha = RandomRange( szToken ); } else if ( !stricmp( szToken, "startred" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartRed = RandomRange( szToken ); } else if ( !stricmp( szToken, "endred" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndRed = RandomRange( szToken ); } else if ( !stricmp( szToken, "startgreen" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartGreen = RandomRange( szToken ); } else if ( !stricmp( szToken, "endgreen" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndGreen = RandomRange( szToken ); } else if ( !stricmp( szToken, "startblue" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartBlue = RandomRange( szToken ); } else if ( !stricmp( szToken, "endblue" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndBlue = RandomRange( szToken ); } else if ( !stricmp( szToken, "startsize" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartSize = RandomRange( szToken ); } else if ( !stricmp( szToken, "sizedelta" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SizeDelta = RandomRange( szToken ); } else if ( !stricmp( szToken, "endsize" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndSize = RandomRange( szToken ); } else if ( !stricmp( szToken, "startangle" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartAngle = RandomRange( szToken ); } else if ( !stricmp( szToken, "angledelta" ) ) { szToken = COM_ParseToken( szFile ); pType->m_AngleDelta = RandomRange( szToken ); } else if ( !stricmp( szToken, "startframe" ) ) { szToken = COM_ParseToken( szFile ); pType->m_StartFrame = RandomRange( szToken ); } else if ( !stricmp( szToken, "endframe" ) ) { szToken = COM_ParseToken( szFile ); pType->m_EndFrame = RandomRange( szToken ); pType->m_bEndFrame = true; } else if ( !stricmp( szToken, "framerate" ) ) { szToken = COM_ParseToken( szFile ); pType->m_FrameRate = RandomRange( szToken ); } else if ( !stricmp( szToken, "lifetime" ) ) { szToken = COM_ParseToken( szFile ); pType->m_Life = RandomRange( szToken ); } else if ( !stricmp( szToken, "spraytype" ) ) { szToken = COM_ParseToken( szFile ); ParticleType *pTemp = GetType(szToken); if (pTemp) pType->m_pSprayType = pTemp; else pType->m_pSprayType = AddPlaceholderType(szToken); } else if ( !stricmp( szToken, "overlaytype" ) ) { szToken = COM_ParseToken( szFile ); ParticleType *pTemp = GetType(szToken); if (pTemp) pType->m_pOverlayType = pTemp; else pType->m_pOverlayType = AddPlaceholderType(szToken); } else if ( !stricmp( szToken, "sprayrate" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SprayRate = RandomRange( szToken ); } else if ( !stricmp( szToken, "sprayforce" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SprayForce = RandomRange( szToken ); } else if ( !stricmp( szToken, "spraypitch" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SprayPitch = RandomRange( szToken ); } else if ( !stricmp( szToken, "sprayyaw" ) ) { szToken = COM_ParseToken( szFile ); pType->m_SprayYaw = RandomRange( szToken ); } else if ( !stricmp( szToken, "drag" ) ) { szToken = COM_ParseToken( szFile ); pType->m_Drag = RandomRange( szToken ); } else if ( !stricmp( szToken, "bounce" ) ) { szToken = COM_ParseToken( szFile ); pType->m_Bounce = RandomRange( szToken ); if (pType->m_Bounce.m_fMin != 0 || pType->m_Bounce.m_fMax != 0) pType->m_bBouncing = true; } else if ( !stricmp( szToken, "bouncefriction" ) ) { szToken = COM_ParseToken( szFile ); pType->m_BounceFriction = RandomRange( szToken ); } else if ( !stricmp( szToken, "rendermode" ) ) { szToken = COM_ParseToken( szFile ); if ( !stricmp( szToken, "additive" ) ) { pType->m_iRenderMode = kRenderTransAdd; } else if ( !stricmp( szToken, "solid" ) ) { pType->m_iRenderMode = kRenderTransAlpha; } else if ( !stricmp( szToken, "texture" ) ) { pType->m_iRenderMode = kRenderTransTexture; } else if ( !stricmp( szToken, "color" ) ) { pType->m_iRenderMode = kRenderTransColor; } } else if ( !stricmp( szToken, "drawcondition" ) ) { szToken = COM_ParseToken( szFile ); if ( !stricmp( szToken, "empty" ) ) { pType->m_iDrawCond = CONTENTS_EMPTY; } else if ( !stricmp( szToken, "water" ) ) { pType->m_iDrawCond = CONTENTS_WATER; } else if ( !stricmp( szToken, "solid" ) ) { pType->m_iDrawCond = CONTENTS_SOLID; } } else if ( !stricmp( szToken, "collision" ) ) { szToken = COM_ParseToken( szFile ); if ( !stricmp( szToken, "none" ) ) { pType->m_iCollision = COLLISION_NONE; } else if ( !stricmp( szToken, "die" ) ) { pType->m_iCollision = COLLISION_DIE; } else if ( !stricmp( szToken, "bounce" ) ) { pType->m_iCollision = COLLISION_BOUNCE; } } // get the next token szToken = COM_ParseToken( szFile ); } if (!pType->m_bIsDefined) { // if this is a newly-defined type, we need to add it to the list pType->m_pNext = m_pFirstType; m_pFirstType = pType; pType->m_bIsDefined = true; } return pType; }
float SV_ChatFunc(const char *func) //parse a condition/function { globalvars_t *pr_globals; float result; int noted = false; const char *s, *os; char namebuf[64]; func_t f; int parm; while (*func <= ' ') func++; if (*func == '!') { noted = true; func++; } s = COM_ParseToken(func, NULL); if (*com_token == '(') {//open bracket //find correct close parm = 1; for (s = func+1; ; s++) { if (!*s) Sys_Error("No close bracket"); if (*s == ')') { parm--; if (!parm)break; } if (*s == '(') parm++; } func = strchr(func, '('); s=COM_ParseToken(s+1, NULL); if (!strncmp(com_token, "&&", 2)) result = SV_ChatFunc(func+1) && SV_ChatFunc(s); else if (!strncmp(com_token, "||", 2)) result = SV_ChatFunc(func+1) || SV_ChatFunc(s); else result = SV_ChatFunc(func+1); } else { strcpy(namebuf, com_token); //get first word while (*s <= ' ') s++; if (*s == '(') //if followed by brackets { s++; pr_globals = PR_globals(svprogfuncs, PR_CURRENT); parm = OFS_PARM0; while((s=COM_ParseToken(os = s, NULL))) { if (*com_token == ')') break; if (*com_token == ',') continue; if (com_tokentype == TTP_STRING) G_INT(parm) = PR_NewString(svprogfuncs, com_token); else if (!strcmp(com_token, "ent")) G_INT(parm) = EDICT_TO_PROG(svprogfuncs, host_client->chat.edict); else G_FLOAT(parm) = SV_ChatFunc(os); parm+=OFS_PARM1-OFS_PARM0; } f = PR_FindFunction(svprogfuncs, namebuf, PR_CURRENT); if (f) { PR_ExecuteProgram(svprogfuncs, f); } else Con_Printf("Failed to find function %s\n", namebuf); pr_globals = PR_globals(svprogfuncs, PR_CURRENT); result = G_FLOAT(OFS_RETURN); } else { //comparision operators if (!strncmp(s, "==", 2)) result = (SV_ChatGetValue(namebuf) == SV_ChatFunc(s+2)); else if (!strncmp(s, ">=", 2)) result = (SV_ChatGetValue(namebuf) >= SV_ChatFunc(s+2)); else if (!strncmp(s, "<=", 2)) result = (SV_ChatGetValue(namebuf) <= SV_ChatFunc(s+2)); else if (!strncmp(s, "!=", 2)) result = (SV_ChatGetValue(namebuf) != SV_ChatFunc(s+2)); else if (!strncmp(s, ">", 1)) result = (SV_ChatGetValue(namebuf) >= SV_ChatFunc(s+2)); else if (!strncmp(s, "<", 1)) result = (SV_ChatGetValue(namebuf) <= SV_ChatFunc(s+2)); //asignment operators else if (!strncmp(s, "=", 1)) result = (SV_ChatSetValue(namebuf, SV_ChatFunc(s+1))); else if (!strncmp(s, "+=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)+SV_ChatFunc(s+2))); else if (!strncmp(s, "-=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)-SV_ChatFunc(s+2))); else if (!strncmp(s, "*=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)*SV_ChatFunc(s+2))); else if (!strncmp(s, "/=", 2)) result = (SV_ChatSetValue(namebuf, SV_ChatGetValue(namebuf)/SV_ChatFunc(s+2))); else if (!strncmp(s, "|=", 2)) result = (SV_ChatSetValue(namebuf, (int)SV_ChatGetValue(namebuf)|(int)SV_ChatFunc(s+2))); else if (!strncmp(s, "&=", 2)) result = (SV_ChatSetValue(namebuf, (int)SV_ChatGetValue(namebuf)&(int)SV_ChatFunc(s+2))); //mathematical operators else if (!strncmp(s, "+", 1)) result = ( SV_ChatGetValue(namebuf)+SV_ChatFunc(s+1)); else if (!strncmp(s, "-", 1)) result = (SV_ChatGetValue(namebuf)-SV_ChatFunc(s+1)); else if (!strncmp(s, "*", 1)) result = (SV_ChatGetValue(namebuf)*SV_ChatFunc(s+1)); else if (!strncmp(s, "/", 1)) result = (SV_ChatGetValue(namebuf)/SV_ChatFunc(s+1)); else if (!strncmp(s, "|", 1)) result = ((int)SV_ChatGetValue(namebuf)|(int)SV_ChatFunc(s+1)); else if (!strncmp(s, "&", 1)) result = ((int)SV_ChatGetValue(namebuf)&(int)SV_ChatFunc(s+1)); //operatorless else result = SV_ChatGetValue(namebuf); } } if (noted) result = !result; return result; }