mirror of
https://gitgud.io/BondageProjects/Bondage-College.git
synced 2025-04-25 17:59:34 +00:00
feat. Lewdgambler Palaace demo
This commit is contained in:
parent
d590640912
commit
45363c15f1
21 changed files with 1181 additions and 88 deletions
BondageClub
Backgrounds
Icons
Screens/Room
Gambling
LewdgamblerEntrance
LewdgamblerGameBiddingDuel
Bubble.pngDialog_NPC_LewdgamblerBiddingGame_Loose.csvDialog_NPC_LewdgamblerBiddingGame_Win.csvLewdgamblerGameBiddingDuel.jscore.js
LewdgamblerHall
MainHall
utils.jsScripts
index.html
BIN
BondageClub/Backgrounds/LewdgamblerEntrance.jpg
Normal file
BIN
BondageClub/Backgrounds/LewdgamblerEntrance.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 871 KiB |
BIN
BondageClub/Backgrounds/LewdgamblerRoom.jpg
Normal file
BIN
BondageClub/Backgrounds/LewdgamblerRoom.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 676 KiB |
BIN
BondageClub/Backgrounds/LewdgamblerRoomGameTable.jpg
Normal file
BIN
BondageClub/Backgrounds/LewdgamblerRoomGameTable.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 127 KiB |
BIN
BondageClub/Icons/Lewdgambler.png
Normal file
BIN
BondageClub/Icons/Lewdgambler.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 2.5 KiB |
|
@ -272,25 +272,25 @@ function GamblingSimpleDiceController(SimpleDiceState) {
|
||||||
if (GamblingPlayerDice > GamblingNpcDice) {
|
if (GamblingPlayerDice > GamblingNpcDice) {
|
||||||
GamblingFirstSub.AllowItem = true;
|
GamblingFirstSub.AllowItem = true;
|
||||||
GamblingFirstSub.Stage = 81;
|
GamblingFirstSub.Stage = 81;
|
||||||
}
|
}
|
||||||
if (GamblingPlayerDice < GamblingNpcDice) {
|
if (GamblingPlayerDice < GamblingNpcDice) {
|
||||||
GamblingFirstSub.AllowItem = false;
|
GamblingFirstSub.AllowItem = false;
|
||||||
GamblingFirstSub.Stage = 82;
|
GamblingFirstSub.Stage = 82;
|
||||||
}
|
}
|
||||||
if (GamblingPlayerDice == GamblingNpcDice) {
|
if (GamblingPlayerDice == GamblingNpcDice) {
|
||||||
GamblingFirstSub.AllowItem = false;
|
GamblingFirstSub.AllowItem = false;
|
||||||
GamblingFirstSub.Stage = 83;
|
GamblingFirstSub.Stage = 83;
|
||||||
}
|
}
|
||||||
} else if (SimpleDiceState == "win") {
|
} else if (SimpleDiceState == "win") {
|
||||||
GamblingFirstSub.Stage = 0;
|
GamblingFirstSub.Stage = 0;
|
||||||
ReputationProgress("Gambling", 1);
|
ReputationProgress("Gambling", 1);
|
||||||
} else if (SimpleDiceState == "lost") {
|
} else if (SimpleDiceState == "lost") {
|
||||||
InventoryWearRandom(Player, "ItemArms");
|
InventoryWearRandom(Player, "ItemArms");
|
||||||
GamblingFirstSub.Stage = 0;
|
GamblingFirstSub.Stage = 0;
|
||||||
} else if (SimpleDiceState == "equal") {
|
} else if (SimpleDiceState == "equal") {
|
||||||
InventoryRemove(Player, "ItemArms");
|
InventoryRemove(Player, "ItemArms");
|
||||||
InventoryRemove(GamblingFirstSub, "ItemArms");
|
InventoryRemove(GamblingFirstSub, "ItemArms");
|
||||||
GamblingFirstSub.Stage = 0;
|
GamblingFirstSub.Stage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ function GamblingTwentyOneController(TwentyOneState) {
|
||||||
GamblingFirstSub.AllowItem = true;
|
GamblingFirstSub.AllowItem = true;
|
||||||
GamblingFirstSub.Stage = 0;
|
GamblingFirstSub.Stage = 0;
|
||||||
ReputationProgress("Gambling", 3);
|
ReputationProgress("Gambling", 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
GamblingPlayerDiceStack = [];
|
GamblingPlayerDiceStack = [];
|
||||||
GamblingNpcDiceStack = [];
|
GamblingNpcDiceStack = [];
|
||||||
|
@ -455,7 +455,7 @@ function GamblingTwentyOneController(TwentyOneState) {
|
||||||
GamblingFirstSub.Appearance = GamblingAppearanceFirst.slice();
|
GamblingFirstSub.Appearance = GamblingAppearanceFirst.slice();
|
||||||
CharacterRefresh(GamblingFirstSub);
|
CharacterRefresh(GamblingFirstSub);
|
||||||
GamblingFirstSub.Stage = 0;
|
GamblingFirstSub.Stage = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GamblingPlayerDiceStack = [];
|
GamblingPlayerDiceStack = [];
|
||||||
GamblingNpcDiceStack = [];
|
GamblingNpcDiceStack = [];
|
||||||
|
@ -472,75 +472,75 @@ function GamblingTwentyOneController(TwentyOneState) {
|
||||||
* @param {"new" | "fox" | "hunter" | "NextDice" | "player_fox_win" | "player_fox_lost" | "player_hunter_lost" | "player_hunter_win"} FoxState - The current state of the game
|
* @param {"new" | "fox" | "hunter" | "NextDice" | "player_fox_win" | "player_fox_lost" | "player_hunter_lost" | "player_hunter_win"} FoxState - The current state of the game
|
||||||
*/
|
*/
|
||||||
function GamblingFoxController(FoxState) {
|
function GamblingFoxController(FoxState) {
|
||||||
if (FoxState == "new") {
|
if (FoxState == "new") {
|
||||||
GamblingPlayerDiceStack = [];
|
GamblingPlayerDiceStack = [];
|
||||||
GamblingNpcDiceStack = [];
|
GamblingNpcDiceStack = [];
|
||||||
GamblingShowMoney = true;
|
GamblingShowMoney = true;
|
||||||
} else if (FoxState == "fox") {
|
} else if (FoxState == "fox") {
|
||||||
GamblingPlayerIsFox = true;
|
GamblingPlayerIsFox = true;
|
||||||
GamblingPlayerDice = Math.floor(Math.random() * 6) + 1;
|
GamblingPlayerDice = Math.floor(Math.random() * 6) + 1;
|
||||||
GamblingPlayerDiceStack[GamblingPlayerDiceStack.length] = GamblingPlayerDice;
|
GamblingPlayerDiceStack[GamblingPlayerDiceStack.length] = GamblingPlayerDice;
|
||||||
GamblingMoneyBet = 5;
|
GamblingMoneyBet = 5;
|
||||||
|
GamblingSecondSub.Stage = 101;
|
||||||
|
} else if (FoxState == "hunter") {
|
||||||
|
GamblingPlayerIsFox = false;
|
||||||
|
GamblingMoneyBet = 5;
|
||||||
|
CharacterChangeMoney(Player, GamblingMoneyBet * -1);
|
||||||
|
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
||||||
|
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
||||||
|
GamblingSecondSub.Stage = 101;
|
||||||
|
} else if (FoxState == "NextDice") {
|
||||||
|
GamblingPlayerDice = Math.floor(Math.random() * 6) + 1;
|
||||||
|
GamblingPlayerDiceStack[GamblingPlayerDiceStack.length] = GamblingPlayerDice;
|
||||||
|
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
||||||
|
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
||||||
|
if (GamblingPlayerIsFox && GamblingDiceStackSum(GamblingPlayerDiceStack) >= 30) {
|
||||||
|
//player has won
|
||||||
|
GamblingSecondSub.Stage = 102;
|
||||||
|
} else if (!GamblingPlayerIsFox && GamblingDiceStackSum(GamblingNpcDiceStack) >= 30) {
|
||||||
|
//npc has won
|
||||||
|
GamblingSecondSub.Stage = 103;
|
||||||
|
} else if (GamblingPlayerIsFox && (GamblingDiceStackSum(GamblingPlayerDiceStack) <= GamblingDiceStackSum(GamblingNpcDiceStack))) {
|
||||||
|
//npc has won
|
||||||
|
GamblingSecondSub.Stage = 104;
|
||||||
|
} else if (!GamblingPlayerIsFox && (GamblingDiceStackSum(GamblingNpcDiceStack) <= GamblingDiceStackSum(GamblingPlayerDiceStack))) {
|
||||||
|
//player has won
|
||||||
|
GamblingSecondSub.Stage = 105;
|
||||||
|
} else {
|
||||||
|
//next dice
|
||||||
GamblingSecondSub.Stage = 101;
|
GamblingSecondSub.Stage = 101;
|
||||||
} else if (FoxState == "hunter") {
|
|
||||||
GamblingPlayerIsFox = false;
|
|
||||||
GamblingMoneyBet = 5;
|
|
||||||
CharacterChangeMoney(Player, GamblingMoneyBet * -1);
|
|
||||||
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
|
||||||
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
|
||||||
GamblingSecondSub.Stage = 101;
|
|
||||||
} else if (FoxState == "NextDice") {
|
|
||||||
GamblingPlayerDice = Math.floor(Math.random() * 6) + 1;
|
|
||||||
GamblingPlayerDiceStack[GamblingPlayerDiceStack.length] = GamblingPlayerDice;
|
|
||||||
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
|
||||||
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
|
||||||
if (GamblingPlayerIsFox && GamblingDiceStackSum(GamblingPlayerDiceStack) >= 30) {
|
|
||||||
//player has won
|
|
||||||
GamblingSecondSub.Stage = 102;
|
|
||||||
} else if (!GamblingPlayerIsFox && GamblingDiceStackSum(GamblingNpcDiceStack) >= 30) {
|
|
||||||
//npc has won
|
|
||||||
GamblingSecondSub.Stage = 103;
|
|
||||||
} else if (GamblingPlayerIsFox && (GamblingDiceStackSum(GamblingPlayerDiceStack) <= GamblingDiceStackSum(GamblingNpcDiceStack))) {
|
|
||||||
//npc has won
|
|
||||||
GamblingSecondSub.Stage = 104;
|
|
||||||
} else if (!GamblingPlayerIsFox && (GamblingDiceStackSum(GamblingNpcDiceStack) <= GamblingDiceStackSum(GamblingPlayerDiceStack))) {
|
|
||||||
//player has won
|
|
||||||
GamblingSecondSub.Stage = 105;
|
|
||||||
} else {
|
|
||||||
//next dice
|
|
||||||
GamblingSecondSub.Stage = 101;
|
|
||||||
}
|
|
||||||
} else if (FoxState == "player_fox_win") {
|
|
||||||
GamblingSecondSub.AllowItem = false;
|
|
||||||
GamblingSecondSub.CurrentDialog = GamblingSecondSub.CurrentDialog.replace("REPLACEMONEY", GamblingMoneyBet.toString());
|
|
||||||
CharacterChangeMoney(Player, GamblingMoneyBet);
|
|
||||||
ReputationProgress("Gambling", 2);
|
|
||||||
GamblingPlayerDiceStack = [];
|
|
||||||
GamblingNpcDiceStack = [];
|
|
||||||
GamblingShowMoney = false;
|
|
||||||
} else if (FoxState == "player_fox_lost") {
|
|
||||||
GamblingSecondSub.AllowItem = false;
|
|
||||||
InventoryWearRandom(Player, "ItemLegs");
|
|
||||||
InventoryWearRandom(Player, "ItemFeet");
|
|
||||||
InventoryWearRandom(Player, "ItemArms");
|
|
||||||
GamblingPlayerDiceStack = [];
|
|
||||||
GamblingNpcDiceStack = [];
|
|
||||||
GamblingShowMoney = false;
|
|
||||||
} else if (FoxState == "player_hunter_win") {
|
|
||||||
InventoryWearRandom(GamblingSecondSub, "ItemArms");
|
|
||||||
GamblingSecondSub.AllowItem = true;
|
|
||||||
GamblingSecondSub.CurrentDialog = GamblingSecondSub.CurrentDialog.replace("REPLACEMONEY", GamblingMoneyBet.toString());
|
|
||||||
CharacterChangeMoney(Player, GamblingMoneyBet);
|
|
||||||
ReputationProgress("Gambling", 1);
|
|
||||||
GamblingPlayerDiceStack = [];
|
|
||||||
GamblingNpcDiceStack = [];
|
|
||||||
GamblingShowMoney = false;
|
|
||||||
} else if (FoxState == "player_hunter_lost") {
|
|
||||||
GamblingSecondSub.AllowItem = false;
|
|
||||||
GamblingPlayerDiceStack = [];
|
|
||||||
GamblingNpcDiceStack = [];
|
|
||||||
GamblingShowMoney = false;
|
|
||||||
}
|
}
|
||||||
|
} else if (FoxState == "player_fox_win") {
|
||||||
|
GamblingSecondSub.AllowItem = false;
|
||||||
|
GamblingSecondSub.CurrentDialog = GamblingSecondSub.CurrentDialog.replace("REPLACEMONEY", GamblingMoneyBet.toString());
|
||||||
|
CharacterChangeMoney(Player, GamblingMoneyBet);
|
||||||
|
ReputationProgress("Gambling", 2);
|
||||||
|
GamblingPlayerDiceStack = [];
|
||||||
|
GamblingNpcDiceStack = [];
|
||||||
|
GamblingShowMoney = false;
|
||||||
|
} else if (FoxState == "player_fox_lost") {
|
||||||
|
GamblingSecondSub.AllowItem = false;
|
||||||
|
InventoryWearRandom(Player, "ItemLegs");
|
||||||
|
InventoryWearRandom(Player, "ItemFeet");
|
||||||
|
InventoryWearRandom(Player, "ItemArms");
|
||||||
|
GamblingPlayerDiceStack = [];
|
||||||
|
GamblingNpcDiceStack = [];
|
||||||
|
GamblingShowMoney = false;
|
||||||
|
} else if (FoxState == "player_hunter_win") {
|
||||||
|
InventoryWearRandom(GamblingSecondSub, "ItemArms");
|
||||||
|
GamblingSecondSub.AllowItem = true;
|
||||||
|
GamblingSecondSub.CurrentDialog = GamblingSecondSub.CurrentDialog.replace("REPLACEMONEY", GamblingMoneyBet.toString());
|
||||||
|
CharacterChangeMoney(Player, GamblingMoneyBet);
|
||||||
|
ReputationProgress("Gambling", 1);
|
||||||
|
GamblingPlayerDiceStack = [];
|
||||||
|
GamblingNpcDiceStack = [];
|
||||||
|
GamblingShowMoney = false;
|
||||||
|
} else if (FoxState == "player_hunter_lost") {
|
||||||
|
GamblingSecondSub.AllowItem = false;
|
||||||
|
GamblingPlayerDiceStack = [];
|
||||||
|
GamblingNpcDiceStack = [];
|
||||||
|
GamblingShowMoney = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -672,9 +672,9 @@ function GamblingDaredSixController(DaredSixState) {
|
||||||
}
|
}
|
||||||
} else if (DaredSixState == "fin") {
|
} else if (DaredSixState == "fin") {
|
||||||
do {
|
do {
|
||||||
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
GamblingNpcDice = Math.floor(Math.random() * 6) + 1;
|
||||||
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
GamblingNpcDiceStack[GamblingNpcDiceStack.length] = GamblingNpcDice;
|
||||||
GamblingMoneyBet++;
|
GamblingMoneyBet++;
|
||||||
} while (GamblingDiceStackSum(GamblingNpcDiceStack) <= GamblingDiceStackSum(GamblingPlayerDiceStack) && GamblingNpcDice != 6 );
|
} while (GamblingDiceStackSum(GamblingNpcDiceStack) <= GamblingDiceStackSum(GamblingPlayerDiceStack) && GamblingNpcDice != 6 );
|
||||||
if (GamblingNpcDice == 6)
|
if (GamblingNpcDice == 6)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
0,0,,"Greetings miss. Welcome to Mistress Lewdgambler Palace! Please, come closer. I have to check your member card before you can enter.",,
|
||||||
|
0,20,What is this place?,"So you’re a newcomer? Okay then, I will give you a quick tour. This is a closed gambling facility for people who are involved in domination relationships. You can play with other visitors, making a bets for money or bondage treats.",,
|
||||||
|
0,900,Here it is,--- > (checks the card and lets you in),GoToHall(),MembershipStatus(1)
|
||||||
|
0,0,What is a member card?,"This is a pass that proofs your membership status. It is required to enter a Palace. We want to make sure that our guest won’t be disturbed by narrow persons or vanillas, if you know what I mean.",,MembershipStatus()
|
||||||
|
0,10,I don’t have any cards,There is an option to buy one. But I need to do some background check first. What is your name again?,,MembershipStatus()
|
||||||
|
10,11,I’m DialogPlayerName,"Good. Give me a moment. … I see, you’re from the Bondage Club right?",,
|
||||||
|
11,12,I am.,Great then. 50$ is a price for a membership status. You will get an entry card signed by Mistress Lewdgambler personally.,,
|
||||||
|
12,900,Deal (pay 50$),Congratulations! Here is your pass and welcome to Lewdgamer Palace. Enjoy.,BuyMembership(),HasMoneyForMembership()
|
||||||
|
12,999,"That is too much, I don't have that money.","Sorry to say that, but I can’t let you in. This is some kind of closed facility and we do care of our guests comfort. Now I will ask you to leave. Good bye!",,
|
||||||
|
12,999,That is too much for a door pay.,"Sorry to say that, but I can’t let you in. This is some kind of closed facility and we do care of our guests comfort. Now I will ask you to leave. Good bye!",,
|
||||||
|
11,999,What is Bondage Club?,"Oh, my apologies. I believe some confusion have place in our data. Sorry to say that, but I can’t let you in. This is some kind of closed facility and we do care of our guests comfort. Now I will ask you to leave. Good bye!",,
|
||||||
|
999,0,(Leave),,DialogLeave();,
|
||||||
|
900,0,Thanks,,DialogLeave();,
|
||||||
|
20,21,(Next),To get in you also need to have a membership card.,,
|
||||||
|
21,0,Got it.,"Now please, present your member card. I have plenty of people waiting.",,
|
||||||
|
0,30,Is there an option to get in without a card?,Owners can take their slaves inside for free with some conditions. So if you’re owned by some Palace member then lucky you.,,MembershipStatus()
|
||||||
|
30,31,(Next),(giggles) Anyway slaves are not allowed to gamble at Palace. However any other way to have fun is allowed.,,
|
||||||
|
31,31,What are conditions for a slave?,"Pacified, collared, leashed, with strict hand restrains.",,
|
||||||
|
31,0,Got it.,"Now please, present your member card. I have plenty of people waiting.",,
|
||||||
|
0,0,(Leave),,DialogLeave();,
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(function _() {
|
||||||
|
const {
|
||||||
|
integrateRoomToWorld,
|
||||||
|
setPlayerGameData,
|
||||||
|
readPlayerGameData,
|
||||||
|
} = __vash_utils;
|
||||||
|
let securityGuy = null;
|
||||||
|
|
||||||
|
const MEMBERSHIP_PRICE = 50;
|
||||||
|
const MEMBERSHIP_PROPERTY_KEY = 'Lewdgambler.isMember';
|
||||||
|
const Background = 'LewdgamblerEntrance';
|
||||||
|
|
||||||
|
const Load = () => {
|
||||||
|
// Default load
|
||||||
|
if (securityGuy == null) {
|
||||||
|
securityGuy = CharacterLoadNPC('NPC_Lewdgambler_Security');
|
||||||
|
securityGuy.Name = 'Security';
|
||||||
|
CharacterNaked(securityGuy);
|
||||||
|
InventoryWear(securityGuy, 'CorsetShirt', 'Cloth', 'Default');
|
||||||
|
InventoryWear(securityGuy, 'ShortPencilSkirt', 'ClothLower', 'Default');
|
||||||
|
InventoryWear(securityGuy, 'Pantyhose1', 'Socks', 'Default');
|
||||||
|
InventoryWear(securityGuy, 'GarterBelt2', 'Garters', 'Default');
|
||||||
|
InventoryWear(securityGuy, 'Heels3', 'Shoes', '#202020');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Run = () => {
|
||||||
|
DrawCharacter(securityGuy, 750, 0, 1);
|
||||||
|
DrawCharacter(Player, 250, 0, 1);
|
||||||
|
if (Player.CanWalk()) DrawButton(1885, 25, 90, 90, '', 'White', 'Icons/Exit.png', TextGet("Leave"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const Click = () => {
|
||||||
|
if (MouseIn(250, 0, 500, 1000)) CharacterSetCurrent(Player);
|
||||||
|
if (MouseIn(750, 0, 500, 1000)) CharacterSetCurrent(securityGuy);
|
||||||
|
if (MouseIn(1885, 25, 90, 90) && Player.CanWalk()) CommonSetScreen('Room', 'MainHall');
|
||||||
|
};
|
||||||
|
|
||||||
|
const MembershipStatus = (requestedStatus) => {
|
||||||
|
const result = readPlayerGameData(MEMBERSHIP_PROPERTY_KEY) == requestedStatus;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HasMoneyForMembership = () =>
|
||||||
|
Player.Money >= MEMBERSHIP_PRICE;
|
||||||
|
|
||||||
|
const BuyMembership = () => {
|
||||||
|
if (HasMoneyForMembership()) {
|
||||||
|
CharacterChangeMoney(Player, -MEMBERSHIP_PRICE);
|
||||||
|
setPlayerGameData('Lewdgambler.isMember', '1');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const GoToHall = () =>
|
||||||
|
CommonSetScreen('Room', 'LewdgamblerGameBiddingDuel');
|
||||||
|
// CommonSetScreen('Room', 'LewdgamblerHall');
|
||||||
|
|
||||||
|
integrateRoomToWorld('LewdgamblerEntrance', {
|
||||||
|
Background, Load, Run, Click, BuyMembership, MembershipStatus, HasMoneyForMembership, GoToHall,
|
||||||
|
});
|
||||||
|
})();
|
|
@ -0,0 +1 @@
|
||||||
|
Leave,"Leave"
|
|
BIN
BondageClub/Screens/Room/LewdgamblerGameBiddingDuel/Bubble.png
Normal file
BIN
BondageClub/Screens/Room/LewdgamblerGameBiddingDuel/Bubble.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 17 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
0,0,,"Oh dear! Looks like you lost it all. Such a poor girl.",,
|
||||||
|
0,1,"(Mumble in the gag.)","Oh stop it. Keep those noises for the visitors, I'll just take your money and will go rob someone else. Guards, take her away!"
|
||||||
|
1,2,"(Struggle in your restraints.)","[You lost this game completely. Opponent takes all money and leave you restrained to the will of Palace security.]"
|
||||||
|
2,0,"(Submit to guards.)",,"HandleLostGame()"
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -0,0 +1,2 @@
|
||||||
|
0,0,,"[You won! (+50$)]"
|
||||||
|
0,0,"Yay!",,"HandleWonGame()"
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
@ -0,0 +1,345 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(function _() {
|
||||||
|
const {
|
||||||
|
integrateRoomToWorld,
|
||||||
|
pipe,
|
||||||
|
} = __vash_utils;
|
||||||
|
|
||||||
|
const {
|
||||||
|
INITIAL_STATE,
|
||||||
|
BID_ZONE,
|
||||||
|
STAGE,
|
||||||
|
addBid,
|
||||||
|
bidForOther,
|
||||||
|
canAddBid,
|
||||||
|
canRemoveBid,
|
||||||
|
removeBid,
|
||||||
|
setPileSize,
|
||||||
|
setStage,
|
||||||
|
switchStageAfterBids,
|
||||||
|
applyOtherDecision,
|
||||||
|
roundEnd,
|
||||||
|
restrain,
|
||||||
|
escape,
|
||||||
|
hasWinner,
|
||||||
|
} = __lewdgambler_biddingGame;
|
||||||
|
|
||||||
|
let opponentGuy = null;
|
||||||
|
const Background = 'LewdgamblerRoomGameTable';
|
||||||
|
const PILE_SIZE = 25;
|
||||||
|
|
||||||
|
const lockWithTimer = (character, groupName) => {
|
||||||
|
const currentItem = InventoryGet(character, groupName);
|
||||||
|
if (!currentItem.Property || !currentItem.Property.LockedBy) {
|
||||||
|
InventoryLock(character, currentItem, {
|
||||||
|
Asset: AssetGet("Female3DCG", "ItemMisc", "TimerPadlock"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const releaseCharacter = (character) => {
|
||||||
|
InventoryRemove(character, 'ItemFeet');
|
||||||
|
InventoryRemove(character, 'ItemBoots');
|
||||||
|
InventoryRemove(character, 'ItemArms');
|
||||||
|
InventoryRemove(character, 'ItemHands');
|
||||||
|
InventoryRemove(character, 'ItemMouth');
|
||||||
|
InventoryRemove(character, 'ItemMouth2');
|
||||||
|
InventoryRemove(character, 'ItemHead');
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyEndgameStateTransition = (state, updatedState) => {
|
||||||
|
const isWinningTransition = !hasWinner(state) && hasWinner(updatedState);
|
||||||
|
if (!isWinningTransition) return;
|
||||||
|
|
||||||
|
if (updatedState.stage === STAGE.PLAYER_LOST) {
|
||||||
|
CharacterSetCurrent(opponentGuy);
|
||||||
|
CharacterLoadCSVDialog(opponentGuy, 'Screens/Room/LewdgamblerGameBiddingDuel/Dialog_NPC_LewdgamblerBiddingGame_Loose');
|
||||||
|
releaseCharacter(opponentGuy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedState.stage === STAGE.PLAYER_WON) {
|
||||||
|
CharacterSetCurrent(opponentGuy);
|
||||||
|
CharacterLoadCSVDialog(opponentGuy, 'Screens/Room/LewdgamblerGameBiddingDuel/Dialog_NPC_LewdgamblerBiddingGame_Win');
|
||||||
|
releaseCharacter(Player);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyRestrains = (character, restrains) => {
|
||||||
|
if (restrains[BID_ZONE.LEGS] > 0) {
|
||||||
|
InventoryWear(character, 'Irish8Cuffs', 'ItemFeet');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemFeet');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.LEGS] > 1) {
|
||||||
|
InventoryWear(character, 'BalletWedges', 'ItemBoots');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemBoots');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.LEGS] > 2) {
|
||||||
|
lockWithTimer(character, 'ItemFeet');
|
||||||
|
lockWithTimer(character, 'ItemBoots');
|
||||||
|
} else {
|
||||||
|
InventoryUnlock(character, 'ItemFeet');
|
||||||
|
InventoryUnlock(character, 'ItemBoots');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HANDS] > 0) {
|
||||||
|
InventoryWear(character, 'CollarCuffs', 'ItemArms');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemArms');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HANDS] > 1) {
|
||||||
|
lockWithTimer(character, 'ItemArms');
|
||||||
|
} else {
|
||||||
|
InventoryUnlock(character, 'ItemArms');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HANDS] > 2) {
|
||||||
|
InventoryWear(character, 'PolishedMittens', 'ItemHands');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemHands');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HEAD] > 0) {
|
||||||
|
InventoryWear(character, 'ClothGag', 'ItemMouth');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemMouth');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HEAD] > 1) {
|
||||||
|
InventoryWear(character, 'MuzzleGag', 'ItemMouth2');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemMouth2');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restrains[BID_ZONE.HEAD] > 2) {
|
||||||
|
InventoryWear(character, 'LeatherBlindfold', 'ItemHead');
|
||||||
|
} else {
|
||||||
|
InventoryRemove(character, 'ItemHead');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let gameState = INITIAL_STATE;
|
||||||
|
const check = selector => selector(gameState);
|
||||||
|
const setState = update => {
|
||||||
|
const updatedState = update(gameState);
|
||||||
|
applyRestrains(Player, updatedState.ownRestrains);
|
||||||
|
applyRestrains(opponentGuy, updatedState.otherRestrains);
|
||||||
|
applyEndgameStateTransition(gameState, updatedState);
|
||||||
|
gameState = updatedState;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DrawCasinoButton = (top, left, w, h, text, hint) => {
|
||||||
|
const hintText = hint ? TextGet(hint) : null;
|
||||||
|
return DrawButton(top, left, w, h, text.toString(), '#61a66f', '', hintText, false, 'White', '#53885d');
|
||||||
|
};
|
||||||
|
|
||||||
|
const Load = () => {
|
||||||
|
if (opponentGuy == null) {
|
||||||
|
opponentGuy = CharacterLoadNPC('');
|
||||||
|
}
|
||||||
|
setState(() => INITIAL_STATE);
|
||||||
|
setState(setStage(STAGE.ROUND_START));
|
||||||
|
setState(setPileSize(PILE_SIZE));
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderOwnBidValue = value => {
|
||||||
|
if (gameState.stage === STAGE.ROUND_START) return '-';
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderOpponentBidValue = value => {
|
||||||
|
if (gameState.stage === STAGE.ROUND_START) return '-';
|
||||||
|
if (gameState.stage === STAGE.BIDDING) return '?';
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderOpponentBubble = text => {
|
||||||
|
DrawImage("Screens/" + CurrentModule + "/" + CurrentScreen + "/Bubble.png", 1500, 16);
|
||||||
|
DrawText(text, 1725, 53, "Black", "Gray");
|
||||||
|
};
|
||||||
|
|
||||||
|
const Run = () => {
|
||||||
|
const {
|
||||||
|
otherBids,
|
||||||
|
otherPale,
|
||||||
|
ownBids,
|
||||||
|
ownPale,
|
||||||
|
stage,
|
||||||
|
winnerPale,
|
||||||
|
} = gameState;
|
||||||
|
|
||||||
|
// characters preview
|
||||||
|
DrawCharacter(opponentGuy, 1500, 75, 0.9);
|
||||||
|
DrawCharacter(Player, 50, 75, 0.9);
|
||||||
|
|
||||||
|
// Bidding labels
|
||||||
|
DrawTextFit(`${Player.Name} (${ownPale}$)`, 750, 295, 150, 'White', 'Black');
|
||||||
|
DrawTextFit(`${opponentGuy.Name} (${otherPale}$)`, 750, 600, 150, 'White', 'Black');
|
||||||
|
DrawTextFit('Head', 900, 80, 150, 'White', 'Black');
|
||||||
|
DrawTextFit('Hands', 1075, 80, 150, 'White', 'Black');
|
||||||
|
DrawTextFit('Feet', 1250, 80, 150, 'White', 'Black');
|
||||||
|
|
||||||
|
// Player bidding zone
|
||||||
|
DrawCasinoButton(855, 250, 90, 90, renderOwnBidValue(ownBids[BID_ZONE.HEAD]));
|
||||||
|
DrawCasinoButton(1030, 250, 90, 90, renderOwnBidValue(ownBids[BID_ZONE.HANDS]));
|
||||||
|
DrawCasinoButton(1205, 250, 90, 90, renderOwnBidValue(ownBids[BID_ZONE.LEGS]));
|
||||||
|
|
||||||
|
// Opponent bidding zone
|
||||||
|
DrawCasinoButton(855, 555, 90, 90, renderOpponentBidValue(otherBids[BID_ZONE.HEAD]));
|
||||||
|
DrawCasinoButton(1030, 555, 90, 90, renderOpponentBidValue(otherBids[BID_ZONE.HANDS]));
|
||||||
|
DrawCasinoButton(1205, 555, 90, 90, renderOpponentBidValue(otherBids[BID_ZONE.LEGS]));
|
||||||
|
|
||||||
|
// Player bid controls for bidding stage
|
||||||
|
if (stage === STAGE.BIDDING) {
|
||||||
|
if (check(canAddBid)) DrawCasinoButton(855, 140, 90, 90, '+', "AddHead");
|
||||||
|
if (check(canRemoveBid(BID_ZONE.HEAD))) DrawCasinoButton(855, 360, 90, 90, '-', "RemoveHead");
|
||||||
|
if (check(canAddBid)) DrawCasinoButton(1030, 140, 90, 90, '+', "AddHands");
|
||||||
|
if (check(canRemoveBid(BID_ZONE.HANDS))) DrawCasinoButton(1030, 360, 90, 90, '-', "RemoveHands");
|
||||||
|
if (check(canAddBid)) DrawCasinoButton(1205, 140, 90, 90, '+', "AddFeet");
|
||||||
|
if (check(canRemoveBid(BID_ZONE.LEGS))) DrawCasinoButton(1205, 360, 90, 90, '-', "RemoveFeet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Winner's pale nocice
|
||||||
|
DrawTextFit(`Winner gains additional (${winnerPale}$)`, 875, 750, 400, 'White', 'Black');
|
||||||
|
|
||||||
|
// Generic actions zone
|
||||||
|
if (stage === STAGE.BIDDING) {
|
||||||
|
renderOpponentBubble('I\'m done. Your move?');
|
||||||
|
DrawButton(1010, 850, 200, 90, 'Confirm', 'White', '', TextGet("ConfirmBidding"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.ROUND_START) {
|
||||||
|
renderOpponentBubble('Scared, you chicken?');
|
||||||
|
DrawButton(1010, 850, 200, 90, 'Go on', 'White', '', TextGet("StartRound"));
|
||||||
|
if (Player.CanWalk()) DrawButton(790, 850, 200, 90, 'Leave', 'White', '', TextGet("Leave"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.WIN_DECISION) {
|
||||||
|
renderOpponentBubble('The round is yours');
|
||||||
|
|
||||||
|
// Release actions zone
|
||||||
|
DrawButton(75, 140, 400, 90, 'Release head', 'White', '', '');
|
||||||
|
DrawButton(75, 250, 400, 90, 'Release hands', 'White', '', '');
|
||||||
|
DrawButton(75, 360, 400, 90, 'Release feet', 'White', '', '');
|
||||||
|
|
||||||
|
// Restrain actions zone
|
||||||
|
DrawButton(1525, 140, 400, 90, 'Restrain head', 'White', '', '');
|
||||||
|
DrawButton(1525, 250, 400, 90, 'Restrain hands', 'White', '', '');
|
||||||
|
DrawButton(1525, 360, 400, 90, 'Restrain feet', 'White', '', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.LOOSE_ACCEPTANCE) {
|
||||||
|
renderOpponentBubble('Looser, huh.');
|
||||||
|
DrawButton(75, 690, 400, 90, 'Do your job...', 'White', '', '');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Click = () => {
|
||||||
|
const {
|
||||||
|
stage,
|
||||||
|
} = gameState;
|
||||||
|
|
||||||
|
if (stage === STAGE.BIDDING) {
|
||||||
|
// bids controls
|
||||||
|
if (MouseIn(855, 140, 90, 90) && check(canAddBid)) setState(addBid(BID_ZONE.HEAD));
|
||||||
|
if (MouseIn(855, 360, 90, 90) && check(canRemoveBid(BID_ZONE.HEAD))) setState(removeBid(BID_ZONE.HEAD));
|
||||||
|
if (MouseIn(1030, 140, 90, 90) && check(canAddBid)) setState(addBid(BID_ZONE.HANDS));
|
||||||
|
if (MouseIn(1030, 360, 90, 90) && check(canRemoveBid(BID_ZONE.HANDS))) setState(removeBid(BID_ZONE.HANDS));
|
||||||
|
if (MouseIn(1205, 140, 90, 90) && check(canAddBid)) setState(addBid(BID_ZONE.LEGS));
|
||||||
|
if (MouseIn(1205, 360, 90, 90) && check(canRemoveBid(BID_ZONE.LEGS))) setState(removeBid(BID_ZONE.LEGS));
|
||||||
|
|
||||||
|
// proceed buttons
|
||||||
|
if (MouseIn(1010, 850, 200, 90)) {
|
||||||
|
// cheat should go here
|
||||||
|
// setState(setStage(STAGE.CHEAT_DECISION));
|
||||||
|
setState(switchStageAfterBids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.ROUND_START) {
|
||||||
|
// leave button
|
||||||
|
if (MouseIn(790, 850, 200, 90)) {
|
||||||
|
if (Player.CanWalk()) CommonSetScreen('Room', 'MainHall');
|
||||||
|
}
|
||||||
|
// proceed buttons
|
||||||
|
if (MouseIn(1010, 850, 200, 90)) {
|
||||||
|
setState(bidForOther);
|
||||||
|
setState(setStage(STAGE.BIDDING));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.LOOSE_ACCEPTANCE) {
|
||||||
|
// loose acceptance buttons
|
||||||
|
if (MouseIn(75, 690, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
applyOtherDecision,
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage === STAGE.WIN_DECISION) {
|
||||||
|
// release buttons
|
||||||
|
if (MouseIn(75, 140, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
escape(BID_ZONE.HEAD),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (MouseIn(75, 250, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
escape(BID_ZONE.HANDS),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (MouseIn(75, 360, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
escape(BID_ZONE.LEGS),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// restrain buttons
|
||||||
|
if (MouseIn(1525, 140, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
restrain(BID_ZONE.HEAD),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (MouseIn(1525, 250, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
restrain(BID_ZONE.HANDS),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (MouseIn(1525, 360, 400, 90)) {
|
||||||
|
setState(pipe(
|
||||||
|
restrain(BID_ZONE.LEGS),
|
||||||
|
roundEnd,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const HandleLostGame = () => {
|
||||||
|
// change to moving to casino hall so maids can't reach you
|
||||||
|
CommonSetScreen('Room', 'MainHall');
|
||||||
|
CharacterChangeMoney(Player, -PILE_SIZE);
|
||||||
|
DialogLeave();
|
||||||
|
};
|
||||||
|
|
||||||
|
const HandleWonGame = () => {
|
||||||
|
CommonSetScreen('Room', 'MainHall');
|
||||||
|
CharacterChangeMoney(Player, PILE_SIZE * 2);
|
||||||
|
DialogLeave();
|
||||||
|
};
|
||||||
|
|
||||||
|
integrateRoomToWorld('LewdgamblerGameBiddingDuel', {
|
||||||
|
Background, Load, Run, Click, HandleLostGame, HandleWonGame,
|
||||||
|
});
|
||||||
|
})();
|
520
BondageClub/Screens/Room/LewdgamblerGameBiddingDuel/core.js
Normal file
520
BondageClub/Screens/Room/LewdgamblerGameBiddingDuel/core.js
Normal file
|
@ -0,0 +1,520 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* eslint-disable semi */
|
||||||
|
window.__lewdgambler_biddingGame = (function _() {
|
||||||
|
const {
|
||||||
|
pipe,
|
||||||
|
complement,
|
||||||
|
sum,
|
||||||
|
anyPass,
|
||||||
|
} = __vash_utils;
|
||||||
|
|
||||||
|
const STAGE = {
|
||||||
|
INITIAL: 'INITIAL',
|
||||||
|
ROUND_START: 'ROUND_START',
|
||||||
|
BIDDING: 'BIDDING',
|
||||||
|
CHEAT_DECISION: 'CHEAT_DECISION',
|
||||||
|
WIN_DECISION: 'WIN_DECISION',
|
||||||
|
LOOSE_ACCEPTANCE: 'LOOSE_ACCEPTANCE',
|
||||||
|
PLAYER_WON: 'PLAYER_WON',
|
||||||
|
PLAYER_LOST: 'PLAYER_LOST',
|
||||||
|
}
|
||||||
|
|
||||||
|
const CHEAT_CHANCE = 0.15
|
||||||
|
const BLUFF_CHANCE = 0.15
|
||||||
|
const MAX_RESTRAIN_LEVEL = 3
|
||||||
|
|
||||||
|
const RESTRAIN = {
|
||||||
|
HEAD_STUFFING: 'stuffing',
|
||||||
|
HEAD_CLEAVE: 'cleave',
|
||||||
|
HEAD_BLINDFOLD: 'blindfold',
|
||||||
|
FEET_TIED: 'tied-feet',
|
||||||
|
FEET_BOOTS: 'boots',
|
||||||
|
FEET_LOCKED: 'locked-feet',
|
||||||
|
HANDS_HANDCUFFS: 'handcuffs',
|
||||||
|
HANDS_TIED_BEHIND: 'armbinder',
|
||||||
|
HANDS_MITTENS: 'mittens',
|
||||||
|
}
|
||||||
|
|
||||||
|
const BID_ZONE = {
|
||||||
|
HEAD: 'head',
|
||||||
|
HANDS: 'hands',
|
||||||
|
LEGS: 'legs',
|
||||||
|
}
|
||||||
|
|
||||||
|
const DECISION = {
|
||||||
|
CHEAT_SKIP: 'CHEAT_SKIP',
|
||||||
|
CHEAT_HANDS: 'CHEAT_HANDS',
|
||||||
|
CHEAT_HEAD: 'CHEAT_HEAD',
|
||||||
|
CHEAT_FEET: 'CHEAT_FEET',
|
||||||
|
ESCAPE_HANDS: 'ESCAPE_HANDS',
|
||||||
|
ESCAPE_HEAD: 'ESCAPE_HEAD',
|
||||||
|
ESCAPE_FEET: 'ESCAPE_FEET',
|
||||||
|
RESTRAIN_HANDS: 'RESTRAIN_HANDS',
|
||||||
|
RESTRAIN_HEAD: 'RESTRAIN_HEAD',
|
||||||
|
RESTRAIN_FEET: 'RESTRAIN_FEET',
|
||||||
|
}
|
||||||
|
|
||||||
|
const RESTRAIN_STATS = {
|
||||||
|
[RESTRAIN.HEAD_STUFFING]: {
|
||||||
|
zone: BID_ZONE.HEAD,
|
||||||
|
level: 1,
|
||||||
|
},
|
||||||
|
[RESTRAIN.HEAD_CLEAVE]: {
|
||||||
|
zone: BID_ZONE.HEAD,
|
||||||
|
level: 2,
|
||||||
|
},
|
||||||
|
[RESTRAIN.HEAD_BLINDFOLD]: {
|
||||||
|
zone: BID_ZONE.HEAD,
|
||||||
|
level: 3,
|
||||||
|
},
|
||||||
|
[RESTRAIN.FEET_TIED]: {
|
||||||
|
zone: BID_ZONE.LEGS,
|
||||||
|
level: 1,
|
||||||
|
},
|
||||||
|
[RESTRAIN.FEET_BOOTS]: {
|
||||||
|
zone: BID_ZONE.LEGS,
|
||||||
|
level: 2,
|
||||||
|
},
|
||||||
|
[RESTRAIN.FEET_LOCKED]: {
|
||||||
|
zone: BID_ZONE.LEGS,
|
||||||
|
level: 3,
|
||||||
|
},
|
||||||
|
[RESTRAIN.HANDS_HANDCUFFS]: {
|
||||||
|
zone: BID_ZONE.HANDS,
|
||||||
|
level: 1,
|
||||||
|
},
|
||||||
|
[RESTRAIN.HANDS_TIED_BEHIND]: {
|
||||||
|
zone: BID_ZONE.HANDS,
|
||||||
|
level: 2,
|
||||||
|
},
|
||||||
|
[RESTRAIN.HANDS_MITTENS]: {
|
||||||
|
zone: BID_ZONE.HANDS,
|
||||||
|
level: 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const BID_STATUS = {
|
||||||
|
WIN: 'win',
|
||||||
|
LOOSE: 'loose',
|
||||||
|
DRAW: 'draw',
|
||||||
|
}
|
||||||
|
|
||||||
|
const INITIAL_STATE = {
|
||||||
|
ownPale: 0,
|
||||||
|
winnerPale: 0,
|
||||||
|
otherPale: 0,
|
||||||
|
stage: STAGE.INITIAL,
|
||||||
|
ownRestrains: {
|
||||||
|
[BID_ZONE.HEAD]: 0,
|
||||||
|
[BID_ZONE.HANDS]: 0,
|
||||||
|
[BID_ZONE.LEGS]: 1,
|
||||||
|
},
|
||||||
|
otherRestrains: {
|
||||||
|
[BID_ZONE.HEAD]: 0,
|
||||||
|
[BID_ZONE.HANDS]: 0,
|
||||||
|
[BID_ZONE.LEGS]: 1,
|
||||||
|
},
|
||||||
|
ownBids: {
|
||||||
|
[BID_ZONE.HEAD]: 0,
|
||||||
|
[BID_ZONE.HANDS]: 0,
|
||||||
|
[BID_ZONE.LEGS]: 0,
|
||||||
|
},
|
||||||
|
otherBids: {
|
||||||
|
[BID_ZONE.HEAD]: 0,
|
||||||
|
[BID_ZONE.HANDS]: 0,
|
||||||
|
[BID_ZONE.LEGS]: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomInt = (min, max) =>
|
||||||
|
Math.floor(Math.random() * (max + 1 - min) + min)
|
||||||
|
|
||||||
|
const checkRestrain = restrainName => restrains => {
|
||||||
|
const { zone, level } = (RESTRAIN_STATS[restrainName] || {})
|
||||||
|
return (restrains[zone] || 0) >= level
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRestrain = restrainName => state =>
|
||||||
|
checkRestrain(restrainName)(state.ownRestrains);
|
||||||
|
const hasRestrains = restrains => state =>
|
||||||
|
restrains.some(restrainName => hasRestrain(restrainName)(state))
|
||||||
|
|
||||||
|
const hasOtherRestrain = restrainName => state =>
|
||||||
|
checkRestrain(restrainName)(state.otherRestrains);
|
||||||
|
const hasOtherRestrains = restrains => state =>
|
||||||
|
restrains.some(restrainName => hasOtherRestrain(restrainName)(state))
|
||||||
|
|
||||||
|
// @TODO: add some intelligence here
|
||||||
|
const rollBid = pale => {
|
||||||
|
const max = Math.floor(pale / 3)
|
||||||
|
return {
|
||||||
|
[BID_ZONE.HEAD]: randomInt(0, max),
|
||||||
|
[BID_ZONE.HANDS]: randomInt(0, max),
|
||||||
|
[BID_ZONE.LEGS]: randomInt(0, max),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bidsTotal = bids => sum(Object.values(bids))
|
||||||
|
|
||||||
|
const canRestrain = zone => state => (state.otherRestrains[zone] || 0) < MAX_RESTRAIN_LEVEL
|
||||||
|
const canOtherRestrain = zone => state => (state.ownRestrains[zone] || 0) < MAX_RESTRAIN_LEVEL
|
||||||
|
const canEscape = zone => state => {
|
||||||
|
if (zone === BID_ZONE.LEGS && hasRestrains([RESTRAIN.FEET_LOCKED])(state)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.ownRestrains[zone] > 0
|
||||||
|
}
|
||||||
|
const canOtherEscape = zone => state => {
|
||||||
|
if (zone === BID_ZONE.LEGS && hasOtherRestrains([RESTRAIN.FEET_LOCKED])(state)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.otherRestrains[zone] > 0
|
||||||
|
}
|
||||||
|
const canLeave = complement(hasRestrains([RESTRAIN.FEET_TIED]))
|
||||||
|
const canCheat = complement(hasRestrains([RESTRAIN.HANDS_HANDCUFFS]))
|
||||||
|
const canBluff = complement(hasRestrains([RESTRAIN.HEAD_STUFFING]))
|
||||||
|
const canRemoveBid = zone => state => state.ownBids[zone] > 0
|
||||||
|
const canAddBid = state => state.ownPale - bidsTotal(state.ownBids) > 0
|
||||||
|
const isWinner = hasOtherRestrains([RESTRAIN.HEAD_BLINDFOLD, RESTRAIN.HANDS_MITTENS])
|
||||||
|
const isLooser = hasRestrains([RESTRAIN.HEAD_BLINDFOLD, RESTRAIN.HANDS_MITTENS])
|
||||||
|
const hasWinner = anyPass([isWinner, isLooser])
|
||||||
|
const dropBids = state => ({
|
||||||
|
...state,
|
||||||
|
ownBids: { [BID_ZONE.HEAD]: 0, [BID_ZONE.HANDS]: 0, [BID_ZONE.LEGS]: 0 },
|
||||||
|
otherBids: { [BID_ZONE.HEAD]: 0, [BID_ZONE.HANDS]: 0, [BID_ZONE.LEGS]: 0 },
|
||||||
|
})
|
||||||
|
const bidForOther = state => ({
|
||||||
|
...state,
|
||||||
|
otherBids: rollBid(state.otherPale),
|
||||||
|
})
|
||||||
|
const addBid = zone => state => ({
|
||||||
|
...state,
|
||||||
|
ownBids: {
|
||||||
|
...state.ownBids,
|
||||||
|
[zone]: state.ownBids[zone] + 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const removeBid = zone => state => ({
|
||||||
|
...state,
|
||||||
|
ownBids: {
|
||||||
|
...state.ownBids,
|
||||||
|
[zone]: state.ownBids[zone] - 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const cheat = zone => state => {
|
||||||
|
const cheatSucceed = Math.random() < CHEAT_CHANCE
|
||||||
|
if (!cheatSucceed) {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
const ownZoneBid = state.ownBids[zone]
|
||||||
|
const otherZoneBid = state.otherBids[zone]
|
||||||
|
const diff = otherZoneBid - ownZoneBid
|
||||||
|
const ownBidSum = bidsTotal(state.ownBids)
|
||||||
|
const addedBid = Math.min(state.ownPale - ownBidSum, diff + 1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ownBids: {
|
||||||
|
...state.ownBids,
|
||||||
|
[zone]: ownZoneBid + addedBid,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bluff = zone => state => {
|
||||||
|
const bluffSucceed = Math.random() < BLUFF_CHANCE
|
||||||
|
if (!bluffSucceed) {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentBid = state.otherBids
|
||||||
|
const paleLeft = state.otherPale - bidsTotal(state.otherBids)
|
||||||
|
const addedBid = randomInt(0, paleLeft)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
otherBids: {
|
||||||
|
...state.otherBids,
|
||||||
|
[zone]: currentBid + addedBid,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const compareBids = zone => state => {
|
||||||
|
const ownBid = state.ownBids[zone]
|
||||||
|
const otherBid = state.otherBids[zone]
|
||||||
|
|
||||||
|
if (ownBid === otherBid) return BID_STATUS.DRAW
|
||||||
|
if (ownBid > otherBid) return BID_STATUS.WIN
|
||||||
|
return BID_STATUS.LOOSE
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBidsStatuses = state => ({
|
||||||
|
[BID_ZONE.HEAD]: compareBids(BID_ZONE.HEAD)(state),
|
||||||
|
[BID_ZONE.HANDS]: compareBids(BID_ZONE.HANDS)(state),
|
||||||
|
[BID_ZONE.LEGS]: compareBids(BID_ZONE.LEGS)(state),
|
||||||
|
})
|
||||||
|
|
||||||
|
const getBidRoundStatus = state => {
|
||||||
|
const statuses = getBidsStatuses(state)
|
||||||
|
const winsAmount = Object.values(statuses)
|
||||||
|
.filter(x => x === BID_STATUS.WIN).length
|
||||||
|
const lossesAmount = Object.values(statuses)
|
||||||
|
.filter(x => x === BID_STATUS.LOOSE).length
|
||||||
|
|
||||||
|
if (winsAmount > lossesAmount) {
|
||||||
|
return BID_STATUS.WIN
|
||||||
|
} else if (winsAmount < lossesAmount) {
|
||||||
|
return BID_STATUS.LOOSE
|
||||||
|
}
|
||||||
|
|
||||||
|
return BID_STATUS.DRAW
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyZoneBid = zone => state => {
|
||||||
|
const ownBid = state.ownBids[zone]
|
||||||
|
const otherBid = state.otherBids[zone]
|
||||||
|
const zoneStatus = compareBids(zone)(state)
|
||||||
|
|
||||||
|
switch (zoneStatus) {
|
||||||
|
case BID_STATUS.DRAW: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ownPale: Math.max(0, state.ownPale - ownBid),
|
||||||
|
otherPale: Math.max(0, state.otherPale - otherBid),
|
||||||
|
winnerPale: state.winnerPale + otherBid + ownBid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case BID_STATUS.WIN: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ownPale: Math.max(0, state.ownPale - ownBid),
|
||||||
|
otherPale: Math.max(0, state.otherPale - otherBid + ownBid),
|
||||||
|
winnerPale: state.winnerPale + otherBid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case BID_STATUS.LOOSE: {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
ownPale: Math.max(0, state.ownPale - ownBid + otherBid),
|
||||||
|
otherPale: Math.max(0, state.otherPale - otherBid),
|
||||||
|
winnerPale: state.winnerPale + ownBid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const recalculatePales = state => Object.values(BID_ZONE)
|
||||||
|
.reduce((acc, zone) => applyZoneBid(zone)(acc), state)
|
||||||
|
|
||||||
|
const applyBids = pipe(
|
||||||
|
recalculatePales,
|
||||||
|
dropBids,
|
||||||
|
)
|
||||||
|
|
||||||
|
const restrain = zone => state => ({
|
||||||
|
...state,
|
||||||
|
otherRestrains: {
|
||||||
|
...state.otherRestrains,
|
||||||
|
[zone]: state.otherRestrains[zone] + 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const otherRestrain = zone => state => ({
|
||||||
|
...state,
|
||||||
|
ownRestrains: {
|
||||||
|
...state.ownRestrains,
|
||||||
|
[zone]: state.ownRestrains[zone] + 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const escape = zone => state => ({
|
||||||
|
...state,
|
||||||
|
ownRestrains: {
|
||||||
|
...state.ownRestrains,
|
||||||
|
[zone]: state.ownRestrains[zone] - 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const otherEscape = zone => state => ({
|
||||||
|
...state,
|
||||||
|
otherRestrains: {
|
||||||
|
...state.otherRestrains,
|
||||||
|
[zone]: state.otherRestrains[zone] - 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const rollLooseDecision = state => {
|
||||||
|
const bidsStatus = getBidsStatuses(state)
|
||||||
|
|
||||||
|
const wins = {
|
||||||
|
[BID_ZONE.HANDS]: bidsStatus[BID_ZONE.HANDS] === BID_STATUS.LOOSE,
|
||||||
|
[BID_ZONE.HEAD]: bidsStatus[BID_ZONE.HEAD] === BID_STATUS.LOOSE,
|
||||||
|
[BID_ZONE.LEGS]: bidsStatus[BID_ZONE.LEGS] === BID_STATUS.LOOSE,
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
wins[BID_ZONE.HANDS]
|
||||||
|
&& canOtherEscape(BID_ZONE.HANDS)(state)
|
||||||
|
&& DECISION.ESCAPE_HANDS,
|
||||||
|
wins[BID_ZONE.HEAD]
|
||||||
|
&& canOtherEscape(BID_ZONE.HEAD)(state)
|
||||||
|
&& DECISION.ESCAPE_HEAD,
|
||||||
|
wins[BID_ZONE.LEGS]
|
||||||
|
&& canOtherEscape(BID_ZONE.LEGS)(state)
|
||||||
|
&& DECISION.ESCAPE_FEET,
|
||||||
|
wins[BID_ZONE.HANDS]
|
||||||
|
&& canOtherRestrain(BID_ZONE.HANDS)(state)
|
||||||
|
&& DECISION.RESTRAIN_HANDS,
|
||||||
|
wins[BID_ZONE.HEAD]
|
||||||
|
&& canOtherRestrain(BID_ZONE.HEAD)(state)
|
||||||
|
&& DECISION.RESTRAIN_HEAD,
|
||||||
|
wins[BID_ZONE.LEGS]
|
||||||
|
&& canOtherRestrain(BID_ZONE.LEGS)(state)
|
||||||
|
&& DECISION.RESTRAIN_FEET,
|
||||||
|
].filter(Boolean)
|
||||||
|
|
||||||
|
const decisionIndex = randomInt(0, options.length - 1)
|
||||||
|
return options[decisionIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCheatDecisions = state => canCheat(state)
|
||||||
|
? [DECISION.CHEAT_HANDS, DECISION.CHEAT_HEAD, DECISION.CHEAT_FEET, DECISION.CHEAT_SKIP]
|
||||||
|
: [DECISION.CHEAT_SKIP]
|
||||||
|
|
||||||
|
const getWinDecisions = state => {
|
||||||
|
const bidsStatus = getBidsStatuses(state)
|
||||||
|
|
||||||
|
const wins = {
|
||||||
|
[BID_ZONE.HANDS]: bidsStatus[BID_ZONE.HANDS] === BID_STATUS.WIN,
|
||||||
|
[BID_ZONE.HEAD]: bidsStatus[BID_ZONE.HEAD] === BID_STATUS.WIN,
|
||||||
|
[BID_ZONE.LEGS]: bidsStatus[BID_ZONE.LEGS] === BID_STATUS.WIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
wins[BID_ZONE.HANDS]
|
||||||
|
&& canEscape(BID_ZONE.HANDS)(state)
|
||||||
|
&& DECISION.ESCAPE_HANDS,
|
||||||
|
wins[BID_ZONE.HEAD]
|
||||||
|
&& canEscape(BID_ZONE.HEAD)(state)
|
||||||
|
&& DECISION.ESCAPE_HEAD,
|
||||||
|
wins[BID_ZONE.LEGS]
|
||||||
|
&& canEscape(BID_ZONE.LEGS)(state)
|
||||||
|
&& DECISION.ESCAPE_FEET,
|
||||||
|
wins[BID_ZONE.HANDS]
|
||||||
|
&& canRestrain(BID_ZONE.HANDS)(state)
|
||||||
|
&& DECISION.RESTRAIN_HANDS,
|
||||||
|
wins[BID_ZONE.HEAD]
|
||||||
|
&& canRestrain(BID_ZONE.HEAD)(state)
|
||||||
|
&& DECISION.RESTRAIN_HEAD,
|
||||||
|
wins[BID_ZONE.LEGS]
|
||||||
|
&& canRestrain(BID_ZONE.LEGS)(state)
|
||||||
|
&& DECISION.RESTRAIN_FEET,
|
||||||
|
].filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setStage = stage => state => ({ ...state, stage })
|
||||||
|
const setPileSize = pileSize => state => ({
|
||||||
|
...state,
|
||||||
|
ownPale: pileSize,
|
||||||
|
otherPale: pileSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
const switchStageAfterBids = state => {
|
||||||
|
const roundStatus = getBidRoundStatus(state)
|
||||||
|
const newStage = roundStatus === BID_STATUS.DRAW
|
||||||
|
? STAGE.ROUND_START
|
||||||
|
: roundStatus === BID_STATUS.WIN
|
||||||
|
? STAGE.WIN_DECISION
|
||||||
|
: STAGE.LOOSE_ACCEPTANCE
|
||||||
|
|
||||||
|
return setStage(newStage)(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyOwnDecision = decision => state => {
|
||||||
|
switch (decision) {
|
||||||
|
case DECISION.RESTRAIN_HEAD:
|
||||||
|
return restrain(BID_ZONE.HEAD)(state)
|
||||||
|
case DECISION.RESTRAIN_HANDS:
|
||||||
|
return restrain(BID_ZONE.HANDS)(state)
|
||||||
|
case DECISION.RESTRAIN_FEET:
|
||||||
|
return restrain(BID_ZONE.LEGS)(state)
|
||||||
|
case DECISION.ESCAPE_HEAD:
|
||||||
|
return escape(BID_ZONE.HEAD)(state)
|
||||||
|
case DECISION.ESCAPE_HANDS:
|
||||||
|
return escape(BID_ZONE.HANDS)(state)
|
||||||
|
case DECISION.ESCAPE_FEET:
|
||||||
|
return escape(BID_ZONE.LEGS)(state)
|
||||||
|
default: return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyOtherDecision = state => {
|
||||||
|
const decision = rollLooseDecision(state)
|
||||||
|
|
||||||
|
switch (decision) {
|
||||||
|
case DECISION.RESTRAIN_HEAD:
|
||||||
|
return otherRestrain(BID_ZONE.HEAD)(state)
|
||||||
|
case DECISION.RESTRAIN_HANDS:
|
||||||
|
return otherRestrain(BID_ZONE.HANDS)(state)
|
||||||
|
case DECISION.RESTRAIN_FEET:
|
||||||
|
return otherRestrain(BID_ZONE.LEGS)(state)
|
||||||
|
case DECISION.ESCAPE_HEAD:
|
||||||
|
return otherEscape(BID_ZONE.HEAD)(state)
|
||||||
|
case DECISION.ESCAPE_HANDS:
|
||||||
|
return otherEscape(BID_ZONE.HANDS)(state)
|
||||||
|
case DECISION.ESCAPE_FEET:
|
||||||
|
return otherEscape(BID_ZONE.LEGS)(state)
|
||||||
|
default: return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const roundEnd = state => {
|
||||||
|
const newStage = isWinner(state)
|
||||||
|
? STAGE.PLAYER_WON
|
||||||
|
: isLooser(state)
|
||||||
|
? STAGE.PLAYER_LOST
|
||||||
|
: STAGE.ROUND_START
|
||||||
|
|
||||||
|
return pipe(
|
||||||
|
setStage(newStage),
|
||||||
|
applyBids,
|
||||||
|
)(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
BID_ZONE,
|
||||||
|
DECISION,
|
||||||
|
INITIAL_STATE,
|
||||||
|
RESTRAIN,
|
||||||
|
STAGE,
|
||||||
|
addBid,
|
||||||
|
applyBids,
|
||||||
|
applyOtherDecision,
|
||||||
|
applyOwnDecision,
|
||||||
|
bidForOther,
|
||||||
|
bluff,
|
||||||
|
canAddBid,
|
||||||
|
canBluff,
|
||||||
|
canLeave,
|
||||||
|
canRemoveBid,
|
||||||
|
cheat,
|
||||||
|
escape,
|
||||||
|
getBidRoundStatus,
|
||||||
|
getCheatDecisions,
|
||||||
|
getWinDecisions,
|
||||||
|
removeBid,
|
||||||
|
restrain,
|
||||||
|
roundEnd,
|
||||||
|
setPileSize,
|
||||||
|
setStage,
|
||||||
|
switchStageAfterBids,
|
||||||
|
checkRestrain,
|
||||||
|
hasWinner,
|
||||||
|
}
|
||||||
|
})();
|
62
BondageClub/Screens/Room/LewdgamblerHall/LewdgamblerHall.js
Normal file
62
BondageClub/Screens/Room/LewdgamblerHall/LewdgamblerHall.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(function _() {
|
||||||
|
const {
|
||||||
|
integrateRoomToWorld,
|
||||||
|
setPlayerGameData,
|
||||||
|
readPlayerGameData,
|
||||||
|
} = __vash_utils;
|
||||||
|
let hostessGuy = null;
|
||||||
|
|
||||||
|
const MEMBERSHIP_PRICE = 50;
|
||||||
|
const MEMBERSHIP_PROPERTY_KEY = 'Lewdgambler.isMember';
|
||||||
|
const Background = 'LewdgamblerHall';
|
||||||
|
|
||||||
|
const Load = () => {
|
||||||
|
// Default load
|
||||||
|
if (hostessGuy == null) {
|
||||||
|
hostessGuy = CharacterLoadNPC('NPC_Lewdgambler_Hostess');
|
||||||
|
hostessGuy.Name = 'Hostess girl';
|
||||||
|
CharacterNaked(hostessGuy);
|
||||||
|
InventoryWear(hostessGuy, 'CorsetShirt', 'Cloth', 'Default');
|
||||||
|
InventoryWear(hostessGuy, 'ShortPencilSkirt', 'ClothLower', 'Default');
|
||||||
|
InventoryWear(hostessGuy, 'Pantyhose1', 'Socks', 'Default');
|
||||||
|
InventoryWear(hostessGuy, 'GarterBelt2', 'Garters', 'Default');
|
||||||
|
InventoryWear(hostessGuy, 'Heels3', 'Shoes', '#202020');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Run = () => {
|
||||||
|
DrawCharacter(hostessGuy, 750, 0, 1);
|
||||||
|
DrawCharacter(Player, 250, 0, 1);
|
||||||
|
if (Player.CanWalk()) DrawButton(1885, 25, 90, 90, '', 'White', 'Icons/Exit.png', TextGet("Leave"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const Click = () => {
|
||||||
|
if (MouseIn(250, 0, 500, 1000)) CharacterSetCurrent(Player);
|
||||||
|
if (MouseIn(750, 0, 500, 1000)) CharacterSetCurrent(hostessGuy);
|
||||||
|
if (MouseIn(1885, 25, 90, 90) && Player.CanWalk()) CommonSetScreen('Room', 'MainHall');
|
||||||
|
};
|
||||||
|
|
||||||
|
const MembershipStatus = (requestedStatus) => {
|
||||||
|
const result = readPlayerGameData(MEMBERSHIP_PROPERTY_KEY) == requestedStatus;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const HasMoneyForMembership = () =>
|
||||||
|
Player.Money >= MEMBERSHIP_PRICE;
|
||||||
|
|
||||||
|
const BuyMembership = () => {
|
||||||
|
if (HasMoneyForMembership()) {
|
||||||
|
CharacterChangeMoney(Player, -MEMBERSHIP_PRICE);
|
||||||
|
setPlayerGameData('Lewdgambler.isMember', '1');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const GoToHall = () =>
|
||||||
|
CommonSetScreen('Room', 'LewdgamblerHall');
|
||||||
|
|
||||||
|
integrateRoomToWorld('LewdgamblerHall', {
|
||||||
|
Background, Load, Run, Click, BuyMembership, MembershipStatus, HasMoneyForMembership, GoToHall,
|
||||||
|
});
|
||||||
|
})();
|
|
@ -0,0 +1 @@
|
||||||
|
Leave,"Leave"
|
|
|
@ -239,6 +239,7 @@ function MainHallRun() {
|
||||||
DrawButton(1885, 505, 90, 90, "", "White", "Icons/Cell.png", TextGet("Cell"));
|
DrawButton(1885, 505, 90, 90, "", "White", "Icons/Cell.png", TextGet("Cell"));
|
||||||
|
|
||||||
// Asylum, College & LARP battles
|
// Asylum, College & LARP battles
|
||||||
|
DrawButton(1525, 625, 90, 90, "", "White", "Icons/Lewdgambler.png", TextGet("Lewdgambler"));
|
||||||
if (!ManagementIsClubSlave()) DrawButton(1645, 625, 90, 90, "", "White", "Icons/Battle.png", TextGet("LARPBattle"));
|
if (!ManagementIsClubSlave()) DrawButton(1645, 625, 90, 90, "", "White", "Icons/Battle.png", TextGet("LARPBattle"));
|
||||||
if (!ManagementIsClubSlave()) DrawButton(1765, 625, 90, 90, "", "White", "Icons/College.png", TextGet("College"));
|
if (!ManagementIsClubSlave()) DrawButton(1765, 625, 90, 90, "", "White", "Icons/College.png", TextGet("College"));
|
||||||
DrawButton(1885, 625, 90, 90, "", "White", "Icons/Asylum.png", TextGet("Asylum"));
|
DrawButton(1885, 625, 90, 90, "", "White", "Icons/Asylum.png", TextGet("Asylum"));
|
||||||
|
@ -389,6 +390,8 @@ function MainHallClick() {
|
||||||
if ((MouseX >= 1885) && (MouseX < 1975) && (MouseY >= 505) && (MouseY < 595)) MainHallWalk("Cell");
|
if ((MouseX >= 1885) && (MouseX < 1975) && (MouseY >= 505) && (MouseY < 595)) MainHallWalk("Cell");
|
||||||
|
|
||||||
// Asylum & College
|
// Asylum & College
|
||||||
|
// if ((MouseX >= 1525) && (MouseX < 1615) && (MouseY >= 625) && (MouseY < 715)) MainHallWalk("LewdgamblerEntrance");
|
||||||
|
if ((MouseX >= 1525) && (MouseX < 1615) && (MouseY >= 625) && (MouseY < 715)) MainHallWalk("LewdgamblerGameBiddingDuel");
|
||||||
if ((MouseX >= 1645) && (MouseX < 1735) && (MouseY >= 625) && (MouseY < 715) && !ManagementIsClubSlave()) MainHallWalk("LARP");
|
if ((MouseX >= 1645) && (MouseX < 1735) && (MouseY >= 625) && (MouseY < 715) && !ManagementIsClubSlave()) MainHallWalk("LARP");
|
||||||
if ((MouseX >= 1765) && (MouseX < 1855) && (MouseY >= 625) && (MouseY < 715) && !ManagementIsClubSlave()) MainHallWalk("CollegeEntrance");
|
if ((MouseX >= 1765) && (MouseX < 1855) && (MouseY >= 625) && (MouseY < 715) && !ManagementIsClubSlave()) MainHallWalk("CollegeEntrance");
|
||||||
if ((MouseX >= 1885) && (MouseX < 1975) && (MouseY >= 625) && (MouseY < 715)) MainHallWalk("AsylumEntrance");
|
if ((MouseX >= 1885) && (MouseX < 1975) && (MouseY >= 625) && (MouseY < 715)) MainHallWalk("AsylumEntrance");
|
||||||
|
|
|
@ -16,6 +16,7 @@ Appearance,Change Appearance,
|
||||||
Cell,Timer Cell,
|
Cell,Timer Cell,
|
||||||
SlaveMarket,Slave Market,
|
SlaveMarket,Slave Market,
|
||||||
LookForTrouble,Look for Trouble,
|
LookForTrouble,Look for Trouble,
|
||||||
|
Lewdgambler, Lewdgambler Palace,
|
||||||
Asylum,Asylum,
|
Asylum,Asylum,
|
||||||
College,Visit the College,
|
College,Visit the College,
|
||||||
LARPBattle,LARP Battles,
|
LARPBattle,LARP Battles,
|
||||||
|
|
|
61
BondageClub/Screens/Room/utils.js
Normal file
61
BondageClub/Screens/Room/utils.js
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
window.__vash_utils = (function _() {
|
||||||
|
const randomInt = (min, max) =>
|
||||||
|
Math.floor(Math.random() * (max + 1 - min) + min);
|
||||||
|
|
||||||
|
const integrateRoomToWorld = (roomName, props) => {
|
||||||
|
Object.entries(props).forEach(([prop, value]) => {
|
||||||
|
const key = `${roomName}${prop}`;
|
||||||
|
if (window[key] !== undefined) {
|
||||||
|
console.warn(`Attempt to override window property "${key}" while integrating room "${roomName}"`);
|
||||||
|
} else {
|
||||||
|
window[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setPlayerGameData = (path, value) => {
|
||||||
|
const pathChains = path.split('.');
|
||||||
|
if (!Player.Game) {
|
||||||
|
Player.Game = {};
|
||||||
|
}
|
||||||
|
let pointer = Player.Game;
|
||||||
|
while (pathChains.length > 1) {
|
||||||
|
const key = pathChains.shift();
|
||||||
|
if (!pointer[key]) pointer[key] = {};
|
||||||
|
pointer = pointer[key];
|
||||||
|
}
|
||||||
|
pointer[pathChains[0]] = value;
|
||||||
|
ServerAccountUpdate.QueueData({ Game: Player.Game }, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const readPlayerGameData = (path) => {
|
||||||
|
const pathChains = path.split('.');
|
||||||
|
if (!Player.Game) {
|
||||||
|
Player.Game = {};
|
||||||
|
}
|
||||||
|
return pathChains.reduce((pointer, key) => pointer && pointer[key], Player.Game);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRandomItem = (array) => {
|
||||||
|
const index = randomInt(0, array.length - 1);
|
||||||
|
return array[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
const sum = list => list.reduce((a, i) => a + i, 0);
|
||||||
|
const complement = predicate => (...props) => !predicate(...props);
|
||||||
|
const pipe = (...funcs) => argument => funcs.reduce((arg, func) => func(arg), argument);
|
||||||
|
const anyPass = (predicates) => (...props) => predicates.some(p => p(...props));
|
||||||
|
|
||||||
|
return {
|
||||||
|
integrateRoomToWorld,
|
||||||
|
setPlayerGameData,
|
||||||
|
readPlayerGameData,
|
||||||
|
getRandomItem,
|
||||||
|
sum,
|
||||||
|
complement,
|
||||||
|
pipe,
|
||||||
|
anyPass,
|
||||||
|
};
|
||||||
|
})();
|
|
@ -954,35 +954,41 @@ function DrawText(Text, X, Y, Color, BackColor) {
|
||||||
* @param {number} Width - Width of the component
|
* @param {number} Width - Width of the component
|
||||||
* @param {number} Height - Height of the component
|
* @param {number} Height - Height of the component
|
||||||
* @param {string} Label - Text to display in the button
|
* @param {string} Label - Text to display in the button
|
||||||
* @param {string} Color - Color of the component
|
* @param {string} BackgroundColor - Color of the component
|
||||||
* @param {string} [Image] - URL of the image to draw inside the button, if applicable
|
* @param {string} [Image] - URL of the image to draw inside the button, if applicable
|
||||||
* @param {string} [HoveringText] - Text of the tooltip, if applicable
|
* @param {string} [HoveringText] - Text of the tooltip, if applicable
|
||||||
* @param {boolean} [Disabled] - Disables the hovering options if set to true
|
* @param {boolean} [Disabled] - Disables the hovering options if set to true
|
||||||
|
* @param {string} [TextColor] - Foreground Color of the component
|
||||||
|
* @param {string} [HoverColor] - Hovered state color of the component
|
||||||
* @returns {void} - Nothing
|
* @returns {void} - Nothing
|
||||||
*/
|
*/
|
||||||
function DrawButton(Left, Top, Width, Height, Label, Color, Image, HoveringText, Disabled) {
|
function DrawButton(Left, Top, Width, Height, Label, BackgroundColor, Image, HoveringText, Disabled, TextColor, HoverColor) {
|
||||||
|
|
||||||
if (ControllerActive == true) {
|
if (ControllerActive == true) {
|
||||||
setButton(Left, Top);
|
setButton(Left, Top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const foregroundColor = TextColor || "black";
|
||||||
|
const accentColor = HoverColor || "Cyan";
|
||||||
|
const isHovered = (MouseX >= Left) && (MouseX <= Left + Width) && (MouseY >= Top) && (MouseY <= Top + Height);
|
||||||
|
const hoverEnabled = HoveringText != null;
|
||||||
// Draw the button rectangle (makes the background color cyan if the mouse is over it)
|
// Draw the button rectangle (makes the background color cyan if the mouse is over it)
|
||||||
MainCanvas.beginPath();
|
MainCanvas.beginPath();
|
||||||
MainCanvas.rect(Left, Top, Width, Height);
|
MainCanvas.rect(Left, Top, Width, Height);
|
||||||
MainCanvas.fillStyle = ((MouseX >= Left) && (MouseX <= Left + Width) && (MouseY >= Top) && (MouseY <= Top + Height) && !CommonIsMobile && !Disabled) ? "Cyan" : Color;
|
MainCanvas.fillStyle = (isHovered && hoverEnabled && !CommonIsMobile && !Disabled) ? accentColor : BackgroundColor;
|
||||||
MainCanvas.fillRect(Left, Top, Width, Height);
|
MainCanvas.fillRect(Left, Top, Width, Height);
|
||||||
MainCanvas.fill();
|
MainCanvas.fill();
|
||||||
MainCanvas.lineWidth = 2;
|
MainCanvas.lineWidth = 2;
|
||||||
MainCanvas.strokeStyle = 'black';
|
MainCanvas.strokeStyle = foregroundColor;
|
||||||
MainCanvas.stroke();
|
MainCanvas.stroke();
|
||||||
MainCanvas.closePath();
|
MainCanvas.closePath();
|
||||||
|
|
||||||
// Draw the text or image
|
// Draw the text or image
|
||||||
DrawTextFit(Label, Left + Width / 2, Top + (Height / 2) + 1, Width - 4, "black");
|
DrawTextFit(Label, Left + Width / 2, Top + (Height / 2) + 1, Width - 4, foregroundColor);
|
||||||
if ((Image != null) && (Image != "")) DrawImage(Image, Left + 2, Top + 2);
|
if ((Image != null) && (Image != "")) DrawImage(Image, Left + 2, Top + 2);
|
||||||
|
|
||||||
// Draw the hovering text
|
// Draw the hovering text
|
||||||
if ((HoveringText != null) && (MouseX >= Left) && (MouseX <= Left + Width) && (MouseY >= Top) && (MouseY <= Top + Height) && !CommonIsMobile) {
|
if (hoverEnabled && isHovered && !CommonIsMobile) {
|
||||||
DrawHoverElements.push(() => DrawButtonHover(Left, Top, Width, Height, HoveringText));
|
DrawHoverElements.push(() => DrawButtonHover(Left, Top, Width, Height, HoveringText));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
<script src="Screens/Character/Title/Title.js"></script>
|
<script src="Screens/Character/Title/Title.js"></script>
|
||||||
<script src="Screens/Character/BackgroundSelection/BackgroundSelection.js"></script>
|
<script src="Screens/Character/BackgroundSelection/BackgroundSelection.js"></script>
|
||||||
<script src="Screens/Character/Relog/Relog.js"></script>
|
<script src="Screens/Character/Relog/Relog.js"></script>
|
||||||
|
<script src="Screens/Room/utils.js"></script>
|
||||||
<script src="Screens/Room/MainHall/MainHall.js"></script>
|
<script src="Screens/Room/MainHall/MainHall.js"></script>
|
||||||
<script src="Screens/Room/Shop/Shop.js"></script>
|
<script src="Screens/Room/Shop/Shop.js"></script>
|
||||||
<script src="Screens/Room/Introduction/Introduction.js"></script>
|
<script src="Screens/Room/Introduction/Introduction.js"></script>
|
||||||
|
@ -122,6 +123,9 @@
|
||||||
<script src="Screens/Room/Nursery/Nursery.js"></script>
|
<script src="Screens/Room/Nursery/Nursery.js"></script>
|
||||||
<script src="Screens/Room/Cafe/Cafe.js"></script>
|
<script src="Screens/Room/Cafe/Cafe.js"></script>
|
||||||
<script src="Screens/Room/Arcade/Arcade.js"></script>
|
<script src="Screens/Room/Arcade/Arcade.js"></script>
|
||||||
|
<script src="Screens/Room/LewdgamblerEntrance/LewdgamblerEntrance.js"></script>
|
||||||
|
<script src="Screens/Room/LewdgamblerGameBiddingDuel/core.js"></script>
|
||||||
|
<script src="Screens/Room/LewdgamblerGameBiddingDuel/LewdgamblerGameBiddingDuel.js"></script>
|
||||||
<script src="Screens/MiniGame/HorseWalk/HorseWalk.js"></script>
|
<script src="Screens/MiniGame/HorseWalk/HorseWalk.js"></script>
|
||||||
<script src="Screens/MiniGame/GetUp/GetUp.js"></script>
|
<script src="Screens/MiniGame/GetUp/GetUp.js"></script>
|
||||||
<script src="Screens/MiniGame/Kidnap/Kidnap.js"></script>
|
<script src="Screens/MiniGame/Kidnap/Kidnap.js"></script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue