Skip to content

Commit

Permalink
Add mass parameter to bullets (fixes #444)
Browse files Browse the repository at this point in the history
Bump bullet json version to 2; old version will
have mass default to power

Also adjust some bullet mass:
- flamer mass 1 (low impulse)
- pulse rifle mass 1 (low impulse)
- heatseeker mass 15 (slightly higher impulse)
- swarmer mass 10 (higher impulse)
- pistol mass 5 (lower impulse)
  • Loading branch information
cxong committed Sep 30, 2016
1 parent d145b53 commit d87525e
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 37 deletions.
25 changes: 20 additions & 5 deletions data/bullets.json
@@ -1,5 +1,5 @@
{
"Version": 1,
"Version": 2,
"DefaultBullet": {
"Pic": {
"Type": "Directional",
Expand Down Expand Up @@ -31,7 +31,8 @@
"Name": "mg",
"Speed": 768,
"Range": 60,
"Power": 10
"Power": 10,
"Mass": 10.0
},
{
"Name": "shotgun",
Expand All @@ -41,7 +42,8 @@
},
"Speed": 640,
"Range": 50,
"Power": 15
"Power": 15,
"Mass": 15.0
},
{
"Name": "flame",
Expand All @@ -53,6 +55,7 @@
"Speed": 384,
"Range": 30,
"Power": 12,
"Mass": 1.0,
"Size": [10, 10],
"Special": "Flame",
"Spark": "",
Expand All @@ -73,6 +76,7 @@
"Speed": 1024,
"Range": 90,
"Power": 20,
"Mass": 20.0,
"Size": [4, 4]
},
{
Expand All @@ -85,13 +89,15 @@
"Speed": 1024,
"Range": 90,
"Power": 50,
"Mass": 50.0,
"Size": [4, 4]
},
{
"Name": "frag",
"Speed": 640,
"Range": 50,
"Power": 40,
"Mass": 40.0,
"HurtAlways": true
},
{
Expand Down Expand Up @@ -260,7 +266,8 @@
"Spark": "spark_blue",
"Speed": 1280,
"Range": 25,
"Power": 6
"Power": 6,
"Mass": 1.0
},
{
"Name": "heatseeker",
Expand All @@ -271,6 +278,7 @@
"Speed": 512,
"Range": 60,
"Power": 20,
"Mass": 40.0,
"Size": [6, 6],
"Spark": "boom",
"HitSounds": {
Expand All @@ -290,6 +298,7 @@
"Speed": 768,
"Range": 45,
"Power": 15,
"Mass": 15.0,
"Erratic": true
},
{
Expand Down Expand Up @@ -350,6 +359,7 @@
"Speed": 700,
"Range": 70,
"Power": 12,
"Mass": 15.0,
"Size": [4, 4],
"Spark": "boom",
"HitSounds": {
Expand Down Expand Up @@ -389,6 +399,7 @@
"Speed": 256,
"Range": 53,
"Power": 5,
"Mass": 5.0,
"Size": [14, 10],
"HurtAlways": true,
"Persists": true,
Expand All @@ -415,6 +426,7 @@
"Speed": 192,
"Range": 71,
"Power": 5,
"Mass": 5.0,
"Size": [14, 10],
"HurtAlways": true,
"Persists": true,
Expand All @@ -441,6 +453,7 @@
"Speed": 128,
"Range": 79,
"Power": 5,
"Mass": 5.0,
"Size": [14, 10],
"HurtAlways": true,
"Persists": true,
Expand Down Expand Up @@ -573,6 +586,7 @@
"Speed": 0,
"Range": 27,
"Power": 3,
"Mass": 10.0,
"Size": [64, 64],
"Persists": true,
"Spark": "",
Expand Down Expand Up @@ -615,7 +629,8 @@
},
"Speed": 1100,
"Range": 27,
"Power": 12
"Power": 12,
"Mass": 5.0
}
]
}
9 changes: 6 additions & 3 deletions missions/doom.cdogscpn/bullets.json
@@ -1,5 +1,5 @@
{
"Version": 1,
"Version": 2,
"Bullets": [
{
"Name": "10mm",
Expand All @@ -9,7 +9,8 @@
},
"Speed": 1100,
"Range": 50,
"Power": 10
"Power": 10,
"Mass": 5.0
},
{
"Name": "fireball",
Expand All @@ -21,6 +22,7 @@
"Speed": 350,
"Range": 200,
"Power": 18,
"Mass": 18.0,
"Size": [3, 3],
"Special": "Flame",
"Spark": "fireball_hit",
Expand All @@ -40,6 +42,7 @@
"Speed": 550,
"Range": 300,
"Power": 40,
"Mass": 40.0,
"Size": [3, 3],
"Special": "Flame",
"Spark": "fireball_green_hit",
Expand All @@ -50,4 +53,4 @@
}
}
]
}
}
17 changes: 3 additions & 14 deletions src/cdogs/actors.c
Expand Up @@ -1441,8 +1441,6 @@ void ActorAddBloodSplatters(TActor *a, const int power, const Vec2i hitVector)
int bloodPower = power * 2;
// Randomly cycle through the blood types
int bloodSize = 1;
// Spray the blood back with the shot if pushback enabled
const bool shotsPushBack = ConfigGetBool(&gConfig, "Game.ShotsPushback");
while (bloodPower > 0)
{
Emitter *em = NULL;
Expand All @@ -1463,18 +1461,9 @@ void ActorAddBloodSplatters(TActor *a, const int power, const Vec2i hitVector)
{
bloodSize = 1;
}
Vec2i vel;
if (shotsPushBack)
{
vel = Vec2iScaleDiv(
Vec2iScale(hitVector, (rand() % 8 + 8) * power),
15 * SHOT_IMPULSE_DIVISOR);
}
else
{
vel = Vec2iScaleDiv(
Vec2iScale(hitVector, rand() % 8 + 8), 20);
}
const Vec2i vel = Vec2iScaleDiv(
Vec2iScale(hitVector, (rand() % 8 + 8) * power),
15 * SHOT_IMPULSE_DIVISOR);
EmitterStart(em, a->Pos, 10, vel);
switch (ga)
{
Expand Down
26 changes: 20 additions & 6 deletions src/cdogs/bullet_class.c
Expand Up @@ -407,7 +407,8 @@ static bool HitItemFunc(TTileItem *ti, void *data)
int targetUID = -1;
hData->HitType = GetHitType(ti, hData->Obj, &targetUID);
Damage(
hData->Obj->vel, hData->Obj->bulletClass->Power,
hData->Obj->vel,
hData->Obj->bulletClass->Power, hData->Obj->bulletClass->Mass,
hData->Obj->flags, hData->Obj->PlayerUID, hData->Obj->ActorUID,
ti->kind, targetUID,
hData->Obj->bulletClass->Special);
Expand Down Expand Up @@ -459,9 +460,10 @@ static HitType GetHitType(



#define VERSION 1
#define VERSION 2
static void LoadBullet(
BulletClass *b, json_t *node, const BulletClass *defaultBullet);
BulletClass *b, json_t *node, const BulletClass *defaultBullet,
const int version);
void BulletInitialize(BulletClasses *bullets)
{
memset(bullets, 0, sizeof *bullets);
Expand All @@ -486,21 +488,22 @@ void BulletLoadJSON(
if (defaultNode != NULL)
{
BulletClassFree(&bullets->Default);
LoadBullet(&bullets->Default, defaultNode->child, NULL);
LoadBullet(&bullets->Default, defaultNode->child, NULL, version);
}

json_t *bulletsNode = json_find_first_label(bulletNode, "Bullets")->child;
for (json_t *child = bulletsNode->child; child; child = child->next)
{
BulletClass b;
LoadBullet(&b, child, &bullets->Default);
LoadBullet(&b, child, &bullets->Default, version);
CArrayPushBack(classes, &b);
}

bullets->root = bulletNode;
}
static void LoadBullet(
BulletClass *b, json_t *node, const BulletClass *defaultBullet)
BulletClass *b, json_t *node, const BulletClass *defaultBullet,
const int version)
{
memset(b, 0, sizeof *b);
if (defaultBullet != NULL)
Expand Down Expand Up @@ -565,6 +568,17 @@ static void LoadBullet(
b->RangeLow = MIN(b->RangeLow, b->RangeHigh);
b->RangeHigh = MAX(b->RangeLow, b->RangeHigh);
LoadInt(&b->Power, node, "Power");

if (version < 2)
{
// Old version default mass = power
b->Mass = b->Power;
}
else
{
LoadDouble(&b->Mass, node, "Mass");
}

LoadVec2i(&b->Size, node, "Size");
tmp = NULL;
LoadStr(&tmp, node, "Special");
Expand Down
1 change: 1 addition & 0 deletions src/cdogs/bullet_class.h
Expand Up @@ -72,6 +72,7 @@ typedef struct
int RangeLow;
int RangeHigh;
int Power;
double Mass;
Vec2i Size;
special_damage_e Special;
bool HurtAlways;
Expand Down
1 change: 0 additions & 1 deletion src/cdogs/config.c
Expand Up @@ -557,7 +557,6 @@ Config ConfigDefault(void)
"SwitchMoveStyle", SWITCHMOVE_SLIDE,
SWITCHMOVE_SLIDE, SWITCHMOVE_NONE,
StrSwitchMoveStyle, SwitchMoveStyleStr));
ConfigGroupAdd(&game, ConfigNewBool("ShotsPushback", true));
ConfigGroupAdd(&game, ConfigNewEnum(
"AllyCollision", ALLYCOLLISION_REPEL,
ALLYCOLLISION_NORMAL, ALLYCOLLISION_NONE,
Expand Down
2 changes: 0 additions & 2 deletions src/cdogs/game_events.h
Expand Up @@ -70,8 +70,6 @@ typedef enum
GAME_EVENT_ACTOR_STATE,
GAME_EVENT_ACTOR_DIR,
GAME_EVENT_ACTOR_SLIDE,
// TODO: event only used by actor hit and screen boundaries
// If the latter is removed, it can be incorporated into actor hit
GAME_EVENT_ACTOR_IMPULSE,
GAME_EVENT_ACTOR_SWITCH_GUN,
GAME_EVENT_ACTOR_PICKUP_ALL,
Expand Down
3 changes: 2 additions & 1 deletion src/cdogs/handle_game_events.c
Expand Up @@ -338,9 +338,10 @@ static void HandleGameEvent(
}
if (!gCampaign.IsClient)
{
// TODO: melee hitback (vel)?
Damage(
Vec2iZero(),
b->Power,
b->Power, b->Mass,
a->flags, a->PlayerUID, a->uid,
(TileItemKind)e.u.Melee.TargetKind, e.u.Melee.TargetUID,
SPECIAL_NONE);
Expand Down
1 change: 0 additions & 1 deletion src/cdogs/net_server.c
Expand Up @@ -419,7 +419,6 @@ void NetServerSendGameStartMessages(NetServer *n, const int peerId)
SendConfig(&gConfig, "Game.Ammo", n, peerId);
SendConfig(&gConfig, "Game.Fog", n, peerId);
SendConfig(&gConfig, "Game.SightRange", n, peerId);
SendConfig(&gConfig, "Game.ShotsPushback", n, peerId);
SendConfig(&gConfig, "Game.AllyCollision", n, peerId);

NetServerSendMsg(n, peerId, GAME_EVENT_NET_GAME_START, NULL);
Expand Down
15 changes: 11 additions & 4 deletions src/cdogs/objs.c
Expand Up @@ -211,6 +211,7 @@ bool HasHitSound(
static void DoDamageCharacter(
const Vec2i hitVector,
const int power,
const double mass,
const int flags,
const int playerUID,
const int uid,
Expand All @@ -219,6 +220,7 @@ static void DoDamageCharacter(
void Damage(
const Vec2i hitVector,
const int power,
const double mass,
const int flags,
const int playerUID,
const int uid,
Expand All @@ -230,7 +232,7 @@ void Damage(
case KIND_CHARACTER:
DoDamageCharacter(
hitVector,
power, flags, playerUID, uid,
power, mass, flags, playerUID, uid,
ActorGetByUID(targetUID), special);
break;
case KIND_OBJECT:
Expand All @@ -252,6 +254,7 @@ void Damage(
static void DoDamageCharacter(
const Vec2i hitVector,
const int power,
const double mass,
const int flags,
const int playerUID,
const int uid,
Expand All @@ -262,12 +265,16 @@ static void DoDamageCharacter(
CASSERT(actor->isInUse, "Cannot damage nonexistent player");
CASSERT(CanHitCharacter(flags, uid, actor), "damaging undamageable actor");

if (ConfigGetBool(&gConfig, "Game.ShotsPushback"))
// Shot pushback, based on mass and velocity
const double impulseFactor = mass / SHOT_IMPULSE_DIVISOR;
const Vec2i vel = Vec2iNew(
(int)Round(hitVector.x * impulseFactor),
(int)Round(hitVector.y * impulseFactor));
if (!Vec2iIsZero(vel))
{
GameEvent ei = GameEventNew(GAME_EVENT_ACTOR_IMPULSE);
ei.u.ActorImpulse.UID = actor->uid;
ei.u.ActorImpulse.Vel = Vec2i2Net(Vec2iScaleDiv(
Vec2iScale(hitVector, power), SHOT_IMPULSE_DIVISOR));
ei.u.ActorImpulse.Vel = Vec2i2Net(vel);
ei.u.ActorImpulse.Pos = Vec2i2Net(actor->Pos);
GameEventsEnqueue(&gGameEvents, ei);
}
Expand Down
1 change: 1 addition & 0 deletions src/cdogs/objs.h
Expand Up @@ -105,6 +105,7 @@ bool HasHitSound(
void Damage(
const Vec2i hitVector,
const int power,
const double mass,
const int flags, const int playerUID, const int uid,
const TileItemKind targetKind, const int targetUID,
const special_damage_e special);
Expand Down

0 comments on commit d87525e

Please sign in to comment.