Migrate projectile to a class
FossilOrigin-Name: d3b4b2d476d809f7ab00502eed47614c949264690b3eccc7a96c73687d0f05bf
This commit is contained in:
parent
dae9d5553c
commit
410e244ed6
9 changed files with 97 additions and 82 deletions
11
src/Projectile.h
Normal file
11
src/Projectile.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#import <ObjFW/ObjFW.h>
|
||||||
|
|
||||||
|
typedef struct dynent dynent;
|
||||||
|
|
||||||
|
@interface Projectile: OFObject
|
||||||
|
@property (nonatomic) OFVector3D o, to;
|
||||||
|
@property (nonatomic) float speed;
|
||||||
|
@property (nonatomic) dynent *owner;
|
||||||
|
@property (nonatomic) int gun;
|
||||||
|
@property (nonatomic) bool inuse, local;
|
||||||
|
@end
|
4
src/Projectile.m
Normal file
4
src/Projectile.m
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#import "Projectile.h"
|
||||||
|
|
||||||
|
@implementation Projectile
|
||||||
|
@end
|
|
@ -9,6 +9,7 @@ executable('client',
|
||||||
'MapModelInfo.m',
|
'MapModelInfo.m',
|
||||||
'Menu.m',
|
'Menu.m',
|
||||||
'MenuItem.m',
|
'MenuItem.m',
|
||||||
|
'Projectile.m',
|
||||||
'Variable.mm',
|
'Variable.mm',
|
||||||
'client.mm',
|
'client.mm',
|
||||||
'clientextras.mm',
|
'clientextras.mm',
|
||||||
|
|
10
src/protos.h
10
src/protos.h
|
@ -125,8 +125,8 @@ extern entity *newentity(
|
||||||
|
|
||||||
// worldlight
|
// worldlight
|
||||||
extern void calclight();
|
extern void calclight();
|
||||||
extern void dodynlight(
|
extern void dodynlight(const OFVector3D &vold, const OFVector3D &v, int reach,
|
||||||
OFVector3D &vold, OFVector3D &v, int reach, int strength, dynent *owner);
|
int strength, dynent *owner);
|
||||||
extern void cleardlights();
|
extern void cleardlights();
|
||||||
extern block *blockcopy(block &b);
|
extern block *blockcopy(block &b);
|
||||||
extern void blockpaste(block &b);
|
extern void blockpaste(block &b);
|
||||||
|
@ -166,7 +166,7 @@ extern void line(int x1, int y1, float z1, int x2, int y2, float z2);
|
||||||
extern void box(block &b, float z1, float z2, float z3, float z4);
|
extern void box(block &b, float z1, float z2, float z3, float z4);
|
||||||
extern void dot(int x, int y, float z);
|
extern void dot(int x, int y, float z);
|
||||||
extern void linestyle(float width, int r, int g, int b);
|
extern void linestyle(float width, int r, int g, int b);
|
||||||
extern void newsphere(OFVector3D &o, float max, int type);
|
extern void newsphere(const OFVector3D &o, float max, int type);
|
||||||
extern void renderspheres(int time);
|
extern void renderspheres(int time);
|
||||||
extern void gl_drawhud(
|
extern void gl_drawhud(
|
||||||
int w, int h, int curfps, int nquads, int curvert, bool underwater);
|
int w, int h, int curfps, int nquads, int curvert, bool underwater);
|
||||||
|
@ -176,7 +176,7 @@ extern void damageblend(int n);
|
||||||
|
|
||||||
// renderparticles
|
// renderparticles
|
||||||
extern void setorient(OFVector3D &r, OFVector3D &u);
|
extern void setorient(OFVector3D &r, OFVector3D &u);
|
||||||
extern void particle_splash(int type, int num, int fade, OFVector3D &p);
|
extern void particle_splash(int type, int num, int fade, const OFVector3D &p);
|
||||||
extern void particle_trail(
|
extern void particle_trail(
|
||||||
int type, int fade, OFVector3D &from, OFVector3D &to);
|
int type, int fade, OFVector3D &from, OFVector3D &to);
|
||||||
extern void render_particles(int time);
|
extern void render_particles(int time);
|
||||||
|
@ -202,7 +202,7 @@ extern void setentphysics(int mml, int mmr);
|
||||||
extern void physicsframe();
|
extern void physicsframe();
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
extern void playsound(int n, OFVector3D *loc = 0);
|
extern void playsound(int n, const OFVector3D *loc = NULL);
|
||||||
extern void playsoundc(int n);
|
extern void playsoundc(int n);
|
||||||
extern void initsound();
|
extern void initsound();
|
||||||
extern void cleansound();
|
extern void cleansound();
|
||||||
|
|
|
@ -89,7 +89,7 @@ sphere spheres[MAXSPHERES], *slist = NULL, *sempty = NULL;
|
||||||
bool sinit = false;
|
bool sinit = false;
|
||||||
|
|
||||||
void
|
void
|
||||||
newsphere(OFVector3D &o, float max, int type)
|
newsphere(const OFVector3D &o, float max, int type)
|
||||||
{
|
{
|
||||||
if (!sinit) {
|
if (!sinit) {
|
||||||
loopi(MAXSPHERES)
|
loopi(MAXSPHERES)
|
||||||
|
|
|
@ -15,8 +15,8 @@ bool parinit = false;
|
||||||
|
|
||||||
VARP(maxparticles, 100, 2000, MAXPARTICLES - 500);
|
VARP(maxparticles, 100, 2000, MAXPARTICLES - 500);
|
||||||
|
|
||||||
void
|
static void
|
||||||
newparticle(OFVector3D &o, OFVector3D &d, int fade, int type)
|
newparticle(const OFVector3D &o, const OFVector3D &d, int fade, int type)
|
||||||
{
|
{
|
||||||
if (!parinit) {
|
if (!parinit) {
|
||||||
loopi(MAXPARTICLES)
|
loopi(MAXPARTICLES)
|
||||||
|
@ -133,7 +133,7 @@ render_particles(int time)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
particle_splash(int type, int num, int fade, OFVector3D &p)
|
particle_splash(int type, int num, int fade, const OFVector3D &p)
|
||||||
{
|
{
|
||||||
loopi(num)
|
loopi(num)
|
||||||
{
|
{
|
||||||
|
@ -144,8 +144,7 @@ particle_splash(int type, int num, int fade, OFVector3D &p)
|
||||||
y = rnd(radius * 2) - radius;
|
y = rnd(radius * 2) - radius;
|
||||||
z = rnd(radius * 2) - radius;
|
z = rnd(radius * 2) - radius;
|
||||||
} while (x * x + y * y + z * z > radius * radius);
|
} while (x * x + y * y + z * z > radius * radius);
|
||||||
OFVector3D d = OFMakeVector3D(x, y, z);
|
newparticle(p, OFMakeVector3D(x, y, z), rnd(fade * 3), type);
|
||||||
newparticle(p, d, rnd(fade * 3), type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/sound.mm
20
src/sound.mm
|
@ -92,14 +92,16 @@ music(OFString *name)
|
||||||
IRIByAppendingPathComponent:path];
|
IRIByAppendingPathComponent:path];
|
||||||
|
|
||||||
#ifdef USE_MIXER
|
#ifdef USE_MIXER
|
||||||
if (mod = Mix_LoadMUS(
|
if ((mod = Mix_LoadMUS(
|
||||||
IRI.fileSystemRepresentation.UTF8String)) {
|
IRI.fileSystemRepresentation.UTF8String)) !=
|
||||||
|
NULL) {
|
||||||
Mix_PlayMusic(mod, -1);
|
Mix_PlayMusic(mod, -1);
|
||||||
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
Mix_VolumeMusic((musicvol * MAXVOL) / 255);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (mod = FMUSIC_LoadSong(
|
if ((mod = FMUSIC_LoadSong(
|
||||||
IRI.fileSystemRepresentation.UTF8String)) {
|
IRI.fileSystemRepresentation.UTF8String)) !=
|
||||||
|
NULL) {
|
||||||
FMUSIC_PlaySong(mod);
|
FMUSIC_PlaySong(mod);
|
||||||
FMUSIC_SetMasterVolume(mod, musicvol);
|
FMUSIC_SetMasterVolume(mod, musicvol);
|
||||||
} else if (stream = FSOUND_Stream_Open(
|
} else if (stream = FSOUND_Stream_Open(
|
||||||
|
@ -166,8 +168,8 @@ cleansound()
|
||||||
|
|
||||||
VAR(stereo, 0, 1, 1);
|
VAR(stereo, 0, 1, 1);
|
||||||
|
|
||||||
void
|
static void
|
||||||
updatechanvol(int chan, OFVector3D *loc)
|
updatechanvol(int chan, const OFVector3D *loc)
|
||||||
{
|
{
|
||||||
int vol = soundvol, pan = 255 / 2;
|
int vol = soundvol, pan = 255 / 2;
|
||||||
if (loc) {
|
if (loc) {
|
||||||
|
@ -194,8 +196,8 @@ updatechanvol(int chan, OFVector3D *loc)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
newsoundloc(int chan, OFVector3D *loc)
|
newsoundloc(int chan, const OFVector3D *loc)
|
||||||
{
|
{
|
||||||
assert(chan >= 0 && chan < MAXCHAN);
|
assert(chan >= 0 && chan < MAXCHAN);
|
||||||
soundlocs[chan].loc = *loc;
|
soundlocs[chan].loc = *loc;
|
||||||
|
@ -230,7 +232,7 @@ playsoundc(int n)
|
||||||
int soundsatonce = 0, lastsoundmillis = 0;
|
int soundsatonce = 0, lastsoundmillis = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
playsound(int n, OFVector3D *loc)
|
playsound(int n, const OFVector3D *loc)
|
||||||
{
|
{
|
||||||
if (nosound)
|
if (nosound)
|
||||||
return;
|
return;
|
||||||
|
|
118
src/weapon.mm
118
src/weapon.mm
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
#include "cube.h"
|
#include "cube.h"
|
||||||
|
|
||||||
struct guninfo {
|
#import "Projectile.h"
|
||||||
short sound, attackdelay, damage, projspeed, part, kickamount;
|
|
||||||
OFString *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int MONSTERDAMAGEFACTOR = 4;
|
static const int MONSTERDAMAGEFACTOR = 4;
|
||||||
static const int SGRAYS = 20;
|
static const int SGRAYS = 20;
|
||||||
static const float SGSPREAD = 2;
|
static const float SGSPREAD = 2;
|
||||||
static OFVector3D sg[SGRAYS];
|
static OFVector3D sg[SGRAYS];
|
||||||
|
|
||||||
static const guninfo guns[NUMGUNS] = {
|
static const struct {
|
||||||
|
short sound, attackdelay, damage, projspeed, part, kickamount;
|
||||||
|
OFString *name;
|
||||||
|
} guns[NUMGUNS] = {
|
||||||
{ S_PUNCH1, 250, 50, 0, 0, 1, @"fist" },
|
{ S_PUNCH1, 250, 50, 0, 0, 1, @"fist" },
|
||||||
{ S_SG, 1400, 10, 0, 0, 20, @"shotgun" }, // *SGRAYS
|
{ S_SG, 1400, 10, 0, 0, 20, @"shotgun" }, // *SGRAYS
|
||||||
{ S_CG, 100, 30, 0, 0, 7, @"chaingun" },
|
{ S_CG, 100, 30, 0, 0, 7, @"chaingun" },
|
||||||
|
@ -83,11 +83,12 @@ createrays(OFVector3D &from,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if lineseg hits entity bounding box
|
||||||
bool
|
bool
|
||||||
intersect(dynent *d, OFVector3D &from,
|
intersect(dynent *d, const OFVector3D &from, const OFVector3D &to)
|
||||||
OFVector3D &to) // if lineseg hits entity bounding box
|
|
||||||
{
|
{
|
||||||
OFVector3D v = to, w = d->o, *p;
|
OFVector3D v = to, w = d->o;
|
||||||
|
const OFVector3D *p;
|
||||||
vsub(v, from);
|
vsub(v, from);
|
||||||
vsub(w, from);
|
vsub(w, from);
|
||||||
float c1 = dotprod(w, v);
|
float c1 = dotprod(w, v);
|
||||||
|
@ -128,37 +129,33 @@ playerincrosshair()
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int MAXPROJ = 100;
|
static const size_t MAXPROJ = 100;
|
||||||
struct projectile {
|
static Projectile *projs[MAXPROJ];
|
||||||
OFVector3D o, to;
|
|
||||||
float speed;
|
|
||||||
dynent *owner;
|
|
||||||
int gun;
|
|
||||||
bool inuse, local;
|
|
||||||
} projs[MAXPROJ];
|
|
||||||
|
|
||||||
void
|
void
|
||||||
projreset()
|
projreset()
|
||||||
{
|
{
|
||||||
loopi(MAXPROJ) projs[i].inuse = false;
|
for (size_t i = 0; i < MAXPROJ; i++)
|
||||||
|
projs[i].inuse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
|
newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
|
||||||
dynent *owner, int gun)
|
dynent *owner, int gun)
|
||||||
{
|
{
|
||||||
loopi(MAXPROJ)
|
for (size_t i = 0; i < MAXPROJ; i++) {
|
||||||
{
|
Projectile *p = projs[i];
|
||||||
projectile *p = &projs[i];
|
|
||||||
if (p->inuse)
|
if (p.inuse)
|
||||||
continue;
|
continue;
|
||||||
p->inuse = true;
|
|
||||||
p->o = from;
|
p.inuse = true;
|
||||||
p->to = to;
|
p.o = from;
|
||||||
p->speed = speed;
|
p.to = to;
|
||||||
p->local = local;
|
p.speed = speed;
|
||||||
p->owner = owner;
|
p.local = local;
|
||||||
p->gun = gun;
|
p.owner = owner;
|
||||||
|
p.gun = gun;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,8 +178,8 @@ hit(int target, int damage, dynent *d, dynent *at)
|
||||||
const float RL_RADIUS = 5;
|
const float RL_RADIUS = 5;
|
||||||
const float RL_DAMRAD = 7; // hack
|
const float RL_DAMRAD = 7; // hack
|
||||||
|
|
||||||
void
|
static void
|
||||||
radialeffect(dynent *o, OFVector3D &v, int cn, int qdam, dynent *at)
|
radialeffect(dynent *o, const OFVector3D &v, int cn, int qdam, dynent *at)
|
||||||
{
|
{
|
||||||
if (o->state != CS_ALIVE)
|
if (o->state != CS_ALIVE)
|
||||||
return;
|
return;
|
||||||
|
@ -199,21 +196,21 @@ radialeffect(dynent *o, OFVector3D &v, int cn, int qdam, dynent *at)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
splash(projectile *p, OFVector3D &v, OFVector3D &vold, int notthisplayer,
|
splash(Projectile *p, const OFVector3D &v, const OFVector3D &vold,
|
||||||
int notthismonster, int qdam)
|
int notthisplayer, int notthismonster, int qdam)
|
||||||
{
|
{
|
||||||
particle_splash(0, 50, 300, v);
|
particle_splash(0, 50, 300, v);
|
||||||
p->inuse = false;
|
p.inuse = false;
|
||||||
if (p->gun != GUN_RL) {
|
if (p.gun != GUN_RL) {
|
||||||
playsound(S_FEXPLODE, &v);
|
playsound(S_FEXPLODE, &v);
|
||||||
// no push?
|
// no push?
|
||||||
} else {
|
} else {
|
||||||
playsound(S_RLHIT, &v);
|
playsound(S_RLHIT, &v);
|
||||||
newsphere(v, RL_RADIUS, 0);
|
newsphere(v, RL_RADIUS, 0);
|
||||||
dodynlight(vold, v, 0, 0, p->owner);
|
dodynlight(vold, v, 0, 0, p.owner);
|
||||||
if (!p->local)
|
if (!p.local)
|
||||||
return;
|
return;
|
||||||
radialeffect(player1, v, -1, qdam, p->owner);
|
radialeffect(player1, v, -1, qdam, p.owner);
|
||||||
loopv(players)
|
loopv(players)
|
||||||
{
|
{
|
||||||
if (i == notthisplayer)
|
if (i == notthisplayer)
|
||||||
|
@ -221,42 +218,43 @@ splash(projectile *p, OFVector3D &v, OFVector3D &vold, int notthisplayer,
|
||||||
dynent *o = players[i];
|
dynent *o = players[i];
|
||||||
if (!o)
|
if (!o)
|
||||||
continue;
|
continue;
|
||||||
radialeffect(o, v, i, qdam, p->owner);
|
radialeffect(o, v, i, qdam, p.owner);
|
||||||
}
|
}
|
||||||
dvector &mv = getmonsters();
|
dvector &mv = getmonsters();
|
||||||
loopv(mv) if (i != notthismonster)
|
loopv(mv) if (i != notthismonster)
|
||||||
radialeffect(mv[i], v, i, qdam, p->owner);
|
radialeffect(mv[i], v, i, qdam, p.owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
projdamage(dynent *o, projectile *p, OFVector3D &v, int i, int im, int qdam)
|
projdamage(dynent *o, Projectile *p, OFVector3D &v, int i, int im, int qdam)
|
||||||
{
|
{
|
||||||
if (o->state != CS_ALIVE)
|
if (o->state != CS_ALIVE)
|
||||||
return;
|
return;
|
||||||
if (intersect(o, p->o, v)) {
|
if (intersect(o, p.o, v)) {
|
||||||
splash(p, v, p->o, i, im, qdam);
|
splash(p, v, p.o, i, im, qdam);
|
||||||
hit(i, qdam, o, p->owner);
|
hit(i, qdam, o, p.owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
moveprojectiles(float time)
|
moveprojectiles(float time)
|
||||||
{
|
{
|
||||||
loopi(MAXPROJ)
|
for (size_t i = 0; i < MAXPROJ; i++) {
|
||||||
{
|
Projectile *p = projs[i];
|
||||||
projectile *p = &projs[i];
|
|
||||||
if (!p->inuse)
|
if (!p.inuse)
|
||||||
continue;
|
continue;
|
||||||
int qdam = guns[p->gun].damage * (p->owner->quadmillis ? 4 : 1);
|
|
||||||
if (p->owner->monsterstate)
|
int qdam = guns[p.gun].damage * (p.owner->quadmillis ? 4 : 1);
|
||||||
|
if (p.owner->monsterstate)
|
||||||
qdam /= MONSTERDAMAGEFACTOR;
|
qdam /= MONSTERDAMAGEFACTOR;
|
||||||
vdist(dist, v, p->o, p->to);
|
vdist(dist, v, p.o, p.to);
|
||||||
float dtime = dist * 1000 / p->speed;
|
float dtime = dist * 1000 / p.speed;
|
||||||
if (time > dtime)
|
if (time > dtime)
|
||||||
dtime = time;
|
dtime = time;
|
||||||
vmul(v, time / dtime);
|
vmul(v, time / dtime);
|
||||||
vadd(v, p->o) if (p->local)
|
vadd(v, p.o) if (p.local)
|
||||||
{
|
{
|
||||||
loopv(players)
|
loopv(players)
|
||||||
{
|
{
|
||||||
|
@ -265,28 +263,28 @@ moveprojectiles(float time)
|
||||||
continue;
|
continue;
|
||||||
projdamage(o, p, v, i, -1, qdam);
|
projdamage(o, p, v, i, -1, qdam);
|
||||||
}
|
}
|
||||||
if (p->owner != player1)
|
if (p.owner != player1)
|
||||||
projdamage(player1, p, v, -1, -1, qdam);
|
projdamage(player1, p, v, -1, -1, qdam);
|
||||||
dvector &mv = getmonsters();
|
dvector &mv = getmonsters();
|
||||||
loopv(mv) if (!vreject(mv[i]->o, v, 10.0f) &&
|
loopv(mv) if (!vreject(mv[i]->o, v, 10.0f) &&
|
||||||
mv[i] != p->owner)
|
mv[i] != p.owner)
|
||||||
projdamage(mv[i], p, v, -1, i, qdam);
|
projdamage(mv[i], p, v, -1, i, qdam);
|
||||||
}
|
}
|
||||||
if (p->inuse) {
|
if (p.inuse) {
|
||||||
if (time == dtime)
|
if (time == dtime)
|
||||||
splash(p, v, p->o, -1, -1, qdam);
|
splash(p, v, p.o, -1, -1, qdam);
|
||||||
else {
|
else {
|
||||||
if (p->gun == GUN_RL) {
|
if (p.gun == GUN_RL) {
|
||||||
dodynlight(p->o, v, 0, 255, p->owner);
|
dodynlight(p.o, v, 0, 255, p.owner);
|
||||||
particle_splash(5, 2, 200, v);
|
particle_splash(5, 2, 200, v);
|
||||||
} else {
|
} else {
|
||||||
particle_splash(1, 1, 200, v);
|
particle_splash(1, 1, 200, v);
|
||||||
particle_splash(
|
particle_splash(
|
||||||
guns[p->gun].part, 1, 1, v);
|
guns[p.gun].part, 1, 1, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->o = v;
|
p.o = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,8 +200,8 @@ cleardlights()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dodynlight(
|
dodynlight(const OFVector3D &vold, const OFVector3D &v, int reach, int strength,
|
||||||
OFVector3D &vold, OFVector3D &v, int reach, int strength, dynent *owner)
|
dynent *owner)
|
||||||
{
|
{
|
||||||
if (!reach)
|
if (!reach)
|
||||||
reach = dynlight;
|
reach = dynlight;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue