Page 1 of 1

Let’s develop: Actor Internal Variables

PostPosted: Sat May 21, 2005 8:41 pm
by Sphagne
Let’s develop: Actor Internal Variables



OK, here is another attempt with cooperative feature developments. Hope this one is more successful.

If you are a C programmer and have enough time to spare on this, please give it a try, because it is worth the effort.



With this feature we want to add some internal general-purpose variables to our DECORATE actors that would hold some information inside each actor for later use, and would let us control the behavior of our actors and weapons via ACS.



If this feature were fully implemented, it would give us some additional possibilities with our decorate actors, like:

We could program new states for our actors, i.e. at some point toggle a flag to trigger a new behavior, and after that, check that flag in our default states to behave differently if set.

For instance in an ACS script we could have an option to give our companion guard a new weapon, and would set an internal variable to trigger the use of that new gun.

If these variables are implemented for the player actors and would be used for weapon definitions, then we could implement weapon mods like silencers or add new fire modes and so on...

With the help of these internal variables, we could start counters to trigger delayed actions.

For instance, we could make actors that behave normally, but have limited life span, or actors that are scared for a limited time and would revert to normal behavior after a while, or like timed bombs that would explode after a while and so on...

These internal variables would enable a great communication bridge between DECORATE lump and ACS script, because those would be a common storage pool that could be accessed by both the different action medias.

Thus, we could change these variables in one media and check them in the other one to take proper action, and vice versa, thus we could control the behavior of our actors and weapons via ACS.



There are lots and lots of different scenarios that could be implemented with the help of these internal variables, but for an example, we can make advanced stealth based modes, like this:

We can make guns that would not awaken the monsters by default, but in their normal fire animation, we could play a loud sound and would call an action function to awaken the monsters.

However, there can be silencer mods that could be added to our guns that would set an internal variable of the player actor, and in the guns’ fire animation, we could check this variable, so that if it was set, then we could change the fire sound and skip the monster awakening part, thus effectively make a silenced weapon.

In addition, we can emulate aware and unaware monsters, like this:

In the beginning of the Spawn state we can clear a variable and in the beginning of the See state we can set it, and after that any time we want to check if the monster is *aware* we can check that variable.

In the death state of the monsters, we can check this variable to see if it was previously aware of us or not, and if it was aware, we can call that “monster awakening” action function to awaken the surrounding monsters. Otherwise, it would die silently and would not awaken the other monsters.

If combined with that “Monster Sight” thingy of my other “Let’s Develop” thread, this would let us make great stealth based levels.



We need to add for instance 16 integer fields to our actors, that could be set by the DECORATE lump for their default values, for the actors.

We also need to add some DECORATE action functions to the current ones, hope Graf would help us with the implementation, but for the starters, we can look the current action function implementations for examples.

Set and check functions:

A_SetVal (index, value)
A_SetValRand (index, val1, val2)
A_JumpValEQ (index, value)
A_JumpValLT (index, value)
A_JumpValGT (index, value)
A_JumpValIN (index, val1, val2)

Some arithmetic:

A_AddVal (index, value)
A_AddVals (index1, index2)
A_SubVals (index1, index2)
A_MulVals (index1, index2)
A_DivVals (index1, index2)

Optional bonus actions:

A_SetValToHealth (index)
A_SetValToSectorLight (index)
A_SetValToHeight (index)
A_SetValToTargetHeight (index)
A_SetValToTargetDist (index)
A_SetValToDir (index)

A_SetHealthToVal (index)
A_SetDirToVal (index)

Optional boolean results:

A_SetVal_if_WaterZone (index)

Optional, set an internal value to reflect a flag bit of the actor:

A_SetVal_to_FlagBit (index, flag_index)

for instance A_SetVal_to_FlagBit (5, FLAG_Floating) would set variable 5 to 1 if the actor is floating, otherwise 0.

We also need to add some ACS functions to access these variables:

Thing_SetValue (tid, val_index, value);
a=Thing_GetValue (tid, val_index);

as always tid of 0 means the activator.

Note: All of these, if used in weapon definitions would refer to the player actor.

Complexity: moderate, but with each optional feature, a bit more complex.


Action log:

I am waiting for comments to add the action steps.

OK, now is the critical part:

