ref: 74c69f3ae34bd47609e5e3b82038d1a18143fd17
dir: /map.c/
#include <u.h> #include <libc.h> #include <draw.h> #include "dat.h" #include "fns.h" Map *map; int mapwidth, mapheight; Node *nodemap; int nodemapwidth, nodemapheight; static void updatemap(Munit *mu) { Munit *bmu; if(isblocked(mu->x, mu->y, mu->u)){ bmu = unitat(mu->x, mu->y); sysfatal("markmunit: attempt to place %s at %d,%d, non-free block having %s at %d,%d", mu->u->name, mu->x, mu->y, bmu->u->name, bmu->x, bmu->y); } linktomap(mu); markmunit(mu, 1); } static int findspawn(int *nx, int *ny, int ofs, Unit *u, Unit *spawn) { int x, y, minx, miny, maxx, maxy; minx = *nx - (ofs+1) * u->w; miny = *ny - (ofs+1) * u->h; maxx = *nx + spawn->w + ofs * u->w; maxy = *ny + spawn->h + ofs * u->h; for(x=minx+u->w, y=maxy; x<maxx; x++) if(!isblocked(x, y, u)) goto found; for(x=maxx, y=maxy; y>miny; y--) if(!isblocked(x, y, u)) goto found; for(x=maxx, y=miny; x>minx; x--) if(!isblocked(x, y, u)) goto found; for(x=minx, y=miny; y<=maxy; y++) if(!isblocked(x, y, u)) goto found; return -1; found: *nx = x; *ny = y; return 0; } static int getspawn(int *nx, int *ny, Unit *u) { int n, x, y; Map *m; Munitl *ml; Munit *mu; Unit **us; x = *nx; y = *ny; if(u->f & Fbuild){ if(isblocked(x, y, u)){ werrstr("getspawn: building placement at %d,%d blocked", x, y); return -1; } }else{ m = map + y / Node2Tile * mapwidth + x / Node2Tile; for(mu=nil, ml=m->ml.l; ml!=&m->ml; ml=ml->l){ mu = ml->mu; for(us=mu->u->spawn, n=mu->u->nspawn; n>0; n--, us++) if(*us == u) break; if(n > 0) break; } if(ml == &m->ml){ werrstr("getspawn: no spawn unit at %d,%d", x, y); return -1; } for(n=0; n<3; n++) if(findspawn(&x, &y, n, u, mu->u) >= 0) break; if(n == 3){ werrstr("getspawn: no free spot for %s at %d,%d", u->name, x, y); return -1; } } *nx = x; *ny = y; return 0; } Munit * mapspawn(int x, int y, Unit *u) { Munit *mu; if(u->f & Fbuild && (x & Node2Tile-1 || y & Node2Tile-1)){ werrstr("mapspawn: building spawn %d,%d not aligned to tile map", x, y); return nil; } if(getspawn(&x, &y, u) < 0) return nil; mu = emalloc(sizeof *mu); mu->uuid = lrand(); mu->x = x; mu->y = y; mu->px = x * Nodewidth; mu->py = y * Nodeheight; mu->subpx = mu->px << Subpxshift; mu->subpy = mu->py << Subpxshift; mu->u = u; mu->f = u->f; mu->hp = u->hp; mu->θ = frand() * 256; updatemap(mu); return mu; } void initmap(void) { nodemapwidth = mapwidth * Node2Tile; nodemapheight = mapheight * Node2Tile; nodemap = emalloc(nodemapwidth * nodemapheight * sizeof *nodemap); initbmap(); }