Jump to content
The Dark Mod Forums
demagogue

Newbie DarkRadiant Questions

Recommended Posts

Just use the model and not the entity.

 

Edit: I don't see how to delete this. See my revised answer two posts below.


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

Share this post


Link to post
Share on other sites

@JackFarmer

This lanternbot only turns toward you but stays idle in the same place. Don't know how it reacts on guards or monsters/

IdleBot.png

Edited by STRUNK

Share this post


Link to post
Share on other sites
1 hour ago, JackFarmer said:

How can I create an inactive bot?

Just use the model and not the entity.

That is if you want it to be forever inactive, like it's just a scrap of metal in a heap. If you want to activate it later and have it start "off", then I don't know offhand, but the first thing I'd do is search the spawnargs (click off the box that says hide hidden spawnargs) for one that looks like it does that job, and change it so it spawns turned off but might be turned on later (however it's set up to do that; I'd first look up if that's a thing it does, and then I'd try just changing the spawnarg, and if nothing works I'd just teleport an active one in its place by script).

Edit: You could change its visual and audio acuity to 0 so it's blind and deaf. Then it's "on" but doesn't do anything.


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

Share this post


Link to post
Share on other sites
11 minutes ago, demagogue said:

Just use the model and not the entity.

That is if you want it to be forever inactive.

Correct. It shall remain inactive during the entire mission, thus a simple model would do the trick.

However, With the keyword "steambot" the only model I can find is the one in the char folder, and that one does not show up ingame (see previous post).

bot2.thumb.jpg.9dc50825d0c9a79748c1e4d61b0bc952.jpg

Hm...

Share this post


Link to post
Share on other sites

The model is going to be listed in the spawnarg list, and I think you can just use the address from that. (If it has the address. I don't have DR in front of me now to check that.)


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

Share this post


Link to post
Share on other sites

I incorporated sliding doors (A) with switches already in HHI and HHVF. They did not pose a problem there, because AI was not meant to operate the switches and walk through the doors on normal patrols.

Well....

sliding_doors.jpg.2d6a8a231bcc2439bb445e7017fd7aee.jpg

A. The sliding doors (A) open/close only through switches (1) and (2).

With closed doors, I've tried the following:

  • path corner inside building -> path corner outside building - result: AI walks in circles before the door. As soon as the player opens the door with the switch, AI passes through it.
  • path corner inside building -> path interact (with target0 - switch) - result: AI stops before switch and refuses to do anything. (I am not even sure if I should put a target property towards the switch, as otherwise it is not possible to give the the path interact another target that would be addressed after the interaction with the switch. I cannot find more information abouth the entity on the Wiki and the inherent properties include nothing special.

Even if I would get this setup working, it would already cause problems as soon as the player would have opened the door BEFORE the AI wants to interact on its patrol.

Can somebody point me to a map with a working setup? I cannot recall seeing something similar...

 

 

Share this post


Link to post
Share on other sites

@Dragofer

 

On 1/4/2020 at 3:48 PM, Dragofer said:

1) the mover could spawn its own speaker (def_attach). A sound for it can be selected from a list provided by a new snd_move spawnarg. (Workaround for bug #5102)

I put the sound spawnargs from the original tdm_func.def in the local tdm_func.def and they work \o/

// Custom defenition

entityDef func_mover_dragofer
{
	"inherit"                               "func_mover"
	"spawnclass"				"idMover"
        "editor_displayFolder"			"Func"
	"editor_usage"				"A custom func_mover by dragofer"

        "editor_var scriptobject"		"Scriptobject this entity uses. Don't change."
        "editor_float time"                     "total time taken to move"
        "editor_float accelTime"                "time taken to accelerate"
        "editor_float decelTime"                "time taken to decelerate"
        "editor_var translate"		        "amount to translate"
        "editor_var rotate"		        "amount to rotate"
        "editor_bool invert"                    "should the mover invert after (invert_count) number of movements"
        "editor_float invert_count"             "number of movements the mover should make before inverting movement direction"
        "editor_var speaker"                    "name of the speaker the speaker bound to the mover. Unfortunately directly scripting sounds for movers is broken. #5102"
        "editor_var button"                     "name of the button controlling the mover"
        
        "editor_snd snd_accel"		        "sound to play when acceleration starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
	"editor_snd snd_move"		        "sound to play when movement starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
	"editor_snd snd_decel"		        "sound to play when deceleration starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
        
        "scriptobject"                          "reusable_script"
        "time"                                  "2"
        "accelTime"                             "1"        
        "decelTime"                             "1"
        "translate"                             "50 0 0"
        "rotate"                                "50 0 0"
        "invert"                                "1"
        "invert_count"                          "4"
        "speaker"                               "put the name of the speaker entity here"
        "button"                                "put the name of the button entity here"
	
        "snd_accel"                             "nosound"
        "snd_move"                              "nosound"
        "snd_decel"                             "nosound"
        

}

 

tdm_func.def

Edited by STRUNK

Share this post


Link to post
Share on other sites

@JackFarmer the circling suggests the AI is trying to get to a position but can't get close enough because something is in the way (monsterclip or the door). It might be the switch is too close to the door / the path_corner is too close to the switch or the door. I'd suggest spreading the switch & the path_corner out more.

(An AI can't get closer than 16 units to a monsterclip wall, and doors/moveables seem to dynamically create monsterclip walls around themselves).

Btw the correct way to use path_interact is to use "ent" spawnarg with the name of the entity to interact with.

  • Like 1

Share this post


Link to post
Share on other sites

@Dragofer

 

I found somethng.

I looked al all the inherited spawnargs/functions and there is "editor_var frob_action_script"           "Script to call when this entity is frobbed."

I put it in the custom def file, and it works when frobbed, not yet when triggered, but I get warnings concerning the reuseable script, so there might be something conflicting : )

  • Like 1

Share this post


Link to post
Share on other sites

@Dragofer   @JackFarmer

Ok, so I have almost all working without having to assign a button/speaker/target_callscriptfunction, but now it's possible to trigger/frob the object and it starts move mover echt time you do, and I can't get that under control.

You're reusable script without the button and the speaker (so button can't be switched off like before)

Spoiler

#ifndef __REUSABLE_SCRIPT__
#define __REUSABLE_SCRIPT__

object reusable_script
{
    
    vector    m_translate;        //amount to translate
    vector    m_rotate;        //amount to rotate
    float    m_time;            //total time taken to move
    float    m_accelTime;        //time taken to accelerate
    float    m_decelTime;        //time taken to decelerate

    boolean    m_invert;        //should the mover invert after (invert_count) number of movements
    float    m_invert_count;        //number of movements the mover should make before inverting movement direction
    float    m_trigger_count;    //how many times the mover has moved in one direction before inverting

    void    init();
    void     move_mover();
};


void reusable_script::init()
{
    
    m_translate        = getVectorKey("translate");
    m_rotate        = getVectorKey("rotate");
    m_time            = getFloatKey("time");        
    m_accelTime        = getFloatKey("accelTime");
    m_decelTime        = getFloatKey("decelTime");
    m_invert        = getBoolKey("invert");
    m_invert_count        = getFloatKey("invert_count");
    m_trigger_count        = -1;
}


void reusable_script::move_mover()
{
    

    if (m_invert)                                //if the mapper desires the mover to invert direction after x number of movements (invert = 1)...
    {
        m_trigger_count = m_trigger_count + 1;                //add 1 to the trigger count
        if(m_trigger_count == m_invert_count)                //when trigger count meets desired count before inverting movement...
            {
                m_translate        = -m_translate;        //invert translation vector
                m_rotate        = -m_rotate;        //invert rotation vector
                m_trigger_count     = 0;            //reset trigger count to 0
            }
    }

    vector m_currentPosition    = self.getOrigin();            //where is the mover now?
    vector m_targetPosition        = m_currentPosition + m_translate;    //add desired translation vector to current position to find target position

    sys.println(m_invert_count);
    sys.println(m_trigger_count);


    self.time(m_time);
    self.accelTime(m_accelTime);
    self.decelTime(m_decelTime);
    self.rotateOnce(m_rotate);
    self.moveToPos(m_targetPosition);
    
}


#endif __REUSABLE_SCRIPT__

The custom def file (does'nt have to be called tdm_func.def I found out)

Spoiler

// Custom defenition

entityDef func_mover_dragofer
{
        "inherit"                              "func_mover"
        "spawnclass"                           "idMover"
        "editor_displayFolder"                   "Func"
        "editor_usage"                           "A custom func_mover by dragofer"
        
        "editor_var scriptobject"               "Scriptobject this entity uses. Don't change."
        "editor_var frob_action_script"           "Script to call when this entity is frobbed. Don't change."
        "editor_float time"                    "total time taken to move"
        "editor_float accelTime"               "time taken to accelerate"
        "editor_float decelTime"               "time taken to decelerate"
        "editor_var translate"                   "amount to translate"
        "editor_var rotate"                       "amount to rotate"
        "editor_bool invert"                   "should the mover invert after (invert_count) number of movements"
        "editor_float invert_count"            "number of movements the mover should make before inverting movement direction"
        
        
        "editor_snd snd_accel"                    "sound to play when acceleration starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
        "editor_snd snd_move"                    "sound to play when movement starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
        "editor_snd snd_decel"                    "sound to play when deceleration starts.  Played on SND_CHANNEL_BODY & SND_CHANNEL_BODY2."
        "editor_var damage"                        "How much damage to cause entities that block mover."
        "editor_bool solid"                        "Whether the mover is solid to other entities."
        "editor_bool nopush"                    "set to 1 to disable pushing objects that block the mover."
        "editor_bool nodraw"                     "If set to 1 this entity is not drawn in game, meaning it is invisible."
        "editor_bool is_mantleable"                "If set to 1, this entity is not mantleable by the player. Defaults to 0."
        "editor_bool frobable"                    "If set to 1 the entity is frobable. It will use the default distance unless 'frob_distance' is set with a different value. frobable doesn't have to be set if 'frob_distance' is also set."
        "editor_int frob_distance"                "Specifes the distance when the frob highlight should become active. This setting will override the default frob distance."
        "editor_bool frob_simple"                "Set this to 1 to let the player interact with this entity even when frobbing of more complex items is forbidden (e.g., when carrying a body over their shoulder)."
        "editor_var used_by"                    "Contains an entity name of an inventory item that can be used on this object.  Multiple used_by keys are possible by numbering them (like 'used_by_3').  A used_by object calls a corresponding used_action_script_<name>, or, if a specific script is not available, it calls the default that is set in the used_action_script key.  Doors and locks use this for keys that open them as well."
        "editor_var used_by_inv_name"            "Same as used_by, but contains the inventory names of the item(s) that be used on this object."
        "editor_bool interruptable"                "Determines whether the mover motion may be stopped and reversed by frobbing it while in motion.  Defaults to true."

        
        "scriptobject"                          "reusable_script"
        "frob_action_script"                    "move_mover"
        "frobable"                              "1"
        "frob_distance"                         "100"
        "frob_simple"                           "1"
        
        "time"                                  "2"
        "accelTime"                             "1"        
        "decelTime"                             "1"
        "translate"                             "50 0 0"
        "rotate"                                "50 0 0"
        "invert"                                "1"
        "invert_count"                          "4"
       
        "snd_accel"                             "nosound"
        "snd_move"                              "nosound"
        "snd_decel"                             "nosound"
        
        "interruptable"                         "0"
        "nopush"                                "0"
        "solid"                                 "1"
        "damage"                                "0"
        "nodraw"                                "0"
        "is_mantleable"                         "0"
        
        "used_by"                               "put entity name of an inventory item here"
        "used_by_inv_name"                      "put inventory name(s) here"
        
        
        
        
        
        //Stim/Response to call the frob_action_script when triggered.
        
        "sr_class_1"           "S"
        "sr_type_1"            "STIM_TRIGGER"
        "sr_state_1"           "1"
        "sr_class_2"           "R"
        "sr_type_2"            "STIM_TRIGGER"
        "sr_state_2"           "1"
        "sr_effect_2_1"        "effect_frob"
        "sr_effect_2_1_arg1"   "_SELF"

 

}      

So .. almost there. I think "interruptable" should'nt be an option now I think of it. You want to have the mover finish the movement anyway. I don't know also if "nopush" should be an option also.

 

 

Share this post


Link to post
Share on other sites

@STRUNK Great, thanks for including all the remaining spawnargs already existing for func_movers in the entity def, that'll make it easier to use those, and for further developing the scriptobject. Haven't had as much time for actual TDM work today so it's nice to see progress still being made.

Regarding the trigger response, there are script commands to deactivate and activate responses. Just need the ID # of 'trigger', which you can find in the S/R editor.

I'd also switch from frob_action_script to S/R for frob and use the above method to deactivate/activate.

(Initially I sought other solutions than S/R because all the 'official' entities seem to use other ways to trigger themselves. But for a community resource that works as it should it's certainly fine.)

Don't really like the existing snd spawnargs. Snd_move starts playing at the start of acceleration, then restarts at the end of acceleration with a pop, then at the start of deceleration there's another pop and then silence. Also, if the soundshader for snd_accel or snd_decel loops by default, it'll continue looping after the mover has finished moving. And unfortunately scripted sounds for movers are broken. That's why I sought to workaround by spawning a speaker that can be controlled more accurately. I think for most scenarios just a single sound throughout the entire movement will be enough, for now.

Edited by Dragofer

Share this post


Link to post
Share on other sites

@Dragofer

As what the sound concerns. I have set them to nosound by default. I tried some non looping sounds and heard something so thought: it works. I'll have a look in some sound fade event I saw.

About s/r, I saw it in some defs .. don't now witch one, there I got the idea. I'm trying now to change the spawnarg/keys that call the scripts, to stop mover_move to react to trigger/frob input, but with no succes. So looking to manipulate s/r seems a good next approach. Somehow this is like a puzzle game on it's own, you only have to set your own objectives : )

 

Share this post


Link to post
Share on other sites

This line can both enable and disable a response to trigger & frob:

void ResponseEnable(float type, float state);

state: 0 = disabled, 1 = enabled

Type is the ID # seen in the S/R Editor

 

 

Hmm, spawning a speaker might not be so good after all. If something stops the mover, how does the scriptobject know it's stopped so it can turn off the speaker? Could maybe check the location & angle every frame, but that may slow things down if there are many movers moving.

Note to self: we also want trigger_at_start and trigger_at_end for all targeted entities. If it's not already existing, we can find suitable code in the candleholder scriptobjects.

Edited by Dragofer

Share this post


Link to post
Share on other sites

I'm thinking if the player drops a crate in the way of the mover. The mover should stop and, when the crate is removed, be able to continue to its target position & angle. Either automatically or when re-triggered.

Would be a good reason to check each frame how far the mover has gotten so it can resume from where it stopped.

Or check i.e. every 10 frames. This would also work, because we have disabled its response to further triggers/frobs, so it can't move any further in those 10 frames.

Edited by Dragofer

Share this post


Link to post
Share on other sites

@Dragofer

		"sr_class_1"           "S"
		"sr_type_1"            "STIM_TRIGGER"
		"sr_state_1"           "1"
        "sr_class_2"           "R"
		"sr_type_2"            "STIM_TRIGGER"
		"sr_state_2"           "1"
		"sr_effect_2_1"        "effect_frob"
		"sr_effect_2_1_arg1"   "_SELF"

I can't find any way to put it in the script without having a blue screen ... above the s/r values

 

It would be fancy to have it be able to be blocked, and move on when unblocked. It woud be interruptble also that way. But I wouldn't know how. Maybe check the script for doors .. ?

Edited by STRUNK

Share this post


Link to post
Share on other sites

@STRUNK those are spawnargs, so they should go into the def file.

Also, blue screen indicates you're working with the script from the /scripts folder? I found it much easier to develop it while it was in the map script.

Share this post


Link to post
Share on other sites

@Dragofer

They are in the def file, and I get a blu escreen when something in the reuseable script is not in the right syntax. I can't find the syntax to put the void ResponseEnable(float type, float state); in the mover_move script, so I showed the spawnags. Maybe you know what the right syntax should be?

It should work from the script folder in the end ... : )

Edited by STRUNK

Share this post


Link to post
Share on other sites

Alright, I can take a look at that tomorrow. Could you edit your post with a link to what you have so far please?

Also, since this discussion has taken on a mostly two-way character I'd suggest switching to direct messages from now on. My hope was a public discussion would let coders weigh in on any roadblocks, but I think that's much more feasible if we keep most of our exchange in a PM and post the roadblocks as precise questions in this thread.

Share this post


Link to post
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.


×
×
  • Create New...