mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 14:01:32 +00:00
09c28e5bf9
ParseActorProperties(). - Fixed: The decorate FindFlag() function returned flags from ActorFlags instead of the passed flags set. - Fixed: The CHT_CHAINSAW, CHT_POWER, CHT_HEALTH, and CHT_RESSURECT needed NULL player->mo checks. - Fixed: The "give all" command didn't give the backpack in Doom, and it must give the backpack before giving ammo. - Fixed: P_SetPsprite() must not call the action function if the player is not attached to an actor. This can happen, for instance, if the level is destroyed while the player is holding a powered-up Phoenix Rod. As part of its EndPowerup() function, it sets the psprite to the regular version, but the player actor has already been destroyed. - Fixed: FinishThingdef() needs to check for valid names, because weapons could have inherited valid pointers from their superclass. - Fixed: fuglyname didn't work. - Fixed: Redefining $ambient sounds leaked memory. - Added Jim's crashcatcher.c fix for better shell support. - VC7.1 seems to have no trouble distinguishing between passing a (const TypeInfo *) reference to operator<< and the generic, templated (object *) version, so a few places that can benefit from it now use it. I believe VC6 had problems with this, which is why I didn't do it all along. The function's implementation was also moved out of dobject.cpp and into farchive.cpp. - Fixed: UnpackPixels() unpacked all chunks in a byte, which is wrong for the last byte in a row if the image width is not an even multiple of the number pixels per byte. - Fixed: P_TranslateLineDef() should only clear monster activation for secret useable lines, not crossable lines. - Fixed: Some leftover P_IsHostile() calls still needed to be rewritten. - Fixed: AWeaponHolder::Serialize() wrote the class type in all circumstances. SVN r20 (trunk)
180 lines
4 KiB
C++
180 lines
4 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);
|
|
arc << FourthWeaponClass << 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;
|
|
}
|