Is there any volunteer programmer who likes to join in, so that we can develop this new feature?

I am sure that it is worth the effort, and the time spent on it, would not be a wasted time.

I know at first, it may look a bit daunting, but after that, it would find its pace, and hopefully would become promising enough for Randy to decide to join in and help us along.

Thanks in advance.

PostPosted: Sun May 22, 2005 12:47 am
by MartinHowe
Programmer-defined variables in new actor classes like this would have helped me a lot. However, until ACS scripts can be passed something other than a TID, writing action functions in ACS is a pain (I know, I've done it).

It would be nice if all items in a game could have acces to Doom's internal TID that is equivalent to the pointer used at C/C++ level in the rest of the source code, so that one could write truly generic functions without having to give all monsters a TID. For example, GetActivatorMobjPointer() or something like that. Of course there would then need to be Mobj* (or whatever) compatible versions of the other routines.

This would be hard work, potentially, but it would make truly custom action functions possible at last. Right now, you have to hack them using global variabes or arrays and assign a TID to every object that you might want to use with them, which, logically, is unnecessary for action functions. I disagree with the idea that ACS is not powerful enough to implement custom action functions; while ACS isn't as powerful as C, you can do a hell of a lot with it and it's better than nothing. String handling support in ACS would make ACS near-complete for this purpose (but that's another discussion).

PostPosted: Sun May 22, 2005 1:32 am
by Hirogen2
Sphagne: write the code.
For anything else, we could [try to] import something like UnrealScript.

PostPosted: Sun May 22, 2005 8:57 pm
by Sphagne
ACS has a great power that would help us a lot, i.e. in lots of these ACS functions passing tid of 0 means the activator of the script.

There can be lots of scenarios that this power would help us a lot, for instance you give a line, a special, that would be run if an actor passes it, and run a script with a tid of 0, this would refer to the actor that has just passed the line.

By the way, these internal variables would let us reduce the amount of the *slow* ACS usage from within the DECORATE code, and that would be great.

On the other hand, they would also give us the power to control the flow of our DECORATE action functions from within ACS code, like the changing attack weapon of an actor, or it's walking animation, and so on...

The power to control individual actors from inside the ACS would be a great feature, but that can be another feature suggestion, and has no impact on usefullness of the actor's internal variable with the current ACS capabilities. :wink:

These would be useful if we ignore the ACS totally, think about delayed DECORATE actions or new states of actor behavior, triggered from within the DECORATE code itself, and so on...

Hirogen2, do you remember the last time we discussed about Unreal Script, in these forums?

PostPosted: Mon May 23, 2005 3:35 pm
by Hirogen2
>Hirogen2, do you remember the last time we discussed about Unreal Script, in these forums?

No, but I could use the search feature... 2nd excellent thing after my memory (wrt. neurons and ai) :-)

PostPosted: Tue May 24, 2005 3:12 am
by MartinHowe
Sphagne wrote:ACS has a great power that would help us a lot, i.e. in lots of these ACS functions passing tid of 0 means the activator of the script.
Indeed, but what if you need to use a function (inside your own function) that takes a TID and an object hasn't got one? Getting hold of a Mobj pointer (or whatever it's called in the ZDoom source) would be cool.

PostPosted: Thu Jul 21, 2005 11:06 am
by MartinHowe
Ok, via an unholy alliance of me in one of those "dammit, gotta do it myself" moods and Graf formalising it, the internal variables thing has been done for the unofficial build! Apologies to Sphagne, I'd forgotten about this thread we're reading now. However, the idea is so obvious to the programmers amongst us.

The example WAD I posted in the other thread contains one way of creating a truly generic ACS-level MOBJ handle (by any other name) so there's little need for TIDs in generic action functions in ACS anymore. I'm not sure off the top of my head which ACS functions MUST be given an explicit TID (i.e., won't work on "the activator" if TID is zero). Anyway, time to rewrite the scurrying rat and reactor room monsters code in my (WIP) Butchery map, once this becomes official. I hope it does, but then who knows what Randy's long-term plans are? Thanks to Graf anyway for taking this onboard.

PostPosted: Thu Jul 21, 2005 3:14 pm
by Sphagne
Thanx guys, great work so far. :smile: