mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-17 17:41:23 +00:00
- scriptified ArtiHealingRadius.
- allow switch/case with names. - fixed break jump target handling for switch/case. This only worked when the break was in the outermost compound statement, those in inner ones were missed.
This commit is contained in:
parent
796c262285
commit
69d4d36429
9 changed files with 151 additions and 120 deletions
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
#include "info.h"
|
|
||||||
#include "a_pickups.h"
|
|
||||||
#include "a_artifacts.h"
|
|
||||||
#include "gstrings.h"
|
|
||||||
#include "p_local.h"
|
|
||||||
#include "s_sound.h"
|
|
||||||
#include "m_random.h"
|
|
||||||
#include "a_action.h"
|
|
||||||
#include "a_hexenglobal.h"
|
|
||||||
#include "gi.h"
|
|
||||||
#include "doomstat.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HEAL_RADIUS_DIST 255.
|
|
||||||
|
|
||||||
static FRandom pr_healradius ("HealRadius");
|
|
||||||
|
|
||||||
// Healing Radius Artifact --------------------------------------------------
|
|
||||||
|
|
||||||
class AArtiHealingRadius : public AInventory
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (AArtiHealingRadius, AInventory)
|
|
||||||
public:
|
|
||||||
bool Use (bool pickup);
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(AArtiHealingRadius, false, false)
|
|
||||||
|
|
||||||
bool AArtiHealingRadius::Use (bool pickup)
|
|
||||||
{
|
|
||||||
bool effective = false;
|
|
||||||
FName mode;
|
|
||||||
|
|
||||||
if (Owner->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
|
|
||||||
{
|
|
||||||
mode = static_cast<PClassPlayerPawn *>(Owner->GetClass())->HealingRadiusType;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
|
||||||
{
|
|
||||||
if (playeringame[i] &&
|
|
||||||
players[i].mo != NULL &&
|
|
||||||
players[i].mo->health > 0 &&
|
|
||||||
players[i].mo->Distance2D (Owner) <= HEAL_RADIUS_DIST)
|
|
||||||
{
|
|
||||||
// Q: Is it worth it to make this selectable as a player property?
|
|
||||||
// A: Probably not - but it sure doesn't hurt.
|
|
||||||
bool gotsome=false;
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
case NAME_Armor:
|
|
||||||
for (int j = 0; j < 4; ++j)
|
|
||||||
{
|
|
||||||
AHexenArmor *armor = Spawn<AHexenArmor> ();
|
|
||||||
armor->health = j;
|
|
||||||
armor->Amount = 1;
|
|
||||||
if (!armor->CallTryPickup (players[i].mo))
|
|
||||||
{
|
|
||||||
armor->Destroy ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gotsome = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NAME_Mana:
|
|
||||||
{
|
|
||||||
int amount = 50 + (pr_healradius() % 50);
|
|
||||||
|
|
||||||
if (players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana1)), amount) ||
|
|
||||||
players[i].mo->GiveAmmo (dyn_cast<PClassAmmo>(PClass::FindClass(NAME_Mana2)), amount))
|
|
||||||
{
|
|
||||||
gotsome = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
//case NAME_Health:
|
|
||||||
gotsome = P_GiveBody (players[i].mo, 50 + (pr_healradius()%50));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (gotsome)
|
|
||||||
{
|
|
||||||
S_Sound (players[i].mo, CHAN_AUTO, "MysticIncant", 1, ATTN_NORM);
|
|
||||||
effective=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return effective;
|
|
||||||
|
|
||||||
}
|
|
|
@ -26,7 +26,6 @@
|
||||||
// Include all the Hexen stuff here to reduce compile time
|
// Include all the Hexen stuff here to reduce compile time
|
||||||
#include "a_flechette.cpp"
|
#include "a_flechette.cpp"
|
||||||
#include "a_flies.cpp"
|
#include "a_flies.cpp"
|
||||||
#include "a_healingradius.cpp"
|
|
||||||
#include "a_heresiarch.cpp"
|
#include "a_heresiarch.cpp"
|
||||||
#include "a_hexenspecialdecs.cpp"
|
#include "a_hexenspecialdecs.cpp"
|
||||||
#include "a_iceguy.cpp"
|
#include "a_iceguy.cpp"
|
||||||
|
|
|
@ -1093,7 +1093,6 @@ DEFINE_ACTION_FUNCTION(AActor, GiveInventoryType)
|
||||||
ACTION_RETURN_OBJECT(self->GiveInventoryType(type));
|
ACTION_RETURN_OBJECT(self->GiveInventoryType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: GiveAmmo
|
// AActor :: GiveAmmo
|
||||||
|
@ -1122,6 +1121,14 @@ bool AActor::GiveAmmo (PClassAmmo *type, int amount)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, GiveAmmo)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
PARAM_CLASS(type, AAmmo);
|
||||||
|
PARAM_INT(amount);
|
||||||
|
ACTION_RETURN_BOOL(self->GiveAmmo(type, amount));
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// AActor :: ClearInventory
|
// AActor :: ClearInventory
|
||||||
|
|
|
@ -3175,6 +3175,19 @@ DEFINE_FIELD(APlayerPawn, FlechetteType)
|
||||||
DEFINE_FIELD(APlayerPawn, DamageFade)
|
DEFINE_FIELD(APlayerPawn, DamageFade)
|
||||||
DEFINE_FIELD(APlayerPawn, ViewBob)
|
DEFINE_FIELD(APlayerPawn, ViewBob)
|
||||||
|
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, HealingRadiusType)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, DisplayName)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, SoundClass)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, Face)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, Portrait)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, Slot)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, InvulMode)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, HexenArmor)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, ColorRangeStart)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, ColorRangeEnd)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, ColorSets)
|
||||||
|
DEFINE_FIELD(PClassPlayerPawn, PainFlashes)
|
||||||
|
|
||||||
DEFINE_FIELD_X(PlayerInfo, player_t, mo)
|
DEFINE_FIELD_X(PlayerInfo, player_t, mo)
|
||||||
DEFINE_FIELD_X(PlayerInfo, player_t, playerstate)
|
DEFINE_FIELD_X(PlayerInfo, player_t, playerstate)
|
||||||
DEFINE_FIELD_X(PlayerInfo, player_t, original_oldbuttons)
|
DEFINE_FIELD_X(PlayerInfo, player_t, original_oldbuttons)
|
||||||
|
|
|
@ -8338,7 +8338,7 @@ bool FxCompoundStatement::CheckLocalVariable(FName name)
|
||||||
FxSwitchStatement::FxSwitchStatement(FxExpression *cond, FArgumentList &content, const FScriptPosition &pos)
|
FxSwitchStatement::FxSwitchStatement(FxExpression *cond, FArgumentList &content, const FScriptPosition &pos)
|
||||||
: FxExpression(EFX_SwitchStatement, pos)
|
: FxExpression(EFX_SwitchStatement, pos)
|
||||||
{
|
{
|
||||||
Condition = new FxIntCast(cond, false);
|
Condition = cond;
|
||||||
Content = std::move(content);
|
Content = std::move(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8352,6 +8352,12 @@ FxExpression *FxSwitchStatement::Resolve(FCompileContext &ctx)
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
SAFE_RESOLVE(Condition, ctx);
|
SAFE_RESOLVE(Condition, ctx);
|
||||||
|
|
||||||
|
if (Condition->ValueType != TypeName)
|
||||||
|
{
|
||||||
|
Condition = new FxIntCast(Condition, false);
|
||||||
|
SAFE_RESOLVE(Condition, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (Content.Size() == 0)
|
if (Content.Size() == 0)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_WARNING, "Empty switch statement");
|
ScriptPosition.Message(MSG_WARNING, "Empty switch statement");
|
||||||
|
@ -8370,15 +8376,15 @@ FxExpression *FxSwitchStatement::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto outerctrl = ctx.ControlStmt;
|
||||||
|
ctx.ControlStmt = this;
|
||||||
|
|
||||||
for (auto &line : Content)
|
for (auto &line : Content)
|
||||||
{
|
{
|
||||||
// Do not resolve breaks, they need special treatment inside switch blocks.
|
SAFE_RESOLVE(line, ctx);
|
||||||
if (line->ExprType != EFX_JumpStatement || static_cast<FxJumpStatement *>(line)->Token != TK_Break)
|
line->NeedResult = false;
|
||||||
{
|
|
||||||
SAFE_RESOLVE(line, ctx);
|
|
||||||
line->NeedResult = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ctx.ControlStmt = outerctrl;
|
||||||
|
|
||||||
if (Condition->isConstant())
|
if (Condition->isConstant())
|
||||||
{
|
{
|
||||||
|
@ -8398,6 +8404,12 @@ FxExpression *FxSwitchStatement::Resolve(FCompileContext &ctx)
|
||||||
auto casestmt = static_cast<FxCaseStatement *>(content[i]);
|
auto casestmt = static_cast<FxCaseStatement *>(content[i]);
|
||||||
if (casestmt->Condition == nullptr) defaultindex = i;
|
if (casestmt->Condition == nullptr) defaultindex = i;
|
||||||
else if (casestmt->CaseValue == static_cast<FxConstant *>(Condition)->GetValue().GetInt()) caseindex = i;
|
else if (casestmt->CaseValue == static_cast<FxConstant *>(Condition)->GetValue().GetInt()) caseindex = i;
|
||||||
|
if (casestmt->Condition && casestmt->Condition->ValueType != Condition->ValueType)
|
||||||
|
{
|
||||||
|
casestmt->Condition->ScriptPosition.Message(MSG_ERROR, "Type mismatch in case statement");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (content[i]->ExprType == EFX_JumpStatement && static_cast<FxJumpStatement *>(content[i])->Token == TK_Break)
|
if (content[i]->ExprType == EFX_JumpStatement && static_cast<FxJumpStatement *>(content[i])->Token == TK_Break)
|
||||||
{
|
{
|
||||||
|
@ -8478,7 +8490,6 @@ ExpEmit FxSwitchStatement::Emit(VMFunctionBuilder *build)
|
||||||
ca.jumpaddress = build->Emit(OP_JMP, 0);
|
ca.jumpaddress = build->Emit(OP_JMP, 0);
|
||||||
}
|
}
|
||||||
size_t DefaultAddress = build->Emit(OP_JMP, 0);
|
size_t DefaultAddress = build->Emit(OP_JMP, 0);
|
||||||
TArray<size_t> BreakAddresses;
|
|
||||||
bool defaultset = false;
|
bool defaultset = false;
|
||||||
|
|
||||||
for (auto line : Content)
|
for (auto line : Content)
|
||||||
|
@ -8504,22 +8515,14 @@ ExpEmit FxSwitchStatement::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFX_JumpStatement:
|
|
||||||
if (static_cast<FxJumpStatement *>(line)->Token == TK_Break)
|
|
||||||
{
|
|
||||||
BreakAddresses.Push(build->Emit(OP_JMP, 0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// fall through for continue.
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
line->Emit(build);
|
line->Emit(build);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto addr : BreakAddresses)
|
for (auto addr : Breaks)
|
||||||
{
|
{
|
||||||
build->BackpatchToHere(addr);
|
build->BackpatchToHere(addr->Address);
|
||||||
}
|
}
|
||||||
if (!defaultset) build->BackpatchToHere(DefaultAddress);
|
if (!defaultset) build->BackpatchToHere(DefaultAddress);
|
||||||
Content.DeleteAndClear();
|
Content.DeleteAndClear();
|
||||||
|
@ -8555,7 +8558,7 @@ bool FxSwitchStatement::CheckReturn()
|
||||||
FxCaseStatement::FxCaseStatement(FxExpression *cond, const FScriptPosition &pos)
|
FxCaseStatement::FxCaseStatement(FxExpression *cond, const FScriptPosition &pos)
|
||||||
: FxExpression(EFX_CaseStatement, pos)
|
: FxExpression(EFX_CaseStatement, pos)
|
||||||
{
|
{
|
||||||
Condition = cond? new FxIntCast(cond, false) : nullptr;
|
Condition = cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
FxCaseStatement::~FxCaseStatement()
|
FxCaseStatement::~FxCaseStatement()
|
||||||
|
@ -8576,7 +8579,17 @@ FxExpression *FxCaseStatement::Resolve(FCompileContext &ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
CaseValue = static_cast<FxConstant *>(Condition)->GetValue().GetInt();
|
// Case labels can be ints or names.
|
||||||
|
if (Condition->ValueType != TypeName)
|
||||||
|
{
|
||||||
|
Condition = new FxIntCast(Condition, false);
|
||||||
|
SAFE_RESOLVE(Condition, ctx);
|
||||||
|
CaseValue = static_cast<FxConstant *>(Condition)->GetValue().GetInt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CaseValue = static_cast<FxConstant *>(Condition)->GetValue().GetName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -8747,10 +8760,13 @@ bool FxIfStatement::CheckReturn()
|
||||||
|
|
||||||
FxExpression *FxLoopStatement::Resolve(FCompileContext &ctx)
|
FxExpression *FxLoopStatement::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
|
auto outerctrl = ctx.ControlStmt;
|
||||||
auto outer = ctx.Loop;
|
auto outer = ctx.Loop;
|
||||||
|
ctx.ControlStmt = this;
|
||||||
ctx.Loop = this;
|
ctx.Loop = this;
|
||||||
auto x = DoResolve(ctx);
|
auto x = DoResolve(ctx);
|
||||||
ctx.Loop = outer;
|
ctx.Loop = outer;
|
||||||
|
ctx.ControlStmt = outerctrl;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9074,9 +9090,17 @@ FxExpression *FxJumpStatement::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
|
|
||||||
if (ctx.Loop != nullptr)
|
if (ctx.ControlStmt != nullptr)
|
||||||
{
|
{
|
||||||
ctx.Loop->Jumps.Push(this);
|
if (ctx.ControlStmt == ctx.Loop || Token == TK_Continue)
|
||||||
|
{
|
||||||
|
ctx.Loop->Jumps.Push(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// break in switch.
|
||||||
|
static_cast<FxSwitchStatement*>(ctx.ControlStmt)->Breaks.Push(this);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -72,6 +72,7 @@ typedef TDeletingArray<FxExpression*> FArgumentList;
|
||||||
|
|
||||||
struct FCompileContext
|
struct FCompileContext
|
||||||
{
|
{
|
||||||
|
FxExpression *ControlStmt = nullptr;
|
||||||
FxLoopStatement *Loop = nullptr;
|
FxLoopStatement *Loop = nullptr;
|
||||||
FxCompoundStatement *Block = nullptr;
|
FxCompoundStatement *Block = nullptr;
|
||||||
PPrototype *ReturnProto;
|
PPrototype *ReturnProto;
|
||||||
|
@ -1656,6 +1657,8 @@ class FxSwitchStatement : public FxExpression
|
||||||
TArray<CaseAddr> CaseAddresses;
|
TArray<CaseAddr> CaseAddresses;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TArray<FxJumpStatement *> Breaks;
|
||||||
|
|
||||||
FxSwitchStatement(FxExpression *cond, FArgumentList &content, const FScriptPosition &pos);
|
FxSwitchStatement(FxExpression *cond, FArgumentList &content, const FScriptPosition &pos);
|
||||||
~FxSwitchStatement();
|
~FxSwitchStatement();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
|
@ -357,6 +357,8 @@ class Actor : Thinker native
|
||||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||||
native Inventory FindInventory(class<Inventory> itemtype, bool subclass = false);
|
native Inventory FindInventory(class<Inventory> itemtype, bool subclass = false);
|
||||||
native Inventory GiveInventoryType(class<Inventory> itemtype);
|
native Inventory GiveInventoryType(class<Inventory> itemtype);
|
||||||
|
native bool GiveAmmo (Class<Ammo> type, int amount);
|
||||||
|
|
||||||
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
|
||||||
native double GetDistance(bool checkz, int ptr = AAPTR_TARGET);
|
native double GetDistance(bool checkz, int ptr = AAPTR_TARGET);
|
||||||
native double GetAngle(int flags, int ptr = AAPTR_DEFAULT);
|
native double GetAngle(int flags, int ptr = AAPTR_DEFAULT);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
|
||||||
// Healing Radius Artifact --------------------------------------------------
|
// Healing Radius Artifact --------------------------------------------------
|
||||||
|
|
||||||
class ArtiHealingRadius : Inventory native
|
class ArtiHealingRadius : Inventory
|
||||||
{
|
{
|
||||||
|
const HEAL_RADIUS_DIST = 255.;
|
||||||
|
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
+COUNTITEM
|
+COUNTITEM
|
||||||
|
@ -21,6 +23,70 @@ class ArtiHealingRadius : Inventory native
|
||||||
Spawn:
|
Spawn:
|
||||||
HRAD ABCDEFGHIJKLMNOP 4 Bright;
|
HRAD ABCDEFGHIJKLMNOP 4 Bright;
|
||||||
Loop;
|
Loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
override bool Use (bool pickup)
|
||||||
|
{
|
||||||
|
bool effective = false;
|
||||||
|
Name mode = 'Health';
|
||||||
|
|
||||||
|
PlayerPawn pp = PlayerPawn(Owner);
|
||||||
|
if (pp) mode = pp.HealingRadiusType;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||||
|
{
|
||||||
|
PlayerPawn mo = players[i].mo;
|
||||||
|
if (playeringame[i] && mo != null && mo.health > 0 && mo.Distance2D (Owner) <= HEAL_RADIUS_DIST)
|
||||||
|
{
|
||||||
|
// Q: Is it worth it to make this selectable as a player property?
|
||||||
|
// A: Probably not - but it sure doesn't hurt.
|
||||||
|
bool gotsome=false;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 'Armor':
|
||||||
|
for (int j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
HexenArmor armor = HexenArmor(Spawn("HexenArmor"));
|
||||||
|
armor.health = j;
|
||||||
|
armor.Amount = 1;
|
||||||
|
if (!armor.CallTryPickup (mo))
|
||||||
|
{
|
||||||
|
armor.Destroy ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gotsome = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Mana':
|
||||||
|
{
|
||||||
|
int amount = 50 + (random[HealRadius]() % 50);
|
||||||
|
|
||||||
|
if (mo.GiveAmmo ("Mana1", amount) ||
|
||||||
|
mo.GiveAmmo ("Mana2", amount))
|
||||||
|
{
|
||||||
|
gotsome = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
//case NAME_Health:
|
||||||
|
gotsome = mo.GiveBody (50 + (random[HealRadius]() % 50));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (gotsome)
|
||||||
|
{
|
||||||
|
mo.A_PlaySound ("MysticIncant", CHAN_AUTO);
|
||||||
|
effective=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return effective;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,18 @@ class PlayerPawn : Actor native
|
||||||
native int PlayerFlags;
|
native int PlayerFlags;
|
||||||
native Inventory InvFirst; // first inventory item displayed on inventory bar
|
native Inventory InvFirst; // first inventory item displayed on inventory bar
|
||||||
native Inventory InvSel; // selected inventory item
|
native Inventory InvSel; // selected inventory item
|
||||||
|
native meta String DisplayName; // Display name (used in menus, etc.)
|
||||||
|
native meta String SoundClass; // Sound class
|
||||||
|
native meta String Face; // Doom status bar face (when used)
|
||||||
|
native meta String Portrait;
|
||||||
|
native meta String Slot[10];
|
||||||
|
native meta Name InvulMode;
|
||||||
|
native meta Name HealingRadiusType;
|
||||||
|
native meta double HexenArmor[5];
|
||||||
|
native meta uint8 ColorRangeStart; // Skin color range
|
||||||
|
native meta uint8 ColorRangeEnd;
|
||||||
|
//FPlayerColorSetMap ColorSets;
|
||||||
|
//PainFlashList PainFlashes;
|
||||||
|
|
||||||
// [GRB] Player class properties
|
// [GRB] Player class properties
|
||||||
native double JumpZ;
|
native double JumpZ;
|
||||||
|
|
Loading…
Reference in a new issue