Skip to content

Commit

Permalink
Add melee weapon slot #742
Browse files Browse the repository at this point in the history
  • Loading branch information
cxong committed Sep 13, 2022
1 parent 1070715 commit 0f23341
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 127 deletions.
Binary file modified graphics/hud/gun_slot_bg_32x40.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 21 additions & 25 deletions src/cdogs/actors.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,17 @@ void UpdateActorState(TActor *actor, int ticks)
{
actor->DrawRadians -= (float)MIN(DRAW_RADIAN_SPEED * ticks, dr);
}

const struct vec2i tilePos = Vec2ToTile(actor->Pos);
const Tile *t = MapGetTile(&gMap, tilePos);

// Footstep sounds
// Step on 2 and 6
// TODO: custom animation and footstep frames
const int frame = AnimationGetFrame(&actor->anim);
const bool isFootstepFrame = actor->anim.Type == ACTORANIMATION_WALKING && (frame == 2 || frame == 6) && actor->anim.newFrame;
const bool isFootstepFrame = actor->anim.Type == ACTORANIMATION_WALKING &&
(frame == 2 || frame == 6) &&
actor->anim.newFrame;
if (isFootstepFrame)
{

Expand Down Expand Up @@ -233,18 +235,19 @@ void UpdateActorState(TActor *actor, int ticks)
}

// Damage when on special tiles
if (!gCampaign.IsClient &&
actor->anim.Type == ACTORANIMATION_WALKING ? isFootstepFrame : (gMission.time % FPS_FRAMELIMIT) == 0)
if (!gCampaign.IsClient && actor->anim.Type == ACTORANIMATION_WALKING
? isFootstepFrame
: (gMission.time % FPS_FRAMELIMIT) == 0)
{
const BulletClass *b = MatGetDamageBullet(t);
if (b != NULL)
{
GameEvent e = GameEventNew(GAME_EVENT_THING_DAMAGE);
e.u.ThingDamage.UID = actor->uid;
e.u.ThingDamage.Kind = KIND_CHARACTER;
BulletToDamageEvent(b, &e);
GameEventsEnqueue(&gGameEvents, e);
}
const BulletClass *b = MatGetDamageBullet(t);
if (b != NULL)
{
GameEvent e = GameEventNew(GAME_EVENT_THING_DAMAGE);
e.u.ThingDamage.UID = actor->uid;
e.u.ThingDamage.Kind = KIND_CHARACTER;
BulletToDamageEvent(b, &e);
GameEventsEnqueue(&gGameEvents, e);
}
}

// Animation
Expand Down Expand Up @@ -757,11 +760,7 @@ void ActorReplaceGun(const NActorReplaceGun rg)
memcpy(&a->guns[rg.GunIdx], &w, sizeof w);
// Switch immediately to picked up gun
const PlayerData *p = PlayerDataGetByUID(a->PlayerUID);
if (wc->Type == GUNTYPE_GRENADE && PlayerHasGrenadeButton(p))
{
a->grenadeIndex = rg.GunIdx - MAX_GUNS;
}
else
if (wc->Type != GUNTYPE_GRENADE || !PlayerHasGrenadeButton(p))
{
a->gunIndex = rg.GunIdx;
}
Expand Down Expand Up @@ -1656,10 +1655,6 @@ TActor *ActorAdd(NActorAdd aa)
{
actor->gunIndex = i;
}
if (i >= MAX_GUNS && ACTOR_GET_GRENADE(actor)->Gun == NULL)
{
actor->grenadeIndex = i - MAX_GUNS;
}
}
p->ActorUID = aa.UID;
}
Expand Down Expand Up @@ -1824,13 +1819,14 @@ bool ActorTrySwitchWeapon(const TActor *a, const bool allGuns)
// If the player does not have a grenade key set, allow switching to
// grenades (classic style)
const int switchCount = allGuns ? MAX_WEAPONS : MAX_GUNS;
const int startIndex =
ActorGetNumGuns(a) > 0 ? a->gunIndex : a->grenadeIndex + MAX_GUNS;
const int startIndex = ActorGetNumGuns(a) > 0 ? a->gunIndex : MAX_GUNS;
int weaponIndex = startIndex;
do
{
weaponIndex = (weaponIndex + 1) % switchCount;
} while (a->guns[weaponIndex].Gun == NULL);
} while (a->guns[weaponIndex].Gun ==
NULL); // TODO: don't cycle to auto-melee or default melee unless
// it's the only gun
if (weaponIndex == startIndex)
{
// No other weapon to switch to
Expand Down
14 changes: 6 additions & 8 deletions src/cdogs/actors.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2021 Cong Xu
Copyright (c) 2013-2022 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -125,16 +125,14 @@ typedef struct Actor
// -1 if human character (get from player data), otherwise index into
// CharacterStore OtherChars
int charId;
int PlayerUID; // -1 unless a human player
int uid; // unique ID across all actors
int pilotUID; // the actor that controls this
// (same as uid for normal actors)
int PlayerUID; // -1 unless a human player
int uid; // unique ID across all actors
int pilotUID; // the actor that controls this
// (same as uid for normal actors)
int vehicleUID; // -1 unless piloting a vehicle
Weapon guns[MAX_WEAPONS];
CArray ammo; // of int
int gunIndex;
// TODO: multiple grenade slots?
int grenadeIndex;

int health;
// A counter for player death
Expand Down Expand Up @@ -217,7 +215,7 @@ void ActorDestroy(TActor *a);
TActor *ActorGetByUID(const int uid);
const Character *ActorGetCharacter(const TActor *a);
#define ACTOR_GET_GUN(a) (&(a)->guns[(a)->gunIndex])
#define ACTOR_GET_GRENADE(a) (&(a)->guns[(a)->grenadeIndex + MAX_GUNS])
#define ACTOR_GET_GRENADE(a) (&(a)->guns[MAX_GUNS])
#define ACTOR_GET_WEAPON(a) \
(ACTOR_GET_GUN(a)->Gun != NULL ? ACTOR_GET_GUN(a) : ACTOR_GET_GRENADE(a))
struct vec2 ActorGetAverageWeaponMuzzleOffset(const TActor *a);
Expand Down
32 changes: 18 additions & 14 deletions src/cdogs/pickup.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ void PickupsUpdate(CArray *pickups, const int ticks)
static bool TreatAsGunPickup(const PickupEffect *pe, const TActor *a);
static bool TryPickupAmmo(TActor *a, const Pickup *p, const PickupEffect *pe);
static bool TryPickupGun(
TActor *a, const PickupEffect *pe, const bool pickupAll, const char **sound);
TActor *a, const PickupEffect *pe, const bool pickupAll,
const char **sound);
void PickupPickup(TActor *a, Pickup *p, const bool pickupAll)
{
if (p->PickedUp)
Expand Down Expand Up @@ -222,7 +223,7 @@ void PickupPickup(TActor *a, Pickup *p, const bool pickupAll)
GameEventsEnqueue(&gGameEvents, e);
}
break;

case PICKUP_LIVES: {
canPickup = true;
GameEvent e = GameEventNew(GAME_EVENT_PLAYER_ADD_LIVES);
Expand Down Expand Up @@ -277,10 +278,8 @@ static bool TreatAsGunPickup(const PickupEffect *pe, const TActor *a)
return false;
case PICKUP_GUN: {
const WeaponClass *wc = IdWeaponClass(pe->u.GunId);
// TODO: support picking up multi guns?
return wc->Type == GUNTYPE_NORMAL ||
(wc->Type == GUNTYPE_GRENADE &&
!HasGunUsingAmmo(a, wc->u.Normal.AmmoId));
return wc->Type != GUNTYPE_GRENADE ||
!HasGunUsingAmmo(a, wc->u.Normal.AmmoId);
}
default:
CASSERT(false, "unexpected pickup type");
Expand Down Expand Up @@ -335,7 +334,8 @@ static bool TryPickupAmmo(TActor *a, const Pickup *p, const PickupEffect *pe)
return true;
}
static bool TryPickupGun(
TActor *a, const PickupEffect *pe, const bool pickupAll, const char **sound)
TActor *a, const PickupEffect *pe, const bool pickupAll,
const char **sound)
{
// Guns can only be picked up manually
if (!pickupAll)
Expand All @@ -354,8 +354,7 @@ static bool TryPickupGun(
const WeaponClass *wc =
pe->Type == PICKUP_GUN
? IdWeaponClass(pe->u.GunId)
: StrWeaponClass(
AmmoGetById(&gAmmo, pe->u.Ammo.Id)->DefaultGun);
: StrWeaponClass(AmmoGetById(&gAmmo, pe->u.Ammo.Id)->DefaultGun);
const int actorsGunIdx = ActorFindGun(a, wc);

if (actorsGunIdx >= 0)
Expand All @@ -377,15 +376,20 @@ static bool TryPickupGun(
// Replace the current gun, unless there's a free slot, in which case
// pick up into the free spot
const int weaponIndexStart =
wc->Type == GUNTYPE_GRENADE ? MAX_GUNS : 0;
wc->Type == GUNTYPE_GRENADE
? MAX_GUNS
: (wc->Type == GUNTYPE_MELEE ? MELEE_SLOT : 0);
const int weaponIndexEnd =
wc->Type == GUNTYPE_GRENADE ? MAX_WEAPONS : MAX_GUNS;
wc->Type == GUNTYPE_GRENADE
? MAX_WEAPONS
: (wc->Type == GUNTYPE_MELEE ? MELEE_SLOT + 1 : MELEE_SLOT);
GameEvent e = GameEventNew(GAME_EVENT_ACTOR_REPLACE_GUN);
e.u.ActorReplaceGun.UID = a->uid;
strcpy(e.u.ActorReplaceGun.Gun, wc->name);
e.u.ActorReplaceGun.GunIdx = wc->Type == GUNTYPE_GRENADE
? a->grenadeIndex + MAX_GUNS
: a->gunIndex;
e.u.ActorReplaceGun.GunIdx =
wc->Type == GUNTYPE_GRENADE
? MAX_GUNS
: (wc->Type == GUNTYPE_MELEE ? MELEE_SLOT : a->gunIndex);
int replaceGunIndex = e.u.ActorReplaceGun.GunIdx;
for (int i = weaponIndexStart; i < weaponIndexEnd; i++)
{
Expand Down
5 changes: 3 additions & 2 deletions src/cdogs/player.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
C-Dogs SDL
A port of the legendary (and fun) action/arcade cdogs.
Copyright (c) 2014-2016, 2018-2020 Cong Xu
Copyright (c) 2014-2016, 2018-2020, 2022 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -29,7 +29,8 @@

#include "character.h"

#define MAX_GUNS 2
#define MAX_GUNS 3
#define MELEE_SLOT 2
#define MAX_GRENADES 1
#define MAX_WEAPONS (MAX_GUNS + MAX_GRENADES)
// TODO: track accuracy
Expand Down
Loading

0 comments on commit 0f23341

Please sign in to comment.