// // ACS_funcThingCountName // static void ACS_funcThingCountName(ACS_FUNCARG) { mobjtype_t type = E_ThingNumForName(ACSVM::GetString(args[0])); int32_t tid = args[1]; *retn++ = ACS_thingCount(type, tid); }
// // ACS_funcThingCountNameSector // static void ACS_funcThingCountNameSector(ACS_FUNCARG) { int32_t tag = args[0]; mobjtype_t type = E_ThingNumForName(ACSVM::GetString(args[1])); int32_t tid = args[2]; *retn++ = ACS_thingCountSector(tag, type, tid); }
// // ACS_funcCheckThingType // static void ACS_funcCheckThingType(ACS_FUNCARG) { Mobj *mo = P_FindMobjFromTID(args[0], NULL, thread->trigger); if(mo) *retn++ = E_ThingNumForName(ACSVM::GetString(args[1])) == mo->type; else *retn++ = 0; }
// // ACS_spawnPoint // static void ACS_spawnPoint(ACS_FUNCARG, bool forced) { mobjtype_t type = E_ThingNumForName(ACSVM::GetString(args[0])); fixed_t x = args[1]; fixed_t y = args[2]; fixed_t z = args[3]; int tid = args[4]; angle_t angle = args[5] << 24; *retn++ = !!ACS_spawn(type, x, y, z, tid, angle, forced); }
// // ACS_spawnSpotAngle // static void ACS_spawnSpotAngle(ACS_FUNCARG, bool forced) { mobjtype_t type = E_ThingNumForName(ACSVM::GetString(args[0])); int spotid = args[1]; int tid = args[2]; Mobj *spot = NULL; *retn = 0; while((spot = P_FindMobjFromTID(spotid, spot, thread->trigger))) *retn += !!ACS_spawn(type, spot->x, spot->y, spot->z, tid, spot->angle, forced); ++retn; }
// // ACS_funcSpawnProjectile // static void ACS_funcSpawnProjectile(ACS_FUNCARG) { int32_t spotid = args[0]; mobjtype_t type = E_ThingNumForName(ACSVM::GetString(args[1])); angle_t angle = args[2] << 24; int32_t speed = args[3] * 8; int32_t vspeed = args[4] * 8; bool gravity = args[5] ? true : false; int32_t tid = args[6]; Mobj *spot = NULL; fixed_t momx = speed * finecosine[angle >> ANGLETOFINESHIFT]; fixed_t momy = speed * finesine[ angle >> ANGLETOFINESHIFT]; fixed_t momz = vspeed << FRACBITS; while((spot = P_FindMobjFromTID(spotid, spot, thread->trigger))) ACS_spawnProjectile(type, spot->x, spot->y, spot->z, momx, momy, momz, tid, spot, angle, gravity); }
// // E_processGamePropsBlock // // Process a single gameproperties block. // static void E_processGamePropsBlock(cfg_t *props) { // Flags if(IS_SET(ITEM_GPROP_FLAGSADD)) { const char *flagstr = cfg_getstr(props, ITEM_GPROP_FLAGSADD); GameModeInfo->flags |= E_ParseFlags(flagstr, &gmi_flagset); } if(IS_SET(ITEM_GPROP_FLAGSREM)) { const char *flagstr = cfg_getstr(props, ITEM_GPROP_FLAGSREM); unsigned int curFlags = GameModeInfo->flags; GameModeInfo->flags &= ~E_ParseFlags(flagstr, &gmi_flagset); GameModeInfo->flags |= (curFlags & GIF_SHAREWARE); // nice try, bitch. } if(IS_SET(ITEM_GPROP_MFLAGSADD)) { const char *flagstr = cfg_getstr(props, ITEM_GPROP_MFLAGSADD); GameModeInfo->missionInfo->flags |= E_ParseFlags(flagstr, &mission_flagset); } if(IS_SET(ITEM_GPROP_MFLAGSREM)) { const char *flagstr = cfg_getstr(props, ITEM_GPROP_MFLAGSREM); GameModeInfo->missionInfo->flags &= ~E_ParseFlags(flagstr, &mission_flagset); } // Demo Loop Properties if(IS_SET(ITEM_GPROP_TITLETICS)) GameModeInfo->titleTics = cfg_getint(props, ITEM_GPROP_TITLETICS); if(IS_SET(ITEM_GPROP_ADVISORTICS)) GameModeInfo->advisorTics = cfg_getint(props, ITEM_GPROP_ADVISORTICS); if(IS_SET(ITEM_GPROP_PAGETICS)) GameModeInfo->pageTics = cfg_getint(props, ITEM_GPROP_PAGETICS); // Menu Properties if(IS_SET(ITEM_GPROP_MENUBKGND)) { E_setDynamicString(GameModeInfo->menuBackground, GI_STR_MENUBKGND, cfg_getstr(props, ITEM_GPROP_MENUBKGND)); } if(IS_SET(ITEM_GPROP_TRANSFRAME)) { int stateNum = E_StateNumForName(cfg_getstr(props, ITEM_GPROP_TRANSFRAME)); if(stateNum >= 0 && (states[stateNum]->dehnum >= 0 || E_AutoAllocStateDEHNum(stateNum))) { GameModeInfo->transFrame = states[stateNum]->dehnum; } } if(IS_SET(ITEM_GPROP_MENUSKVASND)) { sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_MENUSKVASND)); if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd))) GameModeInfo->skvAtkSound = snd->dehackednum; } if(IS_SET(ITEM_GPROP_MENUOFFSET)) GameModeInfo->menuOffset = cfg_getint(props, ITEM_GPROP_MENUOFFSET); if(IS_SET(ITEM_GPROP_MENUPTR1) && GameModeInfo->menuCursor->numpatches >= 1) { E_setDynamicString(GameModeInfo->menuCursor->patches[0], GI_STR_MENUPTR1, cfg_getstr(props, ITEM_GPROP_MENUPTR1)); } if(IS_SET(ITEM_GPROP_MENUPTR2) && GameModeInfo->menuCursor->numpatches >= 2) { E_setDynamicString(GameModeInfo->menuCursor->patches[1], GI_STR_MENUPTR2, cfg_getstr(props, ITEM_GPROP_MENUPTR2)); } // Border Properties if(IS_SET(ITEM_GPROP_BORDERFLAT)) { E_setDynamicString(GameModeInfo->borderFlat, GI_STR_BORDERFLAT, cfg_getstr(props, ITEM_GPROP_BORDERFLAT)); } if(IS_SET(ITEM_GPROP_BORDERTL)) { E_setDynamicString(GameModeInfo->border->c_tl, GI_STR_BORDERTL, cfg_getstr(props, ITEM_GPROP_BORDERTL)); } if(IS_SET(ITEM_GPROP_BORDERTOP)) { E_setDynamicString(GameModeInfo->border->top, GI_STR_BORDERTOP, cfg_getstr(props, ITEM_GPROP_BORDERTOP)); } if(IS_SET(ITEM_GPROP_BORDERTR)) { E_setDynamicString(GameModeInfo->border->c_tr, GI_STR_BORDERTR, cfg_getstr(props, ITEM_GPROP_BORDERTR)); } if(IS_SET(ITEM_GPROP_BORDERLEFT)) { E_setDynamicString(GameModeInfo->border->left, GI_STR_BORDERLEFT, cfg_getstr(props, ITEM_GPROP_BORDERLEFT)); } if(IS_SET(ITEM_GPROP_BORDERRIGHT)) { E_setDynamicString(GameModeInfo->border->right, GI_STR_BORDERRIGHT, cfg_getstr(props, ITEM_GPROP_BORDERRIGHT)); } if(IS_SET(ITEM_GPROP_BORDERBL)) { E_setDynamicString(GameModeInfo->border->c_bl, GI_STR_BORDERBL, cfg_getstr(props, ITEM_GPROP_BORDERBL)); } if(IS_SET(ITEM_GPROP_BORDERBOTT)) { E_setDynamicString(GameModeInfo->border->bottom, GI_STR_BORDERBOTT, cfg_getstr(props, ITEM_GPROP_BORDERBOTT)); } if(IS_SET(ITEM_GPROP_BORDERBR)) { E_setDynamicString(GameModeInfo->border->c_br, GI_STR_BORDERBR, cfg_getstr(props, ITEM_GPROP_BORDERBR)); } // Console Properties if(IS_SET(ITEM_GPROP_CCHARSPERLN)) GameModeInfo->c_numCharsPerLine = cfg_getint(props, ITEM_GPROP_CCHARSPERLN); if(IS_SET(ITEM_GPROP_CBELLSOUND)) { sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_CBELLSOUND)); if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd))) GameModeInfo->c_BellSound = snd->dehackednum; } if(IS_SET(ITEM_GPROP_CCHATSOUND)) { sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_CCHATSOUND)); if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd))) GameModeInfo->c_ChatSound = snd->dehackednum; } if(IS_SET(ITEM_GPROP_CBACKDROP)) { E_setDynamicString(GameModeInfo->consoleBack, GI_STR_CBACKDROP, cfg_getstr(props, ITEM_GPROP_CBACKDROP)); } // HUD Properties if(IS_SET(ITEM_GPROP_PAUSEPATCH)) { E_setDynamicString(GameModeInfo->pausePatch, GI_STR_PAUSEPATCH, cfg_getstr(props, ITEM_GPROP_PAUSEPATCH)); } // Gamesim Properties if(IS_SET(ITEM_GPROP_PUFFTYPE)) { const char *name = cfg_getstr(props, ITEM_GPROP_PUFFTYPE); if(E_ThingNumForName(name) >= 0) E_setDynamicString(GameModeInfo->puffType, GI_STR_PUFFTYPE, name); } if(IS_SET(ITEM_GPROP_TELEFOGTYPE)) { const char *name = cfg_getstr(props, ITEM_GPROP_TELEFOGTYPE); if(E_ThingNumForName(name) >= 0) E_setDynamicString(GameModeInfo->teleFogType, GI_STR_TELEFOGTYPE, name); } if(IS_SET(ITEM_GPROP_TELEFOGHT)) { int num = cfg_getint(props, ITEM_GPROP_TELEFOGHT); GameModeInfo->teleFogHeight = num * FRACUNIT; } if(IS_SET(ITEM_GPROP_TELESOUND)) { sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_TELESOUND)); if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd))) GameModeInfo->teleSound = snd->dehackednum; } if(IS_SET(ITEM_GPROP_THRUSTFACTR)) GameModeInfo->thrustFactor = (int16_t)cfg_getint(props, ITEM_GPROP_THRUSTFACTR); if(IS_SET(ITEM_GPROP_DEFPCLASS)) { E_setDynamicString(GameModeInfo->defPClassName, GI_STR_DEFPCLASS, cfg_getstr(props, ITEM_GPROP_DEFPCLASS)); } // Determines behavior of the Teleport_EndGame line special when LevelInfo // has not provided a specific finale type for the level. if(IS_SET(ITEM_GPROP_FINTYPE)) { int finaleType = E_StrToNumLinear(finaleTypeStrs, FINALE_NUMFINALES, cfg_getstr(props, ITEM_GPROP_FINTYPE)); if(finaleType >= 0 && finaleType < FINALE_NUMFINALES) GameModeInfo->teleEndGameFinaleType = finaleType; } // Finale Properties if(IS_SET(ITEM_GPROP_FINALEX)) GameModeInfo->fTextPos->x = cfg_getint(props, ITEM_GPROP_FINALEX); if(IS_SET(ITEM_GPROP_FINALEY)) GameModeInfo->fTextPos->y = cfg_getint(props, ITEM_GPROP_FINALEY); if(IS_SET(ITEM_GPROP_CASTTITLEY)) GameModeInfo->castTitleY = cfg_getint(props, ITEM_GPROP_CASTTITLEY); if(IS_SET(ITEM_GPROP_CASTNAMEY)) GameModeInfo->castNameY = cfg_getint(props, ITEM_GPROP_CASTNAMEY); // Intermission Properties if(IS_SET(ITEM_GPROP_INTERPIC)) { E_setDynamicString(GameModeInfo->interPic, GI_STR_INTERPIC, cfg_getstr(props, ITEM_GPROP_INTERPIC)); } // Sound Properties if(IS_SET(ITEM_GPROP_DEFMUSNAME)) { E_setDynamicString(GameModeInfo->defMusName, GI_STR_DEFMUSNAME, cfg_getstr(props, ITEM_GPROP_DEFMUSNAME)); } if(IS_SET(ITEM_GPROP_DEFSNDNAME)) { E_setDynamicString(GameModeInfo->defSoundName, GI_STR_DEFSNDNAME, cfg_getstr(props, ITEM_GPROP_DEFSNDNAME)); } // Credit Screen Properties if(IS_SET(ITEM_GPROP_CREDITBKGND)) { E_setDynamicString(GameModeInfo->creditBackground, GI_STR_CREDITBKGND, cfg_getstr(props, ITEM_GPROP_CREDITBKGND)); } if(IS_SET(ITEM_GPROP_CREDITY)) GameModeInfo->creditY = cfg_getint(props, ITEM_GPROP_CREDITY); if(IS_SET(ITEM_GPROP_CREDITTSTEP)) GameModeInfo->creditTitleStep = cfg_getint(props, ITEM_GPROP_CREDITTSTEP); // Exit Properties if(IS_SET(ITEM_GPROP_ENDTEXTNAME)) { E_setDynamicString(GameModeInfo->endTextName, GI_STR_ENDTEXTNAME, cfg_getstr(props, ITEM_GPROP_ENDTEXTNAME)); } }
// // ACS_ChkThingVar // bool ACS_ChkThingVar(Mobj *thing, uint32_t var, int32_t val) { if(!thing) return false; switch(var) { case ACS_THINGVAR_Health: return thing->health == val; case ACS_THINGVAR_Speed: return thing->info->speed == val; case ACS_THINGVAR_Damage: return thing->damage == val; case ACS_THINGVAR_Alpha: return thing->translucency == val; case ACS_THINGVAR_RenderStyle: return false; case ACS_THINGVAR_SeeSound: return false; case ACS_THINGVAR_AttackSound: return false; case ACS_THINGVAR_PainSound: return false; case ACS_THINGVAR_DeathSound: return false; case ACS_THINGVAR_ActiveSound: return false; case ACS_THINGVAR_Ambush: return !!(thing->flags & MF_AMBUSH) == !!val; case ACS_THINGVAR_Invulnerable: return !!(thing->flags2 & MF2_INVULNERABLE) == !!val; case ACS_THINGVAR_JumpZ: return false; case ACS_THINGVAR_ChaseGoal: return false; case ACS_THINGVAR_Frightened: return false; case ACS_THINGVAR_Friendly: return !!(thing->flags & MF_FRIEND) == !!val; case ACS_THINGVAR_SpawnHealth: return thing->info->spawnhealth == val; case ACS_THINGVAR_Dropped: return !!(thing->flags & MF_DROPPED) == !!val; case ACS_THINGVAR_NoTarget: return false; case ACS_THINGVAR_Species: return false; case ACS_THINGVAR_NameTag: return false; case ACS_THINGVAR_Score: return false; case ACS_THINGVAR_NoTrigger: return false; case ACS_THINGVAR_DamageFactor: return false; case ACS_THINGVAR_MasterTID: return false; case ACS_THINGVAR_TargetTID: return thing->target ? thing->target->tid == val : false; case ACS_THINGVAR_TracerTID: return thing->tracer ? thing->tracer->tid == val : false; case ACS_THINGVAR_WaterLevel: return false; case ACS_THINGVAR_ScaleX: return M_FloatToFixed(thing->xscale) == val; case ACS_THINGVAR_ScaleY: return M_FloatToFixed(thing->yscale) == val; case ACS_THINGVAR_Dormant: return !!(thing->flags2 & MF2_DORMANT) == !!val; case ACS_THINGVAR_Mass: return thing->info->mass == val; case ACS_THINGVAR_Accuracy: return false; case ACS_THINGVAR_Stamina: return false; case ACS_THINGVAR_Height: return thing->height == val; case ACS_THINGVAR_Radius: return thing->radius == val; case ACS_THINGVAR_ReactionTime: return thing->reactiontime == val; case ACS_THINGVAR_MeleeRange: return MELEERANGE == val; case ACS_THINGVAR_ViewHeight: return false; case ACS_THINGVAR_AttackZOff: return false; case ACS_THINGVAR_StencilColor: return false; case ACS_THINGVAR_Friction: return false; case ACS_THINGVAR_DamageMult: return false; case ACS_THINGVAR_Angle: return thing->angle >> 16 == (uint32_t)val; case ACS_THINGVAR_Armor: return thing->player ? thing->player->armorpoints == val : false; // ioanch 20160116: extreme sector (portal aware) case ACS_THINGVAR_CeilingTexture: return P_ExtremeSectorAtPoint(thing, true)->ceilingpic == R_FindWall(ACSVM::GetString(val)); case ACS_THINGVAR_CeilingZ: return thing->ceilingz == val; case ACS_THINGVAR_FloorTexture: return P_ExtremeSectorAtPoint(thing, false)->floorpic == R_FindWall(ACSVM::GetString(val)); case ACS_THINGVAR_FloorZ: return thing->floorz == val; case ACS_THINGVAR_Frags: return thing->player ? thing->player->totalfrags == val : false; case ACS_THINGVAR_LightLevel: return thing->subsector->sector->lightlevel == val; case ACS_THINGVAR_MomX: return thing->momx == val; case ACS_THINGVAR_MomY: return thing->momy == val; case ACS_THINGVAR_MomZ: return thing->momz == val; case ACS_THINGVAR_Pitch: return thing->player ? thing->player->pitch >> 16 == val : false; case ACS_THINGVAR_PlayerNumber: return thing->player ? thing->player - players == val : false; case ACS_THINGVAR_SigilPieces: return false; case ACS_THINGVAR_TID: return thing->tid == val; case ACS_THINGVAR_Type: return thing->type == E_ThingNumForName(ACSVM::GetString(val)); case ACS_THINGVAR_X: return thing->x == val; case ACS_THINGVAR_Y: return thing->y == val; case ACS_THINGVAR_Z: return thing->z == val; default: return false; } }
// // E_ProcessBossTypes // // Gets the thing type entries in the boss_spawner_types list, // for use by the SpawnFly codepointer. // // modified by schepe to remove 11-type limit // static void E_ProcessBossTypes(cfg_t *cfg) { int i, a = 0; int numTypes = cfg_size(cfg, SEC_BOSSTYPES); int numProbs = cfg_size(cfg, SEC_BOSSPROBS); bool useProbs = true; E_EDFLogPuts("\t* Processing boss spawn types\n"); if(!numTypes) { // haleyjd 05/31/06: allow zero boss types E_EDFLogPuts("\t\tNo boss types defined\n"); return; } // haleyjd 11/19/03: allow defaults for boss spawn probs if(!numProbs) useProbs = false; if(useProbs ? numTypes != numProbs : numTypes != 11) { E_EDFLoggedErr(2, "E_ProcessBossTypes: %d boss types, %d boss probs\n", numTypes, useProbs ? numProbs : 11); } // haleyjd 11/21/11: allow multiple runs if(BossSpawnTypes) { efree(BossSpawnTypes); BossSpawnTypes = NULL; } if(BossSpawnProbs) { efree(BossSpawnProbs); BossSpawnProbs = NULL; } NumBossTypes = numTypes; BossSpawnTypes = ecalloc(int *, numTypes, sizeof(int)); BossSpawnProbs = ecalloc(int *, numTypes, sizeof(int)); // load boss spawn probabilities for(i = 0; i < numTypes; ++i) { if(useProbs) { a += cfg_getnint(cfg, SEC_BOSSPROBS, i); BossSpawnProbs[i] = a; } else BossSpawnProbs[i] = BossDefaults[i]; } // check that the probabilities total 256 if(useProbs && a != 256) { E_EDFLoggedErr(2, "E_ProcessBossTypes: boss spawn probs do not total 256\n"); } for(i = 0; i < numTypes; ++i) { const char *typeName = cfg_getnstr(cfg, SEC_BOSSTYPES, i); int typeNum = E_ThingNumForName(typeName); if(typeNum == -1) { E_EDFLoggedWarning(2, "Warning: invalid boss type '%s'\n", typeName); typeNum = UnknownThingType; } BossSpawnTypes[i] = typeNum; E_EDFLogPrintf("\t\tAssigned type %s(#%d) to boss type %d\n", mobjinfo[typeNum]->name, typeNum, i); } }
// // E_ProcessCast // // Creates the DOOM II cast call information // static void E_ProcessCast(cfg_t *cfg) { static bool firsttime = true; int i, numcastorder = 0, numcastsections = 0; cfg_t **ci_order; E_EDFLogPuts("\t* Processing cast call\n"); // get number of cast sections numcastsections = cfg_size(cfg, SEC_CAST); if(firsttime && !numcastsections) // on main parse, at least one is required. E_EDFLoggedErr(2, "E_ProcessCast: no cast members defined.\n"); firsttime = false; E_EDFLogPrintf("\t\t%d cast member(s) defined\n", numcastsections); // haleyjd 11/21/11: allow multiple runs if(castorder) { int i; // free names for(i = 0; i < max_castorder; i++) { if(castorder[i].name) efree(castorder[i].name); } // free castorder efree(castorder); castorder = NULL; max_castorder = 0; } // check if the "castorder" array is defined for imposing an // order on the castinfo sections numcastorder = cfg_size(cfg, SEC_CASTORDER); E_EDFLogPrintf("\t\t%d cast member(s) in castorder\n", numcastorder); // determine size of castorder max_castorder = (numcastorder > 0) ? numcastorder : numcastsections; // allocate with size+1 for an end marker castorder = estructalloc(castinfo_t, max_castorder + 1); ci_order = ecalloc(cfg_t **, sizeof(cfg_t *), max_castorder); if(numcastorder > 0) { for(i = 0; i < numcastorder; ++i) { const char *title = cfg_getnstr(cfg, SEC_CASTORDER, i); cfg_t *section = cfg_gettsec(cfg, SEC_CAST, title); if(!section) { E_EDFLoggedErr(2, "E_ProcessCast: unknown cast member '%s' in castorder\n", title); } ci_order[i] = section; } } else { // no castorder array is defined, so use the cast members // in the order they are encountered (for backward compatibility) for(i = 0; i < numcastsections; ++i) ci_order[i] = cfg_getnsec(cfg, SEC_CAST, i); } for(i = 0; i < max_castorder; ++i) { int j; const char *tempstr; int tempint = 0; cfg_t *castsec = ci_order[i]; // resolve thing type tempstr = cfg_getstr(castsec, ITEM_CAST_TYPE); if(!tempstr || (tempint = E_ThingNumForName(tempstr)) == -1) { E_EDFLoggedWarning(2, "Warning: cast %d: unknown thing type %s\n", i, tempstr); tempint = UnknownThingType; } castorder[i].type = tempint; // get cast name, if any -- the first seventeen entries can // default to using the internal string editable via BEX strings tempstr = cfg_getstr(castsec, ITEM_CAST_NAME); if(cfg_size(castsec, ITEM_CAST_NAME) == 0 && i < 17) castorder[i].name = NULL; // set from DeHackEd else castorder[i].name = estrdup(tempstr); // store provided value // get stopattack flag (used by player) castorder[i].stopattack = cfg_getbool(castsec, ITEM_CAST_SA); // process sound blocks (up to four will be processed) tempint = cfg_size(castsec, ITEM_CAST_SOUND); for(j = 0; j < 4; ++j) { castorder[i].sounds[j].frame = 0; castorder[i].sounds[j].sound = 0; } for(j = 0; j < tempint && j < 4; ++j) { int num; sfxinfo_t *sfx; const char *name; cfg_t *soundsec = cfg_getnsec(castsec, ITEM_CAST_SOUND, j); // if these are invalid, just fill them with zero rather // than causing an error, as they're very unimportant // name of sound to play name = cfg_getstr(soundsec, ITEM_CAST_SOUNDNAME); // haleyjd 03/22/06: modified to support dehnum auto-allocation if((sfx = E_EDFSoundForName(name)) == NULL) { E_EDFLoggedWarning(2, "Warning: cast member references invalid sound %s\n", name); castorder[i].sounds[j].sound = 0; } else { if(sfx->dehackednum != -1 || E_AutoAllocSoundDEHNum(sfx)) castorder[i].sounds[j].sound = sfx->dehackednum; else { E_EDFLoggedWarning(2, "Warning: could not auto-allocate a DeHackEd number " "for sound %s\n", name); castorder[i].sounds[j].sound = 0; } } // name of frame that triggers sound event name = cfg_getstr(soundsec, ITEM_CAST_SOUNDFRAME); if((num = E_StateNumForName(name)) < 0) num = 0; castorder[i].sounds[j].frame = num; } } // initialize the end marker to all zeroes memset(&castorder[max_castorder], 0, sizeof(castinfo_t)); // free the ci_order table efree(ci_order); }