Created
September 29, 2024 10:31
-
-
Save huzpsb/607e1f7751d66f6168ec99c328236826 to your computer and use it in GitHub Desktop.
awMazing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name AwMazing | |
// @description Aw's script for BC map mode | |
// @version Full_0 | |
// @namespace awaqwq_awmazing | |
// @match *://*/*BondageClub* | |
// @grant GM_registerMenuCommand | |
// ==/UserScript== | |
(function () { | |
// == Engine of the world == | |
// Passable tiles | |
const matFloorWood = 100 | |
const matFloorStone = 110 | |
const matFloorGravel = 230 | |
const matFloorStoneBrick = 115 | |
const matFloorConcreteBlack = 235 | |
const matFloorConcreteWhite = 240 | |
const matFloorConcreteGrey = 250 | |
const matFloorPadModern = 120 | |
const matFloorPadTraditional = 140 | |
const matFloorSandRed = 130 | |
const matFloorSandYellow = 220 | |
const matFloorSandBlue = 131 | |
const matFloorSandBrown = 132 | |
const matFloorGrassWilted = 200 | |
const matFloorGrassNormal = 210 | |
const matFloorGrassLush = 230 | |
// Impassable tiles | |
const matWallBrickWood = 1000 | |
const matWallBrickStone = 1030 | |
const matWallPlankRed = 1040 | |
const matWallPlankBrown = 1001 | |
const matWallPlankYellow = 1010 | |
const matWallPlankStone = 1050 | |
const matWallSmoothPaper = 1020 | |
const matWallSmoothPink = 1060 | |
const matWallSmoothWhite = 1070 | |
const matWallPad = 1080 | |
// Water tiles | |
const matWaterNormal = 2000 | |
const matWaterClear = 2010 | |
const matWaterDeep = 2020 | |
const matWaterGreen = 2025 | |
awSetBlock = function (X, Y, Value) { | |
if (X < 0 || X >= ChatRoomMapViewHeight || Y < 0 || Y >= ChatRoomMapViewWidth) { | |
return | |
} | |
const pos = X + Y * ChatRoomMapViewWidth | |
ChatRoomData.MapData.Tiles = ChatRoomData.MapData.Tiles.substring(0, pos) + String.fromCharCode(Value) + ChatRoomData.MapData.Tiles.substring(pos + 1); | |
ChatRoomMapViewUpdateFlag() | |
} | |
// Entities | |
const entityNone = 100 | |
// Normal Doors | |
const entityDoorWoodOpen = 4010 | |
const entityDoorWoodNormal = 4011 | |
const entityDoorSteelNormal = 4020 | |
// Lockable Doors & Keys | |
const entityDoorWoodOwner = 4012 | |
const entityDoorWoodBronze = 4013 | |
const entityDoorWoodSilver = 4014 | |
const entityDoorWoodGolden = 4015 | |
const entityKeyBronze = 160 | |
const entityKeySilver = 162 | |
const entityKeyGolden = 164 | |
const entityDoorSteelUp = 4021 | |
const entityDoorSteelDown = 4022 | |
// Entrance & Exit | |
const entityEntrance = 110 | |
const entityExit = 115 | |
// Accessories | |
const entityBed = 120 | |
const entityPillow = 130 | |
const entityDesk = 140 | |
const entityChairSimple = 151 | |
const entityChairFancy = 150 | |
const entityComputer = 210 | |
const entitySeatWithDesk = 220 | |
const entityCookingTable = 250 | |
const entityWashingMachine = 260 | |
const entityLaundryDesk = 270 | |
const entityLaundryShelf = 300 | |
const entityChairLow = 310 | |
const entityBonsai = 320 | |
const entityFridge = 350 | |
// Accessories - Wedding on beach (Activity #1) | |
const entityWeddingBalloonColorful = 510 | |
const entityWeddingBalloonRed = 511 | |
const entityWeddingCake = 520 | |
const entityWeddingDoor = 521 | |
const entityWeddingBonsai = 530 | |
const entityWeddingUmbrella = 560 | |
const entityWeddingBed = 570 | |
// Accessories - Camping in the woods (Activity #2) | |
const entityCampFire = 610 | |
const entityCampSeatLog = 620 | |
const entityCampSeatFoldable = 650 | |
const entityCampTent = 630 | |
const entityCampSleepingBag = 640 | |
const entityCampBlockOne = 660 | |
const entityCampBlockTwo = 670 | |
const entityCampBlockThree = 680 | |
// Accessories - R18 | |
const entityR18Cage = 1010 | |
const entityR18XCross = 1020 | |
const entityR18Bed = 1030 | |
const entityR18Chair = 1040 | |
const entityR18LockerIron = 1050 | |
const entityR18LockerWood = 1060 | |
const entityR18Coffin = 1070 | |
const entityR18BodyShowcase = 1080 | |
awR18AutoApply = function (p, e) { | |
switch (e) { | |
default: | |
return false | |
case entityR18Cage: | |
InventoryWear(p, 'LeatherArmbinder', 'ItemArms', '#202020', 114514) | |
InventoryWear(p, 'Kennel', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'Kennel') { | |
i.Property.TypeRecord.d = 1 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18XCross: | |
InventoryWear(p, 'X-Cross', 'ItemDevices', null, 114514) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18Bed: | |
InventoryWear(p, 'BondageBench', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'BondageBench') { | |
i.Property.TypeRecord.typed = 4 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18Chair: | |
InventoryWear(p, 'LeatherArmbinder', 'ItemArms', '#202020', 114514) | |
InventoryWear(p, 'Trolley', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'Trolley') { | |
i.Property.TypeRecord.typed = 1 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18LockerIron: | |
InventoryWear(p, 'LeatherArmbinder', 'ItemArms', '#202020', 114514) | |
InventoryWear(p, 'Locker', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'Locker') { | |
i.Property.TypeRecord.typed = 1 | |
i.Property.Opacity = 1 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18LockerWood: | |
InventoryWear(p, 'LeatherArmbinder', 'ItemArms', '#202020', 114514) | |
InventoryWear(p, 'WoodenBox', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'WoodenBox') { | |
i.Property.Opacity = 1 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18Coffin: | |
InventoryWear(p, 'LeatherArmbinder', 'ItemArms', '#202020', 114514) | |
InventoryWear(p, 'Coffin', 'ItemDevices', null, 114514) | |
p.Appearance.forEach(i => { | |
if (i.Asset.Name === 'Coffin') { | |
i.Property.TypeRecord.typed = 1 | |
} | |
}) | |
ChatRoomCharacterUpdate(p) | |
return true | |
case entityR18BodyShowcase: | |
InventoryWear(p, 'TheDisplayFrame', 'ItemDevices', null, 114514) | |
ChatRoomCharacterUpdate(p) | |
return true | |
} | |
} | |
// Accessories Impassable | |
const entityImpassableStone = 2005 | |
const entityImpassableCarvedStone = 2010 | |
const entityImpassableWineRack = 2020 | |
const entityImpassableBars = 2030 | |
const entityImpassableRailings = 2031 | |
const entityImpassableTreeNormal = 2040 | |
const entityImpassableTreePine = 2050 | |
const entityImpassableTreeCoconut = 2055 | |
const entityImpassableTreeXmas = 2060 | |
const entityImpassableGlass = 2070 | |
// Accessories On-wall | |
const entityOnWallPainting = 3010 | |
const entityOnWallMirror = 3020 | |
const entityOnWallLight = 3030 | |
const entityOnWallWhip = 3040 | |
const entityOnWallFurnace = 3050 | |
const entityOnWallShield = 3100 | |
const entityOnWallSword = 3110 | |
const entityOnWallBlackboard = 3200 | |
const entityOnWallFirstAid = 3250 | |
const entityOnWallE = 3260 | |
awSetEntity = function (X, Y, Value) { | |
if (X < 0 || X >= ChatRoomMapViewHeight || Y < 0 || Y >= ChatRoomMapViewWidth) { | |
return | |
} | |
const pos = X + Y * ChatRoomMapViewWidth | |
ChatRoomData.MapData.Objects = ChatRoomData.MapData.Objects.substring(0, pos) + String.fromCharCode(Value) + ChatRoomData.MapData.Objects.substring(pos + 1); | |
ChatRoomMapViewUpdateFlag() | |
} | |
// Room-related constants | |
const xDefaultSpawn = 20 | |
const yDefaultSpawn = 20 | |
const xMaxRoomSize = 40 | |
const yMaxRoomSize = 40 | |
awClearRoom = function () { | |
for (let X = 0; X < ChatRoomMapViewHeight; X++) { | |
for (let Y = 0; Y < ChatRoomMapViewWidth; Y++) { | |
let mat = (X % 5 === 2 && Y % 5 === 2) ? matFloorGravel : matFloorWood | |
awSetBlock(X, Y, mat) | |
awSetEntity(X, Y, entityNone) | |
} | |
} | |
} | |
// == Event Handler == | |
EmitMapMoveEvent = null | |
EmitMapMoveEvent0 = function (e) { | |
for (let C of ChatRoomCharacter) { | |
if (C.MemberNumber === e.player) { | |
e.playerObj = C | |
break | |
} | |
} | |
if (EmitMapMoveEvent !== null) { | |
EmitMapMoveEvent(e) | |
} else { | |
if (e.isSelf) { | |
console.log(e) | |
} | |
} | |
} | |
ChatRoomMapViewSyncMapData0 = ChatRoomMapViewSyncMapData | |
ChatRoomMapViewSyncMapData = function (d) { | |
ChatRoomMapViewSyncMapData0(d) | |
let dPlayer = d.MemberNumber | |
let dPosX = d.MapData.X | |
let dPosY = d.MapData.Y | |
let dDestMat = ChatRoomData.MapData.Tiles.charCodeAt(dPosX + dPosY * ChatRoomMapViewWidth) | |
let dObj = ChatRoomData.MapData.Objects.charCodeAt(dPosX + dPosY * ChatRoomMapViewWidth) | |
let moveEvent = { | |
player: dPlayer, | |
posX: dPosX, | |
posY: dPosY, | |
destMat: dDestMat, | |
destObj: dObj, | |
isSelf: false | |
} | |
EmitMapMoveEvent0(moveEvent) | |
} | |
oldX = -1 | |
oldY = -1 | |
ChatRoomMapViewUpdatePlayerSync0 = ChatRoomMapViewUpdatePlayerSync | |
ChatRoomMapViewUpdatePlayerSync = function () { | |
let newX = Player.MapData.Pos.X | |
let newY = Player.MapData.Pos.Y | |
ChatRoomMapViewUpdatePlayerSync0() | |
if (oldX !== newX || oldY !== newY) { | |
oldX = newX | |
oldY = newY | |
let newMat = ChatRoomData.MapData.Tiles.charCodeAt(newX + newY * ChatRoomMapViewWidth) | |
let newObj = ChatRoomData.MapData.Objects.charCodeAt(newX + newY * ChatRoomMapViewWidth) | |
let moveEvent = { | |
player: Player.MemberNumber, | |
posX: newX, | |
posY: newY, | |
destMat: newMat, | |
destObj: newObj, | |
isSelf: true | |
} | |
EmitMapMoveEvent0(moveEvent) | |
} | |
} | |
// == World Gen == | |
let RandomChoice = function (choices) { | |
return choices[Math.floor(Math.random() * choices.length)]; | |
} | |
let RandomInt = function (min, max) { | |
return Math.floor(Math.random() * (max - min + 1) + min); | |
} | |
let RandomR18Ent = function () { | |
const R18e = [ | |
entityR18Cage, | |
entityR18XCross, | |
entityR18Bed, | |
entityR18Chair, | |
entityR18LockerIron, | |
entityR18LockerWood, | |
entityR18Coffin, | |
entityR18BodyShowcase | |
] | |
return RandomChoice(R18e) | |
} | |
let RandomIndoorAccPack = function () { | |
const accPack = [ | |
[entityBed, entityPillow, entityChairSimple, entityDesk], // Bedroom | |
[entityDesk, entityChairFancy, entityBonsai], // Office | |
[entityComputer, entitySeatWithDesk, entityChairLow], // Computer Room | |
[entityCookingTable, entityFridge, entityChairLow], // Kitchen | |
[entityWashingMachine, entityLaundryDesk, entityLaundryShelf], // Laundry | |
[entityWeddingBalloonColorful, entityWeddingBalloonRed, entityWeddingCake, entityWeddingDoor, entityWeddingBonsai, entityWeddingUmbrella, entityWeddingBed], // Wedding | |
] | |
return RandomChoice(accPack) | |
} | |
let RandomOutdoorAccPack = function () { | |
return [entityCampFire, entityCampSeatLog, entityCampSeatFoldable, entityCampTent, entityCampSleepingBag, entityCampBlockOne, entityCampBlockTwo, entityCampBlockThree] | |
} | |
let RandomIndoorBackPack = function () { | |
const backPack = [ | |
{ | |
ground: [matFloorPadModern, matFloorPadTraditional], wall: [matWallPad] | |
}, | |
{ | |
ground: [matFloorSandRed, matFloorSandYellow, matFloorSandBlue, matFloorSandBrown], | |
wall: [matWallBrickWood, matWallBrickStone] | |
}, | |
{ | |
ground: [matFloorConcreteBlack, matFloorConcreteWhite, matFloorConcreteGrey], | |
wall: [matWallSmoothPaper, matWallSmoothPink, matWallSmoothWhite] | |
}, | |
{ | |
ground: [matFloorStone, matFloorStoneBrick], | |
wall: [matWallPlankRed, matWallPlankBrown, matWallPlankYellow, matWallPlankStone] | |
} | |
] | |
const randomPack = RandomChoice(backPack) | |
return { | |
ground: RandomChoice(randomPack.ground), | |
wall: RandomChoice(randomPack.wall) | |
} | |
} | |
let RandomOutdoorBackPack = function () { | |
const randomPack = { | |
ground: [matFloorGrassWilted, matFloorGrassNormal, matFloorGrassLush], | |
wall: [matWallBrickStone, matWallBrickWood] | |
} | |
return { | |
ground: RandomChoice(randomPack.ground), | |
wall: RandomChoice(randomPack.wall) | |
} | |
} | |
let RandomWaterPack = function () { | |
return [matWaterNormal, matWaterClear, matWaterDeep, matWaterGreen] | |
} | |
let RandomOnWall = function () { | |
const ow = [entityOnWallPainting, entityOnWallMirror, entityOnWallLight, entityOnWallWhip, entityOnWallFurnace, entityOnWallShield, entityOnWallSword, entityOnWallBlackboard, entityOnWallFirstAid, entityOnWallE] | |
return RandomChoice(ow) | |
} | |
let RandomDoor = function () { | |
const door = [entityDoorWoodOpen, entityDoorWoodNormal, entityDoorSteelNormal] | |
return RandomChoice(door) | |
} | |
let RandomPackWithAcc = function () { | |
if (Math.random() > 0.3) { | |
const pack = RandomIndoorBackPack() | |
const accPack = RandomIndoorAccPack() | |
return { | |
pack: pack, | |
acc: accPack, | |
indoor: true | |
} | |
} else { | |
const pack = RandomOutdoorBackPack() | |
const accPack = RandomOutdoorAccPack() | |
return { | |
pack: pack, | |
acc: accPack, | |
indoor: false | |
} | |
} | |
} | |
let populateRoom = function (xf, yf, xt, yt) { | |
const pair = RandomPackWithAcc() | |
const pack = pair.pack | |
const accPack = pair.acc | |
for (let x = xf; x <= xt; x++) { | |
awSetBlock(x, yf, pack.wall) | |
} | |
let doorX = RandomInt(xf, xt) | |
if (yf === 0) { | |
doorX = -1 | |
} | |
for (let x = xf; x <= xt; x++) { | |
if (x === doorX) { | |
awSetEntity(x, yf, RandomDoor()) | |
} else { | |
if (Math.random() > 0.7) { | |
awSetEntity(x, yf, RandomOnWall()) | |
} | |
} | |
} | |
for (let x = xf; x <= xt; x++) { | |
for (let y = yf + 1; y <= yt; y++) { | |
awSetBlock(x, y, pack.ground) | |
} | |
} | |
const accCount = RandomInt(15, 30) | |
for (let i = 0; i < accCount; i++) { | |
const acc = RandomChoice(accPack) | |
const ax = RandomInt(xf, xt) | |
const ay = RandomInt(yf + 1, yt) | |
awSetEntity(ax, ay, acc) | |
} | |
const accR18Count = RandomInt(5, 10) | |
for (let i = 0; i < accR18Count; i++) { | |
const ax = RandomInt(xf, xt) | |
const ay = RandomInt(yf + 2, yt - 1) | |
awSetEntity(ax, ay, RandomR18Ent()) | |
} | |
if (!pair.indoor) { | |
const water = RandomChoice(RandomWaterPack()) | |
const waterCenterX = RandomInt(xf + 1, xt - 1) | |
const waterCenterY = RandomInt(yf + 1, yt - 1) | |
for (let x = xf + 1; x <= xt - 1; x++) { | |
for (let y = yf + 1; y <= yt - 1; y++) { | |
const huffmanDist = Math.abs(x - waterCenterX) + Math.abs(y - waterCenterY) + Math.floor(Math.random() * 3) | |
if (huffmanDist < 6) { | |
awSetBlock(x, y, water) | |
} | |
} | |
} | |
} | |
} | |
let chatSend = function (m) { | |
ServerSend('ChatRoomChat', { | |
Content: m, | |
Type: 'Chat', | |
}) | |
} | |
let doPopulate = function () { | |
chatSend("( Attention, please! The map is refreshing...") | |
awClearRoom() | |
let pDiv = [0, 13, 26, 39] | |
const wallMat = RandomIndoorBackPack().wall | |
for (let x = 1; x <= 2; x++) { | |
for (let y = 0; y <= 38; y++) { | |
awSetBlock(pDiv[x], y, wallMat) | |
} | |
} | |
for (let xIdx = 0; xIdx <= 2; xIdx++) { | |
for (let yIdx = 0; yIdx <= 2; yIdx++) { | |
let xF = pDiv[xIdx] | |
xF = (xF === 0) ? 0 : xF + 1; | |
let xT = pDiv[xIdx + 1] | |
xT = (xT === 39) ? 39 : xT - 1; | |
console.log(xF, pDiv[yIdx], xT, pDiv[yIdx + 1]) | |
populateRoom(xF, pDiv[yIdx], xT, pDiv[yIdx + 1]) | |
} | |
} | |
} | |
GM_registerMenuCommand('Map_export', () => { | |
const dict = {}; | |
dict.mp = ChatRoomData.MapData.Tiles; | |
dict.cr = ChatRoomData.MapData.Objects; | |
ChatRoomSendLocal('AwMazing> Done! To import, press F12 and paste the following code.\n' + | |
'let encodedDict = "' + | |
btoa(encodeURI(JSON.stringify(dict))) + | |
'";fetch(\'https://huzpsb.github.io/roomimport.js?\' + new Date().getTime()).then(response => response.text()).then(code => {eval(code);}).catch(error => console.error(error));' | |
) | |
} | |
); | |
GM_registerMenuCommand('Map_generate (Random RP)', () => { | |
doPopulate(); | |
} | |
); | |
GM_registerMenuCommand('Bot_toggle', () => { | |
if (EmitMapMoveEvent) { | |
EmitMapMoveEvent = null; | |
ChatRoomSendLocal('[DEBUG] Bot is now off.') | |
} else { | |
EmitMapMoveEvent = function (e) { | |
if (awR18AutoApply(e.playerObj, e.destObj)) { | |
ChatRoomSendLocal('[DEBUG] ' + e.playerObj.Name + ' triggered the trap!') | |
} | |
} | |
ChatRoomSendLocal('[DEBUG] Bot is now on.') | |
} | |
}); | |
} | |
)(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment