- Added SnowKate709's A_DamageMaster/A_DamageChildren patch.

- Added a SFX_TRANSFERAMBUSHFLAG for A_SpawnItemEx.
- Added "Shaded" as a valid parameter for DECORATE's RenderStyle.
- Added Karate Chris's patch for a MAPINFO option making Strife conversations
  not halt the game.
- Extended the $limit fix that $alias and $random definitions can have their
  own $limit now.
- Fixed: When resolving a linked sound the limit of the current sound was
  ignored and the one of the referenced sound being used. This was particularly
  noticable when using the chaingun in a group of Zombiemen.
- Added a namespc parameter to FWadCollection::CheckNumForFullName which is
  used when a normal lump name has to be looked up and changed all
  CheckNumForFullName/CheckNumForName combinations in the source to use
  the extended version of CheckNumForFullName only to have consistent
  behavior for lump name lookup. 

SVN r865 (trunk)
This commit is contained in:
Christoph Oelckers 2008-03-29 22:59:41 +00:00
parent cd70087ed5
commit d5c3693fd9
18 changed files with 138 additions and 64 deletions

View file

@ -1,3 +1,20 @@
March 29, 2008 (Changes by Graf Zahl)
- Added SnowKate709's A_DamageMaster/A_DamageChildren patch.
- Added a SFX_TRANSFERAMBUSHFLAG for A_SpawnItemEx.
- Added "Shaded" as a valid parameter for DECORATE's RenderStyle.
- Added Karate Chris's patch for a MAPINFO option making Strife conversations
not halt the game.
- Extended the $limit fix that $alias and $random definitions can have their
own $limit now.
- Fixed: When resolving a linked sound the limit of the current sound was
ignored and the one of the referenced sound being used. This was particularly
noticable when using the chaingun in a group of Zombiemen.
- Added a namespc parameter to FWadCollection::CheckNumForFullName which is
used when a normal lump name has to be looked up and changed all
CheckNumForFullName/CheckNumForName combinations in the source to use
the extended version of CheckNumForFullName only to have consistent
behavior for lump name lookup.
March 28, 2008 March 28, 2008
- Moved sound sample rate, buffer size, and buffer count to the - Moved sound sample rate, buffer size, and buffer count to the
advanced sound options menu. Removed opl_enable from the menu. advanced sound options menu. Removed opl_enable from the menu.

View file

@ -108,3 +108,5 @@ ACTOR(DropFire)
ACTOR(ClearTarget) ACTOR(ClearTarget)
ACTOR(LookEx) ACTOR(LookEx)
ACTOR(JumpIfTargetInLOS) ACTOR(JumpIfTargetInLOS)
ACTOR(DamageMaster)
ACTOR(DamageChildren)

View file

@ -310,6 +310,7 @@ static const char *MapInfoMapLevel[] =
"checkswitchrange", "checkswitchrange",
"nocheckswitchrange", "nocheckswitchrange",
"translator", "translator",
"unfreezesingleplayerconversations",
NULL NULL
}; };
@ -460,6 +461,7 @@ MapHandlers[] =
{ MITYPE_SETFLAG, LEVEL_CHECKSWITCHRANGE, 0 }, { MITYPE_SETFLAG, LEVEL_CHECKSWITCHRANGE, 0 },
{ MITYPE_CLRFLAG, LEVEL_CHECKSWITCHRANGE, 0 }, { MITYPE_CLRFLAG, LEVEL_CHECKSWITCHRANGE, 0 },
{ MITYPE_STRING, lioffset(translator), 0 }, { MITYPE_STRING, lioffset(translator), 0 },
{ MITYPE_SETFLAG, LEVEL_CONV_SINGLE_UNFREEZE, 0 },
}; };
static const char *MapInfoClusterLevel[] = static const char *MapInfoClusterLevel[] =

View file

@ -117,6 +117,8 @@
#define LEVEL_FORCETEAMPLAYON UCONST64(0x4000000000000) #define LEVEL_FORCETEAMPLAYON UCONST64(0x4000000000000)
#define LEVEL_FORCETEAMPLAYOFF UCONST64(0x8000000000000) #define LEVEL_FORCETEAMPLAYOFF UCONST64(0x8000000000000)
#define LEVEL_CONV_SINGLE_UNFREEZE UCONST64(0x10000000000000)
struct acsdefered_s; struct acsdefered_s;

View file

@ -137,10 +137,7 @@ void SBarInfo::ParseSBarInfo(int lump)
if(sc.TokenType == TK_Include) if(sc.TokenType == TK_Include)
{ {
sc.MustGetToken(TK_StringConst); sc.MustGetToken(TK_StringConst);
int lump = Wads.CheckNumForFullName(sc.String); //zip/pk3 int lump = Wads.CheckNumForFullName(sc.String, true);
//Do a normal wad lookup.
if (lump == -1 && sc.StringLen <= 8 && !strchr(sc.String, '/'))
lump = Wads.CheckNumForName(sc.String);
if (lump == -1) if (lump == -1)
sc.ScriptError("Lump '%s' not found", sc.String); sc.ScriptError("Lump '%s' not found", sc.String);
ParseSBarInfo(lump); ParseSBarInfo(lump);

View file

@ -639,7 +639,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
int i, j; int i, j;
// [CW] If an NPC is talking to a PC already, then don't let // [CW] If an NPC is talking to a PC already, then don't let
// anyone else talk to NPC. // anyone else talk to the NPC.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i] || pc->player == &players[i]) if (!playeringame[i] || pc->player == &players[i])
@ -826,8 +826,8 @@ static void DrawConversationMenu ()
return; return;
} }
// [CW] Pausing the game in a multiplayer game is a bad idea. // [CW] Freeze the game depending on MAPINFO options.
if (ConversationPauseTic < gametic && !multiplayer) if (ConversationPauseTic < gametic && !multiplayer && !(level.flags & LEVEL_CONV_SINGLE_UNFREEZE))
{ {
menuactive = MENU_On; menuactive = MENU_On;
} }
@ -1037,9 +1037,9 @@ static void PickConversationReply ()
Net_WriteByte (DEM_CONVERSATION); Net_WriteByte (DEM_CONVERSATION);
Net_WriteByte (CONV_NPCANGLE); Net_WriteByte (CONV_NPCANGLE);
// [CW] Set these to NULL because we're not talking to them // [CW] Set these to NULL because we're not using to them
// anymore. However, this can interfere with slideshows so // anymore. However, this can interfere with slideshows
// we don't set them to NULL in that case. // so we don't set them to NULL in that case.
if (gameaction != ga_slideshow) if (gameaction != ga_slideshow)
{ {
Net_WriteByte (DEM_CONVERSATION); Net_WriteByte (DEM_CONVERSATION);

View file

@ -573,8 +573,7 @@ void R_InitSkins (void)
int lump = Wads.CheckNumForName (sc.String, skins[i].namespc); int lump = Wads.CheckNumForName (sc.String, skins[i].namespc);
if (lump == -1) if (lump == -1)
{ {
lump = Wads.CheckNumForFullName (sc.String); lump = Wads.CheckNumForFullName (sc.String, true, ns_sounds);
if (lump == -1) lump = Wads.CheckNumForName (sc.String, ns_sounds);
} }
if (lump != -1) if (lump != -1)
{ {
@ -607,8 +606,7 @@ void R_InitSkins (void)
sndlumps[j] = Wads.CheckNumForName (sc.String, skins[i].namespc); sndlumps[j] = Wads.CheckNumForName (sc.String, skins[i].namespc);
if (sndlumps[j] == -1) if (sndlumps[j] == -1)
{ // Replacement not found, try finding it in the global namespace { // Replacement not found, try finding it in the global namespace
sndlumps[j] = Wads.CheckNumForFullName (sc.String); sndlumps[j] = Wads.CheckNumForFullName (sc.String, true, ns_sounds);
if (sndlumps[j] == -1) sndlumps[j] = Wads.CheckNumForName (sc.String, ns_sounds);
} }
} }
} }

View file

@ -493,8 +493,7 @@ int S_FindSoundTentative (const char *name)
int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc) int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc)
{ {
int lump = Wads.CheckNumForFullName (lumpname); int lump = Wads.CheckNumForFullName (lumpname, true, ns_sounds);
if (lump == -1) lump = Wads.CheckNumForName (lumpname, ns_sounds);
return S_AddSound (logicalname, lump); return S_AddSound (logicalname, lump);
} }
@ -536,6 +535,7 @@ static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc)
sfx->bRandomHeader = false; sfx->bRandomHeader = false;
sfx->link = sfxinfo_t::NO_LINK; sfx->link = sfxinfo_t::NO_LINK;
sfx->bTentative = false; sfx->bTentative = false;
if (sfx->NearLimit < 0) sfx->NearLimit = 2;
//sfx->PitchMask = CurrentPitchMask; //sfx->PitchMask = CurrentPitchMask;
} }
else else
@ -560,7 +560,7 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid,
if (lumpname) if (lumpname)
{ {
lump = Wads.CheckNumForFullName (lumpname); lump = Wads.CheckNumForFullName (lumpname, true, ns_sounds);
if (lump == -1) lump = Wads.CheckNumForName (lumpname, ns_sounds); if (lump == -1) lump = Wads.CheckNumForName (lumpname, ns_sounds);
} }
@ -1104,6 +1104,7 @@ static void S_AddSNDINFO (int lump)
sfxfrom = S_sfx[sfxfrom].link; sfxfrom = S_sfx[sfxfrom].link;
} }
S_sfx[sfxfrom].link = S_FindSoundTentative (sc.String); S_sfx[sfxfrom].link = S_FindSoundTentative (sc.String);
S_sfx[sfxfrom].NearLimit = -1; // Aliases must use the original sound's limit.
} }
break; break;
@ -1233,6 +1234,7 @@ static void S_AddSNDINFO (int lump)
if (list.Size() == 1) if (list.Size() == 1)
{ // Only one sound: treat as $alias { // Only one sound: treat as $alias
S_sfx[random.SfxHead].link = list[0]; S_sfx[random.SfxHead].link = list[0];
S_sfx[random.SfxHead].NearLimit = -1;
} }
else if (list.Size() > 1) else if (list.Size() > 1)
{ // Only add non-empty random lists { // Only add non-empty random lists
@ -1241,6 +1243,7 @@ static void S_AddSNDINFO (int lump)
S_sfx[random.SfxHead].bRandomHeader = true; S_sfx[random.SfxHead].bRandomHeader = true;
S_rnd[S_sfx[random.SfxHead].link].Sounds = new WORD[random.NumSounds]; S_rnd[S_sfx[random.SfxHead].link].Sounds = new WORD[random.NumSounds];
memcpy (S_rnd[S_sfx[random.SfxHead].link].Sounds, &list[0], sizeof(WORD)*random.NumSounds); memcpy (S_rnd[S_sfx[random.SfxHead].link].Sounds, &list[0], sizeof(WORD)*random.NumSounds);
S_sfx[random.SfxHead].NearLimit = -1;
} }
} }
break; break;

View file

