Esempio n. 1
0
void move_player(player_t* p, room_t* r, uint32_t dir)
{
    // 0 = north, 1 = south, 2 = east, 3 = west
    switch(dir)
    {
        case 0:
            if(!is_solid(&r->map[p->pos.y - 1][p->pos.x]))
                p->pos.y -= 1;
            break;

        case 1:
            if(!is_solid(&r->map[p->pos.y + 1][p->pos.x]))
                p->pos.y += 1;
            break;

        case 2:
            if(!is_solid(&r->map[p->pos.y][p->pos.x + 1]))
                p->pos.x += 1;
            break;

        case 3:
            if(!is_solid(&r->map[p->pos.y][p->pos.x - 1]))
                p->pos.x -= 1;
            break;

        default:
            break;
    }
}
Esempio n. 2
0
/*
 * Wall cleanup.  This function has two purposes: (1) remove walls that
 * are totally surrounded by stone - they are redundant.  (2) correct
 * the types so that they extend and connect to each other.
 */
void
wallification(int x1, int y1, int x2, int y2)
{
    uchar type;
    register int x,y;
    struct rm *lev;

    /* sanity check on incoming variables */
    if (x1<0 || x2>=COLNO || x1>x2 || y1<0 || y2>=ROWNO || y1>y2)
        panic("wallification: bad bounds (%d,%d) to (%d,%d)",x1,y1,x2,y2);

    /* Step 1: change walls surrounded by rock to rock. */
    for(x = x1; x <= x2; x++)
        for(y = y1; y <= y2; y++) {
            lev = &levl[x][y];
            type = lev->typ;
            if (IS_WALL(type) && type != DBWALL) {
                if (is_solid(x-1,y-1) &&
                        is_solid(x-1,y  ) &&
                        is_solid(x-1,y+1) &&
                        is_solid(x,  y-1) &&
                        is_solid(x,  y+1) &&
                        is_solid(x+1,y-1) &&
                        is_solid(x+1,y  ) &&
                        is_solid(x+1,y+1))
                    lev->typ = STONE;
            }
        }

    wall_extends(x1,y1,x2,y2);
}
Esempio n. 3
0
/* Create a turret */
static struct SpecialObj *make_turret(int x,int y,int type) {
    double a;
    struct SpecialObj *turret = malloc(sizeof(struct SpecialObj));
    if(!turret) {
        perror(__func__);
        return NULL;
    }
    turret->gfx = turret_gfx[type==2];
    turret->frames = turret_frames[type==2];
    turret->type = type;
    turret->frame=0;
    turret->x = x;
    turret->y = y;
    turret->owner = -1;
    turret->life = -1;
    turret->timer = 0;
    turret->secret = 0;
    turret->health = 0.20;
    turret->hitship = NULL;
    turret->hitprojectile = turret_hitprojectile;
    if(type==2)
        turret->animate = mturret_animate;
    else
        turret->animate = turret_animate;
    turret->destroy = turret_explode;
    turret->turn = 0.05;

    /* Find a good starting angle */
    if(type<2)
        for(a=0;a<2*M_PI;a++)
            if(!is_solid(x+cos(a)*5,y-sin(a)*5)) {turret->angle = a; break;}

