Jump to content
The Dark Mod Forums

Recommended Posts

Posted

Helllo all,

At map start,  I want to have randomly generated digits for the safe locks and accordingly updated readables with the correct numbers.

Has anyone already done that respectively is this even possible? 

Since I am bad to the bone, I am thinking about  an element of wickedness forcing taffers to find the related information themselves.

Posted (edited)

I guess random combinations can be done by script (scriptEvent float random(float range) and setKey(string key, string value)), and I guess it can also be put in a readable, for I remember a mission by MirceaKitsune with changing readable text (after mapstart).

I always brute force safes, so you won't fool me Jack "bad boy" Farmer XD

 

Edited by STRUNK
  • Haha 1
Posted
2 minutes ago, Amadeus said:

I didn't know you could do stuff like this for readables 👀 It might be worth wikifying if it's not already on there

I'll do so.

  • Like 1
  • Thanks 3
Posted
// returns a random 3-digit safe combination. 
string getCombo()
{
	float i;
	string combo;
	combo = "";
	for (i = 0; i < 3; i++)
	{
		float digit = sys.floor(sys.random(10));
		combo = combo + digit;
	}
	return combo;
}

// sets a random combo on the specified atdm:safe_lock or atdm:safe_lock_small
void setCombo(entity safeLock)
{
	string combo = getCombo();
	safeLock.setKey("combination", combo);
}

// test
void setTheCombo()
{
	setCombo($atdm_safe_lock_2);
}

I'm a retired software programmer, so I get excited at the chance of writing a bit of code...

  • Like 2
  • Thanks 2
Posted
3 minutes ago, joebarnin said:
returns a random 3-digit safe combination.

Jack has to have it transferred to the save code(s) at map start, and into the readables.
Can you do that just as fast?

 

Posted

the setCombo method now also puts the combination into a readable. Right now it's a hard-coded location but that can be parameterized

void setCombo(entity safeLock)
{
	// get a random combination
	string combo = getCombo();

	// set it on the lock
	safeLock.setKey("combination", combo);

	// create a note with the combination
	sys.setSpawnArg("gui_page1", "guis/readables/sheets/sheet_paper_calig_mac_humaine.gui");	
	sys.setSpawnArg("page1_body", "The combination is " + combo);
	sys.setSpawnArg("inv_name", "Note with combination");
	sys.setSpawnArg("num_pages", "1");
	sys.setSpawnArg("origin", "1070 2400 -160.993");
	sys.setSpawnArg("rotation", "1 0 0 0 1 0 0 0 1");
	entity comboNote = sys.spawn("atdm:readable_mobile_scroll01");
}

 

  • Like 1
  • Thanks 1
Posted

Here's some slightly better code. Rather than having to hard-code the origin and rotation of the note, you just put a readable into map at the location you want. In this example the note is named "comboNote1". setCombo now takes two args, the lock and the note. The code creates a new readable at the same location as $comboNote1, then deletes $comboNote1

void setCombo(entity safeLock, entity note)
{
	// get a random combination
	string combo = getCombo();
	sys.println("new combo is " + combo);
	
	// set it on the lock
	safeLock.setKey("combination", combo);

	// get the properties of the note and then delete it
	string inv_name = note.getKey("inv_name");
	string origin = note.getKey("origin");
	string rotation = note.getKey("rotation");
	note.remove();
	
	// create a new note at the same location of the old one, containing the combination
	sys.setSpawnArg("gui_page1", "guis/readables/sheets/sheet_paper_calig_mac_humaine.gui");	
	sys.setSpawnArg("page1_body", "The combination is " + combo);
	sys.setSpawnArg("num_pages", "1");
	sys.setSpawnArg("inv_name", inv_name);
	sys.setSpawnArg("origin", origin);
	sys.setSpawnArg("rotation", rotation);
	entity comboNote = sys.spawn("atdm:readable_mobile_scroll01");
}

void setTheCombo()
{
	setCombo($atdm_safe_lock_2, $comboNote1);
}

This code could be parameterized even more, but it's a start. There are some limitations/provisos to this technique, which I will expand upon in the wiki (probably won't get to that until tomorrow).

  • Like 1
  • Thanks 1
Posted

If its useful at this point, I did exactly this in volta 3.  All the codes are randomly generated and included in a few readables. 

I did run into an issue with the text limits on the readables but maybe joebarnins script bypasses that. 

  • Like 1
  • Thanks 2
Posted

Based on what I've learned from what @kingsal did in Volta 3, and some other research, I've got some ideas for doing this in a more general way. The goal would be to be able to define a readable in DR with content like "Hello $1, the combination is $2") and then update the readable text with a script call like updateReadable($mobile_sheet_paper, "Jeff", "375"), and the readable text is now "Hello Jeff, the combination is 375".

