- added 'defaultterrain' option to terrain parser for mods that want to have

a different default terrain than a generic solid surface.
- added format char processing to A_Print(Bold) and all printable messages
  that can be defined in DECORATE.
- Fixed: The railgun code ignored MF3_ALWAYSPUFF.
- added desaturated translations.
- added optional state parameters to A_ReFire and A_GunFlash and A_CountdownArg.


SVN r1921 (trunk)
This commit is contained in:
Christoph Oelckers 2009-10-16 16:04:19 +00:00
parent 34a4738b74
commit 8b27bd1434
15 changed files with 219 additions and 65 deletions

View file

@ -1,5 +1,14 @@
October 16, 2009 (Changes by Graf Zahl)
- added 'defaultterrain' option to terrain parser for mods that want to have
a different default terrain than a generic solid surface.
- added format char processing to A_Print(Bold) and all printable messages
that can be defined in DECORATE.
- Fixed: The railgun code ignored MF3_ALWAYSPUFF.
- added desaturated translations.
- added optional state parameters to A_ReFire and A_GunFlash and A_CountdownArg.
October 15, 2009 (Changes by Graf Zahl)
- added ACS CheckActprClass function
- added ACS CheckActorClass function
- fixed: When a blasted actor collided with another one this other actor's
DONTBLAST flag was not checked.
- added a global DamageFactor actor property. All damage this actor takes is multiplied

View file

@ -1824,8 +1824,8 @@ CCMD (echo)
int last = argv.argc()-1;
for (int i = 1; i <= last; ++i)
{
strbin (argv[i]);
Printf ("%s%s", argv[i], i!=last ? " " : "\n");
FString formatted = strbin1 (argv[i]);
Printf ("%s%s", formatted.GetChars(), i!=last ? " " : "\n");
}
}

View file

@ -252,7 +252,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LoadShotgun2)
DEFINE_ACTION_FUNCTION(AActor, A_CloseShotgun2)
{
S_Sound (self, CHAN_WEAPON, "weapons/sshotc", 1, ATTN_NORM);
CALL_ACTION(A_ReFire, self);
A_ReFire (self);
}

View file

