int LoadFlagsFromFile (char *mapname) { FILE *fp; char buf[1024], *s; // int len; int i; edict_t *ent; vec3_t position; sprintf (buf, "%s/tng/%s.flg", GAMEVERSION, mapname); fp = fopen (buf, "r"); if (!fp) { gi.dprintf ("Warning: No flag definition file for map %s.\n", mapname); return 0; } // FIXME: remove this functionality completely in the future gi.dprintf ("Warning: .flg files are deprecated, use .ctf ones for more control!\n"); i = 0; while (fgets(buf, 1000, fp) != NULL) { //first remove trailing spaces s = buf+strlen(buf)-1; for (; *s && (*s == '\r' || *s == '\n' || *s == ' '); s--) *s = '\0'; //check if it's a valid line if (strlen(buf) >= 5 && strncmp(buf, "#", 1) && strncmp(buf, "//", 2) && i < 2) { //a little bit dirty... :) if (sscanf(buf, "<%f %f %f>", &position[0], &position[1], &position[2]) != 3) continue; ent = G_Spawn (); ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); VectorCopy(position, ent->s.origin); if (!i) // Red Flag ent->classname = ED_NewString ("item_flag_team1"); else // Blue Flag ent->classname = ED_NewString ("item_flag_team2"); ED_CallSpawn (ent); i++; } } fclose (fp); if(i < 2) return (0); return (1); }
/* void medic_dodge (edict_t *self, edict_t *attacker, float eta, trace_t *tr) { if (random() > 0.25) return; if (!self->enemy) self->enemy = attacker; self->monsterinfo.currentmove = &medic_move_duck; //=========== //PMM - rogue rewrite of dodge code. float r; float height; int shooting = 0; // this needs to be before the AI_MEDIC check, because // a) if AI_MEDIC is set, we should have an enemy anyway and // b) FoundTarget calls medic_run, which can set AI_MEDIC if (!self->enemy) { self->enemy = attacker; FoundTarget (self); } // don't dodge if you're healing if (self->monsterinfo.aiflags & AI_MEDIC) return; // PMM - don't bother if it's going to hit anyway; fix for weird in-your-face etas (I was // seeing numbers like 13 and 14) if ((eta < 0.1) || (eta > 5)) return; r = random(); if (r > (0.25*((skill->value)+1))) return; if ((self->monsterinfo.currentmove == &medic_move_attackHyperBlaster) || (self->monsterinfo.currentmove == &medic_move_attackCable) || (self->monsterinfo.currentmove == &medic_move_attackBlaster)) { shooting = 1; } if (self->monsterinfo.aiflags & AI_DODGING) { height = self->absmax[2]; } else { height = self->absmax[2]-32-1; // the -1 is because the absmax is s.origin + maxs + 1 } // check to see if it makes sense to duck if (tr->endpos[2] <= height) { vec3_t right, diff; if (shooting) { self->monsterinfo.attack_state = AS_SLIDING; return; } AngleVectors (self->s.angles, NULL, right, NULL); VectorSubtract (tr->endpos, self->s.origin, diff); if (DotProduct (right, diff) < 0) { self->monsterinfo.lefty = 1; } // if it doesn't sense to duck, try to strafe away monster_done_dodge (self); self->monsterinfo.currentmove = &medic_move_run; self->monsterinfo.attack_state = AS_SLIDING; return; } if (skill->value == 0) { self->monsterinfo.currentmove = &medic_move_duck; // PMM - stupid dodge self->monsterinfo.duck_wait_time = level.time + eta + 1; self->monsterinfo.aiflags |= AI_DODGING; return; } if (!shooting) { self->monsterinfo.currentmove = &medic_move_duck; self->monsterinfo.duck_wait_time = level.time + eta + (0.1 * (3 - skill->value)); self->monsterinfo.aiflags |= AI_DODGING; } return; //PMM //=========== } */ void MedicCommanderCache (void) { edict_t *newEnt; int modelidx; int i; //FIXME - better way to do this? this is quick and dirty for (i=0; i < 7; i++) { newEnt = G_Spawn(); VectorCopy(vec3_origin, newEnt->s.origin); VectorCopy(vec3_origin, newEnt->s.angles); newEnt->classname = ED_NewString (reinforcements[i]); newEnt->monsterinfo.aiflags |= AI_DO_NOT_COUNT; ED_CallSpawn(newEnt); // FIXME - could copy mins/maxs into reinforcements from here G_FreeEdict (newEnt); } modelidx = gi.modelindex("models/items/spawngro/tris.md2"); modelidx = gi.modelindex("models/items/spawngro2/tris.md2"); }
/* * Takes a key/value pair and sets * the binary values in an edict */ void ED_ParseField(char *key, char *value, edict_t *ent) { field_t *f; byte *b; float v; vec3_t vec; for (f = fields; f->name; f++) { if (!Q_stricmp(f->name, key)) { /* found it */ if (f->flags & FFL_SPAWNTEMP) { b = (byte *)&st; } else { b = (byte *)ent; } switch (f->type) { case F_LSTRING: *(char **)(b + f->ofs) = ED_NewString(value); break; case F_VECTOR: sscanf(value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *)(b + f->ofs))[0] = vec[0]; ((float *)(b + f->ofs))[1] = vec[1]; ((float *)(b + f->ofs))[2] = vec[2]; break; case F_INT: *(int *)(b + f->ofs) = atoi(value); break; case F_FLOAT: *(float *)(b + f->ofs) = atof(value); break; case F_ANGLEHACK: v = atof(value); ((float *)(b + f->ofs))[0] = 0; ((float *)(b + f->ofs))[1] = v; ((float *)(b + f->ofs))[2] = 0; break; case F_IGNORE: break; default: break; } return; } } gi.dprintf("%s is not a field\n", key); }
/* =============== ED_ParseField Takes a key/value pair and sets the binary values in an edict =============== */ void ED_ParseField (const char *key, const char *value, edict_t *ent) { field_t *f; byte *b; float v; vec3_t vec; for (f=fields ; f->name ; f++) { if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key)) { // found it if (f->flags & FFL_SPAWNTEMP) b = (byte *)&st; else b = (byte *)ent; switch (f->type) { case F_LSTRING: *(char **)(b+f->ofs) = ED_NewString (value); break; case F_VECTOR: if (sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]) != 3) { gi.dprintf ("WARNING: ED_ParseField: Couldn't parse F_VECTOR %s, using (0, 0, 0)\n", value); VectorClear (vec); } ((float *)(b+f->ofs))[0] = vec[0]; ((float *)(b+f->ofs))[1] = vec[1]; ((float *)(b+f->ofs))[2] = vec[2]; break; case F_INT: *(int *)(b+f->ofs) = atoi(value); break; case F_FLOAT: *(float *)(b+f->ofs) = atof(value); break; case F_ANGLEHACK: v = atof(value); ((float *)(b+f->ofs))[0] = 0; ((float *)(b+f->ofs))[1] = v; ((float *)(b+f->ofs))[2] = 0; break; case F_IGNORE: break; default: break; } return; } } gi.dprintf ("%s is not a field\n", key); }
/* =============== ED_ParseField Takes a key/value pair and sets the binary values in an edict =============== */ void ED_ParseField (char *key, char *value, edict_t * ent) { field_t *f; byte *b; float v; vec3_t vec; for (f = fields; f->name; f++) { // FFL_NOSPAWN check in the following added in 3.20. Adding here. -FB if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp (f->name, key)) { // found it if (f->flags & FFL_SPAWNTEMP) b = (byte *) & st; else b = (byte *) ent; switch (f->type) { case F_LSTRING: *(char **) (b + f->ofs) = ED_NewString (value); break; case F_VECTOR: sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *) (b + f->ofs))[0] = vec[0]; ((float *) (b + f->ofs))[1] = vec[1]; ((float *) (b + f->ofs))[2] = vec[2]; break; case F_INT: *(int *) (b + f->ofs) = atoi (value); break; case F_FLOAT: *(float *) (b + f->ofs) = atof (value); break; case F_ANGLEHACK: v = atof (value); ((float *) (b + f->ofs))[0] = 0; ((float *) (b + f->ofs))[1] = v; ((float *) (b + f->ofs))[2] = 0; break; case F_IGNORE: break; // AQ:TNG JBravo fixing compiler warning. Still not sure 'bout this default: return; // End compiler warning fix } return; } } gi.dprintf ("%s is not a field\n", key); }
/* * ED_ParseField * * Takes a key/value pair and sets the binary values * in an edict */ static void ED_ParseField( char *key, char *value, edict_t *ent ) { const field_t *f; uint8_t *b; float v; vec3_t vec; for( f = fields; f->name; f++ ) { if( !Q_stricmp( f->name, key ) ) { // found it if( f->flags & FFL_SPAWNTEMP ) b = (uint8_t *)&st; else b = (uint8_t *)ent; switch( f->type ) { case F_LSTRING: *(char **)( b+f->ofs ) = ED_NewString( value ); break; case F_VECTOR: sscanf( value, "%f %f %f", &vec[0], &vec[1], &vec[2] ); ( (float *)( b+f->ofs ) )[0] = vec[0]; ( (float *)( b+f->ofs ) )[1] = vec[1]; ( (float *)( b+f->ofs ) )[2] = vec[2]; break; case F_INT: *(int *)( b+f->ofs ) = atoi( value ); break; case F_FLOAT: *(float *)( b+f->ofs ) = atof( value ); break; case F_ANGLEHACK: v = atof( value ); ( (float *)( b+f->ofs ) )[0] = 0; ( (float *)( b+f->ofs ) )[1] = v; ( (float *)( b+f->ofs ) )[2] = 0; break; case F_IGNORE: break; default: break; // FIXME: Should this be error? } return; } } if( developer->integer ) G_Printf( "%s is not a field\n", key ); }
/* =============== ED_ParseField Takes a key/value pair and sets the binary values in an edict =============== */ void ED_ParseField (char *key, char *value, edict_t *ent) { field_t *f; byte *b; float v; vec3_t vec; for (f=fields ; f->name ; f++) { // FFL_NOSPAWN check in the following added in 3.20. Adding here. -FB if (!(f->flags & FFL_NOSPAWN) && !Q_stricmp(f->name, key)) { // found it if (f->flags & FFL_SPAWNTEMP) b = (byte *)&st; else b = (byte *)ent; switch (f->type) { case F_LSTRING: *(char **)(b+f->ofs) = ED_NewString (value); break; case F_VECTOR: sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *)(b+f->ofs))[0] = vec[0]; ((float *)(b+f->ofs))[1] = vec[1]; ((float *)(b+f->ofs))[2] = vec[2]; break; case F_INT: *(int *)(b+f->ofs) = atoi(value); break; case F_FLOAT: *(float *)(b+f->ofs) = atof(value); break; case F_ANGLEHACK: v = atof(value); ((float *)(b+f->ofs))[0] = 0; ((float *)(b+f->ofs))[1] = v; ((float *)(b+f->ofs))[2] = 0; break; case F_IGNORE: break; #if defined (__APPLE__) || defined (MACOSX) default: break; #endif /* __APPLE__ ||ÊMACOSX */ } return; } } gi.dprintf ("%s is not a field\n", key); }
/* =============== ED_ParseField Takes a key/value pair and sets the binary values in an edict =============== */ static qboolean ED_ParseField(const field_t *fields, const char *key, const char *value, byte *b) { const field_t *f; float v; vec3_t vec; for (f = fields; f->name; f++) { if (!Q_stricmp(f->name, key)) { // found it switch (f->type) { case F_LSTRING: *(char **)(b + f->ofs) = ED_NewString(value); break; case F_VECTOR: if (sscanf(value, "%f %f %f", &vec[0], &vec[1], &vec[2]) != 3) { gi.dprintf("%s: couldn't parse '%s'\n", __func__, key); VectorClear(vec); } ((float *)(b + f->ofs))[0] = vec[0]; ((float *)(b + f->ofs))[1] = vec[1]; ((float *)(b + f->ofs))[2] = vec[2]; break; case F_INT: *(int *)(b + f->ofs) = atoi(value); break; case F_FLOAT: *(float *)(b + f->ofs) = atof(value); break; case F_ANGLEHACK: v = atof(value); ((float *)(b + f->ofs))[0] = 0; ((float *)(b + f->ofs))[1] = v; ((float *)(b + f->ofs))[2] = 0; break; case F_IGNORE: break; default: break; } return qtrue; } } return qfalse; }
/** * @brief Takes a key/value pair and sets the binary values in an edict */ static void ED_ParseField (const char *key, const char *value, edict_t * ent) { const field_t *f; byte *b; vec3_t vec; for (f = fields; f->name; f++) { if (!(f->flags & FFL_NOSPAWN) && !Q_strcasecmp(f->name, key)) { /* found it */ if (f->flags & FFL_SPAWNTEMP) b = (byte *) & st; else b = (byte *) ent; switch (f->type) { case F_LSTRING: *(char **) (b + f->ofs) = ED_NewString(value); break; case F_VECTOR: sscanf(value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *) (b + f->ofs))[0] = vec[0]; ((float *) (b + f->ofs))[1] = vec[1]; ((float *) (b + f->ofs))[2] = vec[2]; break; case F_INT: *(int *) (b + f->ofs) = atoi(value); break; case F_BOOL: *(bool *) (b + f->ofs) = atoi(value); break; case F_FLOAT: *(float *) (b + f->ofs) = atof(value); break; case F_IGNORE: break; } return; } } }
/* ============= ED_ParseEval Can parse either fields or globals returns false if error ============= */ qbool ED_ParseEpair (void *base, ddef_t *key, char *s) { int i; char string[128]; ddef_t *def; char *v, *w; void *d; dfunction_t *func; d = (void *)((int *)base + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: *(string_t *)d = PR_SetString(ED_NewString (s)); break; case ev_float: *(float *)d = Q_atof (s); break; case ev_vector: strlcpy (string, s, sizeof(string)); v = string; w = string; for (i=0 ; i<3 ; i++) { while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = Q_atof (w); w = v = v+1; } break; case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(Q_atoi (s))); break; case ev_field: def = ED_FindField (s); if (!def) { Con_Printf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; case ev_function: func = ED_FindFunction (s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } *(func_t *)d = func - pr_functions; break; default: break; } return true; }
/* ============= ED_ParseEval Can parse either fields or globals returns false if error ============= */ static qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s) { int i; char string[128]; ddef_t *def; char *v, *w; void *d; dfunction_t *func; d = (void *)((int *)base + key->ofs); switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: *(string_t *)d = ED_NewString(s); break; case ev_float: *(float *)d = atof (s); break; case ev_vector: strcpy (string, s); v = string; w = string; for (i = 0; i < 3; i++) { while (*v && *v != ' ') v++; *v = 0; ((float *)d)[i] = atof (w); w = v = v+1; } break; case ev_entity: *(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s))); break; case ev_field: def = ED_FindField (s); if (!def) { //johnfitz -- HACK -- suppress error becuase fog/sky fields might not be mentioned in defs.qc if (strncmp(s, "sky", 3) && strcmp(s, "fog")) Con_DPrintf ("Can't find field %s\n", s); return false; } *(int *)d = G_INT(def->ofs); break; case ev_function: func = ED_FindFunction (s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } *(func_t *)d = func - pr_functions; break; default: break; } return true; }
/** * @brief Takes a key/value pair and sets the binary values in an edict */ static void ED_ParseField (const char* key, const char* value, Edict* ent) { KeyValuePair kvp(key, value); if (kvp.isKey("classname")) ent->classname = ED_NewString(value); else if (kvp.isKey("model")) ent->model = ED_NewString(value); else if (kvp.isKey("spawnflags")) ent->spawnflags = kvp.asInt(); else if (kvp.isKey("speed")) ent->speed = kvp.asInt(); else if (kvp.isKey("dir")) ent->dir = kvp.asInt(); else if (kvp.isKey("active")) ent->active = kvp.asBool(); else if (kvp.isKey("target")) ent->target = ED_NewString(value); else if (kvp.isKey("targetname")) ent->targetname = ED_NewString(value); else if (kvp.isKey("item")) ent->item = ED_NewString(value); else if (kvp.isKey("noise")) ent->noise = ED_NewString(value); else if (kvp.isKey("particle")) ent->particle = ED_NewString(value); else if (kvp.isKey("nextmap")) ent->nextmap = ED_NewString(value); else if (kvp.isKey("frame")) ent->frame = kvp.asInt(); else if (kvp.isKey("team")) ent->team = kvp.asInt(); else if (kvp.isKey("group")) ent->group = ED_NewString(value); else if (kvp.isKey("size")) ent->fieldSize = kvp.asInt(); else if (kvp.isKey("count")) ent->count = kvp.asInt(); else if (kvp.isKey("time")) ent->time = kvp.asInt(); else if (kvp.isKey("health")) ent->HP = kvp.asInt(); else if (kvp.isKey("radius")) ent->radius = kvp.asInt(); else if (kvp.isKey("sounds")) ent->sounds = kvp.asInt(); else if (kvp.isKey("material")) ent->material = static_cast<edictMaterial_t>(kvp.asInt()); // enum !! else if (kvp.isKey("light")) ; // ignore /** @todo This (maxteams) should also be handled server side - currently this is * only done client side */ else if (kvp.isKey("maxteams")) ; // ignore else if (kvp.isKey("maxlevel")) ; // ignore else if (kvp.isKey("dmg")) ent->dmg = kvp.asInt(); else if (kvp.isKey("origin")) kvp.asVec3(ent->origin); else if (kvp.isKey("angles")) kvp.asVec3(ent->angles); else if (kvp.isKey("angle")) ent->angle = kvp.asFloat(); else if (kvp.isKey("message")) ent->message = ED_NewString(value); else if (kvp.isKey("norandomspawn")) spawnTemp.noRandomSpawn = kvp.asInt(); else if (kvp.isKey("noequipment")) spawnTemp.noEquipment = kvp.asInt(); }