- Removed A_JumpSet and merged its functionality with A_Jump by turning

A_Jump into a varargs function.
- Fixed: P_MorphPlayer() should check that the desired type is actually a
  PlayerPawn.
- Added an optional parameter to the morphme ccmd that specifies the player
  class to morph into.
- Changed the SetActorPitch, SetActorAngle, Thing_Spawn*, Thing_Projectile*,
  and Thing_Move functions so that TID 0 affects the activator.


SVN r362 (trunk)
This commit is contained in:
Randy Heit 2006-10-27 03:03:34 +00:00
parent 753f280e04
commit bcca366e8f
13 changed files with 168 additions and 71 deletions

View File

@ -1,7 +1,18 @@
October 26, 2006
- Removed A_JumpSet and merged its functionality with A_Jump by turning
A_Jump into a varargs function.
- Fixed: P_MorphPlayer() should check that the desired type is actually a
PlayerPawn.
- Added an optional parameter to the morphme ccmd that specifies the player
class to morph into.
- Changed the SetActorPitch, SetActorAngle, Thing_Spawn*, Thing_Projectile*,
and Thing_Move functions so that TID 0 affects the activator.
October 25, 2006 (Changes by Graf Zahl)
- Moved the sector type translation for Doom format maps into a simple lump
in zdoom.pk3.
- Changed Line_SetIdentification so that the fifth arg is a high-byte for the line ID.
- Changed Line_SetIdentification so that the fifth arg is a high-byte for the
line ID.
October 23, 2006
- Added the A_JumpSet function for what seems to be a fairly common scenario.

View File

@ -175,8 +175,16 @@ CCMD (morphme)
if (CheckCheatmode ())
return;
Net_WriteByte (DEM_GENERICCHEAT);
Net_WriteByte (CHT_MORPH);
if (argv.argc() == 1)
{
Net_WriteByte (DEM_GENERICCHEAT);
Net_WriteByte (CHT_MORPH);
}
else
{
Net_WriteByte (DEM_MORPHEX);
Net_WriteString (argv[1]);
}
}
CCMD (anubis)

View File

@ -2291,6 +2291,16 @@ void Net_DoCommand (int type, BYTE **stream, int player)
}
break;
case DEM_MORPHEX:
{
s = ReadString (stream);
const char *msg = cht_Morph (players + player, PClass::FindClass (s), false);
if (player == consoleplayer)
{
Printf ("%s\n", *msg != '\0' ? msg : "Morph failed.");
}
}
break;
default:
I_Error ("Unknown net command: %d", type);
@ -2325,6 +2335,7 @@ void Net_SkipCommand (int type, BYTE **stream)
case DEM_SUMMON:
case DEM_SUMMONFRIEND:
case DEM_SPRAY:
case DEM_MORPHEX:
skip = strlen ((char *)(*stream)) + 1;
break;

View File

@ -142,6 +142,7 @@ enum EDemoCommand
DEM_RUNSCRIPT2, // 40 Same as DEM_RUNSCRIPT, but always executes
DEM_CHECKAUTOSAVE, // 41 Check if the user has autosaves enabled. Ignored for demoplayback.
DEM_DOAUTOSAVE, // 42 An autosave should be made
DEM_MORPHEX, // 43 String: The class to morph to.
};
// The following are implemented by cht_DoCheat in m_cheat.cpp

View File

@ -48,11 +48,14 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype)
{ // Dead players cannot morph
return false;
}
if (spawntype == NULL)
{
return false;
}
if (!spawntype->IsDescendantOf (RUNTIME_CLASS(APlayerPawn)))
{
return false;
}
morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
DObject::PointerSubstitution (actor, morphed);

View File

@ -122,18 +122,7 @@ void cht_DoCheat (player_t *player, int cheat)
break;
case CHT_MORPH:
if (player->morphTics)
{
if (P_UndoPlayerMorph (player))
{
msg = "You feel like yourself again";
}
}
else if (P_MorphPlayer (player,
PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer)))
{
msg = "You feel strange...";
}
msg = cht_Morph (player, PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer), true);
break;
case CHT_NOTARGET:
@ -415,6 +404,31 @@ void cht_DoCheat (player_t *player, int cheat)
Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg);
}
const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo)
{
if (player->mo == NULL)
{
return "";
}
PClass *oldclass = player->mo->GetClass();
if (player->morphTics)
{
if (P_UndoPlayerMorph (player))
{
if (!quickundo && oldclass != morphclass && P_MorphPlayer (player, morphclass))
{
return "You feel even stranger.";
}
return "You feel like yourself again.";
}
}
else if (P_MorphPlayer (player, morphclass))
{
return "You feel strange...";
}
return "";
}
void GiveSpawner (player_t *player, const PClass *type, int amount)
{
if (player->mo == NULL || player->health <= 0)

View File

@ -29,8 +29,10 @@
// [RH] Functions that actually perform the cheating
class player_s;
struct PClass;
void cht_DoCheat (player_s *player, int cheat);
void cht_Give (player_s *player, char *item, int amount=1);
void cht_Suicide (player_s *player);
const char *cht_Morph (player_s *player, const PClass *morphclass, bool quickundo);
#endif

View File

@ -4793,14 +4793,14 @@ int DLevelScript::RunScript ()
// Like Thing_Projectile(Gravity) specials, but you can give the
// projectile a TID.
// Thing_Projectile2 (tid, type, angle, speed, vspeed, gravity, newtid);
P_Thing_Projectile (STACK(7), STACK(6), NULL, ((angle_t)(STACK(5)<<24)),
P_Thing_Projectile (STACK(7), activator, STACK(6), NULL, ((angle_t)(STACK(5)<<24)),
STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false);
sp -= 7;
break;
case PCD_SPAWNPROJECTILE:
// Same, but takes an actor name instead of a spawn ID.
P_Thing_Projectile (STACK(7), 0, FBehavior::StaticLookupString (STACK(6)), ((angle_t)(STACK(5)<<24)),
P_Thing_Projectile (STACK(7), activator, 0, FBehavior::StaticLookupString (STACK(6)), ((angle_t)(STACK(5)<<24)),
STACK(4)<<(FRACBITS-3), STACK(3)<<(FRACBITS-3), 0, NULL, STACK(2), STACK(1), false);
sp -= 7;
break;
@ -4903,6 +4903,11 @@ int DLevelScript::RunScript ()
break;
case PCD_SETACTORANGLE: // [GRB]
if (STACK(2) == 0)
{
activator->angle = STACK(1) << 16;
}
else
{
FActorIterator iterator (STACK(2));
AActor *actor;
@ -4916,6 +4921,11 @@ int DLevelScript::RunScript ()
break;
case PCD_SETACTORPITCH:
if (STACK(2) == 0)
{
activator->angle = STACK(1) << 16;
}
else
{
FActorIterator iterator (STACK(2));
AActor *actor;

View File

@ -1138,14 +1138,14 @@ FUNC(LS_Thing_Damage)
FUNC(LS_Thing_Projectile)
// Thing_Projectile (tid, type, angle, speed, vspeed)
{
return P_Thing_Projectile (arg0, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
arg4<<(FRACBITS-3), 0, NULL, 0, 0, false);
}
FUNC(LS_Thing_ProjectileGravity)
// Thing_ProjectileGravity (tid, type, angle, speed, vspeed)
{
return P_Thing_Projectile (arg0, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
return P_Thing_Projectile (arg0, it, arg1, NULL, BYTEANGLE(arg2), arg3<<(FRACBITS-3),
arg4<<(FRACBITS-3), 0, NULL, 1, 0, false);
}
@ -1315,35 +1315,35 @@ FUNC(LS_Thing_Hate)
FUNC(LS_Thing_ProjectileAimed)
// Thing_ProjectileAimed (tid, type, speed, target, newtid)
{
return P_Thing_Projectile (arg0, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false);
return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, false);
}
FUNC(LS_Thing_ProjectileIntercept)
// Thing_ProjectileIntercept (tid, type, speed, target, newtid)
{
return P_Thing_Projectile (arg0, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true);
return P_Thing_Projectile (arg0, it, arg1, NULL, 0, arg2<<(FRACBITS-3), 0, arg3, it, 0, arg4, true);
}
// [BC] added newtid for next two
FUNC(LS_Thing_Spawn)
// Thing_Spawn (tid, type, angle, newtid)
{
return P_Thing_Spawn (arg0, arg1, BYTEANGLE(arg2), true, arg3);
return P_Thing_Spawn (arg0, it, arg1, BYTEANGLE(arg2), true, arg3);
}
FUNC(LS_Thing_SpawnNoFog)
// Thing_SpawnNoFog (tid, type, angle, newtid)
{
return P_Thing_Spawn (arg0, arg1, BYTEANGLE(arg2), false, arg3);
return P_Thing_Spawn (arg0, it, arg1, BYTEANGLE(arg2), false, arg3);
}
FUNC(LS_Thing_SpawnFacing)
// Thing_SpawnFacing (tid, type, nofog, newtid)
{
return P_Thing_Spawn (arg0, arg1, ANGLE_MAX, arg2 ? false : true, arg3);
return P_Thing_Spawn (arg0, it, arg1, ANGLE_MAX, arg2 ? false : true, arg3);
}
static bool DoThingRaise(AActor * thing)
static bool DoThingRaise(AActor *thing)
{
if (thing == NULL)
return false; // not valid
@ -1448,7 +1448,7 @@ FUNC(LS_Thing_SetGoal)
FUNC(LS_Thing_Move) // [BC]
// Thing_Move (tid, mapspot, nofog)
{
return P_Thing_Move (arg0, arg1, arg2 ? false : true);
return P_Thing_Move (arg0, it, arg1, arg2 ? false : true);
}
FUNC(LS_Thing_SetTranslation)

View File

@ -125,12 +125,12 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz);
#define MAX_SPAWNABLES (256)
extern const PClass *SpawnableThings[MAX_SPAWNABLES];
bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid);
bool P_Thing_Projectile (int tid, int type, const char * type_name, angle_t angle,
bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid);
bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle,
fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
bool leadTarget);
bool P_MoveThing(AActor * source, fixed_t x, fixed_t y, fixed_t z, bool fog);
bool P_Thing_Move (int tid, int mapspot, bool fog);
bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog);
bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog);
//
// P_ENEMY

View File

@ -51,7 +51,7 @@ const PClass *SpawnableThings[MAX_SPAWNABLES];
static FRandom pr_leadtarget ("LeadTarget");
bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid)
{
int rtn = 0;
const PClass *kind;
@ -70,7 +70,15 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) && (dmflags & DF_NO_MONSTERS))
return false;
while ( (spot = iterator.Next ()) )
if (tid == 0)
{
spot = source;
}
else
{
spot = iterator.Next();
}
while (spot != NULL)
{
mobj = Spawn (kind, spot->x, spot->y, spot->z, ALLOW_REPLACE);
@ -109,6 +117,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
rtn = false;
}
}
spot = iterator.Next();
}
return rtn != 0;
@ -117,7 +126,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
// [BC] Added
// [RH] Fixed
bool P_MoveThing(AActor * source, fixed_t x, fixed_t y, fixed_t z, bool fog)
bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog)
{
fixed_t oldx, oldy, oldz;
@ -142,13 +151,16 @@ bool P_MoveThing(AActor * source, fixed_t x, fixed_t y, fixed_t z, bool fog)
}
}
bool P_Thing_Move (int tid, int mapspot, bool fog)
bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog)
{
FActorIterator iterator1 (tid);
FActorIterator iterator2 (mapspot);
AActor *source, *target;
AActor *target;
source = iterator1.Next ();
if (tid != 0)
{
FActorIterator iterator1(tid);
source = iterator1.Next();
}
FActorIterator iterator2 (mapspot);
target = iterator2.Next ();
if (source != NULL && target != NULL)
@ -158,7 +170,7 @@ bool P_Thing_Move (int tid, int mapspot, bool fog)
return false;
}
bool P_Thing_Projectile (int tid, int type, const char * type_name, angle_t angle,
bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle,
fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
bool leadTarget)
{
@ -191,7 +203,15 @@ bool P_Thing_Projectile (int tid, int type, const char * type_name, angle_t angl
if ((defflags3 & MF3_ISMONSTER) && (dmflags & DF_NO_MONSTERS))
return false;
while ( (spot = iterator.Next ()) )
if (tid == 0)
{
spot = source;
}
else
{
spot = iterator.Next();
}
while (spot != NULL)
{
FActorIterator tit (dest);
@ -376,6 +396,7 @@ nolead:
}
} while (dest != 0 && (targ = tit.Next()));
}
spot = iterator.Next();
}
return rtn != 0;

