Page 105 of 118

Re: Scripters cove

Posted: Fri Jun 10, 2022 1:57 am
by montana05
szaumix wrote: Fri Jun 10, 2022 1:39 am
OK so another question for those who know.
Can anyone briefly expound on auto_weapons and auto_ai in the shipdata plist? What kinds of overrides -- specifically -- can I expect with them flagged as true? I'm in the middle of a shipdata_overrides.plist rebalance of core ship specs and, more significantly, their roles. And I just want to make sure of how exact I should be.

Actually a better question might be, what is the benefit of auto_weapons and auto_ai flagged as true?
Thanks!
auto_ai in most cases is useful. Depending on the role a matching AI will be assigned. Personally, I only turn if off if a specific behavior aka custom AI is required.

auto_weapons permits a change of the weapons defined in the shipdata.plist, therefore, a pulse laser could become a military laser or even an OXP weapon. While offering more variety, I would suggest handling it with care so that not suddenly ueber-pirates or assassins flooding the game.

Re: Scripters cove

Posted: Fri Jun 10, 2022 2:06 am
by szaumix
montana05 wrote: Fri Jun 10, 2022 1:57 am
auto_ai in most cases is useful. Depending on the role a matching AI will be assigned. Personally, I only turn if off if a specific behavior aka custom AI is required.

auto_weapons permits a change of the weapons defined in the shipdata.plist, therefore, a pulse laser could become a military laser or even an OXP weapon. While offering more variety, I would suggest handling it with care so that not suddenly ueber-pirates or assassins flooding the game.
About what I had suspected. I don't suppose you know if anything other than just laser strength is affected? For example laser count (Like adding an aft_weapon? Or subtracting port or starbord lasers that I'd added?)? Or missile count, or type?

Re: Scripters cove

Posted: Fri Jun 10, 2022 8:09 am
by phkb
szaumix wrote: Fri Jun 10, 2022 2:06 am
don't suppose you know if anything other than just laser strength is affected? For example laser count (Like adding an aft_weapon? Or subtracting port or starbord lasers that I'd added?)? Or missile count, or type?
auto_weapons controls the equipment given to ships, based on their role, including lasers. Side lasers aren't ever given to NPC ships by the auto_weapons key.

Re: Scripters cove

Posted: Sat Jun 18, 2022 3:16 am
by szaumix
Thanks fellas. It occurs to me that it would be nice if there were a function to increase or decrease possibility of any given laser strength or missile type as a decimal -- as with other equipment.

Still not sure if this is correct long ago I surmised that the laser I had was affecting the auto_weapons variable of NPCs, and the only solution to this "problem" seems to be entirely new like_ship iterations with auto_weapons disabled and laser/missile preferences preset, with role weight functioning as probability.

Re: Scripters cove

Posted: Fri Jun 24, 2022 1:53 pm
by Alnivel
Hi everyone. I hope this is the right thread to ask for advice. I stumbled upon the following problem:
Script A has a runScreen callback binded to this script. The callback calls runScreen with nobinded callbacks.
I need to call runScreen in script B so that nested callbacks have script A as this.

Now questions:
Is there any way in script B to call a function as if it was called from script A?
Are there other ways to solve the above problem?
How can I get the name of the script that is currently running? (I already have one, via new Error.stack, but is there a better one?)

Re: Scripters cove

Posted: Sat Jun 25, 2022 4:49 am
by phkb
Alnivel wrote: Fri Jun 24, 2022 1:53 pm
Is there any way in script B to call a function as if it was called from script A?
Not sure if this will work, but worth a try.

Code: Select all

this.name = "ScriptB";

this.testFunction = function() {
    var newFunc = worldScripts.ScriptA.runScreen.bind(worldScripts.ScriptA);
    newFunc();
}

Re: Scripters cove

Posted: Sat Jun 25, 2022 8:12 am
by Alnivel
phkb wrote: Sat Jun 25, 2022 4:49 am
Alnivel wrote: Fri Jun 24, 2022 1:53 pm
Is there any way in script B to call a function as if it was called from script A?
Not sure if this will work, but worth a try.

Code: Select all

this.name = "ScriptB";

this.testFunction = function() {
    var newFunc = worldScripts.ScriptA.runScreen.bind(worldScripts.ScriptA);
    newFunc();
}
Now I see that I didn't make it clear enough that by runScreen I mean Mission.runScreen and not a function of script A, sorry.

Re: Scripters cove

Posted: Fri Jul 01, 2022 2:12 pm
by Old Murgh
Kind gents, I have another little twist I hope you could help with.

In looking to recreate my original primitive hOpy casino, without the array of other games offered by skilled maintainers, I've had some luck in boiling it down to the original simple hOopy casino, and I think the game mechanics are working just as they should. Perfect.

–Except, in this .js version, the hoopy_theme starts only once the game is selected in the menu, and then stops and restarts with each screen change which isn't too pleasant.

Code: Select all

"use strict";

this.name = "hoopy_casino";
this.author = "Paul Wilkins (updated by Eric Walch, further updated by spara)";
this.copyright = "(C) 2009 Paul Wilkins";
this.license     = "CC BY-NC-SA 3.0"; 

//add interface
this.startUpComplete = this.shipExitedWitchspace = function() {
	var casinos = system.shipsWithPrimaryRole("casinoship");
	if (casinos.length > 0) {
		for (var i = 0; i < casinos.length; i++) {
			casinos[i].setInterface("hoopy-hoops",{
				title: expandMissionText("hoopy-hoops-title"),
				category: expandMissionText("hoopy-gambling-category"),
				summary: expandMissionText("hoopy-hoops-summary"),
				callback: this.$startGambling.bind(this)
			});
		}
	}
}

//init the hoops
this.shipDockedWithStation = function (station) {
	if (player.ship.docked && station.primaryRole === 'casinoship') {
        missionVariables.hoopy_casino = 'NOT_NOW';
        this.setBoundaries();
    }
};

this.missionScreenOpportunity = function ()
{
    if (player.ship.docked && player.ship.dockedStation.primaryRole === 'casinoship') 
    {
        this.gamble();
    }
};


this.setBoundaries = function () {
        /*
        In the legacy version the random distribution was bad. One could win after analysing the odds
        during some time. This is a feature that should stay in. So we prepare the gamble table now a bit.
        */
        this.boundary1 = 1 + Math.random() - Math.random();
        this.boundary2 = 2 + Math.random() - Math.random();
        if (this.boundary1 > this.boundary2) this.boundary1 = this.boundary2;
        this.startCapital = player.credits;
};

this.$startGambling = function() {
	missionVariables.hoopy_casino = 'HOOPY_ENTER';
	this.gambleChoices('YES_HOOPY');
}

this.gamble = function () {
	/*
    if (missionVariables.hoopy_casino === 'HOOPY_REVISIT') {
        if (player.credits >= 100) {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_intro', overlay: 'hoopy_front.png', choicesKey: 'hoopy_casino_enter_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
            missionVariables.hoopy_casino = 'HOOPY_ENTER';
            return;
        }
    }*/
    if (missionVariables.hoopy_casino === 'HOOPY_GAMEON') {
        mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_choices', overlay: 'hoopy_cover.png', choicesKey: 'hoopy_casino_pick_hoop', music: "hoopy_theme.ogg"}, this.gambleChoices);
        this.hoopy_casino_hoop = Math.random() * 3;
        missionVariables.hoopy_casino = 'HOOPY_MAKE_CHOICE';
        return;
    }
    if (player.credits > this.startCapital + 2000) {
        mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_new_table', overlay: 'hoopy_front.png', choicesKey: 'hoopy_casino_new_table_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
        missionVariables.hoopy_casino = 'HOOPY_NEW_TABLE';
        this.setBoundaries();
    } else {
        if (missionVariables.hoopy_casino === 'HOOPY_WINNER') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_win', overlay: this.hoopy_casino_image, choicesKey: 'hoopy_casino_replay_winner_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
            player.credits += 100;
            missionVariables.hoopy_casino = 'HOOPY_REPLAY';
        }
        if (missionVariables.hoopy_casino === 'HOOPY_LOSER') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_loss', overlay: this.hoopy_casino_image, choicesKey: 'hoopy_casino_replay_loser_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
            player.credits -= 100;
            missionVariables.hoopy_casino = 'HOOPY_REPLAY';
        }
    }
    if (missionVariables.hoopy_casino === 'NOT_NOW') {
        delete this.hoopy_casino_hoop;
        delete this.hoopy_casino_image;
        delete missionVariables.hoopy_casino;
    }
};
this.gambleChoices = function (choice){
    if (missionVariables.hoopy_casino === 'HOOPY_ENTER') {
        if (choice === 'YES_HOOPY') {
			if (player.credits >= 100) {
				mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_desc', overlay: 'hoopy_clean.png', choicesKey: 'hoopy_casino_gamble_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
				missionVariables.hoopy_casino = 'HOOPY_GAMBLE';
			}
			else {
				missionVariables.hoopy_casino = 'HOOPY_REPLAY';
				this.gambleChoices('YES_HOOPY');
				return;
			}
        } else if (choice === 'NO_HOOPY') {
            missionVariables.hoopy_casino = 'NOT_NOW';
        }
        return;
    }
    if (missionVariables.hoopy_casino === 'HOOPY_GAMBLE') {
        if (choice === '0_HOOPY') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_desc', overlay: 'hoopy_clean.png', choicesKey: 'hoopy_casino_gamble_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
        } else if (choice === 'YES_HOOPY') {
            missionVariables.hoopy_casino = 'HOOPY_GAMEON';
        } else if (choice === 'NO_HOOPY') {
            missionVariables.hoopy_casino = 'NOT_NOW';
        }
        return;
    }
    if (missionVariables.hoopy_casino === 'HOOPY_MAKE_CHOICE') {
        missionVariables.hoopy_casino = 'HOOPY_LOSER';
        if (this.hoopy_casino_hoop < this.boundary1) {
			this.hoopy_casino_image = 'hoopy_Lwin.png';
            if (choice === 'LEFT_HOOPY') {
                missionVariables.hoopy_casino = 'HOOPY_WINNER';
            }
        }
        if (this.hoopy_casino_hoop >= this.boundary1 && this.hoopy_casino_hoop < this.boundary2) {
			this.hoopy_casino_image = 'hoopy_Cwin.png';
            if (choice === 'MIDDLE_HOOPY') {
                missionVariables.hoopy_casino = 'HOOPY_WINNER';
            }
        }
        if (this.hoopy_casino_hoop >= this.boundary2) {
			this.hoopy_casino_image = 'hoopy_Rwin.png';
            if (choice === 'RIGHT_HOOPY') {
                missionVariables.hoopy_casino = 'HOOPY_WINNER';
            }
        }
        return;
    }
    if (missionVariables.hoopy_casino === 'HOOPY_NEW_TABLE') {
        if (choice === 'NEW_TABLE_HOOPY') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_desc', overlay: 'hoopy_clean.png', choicesKey: 'hoopy_casino_gamble_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
            missionVariables.hoopy_casino = 'HOOPY_GAMBLE';
        } else if (choice === 'NO_HOOPY') {
            missionVariables.hoopy_casino = 'NOT_NOW';
        }
        return;
    }
    if (missionVariables.hoopy_casino === 'HOOPY_REPLAY') {
        if (choice === '0-WINNER_HOOPY') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_win', overlay: this.hoopy_casino_image, choicesKey: 'hoopy_casino_replay_winner_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
        }
        if (choice === '0-LOSER_HOOPY') {
			mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_loss', overlay: this.hoopy_casino_image, choicesKey: 'hoopy_casino_replay_loser_yesno', music: "hoopy_theme.ogg"}, this.gambleChoices);
        }
        if (choice === 'YES_HOOPY') {
            if (player.credits >= 100) {
                mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_again', overlay: 'hoopy_clean.png', music: "hoopy_theme.ogg"});
                missionVariables.hoopy_casino = 'HOOPY_GAMEON';
            } else {
                mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_nofunds', overlay: 'hoopy_front.png', music: "hoopy_theme.ogg"});
                missionVariables.hoopy_casino = 'NOT_NOW';
            }
        }
        if (choice === 'NO_HOOPY') {
            mission.runScreen({title: "Hoopy Casino", messageKey: 'hoopy_casino_goodbye', overlay: 'hoopy_front.png', music: "hoopy_theme.ogg"});
            missionVariables.hoopy_casino = 'NOT_NOW';
        }
	}    
};
Since I would much rather that the music begins instantly once docked at the casino and plays all the way through until space launch, so I gather I would remove all the current instances of music: "hoopy_theme.ogg", but where would I place the one I want for the play at arrival effect?

That, and I wish I could have the "Play hOopy" option appear at the very top of the menu, but I've learned to accept I can't always get what I want.

Re: Scripters cove

Posted: Fri Jul 01, 2022 7:41 pm
by Alnivel
Old Murgh wrote: Fri Jul 01, 2022 2:12 pm
Since I would much rather that the music begins instantly once docked at the casino and plays all the way through until space launch, so I gather I would remove all the current instances of music: "hoopy_theme.ogg", but where would I place the one I want for the play at arrival effect?
How about using a looped SoundSource in the shipDockedWithStation handler for play and stopping it during shipWillLaunchFromStation?

Code: Select all

this.startUpComplete = function(){
    var bgmSoundSource = new SoundSource;
    bgmSoundSource.sound = "hoopy_theme.ogg";
    bgmSoundSource.loop = true;
    this._bgmSoundSource = bgmSoundSource;
}

this.shipDockedWithStation = function (station) {
    if (player.ship.docked && station.primaryRole === 'casinoship') {
        this._bgmSoundSource.play();
    }
};

this.shipWillLaunchFromStation = function() {
    this._bgmSoundSource.stop();
};
(I would like to point out that I was only able to get the sound to work in that way after I moved it to the Sounds folder.)
Old Murgh wrote: Fri Jul 01, 2022 2:12 pm
That, and I wish I could have the "Play hOopy" option appear at the very top of the menu, but I've learned to accept I can't always get what I want.
Interface menu items are ordered by category first, so you can try changing the category name.
Not sure how good this approach is, but you can try put the interface at the top of the list by adding a (nearly) invisible ASCII control character that is "smaller" than any letter to the beginning of the category name.

Code: Select all

this.startUpComplete = this.shipExitedWitchspace = function() {
    var casinos = system.shipsWithPrimaryRole("casinoship");
    if (casinos.length > 0) {
        for (var i = 0; i < casinos.length; i++) {
            casinos[i].setInterface("hoopy-hoops",{
                title: expandMissionText("hoopy-hoops-title"),
                category: String.fromCharCode(0x1F) + expandMissionText("hoopy-gambling-category"), // Put a control character here...
                summary: expandMissionText("hoopy-hoops-summary"),
                callback: this.$startGambling.bind(this)
            });
        }
    }
}
... or add it directily in "hoopy-gambling-category" in .plist file. I'm not sure, but I think you can write the character as "\x1F" in it.

Re: Scripters cove