@ -3767,6 +3767,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
for (i = 0; i < RailHits.Size (); i++)
{
fixed_t x, y, z;
bool spawnpuff;
x = x1 + FixedMul (RailHits[i].Distance, vx);
y = y1 + FixedMul (RailHits[i].Distance, vy);
@ -3775,13 +3776,15 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
if ((RailHits[i].HitActor->flags & MF_NOBLOOD) ||
(RailHits[i].HitActor->flags2 & (MF2_DORMANT|MF2_INVULNERABLE)))
{
if (puffclass != NULL) P_SpawnPuff (source, puffclass, x, y, z, source->angle - ANG90, 1, PF_HITTHING);
spawnpuff = puffclass != NULL;
}
else
{
spawnpuff = (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF);
P_SpawnBlood (x, y, z, source->angle - ANG180, damage, RailHits[i].HitActor);
P_TraceBleed (damage, x, y, z, RailHits[i].HitActor, source->angle, pitch);
}
if (spawnpuff) P_SpawnPuff (source, puffclass, x, y, z, source->angle - ANG90, 1, PF_HITTHING);
P_DamageMobj (RailHits[i].HitActor, thepuff? thepuff:source, source, damage, damagetype, DMG_INFLICTOR_IS_PUFF);
}
@ -3789,6 +3792,11 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
if (trace.HitType == TRACE_HitWall)
{
SpawnShootDecal (source, trace);
if (puffclass != NULL && puffDefaults->flags3 & MF3_ALWAYSPUFF)
{
P_SpawnPuff (source, puffclass, trace.X, trace.Y, trace.Z, source->angle - ANG90, 1, 0);
}
}
if (trace.HitType == TRACE_HitFloor &&
trace.CrossedWater == NULL &&

View file

@ -206,7 +206,7 @@ void P_BringUpWeapon (player_t *player)
//
//---------------------------------------------------------------------------
void P_FireWeapon (player_t *player)
void P_FireWeapon (player_t *player, FState *state)
{
AWeapon *weapon;
@ -225,7 +225,11 @@ void P_FireWeapon (player_t *player)
player->mo->PlayAttacking ();
weapon->bAltFire = false;
P_SetPsprite (player, ps_weapon, weapon->GetAtkState(!!player->refire));
if (state == NULL)
{
state = weapon->GetAtkState(!!player->refire);
}
P_SetPsprite (player, ps_weapon, state);
if (!(weapon->WeaponFlags & WIF_NOALERT))
{
P_NoiseAlert (player->mo, player->mo, false);
@ -238,7 +242,7 @@ void P_FireWeapon (player_t *player)
//
//---------------------------------------------------------------------------
void P_FireWeaponAlt (player_t *player)
void P_FireWeaponAlt (player_t *player, FState *state)
{
AWeapon *weapon;
@ -258,8 +262,12 @@ void P_FireWeaponAlt (player_t *player)
player->mo->PlayAttacking ();
weapon->bAltFire = true;
if (state == NULL)
{
state = weapon->GetAltAtkState(!!player->refire);
}
P_SetPsprite (player, ps_weapon, weapon->GetAltAtkState(!!player->refire));
P_SetPsprite (player, ps_weapon, state);
if (!(weapon->WeaponFlags & WIF_NOALERT))
{
P_NoiseAlert (player->mo, player->mo, false);
@ -456,7 +464,7 @@ void P_CheckWeaponFire (player_t *player)
if (!player->attackdown || !(weapon->WeaponFlags & WIF_NOAUTOFIRE))
{
player->attackdown = true;
P_FireWeapon (player);
P_FireWeapon (player, NULL);
return;
}
}
@ -465,7 +473,7 @@ void P_CheckWeaponFire (player_t *player)
if (!player->attackdown || !(weapon->WeaponFlags & WIF_NOAUTOFIRE))
{
player->attackdown = true;
P_FireWeaponAlt (player);
P_FireWeaponAlt (player, NULL);
return;
}
}
@ -507,7 +515,15 @@ void P_CheckWeaponSwitch (player_t *player)
//
//---------------------------------------------------------------------------
DEFINE_ACTION_FUNCTION(AInventory, A_ReFire)
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_ReFire)
{
ACTION_PARAM_START(1)
ACTION_PARAM_STATE(state, 0);
A_ReFire(self, state);
}
void A_ReFire(AActor *self, FState *state)
{
player_t *player = self->player;
@ -520,14 +536,14 @@ DEFINE_ACTION_FUNCTION(AInventory, A_ReFire)
&& player->PendingWeapon == WP_NOCHANGE && player->health)
{
player->refire++;
P_FireWeapon (player);
P_FireWeapon (player, state);
}
else if ((player->cmd.ucmd.buttons&BT_ALTATTACK)
&& player->ReadyWeapon->bAltFire
&& player->PendingWeapon == WP_NOCHANGE && player->health)
{
player->refire++;
P_FireWeaponAlt (player);
P_FireWeaponAlt (player, state);
}
else
{
@ -661,8 +677,11 @@ DEFINE_ACTION_FUNCTION(AInventory, A_Raise)
//
// A_GunFlash
//
DEFINE_ACTION_FUNCTION(AInventory, A_GunFlash)
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_GunFlash)
{
ACTION_PARAM_START(1)
ACTION_PARAM_STATE(flash, 0);
player_t *player = self->player;
if (NULL == player)
@ -671,9 +690,11 @@ DEFINE_ACTION_FUNCTION(AInventory, A_GunFlash)
}
player->mo->PlayAttacking2 ();
FState * flash=NULL;
if (player->ReadyWeapon->bAltFire) flash = player->ReadyWeapon->FindState(NAME_AltFlash);
if (flash == NULL) flash = player->ReadyWeapon->FindState(NAME_Flash);
if (flash == NULL)
{
if (player->ReadyWeapon->bAltFire) flash = player->ReadyWeapon->FindState(NAME_AltFlash);
if (flash == NULL) flash = player->ReadyWeapon->FindState(NAME_Flash);
}
P_SetPsprite (player, ps_flash, flash);
}

View file

@ -95,6 +95,6 @@ void DoReadyWeaponToFire(AActor * self, bool primary = true, bool secondary = tr
void DoReadyWeaponToSwitch(AActor * self);
DECLARE_ACTION(A_Raise)
DECLARE_ACTION(A_ReFire)
void A_ReFire(AActor *self, FState *state = NULL);
#endif // __P_PSPR_H__

View file

@ -63,7 +63,8 @@ enum EOuterKeywords
OUT_IFHERETIC,
OUT_IFHEXEN,
OUT_IFSTRIFE,
OUT_ENDIF
OUT_ENDIF,
OUT_DEFAULTTERRAIN
};
enum ETerrainKeywords
@ -125,6 +126,7 @@ static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keyw
void *fields, const char *type, FName name);
static void ParseDamage (FScanner &sc, int keyword, void *fields);
static void ParseFriction (FScanner &sc, int keyword, void *fields);
static void ParseDefault (FScanner &sc);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -133,6 +135,7 @@ static void ParseFriction (FScanner &sc, int keyword, void *fields);
FTerrainTypeArray TerrainTypes;
TArray<FSplashDef> Splashes;
TArray<FTerrainDef> Terrains;
WORD DefaultTerrainType;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -146,6 +149,7 @@ static const char *OuterKeywords[] =
"ifhexen",
"ifstrife",
"endif",
"defaultterrain",
NULL
};
@ -222,27 +226,7 @@ static FGenericParse TerrainParser[] =
{ GEN_Bool, {theoffsetof(FTerrainDef, AllowProtection)} },
};
/*
struct
{
char *name;
int type;
bool Heretic;
}
TerrainTypeDefs[] =
{
{ "FLTWAWA1", FLOOR_WATER, true },
{ "FLTFLWW1", FLOOR_WATER, true },
{ "FLTLAVA1", FLOOR_LAVA, true },
{ "FLATHUH1", FLOOR_LAVA, true },
{ "FLTSLUD1", FLOOR_SLUDGE, true },
{ "X_005", FLOOR_WATER, false },
{ "X_001", FLOOR_LAVA, false },
{ "X_009", FLOOR_SLUDGE, false },
{ "F_033", FLOOR_ICE, false },
{ "END", -1 }
};
*/
// CODE --------------------------------------------------------------------
@ -258,9 +242,9 @@ void P_InitTerrainTypes ()
int lump;
int size;
size = (TexMan.NumTextures()+1)*sizeof(BYTE);
size = (TexMan.NumTextures()+1);
TerrainTypes.Resize(size);
memset (&TerrainTypes[0], 0, size);
TerrainTypes.Clear();
MakeDefaultTerrain ();
@ -343,6 +327,10 @@ static void ParseOuter (FScanner &sc)
ParseFloor (sc);
break;
case OUT_DEFAULTTERRAIN:
ParseDefault (sc);
break;
case OUT_IFDOOM:
if (!(gameinfo.gametype & GAME_DoomChex))
{
@ -676,7 +664,27 @@ static void ParseFloor (FScanner &sc)
Printf ("Unknown terrain %s\n", sc.String);
terrain = 0;
}
TerrainTypes[picnum] = terrain;
TerrainTypes.Set(picnum.GetIndex(), terrain);
}
//==========================================================================
//
// ParseFloor
//
//==========================================================================
static void ParseDefault (FScanner &sc)
{
int terrain;
sc.MustGetString ();
terrain = FindTerrain (sc.String);
if (terrain == -1)
{
Printf ("Unknown terrain %s\n", sc.String);
terrain = 0;
}
DefaultTerrainType = terrain;
}
//==========================================================================

View file

@ -39,25 +39,36 @@
struct PClass;
// This is just a wrapper class so that I don't have to expose FTextureID's implementation
// to anything that doesn't really need it.
extern WORD DefaultTerrainType;
class FTerrainTypeArray
{
public:
TArray<BYTE> Types;
TArray<WORD> Types;
BYTE &operator [](FTextureID tex)
WORD operator [](FTextureID tex) const
{
return Types[tex.GetIndex()];
WORD type = Types[tex.GetIndex()];
return type == 0xffff? DefaultTerrainType : type;
}
BYTE &operator [](int texnum)
WORD operator [](int texnum) const
{
return Types[texnum];
WORD type = Types[texnum];
return type == 0xffff? DefaultTerrainType : type;
}
void Resize(unsigned newsize)
{
Types.Resize(newsize);
}
void Clear()
{
memset (&Types[0], 0xff, Types.Size()*sizeof(WORD));
}
void Set(int index, int value)
{
Types[index] = value;
}
};
extern FTerrainTypeArray TerrainTypes;

View file

@ -396,9 +396,48 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in
//
//----------------------------------------------------------------------------
void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2)
{
r1 = clamp(r1, 0.0f, 2.0f);
g1 = clamp(g1, 0.0f, 2.0f);
b1 = clamp(b1, 0.0f, 2.0f);
r2 = clamp(r2, 0.0f, 2.0f);
g2 = clamp(g2, 0.0f, 2.0f);
b2 = clamp(b2, 0.0f, 2.0f);
r2 -= r1;
g2 -= g1;
b2 -= b1;
r1 *= 255;
g1 *= 255;
b1 *= 255;
for(int c=start; c < end; c++)
{
double intensity = (GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37) / 256.0;
PalEntry pe = PalEntry( MIN(255, int(r1 + intensity*r2)),
MIN(255, int(g1 + intensity*g2)),
MIN(255, int(b1 + intensity*b2)));
Remap[c] = ColorMatcher.Pick(pe);
Palette[c] = pe;
Palette[c].a = c==0? 0:255;
}
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
void FRemapTable::AddToTranslation(const char * range)
{
int start,end;
bool desaturated = false;
FScanner sc;
sc.OpenMem("translation", range, int(strlen(range)));
@ -412,7 +451,15 @@ void FRemapTable::AddToTranslation(const char * range)
sc.MustGetToken(TK_IntConst);
end = sc.Number;
sc.MustGetToken('=');
if (!sc.CheckToken('['))
if (start < 0 || start > 255 || end < 0 || end > 255)
{
sc.ScriptError("Palette index out of range");
return;
}
sc.MustGetAnyToken();
if (sc.TokenType != '[' && sc.TokenType != '%')
{
int pal1,pal2;
@ -423,7 +470,7 @@ void FRemapTable::AddToTranslation(const char * range)
pal2 = sc.Number;
AddIndexRange(start, end, pal1, pal2);
}
else
else if (sc.TokenType == '[')
{
// translation using RGB values
int r1,g1,b1,r2,g2,b2;
@ -456,6 +503,46 @@ void FRemapTable::AddToTranslation(const char * range)
AddColorRange(start, end, r1, g1, b1, r2, g2, b2);
}
else if (sc.TokenType == '%')
{
// translation using RGB values
float r1,g1,b1,r2,g2,b2;
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r1 = float(sc.Float);
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g1 = float(sc.Float);
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b1 = float(sc.Float);
sc.MustGetToken(']');
sc.MustGetToken(':');
sc.MustGetToken('[');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
r2 = float(sc.Float);
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
g2 = float(sc.Float);
sc.MustGetToken(',');
sc.MustGetAnyToken();
if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst);
b2 = float(sc.Float);
sc.MustGetToken(']');
AddDesaturation(start, end, r1, g1, b1, r2, g2, b2);
}
}
catch (CRecoverableError &err)
{

View file

@ -38,6 +38,7 @@ struct FRemapTable
void Serialize(FArchive &ar);
void AddIndexRange(int start, int end, int pal1, int pal2);
void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
void AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2);
void AddToTranslation(const char * range);
int StoreTranslation();

