Jump to content
The Dark Mod Forums

Newbie DarkRadiant Questions


demagogue
 Share

Recommended Posts

@MirceaKitsune

You might define a function, where the passed parameter is either ts or tm as you calculated:

string FormatTime(float t)
{
    string strT = t;
    if(t < 10)
        strT = "0" + strT;
    if(t > 99)
        strT = 99: // cap it
    return strT;
}

Then call it thusly, replacing the last line of your example:
 

string s = FormatTime(tm) + ":" + FormatTime(ts);

 

Link to comment
Share on other sites

3 hours ago, duzenko said:

We can add this as new script function with the C++ backend

That would be nice. For now I can do with coding my own function which should fix the issue.

Stay tuned for something nice that's about to come, potentially tomorrow if I finish it on time :)

Link to comment
Share on other sites

Almost done with my little big side project. Am stuck on one more thing as far as scripting goes: How do I make a function in the scriptobject execute when the entity is activated by something targeting it, for instance an atdm:mover_button? There's frob_action_script for frobbing but no such thing as an activate_action_script: I tried used_action_script but this didn't work, I take it that spawnarg is meant to point to a function for items being used by the player.

Link to comment
Share on other sites

There is an entity called target_callscriptfunction that calls a script function when targeted. The script function to be called is defined by the spawnarg "call", which has to be added. I hope this helps.

Link to comment
Share on other sites

12 hours ago, MirceaKitsune said:

Almost done with my little big side project. Am stuck on one more thing as far as scripting goes: How do I make a function in the scriptobject execute when the entity is activated by something targeting it, for instance an atdm:mover_button? There's frob_action_script for frobbing but no such thing as an activate_action_script: I tried used_action_script but this didn't work, I take it that spawnarg is meant to point to a function for items being used by the player.

It's all in the wiki now: A to Z Scripting

In your case the page on "Ways of calling a script" would be relevant, as well as "Scriptobjects" since what's what you're dealing with.

Link to comment
Share on other sites

Thanks. Already looked at that tutorial as well as existing scripts but couldn't find anything by name or the search terms that popped to mind. I don't want my entity to require a target_callscriptfunction to address, just to respond to normal activation. Luckily that page provides exactly what I was looking for:

sys.onSignal(SIG_TRIGGER, self, "myobject::myvoid");

 

Edited by MirceaKitsune
Link to comment
Share on other sites

I'm working on a custom GUI that simply puts up a full-screen slide in mid-game. Mostly working, but can't figure one thing out. I want the user to be able to use the LMB to end the slide. I've got it triggering the GUI's onActivate block and hiding the slide. But I also need to tell a script about it, either by setting a global value that the script can poll, or by calling a script function. Tried putting the runScript command (from Modwiki circa 2004 documentation) inside onActivate, but got a runtime error that the specified script couldn't be found. Other ideas? Is this something to do with namespaces?

Link to comment
Share on other sites

4 hours ago, Geep said:

But I also need to tell a script about it, either by setting a global value that the script can poll, or by calling a script function.

It looks like there's something like that being done with the spyglass, ZoomInRequest, in spyglass.gui and tdm_playertools.script.

Link to comment
Share on other sites

@Dragofer, thanks, I followed up on that, but not there yet.

My implementation uses a atdm:gui_message, with its "gui" spawnarg pointing to my custom gui. This lets me use the timeout mechanism that atdm:gui_message provides. But that doesn't provide me with the gui handle number. A while ago, you indicated that 10 was the default for atdm:gui_message, so I assumed that.  Following the spyglass example, in my GUI's onActivate I added:

           set "gui::MySlideDone" "1";

In my script (slightly simplified here), I have:

   sys.trigger($atdm_gui_message_slide); // show slide
   float maxtime = $atdm_gui_slide.getFloatKey("show"); // seconds;
   float slide_done == 0;
   while(maxtime > 0)
   {
    slide_done = $player1.getGuiFloat(10, "MySlideDone"); // 10 is default overlayHandle for atdm:gui_message layer
    if(slide_done == 1) // user did gui's onAction, with LMB
        break;
    maxtime -= 0.1; // poll frequency
    sys.wait(0.1);
   }