View File

@ -457,7 +457,6 @@ ACTOR(PlaySoundEx)
ACTOR(StopSoundEx)
ACTOR(SeekerMissile)
ACTOR(Jump)
ACTOR(JumpSet)
ACTOR(ExplodeParms)
ACTOR(CallSpecial)
ACTOR(CustomMissile)
@ -527,6 +526,9 @@ ACTOR(Stop)
* c = color
* x = expression
* y = expression
* If the final character is a +, the previous parameter is repeated indefinitely,
* and an "imaginary" first parameter is inserted containing the total number of
* parameters passed.
*/
#define FUNC(name, parm) { #name, name, parm },
// Declare the code pointer table
@ -677,8 +679,7 @@ AFuncDesc AFTable[]=
FUNC(A_PlaySoundEx, "STi" )
FUNC(A_StopSoundEx, "T" )
FUNC(A_SeekerMissile, "XX" )
FUNC(A_Jump, "XL" )
FUNC(A_JumpSet, "XLLllllllllllllllllll")
FUNC(A_Jump, "XL+" )
FUNC(A_CustomMissile, "MXXxxx" )
FUNC(A_CustomBulletAttack, "XXXXmx" )
FUNC(A_CustomRailgun, "Xxccxxx" )
@ -1655,6 +1656,14 @@ do_stop:
}
int paramindex = PrepareStateParameters(&state, numparams);
int paramstart = paramindex;
bool varargs = params[numparams - 1] == '+';
if (varargs)
{
StateParameters[paramindex++] = 0;
}
while (*params)
{
switch(*params)
@ -1763,11 +1772,28 @@ do_stop:
v = -1;
break;
}
StateParameters[paramindex++]=v;
StateParameters[paramindex++] = v;
params++;
if (varargs)
{
StateParameters[paramstart]++;
}
if (*params)
{
if ((islower(*params) || *params=='!') && SC_CheckString(")")) goto endofstate;
if (*params == '+')
{
if (SC_CheckString(")"))
{
goto endofstate;
}
params--;
v = 0;
StateParameters.Push(v);
}
else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
{
goto endofstate;
}
ChkCom();
}
}

