Beispiel #1
0
static void SaveTemplateDisplayTitle(
	const menu_t *menu, GraphicsDevice *g,
	const Vec2i pos, const Vec2i size, const void *data)
{
	UNUSED(g);
	const PlayerSelectMenuData *d = data;
	char buf[256];

	UNUSED(menu);
	UNUSED(size);

	// Display "Save <template>..." title
	const PlayerData *p = PlayerDataGetByUID(d->display.PlayerUID);
	sprintf(buf, "Save %s...", p->name);
	FontStr(buf, Vec2iAdd(pos, Vec2iNew(0, 0)));
}
Beispiel #2
0
void MapGenerateRandomExitArea(Map *map)
{
	const Tile *t = NULL;
	for (int i = 0; i < 10000 && (t == NULL ||!TileCanWalk(t)); i++)
	{
		map->ExitStart.x = (rand() % (abs(map->Size.x) - EXIT_WIDTH - 1));
		map->ExitEnd.x = map->ExitStart.x + EXIT_WIDTH + 1;
		map->ExitStart.y = (rand() % (abs(map->Size.y) - EXIT_HEIGHT - 1));
		map->ExitEnd.y = map->ExitStart.y + EXIT_HEIGHT + 1;
		// Check that the exit area is walkable
		const Vec2i center = Vec2iNew(
			(map->ExitStart.x + map->ExitEnd.x) / 2,
			(map->ExitStart.y + map->ExitEnd.y) / 2);
		t = MapGetTile(map, center);
	}
}
Beispiel #3
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);
			}
		}
	}
}
Beispiel #4
0
void MapMakeRoom(Map *map, int xOrigin, int yOrigin, int width, int height)
{
	int x, y;
	// Set the perimeter walls and interior
	// If the tile is a room interior already, do not turn it into a wall
	// This is due to overlapping rooms
	for (y = yOrigin; y < yOrigin + height; y++)
	{
		for (x = xOrigin; x < xOrigin + width; x++)
		{
			if (y == yOrigin || y == yOrigin + height - 1 ||
				x == xOrigin || x == xOrigin + width - 1)
			{
				if (IMapGet(map, Vec2iNew(x, y)) == MAP_FLOOR)
				{
					IMapSet(map, Vec2iNew(x, y), MAP_WALL);
				}
			}
			else
			{
				IMapSet(map, Vec2iNew(x, y), MAP_ROOM);
			}
		}
	}
	// Check perimeter again; if there are walls where both sides contain
	// rooms, remove the wall as the rooms have merged
	for (y = yOrigin; y < yOrigin + height; y++)
	{
		for (x = xOrigin; x < xOrigin + width; x++)
		{
			if (y == yOrigin || y == yOrigin + height - 1 ||
				x == xOrigin || x == xOrigin + width - 1)
			{
				if (((IMapGet(map, Vec2iNew(x + 1, y)) & MAP_MASKACCESS) == MAP_ROOM &&
					(IMapGet(map, Vec2iNew(x - 1, y)) & MAP_MASKACCESS) == MAP_ROOM) ||
					((IMapGet(map, Vec2iNew(x, y + 1)) & MAP_MASKACCESS) == MAP_ROOM &&
					(IMapGet(map, Vec2iNew(x, y - 1)) & MAP_MASKACCESS) == MAP_ROOM))
				{
					IMapSet(map, Vec2iNew(x, y), MAP_ROOM);
				}
			}
		}
	}
}
Beispiel #5
0
static void DrawAmmoUpdate(const HUDNumPopup *u, const int flags)
{
	if (u->Amount == 0)
	{
		return;
	}
	const PlayerData *p = PlayerDataGetByUID(u->u.PlayerUID);
	if (!IsPlayerAlive(p)) return;
	const int rowHeight = 1 + FontH();
	const int y = 5 + rowHeight * 4 + LIVES_ROW_EXTRA_Y;
	const TActor *a = ActorGetByUID(p->ActorUID);
	const Weapon *w = ActorGetGun(a);
	char gunNameBuf[256];
	sprintf(gunNameBuf, "%s %%d", w->Gun->name);
	const int ammo = ActorGunGetAmmo(a, w);
	DrawNumUpdate(u, gunNameBuf, ammo, Vec2iNew(5 + GUN_ICON_PAD, y), flags);
}
Beispiel #6
0
static void SetupSpawner(
	MapObject *m, const char *spawnerName, const char *pickupClassName)
{
	memset(m, 0, sizeof *m);
	CSTRDUP(m->Name, spawnerName);
	m->Pic.Type = PICTYPE_NORMAL;
	m->Pic.u.Pic = PicManagerGetPic(&gPicManager, "spawn_pad");
	m->Pic.UseMask = true;
	m->Pic.u1.Mask = colorWhite;
	const Vec2i size = CPicGetSize(&m->Pic);
	m->Offset = Vec2iNew(-size.x / 2, TILE_HEIGHT / 2 - size.y);
	m->Size = TILE_SIZE;
	m->Health = 0;
	m->DrawLast = true;
	m->Type = MAP_OBJECT_TYPE_PICKUP_SPAWNER;
	m->u.PickupClass = StrPickupClass(pickupClassName);
}
Beispiel #7
0
static bool IsPosOK(TActor *actor, Vec2i pos)
{
	Vec2i realPos = Vec2iFull2Real(pos);
	Vec2i size = Vec2iNew(actor->tileItem.w, actor->tileItem.h);
	if (IsCollisionWallOrEdge(&gMap, realPos, size))
	{
		return 0;
	}
	if (GetItemOnTileInCollision(
		&actor->tileItem, realPos, TILEITEM_IMPASSABLE,
		CalcCollisionTeam(1, actor),
		gCampaign.Entry.Mode == CAMPAIGN_MODE_DOGFIGHT))
	{
		return 0;
	}
	return 1;
}
Beispiel #8
0
Vec2i GunGetMuzzleOffset(const GunDescription *desc, const direction_e dir)
{
	if (!GunHasMuzzle(desc))
	{
		return Vec2iZero();
	}
	gunpic_e g = desc->pic;
	CASSERT(g >= 0, "Gun has no pic");
	int body = (int)g < 0 ? BODY_UNARMED : BODY_ARMED;
	Vec2i position = Vec2iNew(
		cGunHandOffset[body][dir].dx +
		cGunPics[g][dir][GUNSTATE_FIRING].dx +
		cMuzzleOffset[g][dir].dx,
		cGunHandOffset[body][dir].dy +
		cGunPics[g][dir][GUNSTATE_FIRING].dy +
		cMuzzleOffset[g][dir].dy + BULLET_Z);
	return Vec2iReal2Full(position);
}
Beispiel #9
0
Vec2i PlacePlayer(
	Map *map, const PlayerData *p, const Vec2i firstPos, const bool pumpEvents)
{
	NetMsgActorAdd aa = NetMsgActorAdd_init_default;
	aa.Id = ActorsGetFreeIndex();
	aa.Health = p->Char.maxHealth;
	aa.PlayerId = p->playerIndex;

	if (IsPVP(gCampaign.Entry.Mode))
	{
		// In a PVP mode, always place players apart
		aa.FullPos = PlaceActor(&gMap);
	}
	else if (gMission.missionData->Type == MAPTYPE_STATIC &&
		!Vec2iIsZero(gMission.missionData->u.Static.Start))
	{
		// place players near the start point
		Vec2i startPoint = Vec2iReal2Full(Vec2iCenterOfTile(
			gMission.missionData->u.Static.Start));
		aa.FullPos = PlaceActorNear(map, startPoint, true);
	}
	else if (gConfig.Interface.Splitscreen == SPLITSCREEN_NEVER &&
		!Vec2iIsZero(firstPos))
	{
		// If never split screen, try to place players near the first player
		aa.FullPos = PlaceActorNear(map, firstPos, true);
	}
	else
	{
		aa.FullPos = PlaceActor(map);
	}

	GameEvent e = GameEventNew(GAME_EVENT_ACTOR_ADD);
	e.u.ActorAdd = aa;
	GameEventsEnqueue(&gGameEvents, e);

	if (pumpEvents)
	{
		// Process the events that actually place the players
		HandleGameEvents(&gGameEvents, NULL, NULL, NULL, &gEventHandlers);
	}

	return Vec2iNew(aa.FullPos.x, aa.FullPos.y);
}
Beispiel #10
0
bool DamageSomething(
	const Vec2i hitVector,
	const int power,
	const int flags,
	const int player,
	const int uid,
	TTileItem *target,
	const special_damage_e special,
	const HitSounds *hitSounds,
	const bool allowFriendlyHitSound)
{
	if (!target)
	{
		return 0;
	}

	const Vec2i pos = Vec2iNew(target->x, target->y);
	switch (target->kind)
	{
	case KIND_CHARACTER:
		return DoDamageCharacter(
			pos, hitVector,
			power, flags, player, uid,
			target, special, hitSounds, allowFriendlyHitSound);

	case KIND_OBJECT:
		DamageObject(power, flags, player, uid, target);
		if (gConfig.Sound.Hits && hitSounds != NULL && power > 0)
		{
			GameEvent es;
			es.Type = GAME_EVENT_SOUND_AT;
			es.u.SoundAt.Sound = hitSounds->Object;
			es.u.SoundAt.Pos = pos;
			GameEventsEnqueue(&gGameEvents, es);
		}
		break;

	case KIND_PARTICLE:
	case KIND_MOBILEOBJECT:
		break;
	}

	return 1;
}
Beispiel #11
0
void UpdateObjects(const int ticks)
{
	for (int i = 0; i < (int)gObjs.size; i++)
	{
		TObject *obj = CArrayGet(&gObjs, i);
		if (!obj->isInUse)
		{
			continue;
		}
		switch (obj->Class->Type)
		{
		case MAP_OBJECT_TYPE_PICKUP_SPAWNER:
			if (gCampaign.IsClient) break;
			// If counter -1, it is inactive i.e. already spawned pickup
			if (obj->counter == -1)
			{
				break;
			}
			obj->counter -= ticks;
			if (obj->counter <= 0)
			{
				// Deactivate spawner by setting counter to -1
				// Spawner reactivated only when ammo taken
				obj->counter = -1;
				GameEvent e = GameEventNew(GAME_EVENT_ADD_PICKUP);
				e.u.AddPickup.UID = PickupsGetNextUID();
				strcpy(
					e.u.AddPickup.PickupClass,
					obj->Class->u.PickupClass->Name);
				e.u.AddPickup.IsRandomSpawned = false;
				e.u.AddPickup.SpawnerUID = obj->uid;
				e.u.AddPickup.TileItemFlags = 0;
				e.u.AddPickup.Pos =
					Vec2i2Net(Vec2iNew(obj->tileItem.x, obj->tileItem.y));
				GameEventsEnqueue(&gGameEvents, e);
			}
			break;
		default:
			// Do nothing
			break;
		}
	}
}
Beispiel #12
0
static void DrawChatter(
	const TTileItem *ti, DrawBuffer *b, const Vec2i offset)
{
	if (!ConfigGetBool(&gConfig, "Graphics.ShowHUD"))
	{
		return;
	}

	const TActor *a = CArrayGet(&gActors, ti->id);
	// Draw character text
	if (strlen(a->Chatter) > 0)
	{
		const Vec2i textPos = Vec2iNew(
			a->tileItem.x - b->xTop + offset.x -
			FontStrW(a->Chatter) / 2,
			a->tileItem.y - b->yTop + offset.y - ACTOR_HEIGHT);
		FontStr(a->Chatter, textPos);
	}
}
Beispiel #13
0
static void DrawAIChatter(const DrawBuffer *b, const Vec2i offset)
{
	Vec2i pos;
	const 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)
	{
		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_OUT_OF_SIGHT))
			{
				// Draw the items that are in LOS
				for (int i = 0; i < (int)tile->things.size; i++)
				{
					const ThingId *tid = CArrayGet(&tile->things, i);
					if (tid->Kind != KIND_CHARACTER)
					{
						continue;
					}
					const TActor *a = CArrayGet(&gActors, tid->Id);
					if (!a->aiContext)
					{
						continue;
					}
					const char *text =
						AIStateGetChatterText(a->aiContext->State);
					Vec2i textPos = Vec2iNew(
						a->tileItem.x - b->xTop + offset.x -
							TextGetStringWidth(text) / 2,
						a->tileItem.y - b->yTop + offset.y - ACTOR_HEIGHT);
					TextString(
						&gTextManager,
						AIStateGetChatterText(a->aiContext->State),
						b->g,
						textPos);
				}
			}
		}
		tile += X_TILES - b->Size.x;
	}
}
Beispiel #14
0
void DrawActorPics(const ActorPics *pics, const Vec2i pos)
{
	if (pics->IsDead)
	{
		if (pics->IsDying)
		{
			DrawDyingBody(&gGraphicsDevice, pics, pos);
		}
	}
	else
	{
		// Draw shadow
		if (!pics->IsTransparent)
		{
			DrawShadow(&gGraphicsDevice, pos, Vec2iNew(8, 6));
		}
		for (int i = 0; i < BODY_PART_COUNT; i++)
		{
			const Pic *pic = pics->OrderedPics[i];
			if (pic == NULL)
			{
				continue;
			}
			const Vec2i drawPos = Vec2iAdd(pos, pics->OrderedOffsets[i]);
			if (pics->IsTransparent)
			{
				BlitBackground(
					&gGraphicsDevice, pic, drawPos, pics->Tint, true);
			}
			else if (pics->Mask != NULL)
			{
				BlitMasked(&gGraphicsDevice, pic, drawPos, *pics->Mask, true);
			}
			else
			{
				BlitCharMultichannel(
					&gGraphicsDevice, pic, drawPos, pics->Colors);
			}
		}
	}
}
void InsertMission(CampaignOptions *co, Mission *mission, int idx)
{
	Mission defaultMission;
	if (mission == NULL)
	{
		MissionInit(&defaultMission);
		defaultMission.Size = Vec2iNew(48, 48);
		// Set some default values for the mission
		defaultMission.u.Classic.CorridorWidth = 1;
		defaultMission.u.Classic.Rooms.Min =
			defaultMission.u.Classic.Rooms.Max = 5;
		defaultMission.u.Classic.Rooms.WallLength = 1;
		defaultMission.u.Classic.Rooms.WallPad = 1;
		defaultMission.u.Classic.Doors.Min =
			defaultMission.u.Classic.Doors.Max = 1;
		defaultMission.u.Classic.Pillars.Min =
			defaultMission.u.Classic.Pillars.Max = 1;
		mission = &defaultMission;
	}
	CArrayInsert(&co->Setting.Missions, idx, mission);
}
Beispiel #16
0
void MenuDisplayItems(MenuSystem *ms)
{
	int d = ms->current->u.normal.displayItems;
	if ((d & MENU_DISPLAY_ITEMS_CREDITS) && ms->creditsDisplayer != NULL)
	{
		ShowCredits(ms->creditsDisplayer);
	}
	if (d & MENU_DISPLAY_ITEMS_AUTHORS)
	{
		PicPaletted *logo = PicManagerGetOldPic(&gPicManager, PIC_LOGO);
		DrawTPic(
			MS_CENTER_X(*ms, logo->w),
			ms->pos.y + ms->size.y / 12,
			logo);
		DrawTextStringSpecial(
			"Version: " CDOGS_SDL_VERSION, TEXT_TOP | TEXT_RIGHT,
			ms->pos,
			ms->size,
			Vec2iNew(20, 20));
	}
}
Beispiel #17
0
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;
	}
}
Beispiel #18
0
static bool TryPlacePickup(HealthPickups *h)
{
	Vec2i size = Vec2iNew(HEALTH_W, HEALTH_H);
	// Attempt to place one in unexplored area
	for (int i = 0; i < 100; i++)
	{
		const Vec2i v = MapGenerateFreePosition(h->map, size);
		if (!Vec2iIsZero(v) && !MapGetTile(h->map, Vec2iToTile(v))->isVisited)
		{
			MapPlaceHealth(v);
			return true;
		}
	}
	// Attempt to place one in out-of-sight area
	for (int i = 0; i < 100; i++)
	{
		const Vec2i v = MapGenerateFreePosition(h->map, size);
		const Vec2i fullpos = Vec2iReal2Full(v);
		const TActor *closestPlayer = AIGetClosestPlayer(fullpos);
		if (!Vec2iIsZero(v) &&
			(!closestPlayer || CHEBYSHEV_DISTANCE(
			fullpos.x, fullpos.y,
			closestPlayer->Pos.x, closestPlayer->Pos.y) >= 256 * 150))
		{
			MapPlaceHealth(v);
			return true;
		}
	}
	// Attempt to place one anyway
	for (int i = 0; i < 100; i++)
	{
		const Vec2i v = MapGenerateFreePosition(h->map, size);
		if (!Vec2iIsZero(v))
		{
			MapPlaceHealth(v);
			return true;
		}
	}
	return false;
}
Beispiel #19
0
static void DisplayGunIcon(
	const menu_t *menu, GraphicsDevice *g, const Vec2i pos, const Vec2i size,
	const void *data)
{
	UNUSED(data);
	if (menu->u.normal.index >= (int)gMission.Weapons.size)
	{
		return;
	}
	// Display a gun icon next to the currently selected weapon
	const GunDescription **gun =
		CArrayGet(&gMission.Weapons, menu->u.normal.index);
	const int menuItems = MIN(
		menu->u.normal.maxItems, (int)menu->u.normal.subMenus.size);
	const int textScroll =
		-menuItems * FontH() / 2 +
		(menu->u.normal.index - menu->u.normal.scroll) * FontH();
	const Vec2i iconPos = Vec2iNew(
		pos.x - (*gun)->Icon->size.x - 4,
		pos.y + size.y / 2 + textScroll + (FontH() - (*gun)->Icon->size.y) / 2);
	Blit(g, (*gun)->Icon, iconPos);
}
Beispiel #20
0
static void MenuDisplayItems(const MenuSystem *ms)
{
	int d = ms->current->u.normal.displayItems;
	if ((d & MENU_DISPLAY_ITEMS_CREDITS) && ms->creditsDisplayer != NULL)
	{
		ShowCredits(ms->creditsDisplayer);
	}
	if (d & MENU_DISPLAY_ITEMS_AUTHORS)
	{
		PicPaletted *logo = PicManagerGetOldPic(&gPicManager, PIC_LOGO);
		DrawTPic(
			MS_CENTER_X(*ms, logo->w),
			ms->pos.y + ms->size.y / 12,
			logo);

		FontOpts opts = FontOptsNew();
		opts.HAlign = ALIGN_END;
		opts.Area = ms->size;
		opts.Pad = Vec2iNew(20, 20);
		FontStrOpt("Version: " CDOGS_SDL_VERSION, ms->pos, opts);
	}
}
Beispiel #21
0
static bool TryAddMapObject(
	Mission *m, const MapObject *mo, const Vec2i pos, CArray *objs)
{
	CASSERT(m->Type == MAPTYPE_STATIC, "invalid map type");
	const unsigned short tile = MissionGetTile(m, pos);

	// Remove any items already there
	TryRemoveMapObjectAt(pos, objs);

	if (MapObjectIsTileOK(
		mo, tile, 1, MissionGetTile(m, Vec2iNew(pos.x, pos.y - 1))))
	{
		// Check if the item already has an entry, and add to its list
		// of positions
		bool hasAdded = false;
		for (int i = 0; i < (int)objs->size; i++)
		{
			MapObjectPositions *mop = CArrayGet(objs, i);
			if (mop->M == mo)
			{
				CArrayPushBack(&mop->Positions, &pos);
				hasAdded = true;
				break;
			}
		}
		// If not, create a new entry
		if (!hasAdded)
		{
			MapObjectPositions mop;
			mop.M = mo;
			CArrayInit(&mop.Positions, sizeof(Vec2i));
			CArrayPushBack(&mop.Positions, &pos);
			CArrayPushBack(objs, &mop);
		}
		return true;
	}
	return false;
}
Beispiel #22
0
static void DogfightScoresDraw(void *data)
{
	UNUSED(data);

	// This will only draw once
	const int w = gGraphicsDevice.cachedConfig.Res.x;
	const int h = gGraphicsDevice.cachedConfig.Res.y;

	GraphicsBlitBkg(&gGraphicsDevice);

	CASSERT(
		gPlayerDatas.size >= 2 && gPlayerDatas.size <= 4,
		"Unimplemented number of players for dogfight");
	for (int i = 0; i < (int)gPlayerDatas.size; i++)
	{
		const Vec2i pos = Vec2iNew(
			w / 4 + (i & 1) * w / 2,
			gPlayerDatas.size == 2 ? h / 2 : h / 4 + (i / 2) * h / 2);
		const PlayerData *p = CArrayGet(&gPlayerDatas, i);
		DisplayCharacterAndName(pos, &p->Char, p->name);
		ShowPlayerScore(pos, p->RoundsWon);
	}
}
Beispiel #23
0
void MenuDisplayPlayer(
	menu_t *menu, GraphicsDevice *g, Vec2i pos, Vec2i size, void *data)
{
	UNUSED(g);
	MenuDisplayPlayerData *d = data;
	Vec2i playerPos;
	char s[22];
	UNUSED(menu);
	pos.x -= size.x;	// move to left half of screen
	playerPos = Vec2iNew(
		pos.x + size.x * 3 / 4 - 12 / 2, CENTER_Y(pos, size, 0));

	if (d->currentMenu && strcmp((*d->currentMenu)->name, "Name") == 0)
	{
		sprintf(s, "%c%s%c", '\020', d->pData->name, '\021');
	}
	else
	{
		strcpy(s, d->pData->name);
	}

	DisplayCharacterAndName(playerPos, d->c, s);
}
Beispiel #24
0
static void AddGraphicsMode(GraphicsDevice *device, const int w, const int h)
{
    // Don't add if mode already exists
    if (FindValidMode(device, w, h) != -1)
    {
        return;
    }

    const int size = w * h;
    int i;
    for (i = 0; i < (int)device->validModes.size; i++)
    {
        // Ordered by actual resolution ascending and scale descending
        const Vec2i *mode = CArrayGet(&device->validModes, i);
        const int actualResolution = mode->x * mode->y;
        if (actualResolution >= size)
        {
            break;
        }
    }
    Vec2i mode = Vec2iNew(w, h);
    CArrayInsert(&device->validModes, i, &mode);
}
static UIObject *CreateAddWreckObjs(Vec2i pos, EditorBrush *brush)
{
	UIObject *o2;
	UIObject *c = UIObjectCreate(UITYPE_CONTEXT_MENU, 0, pos, Vec2iZero());

	UIObject *o = UIObjectCreate(
		UITYPE_CUSTOM, 0,
		Vec2iZero(), Vec2iNew(TILE_WIDTH + 4, TILE_HEIGHT + 4));
	o->ChangeFunc = BrushSetBrushTypeAddWreck;
	o->u.CustomDrawFunc = DrawWreck;
	o->OnFocusFunc = ActivateIndexedEditorBrush;
	o->OnUnfocusFunc = DeactivateIndexedEditorBrush;
	pos = Vec2iZero();
	const int width = 8;
	for (int i = 0; i < (int)gMapObjects.Destructibles.size; i++)
	{
		o2 = UIObjectCopy(o);
		o2->IsDynamicData = 1;
		CMALLOC(o2->Data, sizeof(IndexedEditorBrush));
		((IndexedEditorBrush *)o2->Data)->Brush = brush;
		((IndexedEditorBrush *)o2->Data)->u.ItemIndex = i;
		o2->Pos = pos;
		UIObjectAddChild(c, o2);
		pos.x += o->Size.x;
		if (((i + 1) % width) == 0)
		{
			pos.x = 0;
			pos.y += o->Size.y;
		}
		const char **name = CArrayGet(&gMapObjects.Destructibles, i);
		const MapObject *mo = StrMapObject(*name);
		CSTRDUP(o2->Tooltip, mo->Name);
	}

	UIObjectDestroy(o);
	return c;
}
Beispiel #26
0
void MenuDisplay(MenuSystem *ms)
{
	menu_t *menu = ms->current;
	int i;
	if (menu->type == MENU_TYPE_CUSTOM)
	{
		menu->u.customData.displayFunc(
			ms->graphics, ms->pos, ms->size, menu->u.customData.data);
	}
	else
	{
		MenuDisplayItems(ms);

		if (strlen(menu->u.normal.title) != 0)
		{
			DrawTextStringSpecial(
				menu->u.normal.title,
				TEXT_XCENTER | TEXT_TOP,
				ms->pos,
				ms->size,
				Vec2iNew(0, ms->size.y / 12));
		}

		MenuDisplaySubmenus(ms);
	}
	for (i = 0; i < ms->numCustomDisplayFuncs; i++)
	{
		ms->customDisplayFuncs[i](
			ms->graphics, ms->pos, ms->size, ms->customDisplayDatas[i]);
	}
	if (menu->customDisplayFunc)
	{
		menu->customDisplayFunc(
			ms->graphics, ms->pos, ms->size, menu->customDisplayData);
	}
}
Beispiel #27
0
// Draw a gauge with an outer background and inner level
// +--------------+
// |XXXXXXXX|     |
// +--------------+
static void DrawGauge(
	GraphicsDevice *device,
	Vec2i pos, Vec2i size, int innerWidth,
	color_t barColor, color_t backColor,
	const FontAlign hAlign, const FontAlign vAlign)
{
	Vec2i offset = Vec2iUnit();
	Vec2i barPos = Vec2iAdd(pos, offset);
	Vec2i barSize = Vec2iNew(MAX(0, innerWidth - 2), size.y - 2);
	if (hAlign == ALIGN_END)
	{
		int w = device->cachedConfig.Res.x;
		pos.x = w - pos.x - size.x - offset.x;
		barPos.x = w - barPos.x - barSize.x - offset.x;
	}
	if (vAlign == ALIGN_END)
	{
		int h = device->cachedConfig.Res.y;
		pos.y = h - pos.y - size.y - offset.y;
		barPos.y = h - barPos.y - barSize.y - offset.y;
	}
	DrawRectangle(device, pos, size, backColor, DRAW_FLAG_ROUNDED);
	DrawRectangle(device, barPos, barSize, barColor, 0);
}
Beispiel #28
0
static void DrawThing(DrawBuffer *b, const TTileItem *t, const Vec2i offset)
{
    const Vec2i picPos = Vec2iNew(
                             t->x - b->xTop + offset.x, t->y - b->yTop + offset.y);
#ifdef DEBUG_DRAW_BOUNDS
    Draw_Box(
        picPos.x - t->size.x / 2, picPos.y - t->size.y / 2,
        picPos.x + t->size.x / 2, picPos.y + t->size.y / 2,
        colorGray);
#endif

    if (!Vec2iIsZero(t->ShadowSize))
    {
        DrawShadow(&gGraphicsDevice, picPos, t->ShadowSize);
    }

    if (t->CPicFunc)
    {
        CPicDrawContext c = t->CPicFunc(t->id);
        CPicDraw(b->g, &t->CPic, picPos, &c);
    }
    else if (t->getPicFunc)
    {
        Vec2i picOffset;
        const Pic *pic = t->getPicFunc(t->id, &picOffset);
        Blit(&gGraphicsDevice, pic, Vec2iAdd(picPos, picOffset));
    }
    else if (t->getActorPicsFunc)
    {
        DrawActorPics(t, picPos);
    }
    else
    {
        (*(t->drawFunc))(picPos, &t->drawData);
    }
}
Beispiel #29
0
static Vec2i SeekTowards(
	const Vec2i pos, const Vec2i vel, const double speedMin,
	const Vec2i targetPos, const int seekFactor)
{
	// Compensate for bullet's velocity
	const Vec2i targetVel = Vec2iMinus(Vec2iMinus(targetPos, pos), vel);
	// Don't seek if the coordinates are too big
	if (abs(targetVel.x) > 10000 || abs(targetVel.y) > 10000 ||
		Vec2iIsZero(targetVel))
	{
		return vel;
	}
	const double targetMag = sqrt(
		targetVel.x*targetVel.x + targetVel.y*targetVel.y);
	const double magnitude = MAX(speedMin,
		Vec2iEqual(vel, Vec2iZero()) ? speedMin : sqrt(vel.x*vel.x + vel.y*vel.y));
	const double combinedX =
		vel.x / magnitude * seekFactor + targetVel.x / targetMag;
	const double combinedY =
		vel.y / magnitude * seekFactor + targetVel.y / targetMag;
	return Vec2iNew(
		(int)round(combinedX * magnitude / (seekFactor + 1)),
		(int)round(combinedY * magnitude / (seekFactor + 1)));
}
Beispiel #30
0
static void AddBrass(
	const GunDescription *g, const direction_e d, const Vec2i pos)
{
	CASSERT(g->Brass, "Cannot create brass for no-brass weapon");
	GameEvent e = GameEventNew(GAME_EVENT_ADD_PARTICLE);
	e.u.AddParticle.Class = g->Brass;
	double x, y;
	const double radians = dir2radians[d];
	GetVectorsForRadians(radians, &x, &y);
	const Vec2i ejectionPortOffset = Vec2iReal2Full(Vec2iScale(Vec2iNew(
		(int)round(x), (int)round(y)), 7));
	const Vec2i muzzleOffset = GunGetMuzzleOffset(g, d);
	const Vec2i muzzlePosition = Vec2iAdd(pos, muzzleOffset);
	e.u.AddParticle.FullPos = Vec2iMinus(muzzlePosition, ejectionPortOffset);
	e.u.AddParticle.Z = g->MuzzleHeight;
	e.u.AddParticle.Vel = Vec2iScaleDiv(
		GetFullVectorsForRadians(radians + PI / 2), 3);
	e.u.AddParticle.Vel.x += (rand() % 128) - 64;
	e.u.AddParticle.Vel.y += (rand() % 128) - 64;
	e.u.AddParticle.Angle = RAND_DOUBLE(0, PI * 2);
	e.u.AddParticle.DZ = (rand() % 6) + 6;
	e.u.AddParticle.Spin = RAND_DOUBLE(-0.1, 0.1);
	GameEventsEnqueue(&gGameEvents, e);
}