DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireArrow) { PARAM_ACTION_PROLOGUE; PARAM_CLASS(ti, AActor); angle_t savedangle; if (self->player == NULL) return 0; AWeapon *weapon = self->player->ReadyWeapon; if (weapon != NULL) { if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; } 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); } return 0; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnSingleItem) { PARAM_ACTION_PROLOGUE; PARAM_CLASS (cls, AActor); PARAM_INT_OPT (fail_sp) { fail_sp = 0; } PARAM_INT_OPT (fail_co) { fail_co = 0; } PARAM_INT_OPT (fail_dm) { fail_dm = 0; } AActor *spot = NULL; DSpotState *state = DSpotState::GetSpotState(); if (state != NULL) spot = state->GetRandomSpot(self->GetClass(), true); if (spot == NULL) return 0; if (!multiplayer && pr_spawnmace() < fail_sp) { // Sometimes doesn't show up if not in deathmatch return 0; } if (multiplayer && !deathmatch && pr_spawnmace() < fail_co) { return 0; } if (deathmatch && pr_spawnmace() < fail_dm) { return 0; } if (cls == NULL) { return 0; } AActor *spawned = Spawn(cls, self->Pos(), ALLOW_REPLACE); if (spawned) { spawned->SetOrigin (spot->Pos(), false); spawned->SetZ(spawned->floorz); // We want this to respawn. if (!(self->flags & MF_DROPPED)) { spawned->flags &= ~MF_DROPPED; } if (spawned->IsKindOf(RUNTIME_CLASS(AInventory))) { static_cast<AInventory*>(spawned)->SpawnPointClass = self->GetClass(); } } return 0; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DropWeaponPieces) { PARAM_SELF_PROLOGUE(AActor); PARAM_CLASS(p1, AActor); PARAM_CLASS(p2, AActor); PARAM_CLASS(p3, AActor); for (int i = 0, j = 0; i < 3; ++i) { PClassActor *cls = j == 0 ? p1 : j == 1 ? p2 : p3; if (cls) { AActor *piece = Spawn (cls, self->Pos(), ALLOW_REPLACE); if (piece != NULL) { piece->Vel = self->Vel + DAngle(i*120.).ToVector(1); piece->flags |= MF_DROPPED; j = (j == 0) ? (pr_quietusdrop() & 1) + 1 : 3-j; } } } return 0; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade) { PARAM_ACTION_PROLOGUE; PARAM_CLASS(grenadetype, AActor); PARAM_ANGLE(angleofs); PARAM_STATE(flash) player_t *player = self->player; AActor *grenade; DAngle an; AWeapon *weapon; if (player == nullptr || grenadetype == nullptr) return 0; if ((weapon = player->ReadyWeapon) == nullptr) return 0; if (!weapon->DepleteAmmo (weapon->bAltFire)) return 0; P_SetPsprite (player, PSP_FLASH, flash, true); if (grenadetype != nullptr) { self->AddZ(32); grenade = P_SpawnSubMissile (self, grenadetype, self); self->AddZ(-32); if (grenade == nullptr) return 0; if (grenade->SeeSound != 0) { S_Sound (grenade, CHAN_VOICE, grenade->SeeSound, 1, ATTN_NORM); } grenade->Vel.Z = (-self->Angles.Pitch.TanClamped()) * grenade->Speed + 8; DVector2 offset = self->Angles.Yaw.ToVector(self->radius + grenade->radius); DAngle an = self->Angles.Yaw + angleofs; offset += an.ToVector(15); grenade->SetOrigin(grenade->Vec3Offset(offset.X, offset.Y, 0.), false); } return 0; }