View File

@ -405,33 +405,23 @@ static void DoJump(AActor * self, FState * CallingState, int offset)
void A_Jump(AActor * self)
{
FState * CallingState;
int index=CheckIndex(2, &CallingState);
int index = CheckIndex(3, &CallingState);
int maxchance;
if (index>=0 && pr_cajump() < clamp<int>(EvalExpressionI (StateParameters[index], self), 0, 255))
DoJump(self, CallingState, StateParameters[index+1]);
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
}
//==========================================================================
//
// State jump function
//
//==========================================================================
void A_JumpSet(AActor * self)
{
FState * CallingState;
int index=CheckIndex(21, &CallingState);
int i;
if (index>=0 && pr_cajump() < clamp<int>(EvalExpressionI (StateParameters[index], self), 0, 256))
if (index >= 0 &&
StateParameters[index] >= 2 &&
(maxchance = clamp<int>(EvalExpressionI (StateParameters[index + 1], self), 0, 256),
maxchance == 256 || pr_cajump() < maxchance))
{
// Find out how many targets are actually used
for (i = 0; i < 20 && StateParameters[index+i+1] != 0; ++i)
{ }
DoJump(self, CallingState, StateParameters[index + (pr_cajump() % i) + 1]);
if (StateParameters[index] == 2)
{
DoJump(self, CallingState, StateParameters[index + 2]);
}
else
{
DoJump(self, CallingState, StateParameters[index + (pr_cajump() % (StateParameters[index] - 1)) + 2]);
}
}
if (pStateCall != NULL) pStateCall->Result=false; // Jumps should never set the result for inventory state chains!
}