/* The legend of Zelda: Tears of the Kingdom savegame editor - Pouch class (last update 2023-09-02) by Marc Robledo 2023 item names compiled by Echocolat, Exincracci, HylianLZ and Karlos007 filterable item dropdown by xiyuesaves */ function Pouch(catId){ this.category=catId; this.read(); } Pouch.prototype.read=function(){ var categoryItemStructId=Pouch.getCategoryItemStructId(this.category); this.struct=(new Struct(Pouch.getCategoryStructId(this.category), [{ structArray:categoryItemStructId, variablesInfo:Pouch.getCategoryStruct(this.category) }])); var structExported=this.struct.export(); this.items=[]; this.maxSize=structExported[categoryItemStructId].length; for(var i=0; i=this.items.length) return false; var removedItem=this.items[index]; this.items.splice(index,1); return removedItem; } Pouch.prototype.save=function(){ for(var i=0; i this.maxValue) newVal=this.maxValue; if(newVal===-0) newVal=0; //avoid negative zero this.item.lastInputChanged=this.propertyName; if(this.percentage) this.item[this.propertyName]=newVal / 100; else this.item[this.propertyName]=newVal; Pouch.updateItemRow(this.item); } Pouch._onChangeInputTextFix=function(evt){ var newVal=this.value.substr(0, this.maxLength); if(!newVal) newVal='a'; this.item.lastInputChanged=this.propertyName; this.item[this.propertyName]=newVal; Pouch.updateItemRow(this.item); } const ICON_PATH='./assets/item_icons/'; Pouch.getItemIcon = function (item) { if (item.id === 'Parasail') { var parasailPattern = typeof SavegameEditor.parasailPattern.value === 'string' ? SavegameEditor.parasailPattern.value : hashReverse(SavegameEditor.parasailPattern.value); if (parasailPattern !== 'Default') { return ICON_PATH + item.category + '/' + item.id + '_' + parasailPattern + '.png'; } else { return ICON_PATH + item.category + '/' + item.id + '.png'; } } else if (item.category === 'armors') { if (item.dyeColor === hash('None')) { return ICON_PATH + item.category + '/' + item.getBaseId() + '.png'; } else { return ICON_PATH + item.category + '/dye/' + item.getBaseId() + '_' + hashReverse(item.dyeColor) + '.png'; } } else if (item.category === 'food' && item.id === 'Item_Cook_C_17' && Item.VALID_ELIXIR_EFFECTS.indexOf(hashReverse(item.effect)) !== -1) { return ICON_PATH + item.category + '/Item_Cook_C_17_' + hashReverse(item.effect) + '.png'; } else { return ICON_PATH + item.category + '/' + item.id + '.png'; } }; Pouch.updateItemIcon=function(item){ item._htmlIcon.src=Pouch.getItemIcon(item); }; Pouch.updateItemRow=function(item){ if(!item._htmlRow){ //create if item row does not exist item._htmlIcon=new Image(); item._htmlIcon.className='item-icon'; item._htmlIcon.loading='lazy'; item._htmlIcon.onerror=function(){ //$(this).off('error'); this.src=ICON_PATH+'unknown.png'; } item._htmlItemId=document.createElement('span'); item._htmlItemId.className='item-name clickable'; item._htmlItemId.innerHTML=item.getItemTranslation(); if(item.getItemTranslation()===item.id) item._htmlItemId.style.color='red'; item._htmlItemId.addEventListener('click', function(){ SavegameEditor.editItem(item); }, false); var lastColumn=document.createElement('div'); if(item.category==='weapons' || item.category==='shields' || item.category==='bows') Equipment.buildHtmlElements(item); else if(item.category==='armors') Armor.buildHtmlElements(item); else if(item.category==='food') Item.buildHtmlElements(item); else if(item.category==='horses') Horse.buildHtmlElements(item); else Item.buildHtmlElements(item); $(lastColumn).append(Object.values(item._htmlInputs)); if(item.category==='key' && item.id==='Parasail') $(lastColumn).append(SavegameEditor._htmlSelectParasailPattern); item._htmlRow=document.createElement('div'); item._htmlRow.className='row row-item'; var columnLeft=document.createElement('div'); var columnRight=document.createElement('div'); item._htmlRow.appendChild(columnLeft); item._htmlRow.appendChild(columnRight); columnLeft.appendChild(item._htmlIcon); columnLeft.appendChild(item._htmlItemId); columnRight.appendChild(lastColumn); columnLeft.className='row-item-left'; columnRight.className='row-item-right row-item-right-'+item.category; item._htmlMenuButton=document.createElement('button'); item._htmlMenuButton.appendChild(UI.octicon('kebab_vertical')); item._htmlMenuButton.className='btn-menu-floating'; item._htmlMenuButton.addEventListener('click', function(evt){ evt.stopPropagation(); currentEditingItem=item; var showDivider=false; if(item.category==='weapons'){ $('#dropdown-item-button-pristine').show().prop('disabled', !item.canBeUndecayed()); showDivider=true; }else{ $('#dropdown-item-button-pristine').hide(); } if(item.category==='weapons' || item.category==='bows' || item.category==='shields'){ $('#dropdown-item-button-durability').show().prop('disabled', !item.canBeRestored()); $('#dropdown-item-button-infinite').show().prop('disabled', !item.canBeSetToInfiniteDurability()); showDivider=true; }else{ $('#dropdown-item-button-durability').hide(); $('#dropdown-item-button-infinite').hide(); } if(item.category==='armors' && item.canBeUpgraded()){ $('#dropdown-item-button-upgrade').show(); showDivider=true; }else{ $('#dropdown-item-button-upgrade').hide(); } if(item.category==='weapons' || item.category==='bows' || item.category==='shields' || item.category==='food' || item.category==='horses'){ $('#dropdown-item-button-duplicate').show(); $('#dropdown-item-button-export').show(); $('#dropdown-item-button-import').show(); showDivider=true; }else{ $('#dropdown-item-button-duplicate').hide(); $('#dropdown-item-button-export').hide(); $('#dropdown-item-button-import').hide(); } if(showDivider){ $('#dropdown-item .dropdown-divider').show(); }else{ $('#dropdown-item .dropdown-divider').hide(); } UI.dropdown('item', item._htmlRow); }); item._htmlRow.appendChild(item._htmlMenuButton); item.refreshHtmlInputs(false); Pouch.updateItemIcon(item); }else{ item.refreshHtmlInputs(true); } item._htmlItemId.innerHTML=item.getItemTranslation(); for(var prop in item._htmlInputs){ if(item._htmlInputs[prop].value!=item[prop]) if(item._htmlInputs[prop].percentage) item._htmlInputs[prop].value=item[prop] * 100; else item._htmlInputs[prop].value=item[prop]; } item.lastInputChanged=null; return item._htmlRow; }; Pouch.createItemInput=function(item, propertyName, type, options){ var elementTag=(typeof options.enumValues==='object')? 'select' : 'input'; var className='full-width'; if(type==='Int' || type==='UInt' || type==='Float') className+=' text-right'; var input=document.createElement(elementTag); input.item=item; input.propertyName=propertyName; input.className=className; if(typeof options.label==='string') input.title=options.label; if(elementTag==='select'){ var unknownValue=true; var intValue=typeof item[propertyName]==='string'? hash(item[propertyName]) : item[propertyName]; for(var i=0; i