Join us at the Oolite Anniversary Party -- London, 7th July 2024, 1pm
More details in this thread.

Random Hits OXP

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

Inside the script, define the array like this:

Code: Select all

this.personalities-mclane-attacked=['first text','second text','third','fourth'];
Once you've got that array definition, this.personalities-mclane-attacked[0] will display 'first text' etc...

PS: Using that array, this.personalities-mclane-attacked[0,0] should produce 'f', this.personalities-mclane-attacked[0,4] would give you 't' etc...
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

Yes, I know that, and I could put all the personalities shoutouts into the script in the first place.

However, for convenience reasons I would prefer to leave the texts in descriptions.plist, and only read them into JS arrays on startUp. That would make it much easier to extend the OXP. Instead of re-releasing the script for every new personality, a new set of personalities would come with a new descriptions.plist which would be read and automatically converted into an JS-array by the script. Am I making sense here?

If that's not possible, I would rather leave it as it is. It's just because it was mentioned here that an JS-array is much more efficient that accessing descriptions.plist all the time.
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

It could be done the following way:

descriptions.plist

Code: Select all

{
    mclane-personalities-shoutout0="first";
    mclane-personalities-shoutout1="second";
       
       ....

    mclane-personalities-shoutout10="eleventh";

       ....

}
and inside script.js have:

Code: Select all

this.shoutouts=[];

