Skip to content

Commit 7cc8cd6

Browse files
authored
Merge pull request #17 from TheCodeRaccoons/Backwards-compatibility
Backwards compatibility
2 parents d8eeffc + 631d12e commit 7cc8cd6

8 files changed

Lines changed: 201 additions & 55 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
.section-achievements {
2+
display: flex;
3+
align-items:start;
4+
gap: 1rem;
5+
flex-wrap: wrap;
6+
}
7+
8+
.dishes-grid {
9+
display: flex;
10+
flex-wrap: wrap;
11+
gap: 0.5rem;
12+
}
13+
14+
.dish-item {
15+
display: block;
16+
position: relative;
17+
}
18+
19+
.dish-item .times-cooked {
20+
text-decoration: none;
21+
color: white;
22+
font-weight: bold;
23+
text-shadow: 2px 2px 2px #000;
24+
position: absolute;
25+
bottom: 5px;
26+
right: 0;
27+
}
28+
29+
.achievement-item {
30+
display: flex;
31+
align-items: center;
32+
gap: 0.5rem;
33+
font-weight: bold;
34+
max-width: 30%;
35+
}
36+
37+
.section-achievements img {
38+
width: 3rem !important;
39+
height: 3rem !important;
40+
}
41+
42+
.section-achievements img.achieved {
43+
filter: grayscale(0) brightness(1) !important;
44+
}
45+
46+
.section-achievements img.pending {
47+
filter: grayscale(1) brightness(0.5) !important;
48+
}