    return turret;
}
Esempio n. 4
0
void Editor::load_layers() {
  layerselect.selected_tilemap = NULL;
  layerselect.layers.clear();
  bool tsel = false;
  for(auto& i : currentsector->gameobjects) {
    auto go = i.get();
    auto mo = dynamic_cast<MovingObject*>(go);
    if ( !mo && go->do_save() ) {
      layerselect.add_layer(go);

      auto tm = dynamic_cast<TileMap*>(go);
      if (tm) {
        if ( !tm->is_solid() || tsel ) {
          tm->editor_active = false;
        } else {
          layerselect.selected_tilemap = tm;
          tm->editor_active = true;
          tsel = true;
        }
      }

    }
  }

  layerselect.sort_layers();
  layerselect.refresh_sector_text();
}
Esempio n. 5
0
static void explosive_merge(ClientRegion *rgn,
                            SpanVector const& me, 
                            SpanVector const& neighbor,
                            MeshAccumulator *ma,
                            int x, int y, 
                            int face)
{
  uint8_t me_type[MAX_Z_DEPTH];
  uint8_t neighbor_type[MAX_Z_DEPTH];
  uint8_t me_flags[MAX_Z_DEPTH];

  int me_z = 0;
  for (SpanVector::const_iterator i=me.begin(); i!=me.end(); ++i) {
    memset(&me_flags[me_z], i->flags, i->height);
    if (is_space(i->type)) {
      memset(&me_type[me_z], 0, i->height);
    } else {
      memset(&me_type[me_z], i->type, i->height);
    }
    me_z += i->height;
  }

  int neighbor_z = 0;
  for (SpanVector::const_iterator i=neighbor.begin(); i!=neighbor.end(); ++i) {
    if (is_solid(i->type)) {
      memset(&neighbor_type[neighbor_z], 1, i->height);
    } else {
      memset(&neighbor_type[neighbor_z], 0, i->height);
    }
    neighbor_z += i->height;
  }
  if (me_z > neighbor_z) {
    memset(&neighbor_type[neighbor_z], 0, me_z - neighbor_z);
  }

  int i=0;
  Slab s;
  s.x = x;
  s.y = y;
  while (i < me_z) {
    if (me_type[i] && !neighbor_type[i]) {
      int i0 = i;
      s.type = me_type[i];
      s.flags = me_flags[i];
      while ((i < me_z)
             && (me_type[i] == s.type) 
             && (me_flags[i] == s.flags)
             && !neighbor_type[i]) {
        i++;
      }
      s.z0 = i0 + rgn->basement;
      s.z1 = i + rgn->basement;
      ma->setup(&s);
      ma->face(face);
    } else {
      i++;
    }
  }
}
Esempio n. 6
0
/* Shoot */
static int critter_shoot(struct Critter *critter, double angle) {
    double x = critter->physics.x + cos(angle)* critter->physics.radius;
    double y = critter->physics.y + sin(angle)* critter->physics.radius;
    if(is_solid(Round(x),Round(y))) return 0;
    Vector mvel = {cos(angle) * 10, sin(angle)*10};
    add_projectile(make_bullet(x,y,addVectors(critter->physics.vel,mvel)));
    return 1;
};
Esempio n. 7
0
btCompoundShape * VoxelFile::get_shape()
{
    if (shape != NULL)
        return shape;
    btCompoundShape * shape = new btCompoundShape(true);
    const float s = 0.5f;
    static btBoxShape * box_shape = new btBoxShape(btVector3(s, s, s));
    btTransform transform;
    for (int x = 0; x < x_size; x++)
    for (int y = 0; y < y_size; y++)
    for (int z = 0; z < z_size; z++) {
        if (!is_solid(x, y, z))
            continue;
        // ignore if not an exposed block
        if (is_solid(x + 1, y, z) &&
            is_solid(x - 1, y, z) &&
            is_solid(x, y + 1, z) &&
            is_solid(x, y - 1, z) &&
            is_solid(x, y, z + 1) &&
            is_solid(x, y, z - 1))
            continue;

        transform.setIdentity();
        transform.setOrigin(btVector3(x + x_offset + 0.5f,
                                      y + y_offset + 0.5f,
                                      z + z_offset + 0.5f));
        shape->addChildShape(transform, box_shape);
    }
    this->shape = shape;
    return shape;
}
Esempio n. 8
0
/* Check if there is any solid terrain inside a rectangle */
static int hitsolid_rect (int x, int y, int w, int h)
{
    int x2 = x+w, y2 = y+h;
    for (; x < x2; x++) {
        for (; y < y2; y++) {
            if (is_solid(x,y))
                return 1;
        }
        y-=h;
    }
    return 0;
}
Esempio n. 9
0
/* Turret animation */
static void turret_animate(struct SpecialObj *turret) {
    double dist;
    float targx=-1,targy=-1;
    int targplr;
    /* Get a target */
    targplr = find_nearest_enemy(turret->x,turret->y,turret->owner, &dist);
    if(dist<160.0) {
        targx = players[targplr].ship->physics.x;
        targy = players[targplr].ship->physics.y;
    } else {
        targplr = find_nearest_pilot(turret->x,turret->y,turret->owner, &dist);
        if(dist<160.0) {
            targx = players[targplr].pilot.walker.physics.x;
            targy = players[targplr].pilot.walker.physics.y;
        }
    }
    /* Aim at target if found */
    if(targx>=0) {
        double a = atan2(turret->y-targy, targx-turret->x);
        double d;
        if(a<0) a = 2*M_PI + a;
        d = shortestRotation(turret->angle,a);
        if(d<-0.2) {
            turret->turn = -0.2;
        } else if(d>0.2) {
            turret->turn = 0.2;
        } else {
            turret->turn = d/2;
            if(turret->timer==0)
                turret_shoot(turret);
        }
    } else {
        /* Restore normal turning speed */
        if(turret->turn<0)
            turret->turn=-0.05;
        else
            turret->turn=0.05;
    }
    /* Rotate turret */
    turret->angle += turret->turn;
    if(is_solid(turret->x+cos(turret->angle)*5,turret->y-sin(turret->angle)*5))
    {
        turret->angle -= turret->turn;
        turret->turn = -turret->turn;
    }
    if(turret->angle>2*M_PI) turret->angle=0;
    else if(turret->angle<0) turret->angle=2*M_PI;
    turret->frame = Round(turret->angle/(2*M_PI)*(turret->frames-1));
}
Esempio n. 10
0
/* If ground!=0, only y+ axis is searched */
static int find_turret_xy (int *tx, int *ty,int ground)
{
    int x[4]={*tx,*tx,*tx,*tx}, y[4]={*ty,*ty,*ty,*ty};
    int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
    int r,loops=0;
    while(++loops<400) {
        for(r=0;r<4;r++) {
            if((ground&&r!=0) || is_water(x[r],y[r])) continue;
            x[r] += dx[r];
            y[r] += dy[r];
            if(is_solid(x[r],y[r])) {
                *tx = x[r];
                *ty = y[r];
                return 1;
            }
        }
    }
    return 0;
}
Esempio n. 11
0
File: level.c Progetto: callaa/luola
/* Pixel perfect collision detection. */
int hit_solid_line (int startx, int starty, int endx, int endy, int *newx,
                     int *newy)
{
    int dx, dy, ax, ay, sx, sy, x, y, d;
    if (startx<0 || endx < 0 || startx >= lev_level.width || endx >= lev_level.width) {
        *newx = endx<0?0:endx>=lev_level.width?lev_level.width-1:endx;
        *newy = endy<0?0:endy>=lev_level.height?lev_level.height-1:endy;
        return TER_INDESTRUCT;
    }
    if (startx<0 || endy < 0 || startx >= lev_level.width || endy >= lev_level.height) {
        *newx = endx<0?0:endx>=lev_level.width?lev_level.width-1:endx;
        *newy = endy<0?0:endy>=lev_level.height?lev_level.height-1:endy;
        return TER_INDESTRUCT;
    }
    dx = endx - startx;
    dy = endy - starty;
    ax = abs (dx) << 1;
    ay = abs (dy) << 1;
    sx = (dx >= 0) ? 1 : -1;
    sy = (dy >= 0) ? 1 : -1;
    x = startx;
    y = starty;
    if (ax > ay) {
        d = ay - (ax >> 1);
        while (x != endx) {
            if (is_solid (x, y)) {
                *newx = x;
                *newy = y;
                return lev_level.solid[x][y];
            }
            if (d > 0 || (d == 0 && sx == 1)) {
                y += sy;
                d -= ax;
            }
            x += sx;
            d += ay;
        }
    } else {
Esempio n. 12
0
 inline unsigned char get_safe(int x, int y, int z)
 {
     if (!is_solid(x, y, z))
         return VOXEL_AIR;
     return get(x, y, z);
 }
Esempio n. 13
0
 inline bool is_surface(int x, int y, int z)
 {
     return !(is_solid(x - 1, y, z) && is_solid(x + 1, y, z) &&
              is_solid(x, y - 1, z) && is_solid(x, y + 1, z) &&
              is_solid(x, y, z - 1) && is_solid(x, y, z + 1));
 }
void
uxa_glyphs(CARD8 op,
	   PicturePtr pSrc,
	   PicturePtr pDst,
	   PictFormatPtr maskFormat,
	   INT16 xSrc, INT16 ySrc,
	   int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
	ScreenPtr screen = pDst->pDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok;

		uxa_picture_prepare_access(pDst, UXA_GLAMOR_ACCESS_RW);
		uxa_picture_prepare_access(pSrc, UXA_GLAMOR_ACCESS_RO);
		ok = glamor_glyphs_nf(op,
				     pSrc, pDst, maskFormat,
				     xSrc, ySrc, nlist, list, glyphs);
		uxa_picture_finish_access(pSrc, UXA_GLAMOR_ACCESS_RO);
		uxa_picture_finish_access(pDst, UXA_GLAMOR_ACCESS_RW);

		if (!ok)
			goto fallback;

		return;
	}

	if (!uxa_screen->info->prepare_composite ||
	    uxa_screen->force_fallback ||
	    !uxa_drawable_is_offscreen(pDst->pDrawable) ||
	    pDst->alphaMap || pSrc->alphaMap ||
	    /* XXX we fail to handle (rare) non-solid sources correctly. */
	    !is_solid(pSrc)) {
fallback:
	    uxa_check_glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
	    return;
	}

	/* basic sanity check */
	if (uxa_screen->info->check_composite &&
	    !uxa_screen->info->check_composite(op, pSrc, NULL, pDst, 0, 0)) {
		goto fallback;
	}

	ValidatePicture(pSrc);
	ValidatePicture(pDst);

	if (!maskFormat) {
		/* If we don't have a mask format but all the glyphs have the same format,
		 * require ComponentAlpha and don't intersect, use the glyph format as mask
		 * format for the full benefits of the glyph cache.
		 */
		if (NeedsComponent(list[0].format->format)) {
			Bool sameFormat = TRUE;
			int i;

			maskFormat = list[0].format;

			for (i = 0; i < nlist; i++) {
				if (maskFormat->format != list[i].format->format) {
					sameFormat = FALSE;
					break;
				}
			}

			if (!sameFormat ||
			    uxa_glyphs_intersect(nlist, list, glyphs))
				maskFormat = NULL;
		}
	}

	if (!maskFormat) {
		if (uxa_glyphs_to_dst(op, pSrc, pDst,
				      xSrc, ySrc,
				      nlist, list, glyphs))
			goto fallback;
	} else {
		if (uxa_glyphs_via_mask(op,
					pSrc, pDst, maskFormat,
					xSrc, ySrc,
					nlist, list, glyphs))
			goto fallback;
	}
}
Esempio n. 15
0
	pathfinding::directed_graph_ptr logical_world::create_directed_graph(bool allow_diagonals) const
	{
		profile::manager pman("logical_world::create_directed_graph");

		std::vector<variant> vertex_list;
		std::map<std::pair<int,int>, int> vlist;

		for(auto p : heightmap_) {
			int x = p.first.first;
			int y = p.second;
			int z = p.first.second;

			if(y < size_y() - 1) {
				if(is_solid(x, y+1, z) == false) {
					vertex_list.push_back(variant_list_from_position(x,y+1,z));
					vlist[std::make_pair(x,z)] = y+1;
				}
			} else {
				vertex_list.push_back(variant_list_from_position(x,y+1,z));
				vlist[std::make_pair(x,z)] = y+1;
			}
		}
	
		pathfinding::graph_edge_list edges;
		for(auto p : vertex_list) {
			const int x = p[0].as_int();
			const int y = p[1].as_int();
			const int z = p[2].as_int();

			std::vector<variant> current_edges;
			
			auto it = vlist.find(std::make_pair(x+1,z));
			if(it != vlist.end() && !is_xedge(x+1) && !is_solid(x+1,it->second,z)) {
				current_edges.push_back(variant_list_from_position(x+1,it->second,z));
			}
			it = vlist.find(std::make_pair(x-1,z));
			if(it != vlist.end() && !is_xedge(x-1) && !is_solid(x-1,it->second,z)) {
				current_edges.push_back(variant_list_from_position(x-1,it->second,z));
			}
			it = vlist.find(std::make_pair(x,z+1));
			if(it != vlist.end() && !is_zedge(z+1) && !is_solid(x,it->second,z+1)) {
				current_edges.push_back(variant_list_from_position(x,it->second,z+1));
			}
			it = vlist.find(std::make_pair(x,z-1));
			if(it != vlist.end() && !is_zedge(z-1) && !is_solid(x,it->second,z-1)) {
				current_edges.push_back(variant_list_from_position(x,it->second,z-1));
			}
			if(allow_diagonals) {
				it = vlist.find(std::make_pair(x+1,z+1));
				if(it != vlist.end() && !is_xedge(x+1) && !is_zedge(z+1) && !is_solid(x+1,it->second,z+1)) {
					current_edges.push_back(variant_list_from_position(x+1,it->second,z+1));
				}
				it = vlist.find(std::make_pair(x+1,z-1));
				if(it != vlist.end() && !is_xedge(x+1) && !is_zedge(z-1) && !is_solid(x+1,it->second,z-1)) {
					current_edges.push_back(variant_list_from_position(x+1,it->second,z-1));
				}
				it = vlist.find(std::make_pair(x-1,z+1));
				if(it != vlist.end() && !is_xedge(x-1) && !is_zedge(z+1) && !is_solid(x-1,it->second,z+1)) {
					current_edges.push_back(variant_list_from_position(x-1,it->second,z+1));
				}
				it = vlist.find(std::make_pair(x-1,z-1));
				if(it != vlist.end() && !is_xedge(x-1) && !is_zedge(z-1) && !is_solid(x-1,it->second,z-1)) {
					current_edges.push_back(variant_list_from_position(x-1,it->second,z-1));
				}
			}
			edges[variant_list_from_position(x, y, z)] = current_edges;
		}
		return pathfinding::directed_graph_ptr(new pathfinding::directed_graph(&vertex_list, &edges));
	}
Esempio n. 16
0
void Emitter::update(Player& owner) {

    float t = timer.GetElapsedTime();
    float dt = t - lastUpdate;
    if (dt < 1.0 / 100.0)
        return;
    // printf("dt = %f\n", dt);
    lastUpdate = t;

    // Delete expired particles
    while (!particles.empty()) {
        const Particle& p = particles.front();
        if (t - p.birthday > p.lifetime || p.dead)
            particles.pop_front();
        else
            break;
    }

    // TODO: Use something nicer than an AABB for this
    std::vector<int> playerIDs;
    std::vector<AABB> playerBoundingAreas;
    const int playerRadius = 32;
    for (auto& kvpair : GAME.world.players) {
        if (kvpair.second.identifier == owner.identifier)
            continue; // Ignore collisions with the player since they happen all the time

        playerBoundingAreas.push_back(AABB(kvpair.second.position.x - playerRadius, kvpair.second.position.y - playerRadius, playerRadius * 2, playerRadius * 2));
        playerIDs.push_back(kvpair.second.identifier);
    }

    // Update particles
    for (Particle& p : particles) {
        if (p.dead) continue;

        Vec2<float> v = p.acceleration * dt + p.velocity;
        Vec2<float> r = p.position + (v + p.velocity) * 0.5 * dt;

        p.velocity = v;
        p.position = r;
        p.age = t - p.birthday;

        // Check for collisions
        Tile tile = worldTileAtPixel(p.position.x, p.position.y);
        // printf("tile at (%d, %d) -> %d -> is solid %d\n", (int)p.position.x, (int)p.position.y, (int)tile, is_solid(tile));
        // printf("  yes it really is %u\n", (unsigned)tile);
        // printf("  %u %u %u %u %u %u %u %u %u\n", (unsigned)Tile::Black, (unsigned)Tile::Dirt, (unsigned)Tile::Grass, (unsigned)Tile::Tarmac, (unsigned)Tile::Pavement, (unsigned)Tile::RoadCenterLine, (unsigned)Tile::BrickWall, (unsigned)Tile::DoorClosedN, (unsigned)Tile::LAST);
        if (is_solid(tile))
            p.dead = true;

        for (int i = 0, playerCount = playerBoundingAreas.size(); i < playerCount; i++) {
            // TODO: Work out the direction from the given player
            int dimension = 0; // owner.z
            if (collides(playerBoundingAreas[i], p.position.x, p.position.y, dimension)) {
                // Kill the particle
                p.dead = true;

                // Damage the player
                playerDamaged(owner.identifier, playerIDs[i], 1);
            }
        }

        // Player collisions
    }

    // Spawn new particles
    int n = 0;
    if (particleClock.GetElapsedTime() + lastSpawned > 1.0 / spawnFrequency) {
        lastSpawned += particleClock.GetElapsedTime();
        particleClock.Reset();

        while (lastSpawned >= 1.0 / spawnFrequency) {
            n++;
            lastSpawned -= 1.0 / spawnFrequency;
        }
    }

    if (n == 0)
        return;

    for (int i = 0; i < n; i++) {
        Particle p(t, 1.0, Vec2<float>(position.x, position.y));

        float theta = normalRealInRange(rng, direction.angle - arc.angle / 2.0, direction.angle + arc.angle / 2.0, 2.0);
        float speed = normalRealInRange(rng, averageSpeed / 2.0, averageSpeed * 3.0 / 2.0, 2.0);

        // printf("Random test: %f\n", normalRealInRange(rng, 10.0, 20.0, 2.0));
        // printf("Theta angle: %f | %f => %f\n", direction.angle, arc.angle, theta);
        // printf("Speed: %f => %f\n", averageSpeed, speed);

        p.velocity = Vec2<float>::FromPolar(speed, Angle(theta));

        // float theta2 = normalRealInRange(rng, 2.0 * theta - direction.angle, direction.angle, 2.0);
        // float accel = normalRealInRange(rng, 2.0 * theta - direction.angle, direction.angle, 2.0);
        p.acceleration = Vec2<float>(0.0, 0.0); //Vec2<float>::FromPolar(- speed, Angle(theta2));

        particles.push_back(p);
    }
}