Jump to content
The Dark Mod Forums

Can I pass an entity name to a map script?


Fidcal

Recommended Posts

We're probably all somewhat misunderstanding one another but whoever raised the possibility of passing the activator, although I don't want it for my current player notes, I can see it as useful for a general purpose method:

 

If LordSoAndSo pulled the Gatelever then....

If the player pulled the Gatelever then....

 

Your idea of getkey is fine - I used that for the combo lock - but it cannot pass an entity (or can it?) Mmm... maybe I used getFloat or something. If getkey can get any type then that is the way to go. It presumably relies on whatever variable type you are reading it into.

Link to comment
Share on other sites

  • Replies 62
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Or do I just really misunderstand what pass_self is?

 

I think you do :)

 

There are four (or more) entities involved when some ""Activate()" event happens:

 

* The activator: Whoever presses the button, opens the door, frobs the lever, or walks through the trigger. This is usually relayed from one entity to the next (but not for levers, buttons etc, they instead relay themselves, which I think is a bug!)

* The triggered entity. This is the "callWhatever" entity, which is linked from the trigger or the lever etc.

* The target entity, this is whatever is linked from the call entity.

 

Here is a chart:

 

post-144-128613469869_thumb.jpg

 

(Edit: Forgot to attach the image. Sorry)

 

1: activator, the player

2: lever, activated by the player. Should relay "activator=player" further on to 3, but due to missing code actually relays nothing (or itself) to the next entity.

3: the target (here: callscriptfunction/postscriptevent/callobjectfunction entity). It calls a function, and can pass along either "itself" (the pass_self spawnarg). This is important if you want f.i. someting to be teleported _exactly_ where this triggered target entity is situated. Or it can pass along _activator_ in this case the player.

4: The target, for this will the script function be called. Either via target->Method(...) (callobjectfunction), or as target->Event(...) (postscriptevent). The last possible way is "callscriptfunction", but this will simply ignore all the targets and just call one globalfunction once with no arguments like "SomeFunction();"

 

Now you will notice that none of these ways does exactly what fidcal wants :)

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Okay, this is finally wrapped up :)

 

I added support for a spawnarg called "foreach" on the atdm:target_callscriptfunction entity.

 

* if it is 0 (the default), the script function in "call" is called exactly once, without any arguments, as it was before (to not break old maps).

* if it is set to 1, the function is called for each target, and with the following fixed argument order: "FunctionName(target, activator, triggered_entity);"

 

I modified the test/player_notes.map to use this entity with these spawnargs now. As a bonus, you can now also use "delay" (an initial delay before the first call happens), "wait" (the basis wait time between calls), "wait_add" (a time (positive or negative) that is added to "wait" after each call, and "wait_mul", a factor that is multiplied with "wait" after each call.

 

So you can call the first function call after X seconds, and eachone coming in faster and faster, or slower and slower etc.

 

The testmap has an example for this, too. All the ways to add notes to the player inventory in the testmap work now.

 

To make it easier for mappers, I also added a new global function:

 

void addToPlayerInventory(entity target, entity activator, entity triggered)
{
       // ignore activator, because:
       // * due to some bugs it sometimes is not the player
       // * when an AI opens a door and this should be the trigger, we still
       //   want the item to go into the player inventory
  target.addItemToInv($player1);
}

 

Hope this finally solves this issue (you need a new DLL compiled, tho).

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Thanks Tels. I'll check this out when it gets compiled. A quick perusal - only query is passing of other variable types like floats etc and pass_me.

 

You mean you want to define additional params like so:

 

"param0" "1.2"
"param1" "-5"
"param3" "noggerbugger"

 

? That is certianly doable, albeit it will be a bit of work, because variable params to be implemented might be tricky. Plus, they would always be strings, so either you also need to define the type of variable like:

 

 

"param0" "1.2"
"param0_type" "float"
"param1" "-5"
"param1_type" "float"
"param3" "noggerbugger"
"param0_string" "float"

 

or I need to do some heuristics. Guess it is something for cold long winternights :D

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

As for those extra params, I think everything that can be used with getKey and bunk_spawnargs should be, so that gets you all floats, int's and strings from spawnargs into scripts. I even suspect you could get entities by a getKey'ing a proxy spawnarg that you convert/fill-in in the script with another variable type. like [[[ If spawnarg = "1" then { do something to $entity1 } ]]], but it depends on what you want to do I guess.

 

For the record, I did understand what "pass_self" was above. I just was thinking of an alternative way to do Fidcal's thing using 2 callfunction entities rather than 2 AI frobbing levers to do the same job; just seemed cleaner. But whatever works is cool. And it is better to pass entities directly to a script than mess with proxies, so that's a welcome addition, as is the putInInventory thing.

What do you see when you turn out the light? I can't tell you but I know that it's mine.

Link to comment
Share on other sites

Just thought of a way to make this work with any number of variables using a hybrid of your idea demagogue. Use this script entity to pass the name of an entity and put the keys you want to pass on *that* entity. Then use getkey to read any number of keys from it. The store entity can of course be something you are using anyway; for example the button that triggers the script entity.

Link to comment
Share on other sites

Just thought of a way to make this work with any number of variables using a hybrid of your idea demagogue. Use this script entity to pass the name of an entity and put the keys you want to pass on *that* entity. Then use getkey to read any number of keys from it. The store entity can of course be something you are using anyway; for example the button that triggers the script entity.

 

Ah, yes, of course. You can store the spawnargs on the entity that is the target of the "triggered script entity".

 

You can also store them on the CallScriptEntity itself, and since the script can retrieve them from there via GetKey(), it would be actually silly to try to parse this, then put it into the function args, when the function can also just do a GetKey() itself.

 

However, you can't store args on the button, as this is not relayed to the script. (This would be almost impossible, as there can be an arbitrary number of members in the relay chain, think trigger -> trigger_delay -> stim -> response -> callscriptentity -> target.)

 

You also could store them on the activator, with the cavet that: it must be an AI, not the player, and the activator is not always correctly forwarded to the script.

 

So, the best thing is to either store them on the final target, or the CallScript entity, and then retrieve them in the function.

 

So codewise the functionality should be done.

 

Please report your test results :)

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

@greebo:

 

What do you say to the thing with passing the activator from button/levers. Do you regard this as bug, too (that it doesn't relay it properly), and should Operate() get a new parameter for this, or should the script function just do:

 

button.Operate();
button.ActivateTargets($player1);

 

? The latter has the problem that if the Operate() fails (for whatever reasons, like button blocked) the Activate() still happens. So better would be:

 

button.Operate($player1);

 

Is there a problem changing the Operate() script event? And if so, maybe we can add:

 

button.OperatedBy($player1);

 

instead?

 

Tracked here: http://bugs.angua.at/view.php?id=2393

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Yes, I mean the last entity in the chain; the thing that targets the script caller entity.

 

But I don't see how you can use getkey on the script entity itself since how can you get the name of the script entity? Is pass_me still working? If so, how do we read it in the script?

Link to comment
Share on other sites

Yes, I mean the last entity in the chain; the thing that targets the script caller entity.

 

But I don't see how you can use getkey on the script entity itself since how can you get the name of the script entity? Is pass_me still working? If so, how do we read it in the script?

 

Erm, sometimes I think nobody reads my posts *sigh* :rolleyes::wacko:

 

First:

 

The "last entity in the chain" is indistinguishable from the "first entity in the chain" if you talk about the entities that target the "script caller entity". The reason is there is only entity passed along the chain, and that is the activator. Whoever passes that info along passes only that info along, but who passes it is completely lost. The script controller doesn't know who activates it (a lever? a button? the player?) it only knows who started the event.

 

Usually, this is the player, but it can also be an AI, or an auto-open door etc. (There is a bug that sometimes the activator is not passed along, but instead some entity along the chain. This is a bug. You can ignore this, as it will need to be fixed).

 

And second:

 

The "script caller" thingy calls (in the new functionality I added and already explaine :) a function call with the following arguments:

 

myFunction( target, activator, script_caller );

 

inside that function you can retrieve:

 

* who started the chain (bugs nonwithstanding) and any of its spawnargs (player, AI, auto-door, whatever)

* the target (that thing the script caller entity points at) and any of its spawnargs

* the script caller itself and any of its spawnargs

 

In this case, you do not need any "pass_self".

 

In the other, already existing cases, if you use "pass_self", the script caller is "self" and if you use "pass_activator", the activator (who started the chain) is the activator.

 

I am at a loss on how to explain this more clearly, I thought we already had it all unravalled :)

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Steady on - these are just misunderstandings. I do read the posts but you are not always clear so there is plenty of room for mistakes.

 

Looking back, in my post of http://forums.thedarkmod.com/topic/11772-can-i-pass-an-entity-name-to-a-map-script/page__view__findpost__p__233470 I used the term 'triggering_entity' and defined it with numerous examples as something that triggers, ie something that initiates the whole thing. This is the game event that starts the whole process. As a mapper that is what I am interested in. A gate locks, a crate falls, an AI dies, and it triggers something via script. I'm not talking about an activator but a game situation.

 

You used a similar term 'triggered_entity' in your post of http://forums.thedarkmod.com/topic/11772-can-i-pass-an-entity-name-to-a-map-script/page__view__findpost__p__233494 so I misread that as what I wanted, the initiating entity, whether it be the first or last in chain of relays is not important.

 

Only now you are saying this is the script caller so why not call it that so everything would be clear? You must admit it is very strange (to me anyway) that doom code is unable to tell what last entity targetted the script caller. That is, if entity 1 targets entity2 then there is no way to detect that it was entity1 that triggered it. If it could then only a single script caller would be needed for the same script event. As it is, we need a separate script caller for most situations. This is also true for addToPlayerInventory. I may need 10 or 20 extra entities because each one has to carry the variable that defines what action to take.

 

Anyway, it makes no difference to the functionality so long as there is one named entity that the script can get all necessary variables (hopefully. ;))

Link to comment
Share on other sites

Steady on - these are just misunderstandings. I do read the posts but you are not always clear so there is plenty of room for mistakes.

 

Looking back, in my post of http://forums.thedarkmod.com/topic/11772-can-i-pass-an-entity-name-to-a-map-script/page__view__findpost__p__233470 I used the term 'triggering_entity' and defined it with numerous examples as something that triggers, ie something that initiates the whole thing. This is the game event that starts the whole process. As a mapper that is what I am interested in. A gate locks, a crate falls, an AI dies, and it triggers something via script. I'm not talking about an activator but a game situation.

 

You used a similar term 'triggered_entity' in your post of http://forums.thedarkmod.com/topic/11772-can-i-pass-an-entity-name-to-a-map-script/page__view__findpost__p__233494 so I misread that as what I wanted, the initiating entity, whether it be the first or last in chain of relays is not important.

 

I used the term "script entity" because that is what you used :) I formerly used the term "triggered entity" because it was the entity that is triggered by the lever, but you are right, this is misleading as there can be many triggered entities.

 

Probably need to make a clear wiki article.

 

You must admit it is very strange (to me anyway) that doom code is unable to tell what last entity targetted the script caller. That is, if entity 1 targets entity2 then there is no way to detect that it was entity1 that triggered it. 

 

This is simply an artefact of the code. The code to trigger the "next entity" is:

 

[code
Entity->Activate(entity activator);
[/code]

And you can see it allows only passing one bit of info (the activator) along. The reason is that this function can be automatically cale (when you f.i. trigger a trigger in game), or from code (fi. when something else happens).

Of course, if would be possible to extend this, but apparently nobody needed that before, and it will prove almost impossible to shoehorn this into the existing interface.


If it could then only a single script caller would be needed for the same script event. As it is, we need a separate script caller for most situations. This is also true for addToPlayerInventory. I may need 10 or 20 extra entities because each one has to carry the variable that defines what action to take.


Well, I think it might be possible to add some bit of magic that a script entity looks up what entity triggers it and retrieves a spawnarg from this - but it would only be of limited purpose as you would never be able to add a chain:

 

The script entity would get the activator (player here), but how should it know that the lever or the trigger_relay is the one it needs in addition?

 

Anyway, it makes no difference to the functionality so long as there is one named entity that the script can get all necessary variables (hopefully. ;))

 

It is, either itself, or the target entity (the script entity calls the global function for each of its target entities).

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Yes, but those are only one variable type. The majority of variables will probably be retrieved using getkey, getfloat etc. That is what I want to test when this is compiled because they will likely be the most important.

 

Well, I think it might be possible to add some bit of magic that a script entity looks up what entity triggers it and retrieves a spawnarg from this - but it would only be of limited purpose as you would never be able to add a chain:

 

player => lever => trigger_relay => script_entity

 

The script entity would get the activator (player here), but how should it know that the lever or the trigger_relay is the one it needs in addition?

I don't understand the above at all. You are saying it might be possible to pass the entity that triggers the script entity? Can you not see how useful that would be? It means a single script caller can be used per script event.. The particular link in the chain is irrelevant. Only the chain matters identified by *any* link so the final one that targets the script calling entity is the logical one. The activator is important but only of use in special cases.

 

Let me give an example using the player notes idea:

 

A gate closes. It doesn't matter who closes it only that it has been closed:

gate3 > counter > once_only_relay > whatever > delay77 > script caller99 > call add inventory script event