src/Components/AchieveTabs/Cooking/index.tsx

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,79 @@
1-
import { useState, useEffect } from 'react'
2-
import type { generalFormatedItemType } from 'types/displayDataTypes';
3-
4-
interface dishesCookedType {
5-
cookedItems: generalFormatedItemType[];
6-
}
7-
8-
const Food = ( {cookedItems} : dishesCookedType) => {
9-
const [dishesCooked, setDishesCooked] = useState(0);
10-
if(!cookedItems) return <div>No cooking data available.</div>;
11-
12-
const canMap = (cookedItems && cookedItems.length > 0);
13-
console.log("Cooking data:", cookedItems);
14-
useEffect(() => {
15-
const cookedCount = canMap ? cookedItems.map((num) => (num.times !== undefined && num.times > 0) ? 1 : 0).reduce((n: number, next: number) => n + next, 0) : 0;
16-
setDishesCooked(cookedCount);
17-
}, [cookedItems]);
18-
const cookedCount = canMap ? cookedItems.map((num) => (num.times !== undefined && num.times > 0) ? 1 : 0).reduce((n: number, next: number) => n + next, 0) : 0;
19-
const knownCount = canMap ? cookedItems.map((num) => (num.times !== undefined && num.times >= 0) ? 1 : 0).reduce((n: number, next: number) => n + next, 0) : 0;
1+
import type { cookingDataType } from 'types/displayDataTypes';
2+
import { Cook, SousChef, GourmetChef } from '@media/Achievements';
3+
import './Cooking.css';
204

5+
const Food = ( {cookedItems, knownRecipes, alreadyCookedRecipes} : cookingDataType) => {
216
return (
227
<div className="progress-container">
23-
<span className="a-title"><h1>You have cooked {cookedCount}, knowing {knownCount} out of {cookedItems.length} recipes</h1></span>
8+
<span className="a-title">
9+
<h2>
10+
Has cooked {alreadyCookedRecipes}, knowing {knownRecipes} out of 74 recipes
11+
</h2>
12+
</span>
2413
<br />
2514
<h2>Cooking Achievements</h2>
26-
<ul className="a-List">
27-
<li>Cook: {(dishesCooked >= 10) ? <span className="completed">You have this achievement</span> : <span className="pending">You need to cook {10 - dishesCooked} more dishes to get this</span> } </li>
28-
<li>Sous Chef: {(dishesCooked >= 25) ? <span className="completed">You have this achievement</span> : <span className="pending"> You need to cook {25 - dishesCooked} more dishes to get this</span> }</li>
29-
<li>Gourmet Chef: {(dishesCooked >= 74) ? <span className="completed">You have this achievement</span> : <span className="pending">You need to cook {74 - dishesCooked} more dishes to get this</span> }</li>
30-
</ul>
15+
<div className="section-achievements">
16+
<div className="achievement-item">
17+
<img
18+
className={`${(alreadyCookedRecipes >= 10) ?
19+
"achieved" : "pending"}`}
20+
src={Cook}
21+
alt="Cook Achievement"
22+
/>
23+
<div>
24+
<h3>Cook:</h3>
25+
<p>Cook a total of 10 dishes</p>
26+
</div>
27+
</div>
28+
<div className="achievement-item">
29+
<img
30+
className={`${(alreadyCookedRecipes >= 25) ?
31+
"achieved" : "pending"}`}
32+
src={SousChef}
33+
alt="Sous Chef Achievement"
34+
/>
35+
<div>
36+
<h3>Sous Chef:</h3>
37+
<p>Cook a total of 25 dishes</p>
38+
</div>
39+
</div>
40+
<div className="achievement-item">
41+
<img
42+
className={`${(alreadyCookedRecipes >= 74) ?
43+
"achieved" : "pending"}`}
44+
src={GourmetChef}
45+
alt="Gourmet Chef Achievement"
46+
/>
47+
<div>
48+
<h3>Gourmet Chef:</h3>
49+
<p>Cook a total of 74 dishes</p>
50+
</div>
51+
</div>
52+
</div>
3153
<br />
32-
{ canMap ?
33-
cookedItems.map((d, i) => <a href={`https://stardewvalleywiki.com/${d.link}`} target="blank" key={i}><img src={`https://stardew-tracker.s3.amazonaws.com/Cooking/${d.image}.png`} alt={d.name} className={ (d.times !== undefined) ? ((d.times > 0) ? "done" : "known" ): "" } title={(d.times !== undefined) ? (d.times > 0) ? `Cooked ${d.name} ${d.times} times` : `You haven't cooked ${d.name}` : `You don't know how to cook ${d.name}`} ></img></a>)
34-
: null
54+
<div className="dishes-grid">
55+
{ cookedItems ?
56+
cookedItems.map((d, i) =>
57+
<a
58+
href={`https://stardewvalleywiki.com/${d.link}`}
59+
target="blank"
60+
key={i}
61+
className="dish-item">
62+
<img
63+
src={`https://stardew-tracker.s3.amazonaws.com/Cooking/${d.image}.png`}
64+
alt={d.name}
65+
className={ (d.times !== undefined) ? ((d.times > 0) ? "done" : "known" ): "" }
66+
title={(d.times !== undefined) ?
67+
(d.times > 0) ? `Cooked ${d.name} ${d.times} times`
68+
: `You haven't cooked ${d.name}`
69+
: `You don't know how to cook ${d.name}`
70+
} >
71+
</img>
72+
<p className="times-cooked">x{d.times}</p>
73+
</a>)
74+
: <div>No cooking data available.</div>
3575
}
76+
</div>
3677
</div>
3778
);
3879
};

src/Components/Achievements/Achievements.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const Achievements = ({
2424
professions,
2525
shippedItems,
2626
cropsShipped,
27-
cookedItems,
27+
cookingData,
2828
museumCollection,
2929
availableSpecialRequests,
3030
fishCaught,
@@ -58,7 +58,7 @@ const Achievements = ({
5858
</TabList>
5959
<TabPanel>
6060
<section className="achievement-container">
61-
<Cooking cookedItems={cookedItems}></Cooking>
61+
<Cooking {...cookingData} ></Cooking>
6262
</section>
6363
</TabPanel>
6464
<TabPanel>

src/Components/Utility/Utility.tsx

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import type {
2929
itemFoundType,
3030
experienceType,
3131
formatedFriendshipDataType,
32-
formatedMonsterDataType
32+
formatedMonsterDataType,
33+
cookingDataType
3334
} from 'types/displayDataTypes';
3435
import type { fullPlayerDataType, museumCollectionType } from 'types/displayDataTypes';
3536

@@ -67,7 +68,12 @@ type getParsedUserDataType = Omit<getDetailedInfoType, 'playerData'> & {
6768
}
6869

6970
//Calls the parser and creates an array of players depending on wether it is a single player or multiple
70-
const GetDetailedInfo = ({playerData , collectionStatus, specialRequests, availableSpecialRequests}: getDetailedInfoType) =>{
71+
const GetDetailedInfo = ({
72+
playerData ,
73+
collectionStatus,
74+
specialRequests,
75+
availableSpecialRequests
76+
}: getDetailedInfoType) =>{
7177
let fullPlayerData: fullPlayerDataType[] = []
7278
if(Array.isArray(playerData)){
7379
playerData.forEach(p => {
@@ -86,7 +92,12 @@ const GetDetailedInfo = ({playerData , collectionStatus, specialRequests, availa
8692
}
8793

8894
//Creates an object per player with the cleanup playerData.from the file
89-
const parseData = ({playerData, collectionStatus, specialRequests, availableSpecialRequests}: getParsedUserDataType) : fullPlayerDataType => {
95+
const parseData = ({
96+
playerData,
97+
collectionStatus,
98+
specialRequests,
99+
availableSpecialRequests
100+
}: getParsedUserDataType) : fullPlayerDataType => {
90101
//Not finished
91102
console.log("Parsing data for:", playerData)
92103
let fullPlayerData : fullPlayerDataType = {
@@ -98,16 +109,24 @@ const parseData = ({playerData, collectionStatus, specialRequests, availableSpec
98109
shippedItems: GetShippedItems(playerData.basicShipped) || [],//DONE
99110
cropsShipped: GetCropsAchievements(playerData.basicShipped?.item),//Refactored DONE
100111
//mineralsFound: GetArrayData(playerData.mineralsFound?.item) || [], //DONE
101-
cookedItems: GetCookingData(playerData.recipesCooked, playerData.cookingRecipes.item) || [], //DONE
112+
cookingData: GetCookingData(playerData.recipesCooked, playerData.cookingRecipes.item) || [], //DONE
102113
fishCaught: GetFishes(playerData.fishCaught.item) || [],
103114
tailoredItems: GetArrayDataTimeless(playerData.tailoredItems) || [],
104115
itemsCrafted: GetCraftingRecipes(playerData.craftingRecipes.item) || [],
105116
friendship: GetFriendshipData(playerData.friendshipData.item) || [],
106-
monstersKilled: GetMonsterQuests(playerData.stats.specificMonstersKilled.item, playerData.stats.slimesKilled) || [],
107-
museumCollection: GetMCollection(playerData.archaeologyFound.item, playerData.mineralsFound.item, collectionStatus) || {},
117+
monstersKilled:
118+
GetMonsterQuests(playerData.stats.specificMonstersKilled.item, playerData.stats.slimesKilled) || [],
119+
museumCollection:
120+
GetMCollection(playerData.archaeologyFound.item, playerData.mineralsFound.item, collectionStatus) || {},
108121
questsDone: playerData.stats.questsCompleted || 0,
109-
specialRequests: specialRequests?.SpecialOrder ? GetSpecialRequests(specialRequests.SpecialOrder, townSR.Requests, true) : [],
110-
availableSpecialRequests: specialRequests?.SpecialOrder ? GetSpecialRequests(specialRequests.SpecialOrder, townSR.Requests, false) : []
122+
specialRequests:
123+
specialRequests?.SpecialOrder ?
124+
GetSpecialRequests(specialRequests.SpecialOrder, townSR.Requests, true)
125+
: [],
126+
availableSpecialRequests:
127+
specialRequests?.SpecialOrder ?
128+
GetSpecialRequests(specialRequests.SpecialOrder, townSR.Requests, false)
129+
: []
111130
}
112131

113132
console.log(`%c Grandpa's eval for ${playerData.name}`, 'color: #7289DA')
@@ -207,31 +226,46 @@ const GetShippedItems = (allShipped: itemType) :generalFormatedItemType[] => {
207226
}
208227
/* End of Shipping Related Achievements */
209228

210-
const GetCookingData = (cooked: itemType, known: itemsType[]): generalFormatedItemType[] =>{
229+
const GetCookingData = (cooked: itemType, known: itemsType[]): cookingDataType =>{
211230
let data: generalFormatedItemType[] = [];
231+
let knownRecipes = 0;
232+
let alreadyCooked = 0;
212233
Dishes.Dishes.forEach(item => {
213234
let knownDish = ValidateKnown(known, NameTranslate(item.Name)) || false
235+
let cookedTimes = GetCooked(cooked.item, item.id)
236+
if(cookedTimes > 0) alreadyCooked++;
237+
if(knownDish) knownRecipes++;
238+
console.log('Dish:', item.Name, 'Known:', knownRecipes, 'CookedTimes:', alreadyCooked)
214239
let d = {
215240
name: NameTranslate(item.Name),
216241
id: item.id,
217242
image: GetImages(item.Name),
218243
link: item.link,
219244
knownDish: knownDish,
220-
times: knownDish ? GetCooked(cooked.item, item.id) : 0
245+
times: cookedTimes
221246
}
222247
data.push(d);
223248
})
224-
console.log('Cooking Data:', data);
225-
return data
249+
return { knownRecipes, alreadyCookedRecipes: alreadyCooked, cookedItems: data };
226250
}
227251

228252
const GetCooked = (cookedItems:itemsType[], id: number): number => {
229-
let cooked = 0;
253+
let timesCooked = 0;
230254
if(Array.isArray(cookedItems)){
231-
let i = cookedItems.find(item => item.key.int === id)
232-
cooked = (i !== undefined) ? i.value.int : 0
255+
let i = cookedItems.find(item => {
256+
if (item.key?.int === undefined){
257+
if (item.key?.string !== undefined){
258+
return +item.key.string === id;
259+
} else{
260+
return false;
261+
}
262+
} else {
263+
return item.key.int === id
264+
}
265+
})
266+
timesCooked = (i !== undefined) ? i.value.int : 0
233267
}
234-
return cooked;
268+
return timesCooked;
235269
}
236270

237271
const GetCraftingRecipes = (recipes: itemsType[]): generalFormatedItemType[] => {

src/Components/stats/stats.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const Stats = ({playerData, farmName, farmhandData}: formattedSaveFileType) => {
3636
<img src={Rope} alt=""></img>
3737
</div>
3838
<Achievements
39-
cookedItems={p.cookedItems}
39+
cookingData={p.cookingData}
4040
itemsCrafted={p.itemsCrafted}
4141
cropsShipped={p.cropsShipped}
4242
professions={p.professions}
@@ -74,7 +74,7 @@ const Stats = ({playerData, farmName, farmhandData}: formattedSaveFileType) => {
7474
<img src={Rope} alt=""></img>
7575
</div>
7676
<Achievements
77-
cookedItems={playerData.cookedItems}
77+
cookingData={playerData.cookingData}
7878
itemsCrafted={playerData.itemsCrafted}
7979
professions={playerData.professions}
8080
cropsShipped={playerData.cropsShipped}

src/hooks/useLoadSaveFile.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import { GetDetailedInfo, GetFarmHands } from '@utility/Utility';
44
import type {
55
gameLocationType,
66
itemsType,
7-
itemType,
87
playerType,
9-
saveFileType,
108
saveGameType,
119
specialOrderType
1210
} from 'types/savefile.js';
@@ -62,12 +60,25 @@ const useLoadSaveFile = (): UseLoadSaveFileResult => {
6260
};
6361

6462
const getPlayerData = useCallback(() => {
65-
//getting players
66-
console.log("Getting player data...")
63+
//getting players
6764
if(!fileData) return;
6865
let player = fileData.SaveGame.player;
69-
let farmHands = GetFarmHands(fileData.SaveGame.locations.GameLocation);
70-
let museumLocation: gameLocationType | undefined = fileData.SaveGame.locations.GameLocation.find((loc: gameLocationType) => {
66+
let farmHands: playerType[] = [];
67+
const gameVersion = fileData.SaveGame.gameVersion;
68+
const [major, minor] = gameVersion.split('.').map(Number);
69+
if (major && minor && (major < 1 || (major >= 1 && minor < 5))) {
70+
farmHands = GetFarmHands(fileData.SaveGame.locations.GameLocation);
71+
} else {
72+
if(Array.isArray(fileData.SaveGame.farmhands)){
73+
farmHands = [...fileData.SaveGame.farmhands.Farmers];
74+
} else {
75+
console.log("Legacy single farmhand detected")
76+
console.log(fileData.SaveGame.farmhands)
77+
farmHands = [fileData.SaveGame.farmhands.Farmer];
78+
}
79+
}
80+
let museumLocation: gameLocationType | undefined =
81+
fileData.SaveGame.locations.GameLocation.find((loc: gameLocationType) => {
7182
return loc.name === "ArchaeologyHouse";
7283
});
7384
if(!museumLocation) {

src/types/displayDataTypes.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export type fullPlayerDataType = {
1313
shippedItems: generalFormatedItemType[];
1414
cropsShipped: cropsShippedType;
1515
mineralsFound?: itemFoundType[];
16-
cookedItems: generalFormatedItemType[];
16+
cookingData: cookingDataType;
1717
museumCollection: museumCollectionType;
1818
availableSpecialRequests: string[];
1919
fishCaught: generalFormatedItemType[];
@@ -25,6 +25,12 @@ export type fullPlayerDataType = {
2525
tailoredItems: string[];
2626
};
2727

28+
export type cookingDataType = {
29+
knownRecipes: number;
30+
alreadyCookedRecipes: number;
31+
cookedItems: generalFormatedItemType[];
32+
}
33+
2834
export type generalFormatedItemType = {
2935
id?: number;
3036
image: string;

src/types/savefile.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ export type saveFileType = {
5959
gameVersionLabel: string,
6060
completedSpecialOrders: specialOrderType,
6161
availableSpecialOrders: specialOrderType,
62+
farmhands: legacyFarmerType,
63+
}
64+
65+
type legacyFarmerType = {
66+
Farmer: playerType,
67+
Farmers: playerType[],
6268
}
6369

6470
export type specialOrderType = {

0 commit comments

Comments
 (0)