dd_bool A_LocalQuake(byte* args, mobj_t* actor) { mobj_t* focus, *target; int lastfound = 0; int success = false; DENG_UNUSED(actor); // Find all quake foci. do { if((target = P_FindMobjFromTID(args[4], &lastfound))) { if((focus = P_SpawnMobj(MT_QUAKE_FOCUS, target->origin, 0, 0))) { focus->args[0] = args[0]; focus->args[1] = args[1] / 2; // Decremented every 2 tics. focus->args[2] = args[2]; focus->args[3] = args[3]; focus->args[4] = args[4]; success = true; } } } while(target != NULL); return success; }
// // ACS_funcUniqueTID // static void ACS_funcUniqueTID(ACS_FUNCARG) { int32_t tid = argc > 0 ? args[0] : 0; uint32_t max = argc > 1 ? args[1] : 0; // Start point of 0 means random. How about outside the int16_t range? // We also don't trust no negative TIDs 'round these here parts. if(!tid || tid < 0) tid = P_RangeRandomEx(pr_script, 0x8000, 0xFFFF); while(P_FindMobjFromTID(tid, NULL, NULL)) { // Don't overflow the tid. Again, we don't take kindly to negative TIDs. if(tid == 0xFFFF) tid = 1; else ++tid; // Avoid infinite loops. if(!--max) { tid = 0; break; } } *retn++ = tid; }
// // ACS_funcRadiusQuake // static void ACS_funcRadiusQuake(ACS_FUNCARG) { int32_t tid = args[0]; int32_t intensity = args[1]; int32_t duration = args[2]; int32_t damageRadius = args[3]; int32_t quakeRadius = args[4]; const char *snd = ACSVM::GetString(args[5]); Mobj *mo = NULL; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) { QuakeThinker *qt; qt = new QuakeThinker; qt->addThinker(); qt->intensity = intensity; qt->duration = duration; qt->damageRadius = damageRadius; qt->quakeRadius = quakeRadius; qt->x = mo->x; qt->y = mo->y; qt->z = mo->z; qt->groupid = mo->groupid; S_StartSoundNameAtVolume(qt, snd, 127, ATTN_NORMAL, CHAN_AUTO); } }
// // ACS_funcSetThingState // static void ACS_funcSetThingState(ACS_FUNCARG) { int32_t tid = args[0]; const char *statename = ACSVM::GetString(args[1]); statenum_t statenum = E_StateNumForName(statename); state_t *state; int32_t count = 0; Mobj *mo = NULL; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) { // Look for the named state for that type. if((state = E_GetJumpInfo(mo->info, statename))) { P_SetMobjState(mo, state->index); ++count; } // Otherwise, fall back to the global name. else if(statenum >= 0) { P_SetMobjState(mo, statenum); ++count; } } *retn++ = count; }
// // ACS_funcSetThingMomentum // static void ACS_funcSetThingMomentum(ACS_FUNCARG) { int32_t tid = args[0]; fixed_t momx = args[1]; fixed_t momy = args[2]; fixed_t momz = args[3]; bool add = args[4] ? true : false; Mobj *mo = NULL; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) { if(add) { mo->momx += momx; mo->momy += momy; mo->momz += momz; } else { mo->momx = momx; mo->momy = momy; mo->momz = momz; } } }
// // ACS_funcStopSound // static void ACS_funcStopSound(ACS_FUNCARG) { Mobj *mo = P_FindMobjFromTID(args[0], NULL, thread->trigger); int chan = argc > 1 ? args[1] & 7 : CHAN_BODY; if(!mo) return; S_StopSound(mo, chan); }
// // ACS_funcPlaySound // static void ACS_funcPlaySound(ACS_FUNCARG) { Mobj *mo = P_FindMobjFromTID(args[0], NULL, thread->trigger); sfxinfo_t *sfx = S_SfxInfoForName(ACSVM::GetString(args[1])); if(!mo || !sfx) return; ACS_playSound(mo, sfx, argc, args); }
// // 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; }
boolean EV_ThingSpawn(byte *args, boolean fog) { int tid; angle_t angle; mobj_t *mobj; mobj_t *newMobj; mobj_t *fogMobj; mobjtype_t moType; int searcher; boolean success; fixed_t z; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(nomonsters && (mobjinfo[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; } angle = (int) args[2] << 24; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobjinfo[moType].flags2 & MF2_FLOATBOB) { z = mobj->z - mobj->floorz; } else { z = mobj->z; } newMobj = P_SpawnMobj(mobj->x, mobj->y, z, moType); if(P_TestMobjLocation(newMobj) == false) { // Didn't fit P_RemoveMobj(newMobj); } else { newMobj->angle = angle; if(fog == true) { fogMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, MT_TFOG); S_StartSound(SFX_TELEPORT, fogMobj); } newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(newMobj->flags2 & MF2_FLOATBOB) { newMobj->special1 = newMobj->z - newMobj->floorz; } success = true; } } return success; }
static void ThingCount(int type, int tid) { int count; int searcher; mobj_t *mobj; mobjtype_t moType; thinker_t *think; if (!(type + tid)) { // Nothing to count return; } moType = TranslateThingType[type]; count = 0; searcher = -1; if (tid) { // Count TID things while ((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if (type == 0) { // Just count TIDs count++; } else if (moType == mobj->type) { if (mobj->flags & MF_COUNTKILL && mobj->health <= 0) { // Don't count dead monsters continue; } count++; } } } else { // Count only types for (think = thinkercap.next; think != &thinkercap; think = think->next) { if (think->function != P_MobjThinker) { // Not a mobj thinker continue; } mobj = (mobj_t *) think; if (mobj->type != moType) { // Doesn't match continue; } if (mobj->flags & MF_COUNTKILL && mobj->health <= 0) { // Don't count dead monsters continue; } count++; } } Push(count); }
// // ACS_funcSetThingVar // static void ACS_funcSetThingVar(ACS_FUNCARG) { int32_t tid = args[0]; uint32_t var = args[1]; int32_t val = args[2]; Mobj *mo = NULL; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) ACS_SetThingVar(mo, var, val); }
// // ACS_funcSetThingAngle // static void ACS_funcSetThingAngle(ACS_FUNCARG) { int32_t tid = args[0]; angle_t angle = (angle_t)args[1] << 16; for(Mobj *mo = NULL; (mo = P_FindMobjFromTID(tid, mo, thread->trigger));) { mo->angle = angle; } }
// // ACS_funcThingSound // static void ACS_funcThingSound(ACS_FUNCARG) { int tid = args[0]; const char *snd = ACSVM::GetString(args[1]); int vol = args[2]; Mobj *mo = NULL; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) S_StartSoundNameAtVolume(mo, snd, vol, ATTN_NORMAL, CHAN_AUTO); }
// // ACS_funcSetThingPitch // static void ACS_funcSetThingPitch(ACS_FUNCARG) { int32_t tid = args[0]; angle_t pitch = (angle_t)args[1] << 16; for(Mobj *mo = NULL; (mo = P_FindMobjFromTID(tid, mo, thread->trigger));) { if(mo->player) mo->player->prevpitch = mo->player->pitch = pitch; } }
dd_bool EV_ThingSpawn(byte *args, dd_bool fog) { int tid, searcher; angle_t angle; mobj_t *mobj, *newMobj, *fogMobj; mobjtype_t moType; dd_bool success; //coord_t z; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(G_Ruleset_NoMonsters() && (MOBJINFO[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; } angle = (int) args[2] << 24; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { //z = mobj->origin[VZ]; if((newMobj = P_SpawnMobj(moType, mobj->origin, angle, 0))) { if(P_TestMobjLocation(newMobj) == false) { // Didn't fit P_MobjRemove(newMobj, true); } else { if(fog) { if((fogMobj = P_SpawnMobjXYZ(MT_TFOG, mobj->origin[VX], mobj->origin[VY], mobj->origin[VZ] + TELEFOGHEIGHT, angle + ANG180, 0))) S_StartSound(SFX_TELEPORT, fogMobj); } newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(newMobj->flags2 & MF2_FLOATBOB) { newMobj->special1 = FLT2FIX(newMobj->origin[VZ] - newMobj->floorZ); } success = true; } } } return success; }
// // ACS_funcCheckSight // static void ACS_funcCheckSight(ACS_FUNCARG) { int32_t tid1 = args[0]; int32_t tid2 = args[1]; Mobj *mo1 = NULL; Mobj *mo2 = NULL; while((mo1 = P_FindMobjFromTID(tid1, mo1, thread->trigger))) { while((mo2 = P_FindMobjFromTID(tid2, mo2, thread->trigger))) { if(P_CheckSight(mo1, mo2)) { *retn++ = 1; return; } } } *retn++ = 0; }
dd_bool EV_ThingProjectile(byte* args, dd_bool gravity) { uint an; int tid, searcher; angle_t angle; coord_t speed, vspeed; mobjtype_t moType; mobj_t* mobj, *newMobj; dd_bool success; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(G_Ruleset_NoMonsters() && (MOBJINFO[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; } angle = (int) args[2] << 24; an = angle >> ANGLETOFINESHIFT; speed = FIX2FLT((int) args[3] << 13); vspeed = FIX2FLT((int) args[4] << 13); while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if((newMobj = P_SpawnMobj(moType, mobj->origin, angle, 0))) { if(newMobj->info->seeSound) S_StartSound(newMobj->info->seeSound, newMobj); newMobj->target = mobj; // Originator newMobj->mom[MX] = speed * FIX2FLT(finecosine[an]); newMobj->mom[MY] = speed * FIX2FLT(finesine[an]); newMobj->mom[MZ] = vspeed; newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(gravity == true) { newMobj->flags &= ~MF_NOGRAVITY; newMobj->flags2 |= MF2_LOGRAV; } if(P_CheckMissileSpawn(newMobj) == true) { success = true; } } } return success; }
// // 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; }
boolean EV_ThingProjectile(byte *args, boolean gravity) { int tid; angle_t angle; int fineAngle; fixed_t speed; fixed_t vspeed; mobjtype_t moType; mobj_t *mobj; mobj_t *newMobj; int searcher; boolean success; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(nomonsters && (mobjinfo[moType].flags & MF_COUNTKILL)) { // Don't spawn monsters if -nomonsters return false; } angle = (int) args[2] << 24; fineAngle = angle >> ANGLETOFINESHIFT; speed = (int) args[3] << 13; vspeed = (int) args[4] << 13; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, moType); if(newMobj->info->seesound) { S_StartSound(newMobj->info->seesound, newMobj); } newMobj->target = mobj; // Originator newMobj->angle = angle; newMobj->momx = FixedMul(speed, finecosine[fineAngle]); newMobj->momy = FixedMul(speed, finesine[fineAngle]); newMobj->momz = vspeed; newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(gravity == true) { newMobj->flags &= ~MF_NOGRAVITY; newMobj->flags2 |= MF2_LOGRAV; } if(P_CheckMissileSpawn(newMobj) == true) { success = true; } } return success; }
// // ACS_funcSetThingSpecial // static void ACS_funcSetThingSpecial(ACS_FUNCARG) { int tid = args[0]; //int spec = args[1]; HEXEN_TODO int larg[NUMLINEARGS]; Mobj *mo = NULL; memcpy(larg, args+2, sizeof(larg)); while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) { //mo->special = spec; HEXEN_TODO memcpy(mo->args, larg, sizeof(larg)); } }
// // ACS_funcSetActivatorToTarget // static void ACS_funcSetActivatorToTarget(ACS_FUNCARG) { Mobj *mo = P_FindMobjFromTID(args[0], NULL, thread->trigger); if(mo) { if(mo->target) P_SetTarget(&thread->trigger, mo->target); else P_SetTarget(&thread->trigger, mo); *retn++ = 1; } else *retn++ = 0; }
// // ACS_funcCheckThingFlag // static void ACS_funcCheckThingFlag(ACS_FUNCARG) { Mobj *mo = P_FindMobjFromTID(args[0], NULL, thread->trigger); dehflags_t *flag = deh_ParseFlagCombined(ACSVM::GetString(args[1])); if(!mo || !flag) {*retn++ = 0; return;} switch(flag->index) { case 0: *retn++ = !!(mo->flags & flag->value); break; case 1: *retn++ = !!(mo->flags2 & flag->value); break; case 2: *retn++ = !!(mo->flags3 & flag->value); break; case 3: *retn++ = !!(mo->flags4 & flag->value); break; default: *retn++ = 0; break; } }
// // ACS_funcThingDamage // static void ACS_funcThingDamage(ACS_FUNCARG) { int32_t tid = args[0]; int32_t damage = args[1]; int mod = E_DamageTypeNumForName(ACSVM::GetString(args[2])); Mobj *mo = NULL; int32_t count = 0; while((mo = P_FindMobjFromTID(tid, mo, thread->trigger))) { P_DamageMobj(mo, NULL, NULL, damage, mod); ++count; } *retn++ = count; }
dd_bool EV_ThingDeactivate(int tid) { mobj_t *mobj; int searcher; dd_bool success; success = false; searcher = -1; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(DeactivateThing(mobj) == true) { success = true; } } return success; }
static int CmdThingSound(void) { int tid; int sound; int volume; mobj_t *mobj; int searcher; volume = Pop(); sound = S_GetSoundID(ACStrings[Pop()]); tid = Pop(); searcher = -1; while ((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { S_StartSoundAtVolume(mobj, sound, volume); } return SCRIPT_CONTINUE; }
// // 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); }
dd_bool EV_ThingDestroy(int tid) { mobj_t *mobj; int searcher; dd_bool success; success = false; searcher = -1; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobj->flags & MF_SHOOTABLE) { P_DamageMobj(mobj, NULL, NULL, 10000, false); success = true; } } return success; }
// // ACS_funcClassifyThing // static void ACS_funcClassifyThing(ACS_FUNCARG) { int32_t tid = args[0]; int32_t result; Mobj *mo; mo = P_FindMobjFromTID(tid, NULL, thread->trigger); if(mo) { result = 0; if(mo->player) { result |= THINGCLASS_PLAYER; if(mo->player->mo != mo) result |= THINGCLASS_VOODOODOLL; } if(mo->flags & MF_MISSILE) result |= THINGCLASS_MISSILE; else if(mo->flags3 & MF3_KILLABLE || mo->flags & MF_COUNTKILL) result |= THINGCLASS_MONSTER; else result |= THINGCLASS_GENERIC; if(mo->health > 0) result |= THINGCLASS_ALIVE; else result |= THINGCLASS_DEAD; } else { if(tid) result = THINGCLASS_NONE; else result = THINGCLASS_WORLD; } *retn++ = result; }
dd_bool EV_ThingRemove(int tid) { mobj_t *mobj; int searcher; dd_bool success; success = false; searcher = -1; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobj->type == MT_BRIDGE) { A_BridgeRemove(mobj); return true; } P_MobjRemove(mobj, false); success = true; } return success; }
// // ACS_funcThingProjectile // static void ACS_funcThingProjectile(ACS_FUNCARG) { int32_t spotid = args[0]; int32_t type = 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; if(type < 0 || type >= ACS_NUM_THINGTYPES) return; type = ACS_thingtypes[type]; while((spot = P_FindMobjFromTID(spotid, spot, thread->trigger))) ACS_spawnProjectile(type, spot->x, spot->y, spot->z, momx, momy, momz, tid, spot, angle, gravity); }