ref: 6041c007423da884fffb0ec75fafdc2da3b2266b
parent: 10c73e7824f0d79cf910152355fe3d8fe0c0018e
author: qwx <qwx@sciops.net>
date: Sat Dec 18 23:52:46 EST 2021
major refactoring: use path node coordinates everywhere this avoids a lot of stupid errors, previously 3 different coordinates were saved and it was never clear which ones a function is supposed to use. also: - use Points more - main map is node map, not tilemap - mobj as first argument where applicable to homogenize usage - assume node width and height are the same (will always be the case) - com: don't send mobj coordinates, these will often be stale - com: use constants to avoid problems between send/recv functions - com: additional checks to avoid moving in place - drw: use vectors for vis and drawlists - map: coordinate conversion functions, try to isolate map code here - path: switch to plain a∗ to debug pathing and movement there are A LOT of bugs there, some new, many old
--- a/bmap.c
+++ b/bmap.c
@@ -69,60 +69,60 @@
}
u64int *
-baddr(int x, int y)
+baddr(Point p)
{
- x >>= Bshift;
- x += Npad;
- y += Npad;
- return bmap + y * bmapwidth + x;
+ p.x >>= Bshift;
+ p.x += Npad;
+ p.y += Npad;
+ return bmap + p.y * bmapwidth + p.x;
}
u64int *
-rbaddr(int y, int x)
+rbaddr(Point p)
{
- x >>= Bshift;
- x += Npad;
- y += Npad;
- return rbmap + y * rbmapwidth + x;
+ p.x >>= Bshift;
+ p.x += Npad;
+ p.y += Npad;
+ return rbmap + p.y * rbmapwidth + p.x;
}
static u64int *
-breduce(u64int *p, int Δp, int ofs, int w, int h, int Δw, int Δh, int left)
+breduce(u64int *b, int Δb, int ofs, Point sz, Point Δsz, int left)
{
static u64int row[Nmaxsize+2];
int i, j;
u64int u, m;
- m = (1 << w - 1) - 1;
+ m = (1 << sz.x - 1) - 1;
if(left){
- ofs = 64 - w - Δw - ofs;
- m <<= 63 - w + 1;
+ ofs = 64 - sz.x - Δsz.x - ofs;
+ m <<= 63 - sz.x + 1;
}
m = ~m;
- for(i=0; i<h+Δh; i++, p+=Δp){
- u = p[0];
+ for(i=0; i<sz.y+Δsz.y; i++, b+=Δb){
+ u = b[0];
if(ofs > 0){
if(left){
u >>= ofs;
- u |= p[-1] << 64 - ofs;
+ u |= b[-1] << 64 - ofs;
}else{
u <<= ofs;
- u |= p[1] >> 64 - ofs;
+ u |= b[1] >> 64 - ofs;
}
}
if(left)
- switch(w){
+ switch(sz.x){
case 4: u |= u >> 1 | u >> 2 | u >> 3; break;
case 2: u |= u >> 1; break;
}
else
- switch(w){
+ switch(sz.x){
case 4: u |= u << 1 | u << 2 | u << 3; break;
case 2: u |= u << 1; break;
}
u &= m;
row[i] = u;
- for(j=max(i-h+1, 0); j<i; j++)
+ for(j=max(i-sz.y+1, 0); j<i; j++)
row[j] |= u;
}
return row;
@@ -129,50 +129,50 @@
}
u64int *
-bload(int x, int y, int w, int h, int Δw, int Δh, int left, int rot)
+bload(Point p, Point sz, Point Δsz, int left, int rot)
{
- int ofs, Δp;
- u64int *p;
+ int ofs, Δb;
+ u64int *b;
if(rot){
- p = rbaddr(x, y);
- Δp = rbmapwidth;
- ofs = y & Bmask;
+ b = rbaddr(p);
+ Δb = rbmapwidth;
+ ofs = p.y & Bmask;
}else{
- p = baddr(x, y);
- Δp = bmapwidth;
- ofs = x & Bmask;
+ b = baddr(p);
+ Δb = bmapwidth;
+ ofs = p.x & Bmask;
}
- return breduce(p, Δp, ofs, w, h, Δw, Δh, left);
+ return breduce(b, Δb, ofs, sz, Δsz, left);
}
void
-bset(int x, int y, int w, int h, int set)
+bset(Point p, Point sz, int set)
{
int i, Δ, n;
- u64int *p, m, m´;
+ u64int *b, m, m´;
- p = baddr(x, y);
- n = x & Bmask;
- m = (1ULL << w) - 1 << 64 - w;
+ b = baddr(p);
+ n = p.x & Bmask;
+ m = (1ULL << sz.x) - 1 << 64 - sz.x;
m >>= n;
- Δ = n + w - 64;
+ Δ = n + sz.x - 64;
m´ = (1ULL << Δ) - 1 << 64 - Δ;
- for(i=0; i<h; i++, p+=bmapwidth){
- p[0] = set ? p[0] | m : p[0] & ~m;
+ for(i=0; i<sz.y; i++, b+=bmapwidth){
+ b[0] = set ? b[0] | m : b[0] & ~m;
if(Δ > 0)
- p[1] = set ? p[1] | m´ : p[1] & ~m´;
+ b[1] = set ? b[1] | m´ : b[1] & ~m´;
}
- p = rbaddr(x, y);
- n = y & Bmask;
- m = (1ULL << h) - 1 << 64 - h;
+ b = rbaddr(p);
+ n = p.y & Bmask;
+ m = (1ULL << sz.y) - 1 << 64 - sz.y;
m >>= n;
- Δ = n + h - 64;
+ Δ = n + sz.y - 64;
m´ = (1ULL << Δ) - 1 << 64 - Δ;
- for(i=0; i<w; i++, p+=rbmapwidth){
- p[0] = set ? p[0] | m : p[0] & ~m;
+ for(i=0; i<sz.x; i++, b+=rbmapwidth){
+ b[0] = set ? b[0] | m : b[0] & ~m;
if(Δ > 0)
- p[1] = set ? p[1] | m´ : p[1] & ~m´;
+ b[1] = set ? b[1] | m´ : b[1] & ~m´;
}
}
@@ -192,14 +192,14 @@
{
int i;
- bmapwidth = (nodemapwidth >> Bshift) + 2 * Npad;
- bmapheight = nodemapheight + 2 * Npad;
- rbmapwidth = (nodemapheight >> Bshift) + 2 * Npad;
- rbmapheight = nodemapwidth + 2 * Npad;
+ bmapwidth = (mapwidth >> Bshift) + 2 * Npad;
+ bmapheight = mapheight + 2 * Npad;
+ rbmapwidth = (mapheight >> Bshift) + 2 * Npad;
+ rbmapheight = mapwidth + 2 * Npad;
bmap = emalloc(bmapwidth * bmapheight * sizeof *bmap);
rbmap = emalloc(rbmapwidth * rbmapheight * sizeof *rbmap);
for(i=0; i<Npad; i++){
- memset(bmap + i * nodemapwidth, 0xff, bmapwidth * sizeof *bmap);
+ memset(bmap + i * mapwidth, 0xff, bmapwidth * sizeof *bmap);
memset(bmap + (bmapheight - i - 1) * bmapwidth, 0xff,
bmapwidth * sizeof *bmap);
memset(rbmap + i * rbmapwidth, 0xff, rbmapwidth * sizeof *rbmap);
--- a/com.c
+++ b/com.c
@@ -13,6 +13,11 @@
ushort size;
};
+#define MGATHER "dl dl"
+#define MMOVENEAR "dl dl"
+#define MMOVE "dl dd"
+#define MSTOP "dl"
+
static int
vunpack(uchar *p, uchar *e, char *fmt, va_list a)
{
@@ -74,9 +79,7 @@
int n;
Mobj reqm, reqt, *mo, *tgt;
- if((n = unpack(p, e, "dldd dldd",
- &reqm.idx, &reqm.uuid, &reqm.x, &reqm.y,
- &reqt.idx, &reqt.uuid, &reqt.x, &reqt.y)) < 0)
+ if((n = unpack(p, e, MGATHER, &reqm.idx, &reqm.uuid, &reqt.idx, &reqt.uuid)) < 0)
return -1;
if((mo = mobjfromreq(&reqm)) == nil)
return -1;
@@ -90,6 +93,10 @@
}
if((tgt = mobjfromreq(&reqt)) == nil)
return -1;
+ if(mo == tgt){
+ werrstr("reqgather: object %M targeting itself", mo);
+ return -1;
+ }
if((tgt->o->f & Fresource) == 0){
werrstr("reqgather: target %M not a resource", tgt);
return -1;
@@ -103,18 +110,10 @@
reqmovenear(uchar *p, uchar *e)
{
int n;
- Point click;
Mobj reqm, reqt, *mo, *tgt;
- if((n = unpack(p, e, "dldd dd dldd",
- &reqm.idx, &reqm.uuid, &reqm.x, &reqm.y,
- &click.x, &click.y,
- &reqt.idx, &reqt.uuid, &reqt.x, &reqt.y)) < 0)
+ if((n = unpack(p, e, MMOVENEAR, &reqm.idx, &reqm.uuid, &reqt.idx, &reqt.uuid)) < 0)
return -1;
- if(eqpt(reqm.Point, reqt.Point) || eqpt(reqm.Point, click)){
- dprint("reqmovenear: %P [%#ux,%ld] → %P [%#ux,%ld] (%P), not moving to itself\n", reqm.Point, reqm.idx, reqm.uuid, reqt.Point, reqt.idx, reqt.uuid, click);
- return n;
- }
if((mo = mobjfromreq(&reqm)) == nil)
return -1;
if((mo->o->f & Fimmutable) || mo->o->speed == 0.0){
@@ -123,11 +122,11 @@
}
if((tgt = mobjfromreq(&reqt)) == nil)
return -1;
- if(click.x >= nodemapwidth || click.y >= nodemapheight){
- werrstr("reqmovenear: invalid location %d,%d", click.x, click.y);
+ if(mo == tgt){
+ werrstr("reqmovenear: object %M targeting itself", mo);
return -1;
}
- if(pushmovecommand(click, mo, tgt) < 0)
+ if(pushmovecommand(mo, tgt->Point, tgt) < 0)
return -1;
return n;
}
@@ -139,26 +138,24 @@
Point tgt;
Mobj reqm, *mo;
- if((n = unpack(p, e, "dldd dd",
- &reqm.idx, &reqm.uuid, &reqm.x, &reqm.y,
- &tgt.x, &tgt.y)) < 0)
+ if((n = unpack(p, e, MMOVE, &reqm.idx, &reqm.uuid, &tgt.x, &tgt.y)) < 0)
return -1;
- if(eqpt(reqm.Point, tgt)){
- dprint("reqmove: %P [%#ux,%ld] → %P, not moving to itself\n", reqm.Point, reqm.idx, reqm.uuid, tgt);
- return n;
+ if(!ptinrect(tgt, Rect(0,0,mapwidth,mapheight))){
+ werrstr("reqmove: invalid target %P", tgt);
+ return -1;
}
if((mo = mobjfromreq(&reqm)) == nil)
return -1;
+ if(eqpt(mo->Point, tgt)){
+ werrstr("reqmove: object %M targeting itself", mo);
+ return -1;
+ }
if((mo->o->f & Fimmutable) || mo->o->speed == 0.0){
werrstr("reqmove: object %M can't move", mo);
return -1;
}
- if(tgt.x >= nodemapwidth || tgt.y >= nodemapheight){
- werrstr("reqmove: invalid target %d,%d", tgt.x, tgt.y);
+ if(pushmovecommand(mo, tgt, nil) < 0)
return -1;
- }
- if(pushmovecommand(tgt, mo, nil) < 0)
- return -1;
return n;
}
@@ -168,8 +165,7 @@
int n;
Mobj reqm, *mo;
- if((n = unpack(p, e, "dldd",
- &reqm.idx, &reqm.uuid, &reqm.x, &reqm.y)) < 0)
+ if((n = unpack(p, e, MSTOP, &reqm.idx, &reqm.uuid)) < 0)
return -1;
if((mo = mobjfromreq(&reqm)) == nil)
return -1;
@@ -307,9 +303,7 @@
Msg *m;
m = getclbuf();
- if(packmsg(m, "h dldd dldd", CTgather,
- mo->idx, mo->uuid, mo->x, mo->y,
- tgt->idx, tgt->uuid, tgt->x, tgt->y) < 0){
+ if(packmsg(m, "h" MGATHER, CTgather, mo->idx, mo->uuid, tgt->idx, tgt->uuid) < 0){
fprint(2, "sendgather: %r\n");
return -1;
}
@@ -317,15 +311,12 @@
}
int
-sendmovenear(Mobj *mo, Point click, Mobj *tgt)
+sendmovenear(Mobj *mo, Mobj *tgt)
{
Msg *m;
m = getclbuf();
- if(packmsg(m, "h dldd dd dldd", CTmovenear,
- mo->idx, mo->uuid, mo->x, mo->y,
- click.x, click.y,
- tgt->idx, tgt->uuid, tgt->x, tgt->y) < 0){
+ if(packmsg(m, "h" MMOVENEAR, CTmovenear, mo->idx, mo->uuid, tgt->idx, tgt->uuid) < 0){
fprint(2, "sendmovenear: %r\n");
return -1;
}
@@ -338,9 +329,7 @@
Msg *m;
m = getclbuf();
- if(packmsg(m, "h dldd dd", CTmove,
- mo->idx, mo->uuid, mo->x, mo->y,
- tgt.x, tgt.y) < 0){
+ if(packmsg(m, "h" MMOVE, CTmove, mo->idx, mo->uuid, tgt.x, tgt.y) < 0){
fprint(2, "sendmove: %r\n");
return -1;
}
@@ -353,8 +342,7 @@
Msg *m;
m = getclbuf();
- if(packmsg(m, "h dldd", CTstop,
- mo->idx, mo->uuid, mo->x, mo->y) < 0){
+ if(packmsg(m, "h" MSTOP, CTstop, mo->idx, mo->uuid) < 0){
fprint(2, "sendstop: %r\n");
return -1;
}
--- a/dat.h
+++ b/dat.h
@@ -1,6 +1,7 @@
typedef struct Node Node;
typedef struct Pairheap Pairheap;
typedef struct Attack Attack;
+typedef struct Size Size;
typedef struct Pic Pic;
typedef struct Pics Pics;
typedef struct Obj Obj;
@@ -10,8 +11,8 @@
typedef struct Mresource Mresource;
typedef struct Mobj Mobj;
typedef struct Mobjl Mobjl;
+typedef struct Tilepic Tilepic;
typedef struct Tile Tile;
-typedef struct Map Map;
typedef struct Resource Resource;
typedef struct Team Team;
typedef struct Cbuf Cbuf;
@@ -28,13 +29,12 @@
Nteam = 1 << Nteambits,
Teamshift = 32 - Nteambits,
Teamidxmask = ~(Nteam - 1 << Teamshift),
- Tilewidth = 32,
- Tileheight = Tilewidth,
+ Tilesz = 32,
Node2Tile = 4,
- Nodewidth = Tilewidth / Node2Tile,
- Nodeheight = Tileheight / Node2Tile,
- Subpxshift = 16,
- Subpxmask = (1 << Subpxshift) - 1,
+ Nodesz = Tilesz / Node2Tile,
+ Subshift = 16,
+ Submask = (1 << Subshift) - 1,
+ Pixelshift = 16 - 3,
};
struct Vector{
@@ -70,16 +70,18 @@
Node *from;
Pairheap *p;
};
-extern Node *nodemap;
-extern int nodemapwidth, nodemapheight;
+extern Node *map;
+extern int mapwidth, mapheight;
-struct Pic{
- u32int *p;
+struct Size{
int w;
int h;
- int dx;
- int dy;
};
+struct Pic{
+ u32int *p;
+ Size;
+ Point Δ;
+};
struct Pics{
Pic **pic;
int teamcol;
@@ -152,9 +154,8 @@
};
struct Obj{
char *name;
+ Size;
Pics pics[OSend][PTend];
- int w;
- int h;
int f;
Attack *atk[2];
int hp;
@@ -215,10 +216,7 @@
Command cmds[Ncmd];
int ctail;
Point;
- int px;
- int py;
- int subpx;
- int subpy;
+ Point sub;
Munit;
Mresource;
};
@@ -229,15 +227,15 @@
};
extern char *statename[OSend];
-struct Tile{
+struct Tilepic{
Pic *p;
};
-struct Map{
- Tile *t;
+struct Tile{
+ Tilepic *t;
Mobjl ml;
};
-extern Map *map;
-extern int mapwidth, mapheight;
+extern Tile *tilemap;
+extern int tilemapwidth, tilemapheight;
enum{
Ngatheramount = 8,
--- a/drw.c
+++ b/drw.c
@@ -15,8 +15,7 @@
static Rectangle selr;
static Point panmax;
static Mobj *selected[Nselect];
-static Mobj **visbuf;
-static int nvisbuf, nvis;
+static Vector vis;
enum{
DLgndshad,
@@ -29,10 +28,8 @@
};
typedef struct Drawlist Drawlist;
struct Drawlist{
- Mobj **mo;
- Pic **pics;
- int n;
- int sz;
+ Vector mobj;
+ Vector pics;
int noalpha;
};
static Drawlist drawlist[DLend] = {
@@ -55,51 +52,57 @@
pan.y = panmax.y;
}
-void
-doselect(Point p)
+static Mobj *
+vismobj(Point p)
{
int i;
+ Mobj **mp;
+ if((i = fbvis[p.y * fbw + p.x]) < 0)
+ return nil;
+ mp = vis.p;
+ assert(i < vis.n);
+ return mp[i];
+}
+
+void
+doselect(Point p)
+{
if(!ptinrect(p, selr))
return;
p = divpt(subpt(p, selr.min), scale);
- i = fbvis[p.y * fbw + p.x];
- selected[0] = i == -1 ? nil : visbuf[i];
+ selected[0] = vismobj(p);
}
void
doaction(Point p, int clearcmds)
{
- int i;
- Point vp;
- Mobj *mo, *it;
+ Mobj *mo, *tgt;
- it = selected[0];
- if(it == nil || it->o->f & Fimmutable || !ptinrect(p, selr))
+ mo = selected[0];
+ if(mo == nil || mo->o->f & Fimmutable || !ptinrect(p, selr))
return;
- vp = divpt(subpt(p, selr.min), scale);
- i = fbvis[vp.y * fbw + vp.x];
- mo = i == -1 ? nil : visbuf[i];
- p = divpt(addpt(subpt(p, selr.min), pan), scale);
- p.x /= Nodewidth;
- p.y /= Nodeheight;
- if(nodemapwidth - p.x < it->o->w || nodemapheight - p.y < it->o->h){
- dprint("doaction: %M destination beyond map edge\n", it);
+ p = subpt(p, selr.min);
+ tgt = vismobj(divpt(p, scale));
+ p = divpt(addpt(p, pan), scale);
+ p = divpt(p, Nodesz);
+ if(p.x + mo->o->w > mapwidth || p.y + mo->o->h > mapheight){
+ dprint("doaction: %M target %P beyond map edge\n", mo, p);
return;
}
- if(mo == it || eqpt(it->Point, p)){
- dprint("doaction: %M targeting itself\n", it);
+ if(tgt == mo || eqpt(mo->Point, p)){
+ dprint("doaction: %M targeting moself\n", mo);
return;
}
if(clearcmds)
- sendstop(it);
- if(mo != nil){
- if((mo->o->f & Fresource) && (it->o->f & Fgather))
- sendgather(it, mo);
+ sendstop(mo);
+ if(tgt != nil){
+ if((tgt->o->f & Fresource) && (mo->o->f & Fgather))
+ sendgather(mo, tgt);
else
- sendmovenear(it, p, mo);
+ sendmovenear(mo, tgt);
}else
- sendmove(it, p);
+ sendmove(mo, p);
}
static void
@@ -136,62 +139,57 @@
string(screen, p, display->white, ZP, font, s);
}
-static int
-addvis(Mobj *mo)
+static void
+clearvis(void)
{
- int i;
-
- if((i = nvis++) >= nvisbuf){
- visbuf = erealloc(visbuf, (nvisbuf + 16) * sizeof *visbuf,
- nvisbuf * sizeof *visbuf);
- nvisbuf += 16;
- }
- visbuf[i] = mo;
- return i;
+ clearvec(&vis, sizeof(Mobj*));
}
-static void
-clearvis(void)
+static int
+addvis(Mobj *mo)
{
- if(visbuf != nil)
- memset(visbuf, 0, nvisbuf * sizeof *visbuf);
- nvis = 0;
+ pushvec(&vis, &mo, sizeof mo);
+ return vis.n - 1;
}
static int
-boundpic(Rectangle *r, u32int **q)
+boundpic(Rectangle *rp, Point o, u32int **q)
{
int w;
+ Rectangle r;
- r->min.x -= pan.x / scale;
- r->min.y -= pan.y / scale;
- if(r->min.x + r->max.x < 0 || r->min.x >= fbw
- || r->min.y + r->max.y < 0 || r->min.y >= fbh)
+ r = *rp;
+ r.min = addpt(r.min, o);
+ r.min.x -= pan.x / scale;
+ r.min.y -= pan.y / scale;
+ if(r.min.x + r.max.x < 0 || r.min.x >= fbw
+ || r.min.y + r.max.y < 0 || r.min.y >= fbh)
return -1;
- w = r->max.x;
- if(r->min.x < 0){
+ w = r.max.x;
+ if(r.min.x < 0){
if(q != nil)
- *q -= r->min.x;
- r->max.x += r->min.x;
- r->min.x = 0;
+ *q -= r.min.x;
+ r.max.x += r.min.x;
+ r.min.x = 0;
}
- if(r->min.x + r->max.x > fbw)
- r->max.x -= r->min.x + r->max.x - fbw;
- if(r->min.y < 0){
+ if(r.min.x + r.max.x > fbw)
+ r.max.x -= r.min.x + r.max.x - fbw;
+ if(r.min.y < 0){
if(q != nil)
- *q -= w * r->min.y;
- r->max.y += r->min.y;
- r->min.y = 0;
+ *q -= w * r.min.y;
+ r.max.y += r.min.y;
+ r.min.y = 0;
}
- if(r->min.y + r->max.y > fbh)
- r->max.y -= r->min.y + r->max.y - fbh;
- r->min.x *= scale;
- r->max.x *= scale;
+ if(r.min.y + r.max.y > fbh)
+ r.max.y -= r.min.y + r.max.y - fbh;
+ r.min.x *= scale;
+ r.max.x *= scale;
+ *rp = r;
return 0;
}
static void
-drawpic(int x, int y, Pic *pic, int ivis)
+drawpic(Point o, Pic *pic, int ivis)
{
int n, Δp, Δsp, Δq;
u32int v, *p, *e, *sp, *q;
@@ -200,8 +198,8 @@
if(pic->p == nil)
sysfatal("drawpic: empty pic");
q = pic->p;
- r = Rect(x + pic->dx, y + pic->dy, pic->w, pic->h);
- if(boundpic(&r, &q) < 0)
+ r = Rect(pic->Δ.x, pic->Δ.y, pic->w, pic->h);
+ if(boundpic(&r, o, &q) < 0)
return;
Δq = pic->w - r.max.x / scale;
p = fb + r.min.y * fbws + r.min.x;
@@ -226,18 +224,18 @@
}
static void
-drawpicalpha(int x, int y, Pic *pic)
+drawpicalpha(Point o, Pic *pic)
{
int n, Δp, Δq;
u8int k, a, b;
- u32int o, A, B, *p, *e, *q;
+ u32int f, A, B, *p, *e, *q;
Rectangle r;
if(pic->p == nil)
- sysfatal("drawpic: empty pic");
+ sysfatal("drawpicalpha: empty pic");
q = pic->p;
- r = Rect(x + pic->dx, y + pic->dy, pic->w, pic->h);
- if(boundpic(&r, &q) < 0)
+ r = Rect(pic->Δ.x, pic->Δ.y, pic->w, pic->h);
+ if(boundpic(&r, o, &q) < 0)
return;
Δq = pic->w - r.max.x / scale;
p = fb + r.min.y * fbws + r.min.x;
@@ -251,9 +249,9 @@
for(n=0; n<24; n+=8){
a = A >> n;
b = B >> n;
- o = k * (a - b);
- o = (o + 1 + (o >> 8)) >> 8;
- B = B & ~(0xff << n) | (o + b & 0xff) << n;
+ f = k * (a - b);
+ f = (f + 1 + (f >> 8)) >> 8;
+ B = B & ~(0xff << n) | (f + b & 0xff) << n;
}
for(n=0; n<scale; n++)
*p++ = B;
@@ -264,14 +262,14 @@
}
void
-compose(int x, int y, u32int c)
+compose(Point o, u32int c)
{
int n, Δp;
u32int v, *p, *e;
Rectangle r;
- r = Rect(x * Nodewidth, y * Nodeheight, Nodewidth, Nodeheight);
- if(boundpic(&r, nil) < 0)
+ r = Rpt(ZP, Pt(Nodesz, Nodesz));
+ if(boundpic(&r, o, nil) < 0)
return;
p = fb + r.min.y * fbws + r.min.x;
Δp = fbws - r.max.x;
@@ -329,54 +327,31 @@
{
Drawlist *dl;
- for(dl=drawlist; dl<drawlist+DLend; dl++)
- dl->n = 0;
+ for(dl=drawlist; dl<drawlist+DLend; dl++){
+ clearvec(&dl->mobj, sizeof(Mobj*));
+ clearvec(&dl->pics, sizeof(Pic*));
+ }
}
static void
-drawmobjs(void)
-{
- int n;
- Mobj *mo;
- Drawlist *dl;
-
- for(dl=drawlist; dl<drawlist+DLend; dl++)
- for(n=0; n<dl->n; n++){
- mo = dl->mo[n];
- if(dl->noalpha)
- drawpic(mo->px, mo->py, dl->pics[n], addvis(mo));
- else
- drawpicalpha(mo->px, mo->py, dl->pics[n]);
- }
-}
-
-static void
addpic(Drawlist *dl, Mobj *mo, int type)
{
- int n;
Pic *p;
if((p = frm(mo, type)) == nil)
return;
- if(dl->n >= dl->sz){
- n = dl->sz * sizeof *dl->pics;
- dl->pics = erealloc(dl->pics, n + 16 * sizeof *dl->pics, n);
- dl->mo = erealloc(dl->mo, n + 16 * sizeof *dl->mo, n);
- dl->sz += 16;
- }
- n = dl->n++;
- dl->pics[n] = p;
- dl->mo[n] = mo;
+ pushvec(&dl->mobj, &mo, sizeof mo);
+ pushvec(&dl->pics, &p, sizeof p);
}
static void
-addmobjs(Map *m)
+addmobjs(Tile *t)
{
int air;
Mobj *mo;
Mobjl *ml;
- for(ml=m->ml.l; ml!=&m->ml; ml=ml->l){
+ for(ml=t->ml.l; ml!=&t->ml; ml=ml->l){
mo = ml->mo;
air = mo->o->f & Fair;
addpic(drawlist + (air ? DLairshad : DLgndshad), mo, PTshadow);
@@ -386,44 +361,65 @@
}
}
-static Rectangle
-setdrawrect(void)
+static void
+drawmobjs(void)
{
+ int n;
+ Mobj *mo, **mp;
+ Pic **pp;
+ Drawlist *dl;
+
+ for(dl=drawlist; dl<drawlist+DLend; dl++)
+ for(mp=dl->mobj.p, pp=dl->pics.p, n=0; n<dl->mobj.n; n++, mp++, pp++){
+ mo = *mp;
+ if(dl->noalpha)
+ drawpic(Pt(mo->sub.x >> Pixelshift,
+ mo->sub.y >> Pixelshift), *pp, addvis(mo));
+ else
+ drawpicalpha(Pt(mo->sub.x >> Pixelshift,
+ mo->sub.y >> Pixelshift), *pp);
+ }
+}
+
+static void
+mapdrawrect(Rectangle *rp)
+{
Rectangle r;
- r.min.x = pan.x / scale / Tilewidth;
- r.min.y = pan.y / scale / Tileheight;
- r.max.x = r.min.x + (pan.x / scale % Tilewidth != 0);
- r.max.x += fbw / Tilewidth + (fbw % Tilewidth != 0);
- if(r.max.x > mapwidth)
- r.max.x = mapwidth;
- r.max.y = r.min.y + (pan.y / scale % Tileheight != 0);
- r.max.y += fbh / Tileheight + (fbh % Tilewidth != 0);
- if(r.max.y > mapheight)
- r.max.y = mapheight;
+ r.min = divpt(pan, scale);
+ r.min = divpt(r.min, Tilesz);
+ r.max.x = r.min.x + (pan.x / scale % Tilesz != 0);
+ r.max.x += fbw / Tilesz + (fbw % Tilesz != 0);
+ if(r.max.x > tilemapwidth)
+ r.max.x = tilemapwidth;
+ r.max.y = r.min.y + (pan.y / scale % Tilesz != 0);
+ r.max.y += fbh / Tilesz + (fbh % Tilesz != 0);
+ if(r.max.y > tilemapheight)
+ r.max.y = tilemapheight;
/* enlarge window to capture units overlapping multiple tiles;
* seems like the easiest way to take this into account */
r.min.x = max(r.min.x - 4, 0);
r.min.y = max(r.min.y - 4, 0);
- return r;
+ *rp = r;
}
void
redraw(void)
{
- int x, y;
+ Point p;
Rectangle r;
- Map *m;
+ Tile *t;
clearvis();
clearlists();
- r = setdrawrect();
- for(y=r.min.y, m=map+y*mapwidth+r.min.x; y<r.max.y; y++){
- for(x=r.min.x; x<r.max.x; x++, m++){
- drawpic(x*Tilewidth, y*Tileheight, m->t->p, -1);
- addmobjs(m);
+ mapdrawrect(&r);
+ t = tilemap + p.y * tilemapwidth + r.min.x;
+ for(p.y=r.min.y; p.y<r.max.y; p.y++){
+ for(p.x=r.min.x; p.x<r.max.x; p.x++, t++){
+ drawpic(mulpt(p, Tilesz), t->t->p, -1);
+ addmobjs(t);
}
- m += mapwidth - (r.max.x - r.min.x);
+ t += tilemapwidth - (r.max.x - r.min.x);
}
drawmobjs();
if(debugmap)
@@ -443,13 +439,13 @@
void
resetfb(void)
{
- fbws = min(nodemapwidth * Nodewidth * scale, Dx(screen->r));
- fbh = min(nodemapheight * Nodeheight * scale, Dy(screen->r));
+ fbws = min(mapwidth * Nodesz * scale, Dx(screen->r));
+ fbh = min(mapheight * Nodesz * scale, Dy(screen->r));
selr = Rpt(screen->r.min, addpt(screen->r.min, Pt(fbws, fbh)));
p0 = Pt(screen->r.min.x + 8, screen->r.max.y - 3 * font->height);
p0.y -= (p0.y - screen->r.min.y) % scale;
- panmax.x = max(Nodewidth * nodemapwidth * scale - Dx(screen->r), 0);
- panmax.y = max(Nodeheight * nodemapheight * scale - Dy(screen->r), 0);
+ panmax.x = max(Nodesz * mapwidth * scale - Dx(screen->r), 0);
+ panmax.y = max(Nodesz * mapheight * scale - Dy(screen->r), 0);
if(p0.y < selr.max.y){
panmax.y += selr.max.y - p0.y;
fbh -= selr.max.y - p0.y;
--- a/fns.h
+++ b/fns.h
@@ -4,17 +4,21 @@
int parsemsg(Msg*);
void endmsg(Msg*);
int sendgather(Mobj*, Mobj*);
-int sendmovenear(Mobj*, Point, Mobj*);
+int sendmovenear(Mobj*, Mobj*);
int sendstop(Mobj*);
int sendmove(Mobj*, Point);
int sendpause(void);
void stepsnd(void);
void initsnd(void);
+void setpos(Mobj*, Point);
+void setsubpos(Mobj*, Point);
+void snaptomapgrid(Mobj*);
+Tile* tilepos(Point);
void linktomap(Mobj*);
int pushreturncommand(Mobj*, Mobj*);
int pushgathercommand(Mobj*, Mobj*);
int pushmove(Mobj*);
-int pushmovecommand(Point, Mobj*, Mobj*);
+int pushmovecommand(Mobj*, Point, Mobj*);
void resourcestate(Mobj*);
void depleteresource(Mobj*, int);
void freezefrm(Mobj*, int);
@@ -36,7 +40,7 @@
void dopan(Point);
void doselect(Point);
void doaction(Point, int);
-void compose(int, int, u32int);
+void compose(Point, u32int);
void redraw(void);
void updatefb(void);
void resetfb(void);
@@ -43,19 +47,20 @@
void drawfb(void);
void initimg(void);
void initfs(void);
+double eucdist(Point, Point);
double octdist(Point, Point);
-void setgoal(Point*, Mobj*, Mobj*);
-Mobj* unitat(int, int);
+void setgoal(Mobj*, Point*, Mobj*);
+Mobj* unitat(Point);
int isblocked(Point, Obj*);
void markmobj(Mobj*, int);
int isnextto(Mobj*, Mobj*);
-int findpath(Point, Mobj*);
+int findpath(Mobj*, Point);
void drawnodemap(Rectangle, Mobj*);
-Mobj* mapspawn(Point, Obj*);
+Mobj* mapspawn(Obj*, Point);
void initmap(void);
Mobj* derefmobj(int, long);
-int spawnunit(Point, Obj*, int);
-int spawnresource(Point, Obj*, int);
+int spawnunit(Obj*, Point, int);
+int spawnresource(Obj*, Point, int);
void nukequeue(Pairheap**);
Pairheap* popqueue(Pairheap**);
void decreasekey(Pairheap*, double, Pairheap**);
@@ -62,10 +67,10 @@
void pushqueue(Node*, Pairheap**);
int lsb(uvlong);
int msb(uvlong);
-u64int* baddr(int, int);
-u64int* rbaddr(int, int);
-u64int* bload(int, int, int, int, int, int, int, int);
-void bset(int, int, int, int, int);
+u64int* baddr(Point);
+u64int* rbaddr(Point);
+u64int* bload(Point, Point, Point, int, int);
+void bset(Point, Point, int);
void initbmap(void);
int mobjfmt(Fmt*);
void dprint(char *, ...);
--- a/fs.c
+++ b/fs.c
@@ -39,7 +39,7 @@
};
struct Tilel{
int id;
- Tile *t;
+ Tilepic *t;
Tilel *l;
};
static Tilel tilel0 = {.l = &tilel0}, *tilel = &tilel0;
@@ -80,8 +80,8 @@
pic->p = p;
pic->w = dx;
pic->h = dy;
- pic->dx = i->r.min.x;
- pic->dy = i->r.min.y;
+ pic->Δ.x = i->r.min.x;
+ pic->Δ.y = i->r.min.y;
m = i->depth / 8;
freeimage(i);
s = b;
@@ -215,7 +215,7 @@
return pl->p;
}
-static Tile *
+static Tilepic *
pushtile(int id)
{
Tilel *tl;
@@ -248,6 +248,7 @@
switch(*fmt++){
default: sysfatal("unknown format %c", fmt[-1]);
case 0: return;
+ case ' ': break;
case 'd':
if((n = strtol(*fld++, nil, 0)) < 0)
sysfatal("vunpack: illegal positive integer %d", n);
@@ -301,7 +302,7 @@
sysfatal("vunpack: empty tile");
if((n = strtol(s, nil, 0)) <= 0)
sysfatal("vunpack: illegal tile index %d", n);
- *va_arg(a, Tile**) = pushtile(n);
+ *va_arg(a, Tilepic**) = pushtile(n);
break;
}
}
@@ -323,7 +324,7 @@
Obj *o, **os;
Resource *r;
- unpack(fld, "ro", &r, &o);
+ unpack(fld, "r o", &r, &o);
if(o->res != nil && o->res != r)
sysfatal("readgather %s: obj %s already assigned to %s",
r->name, o->name, o->res->name);
@@ -362,16 +363,16 @@
readmap(char **fld, int n, Table *tab)
{
int x;
- Map *m;
+ Tile *t;
if(tab->row == 0){
tab->ncol = n;
- mapwidth = n;
- map = emalloc(mapheight * n * sizeof *map);
+ tilemapwidth = n;
+ tilemap = emalloc(tilemapheight * n * sizeof *tilemap);
}
- m = map + tab->row * mapwidth;
- for(x=0; x<n; x++, m++)
- unpack(fld++, "t", &m->t);
+ t = tilemap + tab->row * tilemapwidth;
+ for(x=0; x<n; x++, t++)
+ unpack(fld++, "t", &t->t);
}
static void
@@ -383,7 +384,8 @@
if(objp == nil)
objp = emalloc(nobjp * sizeof *objp);
op = objp + tab->row;
- unpack(fld, "oddd", &op->o, &op->x, &op->y, &arg);
+ unpack(fld, "o dd d", &op->o, &op->x, &op->y, &arg);
+ op->Point = mulpt(op->Point, Node2Tile);
if(op->o->f & Fresource){
op->team = 0;
op->resource = 1;
@@ -443,10 +445,11 @@
obj = emalloc(nobj * sizeof *obj);
o = obj + tab->row;
o->name = estrdup(*fld++);
- unpack(fld, "ddddddddddaaffff", &o->f, &o->w, &o->h,
+ unpack(fld, "d dd ddd dddd aa ffff", &o->f, &o->w, &o->h,
&o->hp, &o->def, &o->vis,
o->cost, o->cost+1, o->cost+2, &o->time,
- o->atk, o->atk+1, &o->speed, &o->accel, &o->halt, &o->turn);
+ o->atk, o->atk+1,
+ &o->speed, &o->accel, &o->halt, &o->turn);
if(o->f & Fresource)
o->f |= Fimmutable;
else{
@@ -453,9 +456,9 @@
o->accel /= 256.0;
o->halt /= 256.0;
/* halting distance in path node units */
- o->halt /= Nodewidth;
+ o->halt /= Nodesz;
}
- if(o->w < 1 || o->h < 1)
+ if(o->w < 1 || o->h < 1 || o->w > 4 * Node2Tile || o->h > 4 * Node2Tile)
sysfatal("readobj: %s invalid dimensions %d,%d", o->name, o->w, o->h);
}
@@ -469,7 +472,7 @@
if(n < 4)
sysfatal("readspr %s: %d fields < 4 mandatory columns", o->name, n);
- unpack(fld, "odd", &o, &type, &nr);
+ unpack(fld, "o dd", &o, &type, &nr);
fld += 3;
n -= 3;
state = type & PFstatemask;
@@ -519,7 +522,7 @@
[TBresource] {"resource", readresource, -1, &nresource},
[TBspawn] {"spawn", readspawn, -1, nil},
[TBtileset] {"tileset", readtileset, 1, nil},
- [TBmap] {"map", readmap, -1, &mapheight},
+ [TBmap] {"map", readmap, -1, &tilemapheight},
[TBspr] {"spr", readspr, -1, nil},
[TBgather] {"gather", readgather, -1, nil},
};
@@ -605,17 +608,15 @@
initmapobj(void)
{
Objp *op;
- Map *m;
- Point p;
+ Tile *t;
- for(m=map; m<map+mapwidth*mapheight; m++)
- m->ml.l = m->ml.lp = &m->ml;
+ for(t=tilemap; t<tilemap+tilemapwidth*tilemapheight; t++)
+ t->ml.l = t->ml.lp = &t->ml;
for(op=objp; op<objp+nobjp; op++){
- p = mulpt(op->Point, Node2Tile);
if(op->resource){
- if(spawnresource(p, op->o, op->amount) < 0)
+ if(spawnresource(op->o, op->Point, op->amount) < 0)
sysfatal("initmapobj: %s at %P: %r", op->o->name, op->Point);
- }else if(spawnunit(p, op->o, op->team) < 0)
+ }else if(spawnunit(op->o, op->Point, op->team) < 0)
sysfatal("initmapobj: %s team %d at %P: %r", op->o->name, op->team, op->Point);
}
free(objp);
@@ -649,9 +650,10 @@
sysfatal("checkdb: no tileset defined");
if(nresource != Nresource)
sysfatal("checkdb: incomplete resource specification");
- if(mapwidth % 16 != 0 || mapheight % 16 != 0 || mapwidth * mapheight == 0)
+ if(tilemapwidth % 16 != 0 || tilemapheight % 16 != 0
+ || tilemapwidth * tilemapheight <= 0)
sysfatal("checkdb: map size %d,%d not in multiples of 16",
- mapwidth, mapheight);
+ tilemapwidth, tilemapheight);
if(nteam < 2)
sysfatal("checkdb: not enough teams");
}
--- a/map.c
+++ b/map.c
@@ -4,11 +4,52 @@
#include "dat.h"
#include "fns.h"
-Map *map;
+Tile *tilemap;
+int tilemapwidth, tilemapheight;
+Node *map;
int mapwidth, mapheight;
-Node *nodemap;
-int nodemapwidth, nodemapheight;
+void
+setpos(Mobj *mo, Point p)
+{
+ assert(p.x < mapwidth && p.y < mapheight);
+ mo->Point = p;
+ mo->sub.x = mo->x << Subshift;
+ mo->sub.y = mo->y << Subshift;
+}
+
+void
+setsubpos(Mobj *mo, Point p)
+{
+ mo->sub = p;
+ mo->x = p.x >> Subshift;
+ mo->y = p.y >> Subshift;
+}
+
+void
+snaptomapgrid(Mobj *mo)
+{
+ markmobj(mo, 0);
+ setpos(mo, mo->Point);
+ markmobj(mo, 1);
+}
+
+Tile *
+tilepos(Point p)
+{
+ p = divpt(p, Node2Tile);
+ return tilemap + p.y * tilemapwidth + p.x;
+}
+
+void
+linktomap(Mobj *mo)
+{
+ Tile *t;
+
+ t = tilepos(mo->Point);
+ mo->mapl = linkmobj(mo->o->f & Fair ? t->ml.lp : &t->ml, mo, mo->mapl);
+}
+
static void
updatemap(Mobj *mo)
{
@@ -15,7 +56,7 @@
Mobj *bmo;
if(isblocked(mo->Point, mo->o)){
- bmo = unitat(mo->x, mo->y);
+ bmo = unitat(mo->Point);
sysfatal("markmobj: attempt to place %s at %P, non-free block having %s at %P",
mo->o->name, mo->Point, bmo->o->name, bmo->Point);
}
@@ -26,24 +67,24 @@
static int
findspawn(Point *pp, int ofs, Obj *o, Obj *spawn)
{
- int minx, miny, maxx, maxy;
+ Rectangle r;
Point p;
p = *pp;
- minx = p.x - (ofs+1) * o->w;
- miny = p.y - (ofs+1) * o->h;
- maxx = p.x + spawn->w + ofs * o->w;
- maxy = p.y + spawn->h + ofs * o->h;
- for(p.x=minx+o->w, p.y=maxy; p.x<maxx; p.x++)
+ r.min.x = p.x - (ofs+1) * o->w;
+ r.min.y = p.y - (ofs+1) * o->h;
+ r.max.x = p.x + spawn->w + ofs * o->w;
+ r.max.y = p.y + spawn->h + ofs * o->h;
+ for(p.x=r.min.x+o->w, p.y=r.max.y; p.x<r.max.x; p.x++)
if(!isblocked(p, o))
goto found;
- for(p.x=maxx, p.y=maxy; p.y>miny; p.y--)
+ for(p.x=r.max.x, p.y=r.max.y; p.y>r.min.y; p.y--)
if(!isblocked(p, o))
goto found;
- for(p.x=maxx, p.y=miny; p.x>minx; p.x--)
+ for(p.x=r.max.x, p.y=r.min.y; p.x>r.min.x; p.x--)
if(!isblocked(p, o))
goto found;
- for(p.x=minx, p.y=miny; p.y<=maxy; p.y++)
+ for(p.x=r.min.x, p.y=r.min.y; p.y<=r.max.y; p.y++)
if(!isblocked(p, o))
goto found;
return -1;
@@ -57,7 +98,7 @@
{
int n;
Point p;
- Map *m;
+ Tile *t;
Mobjl *ml;
Mobj *mo;
Obj **os;
@@ -64,13 +105,17 @@
p = *pp;
if(o->f & (Fbuild|Fimmutable)){
+ if((p.x & Node2Tile - 1) || (p.y & Node2Tile - 1)){
+ werrstr("getspawn: unaligned building placement %P", p);
+ return -1;
+ }
if(isblocked(p, o)){
werrstr("getspawn: building placement at %P blocked", p);
return -1;
}
}else{
- m = map + p.y / Node2Tile * mapwidth + p.x / Node2Tile;
- for(mo=nil, ml=m->ml.l; ml!=&m->ml; ml=ml->l){
+ t = tilepos(p);
+ for(mo=nil, ml=t->ml.l; ml!=&t->ml; ml=ml->l){
mo = ml->mo;
for(os=mo->o->spawn, n=mo->o->nspawn; n>0; n--, os++)
if(*os == o)
@@ -78,7 +123,7 @@
if(n > 0)
break;
}
- if(ml == &m->ml){
+ if(ml == &t->ml){
werrstr("getspawn: no spawn object at %P", p);
return -1;
}
@@ -96,23 +141,15 @@
}
Mobj *
-mapspawn(Point p, Obj *o)
+mapspawn(Obj *o, Point p)
{
Mobj *mo;
- if(o->f & (Fbuild|Fimmutable) && (p.x & Node2Tile-1 || p.y & Node2Tile-1)){
- werrstr("mapspawn: building spawn %P not aligned to tile map", p);
- return nil;
- }
if(getspawn(&p, o) < 0)
return nil;
mo = emalloc(sizeof *mo);
mo->uuid = lrand();
- mo->Point = p;
- mo->px = p.x * Nodewidth;
- mo->py = p.y * Nodeheight;
- mo->subpx = mo->px << Subpxshift;
- mo->subpy = mo->py << Subpxshift;
+ setpos(mo, p);
mo->o = o;
updatemap(mo);
return mo;
@@ -121,8 +158,8 @@
void
initmap(void)
{
- nodemapwidth = mapwidth * Node2Tile;
- nodemapheight = mapheight * Node2Tile;
- nodemap = emalloc(nodemapwidth * nodemapheight * sizeof *nodemap);
+ mapwidth = tilemapwidth * Node2Tile;
+ mapheight = tilemapheight * Node2Tile;
+ map = emalloc(mapwidth * mapheight * sizeof *map);
initbmap();
}
--- a/path.c
+++ b/path.c
@@ -61,39 +61,38 @@
void
drawnodemap(Rectangle r, Mobj *sel)
{
- int x, y;
u64int *row, v, m;
- Point *p;
- Path *pp;
+ Point p, *pp;
+ Path *path;
Node *n;
r = Rpt(mulpt(r.min, Node2Tile), mulpt(r.max, Node2Tile));
- for(y=r.min.y, n=nodemap+y*nodemapwidth+r.min.x; y<r.max.y; y++){
- x = r.min.x;
- row = baddr(x, y);
+ for(p.y=r.min.y, n=map+p.y*mapwidth+r.min.x; p.y<r.max.y; p.y++){
+ p.x = r.min.x;
+ row = baddr(p);
v = *row++;
- m = 1ULL << 63 - (x & Bmask);
- for(; x<r.max.x; x++, n++, m>>=1){
+ m = 1ULL << 63 - (p.x & Bmask);
+ for(; p.x<r.max.x; p.x++, n++, m>>=1){
if(m == 0){
v = *row++;
m = 1ULL << 63;
}
if(v & m)
- compose(x, y, 0xff0000);
+ compose(mulpt(p, Nodesz), 0xff0000);
if(n->closed)
- compose(x, y, 0x000077);
+ compose(mulpt(p, Nodesz), 0x000077);
else if(n->open)
- compose(x, y, 0x007777);
+ compose(mulpt(p, Nodesz), 0x007777);
}
- n += nodemapwidth - (r.max.x - r.min.x);
+ n += mapwidth - (r.max.x - r.min.x);
}
if(sel != nil){
- pp = &sel->path;
- if(pp->step == nil)
+ path = &sel->path;
+ if(path->step == nil)
return;
- for(p=pp->step; p>=pp->moves.p; p--)
- compose(p->x / Nodewidth, p->y / Nodeheight, 0x00ff00);
- compose(pp->target.x, pp->target.y, 0x00ff77);
+ for(pp=path->step; pp>=path->moves.p; pp--)
+ compose(mulpt(*pp, Nodesz), 0x00ff00);
+ compose(mulpt(path->target, Nodesz), 0x00ff77);
}
}
@@ -101,7 +100,7 @@
clearpath(void)
{
nukequeue(&queue);
- memset(nodemap, 0, nodemapwidth * nodemapheight * sizeof *nodemap);
+ memset(map, 0, mapwidth * mapheight * sizeof *map);
nearest = nil;
}
@@ -112,34 +111,32 @@
if(o->f & Fair)
return 0;
- row = bload(p.x, p.y, o->w, o->h, 0, 0, 0, 0);
+ row = bload(p, Pt(o->w, o->h), ZP, 0, 0);
return (*row & 1ULL << 63) != 0;
}
Mobj *
-unitat(int px, int py)
+unitat(Point p)
{
- int x, y;
+ Point mp;
Rectangle r, mr;
- Map *m;
+ Tile *t;
Mobjl *ml;
Mobj *mo;
- x = px / Node2Tile;
- y = py / Node2Tile;
- r = Rect(x-4, y-4, x, y);
- for(; y>=r.min.y; y--)
- for(x=r.max.x, m=map+y*mapwidth+x; x>=r.min.x; x--)
- for(ml=m->ml.l; ml!=&m->ml; ml=ml->l){
+ mp = divpt(p, Node2Tile);
+ r = Rpt(subpt(mp, Pt(4, 4)), mp);
+ for(; mp.y>=r.min.y; mp.y--){
+ mp.x = r.max.x;
+ t = tilemap + mp.y * tilemapwidth + mp.x;
+ for(; mp.x>=r.min.x; mp.x--, t--)
+ for(ml=t->ml.l; ml!=&t->ml; ml=ml->l){
mo = ml->mo;
- mr.min.x = mo->x;
- mr.min.y = mo->y;
- mr.max.x = mr.min.x + mo->o->w;
- mr.max.y = mr.min.y + mo->o->h;
- if(px >= mo->x && px <= mo->x + mo->o->w
- && py >= mo->y && py <= mo->y + mo->o->h)
+ mr = Rect(mo->x, mo->y, mo->x+mo->o->w, mo->y+mo->o->h);
+ if(ptinrect(p, mr))
return mo;
}
+ }
return nil;
}
@@ -146,26 +143,29 @@
void
markmobj(Mobj *mo, int set)
{
- int w, h;
+ Point sz;
if(mo->o->f & Fair)
return;
- w = mo->o->w;
- if((mo->subpx & Subpxmask) != 0 && mo->x != (mo->px + 1) / Nodewidth)
- w++;
- h = mo->o->h;
- if((mo->subpy & Subpxmask) != 0 && mo->y != (mo->py + 1) / Nodewidth)
- h++;
- bset(mo->x, mo->y, w, h, set);
+ sz = Pt(mo->o->w, mo->o->h);
+/*
+ if((mo->sub.x & Submask) != 0 && mo->x != ((mo->sub.x>>Pixelshift) + 1) / Nodesz)
+ sz.x++;
+ if((mo->sub.y & Submask) != 0 && mo->y != ((mo->sub.y>>Pixelshift) + 1) / Nodesz)
+ sz.y++;
+*/
+ sz.x += (mo->sub.x & Submask) != 0 && mo->x != mo->sub.x + (1<<Pixelshift) >> Subshift;
+ sz.y += (mo->sub.y & Submask) != 0 && mo->y != mo->sub.y + (1<<Pixelshift) >> Subshift;
+ bset(mo->Point, sz, set);
}
-static double
-eucdist(Node *a, Node *b)
+double
+eucdist(Point a, Point b)
{
- double dx, dy;
+ int dx, dy;
- dx = a->x - b->x;
- dy = a->y - b->y;
+ dx = a.x - b.x;
+ dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
@@ -203,7 +203,7 @@
ss = left ? -1 : 1;
(*v)--;
for(;;){
- row = bload(x, y, w, h, 0, 2, left, rot);
+ row = bload(Pt(x, y), Pt(w, h), Pt(0, 2), left, rot);
bs = row[1];
if(left){
bs |= row[0] << 1 & ~row[0];
@@ -240,8 +240,8 @@
}
if(end)
return nil;
- assert(x < nodemapwidth && y < nodemapheight);
- n = nodemap + y * nodemapwidth + x;
+ assert(x < mapwidth && y < mapheight);
+ n = map + y * mapwidth + x;
n->x = x;
n->y = y;
n->Δg = steps;
@@ -267,7 +267,7 @@
steps++;
x += Δx;
y += Δy;
- if(*bload(x, y, w, h, 0, 0, 0, 0) & 1ULL << 63)
+ if(*bload(Pt(x, y), Pt(w, h), ZP, 0, 0) & 1ULL << 63)
return nil;
if(jumpeast(x, y, w, h, b, &ofs1, left1, 1) != nil
|| jumpeast(x, y, w, h, b, &ofs2, left2, 0) != nil)
@@ -275,8 +275,8 @@
if(ofs1 == 0 || ofs2 == 0)
return nil;
}
- assert(x < nodemapwidth && y < nodemapheight);
- n = nodemap + y * nodemapwidth + x;
+ assert(x < mapwidth && y < mapheight);
+ n = map + y * mapwidth + x;
n->x = x;
n->y = y;
n->Δg = steps;
@@ -367,12 +367,12 @@
{
u64int *row;
- row = bload(x-1, y-1, w, h, 2, 2, 1, 0);
+ row = bload(Pt(x-1,y-1), Pt(w,h), Pt(2,2), 1, 0);
return (row[2] & 7) << 6 | (row[1] & 7) << 3 | row[0] & 7;
}
static Node **
-successors(Node *n, int w, int h, Node *b)
+jpssuccessors(Node *n, Size sz, Node *b)
{
static Node *dir[8+1];
static dtab[2*(nelem(dir)-1)]={
@@ -382,13 +382,13 @@
int i, ns;
Node *s, **p;
- ns = neighbors(n->x, n->y, w, h);
+ ns = neighbors(n->x, n->y, sz.w, sz.h);
ns = prune(ns, n->dir);
memset(dir, 0, sizeof dir);
for(i=0, p=dir; i<nelem(dtab); i+=2){
if(ns & dtab[i])
continue;
- if((s = jump(n->x, n->y, w, h, b, dtab[i+1])) != nil){
+ if((s = jump(n->x, n->y, sz.w, sz.h, b, dtab[i+1])) != nil){
s->dir = dtab[i+1];
*p++ = s;
}
@@ -396,8 +396,33 @@
return dir;
}
+static Node **
+successors(Node *n, Size, Node *)
+{
+ static Node *dir[8+1];
+ static dtab[2*(nelem(dir)-1)]={
+ -1,-1, 0,-1, 1,-1,
+ -1,0, 0,1,
+ -1,1, 0,1, 1,1,
+ };
+ int i;
+ Node *s, **p;
+
+ memset(dir, 0, sizeof dir);
+ for(i=0, p=dir; i<nelem(dtab); i+=2){
+ s = n + dtab[i+1] * mapwidth + dtab[i];
+ if(s >= map && s < map + mapwidth * mapheight){
+ s->Point = addpt(n->Point, Pt(dtab[i], dtab[i+1]));
+ s->Δg = 1;
+ s->Δlen = dtab[i] != 0 && dtab[i+1] != 0 ? SQRT2 : 1;
+ *p++ = s;
+ }
+ }
+ return dir;
+}
+
static Node *
-a∗(Node *a, Node *b, Mobj *mo)
+a∗(Mobj *mo, Node *a, Node *b)
{
double g, Δg;
Node *x, *n, **dp;
@@ -416,10 +441,12 @@
if(x == b)
break;
x->closed = 1;
- dp = successors(x, mo->o->w, mo->o->h, b);
+ dp = successors(x, mo->o->Size, b);
for(n=*dp++; n!=nil; n=*dp++){
if(n->closed)
continue;
+ if(isblocked(n->Point, mo->o))
+ continue;
g = x->g + n->Δg;
Δg = n->g - g;
if(!n->open){
@@ -445,33 +472,28 @@
}
static void
-directpath(Node *a, Node *g, Mobj *mo)
+directpath(Mobj *mo, Node *a, Node *g)
{
- Point p;
Path *pp;
pp = &mo->path;
- pp->dist = eucdist(a, g);
- clearvec(&pp->moves, sizeof p);
- p = Pt(g->x * Nodewidth, g->y * Nodeheight);
- pushvec(&pp->moves, &p, sizeof p);
+ pp->dist = eucdist(a->Point, g->Point);
+ clearvec(&pp->moves, sizeof g->Point);
+ pushvec(&pp->moves, &g->Point, sizeof g->Point);
pp->step = (Point *)pp->moves.p + pp->moves.n - 1;
}
static void
-backtrack(Node *n, Node *a, Mobj *mo)
+backtrack(Mobj *mo, Node *n, Node *a)
{
- Point p;
Path *pp;
pp = &mo->path;
assert(n != a && n->step > 0);
pp->dist = n->len;
- clearvec(&pp->moves, sizeof p);
- for(; n!=a; n=n->from){
- p = Pt(n->x * Nodewidth, n->y * Nodeheight);
- pushvec(&pp->moves, &p, sizeof p);
- }
+ clearvec(&pp->moves, sizeof n->Point);
+ for(; n!=a; n=n->from)
+ pushvec(&pp->moves, &n->Point, sizeof n->Point);
pp->step = (Point *)pp->moves.p + pp->moves.n - 1;
}
@@ -491,7 +513,7 @@
/* FIXME: completely broken */
static Node *
-nearestnonjump(Node *n, Node *b, Mobj *mo)
+nearestnonjump(Mobj *mo, Node *n, Node *b)
{
static Point dirtab[] = {
{0,-1},
@@ -499,23 +521,21 @@
{0,1},
{-1,0},
};
- int i, x, y;
+ int i;
+ Point p;
Node *m, *min;
min = n;
for(i=0; i<nelem(dirtab); i++){
- x = n->x + dirtab[i].x;
- y = n->y + dirtab[i].y;
- while(!isblocked(Pt(x, y), mo->o)){
- m = nodemap + y * nodemapwidth + x;
- m->x = x;
- m->y = y;
+ p = addpt(n->Point, dirtab[i]);
+ while(!isblocked(p, mo->o)){
+ m = map + p.y * mapwidth + p.x;
+ m->Point = p;
m->h = octdist(m->Point, b->Point);
if(min->h < m->h)
break;
min = m;
- x += dirtab[i].x;
- y += dirtab[i].y;
+ p = addpt(p, dirtab[i]);
}
}
if(min != n){
@@ -528,92 +548,82 @@
/* FIXME: completely broken */
void
-setgoal(Point *p, Mobj *mo, Mobj *block)
+setgoal(Mobj *mo, Point *gp, Mobj *block)
{
- int x, y, e;
+ int e;
double Δ, Δ´;
- Node *n1, *n2, *pm;
+ Point p, g;
+ Node *n1, *n2, *gn;
if(mo->o->f & Fair || block == nil){
mo->path.blocked = 0;
return;
}
+ g = *gp;
mo->path.blocked = 1;
- dprint("%M setgoal: moving goal %d,%d in block %#p ", mo, p->x, p->y, block);
- pm = nodemap + p->y * nodemapwidth + p->x;
- pm->x = p->x;
- pm->y = p->y;
+ dprint("%M setgoal: moving goal %P in block %#p ", mo, g, block);
+ gn = map + g.y * mapwidth + g.x;
+ gn->Point = g;
Δ = 0x7ffffff;
- x = block->x;
- y = block->y;
- n1 = nodemap + y * nodemapwidth + x;
- n2 = n1 + (block->o->h - 1) * nodemapwidth;
- for(e=x+block->o->w; x<e; x++, n1++, n2++){
- n1->x = x;
- n1->y = y;
- Δ´ = octdist(pm->Point, n1->Point);
+ p = block->Point;
+ n1 = map + p.y * mapwidth + p.x;
+ n2 = n1 + (block->o->h - 1) * mapwidth;
+ for(e=p.x+block->o->w; p.x<e; p.x++, n1++, n2++){
+ n1->Point = p;
+ Δ´ = octdist(gn->Point, n1->Point);
if(Δ´ < Δ){
Δ = Δ´;
- p->x = x;
- p->y = y;
+ g = p;
}
- n2->x = x;
- n2->y = y + block->o->h - 1;
- Δ´ = octdist(pm->Point, n2->Point);
+ n2->Point = addpt(p, Pt(0, block->o->h-1));
+ Δ´ = octdist(gn->Point, n2->Point);
if(Δ´ < Δ){
Δ = Δ´;
- p->x = x;
- p->y = y + block->o->h - 1;
+ g = n2->Point;
}
}
- x = block->x;
- y = block->y + 1;
- n1 = nodemap + y * nodemapwidth + x;
+ p = addpt(block->Point, Pt(0,1));
+ n1 = map + p.y * mapwidth + p.x;
n2 = n1 + block->o->w - 1;
- for(e=y+block->o->h-2; y<e; y++, n1+=nodemapwidth, n2+=nodemapwidth){
- n1->x = x;
- n1->y = y;
- Δ´ = octdist(pm->Point, n1->Point);
+ for(e=p.y+block->o->h-2; p.y<e; p.y++, n1+=mapwidth, n2+=mapwidth){
+ n1->Point = p;
+ Δ´ = octdist(gn->Point, n1->Point);
if(Δ´ < Δ){
Δ = Δ´;
- p->x = x;
- p->y = y;
+ g = p;
}
- n2->x = x + block->o->w - 1;
- n2->y = y;
- Δ´ = octdist(pm->Point, n2->Point);
+ n2->Point = addpt(p, Pt(block->o->w-1, 0));
+ Δ´ = octdist(gn->Point, n2->Point);
if(Δ´ < Δ){
Δ = Δ´;
- p->x = x + block->o->w - 1;
- p->y = y;
+ g = n2->Point;
}
}
- dprint("to %d,%d\n", p->x, p->y);
+ dprint("to %P\n", g);
+ *gp = g;
}
int
-findpath(Point p, Mobj *mo)
+findpath(Mobj *mo, Point p)
{
Node *a, *b, *n;
- dprint("%M findpath to %P\n", mo, p);
if(eqpt(p, mo->Point)){
werrstr("not moving to itself");
return -1;
}
clearpath();
- a = nodemap + mo->y * nodemapwidth + mo->x;
- a->x = mo->x;
- a->y = mo->y;
- b = nodemap + p.y * nodemapwidth + p.x;
- b->x = p.x;
- b->y = p.y;
+ a = map + mo->y * mapwidth + mo->x;
+ a->Point = mo->Point;
+ b = map + p.y * mapwidth + p.x;
+ b->Point = p;
+ dprint("%M findpath from %P to %P dist %f\n", mo, a->Point, b->Point, octdist(a->Point, b->Point));
if(mo->o->f & Fair){
- directpath(a, b, mo);
+ directpath(mo, a, b);
return 0;
}
markmobj(mo, 0);
- n = a∗(a, b, mo);
+ n = a∗(mo, a, b);
if(n != b){
dprint("%M findpath: goal unreachable\n", mo);
if((n = nearest) == a || n == nil || a->h < n->h){
@@ -621,8 +631,15 @@
markmobj(mo, 1);
return -1;
}
- dprint("%M nearest: %#p %P dist %f\n", mo, n, n->Point, n->h);
- b = nearestnonjump(n, b, mo);
+ dprint("%M findpath: nearest is %#p %P dist %f\n", mo, n, n->Point, n->h);
+ n = nearest;
+ if(n == a){
+ werrstr("a∗: really can't move");
+ markmobj(mo, 1);
+ return -1;
+ }
+ /*
+ b = nearestnonjump(mo, n, b);
if(b == a){
werrstr("a∗: really can't move");
markmobj(mo, 1);
@@ -629,16 +646,16 @@
return -1;
}
clearpath();
- a->x = mo->x;
- a->y = mo->y;
- b->x = (b - nodemap) % nodemapwidth;
- b->y = (b - nodemap) / nodemapwidth;
- if((n = a∗(a, b, mo)) != b){
+ a->Point = mo->Point;
+ b->Point = Pt((b - map) % mapwidth, (b - map) / mapwidth);
+ if((n = a∗(mo, a, b)) != b){
werrstr("bug: failed to find path to nearest non-jump point");
return -1;
}
+ */
}
+ dprint("%M found %#p at %P dist %f\n", mo, n, n->Point, n->h);
markmobj(mo, 1);
- backtrack(n, a, mo);
+ backtrack(mo, n, a);
return 0;
}
--- a/pheap.c
+++ b/pheap.c
@@ -58,6 +58,7 @@
if(p == nil)
return nil;
*queue = mergepairs(p->left);
+ dprint("pop %#p %P g %f sum %f\n", p->n, p->n->Point, p->n->g, p->sum);
return p;
}
@@ -66,6 +67,7 @@
{
p->sum -= Δ;
p->n->g -= Δ;
+ dprint("decrease %#p %P g %f sum %f\n", p->n, p->n->Point, p->n->g, p->sum);
if(p->parent != nil && p->sum < p->parent->sum){
p->parent->left = nil;
p->parent = nil;
@@ -82,5 +84,6 @@
p->n = n;
p->sum = n->h + n->g;
n->p = p;
+ dprint("push %#p %P g %f sum %f\n", p->n, p->n->Point, p->n->g, p->sum);
*queue = mergequeue(p, *queue);
}
--- a/sim.move.c
+++ b/sim.move.c
@@ -4,32 +4,14 @@
#include "dat.h"
#include "fns.h"
-void
-linktomap(Mobj *mo)
-{
- Map *m;
-
- m = map + mo->y / Node2Tile * mapwidth + mo->x / Node2Tile;
- mo->mapl = linkmobj(mo->o->f & Fair ? m->ml.lp : &m->ml, mo, mo->mapl);
-}
-
-static void
-resetcoords(Mobj *mo)
-{
- markmobj(mo, 0);
- mo->subpx = mo->px << Subpxshift;
- mo->subpy = mo->py << Subpxshift;
- markmobj(mo, 1);
-}
-
static double
-facegoal(Point p, Mobj *mo)
+facegoal(Mobj *mo, Point p)
{
int dx, dy;
double vx, vy, d, θ, θ256, Δθ;
- dx = p.x - mo->px;
- dy = p.y - mo->py;
+ dx = p.x - mo->x;
+ dy = p.y - mo->y;
d = sqrt(dx * dx + dy * dy);
if(d == 0.0)
sysfatal("facegoal: %M → %P: moving in place, shouldn't happen", mo, p);
@@ -60,22 +42,21 @@
{
Point p;
- p.x = tgt->px + tgt->o->w * Nodewidth / 2;
- p.y = tgt->py + tgt->o->h * Nodeheight / 2;
- return facegoal(p, mo);
+ p = addpt(tgt->Point, Pt(tgt->o->w / 2, tgt->o->h / 2));
+ return facegoal(mo, p);
}
static void
nextpathnode(Mobj *mo)
{
- resetcoords(mo);
- facegoal(*mo->path.step, mo);
+ snaptomapgrid(mo);
+ facegoal(mo, *mo->path.step);
}
static void
clearpath(Mobj *mo)
{
- resetcoords(mo);
+ snaptomapgrid(mo);
mo->speed = 0.0;
mo->path.step = nil;
clearvec(&mo->path.moves, sizeof *mo->path.step);
@@ -85,7 +66,7 @@
cleanup(Mobj *mo)
{
clearpath(mo);
- mo->path.target = (Point){0,0};
+ mo->path.target = ZP;
mo->path.blocked = 0;
mo->path.dist = 0.0;
mo->path.nerr = 0;
@@ -122,15 +103,13 @@
abortcommands(mo);
}
-/* FIXME: kind of weird to mix up argument order,
- * mo should be first like elsewhere */
static int
-repath(Point p, Mobj *mo)
+repath(Mobj *mo, Point p)
{
clearpath(mo);
mo->path.target = p;
- if(findpath(p, mo) < 0){
- mo->θ = facegoal(p, mo);
+ if(findpath(mo, p) < 0){
+ mo->θ = facegoal(mo, p);
return -1;
}
nextpathnode(mo);
@@ -149,28 +128,26 @@
if(mo->speed > mo->o->speed)
mo->speed = mo->o->speed;
}
+ mo->speed /= 8;
}
static int
trymove(Mobj *mo)
{
- int px, py, sx, sy, Δx, Δy, Δu, Δv, Δrx, Δry, Δpx, Δpy;
- double dx, dy;
- Point p;
+ int Δx, Δy, Δu, Δv, Δrx, Δry, Δpx, Δpy;
+ Point p, from, sub;
markmobj(mo, 0);
- px = mo->px;
- py = mo->py;
- sx = mo->subpx;
- sy = mo->subpy;
- Δu = mo->u * (1 << Subpxshift);
- Δv = mo->v * (1 << Subpxshift);
+ from = mo->Point;
+ sub = mo->sub;
+ Δu = mo->u * (1 << Subshift);
+ Δv = mo->v * (1 << Subshift);
Δx = abs(Δu);
Δy = abs(Δv);
- Δrx = fabs(mo->u * mo->speed) * (1 << Subpxshift);
- Δry = fabs(mo->v * mo->speed) * (1 << Subpxshift);
- Δpx = abs((mo->path.step->x << Subpxshift) - sx);
- Δpy = abs((mo->path.step->y << Subpxshift) - sy);
+ Δrx = fabs(mo->u * mo->speed) * (1 << Subshift);
+ Δry = fabs(mo->v * mo->speed) * (1 << Subshift);
+ Δpx = abs((mo->path.step->x << Subshift) - sub.x);
+ Δpy = abs((mo->path.step->y << Subshift) - sub.y);
if(Δpx < Δrx)
Δrx = Δpx;
if(Δpy < Δry)
@@ -178,20 +155,18 @@
while(Δrx > 0 || Δry > 0){
p = mo->Point;
if(Δrx > 0){
- sx += Δu;
+ sub.x += Δu;
Δrx -= Δx;
if(Δrx < 0)
- sx += mo->u < 0 ? -Δrx : Δrx;
- p.x = (sx >> Subpxshift) + ((sx & Subpxmask) != 0);
- p.x /= Nodewidth;
+ sub.x += mo->u < 0 ? -Δrx : Δrx;
+ p.x = (sub.x >> Subshift) + ((sub.x & Submask) != 0);
}
if(Δry > 0){
- sy += Δv;
+ sub.y += Δv;
Δry -= Δy;
if(Δry < 0)
- sy += mo->v < 0 ? -Δry : Δry;
- p.y = (sy >> Subpxshift) + ((sy & Subpxmask) != 0);
- p.y /= Nodewidth;
+ sub.y += mo->v < 0 ? -Δry : Δry;
+ p.y = (sub.y >> Subshift) + ((sub.y & Submask) != 0);
}
if(isblocked(p, mo->o))
goto end;
@@ -202,30 +177,16 @@
dprint("%M detected corner coasting at %P\n", mo, p);
goto end;
}
- mo->subpx = sx;
- mo->subpy = sy;
- mo->px = sx >> Subpxshift;
- mo->py = sy >> Subpxshift;
- mo->x = mo->px / Nodewidth;
- mo->y = mo->py / Nodeheight;
+ setsubpos(mo, sub);
}
markmobj(mo, 1);
- dx = mo->px - px;
- dx *= dx;
- dy = mo->py - py;
- dy *= dy;
- mo->path.dist -= sqrt(dx + dy) / Nodewidth;
+ mo->path.dist -= eucdist(mo->Point, from);
return 0;
end:
werrstr("trymove: can't move to %P", p);
- mo->subpx = mo->px << Subpxshift;
- mo->subpy = mo->py << Subpxshift;
+ setpos(mo, mo->Point);
markmobj(mo, 1);
- dx = mo->px - px;
- dx *= dx;
- dy = mo->py - py;
- dy *= dy;
- mo->path.dist -= sqrt(dx + dy) / Nodewidth;
+ mo->path.dist -= eucdist(mo->Point, from);
return -1;
}
@@ -272,7 +233,7 @@
static int
nodereached(Mobj *mo)
{
- return mo->px == mo->path.step->x && mo->py == mo->path.step->y;
+ return eqpt(mo->Point, *mo->path.step);
}
static void
@@ -289,9 +250,9 @@
fprint(2, "%M stepmove: bug: infinite loop!\n", mo);
return;
}
- dprint("%M stepmove: failed moving from %d,%d to %P: %r\n",
- mo, mo->px, mo->py, *mo->path.step);
- if(repath(mo->path.target, mo) < 0){
+ dprint("%M stepmove: failed moving from %P to %P: %r\n",
+ mo, mo->Point, *mo->path.step);
+ if(repath(mo, mo->path.target) < 0){
dprint("%M stepmove: failed moving towards target: %r\n", mo);
abortcommands(mo);
return;
@@ -322,7 +283,7 @@
return;
}
dprint("%M stepmove: trying again\n", mo);
- if(mo->path.nerr++ > 1 || repath(mo->path.target, mo) < 0){
+ if(mo->path.nerr++ > 1 || repath(mo, mo->path.target) < 0){
dprint("%M stepmove: still can't reach target: %r\n", mo);
abortmove(mo);
return;
@@ -338,10 +299,10 @@
c = mo->cmds;
c->cleanupfn = cleanup;
goal = c->goal;
- setgoal(&goal, mo, c->target1);
- if(repath(goal, mo) < 0)
+ setgoal(mo, &goal, c->target1);
+ if(repath(mo, goal) < 0)
return -1;
- if(eqpt(goal, mo->Point)){
+ if(eqpt(mo->Point, goal)){
mo->state = OSskymaybe;
return 0;
}
@@ -351,7 +312,7 @@
}
int
-pushmovecommand(Point goal, Mobj *mo, Mobj *target)
+pushmovecommand(Mobj *mo, Point goal, Mobj *target)
{
Command *c;
--- a/sim.return.c
+++ b/sim.return.c
@@ -55,7 +55,7 @@
werrstr("no drops");
return nil;
}
- d = nodemapwidth * nodemapheight;
+ d = mapwidth * mapheight;
for(wp=t->drops.p, we=wp+t->drops.n, wo=nil; wp<we; wp++){
w = *wp;
d´ = octdist(mo->Point, w->Point);
--- a/sim.spawn.c
+++ b/sim.spawn.c
@@ -31,11 +31,11 @@
}
int
-spawnunit(Point p, Obj *o, int team)
+spawnunit(Obj *o, Point p, int team)
{
Mobj *mo;
- if((mo = mapspawn(p, o)) == nil)
+ if((mo = mapspawn(o, p)) == nil)
return -1;
mo->team = team;
mo->θ = frand() * 256;
@@ -46,7 +46,7 @@
}
int
-spawnresource(Point p, Obj *o, int amount)
+spawnresource(Obj *o, Point p, int amount)
{
Mobj *mo;
@@ -54,7 +54,7 @@
werrstr("spawnresource: invalid amount");
return -1;
}
- if((mo = mapspawn(p, o)) == nil)
+ if((mo = mapspawn(o, p)) == nil)
return -1;
mo->team = 0;
mo->amount = amount;