DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_ReFire) { ACTION_PARAM_START(1) ACTION_PARAM_STATE(state, 0); A_ReFire(self, state); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) { AActor *missile; angle_t an; if (!self->target) return; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); A_FaceTarget (self); // Change direction to ... self->angle += FATSPREAD; missile = P_SpawnMissile (self, self->target, spawntype); // [BC] If we're the server, tell clients to spawn the missile. if (( NETWORK_GetState( ) == NETSTATE_SERVER ) && ( missile )) SERVERCOMMANDS_SpawnMissile( missile ); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { missile->angle += FATSPREAD; an = missile->angle >> ANGLETOFINESHIFT; missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]); // [BC] If we're the server, tell clients to spawn the missile. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SpawnMissile( missile ); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod) { ACTION_PARAM_START(1); ACTION_PARAM_CLASS(podtype, 0); AActor *mo; fixed_t x; fixed_t y; fixed_t z; if (self->special1 == MAX_GEN_PODS) { // Too many generated pods return; } x = self->x; y = self->y; z = self->z; mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE); if (!P_CheckPosition (mo, x, y)) { // Didn't fit mo->Destroy (); return; } mo->SetState (mo->FindState("Grow")); P_ThrustMobj (mo, pr_makepod()<<24, (fixed_t)(4.5*FRACUNIT)); S_Sound (mo, CHAN_BODY, self->AttackSound, 1, ATTN_IDLE); self->special1++; // Increment generated pod count mo->master = self; // Link the generator to the pod return; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Fire) { ACTION_PARAM_START(1); ACTION_PARAM_FIXED(height,0); A_Fire(self, height); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FatAttack1) { AActor *missile; angle_t an; if (!self->target) return; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); A_FaceTarget (self); // Change direction to ... self->angle += FATSPREAD; P_SpawnMissile (self, self->target, spawntype); missile = P_SpawnMissile (self, self->target, spawntype); if (missile != NULL) { missile->angle += FATSPREAD; an = missile->angle >> ANGLETOFINESHIFT; missile->velx = FixedMul (missile->Speed, finecosine[an]); missile->vely = FixedMul (missile->Speed, finesine[an]); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit) { angle_t startangle; AActor *ball; fixed_t cx, cy, cz; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(balltype, 0); if (balltype == NULL) balltype = PClass::FindClass("BridgeBall"); cx = self->x; cy = self->y; cz = self->z; startangle = pr_orbit() << 24; self->special1 = 0; // Spawn triad into world -- may be more than a triad now. int ballcount = self->args[2]==0 ? 3 : self->args[2]; for (int i = 0; i < ballcount; i++) { ball = Spawn(balltype, cx, cy, cz, ALLOW_REPLACE); ball->angle = startangle + (ANGLE_45/32) * (256/ballcount) * i; ball->target = self; CALL_ACTION(A_BridgeOrbit, ball); // [Dusk] bridge balls should not be included in full updates // as the bridge thing will spawn them instead. if (NETWORK_GetState() == NETSTATE_SERVER) ball->ulNetworkFlags |= NETFL_ALLOWCLIENTSPAWN; } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveQuestItem) { ACTION_PARAM_START(1); ACTION_PARAM_INT(questitem, 0); // Give one of these quest items to every player in the game for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i]) { AInventory *item = static_cast<AInventory *>(Spawn (QuestItemClasses[questitem-1], 0,0,0, NO_REPLACE)); if (!item->CallTryPickup (players[i].mo)) { item->Destroy (); } } } char messageid[64]; mysnprintf(messageid, countof(messageid), "TXT_QUEST_%d", questitem); const char * name = GStrings[messageid]; if (name != NULL) { C_MidPrint (SmallFont, name); } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces) { ACTION_PARAM_START(3); ACTION_PARAM_CLASS(p1, 0); ACTION_PARAM_CLASS(p2, 1); ACTION_PARAM_CLASS(p3, 2); for (int i = 0, j = 0, fineang = 0; i < 3; ++i) { const PClass *cls = j==0? p1 : j==1? p2 : p3; if (cls) { AActor *piece = Spawn (cls, self->x, self->y, self->z, ALLOW_REPLACE); if (piece != NULL) { piece->velx = self->velx + finecosine[fineang]; piece->vely = self->vely + finesine[fineang]; piece->velz = self->velz; piece->flags |= MF_DROPPED; fineang += FINEANGLES/3; j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j; } } } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) { angle_t savedangle; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(ti, 0); if (self->player == NULL) return; AWeapon *weapon = self->player->ReadyWeapon; if (weapon != NULL) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return; } if (ti) { savedangle = self->angle; self->angle += pr_electric.Random2 () << (18 - self->player->mo->accuracy * 5 / 100); self->player->mo->PlayAttacking2 (); P_SpawnPlayerMissile (self, ti); self->angle = savedangle; S_Sound (self, CHAN_WEAPON, "weapons/xbowshoot", 1, ATTN_NORM); } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_AlertMonsters) { ACTION_PARAM_START(1); ACTION_PARAM_FIXED(maxdist, 0); ACTION_PARAM_INT(Flags, 1); AActor * target = NULL; AActor * emitter = self; if (self->player != NULL || (Flags & AMF_TARGETEMITTER)) { target = self; } else if (self->target != NULL && (Flags & AMF_TARGETNONPLAYER)) { target = self->target; } else if (self->target != NULL && self->target->player != NULL) { target = self->target; } if (Flags & AMF_EMITFROMTARGET) emitter = target; if (target != NULL && emitter != NULL) { P_NoiseAlert(target, emitter, false, maxdist); } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_FireCGun) { // [BC] Don't do this in client mode. if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) || ( CLIENTDEMO_IsPlaying( ))) { return; } if (self->target == NULL) return; ACTION_PARAM_START(1); ACTION_PARAM_BOOL(accurate, 0); S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM); // [BC] If we're the server, tell clients to play this sound. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SoundActor( self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM ); A_FaceTarget (self); P_GunShot2 (self, accurate, P_AimLineAttack (self, self->angle, MISSILERANGE), PClass::FindClass(NAME_BulletPuff)); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_M_Punch) { ACTION_PARAM_START(1); ACTION_PARAM_INT(mult, 0); MarinePunch(self, mult); }
static const PClass *GetSpawnType(DECLARE_PARAMINFO) { ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul"); return spawntype; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullAttack) { ACTION_PARAM_START(1); ACTION_PARAM_FIXED(n, 0); if (n <= 0) n = SKULLSPEED; A_SkullAttack(self, n); }
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_Light) { ACTION_PARAM_START(1); ACTION_PARAM_INT(light, 0); if (self->player != NULL) { self->player->extralight = clamp<int>(light, -20, 20); } }
DEFINE_ACTION_FUNCTION_PARAMS(AWeapon, A_SetCrosshair) { ACTION_PARAM_START(1); ACTION_PARAM_INT(xhair, 0); if (self->player != NULL && self->player->ReadyWeapon != NULL) { self->player->ReadyWeapon->Crosshair = xhair; } }
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_WeaponReady) { ACTION_PARAM_START(1); ACTION_PARAM_INT(paramflags, 0); DoReadyWeaponToSwitch(self, !(paramflags & WRF_NoSwitch)); if ((paramflags & WRF_NoFire) != WRF_NoFire) DoReadyWeaponToFire(self, !(paramflags & WRF_NoPrimary), !(paramflags & WRF_NoSecondary)); if (!(paramflags & WRF_NoBob)) DoReadyWeaponToBob(self); if ((paramflags & WRF_AllowReload)) DoReadyWeaponToReload(self); if ((paramflags & WRF_AllowZoom)) DoReadyWeaponToZoom(self); DoReadyWeaponDisableSwitch(self, paramflags & WRF_DisableSwitch); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) { ACTION_PARAM_START(7); ACTION_PARAM_SOUND(snd,0); ACTION_PARAM_INT(dmg,1); ACTION_PARAM_INT(blastdmg,2); ACTION_PARAM_INT(blastrad,3); ACTION_PARAM_FIXED(thrust,4); ACTION_PARAM_NAME(dmgtype,5); ACTION_PARAM_INT(flags,6); AActor *fire, *target; angle_t an; if (NULL == (target = self->target)) return; A_FaceTarget (self); if (!P_CheckSight (self, target, 0) ) return; S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM); int newdam; if (flags & VAF_DMGTYPEAPPLYTODIRECT) newdam = P_DamageMobj (target, self, self, dmg, dmgtype); else newdam = P_DamageMobj (target, self, self, dmg, NAME_None); P_TraceBleed (newdam > 0 ? newdam : dmg, target); an = self->angle >> ANGLETOFINESHIFT; fire = self->tracer; if (fire != NULL) { // move the fire between the vile and the player fire->SetOrigin (target->x - FixedMul (24*FRACUNIT, finecosine[an]), target->y - FixedMul (24*FRACUNIT, finesine[an]), target->z); P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0); } if (!(target->flags7 & MF7_DONTTHRUST)) target->velz = Scale(thrust, 1000, target->Mass); }
// // A_PainAttack // Spawn a lost soul and launch it at the target // DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PainAttack) { if (!self->target) return; ACTION_PARAM_START(4); ACTION_PARAM_CLASS(spawntype, 0); ACTION_PARAM_ANGLE(angle, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_INT(limit, 3); if (spawntype == NULL) spawntype = PClass::FindClass("LostSoul"); if (!(flags & PAF_AIMFACING)) A_FaceTarget (self); A_PainShootSkull (self, self->angle+angle, spawntype, flags, limit); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnFly) { FSoundID sound; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); if (spawntype != NULL) { sound = GetDefaultByType(spawntype)->SeeSound; } else { spawntype = PClass::FindClass ("SpawnFire"); sound = "brain/spawn"; } SpawnFly(self, spawntype, sound); }
// // A_VileTarget // Spawn the hellfire // DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget) { ACTION_PARAM_START(1); ACTION_PARAM_CLASS(fire,0); AActor *fog; if (!self->target) return; A_FaceTarget (self); fog = Spawn (fire, self->target->x, self->target->y, self->target->z, ALLOW_REPLACE); self->tracer = fog; fog->target = self; fog->tracer = self->target; A_Fire(fog, 0); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ClearUserPSprite) { ACTION_PARAM_START(1) ACTION_PARAM_INT(layer, 0); player_t *ply = self->player; if(ply == NULL) { return; } if(layer < 1 || layer > 8) { layer = 1; } P_SetPsprite(ply, ps_user1 + (layer - 1), NULL); }
DEFINE_ACTION_FUNCTION_PARAMS(AWeapon, A_ZoomFactor) { ACTION_PARAM_START(2); ACTION_PARAM_FLOAT(zoom, 0); ACTION_PARAM_INT(flags, 1); if (self->player != NULL && self->player->ReadyWeapon != NULL) { zoom = 1 / clamp(zoom, 0.1f, 50.f); if (flags & 1) { // Make the zoom instant. self->player->FOV = self->player->DesiredFOV * zoom; } if (flags & 2) { // Disable pitch/yaw scaling. zoom = -zoom; } self->player->ReadyWeapon->FOVScale = zoom; } }
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash) { ACTION_PARAM_START(2) ACTION_PARAM_STATE(flash, 0); ACTION_PARAM_INT(Flags, 1); player_t *player = self->player; if (NULL == player) { return; } if(!(Flags & GFF_NOEXTCHANGE)) player->mo->PlayAttacking2 (); if (flash == NULL) { if (player->ReadyWeapon->bAltFire) flash = player->ReadyWeapon->FindState(NAME_AltFlash); if (flash == NULL) flash = player->ReadyWeapon->FindState(NAME_Flash); } P_SetPsprite (player, ps_flash, flash); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain) { ACTION_PARAM_START(1); ACTION_PARAM_CLASS(gootype, 0); int count; int chance; AActor *goo; chance = pr_podpain (); if (chance < 128) { return; } for (count = chance > 240 ? 2 : 1; count; count--) { goo = Spawn(gootype, self->x, self->y, self->z + 48*FRACUNIT, ALLOW_REPLACE); goo->target = self; goo->velx = pr_podpain.Random2() << 9; goo->vely = pr_podpain.Random2() << 9; goo->velz = FRACUNIT/2 + (pr_podpain() << 9); } }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw) { angle_t angle; angle_t slope; player_t *player; AActor *linetarget; int actualdamage; ACTION_PARAM_START(11); ACTION_PARAM_SOUND(fullsound, 0); ACTION_PARAM_SOUND(hitsound, 1); ACTION_PARAM_INT(damage, 2); ACTION_PARAM_CLASS(pufftype, 3); ACTION_PARAM_INT(Flags, 4); ACTION_PARAM_FIXED(Range, 5); ACTION_PARAM_ANGLE(Spread_XY, 6); ACTION_PARAM_ANGLE(Spread_Z, 7); ACTION_PARAM_FIXED(LifeSteal, 8); ACTION_PARAM_INT(lifestealmax, 9); ACTION_PARAM_CLASS(armorbonustype, 10); if (NULL == (player = self->player)) { return; } if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff); if (damage == 0) damage = 2; if (!(Flags & SF_NORANDOM)) damage *= (pr_saw()%10+1); // use meleerange + 1 so the puff doesn't skip the flash (i.e. plays all states) if (Range == 0) Range = MELEERANGE+1; angle = self->angle + (pr_saw.Random2() * (Spread_XY / 255)); slope = P_AimLineAttack (self, angle, Range, &linetarget) + (pr_saw.Random2() * (Spread_Z / 255)); AWeapon *weapon = self->player->ReadyWeapon; if ((weapon != NULL) && !(Flags & SF_NOUSEAMMO) && !(!linetarget && (Flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO)) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return; } P_LineAttack (self, angle, Range, slope, damage, NAME_Melee, pufftype, false, &linetarget, &actualdamage); if (!linetarget) { if ((Flags & SF_RANDOMLIGHTMISS) && (pr_saw() > 64)) { player->extralight = !player->extralight; } S_Sound (self, CHAN_WEAPON, fullsound, 1, ATTN_NORM); return; } if (Flags & SF_RANDOMLIGHTHIT) { int randVal = pr_saw(); if (randVal < 64) { player->extralight = 0; } else if (randVal < 160) { player->extralight = 1; } else { player->extralight = 2; } } if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN)) { if (Flags & SF_STEALARMOR) { if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus"); if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus))) { ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE)); armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS; armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax; armorbonus->flags |= MF_DROPPED; armorbonus->ClearCounters(); if (!armorbonus->CallTryPickup (self)) { armorbonus->Destroy (); } } } else {
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) { DSpotState *state = DSpotState::GetSpotState(); AActor *targ; AActor *spit; bool isdefault = false; ACTION_PARAM_START(1); ACTION_PARAM_CLASS(spawntype, 0); // shoot a cube at current target targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain)); if (targ != NULL) { if (spawntype == NULL) { spawntype = PClass::FindClass("SpawnShot"); isdefault = true; } // spawn brain missile spit = P_SpawnMissile (self, targ, spawntype); if (spit != NULL) { // Boss cubes should move freely to their destination so it's // probably best to disable all collision detection for them. if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION; spit->target = targ; spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 // if the target had the same y coordinate as the spitter. if ((spit->velx | spit->vely) == 0) { spit->special2 = 0; } else if (abs(spit->vely) > abs(spit->velx)) { spit->special2 = (targ->y - self->y) / spit->vely; } else { spit->special2 = (targ->x - self->x) / spit->velx; } // [GZ] Calculates when the projectile will have reached destination spit->special2 += level.maptime; spit->flags6 |= MF6_BOSSCUBE; } if (!isdefault) { S_Sound(self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NONE); } else { // compatibility fallback S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE); } } }
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_UserPSprite) { ACTION_PARAM_START(2) ACTION_PARAM_INT(layer, 0); ACTION_PARAM_STATE(pspState, 1); player_t *ply = self->player; if(ply == NULL) { return; } if(layer < 1 || layer > 16) { layer = 1; } if(pspState == NULL) { switch(layer) { // [marrub] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA default: case 1: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP1); break; case 2: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP2); break; case 3: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP3); break; case 4: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP4); break; case 5: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP5); break; case 6: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP6); break; case 7: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP7); break; case 8: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP8); break; case 9: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP9); break; case 10: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP10); break; case 11: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP11); break; case 12: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP12); break; case 13: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP13); break; case 14: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP14); break; case 15: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP15); break; case 16: pspState = ply->ReadyWeapon->FindState(NAME_UserPSP16); break; } } P_SetPsprite(ply, ps_user1 + (layer - 1), pspState); }