Update to ZDoom r1669:

- added a compatibility option to restore the original Heretic bug where
  a Minotaur couldn't spawn floor flames when standing in water having its
  feet clipped.
- added vid_vsync to display options.
- fixed: Animations of type 'Range' must be disabled if the textures don't
  come from the same definition unit (i.e both containing file and use type
  are identical.)
- changed: Item pushing is now only done once per P_XYMovement call.
- Increased the push factor of Heretic's pod to 0.5 so that its behavior
  more closely matches the original which depended on several bugs in the engine.
- Removed damage thrust clamping in P_DamageMobj and changed the thrust calculation
  to use floats to prevent overflows. The prevention of the overflows was the
  only reason the clamping was done.
- Added Raven's dagger-like vector sprite for the player to the automap code.
- Changed wad namespacing so that wads with a missing end marker will be
  loaded as if they had one more lump with that end marker. This matches the
  behaviour of previously released ZDooms. (The warning is still present, so
  there's no excuse to release more wads like this.)
- Moved Raw Input processing into a seperate method of FInputDevice so that
  all the devices can share the same setup code.
- Removed F16 mapping for SDL, because I guess it's not present in SDL 1.2.
- Added Gez's Skulltag feature patch, including:
    * BUMPSPECIAL flag: actors with this flag will run their special if collided on by a player
    * WEAPON.NOAUTOAIM flag, though it is restricted to attacks that spawn a missile (it will 
	  not affect autoaim settings for a hitscan or railgun, and that's deliberate)
    * A_FireSTGrenade codepointer, extended to be parameterizable
    * The grenade (as the default actor for A_FireSTGrenade)
    * Protective armors à la RedArmor: they work with a DamageFactor; for example to 
	  recreate the RedArmor from Skulltag, copy its code from skulltag.pk3 but remove 
	  the "native" keyword and add DamageFactor "Fire" 0.1 to its properties.
- Fixed: I_ShutdownInput must NULL all pointers because it can be called twice
  if an ENDOOM screen is displayed.
- Fixed: R_DrawSkyStriped used frontyScale without initializing it first.
- Fixed: P_LineAttack may not check the puff actor for MF6_FORCEPAIN because
  it's not necessarily spawned yet. 
- Fixed: FWeaponSlots::PickNext/PrevWeapon must be limited to one iteration
  through the weapon slots. Otherwise they will hang if there's no weapons
  in a player's inventory.
- Added Line_SetTextureScale.
- Fixed: sv_smartaim 3 treated the player like a shootable decoration.
- Added A_CheckIfInTargetLOS
- Removed redundant A_CheckIfTargetInSight.
- Fixed: The initial play of a GME song always started track 0.
- Fixed: The RAWINPUT buffer that GetRawInputData() fills in is 40 bytes on
  Win32 but 48 bytes on Win64, so Raw Mouse on x64 builds was getting random
  data off the stack because I also interpreted the error return incorrectly.
- added parameter to A_FadeOut so that removing the actor can be made an option.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@344 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-06-14 18:05:00 +00:00
parent 63e67d4a29
commit 169965ea9f
43 changed files with 672 additions and 277 deletions

View file

@ -1,4 +1,61 @@
June 7, 2009 (Changes by Graf Zahl)
June 14, 2009 (Changes by Graf Zahl)
- added a compatibility option to restore the original Heretic bug where
a Minotaur couldn't spawn floor flames when standing in water having its
feet clipped.
- added vid_vsync to display options.
- fixed: Animations of type 'Range' must be disabled if the textures don't
come from the same definition unit (i.e both containing file and use type
are identical.)
- changed: Item pushing is now only done once per P_XYMovement call.
- Increased the push factor of Heretic's pod to 0.5 so that its behavior
more closely matches the original which depended on several bugs in the engine.
- Removed damage thrust clamping in P_DamageMobj and changed the thrust calculation
to use floats to prevent overflows. The prevention of the overflows was the
only reason the clamping was done.
- Added Raven's dagger-like vector sprite for the player to the automap code.
June 10, 2009
- Changed wad namespacing so that wads with a missing end marker will be
loaded as if they had one more lump with that end marker. This matches the
behaviour of previously released ZDooms. (The warning is still present, so
there's no excuse to release more wads like this.)
- Moved Raw Input processing into a seperate method of FInputDevice so that
all the devices can share the same setup code.
June 9, 2009
- Removed F16 mapping for SDL, because I guess it's not present in SDL 1.2.
June 9, 2009 (Changes by Graf Zahl)
- Added Gez's Skulltag feature patch, including:
* BUMPSPECIAL flag: actors with this flag will run their special if collided on by a player
* WEAPON.NOAUTOAIM flag, though it is restricted to attacks that spawn a missile (it will
not affect autoaim settings for a hitscan or railgun, and that's deliberate)
* A_FireSTGrenade codepointer, extended to be parameterizable
* The grenade (as the default actor for A_FireSTGrenade)
* Protective armors à la RedArmor: they work with a DamageFactor; for example to
recreate the RedArmor from Skulltag, copy its code from skulltag.pk3 but remove
the "native" keyword and add DamageFactor "Fire" 0.1 to its properties.
- Fixed: I_ShutdownInput must NULL all pointers because it can be called twice
if an ENDOOM screen is displayed.
- Fixed: R_DrawSkyStriped used frontyScale without initializing it first.
- Fixed: P_LineAttack may not check the puff actor for MF6_FORCEPAIN because
it's not necessarily spawned yet.
- Fixed: FWeaponSlots::PickNext/PrevWeapon must be limited to one iteration
through the weapon slots. Otherwise they will hang if there's no weapons
in a player's inventory.
- Added Line_SetTextureScale.
- Fixed: sv_smartaim 3 treated the player like a shootable decoration.
- Added A_CheckIfInTargetLOS
- Removed redundant A_CheckIfTargetInSight.
June 8, 2009
- Fixed: The initial play of a GME song always started track 0.
- Fixed: The RAWINPUT buffer that GetRawInputData() fills in is 40 bytes on
Win32 but 48 bytes on Win64, so Raw Mouse on x64 builds was getting random
data off the stack because I also interpreted the error return incorrectly.
June 7, 2009 (Changes by Graf Zahl)
- added parameter to A_FadeOut so that removing the actor can be made an option.
- added PERSISTENTPOWER and TRANSFERPOINTERS submissions by Gez.
- fixed FORCEPAIN logic.
- added Gez's infinite ammo powerup and random spawner fix patches.

View file

@ -310,6 +310,7 @@ enum
MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species.
MF6_FORCEPAIN = 0x00000008, // forces target into painstate (unless it has the NOPAIN flag)
MF6_NOFEAR = 0x00000010, // Not scared of frightening players
MF6_BUMPSPECIAL = 0x00000020, // Actor executes its special when being collided (as the ST flag)
// --- mobj.renderflags ---
@ -740,6 +741,7 @@ public:
fixed_t gravity; // [GRB] Gravity factor
int FastChaseStrafeCount;
fixed_t pushfactor;
int lastpush;
AActor *BlockingMobj; // Actor that blocked the last move
line_t *BlockingLine; // Line that blocked the last move

View file

@ -35,6 +35,7 @@
#include "statnums.h"
#include "r_translate.h"
#include "d_event.h"
#include "gi.h"
#include "m_cheat.h"
#include "i_system.h"
@ -251,8 +252,23 @@ mline_t player_arrow[] = {
{ { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
{ { -R+3*R/8, 0 }, { -R+R/8, -R/4 } }
};
mline_t player_arrow_raven[] = {
{ { -R+R/4, 0 }, { 0, 0} }, // center line.
{ { -R+R/4, R/8 }, { R, 0} }, // blade
{ { -R+R/4, -R/8 }, { R, 0 } },
{ { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece
{ { -R+R/8, -R/4 }, { -R+R/8, R/4 } },
{ { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors
{ { -R+R/8, R/4 }, { -R+R/4, R/4} },
{ { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel
{ { -R-R/4, R/8 }, { -R+R/8, R/8 } },
{ { -R-R/4, -R/8}, { -R+R/8, -R/8 } }
};
#undef R
#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
#define NUMPLYRLINES_RAVEN (sizeof(player_arrow_raven)/sizeof(mline_t))
#define R ((8*PLAYERRADIUS)/7)
mline_t cheat_player_arrow[] = {
@ -273,6 +289,7 @@ mline_t cheat_player_arrow[] = {
{ { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } },
{ { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } }
};
#undef R
#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
@ -1632,7 +1649,13 @@ void AM_drawPlayers ()
{
angle = players[consoleplayer].camera->angle;
}
if (am_cheat != 0)
if (gameinfo.gametype & GAME_Raven)
{
arrow = player_arrow_raven;
numarrowlines = NUMPLYRLINES_RAVEN;
}
else if (am_cheat != 0)
{
arrow = cheat_player_arrow;
numarrowlines = NUMCHEATPLYRLINES;

View file

@ -491,6 +491,7 @@ CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS);
CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP);
CVAR (Flag, compat_crossdropoff,compatflags, COMPATF_CROSSDROPOFF);
CVAR (Flag, compat_anybossdeath,compatflags, COMPATF_ANYBOSSDEATH);
CVAR (Flag, compat_minotaur, compatflags, COMPATF_MINOTAUR);
//==========================================================================
//

View file

@ -271,6 +271,7 @@ enum
COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles
COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs
COMPATF_ANYBOSSDEATH = 1 << 21, // [GZ] Any monster which calls BOSSDEATH counts for level specials
COMPATF_MINOTAUR = 1 << 22, // Minotaur's floor flame is exploded immediately when feet are clipped
};
// Emulate old bugs for select maps. These are not exposed by a cvar

View file

@ -361,6 +361,34 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
P_SpawnPlayerMissile (self, PClass::FindClass("Rocket"));
}
//
// A_FireSTGrenade: not exactly backported from ST, but should work the same
//
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
{
player_t *player;
ACTION_PARAM_START(1);
ACTION_PARAM_CLASS(grenade, 0);
if (grenade == NULL) return;
if (NULL == (player = self->player))
{
return;
}
AWeapon *weapon = self->player->ReadyWeapon;
if (weapon != NULL)
{
if (!weapon->DepleteAmmo (weapon->bAltFire))
return;
}
// Temporarily raise the pitch to send the grenade slightly upwards
fixed_t SavedPlayerPitch = self->pitch;
self->pitch -= (1152 << FRACBITS);
P_SpawnPlayerMissile(self, grenade);
self->pitch = SavedPlayerPitch;
}
//
// A_FirePlasma
//

View file

@ -1337,6 +1337,7 @@ MapFlagHandlers[] =
{ "compat_sectorsounds", MITYPE_COMPATFLAG, COMPATF_SECTORSOUNDS},
{ "compat_missileclip", MITYPE_COMPATFLAG, COMPATF_MISSILECLIP},
{ "compat_crossdropoff", MITYPE_COMPATFLAG, COMPATF_CROSSDROPOFF},
{ "compat_minotaur", MITYPE_COMPATFLAG, COMPATF_MINOTAUR},
{ "cd_start_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end1_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end2_track", MITYPE_EATNEXT, 0, 0 },

View file

@ -378,6 +378,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
}
}
else
{
if (self->floorclip > 0 && (i_compatflags & COMPATF_MINOTAUR))
{
// only play the sound.
S_Sound (self, CHAN_WEAPON, "minotaur/fx2hit", 1, ATTN_NORM);
}
else
{
mo = P_SpawnMissile (self, self->target, PClass::FindClass("MinotaurFX2"));
if (mo != NULL)
@ -385,6 +392,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
S_Sound (mo, CHAN_WEAPON, "minotaur/attack1", 1, ATTN_NORM);
}
}
}
if (pr_minotauratk3() < 192 && self->special2 == 0)
{
self->SetState (self->FindState ("HammerLoop"));

View file

@ -139,6 +139,7 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
{
// The armor has become useless
SavePercent = 0;
ArmorType = NAME_None; // Not NAME_BasicArmor.
// Now see if the player has some more armor in their inventory
// and use it if so. As in Strife, the best armor is used up first.
ABasicArmorPickup *best = NULL;
@ -162,6 +163,24 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
}
damage = newdamage;
}
// Once the armor has absorbed its part of the damage, then apply its damage factor, if any, to the player
if ((damage > 0) && (ArmorType != NAME_None)) // BasicArmor is not going to have any damage factor, so skip it.
{
// This code is taken and adapted from APowerProtection::ModifyDamage().
// The differences include not checking for the NAME_None key (doesn't seem appropriate here),
// not using a default value, and of course the way the damage factor info is obtained.
const fixed_t *pdf = NULL;
DmgFactors *df = PClass::FindClass(ArmorType)->ActorInfo->DamageFactors;
if (df != NULL && df->CountUsed() != 0)
{
pdf = df->CheckKey(damageType);
if (pdf != NULL)
{
damage = newdamage = FixedMul(damage, *pdf);
}
}
}
if (Inventory != NULL)
{
Inventory->AbsorbDamage (damage, damageType, newdamage);

View file

@ -1387,7 +1387,7 @@ IMPLEMENT_CLASS (AHealth)
//===========================================================================
//
// AHealth :: TryPickup
// AHealth :: PickupMessage
//
//===========================================================================
const char *AHealth::PickupMessage ()

View file

@ -317,9 +317,10 @@ enum
WIF_POWERED_UP = 0x00000400, // this is a tome-of-power'ed version of its sister
WIF_AMMO_CHECKBOTH = 0x00000800, // check for both primary and secondary fire before switching it off
WIF_NO_AUTO_SWITCH = 0x00001000, // never switch to this weapon when it's picked up
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickba
WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback
WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles)
WIF_CHEATNOTWEAPON = 1<<27, // Give cheat considers this not a weapon (used by Sigil)
WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil)
// Flags used only by bot AI:

View file

@ -974,6 +974,7 @@ static bool FindMostRecentWeapon(player_t *player, int *slot, int *index)
AWeapon *FWeaponSlots::PickNextWeapon(player_t *player)
{
int startslot, startindex;
int slotschecked = 0;
if (player->mo == NULL)
{
@ -997,6 +998,7 @@ AWeapon *FWeaponSlots::PickNextWeapon(player_t *player)
if (++index >= Slots[slot].Size())
{
index = 0;
slotschecked++;
if (++slot >= NUM_WEAPON_SLOTS)
{
slot = 0;
@ -1009,7 +1011,7 @@ AWeapon *FWeaponSlots::PickNextWeapon(player_t *player)
return weap;
}
}
while (slot != startslot || index != startindex);
while ((slot != startslot || index != startindex) && slotschecked < NUM_WEAPON_SLOTS);
}
return player->ReadyWeapon;
}
@ -1027,6 +1029,7 @@ AWeapon *FWeaponSlots::PickNextWeapon(player_t *player)
AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player)
{
int startslot, startindex;
int slotschecked = 0;
if (player->mo == NULL)
{
@ -1049,6 +1052,7 @@ AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player)
{
if (--index < 0)
{
slotschecked++;
if (--slot < 0)
{
slot = NUM_WEAPON_SLOTS - 1;
@ -1062,7 +1066,7 @@ AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player)
return weap;
}
}
while (slot != startslot || index != startindex);
while ((slot != startslot || index != startindex) && slotschecked < NUM_WEAPON_SLOTS);
}
return player->ReadyWeapon;
}

View file

@ -806,9 +806,8 @@ static int __cdecl dicmp (const void *a, const void *b)
case GLDIT_POLY: break;
}
}
if (lights[0]!=lights[1]) return lights[0]-lights[1];
if (tx[0]!=tx[1]) return tx[0]-tx[1];
/*if (lights[0]!=lights[1])*/ return lights[0]-lights[1];
return lights[0]-lights[1];
}

View file

@ -91,6 +91,7 @@ EXTERN_CVAR(Bool, nomonsterinterpolation)
EXTERN_CVAR(Int, showendoom)
EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, compatmode)
EXTERN_CVAR (Bool, vid_vsync)
static value_t Renderers[] = {
{ 0.0, "Software" },
@ -538,6 +539,7 @@ static menuitem_t VideoItems[] = {
{ slider, "Gamma correction", {&Gamma}, {0.1f}, {3.0}, {0.1f}, {NULL} },
{ slider, "Brightness", {&vid_brightness}, {-0.8f}, {0.8f}, {0.05f}, {NULL} },
{ slider, "Contrast", {&vid_contrast}, {0.1f}, {3.0}, {0.1f}, {NULL} },
{ discrete, "Vertical Sync", {&vid_vsync}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ discretes,"Crosshair", {&crosshair}, {8.0}, {0.0}, {0.0}, {NULL} },
{ discrete, "Column render mode", {&r_columnmethod}, {2.0}, {0.0}, {0.0}, {ColumnMethods} },
{ discrete, "Stretch short skies", {&r_stretchsky}, {2.0}, {0.0}, {0.0}, {OnOff} },
@ -556,7 +558,7 @@ static menuitem_t VideoItems[] = {
{ discrete, "Bullet Puff Type", {&cl_pufftype}, {2.0}, {0.0}, {0.0}, {PuffTypes} },
};
#define CROSSHAIR_INDEX 9
#define CROSSHAIR_INDEX 10
menu_t VideoMenu =
{
@ -1160,6 +1162,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "Sector sounds use center as source", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SECTORSOUNDS} },
{ bitflag, "Use Doom heights for missile clipping", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MISSILECLIP} },
{ bitflag, "Allow any bossdeath for level special", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_ANYBOSSDEATH} },
{ bitflag, "No Minotaur floor flames in water", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MINOTAUR} },
{ discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} },
};