Stay tuned...

  • Like 1
  • Thanks 1
Posted
22 hours ago, datiswous said:

Would it matter if the readable text comes from an xdata file or a spawnarg?

 

I've implemented something that reads from the xdata - I figured that's what most modders are using, and it provides flexibility. 

  • Thanks 1
Posted

Okay, I've coded a solution that lets you update a readable with up to three substitution strings. I'll list the limitations up front, just so you don't get too excited:

1) It supports at most three substitution strings (although this is easy to change). Scripting doesn't support arrays, so I had to pick a fixed number. 

2) As @kingsal mentioned, scripting has a problem with strings longer than 127 characters. So this doesn't work well with readables with long strings (see below).

To use:

Create your readable as you normally do. Presumably you'll edit it using the Readable Editor. In the text, use "%1" (no quotes) to indicate a string that you want to substitute (%2 for a second string, and %3 for a third).

So for example, you might have a sheet that his a title of "Hey %1" and a body of "The new combo is %2. Regards, %3"

From a script, you make a call like this:

adjustReadable($testsheet, "Chris", "375", "Jeff");

Where "$testsheet" is the name of the readable entity. The next three strings are the substitutions for %1, %2, and %3. If you only have one or two substitution strings, just pass "" for the remaining args. In game, the sheet looks like this:

image.jpeg.0216acae57b5656817b8090b506d4b50.jpeg

Like I said, it's SMOP (simple matter of programming) to support more than 3 substitution strings. But the 127 character limitation is much more difficult. It's a problem/feature with the scripting code: strings are limited to 127 characters in length. The adjustReadable() call will truncate readable strings to 127 characters, so if you have a long page in a book with a substitution string, the page will be truncated. The code is smart enough to limit the damage - if a readable string doesn't have the substitution characters (i.e., "%1")  then I won't process it at all, and the text isn't truncated. So with some planning you can get this to work - just make sure all of the pages that have substitutions are short (For example, page 1 is a wall of text, 100s of characters with no substitutions. Page 2 is brief, "And that's why I changed the combination to %1".).

Dynamically creating readables with strings longer than 127 characters is possible, but ugly. That's another whole topic, I will discuss separately. 

Here's the code. Drop it into your <fm>.script file, and call it as in the example above. Suggestions for improvement are welcomed.

string substitute(string str, string sub1, string sub2, string sub3)
{
	if (sub1 != "")	str = sys.strReplace(str, "%1", sub1);
	if (sub2 != "")	str = sys.strReplace(str, "%2", sub2);
	if (sub3 != "")	str = sys.strReplace(str, "%3", sub3);
	return str;
}

// Adjusts all of the contents of the specified readable. In any xdata content for this readable, this method will replace "%1", "%2", and "%3"
// with sub1, sub2, sub3, respectively.
void adjustReadable(entity readable, string sub1, string sub2, string sub3)
{
	string xd = readable.getKey("xdata_contents");
	readable.loadExternalData(xd, "xdx_");
    	string key = "";
   	while ((key = readable.getNextKey("xdx_", key)) != "") 
	{
        	string xdName = sys.strSkip(key, 4);
        	string xdValue = readable.getKey(key);
        	if (sys.strFind(xdName, "page", 1, 0, 4) == 0)
        	{
        		if (sys.strFind(xdValue, "%1", 0, 0, -1) >= 0 || 
        			sys.strFind(xdValue, "%2", 0, 0, -1) >= 0 || 
        				sys.strFind(xdValue, "%3", 0, 0, -1) >= 0)
        		{
	        		string newXdValue = substitute(xdValue, sub1, sub2, sub3);
	        		readable.setKey(xdName, newXdValue);
	        	}
	        }
        }
}

 

  • Like 3

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

    • MayheM

      It would be nice to have a link to the forum thread of a mission in download section, rather than having to search for it manually, like on Thief Guild.
      · 0 replies
    • taffernicus

      Anaglypta , floral and damask wallpaper look great in older homes 
      It’s rare to see anyone using “shader not found” wallpaper in their house

       
      · 0 replies
    • Ansome

      Terribly difficult juggling map designing with work, but I'm still alive and chipping away at something very special. I'm actually making a collaboration of sorts with a friend, I make the map itself and he acts as my "Chief Scope Creep Consultant" that checks in every so often to make sure this project isn't getting out of hand. It's a good system!
      · 1 reply
    • JackFarmer

      We don't need artificial intelligence; we need artistic intelligence. 
      Ralf Hütter, Kraftwerk
      · 6 replies
    • taaaki

      The post editor for the dark themes should be working again. Apologies for the inconvenience.
      · 1 reply
×
×
  • Create New...