@ -95,7 +95,7 @@ extern float S_GetMusicVolume (const char *music);
static fixed_t P_AproxDistance2(fixed_t *listener, fixed_t x, fixed_t y); static fixed_t P_AproxDistance2(fixed_t *listener, fixed_t x, fixed_t y);
static void S_StartSound(fixed_t *pt, AActor *mover, int channel, static void S_StartSound(fixed_t *pt, AActor *mover, int channel,
int sound_id, float volume, float attenuation); int sound_id, float volume, float attenuation);
static bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3]); static bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int NearLimit);
static void S_ActivatePlayList(bool goBack); static void S_ActivatePlayList(bool goBack);
static void CalcPosVel(fixed_t *pt, AActor *mover, int constz, float pos[3], static void CalcPosVel(fixed_t *pt, AActor *mover, int constz, float pos[3],
float vel[3]); float vel[3]);
@ -684,20 +684,27 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel,
if (volume <= 0) if (volume <= 0)
return; return;
// When resolving a link we do not want to get the NearLimit of
// the referenced sound so some additional checks are required
int NearLimit = sfx->NearLimit;
// Resolve player sounds, random sounds, and aliases // Resolve player sounds, random sounds, and aliases
while (sfx->link != sfxinfo_t::NO_LINK) while (sfx->link != sfxinfo_t::NO_LINK)
{ {
if (sfx->bPlayerReserve) if (sfx->bPlayerReserve)
{ {
sound_id = S_FindSkinnedSound (mover, sound_id); sound_id = S_FindSkinnedSound (mover, sound_id);
NearLimit = sfx[sound_id].NearLimit;
} }
else if (sfx->bRandomHeader) else if (sfx->bRandomHeader)
{ {
sound_id = S_PickReplacement (sound_id); sound_id = S_PickReplacement (sound_id);
if (NearLimit < 0) NearLimit = sfx[sound_id].NearLimit;
} }
else else
{ {
sound_id = sfx->link; sound_id = sfx->link;
if (NearLimit < 0) NearLimit = sfx[sound_id].NearLimit;
} }
sfx = &S_sfx[sound_id]; sfx = &S_sfx[sound_id];
} }
@ -708,7 +715,7 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel,
// If this sound doesn't like playing near itself, don't play it if // If this sound doesn't like playing near itself, don't play it if
// that's what would happen. // that's what would happen.
if (sfx->NearLimit && pt != NULL && S_CheckSoundLimit(sfx, pos)) if (NearLimit > 0 && pt != NULL && S_CheckSoundLimit(sfx, pos, NearLimit))
return; return;
// Make sure the sound is loaded. // Make sure the sound is loaded.
@ -935,12 +942,12 @@ bool S_CheckSingular(int sound_id)
// //
//========================================================================== //==========================================================================
bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3]) bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3], int NearLimit)
{ {
FSoundChan *chan; FSoundChan *chan;
int count; int count;
for (chan = Channels, count = 0; chan != NULL && count < sfx->NearLimit; chan = chan->NextChan) for (chan = Channels, count = 0; chan != NULL && count < NearLimit; chan = chan->NextChan)
{ {
if (chan->SfxInfo == sfx) if (chan->SfxInfo == sfx)
{ {
@ -953,7 +960,7 @@ bool S_CheckSoundLimit(sfxinfo_t *sfx, float pos[3])
} }
} }
} }
return count >= sfx->NearLimit; return count >= NearLimit;
} }
//========================================================================== //==========================================================================
@ -1315,13 +1322,10 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
if (!FileExists (musicname)) if (!FileExists (musicname))
{ {
if ((lumpnum = Wads.CheckNumForName (musicname, ns_music)) == -1) if ((lumpnum = Wads.CheckNumForFullName (musicname, true, ns_music)) == -1)
{ {
if ((lumpnum = Wads.CheckNumForFullName (musicname)) == -1) Printf ("Music \"%s\" not found\n", musicname);
{ return false;
Printf ("Music \"%s\" not found\n", musicname);
return false;
}
} }
if (!Wads.IsUncompressedFile(lumpnum)) if (!Wads.IsUncompressedFile(lumpnum))
{ {

View file

@ -164,10 +164,10 @@ FScanner &FScanner::operator=(const FScanner &other)
void FScanner::Open (const char *name) void FScanner::Open (const char *name)
{ {
int lump = Wads.CheckNumForFullName(name); int lump = Wads.CheckNumForFullName(name, true);
if (lump == -1) if (lump == -1)
{ {
lump = Wads.GetNumForName(name); I_Error("Could not find script lump '%s'\n", name);
} }
OpenLumpNum(lump, name); OpenLumpNum(lump, name);
} }

View file

@ -530,8 +530,7 @@ void FTextureManager::LoadHiresTex(int wadnum)
FName texname = sc.String; FName texname = sc.String;
sc.MustGetString(); sc.MustGetString();
int lumpnum = Wads.CheckNumForFullName(sc.String); int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc.String, ns_graphics);
if (tlist.Size() == 0) if (tlist.Size() == 0)
{ {
@ -572,7 +571,7 @@ void FTextureManager::LoadHiresTex(int wadnum)
sc.GetString(); sc.GetString();
memcpy(src, sc.String, 8); memcpy(src, sc.String, 8);
int lumpnum = Wads.CheckNumForFullName(sc.String); int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc.String, ns_graphics); if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc.String, ns_graphics);
sc.GetString(); sc.GetString();

View file

@ -1477,7 +1477,9 @@ enum SIX_Flags
SIXF_ABSOLUTEMOMENTUM=8, SIXF_ABSOLUTEMOMENTUM=8,
SIXF_SETMASTER=16, SIXF_SETMASTER=16,
SIXF_NOCHECKPOSITION=32, SIXF_NOCHECKPOSITION=32,
SIXF_TELEFRAG=64 SIXF_TELEFRAG=64,
// 128 is used by Skulltag!
SIXF_TRANSFERAMBUSHFLAG=256,
}; };
void A_SpawnItemEx(AActor * self) void A_SpawnItemEx(AActor * self)
@ -1547,6 +1549,7 @@ void A_SpawnItemEx(AActor * self)
mo->momz=zmom; mo->momz=zmom;
mo->angle=Angle; mo->angle=Angle;
if (flags & SIXF_TELEFRAG) P_TeleportMove(mo, mo->x, mo->y, mo->z, true); if (flags & SIXF_TELEFRAG) P_TeleportMove(mo, mo->x, mo->y, mo->z, true);
if (flags & SIXF_TRANSFERAMBUSHFLAG) mo->flags = (mo->flags&~MF_AMBUSH) | (self->flags & MF_AMBUSH);
} }
} }
@ -2171,4 +2174,66 @@ void A_JumpIfTargetInLOS(AActor * self)
DoJump(self, CallingState, StateParameters[index]); DoJump(self, CallingState, StateParameters[index]);
} }
//===========================================================================
//
// A_DamageMaster (int amount)
// Damages the master of this child by the specified amount. Negative values heal.
//
//===========================================================================
void A_DamageMaster(AActor * self)
{
int index = CheckIndex(2);
if (index<0) return;
int amount = EvalExpressionI (StateParameters[index], self);
ENamedName DamageType = (ENamedName)StateParameters[index+1];
if (self->master != NULL)
{
if (amount > 0)
{
P_DamageMobj(self->master, self, self, amount, DamageType, DMG_NO_ARMOR);
}
else if (amount < 0)
{
amount = -amount;
P_GiveBody(self->master, amount);
}
}
}
//===========================================================================
//
// A_DamageChildren (amount)
// Damages the children of this master by the specified amount. Negative values heal.
//
//===========================================================================
void A_DamageChildren(AActor * self)
{
TThinkerIterator<AActor> it;
AActor * mo;
int index = CheckIndex(2);
if (index<0) return;
int amount = EvalExpressionI (StateParameters[index], self);
ENamedName DamageType = (ENamedName)StateParameters[index+3];
while ( (mo = it.Next()) )
{
if (mo->master == self)
{
if (amount > 0)
{
P_DamageMobj(mo, self, self, amount, DamageType, DMG_NO_ARMOR);
}
else if (amount < 0)
{
amount = -amount;
P_GiveBody(mo, amount);
}
}
}
}
// [KS] *** End of my modifications *** // [KS] *** End of my modifications ***