this.startUp= function() {
    var i=0;
    this.shoutouts=[];
    while(expandDescription('[mclane-personalities-shoutout'+i+']') !='mclane-personalities-shoutout'+i) {
         this.shoutouts.push(expandDescription('[mclane-personalities-shoutout'+(i++)+']');
    }
    //other stuff
       ...
};
the way that while() loop is done, it should pick up all mclane-personalities-shoutoutn as long as there's no gap in the number sequence.

after this.startUp, this.shoutouts[0] should contain the string defined inside mclane-personalities-shoutout0 etc...
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
pmw57
---- E L I T E ----
---- E L I T E ----
Posts: 389
Joined: Sat Sep 26, 2009 2:14 pm
Location: Christchurch, New Zealand

Post by pmw57 »

Commander McLane wrote:
So, how do I convert the arrays in descriptions.plist into an JS-array? I haven't yet managed to address the array-entries in descriptions.plist one by one. If I try something like personalities-mclane-attacked[n], I don't get the n'th entry in the personalities-mclane-attacked array, but the n'th letter in one random entry. What is the correct JS syntax?
The script would need to be told all of the description keys that we want to use. From the top of my head:

Code: Select all

var descriptions = array['mclane-attacked', 'mclane-harried', 'mclane-worried'],
    i,
    descriptionName;
    this.personalityDescriptions = [];
for (i = 0; i < descriptions.length; i += 1) {
    descriptionName = descriptions[i];
    this.descriptions[descriptionName] = expandDescription('personalities-' + descriptionName);
}
after which you would use

Code: Select all

this.descriptions['mclane-attacked']
for an appropriately random message.

There is a trade-off incolved in this technique though. This technique does uses more memory than if they are just left there and retrieved from the plist as an when required.
Last edited by pmw57 on Mon Nov 02, 2009 10:18 pm, edited 2 times in total.
A trumble a day keeps the doctor away, and the tax man;
even the Grim Reaper keeps his distance.
-- Paul Wilkins
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

There's just one problem with pmw57's approach: expandDescription collapses an array of alternative strings into just one string. Using the example above, only one of all possible 'mclane-attacked' strings is ever stored inside the this.descriptions object.

Using my approach all the mclane-attacked strings can be made available for js to pick using Math.random().
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
pmw57
---- E L I T E ----
---- E L I T E ----
Posts: 389
Joined: Sat Sep 26, 2009 2:14 pm
Location: Christchurch, New Zealand

Post by pmw57 »

Kaks wrote:
There's just one problem with pmw57's approach: expandDescription collapses an array of alternative strings into just one string. Using the example above, only one of all possible 'mclane-attacked' strings is ever stored inside the this.descriptions object.

Using my approach all the mclane-attacked strings can be made available for js to pick using Math.random().
I agree. While my base implementation works across the board, improvements such as what Kaks has suggested can make it easier to to code up more flexible solutions.

It is also possible though, to use a customised function that automatically picks a random message.

Code: Select all

this.randomMessage = function (messageBase) {
    var messages = [],
        messageKey = '',
        index = 1;
    // add base message if it exists
    if (this.descriptions[messageBase]) {
        messages.push(this.descriptions[messageBase]);
    }
    // add 0 message if it exists
    if (this.descriptions[messageBase + '0']) {
        messages.push(messageBase + '0');
    }
    // check for messages from 1 upwards
    while (this.descriptions[messageBase + index]) {
        messages.push(messageBase + index);
        index += 1;
    }
    messageKey = messages[Math.floor(messages.length * Math.random())];
    return this.descriptions(messageKey);
};
Which you could then call as:

Code: Select all

message = this.randomMessage('mclane-personalities-shoutout');
A very minor change would also allow the function to receive an array instead, from which it would use the provided keys to return a random message.
A trumble a day keeps the doctor away, and the tax man;
even the Grim Reaper keeps his distance.
-- Paul Wilkins
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

Kaks wrote:
There's just one problem with pmw57's approach: expandDescription collapses an array of alternative strings into just one string. Using the example above, only one of all possible 'mclane-attacked' strings is ever stored inside the this.descriptions object.
So there is no way to convert a descriptions.plist array as it is into a JS array. I was afraid so.

I really don't feel like splitting all the currently 124 arrays (up to ten for each personality) in my descriptions.plist into single keys with sequenced numbers, or putting them in the worldscript in the first place. So I think for the moment everything will stay as it is, and the string expansion will be done from the plist whenever a string is needed. If I understand correctly, this will take more processor time (but not enough to cause a slowdown when a message is displayed), but less memory.

If we want to save processor time by converting descriptions from the plist into a JS script wholesale, it could be a good idea to add an optional parameter to expandDescription(), which points to the n'th position in the array. So, given this entry in descriptions.plist:

Code: Select all

    "personalities-kaks-witchspace" = (
        "This should be interesting...", 
        "Oooh, shiny!", 
        "Ah, that's what it looks like!"
    );

the following

Code: Select all

     this.ship.commsMessage(expandDescription("[personalities-kaks-witchspace]"))
would randomly display one of the three strings, but

Code: Select all

     this.ship.commsMessage(expandDescription("[personalities-kaks-witchspace]", 1))
would specifically display "Oooh, shiny!". Or could be used to put all entries into a JS array first.
pmw57
---- E L I T E ----
---- E L I T E ----
Posts: 389
Joined: Sat Sep 26, 2009 2:14 pm
Location: Christchurch, New Zealand

Post by pmw57 »

Commander McLane wrote:
Kaks wrote:
There's just one problem with pmw57's approach: expandDescription collapses an array of alternative strings into just one string.
It does? Well that's news. Up until now I didn't realise that the descriptions were capable of random messages.
Commander McLane wrote:
Using the example above, only one of all possible 'mclane-attacked' strings is ever stored inside the this.descriptions object.
How about something like this:

Code: Select all

this.descriptions['personalities-kaks-witchspace'] = [
        "This should be interesting...", 
        "Oooh, shiny!", 
        "Ah, that's what it looks like!"
];
We can easily give arrays (all arrays) a random method that they can call on.

Code: Select all

Array.prototype.random = function () {
    return this[Math.floor(Math.random() * this.length)];
};
So you can then show a random description with

Code: Select all

this.ship.commsMessage(this.description['personalities-kaks-witchspace'].random());
And if you wanted a specific message,

Code: Select all

this.ship.commsMessage(this.description['personalities-kaks-witchspace'][1]);
A trumble a day keeps the doctor away, and the tax man;
even the Grim Reaper keeps his distance.
-- Paul Wilkins
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

pmw57 wrote:
Kaks wrote:
There's just one problem with pmw57's approach: expandDescription collapses an array of alternative strings into just one string.
It does? Well that's news. Up until now I didn't realise that the descriptions were capable of random messages.
Well, yes, it does. Actually it's the whole point of having arrays in descriptions.plist. I thought we were there already. If I may remind you of your original question about Random Hits:
Commander McLane wrote:
pmw57 wrote:
The property list uses variables such as [random_hits_rocks_number2].
That's not a variable, but an entry in descriptions.plist (and yes, Random Hits uses a lot of those for the randomized descriptions).

If you want its content in a JS script, use expandDescription("[random_hits_rocks_number2]").
The whole point of using an array named [random_hits_rocks_number2] in descriptions.plist is that when it is expanded (regardless whether by legacy or JS), one of the array-entries is randomly chosen by the engine.

How about something like this:

Code: Select all

this.descriptions['personalities-kaks-witchspace'] = [
        "This should be interesting...", 
        "Oooh, shiny!", 
        "Ah, that's what it looks like!"
];
We can easily give arrays (all arrays) a random method that they can call on.

Code: Select all

Array.prototype.random = function () {
    return this[Math.floor(Math.random() * this.length)];
};
So you can then show a random description with

Code: Select all

this.ship.commsMessage(this.description['personalities-kaks-witchspace'].random());
Yes, I know all that. My only question was specifically: How can I automatically convert the array out of descriptions.plist into an JS-array. Or in other words: How do I get from this (entry in descriptions.plist, not in a JS worldscript):

Code: Select all

    "personalities-kaks-witchspace" = (
        "This should be interesting...", 
        "Oooh, shiny!", 
        "Ah, that's what it looks like!"
    );
to this:

Code: Select all

     this.description = array['descriptions.plist entry personalities-kaks-witchspace, first subentry',
     'descriptions.plist entry personalities-kaks-witchspace, second subentry',
     'descriptions.plist entry personalities-kaks-witchspace, third subentry',
     ...,
     'descriptions.plist entry personalities-kaks-witchspace, last subentry'] 
Perhaps I haven't made myself clear enough, so I try again:

I have a file named descriptions.plist, containing a long list of strings in arrays, for the very purpose of the engine choosing randomly one of those strings on certain occasions. I do not have anything in a JS script. On the previous page Kaks mentioned that it is a lot of work for the engine to extract a string from the descriptions.plist file, and it might be easier to convert all the arrays from descriptions.plist to JS arrays. My one and only question to you guys was and is: How can that be done? I do not want to rewrite the whole list manually. I am asking for a JS routine that would extract the content of descriptions.plist automatically and put it in a list of JS arrays (or a three-dimensional JS-array, doesn't matter). I do not want to know how JS chooses randomly content of an array, because I know that already. I only want to know how I create the array in the first place, without typing it into my worldscript, but only using the existing descriptions.plist.

And the answer I extracted from the bits of information from you and Kaks in my last post here above is: Currently that isn't possible. Therefore my request to make it possible, perhaps by adding an optional parameter to expandDescription(), if that would work.

And now back to Random Hits, and sorry for the thread derailment.
pmw57
---- E L I T E ----
---- E L I T E ----
Posts: 389
Joined: Sat Sep 26, 2009 2:14 pm
Location: Christchurch, New Zealand

Post by pmw57 »

Commander McLane wrote:
I am asking for a JS routine that would extract the content of descriptions.plist automatically and put it in a list of JS arrays (or a three-dimensional JS-array, doesn't matter).
That can not be one automatically from JS, but if you want to migrate the descriptions over you can use some backend processing to automatically convert the OpenStep code to JS property lists. That's about the best solution there is at this stage.
A trumble a day keeps the doctor away, and the tax man;
even the Grim Reaper keeps his distance.
-- Paul Wilkins
User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2866
Joined: Tue Apr 04, 2006 7:02 pm
Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.

Post by LittleBear »

Should point out nothing in Random Hits is hand coded, every message and BB board is randomly generated by the engine on the fly from the words listed in the arrays. The arrays are also nested so it could be a bit of a [random_hits_describe_pain] in the [random_hits_describe_place] to unravel them all! The descriptions file is about 40,000 words in about 5,000 arrays. I'm perfectley happy with you converting if you want to, but it would be an much bigger task than converting the script. If you have a look through the descriptions.plist I've flagged what each word list relates to with comments, but it'd be a big job to convert.
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
pmw57
---- E L I T E ----
---- E L I T E ----
Posts: 389
Joined: Sat Sep 26, 2009 2:14 pm
Location: Christchurch, New Zealand

Post by pmw57 »

LittleBear wrote:
Should point out nothing in Random Hits is hand coded, every message and BB board is randomly generated by the engine on the fly from the words listed in the arrays. The arrays are also nested so it could be a bit of a [random_hits_describe_pain] in the [random_hits_describe_place] to unravel them all! The descriptions file is about 40,000 words in about 5,000 arrays. I'm perfectley happy with you converting if you want to, but it would be an much bigger task than converting the script. If you have a look through the descriptions.plist I've flagged what each word list relates to with comments, but it'd be a big job to convert.
I shall stick with expandDescription for now, as being the most compatible manner in which to achieve things. Developments can occur later on, as and when need be.
A trumble a day keeps the doctor away, and the tax man;
even the Grim Reaper keeps his distance.
-- Paul Wilkins
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

As I said, back to Random Hits:

Yesterday I came across the GalMine Hopper for the first time. Very nice. It tossed around Mine Sweeper satellites, and received packages from automines. Very impressive! :D

But I think there is something wrong with its shaders. On acceleration the whole ship turns yellow, which looks distinctly odd:

Image

My guess is that perhaps only its trusters are supposed to change colour?
Screet
---- E L I T E ----
---- E L I T E ----
Posts: 1883
Joined: Wed Dec 10, 2008 3:02 am
Location: Bremen, Germany

Post by Screet »

Commander McLane wrote:
But I think there is something wrong with its shaders. On acceleration the whole ship turns yellow, which looks distinctly odd:
I once had such a bug when I still had the ATI 4870x2. Sometimes this glow according to my engine speed setting was not only set for my ship, but for every object in the whole ooniverse...since switching to nVidia I have not seen it again, but it might have had it's source somewhere else. Could it be that you did add some new ship which overwrites working shaders for other ships with a buggy one?

Screet
User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2866
Joined: Tue Apr 04, 2006 7:02 pm
Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.

Post by LittleBear »

Suspect its a driver issue of some sort as it looks far too orange even when not using its injectors - Maybe something odd caused by the orange flasher on the top. Looks normal on my system though. This is how it should look (no injectors).

Image
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
Post Reply