aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacopo grandi <jak.sk8@hotmail.it>2021-02-20 00:11:23 +0100
committerjacopo grandi <jak.sk8@hotmail.it>2021-02-20 00:11:23 +0100
commit2eef87c8970db643c4ef09e0fd9e8110c8193043 (patch)
tree78a9bcc7932ab8edb8669ded755ee2c81afc0912
parentc135f85fcdc1eeedd04e0c9e9f626b907500f20a (diff)
finish condition and bad cost function
-rw-r--r--build/army/army.txtbin0 -> 21528 bytes
-rw-r--r--build/content/armor.txt66
-rw-r--r--build/content/autolevel.py20
-rw-r--r--build/test.exebin751762 -> 775710 bytes
-rw-r--r--design/notes.txt95
-rw-r--r--gst/gst.c29
-rw-r--r--gst/gst.h3
-rw-r--r--gst/info.c86
-rw-r--r--gst/info.h1
-rw-r--r--gst/units.c9
-rw-r--r--gst/units.h4
-rw-r--r--hud/hud.c29
-rw-r--r--hud/hud_views.c6
13 files changed, 282 insertions, 66 deletions
diff --git a/build/army/army.txt b/build/army/army.txt
new file mode 100644
index 0000000..033dd7c
--- /dev/null
+++ b/build/army/army.txt
Binary files differ
diff --git a/build/content/armor.txt b/build/content/armor.txt
index 5182a0c..5ceaacc 100644
--- a/build/content/armor.txt
+++ b/build/content/armor.txt
@@ -2,9 +2,9 @@
{
"name": "metal plating",
"weight": [
- 50.0,
- 50.0,
- 50.0
+ 10.0,
+ 10.0,
+ 10.0
],
"pierce": [
5.0,
@@ -20,9 +20,9 @@
{
"name": "heavy metal plating",
"weight": [
- 80.0,
- 80.0,
- 80.0
+ 16.0,
+ 16.0,
+ 16.0
],
"pierce": [
7.0,
@@ -43,9 +43,9 @@
{
"name": "reflective plating",
"weight": [
- 40.0,
- 40.0,
- 40.0
+ 8.0,
+ 8.0,
+ 8.0
],
"laser": [
10.0,
@@ -56,9 +56,9 @@
{
"name": "heat resistent plating",
"weight": [
- 50.0,
- 50.0,
- 50.0
+ 10.0,
+ 10.0,
+ 10.0
],
"fusion": [
8.0,
@@ -69,9 +69,9 @@
{
"name": "padding",
"weight": [
- 20.0,
- 20.0,
- 20.0
+ 4.0,
+ 4.0,
+ 4.0
],
"spread": [
5.0,
@@ -87,9 +87,9 @@
{
"name": "reactive armor",
"weight": [
- 75.0,
- 75.0,
- 75.0
+ 15.0,
+ 15.0,
+ 15.0
],
"explosive": [
12.0,
@@ -100,9 +100,9 @@
{
"name": "energy shields",
"weight": [
- 25.0,
- 25.0,
- 25.0
+ 5.0,
+ 5.0,
+ 5.0
],
"pierce": [
3.0,
@@ -133,9 +133,9 @@
{
"name": "composite armor",
"weight": [
- 30.0,
- 30.0,
- 30.0
+ 6.0,
+ 6.0,
+ 6.0
],
"pierce": [
6.0,
@@ -156,9 +156,9 @@
{
"name": "plastic armor",
"weight": [
- 10.0,
- 10.0,
- 10.0
+ 2.0,
+ 2.0,
+ 2.0
],
"pierce": [
4.0,
@@ -169,9 +169,9 @@
{
"name": "sloped steel armor",
"weight": [
- 45.0,
- 45.0,
- 45.0
+ 9.0,
+ 9.0,
+ 9.0
],
"pierce": [
10.0,
@@ -187,9 +187,9 @@
{
"name": "charged armor",
"weight": [
- 100.0,
- 100.0,
- 100.0
+ 20.0,
+ 20.0,
+ 20.0
],
"explosive": [
25.0,
diff --git a/build/content/autolevel.py b/build/content/autolevel.py
index eac6e09..345bccf 100644
--- a/build/content/autolevel.py
+++ b/build/content/autolevel.py
@@ -1,6 +1,6 @@
import json
-def vectorize (obj, forbidlist):
+def vectorize (obj, forbidlist, _):
for c in obj:
for key in c:
if not(key in forbidlist):
@@ -10,13 +10,18 @@ def vectorize (obj, forbidlist):
try: val = float(val);
except: pass
c[key] = [val for i in range(3)]
- return obj
+
+def query (obj, allowlist, op):
+ for c in obj:
+ for key in c:
+ if key in allowlist:
+ c[key] = op(c[key])
-def comp(filename, forbidlist):
+def comp(filename, l, fun, op=None):
with open(filename+".txt", "r") as f: obj = json.loads(f.read())
- obj = vectorize(obj, forbidlist)
- with open(filename+".txt", "w") as f:
+ fun(obj, l, op)
+ with open(filename+"-new"+".txt", "w") as f:
f.write(json.dumps(obj, indent=4))
if __name__ == "__main__":
@@ -25,4 +30,7 @@ if __name__ == "__main__":
#comp("batteries", ["name"])
#comp("armor", ["name"])
#comp("chassis", ["name"])
- comp("brains", ["name"])
+ #comp("brains", ["name"])
+ #comp("brains", ["name"])
+
+ #comp("armor", ["weight"], query, lambda x: [x[i]/5 for i in range(3)])
diff --git a/build/test.exe b/build/test.exe
index de1814f..a57fe22 100644
--- a/build/test.exe
+++ b/build/test.exe
Binary files differ
diff --git a/design/notes.txt b/design/notes.txt
index ef2bb25..c9903bb 100644
--- a/design/notes.txt
+++ b/design/notes.txt
@@ -1,22 +1,14 @@
tasks: (date)
-[x] implement rm unit (issued on 18:02:21, done on 18:02:21)
-[x] implement armor calculation (issued on 18:02:21, done on 18:02:21)
-[x] implement augment calculations (issued on 18:02:21, done on 18:02:21)
-[x] implement augment hud view (issued on 18:02:21, done on 18:02:21)
-[ ] implement sound (issued on 18:02:21)
-[ ] implement end of battle condition (issued on 19:02:21)
+[ ] implement cost function (issued on 18:02:21)
[ ] implement stats hud view (issued on 18:02:21)
-[x] implement battery calculation (issued on 18:02:21, done on 19:02:21)
-[ ] implement brain behaviour (issued on 18:02:21)
-[ ] implement component levels (issued on 18:02:21)
-[ ] implement persistent settings (issued on 18:02:21)
[ ] implement net hud and minilobby (issued on 18:02:21)
+[ ] implement brain behaviour (issued on 18:02:21)
[ ] implement army hud view (issued on 18:02:21)
-[ ] implement cost function (issued on 18:02:21)
[ ] implement lobby cost constraints (issued on 18:02:21)
[ ] implement edit unit directly (issued on 18:02:21)
[ ] implement naming template and army (issued on 18:02:21)
+[ ] implement persistent settings (issued on 18:02:21)
[ ] implement move animation (issued on 18:02:21)
[ ] implement fire animation (issued on 18:02:21)
[ ] implement explosions (issued on 18:02:21)
@@ -24,7 +16,15 @@ tasks: (date)
[ ] design 3d map tiles (issued on 18:02:21)
[ ] implement 3d units (issued on 18:02:21)
[ ] design component sprites (issued on 18:02:21)
+[ ] implement sound (issued on 18:02:21)
+[x] implement end of battle condition (issued on 19:02:21, done on 19:02:21)
+[x] implement battery calculation (issued on 18:02:21, done on 19:02:21)
+[x] implement component levels (issued on 18:02:21, done on 19:02:21)
+[x] implement rm unit (issued on 18:02:21, done on 18:02:21)
+[x] implement armor calculation (issued on 18:02:21, done on 18:02:21)
+[x] implement augment calculations (issued on 18:02:21, done on 18:02:21)
+[x] implement augment hud view (issued on 18:02:21, done on 18:02:21)
bugs:
@@ -52,6 +52,77 @@ view from 18:02:21 to the end:
details:
+implement cost function:
+ oh boy
+ cost of a component = c_c
+ cost of a unit = c_u
+ cost of an army = c_a
+ c_a = sum {i=0..ar->uslen-1} c_u[i]
+ c_u = sum {comp j} c_c[j] -> maybe unfair, does not consider synergies
+ = sum of stats -> nerfs synergies, confusing and hard to calculate
+ c_c = sum of abs attributes -> ez but trash
+ = basis function of effectiveness of attribute -> cool
+ cost of unit is tricky
+ if i consider the simple sum of c_c, the augment bonuses are left out
+ gun cost 10, better ammo 10, total cost is 20.
+ otherwise every unit is calculated ad hoc.
+ gun cost 10, better ammo 10, dps is way better so total cost is 30
+ -> i'm using the cost by unit final stats, it's better but harder
+ what is effectiveness, i have to find formulas
+ . effectiveness of a weapon
+ + total damage output
+ + range multiplies total damage
+ + aoe multiplies total damage
+ + knockback fixed cost
+ + stun fixed cost
+ - upkeep as a % of total cost
+ - charge per shot required
+ - weight as a % of total cost
+ . effectiveness of a chassis
+ + slots (different by slot type)
+ + speed
+ + hp
+ + weight_max
+ - upkeep
+ . effectiveness of a battery
+ + capacity
+ + recharge based on capacity
+ - weight as a % of total cost
+ . effectiveness of an armor component
+ + armor amount
+ - weight
+ - upkeep
+ . effectiveness of an augment
+ + all add effects, weighted accordingly
+ - weight as a % of total cost
+ . effectiveness of a controller
+ + base cost by complexity of strategy (so base cost is defined in data)
+ - upkeep
+ multiplicative constants (buy with weight):
+ . 1 total damage per turn = 2 weight
+ . 1 armor = 2 weight
+ . 10 hp = 1 weight
+ . 100 capacity = 1 weight
+ . 1 upkeep = 1 weight
+ (they differ in the implementation)
+ basis function: (to modulate the increase in cost, double effectiveness, maybe 4*cost, or 70*cost)
+ . linear y=x
+ . log y=log(x)
+ . exp y=exp(x)
+ . other maybe?
+ cost of a unit: (info_unit_get_cost)
+ . sum of cost of components but with the final modified values
+ i can also price components based on no bonuses to provide a price gauge -> meh
+ i think it's better to focus on the cost indipendently of weight for now
+
+implement end of battle condition:
+ i was thinking i can detect the end as no damage is being dealt in 10 turns
+ and no movement takes place
+ another condition is that the enemy has no units, but it's not necessary.
+ end <==> no movement or fire
+ have to do transition from battle to editor, done ez
+-> done
+
implement components level:
could do it globally, every level is +5%atk and +10% cost
could set each weapon stat as a vector, v[level] is the stat
@@ -67,6 +138,8 @@ implement components level:
. design with a lot more variables in play
before writing 10000 numbers i should design, or autogenerate them
settled on 3 lvls, autogenerated with python
+ missing hud!
+-> done, also some testing
implement rm unit: -> done, paper note solution
diff --git a/gst/gst.c b/gst/gst.c
index 09f3c1c..a97b4f9 100644
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -66,6 +66,24 @@ void gst_tobattle (gamestate *gst) {
gst->starttime = FLT_MAX;
gst->turn = 0;
gst->coveredtime = 0;
+ gst->turn_until_finish = 5;
+ gst->over = 0;
+}
+
+void gst_toeditor(gamestate *gst) {
+ gst->playernum = 1;
+}
+
+int gst_check_victory (gamestate *gst) {
+ int counts[gst->playernum], max=-1, imax = -1;
+ for (int i=0; i<gst->ar.uslen; i++) {
+ counts[gst->ar.us[i].owner] ++;
+ if (counts[gst->ar.us[i].owner] > max) {
+ imax = gst->ar.us[i].owner;
+ max = counts[gst->ar.us[i].owner];
+ }
+ }
+ return imax;
}
void gst_process (gamestate *gst, infos *info, float t) {
@@ -76,8 +94,15 @@ void gst_process (gamestate *gst, infos *info, float t) {
gst->turn ++;
map *m; army *ar;
gst_get_maparmy(gst, &m, &ar);
- army_move(info, ar, m);
- army_fire(info, ar, m);
+ int move = army_move(info, ar, m);
+ int fire = army_fire(info, ar, m);
army_upkeep(info, ar, m);
+ printf("%d, %d\n", move, fire);
+ if (move == 0 && fire == 0) {
+ gst->turn_until_finish--;
+ } else { gst->turn_until_finish = 5; }
+ if (gst->turn_until_finish <= 0) {
+ gst->over = 1;
+ }
}
} \ No newline at end of file
diff --git a/gst/gst.h b/gst/gst.h
index 8acb699..171e213 100644
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -19,12 +19,15 @@ typedef struct {
float coveredtime;
int turn;
float turnspeed;
+ int turn_until_finish;
+ int over;
} gamestate;
void gst_init (gamestate *gst);
void gst_destroy (gamestate *gst);
void gst_get_maparmy(gamestate *gst, map **m, army **ar);
void gst_tobattle (gamestate *gst);
+void gst_toeditor (gamestate *gst);
void gst_process (gamestate *gst, infos *info, float t);
#endif \ No newline at end of file
diff --git a/gst/info.c b/gst/info.c
index 985b7dd..15c7c0b 100644
--- a/gst/info.c
+++ b/gst/info.c
@@ -130,8 +130,10 @@ float info_unit_get_health(infos *info, info_unit *u) {
sum += info->augs[u->augs[i]].add_hp[lvl];
}
}
- sum += info->chassis[u->chassis].hp[lc];
- return sum;
+ float mult = (1 + sum/100.0f);
+ if (mult < 0) mult = 0;
+ float ret = info->chassis[u->chassis].hp[lc] * mult;
+ return ret;
}
float info_unit_get_speed(infos *info, info_unit *u) {
@@ -175,6 +177,39 @@ float info_unit_get_damage_target (infos *info, info_unit *u, int w,
return damage * mult;
}
+float info_unit_get_aoe (infos *info, info_unit *u, int w) {
+ int lc = u->levels[LEVEL_CHASSIS];
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug[lc]) {
+ int lvl = u->levels[LEVEL_AUGS+i];
+ //sum += info->augs[u->augs[i]].add_aoe[lvl];
+ }
+ }
+ int lw = u->levels[LEVEL_WEAPONS+w];
+ float dam = info->weapons[u->weapons[w]].aoe[lw] + sum;
+ return dam;
+}
+
+float info_unit_get_knockback (infos *info, info_unit *u, int w) {
+ int lc = u->levels[LEVEL_CHASSIS];
+ float sum = 0;
+ for(int i=0; i<16; i++) {
+ if (u->augs[i] != -1 && info->chassis[u->chassis].slot_aug[lc]) {
+ int lvl = u->levels[LEVEL_AUGS+i];
+ //sum += info->augs[u->augs[i]].add_knockback[lvl];
+ }
+ }
+ int lw = u->levels[LEVEL_WEAPONS+w];
+ float dam = info->weapons[u->weapons[w]].knockback[lw] + sum;
+ return dam;
+}
+
+float info_unit_get_stun (infos *info, info_unit *u, int w) {
+ // TODO
+ return 0;
+}
+
float info_unit_get_cooldown(infos *info, info_unit *u, int w) {
int lc = u->levels[LEVEL_CHASSIS];
float sum = 0;
@@ -228,6 +263,53 @@ float info_unit_get_armor(infos *info, info_unit *u, int d) {
return sum;
}
+float info_unit_get_cost (infos *info, info_unit *u) {
+ // see design/notes.txt:implement cost function
+ float sum = 0;
+ int lc = u->levels[LEVEL_CHASSIS];
+ info_chassis *chassis = info->chassis+u->chassis;
+ float sumchassis = 0;
+ sumchassis += powf(2, chassis->slot_weapon[lc])*20;
+ sumchassis += powf(2, chassis->slot_armor[lc])*10;
+ sumchassis += powf(2, chassis->slot_aug[lc])*5;
+ sumchassis += chassis->weight_max[lc]/5;
+ sumchassis += chassis->hp[lc]/20;
+ sumchassis += chassis->speed[lc]*32;
+ sum += sumchassis;
+ if (u->battery != -1) {
+ int lb = u->levels[LEVEL_BATTERY];
+ info_battery *battery = info->batteries+u->battery;
+ float sumbattery = 0;
+ sumbattery += battery->capacity[lb];
+ sum += sumbattery;
+ }
+ for(int i=0; i<8; i++) {
+ int lw = u->levels[LEVEL_WEAPONS+i];
+ int la = u->levels[LEVEL_ARMOR+i];
+ if (u->weapons[i] != -1 && i<chassis->slot_weapon[lc]) {
+ info_weapon *weapon = info->weapons+u->weapons[i];
+ float sumweap = 0;
+ float dam = info_unit_get_damage(info, u, i);
+ float cool = info_unit_get_cooldown(info, u, i);
+ float damtot = dam / cool;
+ float aoe = info_unit_get_aoe(info, u, i);
+ float knockback = info_unit_get_knockback(info, u, i);
+ float stun = info_unit_get_stun(info, u, i);
+ float mult = 1+aoe*5 + 10;
+ damtot = damtot*mult;
+ damtot += knockback * 20 + stun * 50;
+ sumweap = damtot;
+ sum += sumweap;
+ }
+ }
+ for(int t=0; t<7; t++) {
+ float armortot = info_unit_get_armor(info, u, t) * 3;
+ sum += armortot;
+ }
+
+ return sum;
+}
+
void weapon_init (info_weapon *w) {
strcpy(w->name, "nameless");
diff --git a/gst/info.h b/gst/info.h
index 8e7fdaf..9219f8b 100644
--- a/gst/info.h
+++ b/gst/info.h
@@ -116,6 +116,7 @@ float info_unit_get_damage_target(infos *info, info_unit *u, int w,
float info_unit_get_cooldown(infos *info, info_unit *u, int w);
float info_unit_get_range(infos *info, info_unit *u, int w);
float info_unit_get_armor(infos *info, info_unit *u, int d);
+float info_unit_get_cost(infos *info, info_unit *u);
void info_load (infos *info);
diff --git a/gst/units.c b/gst/units.c
index dbf177b..b247e3c 100644
--- a/gst/units.c
+++ b/gst/units.c
@@ -168,18 +168,18 @@ int army_move_step (infos *info, army *ar, map *m) {
else return 1;
}
-void army_move (infos *info, army *ar, map *m) {
+int army_move (infos *info, army *ar, map *m) {
for (int i=0; i<ar->uslen; i++) {
ar->us[i].move_points += info_unit_get_speed(info, &ar->us[i].info);
}
- int iter = 0, finished = 0;
+ int iter = 0, finished = army_move_step(info, ar, m);
for (; iter<5 && !finished; iter++) {
finished = army_move_step(info, ar, m);
}
- //printf("stepped %d %d\n", iter, finished);
+ return iter;
}
-void army_fire (infos *info, army *ar, map *m) {
+int army_fire (infos *info, army *ar, map *m) {
for (int i=0; i<ar->uslen; i++) {
unit *u = ar->us+i;
int lw = u->info.levels[LEVEL_CHASSIS];
@@ -216,6 +216,7 @@ void army_fire (infos *info, army *ar, map *m) {
unit_dead(ar, m, dmgs[i].u);
}
}
+ return dmgslen;
}
void army_upkeep (infos *info, army *ar, map *m) {
diff --git a/gst/units.h b/gst/units.h
index 615eaa7..8e78d8d 100644
--- a/gst/units.h
+++ b/gst/units.h
@@ -34,8 +34,8 @@ void army_grid_init(army *ar);
void army_init (army *ar, map *m);
void army_destory(army *ar);
void army_spawn (army *ar, map *m, unit u);
-void army_move (infos *info, army *ar, map *m);
-void army_fire (infos *info, army *ar, map *m);
+int army_move (infos *info, army *ar, map *m);
+int army_fire (infos *info, army *ar, map *m);
void army_upkeep (infos *info, army *ar, map *m);
#endif \ No newline at end of file
diff --git a/hud/hud.c b/hud/hud.c
index 2c73288..7906c84 100644
--- a/hud/hud.c
+++ b/hud/hud.c
@@ -314,6 +314,19 @@ void hud_process_form_new_unit (graphic_settings *gs, hud *h, MKb *mkb,
}
}
+void hud_process_overlay_battle (graphic_settings *gs, hud *h, MKb *mkb,
+ infos *info, army *ar, map *m, txtd *t, gamestate *gst,
+ Mix_Chunk *sounds[])
+{
+ if (gst->over == 1) {
+ h->state = 0;
+ gst->state = 0;
+ gst->cam[0] = -gs->resx/2+gst->map_editor.sx*gst->map_editor.ts/2;
+ gst->cam[1] = -gs->resy/2+gst->map_editor.sy*gst->map_editor.ts/2;
+ gst_toeditor(gst);
+ }
+}
+
void hud_process_overlay_game (graphic_settings *gs, hud *h, MKb *mkb,
infos *info, army *ar, map *m, txtd *t, gamestate *gst,
net_client *netc, net_server *nets, Mix_Chunk *sounds[])
@@ -339,7 +352,7 @@ void hud_process_overlay_game (graphic_settings *gs, hud *h, MKb *mkb,
gst_tobattle(gst);
gst->cam[0] = -gs->resx/2+gst->map_battle.sx*gst->map_battle.ts/2;
gst->cam[1] = -gs->resy/2+gst->map_battle.sy*gst->map_battle.ts/2;
- h->state = 4;
+ h->state = 3;
}
}
}
@@ -355,7 +368,7 @@ void hud_process_overlay_game (graphic_settings *gs, hud *h, MKb *mkb,
gst_tobattle(gst);
gst->cam[0] = -gs->resx/2+gst->map_battle.sx*gst->map_battle.ts/2;
gst->cam[1] = -gs->resy/2+gst->map_battle.sy*gst->map_battle.ts/2;
- h->state = 4;
+ h->state = 3;
}
}
@@ -380,7 +393,7 @@ void hud_process_overlay_game (graphic_settings *gs, hud *h, MKb *mkb,
gst->cam[0] = -gs->resx/2+gst->map_battle.sx*gst->map_battle.ts/2;
gst->cam[1] = -gs->resy/2+gst->map_battle.sy*gst->map_battle.ts/2;
h->og.battle_state = 3;
- h->state = 4;
+ h->state = 3;
Mix_PlayChannel( -1, sounds[SOUND_SUCCESS], 0 );
}
@@ -522,9 +535,13 @@ void hud_process (graphic_settings *gs, hud *h, MKb *mkb,
hud_process_overlay_game(gs, h, mkb, info, ar, m, t, gst,
netc, nets, sounds);
break;
- case 1: hud_process_form_new_unit(gs, h, mkb, info, ar, m, t,
- sounds); break;
- case 2: hud_process_sel(gs, h, mkb, info, ar, m, t, sounds); break;
+ case 1: hud_process_form_new_unit(gs, h, mkb, info, ar, m, t, sounds);
+ break;
+ case 2: hud_process_sel(gs, h, mkb, info, ar, m, t, sounds);
+ break;
+ case 3: hud_process_overlay_battle(gs, h, mkb, info, ar, m, t, gst,
+ sounds);
+ break;
}
}
diff --git a/hud/hud_views.c b/hud/hud_views.c
index 4828275..046ba53 100644
--- a/hud/hud_views.c
+++ b/hud/hud_views.c
@@ -14,6 +14,12 @@ void render_view_stats (SDL_Renderer* rend, txtd *t, int px, int py,
render_text_scaled(rend, sname, pname, t, 2);
h += 35;
+ float cost = info_unit_get_cost(info, tm);
+ float pcost[2] = { px+10, py+h };
+ char scost[64]; sprintf(scost, "COST: %.2f", cost);
+ render_text_scaled(rend, scost, pcost, t, 1);
+ h += 20;
+
float calcweight = info_unit_get_weight(info, tm);
float maxweight = info->chassis[tm->chassis].weight_max[
tm->levels[LEVEL_CHASSIS]];