Jump to content
The Dark Mod Forums

Help with a Thief-style chest. (Solved)


kingsal

Recommended Posts

Hey Guys,

 

I apologize ahead of time, I am a novice at scripting.

 

I am trying to create a thief-style chest; one that when opened, the items are automatically dumped into the player's inventory.

I have pretty hacky prototype. Once the player frobs open the lid (atdm:mover_binarymover_base), it targets a func_callscriptfunction. I have a hacky Stim/response that removes the lid's targets when frobbed. This prevents the player from getting items every time they open the chest. The problem is when I try to lock the lid or attach a froblock, it breaks and nothing happens. The lid doesn't seem to like having other entities bound to it or target it.

 

Any suggestions or help would be awesome?

Thanks a bunch guys.

 

 

EDIT (Solved). Thanks for everyone's help with this.

Here is the .script and .def for anyone who is interested in using this in their FM.

 

Here is the script by SteveL:

#ifndef AUTOLOOT_CHEST
#define AUTOLOOT_CHEST

//Script for autoloot chest by SteveL
// Spawnargs: "random_spawn", "random_chance"
//"random_spawn" = name of inventory item. (example "atdm:ammo_gasarrow")
//"random_chance" = Probability of spawn. (0 to 1)

void autoloot_chest(entity chest, boolean bOpen, boolean bLocked, boolean bInterrupted)
{
    // Fire only if map has been open 3 seconds (avoiding map initialisation) and 
    // only the first time the door/lid is fully opened.
    if ( sys.getTime() > 3 && bOpen && !chest.getBoolKey("already_opened") )
    {
        chest.setKey("already_opened", "1");
        // Search through "random_spawn" spawnargs, and find a matching "random_chance" spawnarg
        string key = chest.getNextKey("random_spawn", "");
        while ( key != "" )
        { 
            float chance = chest.getFloatKey(sys.strReplace(key, "_spawn", "_chance"));
            float r = sys.random(1.0);
            if ( chance > r )
            {
                entity newItem1 = sys.spawn(chest.getKey(key));
                newItem1.addItemToInv($player1);
                sys.wait(1.0);
            }
            key = chest.getNextKey("random_spawn", key);
        }
    }
}	
#endif

And the def file:

Be sure to replace the YOUR FM with your fm's directory.

//++++++++++++++++++++++++Frob Chest++++++++++++++++++++++++++++++
//Auto Loot Chest
//Uses script "autoloot_chest" by SteveL
//Spawnargs: "random_spawn", "random_chance"
//"random_spawn" = Name of inventory item. (example "atdm:ammo_gasarrow")
//"random_chance" = Probability of spawn. (0 to 1)

entityDef frob_chest_lid
{
	//editor stuff
		"inherit"		"atdm:mover_binarymover_base"
		"editor_displayFolder"	"YOUR FM/autoloot_chest/"
		"editor_usage"	        "Auto loot chest. Random_spawn = name of inventory item. (example: atdm:ammo_gasarrow). Random_chance = Probability of spawn. (0 to 1)." 
		"editor_color"		"1.00 0.82 0.29"
		"spawnclass"            "CFrobDoor"
		
	//model
		"model"			"models/darkmod/containers/openable/footlocker_wood_lid.ase"	
		
	//sound
		"snd_open"		"chest_wood_open"
		"snd_close"		"chest_wood_close"
		
	//movement
		"rotate"		"0 0 -80"
		"move_time"             "0.4"
	
	//interaction
		"frobable"              "1"
		"locked"                "0"
		"state_change_callback" "autoloot_chest"
		
}

//Chest Body
entityDef frob_chest
{
	//editor stuff
		"inherit"		"atdm:entity_base"
		"spawnclass"            "idStaticEntity"
		"editor_displayFolder"	"YOUR FM/autoloot_chest/"
		"editor_usage"          "Auto loot chest."
		"editor_color"		"1.00 0.82 0.29"
		
	//model
		"model"                 "models/darkmod/containers/openable/footlocker_wood.ase"
	
	//other stuff
		"solid"                  "1"
}
Edited by kingsal
  • Like 1
Link to comment
Share on other sites

Hello. Your script looks okay, not sure if there's any better arguments to use than just addItemToInv. If you want the items to be added just once, it's as simple as an if loop that closes after 1 frob.

float chestFrobbed = 0;

void function() {

	if (chestFrobbed == 0) {
        entity newItem1 = sys.spawn("atdm:weapon_shortsword");
        newItem1.addItemToInv($player1);
        chestFrobbed = 1;
	sys.waitFrame();
	}
}

It's probably tidier to do it with a boolean, but boolean and entitity data types can't be immediately declared it seems, don't know why.

  • Like 1

My FMs: The King of Diamonds (2016) | Visit my Mapbook thread sometimes! | Read my tutorial on Image-Based Lighting Workflows for TDM!

 

 

Link to comment
Share on other sites

There are no booleans in the scripting language, so you have to use float. Wouldn't it make more sense to use a script object instead a global script to do this? Otherwise you will have to write a separate script function for every chest.

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

Spooks- I tried your script out and it works really well and is much cleaner. It also works with being locked and having a froblock attached to it. Thanks so much! :D

 

Obs- That would definitely be a more solid solution and friendlier to the mission designer. It would be nice to be able to select the items as spawnargs inside darkradiant.

There is one small advantage to each chest having its own script, you can make edits to its contents without digging around for it in the editor. If for instance, you wanted to quickly balance the items across the entire map.

 

Thanks guys for the help!

  • Like 1
Link to comment
Share on other sites

There is one small advantage to each chest having its own script, you can make edits to its contents without digging around for it in the editor. If for instance, you wanted to quickly balance the items across the entire map.

 

You could probably use the menu function that selects all entities that have the same model as the one you have selected. That'd let you skip between chests in the map easily.

 

The script object version would also let you balance the loot distribution by setting a probability against each item so you could have the same spawnargs on every chest and still keep the loot balanced.

 

e.g.

"random_spawn1" "atdm:weapon_shortsword"

"random_chance1" "20"

 

I don't mind providing the starter script object if you want to try it out. The documentation is a bit brief, both ours and ID's.

  • Like 1
Link to comment
Share on other sites

Steve- If its something you're interested in, that would be awesome. I'd definitely like to try it out! It sounds like a much better long term solution.

 

I do like the TDM style chests with the items being optional to pick up, it feels immersive. However, there are some nice advantages to an item dump chest, you don't have to worry about bsp recompiling if you move it and you can easily balance item distribution.

  • Like 1
Link to comment
Share on other sites

There are no booleans in the scripting language, so you have to use float. Wouldn't it make more sense to use a script object instead a global script to do this? Otherwise you will have to write a separate script function for every chest.

 

Somebody needs to update the Scripting Basics page on the wiki then, the Boolean data type is stated to exist there. At the very least it should be noted booleans and entities can't have their values set outside of a function (i.e. at declaration time when they're global variables).

  • Like 1

My FMs: The King of Diamonds (2016) | Visit my Mapbook thread sometimes! | Read my tutorial on Image-Based Lighting Workflows for TDM!

 

 

Link to comment
Share on other sites

The wiki actually states that it is a float.

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

Yes, but unlike floats it throws up errors to the likes of "wrong immediate type of boolean data type" when you try to set a value, unlike float. I'm just wondering why it's even a data type, for some sort of parity? We already don't have int.

My FMs: The King of Diamonds (2016) | Visit my Mapbook thread sometimes! | Read my tutorial on Image-Based Lighting Workflows for TDM!

 

 

Link to comment
Share on other sites

its used to see if a door is open or closed as in (boolean bOpen) it checks that bOpen is true or false if you remove it then doors controlled by scripts will fail to function, and you'll break many maps that use that function.

eg

void sewerhatch1_state(entity mover_lever, boolean bOpen, boolean bLocked, boolean bInterrupted)
{
if (bOpen)
{
$manhole_cover_1a.Open();
}
else
{
$manhole_cover_1a.Close();
}
}

  • Like 1
Link to comment
Share on other sites

void sewerhatch1_state(entity mover_lever, boolean bOpen, boolean bLocked, boolean bInterrupted)

Ah, that's a "state_change_callback" script.

 

@kingsal You could use one of those more simply than a script object to get the job done with the chest. state_change_callback is a way to call a script when a door is moved or a button is pressed. Unlike most ways to call a script, the script gets told which entity fired it.

 

Chest lids are doors, so you could put your spawnargs on the lid along with "state_change_callback" "autoloot_chest"

 

Then in your map script:

void autoloot_chest(entity chest, boolean bOpen, boolean bLocked, boolean bInterrupted)
{
    // Fire only if map has been open 3 seconds (avoiding map initialisation) and 
    // only the first time the door/lid is fully opened.
    if ( sys.getTime() > 3 && bOpen && !chest.getBoolKey("already_opened") )
    {
        chest.setKey("already_opened", "1");
        // Search through "random_spawn" spawnargs, and find a matching "random_chance" spawnarg
        string key = chest.getNextKey("random_spawn", "");
        while ( key != "" )
        { 
            float chance = chest.getFloatKey(sys.strReplace(key, "_spawn", "_chance"));
            float r = sys.random(1.0);
            if ( chance > r )
            {
                entity newItem1 = sys.spawn(chest.getKey(key));
                newItem1.addItemToInv($player1);
                sys.wait(1.0);
            }
            key = chest.getNextKey("random_spawn", key);
        }
    }
}
The script disables a chest by adding a spawnarg to it in real time. You can use any random_spawnXYZ spawnarg naming scheme as long as there's a matching random_chanceXYZ sparnarg for each. Without the matching spawnarg, the chance will come out at 0 so the item won't ever be added.

 

I tested it with these s/args on a chest lid:

"random_spawn1" "atdm:ammo_firearrow"

"random_spawn2" "atdm:ammo_mossarrow"

"random_spawnA" "atdm:ammo_broadhead"

"random_chanceA" "0.5"

"random_chance1" "0.8"

"random_chance2" "0.5"

"state_change_callback" "autoloot_chest"

 

You can make a new entity def with your preferred settings. Then changing the def will change all matching chest lids that haven't overridden the spawnargs.

 

If you want to stick to your original plan of a separate script for each chest then Spooks' global variable is the quick way as you found, but that method only works with a separate script for each chest, because a script shared between chests wouldn't know which chest had triggered it (and so couldn't disable the right chest).

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

Oh awesome Steve.

 

I am a novice when it comes to scripting, but this is really helpful. If I get a chance today or tomorrow I will plug in your script and give it a shot.

This is fantastic.

 

I can see getting a lot of use out of both scripts for different purposes.

  • Like 1
Link to comment
Share on other sites

Cool. I added a fix to the script above by the way by moving
chest.setKey("already_opened", "1");
to the top of the block, so the player can't trigger the script a second time during the sys.wait()s between multiple items being spawned.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Sorry for the delayed response on this.

I've tested out Steve's script and wrote a .def if anyone wants to use it in their FM. Edited in the first post

 

Thanks for the help everyone!

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...