View file

@ -1699,7 +1699,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Print)
con_midtime = time;
}
C_MidPrint(font != NULL ? font : SmallFont, text);
FString formatted = strbin1(text);
C_MidPrint(font != NULL ? font : SmallFont, formatted.GetChars());
con_midtime = saved;
}
}
@ -1729,7 +1730,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PrintBold)
con_midtime = time;
}
C_MidPrintBold(font != NULL ? font : SmallFont, text);
FString formatted = strbin1(text);
C_MidPrintBold(font != NULL ? font : SmallFont, formatted.GetChars());
con_midtime = saved;
}
@ -1987,8 +1989,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_KillSiblings)
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
{
ACTION_PARAM_START(1);
ACTION_PARAM_START(2);
ACTION_PARAM_INT(cnt, 0);
ACTION_PARAM_STATE(state, 1);
if (cnt<0 || cnt>=5) return;
if (!self->args[cnt]--)
@ -2003,7 +2006,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CountdownArg)
}
else
{
self->SetState(self->FindState(NAME_Death));
// can't use "Death" as default parameter with current DECORATE parser.
if (state == NULL) state = self->FindState(NAME_Death);
self->SetState(state);
}
}

View file

@ -592,11 +592,15 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau
// fall through
case 'S':
case 'T':
sc.MustGetString();
conv.s = strings[strings.Reserve(1)] = sc.String;
break;
case 'T':
sc.MustGetString();
conv.s = strings[strings.Reserve(1)] = strbin1(sc.String);
break;
case 'C':
if (sc.CheckNumber ())
{

View file

@ -186,7 +186,7 @@ int MatchString (const char *in, const char **strings)
//==========================================================================
//
//==========================================================================
DEFINE_INFO_PROPERTY(game, T, Actor)
DEFINE_INFO_PROPERTY(game, S, Actor)
{
PROP_STRING_PARM(str, 0);
if (!stricmp(str, "Doom"))
@ -1302,7 +1302,7 @@ DEFINE_CLASS_PROPERTY(pickupflash, S, Inventory)
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(pickupmessage, S, Inventory)
DEFINE_CLASS_PROPERTY(pickupmessage, T, Inventory)
{
PROP_STRING_PARM(str, 0);
info->Class->Meta.SetMetaString(AIMETA_PickupMessage, str);
@ -1354,7 +1354,7 @@ DEFINE_CLASS_PROPERTY(givequest, I, Inventory)
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(lowmessage, IS, Health)
DEFINE_CLASS_PROPERTY(lowmessage, IT, Health)
{
PROP_INT_PARM(i, 0);
PROP_STRING_PARM(str, 1);
@ -1383,7 +1383,7 @@ DEFINE_CLASS_PROPERTY(number, I, PuzzleItem)
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY(failmessage, S, PuzzleItem)
DEFINE_CLASS_PROPERTY(failmessage, T, PuzzleItem)
{
PROP_STRING_PARM(str, 0);
info->Class->Meta.SetMetaString(AIMETA_PuzzFailMessage, str);

View file

@ -224,7 +224,7 @@ ACTOR Actor native //: Thinker
action native A_JumpIfInTargetInventory(class<Inventory> itemtype, int amount, state label);
action native A_GiveToTarget(class<Inventory> itemtype, int amount = 0);
action native A_TakeFromTarget(class<Inventory> itemtype, int amount = 0);
action native A_CountdownArg(int argnum);
action native A_CountdownArg(int argnum, state targstate = "");
action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
action native A_Burst(class<Actor> chunktype);

View file

@ -36,10 +36,10 @@ ACTOR Inventory native
action native A_BFGsound();
action native A_FireBFG();
action native A_FireOldBFG();
action native A_ReFire();
action native A_ReFire(state flash = "");
action native A_ClearReFire();
action native A_CheckReload();
action native A_GunFlash();
action native A_GunFlash(state flash = "");
action native A_Saw(sound fullsound = "weapons/sawfull", sound hitsound = "weapons/sawhit", int damage = 2, class<Actor> pufftype = "BulletPuff");
action native A_CheckForReload(int counter, state label, bool dontincrement = false);
action native A_ResetReloadCounter();