Example #1
0
void PicManagerClear(CArray *pics, CArray *sprites)
{
	for (int i = 0; i < (int)pics->size; i++)
	{
		NamedPic *n = CArrayGet(pics, i);
		CFREE(n->name);
		PicFree(&n->pic);
	}
	CArrayClear(pics);
	for (int i = 0; i < (int)sprites->size; i++)
	{
		NamedSpritesFree(CArrayGet(sprites, i));
	}
	CArrayClear(sprites);
}
Example #2
0
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;
    }
}
Example #3
0
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;
    }
}
Example #4
0
void MapObjectsLoadJSON(CArray *classes, json_t *root)
{
	int version;
	LoadInt(&version, root, "Version");
	if (version > VERSION || version <= 0)
	{
		CASSERT(false, "cannot read map objects file version");
		return;
	}

	json_t *pickupsNode = json_find_first_label(root, "MapObjects")->child;
	for (json_t *child = pickupsNode->child; child; child = child->next)
	{
		MapObject m;
		LoadMapObject(&m, child);
		CArrayPushBack(classes, &m);
	}

	ReloadDestructibles(&gMapObjects);
	// Load blood objects
	CArrayClear(&gMapObjects.Bloods);
	for (int i = 0;; i++)
	{
		char buf[CDOGS_FILENAME_MAX];
		sprintf(buf, "blood%d", i);
		if (StrMapObject(buf) == NULL)
		{
			break;
		}
		char *tmp;
		CSTRDUP(tmp, buf);
		CArrayPushBack(&gMapObjects.Bloods, &tmp);
	}
}
Example #5
0
static void DrawDebris(DrawBuffer *b, struct 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->outOfSight)
			{
				continue;
			}
			CA_FOREACH(ThingId, tid, tile->things)
				const Thing *ti = ThingIdGetThing(tid);
				if (ThingDrawLast(ti))
				{
					CArrayPushBack(&b->displaylist, &ti);
				}
			CA_FOREACH_END()
		}
		DrawBufferSortDisplayList(b);
		CA_FOREACH(const Thing *, tp, b->displaylist)
			DrawThing(b, *tp, offset);
		CA_FOREACH_END()
		tile += X_TILES - b->Size.x;
	}
}
Example #6
0
void BulletClassesClear(CArray *classes)
{
	for (int i = 0; i < (int)classes->size; i++)
	{
		BulletClassFree(CArrayGet(classes, i));
	}
	CArrayClear(classes);
}
Example #7
0
void AmmoClassesClear(CArray *ammo)
{
	CA_FOREACH(Ammo, a, *ammo)
		CFREE(a->Name);
		CFREE(a->Sound);
		CFREE(a->DefaultGun);
	CA_FOREACH_END()
	CArrayClear(ammo);
}
Example #8
0
void SoundClear(CArray *sounds)
{
	for (int i = 0; i < (int)sounds->size; i++)
	{
		SoundData *sound = CArrayGet(sounds, i);
		Mix_FreeChunk(sound->data);
	}
	CArrayClear(sounds);
}
Example #9
0
static void ReloadDestructibles(MapObjects *mo)
{
	CA_FOREACH(char *, s, mo->Destructibles)
		CFREE(*s);
	CA_FOREACH_END()
	CArrayClear(&mo->Destructibles);
	AddDestructibles(mo, &mo->Classes);
	AddDestructibles(mo, &mo->CustomClasses);
}
Example #10
0
void MapObjectsClear(CArray *classes)
{
	for (int i = 0; i < (int)classes->size; i++)
	{
		MapObject *c = CArrayGet(classes, i);
		CFREE(c->Name);
		CArrayTerminate(&c->DestroyGuns);
	}
	CArrayClear(classes);
}
Example #11
0
void WeaponClassesClear(CArray *classes)
{
	for (int i = 0; i < (int)classes->size; i++)
	{
		GunDescription *gd = CArrayGet(classes, i);
		CFREE(gd->name);
		CFREE(gd->Description);
	}
	CArrayClear(classes);
}
Example #12
0
void AmmoClassesClear(CArray *ammo)
{
	for (int i = 0; i < (int)ammo->size; i++)
	{
		Ammo *a = CArrayGet(ammo, i);
		CFREE(a->Name);
		CFREE(a->Sound);
	}
	CArrayClear(ammo);
}
Example #13
0
static void ReloadDestructibles(MapObjects *mo)
{
	for (int i = 0; i < (int)mo->Destructibles.size; i++)
	{
		char **s = CArrayGet(&mo->Destructibles, i);
		CFREE(*s);
	}
	CArrayClear(&mo->Destructibles);
	AddDestructibles(mo, &mo->Classes);
	AddDestructibles(mo, &mo->CustomClasses);
}
Example #14
0
static void DrawWallsAndThings(DrawBuffer *b, struct vec2i offset)
{
	struct 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->Class->Type == TILE_CLASS_WALL)
			{
				DrawLOSPic(tile, tile->Class->Pic, pos, useFog);
			}
			else if (tile->Class->Type == TILE_CLASS_DOOR &&
				tile->ClassAlt && tile->ClassAlt->Pic)
			{
				// Drawing doors
				// Doors may be offset; vertical doors are drawn centered
				// horizontal doors are bottom aligned
				struct vec2i doorPos = pos;
				const Pic *pic = tile->ClassAlt->Pic;
				doorPos.x += (TILE_WIDTH - pic->size.x) / 2;
				if (pic->size.y > 16)
				{
					doorPos.y += TILE_HEIGHT - (pic->size.y % TILE_HEIGHT);
				}
				DrawLOSPic(tile, pic, doorPos, useFog);
			}

			// Draw the items that are in LOS
			if (tile->outOfSight)
			{
				continue;
			}
			CA_FOREACH(ThingId, tid, tile->things)
				const Thing *ti = ThingIdGetThing(tid);
				// Drawn later
				if (ThingDrawLast(ti))
				{
					continue;
				}
				CArrayPushBack(&b->displaylist, &ti);
			CA_FOREACH_END()
		}
		DrawBufferSortDisplayList(b);
		CA_FOREACH(const Thing *, tp, b->displaylist)
			DrawThing(b, *tp, offset);
		CA_FOREACH_END()
		tile += X_TILES - b->Size.x;
	}
}
Example #15
0
void ToTitleScreen(const bool start)
{
	countdownMs = -1;
	ResetMovement();
	MusicSetLoud(false);
	BackgroundsInit(&BG);
	Start = start;
	if (Start)
	{
		sprintf(
			WelcomeMessage,
			"%s to pause\n%s to exit",
			GetPausePrompt(), GetExitGamePrompt());
	}
	else
	{
		// Find out the result of the game
		int maxScore = 0;
		for (int i = 0; i < MAX_PLAYERS; i++)
		{
			if (players[i].Score > maxScore) maxScore = players[i].Score;
		}
		winners = 0;
		for (int i = 0; i < MAX_PLAYERS; i++)
		{
			if (!players[i].Enabled) continue;
			if (players[i].Score == maxScore)
			{
				winnerIndices[winners] = i;
				winners++;
			}
		}
		if (PlayerEnabledCount() == 1)
		{
			sprintf(
				WelcomeMessage,
				"Your score was %d!\n%s to exit",
				maxScore, GetExitGamePrompt());
		}
		else if (winners == 1)
		{
			sprintf(
				WelcomeMessage,
				"Wins with score %d!\n%s to exit",
				maxScore, GetExitGamePrompt());
		}
		else
		{
			sprintf(
				WelcomeMessage,
				"Tied with score %d!\n%s to exit",
				maxScore, GetExitGamePrompt());
		}
		HighScoresAdd(maxScore);
	}

	HighScoreDisplayInit(&HSD);

	CArrayClear(&Particles);
	SpaceReset(&space);
	// Add bottom edge so we don't fall through
	SpaceAddBottomEdge(&space);

	// Initialise players here
	for (int i = 0; i < MAX_PLAYERS; i++)
	{
		PlayerInit(&players[i], i, cpv(
			(i + 1) * FIELD_WIDTH / (MAX_PLAYERS + 1),
			FIELD_HEIGHT * 0.75f));
		playersEnabled[i] = false;
	}

	// Add platforms for players to jump off
	for (int i = 0; i < MAX_PLAYERS; i++)
	{
		BlockInit(
			&blocks[i],
			(i + 1) * FIELD_WIDTH / (MAX_PLAYERS + 1) - BLOCK_WIDTH / 2,
			BLOCK_Y,
			BLOCK_WIDTH);
	}

	GatherInput = TitleScreenGatherInput;
	DoLogic     = TitleScreenDoLogic;
	OutputFrame = TitleScreenOutputFrame;
}
Example #16
0
static void ConvertMission(
	Mission *dest, struct MissionOld *src, const int charCount)
{
	int i;
	CFREE(dest->Title);
	CSTRDUP(dest->Title, src->title);
	CFREE(dest->Description);
	CSTRDUP(dest->Description, src->description);
	dest->Type = MAPTYPE_CLASSIC;
	dest->Size = Vec2iNew(src->mapWidth, src->mapHeight);
	dest->WallStyle = src->wallStyle;
	dest->FloorStyle = src->floorStyle;
	dest->RoomStyle = src->roomStyle;
	dest->ExitStyle = src->exitStyle;
	dest->KeyStyle = src->keyStyle;
	strcpy(dest->DoorStyle, DoorStyleStr(src->doorStyle));
	for (i = 0; i < src->objectiveCount; i++)
	{
		MissionObjective mo;
		memset(&mo, 0, sizeof mo);
		ConvertMissionObjective(&mo, &src->objectives[i]);
		CArrayPushBack(&dest->Objectives, &mo);
	}
	// Note: modulo for compatibility with older, buggy missions
	for (i = 0; i < src->baddieCount; i++)
	{
		int n = src->baddies[i] % charCount;
		CArrayPushBack(&dest->Enemies, &n);
	}
	for (i = 0; i < src->specialCount; i++)
	{
		int n = src->specials[i] % charCount;
		CArrayPushBack(&dest->SpecialChars, &n);
	}
	for (i = 0; i < src->itemCount; i++)
	{
		MapObjectDensity mod;
		mod.M = IntMapObject(src->items[i]);
		mod.Density = src->itemDensity[i];
		CArrayPushBack(&dest->MapObjectDensities, &mod);
	}
	dest->EnemyDensity = src->baddieDensity;
	CArrayClear(&dest->Weapons);
	for (i = 0; i < WEAPON_MAX; i++)
	{
		if ((src->weaponSelection & (1 << i)) || !src->weaponSelection)
		{
			GunDescription *g = CArrayGet(&gGunDescriptions.Guns, i);
			CArrayPushBack(&dest->Weapons, &g);
		}
	}
	strcpy(dest->Song, src->song);
	dest->WallMask = RangeToColor(abs(src->wallRange) % COLORRANGE_COUNT);
	dest->FloorMask = RangeToColor(abs(src->floorRange) % COLORRANGE_COUNT);
	dest->RoomMask = RangeToColor(abs(src->roomRange) % COLORRANGE_COUNT);
	dest->AltMask = RangeToColor(abs(src->altRange) % COLORRANGE_COUNT);

	dest->u.Classic.Walls = src->wallCount;
	dest->u.Classic.WallLength = src->wallLength;
	dest->u.Classic.CorridorWidth = 1;
	dest->u.Classic.Rooms.Count = src->roomCount;
	dest->u.Classic.Rooms.Min = 6;
	dest->u.Classic.Rooms.Max = 10;
	dest->u.Classic.Rooms.Edge = 0;
	dest->u.Classic.Rooms.Walls = 0;
	dest->u.Classic.Squares = src->squareCount;
	dest->u.Classic.Doors.Enabled = 1;
	dest->u.Classic.Doors.Min = dest->u.Classic.Doors.Max = 1;
	dest->u.Classic.Pillars.Count = 0;
}
Example #17
0
void EditorBrushSetHighlightedTiles(EditorBrush *b)
{
	bool useSimpleHighlight = true;
	switch (b->Type)
	{
	case BRUSHTYPE_POINT:	// fallthrough
	case BRUSHTYPE_ROOM_PAINTER:
		useSimpleHighlight = true;
		break;
	case BRUSHTYPE_LINE:
		if (b->IsPainting)
		{
			useSimpleHighlight = 0;
			// highlight a line
			CArrayClear(&b->HighlightedTiles);
			AlgoLineDrawData data;
			data.Draw = EditorBrushHighlightPoint;
			data.data = b;
			BresenhamLineDraw(b->LastPos, b->Pos, &data);
		}
		break;
	case BRUSHTYPE_BOX:	// fallthrough
	case BRUSHTYPE_ROOM:	// fallthrough
	case BRUSHTYPE_SET_EXIT:
		if (b->IsPainting)
		{
			Vec2i v;
			Vec2i d = Vec2iNew(
				b->Pos.x > b->LastPos.x ? 1 : -1,
				b->Pos.y > b->LastPos.y ? 1 : -1);
			useSimpleHighlight = 0;
			CArrayClear(&b->HighlightedTiles);
			for (v.y = b->LastPos.y; v.y != b->Pos.y + d.y; v.y += d.y)
			{
				for (v.x = b->LastPos.x; v.x != b->Pos.x + d.x; v.x += d.x)
				{
					if (v.x == b->LastPos.x || v.x == b->Pos.x ||
						v.y == b->LastPos.y || v.y == b->Pos.y)
					{
						EditorBrushHighlightPoint(b, v);
					}
				}
			}
		}
		break;
	case BRUSHTYPE_BOX_FILLED:
		if (b->IsPainting)
		{
			Vec2i v;
			Vec2i d = Vec2iNew(
				b->Pos.x > b->LastPos.x ? 1 : -1,
				b->Pos.y > b->LastPos.y ? 1 : -1);
			useSimpleHighlight = 0;
			CArrayClear(&b->HighlightedTiles);
			for (v.y = b->LastPos.y; v.y != b->Pos.y + d.y; v.y += d.y)
			{
				for (v.x = b->LastPos.x; v.x != b->Pos.x + d.x; v.x += d.x)
				{
					EditorBrushHighlightPoint(b, v);
				}
			}
		}
		break;
	case BRUSHTYPE_SELECT:
		if (b->IsPainting)
		{
			if (b->IsMoving)
			{
				Vec2i v;
				Vec2i offset = Vec2iNew(
					b->Pos.x - b->DragPos.x, b->Pos.y - b->DragPos.y);
				useSimpleHighlight = 0;
				CArrayClear(&b->HighlightedTiles);
				for (v.y = 0; v.y < b->SelectionSize.y; v.y++)
				{
					for (v.x = 0; v.x < b->SelectionSize.x; v.x++)
					{
						Vec2i vOffset = Vec2iAdd(
							Vec2iAdd(v, b->SelectionStart), offset);
						EditorBrushHighlightPoint(b, vOffset);
					}
				}
			}
			else
			{
				// resize the selection
				Vec2i v;
				Vec2i d = Vec2iNew(
					b->Pos.x > b->LastPos.x ? 1 : -1,
					b->Pos.y > b->LastPos.y ? 1 : -1);
				useSimpleHighlight = 0;
				CArrayClear(&b->HighlightedTiles);
				for (v.y = b->LastPos.y; v.y != b->Pos.y + d.y; v.y += d.y)
				{
					for (v.x = b->LastPos.x; v.x != b->Pos.x + d.x; v.x += d.x)
					{
						EditorBrushHighlightPoint(b, v);
					}
				}
			}
		}
		else
		{
			// If there's a valid selection, draw that instead
			if (b->SelectionSize.x > 0 && b->SelectionSize.y > 0)
			{
				Vec2i v;
				useSimpleHighlight = 0;
				CArrayClear(&b->HighlightedTiles);
				for (v.y = 0; v.y < b->SelectionSize.y; v.y++)
				{
					for (v.x = 0; v.x < b->SelectionSize.x; v.x++)
					{
						Vec2i vOffset = Vec2iAdd(v, b->SelectionStart);
						EditorBrushHighlightPoint(b, vOffset);
					}
				}
			}
		}
	default:
		// do nothing
		break;
	}
	if (useSimpleHighlight)
	{
		// Simple highlight at brush tip based on brush size
		CArrayClear(&b->HighlightedTiles);
		EditorBrushHighlightPoint(b, b->Pos);
	}
}
Example #18
0
EditorResult EditorBrushStopPainting(EditorBrush *b, Mission *m)
{
	EditorResult result = EDITOR_RESULT_NONE;
	if (b->IsPainting)
	{
		switch (b->Type)
		{
		case BRUSHTYPE_LINE:
			EditorBrushPaintLine(b, m);
			result = EDITOR_RESULT_CHANGED;
			break;
		case BRUSHTYPE_BOX:
			EditorBrushPaintBox(b, m, b->PaintType, MAP_UNSET);
			result = EDITOR_RESULT_CHANGED;
			break;
		case BRUSHTYPE_BOX_FILLED:
			EditorBrushPaintBox(b, m, b->PaintType, b->PaintType);
			result = EDITOR_RESULT_CHANGED;
			break;
		case BRUSHTYPE_ROOM:
			EditorBrushPaintBox(b, m, MAP_WALL, MAP_ROOM);
			result = EDITOR_RESULT_CHANGED;
			break;
		case BRUSHTYPE_ROOM_PAINTER:
			// Reload map to update tiles
			result = EDITOR_RESULT_RELOAD;
			break;
		case BRUSHTYPE_SELECT:
			if (b->IsMoving)
			{
				// Move the tiles from the source to the target
				// Need to copy all the tiles to a temp buffer first in case
				// we are moving to an overlapped position
				CArray movedTiles;
				Vec2i v;
				int i;
				int delta;
				CArrayInit(&movedTiles, sizeof(unsigned short));
				// Copy tiles to temp from selection, setting them to MAP_FLOOR
				// in the process
				for (v.y = 0; v.y < b->SelectionSize.y; v.y++)
				{
					for (v.x = 0; v.x < b->SelectionSize.x; v.x++)
					{
						Vec2i vOffset = Vec2iAdd(v, b->SelectionStart);
						int idx = vOffset.y * m->Size.x + vOffset.x;
						unsigned short *tile = CArrayGet(
							&m->u.Static.Tiles, idx);
						CArrayPushBack(&movedTiles, tile);
						*tile = MAP_FLOOR;
					}
				}
				// Move the selection to the new position
				b->SelectionStart.x += b->Pos.x - b->DragPos.x;
				b->SelectionStart.y += b->Pos.y - b->DragPos.y;
				// Copy tiles to the new area, for parts of the new area that
				// are valid
				i = 0;
				for (v.y = 0; v.y < b->SelectionSize.y; v.y++)
				{
					for (v.x = 0; v.x < b->SelectionSize.x; v.x++)
					{
						Vec2i vOffset = Vec2iAdd(v, b->SelectionStart);
						if (vOffset.x >= 0 && vOffset.x < m->Size.x &&
							vOffset.y >= 0 && vOffset.y < m->Size.y)
						{
							int idx = vOffset.y * m->Size.x + vOffset.x;
							unsigned short *tileFrom =
								CArrayGet(&movedTiles, i);
							unsigned short *tileTo = CArrayGet(
								&m->u.Static.Tiles, idx);
							*tileTo = *tileFrom;
							result = EDITOR_RESULT_CHANGED_AND_RELOAD;
						}
						i++;
					}
				}
				// Update the selection to fit within map boundaries
				delta = -b->SelectionStart.x;
				if (delta > 0)
				{
					b->SelectionStart.x += delta;
					b->SelectionSize.x -= delta;
				}
				delta = -b->SelectionStart.y;
				if (delta > 0)
				{
					b->SelectionStart.y += delta;
					b->SelectionSize.y -= delta;
				}
				delta = b->SelectionStart.x + b->SelectionSize.x - m->Size.x;
				if (delta > 0)
				{
					b->SelectionSize.x -= delta;
				}
				delta = b->SelectionStart.y + b->SelectionSize.y - m->Size.y;
				if (delta > 0)
				{
					b->SelectionSize.y -= delta;
				}
				// Check if the selection is still valid; if not, invalidate it
				if (b->SelectionSize.x < 0 || b->SelectionSize.y < 0)
				{
					b->SelectionSize = Vec2iZero();
				}

				b->IsMoving = 0;
			}
			else
			{
				// Record the selection size
				b->SelectionStart = Vec2iMin(b->LastPos, b->Pos);
				b->SelectionSize.x = abs(b->LastPos.x - b->Pos.x) + 1;
				b->SelectionSize.y = abs(b->LastPos.y - b->Pos.y) + 1;
				// Disallow 1x1 selection sizes
				if (b->SelectionSize.x <= 1 && b->SelectionSize.y <= 1)
				{
					b->SelectionSize = Vec2iZero();
				}
			}
			break;
		case BRUSHTYPE_SET_EXIT:
			{
				Vec2i exitStart = Vec2iMin(b->LastPos, b->Pos);
				Vec2i exitEnd = Vec2iMax(b->LastPos, b->Pos);
				// Clamp within map boundaries
				exitStart = Vec2iClamp(
					exitStart, Vec2iZero(), Vec2iMinus(m->Size, Vec2iUnit()));
				exitEnd = Vec2iClamp(
					exitEnd, Vec2iZero(), Vec2iMinus(m->Size, Vec2iUnit()));
				// Check that size is big enough
				Vec2i size =
					Vec2iAdd(Vec2iMinus(exitEnd, exitStart), Vec2iUnit());
				if (size.x >= 3 && size.y >= 3)
				{
					// Check that exit area has changed
					if (!Vec2iEqual(exitStart, m->u.Static.Exit.Start) ||
						!Vec2iEqual(exitEnd, m->u.Static.Exit.End))
					{
						m->u.Static.Exit.Start = exitStart;
						m->u.Static.Exit.End = exitEnd;
						result = EDITOR_RESULT_CHANGED_AND_RELOAD;
					}
				}
			}
			break;
		default:
			// do nothing
			break;
		}
	}
	b->IsPainting = 0;
	CArrayClear(&b->HighlightedTiles);
	return result;
}
Example #19
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;
	}
}
Example #20
0
void CArrayRelease(void *cArray) {
  CArray realArray = (CArray)cArray;
  CArrayClear(realArray);
  free(realArray->elements);
  realArray->capacity = 0;
}
Example #21
0
static void ConvertMission(Mission *dest, struct MissionOld *src)
{
	int i;
	CFREE(dest->Title);
	CSTRDUP(dest->Title, src->title);
	CFREE(dest->Description);
	CSTRDUP(dest->Description, src->description);
	dest->Type = MAPTYPE_CLASSIC;
	dest->Size = Vec2iNew(src->mapWidth, src->mapHeight);
	dest->WallStyle = src->wallStyle;
	dest->FloorStyle = src->floorStyle;
	dest->RoomStyle = src->roomStyle;
	dest->ExitStyle = src->exitStyle;
	dest->KeyStyle = src->keyStyle;
	dest->DoorStyle = src->doorStyle;
	for (i = 0; i < src->objectiveCount; i++)
	{
		MissionObjective mo;
		memset(&mo, 0, sizeof mo);
		ConvertMissionObjective(&mo, &src->objectives[i]);
		CArrayPushBack(&dest->Objectives, &mo);
	}
	for (i = 0; i < src->baddieCount; i++)
	{
		int n = src->baddies[i];
		CArrayPushBack(&dest->Enemies, &n);
	}
	for (i = 0; i < src->specialCount; i++)
	{
		int n = src->specials[i];
		CArrayPushBack(&dest->SpecialChars, &n);
	}
	for (i = 0; i < src->itemCount; i++)
	{
		int n = src->items[i];
		CArrayPushBack(&dest->Items, &n);
	}
	for (i = 0; i < src->itemCount; i++)
	{
		int n = src->itemDensity[i];
		CArrayPushBack(&dest->ItemDensities, &n);
	}
	dest->EnemyDensity = src->baddieDensity;
	CArrayClear(&dest->Weapons);
	for (i = 0; i < WEAPON_MAX; i++)
	{
		if ((src->weaponSelection & (1 << i)) || !src->weaponSelection)
		{
			GunDescription *g = CArrayGet(&gGunDescriptions, i);
			CArrayPushBack(&dest->Weapons, &g);
		}
	}
	strcpy(dest->Song, src->song);
	dest->WallColor = src->wallRange;
	dest->FloorColor = src->floorRange;
	dest->RoomColor = src->roomRange;
	dest->AltColor = src->altRange;

	dest->u.Classic.Walls = src->wallCount;
	dest->u.Classic.WallLength = src->wallLength;
	dest->u.Classic.CorridorWidth = 1;
	dest->u.Classic.Rooms.Count = src->roomCount;
	dest->u.Classic.Rooms.Min = 6;
	dest->u.Classic.Rooms.Max = 10;
	dest->u.Classic.Rooms.Edge = 0;
	dest->u.Classic.Rooms.Walls = 0;
	dest->u.Classic.Squares = src->squareCount;
	dest->u.Classic.Doors.Enabled = 1;
	dest->u.Classic.Doors.Min = dest->u.Classic.Doors.Max = 1;
	dest->u.Classic.Pillars.Count = 0;
}
Example #22
0
static void CreateAddMapItemSubObjs(UIObject *c, void *vData)
{
	const CreateAddMapItemObjsImplData *data = vData;
	const int pageSize = data->GridSize.x * data->GridSize.y;
	// Check if we need to recreate the objs
	// TODO: this is a very heavyweight way to do it
	int count = 0;
	bool allChildrenSame = true;
	for (int i = 0; i < MapObjectsCount(&gMapObjects); i++)
	{
		MapObject *mo = IndexMapObject(i);
		UIObject *o2 =
			UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
		o2->IsDynamicData = true;
		CCALLOC(o2->Data, data->DataSize);
		if (!data->ObjFunc(o2, mo, data->Data))
		{
			UIObjectDestroy(o2);
			continue;
		}
		const int pageIdx = count / pageSize;
		if (pageIdx >= (int)c->Children.size)
		{
			allChildrenSame = false;
			break;
		}
		const UIObject **op = CArrayGet(&c->Children, pageIdx);
		const UIObject **octx = CArrayGet(&(*op)->Children, 0);
		const int idx = count % pageSize;
		if (idx >= (int)(*octx)->Children.size)
		{
			allChildrenSame = false;
			break;
		}
		const UIObject **oc = CArrayGet(&(*octx)->Children, idx);
		if (memcmp(o2->Data, (*oc)->Data, data->DataSize) != 0)
		{
			allChildrenSame = false;
			UIObjectDestroy(o2);
			break;
		}
		count++;
		UIObjectDestroy(o2);
	}
	int cCount = CountAddMapItemSubObjs(c);
	if (cCount == count && allChildrenSame)
	{
		return;
	}

	// Recreate the child UI objects
	c->Highlighted = NULL;
	UIObject **objs = c->Children.data;
	for (int i = 0; i < (int)c->Children.size; i++, objs++)
	{
		UIObjectDestroy(*objs);
	}
	CArrayClear(&c->Children);

	// Create pagination
	int pageNum = 1;
	UIObject *pageLabel = NULL;
	UIObject *page = NULL;
	UIObject *o =
		UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
	o->ChangesData = true;
	const struct vec2i gridStart = svec2i_zero();
	struct vec2i pos = svec2i_zero();
	count = 0;
	for (int i = 0; i < MapObjectsCount(&gMapObjects); i++)
	{
		// Only add normal map objects
		MapObject *mo = IndexMapObject(i);
		UIObject *o2 = UIObjectCopy(o);
		o2->IsDynamicData = true;
		CCALLOC(o2->Data, data->DataSize);
		if (!data->ObjFunc(o2, mo, data->Data))
		{
			UIObjectDestroy(o2);
			continue;
		}
		o2->Pos = pos;
		if (count == 0)
		{
			pageLabel = UIObjectCreate(
				UITYPE_LABEL, 0,
				svec2i((pageNum - 1) * 10, 0), svec2i(10, FontH()));
			char buf[32];
			sprintf(buf, "%d", pageNum);
			UIObjectSetDynamicLabel(pageLabel, buf);
			page = UIObjectCreate(
				UITYPE_CONTEXT_MENU, 0,
				svec2i_add(data->PageOffset, pageLabel->Size), svec2i_zero());
			UIObjectAddChild(pageLabel, page);
			pageNum++;
		}
		UIObjectAddChild(page, o2);
		pos.x += o->Size.x;
		if (((count + 1) % data->GridSize.x) == 0)
		{
			pos.x = gridStart.x;
			pos.y += o->Size.y;
		}
		count++;
		if (count == pageSize)
		{
			count = 0;
			pos = gridStart;
			UIObjectAddChild(c, pageLabel);
		}
	}
	if (pageLabel != NULL)
	{
		UIObjectAddChild(c, pageLabel);
	}

	UIObjectDestroy(o);
}
Example #23
0
void GameEventsClear(CArray *store)
{
	CArrayClear(store);
}