View file

@ -66,8 +66,6 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def);
static void ParseDecorate (FScanner &sc) static void ParseDecorate (FScanner &sc)
{ {
int lump;
// Get actor class name. // Get actor class name.
for(;;) for(;;)
{ {
@ -79,26 +77,13 @@ static void ParseDecorate (FScanner &sc)
switch (sc.TokenType) switch (sc.TokenType)
{ {
case TK_Include: case TK_Include:
{
sc.MustGetString(); sc.MustGetString();
// This is not using SC_Open because it can print a more useful error message when done here FScanner newscanner;
lump = Wads.CheckNumForFullName(sc.String); newscanner.Open(sc.String);
ParseDecorate(newscanner);
// Try a normal WAD name lookup only if it's a proper name without path separator and
// not longer than 8 characters.
if (lump == -1 && sc.StringLen <= 8 && !strchr(sc.String, '/'))
{
lump = Wads.CheckNumForName(sc.String);
}
if (lump == -1)
{
sc.ScriptError("Lump '%s' not found", sc.String);
}
else
{
FScanner newscanner(lump, sc.String);
ParseDecorate(newscanner);
}
break; break;
}
case TK_Class: case TK_Class:
ParseClass (sc); ParseClass (sc);

View file

@ -216,17 +216,14 @@ FFont *V_GetFont(const char *name)
if (font == NULL) if (font == NULL)
{ {
int lump = -1; int lump = -1;
FString fullname;
lump = Wads.CheckNumForFullName(name, true);
if (strlen(name) > 8) if (lump < 0 && strlen(name) > 8)
{ {
FString fullname;
fullname.Format("%s.fon", name); fullname.Format("%s.fon", name);
lump = Wads.CheckNumForFullName(fullname); lump = Wads.CheckNumForFullName(fullname);
} }
else
{
lump = Wads.CheckNumForName (name);
}
if (lump != -1) if (lump != -1)
{ {

View file

@ -916,7 +916,7 @@ int FWadCollection::GetNumForName (const char *name, int space)
// //
//========================================================================== //==========================================================================
int FWadCollection::CheckNumForFullName (const char *name, bool trynormal) int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int namespc)
{ {
WORD i; WORD i;
@ -936,7 +936,7 @@ int FWadCollection::CheckNumForFullName (const char *name, bool trynormal)
if (trynormal && strlen(name) <= 8 && !strpbrk(name, "./")) if (trynormal && strlen(name) <= 8 && !strpbrk(name, "./"))
{ {
return CheckNumForName(name, ns_global); return CheckNumForName(name, namespc);
} }
return -1; return -1;
} }

View file

@ -181,7 +181,7 @@ public:
inline int GetNumForName (const BYTE *name) { return GetNumForName ((const char *)name); } inline int GetNumForName (const BYTE *name) { return GetNumForName ((const char *)name); }
inline int GetNumForName (const BYTE *name, int ns) { return GetNumForName ((const char *)name, ns); } inline int GetNumForName (const BYTE *name, int ns) { return GetNumForName ((const char *)name, ns); }
int CheckNumForFullName (const char *name, bool trynormal = false); int CheckNumForFullName (const char *name, bool trynormal = false, int namespc = ns_global);
int CheckNumForFullName (const char *name, int wadfile); int CheckNumForFullName (const char *name, int wadfile);
int GetNumForFullName (const char *name); int GetNumForFullName (const char *name);

View file

@ -13,6 +13,7 @@ const int SXF_ABSOLUTEMOMENTUM=8;
const int SXF_SETMASTER=16; const int SXF_SETMASTER=16;
const int SXF_NOCHECKPOSITION = 32; const int SXF_NOCHECKPOSITION = 32;
const int SXF_TELEFRAG=64; const int SXF_TELEFRAG=64;
const int SXF_TRANSFERAMBUSHFLAG=128;
// Flags for A_Chase // Flags for A_Chase
const int CHF_FASTCHASE = 1; const int CHF_FASTCHASE = 1;

View file

@ -174,6 +174,8 @@ class Actor extends Thinker
action native A_LookEx(optional eval int flags, optional eval float minseedist, optional eval float maxseedist, optional eval float maxheardist, optional eval float fov, optional state label); action native A_LookEx(optional eval int flags, optional eval float minseedist, optional eval float maxseedist, optional eval float maxheardist, optional eval float fov, optional state label);
action native A_ClearTarget(); action native A_ClearTarget();
action native A_JumpIfTargetInLOS (state label, optional eval float fov); action native A_JumpIfTargetInLOS (state label, optional eval float fov);
action native A_DamageMaster(int amount, optional name damagetype);
action native A_DamageChildren(int amount, optional name damagetype);
action native A_SelectWeapon(class<Weapon> whichweapon); action native A_SelectWeapon(class<Weapon> whichweapon);
action native A_Punch(); action native A_Punch();
} }