- scriptified the rest of the weapon pieces.

This commit is contained in:
Christoph Oelckers 2017-01-18 18:46:24 +01:00
parent 30a8541a15
commit 1ce7b80158
12 changed files with 66 additions and 176 deletions

View file

@ -1148,7 +1148,6 @@ set (PCH_SOURCES
g_inventory/a_armor.cpp g_inventory/a_armor.cpp
g_inventory/a_keys.cpp g_inventory/a_keys.cpp
g_inventory/a_pickups.cpp g_inventory/a_pickups.cpp
g_inventory/a_weaponpiece.cpp
g_inventory/a_weapons.cpp g_inventory/a_weapons.cpp
g_strife/strife_sbar.cpp g_strife/strife_sbar.cpp
g_shared/a_action.cpp g_shared/a_action.cpp

View file

@ -571,7 +571,7 @@ DEFINE_ACTION_FUNCTION(DObject, GetClassName)
void *DObject::ScriptVar(FName field, PType *type) void *DObject::ScriptVar(FName field, PType *type)
{ {
auto sym = dyn_cast<PField>(GetClass()->Symbols.FindSymbol(field, true)); auto sym = dyn_cast<PField>(GetClass()->Symbols.FindSymbol(field, true));
if (sym && sym->Type == type) if (sym && (sym->Type == type || type == nullptr))
{ {
return (((char*)this) + sym->Offset); return (((char*)this) + sym->Offset);
} }

View file

@ -482,6 +482,7 @@ public:
PalEntry &ColorVar(FName field); PalEntry &ColorVar(FName field);
FName &NameVar(FName field); FName &NameVar(FName field);
double &FloatVar(FName field); double &FloatVar(FName field);
template<class T> T*& PointerVar(FName field);
// If you need to replace one object with another and want to // If you need to replace one object with another and want to
// change any pointers from the old object to the new object, // change any pointers from the old object to the new object,

View file

@ -45,7 +45,6 @@
#include "autosegs.h" #include "autosegs.h"
#include "v_text.h" #include "v_text.h"
#include "a_pickups.h" #include "a_pickups.h"
#include "a_weaponpiece.h"
#include "d_player.h" #include "d_player.h"
#include "doomerrors.h" #include "doomerrors.h"
#include "fragglescript/t_fs.h" #include "fragglescript/t_fs.h"

View file

@ -1093,5 +1093,9 @@ inline double &DObject::FloatVar(FName field)
return *(double*)ScriptVar(field, TypeFloat64); return *(double*)ScriptVar(field, TypeFloat64);
} }
template<class T>
inline T *&DObject::PointerVar(FName field)
{
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
}
#endif #endif

View file

@ -1,83 +0,0 @@
/*
** a_weaponpieces.cpp
** Implements generic weapon pieces
**
**---------------------------------------------------------------------------
** Copyright 2006-2016 Cheistoph Oelckers
** Copyright 2006-2016 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "a_pickups.h"
#include "a_weaponpiece.h"
#include "doomstat.h"
#include "serializer.h"
IMPLEMENT_CLASS(AWeaponHolder, false, false)
DEFINE_FIELD(AWeaponHolder, PieceMask);
DEFINE_FIELD(AWeaponHolder, PieceWeapon);
//===========================================================================
//
//
//
//===========================================================================
void AWeaponHolder::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc("piecemask", PieceMask)
("pieceweapon", PieceWeapon);
}
IMPLEMENT_CLASS(AWeaponPiece, false, true)
IMPLEMENT_POINTERS_START(AWeaponPiece)
IMPLEMENT_POINTER(FullWeapon)
IMPLEMENT_POINTER(WeaponClass)
IMPLEMENT_POINTERS_END
//===========================================================================
//
//
//
//===========================================================================
void AWeaponPiece::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
auto def = (AWeaponPiece*)GetDefault();
arc("weaponclass", WeaponClass, def->WeaponClass)
("fullweapon", FullWeapon)
("piecevalue", PieceValue, def->PieceValue);
}
DEFINE_FIELD(AWeaponPiece, PieceValue);
DEFINE_FIELD(AWeaponPiece, WeaponClass);
DEFINE_FIELD(AWeaponPiece, FullWeapon);

View file

@ -1,32 +0,0 @@
#pragma once
#include "a_pickups.h"
#include "a_weapons.h"
class AWeaponPiece : public AInventory
{
DECLARE_CLASS (AWeaponPiece, AInventory)
HAS_OBJECT_POINTERS
protected:
bool PrivateShouldStay ();
public:
virtual void Serialize(FSerializer &arc) override;
int PieceValue;
PClassActor *WeaponClass;
TObjPtr<AWeapon> FullWeapon;
};
// an internal class to hold the information for player class independent weapon piece handling
// [BL] Needs to be available for SBarInfo to check weaponpieces
class AWeaponHolder : public AInventory
{
DECLARE_CLASS (AWeaponHolder, AInventory)
public:
int PieceMask;
PClassActor * PieceWeapon;
virtual void Serialize(FSerializer &arc) override;
};

View file

@ -51,7 +51,6 @@
#include "sbarinfo.h" #include "sbarinfo.h"
#include "gi.h" #include "gi.h"
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "a_weaponpiece.h"
#include "g_level.h" #include "g_level.h"
#include "v_palette.h" #include "v_palette.h"
#include "p_acs.h" #include "p_acs.h"

View file

@ -3145,12 +3145,12 @@ class CommandHasWeaponPiece : public SBarInfoCommandFlowControl
for(AInventory *inv = statusBar->CPlayer->mo->Inventory;inv != NULL;inv=inv->Inventory) for(AInventory *inv = statusBar->CPlayer->mo->Inventory;inv != NULL;inv=inv->Inventory)
{ {
if(inv->IsKindOf(RUNTIME_CLASS(AWeaponHolder))) auto hc = PClass::FindActor("WeaponHolder");
if(inv->IsKindOf(hc))
{ {
AWeaponHolder *hold = static_cast<AWeaponHolder*>(inv); if(inv->PointerVar<PClass>("PieceWeapon") == weapon)
if(hold->PieceWeapon == weapon)
{ {
SetTruth(0 != (hold->PieceMask & (1 << (piece-1))), block, statusBar); SetTruth(0 != (inv->IntVar("PieceMask") & (1 << (piece-1))), block, statusBar);
return; return;
} }
} }

View file

@ -56,7 +56,7 @@
#include "m_argv.h" #include "m_argv.h"
#include "p_local.h" #include "p_local.h"
#include "doomerrors.h" #include "doomerrors.h"
#include "a_weaponpiece.h" #include "a_weapons.h"
#include "p_conversation.h" #include "p_conversation.h"
#include "v_text.h" #include "v_text.h"
#include "thingdef.h" #include "thingdef.h"

View file

@ -67,7 +67,6 @@
#include "teaminfo.h" #include "teaminfo.h"
#include "v_video.h" #include "v_video.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "a_weaponpiece.h"
#include "vmbuilder.h" #include "vmbuilder.h"
#include "a_keys.h" #include "a_keys.h"
#include "g_levellocals.h" #include "g_levellocals.h"
@ -464,23 +463,6 @@ static bool PointerCheck(PType *symtype, PType *checktype)
return symptype != nullptr && checkptype != nullptr && symptype->ClassRestriction->IsDescendantOf(checkptype->ClassRestriction); return symptype != nullptr && checkptype != nullptr && symptype->ClassRestriction->IsDescendantOf(checkptype->ClassRestriction);
} }
static void *ScriptVar(DObject *obj, PClass *cls, FName field, PType *type)
{
auto sym = dyn_cast<PField>(cls->Symbols.FindSymbol(field, true));
if (sym && (sym->Type == type || PointerCheck(sym->Type, type)))
{
return (((char*)obj) + sym->Offset);
}
I_Error("Variable %s of type %s not found in %s\n", field.GetChars(), type->DescriptiveName(), cls->TypeName.GetChars());
return nullptr;
}
template<class T>
T &TypedScriptVar(DObject *obj, PClass *cls, FName field, PType *type)
{
return *(T*)ScriptVar(obj, cls, field, type);
}
//========================================================================== //==========================================================================
// //
// Info Property handlers // Info Property handlers
@ -2223,24 +2205,6 @@ DEFINE_CLASS_PROPERTY(preferredskin, S, Weapon)
// NoOp - only for Skulltag compatibility // NoOp - only for Skulltag compatibility
} }
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(number, I, WeaponPiece)
{
PROP_INT_PARM(i, 0);
defaults->PieceValue = 1 << (i-1);
}
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece)
{
PROP_STRING_PARM(str, 0);
defaults->WeaponClass = FindClassTentativeWeapon(str);
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================
@ -2401,7 +2365,7 @@ DEFINE_SCRIPTED_PROPERTY_PREFIX(powerup, type, S, PowerupGiver)
I_Error("Unknown powerup type %s", str); I_Error("Unknown powerup type %s", str);
} }
} }
TypedScriptVar<PClassActor*>(defaults, info, NAME_PowerupType, NewClassPointer(RUNTIME_CLASS(AActor))) = cls; defaults->PointerVar<PClassActor>(NAME_PowerupType) = cls;
} }
//========================================================================== //==========================================================================
@ -2990,7 +2954,7 @@ DEFINE_CLASS_PROPERTY(unmorphflash, S, MorphProjectile)
DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph) DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph)
{ {
PROP_STRING_PARM(str, 0); PROP_STRING_PARM(str, 0);
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_PlayerClass, NewClassPointer(RUNTIME_CLASS(APlayerPawn))) = FindClassTentativePlayerPawn(str, bag.fromDecorate); defaults->PointerVar<PClassActor>(NAME_PlayerClass) = FindClassTentativePlayerPawn(str, bag.fromDecorate);
} }
//========================================================================== //==========================================================================
@ -2999,7 +2963,7 @@ DEFINE_SCRIPTED_PROPERTY(playerclass, S, PowerMorph)
DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph) DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph)
{ {
PROP_INT_PARM(i, 0); PROP_INT_PARM(i, 0);
TypedScriptVar<int>(defaults, bag.Info, NAME_MorphStyle, TypeSInt32) = i; defaults->IntVar(NAME_MorphStyle) = i;
} }
//========================================================================== //==========================================================================
@ -3008,7 +2972,7 @@ DEFINE_SCRIPTED_PROPERTY(morphstyle, M, PowerMorph)
DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph) DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph)
{ {
PROP_STRING_PARM(str, 0); PROP_STRING_PARM(str, 0);
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_MorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); defaults->PointerVar<PClassActor>(NAME_MorphFlash) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
} }
//========================================================================== //==========================================================================
@ -3017,7 +2981,7 @@ DEFINE_SCRIPTED_PROPERTY(morphflash, S, PowerMorph)
DEFINE_SCRIPTED_PROPERTY(unmorphflash, S, PowerMorph) DEFINE_SCRIPTED_PROPERTY(unmorphflash, S, PowerMorph)
{ {
PROP_STRING_PARM(str, 0); PROP_STRING_PARM(str, 0);
TypedScriptVar<PClassActor*>(defaults, bag.Info, NAME_UnMorphFlash, NewClassPointer(RUNTIME_CLASS(AActor))) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate); defaults->PointerVar<PClassActor>(NAME_UnMorphFlash) = FindClassTentative(str, RUNTIME_CLASS(AActor), bag.fromDecorate);
} }

View file

@ -1,7 +1,42 @@
class WeaponHolder : Inventory native /*
** a_weaponpieces.cpp
** Implements generic weapon pieces
**
**---------------------------------------------------------------------------
** Copyright 2006-2016 Cheistoph Oelckers
** Copyright 2006-2016 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
class WeaponHolder : Inventory
{ {
native int PieceMask; int PieceMask;
native Class<Actor> PieceWeapon; Class<Weapon> PieceWeapon;
Default Default
{ {
@ -11,16 +46,19 @@ class WeaponHolder : Inventory native
} }
} }
class WeaponPiece : Inventory native class WeaponPiece : Inventory
{ {
Default Default
{ {
+WEAPONSPAWN; +WEAPONSPAWN;
} }
native int PieceValue; int PieceValue;
native Class<Weapon> WeaponClass; Class<Weapon> WeaponClass;
native Weapon FullWeapon; Weapon FullWeapon;
property number: PieceValue;
property weapon: WeaponClass;
//========================================================================== //==========================================================================
// //
@ -84,10 +122,11 @@ class WeaponPiece : Inventory native
hold.PieceWeapon = WeaponClass; hold.PieceWeapon = WeaponClass;
} }
int pieceval = 1 << (PieceValue - 1);
if (shouldStay) if (shouldStay)
{ {
// Cooperative net-game // Cooperative net-game
if (hold.PieceMask & PieceValue) if (hold.PieceMask & pieceval)
{ {
// Already has the piece // Already has the piece
return false; return false;
@ -100,7 +139,7 @@ class WeaponPiece : Inventory native
gaveAmmo = toucher.GiveAmmo (Defaults.AmmoType1, Defaults.AmmoGive1) + gaveAmmo = toucher.GiveAmmo (Defaults.AmmoType1, Defaults.AmmoGive1) +
toucher.GiveAmmo (Defaults.AmmoType2, Defaults.AmmoGive2); toucher.GiveAmmo (Defaults.AmmoType2, Defaults.AmmoGive2);
if (hold.PieceMask & PieceValue) if (hold.PieceMask & pieceval)
{ {
// Already has the piece, check if mana needed // Already has the piece, check if mana needed
if (!gaveAmmo) return false; if (!gaveAmmo) return false;
@ -109,7 +148,7 @@ class WeaponPiece : Inventory native
} }
} }
hold.PieceMask |= PieceValue; hold.PieceMask |= pieceval;
// Check if weapon assembled // Check if weapon assembled
if (hold.PieceMask == (1 << Defaults.health) - 1) if (hold.PieceMask == (1 << Defaults.health) - 1)