예제 #1
0
void CollideAllItems(
	const TTileItem *item, const Vec2i pos,
	const int mask, const CollisionTeam team, const bool isPVP,
	CollideItemFunc func, void *data)
{
	const Vec2i tv = Vec2iToTile(pos);
	Vec2i dv;
	// Check collisions with all other items on this tile, in all 8 directions
	for (dv.y = -1; dv.y <= 1; dv.y++)
	{
		for (dv.x = -1; dv.x <= 1; dv.x++)
		{
			const Vec2i dtv = Vec2iAdd(tv, dv);
			if (!MapIsTileIn(&gMap, dtv))
			{
				continue;
			}
			CArray *tileThings = &MapGetTile(&gMap, dtv)->things;
			for (int i = 0; i < (int)tileThings->size; i++)
			{
				TTileItem *ti = ThingIdGetTileItem(CArrayGet(tileThings, i));
				// Don't collide if items are on the same team
				if (!CollisionIsOnSameTeam(ti, team, isPVP))
				{
					if (item != ti &&
						(ti->flags & mask) &&
						ItemsCollide(item, ti, pos))
					{
						func(ti, data);
					}
				}
			}
		}
	}
}
예제 #2
0
파일: draw.c 프로젝트: NSYXin/cdogs-sdl
static void DrawWallsAndThings(DrawBuffer *b, Vec2i offset)
{
    Vec2i pos;
    Tile *tile = &b->tiles[0][0];
    pos.y = b->dy + cWallOffset.dy + offset.y;
    for (int y = 0; y < Y_TILES; y++, pos.y += TILE_HEIGHT)
    {
        CArrayClear(&b->displaylist);
        pos.x = b->dx + cWallOffset.dx + offset.x;
        for (int x = 0; x < b->Size.x; x++, tile++, pos.x += TILE_WIDTH)
        {
            if (tile->flags & MAPTILE_IS_WALL)
            {
                if (!(tile->flags & MAPTILE_DELAY_DRAW))
                {
                    DrawWallColumn(y, pos, tile);
                }
            }
            else if (tile->flags & MAPTILE_OFFSET_PIC)
            {
                // Drawing doors
                // Doors may be offset; vertical doors are drawn centered
                // horizontal doors are bottom aligned
                Vec2i doorPos = pos;
                doorPos.x += (TILE_WIDTH - tile->picAlt->pic.size.x) / 2;
                if (tile->picAlt->pic.size.y > 16)
                {
                    doorPos.y +=
                        TILE_HEIGHT - (tile->picAlt->pic.size.y % TILE_HEIGHT);
                }
                BlitMasked(
                    &gGraphicsDevice,
                    &tile->picAlt->pic,
                    doorPos,
                    GetTileLOSMask(tile),
                    0);
            }

            // Draw the items that are in LOS
            if (tile->flags & MAPTILE_OUT_OF_SIGHT)
            {
                continue;
            }
            CA_FOREACH(ThingId, tid, tile->things)
            const TTileItem *ti = ThingIdGetTileItem(tid);
            // Don't draw debris, they are drawn later
            if (TileItemIsDebris(ti))
            {
                continue;
            }
            CArrayPushBack(&b->displaylist, &ti);
            CA_FOREACH_END()
        }
        DrawBufferSortDisplayList(b);
        CA_FOREACH(const TTileItem *, tp, b->displaylist)
        DrawThing(b, *tp, offset);
        CA_FOREACH_END()
        tile += X_TILES - b->Size.x;
    }
}
예제 #3
0
TTileItem *GetItemOnTileInCollision(
	TTileItem *item, Vec2i pos, int mask, CollisionTeam team, int isDogfight)
{
	Vec2i tv = Vec2iToTile(pos);
	Vec2i dv;
	if (!MapIsTileIn(&gMap, tv))
	{
		return NULL;
	}

	// Check collisions with all other items on this tile, in all 8 directions
	for (dv.y = -1; dv.y <= 1; dv.y++)
	{
		for (dv.x = -1; dv.x <= 1; dv.x++)
		{
			CArray *tileThings = &MapGetTile(&gMap, Vec2iAdd(tv, dv))->things;
			for (int i = 0; i < (int)tileThings->size; i++)
			{
				TTileItem *ti = ThingIdGetTileItem(CArrayGet(tileThings, i));
				// Don't collide if items are on the same team
				if (!CollisionIsOnSameTeam(ti, team, isDogfight))
				{
					if (item != ti &&
						(ti->flags & mask) &&
						ItemsCollide(item, ti, pos))
					{
						return ti;
					}
				}
			}
		}
	}

	return NULL;
}
예제 #4
0
파일: draw.c 프로젝트: NSYXin/cdogs-sdl
static void DrawDebris(DrawBuffer *b, Vec2i offset)
{
    Tile *tile = &b->tiles[0][0];
    for (int y = 0; y < Y_TILES; y++)
    {
        CArrayClear(&b->displaylist);
        for (int x = 0; x < b->Size.x; x++, tile++)
        {
            if (tile->flags & MAPTILE_OUT_OF_SIGHT)
            {
                continue;
            }
            CA_FOREACH(ThingId, tid, tile->things)
            const TTileItem *ti = ThingIdGetTileItem(tid);
            if (TileItemIsDebris(ti))
            {
                CArrayPushBack(&b->displaylist, &ti);
            }
            CA_FOREACH_END()
        }
        DrawBufferSortDisplayList(b);
        CA_FOREACH(const TTileItem *, tp, b->displaylist)
        DrawThing(b, *tp, offset);
        CA_FOREACH_END()
        tile += X_TILES - b->Size.x;
    }
}
예제 #5
0
static void DrawObjectNames(DrawBuffer *b, const Vec2i offset)
{
	const Tile *tile = &b->tiles[0][0];
	for (int y = 0; y < Y_TILES; y++)
	{
		for (int x = 0; x < b->Size.x; x++, tile++)
		{
			CA_FOREACH(ThingId, tid, tile->things)
				const TTileItem *ti = ThingIdGetTileItem(tid);
				if (ti->flags & TILEITEM_OBJECTIVE)
				{
					DrawObjectiveName(ti, b, offset);
				}
				else if (ti->kind == KIND_OBJECT)
				{
					const TObject *obj = CArrayGet(&gObjs, ti->id);
					if (obj->Class->Type == MAP_OBJECT_TYPE_PICKUP_SPAWNER)
					{
						DrawSpawnerName(obj, b, offset);
					}
				}
			CA_FOREACH_END()
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #6
0
파일: draw.c 프로젝트: NSYXin/cdogs-sdl
static void DrawObjectiveHighlights(DrawBuffer *b, Vec2i offset)
{
    Tile *tile = &b->tiles[0][0];
    for (int y = 0; y < Y_TILES; y++)
    {
        for (int x = 0; x < b->Size.x; x++, tile++)
        {
            // Draw the items that are in LOS
            CA_FOREACH(ThingId, tid, tile->things)
            TTileItem *ti = ThingIdGetTileItem(tid);
            DrawObjectiveHighlight(ti, tile, b, offset);
            CA_FOREACH_END()
        }
        tile += X_TILES - b->Size.x;
    }
}
예제 #7
0
static void DrawObjectiveCompass(
	GraphicsDevice *g, Vec2i playerPos, Rect2i r, bool showExit)
{
	// Draw exit position
	if (showExit)
	{
		DrawCompassArrow(
			g, r, MapGetExitPos(&gMap), playerPos, colorGreen, "Exit");
	}

	// Draw objectives
	Map *map = &gMap;
	Vec2i tilePos;
	for (tilePos.y = 0; tilePos.y < map->Size.y; tilePos.y++)
	{
		for (tilePos.x = 0; tilePos.x < map->Size.x; tilePos.x++)
		{
			Tile *tile = MapGetTile(map, tilePos);
			for (int i = 0; i < (int)tile->things.size; i++)
			{
				TTileItem *ti =
					ThingIdGetTileItem(CArrayGet(&tile->things, i));
				if (!(ti->flags & TILEITEM_OBJECTIVE))
				{
					continue;
				}
				int objective = ObjectiveFromTileItem(ti->flags);
				MissionObjective *mo =
					CArrayGet(&gMission.missionData->Objectives, objective);
				if (mo->Flags & OBJECTIVE_HIDDEN)
				{
					continue;
				}
				if (!(mo->Flags & OBJECTIVE_POSKNOWN) &&
					!tile->isVisited)
				{
					continue;
				}
				const ObjectiveDef *o =
					CArrayGet(&gMission.Objectives, objective);
				color_t color = o->color;
				DrawCompassArrow(
					g, r, Vec2iNew(ti->x, ti->y), playerPos, color, NULL);
			}
		}
	}
}
예제 #8
0
파일: draw.c 프로젝트: kodephys/cdogs-sdl
static void DrawObjectiveHighlights(DrawBuffer *b, Vec2i offset)
{
	Tile *tile = &b->tiles[0][0];
	for (int y = 0; y < Y_TILES; y++)
	{
		for (int x = 0; x < b->Size.x; x++, tile++)
		{
			// Draw the items that are in LOS
			for (int i = 0; i < (int)tile->things.size; i++)
			{
				TTileItem *ti =
					ThingIdGetTileItem(CArrayGet(&tile->things, i));
				DrawObjectiveHighlight(ti, tile, b, offset);
			}
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #9
0
void DrawChatters(DrawBuffer *b, const Vec2i offset)
{
	const Tile *tile = &b->tiles[0][0];
	for (int y = 0; y < Y_TILES; y++)
	{
		for (int x = 0; x < b->Size.x; x++, tile++)
		{
			CA_FOREACH(ThingId, tid, tile->things)
				const TTileItem *ti = ThingIdGetTileItem(tid);
				if (ti->kind != KIND_CHARACTER)
				{
					continue;
				}
				DrawChatter(ti, b, offset);
			CA_FOREACH_END()
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #10
0
파일: draw.c 프로젝트: NSYXin/cdogs-sdl
static void DrawChatters(DrawBuffer *b, Vec2i offset)
{
    const Tile *tile = &b->tiles[0][0];
    for (int y = 0; y < Y_TILES; y++)
    {
        for (int x = 0; x < b->Size.x; x++, tile++)
        {
            CA_FOREACH(ThingId, tid, tile->things)
            const TTileItem *ti = ThingIdGetTileItem(tid);
            if (ti->getActorPicsFunc == NULL)
            {
                continue;
            }
            DrawChatter(ti, b, offset);
            CA_FOREACH_END()
        }
        tile += X_TILES - b->Size.x;
    }
}
예제 #11
0
void DrawObjectiveHighlights(DrawBuffer *b, const Vec2i offset)
{
	if (!ConfigGetBool(&gConfig, "Graphics.ShowHUD"))
	{
		return;
	}

	Tile *tile = &b->tiles[0][0];
	for (int y = 0; y < Y_TILES; y++)
	{
		for (int x = 0; x < b->Size.x; x++, tile++)
		{
			// Draw the items that are in LOS
			CA_FOREACH(ThingId, tid, tile->things)
				TTileItem *ti = ThingIdGetTileItem(tid);
				DrawObjectiveHighlight(ti, tile, b, offset);
			CA_FOREACH_END()
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #12
0
파일: draw.c 프로젝트: kodephys/cdogs-sdl
static void DrawDebris(DrawBuffer *b, Vec2i offset)
{
	Tile *tile = &b->tiles[0][0];
	for (int y = 0; y < Y_TILES; y++)
	{
		TTileItem *displayList = NULL;
		for (int x = 0; x < b->Size.x; x++, tile++)
		{
			if (tile->flags & MAPTILE_OUT_OF_SIGHT)
			{
				continue;
			}
			for (int i = 0; i < (int)tile->things.size; i++)
			{
				TTileItem *ti =
					ThingIdGetTileItem(CArrayGet(&tile->things, i));
				if (ti->flags & TILEITEM_IS_WRECK)
				{
					AddItemToDisplayList(ti, &displayList);
				}
			}
		}
		for (TTileItem *t = displayList; t; t = t->nextToDisplay)
		{
			Vec2i pos = Vec2iNew(
				t->x - b->xTop + offset.x, t->y - b->yTop + offset.y);
			if (t->getPicFunc)
			{
				Vec2i picOffset;
				const Pic *pic = t->getPicFunc(t->id, &picOffset);
				Blit(&gGraphicsDevice, pic, Vec2iAdd(pos, picOffset));
			}
			else
			{
				(*(t->drawFunc))(pos, &t->drawData);
			}
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #13
0
파일: draw.c 프로젝트: kodephys/cdogs-sdl
static void DrawWallsAndThings(DrawBuffer *b, Vec2i offset)
{
	Vec2i pos;
	Tile *tile = &b->tiles[0][0];
	pos.y = b->dy + cWallOffset.dy + offset.y;
	for (int y = 0; y < Y_TILES; y++, pos.y += TILE_HEIGHT)
	{
		TTileItem *displayList = NULL;
		pos.x = b->dx + cWallOffset.dx + offset.x;
		for (int x = 0; x < b->Size.x; x++, tile++, pos.x += TILE_WIDTH)
		{
			if (tile->flags & MAPTILE_IS_WALL)
			{
				if (!(tile->flags & MAPTILE_DELAY_DRAW))
				{
					DrawWallColumn(y, pos, tile);
				}
			}
			else if (tile->flags & MAPTILE_OFFSET_PIC)
			{
				// Drawing doors
				BlitMasked(
					&gGraphicsDevice,
					&tile->picAlt,
					pos,
					GetTileLOSMask(tile),
					0);
			}
			if (!(tile->flags & MAPTILE_OUT_OF_SIGHT))
			{
				// Draw the items that are in LOS
				for (int i = 0; i < (int)tile->things.size; i++)
				{
					TTileItem *ti =
						ThingIdGetTileItem(CArrayGet(&tile->things, i));
					if (!(ti->flags & TILEITEM_IS_WRECK))
					{
						AddItemToDisplayList(ti, &displayList);
					}
				}
			}
		}
		for (TTileItem *t = displayList; t; t = t->nextToDisplay)
		{
			Vec2i picPos = Vec2iNew(
				t->x - b->xTop + offset.x, t->y - b->yTop + offset.y);
			if (t->getPicFunc)
			{
				Vec2i picOffset;
				const Pic *pic = t->getPicFunc(t->id, &picOffset);
				Blit(&gGraphicsDevice, pic, Vec2iAdd(picPos, picOffset));
			}
			else if (t->getActorPicsFunc)
			{
				ActorPics pics = t->getActorPicsFunc(t->id);
				if (pics.IsDead)
				{
					if (pics.IsDying)
					{
						int pic = pics.OldPics[0];
						if (pic == 0)
						{
							continue;
						}
						if (pics.IsTransparent)
						{
							DrawBTPic(
								&gGraphicsDevice,
								PicManagerGetFromOld(&gPicManager, pic),
								Vec2iAdd(picPos, pics.Pics[0].offset),
								pics.Tint);
						}
						else
						{
							DrawTTPic(
								picPos.x + pics.Pics[0].offset.x,
								picPos.y + pics.Pics[0].offset.y,
								PicManagerGetOldPic(&gPicManager, pic),
								pics.Table);
						}
					}
				}
				else if (pics.IsTransparent)
				{
					for (int i = 0; i < 3; i++)
					{
						Pic *oldPic = PicManagerGetFromOld(
							&gPicManager, pics.OldPics[i]);
						if (oldPic == NULL)
						{
							continue;
						}
						DrawBTPic(
							&gGraphicsDevice,
							oldPic,
							Vec2iAdd(picPos, pics.Pics[i].offset),
							pics.Tint);
					}
				}
				else
				{
					DrawShadow(&gGraphicsDevice, picPos, Vec2iNew(8, 6));
					for (int i = 0; i < 3; i++)
					{
						PicPaletted *oldPic = PicManagerGetOldPic(
							&gPicManager, pics.OldPics[i]);
						if (oldPic == NULL)
						{
							continue;
						}
						BlitOld(
							picPos.x + pics.Pics[i].offset.x,
							picPos.y + pics.Pics[i].offset.y,
							oldPic,
							pics.Table, BLIT_TRANSPARENT);
					}
				}
			}
			else
			{
				(*(t->drawFunc))(picPos, &t->drawData);
			}
		}
		tile += X_TILES - b->Size.x;
	}
}
예제 #14
0
static void DrawWallsAndThings(DrawBuffer *b, Vec2i offset)
{
	Vec2i pos;
	Tile *tile = &b->tiles[0][0];
	pos.y = b->dy + WALL_OFFSET_Y + offset.y;
	const bool useFog = ConfigGetBool(&gConfig, "Game.Fog");
	for (int y = 0; y < Y_TILES; y++, pos.y += TILE_HEIGHT)
	{
		CArrayClear(&b->displaylist);
		pos.x = b->dx + offset.x;
		for (int x = 0; x < b->Size.x; x++, tile++, pos.x += TILE_WIDTH)
		{
			if (tile->flags & MAPTILE_IS_WALL)
			{
				if (!(tile->flags & MAPTILE_DELAY_DRAW))
				{
					DrawWallColumn(y, pos, tile);
				}
			}
			else if (tile->flags & MAPTILE_OFFSET_PIC)
			{
				// Drawing doors
				// Doors may be offset; vertical doors are drawn centered
				// horizontal doors are bottom aligned
				Vec2i doorPos = pos;
				doorPos.x += (TILE_WIDTH - tile->picAlt->pic.size.x) / 2;
				if (tile->picAlt->pic.size.y > 16)
				{
					doorPos.y +=
						TILE_HEIGHT - (tile->picAlt->pic.size.y % TILE_HEIGHT);
				}
				switch (GetTileLOS(tile, useFog))
				{
				case TILE_LOS_NORMAL:
					Blit(&gGraphicsDevice, &tile->picAlt->pic, doorPos);
					break;
				case TILE_LOS_FOG:
					BlitMasked(
						&gGraphicsDevice,
						&tile->picAlt->pic,
						doorPos,
						colorFog,
						false);
					break;
				case TILE_LOS_NONE:
				default:
					// don't draw anything
					break;
				}
			}

			// Draw the items that are in LOS
			if (tile->flags & MAPTILE_OUT_OF_SIGHT)
			{
				continue;
			}
			CA_FOREACH(ThingId, tid, tile->things)
				const TTileItem *ti = ThingIdGetTileItem(tid);
				// Drawn later
				if (TileItemDrawLast(ti))
				{
					continue;
				}
				CArrayPushBack(&b->displaylist, &ti);
			CA_FOREACH_END()
		}
		DrawBufferSortDisplayList(b);
		CA_FOREACH(const TTileItem *, tp, b->displaylist)
			DrawThing(b, *tp, offset);
		CA_FOREACH_END()
		tile += X_TILES - b->Size.x;
	}
}