Jump to content
The Dark Mod Forums

Ungoliant's mapping questions


ungoliant

Recommended Posts

Not sure what you're doing here

 

attempting to solve the age-old problem of triggering door-closing sounds when the door starts to close. And you, sir, have just solved it for me!! (almost). I haven't put the work into scripting it yet, but this will work for my door perfectly. It wouldn't work well for a standard door because the close state wouldn't go into effect until the door shuts all the way, meaning if you spam-frob the door while its in the process of closing, it will repeat playing the sound over and over again on both opening and closing animations. However, my doors using this script are intentionally uninterruptable, so this will work perfectly.

Thanks fid! :D

 

ooo... before hitting the post button, I just thought of a solution to the spam-frob problem. set up another global float counter initialized to 0, incremented at the end beginning of the script. If > 1, do not play door-close sound, reset counter when door state returns to closed. hmmm this is cool. I might set up some kind of prefab for this..?

 

edit: this is harder than I thought. Various pitfalls/benefits for using a single script function or 2, or triggering from button vs door.

Edited by ungoliant
Link to comment
Share on other sites

nailed it!! as far as i can tell this should work under all circumstances(as long as door is uninterruptable currently). If anyone should wish to duplicate this, here are the details:

 

need a door and a button. Button and door should frob simultaneously, the timing on which is first does not matter.

door should have spawnargs: "trigger_on_close" "1", "trigger_when_opened" "1", "trigger_on_open" "0".

need 2 atdm:target_scriptcallfunction entities, the door should target 1, the button targets the other. here is the script:

 

float doorState = 0;
float k = 0;

void stateCheck() //trigger with button only, fires every time button is pressed.
 //shouldn't matter if fired before/after stateChange()
{
sys.print("checking doorState value");
if(doorState && !k)
{
	sys.print("\ndoor is open and sound has not fired yet");
	$elevator_cargo_floorb_door2.startSound( "darkmod/gate_close01", 1, 0 ); //channel, netsynch? NOT WORKING
	k++;
	sys.print("\nsound fired");
}
else
{
	sys.print("\ndoor is closed, or is open and sound has already fired");
}
}

void stateChange() //trigger with door only, fires only on_close and when_opened
 //shouldn't matter if fired before/after stateCheck()
{
sys.print("\nchanging door state");
if(doorState)
	doorState = 0;
else
{
	doorState = 1;
	k = 0;
}
//PROBLEM: if door is interrupted and swung the other way, doorState change will be incorrect. uninterruptable only.
}

 

the only problem now is I can't get the actual sound to work.... what am I doing wrong? do i really need to set up a speaker to trigger here?

Edited by ungoliant
Link to comment
Share on other sites

hmmm i believe i have a fix for the uninterruptable only problem. because i decided to use when_opened and on_close only, the changeState() script will certainly only function after each change of state now. I think in this way, $doorname.IsOpen() or .$doorname.IsClosed() will function properly now. The initial problem that led me to posting was that I was using spawnargs on_open and on_close, whereas now i'm using when_opened and on_close, which should fix the problem of detecting if the door is in a closed state at the beginning of the script due to timing errors. I think i'll still keep the changeState() function though because of the ability to reset the counter associated with how many times the sound has played based on the change of state. Should work properly for all cases after fixing it up, minus the ability to actually get the damn sound to play.

 

speaking of which, still need some advice on that startSound() method? is this the best way, and am i using it properly?

Link to comment
Share on other sites

Always worth checking that sound separately with a speaker on its own to make sure its OK. I've got one right now in my own FM that works fine in Dark Radiant but will not work at all in-game. So your script might be correct but the damn sound won't play for some other reason. You could also try a different proven sound just to test it.

Link to comment
Share on other sites

You could also try a different proven sound just to test it.

 

did it 2 days ago after i set up the soundshader for my new sound. tested on snd_open on a door, it works good. Also replaced it with a default stock tdm sound, no go. i think the problem is with the channel or netsynch spawnargs. i've tried a few different string path arguments to the shader itself as well. just plain can't get it workin. pretty sure its just something i'm doing wrong with the params, but i don't know what. maybe i'm just using the wrong script function altogether, but i can't find one that suits my needs better.

Edited by ungoliant
Link to comment
Share on other sites

adjusted the script. This system should now be able to play sounds upon the start of door closing for ANY door type.

here is the adjustment, replace the old stateChange() function listed above with this one.

 

void stateChange() //trigger with door only, fires only on_close and when_opened
 //shouldn't matter if fired before/after stateCheck()
{
sys.print("\nchanging door state");
if($elevator_cargo_floorb_door2.IsOpen())
{
	sys.print("\nopening door state");
	doorState = 1;
	k = 0;
}
else
{
	sys.print("\nclosing door state");
	doorState = 0;
}
}

Edited by ungoliant
Link to comment
Share on other sites

  • 5 months later...

its come to my attention that since i'm building a map constructed primarily of patches and models, that I should pay more attention to pathfinding.

 

So I bound _impulse27 to a key via the pathfinding wiki page, but i'm not really getting a lot of wireframe info. I put in 1 AI inside a big patch cylinder (worldspawn) with some verts dragged around a lot and let him roam free. But when i use the pathfinding key, all that shows up is a red "1", and sometimes randomly a little purple or yellow square on a spot on the ground, but thats it. Is there something I'm doing improperly?

Link to comment
Share on other sites

Dunno. I never had much success with those path console commands and cvars. I could never get any sensible info out of them that helped.

 

With an internal patch cylinder you'll need a flat monster clip worldspawn brush along the floor. It can clip through a few units above the centre. AI should be able to walk along OK.

 

Here's one I did a while back. I see I used clip not monsterclip so it was easier for the player not to get stuck....

 

post-400-131299846793_thumb.jpg

Link to comment
Share on other sites

Ok, so theres no way to visualize what is being checked against AI pathfinding. That sorta sucks. Well, riddle me this: If any piece of a patch is calculated for pathfinding, is the entire patch calculated regardless of where monsterclip is placed?

 

I ask this only because of the issue with func_statics still being rendered if any piece of it sticks through a visportal, so I'm a bit paranoid about pathfinding in my map with patches sticking out of monsterclip.

 

Also, of note, my AI are capable of walking along func_static patches with lots of dips and rises without any monsterclip added..... huh?!? Should that even be possible? If that is possible, and its just AI colliding with invisible func_static barrier with no added pathfinding, is it possible I can exploit this to make tons of func_static patch terrain with 0 pathfinding???? (i guess the AI thinks it is walking along the brush floor beneath it?)

Edited by ungoliant
Link to comment
Share on other sites

Ok, so theres no way to visualize what is being checked against AI pathfinding. That sorta sucks. Well, riddle me this: If any piece of a patch is calculated for pathfinding, is the entire patch calculated regardless of where monsterclip is placed?

 

I ask this only because of the issue with func_statics still being rendered if any piece of it sticks through a visportal, so I'm a bit paranoid about pathfinding in my map with patches sticking out of monsterclip.

 

Also, of note, my AI are capable of walking along func_static patches with lots of dips and rises without any monsterclip added..... huh?!? Should that even be possible? If that is possible, and its just AI colliding with invisible func_static barrier with no added pathfinding, is it possible I can exploit this to make tons of func_static patch terrain with 0 pathfinding???? (i guess the AI thinks it is walking along the brush floor beneath it?)

 

Yes. The AI can travel into a patch floor that is 16 units above any worldspawn brushwork. (someone, please correct me for the exact correct value). If you have a larger gap, the AI starts dropping traveling warning messages to the console. (WARNING: GetPointOutsideObstacles: no valid point found or Destination unreachable...). Or does not, but simply cannot walk there. The AI may also start skipping path_nodes it feels it cannot reach.

 

If you make patch ground, just make sure you always have simple blocky worldspawn brushwork closely below it. The AI can walk there just fine. If your worldspawn brushwork is caulked, it doesn't consume tris, but will still aid the AI.

 

Do note, however, that the AI will not understand it is above the worldspawn: it will walk on a pathfinding information that is based on the worldspawn, not the patch. This means that the AI may bump into objects it would not hit if it really walked on the brushwork. But now the patch raises him high enough to hit the obstacle. That is why it is important to always have your monsterclip brushes (and other worldspawn brushes) touch all the way to the worldspawn brushes below the patch.

 

I had a lot of warnings as shown above until I found out several worldspawn brushes which floated over the lowest ground worldspawn brushwork, while it still appeared to sit on the patchwork ground.

 

In the end, a good way to test you pathfinding is to have AI's patrolling around for a while. Check you console for the warning messages shown above. Also you can alert the AI and make him run after you everywhere you suspect the AI might have difficulty in. If the AI manages just fine and there are no warnings, you're probably doin' it right.

Clipper

-The mapper's best friend.

Link to comment
Share on other sites

Yes. The AI can travel into a patch floor that is 16 units above any worldspawn brushwork. If you have a larger gap, the AI starts dropping traveling warning messages to the console or does not, but simply cannot walk there. The AI may also start skipping path_nodes it feels it cannot reach.

At its lowest point, the patch is about 89 units above worldspawn. Putting much more distance between them will cause it to stop working properly. What I don't get is why the pathnodes ONLY work when the origin of the nodes are placed inside a few units of the surface of the patch. If the AI don't know where it is, then whats the deal?

 

Do note, however, that the AI will not understand it is above the worldspawn: it will walk on a pathfinding information that is based on the worldspawn, not the patch. This means that the AI may bump into objects it would not hit if it really walked on the brushwork. But now the patch raises him high enough to hit the obstacle. That is why it is important to always have your monsterclip brushes (and other worldspawn brushes) touch all the way to the worldspawn brushes below the patch.

 

I don't get this. The AI is bumping into rock models that are over 150 units above worldspawn. If the AI believes it is on the ground, how is that possible? Unless.... D3 is putting in a relative offset from the actual brush used as pathfinding, which would make the path nodes work (roughly, if not spaced too high above/below eachother), and would allow the player to walk on collision model instead of pathfinding area, yet still bump into objects far above the ground.

 

Am I getting warm, now?

 

edit: ok if I'm getting this right, now matter how highly tesselated the patches are, or highly complex a FS is, its part of the collison model and hence not part of pathfinding, and has no impact on performance. yes? If so, where is all the performance drain coming from with pathfinding?

Edited by ungoliant
Link to comment
Share on other sites

  • 2 weeks later...

how do I set up a new def_attach position, or possibly put in an offset of an existing def_attach? a regular bind will not work here.

 

edit: this is probably going to be harder than I thought. scanning through def files, it seems that werebeasts, and monsters in general have no attach points.

Edited by ungoliant
Link to comment
Share on other sites

Link to comment
Share on other sites

  • 1 month later...

almost done with a new contribution for the mod (and my FM). Having some trouble though, and it may be insurmountable, unless i can think of something more smarter.

 

Is it possible to reference shaderparms inside the declaration of a lookup table???

 

example: mytable { { (1 - parm5), (.8 - parm5), (.6 - parm5), (.8 - parm5), (1 - parm5) } }

 

it will not really create more work if this is not possible (it was actually already done, and i decided to feature-creep), but it does restrict my intended use of the end-product. I've tried it already but it just seems to hold steady with all table lookups returning '1'. maybe its not even 1, but its always returns the same value on every lookup.

 

any ideas?

Link to comment
Share on other sites

Is it possible to reference shaderparms inside the declaration of a lookup table???

 

example: mytable { { (1 - parm5), (.8 - parm5), (.6 - parm5), (.8 - parm5), (1 - parm5) } }

Nop, it cant use any back-refrence type stuff :(

 

If you can explain (because that example... I don't even.) what you're trying to do - I may have some tricks to do it. PM me if its sekrit hush hush stuff.

Link to comment
Share on other sites

not really a secret, and i can tell you what i'm doing in that table without giving the game away.

 

Basically, I'm trying to create a pulse (sawtooth waveform) where the amplitude is customizable via spawnarg. I've already got phase shift and frequency set up on parm3 and parm4, and they work, but amplitude is... more trickier.

 

Here is the actual table i set up (and i friggin know this would work if it accepted shaderparms):

 

table mytable { { 1, (.8 + parm5 *.2), (.6 + parm5 * .4), (.4 + parm5 * .6), (.2 + parm5 * .8), 0 + parm5, 0 + parm5, (.2 + parm5 * .8), (.4 + parm5 * .6), (.6 + parm5 * .4), (.8 + parm5 *.2), 1 } }

 

If that looks more confusing than the first example, heres a breakdown: my original static tables were:

 

table mytable1 { { 1, .8, .6, .4, .2, 0, 0, .2, .4, .6, .8, 1 } }

table mytable2 { { 1, .9, .8, .7, .6, .5, .5, .6, .7, .8, .9, 1 } }

 

notice here the peak rise of the first wave is 1 (max brightness) and the low is 0. But I also wanted a version that does not fluctuate between on and off, so i devised the second wave that is between .5 - 1. Then I decided "who am I to restrict the mapper between these 2 different waves. I should mappers control these values", so i devised the third table. It takes a parm5 value between 0-1. If parm5 == 0, the table equates to mytable1. If parm5 == 1, all values in the table equal 1.

 

This way, the mapper chooses any amplitude of brightness between 0 and 1, where the peak value is always 1 (which will end up reflecting the exact rgb values passed to _color spawnarg, so there is no guesswork to the mapper on what the result looksl like).

 

edit: my brain is working overtime here, but I think i might have just solved my own problem.

 

"notice here the peak rise of the first wave is 1 (max brightness) and the low is 0"

 

with this same table, the mapper already technically has amplitude control via the _color spawnarg, but INVERTED. the low value is always 0, and the mapper controlled peak value is between 0-1. So if i took all the final values of the table lookups and modifications, and inverted the result, then the player can choose amplitude with max brightness 1 simply by increasing/reducing the _color value????? problem here is that the in-game color will be the invert of what they chose on the colorwheel. so thats not really a solution, i guess...

 

is this correct?

 

re-edit: btw that peak value isn't actually rgb 1. Its just a multiplier for the rgb value, so the max amplitude peak is actually just the rgb value the mapper inputs, not white.

Edited by ungoliant
Link to comment
Share on other sites

Why not make a "unit" lookup-table that goes between 0 and 1 or -1 and 1, and then apply this in the material :

 

yourTable[ time * frequencyControl + phaseShift ] * amplitudeMultiplier + valueShift

 

For the control-values you could put the different shaderParms.

Maybe even switch some things around if you want phaseShift to be applied before frequency or somesuch.

Link to comment
Share on other sites

thought about putting the amp multiplier outside of the table but heres the trouble: this reduces the max values, not increasing the min values of the wave. i need the high peak to be constant at '1'. having an outside multiplier like that will not do this, unless i'm missing some sort of mathematical expression that could do this outside of the table.

Link to comment
Share on other sites

But the "valueShift" can be used to change the min-values, unless i'm understanding wrong what you're trying to do.

 

Say you want a wave that goes between 1 and 0.5, you could put the amplitudeMultiplier to 0.5, and the valueshift to 0.5.

If the base Table went from 1 to 0, you would then end up with a wave that goes between 1 and 0.5.

 

Or if you always want the max value to stay at 1, and only control the minimum value :

 

yourTable[ time * frequencyControl + phaseShift ] * ( 1.0 - minValue ) + minValue

Link to comment
Share on other sites

right ungoliant, just a matter of 5 minutes writing a simple entity class :rolleyes: ... *sigh*.

 

Ok questions about entityDef's:

 

is it possible to combine a model and a light into an entity without needing the light to be def_attached to the model?

 

in either case, is it possible to pass shaderparm values to both light and model?

Link to comment
Share on other sites

Dunno. Wild guess. Include the def_attach then find out how to remove it in-game. Maybe def_attach - property or something. We know def_attach can be removed because it already happens in animations, sword-dropping etc but I don't know if it needs code support.

Link to comment
Share on other sites

pretty sure i found something to work as an inherited class: light_colorme_model. to all appearances its a light spawnclass that takes a model . probably works better than a model with a def_attached light.

 

now that i've started defining my entity class in earnest, i am confused: what does "atdm:" mean??? when should an entity def use this prefix??

 

edit: also, what are the spawnargs for turning self_lit and self_shadows off? cannot find documentation on wiki, bloodgate, or existing def files, but i know they exist somewhere...

Edited by ungoliant
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 )
      · 0 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
       
      · 3 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
    • The Black Arrow

      I wanna play Doom 3, but fhDoom has much better features than dhewm3, yet fhDoom is old, outdated and probably not supported. Damn!
      Makes me think that TDM engine for Doom 3 itself would actually be perfect.
      · 6 replies
×
×
  • Create New...