View file

@ -2957,7 +2957,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
{
FName p(FBehavior::StaticLookupString(args[0]));
ABasicArmor * armor = (ABasicArmor *) players[args[1]].mo->FindInventory(NAME_BasicArmor);
if (armor->ArmorType == p) return 1;
if (armor && armor->ArmorType == p) return armor->Amount;
}
return 0;
}

View file

@ -1039,12 +1039,20 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
ang = R_PointToAngle2 (origin->x, origin->y,
target->x, target->y);
thrust = damage*(FRACUNIT>>3)*kickback / target->Mass;
// Calculate this as float to avoid overflows so that the
// clamping that had to be done here can be removed.
thrust = FLOAT2FIXED((damage * 0.125 * kickback) / target->Mass);
// [RH] If thrust overflows, use a more reasonable amount
/* old fixed point code that could overflow.
thrust = damage*(FRACUNIT>>3)*kickback / target->Mass;
if (thrust < 0 || thrust > 10*FRACUNIT)
{
thrust = 10*FRACUNIT;
}
*/
// make fall forwards sometimes
if ((damage < 40) && (damage > target->health)
&& (target->z - origin->z > 64*FRACUNIT)

View file

@ -2357,6 +2357,57 @@ FUNC(LS_Line_SetTextureOffset)
return true;
}
FUNC(LS_Line_SetTextureScale)
// Line_SetTextureScale (id, x, y, side, flags)
{
const fixed_t NO_CHANGE = 32767<<FRACBITS;
if (arg0 == 0 || arg3 < 0 || arg3 > 1)
return false;
for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; )
{
if (lines[line].sidenum[arg3] != NO_SIDE)
{
side_t *side = &sides[lines[line].sidenum[arg3]];
if ((arg4&8)==0)
{
// set
if (arg1 != NO_CHANGE)
{
if (arg4&1) side->SetTextureXScale(side_t::top, arg1);
if (arg4&2) side->SetTextureXScale(side_t::mid, arg1);
if (arg4&4) side->SetTextureXScale(side_t::bottom, arg1);
}
if (arg2 != NO_CHANGE)
{
if (arg4&1) side->SetTextureYScale(side_t::top, arg2);
if (arg4&2) side->SetTextureYScale(side_t::mid, arg2);
if (arg4&4) side->SetTextureYScale(side_t::bottom, arg2);
}
}
else
{
// add
if (arg1 != NO_CHANGE)
{
if (arg4&1) side->MultiplyTextureXScale(side_t::top, arg1);
if (arg4&2) side->MultiplyTextureXScale(side_t::mid, arg1);
if (arg4&4) side->MultiplyTextureXScale(side_t::bottom, arg1);
}
if (arg2 != NO_CHANGE)
{
if (arg4&1) side->MultiplyTextureYScale(side_t::top, arg2);
if (arg4&2) side->MultiplyTextureYScale(side_t::mid, arg2);
if (arg4&4) side->MultiplyTextureYScale(side_t::bottom, arg2);
}
}
}
}
return true;
}
FUNC(LS_Line_SetBlocking)
// Line_SetBlocking (id, setflags, clearflags)
{
@ -2978,7 +3029,7 @@ lnSpecFunc LineSpecials[256] =
LS_Line_SetTextureOffset,
LS_Sector_ChangeFlags,
LS_Line_SetBlocking,
LS_NOP, // 56
LS_Line_SetTextureScale,
LS_NOP, // 57
LS_NOP, // 58
LS_NOP, // 59

View file

@ -350,11 +350,13 @@ struct FCheckPosition
// ripping damage once per tic instead of once per move.
bool DoRipping;
AActor *LastRipped;
int PushTime;
FCheckPosition(bool rip=false)
{
DoRipping = rip;
LastRipped = NULL;
PushTime = 0;
}
};

