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];