mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-08 05:51:09 +00:00
189 lines
4.1 KiB
C++
189 lines
4.1 KiB
C++
|
#include "actor.h"
|
||
|
#include "gi.h"
|
||
|
#include "m_random.h"
|
||
|
#include "s_sound.h"
|
||
|
#include "d_player.h"
|
||
|
#include "a_action.h"
|
||
|
#include "p_local.h"
|
||
|
#include "p_enemy.h"
|
||
|
#include "a_action.h"
|
||
|
#include "p_pspr.h"
|
||
|
#include "gstrings.h"
|
||
|
#include "a_hexenglobal.h"
|
||
|
#include "sbar.h"
|
||
|
|
||
|
IMPLEMENT_POINTY_CLASS (AFourthWeaponPiece)
|
||
|
DECLARE_POINTER (TempFourthWeapon)
|
||
|
END_POINTERS
|
||
|
|
||
|
BEGIN_STATELESS_DEFAULTS (AFourthWeaponPiece, Hexen, -1, 0)
|
||
|
PROP_Inventory_PickupSound ("misc/w_pkup")
|
||
|
END_DEFAULTS
|
||
|
|
||
|
void AFourthWeaponPiece::Serialize (FArchive &arc)
|
||
|
{
|
||
|
Super::Serialize (arc);
|
||
|
if (arc.IsStoring ())
|
||
|
{
|
||
|
arc.UserWriteClass (FourthWeaponClass);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
arc.UserReadClass (FourthWeaponClass);
|
||
|
}
|
||
|
arc << PieceValue << TempFourthWeapon;
|
||
|
}
|
||
|
|
||
|
const char *AFourthWeaponPiece::PickupMessage ()
|
||
|
{
|
||
|
if (TempFourthWeapon != NULL)
|
||
|
{
|
||
|
return TempFourthWeapon->PickupMessage ();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return PieceMessage ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool AFourthWeaponPiece::MatchPlayerClass (AActor *toucher)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
const char *AFourthWeaponPiece::PieceMessage ()
|
||
|
{
|
||
|
return "A weapon piece! This is your lucky day!";
|
||
|
}
|
||
|
|
||
|
void AFourthWeaponPiece::PlayPickupSound (AActor *toucher)
|
||
|
{
|
||
|
if (TempFourthWeapon != NULL)
|
||
|
{
|
||
|
// Play the build-sound full volume for all players
|
||
|
S_Sound (toucher, CHAN_ITEM, "WeaponBuild", 1, ATTN_SURROUND);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Super::PlayPickupSound (toucher);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//==========================================================================
|
||
|
//
|
||
|
// TryPickupWeaponPiece
|
||
|
//
|
||
|
//==========================================================================
|
||
|
|
||
|
bool AFourthWeaponPiece::TryPickup (AActor *toucher)
|
||
|
{
|
||
|
bool shouldStay;
|
||
|
bool checkAssembled;
|
||
|
bool gaveWeapon;
|
||
|
int gaveMana;
|
||
|
|
||
|
checkAssembled = true;
|
||
|
gaveWeapon = false;
|
||
|
gaveMana = 0;
|
||
|
shouldStay = PrivateShouldStay ();
|
||
|
if (!MatchPlayerClass (toucher))
|
||
|
{ // Wrong class, but try to pick up for mana
|
||
|
if (shouldStay)
|
||
|
{ // Can't pick up wrong-class weapons in coop netplay
|
||
|
return false;
|
||
|
}
|
||
|
checkAssembled = false;
|
||
|
gaveMana = toucher->GiveAmmo (RUNTIME_CLASS(AMana1), 20) +
|
||
|
toucher->GiveAmmo (RUNTIME_CLASS(AMana2), 20);
|
||
|
if (!gaveMana)
|
||
|
{ // Didn't need the mana, so don't pick it up
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
else if (shouldStay)
|
||
|
{ // Cooperative net-game
|
||
|
if (toucher->player->pieces & PieceValue)
|
||
|
{ // Already has the piece
|
||
|
return false;
|
||
|
}
|
||
|
toucher->GiveAmmo (RUNTIME_CLASS(AMana1), 20);
|
||
|
toucher->GiveAmmo (RUNTIME_CLASS(AMana2), 20);
|
||
|
}
|
||
|
else
|
||
|
{ // Deathmatch or singleplayer game
|
||
|
gaveMana = toucher->GiveAmmo (RUNTIME_CLASS(AMana1), 20) +
|
||
|
toucher->GiveAmmo (RUNTIME_CLASS(AMana2), 20);
|
||
|
if (toucher->player->pieces & PieceValue)
|
||
|
{ // Already has the piece, check if mana needed
|
||
|
if (!gaveMana)
|
||
|
{ // Didn't need the mana, so don't pick it up
|
||
|
return false;
|
||
|
}
|
||
|
checkAssembled = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check if fourth weapon assembled
|
||
|
if (checkAssembled)
|
||
|
{
|
||
|
toucher->player->pieces |= PieceValue;
|
||
|
for (int i = 0; i < 9; i += 3)
|
||
|
{
|
||
|
int mask = (WPIECE1|WPIECE2|WPIECE3) << i;
|
||
|
|
||
|
if (PieceValue & mask)
|
||
|
{
|
||
|
if (toucher->CheckLocalView (consoleplayer))
|
||
|
{
|
||
|
StatusBar->SetInteger (0, i);
|
||
|
}
|
||
|
if ((toucher->player->pieces & mask) == mask)
|
||
|
{
|
||
|
gaveWeapon = (FourthWeaponClass != NULL);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gaveWeapon)
|
||
|
{
|
||
|
TempFourthWeapon = static_cast<AInventory *>(Spawn (FourthWeaponClass, x, y, z));
|
||
|
if (TempFourthWeapon != NULL)
|
||
|
{
|
||
|
gaveWeapon = TempFourthWeapon->TryPickup (toucher);
|
||
|
if (!gaveWeapon)
|
||
|
{
|
||
|
TempFourthWeapon->GoAwayAndDie ();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gaveWeapon = false;
|
||
|
}
|
||
|
}
|
||
|
if (gaveWeapon || gaveMana || checkAssembled)
|
||
|
{
|
||
|
GoAwayAndDie ();
|
||
|
}
|
||
|
return gaveWeapon || gaveMana || checkAssembled;
|
||
|
}
|
||
|
|
||
|
bool AFourthWeaponPiece::ShouldStay ()
|
||
|
{
|
||
|
return PrivateShouldStay ();
|
||
|
}
|
||
|
|
||
|
bool AFourthWeaponPiece::PrivateShouldStay ()
|
||
|
{
|
||
|
// We want a weapon piece to behave like a weapon, so follow the exact
|
||
|
// same logic as weapons when deciding whether or not to stay.
|
||
|
if (((multiplayer &&
|
||
|
(!deathmatch && !alwaysapplydmflags)) || (dmflags & DF_WEAPONS_STAY)) &&
|
||
|
!(flags & MF_DROPPED))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|