コード例 #1
0
static void DrawObjectiveInfo(
	const struct MissionOptions *mo, const int idx, const Vec2i pos)
{
	const MissionObjective *mobj =
		CArrayGet(&mo->missionData->Objectives, idx);
	const ObjectiveDef *o = CArrayGet(&mo->Objectives, idx);
	const CharacterStore *store = &gCampaign.Setting.characters;

	switch (mobj->Type)
	{
	case OBJECTIVE_KILL:
		{
			const Character *cd = CArrayGet(
				&store->OtherChars, CharacterStoreGetSpecialId(store, 0));
			const int i = cd->looks.face;
			TOffsetPic pic;
			pic.picIndex = cHeadPic[i][DIRECTION_DOWN][STATE_IDLE];
			pic.dx = cHeadOffset[i][DIRECTION_DOWN].dx;
			pic.dy = cHeadOffset[i][DIRECTION_DOWN].dy;
			DrawTTPic(
				pos.x + pic.dx, pos.y + pic.dy,
				PicManagerGetOldPic(&gPicManager, pic.picIndex), &cd->table);
		}
		break;
	case OBJECTIVE_RESCUE:
		{
			const Character *cd = CArrayGet(
				&store->OtherChars, CharacterStoreGetPrisonerId(store, 0));
			const int i = cd->looks.face;
			TOffsetPic pic;
			pic.picIndex = cHeadPic[i][DIRECTION_DOWN][STATE_IDLE];
			pic.dx = cHeadOffset[i][DIRECTION_DOWN].dx;
			pic.dy = cHeadOffset[i][DIRECTION_DOWN].dy;
			DrawTTPic(
				pos.x + pic.dx, pos.y + pic.dy,
				PicManagerGetOldPic(&gPicManager, pic.picIndex), &cd->table);
		}
		break;
	case OBJECTIVE_COLLECT:
		{
			const Pic *p = o->pickupClass->Pic;
			Blit(&gGraphicsDevice, p, Vec2iAdd(pos, p->offset));
		}
		break;
	case OBJECTIVE_DESTROY:
		{
			Vec2i picOffset;
			const Pic *p =
				MapObjectGetPic(IntMapObject(mobj->Index), &picOffset, false);
			Blit(&gGraphicsDevice, p, Vec2iAdd(pos, picOffset));
		}
		break;
	case OBJECTIVE_INVESTIGATE:
		// Don't draw
		return;
	default:
		CASSERT(false, "Unknown objective type");
		return;
	}
}
コード例 #2
0
ファイル: draw_actor.c プロジェクト: CliffsDover/cdogs-sdl
void DrawActorHighlight(
	const ActorPics *pics, const Vec2i pos, const color_t color)
{
	// Do not highlight dead, dying or transparent characters
	if (pics->IsDead || pics->IsTransparent)
	{
		return;
	}
	BlitPicHighlight(
		&gGraphicsDevice, pics->Head, Vec2iAdd(pos, pics->HeadOffset), color);
	if (pics->Body != NULL)
	{
		BlitPicHighlight(
			&gGraphicsDevice, pics->Body, Vec2iAdd(pos, pics->BodyOffset),
			color);
	}
	if (pics->Legs != NULL)
	{
		BlitPicHighlight(
			&gGraphicsDevice, pics->Legs, Vec2iAdd(pos, pics->LegsOffset),
			color);
	}
	if (pics->Gun != NULL)
	{
		BlitPicHighlight(
			&gGraphicsDevice, pics->Gun, Vec2iAdd(pos, pics->GunOffset), color);
	}
}
コード例 #3
0
static void MissionBriefingDraw(void *data)
{
	const MissionBriefingData *mData = data;

	GraphicsClear(&gGraphicsDevice);

	// Mission title
	FontStrOpt(mData->Title, Vec2iZero(), mData->TitleOpts);
	// Display password
	FontStrOpt(mData->Password, Vec2iZero(), mData->PasswordOpts);
	// Display description with typewriter effect
	FontStr(mData->TypewriterBuf, mData->DescriptionPos);
	// Display objectives
	CA_FOREACH(
		const Objective, o, mData->MissionOptions->missionData->Objectives)
		// Do not brief optional objectives
		if (o->Required == 0)
		{
			continue;
		}
		Vec2i offset = Vec2iNew(0, _ca_index * mData->ObjectiveHeight);
		FontStr(o->Description, Vec2iAdd(mData->ObjectiveDescPos, offset));
		// Draw the icons slightly offset so that tall icons don't overlap each
		// other
		offset.x = -16 * (_ca_index & 1);
		DrawObjectiveInfo(o, Vec2iAdd(mData->ObjectiveInfoPos, offset));
	CA_FOREACH_END()
}
コード例 #4
0
ファイル: briefing_screens.c プロジェクト: Wuzzy2/cdogs-sdl
static void MissionBriefingDraw(void *data)
{
	const MissionBriefingData *mData = data;

	GraphicsBlitBkg(&gGraphicsDevice);

	// Mission title
	FontStrOpt(mData->Title, Vec2iZero(), mData->TitleOpts);
	// Display password
	FontStrOpt(mData->Password, Vec2iZero(), mData->PasswordOpts);
	// Display description with typewriter effect
	FontStr(mData->TypewriterBuf, mData->DescriptionPos);
	// Display objectives
	for (int i = 0;
		i < (int)mData->MissionOptions->missionData->Objectives.size;
		i++)
	{
		const MissionObjective *o =
			CArrayGet(&mData->MissionOptions->missionData->Objectives, i);
		// Do not brief optional objectives
		if (o->Required == 0)
		{
			continue;
		}
		const Vec2i yInc = Vec2iNew(0, i * mData->ObjectiveHeight);
		FontStr(o->Description, Vec2iAdd(mData->ObjectiveDescPos, yInc));
		DrawObjectiveInfo(
			mData->MissionOptions, i, Vec2iAdd(mData->ObjectiveInfoPos, yInc));
	}
}
コード例 #5
0
// Check collision with a diamond shape
// This means that the bounding box could be in collision, but the bounding
// "radius" is not. The diamond is expressed with a single "radius" - that is,
// the diamond is the same height and width.
// This arrangement is used so that axis movement can slide off corners by
// moving in a diagonal direction.
// E.g. this is not a collision:
//       x
//     x   x
//   x       x
// x           x
//   x       x
//     x   x wwwww
//       x   w
//           w
// Where 'x' denotes the bounding diamond, and 'w' represents a wall corner.
bool IsCollisionDiamond(const Map *map, const Vec2i pos, const Vec2i fullSize)
{
	const Vec2i mapSize =
		Vec2iNew(map->Size.x * TILE_WIDTH, map->Size.y * TILE_HEIGHT);
	const Vec2i size = Vec2iScaleDiv(fullSize, 2);
	if (pos.x - size.x < 0 || pos.x + size.x >= mapSize.x ||
		pos.y - size.y < 0 || pos.y + size.y >= mapSize.y)
	{
		return true;
	}

	// Only support wider-than-taller collision diamonds for now
	CASSERT(size.x >= size.y, "not implemented, taller than wider diamond");
	const double gradient = (double)size.y / size.x;

	// Now we need to check in a diamond pattern that the boundary does not
	// collide
	// Top to right
	for (int i = 0; i < size.x; i++)
	{
		const int y = (int)Round((-size.x + i)* gradient);
		const Vec2i p = Vec2iAdd(pos, Vec2iNew(i, y));
		if (HitWall(p.x, p.y))
		{
			return true;
		}
	}
	// Right to bottom
	for (int i = 0; i < size.x; i++)
	{
		const int y = (int)Round(i * gradient);
		const Vec2i p = Vec2iAdd(pos, Vec2iNew(size.x - i, y));
		if (HitWall(p.x, p.y))
		{
			return true;
		}
	}
	// Bottom to left
	for (int i = 0; i < size.x; i++)
	{
		const int y = (int)Round((size.x - i) * gradient);
		const Vec2i p = Vec2iAdd(pos, Vec2iNew(-i, y));
		if (HitWall(p.x, p.y))
		{
			return true;
		}
	}
	// Left to top
	for (int i = 0; i < size.x; i++)
	{
		const int y = (int)Round(-i * gradient);
		const Vec2i p = Vec2iAdd(pos, Vec2iNew(-size.x + i, y));
		if (HitWall(p.x, p.y))
		{
			return true;
		}
	}
	return false;
}
コード例 #6
0
static void DrawMapItem(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	UNUSED(g);
	const EditorBrush *brush = vData;
	DisplayMapItem(
		Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2)),
		brush->u.MapObject);
}
コード例 #7
0
ファイル: editor_ui_common.c プロジェクト: evktalo/cdogs-sdl
void DrawKey(UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	UNUSED(g);
	EditorBrushAndCampaign *data = vData;
	PicPaletted *keyPic = PicManagerGetOldPic(
		&gPicManager,
		cGeneralPics[gMission.keyPics[data->Brush.ItemIndex]].picIndex);
	pos = Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2));
	DrawTPic(pos.x, pos.y, keyPic);
}
コード例 #8
0
static void DrawPickupSpawner(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	const IndexedEditorBrush *data = vData;
	const MapObject *mo = data->u.MapObject;
	DisplayMapItem(
		Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2)), mo);
	const Pic *pic = mo->u.PickupClass->Pic;
	pos = Vec2iMinus(pos, Vec2iScaleDiv(pic->size, 2));
	Blit(g, pic, Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2)));
}
コード例 #9
0
ファイル: ui_object.c プロジェクト: depoorterp/cdogs-sdl
void UITooltipDraw(GraphicsDevice *device, Vec2i pos, const char *s)
{
	Vec2i bgSize = FontStrSize(s);
	pos = Vec2iAdd(pos, Vec2iNew(10, 10));	// add offset
	DrawRectangle(
		device,
		Vec2iAdd(pos, Vec2iScale(Vec2iUnit(), -TOOLTIP_PADDING)),
		Vec2iAdd(bgSize, Vec2iScale(Vec2iUnit(), 2 * TOOLTIP_PADDING)),
		bgColor,
		0);
	FontStr(s, pos);
}
コード例 #10
0
static void DrawCharacter(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	UNUSED(g);
	EditorBrushAndCampaign *data = vData;
	CharacterStore *store = &data->Campaign->Setting.characters;
	Character *c = CArrayGet(&store->OtherChars, data->Brush.u.ItemIndex);
	DrawCharacterSimple(
		c,
		Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2)),
		DIRECTION_DOWN, false, false);
}
コード例 #11
0
ファイル: ui_object.c プロジェクト: kodephys/cdogs-sdl
void UITooltipDraw(GraphicsDevice *device, Vec2i pos, const char *s)
{
	Vec2i bgSize = TextGetSize(s);
	pos = Vec2iAdd(pos, Vec2iNew(10, 10));	// add offset
	DrawRectangle(
		device,
		Vec2iAdd(pos, Vec2iScale(Vec2iUnit(), -TOOLTIP_PADDING)),
		Vec2iAdd(bgSize, Vec2iScale(Vec2iUnit(), 2 * TOOLTIP_PADDING)),
		bgColor,
		0);
	TextString(&gTextManager, s, device, pos);
}
コード例 #12
0
static void DrawWreck(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	const IndexedEditorBrush *data = vData;
	const char **name =
		CArrayGet(&gMapObjects.Destructibles, data->u.ItemIndex);
	const MapObject *mo = StrMapObject(*name);
	pos = Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2));
	Vec2i offset;
	const Pic *pic = MapObjectGetPic(mo, &offset, true);
	Blit(g, pic, Vec2iAdd(pos, offset));
}
コード例 #13
0
void DrawKey(UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	EditorBrushAndCampaign *data = vData;
	if (data->Brush.ItemIndex == -1)
	{
		// No key; don't draw
		return;
	}
	const Pic *pic =
		KeyPickupClass(gMission.keyStyle, data->Brush.ItemIndex)->Pic;
	pos = Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2));
	pos = Vec2iMinus(pos, Vec2iScaleDiv(pic->size, 2));
	Blit(g, pic, pos);
}
コード例 #14
0
ファイル: draw.c プロジェクト: NSYXin/cdogs-sdl
void DisplayCharacter(
    const Vec2i pos, const Character *c, const bool hilite, const bool showGun)
{
    DrawCharacterSimple(
        c, pos,
        DIRECTION_DOWN, STATE_IDLE, -1, GUNSTATE_READY, &c->table);
    if (hilite)
    {
        FontCh('>', Vec2iAdd(pos, Vec2iNew(-8, -16)));
        if (showGun)
        {
            FontStr(c->Gun->name, Vec2iAdd(pos, Vec2iNew(-8, 8)));
        }
    }
}
コード例 #15
0
ファイル: collision.c プロジェクト: Wuzzy2/cdogs-sdl
bool AreasCollide(
	const Vec2i pos1, const Vec2i pos2, const Vec2i size1, const Vec2i size2)
{
	const Vec2i d = Vec2iNew(abs(pos1.x - pos2.x), abs(pos1.y - pos2.y));
	const Vec2i r = Vec2iAdd(size1, size2);
	return d.x < r.x && d.y < r.y;
}
コード例 #16
0
ファイル: collision.c プロジェクト: kodephys/cdogs-sdl
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;
}
コード例 #17
0
static void DrawObjectiveHighlight(
	TTileItem *ti, Tile *tile, DrawBuffer *b, Vec2i offset)
{
	color_t color;
	if (ti->flags & TILEITEM_OBJECTIVE)
	{
		// Objective
		const int objective = ObjectiveFromTileItem(ti->flags);
		const Objective *o =
			CArrayGet(&gMission.missionData->Objectives, objective);
		if (o->Flags & OBJECTIVE_HIDDEN)
		{
			return;
		}
		if (!(o->Flags & OBJECTIVE_POSKNOWN) &&
			(tile->flags & MAPTILE_OUT_OF_SIGHT))
		{
			return;
		}
		color = o->color;
	}
	else if (ti->kind == KIND_PICKUP)
	{
		// Gun pickup
		const Pickup *p = CArrayGet(&gPickups, ti->id);
		if (!PickupIsManual(p))
		{
			return;
		}
		color = colorDarker;
	}
	else
	{
		return;
	}
	
	const Vec2i pos = Vec2iNew(
		ti->x - b->xTop + offset.x, ti->y - b->yTop + offset.y);
	const int pulsePeriod = ConfigGetInt(&gConfig, "Game.FPS");
	int alphaUnscaled =
		(gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
	if (alphaUnscaled > 255)
	{
		alphaUnscaled = 255 * 2 - alphaUnscaled;
	}
	color.a = (Uint8)alphaUnscaled;
	if (ti->getPicFunc != NULL)
	{
		Vec2i picOffset;
		const Pic *pic = ti->getPicFunc(ti->id, &picOffset);
		BlitPicHighlight(
			&gGraphicsDevice, pic, Vec2iAdd(pos, picOffset), color);
	}
	else if (ti->kind == KIND_CHARACTER)
	{
		TActor *a = CArrayGet(&gActors, ti->id);
		ActorPics pics = GetCharacterPicsFromActor(a);
		DrawActorHighlight(&pics, pos, color);
	}
}
コード例 #18
0
ファイル: weapon_menu.c プロジェクト: ChunHungLiu/cdogs-sdl
static void DisplayEquippedWeapons(
	const menu_t *menu, GraphicsDevice *g,
	const Vec2i pos, const Vec2i size, const void *data)
{
	UNUSED(g);
	const WeaponMenuData *d = data;
	Vec2i weaponsPos;
	Vec2i maxTextSize = FontStrSize("LongestWeaponName");
	UNUSED(menu);
	Vec2i dPos = pos;
	dPos.x -= size.x;	// move to left half of screen
	weaponsPos = Vec2iNew(
		dPos.x + size.x * 3 / 4 - maxTextSize.x / 2,
		CENTER_Y(dPos, size, 0) + 14);
	const PlayerData *p = PlayerDataGetByUID(d->display.PlayerUID);
	if (p->weaponCount == 0)
	{
		FontStr("None selected...", weaponsPos);
	}
	else
	{
		for (int i = 0; i < p->weaponCount; i++)
		{
			FontStr(
				p->weapons[i]->name,
				Vec2iAdd(weaponsPos, Vec2iNew(0, i * FontH())));
		}
	}
}
コード例 #19
0
ファイル: map_classic.c プロジェクト: ChunHungLiu/cdogs-sdl
static int FindWallRun(
	const Map *map, const Vec2i mid, const Vec2i d, const int len)
{
	int run = 0;
	int next = 0;
	bool plus = false;
	// Find the wall run by starting from a midpoint and expanding outwards in
	// both directions, in a series 0, 1, -1, 2, -2...
	for (int i = 0; i < len; i++, run++)
	{
		// Check if this is a wall so we can add a door here
		// Also check if the two tiles aside are not walls

		// Note: we must look for runs

		if (plus)
		{
			next += i;
		}
		else
		{
			next -= i;
		}
		const Vec2i v = Vec2iAdd(mid, Vec2iScale(d, next));
		plus = !plus;

		if (IMapGet(map, v) != MAP_WALL ||
			IMapGet(map, Vec2iNew(v.x + d.y, v.y + d.x)) == MAP_WALL ||
			IMapGet(map, Vec2iNew(v.x - d.y, v.y - d.x)) == MAP_WALL)
		{
			break;
		}
	}
	return run;
}
コード例 #20
0
ファイル: collision.c プロジェクト: Wuzzy2/cdogs-sdl
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);
					}
				}
			}
		}
	}
}
コード例 #21
0
ファイル: weapon.c プロジェクト: depoorterp/cdogs-sdl
void WeaponFire(
	Weapon *w, const direction_e d, const Vec2i pos,
	const int flags, const int player, const int uid)
{
	if (w->state != GUNSTATE_FIRING && w->state != GUNSTATE_RECOIL)
	{
		WeaponSetState(w, GUNSTATE_FIRING);
	}
	if (!w->Gun->CanShoot)
	{
		return;
	}

	const double radians = dir2radians[d];
	const Vec2i muzzleOffset = GunGetMuzzleOffset(w->Gun, d);
	const Vec2i muzzlePosition = Vec2iAdd(pos, muzzleOffset);
	const bool playSound = w->soundLock <= 0;
	GunAddBullets(
		w->Gun, muzzlePosition, w->Gun->MuzzleHeight, radians,
		flags, player, uid, playSound);
	if (playSound)
	{
		w->soundLock = w->Gun->SoundLockLength;
	}

	// Brass shells
	// If we have a reload lead, defer the creation of shells until then
	if (w->Gun->Brass && w->Gun->ReloadLead == 0)
	{
		AddBrass(w->Gun, d, pos);
	}

	w->lock = w->Gun->Lock;
}
コード例 #22
0
int AIHunt(TActor *actor, Vec2i targetPos)
{
    Vec2i fullPos = Vec2iAdd(
                        actor->Pos, GunGetMuzzleOffset(actor->weapon.Gun, actor->direction));
    const int dx = abs(targetPos.x - fullPos.x);
    const int dy = abs(targetPos.y - fullPos.y);

    int cmd = 0;
    if (2 * dx > dy)
    {
        if (fullPos.x < targetPos.x)		cmd |= CMD_RIGHT;
        else if (fullPos.x > targetPos.x)	cmd |= CMD_LEFT;
    }
    if (2 * dy > dx)
    {
        if (fullPos.y < targetPos.y)		cmd |= CMD_DOWN;
        else if (fullPos.y > targetPos.y)	cmd |= CMD_UP;
    }
    // If it's a coward, reverse directions...
    if (actor->flags & FLAGS_RUNS_AWAY)
    {
        cmd = AIReverseDirection(cmd);
    }

    return cmd;
}
コード例 #23
0
static void DrawLives(
	const GraphicsDevice *device, const PlayerData *player, const Vec2i pos,
	const FontAlign hAlign, const FontAlign vAlign)
{
	const int xStep = hAlign == ALIGN_START ? 10 : -10;
	const Vec2i offset = Vec2iNew(5, 20);
	Vec2i drawPos = Vec2iAdd(pos, offset);
	if (hAlign == ALIGN_END)
	{
		const int w = device->cachedConfig.Res.x;
		drawPos.x = w - drawPos.x - offset.x;
	}
	if (vAlign == ALIGN_END)
	{
		const int h = device->cachedConfig.Res.y;
		drawPos.y = h - drawPos.y + offset.y + 5;
	}
	const TOffsetPic head = GetHeadPic(
		BODY_ARMED, DIRECTION_DOWN, player->Char.looks.Face, STATE_IDLE);
	for (int i = 0; i < player->Lives; i++)
	{
		BlitOld(
			drawPos.x + head.dx, drawPos.y + head.dy,
			PicManagerGetOldPic(&gPicManager, head.picIndex),
			&player->Char.table, BLIT_TRANSPARENT);
		drawPos.x += xStep;
	}
}
コード例 #24
0
void DrawLaserSight(
	const ActorPics *pics, const TActor *a, const Vec2i picPos)
{
	// Don't draw if dead or transparent
	if (pics->IsDead || pics->IsTransparent) return;
	// Check config
	const LaserSight ls = ConfigGetEnum(&gConfig, "Game.LaserSight");
	if (ls != LASER_SIGHT_ALL &&
		!(ls == LASER_SIGHT_PLAYERS && a->PlayerUID >= 0))
	{
		return;
	}
	// Draw weapon indicators
	const GunDescription *g = ActorGetGun(a)->Gun;
	Vec2i muzzlePos = Vec2iAdd(
		picPos, Vec2iFull2Real(GunGetMuzzleOffset(g, a->direction)));
	muzzlePos.y -= g->MuzzleHeight / Z_FACTOR;
	const double radians = dir2radians[a->direction] + g->AngleOffset;
	const int range = GunGetRange(g);
	color_t color = colorCyan;
	color.a = 64;
	const double spreadHalf =
		(g->Spread.Count - 1) * g->Spread.Width / 2 + g->Recoil / 2;
	if (spreadHalf > 0)
	{
		DrawLaserSightSingle(muzzlePos, radians - spreadHalf, range, color);
		DrawLaserSightSingle(muzzlePos, radians + spreadHalf, range, color);
	}
	else
	{
		DrawLaserSightSingle(muzzlePos, radians, range, color);
	}
}
コード例 #25
0
void DrawCharacterSimple(
	Character *c, const Vec2i pos, const direction_e d,
	const bool hilite, const bool showGun)
{
	ActorPics pics;
	GetCharacterPics(
		&pics, c, d, STATE_IDLE, NULL, GUNSTATE_READY, false, NULL, NULL, 0);
	DrawActorPics(&pics, pos, d);
	if (hilite)
	{
		FontCh('>', Vec2iAdd(pos, Vec2iNew(-8, -16)));
		if (showGun)
		{
			FontStr(c->Gun->name, Vec2iAdd(pos, Vec2iNew(-8, 8)));
		}
	}
}
コード例 #26
0
ファイル: draw.c プロジェクト: kodephys/cdogs-sdl
static void DrawObjectiveHighlight(
	TTileItem *ti, Tile *tile, DrawBuffer *b, Vec2i offset)
{
	if (!(ti->flags & TILEITEM_OBJECTIVE))
	{
		return;
	}
	int objective = ObjectiveFromTileItem(ti->flags);
	MissionObjective *mo =
		CArrayGet(&gMission.missionData->Objectives, objective);
	if (mo->Flags & OBJECTIVE_HIDDEN)
	{
		return;
	}
	if (!(mo->Flags & OBJECTIVE_POSKNOWN) &&
		(tile->flags & MAPTILE_OUT_OF_SIGHT))
	{
		return;
	}
	Vec2i pos = Vec2iNew(
		ti->x - b->xTop + offset.x, ti->y - b->yTop + offset.y);
	struct Objective *o =
		CArrayGet(&gMission.Objectives, objective);
	color_t color = o->color;
	int pulsePeriod = FPS_FRAMELIMIT;
	int alphaUnscaled =
		(gMission.time % pulsePeriod) * 255 / (pulsePeriod / 2);
	if (alphaUnscaled > 255)
	{
		alphaUnscaled = 255 * 2 - alphaUnscaled;
	}
	color.a = (Uint8)alphaUnscaled;
	if (ti->getPicFunc != NULL)
	{
		Vec2i picOffset;
		const Pic *pic = ti->getPicFunc(ti->id, &picOffset);
		BlitPicHighlight(
			&gGraphicsDevice, pic, Vec2iAdd(pos, picOffset), color);
	}
	else if (ti->getActorPicsFunc != NULL)
	{
		ActorPics pics = ti->getActorPicsFunc(ti->id);
		// Do not highlight dead, dying or transparent characters
		if (!pics.IsDead && !pics.IsTransparent)
		{
			for (int i = 0; i < 3; i++)
			{
				if (PicIsNotNone(&pics.Pics[i]))
				{
					BlitPicHighlight(
						&gGraphicsDevice,
						&pics.Pics[i], pos, color);
				}
			}
		}
	}
}
コード例 #27
0
ファイル: emitter.c プロジェクト: ChunHungLiu/cdogs-sdl
void EmitterStart(
	Emitter *em, const Vec2i fullPos, const int z, const Vec2i vel)
{
	const Vec2i p = Vec2iAdd(fullPos, Vec2iReal2Full(em->offset));

	// TODO: single event multiple particles
	GameEvent e = GameEventNew(GAME_EVENT_ADD_PARTICLE);
	e.u.AddParticle.FullPos = p;
	e.u.AddParticle.Z = z * Z_FACTOR;
	e.u.AddParticle.Class = em->p;
	const int speed = RAND_INT(em->minSpeed, em->maxSpeed);
	const Vec2i baseVel = Vec2iFromPolar(speed, RAND_DOUBLE(0, PI * 2));
	e.u.AddParticle.Vel = Vec2iAdd(vel, baseVel);
	e.u.AddParticle.Angle = RAND_DOUBLE(0, PI * 2);
	e.u.AddParticle.DZ = RAND_INT(em->minDZ, em->maxDZ);
	e.u.AddParticle.Spin = RAND_DOUBLE(em->minRotation, em->maxRotation);
	GameEventsEnqueue(&gGameEvents, e);
}
コード例 #28
0
static void DrawLaserSightSingle(
	const Vec2i from, const double radians, const int range,
	const color_t color)
{
	double x, y;
	GetVectorsForRadians(radians, &x, &y);
	const Vec2i to = Vec2iAdd(
		from, Vec2iNew((int)round(x * range), (int)round(y * range)));
	DrawLine(from, to, color);
}
コード例 #29
0
static void DrawObjective(
	UIObject *o, GraphicsDevice *g, Vec2i pos, void *vData)
{
	UNUSED(g);
	EditorBrushAndCampaign *data = vData;
	Mission *m = CampaignGetCurrentMission(data->Campaign);
	const Objective *obj = CArrayGet(&m->Objectives, data->Brush.u.ItemIndex);
	CharacterStore *store = &data->Campaign->Setting.characters;
	pos = Vec2iAdd(Vec2iAdd(pos, o->Pos), Vec2iScaleDiv(o->Size, 2));
	switch (obj->Type)
	{
	case OBJECTIVE_KILL:
		{
			Character *c = CArrayGet(
				&store->OtherChars,
				CharacterStoreGetSpecialId(store, data->Brush.Index2));
			DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
		}
		break;
	case OBJECTIVE_RESCUE:
		{
			Character *c = CArrayGet(
				&store->OtherChars,
				CharacterStoreGetPrisonerId(store, data->Brush.Index2));
			DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
		}
		break;
	case OBJECTIVE_COLLECT:
		{
			const Pic *p = obj->u.Pickup->Pic;
			pos = Vec2iMinus(pos, Vec2iScaleDiv(p->size, 2));
			Blit(&gGraphicsDevice, p, pos);
		}
		break;
	case OBJECTIVE_DESTROY:
		DisplayMapItem(pos, obj->u.MapObject);
		break;
	default:
		assert(0 && "invalid objective type");
		break;
	}
}
コード例 #30
0
static void DrawWeaponStatus(
	HUD *hud, const TActor *actor, Vec2i pos,
	const FontAlign hAlign, const FontAlign vAlign)
{
	const Weapon *weapon = ActorGetGun(actor);

	// Draw gun icon, and allocate padding to draw the gun icon
	const GunDescription *g = ActorGetGun(actor)->Gun;
	const Vec2i iconPos = Vec2iAligned(
		Vec2iNew(pos.x - 2, pos.y - 2),
		g->Icon->size, hAlign, vAlign, gGraphicsDevice.cachedConfig.Res);
	Blit(&gGraphicsDevice, g->Icon, iconPos);

	// don't draw gauge if not reloading
	if (weapon->lock > 0)
	{
		const Vec2i gaugePos = Vec2iAdd(pos, Vec2iNew(-1 + GUN_ICON_PAD, -1));
		const Vec2i size = Vec2iNew(GAUGE_WIDTH - GUN_ICON_PAD, FontH() + 2);
		const color_t barColor = { 0, 0, 255, 255 };
		const int maxLock = weapon->Gun->Lock;
		int innerWidth;
		color_t backColor = { 128, 128, 128, 255 };
		if (maxLock == 0)
		{
			innerWidth = 0;
		}
		else
		{
			innerWidth = MAX(1, size.x * (maxLock - weapon->lock) / maxLock);
		}
		DrawGauge(
			hud->device, gaugePos, size, innerWidth, barColor, backColor,
			hAlign, vAlign);
	}
	FontOpts opts = FontOptsNew();
	opts.HAlign = hAlign;
	opts.VAlign = vAlign;
	opts.Area = gGraphicsDevice.cachedConfig.Res;
	opts.Pad = Vec2iNew(pos.x + GUN_ICON_PAD, pos.y);
	char buf[128];
	if (ConfigGetBool(&gConfig, "Game.Ammo") && weapon->Gun->AmmoId >= 0)
	{
		// Include ammo counter
		sprintf(buf, "%s %d/%d",
			weapon->Gun->name,
			ActorGunGetAmmo(actor, weapon),
			AmmoGetById(&gAmmo, weapon->Gun->AmmoId)->Max);
	}
	else
	{
		strcpy(buf, weapon->Gun->name);
	}
	FontStrOpt(buf, Vec2iZero(), opts);
}