init monorepo with nitro-react
|
@ -37,3 +37,5 @@ testem.log
|
|||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
apps/**/public/*.json
|
13
.prettierrc
|
@ -1,3 +1,12 @@
|
|||
{
|
||||
"singleQuote": true
|
||||
}
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"bracketSpacing": false,
|
||||
"singleQuote": false,
|
||||
"arrowParens": "avoid",
|
||||
"printWidth": 160,
|
||||
"jsxBracketSameLine": true,
|
||||
"importOrder": ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
|
||||
"importOrderSeparation": true,
|
||||
"importOrderSortSpecifiers": true
|
||||
}
|
|
@ -2,15 +2,34 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Frontend</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/src/styles.scss" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" crossorigin="use-credentials" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000">
|
||||
<meta name="apple-mobile-web-app-title" content="Nitro">
|
||||
<meta name="application-name" content="Nitro">
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<base href="./">
|
||||
<title>Nitro</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="w-100 h-100"></div>
|
||||
<script>
|
||||
const NitroConfig = {
|
||||
"config.urls": [ '/renderer-config.json', '/ui-config.json' ],
|
||||
"sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null),
|
||||
"forward.type": (new URLSearchParams(window.location.search).get('room') ? 2 : -1),
|
||||
"forward.id": (new URLSearchParams(window.location.search).get('room') || 0),
|
||||
"friend.id": (new URLSearchParams(window.location.search).get('friend') || 0),
|
||||
};
|
||||
</script>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 8.0 KiB |
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
After Width: | Height: | Size: 1017 B |
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 6.4 KiB |
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"socket.url": "wss://ws.website.com:2096",
|
||||
"asset.url": "https://website.com",
|
||||
"image.library.url": "https://website.com/c_images/",
|
||||
"hof.furni.url": "https://website.com/dcr/hof_furni",
|
||||
"images.url": "${asset.url}/images",
|
||||
"gamedata.url": "${asset.url}/gamedata",
|
||||
"sounds.url": "${asset.url}/sounds/%sample%.mp3",
|
||||
"external.texts.url": [ "${gamedata.url}/ExternalTexts.json", "${gamedata.url}/UITexts.json" ],
|
||||
"external.samples.url": "${hof.furni.url}/mp3/sound_machine_sample_%sample%.mp3",
|
||||
"furnidata.url": "${gamedata.url}/FurnitureData.json",
|
||||
"productdata.url": "${gamedata.url}/ProductData.json",
|
||||
"avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json",
|
||||
"avatar.figuredata.url": "${gamedata.url}/FigureData.json",
|
||||
"avatar.figuremap.url": "${gamedata.url}/FigureMap.json",
|
||||
"avatar.effectmap.url": "${gamedata.url}/EffectMap.json",
|
||||
"avatar.asset.url": "${asset.url}/bundled/figure/%libname%.nitro",
|
||||
"avatar.asset.effect.url": "${asset.url}/bundled/effect/%libname%.nitro",
|
||||
"furni.asset.url": "${asset.url}/bundled/furniture/%libname%.nitro",
|
||||
"furni.asset.icon.url": "${hof.furni.url}/icons/%libname%%param%_icon.png",
|
||||
"pet.asset.url": "${asset.url}/bundled/pet/%libname%.nitro",
|
||||
"generic.asset.url": "${asset.url}/bundled/generic/%libname%.nitro",
|
||||
"badge.asset.url": "${image.library.url}album1584/%badgename%.gif",
|
||||
"furni.rotation.bounce.steps": 20,
|
||||
"furni.rotation.bounce.height": 0.0625,
|
||||
"enable.avatar.arrow": false,
|
||||
"system.log.debug": false,
|
||||
"system.log.warn": false,
|
||||
"system.log.error": false,
|
||||
"system.log.events": false,
|
||||
"system.log.packets": false,
|
||||
"system.fps.animation": 24,
|
||||
"system.fps.max": 60,
|
||||
"system.pong.manually": true,
|
||||
"system.pong.interval.ms": 20000,
|
||||
"room.color.skip.transition": true,
|
||||
"room.landscapes.enabled": true,
|
||||
"avatar.mandatory.libraries": [
|
||||
"bd:1",
|
||||
"li:0"
|
||||
],
|
||||
"avatar.mandatory.effect.libraries": [
|
||||
"dance.1",
|
||||
"dance.2",
|
||||
"dance.3",
|
||||
"dance.4"
|
||||
],
|
||||
"avatar.default.figuredata": {"palettes":[{"id":1,"colors":[{"id":99999,"index":1001,"club":0,"selectable":false,"hexCode":"DDDDDD"},{"id":99998,"index":1001,"club":0,"selectable":false,"hexCode":"FAFAFA"}]},{"id":3,"colors":[{"id":10001,"index":1001,"club":0,"selectable":false,"hexCode":"EEEEEE"},{"id":10002,"index":1002,"club":0,"selectable":false,"hexCode":"FA3831"},{"id":10003,"index":1003,"club":0,"selectable":false,"hexCode":"FD92A0"},{"id":10004,"index":1004,"club":0,"selectable":false,"hexCode":"2AC7D2"},{"id":10005,"index":1005,"club":0,"selectable":false,"hexCode":"35332C"},{"id":10006,"index":1006,"club":0,"selectable":false,"hexCode":"EFFF92"},{"id":10007,"index":1007,"club":0,"selectable":false,"hexCode":"C6FF98"},{"id":10008,"index":1008,"club":0,"selectable":false,"hexCode":"FF925A"},{"id":10009,"index":1009,"club":0,"selectable":false,"hexCode":"9D597E"},{"id":10010,"index":1010,"club":0,"selectable":false,"hexCode":"B6F3FF"},{"id":10011,"index":1011,"club":0,"selectable":false,"hexCode":"6DFF33"},{"id":10012,"index":1012,"club":0,"selectable":false,"hexCode":"3378C9"},{"id":10013,"index":1013,"club":0,"selectable":false,"hexCode":"FFB631"},{"id":10014,"index":1014,"club":0,"selectable":false,"hexCode":"DFA1E9"},{"id":10015,"index":1015,"club":0,"selectable":false,"hexCode":"F9FB32"},{"id":10016,"index":1016,"club":0,"selectable":false,"hexCode":"CAAF8F"},{"id":10017,"index":1017,"club":0,"selectable":false,"hexCode":"C5C6C5"},{"id":10018,"index":1018,"club":0,"selectable":false,"hexCode":"47623D"},{"id":10019,"index":1019,"club":0,"selectable":false,"hexCode":"8A8361"},{"id":10020,"index":1020,"club":0,"selectable":false,"hexCode":"FF8C33"},{"id":10021,"index":1021,"club":0,"selectable":false,"hexCode":"54C627"},{"id":10022,"index":1022,"club":0,"selectable":false,"hexCode":"1E6C99"},{"id":10023,"index":1023,"club":0,"selectable":false,"hexCode":"984F88"},{"id":10024,"index":1024,"club":0,"selectable":false,"hexCode":"77C8FF"},{"id":10025,"index":1025,"club":0,"selectable":false,"hexCode":"FFC08E"},{"id":10026,"index":1026,"club":0,"selectable":false,"hexCode":"3C4B87"},{"id":10027,"index":1027,"club":0,"selectable":false,"hexCode":"7C2C47"},{"id":10028,"index":1028,"club":0,"selectable":false,"hexCode":"D7FFE3"},{"id":10029,"index":1029,"club":0,"selectable":false,"hexCode":"8F3F1C"},{"id":10030,"index":1030,"club":0,"selectable":false,"hexCode":"FF6393"},{"id":10031,"index":1031,"club":0,"selectable":false,"hexCode":"1F9B79"},{"id":10032,"index":1032,"club":0,"selectable":false,"hexCode":"FDFF33"}]}],"setTypes":[{"type":"hd","paletteId":1,"mandatory_f_0":true,"mandatory_f_1":true,"mandatory_m_0":true,"mandatory_m_1":true,"sets":[{"id":99999,"gender":"U","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":1,"type":"bd","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"hd","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"lh","colorable":true,"index":0,"colorindex":1},{"id":1,"type":"rh","colorable":true,"index":0,"colorindex":1}]}]},{"type":"bds","paletteId":1,"mandatory_f_0":false,"mandatory_f_1":false,"mandatory_m_0":false,"mandatory_m_1":false,"sets":[{"id":10001,"gender":"U","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10001,"type":"bds","colorable":true,"index":0,"colorindex":1},{"id":10001,"type":"lhs","colorable":true,"index":0,"colorindex":1},{"id":10001,"type":"rhs","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"bd"},{"partType":"rh"},{"partType":"lh"}]}]},{"type":"ss","paletteId":3,"mandatory_f_0":false,"mandatory_f_1":false,"mandatory_m_0":false,"mandatory_m_1":false,"sets":[{"id":10010,"gender":"F","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10001,"type":"ss","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"ch"},{"partType":"lg"},{"partType":"ca"},{"partType":"wa"},{"partType":"sh"},{"partType":"ls"},{"partType":"rs"},{"partType":"lc"},{"partType":"rc"},{"partType":"cc"},{"partType":"cp"}]},{"id":10011,"gender":"M","club":0,"colorable":true,"selectable":false,"preselectable":false,"sellable":false,"parts":[{"id":10002,"type":"ss","colorable":true,"index":0,"colorindex":1}],"hiddenLayers":[{"partType":"ch"},{"partType":"lg"},{"partType":"ca"},{"partType":"wa"},{"partType":"sh"},{"partType":"ls"},{"partType":"rs"},{"partType":"lc"},{"partType":"rc"},{"partType":"cc"},{"partType":"cp"}]}]}]},
|
||||
"avatar.default.actions": {
|
||||
"actions": [
|
||||
{
|
||||
"id": "Default",
|
||||
"state": "std",
|
||||
"precedence": 1000,
|
||||
"main": true,
|
||||
"isDefault": true,
|
||||
"geometryType": "vertical",
|
||||
"activePartSet": "figure",
|
||||
"assetPartDefinition": "std"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pet.types": [
|
||||
"dog",
|
||||
"cat",
|
||||
"croco",
|
||||
"terrier",
|
||||
"bear",
|
||||
"pig",
|
||||
"lion",
|
||||
"rhino",
|
||||
"spider",
|
||||
"turtle",
|
||||
"chicken",
|
||||
"frog",
|
||||
"dragon",
|
||||
"monster",
|
||||
"monkey",
|
||||
"horse",
|
||||
"monsterplant",
|
||||
"bunnyeaster",
|
||||
"bunnyevil",
|
||||
"bunnydepressed",
|
||||
"bunnylove",
|
||||
"pigeongood",
|
||||
"pigeonevil",
|
||||
"demonmonkey",
|
||||
"bearbaby",
|
||||
"terrierbaby",
|
||||
"gnome",
|
||||
"gnome",
|
||||
"kittenbaby",
|
||||
"puppybaby",
|
||||
"pigletbaby",
|
||||
"haloompa",
|
||||
"fools",
|
||||
"pterosaur",
|
||||
"velociraptor",
|
||||
"cow",
|
||||
"LeetPen",
|
||||
"bbwibb",
|
||||
"elephants"
|
||||
],
|
||||
"preload.assets.urls": [
|
||||
"${asset.url}/bundled/generic/avatar_additions.nitro",
|
||||
"${asset.url}/bundled/generic/group_badge.nitro",
|
||||
"${asset.url}/bundled/generic/floor_editor.nitro",
|
||||
"${images.url}/loading_icon.png",
|
||||
"${images.url}/clear_icon.png",
|
||||
"${images.url}/big_arrow.png"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
|
@ -0,0 +1,154 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="850.000000pt" height="850.000000pt" viewBox="0 0 850.000000 850.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,850.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M4838 8495 c-2 -2 -24 -5 -49 -8 -54 -6 -182 -48 -242 -78 -193 -98
|
||||
-347 -291 -430 -539 -32 -95 -38 -121 -52 -210 -2 -14 -7 -45 -11 -70 -4 -25
|
||||
-6 -115 -5 -200 5 -279 4 -424 -3 -460 -20 -98 -32 -132 -72 -216 -48 -98
|
||||
-116 -178 -194 -230 -52 -34 -116 -65 -122 -58 -3 2 1 30 8 61 13 65 10 244
|
||||
-6 273 -5 10 -10 27 -10 36 0 23 -79 184 -91 184 -5 0 -9 6 -9 13 0 8 -29 40
|
||||
-64 73 -78 73 -81 74 -136 104 -25 14 -46 28 -48 33 -2 4 -9 7 -15 7 -6 0 -39
|
||||
12 -75 26 -35 14 -66 24 -68 21 -2 -2 5 -15 16 -29 40 -51 92 -175 104 -248 3
|
||||
-14 5 -25 6 -25 1 0 3 -21 4 -48 2 -26 5 -50 8 -53 4 -3 2 -19 -2 -35 -5 -17
|
||||
-5 -29 0 -29 5 0 7 -6 5 -12 -2 -7 -6 -38 -9 -68 -9 -109 -57 -294 -103 -400
|
||||
-24 -57 -143 -291 -154 -303 -28 -34 -155 -240 -180 -292 -16 -33 -36 -89 -45
|
||||
-125 -17 -65 -22 -199 -10 -238 9 -26 3 -29 -64 -36 -30 -4 -71 -9 -90 -11
|
||||
-19 -2 -60 -7 -90 -10 -30 -4 -66 -8 -80 -10 -14 -2 -54 -7 -90 -10 -36 -4
|
||||
-78 -9 -95 -11 -16 -2 -52 -6 -80 -9 -27 -3 -66 -7 -85 -10 -19 -2 -60 -7 -90
|
||||
-10 -30 -4 -66 -8 -80 -10 -14 -2 -52 -7 -85 -10 -33 -3 -71 -7 -85 -9 -66 -9
|
||||
-139 -17 -180 -21 -25 -2 -63 -6 -85 -9 -22 -3 -64 -8 -93 -10 -60 -5 -81 -15
|
||||
-36 -18 28 -1 40 -3 57 -8 13 -4 21 -6 77 -14 30 -4 62 -9 70 -11 8 -1 33 -6
|
||||
55 -9 38 -6 87 -14 130 -22 11 -2 40 -7 65 -10 25 -3 54 -8 65 -10 11 -3 36
|
||||
-7 55 -9 19 -3 51 -8 70 -11 19 -3 46 -8 60 -10 32 -5 89 -15 117 -20 13 -3
|
||||
35 -6 50 -8 16 -2 44 -6 63 -10 19 -3 51 -8 70 -10 19 -3 107 -17 195 -31 88
|
||||
-14 171 -28 185 -30 14 -2 41 -7 60 -10 19 -4 46 -8 60 -10 14 -2 41 -6 60
|
||||
-10 19 -4 44 -8 55 -9 11 -2 34 -6 50 -9 17 -3 46 -9 65 -11 19 -3 45 -8 56
|
||||
-10 12 -2 39 -7 60 -10 45 -8 57 -16 23 -17 -13 0 -33 -2 -44 -4 -11 -2 -47
|
||||
-7 -80 -10 -33 -4 -71 -8 -85 -10 -14 -2 -52 -6 -85 -10 -33 -3 -71 -8 -85
|
||||
-11 -14 -2 -50 -6 -80 -9 -30 -3 -71 -8 -90 -11 -77 -10 -107 -14 -155 -19
|
||||
-102 -12 -121 -14 -165 -20 -25 -4 -65 -8 -90 -11 -25 -2 -61 -7 -80 -9 -19
|
||||
-3 -51 -8 -70 -10 -56 -6 -152 -17 -185 -21 -16 -2 -55 -6 -85 -8 -30 -3 -66
|
||||
-8 -80 -11 -14 -3 -45 -7 -70 -10 -25 -3 -63 -8 -85 -11 -22 -3 -56 -8 -75
|
||||
-10 -47 -5 -131 -15 -152 -18 -10 -1 -21 -6 -25 -10 -5 -4 -3 -6 2 -5 6 2 33
|
||||
-1 60 -5 28 -5 59 -10 70 -11 11 -2 47 -8 80 -14 76 -14 100 -18 150 -26 22
|
||||
-3 94 -15 160 -26 66 -11 134 -22 150 -25 17 -2 44 -7 60 -10 17 -4 44 -9 60
|
||||
-11 17 -1 57 -8 90 -13 33 -6 78 -13 100 -15 22 -3 46 -8 54 -11 8 -2 30 -7
|
||||
50 -10 20 -3 74 -12 121 -19 47 -8 103 -17 125 -20 22 -3 51 -8 65 -12 14 -3
|
||||
36 -7 50 -9 14 -2 36 -5 50 -8 14 -2 43 -7 65 -11 22 -3 78 -13 125 -22 102
|
||||
-18 118 -20 149 -22 13 0 22 -4 19 -7 -6 -5 -38 -11 -113 -19 -22 -2 -49 -6
|
||||
-60 -8 -17 -4 -71 -11 -175 -23 -14 -1 -41 -5 -60 -7 -19 -3 -60 -8 -90 -12
|
||||
-30 -3 -66 -8 -80 -10 -31 -5 -124 -16 -170 -21 -19 -2 -48 -5 -65 -7 -16 -3
|
||||
-57 -8 -90 -12 -32 -4 -66 -8 -75 -10 -14 -2 -90 -12 -165 -20 -76 -9 -140
|
||||
-17 -157 -20 -11 -2 -46 -7 -79 -10 -33 -4 -69 -8 -79 -10 -10 -2 -46 -6 -79
|
||||
-10 -33 -3 -70 -8 -83 -10 -13 -3 -45 -7 -73 -10 -27 -3 -59 -8 -70 -10 -11
|
||||
-2 -31 -4 -44 -4 -32 -1 -20 -13 19 -17 16 -2 42 -6 58 -9 15 -3 77 -14 137
|
||||
-25 61 -10 121 -21 135 -24 14 -3 43 -8 64 -11 21 -3 48 -7 60 -10 12 -2 37
|
||||
-7 56 -10 37 -5 73 -11 130 -21 36 -7 52 -9 105 -18 33 -5 76 -13 115 -21 14
|
||||
-3 43 -8 65 -11 22 -2 54 -7 70 -10 17 -4 39 -8 50 -9 11 -2 90 -16 175 -30
|
||||
85 -15 164 -29 175 -30 11 -2 34 -6 50 -9 48 -9 120 -22 232 -41 17 -3 42 -9
|
||||
55 -14 22 -9 22 -10 -7 -11 -42 -2 -85 -7 -131 -15 -40 -7 -67 -10 -142 -20
|
||||
-105 -13 -138 -18 -157 -22 -11 -2 -42 -6 -70 -8 -27 -3 -59 -7 -70 -9 -11 -2
|
||||
-49 -7 -85 -11 -36 -4 -73 -9 -84 -11 -10 -2 -44 -6 -75 -9 -31 -4 -67 -8 -81
|
||||
-10 -35 -6 -120 -17 -150 -20 -14 -2 -45 -6 -70 -9 -48 -7 -89 -12 -160 -21
|
||||
-25 -3 -56 -7 -70 -10 -14 -3 -45 -7 -70 -10 -64 -7 -121 -15 -150 -20 -14 -2
|
||||
-52 -7 -85 -11 -53 -5 -97 -20 -63 -21 7 0 103 -17 213 -38 110 -20 209 -38
|
||||
220 -40 11 -1 48 -8 83 -14 34 -6 90 -16 125 -22 34 -6 71 -13 82 -14 22 -3
|
||||
124 -21 168 -30 15 -3 37 -7 50 -9 12 -3 38 -7 57 -10 19 -3 46 -8 60 -11 28
|
||||
-6 181 -34 220 -40 54 -9 194 -35 209 -39 9 -3 32 -7 51 -10 19 -3 56 -9 82
|
||||
-14 26 -5 50 -7 54 -3 4 3 5 0 2 -8 -2 -8 -13 -16 -24 -17 -10 -2 -39 -6 -64
|
||||
-9 -25 -3 -58 -8 -75 -10 -16 -2 -50 -7 -75 -10 -25 -3 -54 -7 -66 -9 -12 -2
|
||||
-45 -7 -75 -11 -30 -3 -61 -8 -69 -10 -8 -2 -40 -7 -70 -10 -51 -6 -82 -10
|
||||
-150 -20 -45 -7 -254 -36 -296 -41 -23 -3 -53 -7 -65 -9 -13 -3 -47 -8 -75
|
||||
-10 -28 -3 -60 -7 -71 -9 -11 -3 -42 -7 -69 -11 -53 -6 -89 -13 -89 -15 0 -1
|
||||
-16 -3 -35 -4 -19 -2 -73 -9 -120 -16 -77 -11 -128 -18 -154 -19 -24 -2 8 -13
|
||||
80 -27 125 -25 226 -44 259 -49 16 -3 64 -11 105 -19 118 -23 143 -27 175 -32
|
||||
17 -3 64 -12 105 -20 41 -8 113 -22 160 -30 47 -8 96 -17 110 -20 14 -2 61
|
||||
-11 105 -19 44 -8 91 -17 105 -20 14 -3 86 -17 161 -30 75 -14 150 -30 167
|
||||
-34 17 -5 33 -7 36 -3 3 3 6 -2 6 -11 0 -10 -3 -17 -7 -18 -5 0 -15 -2 -23 -4
|
||||
-8 -1 -35 -6 -60 -9 -40 -6 -116 -18 -130 -21 -3 -1 -32 -5 -65 -9 -32 -4 -66
|
||||
-9 -75 -11 -8 -1 -42 -6 -75 -10 -32 -3 -62 -8 -65 -10 -3 -1 -30 -6 -61 -9
|
||||
-31 -4 -67 -9 -80 -11 -13 -3 -42 -7 -64 -10 -22 -2 -51 -6 -65 -9 -24 -4
|
||||
-101 -15 -145 -21 -11 -2 -40 -6 -65 -10 -25 -3 -56 -8 -70 -10 -73 -10 -118
|
||||
-17 -145 -21 -16 -3 -41 -7 -55 -9 -27 -4 -90 -14 -129 -20 -23 -4 -86 -14
|
||||
-123 -19 -23 -3 -35 -16 -17 -17 8 0 21 -2 29 -4 8 -2 33 -6 55 -10 22 -3 48
|
||||
-8 57 -11 9 -3 25 -6 35 -8 21 -4 94 -18 108 -21 6 -2 26 -5 45 -9 43 -7 76
|
||||
-14 115 -23 17 -3 39 -7 50 -9 11 -1 56 -9 100 -19 44 -9 87 -18 95 -20 37 -7
|
||||
97 -17 120 -21 14 -2 45 -9 70 -14 25 -5 56 -12 70 -14 40 -8 80 -16 155 -31
|
||||
39 -8 81 -16 95 -18 14 -3 61 -13 105 -22 44 -9 91 -19 104 -21 14 -3 28 -7
|
||||
33 -10 9 -6 -9 -45 -20 -42 -7 2 -93 -9 -137 -18 -11 -2 -40 -6 -65 -10 -25
|
||||
-3 -52 -8 -62 -9 -9 -2 -38 -7 -65 -11 -26 -3 -57 -8 -68 -11 -28 -6 -74 -13
|
||||
-115 -18 -31 -3 -122 -17 -190 -29 -54 -10 -106 -18 -135 -21 -16 -2 -43 -6
|
||||
-60 -10 -30 -6 -68 -12 -127 -19 -18 -2 -44 -7 -58 -10 -14 -3 -41 -8 -60 -11
|
||||
-89 -13 -112 -17 -128 -20 -9 -2 -39 -7 -65 -11 -26 -3 -45 -9 -42 -13 7 -6
|
||||
110 -31 135 -32 8 0 29 -5 45 -9 17 -5 44 -11 60 -14 55 -9 136 -26 143 -30 4
|
||||
-2 26 -7 48 -10 22 -4 105 -20 184 -37 80 -16 156 -32 170 -35 46 -9 175 -36
|
||||
195 -40 11 -3 34 -7 50 -10 17 -3 46 -9 65 -14 35 -9 182 -40 210 -45 14 -2
|
||||
15 -8 11 -48 0 -7 -9 -13 -18 -14 -17 -1 -183 -29 -233 -39 -14 -3 -41 -7 -60
|
||||
-10 -19 -2 -46 -6 -60 -9 -14 -3 -36 -7 -50 -10 -14 -2 -68 -11 -120 -20 -52
|
||||
-9 -108 -19 -125 -21 -16 -2 -41 -6 -55 -9 -14 -3 -41 -8 -60 -10 -19 -3 -46
|
||||
-8 -60 -11 -13 -3 -38 -7 -55 -10 -16 -2 -41 -6 -55 -9 -14 -3 -50 -9 -80 -15
|
||||
-30 -6 -66 -12 -80 -15 -34 -7 -112 -18 -127 -18 -7 0 -13 -4 -13 -8 0 -8 27
|
||||
-15 86 -25 21 -3 42 -8 45 -10 3 -2 19 -6 35 -8 51 -10 198 -41 257 -55 20 -5
|
||||
37 -7 37 -5 0 3 8 1 17 -5 10 -5 36 -11 58 -14 22 -3 47 -8 55 -11 8 -3 26 -8
|
||||
40 -10 20 -4 145 -33 265 -62 34 -8 109 -25 130 -29 11 -2 51 -11 88 -21 67
|
||||
-17 68 -18 64 -48 -3 -28 -8 -32 -58 -43 -30 -7 -70 -15 -89 -17 -19 -3 -66
|
||||
-11 -105 -20 -38 -8 -88 -17 -110 -20 -39 -6 -55 -9 -107 -21 -13 -3 -34 -7
|
||||
-48 -10 -39 -8 -71 -14 -126 -25 -28 -6 -61 -13 -75 -15 -118 -22 -374 -77
|
||||
-378 -81 -7 -7 3 -13 29 -17 14 -3 57 -13 95 -22 39 -9 79 -18 90 -21 11 -2
|
||||
29 -6 40 -8 11 -2 70 -16 130 -31 121 -29 136 -33 163 -39 10 -2 63 -16 118
|
||||
-30 54 -15 108 -28 119 -30 11 -3 47 -12 80 -21 33 -9 78 -21 100 -26 53 -13
|
||||
62 -23 57 -59 -5 -34 -20 -45 -72 -54 -19 -3 -45 -8 -57 -11 -13 -3 -33 -7
|
||||
-45 -10 -13 -3 -39 -8 -58 -11 -46 -8 -64 -12 -67 -14 -4 -3 -13 -6 -58 -14
|
||||
-22 -5 -87 -19 -145 -33 -58 -14 -115 -27 -127 -29 -12 -2 -34 -9 -48 -14 -14
|
||||
-5 -25 -8 -25 -5 0 2 -15 -1 -32 -6 -18 -6 -42 -12 -53 -14 -68 -14 -155 -38
|
||||
-152 -41 2 -2 33 -6 68 -9 35 -3 75 -8 89 -10 14 -2 48 -7 75 -10 107 -12 141
|
||||
-16 165 -20 51 -9 96 -16 120 -20 52 -7 230 -46 296 -65 64 -19 102 -20 566
|
||||
-20 435 0 498 2 499 15 1 8 2 18 3 23 1 4 6 36 10 72 11 89 13 110 20 145 5
|
||||
30 14 97 21 165 2 19 7 48 10 65 3 16 8 47 10 70 2 22 9 74 14 115 6 41 13 91
|
||||
16 110 9 68 15 116 19 135 2 11 7 49 11 85 4 36 9 74 11 85 2 10 6 37 9 60 3
|
||||
22 8 56 10 75 3 19 7 51 10 70 2 19 6 51 9 70 8 51 27 199 32 240 2 19 6 44 8
|
||||
56 4 21 16 107 21 154 3 26 23 178 30 220 7 47 15 105 20 145 2 22 7 54 9 70
|
||||
3 17 10 66 16 110 6 44 13 96 16 115 3 19 7 51 9 70 6 59 15 124 20 140 2 8 7
|
||||
40 10 70 3 30 8 66 11 80 2 14 6 36 9 49 2 14 7 45 10 70 3 25 7 62 10 81 2
|
||||
19 7 64 10 100 15 184 22 240 29 247 1 2 28 -68 60 -155 31 -86 61 -166 66
|
||||
-177 5 -11 48 -126 96 -255 47 -129 100 -271 116 -315 16 -44 41 -111 55 -150
|
||||
13 -38 29 -79 34 -90 9 -20 58 -151 63 -170 2 -5 8 -23 14 -38 7 -16 12 -33
|
||||
12 -38 0 -5 4 -17 10 -27 5 -9 23 -53 39 -97 16 -44 32 -89 37 -100 4 -11 8
|
||||
-22 8 -25 1 -3 9 -25 19 -50 83 -221 119 -317 121 -325 1 -5 11 -35 23 -65 12
|
||||
-30 54 -143 93 -250 39 -107 75 -204 80 -215 4 -11 18 -47 30 -80 12 -33 25
|
||||
-69 30 -80 24 -63 91 -242 170 -460 10 -27 22 -59 26 -70 4 -11 17 -47 29 -80
|
||||
l22 -60 506 -3 c279 -1 507 1 508 5 1 9 3 22 13 98 15 113 19 141 22 157 3 21
|
||||
15 104 29 208 10 73 15 106 20 130 2 14 7 46 10 72 5 46 12 99 20 148 3 14 10
|
||||
61 16 105 6 44 13 94 15 110 3 17 7 48 9 70 7 53 14 102 21 145 3 19 7 49 9
|
||||
65 2 17 4 30 5 30 1 0 3 11 4 25 10 93 18 155 21 160 2 3 7 33 10 65 4 33 9
|
||||
67 10 77 2 9 6 38 10 65 4 26 8 59 10 73 9 57 18 127 20 150 2 14 4 25 5 25 0
|
||||
0 3 18 5 40 3 21 7 55 10 75 3 19 7 46 10 60 2 14 6 48 10 75 12 92 21 153 28
|
||||
200 3 17 8 53 12 80 7 55 12 90 25 180 5 33 12 83 15 110 3 28 8 57 10 65 2 8
|
||||
7 40 10 70 3 30 10 80 15 110 5 30 12 78 15 105 10 86 13 108 24 175 6 36 13
|
||||
88 16 115 4 28 8 61 11 75 2 14 6 45 10 70 3 25 7 52 9 60 5 17 18 123 19 158
|
||||
1 12 3 22 6 22 3 0 5 10 6 23 0 26 13 122 19 151 3 12 7 41 10 66 3 25 8 59
|
||||
10 75 3 17 7 48 9 70 3 22 7 49 10 61 2 11 7 45 10 75 3 30 8 63 10 74 2 11 7
|
||||
43 10 70 4 28 11 77 16 110 11 75 20 134 25 177 2 18 7 49 10 68 3 19 7 53 10
|
||||
75 6 55 14 115 20 145 2 14 7 48 10 75 4 28 8 57 10 65 5 17 18 125 19 155 1
|
||||
19 -6 20 -109 21 -60 1 -117 2 -126 3 -18 1 -153 266 -210 409 -91 228 -116
|
||||
499 -68 712 6 25 13 56 15 70 3 14 21 78 40 142 31 101 43 157 46 218 5 75
|
||||
-46 252 -84 295 -7 8 -26 32 -43 54 -40 53 -59 61 -50 21 7 -31 8 -102 2 -130
|
||||
-6 -31 -52 -111 -89 -157 -45 -54 -145 -169 -169 -192 -8 -9 -33 -38 -55 -66
|
||||
-21 -27 -45 -57 -53 -65 -39 -40 -128 -198 -136 -239 -2 -9 -4 -17 -5 -18 -2
|
||||
-2 -4 -7 -5 -13 -1 -5 -3 -11 -5 -12 -2 -4 -7 -23 -19 -83 -13 -69 -11 -230 5
|
||||
-290 20 -73 19 -74 -37 -20 -91 89 -175 232 -199 340 -21 94 -24 123 -23 225
|
||||
2 134 7 174 38 290 14 52 27 102 29 110 2 8 20 58 40 110 21 52 39 103 41 112
|
||||
2 9 9 26 15 38 12 22 14 30 29 108 11 54 5 196 -9 221 -5 11 -10 29 -10 40 0
|
||||
12 -4 21 -10 21 -5 0 -9 3 -8 8 2 10 -34 82 -42 82 -3 0 -6 -17 -7 -37 0 -119
|
||||
-46 -217 -147 -323 -132 -137 -337 -212 -511 -186 -165 24 -341 146 -454 314
|
||||
-13 20 -27 39 -31 42 -18 14 -92 185 -109 250 -41 155 -14 328 71 469 21 34
|
||||
38 65 38 68 0 3 38 43 84 89 l84 84 -44 -2 c-24 0 -45 -2 -46 -3z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"start_url": "/",
|
||||
"name": "Nitro",
|
||||
"short_name": "Nitro",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
$toolbar-me-zindex: 90;
|
||||
$chatinput-zindex: 80;
|
||||
$toolbar-zindex: 70;
|
||||
$rightside-zindex: 69;
|
||||
$notification-center-zindex: 68;
|
||||
$toolbar-memenu-zindex: 60;
|
||||
$roomtools-zindex: 50;
|
||||
$context-menu-zindex: 40;
|
||||
$infostand-zindex: 30;
|
||||
$quiz-zindex: 21;
|
||||
$chat-zindex: 20;
|
||||
$highscore-zindex: 19;
|
||||
|
||||
$grid-bg-color: #cdd3d9;
|
||||
$grid-border-color: $muted;
|
||||
$grid-active-bg-color: #ececec;
|
||||
$grid-active-border-color: $white;
|
||||
|
||||
$toolbar-height: 55px;
|
||||
|
||||
$achievement-width: 375px;
|
||||
$achievement-height: 405px;
|
||||
|
||||
$avatar-editor-width: 620px;
|
||||
$avatar-editor-height: 374px;
|
||||
|
||||
$catalog-width: 630px;
|
||||
$catalog-height: 400px;
|
||||
|
||||
$inventory-width: 528px;
|
||||
$inventory-height: 320px;
|
||||
|
||||
$navigator-width: 420px;
|
||||
$navigator-height: 440px;
|
||||
|
||||
$chat-input-style-selector-widget-width: 210px;
|
||||
$chat-input-style-selector-widget-height: 200px;
|
||||
|
||||
$user-profile-width: 470px;
|
||||
$user-profile-height: 460px;
|
||||
|
||||
$nitro-widget-custom-stack-height-width: 275px;
|
||||
$nitro-widget-custom-stack-height-height: 220px;
|
||||
|
||||
$nitro-widget-exchange-credit-width: 375px;
|
||||
$nitro-widget-exchange-credit-height: 150px;
|
||||
|
||||
$nitro-widget-crafting-width: 500px;
|
||||
$nitro-widget-crafting-height: 300px;
|
||||
|
||||
$chat-history-width: 300px;
|
||||
$chat-history-height: 300px;
|
||||
|
||||
$friends-list-width: 250px;
|
||||
$friends-list-height: 300px;
|
||||
|
||||
$help-width: 450px;
|
||||
$help-height: 290px;
|
||||
|
||||
$nitropedia-width: 400px;
|
||||
$nitropedia-height: 400px;
|
||||
|
||||
$messenger-width: 500px;
|
||||
$messenger-height: 370px;
|
||||
|
||||
$marketplace-post-offer-width: 430px;
|
||||
$marketplace-post-offer-height: 250px;
|
||||
|
||||
$camera-editor-width: 600px;
|
||||
$camera-editor-height: 500px;
|
||||
|
||||
$camera-checkout-width: 350px;
|
||||
|
||||
$room-info-width: 325px;
|
||||
|
||||
$nitro-group-creator-width: 383px;
|
||||
$nitro-mod-tools-width: 175px;
|
||||
|
||||
$nitro-group-manager-width: 390px;
|
||||
$nitro-group-manager-height: 355px;
|
||||
|
||||
$nitro-chooser-width: 200px;
|
||||
$nitro-chooser-height: 200px;
|
||||
|
||||
$nitro-doorbell-width: 300px;
|
||||
$nitro-doorbell-height: 200px;
|
||||
|
||||
$nitro-guide-tool-width: 250px;
|
||||
|
||||
$nitro-floor-editor-width: 760px;
|
||||
$nitro-floor-editor-height: 500px;
|
||||
|
||||
$nitro-calendar-width: 850px;
|
||||
$nitro-calendar-height: 400px;
|
||||
|
||||
.nitro-app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@import './common';
|
||||
@import './components';
|
|
@ -0,0 +1,141 @@
|
|||
import { ConfigurationEvent, GetAssetManager, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroConfiguration, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api';
|
||||
import { Base, TransitionAnimation, TransitionAnimationTypes } from './common';
|
||||
import { LoadingView } from './components/loading/LoadingView';
|
||||
import { MainView } from './components/main/MainView';
|
||||
import { useConfigurationEvent, useLocalizationEvent, useMainEvent, useRoomEngineEvent } from './hooks';
|
||||
|
||||
NitroVersion.UI_VERSION = GetUIVersion();
|
||||
|
||||
export const App: FC<{}> = props =>
|
||||
{
|
||||
const [ isReady, setIsReady ] = useState(false);
|
||||
const [ isError, setIsError ] = useState(false);
|
||||
const [ message, setMessage ] = useState('Getting Ready');
|
||||
const [ percent, setPercent ] = useState(0);
|
||||
const [ imageRendering, setImageRendering ] = useState<boolean>(true);
|
||||
|
||||
if(!GetNitroInstance())
|
||||
{
|
||||
//@ts-ignore
|
||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||
|
||||
Nitro.bootstrap();
|
||||
}
|
||||
|
||||
const handler = useCallback(async (event: NitroEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case ConfigurationEvent.LOADED:
|
||||
GetNitroInstance().localization.init();
|
||||
setPercent(prevValue => (prevValue + 20));
|
||||
return;
|
||||
case ConfigurationEvent.FAILED:
|
||||
setIsError(true);
|
||||
setMessage('Configuration Failed');
|
||||
return;
|
||||
case Nitro.WEBGL_UNAVAILABLE:
|
||||
setIsError(true);
|
||||
setMessage('WebGL Required');
|
||||
return;
|
||||
case Nitro.WEBGL_CONTEXT_LOST:
|
||||
setIsError(true);
|
||||
setMessage('WebGL Context Lost - Reloading');
|
||||
|
||||
setTimeout(() => window.location.reload(), 1500);
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING:
|
||||
setPercent(prevValue => (prevValue + 20));
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED:
|
||||
setIsError(true);
|
||||
setMessage('Handshake Failed');
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED:
|
||||
setPercent(prevValue => (prevValue + 20));
|
||||
|
||||
GetNitroInstance().init();
|
||||
|
||||
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'authentication', 'authok', []);
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_ERROR:
|
||||
setIsError(true);
|
||||
setMessage('Connection Error');
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_CLOSED:
|
||||
//if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose();
|
||||
//setIsError(true);
|
||||
setMessage('Connection Error');
|
||||
|
||||
HabboWebTools.send(-1, 'client.init.handshake.fail');
|
||||
return;
|
||||
case RoomEngineEvent.ENGINE_INITIALIZED:
|
||||
setPercent(prevValue => (prevValue + 20));
|
||||
|
||||
setTimeout(() => setIsReady(true), 300);
|
||||
return;
|
||||
case NitroLocalizationEvent.LOADED: {
|
||||
const assetUrls = GetConfiguration<string[]>('preload.assets.urls');
|
||||
const urls: string[] = [];
|
||||
|
||||
if(assetUrls && assetUrls.length) for(const url of assetUrls) urls.push(NitroConfiguration.interpolate(url));
|
||||
|
||||
const status = await GetAssetManager().downloadAssets(urls);
|
||||
|
||||
if(status)
|
||||
{
|
||||
GetCommunication().init();
|
||||
|
||||
setPercent(prevValue => (prevValue + 20))
|
||||
}
|
||||
else
|
||||
{
|
||||
setIsError(true);
|
||||
setMessage('Assets Failed');
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
useMainEvent(Nitro.WEBGL_UNAVAILABLE, handler);
|
||||
useMainEvent(Nitro.WEBGL_CONTEXT_LOST, handler);
|
||||
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING, handler);
|
||||
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED, handler);
|
||||
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, handler);
|
||||
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_ERROR, handler);
|
||||
useMainEvent(NitroCommunicationDemoEvent.CONNECTION_CLOSED, handler);
|
||||
useRoomEngineEvent(RoomEngineEvent.ENGINE_INITIALIZED, handler);
|
||||
useLocalizationEvent(NitroLocalizationEvent.LOADED, handler);
|
||||
useConfigurationEvent(ConfigurationEvent.LOADED, handler);
|
||||
useConfigurationEvent(ConfigurationEvent.FAILED, handler);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
GetNitroInstance().core.configuration.init();
|
||||
|
||||
const resize = (event: UIEvent) => setImageRendering(!(window.devicePixelRatio % 1));
|
||||
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
resize(null);
|
||||
|
||||
return () =>
|
||||
{
|
||||
window.removeEventListener('resize', resize);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Base fit overflow="hidden" className={ imageRendering && 'image-rendering-pixelated' }>
|
||||
{ (!isReady || isError) &&
|
||||
<LoadingView isError={ isError } message={ message } percent={ percent } /> }
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady) }>
|
||||
<MainView />
|
||||
</TransitionAnimation>
|
||||
<Base id="draggable-windows-container" />
|
||||
</Base>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import { NitroVersion } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const GetRendererVersion = () => NitroVersion.RENDERER_VERSION;
|
|
@ -0,0 +1 @@
|
|||
export const GetUIVersion = () => '2.1.1';
|
|
@ -0,0 +1,40 @@
|
|||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
import { AchievementUtilities } from './AchievementUtilities';
|
||||
import { IAchievementCategory } from './IAchievementCategory';
|
||||
|
||||
export class AchievementCategory implements IAchievementCategory
|
||||
{
|
||||
private _code: string;
|
||||
private _achievements: AchievementData[];
|
||||
|
||||
constructor(code: string)
|
||||
{
|
||||
this._code = code;
|
||||
this._achievements = [];
|
||||
}
|
||||
|
||||
public getProgress(): number
|
||||
{
|
||||
return AchievementUtilities.getAchievementCategoryProgress(this);
|
||||
}
|
||||
|
||||
public getMaxProgress(): number
|
||||
{
|
||||
return AchievementUtilities.getAchievementCategoryMaxProgress(this);
|
||||
}
|
||||
|
||||
public get code(): string
|
||||
{
|
||||
return this._code;
|
||||
}
|
||||
|
||||
public get achievements(): AchievementData[]
|
||||
{
|
||||
return this._achievements;
|
||||
}
|
||||
|
||||
public set achievements(achievements: AchievementData[])
|
||||
{
|
||||
this._achievements = achievements;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration, GetLocalization } from '../nitro';
|
||||
import { IAchievementCategory } from './IAchievementCategory';
|
||||
|
||||
export class AchievementUtilities
|
||||
{
|
||||
public static getAchievementBadgeCode(achievement: AchievementData): string
|
||||
{
|
||||
if(!achievement) return null;
|
||||
|
||||
let badgeId = achievement.badgeId;
|
||||
|
||||
if(!achievement.finalLevel) badgeId = GetLocalization().getPreviousLevelBadgeId(badgeId);
|
||||
|
||||
return badgeId;
|
||||
}
|
||||
|
||||
public static getAchievementCategoryImageUrl(category: IAchievementCategory, progress: number = null, icon: boolean = false): string
|
||||
{
|
||||
const imageUrl = GetConfiguration<string>('achievements.images.url');
|
||||
|
||||
let imageName = icon ? 'achicon_' : 'achcategory_';
|
||||
|
||||
imageName += category.code;
|
||||
|
||||
if(progress !== null) imageName += `_${ ((progress > 0) ? 'active' : 'inactive') }`;
|
||||
|
||||
return imageUrl.replace('%image%', imageName);
|
||||
}
|
||||
|
||||
public static getAchievementCategoryMaxProgress(category: IAchievementCategory): number
|
||||
{
|
||||
if(!category) return 0;
|
||||
|
||||
let progress = 0;
|
||||
|
||||
for(const achievement of category.achievements)
|
||||
{
|
||||
progress += achievement.levelCount;
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
public static getAchievementCategoryProgress(category: IAchievementCategory): number
|
||||
{
|
||||
if(!category) return 0;
|
||||
|
||||
let progress = 0;
|
||||
|
||||
for(const achievement of category.achievements) progress += (achievement.finalLevel ? achievement.level : (achievement.level - 1));
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
public static getAchievementCategoryTotalUnseen(category: IAchievementCategory): number
|
||||
{
|
||||
if(!category) return 0;
|
||||
|
||||
let unseen = 0;
|
||||
|
||||
for(const achievement of category.achievements) ((achievement.unseen > 0) && unseen++);
|
||||
|
||||
return unseen;
|
||||
}
|
||||
|
||||
public static getAchievementHasStarted(achievement: AchievementData): boolean
|
||||
{
|
||||
if(!achievement) return false;
|
||||
|
||||
if(achievement.finalLevel || ((achievement.level - 1) > 0)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static getAchievementIsIgnored(achievement: AchievementData): boolean
|
||||
{
|
||||
if(!achievement) return false;
|
||||
|
||||
const ignored = GetConfiguration<string[]>('achievements.unseen.ignored');
|
||||
const value = achievement.badgeId.replace(/[0-9]/g, '');
|
||||
const index = ignored.indexOf(value);
|
||||
|
||||
if(index >= 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static getAchievementLevel(achievement: AchievementData): number
|
||||
{
|
||||
if(!achievement) return 0;
|
||||
|
||||
if(achievement.finalLevel) return achievement.level;
|
||||
|
||||
return (achievement.level - 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface IAchievementCategory
|
||||
{
|
||||
code: string;
|
||||
achievements: AchievementData[];
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './AchievementCategory';
|
||||
export * from './AchievementUtilities';
|
||||
export * from './IAchievementCategory';
|
|
@ -0,0 +1,7 @@
|
|||
export class AvatarEditorAction
|
||||
{
|
||||
public static ACTION_SAVE: string = 'AEA_ACTION_SAVE';
|
||||
public static ACTION_CLEAR: string = 'AEA_ACTION_CLEAR';
|
||||
public static ACTION_RESET: string = 'AEA_ACTION_RESET';
|
||||
public static ACTION_RANDOMIZE: string = 'AEA_ACTION_RANDOMIZE';
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import { ColorConverter, IPartColor } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class AvatarEditorGridColorItem
|
||||
{
|
||||
private _partColor: IPartColor;
|
||||
private _isDisabled: boolean;
|
||||
private _isHC: boolean;
|
||||
private _isSelected: boolean;
|
||||
private _notifier: () => void;
|
||||
|
||||
constructor(partColor: IPartColor, isDisabled: boolean = false)
|
||||
{
|
||||
this._partColor = partColor;
|
||||
this._isDisabled = isDisabled;
|
||||
this._isHC = (this._partColor.clubLevel > 0);
|
||||
this._isSelected = false;
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
this._partColor = null;
|
||||
}
|
||||
|
||||
public get partColor(): IPartColor
|
||||
{
|
||||
return this._partColor;
|
||||
}
|
||||
|
||||
public get color(): string
|
||||
{
|
||||
return ColorConverter.int2rgb(this._partColor.rgb);
|
||||
}
|
||||
|
||||
public get isDisabled(): boolean
|
||||
{
|
||||
return this._isDisabled;
|
||||
}
|
||||
|
||||
public get isHC(): boolean
|
||||
{
|
||||
return this._isHC;
|
||||
}
|
||||
|
||||
public get isSelected(): boolean
|
||||
{
|
||||
return this._isSelected;
|
||||
}
|
||||
|
||||
public set isSelected(flag: boolean)
|
||||
{
|
||||
this._isSelected = flag;
|
||||
|
||||
if(this.notify) this.notify();
|
||||
}
|
||||
|
||||
public get notify(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notify(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
import { AvatarFigurePartType, IAvatarImageListener, IAvatarRenderManager, IFigurePart, IFigurePartSet, IGraphicAsset, IPartColor, NitroAlphaFilter, NitroContainer, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class AvatarEditorGridPartItem implements IAvatarImageListener
|
||||
{
|
||||
private static ALPHA_FILTER: NitroAlphaFilter = new NitroAlphaFilter(0.2);
|
||||
private static THUMB_DIRECTIONS: number[] = [ 2, 6, 0, 4, 3, 1 ];
|
||||
private static DRAW_ORDER: string[] = [
|
||||
AvatarFigurePartType.LEFT_HAND_ITEM,
|
||||
AvatarFigurePartType.LEFT_HAND,
|
||||
AvatarFigurePartType.LEFT_SLEEVE,
|
||||
AvatarFigurePartType.LEFT_COAT_SLEEVE,
|
||||
AvatarFigurePartType.BODY,
|
||||
AvatarFigurePartType.SHOES,
|
||||
AvatarFigurePartType.LEGS,
|
||||
AvatarFigurePartType.CHEST,
|
||||
AvatarFigurePartType.CHEST_ACCESSORY,
|
||||
AvatarFigurePartType.COAT_CHEST,
|
||||
AvatarFigurePartType.CHEST_PRINT,
|
||||
AvatarFigurePartType.WAIST_ACCESSORY,
|
||||
AvatarFigurePartType.RIGHT_HAND,
|
||||
AvatarFigurePartType.RIGHT_SLEEVE,
|
||||
AvatarFigurePartType.RIGHT_COAT_SLEEVE,
|
||||
AvatarFigurePartType.HEAD,
|
||||
AvatarFigurePartType.FACE,
|
||||
AvatarFigurePartType.EYES,
|
||||
AvatarFigurePartType.HAIR,
|
||||
AvatarFigurePartType.HAIR_BIG,
|
||||
AvatarFigurePartType.FACE_ACCESSORY,
|
||||
AvatarFigurePartType.EYE_ACCESSORY,
|
||||
AvatarFigurePartType.HEAD_ACCESSORY,
|
||||
AvatarFigurePartType.HEAD_ACCESSORY_EXTRA,
|
||||
AvatarFigurePartType.RIGHT_HAND_ITEM,
|
||||
];
|
||||
|
||||
private _renderManager: IAvatarRenderManager;
|
||||
private _partSet: IFigurePartSet;
|
||||
private _partColors: IPartColor[];
|
||||
private _useColors: boolean;
|
||||
private _isDisabled: boolean;
|
||||
private _thumbContainer: NitroContainer;
|
||||
private _imageUrl: string;
|
||||
private _maxColorIndex: number;
|
||||
private _isValidFigure: boolean;
|
||||
private _isHC: boolean;
|
||||
private _isSellable: boolean;
|
||||
private _isClear: boolean;
|
||||
private _isSelected: boolean;
|
||||
private _disposed: boolean;
|
||||
private _isInitalized: boolean;
|
||||
private _notifier: () => void;
|
||||
|
||||
constructor(partSet: IFigurePartSet, partColors: IPartColor[], useColors: boolean = true, isDisabled: boolean = false)
|
||||
{
|
||||
this._renderManager = GetAvatarRenderManager();
|
||||
this._partSet = partSet;
|
||||
this._partColors = partColors;
|
||||
this._useColors = useColors;
|
||||
this._isDisabled = isDisabled;
|
||||
this._thumbContainer = null;
|
||||
this._imageUrl = null;
|
||||
this._maxColorIndex = 0;
|
||||
this._isValidFigure = false;
|
||||
this._isHC = false;
|
||||
this._isSellable = false;
|
||||
this._isClear = false;
|
||||
this._isSelected = false;
|
||||
this._disposed = false;
|
||||
this._isInitalized = false;
|
||||
|
||||
if(partSet)
|
||||
{
|
||||
const colors = partSet.parts;
|
||||
|
||||
for(const color of colors) this._maxColorIndex = Math.max(this._maxColorIndex, color.colorLayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public init(): void
|
||||
{
|
||||
if(this._isInitalized) return;
|
||||
|
||||
this._isInitalized = true;
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
if(this._disposed) return;
|
||||
|
||||
this._renderManager = null;
|
||||
this._partSet = null;
|
||||
this._partColors = null;
|
||||
this._imageUrl = null;
|
||||
this._disposed = true;
|
||||
this._isInitalized = false;
|
||||
|
||||
if(this._thumbContainer)
|
||||
{
|
||||
this._thumbContainer.destroy();
|
||||
|
||||
this._thumbContainer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public update(): void
|
||||
{
|
||||
this.updateThumbVisualization();
|
||||
}
|
||||
|
||||
private analyzeFigure(): boolean
|
||||
{
|
||||
if(!this._renderManager || !this._partSet || !this._partSet.parts || !this._partSet.parts.length) return false;
|
||||
|
||||
const figureContainer = this._renderManager.createFigureContainer(((this.partSet.type + '-') + this.partSet.id));
|
||||
|
||||
if(!this._renderManager.isFigureContainerReady(figureContainer))
|
||||
{
|
||||
this._renderManager.downloadAvatarFigure(figureContainer, this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this._isValidFigure = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private renderThumb(): NitroContainer
|
||||
{
|
||||
if(!this._renderManager || !this._partSet) return null;
|
||||
|
||||
if(!this._isValidFigure)
|
||||
{
|
||||
if(!this.analyzeFigure()) return null;
|
||||
}
|
||||
|
||||
const parts = this._partSet.parts.concat().sort(this.sortByDrawOrder);
|
||||
const container = new NitroContainer();
|
||||
|
||||
for(const part of parts)
|
||||
{
|
||||
if(!part) continue;
|
||||
|
||||
let asset: IGraphicAsset = null;
|
||||
let direction = 0;
|
||||
let hasAsset = false;
|
||||
|
||||
while(!hasAsset && (direction < AvatarEditorGridPartItem.THUMB_DIRECTIONS.length))
|
||||
{
|
||||
const assetName = ((((((((((FigureData.SCALE + '_') + FigureData.STD) + '_') + part.type) + '_') + part.id) + '_') + AvatarEditorGridPartItem.THUMB_DIRECTIONS[direction]) + '_') + FigureData.DEFAULT_FRAME);
|
||||
|
||||
asset = this._renderManager.getAssetByName(assetName);
|
||||
|
||||
if(asset && asset.texture)
|
||||
{
|
||||
hasAsset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
direction++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!hasAsset) continue;
|
||||
|
||||
const x = asset.offsetX;
|
||||
const y = asset.offsetY;
|
||||
let partColor: IPartColor = null;
|
||||
|
||||
if(this._useColors && (part.colorLayerIndex > 0))
|
||||
{
|
||||
const color = this._partColors[(part.colorLayerIndex - 1)];
|
||||
|
||||
if(color) partColor = color;
|
||||
}
|
||||
|
||||
const sprite = new NitroSprite(asset.texture);
|
||||
|
||||
sprite.position.set(x, y);
|
||||
|
||||
if(partColor) sprite.tint = partColor.rgb;
|
||||
|
||||
container.addChild(sprite);
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private updateThumbVisualization(): void
|
||||
{
|
||||
if(!this._isInitalized) return;
|
||||
|
||||
let container = this._thumbContainer;
|
||||
|
||||
if(!container) container = this.renderThumb();
|
||||
|
||||
if(!container) return;
|
||||
|
||||
if(this._partSet)
|
||||
{
|
||||
this._isHC = (this._partSet.clubLevel > 0);
|
||||
this._isSellable = this._partSet.isSellable;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._isHC = false;
|
||||
this._isSellable = false;
|
||||
}
|
||||
|
||||
if(this._isDisabled) this.setAlpha(container, 0.2);
|
||||
|
||||
this._imageUrl = TextureUtils.generateImageUrl(container);
|
||||
|
||||
if(this.notify) this.notify();
|
||||
}
|
||||
|
||||
private setAlpha(container: NitroContainer, alpha: number): NitroContainer
|
||||
{
|
||||
container.filters = [ AvatarEditorGridPartItem.ALPHA_FILTER ];
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private sortByDrawOrder(a: IFigurePart, b: IFigurePart): number
|
||||
{
|
||||
const indexA = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(a.type);
|
||||
const indexB = AvatarEditorGridPartItem.DRAW_ORDER.indexOf(b.type);
|
||||
|
||||
if(indexA < indexB) return -1;
|
||||
|
||||
if(indexA > indexB) return 1;
|
||||
|
||||
if(a.index < b.index) return -1;
|
||||
|
||||
if(a.index > b.index) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public resetFigure(figure: string): void
|
||||
{
|
||||
if(!this.analyzeFigure()) return;
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
public get disposed(): boolean
|
||||
{
|
||||
return this._disposed;
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
if(!this._partSet) return -1;
|
||||
|
||||
return this._partSet.id;
|
||||
}
|
||||
|
||||
public get partSet(): IFigurePartSet
|
||||
{
|
||||
return this._partSet;
|
||||
}
|
||||
|
||||
public set partColors(partColors: IPartColor[])
|
||||
{
|
||||
this._partColors = partColors;
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
public get isDisabled(): boolean
|
||||
{
|
||||
return this._isDisabled;
|
||||
}
|
||||
|
||||
public set thumbContainer(container: NitroContainer)
|
||||
{
|
||||
this._thumbContainer = container;
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
public get imageUrl(): string
|
||||
{
|
||||
return this._imageUrl;
|
||||
}
|
||||
|
||||
public get maxColorIndex(): number
|
||||
{
|
||||
return this._maxColorIndex;
|
||||
}
|
||||
|
||||
public get isHC(): boolean
|
||||
{
|
||||
return this._isHC;
|
||||
}
|
||||
|
||||
public get isSellable(): boolean
|
||||
{
|
||||
return this._isSellable;
|
||||
}
|
||||
|
||||
public get isClear(): boolean
|
||||
{
|
||||
return this._isClear;
|
||||
}
|
||||
|
||||
public set isClear(flag: boolean)
|
||||
{
|
||||
this._isClear = flag;
|
||||
}
|
||||
|
||||
public get isSelected(): boolean
|
||||
{
|
||||
return this._isSelected;
|
||||
}
|
||||
|
||||
public set isSelected(flag: boolean)
|
||||
{
|
||||
this._isSelected = flag;
|
||||
|
||||
if(this.notify) this.notify();
|
||||
}
|
||||
|
||||
public get notify(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notify(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
import { IPartColor } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarPalette, GetAvatarRenderManager, GetAvatarSetType, GetClubMemberLevel, GetConfiguration } from '../nitro';
|
||||
import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem';
|
||||
import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { CategoryData } from './CategoryData';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class AvatarEditorUtilities
|
||||
{
|
||||
private static MAX_PALETTES: number = 2;
|
||||
|
||||
public static CURRENT_FIGURE: FigureData = null;
|
||||
public static FIGURE_SET_IDS: number[] = [];
|
||||
public static BOUND_FURNITURE_NAMES: string[] = [];
|
||||
|
||||
public static getGender(gender: string): string
|
||||
{
|
||||
switch(gender)
|
||||
{
|
||||
case FigureData.MALE:
|
||||
case 'm':
|
||||
case 'M':
|
||||
gender = FigureData.MALE;
|
||||
break;
|
||||
case FigureData.FEMALE:
|
||||
case 'f':
|
||||
case 'F':
|
||||
gender = FigureData.FEMALE;
|
||||
break;
|
||||
default:
|
||||
gender = FigureData.MALE;
|
||||
}
|
||||
|
||||
return gender;
|
||||
}
|
||||
|
||||
public static hasFigureSetId(setId: number): boolean
|
||||
{
|
||||
return (this.FIGURE_SET_IDS.indexOf(setId) >= 0);
|
||||
}
|
||||
|
||||
public static createCategory(model: CategoryBaseModel, name: string): CategoryData
|
||||
{
|
||||
if(!model || !name || !this.CURRENT_FIGURE) return null;
|
||||
|
||||
const partItems: AvatarEditorGridPartItem[] = [];
|
||||
const colorItems: AvatarEditorGridColorItem[][] = [];
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this.MAX_PALETTES)
|
||||
{
|
||||
colorItems.push([]);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
const setType = GetAvatarSetType(name);
|
||||
|
||||
if(!setType) return null;
|
||||
|
||||
const palette = GetAvatarPalette(setType.paletteID);
|
||||
|
||||
if(!palette) return null;
|
||||
|
||||
let colorIds = this.CURRENT_FIGURE.getColorIds(name);
|
||||
|
||||
if(!colorIds) colorIds = [];
|
||||
|
||||
const partColors: IPartColor[] = new Array(colorIds.length);
|
||||
const clubItemsDimmed = this.clubItemsDimmed;
|
||||
const clubMemberLevel = GetClubMemberLevel();
|
||||
|
||||
for(const partColor of palette.colors.getValues())
|
||||
{
|
||||
if(partColor.isSelectable && (clubItemsDimmed || (clubMemberLevel >= partColor.clubLevel)))
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < this.MAX_PALETTES)
|
||||
{
|
||||
const isDisabled = (clubMemberLevel < partColor.clubLevel);
|
||||
const colorItem = new AvatarEditorGridColorItem(partColor, isDisabled);
|
||||
|
||||
colorItems[i].push(colorItem);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(name !== FigureData.FACE)
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < colorIds.length)
|
||||
{
|
||||
if(partColor.id === colorIds[i]) partColors[i] = partColor;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mandatorySetIds: string[] = [];
|
||||
|
||||
if(clubItemsDimmed)
|
||||
{
|
||||
mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
mandatorySetIds = GetAvatarRenderManager().getMandatoryAvatarPartSetIds(this.CURRENT_FIGURE.gender, clubMemberLevel);
|
||||
}
|
||||
|
||||
const isntMandatorySet = (mandatorySetIds.indexOf(name) === -1);
|
||||
|
||||
if(isntMandatorySet)
|
||||
{
|
||||
const partItem = new AvatarEditorGridPartItem(null, null, false);
|
||||
|
||||
partItem.isClear = true;
|
||||
|
||||
partItems.push(partItem);
|
||||
}
|
||||
|
||||
const usesColors = (name !== FigureData.FACE);
|
||||
const partSets = setType.partSets;
|
||||
const totalPartSets = partSets.length;
|
||||
|
||||
i = (totalPartSets - 1);
|
||||
|
||||
while(i >= 0)
|
||||
{
|
||||
const partSet = partSets.getWithIndex(i);
|
||||
|
||||
let isValidGender = false;
|
||||
|
||||
if(partSet.gender === FigureData.UNISEX)
|
||||
{
|
||||
isValidGender = true;
|
||||
}
|
||||
|
||||
else if(partSet.gender === this.CURRENT_FIGURE.gender)
|
||||
{
|
||||
isValidGender = true;
|
||||
}
|
||||
|
||||
if(partSet.isSelectable && isValidGender && (clubItemsDimmed || (clubMemberLevel >= partSet.clubLevel)))
|
||||
{
|
||||
const isDisabled = (clubMemberLevel < partSet.clubLevel);
|
||||
|
||||
let isValid = true;
|
||||
|
||||
if(partSet.isSellable) isValid = this.hasFigureSetId(partSet.id);
|
||||
|
||||
if(isValid) partItems.push(new AvatarEditorGridPartItem(partSet, partColors, usesColors, isDisabled));
|
||||
}
|
||||
|
||||
i--;
|
||||
}
|
||||
|
||||
partItems.sort(this.clubItemsFirst ? this.clubSorter : this.noobSorter);
|
||||
|
||||
// if(this._forceSellableClothingVisibility || GetNitroInstance().getConfiguration<boolean>("avatareditor.support.sellablefurni", false))
|
||||
// {
|
||||
// _local_31 = (this._manager.windowManager.assets.getAssetByName("camera_zoom_in") as BitmapDataAsset);
|
||||
// _local_32 = (_local_31.content as BitmapData).clone();
|
||||
// _local_33 = (AvatarEditorView._Str_6802.clone() as IWindowContainer);
|
||||
// _local_33.name = AvatarEditorGridView.GET_MORE;
|
||||
// _local_7 = new AvatarEditorGridPartItem(_local_33, k, null, null, false);
|
||||
// _local_7._Str_3093 = _local_32;
|
||||
// _local_3.push(_local_7);
|
||||
// }
|
||||
|
||||
i = 0;
|
||||
|
||||
while(i < this.MAX_PALETTES)
|
||||
{
|
||||
colorItems[i].sort(this.colorSorter);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return new CategoryData(name, partItems, colorItems);
|
||||
}
|
||||
|
||||
public static clubSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number
|
||||
{
|
||||
const clubLevelA = (!a.partSet ? 9999999999 : a.partSet.clubLevel);
|
||||
const clubLevelB = (!b.partSet ? 9999999999 : b.partSet.clubLevel);
|
||||
const isSellableA = (!a.partSet ? false : a.partSet.isSellable);
|
||||
const isSellableB = (!b.partSet ? false : b.partSet.isSellable);
|
||||
|
||||
if(isSellableA && !isSellableB) return 1;
|
||||
|
||||
if(isSellableB && !isSellableA) return -1;
|
||||
|
||||
if(clubLevelA > clubLevelB) return -1;
|
||||
|
||||
if(clubLevelA < clubLevelB) return 1;
|
||||
|
||||
if(a.partSet.id > b.partSet.id) return -1;
|
||||
|
||||
if(a.partSet.id < b.partSet.id) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static colorSorter(a: AvatarEditorGridColorItem, b: AvatarEditorGridColorItem): number
|
||||
{
|
||||
const clubLevelA = (!a.partColor ? -1 : a.partColor.clubLevel);
|
||||
const clubLevelB = (!b.partColor ? -1 : b.partColor.clubLevel);
|
||||
|
||||
if(clubLevelA < clubLevelB) return -1;
|
||||
|
||||
if(clubLevelA > clubLevelB) return 1;
|
||||
|
||||
if(a.partColor.index < b.partColor.index) return -1;
|
||||
|
||||
if(a.partColor.index > b.partColor.index) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static noobSorter(a: AvatarEditorGridPartItem, b: AvatarEditorGridPartItem): number
|
||||
{
|
||||
const clubLevelA = (!a.partSet ? -1 : a.partSet.clubLevel);
|
||||
const clubLevelB = (!b.partSet ? -1 : b.partSet.clubLevel);
|
||||
const isSellableA = (!a.partSet ? false : a.partSet.isSellable);
|
||||
const isSellableB = (!b.partSet ? false : b.partSet.isSellable);
|
||||
|
||||
if(isSellableA && !isSellableB) return 1;
|
||||
|
||||
if(isSellableB && !isSellableA) return -1;
|
||||
|
||||
if(clubLevelA < clubLevelB) return -1;
|
||||
|
||||
if(clubLevelA > clubLevelB) return 1;
|
||||
|
||||
if(a.partSet.id < b.partSet.id) return -1;
|
||||
|
||||
if(a.partSet.id > b.partSet.id) return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static avatarSetFirstSelectableColor(name: string): number
|
||||
{
|
||||
const setType = GetAvatarSetType(name);
|
||||
|
||||
if(!setType) return -1;
|
||||
|
||||
const palette = GetAvatarPalette(setType.paletteID);
|
||||
|
||||
if(!palette) return -1;
|
||||
|
||||
for(const color of palette.colors.getValues())
|
||||
{
|
||||
if(!color.isSelectable || (GetClubMemberLevel() < color.clubLevel)) continue;
|
||||
|
||||
return color.id;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static get clubItemsFirst(): boolean
|
||||
{
|
||||
return GetConfiguration<boolean>('avatareditor.show.clubitems.first', true);
|
||||
}
|
||||
|
||||
public static get clubItemsDimmed(): boolean
|
||||
{
|
||||
return GetConfiguration<boolean>('avatareditor.show.clubitems.dimmed', true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import { AvatarEditorFigureCategory, AvatarScaleType, AvatarSetType } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class BodyModel extends CategoryBaseModel
|
||||
{
|
||||
private _imageCallBackHandled: boolean = false;
|
||||
|
||||
public init(): void
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.addCategory(FigureData.FACE);
|
||||
|
||||
this._isInitalized = true;
|
||||
}
|
||||
|
||||
public selectColor(category: string, colorIndex: number, paletteId: number): void
|
||||
{
|
||||
super.selectColor(category, colorIndex, paletteId);
|
||||
|
||||
this.updateSelectionsFromFigure(FigureData.FACE);
|
||||
}
|
||||
|
||||
protected updateSelectionsFromFigure(name: string): void
|
||||
{
|
||||
if(!this._categories || !AvatarEditorUtilities.CURRENT_FIGURE) return;
|
||||
|
||||
const category = this._categories.get(name);
|
||||
|
||||
if(!category) return;
|
||||
|
||||
const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(name);
|
||||
|
||||
let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(name);
|
||||
|
||||
if(!colorIds) colorIds = [];
|
||||
|
||||
category.selectPartId(setId);
|
||||
category.selectColorIds(colorIds);
|
||||
|
||||
for(const part of category.parts)
|
||||
{
|
||||
const resetFigure = (figure: string) =>
|
||||
{
|
||||
const figureString = AvatarEditorUtilities.CURRENT_FIGURE.getFigureStringWithFace(part.id);
|
||||
const avatarImage = GetAvatarRenderManager().createAvatarImage(figureString, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false });
|
||||
|
||||
const sprite = avatarImage.getImageAsSprite(AvatarSetType.HEAD);
|
||||
|
||||
if(sprite)
|
||||
{
|
||||
sprite.y = 10;
|
||||
|
||||
part.thumbContainer = sprite;
|
||||
|
||||
setTimeout(() => avatarImage.dispose(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
resetFigure(null);
|
||||
}
|
||||
}
|
||||
|
||||
public get canSetGender(): boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return AvatarEditorFigureCategory.GENERIC;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
|
||||
import { CategoryData } from './CategoryData';
|
||||
import { IAvatarEditorCategoryModel } from './IAvatarEditorCategoryModel';
|
||||
|
||||
export class CategoryBaseModel implements IAvatarEditorCategoryModel
|
||||
{
|
||||
protected _categories: Map<string, CategoryData>;
|
||||
protected _isInitalized: boolean;
|
||||
protected _maxPaletteCount: number;
|
||||
private _disposed: boolean;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this._isInitalized = false;
|
||||
this._maxPaletteCount = 0;
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
this._categories = null;
|
||||
this._disposed = true;
|
||||
}
|
||||
|
||||
public get disposed(): boolean
|
||||
{
|
||||
return this._disposed;
|
||||
}
|
||||
|
||||
public init(): void
|
||||
{
|
||||
if(!this._categories) this._categories = new Map();
|
||||
}
|
||||
|
||||
public reset(): void
|
||||
{
|
||||
this._isInitalized = false;
|
||||
|
||||
if(this._categories)
|
||||
{
|
||||
for(const category of this._categories.values()) (category && category.dispose());
|
||||
}
|
||||
|
||||
this._categories = new Map();
|
||||
}
|
||||
|
||||
protected addCategory(name: string): void
|
||||
{
|
||||
let existing = this._categories.get(name);
|
||||
|
||||
if(existing) return;
|
||||
|
||||
existing = AvatarEditorUtilities.createCategory(this, name);
|
||||
|
||||
if(!existing) return;
|
||||
|
||||
this._categories.set(name, existing);
|
||||
|
||||
this.updateSelectionsFromFigure(name);
|
||||
}
|
||||
|
||||
protected updateSelectionsFromFigure(figure: string): void
|
||||
{
|
||||
const category = this._categories.get(figure);
|
||||
|
||||
if(!category) return;
|
||||
|
||||
const setId = AvatarEditorUtilities.CURRENT_FIGURE.getPartSetId(figure);
|
||||
|
||||
let colorIds = AvatarEditorUtilities.CURRENT_FIGURE.getColorIds(figure);
|
||||
|
||||
if(!colorIds) colorIds = [];
|
||||
|
||||
category.selectPartId(setId);
|
||||
category.selectColorIds(colorIds);
|
||||
}
|
||||
|
||||
public hasClubSelectionsOverLevel(level: number): boolean
|
||||
{
|
||||
if(!this._categories) return false;
|
||||
|
||||
for(const category of this._categories.values())
|
||||
{
|
||||
if(!category) continue;
|
||||
|
||||
if(category.hasClubSelectionsOverLevel(level)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public hasInvalidSelectedItems(ownedItems: number[]): boolean
|
||||
{
|
||||
if(!this._categories) return false;
|
||||
|
||||
for(const category of this._categories.values())
|
||||
{
|
||||
if(category.hasInvalidSelectedItems(ownedItems)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public stripClubItemsOverLevel(level: number): boolean
|
||||
{
|
||||
if(!this._categories) return false;
|
||||
|
||||
let didStrip = false;
|
||||
|
||||
for(const [ name, category ] of this._categories.entries())
|
||||
{
|
||||
let isValid = false;
|
||||
|
||||
if(category.stripClubItemsOverLevel(level)) isValid = true;
|
||||
|
||||
if(category.stripClubColorsOverLevel(level)) isValid = true;
|
||||
|
||||
if(isValid)
|
||||
{
|
||||
const partItem = category.getCurrentPart();
|
||||
|
||||
if(partItem && AvatarEditorUtilities.CURRENT_FIGURE)
|
||||
{
|
||||
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true);
|
||||
}
|
||||
|
||||
didStrip = true;
|
||||
}
|
||||
}
|
||||
|
||||
return didStrip;
|
||||
}
|
||||
|
||||
public stripInvalidSellableItems(): boolean
|
||||
{
|
||||
if(!this._categories) return false;
|
||||
|
||||
let didStrip = false;
|
||||
|
||||
for(const [ name, category ] of this._categories.entries())
|
||||
{
|
||||
const isValid = false;
|
||||
|
||||
// if(category._Str_8360(this._Str_2278.manager.inventory)) _local_6 = true;
|
||||
|
||||
if(isValid)
|
||||
{
|
||||
const partItem = category.getCurrentPart();
|
||||
|
||||
if(partItem && AvatarEditorUtilities.CURRENT_FIGURE)
|
||||
{
|
||||
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(name, partItem.id, category.getSelectedColorIds(), true);
|
||||
}
|
||||
|
||||
didStrip = true;
|
||||
}
|
||||
}
|
||||
|
||||
return didStrip;
|
||||
}
|
||||
|
||||
public selectPart(category: string, partIndex: number): void
|
||||
{
|
||||
const categoryData = this._categories.get(category);
|
||||
|
||||
if(!categoryData) return;
|
||||
|
||||
const selectedPartIndex = categoryData.selectedPartIndex;
|
||||
|
||||
categoryData.selectPartIndex(partIndex);
|
||||
|
||||
const partItem = categoryData.getCurrentPart();
|
||||
|
||||
if(!partItem) return;
|
||||
|
||||
if(partItem.isDisabled)
|
||||
{
|
||||
categoryData.selectPartIndex(selectedPartIndex);
|
||||
|
||||
// open hc window
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._maxPaletteCount = partItem.maxColorIndex;
|
||||
|
||||
AvatarEditorUtilities.CURRENT_FIGURE.savePartData(category, partItem.id, categoryData.getSelectedColorIds(), true);
|
||||
}
|
||||
|
||||
public selectColor(category: string, colorIndex: number, paletteId: number): void
|
||||
{
|
||||
const categoryData = this._categories.get(category);
|
||||
|
||||
if(!categoryData) return;
|
||||
|
||||
const paletteIndex = categoryData.getCurrentColorIndex(paletteId);
|
||||
|
||||
categoryData.selectColorIndex(colorIndex, paletteId);
|
||||
|
||||
const colorItem = categoryData.getSelectedColor(paletteId);
|
||||
|
||||
if(colorItem.isDisabled)
|
||||
{
|
||||
categoryData.selectColorIndex(paletteIndex, paletteId);
|
||||
|
||||
// open hc window
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AvatarEditorUtilities.CURRENT_FIGURE.savePartSetColourId(category, categoryData.getSelectedColorIds(), true);
|
||||
}
|
||||
|
||||
public getCategoryData(category: string): CategoryData
|
||||
{
|
||||
if(!this._isInitalized) this.init();
|
||||
|
||||
if(!this._categories) return null;
|
||||
|
||||
return this._categories.get(category);
|
||||
}
|
||||
|
||||
public get categories(): Map<string, CategoryData>
|
||||
{
|
||||
return this._categories;
|
||||
}
|
||||
|
||||
public get canSetGender(): boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public get maxPaletteCount(): number
|
||||
{
|
||||
return (this._maxPaletteCount || 1);
|
||||
}
|
||||
|
||||
public set maxPaletteCount(count: number)
|
||||
{
|
||||
this._maxPaletteCount = count;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,487 @@
|
|||
import { IPartColor } from '@nitrots/nitro-renderer';
|
||||
import { AvatarEditorGridColorItem } from './AvatarEditorGridColorItem';
|
||||
import { AvatarEditorGridPartItem } from './AvatarEditorGridPartItem';
|
||||
|
||||
export class CategoryData
|
||||
{
|
||||
private _name: string;
|
||||
private _parts: AvatarEditorGridPartItem[];
|
||||
private _palettes: AvatarEditorGridColorItem[][];
|
||||
private _selectedPartIndex: number = -1;
|
||||
private _paletteIndexes: number[];
|
||||
|
||||
constructor(name: string, partItems: AvatarEditorGridPartItem[], colorItems: AvatarEditorGridColorItem[][])
|
||||
{
|
||||
this._name = name;
|
||||
this._parts = partItems;
|
||||
this._palettes = colorItems;
|
||||
this._selectedPartIndex = -1;
|
||||
}
|
||||
|
||||
private static defaultColorId(palettes: AvatarEditorGridColorItem[], clubLevel: number): number
|
||||
{
|
||||
if(!palettes || !palettes.length) return -1;
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < palettes.length)
|
||||
{
|
||||
const colorItem = palettes[i];
|
||||
|
||||
if(colorItem.partColor && (colorItem.partColor.clubLevel <= clubLevel))
|
||||
{
|
||||
return colorItem.partColor.id;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public init(): void
|
||||
{
|
||||
for(const part of this._parts)
|
||||
{
|
||||
if(!part) continue;
|
||||
|
||||
part.init();
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void
|
||||
{
|
||||
if(this._parts)
|
||||
{
|
||||
for(const part of this._parts) part.dispose();
|
||||
|
||||
this._parts = null;
|
||||
}
|
||||
|
||||
if(this._palettes)
|
||||
{
|
||||
for(const palette of this._palettes) for(const colorItem of palette) colorItem.dispose();
|
||||
|
||||
this._palettes = null;
|
||||
}
|
||||
|
||||
this._selectedPartIndex = -1;
|
||||
this._paletteIndexes = null;
|
||||
}
|
||||
|
||||
public selectPartId(partId: number): void
|
||||
{
|
||||
if(!this._parts) return;
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this._parts.length)
|
||||
{
|
||||
const partItem = this._parts[i];
|
||||
|
||||
if(partItem.id === partId)
|
||||
{
|
||||
this.selectPartIndex(i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public selectColorIds(colorIds: number[]): void
|
||||
{
|
||||
if(!colorIds || !this._palettes) return;
|
||||
|
||||
this._paletteIndexes = new Array(colorIds.length);
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this._palettes.length)
|
||||
{
|
||||
const palette = this.getPalette(i);
|
||||
|
||||
if(palette)
|
||||
{
|
||||
let colorId = 0;
|
||||
|
||||
if(colorIds.length > i)
|
||||
{
|
||||
colorId = colorIds[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
const colorItem = palette[0];
|
||||
|
||||
if(colorItem && colorItem.partColor) colorId = colorItem.partColor.id;
|
||||
}
|
||||
|
||||
let j = 0;
|
||||
|
||||
while(j < palette.length)
|
||||
{
|
||||
const colorItem = palette[j];
|
||||
|
||||
if(colorItem.partColor.id === colorId)
|
||||
{
|
||||
this._paletteIndexes[i] = j;
|
||||
|
||||
colorItem.isSelected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorItem.isSelected = false;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
this.updatePartColors();
|
||||
}
|
||||
|
||||
public selectPartIndex(partIndex: number): AvatarEditorGridPartItem
|
||||
{
|
||||
if(!this._parts) return null;
|
||||
|
||||
if((this._selectedPartIndex >= 0) && (this._parts.length > this._selectedPartIndex))
|
||||
{
|
||||
const partItem = this._parts[this._selectedPartIndex];
|
||||
|
||||
if(partItem) partItem.isSelected = false;
|
||||
}
|
||||
|
||||
if(this._parts.length > partIndex)
|
||||
{
|
||||
const partItem = this._parts[partIndex];
|
||||
|
||||
if(partItem)
|
||||
{
|
||||
partItem.isSelected = true;
|
||||
|
||||
this._selectedPartIndex = partIndex;
|
||||
|
||||
return partItem;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public selectColorIndex(colorIndex: number, paletteId: number): AvatarEditorGridColorItem
|
||||
{
|
||||
const palette = this.getPalette(paletteId);
|
||||
|
||||
if(!palette) return null;
|
||||
|
||||
if(palette.length <= colorIndex) return null;
|
||||
|
||||
this.deselectColorIndex(this._paletteIndexes[paletteId], paletteId);
|
||||
|
||||
this._paletteIndexes[paletteId] = colorIndex;
|
||||
|
||||
const colorItem = palette[colorIndex];
|
||||
|
||||
if(!colorItem) return null;
|
||||
|
||||
colorItem.isSelected = true;
|
||||
|
||||
this.updatePartColors();
|
||||
|
||||
return colorItem;
|
||||
}
|
||||
|
||||
public getCurrentColorIndex(k: number): number
|
||||
{
|
||||
return this._paletteIndexes[k];
|
||||
}
|
||||
|
||||
private deselectColorIndex(colorIndex: number, paletteIndex: number): void
|
||||
{
|
||||
const palette = this.getPalette(paletteIndex);
|
||||
|
||||
if(!palette) return;
|
||||
|
||||
if(palette.length <= colorIndex) return;
|
||||
|
||||
const colorItem = palette[colorIndex];
|
||||
|
||||
if(!colorItem) return;
|
||||
|
||||
colorItem.isSelected = false;
|
||||
}
|
||||
|
||||
public getSelectedColorIds(): number[]
|
||||
{
|
||||
if(!this._paletteIndexes || !this._paletteIndexes.length) return null;
|
||||
|
||||
if(!this._palettes || !this._palettes.length) return null;
|
||||
|
||||
const palette = this._palettes[0];
|
||||
|
||||
if(!palette || (!palette.length)) return null;
|
||||
|
||||
const colorItem = palette[0];
|
||||
|
||||
if(!colorItem || !colorItem.partColor) return null;
|
||||
|
||||
const colorId = colorItem.partColor.id;
|
||||
const colorIds: number[] = [];
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this._paletteIndexes.length)
|
||||
{
|
||||
const paletteSet = this._palettes[i];
|
||||
|
||||
if(!((!(paletteSet)) || (paletteSet.length <= i)))
|
||||
{
|
||||
if(paletteSet.length > this._paletteIndexes[i])
|
||||
{
|
||||
const color = paletteSet[this._paletteIndexes[i]];
|
||||
|
||||
if(color && color.partColor)
|
||||
{
|
||||
colorIds.push(color.partColor.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
colorIds.push(colorId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
colorIds.push(colorId);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
const partItem = this.getCurrentPart();
|
||||
|
||||
if(!partItem) return null;
|
||||
|
||||
return colorIds.slice(0, Math.max(partItem.maxColorIndex, 1));
|
||||
}
|
||||
|
||||
private getSelectedColors(): IPartColor[]
|
||||
{
|
||||
const partColors: IPartColor[] = [];
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < this._paletteIndexes.length)
|
||||
{
|
||||
const colorItem = this.getSelectedColor(i);
|
||||
|
||||
if(colorItem)
|
||||
{
|
||||
partColors.push(colorItem.partColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
partColors.push(null);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return partColors;
|
||||
}
|
||||
|
||||
public getSelectedColor(paletteId: number): AvatarEditorGridColorItem
|
||||
{
|
||||
const palette = this.getPalette(paletteId);
|
||||
|
||||
if(!palette || (palette.length <= this._paletteIndexes[paletteId])) return null;
|
||||
|
||||
return palette[this._paletteIndexes[paletteId]];
|
||||
}
|
||||
|
||||
public getSelectedColorId(paletteId: number): number
|
||||
{
|
||||
const colorItem = this.getSelectedColor(paletteId);
|
||||
|
||||
if(colorItem && (colorItem.partColor)) return colorItem.partColor.id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public getPalette(paletteId: number): AvatarEditorGridColorItem[]
|
||||
{
|
||||
if(!this._paletteIndexes || !this._palettes || (this._palettes.length <= paletteId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return this._palettes[paletteId];
|
||||
}
|
||||
|
||||
public getCurrentPart(): AvatarEditorGridPartItem
|
||||
{
|
||||
return this._parts[this._selectedPartIndex] as AvatarEditorGridPartItem;
|
||||
}
|
||||
|
||||
private updatePartColors(): void
|
||||
{
|
||||
const partColors = this.getSelectedColors();
|
||||
|
||||
for(const partItem of this._parts)
|
||||
{
|
||||
if(partItem) partItem.partColors = partColors;
|
||||
}
|
||||
}
|
||||
|
||||
public hasClubSelectionsOverLevel(level: number): boolean
|
||||
{
|
||||
let hasInvalidSelections = false;
|
||||
|
||||
const partColors = this.getSelectedColors();
|
||||
|
||||
if(partColors)
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < partColors.length)
|
||||
{
|
||||
const partColor = partColors[i];
|
||||
|
||||
if(partColor && (partColor.clubLevel > level)) hasInvalidSelections = true;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
const partItem = this.getCurrentPart();
|
||||
|
||||
if(partItem && partItem.partSet)
|
||||
{
|
||||
const partSet = partItem.partSet;
|
||||
|
||||
if(partSet && (partSet.clubLevel > level)) hasInvalidSelections = true;
|
||||
}
|
||||
|
||||
return hasInvalidSelections;
|
||||
}
|
||||
|
||||
public hasInvalidSelectedItems(ownedItems: number[]): boolean
|
||||
{
|
||||
const part = this.getCurrentPart();
|
||||
|
||||
if(!part) return false;
|
||||
|
||||
const partSet = part.partSet;
|
||||
|
||||
if(!partSet || !partSet.isSellable) return;
|
||||
|
||||
return (ownedItems.indexOf(partSet.id) > -1);
|
||||
}
|
||||
|
||||
public stripClubItemsOverLevel(level: number): boolean
|
||||
{
|
||||
const partItem = this.getCurrentPart();
|
||||
|
||||
if(partItem && partItem.partSet)
|
||||
{
|
||||
const partSet = partItem.partSet;
|
||||
|
||||
if(partSet.clubLevel > level)
|
||||
{
|
||||
const newPartItem = this.selectPartIndex(0);
|
||||
|
||||
if(newPartItem && !newPartItem.partSet) this.selectPartIndex(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public stripClubColorsOverLevel(level: number): boolean
|
||||
{
|
||||
const colorIds: number[] = [];
|
||||
const partColors = this.getSelectedColors();
|
||||
const colorItems = this.getPalette(0);
|
||||
|
||||
let didStrip = false;
|
||||
|
||||
const colorId = CategoryData.defaultColorId(colorItems, level);
|
||||
|
||||
if(colorId === -1) return false;
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < partColors.length)
|
||||
{
|
||||
const partColor = partColors[i];
|
||||
|
||||
if(!partColor)
|
||||
{
|
||||
colorIds.push(colorId);
|
||||
|
||||
didStrip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(partColor.clubLevel > level)
|
||||
{
|
||||
colorIds.push(colorId);
|
||||
|
||||
didStrip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorIds.push(partColor.id);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(didStrip) this.selectColorIds(colorIds);
|
||||
|
||||
return didStrip;
|
||||
}
|
||||
|
||||
// public stripInvalidSellableItems(k:IHabboInventory): boolean
|
||||
// {
|
||||
// var _local_3:IFigurePartSet;
|
||||
// var _local_4:AvatarEditorGridPartItem;
|
||||
// var _local_2:AvatarEditorGridPartItem = this._Str_6315();
|
||||
// if (((_local_2) && (_local_2.partSet)))
|
||||
// {
|
||||
// _local_3 = _local_2.partSet;
|
||||
// if (((_local_3.isSellable) && (!(k._Str_14439(_local_3.id)))))
|
||||
// {
|
||||
// _local_4 = this._Str_8066(0);
|
||||
// if (((!(_local_4 == null)) && (_local_4.partSet == null)))
|
||||
// {
|
||||
// this._Str_8066(1);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get parts(): AvatarEditorGridPartItem[]
|
||||
{
|
||||
return this._parts;
|
||||
}
|
||||
|
||||
public get selectedPartIndex(): number
|
||||
{
|
||||
return this._selectedPartIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
import { AvatarEditorUtilities } from './AvatarEditorUtilities';
|
||||
|
||||
export class FigureData
|
||||
{
|
||||
private static DEFAULT_DIRECTION: number = 4;
|
||||
|
||||
public static MALE: string = 'M';
|
||||
public static FEMALE: string = 'F';
|
||||
public static UNISEX: string = 'U';
|
||||
public static SCALE: string = 'h';
|
||||
public static STD: string = 'std';
|
||||
public static DEFAULT_FRAME: string = '0';
|
||||
public static FACE: string = 'hd';
|
||||
public static HAIR: string = 'hr';
|
||||
public static HAT: string = 'ha';
|
||||
public static HEAD_ACCESSORIES: string = 'he';
|
||||
public static EYE_ACCESSORIES: string = 'ea';
|
||||
public static FACE_ACCESSORIES: string = 'fa';
|
||||
public static JACKET: string = 'cc';
|
||||
public static SHIRT: string = 'ch';
|
||||
public static CHEST_ACCESSORIES: string = 'ca';
|
||||
public static CHEST_PRINTS: string = 'cp';
|
||||
public static TROUSERS: string = 'lg';
|
||||
public static SHOES: string = 'sh';
|
||||
public static TROUSER_ACCESSORIES: string = 'wa';
|
||||
public static SET_TYPES = [ FigureData.FACE, FigureData.HAIR, FigureData.HAT, FigureData.HEAD_ACCESSORIES, FigureData.EYE_ACCESSORIES, FigureData.FACE_ACCESSORIES, FigureData.JACKET, FigureData.SHIRT, FigureData.CHEST_ACCESSORIES, FigureData.CHEST_PRINTS, FigureData.TROUSERS, FigureData.SHOES, FigureData.TROUSERS ];
|
||||
|
||||
private _data: Map<string, number>;
|
||||
private _colors: Map<string, number[]>;
|
||||
private _gender: string = 'M';
|
||||
private _direction: number = FigureData.DEFAULT_DIRECTION;
|
||||
private _avatarEffectType: number = -1;
|
||||
private _notifier: () => void = null;
|
||||
|
||||
public loadAvatarData(figureString: string, gender: string): void
|
||||
{
|
||||
this._data = new Map();
|
||||
this._colors = new Map();
|
||||
this._gender = gender;
|
||||
|
||||
this.parseFigureString(figureString);
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
private parseFigureString(figure: string): void
|
||||
{
|
||||
if(!figure) return;
|
||||
|
||||
const sets = figure.split('.');
|
||||
|
||||
if(!sets || !sets.length) return;
|
||||
|
||||
for(const set of sets)
|
||||
{
|
||||
const parts = set.split('-');
|
||||
|
||||
if(!parts.length) continue;
|
||||
|
||||
const setType = parts[0];
|
||||
const setId = parseInt(parts[1]);
|
||||
const colorIds: number[] = [];
|
||||
|
||||
let offset = 2;
|
||||
|
||||
while(offset < parts.length)
|
||||
{
|
||||
colorIds.push(parseInt(parts[offset]));
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
||||
if(!colorIds.length) colorIds.push(0);
|
||||
|
||||
this.savePartSetId(setType, setId, false);
|
||||
this.savePartSetColourId(setType, colorIds, false);
|
||||
}
|
||||
}
|
||||
|
||||
public getPartSetId(setType: string): number
|
||||
{
|
||||
const existing = this._data.get(setType);
|
||||
|
||||
if(existing !== undefined) return existing;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public getColorIds(setType: string): number[]
|
||||
{
|
||||
const existing = this._colors.get(setType);
|
||||
|
||||
if(existing !== undefined) return existing;
|
||||
|
||||
return [ AvatarEditorUtilities.avatarSetFirstSelectableColor(setType) ];
|
||||
}
|
||||
|
||||
public getFigureString(): string
|
||||
{
|
||||
let figureString = '';
|
||||
const setParts: string[] = [];
|
||||
|
||||
for(const [ setType, setId ] of this._data.entries())
|
||||
{
|
||||
const colorIds = this._colors.get(setType);
|
||||
|
||||
let setPart = ((setType + '-') + setId);
|
||||
|
||||
if(colorIds && colorIds.length)
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < colorIds.length)
|
||||
{
|
||||
setPart = (setPart + ('-' + colorIds[i]));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
setParts.push(setPart);
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < setParts.length)
|
||||
{
|
||||
figureString = (figureString + setParts[i]);
|
||||
|
||||
if(i < (setParts.length - 1)) figureString = (figureString + '.');
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return figureString;
|
||||
}
|
||||
|
||||
public savePartData(setType: string, partId: number, colorIds: number[], update: boolean = false): void
|
||||
{
|
||||
this.savePartSetId(setType, partId, update);
|
||||
this.savePartSetColourId(setType, colorIds, update);
|
||||
}
|
||||
|
||||
private savePartSetId(setType: string, partId: number, update: boolean = true): void
|
||||
{
|
||||
switch(setType)
|
||||
{
|
||||
case FigureData.FACE:
|
||||
case FigureData.HAIR:
|
||||
case FigureData.HAT:
|
||||
case FigureData.HEAD_ACCESSORIES:
|
||||
case FigureData.EYE_ACCESSORIES:
|
||||
case FigureData.FACE_ACCESSORIES:
|
||||
case FigureData.SHIRT:
|
||||
case FigureData.JACKET:
|
||||
case FigureData.CHEST_ACCESSORIES:
|
||||
case FigureData.CHEST_PRINTS:
|
||||
case FigureData.TROUSERS:
|
||||
case FigureData.SHOES:
|
||||
case FigureData.TROUSER_ACCESSORIES:
|
||||
if(partId >= 0)
|
||||
{
|
||||
this._data.set(setType, partId);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._data.delete(setType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(update) this.updateView();
|
||||
}
|
||||
|
||||
public savePartSetColourId(setType: string, colorIds: number[], update: boolean = true): void
|
||||
{
|
||||
switch(setType)
|
||||
{
|
||||
case FigureData.FACE:
|
||||
case FigureData.HAIR:
|
||||
case FigureData.HAT:
|
||||
case FigureData.HEAD_ACCESSORIES:
|
||||
case FigureData.EYE_ACCESSORIES:
|
||||
case FigureData.FACE_ACCESSORIES:
|
||||
case FigureData.SHIRT:
|
||||
case FigureData.JACKET:
|
||||
case FigureData.CHEST_ACCESSORIES:
|
||||
case FigureData.CHEST_PRINTS:
|
||||
case FigureData.TROUSERS:
|
||||
case FigureData.SHOES:
|
||||
case FigureData.TROUSER_ACCESSORIES:
|
||||
this._colors.set(setType, colorIds);
|
||||
break;
|
||||
}
|
||||
|
||||
if(update) this.updateView();
|
||||
}
|
||||
|
||||
public getFigureStringWithFace(k: number, override = true): string
|
||||
{
|
||||
let figureString = '';
|
||||
|
||||
const setTypes: string[] = [ FigureData.FACE ];
|
||||
const figureSets: string[] = [];
|
||||
|
||||
for(const setType of setTypes)
|
||||
{
|
||||
const colors = this._colors.get(setType);
|
||||
|
||||
if(!colors) continue;
|
||||
|
||||
let setId = this._data.get(setType);
|
||||
|
||||
if((setType === FigureData.FACE) && override) setId = k;
|
||||
|
||||
let figureSet = ((setType + '-') + setId);
|
||||
|
||||
if(setId >= 0)
|
||||
{
|
||||
let i = 0;
|
||||
|
||||
while(i < colors.length)
|
||||
{
|
||||
figureSet = (figureSet + ('-' + colors[i]));
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
figureSets.push(figureSet);
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < figureSets.length)
|
||||
{
|
||||
figureString = (figureString + figureSets[i]);
|
||||
|
||||
if(i < (figureSets.length - 1)) figureString = (figureString + '.');
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return figureString;
|
||||
}
|
||||
|
||||
public updateView(): void
|
||||
{
|
||||
if(this.notify) this.notify();
|
||||
}
|
||||
|
||||
public get gender(): string
|
||||
{
|
||||
return this._gender;
|
||||
}
|
||||
|
||||
public get direction(): number
|
||||
{
|
||||
return this._direction;
|
||||
}
|
||||
|
||||
public set direction(direction: number)
|
||||
{
|
||||
this._direction = direction;
|
||||
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
public set avatarEffectType(k: number)
|
||||
{
|
||||
this._avatarEffectType = k;
|
||||
}
|
||||
|
||||
public get avatarEffectType(): number
|
||||
{
|
||||
return this._avatarEffectType;
|
||||
}
|
||||
|
||||
public get notify(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notify(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
import { AvatarFigureContainer, IFigurePartSet, IPalette, IPartColor, SetType } from '@nitrots/nitro-renderer';
|
||||
import { GetAvatarRenderManager } from '../nitro';
|
||||
import { Randomizer } from '../utils';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
function getTotalColors(partSet: IFigurePartSet): number
|
||||
{
|
||||
const parts = partSet.parts;
|
||||
|
||||
let totalColors = 0;
|
||||
|
||||
for(const part of parts) totalColors = Math.max(totalColors, part.colorLayerIndex);
|
||||
|
||||
return totalColors;
|
||||
}
|
||||
|
||||
function getRandomSetTypes(requiredSets: string[], options: string[]): string[]
|
||||
{
|
||||
options = options.filter(option => (requiredSets.indexOf(option) === -1));
|
||||
|
||||
return [ ...requiredSets, ...Randomizer.getRandomElements(options, (Randomizer.getRandomNumber(options.length) + 1)) ];
|
||||
}
|
||||
|
||||
function getRandomPartSet(setType: SetType, gender: string, clubLevel: number = 0, figureSetIds: number[] = []): IFigurePartSet
|
||||
{
|
||||
if(!setType) return null;
|
||||
|
||||
const options = setType.partSets.getValues().filter(option =>
|
||||
{
|
||||
if(!option.isSelectable || ((option.gender !== 'U') && (option.gender !== gender)) || (option.clubLevel > clubLevel) || (option.isSellable && (figureSetIds.indexOf(option.id) === -1))) return null;
|
||||
|
||||
return option;
|
||||
});
|
||||
|
||||
if(!options || !options.length) return null;
|
||||
|
||||
return Randomizer.getRandomElement(options);
|
||||
}
|
||||
|
||||
function getRandomColors(palette: IPalette, partSet: IFigurePartSet, clubLevel: number = 0): IPartColor[]
|
||||
{
|
||||
if(!palette) return [];
|
||||
|
||||
const options = palette.colors.getValues().filter(option =>
|
||||
{
|
||||
if(!option.isSelectable || (option.clubLevel > clubLevel)) return null;
|
||||
|
||||
return option;
|
||||
});
|
||||
|
||||
if(!options || !options.length) return null;
|
||||
|
||||
return Randomizer.getRandomElements(options, getTotalColors(partSet));
|
||||
}
|
||||
|
||||
export function generateRandomFigure(figureData: FigureData, gender: string, clubLevel: number = 0, figureSetIds: number[] = [], ignoredSets: string[] = []): string
|
||||
{
|
||||
const structure = GetAvatarRenderManager().structure;
|
||||
const figureContainer = new AvatarFigureContainer('');
|
||||
const requiredSets = getRandomSetTypes(structure.getMandatorySetTypeIds(gender, clubLevel), FigureData.SET_TYPES);
|
||||
|
||||
for(const setType of ignoredSets)
|
||||
{
|
||||
const partSetId = figureData.getPartSetId(setType);
|
||||
const colors = figureData.getColorIds(setType);
|
||||
|
||||
figureContainer.updatePart(setType, partSetId, colors);
|
||||
}
|
||||
|
||||
for(const type of requiredSets)
|
||||
{
|
||||
if(figureContainer.hasPartType(type)) continue;
|
||||
|
||||
const setType = (structure.figureData.getSetType(type) as SetType);
|
||||
const selectedSet = getRandomPartSet(setType, gender, clubLevel, figureSetIds);
|
||||
|
||||
if(!selectedSet) continue;
|
||||
|
||||
let selectedColors: number[] = [];
|
||||
|
||||
if(selectedSet.isColorable)
|
||||
{
|
||||
selectedColors = getRandomColors(structure.figureData.getPalette(setType.paletteID), selectedSet, clubLevel).map(color => color.id);
|
||||
}
|
||||
|
||||
figureContainer.updatePart(setType.type, selectedSet.id, selectedColors);
|
||||
}
|
||||
|
||||
return figureContainer.getFigureString();
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class HeadModel extends CategoryBaseModel
|
||||
{
|
||||
public init(): void
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.addCategory(FigureData.HAIR);
|
||||
this.addCategory(FigureData.HAT);
|
||||
this.addCategory(FigureData.HEAD_ACCESSORIES);
|
||||
this.addCategory(FigureData.EYE_ACCESSORIES);
|
||||
this.addCategory(FigureData.FACE_ACCESSORIES);
|
||||
|
||||
this._isInitalized = true;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return AvatarEditorFigureCategory.HEAD;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { CategoryData } from './CategoryData';
|
||||
|
||||
export interface IAvatarEditorCategoryModel
|
||||
{
|
||||
init(): void;
|
||||
dispose(): void;
|
||||
reset(): void;
|
||||
getCategoryData(category: string): CategoryData;
|
||||
selectPart(category: string, partIndex: number): void;
|
||||
selectColor(category: string, colorIndex: number, paletteId: number): void;
|
||||
hasClubSelectionsOverLevel(level: number): boolean;
|
||||
hasInvalidSelectedItems(ownedItems: number[]): boolean;
|
||||
stripClubItemsOverLevel(level: number): boolean;
|
||||
stripInvalidSellableItems(): boolean;
|
||||
categories: Map<string, CategoryData>;
|
||||
canSetGender: boolean;
|
||||
maxPaletteCount: number;
|
||||
name: string;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class LegModel extends CategoryBaseModel
|
||||
{
|
||||
public init(): void
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.addCategory(FigureData.TROUSERS);
|
||||
this.addCategory(FigureData.SHOES);
|
||||
this.addCategory(FigureData.TROUSER_ACCESSORIES);
|
||||
|
||||
this._isInitalized = true;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return AvatarEditorFigureCategory.LEGS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { AvatarEditorFigureCategory } from '@nitrots/nitro-renderer';
|
||||
import { CategoryBaseModel } from './CategoryBaseModel';
|
||||
import { FigureData } from './FigureData';
|
||||
|
||||
export class TorsoModel extends CategoryBaseModel
|
||||
{
|
||||
public init(): void
|
||||
{
|
||||
super.init();
|
||||
|
||||
this.addCategory(FigureData.SHIRT);
|
||||
this.addCategory(FigureData.CHEST_PRINTS);
|
||||
this.addCategory(FigureData.JACKET);
|
||||
this.addCategory(FigureData.CHEST_ACCESSORIES);
|
||||
|
||||
this._isInitalized = true;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return AvatarEditorFigureCategory.TORSO;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
export * from './AvatarEditorAction';
|
||||
export * from './AvatarEditorGridColorItem';
|
||||
export * from './AvatarEditorGridPartItem';
|
||||
export * from './AvatarEditorUtilities';
|
||||
export * from './BodyModel';
|
||||
export * from './CategoryBaseModel';
|
||||
export * from './CategoryData';
|
||||
export * from './FigureData';
|
||||
export * from './FigureGenerator';
|
||||
export * from './HeadModel';
|
||||
export * from './IAvatarEditorCategoryModel';
|
||||
export * from './LegModel';
|
||||
export * from './TorsoModel';
|
|
@ -0,0 +1,5 @@
|
|||
export class CameraEditorTabs
|
||||
{
|
||||
public static readonly COLORMATRIX: string = 'colormatrix';
|
||||
public static readonly COMPOSITE: string = 'composite';
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { NitroTexture } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class CameraPicture
|
||||
{
|
||||
constructor(
|
||||
public texture: NitroTexture,
|
||||
public imageUrl: string)
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export class CameraPictureThumbnail
|
||||
{
|
||||
constructor(
|
||||
public effectName: string,
|
||||
public thumbnailUrl: string)
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './CameraEditorTabs';
|
||||
export * from './CameraPicture';
|
||||
export * from './CameraPictureThumbnail';
|
|
@ -0,0 +1,30 @@
|
|||
import { ICalendarItem } from './ICalendarItem';
|
||||
|
||||
export class CalendarItem implements ICalendarItem
|
||||
{
|
||||
private _productName: string;
|
||||
private _customImage: string;
|
||||
private _furnitureClassName: string;
|
||||
|
||||
constructor(productName: string, customImage: string, furnitureClassName: string)
|
||||
{
|
||||
this._productName = productName;
|
||||
this._customImage = customImage;
|
||||
this._furnitureClassName = furnitureClassName;
|
||||
}
|
||||
|
||||
public get productName(): string
|
||||
{
|
||||
return this._productName;
|
||||
}
|
||||
|
||||
public get customImage(): string
|
||||
{
|
||||
return this._customImage;
|
||||
}
|
||||
|
||||
public get furnitureClassName(): string
|
||||
{
|
||||
return this._furnitureClassName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export class CalendarItemState
|
||||
{
|
||||
public static readonly STATE_UNLOCKED = 1;
|
||||
public static readonly STATE_LOCKED_AVAILABLE = 2;
|
||||
public static readonly STATE_LOCKED_EXPIRED = 3;
|
||||
public static readonly STATE_LOCKED_FUTURE = 4;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface ICalendarItem
|
||||
{
|
||||
readonly productName: string;
|
||||
readonly customImage: string;
|
||||
readonly furnitureClassName: string;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './CalendarItem';
|
||||
export * from './CalendarItemState';
|
||||
export * from './ICalendarItem';
|
|
@ -0,0 +1,10 @@
|
|||
export class BuilderFurniPlaceableStatus
|
||||
{
|
||||
public static OKAY: number = 0;
|
||||
public static MISSING_OFFER: number = 1;
|
||||
public static FURNI_LIMIT_REACHED: number = 2;
|
||||
public static NOT_IN_ROOM: number = 3;
|
||||
public static NOT_ROOM_OWNER: number = 4;
|
||||
public static GUILD_ROOM: number = 5;
|
||||
public static VISITORS_IN_ROOM: number = 6;
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
import { NodeData } from '@nitrots/nitro-renderer';
|
||||
import { ICatalogNode } from './ICatalogNode';
|
||||
|
||||
export class CatalogNode implements ICatalogNode
|
||||
{
|
||||
private _depth: number = 0;
|
||||
private _localization: string = '';
|
||||
private _pageId: number = -1;
|
||||
private _pageName: string = '';
|
||||
private _iconId: number = 0;
|
||||
private _children: ICatalogNode[];
|
||||
private _offerIds: number[];
|
||||
private _parent: ICatalogNode;
|
||||
private _isVisible: boolean;
|
||||
private _isActive: boolean;
|
||||
private _isOpen: boolean;
|
||||
|
||||
constructor(node: NodeData, depth: number, parent: ICatalogNode)
|
||||
{
|
||||
this._depth = depth;
|
||||
this._parent = parent;
|
||||
this._localization = node.localization;
|
||||
this._pageId = node.pageId;
|
||||
this._pageName = node.pageName;
|
||||
this._iconId = node.icon;
|
||||
this._children = [];
|
||||
this._offerIds = node.offerIds;
|
||||
this._isVisible = node.visible;
|
||||
this._isActive = false;
|
||||
this._isOpen = false;
|
||||
}
|
||||
|
||||
public activate(): void
|
||||
{
|
||||
this._isActive = true;
|
||||
}
|
||||
|
||||
public deactivate(): void
|
||||
{
|
||||
this._isActive = false;
|
||||
}
|
||||
|
||||
public open(): void
|
||||
{
|
||||
this._isOpen = true;
|
||||
}
|
||||
|
||||
public close(): void
|
||||
{
|
||||
this._isOpen = false;
|
||||
}
|
||||
|
||||
public addChild(child: ICatalogNode):void
|
||||
{
|
||||
if(!child) return;
|
||||
|
||||
this._children.push(child);
|
||||
}
|
||||
|
||||
public get depth(): number
|
||||
{
|
||||
return this._depth;
|
||||
}
|
||||
|
||||
public get isBranch(): boolean
|
||||
{
|
||||
return (this._children.length > 0);
|
||||
}
|
||||
|
||||
public get isLeaf(): boolean
|
||||
{
|
||||
return (this._children.length === 0);
|
||||
}
|
||||
|
||||
public get localization(): string
|
||||
{
|
||||
return this._localization;
|
||||
}
|
||||
|
||||
public get pageId(): number
|
||||
{
|
||||
return this._pageId;
|
||||
}
|
||||
|
||||
public get pageName(): string
|
||||
{
|
||||
return this._pageName;
|
||||
}
|
||||
|
||||
public get iconId(): number
|
||||
{
|
||||
return this._iconId;
|
||||
}
|
||||
|
||||
public get children(): ICatalogNode[]
|
||||
{
|
||||
return this._children;
|
||||
}
|
||||
|
||||
public get offerIds(): number[]
|
||||
{
|
||||
return this._offerIds;
|
||||
}
|
||||
|
||||
public get parent(): ICatalogNode
|
||||
{
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
public get isVisible(): boolean
|
||||
{
|
||||
return this._isVisible;
|
||||
}
|
||||
|
||||
public get isActive(): boolean
|
||||
{
|
||||
return this._isActive;
|
||||
}
|
||||
|
||||
public get isOpen(): boolean
|
||||
{
|
||||
return this._isOpen;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { ICatalogPage } from './ICatalogPage';
|
||||
import { IPageLocalization } from './IPageLocalization';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
||||
export class CatalogPage implements ICatalogPage
|
||||
{
|
||||
public static MODE_NORMAL: number = 0;
|
||||
|
||||
private _pageId: number;
|
||||
private _layoutCode: string;
|
||||
private _localization: IPageLocalization;
|
||||
private _offers: IPurchasableOffer[];
|
||||
private _acceptSeasonCurrencyAsCredits: boolean;
|
||||
private _mode: number;
|
||||
|
||||
constructor(pageId: number, layoutCode: string, localization: IPageLocalization, offers: IPurchasableOffer[], acceptSeasonCurrencyAsCredits: boolean, mode: number = -1)
|
||||
{
|
||||
this._pageId = pageId;
|
||||
this._layoutCode = layoutCode;
|
||||
this._localization = localization;
|
||||
this._offers = offers;
|
||||
this._acceptSeasonCurrencyAsCredits = acceptSeasonCurrencyAsCredits;
|
||||
|
||||
for(const offer of offers) (offer.page = this);
|
||||
|
||||
if(mode === -1) this._mode = CatalogPage.MODE_NORMAL;
|
||||
else this._mode = mode;
|
||||
}
|
||||
|
||||
public get pageId(): number
|
||||
{
|
||||
return this._pageId;
|
||||
}
|
||||
|
||||
public get layoutCode(): string
|
||||
{
|
||||
return this._layoutCode;
|
||||
}
|
||||
|
||||
public get localization(): IPageLocalization
|
||||
{
|
||||
return this._localization;
|
||||
}
|
||||
|
||||
public get offers(): IPurchasableOffer[]
|
||||
{
|
||||
return this._offers;
|
||||
}
|
||||
|
||||
public get acceptSeasonCurrencyAsCredits(): boolean
|
||||
{
|
||||
return this._acceptSeasonCurrencyAsCredits;
|
||||
}
|
||||
|
||||
public get mode(): number
|
||||
{
|
||||
return this._mode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
export class CatalogPageName
|
||||
{
|
||||
public static DUCKET_INFO: string = 'ducket_info';
|
||||
public static CREDITS: string = 'credits';
|
||||
public static AVATAR_EFFECTS: string = 'avatar_effects';
|
||||
public static HC_MEMBERSHIP: string = 'hc_membership';
|
||||
public static CLUB_GIFTS: string = 'club_gifts';
|
||||
public static LIMITED_SOLD: string = 'limited_sold';
|
||||
public static PET_ACCESSORIES: string = 'pet_accessories';
|
||||
public static TRAX_SONGS: string = 'trax_songs';
|
||||
public static NEW_ADDITIONS: string = 'new_additions';
|
||||
public static QUEST_SHELL: string = 'quest_shell';
|
||||
public static QUEST_SNOWFLAKES: string = 'quest_snowflakes';
|
||||
public static VAL_QUESTS: string = 'val_quests';
|
||||
public static GUILD_CUSTOM_FURNI: string = 'guild_custom_furni';
|
||||
public static GIFT_SHOP: string = 'gift_shop';
|
||||
public static HORSE_STYLES: string = 'horse_styles';
|
||||
public static HORSE_SHOE: string = 'horse_shoe';
|
||||
public static SET_EASTER: string = 'set_easter';
|
||||
public static ECOTRON_TRANSFORM: string = 'ecotron_transform';
|
||||
public static LOYALTY_INFO: string = 'loyalty_info';
|
||||
public static ROOM_BUNDLES: string = 'room_bundles';
|
||||
public static ROOM_BUNDLES_MOBILE: string = 'room_bundles_mobile';
|
||||
public static HABBO_CLUB_DESKTOP: string = 'habbo_club_desktop';
|
||||
public static MOBILE_SUBSCRIPTIONS: string = 'mobile_subscriptions';
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class CatalogPetPalette
|
||||
{
|
||||
constructor(
|
||||
public readonly breed: string,
|
||||
public readonly palettes: SellablePetPaletteData[]
|
||||
)
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
export class CatalogPurchaseState
|
||||
{
|
||||
public static NONE = 0;
|
||||
public static CONFIRM = 1;
|
||||
public static PURCHASE = 2;
|
||||
public static NO_CREDITS = 3;
|
||||
public static NO_POINTS = 4;
|
||||
public static SOLD_OUT = 5;
|
||||
public static FAILED = 6;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export class CatalogType
|
||||
{
|
||||
public static NORMAL: string = 'NORMAL';
|
||||
public static BUILDER: string = 'BUILDERS_CLUB';
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
import { SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../nitro';
|
||||
import { ICatalogNode } from './ICatalogNode';
|
||||
|
||||
export const GetPixelEffectIcon = (id: number) =>
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
export const GetSubscriptionProductIcon = (id: number) =>
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) =>
|
||||
{
|
||||
const nodes = offerNodes.get(offerId);
|
||||
const allowedNodes: ICatalogNode[] = [];
|
||||
|
||||
if(nodes && nodes.length)
|
||||
{
|
||||
for(const node of nodes)
|
||||
{
|
||||
if(!node.isVisible) continue;
|
||||
|
||||
allowedNodes.push(node);
|
||||
}
|
||||
}
|
||||
|
||||
return allowedNodes;
|
||||
}
|
||||
|
||||
export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) =>
|
||||
{
|
||||
if(node.isVisible && (node.pageId > 0))
|
||||
{
|
||||
let nodeAdded = false;
|
||||
|
||||
const hayStack = [ node.pageName, node.localization ].join(' ').toLowerCase().replace(/ /gi, '');
|
||||
|
||||
if(hayStack.indexOf(search) > -1)
|
||||
{
|
||||
nodes.push(node);
|
||||
|
||||
nodeAdded = true;
|
||||
}
|
||||
|
||||
if(!nodeAdded)
|
||||
{
|
||||
for(const furniLine of furniLines)
|
||||
{
|
||||
if(hayStack.indexOf(furniLine) >= 0)
|
||||
{
|
||||
nodes.push(node);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(const child of node.children) FilterCatalogNode(search, furniLines, child, nodes);
|
||||
}
|
||||
|
||||
export function GetPetIndexFromLocalization(localization: string)
|
||||
{
|
||||
if(!localization.length) return 0;
|
||||
|
||||
let index = (localization.length - 1);
|
||||
|
||||
while(index >= 0)
|
||||
{
|
||||
if(isNaN(parseInt(localization.charAt(index)))) break;
|
||||
|
||||
index--;
|
||||
}
|
||||
|
||||
if(index > 0) return parseInt(localization.substring(index + 1));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function GetPetAvailableColors(petIndex: number, palettes: SellablePetPaletteData[]): number[][]
|
||||
{
|
||||
switch(petIndex)
|
||||
{
|
||||
case 0:
|
||||
return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ];
|
||||
case 1:
|
||||
return [ [ 16743226 ], [ 16750435 ], [ 16764339 ], [ 0xF59500 ], [ 16498012 ], [ 16704690 ], [ 0xEDD400 ], [ 16115545 ], [ 16513201 ], [ 8694111 ], [ 11585939 ], [ 14413767 ], [ 6664599 ], [ 9553845 ], [ 12971486 ], [ 8358322 ], [ 10002885 ], [ 13292268 ], [ 10780600 ], [ 12623573 ], [ 14403561 ], [ 12418717 ], [ 14327229 ], [ 15517403 ], [ 14515069 ], [ 15764368 ], [ 16366271 ], [ 0xABABAB ], [ 0xD4D4D4 ], [ 0xFFFFFF ], [ 14256481 ], [ 14656129 ], [ 15848130 ], [ 14005087 ], [ 14337152 ], [ 15918540 ], [ 15118118 ], [ 15531929 ], [ 9764857 ], [ 11258085 ] ];
|
||||
case 2:
|
||||
return [ [ 16579283 ], [ 15378351 ], [ 8830016 ], [ 15257125 ], [ 9340985 ], [ 8949607 ], [ 6198292 ], [ 8703620 ], [ 9889626 ], [ 8972045 ], [ 12161285 ], [ 13162269 ], [ 8620113 ], [ 12616503 ], [ 8628101 ], [ 0xD2FF00 ], [ 9764857 ] ];
|
||||
case 3:
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ];
|
||||
case 4:
|
||||
return [ [ 0xFFFFFF ], [ 16053490 ], [ 15464440 ], [ 16248792 ], [ 15396319 ], [ 15007487 ] ];
|
||||
case 5:
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ] ];
|
||||
case 6:
|
||||
return [ [ 0xFFFFFF ], [ 0xEEEEEE ], [ 0xDDDDDD ], [ 16767177 ], [ 16770205 ], [ 16751331 ] ];
|
||||
case 7:
|
||||
return [ [ 0xCCCCCC ], [ 0xAEAEAE ], [ 16751331 ], [ 10149119 ], [ 16763290 ], [ 16743786 ] ];
|
||||
default: {
|
||||
const colors: number[][] = [];
|
||||
|
||||
for(const palette of palettes)
|
||||
{
|
||||
const petColorResult = GetRoomEngine().getPetColorResult(petIndex, palette.paletteId);
|
||||
|
||||
if(!petColorResult) continue;
|
||||
|
||||
if(petColorResult.primaryColor === petColorResult.secondaryColor)
|
||||
{
|
||||
colors.push([ petColorResult.primaryColor ]);
|
||||
}
|
||||
else
|
||||
{
|
||||
colors.push([ petColorResult.primaryColor, petColorResult.secondaryColor ]);
|
||||
}
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
import { GetProductOfferComposer, IFurnitureData } from '@nitrots/nitro-renderer';
|
||||
import { GetProductDataForLocalization, SendMessageComposer } from '..';
|
||||
import { ICatalogPage } from './ICatalogPage';
|
||||
import { IProduct } from './IProduct';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
import { Offer } from './Offer';
|
||||
import { Product } from './Product';
|
||||
|
||||
export class FurnitureOffer implements IPurchasableOffer
|
||||
{
|
||||
private _furniData:IFurnitureData;
|
||||
private _page: ICatalogPage;
|
||||
private _product: IProduct;
|
||||
|
||||
constructor(furniData: IFurnitureData)
|
||||
{
|
||||
this._furniData = furniData;
|
||||
this._product = (new Product(this._furniData.type, this._furniData.id, this._furniData.customParams, 1, GetProductDataForLocalization(this._furniData.className), this._furniData) as IProduct);
|
||||
}
|
||||
|
||||
public activate(): void
|
||||
{
|
||||
SendMessageComposer(new GetProductOfferComposer((this._furniData.rentOfferId > -1) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId));
|
||||
}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return (this.isRentOffer) ? this._furniData.rentOfferId : this._furniData.purchaseOfferId;
|
||||
}
|
||||
|
||||
public get priceInActivityPoints(): number
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get activityPointType(): number
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get priceInCredits(): number
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get page(): ICatalogPage
|
||||
{
|
||||
return this._page;
|
||||
}
|
||||
|
||||
public set page(page: ICatalogPage)
|
||||
{
|
||||
this._page = page;
|
||||
}
|
||||
|
||||
public get priceType(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public get product(): IProduct
|
||||
{
|
||||
return this._product;
|
||||
}
|
||||
|
||||
public get products(): IProduct[]
|
||||
{
|
||||
return [ this._product ];
|
||||
}
|
||||
|
||||
public get localizationId(): string
|
||||
{
|
||||
return 'roomItem.name.' + this._furniData.id;
|
||||
}
|
||||
|
||||
public get bundlePurchaseAllowed(): boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public get isRentOffer(): boolean
|
||||
{
|
||||
return (this._furniData.rentOfferId > -1);
|
||||
}
|
||||
|
||||
public get giftable(): boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public get pricingModel(): string
|
||||
{
|
||||
return Offer.PRICING_MODEL_FURNITURE;
|
||||
}
|
||||
|
||||
public get clubLevel(): number
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get badgeCode(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public get localizationName(): string
|
||||
{
|
||||
return this._furniData.name;
|
||||
}
|
||||
|
||||
public get localizationDescription(): string
|
||||
{
|
||||
return this._furniData.description;
|
||||
}
|
||||
|
||||
public get isLazy(): boolean
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { GetRoomEngine } from '../nitro';
|
||||
import { ProductTypeEnum } from './ProductTypeEnum';
|
||||
|
||||
export const GetImageIconUrlForProduct = (productType: string, productClassId: number, extraData: string = null) =>
|
||||
{
|
||||
let imageUrl: string = null;
|
||||
|
||||
switch(productType.toLocaleLowerCase())
|
||||
{
|
||||
case ProductTypeEnum.FLOOR:
|
||||
imageUrl = GetRoomEngine().getFurnitureFloorIconUrl(productClassId);
|
||||
break;
|
||||
case ProductTypeEnum.WALL:
|
||||
imageUrl = GetRoomEngine().getFurnitureWallIconUrl(productClassId, extraData);
|
||||
break;
|
||||
}
|
||||
|
||||
return imageUrl;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import { GiftWrappingConfigurationParser } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class GiftWrappingConfiguration
|
||||
{
|
||||
private _isEnabled: boolean = false;
|
||||
private _price: number = null;
|
||||
private _stuffTypes: number[] = null;
|
||||
private _boxTypes: number[] = null;
|
||||
private _ribbonTypes: number[] = null;
|
||||
private _defaultStuffTypes: number[] = null;
|
||||
|
||||
constructor(parser: GiftWrappingConfigurationParser)
|
||||
{
|
||||
this._isEnabled = parser.isEnabled;
|
||||
this._price = parser.price;
|
||||
this._boxTypes = parser.boxTypes;
|
||||
this._ribbonTypes = parser.ribbonTypes;
|
||||
this._stuffTypes = parser.giftWrappers;
|
||||
this._defaultStuffTypes = parser.giftFurnis;
|
||||
}
|
||||
|
||||
public get isEnabled(): boolean
|
||||
{
|
||||
return this._isEnabled;
|
||||
}
|
||||
|
||||
public get price(): number
|
||||
{
|
||||
return this._price;
|
||||
}
|
||||
|
||||
public get stuffTypes(): number[]
|
||||
{
|
||||
return this._stuffTypes;
|
||||
}
|
||||
|
||||
public get boxTypes(): number[]
|
||||
{
|
||||
return this._boxTypes;
|
||||
}
|
||||
|
||||
public get ribbonTypes(): number[]
|
||||
{
|
||||
return this._ribbonTypes;
|
||||
}
|
||||
|
||||
public get defaultStuffTypes(): number[]
|
||||
{
|
||||
return this._defaultStuffTypes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
export interface ICatalogNode
|
||||
{
|
||||
activate(): void;
|
||||
deactivate(): void;
|
||||
open(): void;
|
||||
close(): void;
|
||||
addChild(node: ICatalogNode): void;
|
||||
readonly depth: number;
|
||||
readonly isBranch: boolean;
|
||||
readonly isLeaf: boolean;
|
||||
readonly localization: string;
|
||||
readonly pageId: number;
|
||||
readonly pageName: string;
|
||||
readonly iconId: number;
|
||||
readonly children: ICatalogNode[];
|
||||
readonly offerIds: number[];
|
||||
readonly parent: ICatalogNode;
|
||||
readonly isVisible: boolean;
|
||||
readonly isActive: boolean;
|
||||
readonly isOpen: boolean;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { ClubGiftInfoParser, ClubOfferData, HabboGroupEntryData, MarketplaceConfigurationMessageParser } from '@nitrots/nitro-renderer';
|
||||
import { CatalogPetPalette } from './CatalogPetPalette';
|
||||
import { GiftWrappingConfiguration } from './GiftWrappingConfiguration';
|
||||
|
||||
export interface ICatalogOptions
|
||||
{
|
||||
groups?: HabboGroupEntryData[];
|
||||
petPalettes?: CatalogPetPalette[];
|
||||
clubOffers?: ClubOfferData[];
|
||||
clubGifts?: ClubGiftInfoParser;
|
||||
giftConfiguration?: GiftWrappingConfiguration;
|
||||
marketplaceConfiguration?: MarketplaceConfigurationMessageParser;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { IPageLocalization } from './IPageLocalization';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
||||
export interface ICatalogPage
|
||||
{
|
||||
readonly pageId: number;
|
||||
readonly layoutCode: string;
|
||||
readonly localization: IPageLocalization;
|
||||
readonly offers: IPurchasableOffer[];
|
||||
readonly acceptSeasonCurrencyAsCredits: boolean;
|
||||
readonly mode: number;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export interface IMarketplaceSearchOptions
|
||||
{
|
||||
query: string;
|
||||
type: number;
|
||||
minPrice: number;
|
||||
maxPrice: number;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export interface IPageLocalization
|
||||
{
|
||||
getText(index: number): string
|
||||
getImage(index: number): string
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { IFurnitureData, IProductData } from '@nitrots/nitro-renderer';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
||||
export interface IProduct
|
||||
{
|
||||
getIconUrl(offer?: IPurchasableOffer): string;
|
||||
productType: string;
|
||||
productClassId: number;
|
||||
extraParam: string;
|
||||
productCount: number;
|
||||
productData: IProductData;
|
||||
furnitureData: IFurnitureData;
|
||||
isUniqueLimitedItem: boolean;
|
||||
uniqueLimitedItemSeriesSize: number;
|
||||
uniqueLimitedItemsLeft: number;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { ICatalogPage } from './ICatalogPage';
|
||||
import { IProduct } from './IProduct';
|
||||
|
||||
export interface IPurchasableOffer
|
||||
{
|
||||
activate(): void;
|
||||
clubLevel: number;
|
||||
page: ICatalogPage;
|
||||
offerId: number;
|
||||
localizationId: string;
|
||||
priceInCredits: number;
|
||||
priceInActivityPoints: number;
|
||||
activityPointType: number;
|
||||
giftable: boolean;
|
||||
product: IProduct;
|
||||
pricingModel: string;
|
||||
priceType: string;
|
||||
bundlePurchaseAllowed: boolean;
|
||||
isRentOffer: boolean;
|
||||
badgeCode: string;
|
||||
localizationName: string;
|
||||
localizationDescription: string;
|
||||
isLazy: boolean;
|
||||
products: IProduct[];
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { IObjectData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface IPurchaseOptions
|
||||
{
|
||||
quantity?: number;
|
||||
extraData?: string;
|
||||
extraParamRequired?: boolean;
|
||||
previewStuffData?: IObjectData;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
import { IObjectData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class MarketplaceOfferData
|
||||
{
|
||||
public static readonly TYPE_FLOOR: number = 1;
|
||||
public static readonly TYPE_WALL: number = 2;
|
||||
|
||||
private _offerId: number;
|
||||
private _furniId: number;
|
||||
private _furniType: number;
|
||||
private _extraData: string;
|
||||
private _stuffData: IObjectData;
|
||||
private _price: number;
|
||||
private _averagePrice: number;
|
||||
private _imageCallback: number;
|
||||
private _status: number;
|
||||
private _timeLeftMinutes: number = -1;
|
||||
private _offerCount: number;
|
||||
private _image: string;
|
||||
|
||||
constructor(offerId: number, furniId: number, furniType: number, extraData: string, stuffData: IObjectData, price: number, status: number, averagePrice: number, offerCount: number = -1)
|
||||
{
|
||||
this._offerId = offerId;
|
||||
this._furniId = furniId;
|
||||
this._furniType = furniType;
|
||||
this._extraData = extraData;
|
||||
this._stuffData = stuffData;
|
||||
this._price = price;
|
||||
this._status = status;
|
||||
this._averagePrice = averagePrice;
|
||||
this._offerCount = offerCount;
|
||||
}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return this._offerId;
|
||||
}
|
||||
|
||||
public set offerId(offerId: number)
|
||||
{
|
||||
this._offerId = offerId;
|
||||
}
|
||||
|
||||
public get furniId(): number
|
||||
{
|
||||
return this._furniId;
|
||||
}
|
||||
|
||||
public get furniType(): number
|
||||
{
|
||||
return this._furniType;
|
||||
}
|
||||
|
||||
public get extraData(): string
|
||||
{
|
||||
return this._extraData;
|
||||
}
|
||||
|
||||
public get stuffData(): IObjectData
|
||||
{
|
||||
return this._stuffData;
|
||||
}
|
||||
|
||||
public get price(): number
|
||||
{
|
||||
return this._price;
|
||||
}
|
||||
|
||||
public set price(price: number)
|
||||
{
|
||||
this._price = price;
|
||||
}
|
||||
|
||||
public get averagePrice(): number
|
||||
{
|
||||
return this._averagePrice;
|
||||
}
|
||||
|
||||
public get image(): string
|
||||
{
|
||||
return this._image;
|
||||
}
|
||||
|
||||
public set image(image: string)
|
||||
{
|
||||
this._image = image;
|
||||
}
|
||||
|
||||
public get imageCallback(): number
|
||||
{
|
||||
return this._imageCallback;
|
||||
}
|
||||
|
||||
public set imageCallback(callback: number)
|
||||
{
|
||||
this._imageCallback = callback;
|
||||
}
|
||||
|
||||
public get status(): number
|
||||
{
|
||||
return this._status;
|
||||
}
|
||||
|
||||
public get timeLeftMinutes(): number
|
||||
{
|
||||
return this._timeLeftMinutes;
|
||||
}
|
||||
|
||||
public set timeLeftMinutes(minutes: number)
|
||||
{
|
||||
this._timeLeftMinutes = minutes;
|
||||
}
|
||||
|
||||
public get offerCount(): number
|
||||
{
|
||||
return this._offerCount;
|
||||
}
|
||||
|
||||
public set offerCount(count: number)
|
||||
{
|
||||
this._offerCount = count;
|
||||
}
|
||||
|
||||
public get isUniqueLimitedItem(): boolean
|
||||
{
|
||||
return (this.stuffData && (this.stuffData.uniqueSeries > 0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export class MarketPlaceOfferState
|
||||
{
|
||||
public static readonly ONGOING = 1;
|
||||
public static readonly ONGOING_OWN = 1;
|
||||
public static readonly SOLD = 2;
|
||||
public static readonly EXPIRED = 3;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export class MarketplaceSearchType
|
||||
{
|
||||
public static readonly BY_ACTIVITY = 1;
|
||||
public static readonly BY_VALUE = 2;
|
||||
public static readonly ADVANCED = 3;
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
import { GetFurnitureData, GetProductDataForLocalization, LocalizeText, ProductTypeEnum } from '..';
|
||||
import { ICatalogPage } from './ICatalogPage';
|
||||
import { IProduct } from './IProduct';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
import { Product } from './Product';
|
||||
|
||||
export class Offer implements IPurchasableOffer
|
||||
{
|
||||
public static PRICING_MODEL_UNKNOWN: string = 'pricing_model_unknown';
|
||||
public static PRICING_MODEL_SINGLE: string = 'pricing_model_single';
|
||||
public static PRICING_MODEL_MULTI: string = 'pricing_model_multi';
|
||||
public static PRICING_MODEL_BUNDLE: string = 'pricing_model_bundle';
|
||||
public static PRICING_MODEL_FURNITURE: string = 'pricing_model_furniture';
|
||||
public static PRICE_TYPE_NONE: string = 'price_type_none';
|
||||
public static PRICE_TYPE_CREDITS: string = 'price_type_credits';
|
||||
public static PRICE_TYPE_ACTIVITYPOINTS: string = 'price_type_activitypoints';
|
||||
public static PRICE_TYPE_CREDITS_ACTIVITYPOINTS: string = 'price_type_credits_and_activitypoints';
|
||||
|
||||
private _pricingModel: string;
|
||||
private _priceType: string;
|
||||
private _offerId: number;
|
||||
private _localizationId: string;
|
||||
private _priceInCredits: number;
|
||||
private _priceInActivityPoints: number;
|
||||
private _activityPointType: number;
|
||||
private _giftable: boolean;
|
||||
private _isRentOffer: boolean;
|
||||
private _page: ICatalogPage;
|
||||
private _clubLevel: number = 0;
|
||||
private _products: IProduct[];
|
||||
private _badgeCode: string;
|
||||
private _bundlePurchaseAllowed: boolean = false;
|
||||
|
||||
constructor(offerId: number, localizationId: string, isRentOffer: boolean, priceInCredits: number, priceInActivityPoints: number, activityPointType: number, giftable: boolean, clubLevel: number, products: IProduct[], bundlePurchaseAllowed: boolean)
|
||||
{
|
||||
this._offerId = offerId;
|
||||
this._localizationId = localizationId;
|
||||
this._isRentOffer = isRentOffer;
|
||||
this._priceInCredits = priceInCredits;
|
||||
this._priceInActivityPoints = priceInActivityPoints;
|
||||
this._activityPointType = activityPointType;
|
||||
this._giftable = giftable;
|
||||
this._clubLevel = clubLevel;
|
||||
this._products = products;
|
||||
this._bundlePurchaseAllowed = bundlePurchaseAllowed;
|
||||
|
||||
this.setPricingModelForProducts();
|
||||
this.setPricingType();
|
||||
|
||||
for(const product of products)
|
||||
{
|
||||
if(product.productType === ProductTypeEnum.BADGE)
|
||||
{
|
||||
this._badgeCode = product.extraParam;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public activate(): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public get clubLevel(): number
|
||||
{
|
||||
return this._clubLevel;
|
||||
}
|
||||
|
||||
public get page(): ICatalogPage
|
||||
{
|
||||
return this._page;
|
||||
}
|
||||
|
||||
public set page(k: ICatalogPage)
|
||||
{
|
||||
this._page = k;
|
||||
}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return this._offerId;
|
||||
}
|
||||
|
||||
public get localizationId(): string
|
||||
{
|
||||
return this._localizationId;
|
||||
}
|
||||
|
||||
public get priceInCredits(): number
|
||||
{
|
||||
return this._priceInCredits;
|
||||
}
|
||||
|
||||
public get priceInActivityPoints(): number
|
||||
{
|
||||
return this._priceInActivityPoints;
|
||||
}
|
||||
|
||||
public get activityPointType(): number
|
||||
{
|
||||
return this._activityPointType;
|
||||
}
|
||||
|
||||
public get giftable(): boolean
|
||||
{
|
||||
return this._giftable;
|
||||
}
|
||||
|
||||
public get product(): IProduct
|
||||
{
|
||||
if(!this._products || !this._products.length) return null;
|
||||
|
||||
if(this._products.length === 1) return this._products[0];
|
||||
|
||||
const products = Product.stripAddonProducts(this._products);
|
||||
|
||||
if(products.length) return products[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get pricingModel(): string
|
||||
{
|
||||
return this._pricingModel;
|
||||
}
|
||||
|
||||
public get priceType(): string
|
||||
{
|
||||
return this._priceType;
|
||||
}
|
||||
|
||||
public get bundlePurchaseAllowed(): boolean
|
||||
{
|
||||
return this._bundlePurchaseAllowed;
|
||||
}
|
||||
|
||||
public get isRentOffer(): boolean
|
||||
{
|
||||
return this._isRentOffer;
|
||||
}
|
||||
|
||||
public get badgeCode(): string
|
||||
{
|
||||
return this._badgeCode;
|
||||
}
|
||||
|
||||
public get localizationName(): string
|
||||
{
|
||||
const productData = GetProductDataForLocalization(this._localizationId);
|
||||
|
||||
if(productData) return productData.name;
|
||||
|
||||
return LocalizeText(this._localizationId);
|
||||
}
|
||||
|
||||
public get localizationDescription(): string
|
||||
{
|
||||
const productData = GetProductDataForLocalization(this._localizationId);
|
||||
|
||||
if(productData) return productData.description;
|
||||
|
||||
return LocalizeText(this._localizationId);
|
||||
}
|
||||
|
||||
public get isLazy(): boolean
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public get products(): IProduct[]
|
||||
{
|
||||
return this._products;
|
||||
}
|
||||
|
||||
private setPricingModelForProducts(): void
|
||||
{
|
||||
const products = Product.stripAddonProducts(this._products);
|
||||
|
||||
if(products.length === 1)
|
||||
{
|
||||
if(products[0].productCount === 1)
|
||||
{
|
||||
this._pricingModel = Offer.PRICING_MODEL_SINGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._pricingModel = Offer.PRICING_MODEL_MULTI;
|
||||
}
|
||||
}
|
||||
|
||||
else if(products.length > 1)
|
||||
{
|
||||
this._pricingModel = Offer.PRICING_MODEL_BUNDLE;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
this._pricingModel = Offer.PRICING_MODEL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private setPricingType(): void
|
||||
{
|
||||
if((this._priceInCredits > 0) && (this._priceInActivityPoints > 0))
|
||||
{
|
||||
this._priceType = Offer.PRICE_TYPE_CREDITS_ACTIVITYPOINTS;
|
||||
}
|
||||
|
||||
else if(this._priceInCredits > 0)
|
||||
{
|
||||
this._priceType = Offer.PRICE_TYPE_CREDITS;
|
||||
}
|
||||
|
||||
else if(this._priceInActivityPoints > 0)
|
||||
{
|
||||
this._priceType = Offer.PRICE_TYPE_ACTIVITYPOINTS;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
this._priceType = Offer.PRICE_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public clone(): IPurchasableOffer
|
||||
{
|
||||
const products: IProduct[] = [];
|
||||
const productData = GetProductDataForLocalization(this.localizationId);
|
||||
|
||||
for(const product of this._products)
|
||||
{
|
||||
const furnitureData = GetFurnitureData(product.productClassId, product.productType);
|
||||
|
||||
products.push(new Product(product.productType, product.productClassId, product.extraParam, product.productCount, productData, furnitureData));
|
||||
}
|
||||
|
||||
const offer = new Offer(this.offerId, this.localizationId, this.isRentOffer, this.priceInCredits, this.priceInActivityPoints, this.activityPointType, this.giftable, this.clubLevel, products, this.bundlePurchaseAllowed);
|
||||
|
||||
offer.page = this.page;
|
||||
|
||||
return offer;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import { GetConfiguration } from '../nitro';
|
||||
import { IPageLocalization } from './IPageLocalization';
|
||||
|
||||
export class PageLocalization implements IPageLocalization
|
||||
{
|
||||
private _images: string[];
|
||||
private _texts: string[]
|
||||
|
||||
constructor(images: string[], texts: string[])
|
||||
{
|
||||
this._images = images;
|
||||
this._texts = texts;
|
||||
}
|
||||
|
||||
public getText(index: number): string
|
||||
{
|
||||
let message = (this._texts[index] || '');
|
||||
|
||||
if(message && message.length) message = message.replace(/\r\n|\r|\n/g, '<br />');
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
public getImage(index: number): string
|
||||
{
|
||||
const imageName = (this._images[index] || '');
|
||||
|
||||
if(!imageName || !imageName.length) return null;
|
||||
|
||||
let assetUrl = GetConfiguration<string>('catalog.asset.image.url');
|
||||
|
||||
assetUrl = assetUrl.replace('%name%', imageName);
|
||||
|
||||
return assetUrl;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { IFurnitureData, IProductData } from '@nitrots/nitro-renderer';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
||||
export class PlacedObjectPurchaseData
|
||||
{
|
||||
constructor(
|
||||
public readonly roomId: number,
|
||||
public readonly objectId: number,
|
||||
public readonly category: number,
|
||||
public readonly wallLocation: string,
|
||||
public readonly x: number,
|
||||
public readonly y: number,
|
||||
public readonly direction: number,
|
||||
public readonly offer: IPurchasableOffer)
|
||||
{}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return this.offer.offerId;
|
||||
}
|
||||
|
||||
public get productClassId(): number
|
||||
{
|
||||
return this.offer.product.productClassId;
|
||||
}
|
||||
|
||||
public get productData(): IProductData
|
||||
{
|
||||
return this.offer.product.productData;
|
||||
}
|
||||
|
||||
public get furniData(): IFurnitureData
|
||||
{
|
||||
return this.offer.product.furnitureData;
|
||||
}
|
||||
|
||||
public get extraParam(): string
|
||||
{
|
||||
return this.offer.product.extraParam;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
import { IFurnitureData, IObjectData, IProductData } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration, GetRoomEngine, GetSessionDataManager } from '../nitro';
|
||||
import { GetPixelEffectIcon, GetSubscriptionProductIcon } from './CatalogUtilities';
|
||||
import { IProduct } from './IProduct';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
import { ProductTypeEnum } from './ProductTypeEnum';
|
||||
|
||||
export class Product implements IProduct
|
||||
{
|
||||
public static EFFECT_CLASSID_NINJA_DISAPPEAR: number = 108;
|
||||
|
||||
private _productType: string;
|
||||
private _productClassId: number;
|
||||
private _extraParam: string;
|
||||
private _productCount: number;
|
||||
private _productData: IProductData;
|
||||
private _furnitureData: IFurnitureData;
|
||||
private _isUniqueLimitedItem: boolean;
|
||||
private _uniqueLimitedItemSeriesSize: number;
|
||||
private _uniqueLimitedItemsLeft: number;
|
||||
|
||||
constructor(productType: string, productClassId: number, extraParam: string, productCount: number, productData: IProductData, furnitureData: IFurnitureData, isUniqueLimitedItem: boolean = false, uniqueLimitedItemSeriesSize: number = 0, uniqueLimitedItemsLeft: number = 0)
|
||||
{
|
||||
this._productType = productType.toLowerCase();
|
||||
this._productClassId = productClassId;
|
||||
this._extraParam = extraParam;
|
||||
this._productCount = productCount;
|
||||
this._productData = productData;
|
||||
this._furnitureData = furnitureData;
|
||||
this._isUniqueLimitedItem = isUniqueLimitedItem;
|
||||
this._uniqueLimitedItemSeriesSize = uniqueLimitedItemSeriesSize;
|
||||
this._uniqueLimitedItemsLeft = uniqueLimitedItemsLeft;
|
||||
}
|
||||
|
||||
public static stripAddonProducts(products: IProduct[]): IProduct[]
|
||||
{
|
||||
if(products.length === 1) return products;
|
||||
|
||||
return products.filter(product => ((product.productType !== ProductTypeEnum.BADGE) && (product.productType !== ProductTypeEnum.EFFECT) && (product.productClassId !== Product.EFFECT_CLASSID_NINJA_DISAPPEAR)));
|
||||
}
|
||||
|
||||
public getIconUrl(offer: IPurchasableOffer = null, stuffData: IObjectData = null): string
|
||||
{
|
||||
switch(this._productType)
|
||||
{
|
||||
case ProductTypeEnum.FLOOR:
|
||||
return GetRoomEngine().getFurnitureFloorIconUrl(this.productClassId);
|
||||
case ProductTypeEnum.WALL: {
|
||||
if(offer && this._furnitureData)
|
||||
{
|
||||
let iconName = '';
|
||||
|
||||
switch(this._furnitureData.className)
|
||||
{
|
||||
case 'floor':
|
||||
iconName = [ 'th', this._furnitureData.className, offer.product.extraParam ].join('_');
|
||||
break;
|
||||
case 'wallpaper':
|
||||
iconName = [ 'th', 'wall', offer.product.extraParam ].join('_');
|
||||
break;
|
||||
case 'landscape':
|
||||
iconName = [ 'th', this._furnitureData.className, (offer.product.extraParam || '').replace('.', '_'), '001' ].join('_');
|
||||
break;
|
||||
}
|
||||
|
||||
if(iconName !== '')
|
||||
{
|
||||
const assetUrl = GetConfiguration<string>('catalog.asset.url');
|
||||
|
||||
return `${ assetUrl }/${ iconName }.png`;
|
||||
}
|
||||
}
|
||||
|
||||
return GetRoomEngine().getFurnitureWallIconUrl(this.productClassId, this._extraParam);
|
||||
}
|
||||
case ProductTypeEnum.EFFECT:
|
||||
return GetPixelEffectIcon(this.productClassId);
|
||||
case ProductTypeEnum.HABBO_CLUB:
|
||||
return GetSubscriptionProductIcon(this.productClassId);
|
||||
case ProductTypeEnum.BADGE:
|
||||
return GetSessionDataManager().getBadgeUrl(this._extraParam);
|
||||
case ProductTypeEnum.ROBOT:
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get productType(): string
|
||||
{
|
||||
return this._productType;
|
||||
}
|
||||
|
||||
public get productClassId(): number
|
||||
{
|
||||
return this._productClassId;
|
||||
}
|
||||
|
||||
public get extraParam(): string
|
||||
{
|
||||
return this._extraParam;
|
||||
}
|
||||
|
||||
public set extraParam(extraParam: string)
|
||||
{
|
||||
this._extraParam = extraParam;
|
||||
}
|
||||
|
||||
public get productCount(): number
|
||||
{
|
||||
return this._productCount;
|
||||
}
|
||||
|
||||
public get productData(): IProductData
|
||||
{
|
||||
return this._productData;
|
||||
}
|
||||
|
||||
public get furnitureData(): IFurnitureData
|
||||
{
|
||||
return this._furnitureData;
|
||||
}
|
||||
|
||||
public get isUniqueLimitedItem(): boolean
|
||||
{
|
||||
return this._isUniqueLimitedItem;
|
||||
}
|
||||
|
||||
public get uniqueLimitedItemSeriesSize(): number
|
||||
{
|
||||
return this._uniqueLimitedItemSeriesSize;
|
||||
}
|
||||
|
||||
public get uniqueLimitedItemsLeft(): number
|
||||
{
|
||||
return this._uniqueLimitedItemsLeft;
|
||||
}
|
||||
|
||||
public set uniqueLimitedItemsLeft(uniqueLimitedItemsLeft: number)
|
||||
{
|
||||
this._uniqueLimitedItemsLeft = uniqueLimitedItemsLeft;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
export class ProductTypeEnum
|
||||
{
|
||||
public static WALL: string = 'i';
|
||||
public static FLOOR: string = 's';
|
||||
public static EFFECT: string = 'e';
|
||||
public static HABBO_CLUB: string = 'h';
|
||||
public static BADGE: string = 'b';
|
||||
public static GAME_TOKEN: string = 'GAME_TOKEN';
|
||||
public static PET: string = 'p';
|
||||
public static ROBOT: string = 'r';
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
export class RequestedPage
|
||||
{
|
||||
public static REQUEST_TYPE_NONE: number = 0;
|
||||
public static REQUEST_TYPE_ID: number = 1;
|
||||
public static REQUEST_TYPE_OFFER: number = 2;
|
||||
public static REQUEST_TYPE_NAME: number = 3;
|
||||
|
||||
private _requestType: number;
|
||||
private _requestById: number;
|
||||
private _requestedByOfferId: number;
|
||||
private _requestByName: string;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this._requestType = RequestedPage.REQUEST_TYPE_NONE;
|
||||
}
|
||||
|
||||
public resetRequest():void
|
||||
{
|
||||
this._requestType = RequestedPage.REQUEST_TYPE_NONE;
|
||||
this._requestById = -1;
|
||||
this._requestedByOfferId = -1;
|
||||
this._requestByName = null;
|
||||
}
|
||||
|
||||
public get requestType(): number
|
||||
{
|
||||
return this._requestType;
|
||||
}
|
||||
|
||||
public get requestById(): number
|
||||
{
|
||||
return this._requestById;
|
||||
}
|
||||
|
||||
public set requestById(id: number)
|
||||
{
|
||||
this._requestType = RequestedPage.REQUEST_TYPE_ID;
|
||||
this._requestById = id;
|
||||
}
|
||||
|
||||
public get requestedByOfferId(): number
|
||||
{
|
||||
return this._requestedByOfferId;
|
||||
}
|
||||
|
||||
public set requestedByOfferId(offerId: number)
|
||||
{
|
||||
this._requestType = RequestedPage.REQUEST_TYPE_OFFER;
|
||||
this._requestedByOfferId = offerId;
|
||||
}
|
||||
|
||||
public get requestByName(): string
|
||||
{
|
||||
return this._requestByName;
|
||||
}
|
||||
|
||||
public set requestByName(name: string)
|
||||
{
|
||||
this._requestType = RequestedPage.REQUEST_TYPE_NAME;
|
||||
this._requestByName = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { ICatalogNode } from './ICatalogNode';
|
||||
import { IPurchasableOffer } from './IPurchasableOffer';
|
||||
|
||||
export class SearchResult
|
||||
{
|
||||
constructor(
|
||||
public readonly searchValue: string,
|
||||
public readonly offers: IPurchasableOffer[],
|
||||
public readonly filteredNodes: ICatalogNode[])
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
export * from './BuilderFurniPlaceableStatus';
|
||||
export * from './CatalogNode';
|
||||
export * from './CatalogPage';
|
||||
export * from './CatalogPageName';
|
||||
export * from './CatalogPetPalette';
|
||||
export * from './CatalogPurchaseState';
|
||||
export * from './CatalogType';
|
||||
export * from './CatalogUtilities';
|
||||
export * from './FurnitureOffer';
|
||||
export * from './GetImageIconUrlForProduct';
|
||||
export * from './GiftWrappingConfiguration';
|
||||
export * from './ICatalogNode';
|
||||
export * from './ICatalogOptions';
|
||||
export * from './ICatalogPage';
|
||||
export * from './IMarketplaceSearchOptions';
|
||||
export * from './IPageLocalization';
|
||||
export * from './IProduct';
|
||||
export * from './IPurchasableOffer';
|
||||
export * from './IPurchaseOptions';
|
||||
export * from './MarketplaceOfferData';
|
||||
export * from './MarketplaceOfferState';
|
||||
export * from './MarketplaceSearchType';
|
||||
export * from './Offer';
|
||||
export * from './PageLocalization';
|
||||
export * from './PlacedObjectPurchaseData';
|
||||
export * from './Product';
|
||||
export * from './ProductTypeEnum';
|
||||
export * from './RequestedPage';
|
||||
export * from './SearchResult';
|
|
@ -0,0 +1,6 @@
|
|||
export class ChatEntryType
|
||||
{
|
||||
public static TYPE_CHAT = 1;
|
||||
public static TYPE_ROOM_INFO = 2;
|
||||
public static TYPE_IM = 3;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export const ChatHistoryCurrentDate = () =>
|
||||
{
|
||||
const currentTime = new Date();
|
||||
|
||||
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
export interface IChatEntry
|
||||
{
|
||||
id: number;
|
||||
webId: number;
|
||||
entityId: number;
|
||||
name: string;
|
||||
look?: string;
|
||||
message?: string;
|
||||
entityType?: number;
|
||||
style?: number;
|
||||
chatType?: number;
|
||||
imageUrl?: string;
|
||||
color?: string;
|
||||
roomId: number;
|
||||
timestamp: string;
|
||||
type: number;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export interface IRoomHistoryEntry
|
||||
{
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export const MessengerHistoryCurrentDate = (secondsSinceNow: number = 0) =>
|
||||
{
|
||||
const currentTime = secondsSinceNow ? new Date(Date.now() - secondsSinceNow * 1000) : new Date();
|
||||
|
||||
return `${ currentTime.getHours().toString().padStart(2, '0') }:${ currentTime.getMinutes().toString().padStart(2, '0') }`;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export * from './ChatEntryType';
|
||||
export * from './ChatHistoryCurrentDate';
|
||||
export * from './IChatEntry';
|
||||
export * from './IRoomHistoryEntry';
|
||||
export * from './MessengerHistoryCurrentDate';
|
|
@ -0,0 +1,3 @@
|
|||
import { IEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const DispatchEvent = (eventDispatcher: IEventDispatcher, event: NitroEvent) => eventDispatcher.dispatchEvent(event);
|
|
@ -0,0 +1,5 @@
|
|||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { GetNitroInstance } from '../nitro';
|
||||
import { DispatchEvent } from './DispatchEvent';
|
||||
|
||||
export const DispatchMainEvent = (event: NitroEvent) => DispatchEvent(GetNitroInstance().events, event);
|
|
@ -0,0 +1,5 @@
|
|||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { DispatchEvent } from './DispatchEvent';
|
||||
import { UI_EVENT_DISPATCHER } from './UI_EVENT_DISPATCHER';
|
||||
|
||||
export const DispatchUiEvent = (event: NitroEvent) => DispatchEvent(UI_EVENT_DISPATCHER, event);
|
|
@ -0,0 +1,3 @@
|
|||
import { EventDispatcher, IEventDispatcher } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const UI_EVENT_DISPATCHER: IEventDispatcher = new EventDispatcher();
|
|
@ -0,0 +1,4 @@
|
|||
export * from './DispatchEvent';
|
||||
export * from './DispatchMainEvent';
|
||||
export * from './DispatchUiEvent';
|
||||
export * from './UI_EVENT_DISPATCHER';
|
|
@ -0,0 +1,13 @@
|
|||
import { IGroupChatData } from './IGroupChatData';
|
||||
|
||||
export const GetGroupChatData = (extraData: string) =>
|
||||
{
|
||||
if(!extraData || !extraData.length) return null;
|
||||
|
||||
const splitData = extraData.split('/');
|
||||
const username = splitData[0];
|
||||
const figure = splitData[1];
|
||||
const userId = parseInt(splitData[2]);
|
||||
|
||||
return ({ username: username, figure: figure, userId: userId } as IGroupChatData);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface IGroupChatData
|
||||
{
|
||||
username: string;
|
||||
figure: string;
|
||||
userId: number;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import { FriendParser } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class MessengerFriend
|
||||
{
|
||||
public static RELATIONSHIP_NONE: number = 0;
|
||||
public static RELATIONSHIP_HEART: number = 1;
|
||||
public static RELATIONSHIP_SMILE: number = 2;
|
||||
public static RELATIONSHIP_BOBBA: number = 3;
|
||||
|
||||
public id: number = -1;
|
||||
public name: string = null;
|
||||
public gender: number = 0;
|
||||
public online: boolean = false;
|
||||
public followingAllowed: boolean = false;
|
||||
public figure: string = null;
|
||||
public categoryId: number = 0;
|
||||
public motto: string = null;
|
||||
public realName: string = null;
|
||||
public lastAccess: string = null;
|
||||
public persistedMessageUser: boolean = false;
|
||||
public vipMember: boolean = false;
|
||||
public pocketHabboUser: boolean = false;
|
||||
public relationshipStatus: number = -1;
|
||||
public unread: number = 0;
|
||||
|
||||
public populate(parser: FriendParser): void
|
||||
{
|
||||
this.id = parser.id;
|
||||
this.name = parser.name;
|
||||
this.gender = parser.gender;
|
||||
this.online = parser.online;
|
||||
this.followingAllowed = parser.followingAllowed;
|
||||
this.figure = parser.figure;
|
||||
this.categoryId = parser.categoryId;
|
||||
this.motto = parser.motto;
|
||||
this.realName = parser.realName;
|
||||
this.lastAccess = parser.lastAccess;
|
||||
this.persistedMessageUser = parser.persistedMessageUser;
|
||||
this.vipMember = parser.vipMember;
|
||||
this.pocketHabboUser = parser.pocketHabboUser;
|
||||
this.relationshipStatus = parser.relationshipStatus;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
export class MessengerGroupType
|
||||
{
|
||||
public static readonly GROUP_CHAT = 0;
|
||||
public static readonly PRIVATE_CHAT = 1;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export class MessengerIconState
|
||||
{
|
||||
public static HIDDEN: number = 0;
|
||||
public static SHOW: number = 1;
|
||||
public static UNREAD: number = 2;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { FriendRequestData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class MessengerRequest
|
||||
{
|
||||
private _id: number;
|
||||
private _name: string;
|
||||
private _requesterUserId: number;
|
||||
private _figureString: string;
|
||||
|
||||
public populate(data: FriendRequestData): boolean
|
||||
{
|
||||
if(!data) return false;
|
||||
|
||||
this._id = data.requestId;
|
||||
this._name = data.requesterName;
|
||||
this._figureString = data.figureString;
|
||||
this._requesterUserId = data.requesterUserId;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get requesterUserId(): number
|
||||
{
|
||||
return this._requesterUserId;
|
||||
}
|
||||
|
||||
public get figureString(): string
|
||||
{
|
||||
return this._figureString;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { FriendCategoryData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export class MessengerSettings
|
||||
{
|
||||
constructor(
|
||||
public userFriendLimit: number = 0,
|
||||
public normalFriendLimit: number = 0,
|
||||
public extendedFriendLimit: number = 0,
|
||||
public categories: FriendCategoryData[] = [])
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
import { GetGroupChatData } from './GetGroupChatData';
|
||||
import { MessengerFriend } from './MessengerFriend';
|
||||
import { MessengerGroupType } from './MessengerGroupType';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
import { MessengerThreadChatGroup } from './MessengerThreadChatGroup';
|
||||
|
||||
export class MessengerThread
|
||||
{
|
||||
public static MESSAGE_RECEIVED: string = 'MT_MESSAGE_RECEIVED';
|
||||
public static THREAD_ID: number = 0;
|
||||
|
||||
private _threadId: number;
|
||||
private _participant: MessengerFriend;
|
||||
private _groups: MessengerThreadChatGroup[];
|
||||
private _lastUpdated: Date;
|
||||
private _unreadCount: number;
|
||||
|
||||
constructor(participant: MessengerFriend)
|
||||
{
|
||||
this._threadId = ++MessengerThread.THREAD_ID;
|
||||
this._participant = participant;
|
||||
this._groups = [];
|
||||
this._lastUpdated = new Date();
|
||||
this._unreadCount = 0;
|
||||
}
|
||||
|
||||
public addMessage(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0): MessengerThreadChat
|
||||
{
|
||||
const isGroupChat = (senderId < 0 && extraData);
|
||||
const userId = isGroupChat ? GetGroupChatData(extraData).userId : senderId;
|
||||
|
||||
const group = this.getLastGroup(userId);
|
||||
|
||||
if(!group) return;
|
||||
|
||||
if(isGroupChat) group.type = MessengerGroupType.GROUP_CHAT;
|
||||
|
||||
const chat = new MessengerThreadChat(senderId, message, secondsSinceSent, extraData, type);
|
||||
|
||||
group.addChat(chat);
|
||||
|
||||
this._lastUpdated = new Date();
|
||||
|
||||
this._unreadCount++;
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
private getLastGroup(userId: number): MessengerThreadChatGroup
|
||||
{
|
||||
let group = this._groups[(this._groups.length - 1)];
|
||||
|
||||
if(group && (group.userId === userId)) return group;
|
||||
|
||||
group = new MessengerThreadChatGroup(userId);
|
||||
|
||||
this._groups.push(group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public setRead(): void
|
||||
{
|
||||
this._unreadCount = 0;
|
||||
}
|
||||
|
||||
public get threadId(): number
|
||||
{
|
||||
return this._threadId;
|
||||
}
|
||||
|
||||
public get participant(): MessengerFriend
|
||||
{
|
||||
return this._participant;
|
||||
}
|
||||
|
||||
public get groups(): MessengerThreadChatGroup[]
|
||||
{
|
||||
return this._groups;
|
||||
}
|
||||
|
||||
public get lastUpdated(): Date
|
||||
{
|
||||
return this._lastUpdated;
|
||||
}
|
||||
|
||||
public get unreadCount(): number
|
||||
{
|
||||
return this._unreadCount;
|
||||
}
|
||||
|
||||
public get unread(): boolean
|
||||
{
|
||||
return (this._unreadCount > 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
export class MessengerThreadChat
|
||||
{
|
||||
public static CHAT: number = 0;
|
||||
public static ROOM_INVITE: number = 1;
|
||||
public static STATUS_NOTIFICATION: number = 2;
|
||||
public static SECURITY_NOTIFICATION: number = 3;
|
||||
|
||||
private _type: number;
|
||||
private _senderId: number;
|
||||
private _message: string;
|
||||
private _secondsSinceSent: number;
|
||||
private _extraData: string;
|
||||
private _date: Date;
|
||||
|
||||
constructor(senderId: number, message: string, secondsSinceSent: number = 0, extraData: string = null, type: number = 0)
|
||||
{
|
||||
this._type = type;
|
||||
this._senderId = senderId;
|
||||
this._message = message;
|
||||
this._secondsSinceSent = secondsSinceSent;
|
||||
this._extraData = extraData;
|
||||
this._date = new Date();
|
||||
}
|
||||
|
||||
public get type(): number
|
||||
{
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public get senderId(): number
|
||||
{
|
||||
return this._senderId;
|
||||
}
|
||||
|
||||
public get message(): string
|
||||
{
|
||||
return this._message;
|
||||
}
|
||||
|
||||
public get secondsSinceSent(): number
|
||||
{
|
||||
return this._secondsSinceSent;
|
||||
}
|
||||
|
||||
public get extraData(): string
|
||||
{
|
||||
return this._extraData;
|
||||
}
|
||||
|
||||
public get date(): Date
|
||||
{
|
||||
return this._date;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import { MessengerGroupType } from './MessengerGroupType';
|
||||
import { MessengerThreadChat } from './MessengerThreadChat';
|
||||
|
||||
export class MessengerThreadChatGroup
|
||||
{
|
||||
private _userId: number;
|
||||
private _chats: MessengerThreadChat[];
|
||||
private _type: number;
|
||||
|
||||
constructor(userId: number, type = MessengerGroupType.PRIVATE_CHAT)
|
||||
{
|
||||
this._userId = userId;
|
||||
this._chats = [];
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
public addChat(message: MessengerThreadChat): void
|
||||
{
|
||||
this._chats.push(message);
|
||||
}
|
||||
|
||||
public get userId(): number
|
||||
{
|
||||
return this._userId;
|
||||
}
|
||||
|
||||
public get chats(): MessengerThreadChat[]
|
||||
{
|
||||
return this._chats;
|
||||
}
|
||||
|
||||
public get type(): number
|
||||
{
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public set type(type: number)
|
||||
{
|
||||
this._type = type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { CreateLinkEvent } from '..';
|
||||
|
||||
export function OpenMessengerChat(friendId: number = 0): void
|
||||
{
|
||||
if(friendId === 0) CreateLinkEvent('friends-messenger/toggle');
|
||||
else CreateLinkEvent(`friends-messenger/${ friendId }`);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
export * from './GetGroupChatData';
|
||||
export * from './IGroupChatData';
|
||||
export * from './MessengerFriend';
|
||||
export * from './MessengerGroupType';
|
||||
export * from './MessengerIconState';
|
||||
export * from './MessengerRequest';
|
||||
export * from './MessengerSettings';
|
||||
export * from './MessengerThread';
|
||||
export * from './MessengerThreadChat';
|
||||
export * from './MessengerThreadChatGroup';
|
||||
export * from './OpenMessengerChat';
|
|
@ -0,0 +1,7 @@
|
|||
import { GroupInformationComposer } from '@nitrots/nitro-renderer';
|
||||
import { SendMessageComposer } from '..';
|
||||
|
||||
export function GetGroupInformation(groupId: number): void
|
||||
{
|
||||
SendMessageComposer(new GroupInformationComposer(groupId, true));
|
||||
}
|