While maxtime is working fine, the "MySlideDone" value doesn't seem to be passed. I'm guessing because the handle number isn't 10. Nothing reported to console problem-wise. Any good way to get the handle?

 

Link to comment
Share on other sites

2 hours ago, Geep said:

@Dragofer, thanks, I followed up on that, but not there yet.

My implementation uses a atdm:gui_message, with its "gui" spawnarg pointing to my custom gui. This lets me use the timeout mechanism that atdm:gui_message provides. But that doesn't provide me with the gui handle number. A while ago, you indicated that 10 was the default for atdm:gui_message, so I assumed that.  Following the spyglass example, in my GUI's onActivate I added:

           set "gui::MySlideDone" "1";

In my script (slightly simplified here), I have:

   sys.trigger($atdm_gui_message_slide); // show slide
   float maxtime = $atdm_gui_slide.getFloatKey("show"); // seconds;
   float slide_done == 0;
   while(maxtime > 0)
   {
    slide_done = $player1.getGuiFloat(10, "MySlideDone"); // 10 is default overlayHandle for atdm:gui_message layer
    if(slide_done == 1) // user did gui's onAction, with LMB
        break;
    maxtime -= 0.1; // poll frequency
    sys.wait(0.1);
   }

While maxtime is working fine, the "MySlideDone" value doesn't seem to be passed. I'm guessing because the handle number isn't 10. Nothing reported to console problem-wise. Any good way to get the handle?

 

If I'm not misremembering, every time a message GUI entity is triggered, the overlay that's created is assigned the next highest handle, so 0, 1, 2, 3, 4 etc.. So you can't say that a GUI message's handle will be 10.

When the overlay is created, you can catch its handle like this:

float GUI_handle = $player1.createOverlay(.....);

 

So you can store this handle as a variable inside the GUI message entity's scriptobject, roughly like this:

[scriptobject, custom version that inherits from the stock scriptobject, only needed if the handle isn't already defined as a variable ]
object gui_message_custom : gui_message
{
	....
	float GUI_handle;
};

void gui_message_custom::show_message
{
	....
	GUI_handle = $player1.createOverlay(....);
}

 

And retrieve it from your global script:

[global script]
{
	gui_message_custom    e            = $atdm_message_entity_1;
	float                handle        = e.GUI_handle;
	....
}

 

  • Like 1
Link to comment
Share on other sites

Success, with some further investigation and tweaks. Details follow for those curious.

Spoiler

The class object atdm:gui_message has a scriptobject spawnarg with default value "tdm_gui_message" (not gui_message). That scriptobject does define a "gui" variable handle. However, the handle is zero initially, until createOverlay is called, and the latter is not called immediately. If the atdm_gui_message spawnarg "delay" is set, then it waits for that. But if it's not set (e.g., left at 0), then a 0.1 second delay is explicitly imposed anyway. So my code to fetch the handle is:

   tdm_gui_message e = $atdm_gui_message_slide // cast to access the script object
   float handlenum = 0;
   while(handlenum == 0)
   {
                handlenum = e.gui;
                sys.wait(0.1);
   }


I'll eventually form this into a wiki article about creating an in_game slide.

Thanks again, @Dragofer BTW, you should make it easier to find your "A to Z Scripting" if I just type "Scripting" into the wiki search.

  • Like 1
Link to comment
Share on other sites

Thank you for the scripting help yesterday: It helped me finish a project I think other players and mappers are going to enjoy. If anyone wants to see what I needed it for, check out its thread and maybe give the pk4 a try in your FM! TLDR we now have a playable in-world game, yay for steampunk arcade machines :)

 

Link to comment
Share on other sites

Not sure if this counts as a newbie question. I'm using a func_teleporter. The teleporter fires at an unpredictable time; as an example, presume that I've got a script that invokes the teleporter every 5 minutes (that's not exactly what I'm doing, but it works as an example). It works fine normally, but if the player happens to be climbing a rope (from a rope arrow) when the teleporter fires, the teleporting doesn't work as I expect. The player is teleported to an incorrect location, and the physics engine seems to think that he is still climbing a rope (i.e., the player can still climb up and down as if they were on a rope, but there is no rope at the new location). It looks like the teleport code doesn't cause the user to "let go" of the rope, or something? Is this a bug, or ...? In scripting, is there a way to force the player to let go of a rope? I've experimented with removing the deployed rope, and that does cause the player to let go and the teleport works as expected, but that's suboptimal (now the rope is missing).

Link to comment
Share on other sites

@joebarnin I think you'll need to clear immobilisation flags from the player - MirceaKitsune's recent arcade machine posted to the Art Assets thread has a script that works with these flags.

scriptEvent void setImmobilization(string source, float type);

    Used to set immobilization from a source. Warning: Not a finalized version. It's subject to change, so use it at your own risk.)

    Spawnclasses responding to this event: idPlayer

Btw, this is how the player is detached from a ladder in the engine (Physics_Player.cpp):

Spoiler
/*
============
idPhysics_Player::ClimbDetach
============
*/
void idPhysics_Player::ClimbDetach( bool bStepUp ) 
{
	m_bOnClimb = false;
	m_ClimbingOnEnt = NULL;
	m_bClimbDetachThisFrame = true;

	static_cast<idPlayer *>(self)->SetImmobilization("ClimbMove", 0);

	current.velocity += m_RefEntVelocity;

	// switch movement modes to the appropriate one
	if( bStepUp )
	{
		// Step up at the top of a ladder
		idVec3 ClimbNormXY = m_vClimbNormal - (gravityNormal * m_vClimbNormal) * gravityNormal;
		ClimbNormXY.Normalize();
		current.velocity += -ClimbNormXY * LADDER_TOPVELOCITY;
		idPhysics_Player::SlideMove( false, true, false, true );
	}
	else if ( waterLevel > WATERLEVEL_FEET ) 
	{
		WaterMove();
	}
	else 
	{
		AirMove();
	}

	SetNextAttachTime(gameLocal.time + cv_tdm_reattach_delay.GetFloat());

}

 

Yeah I think it's a bug that teleportation doesn't automatically do this. It could be worth a ticket.

  • Thanks 1
Link to comment
Share on other sites

I'd still like an answer to my previous question please.

How do I make monsters like the werebeast and manbeast able to have idle chatter with human guards, as well as using the human alert system so they search around a tad longer?

Link to comment
Share on other sites

@DragoferThanks. I just tried your suggestion, and it looks like clearing immobilization is necessary, but not sufficient. Without a way to set m_bOnClimb=false (or m_bOnRope = false in the case of climbing a rope), the game still thinks the user is climbing on the ladder/rope. There doesn't appear to be a way to call ClimbDetach() or RopeDetach() from a script. The only way I can find to cause RopeDetach() to get called indirectly is to remove the rope, which I'd rather not do.

I'll submit a ticket.

Link to comment
Share on other sites

@joebarnin
Maybe you can spawn a new rope at the same location and rotation? Possibly a stuck rope arrow and/or the rope arrow result entity. Otherwise it'd have to be that the script waits for the player to get off the rope.

For fixing this, it should be possible to either expose the detach functions to scripting or call them from teleportation functions.

@MirceaKitsune
The only thing I can suggest is to look at all the spawnargs, I have no experience making animals that are like humans. Search cooldown timers for a fact have a lot of spawnargs governing them. And maybe you need to set some kind of rank so other AIs know what to greet them as.

  • Thanks 1
Link to comment
Share on other sites

@joebarnin Depending on what exactly you try to achieve and if the teleporter is activated by a script, it may be possible for the script to check if the player is currently climbing? If so, you may be able to delay the teleport until the player has stopped climbing, which in turn would avoid the problem you are having. Not sure if or how this is actually possible, but it may be worth looking into.

@MirceaKitsune The first spawnargs that would come to mind for me would be "team", "personGender", "personType" and "AIuse", since these mainly affect how AI interact with an entity. However, this only changes how AI interact with the entity, not the other way round. I would assume (at least I have seen no spawnargs that suggest otherwise) that the behaviour of your entity with other AI is hard coded in the entity class. This means you would have to take one of the AI entity classes and manually change all physical properties to match the werebeast/manbeast (e.g. model, animations, skeleton definitions, ik definition, etc.). If you want to try that, I would suggest you the open the def file of an AI entity (e.g. a guard or a civilian) and copy paste any spawnargs from the werebeast/manbeast that appear to have anything to do with animations, models, or other physical interaction. Which ones exactly you need, would be trial an error. It is a lot of work and I am not even sure if this works, but it is the only thing that I can think of.

Link to comment
Share on other sites

6 hours ago, Destined said:

@joebarnin Depending on what exactly you try to achieve and if the teleporter is activated by a script, it may be possible for the script to check if the player is currently climbing? If so, you may be able to delay the teleport until the player has stopped climbing, which in turn would avoid the problem you are having. Not sure if or how this is actually possible, but it may be worth looking into.

@MirceaKitsune The first spawnargs that would come to mind for me would be "team", "personGender", "personType" and "AIuse", since these mainly affect how AI interact with an entity. However, this only changes how AI interact with the entity, not the other way round. I would assume (at least I have seen no spawnargs that suggest otherwise) that the behaviour of your entity with other AI is hard coded in the entity class. This means you would have to take one of the AI entity classes and manually change all physical properties to match the werebeast/manbeast (e.g. model, animations, skeleton definitions, ik definition, etc.). If you want to try that, I would suggest you the open the def file of an AI entity (e.g. a guard or a civilian) and copy paste any spawnargs from the werebeast/manbeast that appear to have anything to do with animations, models, or other physical interaction. Which ones exactly you need, would be trial an error. It is a lot of work and I am not even sure if this works, but it is the only thing that I can think of.

Aha, I see. Thanks! Already set those spawnargs, wasn't sure if there were more. In that case I can leave it as is, just assumed patrol / alert types were also a spawnarg I just couldn't find. And that there's a particular one for monsters so manbeast / werebeast use the same default as spiders but it can be changed. This would probably require me to remap animations and such... as long as voice packs and salutes still work (they do to some extent) I'm good in the end.

Link to comment
Share on other sites

I was looking into the i18n system for my FM, but I'm getting the feeling that, given the neglected state of i18n affairs with DR and the FM update/distribution system, the best guidance to mappers should be, "forget about it". That is, it's not worth the effort for mappers, and translators may or may not use it.

Am I wrong?

Link to comment
Share on other sites

3 minutes ago, Geep said:

I was looking into the i18n system for my FM, but I'm getting the feeling that, given the neglected state of i18n affairs with DR and the FM update/distribution system, the best guidance to mappers should be, "forget about it". That is, it's not worth the effort for mappers, and translators may or may not use it.

Am I wrong?

I agree with you.

  • Like 1
Link to comment
Share on other sites

I'm expecting the answer to be no since I already looked and couldn't find any, but still wanted to make sure: Do we currently have any blending terrain textures by default? Meaning terrain materials that alternate between images based on the surface normals, blending one image horizontally and another vertically for more realism. Obviously ones that work with patch terrains. They're popular for years in some engines and can offer quite some good looks!

Blender_free_terrain.jpg

Link to comment
Share on other sites

Not sure if this is what you wanted or if TDM engine as something better but idtech 4 does have the ability too blend two materials, afaik only two, using Black and white (RGBA) vertex colors painted unto the mesh, was used on Doom 3 for many Mars and hell terrain models.

https://modwiki.dhewm3.org/VertexColor_(Material_stage_keyword)

https://wiki.thedarkmod.com/index.php?title=DrVertexBlend_(tutorial)

https://web.archive.org/web/20080418194854/http://www.doom3world.org/phpbb2/viewtopic.php?t=12067

The ability to use terrain masking, to support more than two materials, like what Quake Wars used for their terrain, would be awesome but alas no source code for us to see how they did it.

Apart from the later the only other option more or less possible, that I personally know, is painting all the materials you want, in blender (or other 3D tool) and bake them down into a single texture, than if possible, use the unfinished Mega Texturing system, to display this huge, baked single terrain texture, in small chunks very fast but afaik that code was removed entirely from the TDM engine.

Without MT or unless someone implements virtual texturing into TDM, unfortunately, this means that with this technique, only very small terrain peace's are viable, why, because this can create a huge terrain texture that even with compression, could have many GB of size (depending on resolution and compression used), and so be very heavy, specially for older GPU's, with low amounts of VRAM space.

Btw perhaps something like this is now possible in TDM? Perhaps using a GLSL shader? Or can it be replicated using the existing material system?

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.

 Share

×
×
  • Create New...