ref: 063901a12ba4031e700716f193818a88a25439b2
parent: 2d226f3ddc911ad4a47d7c986b359075d89f7eea
author: qwx <qwx@sciops.net>
date: Tue Feb 16 13:31:52 EST 2021
sim: basic production states logic
--- a/dat.h
+++ b/dat.h
@@ -58,11 +58,12 @@
};
struct Building{char *name;
- int time;
int buildtime;
- int costs[Gtot];
+ int buildcost[Gtot];
+ int prodtime;
+ int product[Gtot];
+ int prodcost[Gtot];
int terrain;
- int goods[Gtot];
int upkeep[Rtot];
};
extern Building buildings[Btot];
@@ -87,16 +88,25 @@
enum{Snull,
+ Svoid,
+ Swaitbuild,
Sbuild,
- Swait,
+ Sstarved,
+ Swaitsupply,
Sproduce,
};
struct Tile{Terrain *t;
- Building *b;
+ int distance;
int stock;
+ Building *b;
int state;
- int clock;
+ int gotsupply;
+ int prodstock[Gtot];
+ vlong clock;
+ vlong prodΔt;
+ vlong supplyΔt;
+ vlong pickupΔt;
};
extern Tile *map;
extern int mapwidth, mapheight;
--- a/defs.c
+++ b/defs.c
@@ -100,87 +100,97 @@
Building buildings[] = { [Btownhall]{.name "townhall",
- .time 0,
.buildtime 1000,
- .costs {0},+ .buildcost {0},.terrain Tplain,
- .goods {0},+ .prodtime 0,
+ .product {0},+ .prodcost {0}, .upkeep {[Rfood] 1,
},
+ },[Bfishyard]{+ .name "fishyard",
+ .buildtime 50,
+ .buildcost {+ [Ggold] 5,
+ [Gwood] 5,
+ },
+ .terrain Tpond,
+ .prodtime 25,
+ .product {+ [Gfish] 1,
+ },
+ .prodcost {0},+ .upkeep {+ [Rfood] 1,
+ },
},[Bcarpentry]{.name "carpentry",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 3,
[Gwood] 3,
},
.terrain Tplain,
- .goods {+ .prodtime 25,
+ .product {[Gwood] 1,
},
+ .prodcost {0}, .upkeep {[Rfood] 1,
},
},[Bsawmill]{.name "sawmill",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 10,
[Gwood] 10,
},
.terrain Tplain,
- .goods {+ .prodtime 50,
+ .product {[Glumber] 1,
},
+ .prodcost {+ [Gwood] 1,
+ },
.upkeep {[Rfood] 2,
},
- },[Bfishyard]{- .name "fishyard",
- .time 25,
- .buildtime 50,
- .costs {- [Ggold] 5,
- [Gwood] 5,
- },
- .terrain Tpond,
- .goods {- [Gfish] 1,
- },
- .upkeep {- [Rfood] 1,
- },
},[Bmill]{.name "mill",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 8,
[Glumber] 8,
},
.terrain Tplain,
- .goods {+ .prodtime 25,
+ .product {[Gwheat] 2,
},
+ .prodcost {0}, .upkeep {[Rfood] 1,
},
},[Bfarm]{.name "farm",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 8,
[Glumber] 4,
[Gwheat] 4,
},
.terrain Tplain,
- .goods {+ .prodtime 25,
+ .product {[Gcattle] 2,
},
+ .prodcost {+ [Gwheat] 1,
+ },
.upkeep {[Rfood] 1,
[Rlumber] 1,
@@ -187,25 +197,25 @@
},
},[Bquarry]{.name "quarry",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 5,
[Glumber] 2,
[Gwheat] 3,
},
.terrain Tplain,
- .goods {+ .prodtime 25,
+ .product {[Gstone] 1,
},
+ .prodcost {0}, .upkeep {[Rfood] 1,
},
},[Bsmeltery]{.name "smeltery",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 12,
[Glumber] 6,
[Gstone] 4,
@@ -212,17 +222,20 @@
[Gwood] 2,
},
.terrain Tplain,
- .goods {+ .prodtime 50,
+ .product {[Giron] 1,
},
+ .prodcost {+ [Gwood] 2,
+ },
.upkeep {[Rfood] 2,
},
},[Bforge]{.name "forge",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 10,
[Glumber] 4,
[Gstone] 4,
@@ -229,17 +242,21 @@
[Giron] 2,
},
.terrain Tplain,
- .goods {+ .prodtime 25,
+ .product {[Gtools] 1,
},
+ .prodcost {+ [Gwood] 1,
+ [Giron] 1,
+ },
.upkeep {[Rfood] 2,
},
},[Blapidary]{.name "lapidary",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 26,
[Gstone] 16,
[Giron] 14,
@@ -246,22 +263,29 @@
[Gtools] 14,
},
.terrain Tplain,
- .goods {+ .prodtime 100,
+ .product {[Gjewelry] 1,
},
+ .prodcost {+ [Gwood] 2,
+ [Giron] 2,
+ [Gtools] 2,
+ },
.upkeep {[Rfood] 2,
},
},[Bmarket]{.name "market",
- .time 25,
.buildtime 50,
- .costs {+ .buildcost {[Ggold] 10,
[Glumber] 10,
},
.terrain Tplain,
- .goods {0},+ .prodtime 0,
+ .product {0},+ .prodcost {0}, .upkeep {[Rgold] 1,
[Rfood] 5,
--- a/fns.h
+++ b/fns.h
@@ -3,3 +3,4 @@
void initmap(void);
void step(void);
void input(void);
+int mhdist(int, int, int, int);
--- a/map.c
+++ b/map.c
@@ -6,6 +6,12 @@
int mapwidth, mapheight;
Tile *map;
+int
+mhdist(int x, int y, int x´, int y´)
+{+ return abs(x - x´) + abs(y - y´);
+}
+
void
loadmap(void)
{--- a/sim.c
+++ b/sim.c
@@ -45,7 +45,7 @@
static void
starve(Tile *o)
{- o->state = Swait;
+ o->state = Svoid;
}
static void
@@ -58,7 +58,7 @@
return;
for(ol=objhead-1; ol>=objs; ol--){o = *ol;
- if(o->state <= Swait)
+ if(o->state <= Svoid)
continue;
if(o->b == nil)
sysfatal("empty active tile");@@ -84,35 +84,96 @@
}
}
+static int
+trypickup(Tile *o)
+{+ int g;
+
+ if(o->pickupΔt == 0 || o->clock < o->pickupΔt)
+ return 0;
+ for(g=0; g<nelem(goods); g++)
+ stock[g] += o->prodstock[g];
+ o->pickupΔt = 0;
+ return 1;
+}
+
+static int
+trysupply(Tile *o)
+{+ int g;
+ for(g=0; g<nelem(goods); g++)
+ if(o->b->prodcost[g] > stock[g])
+ return 0;
+ for(g=0; g<nelem(goods); g++)
+ if(o->b->prodcost[g] > 0)
+ stock[g] -= o->b->prodcost[g];
+ o->supplyΔt = o->clock + o->distance;
+ return 1;
+}
+
static void
updateobj(void)
{+ int g;
Tile *o, **ol;
for(ol=objhead-1; ol>=objs; ol--){o = *ol;
+ o->clock++;
switch(o->state){+ case Swaitbuild:
+ if(o->clock >= o->distance){+ o->clock = 0;
+ o->state = Sbuild;
+ }
+ break;
case Sbuild:
- /*
- call for supplies, start travel towards building site
- done?
- start production
- */
+ if(o->clock >= o->b->buildtime){+ o->clock = 0;
+ o->state = o->b->prodtime > 0 ? Sstarved : Svoid;
+ }
+ break;
+ case Sstarved:
+ trypickup(o);
+ if(trysupply(o))
+ o->state = Swaitsupply;
+ break;
+ case Swaitsupply:
+ trypickup(o);
+ if(o->clock >= o->supplyΔt){+ o->gotsupply = 0;
+ o->supplyΔt = 0;
+ o->prodΔt = o->clock + o->b->prodtime;
+ o->state = Sproduce;
+ }
+ break;
case Sproduce:
- /*
- call for supplies
- enough supplies? else wait until next tick (loop)
- decrement stocks, start traveling from townhall
- reached building?
- increment supplies
- begin production
- while producing, if we can call for supplies earlier to restart immediately, do it
- finished producing?
- start travel towards building
- reached building?
- call for pickup
- loop
- */
+ if(!o->gotsupply){+ if(o->supplyΔt == 0){+ if(!trysupply(o))
+ return;
+ for(g=0; g<nelem(goods); g++)
+ if(o->b->prodcost[g] > stock[g])
+ break;
+ }else if(o->clock >= o->supplyΔt){+ o->gotsupply = 1;
+ o->supplyΔt = 0;
+ }
+ }
+ trypickup(o);
+ if(o->clock >= o->prodΔt){+ o->pickupΔt = o->clock + o->distance * 2;
+ if(!o->gotsupply){+ if(o->supplyΔt == 0)
+ o->state = Sstarved;
+ else
+ o->state = Swaitsupply;
+ }else{+ o->prodΔt += o->b->prodtime;
+ o->gotsupply = 0;
+ }
+ }
+ break;
default: break;
}
}
@@ -125,16 +186,35 @@
updateobj();
}
+static void
+calcdists(int n)
+{+ int x, y, x´, y´;
+ Tile *o;
+
+ x = n % mapwidth;
+ y = n / mapheight;
+ for(o=map, x´=0, y´=0; o<map+mapwidth*mapheight; o++, x´++){+ o->distance = mhdist(x, y, x´, y´);
+ if(x´ == mapwidth){+ x´ = 0;
+ y´++;
+ }
+ }
+}
+
void
init(void)
{- int i;
+ int i, n;
initmap();
maxobj = mapwidth * mapheight;
objs = emalloc(maxobj * sizeof *objs);
objhead = objs;
- spawn(map + nrand(maxobj), Btownhall);
+ n = nrand(maxobj);
+ spawn(map + n, Btownhall);
+ calcdists(n);
for(i=0; i<nelem(initialstock); i++){stock[i] = initialstock[i];
rstock[goods[i].resource] += stock[i];
--
⑨