more header cleanup

This commit is contained in:
Zeno Rogue 2019-08-09 23:08:42 +02:00
parent e1194ff588
commit 05bd7a905c
9 changed files with 231 additions and 378 deletions

View File

@ -472,7 +472,7 @@ EX void initConfig() {
addsaver(nisot::geodesic_movement, "solv_geodesic_movement", true);
#if CAP_SHMUP
shmup::initConfig();
multi::initConfig();
#endif
#if CAP_CONFIG
@ -1621,7 +1621,7 @@ EX void showCustomizeChar() {
gamescreen(4);
dialog::init(XLAT("Customize character"));
if(shmup::on || multi::players) shmup::cpid = shmup::cpid_edit % shmup::players;
if(shmup::on || multi::players) multi::cpid = multi::cpid_edit % multi::players;
charstyle& cs = getcs();
dialog::addSelItem(XLAT("character"), csname(cs), 'g');
@ -1639,7 +1639,7 @@ EX void showCustomizeChar() {
if(!shmup::on && multi::players == 1) dialog::addSelItem(XLAT("save whom"), XLAT1(minf[moPrincess].name), 'p');
if(numplayers() > 1) dialog::addSelItem(XLAT("player"), its(shmup::cpid+1), 'a');
if(numplayers() > 1) dialog::addSelItem(XLAT("player"), its(multi::cpid+1), 'a');
dialog::addBoolItem(XLAT("left-handed"), cs.lefthanded, 'l');
@ -1666,10 +1666,10 @@ EX void showCustomizeChar() {
keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni);
if(shmup::on || multi::players) shmup::cpid = shmup::cpid_edit % shmup::players;
if(shmup::on || multi::players) multi::cpid = multi::cpid_edit % multi::players;
charstyle& cs = getcs();
bool cat = cs.charid >= 4;
if(uni == 'a') { shmup::cpid_edit++; shmup::cpid_edit %= 60; }
if(uni == 'a') { multi::cpid_edit++; multi::cpid_edit %= 60; }
else if(uni == 'g') {
cs.charid++;
if(cs.charid == 2 && !princess::everSaved && !autocheat) cs.charid = 4;
@ -1980,7 +1980,7 @@ EX void showSettings() {
#if CAP_SHMUP
if(CAP_SHMUP && !ISMOBILE) {
dialog::addSelItem(XLAT("keyboard & joysticks"), "", 'k');
dialog::add_action(shmup::configure);
dialog::add_action(multi::configure);
}
#endif

View File

@ -311,7 +311,7 @@ EX void countLocalTreasure() {
}
}
EX int gold(int no) {
EX int gold(int no IS(0)) {
int i = 0;
if(!(no & NO_YENDOR)) i += items[itOrbYendor] * 50;
if(!(no & NO_GRAIL)) i += items[itHolyGrail] * 10;

View File

@ -377,7 +377,7 @@ EX transmatrix iddspin(cell *c, int d, ld bonus IS(0)) {
#define UNTRANS (DIM == 3 ? 0x000000FF : 0)
void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
EX void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
if(!onplayer && !items[itOrbEmpathy]) return;
if(items[itOrbShield] > (shmup::on ? 0 : ORBBASE)) drawShield(V, itOrbShield);
if(items[itOrbShell] > (shmup::on ? 0 : ORBBASE)) drawShield(V, itOrbShell);
@ -552,7 +552,7 @@ double footfun(double d) {
d-1;
}
bool ivoryz;
EX bool ivoryz;
void animallegs(const transmatrix& V, eMonster mo, color_t col, double footphase) {
#if CAP_SHAPES
@ -793,7 +793,7 @@ pair<bool, hyperpoint> makeradar(hyperpoint h) {
return {true, h};
}
void addradar(const transmatrix& V, char ch, color_t col, color_t outline) {
EX void addradar(const transmatrix& V, char ch, color_t col, color_t outline) {
hyperpoint h = tC0(V);
auto hp = makeradar(h);
if(hp.first)
@ -817,13 +817,13 @@ color_t kind_outline(eItem it) {
return OUTLINE_OTHER;
}
transmatrix face_the_player(const transmatrix V) {
EX transmatrix face_the_player(const transmatrix V) {
if(DIM == 2) return V;
if(nonisotropic) return V * cspin(0, 2, ptick(618, 0));
return rgpushxto0(tC0(V));
}
hpcshape& orbshape(eOrbshape s) {
EX hpcshape& orbshape(eOrbshape s) {
switch(s) {
case osLove: return cgi.shLoveRing;
case osRanged: return cgi.shTargetRing;
@ -1347,7 +1347,7 @@ void drawMimic(eMonster m, cell *where, const transmatrix& V, color_t col, doubl
}
}
bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col, double footphase, color_t asciicol) {
EX bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col, double footphase, color_t asciicol) {
#if MAXMDIM >= 4
if(DIM == 3 && m != moPlayer && asciicol != NOCOLOR)
@ -3065,7 +3065,7 @@ EX int countMinesAround(cell *c) {
return mines;
}
transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si) {
EX transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si) {
if(NONSTDVAR || binarytiling) return Id;
transmatrix V = ddspin(c, si.dir, M_PI);
if(si.reflect) V = V * Mirror;
@ -6754,14 +6754,14 @@ EX void drawFireParticles(cell *c, int qty, int maxspeed IS(100)) {
for(int i=0; i<qty; i++)
drawParticle(c, firegradient(i / (qty-1.)), maxspeed);
}
void fallingFloorAnimation(cell *c, eWall w, eMonster m) {
EX void fallingFloorAnimation(cell *c, eWall w IS(waNone), eMonster m IS(moNone)) {
if(!wmspatial) return;
fallanim& fa = fallanims[c];
fa.t_floor = ticks;
fa.walltype = w; fa.m = m;
// drawParticles(c, darkenedby(linf[c->land].color, 1), 4, 50);
}
void fallingMonsterAnimation(cell *c, eMonster m, int id) {
EX void fallingMonsterAnimation(cell *c, eMonster m, int id IS(multi::cpid)) {
if(!mmspatial) return;
fallanim& fa = fallanims[c];
fa.t_mon = ticks;
@ -7836,7 +7836,25 @@ auto graphcm = addHook(clearmemory, 0, [] () {
//=== animation
array<map<cell*, animation>, ANIMLAYERS> animations;
#if HDR
struct animation {
int ltick;
double footphase;
transmatrix wherenow;
int attacking;
transmatrix attackat;
bool mirrored;
};
// we need separate animation layers for Orb of Domination and Tentacle+Ghost,
// and also to mark Boats
#define ANIMLAYERS 3
#define LAYER_BIG 0 // for worms and krakens
#define LAYER_SMALL 1 // for others
#define LAYER_BOAT 2 // mark that a boat has moved
#endif
EX array<map<cell*, animation>, ANIMLAYERS> animations;
EX int revhint(cell *c, int hint) {
if(hint >= 0 && hint < c->type) return c->c.spin(hint);

14
hud.cpp
View File

@ -3,6 +3,20 @@
namespace hr {
#if HDR
struct radarpoint {
hyperpoint h;
char glyph;
color_t color;
color_t line;
};
struct radarline {
hyperpoint h1, h2;
color_t line;
};
#endif
EX vector<radarpoint> radarpoints;
EX vector<radarline> radarlines;

289
hyper.h
View File

@ -891,161 +891,16 @@ void initcs(charstyle& cs);
extern bool flipplayer;
namespace multi {
extern bool alwaysuse;
void recall();
extern cell *origpos[MAXPLAYER], *origtarget[MAXPLAYER];
extern int players;
extern cellwalker player[MAXPLAYER];
extern bool flipped[MAXPLAYER];
cell *mplayerpos(int i);
extern vector<int> revive_queue; // queue for revival
extern movedir whereto[MAXPLAYER]; // player's target cell
extern int cpid; // player id -- an extra parameter for player-related functions
extern int cpid_edit; // cpid currently being edited
// treasure collection, kill, and death statistics
extern int treasures[MAXPLAYER], kills[MAXPLAYER], deaths[MAXPLAYER];
void saveConfig(FILE *f);
void loadConfig(FILE *f);
void initConfig();
extern charstyle scs[MAXPLAYER];
bool playerActive(int p);
int activePlayers();
cell *multiPlayerTarget(int i);
void checklastmove();
void leaveGame(int i);
void configure();
void showConfigureMultiplayer();
}
template<class T> class hookset : public map<int, function<T>> {};
typedef hookset<void()> *purehookset;
namespace shmup {
using namespace multi;
void recall();
extern bool on;
extern bool delayed_safety;
extern int curtime;
void clearMonsters();
void clearMemory();
void init();
void teleported();
struct monster {
eMonster type;
cell *base;
cell *torigin;
// tortoises: origin
// butterflies: last position
transmatrix at;
transmatrix pat;
eMonster stk;
bool dead;
bool notpushed;
bool inBoat;
bool no_targetting;
monster *parent; // who shot this missile
eMonster parenttype; // type of the parent
int nextshot; // when will it be able to shot (players/flailers)
int pid; // player ID
int hitpoints; // hitpoints; or time elapsed in Asteroids
int stunoff;
int blowoff;
double swordangle; // sword angle wrt at
double vel; // velocity, for flail balls
double footphase;
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
hyperpoint inertia;// for frictionless lands
monster() {
dead = false; inBoat = false; parent = NULL; nextshot = 0;
stunoff = 0; blowoff = 0; footphase = 0; no_targetting = false;
swordangle = 0; inertia = Hypc;
}
void store();
void findpat();
cell *findbase(const transmatrix& T);
void rebasePat(const transmatrix& new_pat);
};
extern struct monster* mousetarget;
extern monster *pc[MAXPLAYER];
extern eItem targetRangedOrb(orbAction a);
void degradeDemons();
void killThePlayer(eMonster m);
void killThePlayer(eMonster m, int i);
void visibleFor(int t);
bool verifyTeleport();
bool dragonbreath(cell *dragon);
void shmupDrownPlayers(cell *c);
cell *playerpos(int i);
bool playerInBoat(int i);
void destroyBoats(cell *c);
bool boatAt(cell *c);
void fixStorage();
void addShmupHelp(string& out);
void activateArrow(cell *c);
void pushmonsters();
void popmonsters();
extern hookset<bool(int)> *hooks_turn;
extern hookset<bool(const transmatrix&, cell*, shmup::monster*)> *hooks_draw;
extern hookset<bool(shmup::monster*)> *hooks_kill;
extern hookset<bool(shmup::monster*, string&)> *hooks_describe;
void turn(int);
extern monster *lmousetarget;
void virtualRebase(shmup::monster *m, bool tohex);
extern monster *pc[MAXPLAYER];
int reflect(cell*& c2, cell*& mbase, transmatrix& nat);
void switch_shmup();
}
static const int NOHINT = -1;
typedef color_t color_t;
inline string ONOFF(bool b) { return XLAT(b ? "ON" : "OFF"); }
typedef function<void()> reaction_t;
typedef function<bool()> bool_reaction_t;
#define HELPFUN(x) (help_delegate = x, "HELPFUN")
struct radarpoint {
hyperpoint h;
char glyph;
color_t color;
color_t line;
};
struct radarline {
hyperpoint h1, h2;
color_t line;
};
extern vector< function<void()> > screens;
template<class T> void pushScreen(const T& x) { screens.push_back(x); }
@ -1095,75 +950,6 @@ extern display_data *current_display;
typedef function<int(cell*)> cellfunction;
int coastvalEdge(cell *c);
namespace patterns {
extern char whichShape;
extern int canvasback;
extern cpatterntype cgroup, old_cgroup;
enum ePattern : char {
PAT_NONE = 0,
PAT_TYPES = 'T',
PAT_ZEBRA = 'z',
PAT_EMERALD = 'f',
PAT_PALACE = 'p',
PAT_FIELD = 'F',
PAT_DOWN = 'H',
PAT_COLORING = 'C',
PAT_SIBLING = 'S',
PAT_CHESS = 'c',
PAT_SINGLETYPE = 't'
};
extern ePattern whichPattern;
extern int subpattern_flags;
static const int SPF_ROT = 1;
static const int SPF_SYM01 = 2;
static const int SPF_SYM02 = 4;
static const int SPF_SYM03 = 8;
static const int SPF_CHANGEROT = 16;
static const int SPF_TWOCOL = 32;
static const int SPF_EXTRASYM = 64;
static const int SPF_ALTERNATE = 128;
static const int SPF_FOOTBALL = 256;
static const int SPF_FULLSYM = 512;
static const int SPF_DOCKS = 1024;
static const int SPF_NO_SUBCODES = 2048;
static const int SPF_SYM0123 = SPF_SYM01 | SPF_SYM02 | SPF_SYM03;
extern char whichCanvas;
extern bool displaycodes;
int generateCanvas(cell *c);
struct patterninfo {
int id;
int dir;
bool reflect;
int symmetries;
};
patterninfo getpatterninfo(cell *c, ePattern pat, int sub);
inline patterninfo getpatterninfo0(cell *c) {
return getpatterninfo(c, whichPattern, subpattern_flags);
}
bool compatible(cpatterntype oldp, cpatterntype newp);
extern void pushChangeablePatterns();
void computeCgroup();
void showPattern();
void val38(cell *c, patterninfo &si, int sub, int pat);
int downdir(cell *c, const cellfunction& cf = coastvalEdge);
}
namespace mapeditor {
#if CAP_EDIT
extern map<int, cell*> modelcell;
@ -1299,6 +1085,8 @@ extern ld ruggo;
#define HASLINEVIEW
namespace shmup { struct monster; }
namespace conformal {
extern bool on;
extern vector<pair<cell*, eMonster> > killhistory;
@ -1351,7 +1139,7 @@ namespace conformal {
void apply();
void movetophase();
void renderAutoband();
extern vector<shmup::monster*> v;
extern double phase;
void applyIB();
@ -1488,9 +1276,6 @@ static const int NO_YENDOR = 2;
static const int NO_GRAIL = 4;
static const int NO_LOVE = 8;
int gold(int no = 0);
int tkills();
bool markOrb(eItem it); // mark the orb as 'used', return true if exists
bool markEmpathy(eItem it); // mark both the given orb and Empathy as 'used', return true if exists
bool markEmpathy2(eItem it); // as above, but next turn
@ -1644,9 +1429,6 @@ bool isDragon(eMonster m);
extern "C" { void *_Unwind_Resume = 0; }
#endif
extern bool autocheat;
extern bool inHighQual;
void mountmove(cell *c, int spin, bool fp);
void mountmove(cell *c, int spin, bool fp, cell *ppos);
void mountswap(cell *c1, int spin1, bool fp1, cell *c2, int spin2, bool fp2);
@ -1749,8 +1531,6 @@ namespace svg {
}
#endif
extern int sightrange_bonus, genrange_bonus, gamerange_bonus;
namespace halloween {
void getTreat(cell *where);
}
@ -1758,55 +1538,12 @@ namespace halloween {
// just in case if I change my mind about when Orbs lose their power
#define ORBBASE 0
transmatrix mscale(const transmatrix& t, double fac);
transmatrix mzscale(const transmatrix& t, double fac);
extern bool ivoryz;
#define mmscale(V, x) (mmspatial ? (ivoryz ? mzscale(V,x) : mscale(V, x)) : (V))
#define SHADOW_WALL 0x60
#define SHADOW_SL 0x18
#define SHADOW_MON 0x30
transmatrix face_the_player(const transmatrix V);
void addradar(const transmatrix& V, char ch, color_t col, color_t outline);
bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, color_t col, double footphase, color_t asciicol);
void drawPlayerEffects(const transmatrix& V, cell *c, bool onPlayer);
// monster movement animations
struct animation {
int ltick;
double footphase;
transmatrix wherenow;
int attacking;
transmatrix attackat;
bool mirrored;
};
// we need separate animation layers for Orb of Domination and Tentacle+Ghost,
// and also to mark Boats
#define ANIMLAYERS 3
#define LAYER_BIG 0 // for worms and krakens
#define LAYER_SMALL 1 // for others
#define LAYER_BOAT 2 // mark that a boat has moved
extern array<map<cell*, animation>, ANIMLAYERS> animations;
void animateAttack(cell *src, cell *tgt, int layer, int direction_hint);
void animateMovement(cell *src, cell *tgt, int layer, int direction_hint);
// for animations which might use the same locations,
// such as replacements or multi-tile monsters
void indAnimateMovement(cell *src, cell *tgt, int layer, int direction_hint);
void commitAnimations(int layer);
void animateReplacement(cell *a, cell *b, int layer, int direction_hinta, int direction_hintb);
void fallingFloorAnimation(cell *c, eWall w = waNone, eMonster m = moNone);
void fallingMonsterAnimation(cell *c, eMonster m, int id = multi::cpid);
// ranks:
enum class PPR {
ZERO, EUCLIDEAN_SKY, OUTCIRCLE, MOVESTAR,
@ -2002,6 +1739,8 @@ color_t darkena(color_t c, int lev, int a);
namespace anims { void animate_parameter(ld &x, string f, const reaction_t& r); }
extern bool timerghost;
extern bool autocheat;
extern int cheater;
namespace arg {
#if CAP_COMMANDLINE
@ -2748,20 +2487,9 @@ extern colortable nestcolors;
unsigned char& part(color_t& col, int i);
transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si);
int pattern_threecolor(cell *c);
int fiftyval200(cell *c);
// T * C0, optimized
inline hyperpoint tC0(const transmatrix &T) {
hyperpoint z;
for(int i=0; i<MDIM; i++) z[i] = T[i][DIM];
return z;
}
transmatrix actualV(const heptspin& hs, const transmatrix& V);
transmatrix cview();
bool isWall3(cell *c, color_t& wcol);
extern transmatrix actual_view_transform, radar_transform;
ld wall_radar(cell *c, transmatrix T);
@ -3457,4 +3185,11 @@ namespace hr {
inline hyperpoint xpush0(ld x) { return cpush0(0, x); }
inline hyperpoint ypush0(ld x) { return cpush0(1, x); }
inline void reset_projection() { new_projection_needed = true; }
// T * C0, optimized
inline hyperpoint tC0(const transmatrix &T) {
hyperpoint z;
for(int i=0; i<MDIM; i++) z[i] = T[i][DIM];
return z;
}
}

View File

@ -15,10 +15,10 @@ int lastexplore;
EX bool randomPatternsMode = false;
EX int randompattern[landtypes];
int genrange_bonus = 0;
EX int genrange_bonus = 0;
bool chaosUnlocked = false;
bool chaosAchieved = false;
EX bool chaosUnlocked = false;
EX bool chaosAchieved = false;
void doOvergenerate() {
for(int i=0; i<numplayers(); i++)

View File

@ -822,7 +822,7 @@ EX void showStartMenu() {
welcomeMessage();
stampbase = ticks;
if(uni == 's')
shmup::configure();
multi::configure();
}
else if(uni == 'Z') {
popScreenAll();
@ -997,7 +997,7 @@ int read_menu_args() {
PHASEFROM(2); launch_dialog(showChangeMode);
}
else if(argis("-d:shmup")) {
PHASEFROM(2); launch_dialog(); shmup::configure();
PHASEFROM(2); launch_dialog(); multi::configure();
}
else return 1;
return 0;

View File

@ -519,7 +519,45 @@ int getHemisphere(cell *c, int which) {
}
}
namespace patterns {
EX namespace patterns {
#if HDR
enum ePattern : char {
PAT_NONE = 0,
PAT_TYPES = 'T',
PAT_ZEBRA = 'z',
PAT_EMERALD = 'f',
PAT_PALACE = 'p',
PAT_FIELD = 'F',
PAT_DOWN = 'H',
PAT_COLORING = 'C',
PAT_SIBLING = 'S',
PAT_CHESS = 'c',
PAT_SINGLETYPE = 't'
};
static const int SPF_ROT = 1;
static const int SPF_SYM01 = 2;
static const int SPF_SYM02 = 4;
static const int SPF_SYM03 = 8;
static const int SPF_CHANGEROT = 16;
static const int SPF_TWOCOL = 32;
static const int SPF_EXTRASYM = 64;
static const int SPF_ALTERNATE = 128;
static const int SPF_FOOTBALL = 256;
static const int SPF_FULLSYM = 512;
static const int SPF_DOCKS = 1024;
static const int SPF_NO_SUBCODES = 2048;
static const int SPF_SYM0123 = SPF_SYM01 | SPF_SYM02 | SPF_SYM03;
struct patterninfo {
int id;
int dir;
bool reflect;
int symmetries;
};
#endif
void valSibling(cell *c, patterninfo& si, int sub, int pat) {
if(ctof(c)) {
@ -651,7 +689,7 @@ namespace patterns {
}
}
void val38(cell *c, patterninfo &si, int sub, int pat) {
EX void val38(cell *c, patterninfo &si, int sub, int pat) {
bool symRotation = sub & SPF_ROT;
if(ctof(c)) {
@ -879,9 +917,9 @@ namespace patterns {
if(GOLDBERG && has_nice_dual() && !ishept(c) && ishex1(c)) si.dir = gmod(si.dir+3, S6);
}
ePattern whichPattern = PAT_NONE;
EX ePattern whichPattern = PAT_NONE;
int subpattern_flags;
EX int subpattern_flags;
void val_threecolors(cell *c, patterninfo& si, int sub) {
int pcol = pattern_threecolor(c);
@ -907,7 +945,7 @@ namespace patterns {
applyAlt(si, sub, PAT_COLORING);
}
patterninfo getpatterninfo(cell *c, ePattern pat, int sub) {
EX patterninfo getpatterninfo(cell *c, ePattern pat, int sub) {
if(!(sub & SPF_NO_SUBCODES)) {
auto si = getpatterninfo(c, pat, sub | SPF_NO_SUBCODES);
if(1) ;
@ -1118,7 +1156,13 @@ namespace patterns {
return si;
}
}
#if HDR
inline patterninfo getpatterninfo0(cell *c) {
return getpatterninfo(c, whichPattern, subpattern_flags);
}
#endif
EX }
EX bool geosupport_chessboard() {
return
@ -1398,12 +1442,12 @@ color_t random_landscape(cell *c, int mul, int div, int step, color_t base) {
return (base + col[0] + (col[1] << 8) + (col[2] << 16));
}
namespace patterns {
int canvasback = linf[laCanvas].color >> 2;
int subcanvas;
bool displaycodes;
char whichShape = 0;
char whichCanvas = 0;
EX namespace patterns {
EX int canvasback = linf[laCanvas].color >> 2;
EX int subcanvas;
EX bool displaycodes;
EX char whichShape = 0;
EX char whichCanvas = 0;
int sevenval(cell *c) {
if(!euclid) return 0;
@ -1445,7 +1489,7 @@ namespace patterns {
return ep.parse();
}
int generateCanvas(cell *c) {
EX int generateCanvas(cell *c) {
switch(whichCanvas) {
#if CAP_CRYSTAL
case 'K':
@ -1710,7 +1754,7 @@ namespace patterns {
#define REMAP_TEXTURE (void)0
#endif
void showPattern() {
EX void showPattern() {
cmode = sm::SIDE | sm::MAYDARK;
{
dynamicval<bool> dc(displaycodes, whichPattern);
@ -1886,7 +1930,7 @@ namespace patterns {
};
}
bool compatible(cpatterntype oldp, cpatterntype newp) {
EX bool compatible(cpatterntype oldp, cpatterntype newp) {
// larges are not incompatible between themselves
if(newp == cpLarge || newp == cpZebra)
return false;
@ -1996,7 +2040,7 @@ namespace patterns {
}}
};
cpatterntype cgroup, old_cgroup;
EX cpatterntype cgroup, old_cgroup;
void showChangeablePatterns() {
cmode = sm::SIDE | sm::MAYDARK;
@ -2067,7 +2111,7 @@ namespace patterns {
};
}
void computeCgroup() {
EX void computeCgroup() {
cgroup = cpUnknown;
if(whichPattern == PAT_SINGLETYPE) {
cgroup = cpSingle;
@ -2093,11 +2137,11 @@ namespace patterns {
old_cgroup = cgroup;
}
void pushChangeablePatterns() {
EX void pushChangeablePatterns() {
pushScreen(showChangeablePatterns);
computeCgroup();
}
}
EX }
bool is_master(cell *c) {
if(euclid) return pseudohept(c);

162
shmup.cpp
View File

@ -22,24 +22,25 @@ namespace shmupballs {
}
}
namespace multi {
EX namespace multi {
config scfg;
charstyle scs[MAXPLAYER];
EX charstyle scs[MAXPLAYER];
int players = 1;
cellwalker player[MAXPLAYER];
vector<int> revive_queue; // queue for revival
EX int players = 1;
EX cellwalker player[MAXPLAYER];
EX vector<int> revive_queue; // queue for revival
cell *origpos[MAXPLAYER], *origtarget[MAXPLAYER];
EX cell *origpos[MAXPLAYER], *origtarget[MAXPLAYER];
bool flipped[MAXPLAYER];
EX bool flipped[MAXPLAYER];
int treasures[MAXPLAYER], kills[MAXPLAYER], deaths[MAXPLAYER];
// treasure collection, kill, and death statistics
EX int treasures[MAXPLAYER], kills[MAXPLAYER], deaths[MAXPLAYER];
bool alwaysuse = false;
EX bool alwaysuse = false;
void recall() {
EX void recall() {
for(int i=0; i<numplayers(); i++) {
int idir = (3 * i) % cwt.at->type;
cell *c2 = cwt.at->move(idir);
@ -60,10 +61,10 @@ namespace multi {
bool combo[MAXPLAYER];
int cpid; // player id -- an extra parameter for player-related functions
int cpid_edit; // cpid currently being edited
EX int cpid; // player id -- an extra parameter for player-related functions
EX int cpid_edit; // cpid currently being edited
movedir whereto[MAXPLAYER]; // player's target cell
EX movedir whereto[MAXPLAYER]; // player's target cell
double mdx[MAXPLAYER], mdy[MAXPLAYER]; // movement vector for the next move
@ -471,11 +472,11 @@ struct shmup_configurer {
}
};
void configure() {
EX void configure() {
pushScreen(shmup_configurer());
}
void showConfigureMultiplayer() {
EX void showConfigureMultiplayer() {
gamescreen(1);
dialog::init("multiplayer");
@ -500,7 +501,7 @@ void showConfigureMultiplayer() {
});
dialog::addSelItem(XLAT("keyboard & joysticks"), "", 'k');
dialog::add_action(shmup::configure);
dialog::add_action(multi::configure);
}
else dialog::addBreak(200);
@ -532,7 +533,7 @@ bool notremapped(int sym) {
return k > multi::players;
}
void initConfig() {
EX void initConfig() {
char* t = scfg.keyaction;
@ -750,26 +751,25 @@ void handleInput(int delta) {
int tableid[7] = {1, 2, 4, 5, 6, 7, 8};
void leaveGame(int i) {
EX void leaveGame(int i) {
multi::player[i].at = NULL;
multi::deaths[i]++;
revive_queue.push_back(i);
checklastmove();
}
bool playerActive(int p) {
EX bool playerActive(int p) {
if(multi::players == 1 || shmup::on) return true;
return player[p].at;
}
int activePlayers() {
EX int activePlayers() {
int q = 0;
for(int i=0; i<players; i++) if(playerActive(i)) q++;
return q;
}
cell *multiPlayerTarget(int i) {
EX cell *multiPlayerTarget(int i) {
cellwalker cwti = multi::player[i];
if(!cwti.at) return NULL;
int dir = multi::whereto[i].d;
@ -780,7 +780,7 @@ void handleInput(int delta) {
return cwti.at;
}
void checklastmove() {
EX void checklastmove() {
for(int i=0; i<numplayers(); i++) if(playerActive(i)) {
multi::cpid = i;
cwt = multi::player[i]; break;
@ -959,7 +959,7 @@ void handleInput(int delta) {
((countplayers == 2 && !countplayers_undecided) || countplayers_undecided >= 2);
}
}
EX }
/*
const char *lastprofile = "";
@ -976,7 +976,51 @@ void profile(const char *buf) {
#define SCALE cgi.scalefactor
#define SCALE2 (SCALE*SCALE)
namespace shmup {
EX namespace shmup {
#if HDR
struct monster {
eMonster type;
cell *base;
cell *torigin;
// tortoises: origin
// butterflies: last position
transmatrix at;
transmatrix pat;
eMonster stk;
bool dead;
bool notpushed;
bool inBoat;
bool no_targetting;
monster *parent; // who shot this missile
eMonster parenttype; // type of the parent
int nextshot; // when will it be able to shot (players/flailers)
int pid; // player ID
int hitpoints; // hitpoints; or time elapsed in Asteroids
int stunoff;
int blowoff;
double swordangle; // sword angle wrt at
double vel; // velocity, for flail balls
double footphase;
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
hyperpoint inertia;// for frictionless lands
monster() {
dead = false; inBoat = false; parent = NULL; nextshot = 0;
stunoff = 0; blowoff = 0; footphase = 0; no_targetting = false;
swordangle = 0; inertia = Hypc;
}
void store();
void findpat();
cell *findbase(const transmatrix& T);
void rebasePat(const transmatrix& new_pat);
};
#endif
using namespace multi;
@ -985,14 +1029,12 @@ eItem keyresult[MAXPLAYER];
ld fabsl(ld x) { return x>0?x:-x; }
bool on = false;
bool delayed_safety = false;
EX bool on = false;
EX bool delayed_safety = false;
bool lastdead = false;
struct monster;
multimap<cell*, monster*> monstersAt;
EX multimap<cell*, monster*> monstersAt;
typedef multimap<cell*, monster*>::iterator mit;
@ -1110,9 +1152,9 @@ bool trackroute(monster *m, transmatrix goal, double spd) {
return true;
}
monster *pc[MAXPLAYER], *mousetarget, *lmousetarget;
EX monster *pc[MAXPLAYER], *mousetarget, *lmousetarget;
int curtime, nextmove, nextdragon;
EX int curtime, nextmove, nextdragon;
bool isBullet(monster *m) {
return isBulletType(m->type);
@ -1120,7 +1162,7 @@ bool isBullet(monster *m) {
bool isPlayer(monster *m) { return m->type == moPlayer; }
bool isMonster(monster *m) { return m->type != moPlayer && m->type != moBullet; }
hookset<bool(shmup::monster*)> *hooks_kill;
EX hookset<bool(shmup::monster*)> *hooks_kill;
void killMonster(monster* m, eMonster who_kills, int flags = 0) {
int tk = tkills();
@ -1147,7 +1189,7 @@ void killMonster(monster* m, eMonster who_kills, int flags = 0) {
multi::kills[multi::cpid] += tkills() - tk;
}
void pushmonsters() {
EX void pushmonsters() {
for(monster *m: nonvirtual) {
m->notpushed = isPlayer(m) || m->dead || (m->base->monst && m->base->monst != m->type);
if(!m->notpushed) {
@ -1157,7 +1199,7 @@ void pushmonsters() {
}
}
void popmonsters() {
EX void popmonsters() {
for(int i=isize(nonvirtual)-1; i>=0; i--) {
monster *m = nonvirtual[i];
if(!m->notpushed) {
@ -1176,7 +1218,7 @@ void popmonsters() {
}
}
void degradeDemons() {
EX void degradeDemons() {
for(monster* m: nonvirtual) {
if(m->type == moGreater) m->type = moLesser;
if(m->stk == moGreater) m->type = moLesser;
@ -1232,7 +1274,7 @@ void awakenMimics(monster *m, cell *c2) {
int visibleAt;
void visibleFor(int t) {
EX void visibleFor(int t) {
visibleAt = max(visibleAt, curtime + t);
}
@ -1292,7 +1334,7 @@ void shootBullet(monster *m) {
}
}
void killThePlayer(eMonster m) {
EX void killThePlayer(eMonster m) {
if(cpid >= 0 && cpid < MAXPLAYER && pc[cpid])
pc[cpid]->dead = true;
}
@ -1497,7 +1539,7 @@ bool hornKills(eMonster m) {
queue<pair<int, cell*>> traplist, firetraplist;
void activateArrow(cell *c) {
EX void activateArrow(cell *c) {
if(isCentralTrap(c))
traplist.emplace(ticks + 500, c);
}
@ -2203,7 +2245,7 @@ bool reflectmatrix(transmatrix& M, cell *c1, cell *c2, bool onlypos) {
return true;
}
int reflect(cell*& c2, cell*& mbase, transmatrix& nat) {
EX int reflect(cell*& c2, cell*& mbase, transmatrix& nat) {
int reflections = 0;
if(c2 != mbase && c2->wall == waMirrorWall && inmirror(c2)) {
if(reflectmatrix(nat, mbase, c2, false)) {
@ -2292,7 +2334,7 @@ monster *parentOrSelf(monster *m) {
return m->parent ? m->parent : m;
}
bool verifyTeleport() {
EX bool verifyTeleport() {
if(!on) return true;
if(playerCrash(pc[cpid], mouseh)) return false;
return true;
@ -2304,7 +2346,7 @@ void destroyMimics() {
m->dead = true;
}
void teleported() {
EX void teleported() {
monster *m = pc[cpid];
m->base = cwt.at;
m->at = rgpushxto0(inverse(gmatrix[cwt.at]) * mouseh) * spin(rand() % 1000 * M_PI / 2000);
@ -2357,7 +2399,7 @@ eItem targetRangedOrbKey(orbAction a) {
return r;
}
eItem targetRangedOrb(orbAction a) {
EX eItem targetRangedOrb(orbAction a) {
if(!on) return itNone;
monster *wpc = pc[cpid];
if(a != roCheck && !wpc) return itNone;
@ -2664,7 +2706,7 @@ bool closer(monster *m1, monster *m2) {
return intval(m1->pat*C0, closerTo) < intval(m2->pat*C0, closerTo);
}
bool dragonbreath(cell *dragon) {
EX bool dragonbreath(cell *dragon) {
int randplayer = hrand(numplayers());
monster* bullet = new monster;
bullet->base = dragon;
@ -3284,7 +3326,7 @@ void activateMonstersAt(cell *c) {
}
}
void fixStorage() {
EX void fixStorage() {
vector<monster*> restore;
@ -3296,9 +3338,9 @@ void fixStorage() {
for(monster *m: restore) m->store();
}
hookset<bool(int)> *hooks_turn;
EX hookset<bool(int)> *hooks_turn;
void turn(int delta) {
EX void turn(int delta) {
if(racing::on && subscreens::split( [delta] () { turn(delta); })) return;
@ -3554,7 +3596,7 @@ void turn(int delta) {
active.clear();
}
void recall() {
EX void recall() {
for(int i=0; i<players; i++) {
pc[i]->base = cwt.at;
if(players == 1)
@ -3568,7 +3610,7 @@ void recall() {
destroyMimics();
}
void init() {
EX void init() {
for(int i=0; i<players; i++) pc[i] = NULL;
@ -3598,7 +3640,7 @@ void init() {
delayed_safety = false;
}
bool boatAt(cell *c) {
EX bool boatAt(cell *c) {
pair<mit, mit> p =
monstersAt.equal_range(c);
for(mit it = p.first; it != p.second; it++) {
@ -3608,7 +3650,7 @@ bool boatAt(cell *c) {
return false;
}
hookset<bool(const transmatrix&, cell*, shmup::monster*)> *hooks_draw;
EX hookset<bool(const transmatrix&, cell*, shmup::monster*)> *hooks_draw;
bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, transmatrix& Vboat0, const transmatrix *Vdp) {
#if CAP_SHAPES
@ -3789,7 +3831,7 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans
return false;
}
void clearMonsters() {
EX void clearMonsters() {
for(mit it = monstersAt.begin(); it != monstersAt.end(); it++)
delete(it->second);
for(monster *m: active) delete m;
@ -3799,7 +3841,7 @@ void clearMonsters() {
active.clear();
}
void clearMemory() {
EX void clearMemory() {
clearMonsters();
gmatrix.clear();
while(!traplist.empty()) traplist.pop();
@ -3830,29 +3872,29 @@ void gamedata(hr::gamedata* gd) {
}
}
cell *playerpos(int i) {
EX cell *playerpos(int i) {
if(!pc[i]) return NULL;
return pc[i]->base;
}
bool playerInBoat(int i) {
EX bool playerInBoat(int i) {
if(!pc[i]) return false;
return pc[i]->inBoat;
}
void destroyBoats(cell *c) {
EX void destroyBoats(cell *c) {
for(monster *m: active)
if(m->base == c && m->inBoat)
m->inBoat = false;
}
void virtualRebase(shmup::monster *m, bool tohex) {
EX void virtualRebase(shmup::monster *m, bool tohex) {
virtualRebase(m->base, m->at, tohex);
}
hookset<bool(shmup::monster*, string&)> *hooks_describe;
EX hookset<bool(shmup::monster*, string&)> *hooks_describe;
void addShmupHelp(string& out) {
EX void addShmupHelp(string& out) {
if(shmup::mousetarget && intval(mouseh, tC0(shmup::mousetarget->pat)) < .1) {
if(callhandlers(false, hooks_describe, shmup::mousetarget, out)) return;
out += XLAT1(minf[shmup::mousetarget->type].name);
@ -3873,7 +3915,7 @@ auto hooks = addHook(clearmemory, 0, shmup::clearMemory) +
}
});
void switch_shmup() {
EX void switch_shmup() {
stop_game();
switch_game_mode(rg::shmup);
resetScores();