static void EnumerateField(const save_field_t *pField, const byte *pbBase) { void *pv = (void *)(pbBase + pField->iOffset); switch (pField->eFieldType) { case F_STRING: *(int *)pv = GetStringNum(*(char **)pv); break; case F_GENTITY: *(int *)pv = GetGEntityNum(*(gentity_t **)pv); break; case F_GROUP: *(int *)pv = GetGroupNumber(*(AIGroupInfo_t **)pv); break; case F_GCLIENT: *(int *)pv = GetGClientNum(*(gclient_t **)pv, (gentity_t *) pbBase); break; case F_ITEM: *(int *)pv = GetGItemNum(*(gitem_t **)pv); break; case F_VEHINFO: *(int *)pv = GetVehicleInfoNum(*(vehicleInfo_t **)pv); break; case F_BEHAVIORSET: { const char **p = (const char **) pv; for (int i=0; i<NUM_BSETS; i++) { pv = &p[i]; // since you can't ++ a void ptr *(int *)pv = GetStringNum(*(char **)pv); } } break; /*MCG case F_BODYQUEUE: { gentity_t **p = (gentity_t **) pv; for (int i=0; i<BODY_QUEUE_SIZE; i++) { pv = &p[i]; // since you can't ++ a void ptr *(int *)pv = GetGEntityNum(*(gentity_t **)pv); } } break; */ case F_ALERTEVENT: // convert all gentity_t ptrs in an alertEvent array into indexes... { alertEvent_t* p = (alertEvent_t *) pv; for (int i=0; i<MAX_ALERT_EVENTS; i++) { p[i].owner = (gentity_t *) GetGEntityNum(p[i].owner); } } break; case F_AIGROUPS: // convert to ptrs within this into indexes... { AIGroupInfo_t* p = (AIGroupInfo_t *) pv; for (int i=0; i<MAX_FRAME_GROUPS; i++) { p[i].enemy = (gentity_t *) GetGEntityNum(p[i].enemy); p[i].commander = (gentity_t *) GetGEntityNum(p[i].commander); } } break; case F_ANIMFILESETS: { animFileSet_t* p = (animFileSet_t *) pv; for (int i=0; i<MAX_ANIM_FILES; i++) { for ( int j=0; j<MAX_ANIM_EVENTS; j++ ) { const char *ptAnimEventStringData = p[i].torsoAnimEvents[j].stringData; *(int *)(&p[i].torsoAnimEvents[j].stringData) = GetStringNum( ptAnimEventStringData ); const char *plAnimEventStringData = p[i].legsAnimEvents[j].stringData; *(int *)(&p[i].legsAnimEvents[j].stringData) = GetStringNum( plAnimEventStringData ); } } } break; case F_BOOLPTR: *(qboolean *)pv = !!(*(int *)pv); break; // These are pointers that are always recreated case F_NULL: *(void **)pv = NULL; break; case F_IGNORE: break; default: G_Error ("EnumerateField: unknown field type"); break; } }
void EnumerateField(field_t *pField, byte *pbBase) { void *pv = (void *)(pbBase + pField->iOffset); switch (pField->eFieldType) { case F_STRING: *(int *)pv = GetStringNum(*(char **)pv); break; case F_GENTITY: *(int *)pv = GetGEntityNum(*(gentity_t **)pv); break; case F_GROUP: *(int *)pv = GetGroupNumber(*(AIGroupInfo_t **)pv); break; case F_GCLIENT: { // unfortunately, I now need to see if this is a 'real' client (and therefore resolve to an enum), or // whether it's one of Mike G's private clients that needs saving here (thanks Mike...) // gentity_t *ent = (gentity_t *) pbBase; if (ent->NPC == NULL) { // regular client... // *(int *)pv = GetGClientNum(*(gclient_t **)pv); break; } else { // this must be one of Mike's, so mark it as special... // *(int *)pv = -2; // yeuch, but distinguishes it from a valid 0 index, or -1 for client==NULL } } break; case F_ITEM: *(int *)pv = GetGItemNum(*(gitem_t **)pv); break; case F_BEHAVIORSET: { const char **p = (const char **) pv; for (int i=0; i<NUM_BSETS; i++) { pv = &p[i]; // since you can't ++ a void ptr *(int *)pv = GetStringNum(*(char **)pv); } } break; /*MCG case F_BODYQUEUE: { gentity_t **p = (gentity_t **) pv; for (int i=0; i<BODY_QUEUE_SIZE; i++) { pv = &p[i]; // since you can't ++ a void ptr *(int *)pv = GetGEntityNum(*(gentity_t **)pv); } } break; */ case F_ALERTEVENT: // convert all gentity_t ptrs in an alertEvent array into indexes... { alertEvent_t* p = (alertEvent_t *) pv; for (int i=0; i<MAX_ALERT_EVENTS; i++) { p[i].owner = (gentity_t *) GetGEntityNum(p[i].owner); } } break; case F_AIGROUPS: // convert to ptrs within this into indexes... { AIGroupInfo_t* p = (AIGroupInfo_t *) pv; for (int i=0; i<MAX_FRAME_GROUPS; i++) { p[i].enemy = (gentity_t *) GetGEntityNum(p[i].enemy); p[i].commander = (gentity_t *) GetGEntityNum(p[i].commander); } } break; case F_BOOLPTR: *(qboolean *)pv = !!(*(int *)pv); break; // These are pointers that are always recreated case F_NULL: *(void **)pv = NULL; break; case F_IGNORE: break; default: G_Error ("EnumerateField: unknown field type"); break; } }