diff --git a/rogueviz/ads/ads-game.cpp b/rogueviz/ads/ads-game.cpp index b94c1f62..c19fd400 100644 --- a/rogueviz/ads/ads-game.cpp +++ b/rogueviz/ads/ads-game.cpp @@ -3,9 +3,9 @@ #include "math.cpp" #include "globals.cpp" #include "shapes.cpp" +#include "resources.cpp" #include "map.cpp" #include "control.cpp" -#include "resources.cpp" #include "display.cpp" #include "menu.cpp" diff --git a/rogueviz/ads/control.cpp b/rogueviz/ads/control.cpp index 9537820c..755a3e7a 100644 --- a/rogueviz/ads/control.cpp +++ b/rogueviz/ads/control.cpp @@ -5,6 +5,8 @@ namespace ads_game { vector move_names = { "acc down", "acc left", "acc up", "acc right", "fire", "pause", "display times", "switch spin", "menu" }; void fire() { + if(!pdata.ammo) return; + pdata.ammo--; auto g = hybrid::get_where(vctr); auto c = g.first; if(g.second != 0) println(hlog, "WARNING: vctr not zeroed"); @@ -132,15 +134,27 @@ bool ads_turn(int idelta) { bool up = a[16+2]; bool down = a[16]; - if(left) apply_lorentz(lorentz(0, 2, delta*accel)), ang = 180; - if(right) apply_lorentz(lorentz(0, 2, -delta*accel)), ang = 0; - if(up) apply_lorentz(lorentz(1, 2, delta*accel)), ang = 90; - if(down) apply_lorentz(lorentz(1, 2, -delta*accel)), ang = 270; + int clicks = (left?1:0) + (right?1:0) + (up?1:0) + (down?1:0); + + if(left && right) left = right = false; + if(up && down) up = down = false; + + if(left) ang = 180; + if(right) ang = 0; + if(up) ang = 90; + if(down) ang = 270; if(left && up) ang = 135; if(left && down) ang = 225; if(right && up) ang = 45; if(right && down) ang = 315; + + ld mul = clicks ? 1 : 0; + if(clicks > 2) mul *= .3; + if(pdata.fuel < 0) mul = 0; + + apply_lorentz(spin(ang*degree) * lorentz(0, 2, -delta*accel*mul) * spin(-ang*degree)); + pdata.fuel -= delta*accel*mul; current.T = cspin(3, 2, pt) * current.T; optimize_shift(current); @@ -152,6 +166,11 @@ bool ads_turn(int idelta) { ang += pt / degree; ship_pt += pt; + pdata.oxygen -= pt; + if(pdata.oxygen < 0) { + pdata.oxygen = 0; + game_over = true; + } } fixmatrix_ads(current.T); diff --git a/rogueviz/ads/display.cpp b/rogueviz/ads/display.cpp index e4242b7b..89c7c9a7 100644 --- a/rogueviz/ads/display.cpp +++ b/rogueviz/ads/display.cpp @@ -209,7 +209,13 @@ bool view_ads_game() { if(true) { poly_outline = 0xFF; - queuepolyat(shiftless(spin(ang*degree) * Id), shShip, 0x2020FFFF, PPR::LINE); + color_t shipcolor = 0x2020FFFF; + if(ship_pt < invincibility_pt) { + ld u = (invincibility_pt-ship_pt) / how_much_invincibility; + poly_outline = gradient(shipcolor, rsrc_color[rtHull], 0, 0.5 + cos(5*u*TAU), 1); + } + queuepolyat(shiftless(spin(ang*degree) * Id), shShip, shipcolor, PPR::LINE); + poly_outline = 0xFF; if(view_proper_times) { string str = format(tformat, ship_pt / TAU); diff --git a/rogueviz/ads/globals.cpp b/rogueviz/ads/globals.cpp index d0d6d72b..b84a17e1 100644 --- a/rogueviz/ads/globals.cpp +++ b/rogueviz/ads/globals.cpp @@ -26,6 +26,9 @@ ld ang = 0; /** ship's current proper time */ ld ship_pt; +/** until when is the ship invincible */ +ld invincibility_pt; + /** is the game paused */ bool paused; @@ -45,6 +48,8 @@ vector displayed; color_t missile_color = 0xFF0000FF; +bool game_over; + struct player_data { int hitpoints; int score; @@ -53,6 +58,8 @@ struct player_data { ld oxygen; }; +ld how_much_invincibility = TAU / 4; + player_data pdata, max_pdata, tank_pdata; }} diff --git a/rogueviz/ads/map.cpp b/rogueviz/ads/map.cpp index 72e244c0..a5ffbfcd 100644 --- a/rogueviz/ads/map.cpp +++ b/rogueviz/ads/map.cpp @@ -4,13 +4,6 @@ namespace ads_game { enum eObjType { oRock, oMissile, oParticle, oResource }; -enum eResourceType { rtNone, rtHull, rtGold, rtAmmo, rtFuel, rtOxygen }; - -color_t rock_color[6] = { 0x703800FF, 0xC0A080FF, 0xC08010FF, 0xC04000FF, 0x408000FF, 0x8040A0FF, }; -color_t rsrc_color[6] = {0, 0xC0C0C0FF, 0xFFD500FF, 0xFF0000FF, 0x00FF00FF, 0x0000FFFF }; - -vector* rsrc_shape[6] = { nullptr, &shape_heart, &shape_gold, &shape_weapon, &shape_fuel, &shape_airtank }; - struct ads_object { eObjType type; eResourceType resource; @@ -172,34 +165,47 @@ void gen_resource(cell *c, shiftmatrix from, eResourceType rsrc) { r->shape = rsrc_shape[rsrc]; r->life_end = HUGE_VAL; r->life_start = 0; + r->resource = rsrc; ci_at[c].rocks.emplace_back(std::move(r)); } +bool pointcrash(hyperpoint h, const vector& vf) { + int winding = 0; + vector kleins; + for(auto& p: vf) kleins.push_back(kleinize(p.h) - h); + auto take = [&] (hyperpoint& a, hyperpoint& b) { + if(asign(a[1], b[1]) && xcross(b[0], b[1], a[0], a[1]) < 1e-6) + winding++; + }; + for(int i=1; i missiles; vector rocks; + vector resources; for(auto m: displayed) { if(m->type == oMissile) missiles.push_back(m); if(m->type == oRock) rocks.push_back(m); + if(m->type == oResource) + resources.push_back(m); } hybrid::in_underlying_geometry([&] { for(auto m: missiles) { hyperpoint h = kleinize(m->pt_main.h); for(auto r: rocks) { - int winding = 0; - vector kleins; - for(auto& p: r->pts) kleins.push_back(kleinize(p.h) - h); - auto take = [&] (hyperpoint& a, hyperpoint& b) { - if(asign(a[1], b[1]) && xcross(b[0], b[1], a[0], a[1]) < 1e-6) - winding++; - }; - for(int i=1; i