diff --git a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.css b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.css index 69f0968199..e38e12b985 100644 --- a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.css +++ b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.css @@ -57,6 +57,7 @@ p { .sheet-passengers, .sheet-freight, .sheet-speculative, +.sheet-salvage, .sheet-tradelog, .sheet-trade, .sheet-help, @@ -197,6 +198,14 @@ p { opacity: 1; } +.sheet-tradetoggle[value="salvage"] ~ .sheet-salvage { + display: block; + margin-left: 3px; + animation-name: slide-in; + animation-duration: 1s; + opacity: 1; +} + .sheet-tradetoggle[value="tradelog"] ~ .sheet-tradelog { display: block; margin-left: 3px; @@ -1366,6 +1375,7 @@ input.sheet-vehicletypeshow[value="vehiclenotes"] ~ .sheet-type-vehiclenotes, input.sheet-tradetypeshow[value="passengers"] ~ .sheet-type-passengers, input.sheet-tradetypeshow[value="freight"] ~ .sheet-type-freight, input.sheet-tradetypeshow[value="speculative"] ~ .sheet-type-speculative, +input.sheet-tradetypeshow[value="salvage"] ~ .sheet-type-salvage, input.sheet-tradetypeshow[value="tradelog"] ~ .sheet-type-tradelog, input.sheet-typeshow[value="trade"] ~ .sheet-type-trade, input.sheet-typeshow[value="help"] ~ .sheet-type-help, @@ -1542,6 +1552,7 @@ button.btn.repcontrol_edit::after { .sheet-passengers, .sheet-freight, .sheet-speculative, +.sheet-salvage, .sheet-tradelog{ font-size: 1.1em !important; } @@ -1657,6 +1668,33 @@ div[data-groupname=repeating_speculative-freight-goods].repcontrol { display: none; } +/* Hide the buttons for repeating group as salvage list is preset */ +.sheet-salvage > .repcontrol { + display: none; +} + +.sheet-salvage-control { + width: 50%; + display: grid; + grid-template-columns: 4fr 1fr; +} + +.sheet-salvage-control > button { + height: 28px; +} + +.sheet-salvage-control > input { + margin-top: 2px; +} + +div.sheet-salvage-row { +/* width: 50%;*/ + display: grid; + grid-template-columns: 0.25fr 2fr 1fr 0.1fr 0.25fr 2fr 1fr; + column-gap: 5px; + font-size: 1.1em; +} + .sheet-rolltemplate-alt:has(.sheet-template-hazard-border) div:before, .sheet-rolltemplate-alt:has(.sheet-template-hazard-border) div:after { border-top: 0; diff --git a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.html b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.html index 200e7408ef..cd342b3c61 100644 --- a/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.html +++ b/Mongoose Traveller 2e Official/Official Mongoose Publishing Traveller 2nd Edition.html @@ -11554,11 +11554,15 @@ data-i18n="speculative-u"> Speculative + + value="Rules:CR-TRADE-1"> (It is recommended using the Purchase and Sale UWPs as these will auto-fill attributes across all Trade types) @@ -11633,8 +11637,7 @@ Total Tons:
-

- Speculative Goods

+

Speculative Goods (⛏ = Salvage)

@@ -11734,8 +11737,7 @@
-

- Passengers

+

Passengers


Broker, Carouse or Streetwise Check Effect @@ -11918,8 +11920,7 @@
-

- Freight

+

Freight


Freight (Notecoloured parameters only applicable to @@ -12260,8 +12261,7 @@

-

- Speculative

+

Speculative


+
+

Salvage

+
+
+ +
+
+ Key + Type + Tons + + Key + Type + Tons + + 11 + Common Electronics + + + 12 + Common Industrial Goods + + + 13 + Common Manufactured Goods + + + 14 + Common Raw Materials + + + 15 + Common Consumables + + + 16 + Common Ore + + + 21 + Advanced Electronics + + + 22 + Advanced Machine Parts + + + 23 + Advanced Manufactured Goods + + + 24 + Advanced Weapons + + + 25 + Advanced Vehicles + + + 26 + Biochemicals + + + 31 + Crystals & Gems + + + 32 + Cybernetics + + + 33 + Live Animals + + + 34 + Luxury Consumables + + + 35 + Luxury Goods + + + 36 + Medical Supplies + + + 41 + Petrochemicals + + + 42 + Pharmaceuticals + + + 43 + Polymers + + + 44 + Precious Metals + + + 45 + Radioactives + + + 46 + Robots + + + 51 + Spices + + + 52 + Textiles + + + 53 + Uncommon Ore + + + 54 + Uncommon Raw Materials + + + 55 + Wood + + + 56 + Vehicles + + + 61 + Illegal Biochemicals + + + 62 + Cybernetics, Illegal + + + 63 + Drugs, Illegal + + + 64 + Luxuries, Illegal + + + 65 + Weapons, Illegal + + + 66 + Exotics + + +
+

Trade Log

@@ -12813,12 +12974,13 @@
-

Character Sheet Version 1.1.11

+

Character Sheet Version 1.1.12


Assigning Attributes To Tokens

To represent the core character attributes on a token so they can be edited via the 'bubbles' use:
- currwithmax-<Characteristic>, e.g. currwithmax-Strength.

This works for the core characteristics, Psionic + currwithmax-<Characteristic>, e.g. currwithmax-Strength.

This works for the core characteristics, + Psionic Strength and also the Morale characteristic found on the Ship -> Combat tab.

@@ -14210,7 +14372,7 @@ }); }); - const buttonlist_sheettradetype = ["passengers", "freight", "speculative", "tradelog"]; + const buttonlist_sheettradetype = ["passengers", "freight", "speculative", "salvage", "tradelog"]; buttonlist_sheettradetype.forEach(button => { on(`clicked:${button}`, function() { setAttrs({ @@ -16641,35 +16803,46 @@ repSpeculativeSaleGoodsChanged(); } else { - getSectionIDs("repeating_speculative-sale-goods", function(idArray) { + getSectionIDs("speculative-sale-goods", function(idArray) { addTradeLogMessage("- Consolidating hold goods", true); var keyAttrs = []; for(var i=0; i < idArray.length; i++) { // Create attribute names for keys - var key = "repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_key"; + var key = "repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_type"; keyAttrs.push(key); key = "repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_tons_display"; keyAttrs.push(key); + key = "repeating_speculative-sale-goods_" + idArray[i] + "_speculative_pg_price"; + keyAttrs.push(key); } // Get the rows var updates = {}; - var tradeKeyInfo = {}; + var tradeTypeInfo = {}; getAttrs(keyAttrs, function (value) { - for(var i=0; i < idArray.length; i++) { - var tradeKey = value["repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_key"]; - var tons = +value["repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_tons_display"]; - if(tradeKeyInfo[tradeKey] === undefined) { + // Note that we are keying on type of commodity ('Common Electronics'), not key ('11'), this + // is because salvage is appended with an icon and we don't want to match on salvaged goods... + // We also have to match on price as we cannot consolidate multiple entries for the same + // commodity with different prices + + for(var i=0; i < idArray.length; i++) { + var tradeType = value["repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_type"]; + var tons = +value["repeating_speculative-sale-goods_" + idArray[i] + "_speculative_sg_tons_display"]; + var price = +value["repeating_speculative-sale-goods_" + idArray[i] + "_speculative_pg_price"]; + + if(tradeTypeInfo[tradeType] === undefined) { // First time seen - tradeKeyInfo[tradeKey] = { tons: tons, id: idArray[i] } + tradeTypeInfo[tradeType] = { tons: tons, id: idArray[i], price: price } } else { - // We have a duplicate, create/update a setAttr object key... - updates["repeating_speculative-sale-goods_" + tradeKeyInfo[tradeKey].id + "_speculative_sg_tons_display"] = tradeKeyInfo[tradeKey].tons + tons; - // ...and delete this duplicate row - removeRepeatingRow("repeating_speculative-sale-goods_" + idArray[i]); - repSpeculativeSaleGoodsChanged(); + // We have a duplicate, create/update a setAttr object key if price is the same + if(tradeTypeInfo[tradeType].price === price) { + updates["repeating_speculative-sale-goods_" + tradeTypeInfo[tradeType].id + "_speculative_sg_tons_display"] = tradeTypeInfo[tradeType].tons + tons; + // ...and delete this duplicate row + removeRepeatingRow("repeating_speculative-sale-goods_" + idArray[i]); + repSpeculativeSaleGoodsChanged(); + } } } setAttrs(updates); @@ -16761,7 +16934,9 @@ // So the above does a bit of a switcheroo, if we lose the 0x freight codes, we have to recombobulate rowIdsArray as we index into both // to find the key, and then the unique row id corresponding to that key, ergh! rowIdsArray = tmpRowIdsArray; - saleGoodsKeys = [...new Set(saleGoodsKeys)]; + // NOTE: Previously we made this a unique set, but with salvage we need to allow duplicate goods keys as they were bought for 'free' + // so are pure profit...Got to be VERY careful with these changes as trade is so complicated! + //saleGoodsKeys = [...new Set(saleGoodsKeys)]; addTradeLogMessage("- Unique trade code keys: " + JSON.stringify(saleGoodsKeys), true); // We also will need to roll 3D6 for each UNIQUE goods key for price, may as well do it now and pluck off the rolls we need @@ -16931,7 +17106,7 @@ priceAttrs["repeating_speculative-sale-goods_" + rowIdsArray[i] + "_speculative_sg_pl_neg"] = " "; priceAttrs["repeating_speculative-sale-goods_" + rowIdsArray[i] + "_speculative_sg_pl"] = pl; } - console.log("- PriceAttrs: " + JSON.stringify(priceAttrs)); + //console.log("- PriceAttrs: " + JSON.stringify(priceAttrs)); } }); finishRoll(qtyResults.rollId, {}); @@ -17298,7 +17473,7 @@ // Calculate fee, I used the locale string to format so need to unformat by replacing commas, hacky but safe as we specify en-US on our toLocaleString() // We also add a total total, e.g. supplier total plus fee showing the actual final amount the Traverllers have to pay - console.log("- About to info.newValue.replaceAll"); + // For some reason info.newValue can be undefined occasionally so the replaceAll fails, check and zero I guess... var total = info.newValue ? +info.newValue.replaceAll(",", "") : 0; var fee = Math.round(total * brokerFeeMultiplier); @@ -17556,6 +17731,84 @@ }); } + /* + * Populate salvage on sheet open, this could be hardcoded but hmmm... + */ + on("xxxxxsheet:opened", (info) => { + + //console.log("MgT2E: Show salvage"); + + // Clear out salvage rows + deleteRepeatingRows("repeating_salvage"); + + // Repopulate salvage rows + let newAttrs = {}; + + rowIdCnt=0; + let tradeGoodKeys = Object.keys(tradeGoods).sort(); + tradeGoodKeys.forEach(tradeGoodKey => { + const tradeGood = tradeGoods[tradeGoodKey]; + let newId = generateRowID(); + newAttrs["repeating_salvage_" + newId + "_salvage_key"] = tradeGoodKey; + newAttrs["repeating_salvage_" + newId + "_salvage_type"] = tradeGood.type; + newAttrs["repeating_salvage_" + newId + "_salvage_tons"] = 0; + console.log(tradeGoodKey + " " + tradeGood.type); + }); + // Now do the illegals + tradeGoodKeys = Object.keys(tradeGoodsIllegal).sort() + tradeGoodKeys.forEach(tradeGoodKey => { + const tradeGood = tradeGoodsIllegal[tradeGoodKey]; + let newId = generateRowID(); + newAttrs["repeating_salvage_" + newId + "_salvage_key"] = tradeGoodKey; + newAttrs["repeating_salvage_" + newId + "_salvage_type"] = tradeGood.type; + newAttrs["repeating_salvage_" + newId + "_salvage_tons"] = 0; + console.log(tradeGoodKey + " " + tradeGood.type); + }); + + setAttrs(newAttrs); + }); + + /* + * Apply salvage + */ + on("clicked:apply-salvage", (info) => { + + const tradeKeys = ["11", "12", "13", "14", "15", "16", "21", "22", "23", "24", "25", "26", "31", "32", "33", + "34", "35", "36", "41", "42", "43", "44", "45", "46", "51", "52", "53", "54", "55", "56", "61", "62", + "63", "64", "65", "66", ]; + + let attrs = []; + tradeKeys.forEach(key => { + attrs.push("salvage_tons_" + key); + }); + + getAttrs(attrs, function (values) { + let newAttrs = {}; + tradeKeys.forEach(key => { + let tons = parseFloat(values["salvage_tons_" + key]); + if(tons > 0) { + + let tradeGoodsObj = tradeGoods[key]; + if(!tradeGoodsObj) { + tradeGoodsObj = tradeGoodsIllegal[key]; + } + var newId = generateRowID(); + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_sg_key"] = key; + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_sg_type"] = tradeGoodsObj.type + " ⛏"; + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_sg_tons"] = tons; + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_sg_tons_display"] = tons; + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_sg_baseprice"] = tradeGoodsObj.basePrice + newAttrs["repeating_speculative-sale-goods_" + newId + "_speculative_pg_price"] = 0; + // Reset the salvage row + newAttrs["salvage_tons_" + key] = 0; + } + }); + setAttrs(newAttrs); + }); + + + }); + on("clicked:repeating_animalskills:animalskill", (info) => { console.log("MgT2E: Animal skill: " + JSON.stringify(info)) diff --git a/Mongoose Traveller 2e Official/README.md b/Mongoose Traveller 2e Official/README.md index 313673430b..d4cb2dc2d0 100644 --- a/Mongoose Traveller 2e Official/README.md +++ b/Mongoose Traveller 2e Official/README.md @@ -131,6 +131,10 @@ This is the Official Mongoose Traveller 2nd Edition Character Sheet ### Version 1.1.11 - Added STR modifier when weapon range is 'Melee' as per rules - Added repeating groups under all ship sheet components to allow for extended/custom/2300AD entries -- + +### Version 1.1.12 +- Added Salvage tab to Trade to allow for free stuff Travellers get +- Fixed Consolidate button in Manifest for Trade to only consolidate where price paid and commodity match (and ensure salvage does not get consolidated) + ![Image](Official%20Mongoose%20Publishing%20Traveller%202nd%20Edition.png) diff --git a/Mongoose Traveller 2e Official/translation.json b/Mongoose Traveller 2e Official/translation.json index 6771a7bd42..e43527252f 100644 --- a/Mongoose Traveller 2e Official/translation.json +++ b/Mongoose Traveller 2e Official/translation.json @@ -216,6 +216,7 @@ "passengers-u": "Passengers", "freight-u": "Freight", "speculative-u": "Speculative", + "salvage-u": "Salvage", "trade-u": "Trade", "sheettype-u": "Sheet Type:", "rollbehaviour-u": "Roll behaviour:",