if delay77 then add note 16 to inventory (or if gate3 I don't care which because both are exclusive to this chain. Both identify this chain and only this chain so either will do. What matters here is that the gate closes not who closed it or even if it auto-closed or was triggered by a random trigger or whatever.

 

A crate falls off a ledge. Doesn't matter who pushed it or if it was random. It falls into a trigger_brush:

trigger_brush > relay1 > relay2 > whatever > delay24 > script caller99 > call add inventory script event

if delay24 then add note 44 to inventory.

 

Notice that both of the above call a single script caller: script caller99 which is used exclusively for adding any number of notes as needed. Script caller99 might be named AddNotesToPlayer or whatever. Who knows how many notes and a script caller for each one will be needed?

 

Any particular link in the chain is irrelevant. Only that the chain is identified in some way so the script knows which note to add.

 

A single script event is used and a single script caller entity is used. If the activator is also passed then by this means a mapper can do virtually anything. He can read a dozen different variables of different types using getkey (if it does - I've still not had chance to try it.)

 

Let me repeat what has been said throughout this thread. In most cases the mapper has NO interest in the activator. That is for special cases. What is the mapper interested in? The mapper is interested in passing variables, some with specific values, some just as a signal to tell the script specifically what to do. What kind of variables? ALL KINDS OF VARIABLES, not just entities but floats, strings, vectors, etc.

 

Take a look at Alchemist. I had to use NINE different calling entities for each of two combo locks; that's EIGHTEEN entities where one would do.

 

In Heart I had 10 calling entities for 10 secrets.

 

Now if it's technically not possible in our code then so be it but I'd hate to think it didn't happen just because you thought mappers were only interested in activators and entity types.

Link to comment
Share on other sites

OK, code is now compiled for Windows on SVN so I can try things out.

I made another test map which I'll probably submit over the next few days test/script_parms.map

 

Info is fragmented all over this thread, incomplete, and changed as it went along plus info from the map that is not obvious from this thread so I'm gathering in this thread a summary of everything so it can go on the wiki. Correct me if anything wrong.

 

WIP NOTES:

 

================================

atdm:target_callscriptfunction

 

call = script to be called

 

foreach = 0 (default) = calls script once, no arguments, as before

 

foreach =1 = calls script multiple times, once for each target, and with the following fixed argument order: "FunctionName(target, activator, script_caller);"

 

target = entity to be passed to script. Any number of targets can be passed using the normal syntax target1, target2, etc. Note that the script is called multiple times and target is passed each time. If you wish to pass several entities at once or other variable types such as floats then see [[*Passing other variables]] below

 

activator = initiating entity, eg, player, AI, sys?

[test: what do I get if there is no obvious activator? sys?]

 

script_caller = the name of this atdm:target_callscriptfunction

[test: might be possible to use getkey, getfloat etc to get other params]

 

Optional extra spawnargs:

delay = delay before the first call

wait = wait between calls

wait_add = (positive or negative) added to "wait" after each call

wait_mul = a factor that is multiplied with "wait" after each call.

 

So you can call the first function call after X seconds, and each one coming in faster and faster, or slower and slower etc.

 

Example script 1:

 

void myScript()

{

do something;

//No arguments needed or received because the spawnarg 'foreach' is left at the default 0

}

 

 

TO BE TESTED....

Example script 2:

 

void myScript(entity mytarget, entity activator, entity scriptCaller)

{

string mykey;

 

//activator unused here but has to be included in args

//scriptCaller unused here but has to be included in args

 

mykey = mytarget.getKey("myparm1");

 

if (mykey == "99") etc etc

}

 

 

==============================

 

New inventory script event: addToPlayerInventory

 

Call from atdm:target_callscriptfunction entity with target. The target will go into the player inventory, eg,

 

atdm:target_callscriptfunction

call addToPlayerInventory

target my_gift_to_player

 

In the above, the entity named 'my_gift_to_player' will be added to the player's inventory when this atdm:target_callscriptfunction entity is triggered.

 

===============================

 

atdm:target_postscriptevent (*this is the self referred to in pass_self below)

 

event = script to be called

 

pass_self = 1 = self* = first argument

 

pass_activator = 1 = activator = first argument (except if pass_self is 1 then pass_activator is second.)

 

Optional extra spawnargs:

delay = delay before the first call

wait = wait between calls

wait_add = (positive or negative) added to "wait" after each call

wait_mul = a factor that is multiplied with "wait" after each call.

 

So you can call the first function call after X seconds, and each one coming in faster and faster, or slower and slower etc.

 

target = entity to be passed to script. Any number of targets can be passed using the normal syntax target1, target2, etc. Note that the script is called multiple times and target is passed each time. If you wish to pass several entities at once or other variable types such as floats then see [[*Passing other variables]] below

 

propagate_to_team = 1 = event also propagated to the team (aka any bound children) of each target. (??)

 

===================================

 

==Passing other variables==

 

WIP

Link to comment
Share on other sites

Yes, but those are only one variable type. The majority of variables will probably be retrieved using getkey, getfloat etc. That is what I want to test when this is compiled because they will likely be the most important.

 

I don't understand the above at all. You are saying it might be possible to pass the entity that triggers the script entity? Can you not see how useful that would be? It means a single script caller can be used per script event.. The particular link in the chain is irrelevant. Only the chain matters identified by *any* link so the final one that targets the script calling entity is the logical one. The activator is important but only of use in special cases.

 

Let me give an example using the player notes idea:

 

I see what you mean, but this is *completely* unsupported in the code. And by completely I mean the id design doesn't even attempt to do this. All what the target entity knows is that it:

 

* got Activated()

* and who is the activator (which is usually the player, or an AI)

 

Yeah, if you think about it, it would have made sense to keep a stack of the full chain and a lot of other info (like not only having Activate(), but also Deactivate(), and Toggle() events), but apparently for a mindless shooter having a way to distinguish between a monster and the player upon triggering a teleport or something was enough :)

 

We just have to live with that, or somebody needs to go and design a whole new system and then use it everywhere to replace the old one. I don't think this is going to happen, tho. Sorry.

 

Take a look at Alchemist. I had to use NINE different calling entities for each of two combo locks; that's EIGHTEEN entities where one would do.

 

While entities are not cheap, it does not really matter whether you waste 10 or 20 more or less. We have 8192 to play with :)

 

Especially the "scipt caller" and so on are passive entities - they don't do anything until they are needed, so they do not waste CPU, only abit of memory, and we have enough of that.

 

(I regulary test maps with multiple thousand of entities and I can attest it works just fine - unless you try all of them to be something that is rendered or used for collision testing :)

 

Also, IMO it is easier to visually see 10 entities that target 10 other entities and do something, than have one entity and the spawnargs on other entities. The first is "visual coding", the latter is "data driven coding". And while the data driven does has its advantages (less entities) it also has the disadvantage that it is hard to debug/change.

 

For instance, if the spawnarg you mention is an entity name, how would DR know that if you rename the entity, it also must rename the spawnarg? With the "target" links this is done automatically, so it frees the mapper from this task and makes things more error prone.

 

Anyway, I see that you would like to have it otherway, but I see no way atm.

 

In Heart I had 10 calling entities for 10 secrets.

 

Now if it's technically not possible in our code then so be it but I'd hate to think it didn't happen just because you thought mappers were only interested in activators and entity types.

 

I didn't design the id engine :)

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

OK, code is now compiled for Windows on SVN so I can try things out.

I made another test map which I'll probably submit over the next few days test/script_parms.map

 

Info is fragmented all over this thread, incomplete, and changed as it went along plus info from the map that is not obvious from this thread so I'm gathering in this thread a summary of everything so it can go on the wiki. Correct me if anything wrong.

 

WIP NOTES:

 

================================

atdm:target_callscriptfunction

 

call = script to be called

 

foreach = 0 (default) = calls script once, no arguments, as before

 

foreach =1 = calls script multiple times, once for each target, and with the following fixed argument order: "FunctionName(target, activator, script_caller);"

 

activator = initiating entity, eg, player, AI, sys?

[test: what do I get if there is no obvious activator? sys?]

 

There is always something that activates an entity, even if it is the entity itself (like an auto-close door). The only way you get something else is:

 

* manually calling $entity_name->Activate( $some_other_entity );

* manually calling $entity_name->Activate( $null_entity );

* the C++ code somewhere deep inside calls ActivateTargets(this); (e.g. you get self, the entity itself activated it) This is usually a bug, but also can happen if there is no activator, like when a door auto-closes. The latter is the most common case.

 

Frankly, the whole Activate() thing seems not entirely thought through, in some cases never used (like our callobjectfunction) and in some cases just plainly buggy. However, don't blame me for that :)

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Just thought of a way to make this work with any number of variables using a hybrid of your idea demagogue. Use this script entity to pass the name of an entity and put the keys you want to pass on *that* entity.

 

Uh, that wasn't just a hybrid of my idea. That *was* my idea, lol. Admittedly not well explained maybe. :laugh:

(Edit: In fairness, not explained at all in my last post, but I think in a previous post; it's what I meant anyway. But if you follow the method below, it will explain why I didn't emphasize it; edit2: Now with PPS to directly explain it.)

 

I'm going to try to describe my original "pass_self" idea again, and see if it makes sense now. I know that Tels likes pass_activator (or has been talking about it all this time; I wouldn't say he "likes" it), but it has a few quirks, and I'm still not sure what's wrong with my approach. But I might not have explained it well yet.

 