View file

@ -755,7 +755,7 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS)
return true;
if ((tm.thing->flags6 & MF6_THRUSPECIES) && (tm.thing->Species == thing->Species))
if ((tm.thing->flags6 & MF6_THRUSPECIES) && (tm.thing->GetSpecies() == thing->GetSpecies()))
return true;
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)) )
@ -826,6 +826,13 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
return false;
}
}
// Check for players touching a thing with MF6_BUMPSPECIAL
// A blind recreation of what the Skulltag code is probably like.
if (tm.thing->player && (thing->flags6 & MF6_BUMPSPECIAL) && thing->special)
{
LineSpecials[thing->special] (NULL, tm.thing, false, thing->args[0],
thing->args[1], thing->args[2], thing->args[3], thing->args[4]);
}
// Check for missile
if (tm.thing->flags & MF_MISSILE)
{
@ -1001,8 +1008,12 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
if (thing->flags2 & MF2_PUSHABLE
&& !(tm.thing->flags2 & MF2_CANNOTPUSH))
{ // Push thing
thing->momx += tm.thing->momx>>2;
thing->momy += tm.thing->momy>>2;
if (thing->lastpush != tm.PushTime)
{
thing->momx += FixedMul(tm.thing->momx, thing->pushfactor);
thing->momy += FixedMul(tm.thing->momy, thing->pushfactor);
thing->lastpush = tm.PushTime;
}
}
}
spechit.Clear ();
@ -1041,8 +1052,12 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm)
if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH) &&
(tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)))
{ // Push thing
if (thing->lastpush != tm.PushTime)
{
thing->momx += FixedMul(tm.thing->momx, thing->pushfactor);
thing->momy += FixedMul(tm.thing->momy, thing->pushfactor);
thing->lastpush = tm.PushTime;
}
}
solid = (thing->flags & MF_SOLID) &&
!(thing->flags & MF_NOCLIP) &&
@ -2926,7 +2941,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
pitch_friend=thingpitch;
}
}
else if (!(th->flags3&MF3_ISMONSTER) )
else if (!(th->flags3&MF3_ISMONSTER) && th->player == NULL)
{
if (sv_smartaim < 3)
{
@ -3244,7 +3259,8 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
}
}
// [GZ] If MF6_FORCEPAIN is set, we need to call P_DamageMobj even if damage is 0!
if (damage || puff->flags6 & MF6_FORCEPAIN)
// Note: The puff may not yet be spawned here so we must check the class defaults, not the actor.
if (damage || (puffDefaults->flags6 & MF6_FORCEPAIN))
{
int flags = DMG_INFLICTOR_IS_PUFF;
// Allow MF5_PIERCEARMOR on a weapon as well.

View file

@ -296,6 +296,7 @@ void AActor::Serialize (FArchive &arc)
<< smokecounter
<< BlockingMobj
<< BlockingLine
<< pushfactor
<< Species;
if (arc.IsStoring ())
@ -1499,6 +1500,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
{
static int pushtime = 0;
bool bForceSlide = scrollx || scrolly;
angle_t angle;
fixed_t ptryx, ptryy;
@ -1658,11 +1660,16 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
// last actor ripped through is recorded so that if the projectile
// passes through more than one actor this tic, each one takes damage
// and not just the first one.
pushtime++;
FCheckPosition tm(!!(mo->flags2 & MF2_RIP));
do
{
if (i_compatflags & COMPATF_WALLRUN) pushtime++;
tm.PushTime = pushtime;
ptryx = startx + Scale (xmove, step, steps);
ptryy = starty + Scale (ymove, step, steps);
@ -1722,7 +1729,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
fixed_t tx, ty;
tx = 0, ty = onestepy;
walkplane = P_CheckSlopeWalk (mo, tx, ty);
if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane))
if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm))
{
mo->momx = 0;
}
@ -1730,7 +1737,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
{
tx = onestepx, ty = 0;
walkplane = P_CheckSlopeWalk (mo, tx, ty);
if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane))
if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm))
{
mo->momy = 0;
}
@ -5014,7 +5021,15 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
AActor *linetarget;
int vrange = nofreeaim? ANGLE_1*35 : 0;
// see which target is to be aimed at
// Note: NOAUTOAIM is implemented only here, and not in the hitscan or rail attack functions.
// That is because it is only justified for projectiles affected by gravity, not for other attacks.
if (source && source->player && source->player->ReadyWeapon && (source->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM))
{
// Keep exactly the same angle and pitch as the player's own aim
pitch = source->pitch; linetarget = NULL;
}
else // see which target is to be aimed at
{
i = 2;
do
{
@ -5029,6 +5044,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
break;
}
} while (linetarget == NULL && --i >= 0);
}
if (linetarget == NULL)
{

View file

@ -199,18 +199,6 @@ void R_InitPicAnims (void)
tex2->Name, pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump()));
}
/* FIXME: doesn't work with hires texture replacements.
int l1 = tex1->GetSourceLump();
int l2 = tex2->GetSourceLump();
if (tex1->UseType == FTexture::TEX_Wall && l1 != l2)
{
// Animated walls must be in the same definition lumo
continue;
}
*/
// [RH] Allow for backward animations as well as forward.
if (pic1 > pic2)
{
@ -243,6 +231,8 @@ void R_InitPicAnims (void)
//==========================================================================
void R_AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD speedmin, DWORD speedrange)
{
if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1)))
{
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
anim->CurFrame = 0;
@ -255,6 +245,7 @@ void R_AddSimpleAnim (FTextureID picnum, int animcount, int animtype, DWORD spee
anim->Frames[0].FramePic = anim->BasePic;
Anims.AddAnim (anim);
}
}
//==========================================================================
//

View file

@ -824,6 +824,11 @@ struct side_t
{
return textures[which].xscale;
}
void MultiplyTextureXScale(int which, fixed_t delta)
{
textures[which].xscale = FixedMul(textures[which].xscale, delta);
}
void SetTextureYScale(int which, fixed_t scale)
{
@ -837,6 +842,10 @@ struct side_t
{
return textures[which].yscale;
}
void MultiplyTextureYScale(int which, fixed_t delta)
{
textures[which].yscale = FixedMul(textures[which].yscale, delta);
}
DInterpolation *SetInterpolation(int position);
void StopInterpolation(int position);

View file

@ -906,7 +906,7 @@ static void R_DrawSkyStriped (visplane_t *pl)
{
lastskycol[x] = 0xffffffff;
}
wallscan (pl->minx, pl->maxx, top, bot, swall, lwall, frontyScale,
wallscan (pl->minx, pl->maxx, top, bot, swall, lwall, rw_pic->yScale,
backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns);
yl = yh;
yh += drawheight;

View file

@ -224,7 +224,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
i++;
continue;
}
// same for x_START markers
// same for x_END markers
while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1))
{
Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker);
@ -235,13 +235,16 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name
if (i >= markers.Size())
{
Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker);
return;
end = NumLumps;
}
else
{
end = markers[i++].index;
}
end = i++;
// we found a marked block
DPrintf("Found %s block at (%d-%d)\n", startmarker, markers[start].index, markers[end].index);
for(int j = markers[start].index+1; j < markers[end].index; j++)
DPrintf("Found %s block at (%d-%d)\n", startmarker, markers[start].index, end);
for(int j = markers[start].index + 1; j < end; j++)
{
if (Lumps[j].Namespace != ns_global)
{

View file

@ -170,14 +170,14 @@ static WORD DIKToKeySym[256] =
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ,
SDLK_RALT, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, SDLK_HOME,
0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME,
SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END,
SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0,
0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, SDLK_PAUSE
0, 0, 0, 0, 0, 0, 0, 0
};
static void FlushDIKState (int low=0, int high=NUM_KEYS-1)

View file

@ -528,7 +528,7 @@ MusInfo *I_RegisterSong (const char *filename, BYTE *musiccache, int offset, int
}
}
// Check for game music
else if ((fmt = GME_CheckFormat(id)) != NULL)
else if ((fmt = GME_CheckFormat(id)) != NULL && fmt[0] != '\0')
{
info = GME_OpenSong(file, musiccache, len, fmt);
}

