///
///
///
///
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(){ //<>
if(!this._wornItems.panties)
return 'none';
let identificator = this.itemData(this._wornItems.panties);
return identificator.vendor;
}
get pantywornnumber(){ //<>
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(){ //<>
if(!this._wornItems.shoes)
return 'none';
let identificator = this.itemData(this._wornItems.shoes);
return identificator.vendor;
}
get shoewornnumber(){ //<>
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 = {};