1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132 |
- /// <reference path="../wardrobe/OutfitItem/OutfitItem.ts" />
- /// <reference path="../wardrobe/OutfitItem/Clothes.ts" />
- /// <reference path="../wardrobe/OutfitItem/Purse.ts" />
- /// <reference path="../wardrobe/OutfitItem/Shoes.ts" />
- const enum EWearableBMI{
- NOT_APPLICABLE = -2,
- ANY = -1,
- TOO_LOSE = 0,
- TOO_TIGHT = 1,
- ALMOST_TOO_LOSE = 2,
- ALMOST_TOO_TIGHT = 3,
- OKAY = 4
- }
- setup.wardrobeSettings = {
- bmiSizeMaxDifference: 2
- }
- setup.outfitsDefaults={
- clothes:{
- h:100,
- bmi:'$pc.bmi'
- }
- }
- setup.wardrobeWearableFunctions = {};
- class Wardrobe{
- _ownedItems:{[itemId:string]:OutfitOwnerShipData} = {}
-
- /**
- * Owned Item
- * @param {string} itemId
- */
- item(itemId:string):OutfitOwned{
- let item = OutfitItem.get(itemId) as OutfitItemClothes; // Trick Typescript
- let owneditem:OutfitOwned = Object.assign(item,{l:0,bmi:-2,h:-2},this._ownedItems[itemId]); // Item needs to be first, otherwise all its functions are broken
- return owneditem;
- }
- /**
- * Owned Items
- * @readonly
- * @type {{[key:string]:OutfitItem}}
- */
- get items():{[key:string]:OutfitOwned}{
- let result:{[key:string]:OutfitOwned} = {};
- for(const [itemId, itemData] of Object.entries(this._ownedItems)){
- //let item = OutfitItem.get(itemId);
- //Object.assign({l:0,bmi:-2,h:-2},item,itemData);
- result[itemId] = this.item(itemId);
- }
- return result;
- }
- itemsFiltered(filter:Filter){
- return setup.filterDict(this.items,filter);
- }
- //#region Worn Items
- _wornItems:WornOutfitDefinition = {
- bra: null,
- coat: null,
- clothes: null,
- panties: null,
- purse: null,
- shoes: null
- }
- get wornItems(){
- return {
- bra: this.bra,
- coat: this.coat,
- clothes: this.clothes,
- panties: this.panties,
- purse: this.purse,
- shoes: this.shoes
- }
- }
- get wornItemIds(){
- return this._wornItems;
- }
- get bra():OutfitItemBra{
- let braId = this.wornItemIds.bra;
- if(braId)
- return this.item(braId) as OutfitItemBra;
- return new OutfitItemBra();
- }
- get clothes():OutfitItemClothes|OutfitItemSwimwear{
- let clothesId = this.wornItemIds.clothes;
- if(clothesId)
- return this.item(clothesId) as OutfitItemClothes;
- return new OutfitItemClothes();
- }
- get coat():OutfitItemCoat{
- let coatId = this.wornItemIds.coat;
- if(coatId)
- return this.item(coatId) as OutfitItemCoat;
- return new OutfitItemCoat();
- }
- get panties():OutfitItemPanties{
- let pantiesId = this.wornItemIds.panties;
- if(pantiesId)
- return this.item(pantiesId) as OutfitItemPanties;
- return new OutfitItemPanties();
- }
- get purse():OutfitItemPurse{
- let purseId = this.wornItemIds.purse;
- if(purseId)
- return this.item(purseId) as OutfitItemPurse;
- return new OutfitItemPurse();
- }
- get shoes():OutfitItemShoes{
- let shoesId = this.wornItemIds.shoes;
- if(shoesId)
- return this.item(shoesId) as OutfitItemShoes;
- return new OutfitItemShoes();
- }
- //#endregion
-
- _lastWorn:{[key:string]:WornOutfitDefinition} = {
- last:{
- bra: null,
- coat: null,
- clothes: null,
- panties: null,
- purse: null,
- shoes: null
- }
- }
- _outfits:{[key:string]:WornOutfitDefinition} = {
- }
- outfitSports = '';
- outfitSchool = '';
- get outfits(){
- return this._outfits;
- }
- clothingDecreaseHealth(v){
- let clothesId = this._wornItems.clothes;
- if(clothesId in this._ownedItems){
- if(this._ownedItems[clothesId].h > 0){ //Health -1 is save
- this._ownedItems[clothesId].h = Math.max(0,this._ownedItems[clothesId].h - v);
- }
- }
- }
- /*get clothingIsNude(){
- return (!this._wornItems.clothes);
- }*/
- /*get clothingWorn(){
- return this._wornItems.clothes;
- }*/
- /*get clothingworntype(){
- if(!this._wornItems.clothes)
- return 'nude';
- let identificator = this.itemData(this._wornItems.clothes) as OutfitDefinitionClothes;
- return identificator.vendor+'_'+identificator.subtype;
- }*/
- /*
- get clothingwornnumber(){
- if(!this._wornItems.clothes)
- return 0;
- let identificator = this.itemData(this._wornItems.clothes) as OutfitDefinitionClothes;
- return identificator.index;
- }*/
- /*get coatworntype(){
- if(!this._wornItems.coat)
- return 'none';
- let identificator = this.itemData(this._wornItems.coat);
- return identificator.vendor;
- }*/
- /*get coatwornnumber(){
- if(!this._wornItems.coat)
- return 0;
- let identificator = this.itemData(this._wornItems.coat);
- return identificator.index;
- }*/
- /*get isWearingBra(){
- return (!(!this._wornItems.bra));
- }*/
- /*get isWearingPanties(){
- return (!(!this._wornItems.panties));
- }*/
- get isNaked(){
- return (!this.clothes.isValidItem && !this.bra.isValidItem && !this.panties.isValidItem);
- }
- /*get PCloQuality(){
- if(this.clothingIsNude){
- let bmi = State.variables.pc.bmi;
- if(bmi >= 19 && bmi < 30)
- return 3;
- return 1;
- }
- return this.wornItemData('clothes','quality',0)
- }
- get PCloThinness(){return this.wornItemData('clothes','thinness',0)}
- get PCloTopCut(){
- const pc = State.variables.pc;
- let wiD = this.wornItemData('clothes','CloTopCut',0);
- if(wiD > 1){
- if(pc.tits == 2 || pc.tits == 3)
- wiD += 1;
- else if(pc.tits >= 4)
- wiD += 2;
- if(wiD > 2 && pc.tits >= 6)
- wiD += 1;
- }
- return wiD;
- }
- get PCloBra(){return this.wornItemData('clothes','includesBra',0)}
- get PCloOnePiece(){return this.wornItemData('clothes','isOnepiece',0)}
- get PCloPants(){return this.wornItemData('clothes','pantsShortness',0)}
- get PCloSkirt(){return this.wornItemData('clothes','skirtShortness',0)}
- get skirtLength(){return this.PCloSkirt;}
- get PCloPanties(){return this.wornItemData('clothes','includesPanties',0)}
- get PCloDress(){return this.wornItemData('clothes','isDress',0)}
- get PCloStyle(){return this.wornItemData('clothes','style',0)}
- get PCloStyle2(){return this.wornItemData('clothes','style2',0)}
- get PCloStyle3(){return this.wornItemData('clothes','style3',0)}
- get PCloInhibit(){return this.wornItemData('clothes','inhibition',0)}
- get PCloBimbo(){return this.wornItemData('clothes','bimbo',0)}
- get PCloCoverTop(){return this.wornItemData('clothes','coverTop',4)}
- get PCloCoverBack(){return this.wornItemData('clothes','coverBack',4)}
- get PCloCoverFront(){return this.wornItemData('clothes','coverFront',4)}
- //get PCloCoverFront(){return this.wornItemData('clothes','coverFront',0)}
- */
- /*get PXCloThinness(){
- let PCloThinness = this.PCloThinness;
- switch(PCloThinness){
- case 1: return 150;
- case 2: return 200;
- case 3: return 250;
- case 4: return 300;
- case 5: return 350;
- case 6: return 400;
- }
- if(PCloThinness > 6)
- return 400;
- return 0;
- }*/
- /*get PXCloTopCut(){
- if(this.PCloBra == 1) return 400;
- if(this.PCloBra == 2) return 500;
- let PCloTopCut = this.PCloTopCut;
- switch(PCloTopCut){
- case 1: return 100;
- case 2: return 150;
- case 3: return 200;
- case 4: return 250;
- case 5: return 300;
- case 6: return 350;
- case 7: return 400;
- }
- if(PCloTopCut > 7)
- return 400;
- return 0;
- }*/
- /*get PXCloBottomShortness(){
- if(this.PCloPanties == 1) return 400;
- let PCloSkirt = this.PCloSkirt;
- if(PCloSkirt > 0){
- switch(PCloSkirt){
- case 1: return 100;
- case 2: return 150;
- case 3: return 200;
- case 4: return 250;
- case 5: return 300;
- case 6: return 350;
- case 7: return 400;
- }
- if(this.PCloThinness > 7)
- return 400;
- }
- let PCloPants = this.PCloPants;
- if(PCloPants > 0){
- switch(PCloPants){
- case 1: return 100;
- case 2: return 150;
- case 3: return 200;
- case 4: return 250;
- case 5: return 300;
- case 6: return 350;
- case 7: return 400;
- }
- if(PCloPants > 7)
- return 400;
- }
- return 0;
- }*/
- /*get PCloswimwear(){
- if(!this._wornItems.clothes)
- return 0;
- let identificator = this.itemData(this._wornItems.clothes) as OutfitDefinitionClothes;
- if(identificator.subtype == 'bikini' || identificator.subtype == 'swimsuit' || identificator.subtype == 'swim_one' || identificator.subtype == 'swim_two')
- return 1;
- return 0;
- }*/
- /*get isWearingSwimwear(){
- return !(!this.PCloswimwear);
- }*/
- /*get CoverTop(){return Math.max(this.PCloCoverTop + this.PBraCover - 4,0);}
- get CoverBack(){return Math.max(this.PCloCoverBack + this.PPanCoverBack - 4,0);}
- get CoverFront(){return Math.max(this.PCloCoverFront + this.PPanCoverFront - 4,0);}
-
- get isSchoolOutfit(){
- return this.wornItemData('clothes','subtype','') === 'school';
- }
- get isSportsOutfit(){
- return this.clothingworntype === 'danilovich_outfit';
- }*/
- // ----- Bra -----
-
- /*get braworntype(){
- if(!this._wornItems.bra)
- return 'none';
- let identificator = this.itemData(this._wornItems.bra);
- return identificator.vendor;
- }
- get brawornnumber(){
- if(!this._wornItems.bra)
- return 0;
- let identificator = this.itemData(this._wornItems.bra);
- return identificator.index;
- }
- get PBraMaterial(){return this.wornItemData('bra','material',0)}
- get PBraType(){return this.wornItemData('bra','subtype',0)}
- get PBraFun(){return this.wornItemData('bra','fun',0)}
- get PBraQuality(){return this.wornItemData('bra','quality',0)}
- get PBraThinness(){return this.wornItemData('bra','thinness',0)}
- get PBraCover(){return this.wornItemData('bra','cover',0)}
- get bra_appearanceBonus(){
- //Todo: Should be saved in const data
- switch(this.braworntype){
- case 'lusso': return 4;
- case 'fashionista': return 2;
- }
- return 0;
- }*/
- // ----- Panties -----
- /*
- get pantyworntype(){ //<<set $pantyworntype = $location_var[$here][1]>>
- if(!this._wornItems.panties)
- return 'none';
- let identificator = this.itemData(this._wornItems.panties);
- return identificator.vendor;
- }
- get pantywornnumber(){ //<<set $pantywornnumber = $location_var[$here][2]>>
- if(!this._wornItems.panties)
- return 0;
- let identificator = this.itemData(this._wornItems.panties);
- return identificator.index;
- }
- get PPanMaterial(){return this.wornItemData('panties','material',0)}
- get PPantyFun(){return this.wornItemData('panties','fun',0)}
- get PPanQuality(){return this.wornItemData('panties','quality',0)}
- get PPanThinness(){return this.wornItemData('panties','thinness',0)}
- get PPanCoverFront(){return this.wornItemData('panties','coverFront',0)}
- get PPanCoverBack(){return this.wornItemData('panties','coverBack',0)}
- get PPanType(){return this.wornItemData('panties','subtype',0)}
- get panties_appearanceBonus(){
- //Todo: Should be saved in const data
- switch(this.pantyworntype){
- case 'lusso': return 4;
- case 'fashionista': return 2;
- }
- return 0;
- }*/
- // ----- Shoes -----
-
- /**
- * Is the character currently wearing shoes? They could be taken manually or autoatically, because the character is inside.
- * @type {boolean}
- */
- get isWearingShoes(){
- //return !(!this._wornItems.shoes);
- if(!this.shoes.isValidItem)
- return false;
- if(!State.variables.settings.shoes_keepOnPrivateIndoors && !State.variables.location.isPublic && !State.variables.location.isOutdoors)
- return false;
- return true;
- }
- itemImage(itemId:string):string{
- return OutfitItem.get(itemId).image;
- }
- /*get shoeworntype(){ //<<set $pantyworntype = $location_var[$here][1]>>
- if(!this._wornItems.shoes)
- return 'none';
- let identificator = this.itemData(this._wornItems.shoes);
- return identificator.vendor;
- }
- get shoewornnumber(){ //<<set $pantywornnumber = $location_var[$here][2]>>
- if(!this._wornItems.shoes)
- return 0;
- let identificator = this.itemData(this._wornItems.shoes);
- return identificator.index;
- }
- get PShoQuaility(){
- if(this.isWearingShoes)
- return this.wornItemData('shoes','quality',0)
- return 0;
- }
- get PShoCut(){
- if(this.isWearingShoes)
- return this.wornItemData('shoes','cut',0)
- return 0;
- }
- get PShoHeels(){
- if(this.isWearingShoes)
- return this.wornItemData('shoes','heels',0)
- return 0;
- }
- get PShoStyle(){
- if(this.isWearingShoes)
- return this.wornItemData('shoes','style',0)
- return 0;
- }*/
- /**
- * Return heel height of worn shoes in mm.
- * @readonly
- * @type {(0 | 60 | 100 | 150 | 200 | 240 | 280 | 300)}
- */
- /*get shoesHeight(){
- switch(this.PShoHeels){
- case 0: return 0;
- case 1: return 0;
- case 2: return 60;
- case 3: return 100;
- case 4: return 150;
- case 5: return 200;
- case 6: return 240;
- case 7: return 280;
- default: return 300;
- }
- }*/
- /**
- * Appearance Bonus of worn shoes.
- * @date 6/16/2023 - 7:05:32 AM
- *
- * @readonly
- * @type {(25 | 50 | 100 | 150 | 200 | 300 | 400 | 0)}
- */
- /*get PXShoHeels(){
- let PShoHeels = this.PShoHeels;
- if(PShoHeels > 0){
- switch(PShoHeels){
- case 1: return 25;
- case 2: return 50;
- case 3: return 100;
- case 4: return 150;
- case 5: return 200;
- case 6: return 300;
- case 7: return 400;
- }
- if(PShoHeels > 7)
- return 400;
- }
- return 0;
- }*/
- /*get shoes_appearanceBonus(){
- return this.PShoQuaility;
- }*/
- // ----- Coats -----
- /*get PCoatWarm(){return this.wornItemData('coat','warm',0)}
- get PCoatQuality(){return this.wornItemData('coat','quality',0)}
- get coat_appearanceBonus(){
- let location = State.variables.location;
- if(location.isOutdoors)
- return this.PCoatQuality - 2;
- return 0;
- }*/
- // ----- Purses -----
- /*get purseEquipped(){
- return (this._wornItems.purse) ? true : false;
- }
- */
- get outfitQuality(){
- if(this.isWearingShoes)
- return Math.floor((this.clothes.quality * 2 + this.shoes.quality) / 3);
- return this.clothes.quality;
- }
- get outfitIndecency(){
- return setup.func('outfitIndecency');
- }
-
- /**
- * Low-Level adds an item to the wardrobe.
- * @param {string} itemId
- * @param {{}} [metadata={}]
- */
- add(itemId:string,metadata: {}={}){
- let constData = this.itemConstantData(itemId);
- let type_defaults = setup.outfitsDefaults[constData.type] || {};
- let vendor_defaults = setup.outfitsDefaults[constData.vendor] || {};
- metadata = Object.assign({},type_defaults,vendor_defaults,metadata);
- let iterateObject = clone(metadata);
- for (const [key, value] of Object.entries(iterateObject)) {
- if(typeof value === "string" && value.startsWith('$'))
- metadata[key] = State.getVar(value);
- }
- this._ownedItems[itemId] = metadata;
- console.log("ITEM ADDED",itemId,metadata);
- }
-
- /**
- * Low-Level removes an item from the wardrobe.
- * @param {string} itemId
- */
- delete(itemId:string){
- delete this._ownedItems[itemId];
- }
- deleteOutfit(outfitId:string){
- return delete this.outfits[outfitId];
- }
- dispose(itemId:string){
- this.delete(itemId);
- }
- disposeWorn(type:string){
- let itemId = this._wornItems[type];
- if(itemId){
- this.strip(type);
- this.dispose(itemId);
- }
- }
-
- /**
- * All defined items.
- */
- get allItems(): {[key: string]: OutfitDefinition}{
- return setup.outfits;
- }
- allItemsFiltered(filter:Filter){
- return setup.filterDict(this.allItems,filter);
- }
- allItemIdsFiltered(filter:Filter,count=undefined,randomOrder=false){
- let itemIds = Object.keys(this.allItemsFiltered(filter));
- if(randomOrder)
- itemIds.shuffle();
- if(count)
- itemIds = itemIds.slice(0,count);
- return itemIds;
- }
- /**
- * Returns all items (owned or not) that match filters.
- * @param {*} filters
- * @returns
- */
- /*getItems(filters={}):{[key:string]:OutfitDefinition}{
- let items:{[key:string]:OutfitDefinition} = this.filterItems(this.allItems,filters);
- return items;
- }*/
- /*getItemIds(filters={},count=undefined,randomOrder=false){
- let itemIds = Object.keys(this.getItems(filters))
- if(randomOrder)
- itemIds.shuffle();
- if(count)
- itemIds = itemIds.slice(0,count);
- return itemIds;
- }*/
- /*filterItems(items:{[key:string]:OutfitDefinition},filters:Filter):{[key:string]:OutfitDefinition}{
- return setup.filterDict(items,filters);
- }*/
- // Gets a list of owned items
- /*getList(filters={}){
- let results = [];
- itemloop: for (const [item_id, item_data] of Object.entries(this._ownedItems)) {
- let itemData = this.get(item_id);
- let vendor = itemData.vendor;
- let type = itemData.type;
- let subtype = itemData.subtype;
- let index = itemData.index;
- filterloop: for (const [filter_key, filter_value] of Object.entries(filters)) {
- if(filter_value === null || filter_value === undefined)
- continue filterloop;
- if(filter_key == 'type'){
- if(type != filter_value)
- continue itemloop;
- continue filterloop;
- }else if(filter_key == 'vendor'){
- if(vendor != filter_value)
- continue itemloop;
- continue filterloop;
- }else if(filter_key == 'subtype'){
- if(subtype != filter_value)
- continue itemloop;
- continue filterloop;
- }else if(filter_key == 'index'){
- if(index != filter_value)
- continue itemloop;
- continue filterloop;
- }else if(filter_key == 'location'){
- if(Array.isArray(filter_value)){
- if(!filter_value.includes(itemData[filter_key]))
- continue itemloop;
- continue filterloop;
- }
- if(filter_value == -1)
- continue filterloop;
- if(filter_value == 0){
- if(!("location" in itemData) || itemData.location == 0)
- continue filterloop;
- continue itemloop;
- }
- if(!("location" in itemData))
- continue itemloop;
- if(itemData.location != filter_value)
- continue itemloop;
- continue filterloop;
- }else{
- if(Array.isArray(filter_value)){
- if(!filter_value.includes(itemData[filter_key] || 0))
- continue itemloop;
- continue filterloop;
- }else if(['string','number'].includes(typeof filter_value)){
- if(itemData[filter_key] != filter_value)
- continue itemloop;
- continue filterloop;
- }else{
- console.warn('Unreckognized filter format in $wardrobe.getlist():',filter_value);
- }
- }
- }
- let result = {
- id: item_id,
- type: type,
- vendor: vendor,
- subtype: subtype,
- index: index,
- image: this.itemImage(item_id),
- location: ("l" in item_data) ? item_data.l : 0,
- health: ("h" in item_data) ? item_data.h : -1,
- }
- results.push(result);
- }
- console.log("wardrobe.getList",filters,results);
- return results;
- }*/
- has(itemId){
- return (itemId in this._ownedItems);
- }
- inhibition(itemId:string){
- return OutfitItem.get(itemId).inhibition;
- }
- isWearing(itemId:string):boolean{
- for(const wornItemId of Object.values(this._wornItems)){
- if(itemId == wornItemId)
- return true;
- }
- return false;
- }
- isWeargingItemAtSlot(type){
- return(!(this._wornItems[type] == null));
- }
-
- /**
- * @deprecated
- * @param {string} itemId
- * @returns {OutfitDefinition}
- */
- itemConstantData(itemId:string):OutfitDefinition{
- if(!setup.outfits[itemId])
- return null;
- let raw = setup.outfits[itemId];
-
- return raw;
- }
- /**
- * Return the constant data of an item
- * @deprecated
- * @param {string} itemId
- * @returns
- */
- itemData(itemId:string):OutfitDefinition{
- let constantData = this.itemConstantData(itemId);
- return constantData;
- }
- /*itemImage(itemId){
- let identificator = this.itemData(itemId);
- let template = setup.outfitItemImagePath[identificator.type];
- if(!template)
- console.error("ERROR: template not found",identificator);
- if(typeof template === "string")
- return template.formatUnicorn({vendor:identificator.vendor,id:identificator.index});
- if(!template[identificator.vendor]?.[identificator.subtype])
- console.error("ERROR: item-image-template is undefined",identificator,template[identificator.vendor]);
- return template[identificator.vendor][identificator.subtype].formatUnicorn({vendor:identificator.vendor,id:identificator.index});
- }*/
- /*
- itemImageAtSlot(slotId){
- return this.itemImage(this._wornItems[slotId]);
- }*/
- itemPrice(itemId,baseprice,pricemod=0){
- let itemData = this.itemData(itemId);
- let type = itemData.type;
- if(type != 'shoes' && type != 'clothes')
- return baseprice;
- let quality = itemData.quality;
- let price_raw = (baseprice * ((5 * quality) + 100) / 100) * 1000 / (1250 - pricemod) * 3 / 2;
- let price_rounded = Math.round(price_raw / 50) * 50;
- return price_rounded;
- }
- lastWornSet(key){
- this._lastWorn[key] = clone(this._wornItems);
- }
- //#region Outfit
- outfitAdd(key, outfitData=null){
- if(!this._outfits)
- this._outfits = {};
- if(outfitData)
- this._outfits[key] = clone(outfitData);
- else
- this._outfits[key] = clone(this._wornItems);
- }
- outfitIsWearable(key){
- if(!(key in this._outfits)){
- return false;
- }
- let slots = ['bra','clothes','panties','shoes'];
- for(let slot of slots){
- let wearable = this.wearable(this._outfits[key][slot]);
- if(!wearable.total){
- return false;
- }
- }
- return true;
- }
- //#endregion
- get isWearingSwimwear():boolean{
- return (this.clothes.type == 'swimwear');
- }
- get ownsSwimmingItem():boolean{
- //return (this.getList({subtype:'bikini'}).length + this.getList({subtype:'swimsuit'}).length > 0) ? true : false;
- return (Object.keys(this.itemsFiltered({type:'swimwear'})).length > 0);
- }
- /**
- * Sends an item to the specified location.
- * Side effect: adds the item to the inventory if it isn't already in it.
- * @param {*} itemIdentification
- * @param {number} location
- */
- sendToLocation(itemId,location){
- let set = {l:location};
- this.setMetadata(itemId,set);
- }
- setMetadata(itemId,metadata){
- let temp = Object.assign({}, this._ownedItems[itemId], metadata);
- console.log("Item METADATA SET:",itemId,metadata,this._ownedItems[itemId],temp);
- this._ownedItems[itemId] = temp;
- }
- strip(type:string){
- let item:OutfitItem = this[type];
- if(!item.isValidItem)
- return;
- for(const slot of item.slots)
- this._wornItems[slot] = null;
- }
- stripAll(){
- this.strip('bra');
- this.strip('clothes');
- this.strip('panties');
- this.strip('shoes');
- }
- wearable(itemId:string){
- let result = {
- owned: true,
- health: true,
- inhibition: true,
- hips: true,
- various:[],
- total: true
- }
- var itemData:OutfitOwned;
- if(!this.has(itemId)){
- result.owned = false;
- result.health = false;
- result.hips = false;
- result.total = false;
- return result;
- }else{
- itemData = this.item(itemId);
- if(itemData.h == 0)
- result.health = false;
- if(itemData.bmi > 0){
- result.hips = !([EWearableBMI.TOO_LOSE,EWearableBMI.TOO_TIGHT].includes(this.wearableBMI(itemId)));
- }
- }
- if(!this.wearbleInhibition(itemId))
- result.inhibition = false;
- result.total = (result.owned && result.health && result.inhibition && result.hips);
- for(const wardrobeWearableFunction of Object.values(setup.wardrobeWearableFunctions)){
- let functionValue = wardrobeWearableFunction(itemData);
- if(functionValue){
- result.total = false;
- result.various.push(functionValue);
- }
- }
- return result;
- }
- wearableBMI(itemId:string):EWearableBMI{
- const itemData = this.item(itemId);
- if(itemData.bmi === undefined)
- return EWearableBMI.NOT_APPLICABLE;
- if(!itemData.bmi)
- return EWearableBMI.ANY;
- if(itemData.bmi < 0)
- return EWearableBMI.NOT_APPLICABLE;
- const pcbmi = State.variables.pc.bmi;
- if(itemData.bmi - pcbmi > setup.wardrobeSettings.bmiSizeMaxDifference)
- return EWearableBMI.TOO_TIGHT;
- if(pcbmi - itemData.bmi > setup.wardrobeSettings.bmiSizeMaxDifference)
- return EWearableBMI.TOO_LOSE;
- if(itemData.bmi - pcbmi > setup.wardrobeSettings.bmiSizeMaxDifference * 0.75)
- return EWearableBMI.ALMOST_TOO_TIGHT;
- if(pcbmi - itemData.bmi > setup.wardrobeSettings.bmiSizeMaxDifference * 0.75)
- return EWearableBMI.ALMOST_TOO_LOSE;
- return EWearableBMI.OKAY;
- }
- //Return 0 if inhibition blocks, 1 if exciting and 2 in every other case
- wearbleInhibition(itemId){
- const inhibition = this.inhibition(itemId);
- let playerInhib = State.variables.pc.pcs_inhib;
- if(inhibition <= playerInhib)
- return 2;
- if(inhibition - 10 <= playerInhib)
- return 1;
- return 0;
- }
- /**
- * Wear the specified item. Send it to the default wardrobe section. Adds the item to the inventory, if it isn't in it.
- * @param {*} itemIdentification
- * @param {boolean} [replace=true] replace what's currently worn? If false only adds the item to the inventory.
- */
- wear(itemId,replace=true):boolean{
- if(!this.has(itemId))
- this.add(itemId);
- //let itemType = this.itemData(itemId).type;
- if(!replace){
- let item = OutfitItem.get(itemId);
- for(const slot of item.slots){
- let itemAtSlot:OutfitItem = this[slot];
- if(itemAtSlot.isValidItem)
- return false;
- }
- }
-
- this.sendToLocation(itemId,0);
- console.log("WEARING NOW",itemId);
- this._wear(itemId);
-
- return true;
- }
- wearTemporary(itemId){
- let itemType = this.itemData(itemId).type;
- this.strip(itemType);
- console.log("WEARING NOW",itemId,itemType);
- this._wear(itemId);
- }
- /*wear_clothes_legacy(type,vendorAndSubtype,index){
- let parts = vendorAndSubtype.split('_',2);
- this.wear([type,parts[0],index,parts[1]]);
- }*/
- //Caution: Unlike wear, this will not change the location of the worn item.
- _wear(itemOrId:string|OutfitItem){
- let item:OutfitItem;
- if(typeof itemOrId == "string")
- item = OutfitItem.get(itemOrId);
- else
- item = itemOrId;
- for(const slot of item.slots){
- this.strip(slot);
- this._wornItems[slot] = item.id;
- this._lastWorn['last'][slot] = item.id;
- }
- /*let itemType = this.itemData(itemId).type;
- this._wornItems[itemType] = itemId;
- this._lastWorn['last'][itemType] = itemId;*/
- /*if(this.PCloBra == 1)
- this.strip('bra');
- */
- }
- /*wear_last(type){
- this._wear(this._lastWorn['last'][type]);
- }*/
- hasLastWorn(key){
- return !(!this._lastWorn[key]);
- }
- wearLastWorn(key,consume=false){
- if(!this._lastWorn[key]){
- console.error("The last item set with key "+key+" has not been set!");
- }
- this._wornItems = clone(this._lastWorn[key]);
- if(consume)
- delete this._lastWorn[key];
- }
- wearOutfit(key){
- this._wornItems = clone(this._outfits[key]);
- }
- wornItemData(type,index,def:any=0){
- if(!this._wornItems[type])
- return def;
- let id = this._wornItems[type];
- let data = this.itemData(id);
- let returnValue = data[index]
- if(returnValue == undefined || returnValue == null)
- return def;
- return returnValue;
- }
- _shopitems = {} //{shopid:{expireday:day,pricemod:pricemod,list:[]}}
- shopItemIds(shopid:string,filters,count=30,expireday=undefined):string[]
- {
- if(shopid in this._shopitems){
- if(this._shopitems[shopid].expireday >= State.variables.time.daystart){
- let cachedList = this._shopitems[shopid].list;
- console.warn('Returning cached list',cachedList);
- return cachedList;
- }
- }
- let pricemod = rand(0,500);
- expireday ??= State.variables.time.daystart;
- let entrys:string[] = this.allItemIdsFiltered(filters,count,true);
- entrys = entrys.filter(itemId=>!this.has(itemId));
- this.shopItemListSet(shopid,expireday,pricemod,entrys);
- return entrys;
- }
- shopItemList(shopid,filters,baseprice,count=30,expireday=null):{[itemId:string]:OutfitItem}{
- let result:{[itemId:string]:OutfitItem} = {};
- for(const itemId of this.shopItemIds(shopid,filters,count,expireday)){
- let item = OutfitItem.get(itemId);
- Object.assign(item,{id: itemId,price: this.itemPrice(itemId,baseprice)});
- result[itemId] = item;
- }
- return result;
- }
- shopItemListSet(shopid,expireday,pricemod,items){
- this._shopitems[shopid] = {
- expireday: expireday,
- pricemod:pricemod,
- list: items
- }
- }
- filters = {
- shop_cost:true,
- shop_owned:false,
- shop_inhib_toohigh:false,
- shop_inhib_high:true,
- shop_inhib_low:true
- };
-
- /*execute_every_1_hour(){
- }
- execute_every_1_day(){
- }*/
- _init(wardrobe){
- Object.keys(wardrobe).forEach(function (pn) {
- this[pn] = clone(wardrobe[pn]);
- }, this);
- return this;
- }
- clone = function () {
- return (new Wardrobe())._init(this);
- };
- toJSON = function () {
- var ownData = {};
- Object.keys(this).forEach(function (pn) {
- if(typeof this[pn] !== "function")
- ownData[pn] = clone(this[pn]);
- }, this);
- return JSON.reviveWrapper('(new Wardrobe())._init($ReviveData$)', ownData);
- };
- }
- window.Wardrobe = Wardrobe;
- setup.outfits = {};
|