The key to my idea is to remember: 2 different Script Callers can call the SAME SCRIPT. Then remember that the SAME SCRIPT can get the name of BOTH SCRIPT CALLERS with "pass_self", depending on which one called it. (Notice I'm not even mentioning pass_activator; it's not part of my scheme at all, but it is for what Tels has been talking about in all his posts.)

 

So I'm going to explain this by repeating Fidcal's instructions[*footnote] with changes made in bold. Notes:

* This is all happening in ONE SCRIPT function I'm going to call "Fid_add_inventory".

* That function is declared in the script like "void Fid_add_inventory( entity script_caller_name )",

* The "script_caller_name" variable is, you guessed it, the name of the script_caller, which is passed by "pass_self".

* Then there are TWO script call entities, 100 & 101,

* BOTH 100 & 101 call "Fid_add_inventory" and BOTH have "Pass_self" "1".

 

A gate closes. It doesn't matter who closes it only that it has been closed:

gate3 > counter > once_only_relay > whatever > delay > script caller100 > call "Fid_add_inventory" script event.

if script_caller_name == script caller100 then add note 16 to inventory

 

A crate falls off a ledge. Doesn't matter who pushed it or if it was random. It falls into a trigger_brush:

trigger_brush > relay1 > relay2 > whatever > delay > script caller101 > call "Fid_add_inventory" script event.

if script_caller_name == script caller101 then add note 44 to inventory.

 

Does that make sense? No tracking of who frobs what, just handle each case with its own separate script caller entity. Clean & easy.

 

(P.S. I totally sympathize with all the confusion, so that's why I used CAPS and bold and over-explaining; I'm not trying to sound patronizing!)

 

P.P.S. Going back to getKey'ing spawnargs from the start of this post: If you had

if script_caller_name == script caller100 then getKey $any.old.entity1("X")
and 
if script_caller_name == script caller101 then getKey $any.old.entity1("Y")

or some variation of that, then you can see how you could still put the spawnargs on any old entity and get the same result as putting it on the script caller entity itself. That's why I didn't emphasize it. But you're right, in a lot of cases it's probably easiest to just put the spawnargs on the script_caller_entity itself and keep it straight-forward. Then it's just [[ getKey script_caller_name("X"); ]] for every case. Yes, that's very easy too, and more compact & versatile.

 

Edit3: *Footnote. What Fidcal wrote before wouldn't work for the reason Tels mentioned. You (unfortunately) can't pass a "delay" entity, or a "lever", or anything else in the chain (with the one exception for the last link alone, the script caller itself, with "pass_self"). Otherwise, you can *only* pass $player1 triggering the chain with "pass_activator" (or an $AI in the rare case it's an AI that triggers it; and if there are multiple activators in the chain, it just passes the most recent activator, the last "guy" that touched something, remembering that it's usually $player1 even when it looks like it's going off on its "own power".).

What do you see when you turn out the light? I can't tell you but I know that it's mine.

Link to comment
Share on other sites

Not sure I've grasped the main point of your post demagogue but if it is a wish to be able to pass the script caller then that *is* possible with both these two types. So it now does almost everything we want.

 

I'm still collecting the info together and testing to check what they all do and will eventually do a wiki article (see my post a few posts back.)

Link to comment
Share on other sites

Not sure I've grasped the main point of your post demagogue but if it is a wish to be able to pass the script caller then that *is* possible with both these two types. So it now does almost everything we want.

 

I know. I wasn't wishing for it. I was giving instructions for how to set it up to do your task (if you wanted to; or just to see how it would work).

 

My main point was that the instructions you posted for your inventory task won't work (you can't pass a "delay" entity, or "relay", or "lever", etc), so I re-wrote your instructions in a form that will do your task using "pass_self". I thought, since you posted those instructions, you should see what was broken and how to make it work.

 

My secondary point was the suggestion that *all* tasks of this general type should be handled by "pass_self" following these instructions, and not any other way (i.e., not using "pass_activator", which is unreliable; forget AI pulling levers IMO).

 