View file

@ -201,7 +201,7 @@ void GMESong::Play(bool looping, int track)
{
m_Status = STATE_Stopped;
m_Looping = looping;
if (StartTrack(0) && m_Stream->Play(looping, 1))
if (StartTrack(track) && m_Stream->Play(looping, 1))
{
m_Status = STATE_Playing;
}

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "1650"
#define ZD_SVN_REVISION_NUMBER 1650
#define ZD_SVN_REVISION_STRING "1668"
#define ZD_SVN_REVISION_NUMBER 1668

View file

@ -371,6 +371,40 @@ void FTextureManager::ReplaceTexture (FTextureID picnum, FTexture *newtexture, b
}
}
//==========================================================================
//
// FTextureManager :: AreTexturesCompatible
//
// Checks if 2 textures are compatible for a ranged animation
//
//==========================================================================
bool FTextureManager::AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2)
{
int index1 = picnum1.GetIndex();
int index2 = picnum2.GetIndex();
if (unsigned(index1) >= Textures.Size() || unsigned(index2) >= Textures.Size())
return false;
FTexture *texture1 = Textures[index1].Texture;
FTexture *texture2 = Textures[index2].Texture;
// both textures must be the same type.
if (texture1 == NULL || texture2 == NULL || texture1->UseType != texture2->UseType)
return false;
// both textures must be from the same file
for(unsigned i = 0; i < FirstTextureForFile.Size() - 1; i++)
{
if (index1 >= FirstTextureForFile[i] && index1 < FirstTextureForFile[i+1])
{
return (index2 >= FirstTextureForFile[i] && index2 < FirstTextureForFile[i+1]);
}
}
return false;
}
//==========================================================================
//
// FTextureManager :: AddGroup
@ -707,6 +741,8 @@ void FTextureManager::AddTexturesForWad(int wadnum)
int firsttexture = Textures.Size();
int lumpcount = Wads.GetNumLumps();
FirstTextureForFile.Push(firsttexture);
// First step: Load sprites
AddGroup(wadnum, ns_sprites, FTexture::TEX_Sprite);
@ -857,7 +893,12 @@ void FTextureManager::Init()
{
AddTexturesForWad(i);
}
// Add one marker so that the last WAD is easier to handle and treat
// Build tiles as a completely separate block.
FirstTextureForFile.Push(Textures.Size());
R_InitBuildTiles ();
FirstTextureForFile.Push(Textures.Size());
DefaultTexture = CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0);

