mirror of
https://github.com/cxong/cdogs-sdl.git
synced 2025-07-23 07:23:01 +02:00
Draw gun in character previews
This commit is contained in:
@@ -819,7 +819,7 @@ static void DrawPlayerSummary(
|
||||
|
||||
DisplayCharacterAndName(
|
||||
svec2i_add(pos, svec2i(size.x / 4, size.y / 2)), &data->Pd->Char,
|
||||
DIRECTION_DOWN, data->Pd->name, colorWhite);
|
||||
DIRECTION_DOWN, data->Pd->name, colorWhite, data->Pd->guns[0]);
|
||||
|
||||
if (data->Pd->survived)
|
||||
{
|
||||
|
@@ -164,7 +164,7 @@ ActorPics GetCharacterPicsFromActor(TActor *a)
|
||||
static const Pic *GetBodyPic(
|
||||
PicManager *pm, const CharSprites *cs, const direction_e dir,
|
||||
const ActorAnimation anim, const int frame, const int numBarrels,
|
||||
const CharColors *colors);
|
||||
const int grips, const CharColors *colors);
|
||||
static const Pic *GetLegsPic(
|
||||
PicManager *pm, const CharSprites *cs, const direction_e dir,
|
||||
const ActorAnimation anim, const int frame, const CharColors *colors);
|
||||
@@ -240,6 +240,7 @@ ActorPics GetCharacterPics(
|
||||
break;
|
||||
}
|
||||
}
|
||||
const int grips = gun == NULL ? 0 : gun->Grips;
|
||||
pics.Head = GetHeadPic(c->Class, headDir, grimace, colors);
|
||||
pics.HeadOffset = GetActorDrawOffset(
|
||||
pics.Head, BODY_PART_HEAD, c->Class->Sprites, anim, frame, dir,
|
||||
@@ -269,7 +270,7 @@ ActorPics GetCharacterPics(
|
||||
|
||||
// Body
|
||||
pics.Body = GetBodyPic(
|
||||
&gPicManager, c->Class->Sprites, dir, anim, frame, numBarrels, colors);
|
||||
&gPicManager, c->Class->Sprites, dir, anim, frame, numBarrels, grips, colors);
|
||||
pics.BodyOffset = GetActorDrawOffset(
|
||||
pics.Body, BODY_PART_BODY, c->Class->Sprites, anim, frame, dir,
|
||||
GUNSTATE_READY);
|
||||
@@ -480,7 +481,7 @@ const Pic *GetHairPic(
|
||||
static const Pic *GetBodyPic(
|
||||
PicManager *pm, const CharSprites *cs, const direction_e dir,
|
||||
const ActorAnimation anim, const int frame, const int numBarrels,
|
||||
const CharColors *colors)
|
||||
const int grips, const CharColors *colors)
|
||||
{
|
||||
const int stride = anim == ACTORANIMATION_WALKING ? 8 : 1;
|
||||
const int col = frame % stride;
|
||||
@@ -488,13 +489,10 @@ static const Pic *GetBodyPic(
|
||||
const int idx = col + row * stride;
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
CASSERT(numBarrels <= 2, "up to 2 barrels supported");
|
||||
const char *upperPose = "";
|
||||
const NamedSprites *ns = NULL;
|
||||
if (numBarrels == 1)
|
||||
{
|
||||
upperPose = "_handgun";
|
||||
}
|
||||
else if (numBarrels == 2)
|
||||
const char *upperPose = "_handgun";
|
||||
// TODO: 2 grip firing pic
|
||||
if (numBarrels == 2 || grips == 2)
|
||||
{
|
||||
upperPose = "_dualgun";
|
||||
}
|
||||
@@ -507,7 +505,7 @@ static const Pic *GetBodyPic(
|
||||
// Get or generate masked sprites
|
||||
ns = PicManagerGetCharSprites(pm, buf, colors);
|
||||
// TODO: provide dualgun sprites for all body types
|
||||
if (ns == NULL && numBarrels == 2)
|
||||
if (ns == NULL && strcmp(upperPose, "_dualgun") == 0)
|
||||
{
|
||||
upperPose = "_handgun";
|
||||
continue;
|
||||
@@ -552,11 +550,11 @@ static const Pic *GetDeathPic(PicManager *pm, const int frame)
|
||||
|
||||
void DrawCharacterSimple(
|
||||
const Character *c, const struct vec2i pos, const direction_e d,
|
||||
const bool hilite, const bool showGun)
|
||||
const bool hilite, const bool showGun, const WeaponClass *gun)
|
||||
{
|
||||
const gunstate_e barrelStates[MAX_BARRELS] = { GUNSTATE_READY, GUNSTATE_READY };
|
||||
ActorPics pics = GetCharacterPics(
|
||||
c, d, d, ACTORANIMATION_IDLE, 0, NULL, barrelStates, false,
|
||||
c, d, d, ACTORANIMATION_IDLE, 0, gun, barrelStates, false,
|
||||
colorBlack, NULL, NULL, 0);
|
||||
DrawActorPics(&pics, pos, Rect2iZero());
|
||||
if (hilite)
|
||||
|
@@ -77,7 +77,7 @@ typedef struct
|
||||
|
||||
void DrawCharacterSimple(
|
||||
const Character *c, const struct vec2i pos, const direction_e d,
|
||||
const bool hilite, const bool showGun);
|
||||
const bool hilite, const bool showGun, const WeaponClass *gun);
|
||||
void DrawHead(
|
||||
SDL_Renderer *renderer, const Character *c, const direction_e dir,
|
||||
const struct vec2i pos);
|
||||
|
@@ -161,6 +161,8 @@ static void LoadGunDescription(
|
||||
}
|
||||
CFREE(tmp);
|
||||
}
|
||||
wc->Grips = 1;
|
||||
LoadInt(&wc->Grips, node, "Grips");
|
||||
|
||||
LoadBool(&wc->IsGrenade, node, "IsGrenade");
|
||||
|
||||
|
@@ -67,6 +67,7 @@ typedef struct
|
||||
{
|
||||
char *Sprites;
|
||||
const Pic *Icon;
|
||||
int Grips;
|
||||
bool IsGrenade;
|
||||
char *name;
|
||||
char *Description;
|
||||
|
@@ -412,10 +412,11 @@ static void MissionDrawEnemy(
|
||||
}
|
||||
const CharacterStore *store = &data->co->Setting.characters;
|
||||
const int charIndex = *(int *)CArrayGet(&store->baddieIds, data->index);
|
||||
const Character *ch = CArrayGet(&store->OtherChars, charIndex);
|
||||
DrawCharacterSimple(
|
||||
CArrayGet(&store->OtherChars, charIndex),
|
||||
ch,
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
DIRECTION_DOWN, UIObjectIsHighlighted(o), true);
|
||||
DIRECTION_DOWN, UIObjectIsHighlighted(o), true, ch->Gun);
|
||||
}
|
||||
static void MissionDrawSpecialChar(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
@@ -431,10 +432,11 @@ static void MissionDrawSpecialChar(
|
||||
}
|
||||
const CharacterStore *store = &data->co->Setting.characters;
|
||||
const int charIndex = CharacterStoreGetSpecialId(store, data->index);
|
||||
const Character *ch = CArrayGet(&store->OtherChars, charIndex);
|
||||
DrawCharacterSimple(
|
||||
CArrayGet(&store->OtherChars, charIndex),
|
||||
ch,
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
DIRECTION_DOWN, UIObjectIsHighlighted(o), true);
|
||||
DIRECTION_DOWN, UIObjectIsHighlighted(o), true, ch->Gun);
|
||||
}
|
||||
static void MissionDrawMapItem(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
|
@@ -490,11 +490,11 @@ static void MissionDrawKillObjective(
|
||||
CharacterStore *store = &data->co->Setting.characters;
|
||||
if (store->specialIds.size > 0)
|
||||
{
|
||||
Character *c = CArrayGet(
|
||||
const Character *c = CArrayGet(
|
||||
&store->OtherChars, CharacterStoreGetSpecialId(store, 0));
|
||||
const struct vec2i drawPos = svec2i_add(
|
||||
svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2));
|
||||
DrawCharacterSimple(c, drawPos, DIRECTION_DOWN, false, true);
|
||||
DrawCharacterSimple(c, drawPos, DIRECTION_DOWN, false, true, c->Gun);
|
||||
}
|
||||
}
|
||||
static void MissionDrawCollectObjective(
|
||||
@@ -551,11 +551,11 @@ static void MissionDrawRescueObjective(
|
||||
CharacterStore *store = &data->co->Setting.characters;
|
||||
if (store->prisonerIds.size > 0)
|
||||
{
|
||||
Character *c = CArrayGet(
|
||||
const Character *c = CArrayGet(
|
||||
&store->OtherChars, CharacterStoreGetPrisonerId(store, 0));
|
||||
const struct vec2i drawPos = svec2i_add(
|
||||
svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2));
|
||||
DrawCharacterSimple(c, drawPos, DIRECTION_DOWN, false, true);
|
||||
DrawCharacterSimple(c, drawPos, DIRECTION_DOWN, false, true, c->Gun);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -132,11 +132,11 @@ static void DrawCharacter(
|
||||
UNUSED(g);
|
||||
EditorBrushAndCampaign *data = vData;
|
||||
CharacterStore *store = &data->Campaign->Setting.characters;
|
||||
Character *c = CArrayGet(&store->OtherChars, data->Brush.u.ItemIndex);
|
||||
const Character *c = CArrayGet(&store->OtherChars, data->Brush.u.ItemIndex);
|
||||
DrawCharacterSimple(
|
||||
c,
|
||||
svec2i_add(svec2i_add(pos, o->Pos), svec2i_scale_divide(o->Size, 2)),
|
||||
DIRECTION_DOWN, false, false);
|
||||
DIRECTION_DOWN, false, false, c->Gun);
|
||||
}
|
||||
static void DrawObjective(
|
||||
UIObject *o, GraphicsDevice *g, struct vec2i pos, void *vData)
|
||||
@@ -154,17 +154,17 @@ static void DrawObjective(
|
||||
switch (obj->Type)
|
||||
{
|
||||
case OBJECTIVE_KILL: {
|
||||
Character *c = CArrayGet(
|
||||
const Character *c = CArrayGet(
|
||||
&store->OtherChars,
|
||||
CharacterStoreGetSpecialId(store, data->Brush.Index2));
|
||||
DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
|
||||
DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false, c->Gun);
|
||||
}
|
||||
break;
|
||||
case OBJECTIVE_RESCUE: {
|
||||
Character *c = CArrayGet(
|
||||
const Character *c = CArrayGet(
|
||||
&store->OtherChars,
|
||||
CharacterStoreGetPrisonerId(store, data->Brush.Index2));
|
||||
DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false);
|
||||
DrawCharacterSimple(c, pos, DIRECTION_DOWN, false, false, c->Gun);
|
||||
}
|
||||
break;
|
||||
case OBJECTIVE_COLLECT: {
|
||||
|
@@ -39,13 +39,13 @@
|
||||
// centered around the target position
|
||||
void DisplayCharacterAndName(
|
||||
struct vec2i pos, const Character *c, const direction_e d,
|
||||
const char *name, const color_t color)
|
||||
const char *name, const color_t color, const WeaponClass *gun)
|
||||
{
|
||||
// Move the point down a bit since the default character draw point is at
|
||||
// its feet
|
||||
pos.y += 8;
|
||||
struct vec2i namePos = svec2i_add(pos, svec2i(-FontStrW(name) / 2, -30));
|
||||
DrawCharacterSimple(c, pos, d, false, false);
|
||||
DrawCharacterSimple(c, pos, d, false, false, gun);
|
||||
FontStrMask(name, namePos, color);
|
||||
}
|
||||
|
||||
@@ -72,8 +72,13 @@ void MenuDisplayPlayer(
|
||||
{
|
||||
strcpy(s, pData->name);
|
||||
}
|
||||
const WeaponClass *gun = NULL;
|
||||
if (d->GunIdx >= 0)
|
||||
{
|
||||
gun = pData->guns[d->GunIdx];
|
||||
}
|
||||
|
||||
DisplayCharacterAndName(playerPos, &pData->Char, d->Dir, s, colorWhite);
|
||||
DisplayCharacterAndName(playerPos, &pData->Char, d->Dir, s, colorWhite, gun);
|
||||
}
|
||||
|
||||
void MenuDisplayPlayerControls(
|
||||
|
@@ -2,7 +2,7 @@
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
|
||||
Copyright (c) 2013-2016, Cong Xu
|
||||
Copyright (c) 2013-2016, 2021 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -37,6 +37,7 @@ typedef struct
|
||||
int PlayerUID;
|
||||
menu_t **currentMenu;
|
||||
direction_e Dir;
|
||||
int GunIdx;
|
||||
} MenuDisplayPlayerData;
|
||||
void MenuDisplayPlayer(
|
||||
const menu_t *menu, GraphicsDevice *g,
|
||||
@@ -49,4 +50,4 @@ void MenuDisplayPlayerControls(
|
||||
|
||||
void DisplayCharacterAndName(
|
||||
struct vec2i pos, const Character *c, const direction_e d,
|
||||
const char *name, const color_t color);
|
||||
const char *name, const color_t color, const WeaponClass *gun);
|
||||
|
@@ -232,7 +232,7 @@ static void PlayerListCustomDraw(
|
||||
// Draw the players offset on alternate rows
|
||||
DisplayCharacterAndName(
|
||||
svec2i(x + (i & 1) * 16, y + 4), &p->Char, DIRECTION_DOWN, p->name,
|
||||
textColor);
|
||||
textColor, p->guns[0]);
|
||||
|
||||
// Draw score
|
||||
x += 100;
|
||||
|
@@ -92,10 +92,10 @@ static void DisplayGunIcon(
|
||||
const struct vec2i size, const void *data);
|
||||
static void AddEquippedMenuItem(
|
||||
menu_t *menu, const PlayerData *p, const int slot, const bool enabled);
|
||||
static void PostInputRotatePlayer(menu_t *menu, int cmd, void *data)
|
||||
static void PostInputEquipMenu(menu_t *menu, int cmd, void *data)
|
||||
{
|
||||
UNUSED(menu);
|
||||
MenuDisplayPlayerData *d = data;
|
||||
|
||||
// Rotate player using left/right keys
|
||||
const int dx = (cmd & CMD_LEFT) ? 1 : ((cmd & CMD_RIGHT) ? -1 : 0);
|
||||
if (dx != 0)
|
||||
@@ -107,6 +107,9 @@ static void PostInputRotatePlayer(menu_t *menu, int cmd, void *data)
|
||||
sprintf(buf, "footsteps/%s", p->Char.Class->Footsteps);
|
||||
SoundPlay(&gSoundDevice, StrSound(buf));
|
||||
}
|
||||
|
||||
// Display gun based on menu index
|
||||
d->GunIdx = MIN(menu->u.normal.index, MAX_WEAPONS);
|
||||
}
|
||||
static void CreateEquippedWeaponsMenu(
|
||||
MenuSystem *ms, EventHandlers *handlers, GraphicsDevice *g,
|
||||
@@ -156,7 +159,7 @@ static void CreateEquippedWeaponsMenu(
|
||||
ms->root, MenuCreateNormal(END_MENU_LABEL, "", MENU_TYPE_NORMAL, 0));
|
||||
|
||||
MenuSetCustomDisplay(ms->root, DisplayGunIcon, NULL);
|
||||
MenuSetPostInputFunc(ms->root, PostInputRotatePlayer, display);
|
||||
MenuSetPostInputFunc(ms->root, PostInputEquipMenu, display);
|
||||
|
||||
// Pre-select the End menu
|
||||
ms->root->u.normal.index = (int)(ms->root->u.normal.subMenus.size - 1);
|
||||
|
Reference in New Issue
Block a user