mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- Moved the implementation for the Thing_Damage special into another function
so that I can create the ACS function Thing_Damage2. It's exactly the same as Thing_Damage, except the damage type is specified by name. When I did this, I noticed that it didn't do anything useful for a TID of 0, so I made it affect the activator in that case. - Added a new SetActorState ACS function: int SetActorState (int tid, str statename, optional bool exact); If tid is 0, it affects the script activator, otherwise it affects all the matching actors. Statename is the name of the state you want to put the actor in. The final parameter, exact, specifies whether or not partial state name matches are accepted. If you don't specify it or set it to false, if you try to do something like: SetActorState (0, "Foo.Bar"); And the actor has a Foo state but no Foo.Bar state, it will enter the Foo state. If you set exact to true: SetActorState (0, "Foo.Bar", true); Then the actor must have a Foo.Bar state, or it will not change state at all, even if it has a Foo state. The return value for this function is the number of actors that successfully changed state. Note that you should refrain from using this function to enter special states such as Death, or unpredictable results could occur. SVN r505 (trunk)
This commit is contained in:
parent
38c821a96e
commit
490742cf46
7 changed files with 131 additions and 32 deletions
|
@ -1,6 +1,31 @@
|
|||
March 20, 2007
|
||||
- Moved the implementation for the Thing_Damage special into another function
|
||||
so that I can create the ACS function Thing_Damage2. It's exactly the same as
|
||||
Thing_Damage, except the damage type is specified by name. When I did this,
|
||||
I noticed that it didn't do anything useful for a TID of 0, so I made it
|
||||
affect the activator in that case.
|
||||
|
||||
March 19, 2007
|
||||
- Added a new SetActorState ACS function:
|
||||
int SetActorState (int tid, str statename, optional bool exact);
|
||||
If tid is 0, it affects the script activator, otherwise it affects all the
|
||||
matching actors. Statename is the name of the state you want to put the
|
||||
actor in. The final parameter, exact, specifies whether or not partial
|
||||
state name matches are accepted. If you don't specify it or set it to
|
||||
false, if you try to do something like:
|
||||
SetActorState (0, "Foo.Bar");
|
||||
And the actor has a Foo state but no Foo.Bar state, it will enter the Foo
|
||||
state. If you set exact to true:
|
||||
SetActorState (0, "Foo.Bar", true);
|
||||
Then the actor must have a Foo.Bar state, or it will not change state at
|
||||
all, even if it has a Foo state.
|
||||
The return value for this function is the number of actors that successfully
|
||||
changed state. Note that you should refrain from using this function to
|
||||
enter special states such as Death, or unpredictable results could occur.
|
||||
|
||||
March 13, 2007
|
||||
- Fixed: Morphed players did not regain their innate armor when unmorphing.
|
||||
(Only Hexen has players with innate armor.)
|
||||
(Only Hexen has players with innate armor, under normal conditions.)
|
||||
|
||||
March 12, 2007
|
||||
- Changed the default player.startitem amount from 0 to 1.
|
||||
|
|
11
src/info.cpp
11
src/info.cpp
|
@ -486,7 +486,7 @@ FState *AActor::FindState (FName label, FName sublabel, bool exact) const
|
|||
FStateLabel *slabel = info->StateList->FindLabel (label);
|
||||
if (slabel != NULL)
|
||||
{
|
||||
if (slabel->Children != NULL)
|
||||
if (sublabel != NAME_None && slabel->Children != NULL)
|
||||
{
|
||||
FStateLabel *slabel2 = slabel->Children->FindLabel(sublabel);
|
||||
if (slabel2 != NULL)
|
||||
|
@ -494,7 +494,14 @@ FState *AActor::FindState (FName label, FName sublabel, bool exact) const
|
|||
return slabel2->State;
|
||||
}
|
||||
}
|
||||
if (!exact) return slabel->State;
|
||||
if (sublabel == NAME_None && slabel->Children != NULL && exact)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!exact)
|
||||
{
|
||||
return slabel->State;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -4990,6 +4990,57 @@ int DLevelScript::RunScript ()
|
|||
sp -= 2;
|
||||
break;
|
||||
|
||||
case PCD_SETACTORSTATE:
|
||||
{
|
||||
const char *statename = FBehavior::StaticLookupString (STACK(2));
|
||||
const char *dot;
|
||||
FName label1, label2;
|
||||
FState *state;
|
||||
|
||||
dot = strchr (statename, '.');
|
||||
if (dot != NULL)
|
||||
{
|
||||
label1 = FName(statename, dot - statename, true);
|
||||
label2 = FName(dot + 1, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
label1 = FName(statename, true);
|
||||
}
|
||||
if (STACK(3) == 0)
|
||||
{
|
||||
state = activator->FindState (label1, label2, !!STACK(1));
|
||||
if (state != NULL)
|
||||
{
|
||||
activator->SetState (state);
|
||||
STACK(3) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
STACK(3) = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator iterator (STACK(3));
|
||||
AActor *actor;
|
||||
int count = 0;
|
||||
|
||||
while ( (actor = iterator.Next ()) )
|
||||
{
|
||||
state = actor->FindState (label1, label2, !!STACK(1));
|
||||
if (state != NULL)
|
||||
{
|
||||
actor->SetState (state);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
STACK(3) = count;
|
||||
}
|
||||
sp -= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCD_PLAYERCLASS: // [GRB]
|
||||
if (STACK(1) < 0 || STACK(1) >= MAXPLAYERS || !playeringame[STACK(1)])
|
||||
{
|
||||
|
@ -5095,6 +5146,11 @@ int DLevelScript::RunScript ()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
case PCD_THINGDAMAGE2:
|
||||
STACK(3) = P_Thing_Damage (STACK(3), activator, STACK(2), FName(FBehavior::StaticLookupString(STACK(1))));
|
||||
sp -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
** ACS script stuff
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2006 Randy Heit
|
||||
** Copyright 1998-2007 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -539,6 +539,8 @@ public:
|
|||
PCD_GETACTORPITCH,
|
||||
PCD_SETACTORPITCH,
|
||||
PCD_PRINTBIND,
|
||||
PCD_SETACTORSTATE,
|
||||
PCD_THINGDAMAGE2,
|
||||
|
||||
PCODE_COMMAND_COUNT
|
||||
};
|
||||
|
|
|
@ -1127,34 +1127,7 @@ FUNC(LS_Thing_Destroy)
|
|||
FUNC(LS_Thing_Damage)
|
||||
// Thing_Damage (tid, amount, MOD)
|
||||
{
|
||||
FActorIterator iterator (arg0);
|
||||
AActor *actor;
|
||||
|
||||
actor = iterator.Next ();
|
||||
while (actor)
|
||||
{
|
||||
AActor *next = iterator.Next ();
|
||||
if (actor->flags & MF_SHOOTABLE)
|
||||
{
|
||||
if (arg1 > 0)
|
||||
{
|
||||
P_DamageMobj (actor, NULL, it, arg1, MODtoDamageType (arg2));
|
||||
}
|
||||
else if (actor->health < actor->GetDefault()->health)
|
||||
{
|
||||
actor->health -= arg1;
|
||||
if (actor->health > actor->GetDefault()->health)
|
||||
{
|
||||
actor->health = actor->GetDefault()->health;
|
||||
}
|
||||
if (actor->player != NULL)
|
||||
{
|
||||
actor->player->health = actor->health;
|
||||
}
|
||||
}
|
||||
}
|
||||
actor = next;
|
||||
}
|
||||
P_Thing_Damage (arg0, it, arg1, MODtoDamageType (arg2));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_na
|
|||
bool leadTarget);
|
||||
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);
|
||||
int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type);
|
||||
|
||||
//
|
||||
// P_ENEMY
|
||||
|
|
|
@ -375,6 +375,41 @@ nolead: mobj->angle = R_PointToAngle2 (mobj->x, mobj->y, targ->x, targ->y);
|
|||
return rtn != 0;
|
||||
}
|
||||
|
||||
int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type)
|
||||
{
|
||||
FActorIterator iterator (tid);
|
||||
int count = 0;
|
||||
AActor *actor;
|
||||
|
||||
actor = (tid == 0 ? whofor0 : iterator.Next());
|
||||
while (actor)
|
||||
{
|
||||
AActor *next = tid == 0 ? NULL : iterator.Next ();
|
||||
if (actor->flags & MF_SHOOTABLE)
|
||||
{
|
||||
if (amount > 0)
|
||||
{
|
||||
P_DamageMobj (actor, NULL, whofor0, amount, type);
|
||||
}
|
||||
else if (actor->health < actor->GetDefault()->health)
|
||||
{
|
||||
actor->health -= amount;
|
||||
if (actor->health > actor->GetDefault()->health)
|
||||
{
|
||||
actor->health = actor->GetDefault()->health;
|
||||
}
|
||||
if (actor->player != NULL)
|
||||
{
|
||||
actor->player->health = actor->health;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
actor = next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
CCMD (dumpspawnables)
|
||||
{
|
||||
int i;
|
||||
|
|
Loading…
Reference in a new issue