Skip to content

Commit 00af846

Browse files
committed
Add Shop data and names Merchants Beedle and Shops
1 parent 775dd5a commit 00af846

6 files changed

Lines changed: 1087 additions & 7 deletions

File tree

src/components/AppMapDetailsObj.ts

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ function numOrArrayToArray(x: number | [number, number, number] | undefined): [n
8484

8585
function isAreaObject(obj: ObjectMinData) {
8686
const areaObjectNames = ["Area", "BoxWater", "SpotBgmTag", "PointWindSetTag", "AreaCulling_InnerHide",
87-
"AreaCulling_InnerOn", "AreaCulling_OuterNPCMementary", "FarModelCullingArea"];
87+
"AreaCulling_InnerOn", "AreaCulling_OuterNPCMementary", "FarModelCullingArea", "CastleBarrier"];
8888
return areaObjectNames.includes(obj.name) || obj.name.startsWith('AirWall');
8989
}
9090

@@ -113,6 +113,7 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
113113

114114
private dropTables: { [key: string]: any } = {};
115115
private shopData: { [key: string]: any } = {};
116+
private shopName: string | null = null;
116117
private links: PlacementLink[] = [];
117118
private linksToSelf: PlacementLink[] = [];
118119
private linkTagInputs: PlacementLink[] = [];
@@ -141,6 +142,7 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
141142
this.railMarkers.forEach(m => m.remove());
142143
this.railMarkers = [];
143144
this.shopData = {};
145+
this.shopName = null;
144146
if (this.minObj.objid) {
145147
this.obj = (await MapMgr.getInstance().getObjByObjId(this.minObj.objid))!;
146148
} else {
@@ -171,6 +173,39 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
171173
}
172174
}
173175

176+
// @ts-ignore
177+
if (this.obj.data.ShopData) {
178+
// @ts-ignore
179+
this.shopData = this.obj.data.ShopData//await MapMgr.getInstance().getObjShopData()
180+
}
181+
// Count Items in GenGroup with ForSale
182+
let ggHasForSale = genGroupForSaleCount(this.genGroup)
183+
184+
if (ggHasForSale) {
185+
this.shopData = {}
186+
187+
let gg = genGroupFilterItems(this.obj.name, this.genGroup)
188+
189+
let owner = gg.find((g: any) => g.data.ShopName)
190+
if (owner) {
191+
this.shopName = owner.data.ShopName
192+
} else {
193+
owner = gg.find((g: any) => g.data['!Parameters'].ProfileUser == "NPC")
194+
if (owner && this.getName(owner.name) != owner.name) {
195+
this.shopName = "Shop / " + this.getName(owner.name)
196+
}
197+
}
198+
// Identify items ForSale and count them
199+
let items: any = gg
200+
.filter(g => g.data.LinksToObj)
201+
.filter(g => g.data.LinksToObj.some((gobj: any) => gobj.DefinitionName == "ForSale"))
202+
.map(g => g.name)
203+
// @ts-ignore
204+
.reduce((acc, name) => { acc[name] = (acc[name] || 0) + 1; return acc }, {})
205+
let Normal = shopDataFromItems(items)
206+
this.shopData = { Header: { TableNum: 1, Table01: "Normal" }, Normal }
207+
}
208+
174209
if (this.obj.data.LinksToRail || DRAGON_HASH_IDS.includes(this.obj.hash_id)) {
175210
this.rails = await MapMgr.getInstance().getObjRails(this.obj.hash_id);
176211
}
@@ -226,6 +261,10 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
226261
if (this.railLimits.max === undefined) { this.railLimits.max = yvals[0]; }
227262
this.railLimits.min = Math.min(this.railLimits.min, ...yvals);
228263
this.railLimits.max = Math.max(this.railLimits.max, ...yvals);
264+
if (Math.abs(this.railLimits.min - this.railLimits.max) < 5) {
265+
this.railLimits.min -= 3
266+
this.railLimits.max += 3
267+
}
229268
// Draw polyline [x,z,y] but z is North-South and y is Up-Down
230269
pts = pts.map((pt: any) => [pt[2], pt[0], pt[1]]);
231270
// @ts-ignore
@@ -632,6 +671,20 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
632671
return Object.keys(this.shopData).length > 0;
633672
}
634673