View file

@ -337,6 +337,7 @@ public:
void LoadTextureDefs(int wadnum, const char *lumpname);
void ParseXTexture(FScanner &sc, int usetype);
void SortTexturesByType(int start, int end);
bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2);
FTextureID CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture
FTextureID AddTexture (FTexture *texture);
@ -374,6 +375,7 @@ private:
TArray<int> Translation;
int HashFirst[HASH_SIZE];
FTextureID DefaultTexture;
TArray<int> FirstTextureForFile;
};
extern FTextureManager TexMan;

View file

@ -535,12 +535,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType)
ACTION_PARAM_START(3);
ACTION_PARAM_NAME(Type, 0);
ACTION_PARAM_STATE(JumpOffset, 1);
ACTION_PARAM_INT(amount, 2);
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
ABasicArmor * armor = (ABasicArmor *) self->FindInventory(NAME_BasicArmor);
if (armor && armor->ArmorType == Type)
if (armor && armor->ArmorType == Type && armor->Amount >= amount)
ACTION_JUMP(JumpOffset);
}
@ -1705,14 +1706,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn)
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut)
{
ACTION_PARAM_START(1);
ACTION_PARAM_START(2);
ACTION_PARAM_FIXED(reduce, 0);
ACTION_PARAM_BOOL(remove, 1);
if (reduce == 0) reduce = FRACUNIT/10;
self->RenderStyle.Flags &= ~STYLEF_Alpha1;
self->alpha -= reduce;
if (self->alpha<=0) self->Destroy();
if (self->alpha<=0 && remove) self->Destroy();
}
//===========================================================================
@ -1780,24 +1782,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight)
}
//===========================================================================
//
// A_JumpIfTargetInSight
// jumps if monster can see its target
//
//===========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInSight)
{
ACTION_PARAM_START(1);
ACTION_PARAM_STATE(jump, 0);
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
if (self->target == NULL || !P_CheckSight(self, self->target,4)) return;
ACTION_JUMP(jump);
}
//===========================================================================
//
// Inventory drop
@ -2210,6 +2194,62 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
ACTION_JUMP(jump);
}
//==========================================================================
//
// A_JumpIfInTargetLOS (state label, optional fixed fov, optional bool
// projectiletarget)
//
//==========================================================================
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfInTargetLOS)
{
ACTION_PARAM_START(3);
ACTION_PARAM_STATE(jump, 0);
ACTION_PARAM_ANGLE(fov, 1);
ACTION_PARAM_BOOL(projtarg, 2);
angle_t an;
AActor *target;
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
if (self->flags & MF_MISSILE && projtarg)
{
if (self->flags2 & MF2_SEEKERMISSILE)
target = self->tracer;
else
target = NULL;
}
else
{
target = self->target;
}
if (!target) return; // [KS] Let's not call P_CheckSight unnecessarily in this case.
if (!P_CheckSight (target, self, 1))
return;
if (fov && (fov < ANGLE_MAX))
{
an = R_PointToAngle2 (self->x,
self->y,
target->x,
target->y)
- self->angle;
if (an > (fov / 2) && an < (ANGLE_MAX - (fov / 2)))
{
return; // [KS] Outside of FOV - return
}
}
ACTION_JUMP(jump);
}
//===========================================================================
//
// A_DamageMaster (int amount)

View file

@ -214,6 +214,7 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF6, MTHRUSPECIES, AActor, flags6),
DEFINE_FLAG(MF6, FORCEPAIN, AActor, flags6),
DEFINE_FLAG(MF6, NOFEAR, AActor, flags6),
DEFINE_FLAG(MF6, BUMPSPECIAL, AActor, flags6),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
@ -234,9 +235,12 @@ static FFlagDef ActorFlags[]=
DEFINE_DEPRECATED_FLAG(HERETICBOUNCE),
DEFINE_DEPRECATED_FLAG(HEXENBOUNCE),
DEFINE_DEPRECATED_FLAG(DOOMBOUNCE),
DEFINE_DUMMY_FLAG(NONETID),
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN),
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY),
// Various Skulltag flags that are quite irrelevant to ZDoom
DEFINE_DUMMY_FLAG(NONETID), // netcode-based
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), // netcode-based
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), // netcode-based
DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless
};
static FFlagDef InventoryFlags[] =
@ -281,6 +285,7 @@ static FFlagDef WeaponFlags[] =
DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, AMMO_CHECKBOTH, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, NOAUTOAIM, AWeapon, WeaponFlags),
DEFINE_DUMMY_FLAG(NOLMS),
};

View file

@ -1262,6 +1262,14 @@ DEFINE_CLASS_PROPERTY(pickupsound, S, Inventory)
defaults->PickupSound = str;
}
//==========================================================================
// Dummy for Skulltag compatibility...
//==========================================================================
DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory)
{
PROP_STRING_PARM(str, 0);
}
//==========================================================================
//
//==========================================================================

