Skip to content

Commit

Permalink
Persist resource settings (#109)
Browse files Browse the repository at this point in the history
* fix: Broken font references (#108)

Every time these themes are loaded, a 400 error is produced for these invalid font requests.

* Improve workshop crafting speed tooltip

* Make auto-pin Leviathans to persist between save/load cycles

* Make hidden pseudo-resources persist between save/load cycles

* Set unlocked flag for pseudo-resources

* Write mediocre shouldComponentUpdate that works well enough for now

* Fix meaningless resPercent if maxValue was zero

* Fix misspelling in PA description

* Replace dojo.some with Array.prototype.some

---------

Co-authored-by: Oliver Salzburg <[email protected]>
  • Loading branch information
Brent-Call and oliversalzburg authored Jan 17, 2025
1 parent a9fbcdc commit af758ef
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 81 deletions.
4 changes: 4 additions & 0 deletions js/diplomacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,15 @@ dojo.declare("classes.managers.DiplomacyManager", null, {
"name", "embassyLevel", "unlocked", "collapsed", "energy", "duration", "pinned"
])
};
if (this.get("leviathans").autoPinned) {
saveData.diplomacy.autoPinLeviathans = true;
}
},

load: function(saveData){
if (saveData.diplomacy) {
this.game.bld.loadMetadata(this.races, saveData.diplomacy.races);
this.get("leviathans").autoPinned = saveData.diplomacy.autoPinLeviathans || false;
}
},

Expand Down
156 changes: 89 additions & 67 deletions js/jsx/left.jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,54 +47,33 @@ WCollapsiblePanel = React.createClass({
WResourceRow = React.createClass({

getDefaultProperties: function(){
return {resource: null, isEditMode: false, isRequired: false, showHiddenResources: false};
return {resource: null, isEditMode: false, isRequired: false, showHiddenResources: false, isTemporalParadox: false};
},

//this is a bit ugly, probably React.PureComponent + immutable would be a much better approach
//TODO: this function needs a proper rewrite. I'm pretty sure it doesn't work at all as intended.
//I'm going for a solution that is technically less accurate, but is much simpler to understand.
//This function tells React to skip rendering for invisible resources.
//I think it's good enough for now.
shouldComponentUpdate: function(nextProp, nextState){
var oldRes = this.oldRes || {},
newRes = nextProp.resource;

var isEqual =
oldRes.value == newRes.value &&
oldRes.maxValue == newRes.maxValue &&
oldRes.perTickCached == newRes.perTickCached &&
this.props.isEditMode == nextProp.isEditMode &&
this.props.isRequired == nextProp.isRequired &&
this.props.showHiddenResources == nextProp.showHiddenResources &&
this.props.isTemporalParadox != nextProp.isTemporalParadox &&
true /*this.state.visible == nextState.visible*/;

if (isEqual){
return false;
var newVisibility = this.getIsResInMainTable(nextProp.resource, nextProp);
if (this.oldVisibility !== newVisibility) {
//Remember new visibility state
this.oldVisibility = newVisibility;
//Resource will appear/disappear, therefore component should update
return true;
}
this.oldRes = {
value: newRes.value,
maxValue: newRes.maxValue,
perTickCached: newRes.perTickCached
};
return true;
//Update component if it will be displayed
//Don't update component if it won't be displayed
return newVisibility;
},

render: function(){
var res = this.props.resource;

if (!res.visible && !this.props.showHiddenResources){
//Only render this resource if it's unlocked, visible, etc.
if (!this.getIsResInMainTable()) {
return null;
}

var hasVisibility = (res.unlocked || (res.name == "kittens" && res.maxValue));

if (!hasVisibility || (!this.getIsVisible() && !this.props.isEditMode)){
return null;
}

//migrate dual resources (e.g. blueprint) to lower table once craft recipe is unlocked
if (game.resPool.isNormalCraftableResource(res) && game.workshop.getCraft(res.name).unlocked){
return null;
}

//wtf is this code
var isTimeParadox = this.props.isTemporalParadox;

Expand Down Expand Up @@ -207,7 +186,13 @@ WResourceRow = React.createClass({
(!res.visible ? " hidden" : "")
;

var resPercent = ((res.value / res.maxValue) * 100).toFixed();
var resPercent = "";
if (res.maxValue) {
resPercent = ((res.value / res.maxValue) * 100).toFixed() + "%/" + game.getDisplayValueExt(res.maxValue);
} else {
//Display value with 1 digit of precision
resPercent = game.getDisplayValueExt(Math.round(res.value), false /*prefix*/, false /*perTickHack*/, 1);
}

return $r("div", {role: "row", className: resRowClass}, [
this.props.isEditMode ?
Expand All @@ -225,7 +210,7 @@ WResourceRow = React.createClass({
className:"res-cell resource-name",
style:resNameCss,
onClick: this.onClickName,
title: (res.title || res.name) + " " + resPercent + "%/" + game.getDisplayValueExt(res.maxValue) + " " + perTickVal,
title: (res.title || res.name) + " " + resPercent + " " + perTickVal,
role: "gridcell",
userFocus:"normal",
tabIndex: 0,
Expand All @@ -248,11 +233,35 @@ WResourceRow = React.createClass({
},

toggleView: function(){
this.props.resource.isHidden = !this.props.resource.isHidden;
game.resPool.setResourceIsHidden(this.props.resource.name, !this.props.resource.isHidden);
},

getIsVisible: function() {
return !this.props.resource.isHidden;
//Parameter is optional.
//If not given, defaults to this.props.resource
getIsVisible: function(res) {
res = res || this.props.resource;
return !res.isHidden;
},

//Both parameters are optional.
//If not given, they default to this.props
getIsResInMainTable: function(res, props) {
res = res || this.props.resource;
props = props || this.props;

if (!res.visible && !props.showHiddenResources){
return false;
}
var hasVisibility = (res.unlocked || (res.name == "kittens" && res.maxValue));
if (!hasVisibility || (!this.getIsVisible(res) && !props.isEditMode)){
return false;
}
//migrate dual resources (e.g. blueprint) to lower table once craft recipe is unlocked
if (game.resPool.isNormalCraftableResource(res) && game.workshop.getCraft(res.name).unlocked){
return false;
}
//Else, resource is visible && unlocked && not displayed somewhere else instead:
return true;
},

componentDidMount: function(){
Expand Down Expand Up @@ -405,33 +414,31 @@ WCraftShortcut = React.createClass({
WCraftRow = React.createClass({

getDefaultProperties: function(){
return {resource: null, isEditMode: false};
return {resource: null, isEditMode: false, isRequired: false};
},

//I'm going for a solution that is technically less accurate, but is much simpler to understand.
//This function tells React to skip rendering for invisible resources.
//I think it's good enough for now.
shouldComponentUpdate: function(nextProp, nextState){
var newRes = nextProp.resource;

/*var isEqual =
oldRes.value == newRes.value &&
this.props.isEditMode == nextProp.isEditMode &&
this.props.isRequired == nextProp.isRequired &&
this.state.visible == nextState.visible;
if (isEqual){
return false;
}*/
this.oldRes = {
value: newRes.value,
};
return true;
var newVisibility = this.getIsResInCraftTable(nextProp.resource, nextProp);
if (this.oldVisibility !== newVisibility) {
//Remember new visibility state
this.oldVisibility = newVisibility;
//Resource will appear/disappear, therefore component should update
return true;
}
//Update component if it will be displayed
//Don't update component if it won't be displayed
return newVisibility;
},

render: function(){
var res = this.props.resource;

var recipe = game.workshop.getCraft(res.name);
var hasVisibility = (res.unlocked && recipe.unlocked /*&& this.workshop.on > 0*/);
if (!hasVisibility || (!this.getIsVisible() && !this.props.isEditMode)){

//Only render if this resource is unlocked, not marked as hidden, etc.
if (!this.getIsResInCraftTable()) {
return null;
}

Expand Down Expand Up @@ -502,15 +509,31 @@ WCraftRow = React.createClass({
}
},

getIsVisible: function() {
var res = this.props.resource;
//Parameter is optional.
//If not given, defaults to this.props.resource
getIsVisible: function(res) {
res = res || this.props.resource;
if (res.name == "wood") {
//(Wood is special because it appears twice, separately)
return !res.isHiddenFromCrafting;
}
return !res.isHidden;
},

//Both parameters are optional.
//If not given, they default to this.props
getIsResInCraftTable: function(res, props) {
res = res || this.props.resource;
props = props || this.props;

var recipe = game.workshop.getCraft(res.name);
var hasVisibility = (res.unlocked && recipe.unlocked);
if (!hasVisibility || (!this.getIsVisible(res) && !props.isEditMode)){
return false;
}
return true;
},

componentDidMount: function(){
var node = React.findDOMNode(this.refs.perTickNode);
if (node){
Expand Down Expand Up @@ -542,8 +565,7 @@ WResourceTable = React.createClass({
getInitialState: function(){
return {
isEditMode: false,
isCollapsed: false,
showHiddenResources: false
isCollapsed: false
};
},
render: function(){
Expand All @@ -557,7 +579,7 @@ WResourceTable = React.createClass({
resource: res,
isEditMode: this.state.isEditMode,
isRequired: isRequired,
showHiddenResources: this.state.showHiddenResources,
showHiddenResources: game.resPool.showHiddenResources,
isTemporalParadox: game.calendar.day < 0
})
);
Expand Down Expand Up @@ -607,7 +629,7 @@ WResourceTable = React.createClass({
$r("div", {className:"res-toggle-hidden"}, [
$r("input", {
type:"checkbox",
checked: this.state.showHiddenResources,
checked: game.resPool.showHiddenResources,
onClick: this.toggleHiddenResources,
style:{display:"inline-block"},
}),
Expand All @@ -631,7 +653,7 @@ WResourceTable = React.createClass({
},

toggleHiddenResources: function(e){
this.setState({showHiddenResources: e.target.checked});
game.resPool.showHiddenResources = e.target.checked;
}
});

Expand Down
Loading

0 comments on commit af758ef

Please sign in to comment.