- 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) October 25, 2006 (Changes by Graf Zahl)
- Moved the sector type translation for Doom format maps into a simple lump - Moved the sector type translation for Doom format maps into a simple lump
in zdoom.pk3. 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 October 23, 2006
- Added the A_JumpSet function for what seems to be a fairly common scenario. - Added the A_JumpSet function for what seems to be a fairly common scenario.

View file

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

View file

@ -2291,6 +2291,16 @@ void Net_DoCommand (int type, BYTE **stream, int player)
} }
break; 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: default:
I_Error ("Unknown net command: %d", type); I_Error ("Unknown net command: %d", type);
@ -2325,6 +2335,7 @@ void Net_SkipCommand (int type, BYTE **stream)
case DEM_SUMMON: case DEM_SUMMON:
case DEM_SUMMONFRIEND: case DEM_SUMMONFRIEND:
case DEM_SPRAY: case DEM_SPRAY:
case DEM_MORPHEX:
skip = strlen ((char *)(*stream)) + 1; skip = strlen ((char *)(*stream)) + 1;
break; break;

View file

@ -142,6 +142,7 @@ enum EDemoCommand
DEM_RUNSCRIPT2, // 40 Same as DEM_RUNSCRIPT, but always executes DEM_RUNSCRIPT2, // 40 Same as DEM_RUNSCRIPT, but always executes
DEM_CHECKAUTOSAVE, // 41 Check if the user has autosaves enabled. Ignored for demoplayback. DEM_CHECKAUTOSAVE, // 41 Check if the user has autosaves enabled. Ignored for demoplayback.
DEM_DOAUTOSAVE, // 42 An autosave should be made 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 // 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 { // Dead players cannot morph
return false; return false;
} }
if (spawntype == NULL) if (spawntype == NULL)
{ {
return false; return false;
} }
if (!spawntype->IsDescendantOf (RUNTIME_CLASS(APlayerPawn)))
{
return false;
}
morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE)); morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
DObject::PointerSubstitution (actor, morphed); DObject::PointerSubstitution (actor, morphed);

View file

@ -122,18 +122,7 @@ void cht_DoCheat (player_t *player, int cheat)
break; break;
case CHT_MORPH: case CHT_MORPH:
if (player->morphTics) msg = cht_Morph (player, PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer), true);
{
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...";
}
break; break;
case CHT_NOTARGET: 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); 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) void GiveSpawner (player_t *player, const PClass *type, int amount)
{ {
if (player->mo == NULL || player->health <= 0) if (player->mo == NULL || player->health <= 0)

View file

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

View file

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

View file

@ -1138,14 +1138,14 @@ FUNC(LS_Thing_Damage)
FUNC(LS_Thing_Projectile) FUNC(LS_Thing_Projectile)
// Thing_Projectile (tid, type, angle, speed, vspeed) // 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); arg4<<(FRACBITS-3), 0, NULL, 0, 0, false);
} }
FUNC(LS_Thing_ProjectileGravity) FUNC(LS_Thing_ProjectileGravity)
// Thing_ProjectileGravity (tid, type, angle, speed, vspeed) // 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); arg4<<(FRACBITS-3), 0, NULL, 1, 0, false);
} }
@ -1315,35 +1315,35 @@ FUNC(LS_Thing_Hate)
FUNC(LS_Thing_ProjectileAimed) FUNC(LS_Thing_ProjectileAimed)
// Thing_ProjectileAimed (tid, type, speed, target, newtid) // 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) FUNC(LS_Thing_ProjectileIntercept)
// Thing_ProjectileIntercept (tid, type, speed, target, newtid) // 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 // [BC] added newtid for next two
FUNC(LS_Thing_Spawn) FUNC(LS_Thing_Spawn)
// Thing_Spawn (tid, type, angle, newtid) // 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) FUNC(LS_Thing_SpawnNoFog)
// Thing_SpawnNoFog (tid, type, angle, newtid) // 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) FUNC(LS_Thing_SpawnFacing)
// Thing_SpawnFacing (tid, type, nofog, newtid) // 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) if (thing == NULL)
return false; // not valid return false; // not valid
@ -1448,7 +1448,7 @@ FUNC(LS_Thing_SetGoal)
FUNC(LS_Thing_Move) // [BC] FUNC(LS_Thing_Move) // [BC]
// Thing_Move (tid, mapspot, nofog) // 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) FUNC(LS_Thing_SetTranslation)

View file

@ -125,12 +125,12 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz);
#define MAX_SPAWNABLES (256) #define MAX_SPAWNABLES (256)
extern const PClass *SpawnableThings[MAX_SPAWNABLES]; extern const PClass *SpawnableThings[MAX_SPAWNABLES];
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);
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, fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
bool leadTarget); bool leadTarget);
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);
bool P_Thing_Move (int tid, int mapspot, bool fog); bool P_Thing_Move (int tid, AActor *source, int mapspot, bool fog);
// //
// P_ENEMY // P_ENEMY

View file

@ -51,7 +51,7 @@ const PClass *SpawnableThings[MAX_SPAWNABLES];
static FRandom pr_leadtarget ("LeadTarget"); 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; int rtn = 0;
const PClass *kind; 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)) if ((GetDefaultByType (kind)->flags3 & MF3_ISMONSTER) && (dmflags & DF_NO_MONSTERS))
return false; 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); 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; rtn = false;
} }
} }
spot = iterator.Next();
} }
return rtn != 0; return rtn != 0;
@ -117,7 +126,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
// [BC] Added // [BC] Added
// [RH] Fixed // [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; 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); AActor *target;
FActorIterator iterator2 (mapspot);
AActor *source, *target;
source = iterator1.Next (); if (tid != 0)
{
FActorIterator iterator1(tid);
source = iterator1.Next();
}
FActorIterator iterator2 (mapspot);
target = iterator2.Next (); target = iterator2.Next ();
if (source != NULL && target != NULL) if (source != NULL && target != NULL)
@ -158,7 +170,7 @@ bool P_Thing_Move (int tid, int mapspot, bool fog)
return false; 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, fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
bool leadTarget) 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)) if ((defflags3 & MF3_ISMONSTER) && (dmflags & DF_NO_MONSTERS))
return false; return false;
while ( (spot = iterator.Next ()) ) if (tid == 0)
{
spot = source;
}
else
{
spot = iterator.Next();
}
while (spot != NULL)
{ {
FActorIterator tit (dest); FActorIterator tit (dest);
@ -376,6 +396,7 @@ nolead:
} }
} while (dest != 0 && (targ = tit.Next())); } while (dest != 0 && (targ = tit.Next()));
} }
spot = iterator.Next();
} }
return rtn != 0; return rtn != 0;

View file

@ -457,7 +457,6 @@ ACTOR(PlaySoundEx)
ACTOR(StopSoundEx) ACTOR(StopSoundEx)
ACTOR(SeekerMissile) ACTOR(SeekerMissile)
ACTOR(Jump) ACTOR(Jump)
ACTOR(JumpSet)
ACTOR(ExplodeParms) ACTOR(ExplodeParms)
ACTOR(CallSpecial) ACTOR(CallSpecial)
ACTOR(CustomMissile) ACTOR(CustomMissile)
@ -527,6 +526,9 @@ ACTOR(Stop)
* c = color * c = color
* x = expression * x = expression
* y = 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 }, #define FUNC(name, parm) { #name, name, parm },
// Declare the code pointer table // Declare the code pointer table
@ -677,8 +679,7 @@ AFuncDesc AFTable[]=
FUNC(A_PlaySoundEx, "STi" ) FUNC(A_PlaySoundEx, "STi" )
FUNC(A_StopSoundEx, "T" ) FUNC(A_StopSoundEx, "T" )
FUNC(A_SeekerMissile, "XX" ) FUNC(A_SeekerMissile, "XX" )
FUNC(A_Jump, "XL" ) FUNC(A_Jump, "XL+" )
FUNC(A_JumpSet, "XLLllllllllllllllllll")
FUNC(A_CustomMissile, "MXXxxx" ) FUNC(A_CustomMissile, "MXXxxx" )
FUNC(A_CustomBulletAttack, "XXXXmx" ) FUNC(A_CustomBulletAttack, "XXXXmx" )
FUNC(A_CustomRailgun, "Xxccxxx" ) FUNC(A_CustomRailgun, "Xxccxxx" )
@ -1655,6 +1656,14 @@ do_stop:
} }
int paramindex = PrepareStateParameters(&state, numparams); int paramindex = PrepareStateParameters(&state, numparams);
int paramstart = paramindex;
bool varargs = params[numparams - 1] == '+';
if (varargs)
{
StateParameters[paramindex++] = 0;
}
while (*params) while (*params)
{ {
switch(*params) switch(*params)
@ -1763,11 +1772,28 @@ do_stop:
v = -1; v = -1;
break; break;
} }
StateParameters[paramindex++]=v; StateParameters[paramindex++] = v;
params++; params++;
if (varargs)
{
StateParameters[paramstart]++;
}
if (*params) 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(); ChkCom();
} }
} }

View file

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