Jump to content
The Dark Mod Forums

Ungoliant's mapping questions


ungoliant

Recommended Posts

alright, that last one actually wasn't what i needed. I guess what I want to know now is how setting up my own user-defined parameters to pass in script functions works. Can I create my own and just pass whatever i want? what kind of restrictions are there on that sort of thing?

Link to comment
Share on other sites

What exactly are you trying to achieve?

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

that is a pretty long assed story. i'd rather get some education than achieve the specific result though.

 

alright i'll give you the rough of it. I want to access an entity dynamically rather than explicitly, to call a script event on it. i have many buttons and many doors. each button opens or closes a pair of doubledoors. each open or close action needs to run 2 different script functions that are part of a sortof state machine thing. a statecheck and a statechange. the statecheck is where i want to fire off a script event on one of the doors.

so right now the setup is thus: a button targets door1, door2, and a target_callscriptfunction entity that calls stateCheck every time the button is pressed. when door1 is activated by the button it also targets a separate target_callscriptfunction entity that calls stateChange.

 

So, I want to run script event on door 1. the script function that wants to do this is called by target_callscriptfunction that is activated by button that targets 3 things, 1 of which is door 1. So somehow i need to chain back and forth to get to door1 to call it dynamically. Like, activator.target(3).scripEventX()

 

I do not know how to do that. If i don't do that i need a pair of target_callscriptfunction's and a new function (that does the exact same thing) for each button+doorpair to call the different doors explicitly. I refuse to do that on general principle and would rather set my map on fire.

Link to comment
Share on other sites

alright i guess the foreach 1 + call does work, i thought it was going to trigger the target, but I guess it doesn't. That was hella fun figuring out how to work all that garbage. Also unpredictable results if you don't start with target0, but printing getName() on all the args passed helps to figure out exactly what is going on. Also i had no idea that you don't put the arguments in the call spawnarg. its just 'call stateCheck' not 'call stateCheck(this, that, other)'.

 

Now on to the next problem, the state machine simply isn't going to accommodate multiple sets of doors without some kind of fancy footwork, unless i can come up with a better implementation, because its pulling states from random doors that might be opened/closed at any time, and i think a new state machine might be required for each set...

Here is a copy of the script if anyone wants to take a stab at it:

 

 

void stateCheck(entity A, entity B, entity C)  //trigger with button only, fires every time button is pressed.
//shouldn't matter if fired before/after stateChange()
{
sys.print("checking doorState value\n");
if(doorState && !k)
{
 sys.print("door is open and sound has not fired yet\n");
 //$elevator_cargo_floorb_door2.startSound( "snd_lockpick_pin_14", 0, 1 );
 A.startSound( "snd_lockpick_pin_14", 0, 1 );
 //sys.print(A.getName() + "\n");
 //sys.print(B.getName() + "\n");
 //sys.print(C.getName() + "\n");
 k++;
 sys.print("sound fired\n---------------\n");
}
else
{
 sys.print("door is closed, or is open and sound has already fired\n------------------\n");
}
}
void stateChange()  //trigger with door only, fires only on_close and when_opened
 //shouldn't matter if fired before/after stateCheck()
{
sys.print("changing door state to: ");
if($elevator_cargo_floorb_door2.IsOpen())
{
 sys.print("open\n-------------------\n");
 doorState = 1;
 k = 0;
}
else
{
 sys.print("closed\n--------------------\n");
 doorState = 0;
}
}

 

basic rundown: doors are all set uninterruptable, k represents whether sound has been fired, doorState is if its fully open/closed when checked. sound should only be fired if k=0, once sound fires k set to 1. basically prevents sound from firing repeatedly if player spams the button while the door is in the process of closing.

Edited by ungoliant
Link to comment
Share on other sites

This sounds pretty messy for the purpose of simply opening a door :)

 

I'm still not sure I really understand it.

  • You have several buttons in your mission
  • the purpose of these buttons is to open one of the double-doors
  • in addition, a sound should be played (on entity A, which one is that?)
  • and a variable should be changed to a value that is already represented by the command you are using to get its value (see below script)

void stateChange()
{
 doorState = $door.IsOpen;
 k = k && !doorState;
}

(the second one is very shortened, you could also use a if-clause instead)

 

From how I understand it you could set the opening/closing sounds on entity A. Double-doors can be setup so that if one opens the other does, too. If entity A is the button, you can prevent the player from spamming it by setting the frob_action_script to a function that makes the button unfrobbalbe for an amount a bit longer then is needed for the door to open/close.

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

This sounds pretty messy for the purpose of simply opening a door :)

well the doors open fine without the script. its the sound thats the issue. The whole thing is a work-around to the lack of a 'play-when-mover-starts-closing' spawnarg. I could just wait until one pops up, but I think its been several years since the issue was first reported. Also, its great practice to start messing around with scripting again.

 

  • a sound should be played (on entity A, which one is that?)
  • and a variable should be changed to a value that is already represented by the command you are using to get its value (see below script).

entity A is just an arbitrary choice of one of the doors in a doubledoor. It is a target of the target_callscriptfunction entity with 'foreach 1' setup. I mean, I could target anything in the map and pass it to the function. Its fucking amazing. B and C are the activator of the target_callscriptfunction and the target_callscriptfunction entity itself, which i dont need here, but is pretty freakin awesome to have access to the activator entity, which in this case is the button, not the player.

 

I guess thats true about doorState, but at the time i was writing it, I wanted text output to keep track of stuff and when it was happening.

From how I understand it you could set the opening/closing sounds on entity A. Double-doors can be setup so that if one opens the other does, too. If entity A is the button, you can prevent the player from spamming it by setting the frob_action_script to a function that makes the button unfrobbalbe for an amount a bit longer then is needed for the door to open/close.

The closing sound in question is indeed on entity A on spawnarg snd_lockpick_pin_14. The double doors are already setup to open together, thats not an issue.

However, using frob_action_script in the way you describe could completely eliminate the need for a state machine at all, which would be fucking fantastic. I tried using it once, but all it did was prevent me from ever frobbing the button. probably because I did it wrong.

Edited by ungoliant
Link to comment
Share on other sites

i think frob_action_script might be a bit too much to handle. it looks like it replaces everything that the frob would normally do with the script function. so the button doesn't depress or undepress, doors dont open, button sound doesn't fire, targets aren't triggered. its a mess.

Link to comment
Share on other sites

Oops, sorry, forgot to point that out. By default the frob_action_script on a door points to frob_door, which looks like this:

void frob_door(entity ent)
{
 ent.ToggleOpen();  //ent is the door
}

So if you want to replace that one, you have to have this line in your script as well. ;)

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

frobbing doors is not allowed! buttons only! (its an elevator) :D

I suspect the reason that i lost frob capability was because i changed that argument to a different script function. The defaults are different depending on the mover. Button default is frob_button. door default is frob_door. the button needs run frob_button or nothing happens, if you are on a door, it needs to run frob_door script event on itself too in order to open. so basically, if you change that spawnarg to anything else, you dont get the expected behavior.

 

i think frob_action_script is most likely meant to be left alone, and not sullied by dirty scripter hands.

or maybe not. I think entities with no expected default frob behavior could make efficient use of this. like a stone or something the player touches that updates an objective or something. but using it on a button or door where you want to keep the basic functionality and add a little more is kind of like reinventing the wheel because you have to manually add all that default frob behavior.

 

state_change_callback is likely a better option. but I've found with buttons that 1 frob = 2 state changes = 2 script calls. annoying.

Edited by ungoliant
Link to comment
Share on other sites

void frob_function(entity ent)
{
 frob_button(ent);
 ... // your stuff here
}

You don't change the default frob action function, you just extend it.

i think frob_action_script is most likely meant to be left alone, and not sullied by dirty scripter hands.

If this were the case, it would be hard-coded. ;)

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

can't believe i didn't see that.

well now i just need a way to disable new frob_action_script calls while door open/close anim plays, and possibly remove the frob highlight while door opens/closes. really wish bloodgate was up right now, and i'm sure it exists.

Edited by ungoliant
Link to comment
Share on other sites

void setFrobable(float frobable) (you can call this on any entity)

 

for the button something like

void frob_function(entity ent)
{
 frob_button(ent);
 ent.setFrobable(0);
 sys.waitFor(ent.getTarget(0)); // retrieves target0 (the door), and wait til it finishes its move
 ent.setFrobable(1);
}

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

void setFrobable(float frobable) (you can call this on any entity)

 

for the button something like

void frob_function(entity ent)
{
 frob_button(ent);
 ent.setFrobable(0);
 sys.waitFor(ent.getTarget(0)); // retrieves target0 (the door), and wait til it finishes its move
 ent.setFrobable(1);
}

yep that eliminates the whole state machine. pretty sure i can run the whole script right from this spawnarg on any button linked to any doors. since i want to trigger when door starts closing, i think i'll just fire the sound when button frobbed and door is open. on an uninterruptible door that can't be frobbed that only uses button that is unfrobbable during open/close animation, i think it works.

 

also, how did you know that frob_action_script passes an entity argument that passes itself? intuition? or did you look it up somehow? normally i'd use bloodgate to see this sort of thing, but I dont know where to go now. searching wiki for frob_action_script doesn't turn up anything useful on that subject.

Edited by ungoliant
Link to comment
Share on other sites

ent.setFrobable(0);
sys.waitFor(ent.getTarget(0)); // retrieves target0 (the door), and wait til it finishes its move
ent.setFrobable(1);

i dont know what this is supposed to do, but it does not seem to prevent frobbing at all (yea i got it linked up to the door, and verified the link works). Im trying to find private data of mover entities, or mover script events, or anything at all that can just tell me, or that i can use to find out when there is a state change when a door fully opens or closes, and i cannot find a damned thing without bloodgate.

 

Ok so i looked up waitFor

/**
* Waits for the given entity to complete it's move.
*/
scriptEvent void		waitFor(entity mover);

that looks like it should do what you described, but now i'm aggravated that how the hell would I even find that if i wasn't told about it? just spend 45 minutes scanning script files and def files until i find something that sounds like it fits what i'm looking for? its madness. i'm really frustrated right now. i can't find anything i need, and stuff i need doesn't work, and blah. i need bloodgate or i'm gonna go nuts soon.

Edited by ungoliant
Link to comment
Share on other sites

now i'm really worried.

sys.wait and sys.waitFor both don't work. thats a gamebreaker. am i the only one experiencing this?

 

edit: ok it works in other script functions. but not in the one called by frob_action_script. really weird...

Edited by ungoliant
Link to comment
Share on other sites

also, how did you know that frob_action_script passes an entity argument that passes itself? intuition? or did you look it up somehow? normally i'd use bloodgate to see this sort of thing, but I dont know where to go now. searching wiki for frob_action_script doesn't turn up anything useful on that subject.

frobactions.script . In addition, I've used this several times before.

Regarding the button frobability, you could try to insert a sys.waitFrame() before the waitFor, as it is possible that at the time this command is executed the door not started to move yet, so the script thinks the movement is finished. (Like the script gets called before the door gets triggered).

 

if the wait commands do not do anything at all, you may have to put the code in a different function and start it as a thread from the frob_function(...). I barely remember that some functions don't execute wait commands, but have forgotten which ones actually (I tend to use script objects nowadays).

FM's: Builder Roads, Old Habits, Old Habits Rebuild

Mapping and Scripting: Apples and Peaches

Sculptris Models and Tutorials: Obsttortes Models

My wiki articles: Obstipedia

Texture Blending in DR: DR ASE Blend Exporter

Link to comment
Share on other sites

so sys.waitFrame() does nothing here, and yea it just skips the whole check before it starts moving.

sys.wait and friends don't work in threads called by threads called by frob_action_script either, as far as i can tell.

 

*sigh* i'm gettin ready to throw in the towel here. also tried using a while(door.isMoving()), but it still needs the waitFrame to work. there is just no winning with frob_action_script.

Link to comment
Share on other sites

ITS DONE. finally. fuck frob_action_script i translated the whole thing to work on a target_callscriptfunction entity that can actually use the sys.wait family of script events.

here is the code for posterity and any lurkers interested:

void closing_sound(entity target, entity activator, entity this)
{
if(activator.getTarget(0).IsOpen())
	activator.getTarget(0).startSound("snd_lockpick_pin_14", 0, 1);
frob_button(activator);
sys.waitFor(activator);
activator.setFrobable(0);
sys.waitFor(activator.getTarget(0));
activator.setFrobable(1);
}
void nu_Frob(entity this)
{
$DoorSound.activate(this);
}

this script adds "while closing" sound functionality to any doors that use a button. i guess a lever, or other things might work too.

doors must be uninterruptible. can be single door, double door, doesn't matter

 

button: target any door on target0. do not target the target_callscriptfunction entity with the button, or anything else (leave it untargeted). Set 'frob_action_script nu_Frob' on button.

door: set 'snd_lockpick_pin_14 mySoundGoesHere', or use any other "snd_x" spawnarg you think will never get used to your desired closing sound on the door entity. set 'snd_close -' on door unless you have another sound to play when door snaps shut.

target_callscriptfunction: only need to make 1. Name it DoorSound. set 'call closing_sound', 'foreach 1' on it. target any entity with it, doesn't matter what. good choices are probably ambient_world or the info_player_start, or something that will always be in the map.

Edited by ungoliant
  • Like 1
Link to comment
Share on other sites

more wrenches, stupid thing is actually firing the close sound on open and close animations. apparently the door "opens" on frob when targets are triggered and doesn't wait around for the script or actual animation or to start. The IsOpen() check always returns true.

 

So i tried using frob_action_script again...

 

float doorState;

void closing_sound(entity target, entity activator, entity this)
{
if(doorState)
 activator.getTarget(0).startSound("snd_lockpick_pin_14", 0, 1);
activator.setFrobable(0);
sys.waitFrame();   //sys.print("done waiting");
sys.waitFor(activator.getTarget(0));
activator.setFrobable(1);
}
void nu_Frob(entity that)
{
doorState = that.getTarget(0).IsOpen();
frob_button(that);
}

 

 

APPARENTLY all global data is reinitialized any time a script function is run GGRRRRRRRALSKDJFASLFVNKZX<>M@P#$(5u@#P%..... now i'm really pissed. like... urrrghhh.... any ideas how to do this check without rewriting the state machine? function just needs to know when the button is frobbed when door is in closed state, it doesn't care about anything else to work properly.

Link to comment
Share on other sites

lol ok, solution is stark hilarious. frobbing the door no longer frobs the door...directly. On top of that, nothing in the map targets the target_callscriptfunction...directly. once again, to hell with frob_action_script, tempted to file a bugtracker report on it if it hasn't been done already.

so the target_callscriptfunction entity is removed as a target from all buttons. instead, frob_action_script runs $scriptentity.activate(daButton); where the button passes itself as arg to make itself activator of the target_callscriptfunction to simulate being triggered like a frob, but its not, to prevent infinite looping. also using activate function prevents the whole thread from being called directly by frob_action_script and hence disabling all the sys functions. script function runs frob_button AFTER the door state check, then its business as usual after that. updating original "release" post with the relevant info.

Edited by ungoliant
Link to comment
Share on other sites

Alright so I'm learning some python, and I've got some questions about DR scripting.

What SceneNode's would have a type of 'map' or 'unknown'? other than GlobalSceneGraph.root()

Why would a node be null? like a spawnarg with its value set to "-"? if i deleted a brush without saving? other stuff?

Is GlobalSceneGraph the only ScreenGraph in an FM?

Does the list of children of GlobalSceneGraph.root() look something like: worldspawn, entity 1, entity 2, entity 3, etc etc extending the entire list of entities placed by the mapper? or would there be some extra stuff in there?

Edited by ungoliant
Link to comment
Share on other sites

I don't think that 'map' exists. The node types I've seen in the wild are: entity, primitive, model, and unknown. The GlobalSceneGraph seems to be a shallow tree with 2 layers of children below the root: its immediate children are entities, and their children are primitives or models.

 

The first child of GlobalSceneGraph.root() is an entity of class "world" whose name is "world". It's children are your worldspawn. Then comes every other entity, optionally with its own primitive or model children.

 

I've only seen 'unknown' when I have components selected (verts or faces) and I check the selected nodes. You don't see 'unknown' when traversing the GlobalSceneGraph.

 

You'll see the null entity most often when requesting a node that doesn't exist, e.g. node.getBrush() when node is actually a patch, or node.getParent() on the root.

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

    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
×
×
  • Create New...