Posted: Fri Jul 01, 2022 10:12 pm
by Old Murgh
Alnivel wrote: Fri Jul 01, 2022 7:41 pm
How about using a looped SoundSource in the shipDockedWithStation handler for play and stopping it during shipWillLaunchFromStation? ...
You're a wizard, sir, and your username obviously appropriate.
That did exactly what I hoped.
It feels so good to copy and paste the brainwork of smarter people.

As you point out the alphabetical nature of the categories does allow for a low-tech way to sneak to the top of the queue. Since I dread messing with all that works from the missiontext.plist angle (well I couldn't make "\x1F" do anything other than print just that), the easy way is to skip ahead of "Activities" is to rename Gambling to Absorbing Gambling. Or should that be Abhorrent Gambling?

At any rate, the obstacle of the day is conquered. Thank you very much!

Re: Scripters cove

Posted: Thu Jul 07, 2022 11:48 pm
by Old Murgh
I'm trying to get a better grip on how to interpret this line, but it's not easy when one's brain isn't wired for such things.
phkb wrote: Sat Jun 04, 2022 9:57 am
To keep the dice roll function as is, you'd need to do this:

Code: Select all

this.systemWillPopulate = function ()
{
	if (Math.floor(Math.random() > 0.10)  // 90% chance
..
which was later amended to
montana05 wrote: Sat Jun 04, 2022 2:44 pm

Code: Select all

if (Math.floor(Math.random() * 10) > 0)  // returns a random integer from 0 to 9 so there is a 90% chance
The bottom one works fine for the 90% appearance, but if I'm trying to know what I'm doing, and I would like a less frequent appearance, do I interpret the above as 10% not appearing, so to achieve 40% appearance probability, do I make the 10 into 60? Or am I thinking wrong?

Re: Scripters cove

Posted: Fri Jul 08, 2022 12:14 am
by montana05
Old Murgh wrote: Thu Jul 07, 2022 11:48 pm
I'm trying to get a better grip on how to interpret this line, but it's not easy when one's brain isn't wired for such things.
phkb wrote: Sat Jun 04, 2022 9:57 am
To keep the dice roll function as is, you'd need to do this:

Code: Select all

this.systemWillPopulate = function ()
{
	if (Math.floor(Math.random() > 0.10)  // 90% chance
..
which was later amended to
montana05 wrote: Sat Jun 04, 2022 2:44 pm

Code: Select all

if (Math.floor(Math.random() * 10) > 0)  // returns a random integer from 0 to 9 so there is a 90% chance
The bottom one works fine for the 90% appearance, but if I'm trying to know what I'm doing, and I would like a less frequent appearance, do I interpret the above as 10% not appearing, so to achieve 40% appearance probability, do I make the 10 into 60? Or am I thinking wrong?
Have a look here: https://www.w3schools.com/js/js_random.asp

Basically, this function will return a random number between 0 and 9 so to lower the appearing you would need to change it to > 6 which would offer only a 30% chance for example.

Re: Scripters cove

Posted: Fri Jul 08, 2022 12:53 am
by Old Murgh
montana05 wrote: Fri Jul 08, 2022 12:14 am
Have a look here: https://www.w3schools.com/js/js_random.asp

Basically, this function will return a random number between 0 and 9 so to lower the appearing you would need to change it to > 6 which would offer only a 30% chance for example.
I think (no, hope is the word) I get it.
Because it will never return a perfect 1, am I then correct in thinking

Code: Select all

if (Math.floor(Math.random() * 10) > 4)  
will result in a 50/50 coinflip? :shock:

Re: Scripters cove

Posted: Fri Jul 08, 2022 7:19 am
by cbr
or

Math.round(Math.random())

= 0/1

Re: Scripters cove

Posted: Fri Jul 08, 2022 10:50 pm
by phkb
My suggestion is

Code: Select all

if (Math.random() < 0.1) 
Because it removes unnecessary calculations, while still being clear what percentage is being checked, in this case a 10% chance. To make it 50% just change 0.1 to 0.5.