@adatechnology/game-items-goods 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -1
- package/dist/index.global.js +550 -465
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +550 -463
- package/dist/index.js.map +1 -1
- package/package.json +5 -6
package/dist/index.global.js
CHANGED
|
@@ -2787,7 +2787,11 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
2787
2787
|
"road"
|
|
2788
2788
|
]
|
|
2789
2789
|
},
|
|
2790
|
-
model: "canned_sardines"
|
|
2790
|
+
model: "canned_sardines",
|
|
2791
|
+
seal: {
|
|
2792
|
+
byHand: true,
|
|
2793
|
+
spoilsWhenBreached: true
|
|
2794
|
+
}
|
|
2791
2795
|
},
|
|
2792
2796
|
{
|
|
2793
2797
|
id: "canned_corn_and_peas",
|
|
@@ -2969,7 +2973,13 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
2969
2973
|
"school"
|
|
2970
2974
|
]
|
|
2971
2975
|
},
|
|
2972
|
-
model: "rice"
|
|
2976
|
+
model: "rice",
|
|
2977
|
+
powder: {
|
|
2978
|
+
color: 15722710
|
|
2979
|
+
},
|
|
2980
|
+
estimated: [
|
|
2981
|
+
"powder"
|
|
2982
|
+
]
|
|
2973
2983
|
},
|
|
2974
2984
|
{
|
|
2975
2985
|
id: "beans",
|
|
@@ -3307,7 +3317,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3307
3317
|
nonPerishable: true,
|
|
3308
3318
|
estimated: [
|
|
3309
3319
|
"nonPerishable"
|
|
3310
|
-
]
|
|
3320
|
+
],
|
|
3321
|
+
seal: {
|
|
3322
|
+
byHand: true
|
|
3323
|
+
}
|
|
3311
3324
|
},
|
|
3312
3325
|
{
|
|
3313
3326
|
id: "bread",
|
|
@@ -3849,7 +3862,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3849
3862
|
"lodge"
|
|
3850
3863
|
]
|
|
3851
3864
|
},
|
|
3852
|
-
model: "home_preserves"
|
|
3865
|
+
model: "home_preserves",
|
|
3866
|
+
seal: {
|
|
3867
|
+
byHand: true
|
|
3868
|
+
}
|
|
3853
3869
|
},
|
|
3854
3870
|
{
|
|
3855
3871
|
id: "dog_food",
|
|
@@ -3922,8 +3938,12 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3922
3938
|
},
|
|
3923
3939
|
model: "sugar",
|
|
3924
3940
|
nonPerishable: true,
|
|
3941
|
+
powder: {
|
|
3942
|
+
color: 16184558
|
|
3943
|
+
},
|
|
3925
3944
|
estimated: [
|
|
3926
|
-
"nonPerishable"
|
|
3945
|
+
"nonPerishable",
|
|
3946
|
+
"powder"
|
|
3927
3947
|
]
|
|
3928
3948
|
},
|
|
3929
3949
|
{
|
|
@@ -3961,8 +3981,12 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3961
3981
|
},
|
|
3962
3982
|
model: "salt",
|
|
3963
3983
|
nonPerishable: true,
|
|
3984
|
+
powder: {
|
|
3985
|
+
color: 15921902
|
|
3986
|
+
},
|
|
3964
3987
|
estimated: [
|
|
3965
|
-
"nonPerishable"
|
|
3988
|
+
"nonPerishable",
|
|
3989
|
+
"powder"
|
|
3966
3990
|
]
|
|
3967
3991
|
},
|
|
3968
3992
|
{
|
|
@@ -3999,7 +4023,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
3999
4023
|
"supermarket"
|
|
4000
4024
|
]
|
|
4001
4025
|
},
|
|
4002
|
-
model: "cooking_oil"
|
|
4026
|
+
model: "cooking_oil",
|
|
4027
|
+
seal: {
|
|
4028
|
+
byHand: true
|
|
4029
|
+
}
|
|
4003
4030
|
},
|
|
4004
4031
|
{
|
|
4005
4032
|
id: "coffee",
|
|
@@ -4037,7 +4064,13 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4037
4064
|
"police_station"
|
|
4038
4065
|
]
|
|
4039
4066
|
},
|
|
4040
|
-
model: "coffee"
|
|
4067
|
+
model: "coffee",
|
|
4068
|
+
powder: {
|
|
4069
|
+
color: 4861984
|
|
4070
|
+
},
|
|
4071
|
+
estimated: [
|
|
4072
|
+
"powder"
|
|
4073
|
+
]
|
|
4041
4074
|
},
|
|
4042
4075
|
{
|
|
4043
4076
|
id: "water_bottle",
|
|
@@ -4081,7 +4114,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4081
4114
|
estimated: [
|
|
4082
4115
|
"nonPerishable",
|
|
4083
4116
|
"fluid"
|
|
4084
|
-
]
|
|
4117
|
+
],
|
|
4118
|
+
seal: {
|
|
4119
|
+
byHand: true
|
|
4120
|
+
}
|
|
4085
4121
|
},
|
|
4086
4122
|
{
|
|
4087
4123
|
id: "water_jug_5l",
|
|
@@ -4121,7 +4157,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4121
4157
|
estimated: [
|
|
4122
4158
|
"nonPerishable",
|
|
4123
4159
|
"fluid"
|
|
4124
|
-
]
|
|
4160
|
+
],
|
|
4161
|
+
seal: {
|
|
4162
|
+
byHand: true
|
|
4163
|
+
}
|
|
4125
4164
|
},
|
|
4126
4165
|
{
|
|
4127
4166
|
id: "dirty_water",
|
|
@@ -4158,7 +4197,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4158
4197
|
estimated: [
|
|
4159
4198
|
"nonPerishable",
|
|
4160
4199
|
"fluid"
|
|
4161
|
-
]
|
|
4200
|
+
],
|
|
4201
|
+
seal: {
|
|
4202
|
+
byHand: true
|
|
4203
|
+
}
|
|
4162
4204
|
},
|
|
4163
4205
|
{
|
|
4164
4206
|
id: "soda_can",
|
|
@@ -4366,7 +4408,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4366
4408
|
},
|
|
4367
4409
|
estimated: [
|
|
4368
4410
|
"fluid"
|
|
4369
|
-
]
|
|
4411
|
+
],
|
|
4412
|
+
seal: {
|
|
4413
|
+
byHand: true
|
|
4414
|
+
}
|
|
4370
4415
|
},
|
|
4371
4416
|
{
|
|
4372
4417
|
id: "energy_drink",
|
|
@@ -4407,7 +4452,11 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4407
4452
|
},
|
|
4408
4453
|
estimated: [
|
|
4409
4454
|
"fluid"
|
|
4410
|
-
]
|
|
4455
|
+
],
|
|
4456
|
+
seal: {
|
|
4457
|
+
byHand: true,
|
|
4458
|
+
spoilsWhenBreached: true
|
|
4459
|
+
}
|
|
4411
4460
|
},
|
|
4412
4461
|
{
|
|
4413
4462
|
id: "coconut_water",
|
|
@@ -4447,7 +4496,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4447
4496
|
},
|
|
4448
4497
|
estimated: [
|
|
4449
4498
|
"fluid"
|
|
4450
|
-
]
|
|
4499
|
+
],
|
|
4500
|
+
seal: {
|
|
4501
|
+
byHand: true
|
|
4502
|
+
}
|
|
4451
4503
|
},
|
|
4452
4504
|
{
|
|
4453
4505
|
id: "beer_can",
|
|
@@ -4547,7 +4599,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4547
4599
|
"parts",
|
|
4548
4600
|
"impact",
|
|
4549
4601
|
"leftover"
|
|
4550
|
-
]
|
|
4602
|
+
],
|
|
4603
|
+
seal: {
|
|
4604
|
+
byHand: true
|
|
4605
|
+
}
|
|
4551
4606
|
},
|
|
4552
4607
|
{
|
|
4553
4608
|
id: "communion_wine",
|
|
@@ -4603,7 +4658,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
4603
4658
|
"parts",
|
|
4604
4659
|
"impact",
|
|
4605
4660
|
"leftover"
|
|
4606
|
-
]
|
|
4661
|
+
],
|
|
4662
|
+
seal: {
|
|
4663
|
+
byHand: true
|
|
4664
|
+
}
|
|
4607
4665
|
},
|
|
4608
4666
|
{
|
|
4609
4667
|
id: "bandage",
|
|
@@ -11149,9 +11207,13 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
11149
11207
|
hydration: -8
|
|
11150
11208
|
},
|
|
11151
11209
|
shelfLife: 365,
|
|
11210
|
+
powder: {
|
|
11211
|
+
color: 15986662
|
|
11212
|
+
},
|
|
11152
11213
|
estimated: [
|
|
11153
11214
|
"nutrition",
|
|
11154
|
-
"shelfLife"
|
|
11215
|
+
"shelfLife",
|
|
11216
|
+
"powder"
|
|
11155
11217
|
]
|
|
11156
11218
|
},
|
|
11157
11219
|
{
|
|
@@ -11176,9 +11238,13 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
11176
11238
|
hydration: -5
|
|
11177
11239
|
},
|
|
11178
11240
|
shelfLife: 270,
|
|
11241
|
+
powder: {
|
|
11242
|
+
color: 14201962
|
|
11243
|
+
},
|
|
11179
11244
|
estimated: [
|
|
11180
11245
|
"nutrition",
|
|
11181
|
-
"shelfLife"
|
|
11246
|
+
"shelfLife",
|
|
11247
|
+
"powder"
|
|
11182
11248
|
]
|
|
11183
11249
|
},
|
|
11184
11250
|
{
|
|
@@ -13377,6 +13443,15 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
13377
13443
|
"chew"
|
|
13378
13444
|
]
|
|
13379
13445
|
},
|
|
13446
|
+
seal: {
|
|
13447
|
+
openWith: [
|
|
13448
|
+
"can_opener",
|
|
13449
|
+
"pocket_knife",
|
|
13450
|
+
"knife",
|
|
13451
|
+
"tactical_knife"
|
|
13452
|
+
],
|
|
13453
|
+
spoilsWhenBreached: true
|
|
13454
|
+
},
|
|
13380
13455
|
leftover: {
|
|
13381
13456
|
item: "empty_can",
|
|
13382
13457
|
despawnSeconds: 600
|
|
@@ -13538,6 +13613,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
13538
13613
|
"gulp"
|
|
13539
13614
|
]
|
|
13540
13615
|
},
|
|
13616
|
+
seal: {
|
|
13617
|
+
byHand: true,
|
|
13618
|
+
spoilsWhenBreached: true
|
|
13619
|
+
},
|
|
13541
13620
|
leftover: {
|
|
13542
13621
|
item: "empty_can",
|
|
13543
13622
|
despawnSeconds: 600
|
|
@@ -18051,208 +18130,461 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
18051
18130
|
var GOODS_KINDS = kinds_default;
|
|
18052
18131
|
var GOODS_KNOWN_GAPS = known_gaps_default;
|
|
18053
18132
|
|
|
18054
|
-
// src/
|
|
18055
|
-
var
|
|
18056
|
-
|
|
18057
|
-
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
containers: GOODS_CONTAINERS,
|
|
18061
|
-
useEffects: GOODS_USE_EFFECTS,
|
|
18062
|
-
recipes: GOODS_RECIPES,
|
|
18063
|
-
pools: GOODS_HOUSE_POOLS.pools,
|
|
18064
|
-
poolAliases: { ...GOODS_HOUSE_POOLS.aliasOf, ...FLOORPLAN_POOL_ALIASES }
|
|
18133
|
+
// src/data/item-contracts.json
|
|
18134
|
+
var item_contracts_default = {
|
|
18135
|
+
densityKgPerLitre: { min: 0.02, max: 22 },
|
|
18136
|
+
impactResponses: ["dent", "break", "shatter", "tear", "squash", "pierce", "none"],
|
|
18137
|
+
heatResistantMaterials: ["steel", "cast_iron", "aluminium", "copper", "ceramic", "tempered_glass", "stone", "brick"],
|
|
18138
|
+
bodySlots: ["head", "eyes", "torso", "arms", "hands", "legs", "feet", "over"]
|
|
18065
18139
|
};
|
|
18066
|
-
var createGoodsItems = (options = {}) => createItems({ ...options, packs: [goodsPack, ...options.packs ?? []] });
|
|
18067
18140
|
|
|
18068
|
-
// src/
|
|
18069
|
-
var
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
|
|
18082
|
-
|
|
18083
|
-
|
|
18084
|
-
|
|
18085
|
-
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
|
|
18096
|
-
|
|
18097
|
-
|
|
18098
|
-
|
|
18099
|
-
|
|
18100
|
-
|
|
18101
|
-
|
|
18102
|
-
|
|
18103
|
-
|
|
18104
|
-
|
|
18105
|
-
|
|
18106
|
-
|
|
18107
|
-
|
|
18108
|
-
|
|
18109
|
-
|
|
18110
|
-
|
|
18111
|
-
|
|
18112
|
-
|
|
18113
|
-
|
|
18114
|
-
|
|
18115
|
-
|
|
18116
|
-
|
|
18117
|
-
|
|
18118
|
-
|
|
18119
|
-
|
|
18120
|
-
|
|
18121
|
-
|
|
18122
|
-
|
|
18123
|
-
|
|
18124
|
-
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
|
|
18128
|
-
|
|
18129
|
-
|
|
18130
|
-
|
|
18131
|
-
|
|
18132
|
-
|
|
18133
|
-
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
|
|
18137
|
-
|
|
18138
|
-
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18141
|
+
// src/contracts.ts
|
|
18142
|
+
var IMPACT_RESPONSES = item_contracts_default.impactResponses;
|
|
18143
|
+
var HEAT_RESISTANT_MATERIALS = item_contracts_default.heatResistantMaterials;
|
|
18144
|
+
var DENSITY_KG_PER_LITRE = item_contracts_default.densityKgPerLitre;
|
|
18145
|
+
var BODY_SLOTS2 = item_contracts_default.bodySlots;
|
|
18146
|
+
var SNAKE_CASE = /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;
|
|
18147
|
+
var LITRES_PER_CUBIC_METRE2 = 1e3;
|
|
18148
|
+
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
18149
|
+
var isFraction2 = (value) => isNumber(value) && value >= 0 && value <= 1;
|
|
18150
|
+
var catalogOf = (options) => options.items ?? GOODS_ITEMS;
|
|
18151
|
+
var parts = (item) => Array.isArray(item.parts) ? item.parts : [];
|
|
18152
|
+
var physical = (options) => {
|
|
18153
|
+
const range = options.density ?? DENSITY_KG_PER_LITRE;
|
|
18154
|
+
return {
|
|
18155
|
+
id: "physical",
|
|
18156
|
+
check: (item) => {
|
|
18157
|
+
const problems = [];
|
|
18158
|
+
const size = item.size;
|
|
18159
|
+
const sizeOk = Array.isArray(size) && size.length === 3 && size.every((side) => isNumber(side) && side > 0);
|
|
18160
|
+
if (!sizeOk) problems.push("size must be 3 finite positive numbers in metres");
|
|
18161
|
+
if (!isNumber(item.weight) || item.weight < 0) problems.push("weight must be a finite number >= 0 (kg)");
|
|
18162
|
+
if (sizeOk && isNumber(item.weight) && item.weight > 0) {
|
|
18163
|
+
const [width, height, depth] = size;
|
|
18164
|
+
const density = item.weight / (width * height * depth * LITRES_PER_CUBIC_METRE2);
|
|
18165
|
+
if (density < range.min || density > range.max) problems.push(`density ${Number(density.toPrecision(2))} kg/L is outside ${range.min}..${range.max}`);
|
|
18166
|
+
}
|
|
18167
|
+
return problems;
|
|
18168
|
+
}
|
|
18169
|
+
};
|
|
18170
|
+
};
|
|
18171
|
+
var destructible = (options) => {
|
|
18172
|
+
const materials = options.materials ? new Set(options.materials) : void 0;
|
|
18173
|
+
return {
|
|
18174
|
+
id: "destructible",
|
|
18175
|
+
check: (item) => {
|
|
18176
|
+
const list = parts(item);
|
|
18177
|
+
if (list.length === 0) return ["missing parts"];
|
|
18178
|
+
const problems = [];
|
|
18179
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18180
|
+
for (const part of list) {
|
|
18181
|
+
if (typeof part.id !== "string" || part.id === "") problems.push("a part has no id");
|
|
18182
|
+
else if (seen.has(part.id)) problems.push(`duplicate part "${part.id}"`);
|
|
18183
|
+
else seen.add(part.id);
|
|
18184
|
+
if (typeof part.material !== "string" || part.material === "") problems.push(`part "${part.id}" has no material`);
|
|
18185
|
+
else if (materials && !materials.has(part.material)) problems.push(`part "${part.id}" has unknown material "${part.material}"`);
|
|
18186
|
+
if (part.thickness !== void 0 && !(isNumber(part.thickness) && part.thickness > 0)) problems.push(`part "${part.id}" thickness must be a positive number`);
|
|
18187
|
+
}
|
|
18188
|
+
if (problems.length === 0 && list.every((part) => part.shape !== void 0 && part.position !== void 0)) {
|
|
18189
|
+
const report = checkSpec({ parts: list }, materials ? { materials } : {});
|
|
18190
|
+
for (const problem of report.problems) problems.push(`spec: ${problem}`);
|
|
18191
|
+
}
|
|
18192
|
+
return problems;
|
|
18193
|
+
}
|
|
18194
|
+
};
|
|
18195
|
+
};
|
|
18196
|
+
var impact = {
|
|
18197
|
+
id: "impact",
|
|
18198
|
+
check: (item) => {
|
|
18199
|
+
const value = item.impact;
|
|
18200
|
+
if (!value) return ["missing impact"];
|
|
18201
|
+
const problems = [];
|
|
18202
|
+
if (!IMPACT_RESPONSES.includes(value.response ?? "")) problems.push(`impact.response must be one of ${IMPACT_RESPONSES.join(", ")}`);
|
|
18203
|
+
if (typeof value.pushImpulse !== "boolean") problems.push("impact.pushImpulse must be true or false");
|
|
18204
|
+
if (value.shed !== void 0 && typeof value.shed !== "boolean") problems.push("impact.shed must be true or false");
|
|
18205
|
+
return problems;
|
|
18206
|
+
}
|
|
18207
|
+
};
|
|
18208
|
+
var useAnimation = {
|
|
18209
|
+
id: "use_animation",
|
|
18210
|
+
check: (item) => {
|
|
18211
|
+
const problems = [];
|
|
18212
|
+
const clip = item.use?.clip;
|
|
18213
|
+
if (clip === void 0) problems.push("missing use.clip");
|
|
18214
|
+
else if (!SNAKE_CASE.test(clip)) problems.push(`use.clip "${clip}" must be snake_case`);
|
|
18215
|
+
const sounds = item.use?.sounds;
|
|
18216
|
+
if (!Array.isArray(sounds) || sounds.length === 0 || sounds.some((sound) => typeof sound !== "string" || sound === "")) problems.push("missing use.sounds (a non-empty list of sound ids)");
|
|
18217
|
+
return problems;
|
|
18218
|
+
}
|
|
18219
|
+
};
|
|
18220
|
+
var leftover = (options) => {
|
|
18221
|
+
const ids = new Set(catalogOf(options).map((item) => item.id));
|
|
18222
|
+
return {
|
|
18223
|
+
id: "leftover",
|
|
18224
|
+
check: (item) => {
|
|
18225
|
+
const value = item.leftover;
|
|
18226
|
+
if (value === void 0) return ["missing leftover"];
|
|
18227
|
+
if (value === "none") return [];
|
|
18228
|
+
const problems = [];
|
|
18229
|
+
if (typeof value !== "object" || value === null) return ['leftover must be an object or "none"'];
|
|
18230
|
+
if (typeof value.item !== "string" || value.item === "") problems.push("missing leftover.item");
|
|
18231
|
+
else if (!ids.has(value.item)) problems.push(`leftover.item "${value.item}" is not in the catalog`);
|
|
18232
|
+
if (!isNumber(value.despawnSeconds) || value.despawnSeconds < 0) problems.push("missing leftover.despawnSeconds");
|
|
18233
|
+
return problems;
|
|
18234
|
+
}
|
|
18235
|
+
};
|
|
18236
|
+
};
|
|
18237
|
+
var edible = {
|
|
18238
|
+
id: "edible",
|
|
18239
|
+
check: (item) => {
|
|
18240
|
+
const problems = [];
|
|
18241
|
+
const nutrition = item.nutrition;
|
|
18242
|
+
if (!nutrition || !(isNumber(nutrition.satiety) || isNumber(nutrition.hydration))) problems.push("missing nutrition");
|
|
18243
|
+
if (item.shelfLife === void 0 && item.nonPerishable !== true) problems.push("missing shelfLife (a number of days, or nonPerishable: true)");
|
|
18244
|
+
else if (item.shelfLife !== void 0 && !(isNumber(item.shelfLife) && item.shelfLife > 0)) problems.push("shelfLife must be a positive number of days");
|
|
18245
|
+
if (!isFraction2(item.rawEffect?.sickChance)) problems.push("missing rawEffect.sickChance (0..1)");
|
|
18246
|
+
return problems;
|
|
18247
|
+
}
|
|
18248
|
+
};
|
|
18249
|
+
var inputsOf = (recipe) => recipe.inputs ?? [];
|
|
18250
|
+
var toolsOf = (recipe) => recipe.tools ?? [];
|
|
18251
|
+
var consumes = (input, item) => {
|
|
18252
|
+
if (input.item === item.id) return true;
|
|
18253
|
+
if (input.any?.includes(item.id)) return true;
|
|
18254
|
+
if (!input.match) return false;
|
|
18255
|
+
const entries = Object.entries(input.match);
|
|
18256
|
+
return entries.length > 0 && entries.every(([key, value]) => item[key] === value);
|
|
18257
|
+
};
|
|
18258
|
+
var recipeInput = (options) => {
|
|
18259
|
+
const recipes = options.recipes ?? GOODS_RECIPES;
|
|
18260
|
+
return {
|
|
18261
|
+
id: "recipe_input",
|
|
18262
|
+
check: (item) => recipes.some((recipe) => inputsOf(recipe).some((input) => consumes(input, item))) ? [] : ["is not an input of any recipe"]
|
|
18263
|
+
};
|
|
18264
|
+
};
|
|
18265
|
+
var preparation = (options) => {
|
|
18266
|
+
const recipes = options.recipes ?? GOODS_RECIPES;
|
|
18267
|
+
const cookware = new Set(catalogOf(options).filter((item) => item.kind === "cookware").map((item) => item.id));
|
|
18268
|
+
return {
|
|
18269
|
+
id: "preparation",
|
|
18270
|
+
check: (item) => {
|
|
18271
|
+
const usable = recipes.filter((recipe) => inputsOf(recipe).some((input) => consumes(input, item)));
|
|
18272
|
+
if (usable.length === 0) return ["has no recipe that prepares it"];
|
|
18273
|
+
const prepares = usable.some((recipe) => {
|
|
18274
|
+
const heat = toolsOf(recipe).some((tool) => tool.world?.includes("fire"));
|
|
18275
|
+
const vessel = [...inputsOf(recipe).flatMap((input) => input.item ? [input.item] : []), ...toolsOf(recipe).flatMap((tool) => tool.anyOf ?? [])].some((id) => cookware.has(id));
|
|
18276
|
+
return heat && vessel;
|
|
18277
|
+
});
|
|
18278
|
+
return prepares ? [] : ["has no recipe that needs fire and a cooking vessel"];
|
|
18279
|
+
}
|
|
18280
|
+
};
|
|
18281
|
+
};
|
|
18282
|
+
var liquidContainer = {
|
|
18283
|
+
id: "liquid_container",
|
|
18284
|
+
check: (item) => {
|
|
18285
|
+
const fluid = item.fluid;
|
|
18286
|
+
if (fluid) {
|
|
18287
|
+
const problems = [];
|
|
18288
|
+
if (typeof fluid.liquid !== "string" || !SNAKE_CASE.test(fluid.liquid)) problems.push("fluid.liquid must be a liquid id");
|
|
18289
|
+
if (!isNumber(fluid.liters) || fluid.liters < 0) problems.push("fluid.liters must be a number >= 0");
|
|
18290
|
+
return problems;
|
|
18291
|
+
}
|
|
18292
|
+
return isNumber(item.container?.capacityLiters) && (item.container?.capacityLiters ?? 0) > 0 ? [] : ["missing fluid { liquid, liters } or container.capacityLiters"];
|
|
18293
|
+
}
|
|
18294
|
+
};
|
|
18295
|
+
var heatResistant = (options) => {
|
|
18296
|
+
const allowed = new Set(options.heatResistant ?? HEAT_RESISTANT_MATERIALS);
|
|
18297
|
+
return {
|
|
18298
|
+
id: "heat_resistant",
|
|
18299
|
+
check: (item) => parts(item).filter((part) => !allowed.has(part.material)).map((part) => `part "${part.id}" is ${part.material}, which does not take a flame`)
|
|
18300
|
+
};
|
|
18301
|
+
};
|
|
18302
|
+
var weapon = (options) => {
|
|
18303
|
+
const weaponIds = options.weaponIds ? new Set(options.weaponIds) : void 0;
|
|
18304
|
+
const calibers = options.calibers ? new Set(options.calibers) : void 0;
|
|
18305
|
+
return {
|
|
18306
|
+
id: "weapon",
|
|
18307
|
+
check: (item, ctx) => {
|
|
18308
|
+
if (ctx.chain.includes("ammo")) {
|
|
18309
|
+
if (typeof item.caliber !== "string" || item.caliber === "") return ["missing caliber"];
|
|
18310
|
+
return calibers && !calibers.has(item.caliber) ? [`caliber "${item.caliber}" is not in the arsenal`] : [];
|
|
18311
|
+
}
|
|
18312
|
+
if (typeof item.weapon !== "string" || item.weapon === "") return ["missing weapon (the arsenal id)"];
|
|
18313
|
+
return weaponIds && !weaponIds.has(item.weapon) ? [`weapon "${item.weapon}" is not in the arsenal`] : [];
|
|
18314
|
+
}
|
|
18315
|
+
};
|
|
18316
|
+
};
|
|
18317
|
+
var wearable = {
|
|
18318
|
+
id: "wearable",
|
|
18319
|
+
check: (item, ctx) => {
|
|
18320
|
+
const problems = [];
|
|
18321
|
+
const { protection, carry } = item;
|
|
18322
|
+
if (!protection && !carry) return [ctx.chain.includes("bag") ? "missing carry" : "missing protection"];
|
|
18323
|
+
if (ctx.chain.includes("bag") && !carry) problems.push("missing carry");
|
|
18324
|
+
if (ctx.chain.includes("clothing") && !protection) problems.push("missing protection");
|
|
18325
|
+
if (protection) {
|
|
18326
|
+
const slots = protection.slots;
|
|
18327
|
+
if (!Array.isArray(slots) || slots.length === 0) problems.push("protection.slots must list at least one body slot");
|
|
18328
|
+
else for (const slot of slots) if (!BODY_SLOTS2.includes(slot)) problems.push(`protection.slots has unknown slot "${slot}"`);
|
|
18329
|
+
for (const field of ["bite", "scratch", "warmth"]) if (protection[field] !== void 0 && !isFraction2(protection[field])) problems.push(`protection.${field} must be between 0 and 1`);
|
|
18330
|
+
}
|
|
18331
|
+
if (carry) {
|
|
18332
|
+
if (!(isNumber(carry.capacityKg) && carry.capacityKg > 0)) problems.push("carry.capacityKg must be positive");
|
|
18333
|
+
if (!isFraction2(carry.weightReduction)) problems.push("carry.weightReduction must be between 0 and 1");
|
|
18334
|
+
if (!(isNumber(carry.quickSlots) && carry.quickSlots >= 0)) problems.push("carry.quickSlots must be >= 0");
|
|
18335
|
+
}
|
|
18336
|
+
return problems;
|
|
18337
|
+
}
|
|
18338
|
+
};
|
|
18339
|
+
var battery = {
|
|
18340
|
+
id: "battery",
|
|
18341
|
+
check: (item) => isNumber(item.charge?.lossPerMonth) && (item.charge?.lossPerMonth ?? -1) >= 0 ? [] : ["missing charge.lossPerMonth"]
|
|
18342
|
+
};
|
|
18343
|
+
var createItemContracts = (options = {}) => [
|
|
18344
|
+
physical(options),
|
|
18345
|
+
destructible(options),
|
|
18346
|
+
impact,
|
|
18347
|
+
useAnimation,
|
|
18348
|
+
leftover(options),
|
|
18349
|
+
edible,
|
|
18350
|
+
preparation(options),
|
|
18351
|
+
recipeInput(options),
|
|
18352
|
+
liquidContainer,
|
|
18353
|
+
heatResistant(options),
|
|
18354
|
+
weapon(options),
|
|
18355
|
+
wearable,
|
|
18356
|
+
battery
|
|
18357
|
+
];
|
|
18358
|
+
var ITEM_CONTRACTS = createItemContracts();
|
|
18359
|
+
|
|
18360
|
+
// src/kinds.ts
|
|
18361
|
+
var createGoodsKinds = (options = {}) => defineCategories(GOODS_KINDS, options);
|
|
18362
|
+
var lootCategoriesOf = (kinds, kind) => {
|
|
18363
|
+
const value = kinds.defaults(kind).lootCategory;
|
|
18364
|
+
if (value === void 0) return void 0;
|
|
18365
|
+
return Array.isArray(value) ? value : [String(value)];
|
|
18366
|
+
};
|
|
18367
|
+
var checkGoodsItems = (options = {}) => {
|
|
18368
|
+
const kinds = options.kinds ?? createGoodsKinds();
|
|
18369
|
+
const entries = options.entries ?? GOODS_ITEMS;
|
|
18370
|
+
const report = checkCategorized(entries, kinds, createItemContracts({ items: entries, ...options }), { allow: options.allow ?? GOODS_KNOWN_GAPS });
|
|
18371
|
+
const problems = [...report.problems];
|
|
18372
|
+
for (const entry of entries) {
|
|
18373
|
+
if (!kinds.has(entry.kind) || kinds.get(entry.kind)?.abstract) continue;
|
|
18374
|
+
const declared = lootCategoriesOf(kinds, entry.kind);
|
|
18375
|
+
if (declared && !declared.includes(entry.category)) problems.push(`"${entry.id}" (${entry.kind}): category "${entry.category}" is not one of ${declared.join(", ")}, required by the kind's lootCategory`);
|
|
18376
|
+
}
|
|
18377
|
+
return { ok: problems.length === 0, problems, allowed: report.allowed };
|
|
18378
|
+
};
|
|
18379
|
+
|
|
18380
|
+
// src/pack.ts
|
|
18381
|
+
var KINDS = createGoodsKinds();
|
|
18382
|
+
var withSeal = (item) => {
|
|
18383
|
+
const kind = item.kind;
|
|
18384
|
+
const seal = kind && KINDS.has(kind) ? KINDS.defaults(kind).seal : void 0;
|
|
18385
|
+
return seal ? { ...item, seal: { ...seal, ...item.seal } } : item;
|
|
18386
|
+
};
|
|
18387
|
+
var goodsPack = {
|
|
18388
|
+
id: "goods",
|
|
18389
|
+
items: GOODS_ITEMS.map(withSeal),
|
|
18390
|
+
categories: GOODS_CATEGORIES,
|
|
18391
|
+
places: GOODS_PLACES,
|
|
18392
|
+
containers: GOODS_CONTAINERS,
|
|
18393
|
+
useEffects: GOODS_USE_EFFECTS,
|
|
18394
|
+
recipes: GOODS_RECIPES,
|
|
18395
|
+
pools: GOODS_HOUSE_POOLS.pools,
|
|
18396
|
+
poolAliases: { ...GOODS_HOUSE_POOLS.aliasOf, ...FLOORPLAN_POOL_ALIASES }
|
|
18397
|
+
};
|
|
18398
|
+
var createGoodsItems = (options = {}) => createItems({ ...options, packs: [goodsPack, ...options.packs ?? []] });
|
|
18399
|
+
|
|
18400
|
+
// src/data/locales/en.json
|
|
18401
|
+
var en_default = {
|
|
18402
|
+
"item.canned_beans": "Canned beans",
|
|
18403
|
+
"item.canned_sardines": "Canned sardines",
|
|
18404
|
+
"item.canned_corn_and_peas": "Canned corn and peas",
|
|
18405
|
+
"item.canned_sausages": "Canned sausages",
|
|
18406
|
+
"item.condensed_milk": "Condensed milk",
|
|
18407
|
+
"item.military_ration": "Army field ration",
|
|
18408
|
+
"item.rice": "Rice (1 kg)",
|
|
18409
|
+
"item.beans": "Beans (1 kg)",
|
|
18410
|
+
"item.pasta": "Pasta",
|
|
18411
|
+
"item.instant_noodles": "Instant noodles",
|
|
18412
|
+
"item.cassava_flour": "Cassava flour (1 kg)",
|
|
18413
|
+
"item.biscuits": "Biscuits",
|
|
18414
|
+
"item.snack_chips": "Bagged snack chips",
|
|
18415
|
+
"item.chocolate_bar": "Chocolate bar",
|
|
18416
|
+
"item.rapadura": "Rapadura (raw cane sugar block)",
|
|
18417
|
+
"item.honey_jar": "Jar of honey",
|
|
18418
|
+
"item.bread": "Bread",
|
|
18419
|
+
"item.cheese": "Cheese",
|
|
18420
|
+
"item.mortadella": "Mortadella (whole piece)",
|
|
18421
|
+
"item.raw_beef": "Raw beef (1 kg)",
|
|
18422
|
+
"item.frozen_chicken": "Frozen chicken",
|
|
18423
|
+
"item.eggs": "Eggs (dozen)",
|
|
18424
|
+
"item.banana_bunch": "Bunch of bananas",
|
|
18425
|
+
"item.orange": "Orange",
|
|
18426
|
+
"item.potatoes": "Potatoes (1 kg)",
|
|
18427
|
+
"item.cassava_root": "Cassava root",
|
|
18428
|
+
"item.fresh_fish": "Fresh fish",
|
|
18429
|
+
"item.salted_fish": "Salted fish",
|
|
18430
|
+
"item.jerked_beef": "Jerked beef",
|
|
18431
|
+
"item.game_meat": "Game meat (capybara, wild boar)",
|
|
18432
|
+
"item.home_preserves": "Home preserves (jar)",
|
|
18433
|
+
"item.dog_food": "Dog food (1 kg)",
|
|
18434
|
+
"item.sugar": "Sugar",
|
|
18435
|
+
"item.salt": "Salt",
|
|
18436
|
+
"item.cooking_oil": "Cooking oil",
|
|
18437
|
+
"item.coffee": "Coffee",
|
|
18438
|
+
"item.water_bottle": "Water bottle",
|
|
18439
|
+
"item.water_jug_5l": "Water jug (5 L)",
|
|
18440
|
+
"item.dirty_water": "River or puddle water",
|
|
18441
|
+
"item.soda_can": "Soda can",
|
|
18442
|
+
"item.juice_box": "Juice box",
|
|
18443
|
+
"item.milk_carton": "Milk carton",
|
|
18444
|
+
"item.sports_drink": "Sports drink",
|
|
18445
|
+
"item.energy_drink": "Energy drink (can)",
|
|
18446
|
+
"item.coconut_water": "Coconut water",
|
|
18447
|
+
"item.beer_can": "Beer (can)",
|
|
18448
|
+
"item.cachaca": "Cachaca (bottle)",
|
|
18449
|
+
"item.communion_wine": "Communion wine",
|
|
18450
|
+
"item.bandage": "Bandage",
|
|
18451
|
+
"item.sterile_gauze": "Sterile gauze",
|
|
18452
|
+
"item.adhesive_bandages": "Adhesive bandages (box)",
|
|
18453
|
+
"item.medical_tape": "Medical tape",
|
|
18454
|
+
"item.alcohol_70": "Alcohol 70%",
|
|
18455
|
+
"item.povidone_iodine": "Povidone-iodine",
|
|
18456
|
+
"item.saline_iv_bag": "Saline bag with IV set",
|
|
18457
|
+
"item.painkillers": "Painkillers",
|
|
18458
|
+
"item.ibuprofen": "Anti-inflammatory (ibuprofen)",
|
|
18459
|
+
"item.tramadol": "Strong painkiller (tramadol)",
|
|
18460
|
+
"item.clonazepam": "Sedative (clonazepam)",
|
|
18461
|
+
"item.amoxicillin": "Antibiotic (amoxicillin)",
|
|
18462
|
+
"item.ceftriaxone": "Injectable antibiotic (ceftriaxone)",
|
|
18463
|
+
"item.syringe": "Disposable syringe",
|
|
18464
|
+
"item.suture_kit": "Suture kit",
|
|
18465
|
+
"item.splint": "Immobilizing splint",
|
|
18466
|
+
"item.first_aid_kit": "First aid kit",
|
|
18467
|
+
"item.exam_gloves": "Exam gloves",
|
|
18468
|
+
"item.n95_mask": "N95 mask",
|
|
18469
|
+
"item.activated_charcoal": "Activated charcoal",
|
|
18470
|
+
"item.rehydration_salts": "Rehydration salts",
|
|
18471
|
+
"item.antihistamine": "Antihistamine",
|
|
18472
|
+
"item.antivenom": "Snake antivenom",
|
|
18473
|
+
"item.thermometer": "Thermometer",
|
|
18474
|
+
"item.maintenance_medication": "Daily-use medication",
|
|
18475
|
+
"item.multivitamin": "Multivitamin",
|
|
18476
|
+
"item.hammer": "Hammer",
|
|
18477
|
+
"item.screwdriver": "Screwdriver",
|
|
18478
|
+
"item.crowbar": "Crowbar",
|
|
18479
|
+
"item.handsaw": "Handsaw",
|
|
18480
|
+
"item.hacksaw": "Hacksaw",
|
|
18481
|
+
"item.bolt_cutters": "Bolt cutters",
|
|
18482
|
+
"item.pliers": "Pliers",
|
|
18483
|
+
"item.adjustable_wrench": "Adjustable wrench",
|
|
18484
|
+
"item.mechanic_toolbox": "Mechanic's toolbox",
|
|
18485
|
+
"item.car_jack": "Car jack and wheel wrench",
|
|
18486
|
+
"item.gas_torch": "Gas torch",
|
|
18487
|
+
"item.inverter_welder": "Inverter welder",
|
|
18488
|
+
"item.cordless_drill": "Cordless drill",
|
|
18489
|
+
"item.shovel": "Shovel",
|
|
18490
|
+
"item.hoe": "Hoe",
|
|
18491
|
+
"item.pocket_knife": "Multi-tool pocket knife",
|
|
18492
|
+
"item.can_opener": "Can opener",
|
|
18493
|
+
"item.scissors": "Scissors",
|
|
18494
|
+
"item.duct_tape": "Duct tape",
|
|
18495
|
+
"item.pot": "Pot",
|
|
18496
|
+
"item.camp_stove": "Camping stove",
|
|
18497
|
+
"item.sewing_kit": "Sewing kit",
|
|
18498
|
+
"item.lockpick_kit": "Locksmith kit (lock picks)",
|
|
18499
|
+
"item.lighter": "Lighter",
|
|
18500
|
+
"item.matches": "Matches",
|
|
18501
|
+
"item.flint_striker": "Flint and striker",
|
|
18502
|
+
"item.bucket": "Bucket",
|
|
18503
|
+
"item.binoculars": "Binoculars",
|
|
18504
|
+
"item.fire_extinguisher": "Dry-powder fire extinguisher",
|
|
18505
|
+
"item.sharpening_stone": "Sharpening stone",
|
|
18506
|
+
"item.knife": "Kitchen knife",
|
|
18507
|
+
"item.tactical_knife": "Tactical knife",
|
|
18508
|
+
"item.machete": "Machete",
|
|
18509
|
+
"item.meat_cleaver": "Butcher's cleaver",
|
|
18510
|
+
"item.hatchet": "Hatchet",
|
|
18511
|
+
"item.axe": "Axe",
|
|
18512
|
+
"item.baseball_bat": "Baseball bat",
|
|
18513
|
+
"item.nail_bat": "Nail bat",
|
|
18514
|
+
"item.iron_pipe": "Iron pipe",
|
|
18515
|
+
"item.sledgehammer": "Sledgehammer",
|
|
18516
|
+
"item.pickaxe": "Pickaxe",
|
|
18517
|
+
"item.sickle": "Sickle",
|
|
18518
|
+
"item.police_baton": "Police baton",
|
|
18519
|
+
"item.cast_iron_skillet": "Cast iron skillet",
|
|
18520
|
+
"item.improvised_spear": "Improvised spear",
|
|
18521
|
+
"item.chainsaw": "Chainsaw",
|
|
18522
|
+
"item.slingshot": "Slingshot",
|
|
18523
|
+
"item.recurve_bow": "Recurve bow",
|
|
18524
|
+
"item.crossbow": "Crossbow",
|
|
18525
|
+
"item.arrows_and_bolts": "Arrows and bolts (6)",
|
|
18526
|
+
"item.wooden_plank": "Wooden plank",
|
|
18527
|
+
"item.nails": "Nails (box of 100)",
|
|
18528
|
+
"item.screws": "Screws (box of 50)",
|
|
18529
|
+
"item.sheet_metal": "Sheet metal",
|
|
18530
|
+
"item.scrap_metal": "Scrap metal",
|
|
18531
|
+
"item.wire_roll": "Wire (10 m roll)",
|
|
18532
|
+
"item.barbed_wire": "Barbed wire (25 m roll)",
|
|
18533
|
+
"item.rope": "Rope",
|
|
18534
|
+
"item.tarp": "Tarp (4 x 4 m)",
|
|
18535
|
+
"item.raffia_sack": "Raffia sack",
|
|
18536
|
+
"item.bricks": "Bricks (10)",
|
|
18537
|
+
"item.cement_bag": "Cement (25 kg bag)",
|
|
18538
|
+
"item.rag": "Rag",
|
|
18539
|
+
"item.glass_bottle": "Empty glass bottle",
|
|
18540
|
+
"item.pet_bottle": "Empty PET bottle",
|
|
18541
|
+
"item.empty_can": "Empty can",
|
|
18542
|
+
"item.glass_shards": "Glass shards",
|
|
18543
|
+
"item.epoxy_glue": "Epoxy glue",
|
|
18544
|
+
"item.electronic_components": "Electronic components",
|
|
18545
|
+
"item.copper_wire": "Copper wire (5 m)",
|
|
18546
|
+
"item.firewood": "Firewood",
|
|
18547
|
+
"item.rebar": "Rebar",
|
|
18548
|
+
"item.lubricant_spray": "Spray lubricant oil",
|
|
18549
|
+
"item.tshirt": "T-shirt",
|
|
18550
|
+
"item.hoodie": "Hoodie",
|
|
18551
|
+
"item.denim_jacket": "Denim jacket",
|
|
18552
|
+
"item.leather_motorcycle_jacket": "Motorcycle jacket (leather)",
|
|
18553
|
+
"item.jeans": "Jeans",
|
|
18554
|
+
"item.leather_motorcycle_pants": "Motorcycle pants",
|
|
18555
|
+
"item.army_camouflage_uniform": "Army camouflage uniform",
|
|
18556
|
+
"item.mechanic_coveralls": "Mechanic's coveralls",
|
|
18557
|
+
"item.firefighter_suit": "Firefighter suit",
|
|
18558
|
+
"item.beekeeper_suit": "Beekeeper suit",
|
|
18559
|
+
"item.raincoat": "Raincoat",
|
|
18560
|
+
"item.padded_coat": "Padded coat",
|
|
18561
|
+
"item.motorcycle_helmet": "Full-face motorcycle helmet",
|
|
18562
|
+
"item.hard_hat": "Hard hat (PPE)",
|
|
18563
|
+
"item.safety_goggles": "Safety goggles",
|
|
18564
|
+
"item.leather_work_gloves": "Leather work gloves",
|
|
18565
|
+
"item.combat_boots": "Combat boots",
|
|
18566
|
+
"item.rubber_boots": "Rubber boots",
|
|
18567
|
+
"item.sneakers": "Sneakers",
|
|
18568
|
+
"item.flip_flops": "Flip-flops",
|
|
18569
|
+
"item.magazine_arm_guard": "Magazine arm guard",
|
|
18570
|
+
"item.sheet_metal_forearm_guard": "Sheet metal forearm guard",
|
|
18571
|
+
"item.ballistic_vest": "Ballistic vests (II-A, III-A, III)",
|
|
18572
|
+
"item.shopping_bag": "Shopping bag",
|
|
18573
|
+
"item.trash_bag": "Trash bag",
|
|
18574
|
+
"item.fanny_pack": "Fanny pack",
|
|
18575
|
+
"item.crossbody_bag": "Crossbody bag",
|
|
18576
|
+
"item.backpack": "Backpack",
|
|
18577
|
+
"item.delivery_bag": "Delivery bag",
|
|
18578
|
+
"item.hiking_backpack_40l": "Hiking backpack 40 L",
|
|
18579
|
+
"item.military_backpack": "Military backpack",
|
|
18580
|
+
"item.trekking_backpack_70l": "Trekking backpack 70 L",
|
|
18581
|
+
"item.rolling_suitcase": "Rolling suitcase",
|
|
18582
|
+
"item.tactical_vest": "Tactical vest",
|
|
18583
|
+
"item.tool_belt": "Tool belt",
|
|
18584
|
+
"item.cooler_box": "Cooler box",
|
|
18585
|
+
"item.shopping_cart": "Shopping cart",
|
|
18586
|
+
"item.wheelbarrow": "Wheelbarrow",
|
|
18587
|
+
"item.flashlight": "Flashlight",
|
|
18256
18588
|
"item.headlamp": "Headlamp",
|
|
18257
18589
|
"item.batteries": "Batteries",
|
|
18258
18590
|
"item.battery_9v": "9 V battery",
|
|
@@ -19089,253 +19421,6 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
|
|
|
19089
19421
|
var GOODS_STRINGS = { en: en_default, "pt-BR": pt_BR_default };
|
|
19090
19422
|
var pickGoodsLocale = (locale) => locale?.toLowerCase().startsWith("pt") ? "pt-BR" : "en";
|
|
19091
19423
|
var goodsText = (key, locale) => GOODS_STRINGS[pickGoodsLocale(locale)][key] ?? key;
|
|
19092
|
-
|
|
19093
|
-
// src/data/item-contracts.json
|
|
19094
|
-
var item_contracts_default = {
|
|
19095
|
-
densityKgPerLitre: { min: 0.02, max: 22 },
|
|
19096
|
-
impactResponses: ["dent", "break", "shatter", "tear", "squash", "pierce", "none"],
|
|
19097
|
-
heatResistantMaterials: ["steel", "cast_iron", "aluminium", "copper", "ceramic", "tempered_glass", "stone", "brick"],
|
|
19098
|
-
bodySlots: ["head", "eyes", "torso", "arms", "hands", "legs", "feet", "over"]
|
|
19099
|
-
};
|
|
19100
|
-
|
|
19101
|
-
// src/contracts.ts
|
|
19102
|
-
var IMPACT_RESPONSES = item_contracts_default.impactResponses;
|
|
19103
|
-
var HEAT_RESISTANT_MATERIALS = item_contracts_default.heatResistantMaterials;
|
|
19104
|
-
var DENSITY_KG_PER_LITRE = item_contracts_default.densityKgPerLitre;
|
|
19105
|
-
var BODY_SLOTS2 = item_contracts_default.bodySlots;
|
|
19106
|
-
var SNAKE_CASE = /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;
|
|
19107
|
-
var LITRES_PER_CUBIC_METRE2 = 1e3;
|
|
19108
|
-
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
19109
|
-
var isFraction2 = (value) => isNumber(value) && value >= 0 && value <= 1;
|
|
19110
|
-
var catalogOf = (options) => options.items ?? GOODS_ITEMS;
|
|
19111
|
-
var parts = (item) => Array.isArray(item.parts) ? item.parts : [];
|
|
19112
|
-
var physical = (options) => {
|
|
19113
|
-
const range = options.density ?? DENSITY_KG_PER_LITRE;
|
|
19114
|
-
return {
|
|
19115
|
-
id: "physical",
|
|
19116
|
-
check: (item) => {
|
|
19117
|
-
const problems = [];
|
|
19118
|
-
const size = item.size;
|
|
19119
|
-
const sizeOk = Array.isArray(size) && size.length === 3 && size.every((side) => isNumber(side) && side > 0);
|
|
19120
|
-
if (!sizeOk) problems.push("size must be 3 finite positive numbers in metres");
|
|
19121
|
-
if (!isNumber(item.weight) || item.weight < 0) problems.push("weight must be a finite number >= 0 (kg)");
|
|
19122
|
-
if (sizeOk && isNumber(item.weight) && item.weight > 0) {
|
|
19123
|
-
const [width, height, depth] = size;
|
|
19124
|
-
const density = item.weight / (width * height * depth * LITRES_PER_CUBIC_METRE2);
|
|
19125
|
-
if (density < range.min || density > range.max) problems.push(`density ${Number(density.toPrecision(2))} kg/L is outside ${range.min}..${range.max}`);
|
|
19126
|
-
}
|
|
19127
|
-
return problems;
|
|
19128
|
-
}
|
|
19129
|
-
};
|
|
19130
|
-
};
|
|
19131
|
-
var destructible = (options) => {
|
|
19132
|
-
const materials = options.materials ? new Set(options.materials) : void 0;
|
|
19133
|
-
return {
|
|
19134
|
-
id: "destructible",
|
|
19135
|
-
check: (item) => {
|
|
19136
|
-
const list = parts(item);
|
|
19137
|
-
if (list.length === 0) return ["missing parts"];
|
|
19138
|
-
const problems = [];
|
|
19139
|
-
const seen = /* @__PURE__ */ new Set();
|
|
19140
|
-
for (const part of list) {
|
|
19141
|
-
if (typeof part.id !== "string" || part.id === "") problems.push("a part has no id");
|
|
19142
|
-
else if (seen.has(part.id)) problems.push(`duplicate part "${part.id}"`);
|
|
19143
|
-
else seen.add(part.id);
|
|
19144
|
-
if (typeof part.material !== "string" || part.material === "") problems.push(`part "${part.id}" has no material`);
|
|
19145
|
-
else if (materials && !materials.has(part.material)) problems.push(`part "${part.id}" has unknown material "${part.material}"`);
|
|
19146
|
-
if (part.thickness !== void 0 && !(isNumber(part.thickness) && part.thickness > 0)) problems.push(`part "${part.id}" thickness must be a positive number`);
|
|
19147
|
-
}
|
|
19148
|
-
if (problems.length === 0 && list.every((part) => part.shape !== void 0 && part.position !== void 0)) {
|
|
19149
|
-
const report = checkSpec({ parts: list }, materials ? { materials } : {});
|
|
19150
|
-
for (const problem of report.problems) problems.push(`spec: ${problem}`);
|
|
19151
|
-
}
|
|
19152
|
-
return problems;
|
|
19153
|
-
}
|
|
19154
|
-
};
|
|
19155
|
-
};
|
|
19156
|
-
var impact = {
|
|
19157
|
-
id: "impact",
|
|
19158
|
-
check: (item) => {
|
|
19159
|
-
const value = item.impact;
|
|
19160
|
-
if (!value) return ["missing impact"];
|
|
19161
|
-
const problems = [];
|
|
19162
|
-
if (!IMPACT_RESPONSES.includes(value.response ?? "")) problems.push(`impact.response must be one of ${IMPACT_RESPONSES.join(", ")}`);
|
|
19163
|
-
if (typeof value.pushImpulse !== "boolean") problems.push("impact.pushImpulse must be true or false");
|
|
19164
|
-
if (value.shed !== void 0 && typeof value.shed !== "boolean") problems.push("impact.shed must be true or false");
|
|
19165
|
-
return problems;
|
|
19166
|
-
}
|
|
19167
|
-
};
|
|
19168
|
-
var useAnimation = {
|
|
19169
|
-
id: "use_animation",
|
|
19170
|
-
check: (item) => {
|
|
19171
|
-
const problems = [];
|
|
19172
|
-
const clip = item.use?.clip;
|
|
19173
|
-
if (clip === void 0) problems.push("missing use.clip");
|
|
19174
|
-
else if (!SNAKE_CASE.test(clip)) problems.push(`use.clip "${clip}" must be snake_case`);
|
|
19175
|
-
const sounds = item.use?.sounds;
|
|
19176
|
-
if (!Array.isArray(sounds) || sounds.length === 0 || sounds.some((sound) => typeof sound !== "string" || sound === "")) problems.push("missing use.sounds (a non-empty list of sound ids)");
|
|
19177
|
-
return problems;
|
|
19178
|
-
}
|
|
19179
|
-
};
|
|
19180
|
-
var leftover = (options) => {
|
|
19181
|
-
const ids = new Set(catalogOf(options).map((item) => item.id));
|
|
19182
|
-
return {
|
|
19183
|
-
id: "leftover",
|
|
19184
|
-
check: (item) => {
|
|
19185
|
-
const value = item.leftover;
|
|
19186
|
-
if (value === void 0) return ["missing leftover"];
|
|
19187
|
-
if (value === "none") return [];
|
|
19188
|
-
const problems = [];
|
|
19189
|
-
if (typeof value !== "object" || value === null) return ['leftover must be an object or "none"'];
|
|
19190
|
-
if (typeof value.item !== "string" || value.item === "") problems.push("missing leftover.item");
|
|
19191
|
-
else if (!ids.has(value.item)) problems.push(`leftover.item "${value.item}" is not in the catalog`);
|
|
19192
|
-
if (!isNumber(value.despawnSeconds) || value.despawnSeconds < 0) problems.push("missing leftover.despawnSeconds");
|
|
19193
|
-
return problems;
|
|
19194
|
-
}
|
|
19195
|
-
};
|
|
19196
|
-
};
|
|
19197
|
-
var edible = {
|
|
19198
|
-
id: "edible",
|
|
19199
|
-
check: (item) => {
|
|
19200
|
-
const problems = [];
|
|
19201
|
-
const nutrition = item.nutrition;
|
|
19202
|
-
if (!nutrition || !(isNumber(nutrition.satiety) || isNumber(nutrition.hydration))) problems.push("missing nutrition");
|
|
19203
|
-
if (item.shelfLife === void 0 && item.nonPerishable !== true) problems.push("missing shelfLife (a number of days, or nonPerishable: true)");
|
|
19204
|
-
else if (item.shelfLife !== void 0 && !(isNumber(item.shelfLife) && item.shelfLife > 0)) problems.push("shelfLife must be a positive number of days");
|
|
19205
|
-
if (!isFraction2(item.rawEffect?.sickChance)) problems.push("missing rawEffect.sickChance (0..1)");
|
|
19206
|
-
return problems;
|
|
19207
|
-
}
|
|
19208
|
-
};
|
|
19209
|
-
var inputsOf = (recipe) => recipe.inputs ?? [];
|
|
19210
|
-
var toolsOf = (recipe) => recipe.tools ?? [];
|
|
19211
|
-
var consumes = (input, item) => {
|
|
19212
|
-
if (input.item === item.id) return true;
|
|
19213
|
-
if (input.any?.includes(item.id)) return true;
|
|
19214
|
-
if (!input.match) return false;
|
|
19215
|
-
const entries = Object.entries(input.match);
|
|
19216
|
-
return entries.length > 0 && entries.every(([key, value]) => item[key] === value);
|
|
19217
|
-
};
|
|
19218
|
-
var recipeInput = (options) => {
|
|
19219
|
-
const recipes = options.recipes ?? GOODS_RECIPES;
|
|
19220
|
-
return {
|
|
19221
|
-
id: "recipe_input",
|
|
19222
|
-
check: (item) => recipes.some((recipe) => inputsOf(recipe).some((input) => consumes(input, item))) ? [] : ["is not an input of any recipe"]
|
|
19223
|
-
};
|
|
19224
|
-
};
|
|
19225
|
-
var preparation = (options) => {
|
|
19226
|
-
const recipes = options.recipes ?? GOODS_RECIPES;
|
|
19227
|
-
const cookware = new Set(catalogOf(options).filter((item) => item.kind === "cookware").map((item) => item.id));
|
|
19228
|
-
return {
|
|
19229
|
-
id: "preparation",
|
|
19230
|
-
check: (item) => {
|
|
19231
|
-
const usable = recipes.filter((recipe) => inputsOf(recipe).some((input) => consumes(input, item)));
|
|
19232
|
-
if (usable.length === 0) return ["has no recipe that prepares it"];
|
|
19233
|
-
const prepares = usable.some((recipe) => {
|
|
19234
|
-
const heat = toolsOf(recipe).some((tool) => tool.world?.includes("fire"));
|
|
19235
|
-
const vessel = [...inputsOf(recipe).flatMap((input) => input.item ? [input.item] : []), ...toolsOf(recipe).flatMap((tool) => tool.anyOf ?? [])].some((id) => cookware.has(id));
|
|
19236
|
-
return heat && vessel;
|
|
19237
|
-
});
|
|
19238
|
-
return prepares ? [] : ["has no recipe that needs fire and a cooking vessel"];
|
|
19239
|
-
}
|
|
19240
|
-
};
|
|
19241
|
-
};
|
|
19242
|
-
var liquidContainer = {
|
|
19243
|
-
id: "liquid_container",
|
|
19244
|
-
check: (item) => {
|
|
19245
|
-
const fluid = item.fluid;
|
|
19246
|
-
if (fluid) {
|
|
19247
|
-
const problems = [];
|
|
19248
|
-
if (typeof fluid.liquid !== "string" || !SNAKE_CASE.test(fluid.liquid)) problems.push("fluid.liquid must be a liquid id");
|
|
19249
|
-
if (!isNumber(fluid.liters) || fluid.liters < 0) problems.push("fluid.liters must be a number >= 0");
|
|
19250
|
-
return problems;
|
|
19251
|
-
}
|
|
19252
|
-
return isNumber(item.container?.capacityLiters) && (item.container?.capacityLiters ?? 0) > 0 ? [] : ["missing fluid { liquid, liters } or container.capacityLiters"];
|
|
19253
|
-
}
|
|
19254
|
-
};
|
|
19255
|
-
var heatResistant = (options) => {
|
|
19256
|
-
const allowed = new Set(options.heatResistant ?? HEAT_RESISTANT_MATERIALS);
|
|
19257
|
-
return {
|
|
19258
|
-
id: "heat_resistant",
|
|
19259
|
-
check: (item) => parts(item).filter((part) => !allowed.has(part.material)).map((part) => `part "${part.id}" is ${part.material}, which does not take a flame`)
|
|
19260
|
-
};
|
|
19261
|
-
};
|
|
19262
|
-
var weapon = (options) => {
|
|
19263
|
-
const weaponIds = options.weaponIds ? new Set(options.weaponIds) : void 0;
|
|
19264
|
-
const calibers = options.calibers ? new Set(options.calibers) : void 0;
|
|
19265
|
-
return {
|
|
19266
|
-
id: "weapon",
|
|
19267
|
-
check: (item, ctx) => {
|
|
19268
|
-
if (ctx.chain.includes("ammo")) {
|
|
19269
|
-
if (typeof item.caliber !== "string" || item.caliber === "") return ["missing caliber"];
|
|
19270
|
-
return calibers && !calibers.has(item.caliber) ? [`caliber "${item.caliber}" is not in the arsenal`] : [];
|
|
19271
|
-
}
|
|
19272
|
-
if (typeof item.weapon !== "string" || item.weapon === "") return ["missing weapon (the arsenal id)"];
|
|
19273
|
-
return weaponIds && !weaponIds.has(item.weapon) ? [`weapon "${item.weapon}" is not in the arsenal`] : [];
|
|
19274
|
-
}
|
|
19275
|
-
};
|
|
19276
|
-
};
|
|
19277
|
-
var wearable = {
|
|
19278
|
-
id: "wearable",
|
|
19279
|
-
check: (item, ctx) => {
|
|
19280
|
-
const problems = [];
|
|
19281
|
-
const { protection, carry } = item;
|
|
19282
|
-
if (!protection && !carry) return [ctx.chain.includes("bag") ? "missing carry" : "missing protection"];
|
|
19283
|
-
if (ctx.chain.includes("bag") && !carry) problems.push("missing carry");
|
|
19284
|
-
if (ctx.chain.includes("clothing") && !protection) problems.push("missing protection");
|
|
19285
|
-
if (protection) {
|
|
19286
|
-
const slots = protection.slots;
|
|
19287
|
-
if (!Array.isArray(slots) || slots.length === 0) problems.push("protection.slots must list at least one body slot");
|
|
19288
|
-
else for (const slot of slots) if (!BODY_SLOTS2.includes(slot)) problems.push(`protection.slots has unknown slot "${slot}"`);
|
|
19289
|
-
for (const field of ["bite", "scratch", "warmth"]) if (protection[field] !== void 0 && !isFraction2(protection[field])) problems.push(`protection.${field} must be between 0 and 1`);
|
|
19290
|
-
}
|
|
19291
|
-
if (carry) {
|
|
19292
|
-
if (!(isNumber(carry.capacityKg) && carry.capacityKg > 0)) problems.push("carry.capacityKg must be positive");
|
|
19293
|
-
if (!isFraction2(carry.weightReduction)) problems.push("carry.weightReduction must be between 0 and 1");
|
|
19294
|
-
if (!(isNumber(carry.quickSlots) && carry.quickSlots >= 0)) problems.push("carry.quickSlots must be >= 0");
|
|
19295
|
-
}
|
|
19296
|
-
return problems;
|
|
19297
|
-
}
|
|
19298
|
-
};
|
|
19299
|
-
var battery = {
|
|
19300
|
-
id: "battery",
|
|
19301
|
-
check: (item) => isNumber(item.charge?.lossPerMonth) && (item.charge?.lossPerMonth ?? -1) >= 0 ? [] : ["missing charge.lossPerMonth"]
|
|
19302
|
-
};
|
|
19303
|
-
var createItemContracts = (options = {}) => [
|
|
19304
|
-
physical(options),
|
|
19305
|
-
destructible(options),
|
|
19306
|
-
impact,
|
|
19307
|
-
useAnimation,
|
|
19308
|
-
leftover(options),
|
|
19309
|
-
edible,
|
|
19310
|
-
preparation(options),
|
|
19311
|
-
recipeInput(options),
|
|
19312
|
-
liquidContainer,
|
|
19313
|
-
heatResistant(options),
|
|
19314
|
-
weapon(options),
|
|
19315
|
-
wearable,
|
|
19316
|
-
battery
|
|
19317
|
-
];
|
|
19318
|
-
var ITEM_CONTRACTS = createItemContracts();
|
|
19319
|
-
|
|
19320
|
-
// src/kinds.ts
|
|
19321
|
-
var createGoodsKinds = (options = {}) => defineCategories(GOODS_KINDS, options);
|
|
19322
|
-
var lootCategoriesOf = (kinds, kind) => {
|
|
19323
|
-
const value = kinds.defaults(kind).lootCategory;
|
|
19324
|
-
if (value === void 0) return void 0;
|
|
19325
|
-
return Array.isArray(value) ? value : [String(value)];
|
|
19326
|
-
};
|
|
19327
|
-
var checkGoodsItems = (options = {}) => {
|
|
19328
|
-
const kinds = options.kinds ?? createGoodsKinds();
|
|
19329
|
-
const entries = options.entries ?? GOODS_ITEMS;
|
|
19330
|
-
const report = checkCategorized(entries, kinds, createItemContracts({ items: entries, ...options }), { allow: options.allow ?? GOODS_KNOWN_GAPS });
|
|
19331
|
-
const problems = [...report.problems];
|
|
19332
|
-
for (const entry of entries) {
|
|
19333
|
-
if (!kinds.has(entry.kind) || kinds.get(entry.kind)?.abstract) continue;
|
|
19334
|
-
const declared = lootCategoriesOf(kinds, entry.kind);
|
|
19335
|
-
if (declared && !declared.includes(entry.category)) problems.push(`"${entry.id}" (${entry.kind}): category "${entry.category}" is not one of ${declared.join(", ")}, required by the kind's lootCategory`);
|
|
19336
|
-
}
|
|
19337
|
-
return { ok: problems.length === 0, problems, allowed: report.allowed };
|
|
19338
|
-
};
|
|
19339
19424
|
return __toCommonJS(index_exports);
|
|
19340
19425
|
})();
|
|
19341
19426
|
//# sourceMappingURL=index.global.js.map
|