One footnote: unless, of course, there's a direct function like a put_In_Inventory to do a task. But if not, my thesis is: "pass_self" is the best way (IMO) to get one script to handle multiple "triggerable" conditions in the world, for ANY and ALL tasks of this form. I can make a test map and write a wiki entry on it since I think it's so versatile.

 

I'm still collecting the info together and testing to check what they all do and will eventually do a wiki article (see my post a few posts back.)

 

Very good. That's helpful. We should also explain it in layman's terms and idiot-proof it as much as possible, e.g., using very concrete examples (like your inventory-task, and the ones Tels mentioned, teleporting & the other one) and pictures of the entities, for each item, so people can see what's going on in concrete practice.

What do you see when you turn out the light? I can't tell you but I know that it's mine.

Link to comment
Share on other sites

Take a look at Alchemist. I had to use NINE different calling entities for each of two combo locks; that's EIGHTEEN entities where one would do.

 

It does suck that you have to use many calling entities (though you already have to use 18 triggers; nature of the beast). But at least you can still make them all call the same single script (not 18 of them) and the script can act based on which calling entity called it (so it knows which "chain" it's on).

 

And if you can do that, then you should be able get the script to GetKey any specific variables off a single entity based on which calling entity called it (except for "entity" variables, in which case you need to pass "target"), or you can even hard wire the parameters into the script itself (if they aren't changing in the game), according to which calling entity called it. So you can still have 1 script and put most variables as spawnargs on 1 entity, and all the script callers have to contribute is their name. It's just the number of script calling entities itself that's hard to get around.

 

By the way, crazy idea: can trigger entities inherit callObjectFunction in their .def, target themselves, so they "call" the script themselves and "pass_self" so the script gets their name? If it worked, that would save you your extra entities. :P

What do you see when you turn out the light? I can't tell you but I know that it's mine.

Link to comment
Share on other sites

That's not so crazy because some other entities already can call script direct. For instance, you can call a script from a trigger_once I think so probably all those trigger types. Also buttons I think. I recall in the combo lock I set it up to call direct from the buttons but there was a separate problem in that particular case so I redid it.

 

I'll try to remember to look at these different options when I do the article.

Link to comment
Share on other sites

Yeah I just had a look, all (or most) triggers have a "call" spawnarg. It should be easy to expand this to support "foreach" so each trigger not only calls the script function once, but for each of the targets. If you then link all the stuff to the trigger, you could skip the callscript entity. Good idea.

 

Please file a tracker for this, or I'll forget it again. Won't have time until wednesday.

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." -- George Bernard Shaw (1856 - 1950)

 

"Remember: If the game lets you do it, it's not cheating." -- Xarax

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recent Status Updates

    • nbohr1more

      Was checking out old translation packs and decided to fire up TDM 1.07. Rightful Property with sub-20 FPS areas yay! ( same areas run at 180FPS with cranked eye candy on 2.12 )
      · 2 replies
    • taffernicus

      i am so euphoric to see new FMs keep coming out and I am keen to try it out in my leisure time, then suddenly my PC is spouting a couple of S.M.A.R.T errors...
      tbf i cannot afford myself to miss my network emulator image file&progress, important ebooks, hyper-v checkpoint & hyper-v export and the precious thief & TDM gamesaves. Don't fall yourself into & lay your hands on crappy SSD
       
      · 5 replies
    • OrbWeaver

      Does anyone actually use the Normalise button in the Surface inspector? Even after looking at the code I'm not quite sure what it's for.
      · 7 replies
    • Ansome

      Turns out my 15th anniversary mission idea has already been done once or twice before! I've been beaten to the punch once again, but I suppose that's to be expected when there's over 170 FMs out there, eh? I'm not complaining though, I love learning new tricks and taking inspiration from past FMs. Best of luck on your own fan missions!
      · 4 replies
×
×
  • Create New...