674+
getShopData() {
675+
let location = this.getLocationSub()
676+
if (location) {
677+
return this.shopData[location]
678+
}
679+
return this.shopData
680+
}
681+
682+
getShopName() {
683+
// @ts-ignore
684+
return (this.shopName) ? this.shopName : null
685+
}
686+
687+
635688
formatDropTable(): string {
636689
let lines = [];
637690
let names = Object.keys(this.dropTables);
@@ -807,3 +860,50 @@ export default class AppMapDetailsObj extends AppMapDetailsBase<MapMarkerObj | M
807860
this.forgetColorScale();
808861
}
809862
}
863+
864+
function genGroupForSaleCount(genGroup: ObjectData[]) {
865+
return genGroup
866+
.map(g => g.data.LinksToObj)
867+
.filter(g => g)
868+
.map(g =>
869+
g.map((gobj: any) => gobj.DefinitionName)
870+
.filter((name: string) => name == "ForSale"))
871+
.flat().length
872+
}
873+
874+
function genGroupFilterItems(name: string, genGroup: ObjectData[]) {
875+
// Tarrey Town groups all Shops together
876+
// Search for Owner and get Shop Name
877+
// Filter out names of items in shop
878+
if (!(genGroup.some(g => g.name == "Npc_oasis050"))) { // Found Rhondson in genGroup (Tarrey Town)
879+
return genGroup
880+
}
881+
if (name.startsWith("Mannequin_006_") || name == "Npc_oasis050") {
882+
return genGroup.filter(g => g.name.startsWith("Mannequin_006_") || g.name == "Npc_oasis050")
883+
}
884+
if (name.startsWith("Item_Ore_") || name == "Npc_Goron025") {
885+
return genGroup.filter(g => g.name.startsWith("Item_Ore_") || g.name == "Npc_Goron025")
886+
}
887+
if (name.startsWith("Obj_") || name == "Npc_HighMountain010") {
888+
return genGroup.filter(g => g.name.startsWith("Obj_") || g.name == "Npc_HighMountain010")
889+
.filter(g => !g.name.startsWith("Obj_Tree"))
890+
}
891+
return []
892+
}
893+
894+
function shopDataFromItems(items: any) {
895+
let Normal: any = { ColumnNum: Object.keys(items).length }
896+
let BuyingPrice = MapMgr.getInstance().getBuyingPrice()
897+
Object.keys(items).forEach((name, i) => {
898+
let I = (i + 1).toString().padStart(3, '0')
899+
Normal[`ItemsSort${I}`] = i + 1
900+
Normal[`ItemName${I}`] = name
901+
Normal[`ItemNum${I}`] = items[name]
902+
Normal[`ItemPriceBase${I}`] = BuyingPrice[name]
903+
Normal[`ItemAdjustPrice${I}`] = 0
904+
Normal[`ItemPrice${I}`] = BuyingPrice[name]
905+
if (!BuyingPrice[name])
906+
console.log("No buying price: ", name)
907+
})
908+
return Normal
909+
}

src/components/AppMapDetailsObj.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
</section>
6868

6969
<section v-if="shopDataExists()">
70-
<ShopData :data="shopData[this.getLocationSub()]" />
70+
<ShopData :data="getShopData()" :shop_ui_name="getShopName()" />
7171
</section>
7272

7373
<section v-if="obj.data['!Parameters']">

src/components/ShopData.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,45 @@ export default class ShopData extends mixins(MixinUtil) {
99
@Prop()
1010
private data!: any;
1111

12+
@Prop()
13+
private shop_ui_name!: any;
14+
15+
table: string = "Normal"
16+
17+
private created() {
18+
if (Object.keys(this.data || []).length) {
19+
if (this.data.Normal)
20+
this.table = "Normal"
21+
else
22+
this.table = Object.keys(this.data)[0]
23+
}
24+
}
25+
shop_name() {
26+
if (this.shop_ui_name)
27+
return this.shop_ui_name
28+
if (this.data.Cooking && this.data.Compound) {
29+
return "Beedle Shop Data"
30+
}
31+
return "Shop"
32+
}
1233
length() {
13-
return this.data.Normal.ColumnNum;
34+
if (this.data[this.table])
35+
return this.data[this.table].ColumnNum;
36+
return 0
1437
}
1538
name(i: number) {
1639
const n = i.toString().padStart(3, '0')
17-
return ui.getName(this.data.Normal[`ItemName${n}`]);
40+
return ui.getName(this.data[this.table][`ItemName${n}`]);
1841
}
1942
num(i: number) {
2043
const n = i.toString().padStart(3, '0')
21-
return this.data.Normal[`ItemNum${n}`];
44+
return this.data[this.table][`ItemNum${n}`];
2245
}
2346
price(i: number) {
2447
const n = i.toString().padStart(3, '0')
25-
return this.data.Normal[`ItemPrice${n}`];
48+
return this.data[this.table][`ItemPrice${n}`];
49+
}
50+
tables() {
51+
return Object.keys(this.data).filter(v => v != "Header")
2652
}
2753
}

src/components/ShopData.vue

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<template>
22
<section >
33
<hr>
4-
<h4 class="subsection-heading">Beedle Shop Data</h4>
4+
<h4 class="subsection-heading">{{shop_name()}}</h4>
5+
<div v-if="shop_name() != 'Beedle Shop Data' && tables().length > 1">
6+
<b-form-select v-model="table" :options="tables()" class="mb-2 select_table" size="sm"> </b-form-select>
7+
</div>
58
<div class="table">
69
<div v-for="idx in length()" :key="idx" class="table-row">
710
<div class="cell">{{name(idx)}}</div>
@@ -24,5 +27,18 @@
2427
.table-row .cell {
2528
display: table-cell;
2629
}
30+
.select_table {
31+
color: white;
32+
background: rgba(0,0,0,0.2);
33+
border: rgba(255,255,255,0.2) 1px solid;
34+
35+
-webkit-appearance: none; /* For Chrome, Safari */
36+
-moz-appearance: none; /* For Firefox */
37+
appearance: none; /* Standard property */
38+
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8"><polygon points="0,2 4,6 8,2" fill="white"/></svg>') no-repeat right 10px center;
39+
background-size: 10px;
40+
padding-right: 30px; /* Make space for the custom arrow */
41+
}
42+
2743
</style>
2844
<script src="./ShopData.ts"></script>

src/services/MapMgr.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
import { GAME_FILES } from '@/util/map';
33

4+
import { BuyingPrice } from './buying_price'
5+
46
const RADAR_URL = process.env.VUE_APP_RADAR_URL;
57

68
export type Vec3 = [number, number, number];
@@ -113,6 +115,10 @@ export class MapMgr {
113115
return fetch(`${GAME_FILES}/ecosystem/beedle_shop_data.json`).then(parse);
114116
}
115117

118+
getBuyingPrice() {
119+
return BuyingPrice
120+
}
121+
116122
getObjDropTables(unitConfigName: string, tableName: string) {
117123
return fetch(`${RADAR_URL}/drop/${unitConfigName}/${tableName}`).then(parse);
118124
}

0 commit comments

Comments
 (0)