View file

@ -71,6 +71,10 @@
// w32api does not #define the PBT_ macros in winuser.h like the PSDK does
#include <pbt.h>
#endif
#ifndef GET_RAWINPUT_CODE_WPARAM
#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff)
#endif
#define USE_WINDOWS_DWORD
#include "c_dispatch.h"
@ -460,6 +464,32 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result;
if (message == WM_INPUT)
{
if (MyGetRawInputData != NULL)
{
UINT size;
if (!MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) &&
size != 0)
{
BYTE *buffer = (BYTE *)alloca(size);
if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) == size)
{
int code = GET_RAWINPUT_CODE_WPARAM(wParam);
if (Keyboard == NULL || !Keyboard->ProcessRawInput((RAWINPUT *)buffer, code))
{
if (Mouse != NULL)
{
Mouse->ProcessRawInput((RAWINPUT *)buffer, code);
}
}
}
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
if (CallHook(Keyboard, hWnd, message, wParam, lParam, &result))
{
return result;
@ -1184,10 +1214,12 @@ void I_ShutdownInput ()
if (Keyboard != NULL)
{
delete Keyboard;
Keyboard = NULL;
}
if (Mouse != NULL)
{
delete Mouse;
Mouse = NULL;
}
if (g_pJoy)
{
@ -1336,6 +1368,34 @@ FInputDevice::~FInputDevice()
{
}
//==========================================================================
//
// FInputDevice :: ProcessInput
//
// Gives subclasses an opportunity to do input handling that doesn't involve
// window messages.
//
//==========================================================================
void FInputDevice::ProcessInput()
{
}
//==========================================================================
//
// FInputDevice :: ProcessRawInput
//
// Gives subclasses a chance to handle WM_INPUT messages. This is not part
// of WndProcHook so that we only need to fill the RAWINPUT buffer once
// per message and be sure it gets cleaned up properly.
//
//==========================================================================
bool FInputDevice::ProcessRawInput(RAWINPUT *raw, int code)
{
return false;
}
//==========================================================================
//
// FInputDevice :: WndProcHook

View file

@ -57,12 +57,15 @@ extern void DI_EnumJoy ();
#ifdef USE_WINDOWS_DWORD
// Don't make these definitions available to the main body of the source code.
struct tagRAWINPUT;
class FInputDevice
{
public:
virtual ~FInputDevice() = 0;
virtual bool GetDevice() = 0;
virtual void ProcessInput() = 0;
virtual void ProcessInput();
virtual bool ProcessRawInput(tagRAWINPUT *raw, int code);
virtual bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
};

View file

@ -21,11 +21,6 @@
#define DINPUT_BUFFERSIZE 32
// Hi, w32api!
#ifndef GET_RAWINPUT_CODE_WPARAM
#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff)
#endif
// TYPES -------------------------------------------------------------------
class FDInputKeyboard : public FKeyboard
@ -36,7 +31,6 @@ public:
bool GetDevice();
void ProcessInput();
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
protected:
LPDIRECTINPUTDEVICE8 Device;
@ -49,8 +43,7 @@ public:
~FRawKeyboard();
bool GetDevice();
void ProcessInput();
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
bool ProcessRawInput(RAWINPUT *rawinput, int code);
protected:
USHORT E1Prefix;
@ -377,16 +370,8 @@ void FDInputKeyboard::ProcessInput()
}
}
//==========================================================================
//
// FDInputKeyboard :: WndProcHook
//
//==========================================================================
bool FDInputKeyboard::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
{
return false;
}
/**************************************************************************/
/**************************************************************************/
//==========================================================================
//
@ -447,17 +432,7 @@ bool FRawKeyboard::GetDevice()
//==========================================================================
//
// FRawKeyboard :: ProcessInput
//
//==========================================================================
void FRawKeyboard::ProcessInput()
{
}
//==========================================================================
//
// FRawKeyboard :: WndProcHook
// FRawKeyboard :: ProcessRawInput
//
// Convert scan codes to DirectInput key codes. For the most part, this is
// straight forward: Scan codes without any prefix are passed unmodified.
@ -476,25 +451,13 @@ void FRawKeyboard::ProcessInput()
//
//==========================================================================
bool FRawKeyboard::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
bool FRawKeyboard::ProcessRawInput(RAWINPUT *raw, int code)
{
if (message != WM_INPUT)
{
return false;
}
BYTE buffer[40];
UINT size = sizeof(buffer);
int keycode;
if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) > 0)
{
RAWINPUT *raw = (RAWINPUT *)buffer;
if (raw->header.dwType != RIM_TYPEKEYBOARD)
{
return false;
}
keycode = raw->data.keyboard.MakeCode;
int keycode = raw->data.keyboard.MakeCode;
if (keycode == 0 && (raw->data.keyboard.Flags & RI_KEY_E0))
{ // Even if the make code is 0, we might still be able to extract a
// useful key from the message.
@ -568,10 +531,8 @@ bool FRawKeyboard::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
// their keypad counterparts.
// Okay, we're done translating the keycode. Post it (or ignore it.)
PostKeyEvent(keycode, !(raw->data.keyboard.Flags & RI_KEY_BREAK),
GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT);
}
return false;
PostKeyEvent(keycode, !(raw->data.keyboard.Flags & RI_KEY_BREAK), code == RIM_INPUT);
return true;
}
//==========================================================================

View file

@ -47,7 +47,7 @@ public:
~FRawMouse();
bool GetDevice();
void ProcessInput();
bool ProcessRawInput(RAWINPUT *rawinput, int code);
bool WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
void Grab();
void Ungrab();
@ -492,25 +492,12 @@ bool FRawMouse::GetDevice()
return true;
}
//==========================================================================
//
// FRawMouse :: ProcessInput
//
// All input comes through WM_INPUT messages, so nothing to do here.
//
//==========================================================================
void FRawMouse::ProcessInput()
{
}
//==========================================================================
//
// FRawMouse :: Grab
//
//==========================================================================
extern BOOL AppActive;
void FRawMouse::Grab()
{
if (!Grabbed)
@ -563,37 +550,22 @@ void FRawMouse::Ungrab()
//==========================================================================
//
// FRawMouse :: WndProcHook
// FRawMouse :: ProcessRawInput
//
//==========================================================================
bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
bool FRawMouse::ProcessRawInput(RAWINPUT *raw, int code)
{
if (!Grabbed)
if (!Grabbed || raw->header.dwType != RIM_TYPEMOUSE)
{
return false;
}
if (message == WM_INPUT)
{
BYTE buffer[40];
UINT size = sizeof(buffer);
int i;
USHORT mask;
if (MyGetRawInputData((HRAWINPUT)lParam, RID_INPUT, buffer, &size, sizeof(RAWINPUTHEADER)) > 0)
{
RAWINPUT *raw = (RAWINPUT *)buffer;
if (raw->header.dwType != RIM_TYPEMOUSE)
{
return false;
}
// Check buttons. The up and down motions are stored in the usButtonFlags field.
// The ulRawButtons field, unfortunately, is device-dependant, and may well
// not contain any data at all. This means it is apparently impossible
// to read more than five mouse buttons with Windows, because RI_MOUSE_WHEEL
// gets in the way when trying to extrapolate to more than five.
for (i = 0, mask = 1; i < 5; ++i)
for (int i = 0, mask = 1; i < 5; ++i)
{
if (raw->data.mouse.usButtonFlags & mask) // button down
{
@ -616,10 +588,22 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
}
PostMouseMove(m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX<<2,
-raw->data.mouse.lLastY);
return true;
}
//==========================================================================
//
// FRawMouse :: WndProcHook
//
//==========================================================================
bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
{
if (!Grabbed)
{
return false;
}
else if (message == WM_SYSCOMMAND)
if (message == WM_SYSCOMMAND)
{
wParam &= 0xFFF0;
if (wParam == SC_MOVE || wParam == SC_SIZE)
@ -630,6 +614,9 @@ bool FRawMouse::WndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
return false;
}
/**************************************************************************/
/**************************************************************************/
//==========================================================================
//
// CreateDInputMouse
@ -1126,6 +1113,9 @@ void FWin32Mouse::CenterMouse(int curx, int cury)
}
}
/**************************************************************************/
/**************************************************************************/
//==========================================================================
//
// I_StartupMouse
@ -1193,4 +1183,3 @@ void I_StartupMouse ()
NativeMouse = true;
}
}

View file

@ -176,7 +176,7 @@ ACTOR Actor native //: Thinker
action native A_JumpIfHealthLower(int health, state label);
action native A_JumpIfCloser(float distance, state label);
action native A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label);
action native A_JumpIfArmorType(string Type, state label);
action native A_JumpIfArmorType(string Type, state label, int amount = 1);
action native A_GiveInventory(class<Inventory> itemtype, int amount = 0);
action native A_TakeInventory(class<Inventory> itemtype, int amount = 0);
action native A_SpawnItem(class<Actor> itemtype, float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
@ -184,7 +184,7 @@ ACTOR Actor native //: Thinker
action native A_Print(string whattoprint, float time = 0, string fontname = "");
action native A_SetTranslucent(float alpha, int style = 0);
action native A_FadeIn(float reduce = 0.1);
action native A_FadeOut(float reduce = 0.1);
action native A_FadeOut(float reduce = 0.1, bool remove = true);
action native A_SpawnDebris(class<Actor> spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1);
action native A_CheckSight(state label);
action native A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
@ -221,6 +221,7 @@ ACTOR Actor native //: Thinker
action native A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = "");
action native A_ClearTarget();
action native A_JumpIfTargetInLOS (state label, float fov = 0, bool projectiletarget = false);
action native A_JumpIfInTargetLOS (state label, float fov = 0, bool projectiletarget = false);
action native A_DamageMaster(int amount, name damagetype = "none");
action native A_DamageChildren(int amount, name damagetype = "none");
action native A_DamageSiblings(int amount, name damagetype = "none");
@ -236,8 +237,6 @@ ACTOR Actor native //: Thinker
action native A_RemoveForcefield();
action native A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
action native A_PigPain ();
action native A_JumpIfTargetInSight(state label);
action native A_MonsterRefire(int chance, state label);
States

View file

@ -340,6 +340,45 @@ ACTOR Rocket
}
}
// --------------------------------------------------------------------------
//
// Grenade -- Taken and adapted from Skulltag
//
// --------------------------------------------------------------------------
ACTOR Grenade
{
SpawnID 216
Radius 8
Height 8
Speed 25
Damage 20
Projectile
-NOGRAVITY
+RANDOMIZE
+DEHEXPLOSION
+GRENADETRAIL
BounceType "Doom"
Gravity 0.25
SeeSound "weapons/grenlf"
DeathSound "weapons/grenlx"
BounceSound "weapons/grbnce"
Obituary "$OB_GRENADE"
DamageType Grenade
States
{
Spawn:
SGRN A 1 Bright
Loop
Death:
MISL B 8 Bright A_Explode
MISL C 6 Bright
MISL D 4 Bright
Stop
}
}
// --------------------------------------------------------------------------
//
// Plasma rifle

View file

@ -14,6 +14,7 @@ ACTOR Pod 2035
+CANPASS +TELESTOMP +DONTMORPH
+NOBLOCKMONST +DONTGIB +OLDRADIUSDMG
DeathSound "world/podexplode"
PushFactor 0.5
action native A_PodPain (class<Actor> podtype = "PodGoo");
action native A_RemovePod ();

View file

@ -25,6 +25,7 @@ ACTOR Inventory native
action native A_LoadShotgun2();
action native A_CloseShotgun2();
action native A_FireCGun();
action native A_FireSTGrenade(class<Actor> grenadetype = "Grenade");
action native A_FireMissile();
action native A_FirePlasma();
action native A_FireRailgun();

View file

@ -201,6 +201,9 @@ weapons/plasmax dsfirxpl
weapons/bfgf dsbfg
weapons/bfgx dsrxplod
weapons/railgf railgf1
weapons/grbnce dsbounce
weapons/grenlx dsgrnexp
weapons/grenlf dsglaunc
// Problem: weapons/rocklx needs to be unlimited but
// is also used for the MAP30 brain explosion.