Cube  Diff

Differences From Artifact [a095df6286]:

To Artifact [652afaa3f5]:


1
2
3
4
5

6
7
8
9
10
11
12
13
14
15




16
17
18
19
20
21
22
1
2
3
4

5



6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22




-
+
-
-
-






-
+
+
+
+







// weapon.cpp: all shooting and effects code

#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 SGRAYS = 20;
static const float SGSPREAD = 2;
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_SG, 1400, 10, 0, 0, 20, @"shotgun" }, // *SGRAYS
	{ S_CG, 100, 30, 0, 0, 7, @"chaingun" },
	{ S_RLFIRE, 800, 120, 80, 0, 10, @"rocketlauncher" },
	{ S_RIFLE, 1500, 100, 0, 0, 30, @"rifle" },
	{ S_FLAUNCH, 200, 20, 50, 4, 1, @"fireball" },
	{ S_ICEBALL, 200, 40, 30, 6, 1, @"iceball" },
79
80
81
82
83
84
85

86
87

88
89
90


91
92
93
94
95
96
97
79
80
81
82
83
84
85
86
87

88

89

90
91
92
93
94
95
96
97
98







+

-
+
-

-
+
+







#define RNDD (rnd(101) - 50) * f
		OFVector3D r = OFMakeVector3D(RNDD, RNDD, RNDD);
		sg[i] = to;
		vadd(sg[i], r);
	}
}

// if lineseg hits entity bounding box
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(w, from);
	float c1 = dotprod(w, v);

	if (c1 <= 0)
		p = &from;
	else {
124
125
126
127
128
129
130
131

132
133
134
135
136
137
138

139
140
141
142

143

144
145
146
147
148
149
150
151



152
153

154

155
156
157
158
159
160
161







162
163
164
165
166
167
168
125
126
127
128
129
130
131

132







133
134
135
136
137
138

139
140
141
142
143
144
145


146
147
148


149
150
151







152
153
154
155
156
157
158
159
160
161
162
163
164
165







-
+
-
-
-
-
-
-
-
+




+
-
+






-
-
+
+
+
-
-
+

+
-
-
-
-
-
-
-
+
+
+
+
+
+
+







		if (intersect(o, player1->o, worldpos))
			return @(o->name);
	}

	return nil;
}

const int MAXPROJ = 100;
static const size_t MAXPROJ = 100;
struct projectile {
	OFVector3D o, to;
	float speed;
	dynent *owner;
	int gun;
	bool inuse, local;
} projs[MAXPROJ];
static Projectile *projs[MAXPROJ];

void
projreset()
{
	for (size_t i = 0; i < MAXPROJ; i++)
	loopi(MAXPROJ) projs[i].inuse = false;
		projs[i].inuse = false;
}

void
newprojectile(OFVector3D &from, OFVector3D &to, float speed, bool local,
    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;

		p->inuse = true;
		p->o = from;
		p->to = to;
		p->speed = speed;
		p->local = local;
		p->owner = owner;
		p->gun = gun;
		p.inuse = true;
		p.o = from;
		p.to = to;
		p.speed = speed;
		p.local = local;
		p.owner = owner;
		p.gun = gun;
		return;
	}
}

void
hit(int target, int damage, dynent *d, dynent *at)
{
177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203


204
205
206
207


208
209
210
211
212
213
214


215
216

217
218
219
220
221
222
223
224

225
226
227
228

229
230
231
232
233

234
235
236
237
238
239



240
241
242
243
244
245
246
247



248
249

250

251
252


253
254
255


256
257
258
259

260
261
262
263
264
265
266
267
268

269
270
271
272

273
274
275

276
277

278
279
280


281
282
283
284
285

286
287
288
289

290
291
292
293
294
295
296
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198


199
200
201
202


203
204
205
206
207
208
209


210
211
212

213
214
215
216
217
218
219
220

221
222
223
224

225
226
227
228
229

230
231
232
233



234
235
236
237
238
239
240
241
242


243
244
245


246
247
248


249
250
251


252
253
254
255
256

257
258
259
260
261
262
263
264
265

266
267
268
269

270
271
272

273
274

275
276


277
278
279
280
281
282

283
284
285
286

287
288
289
290
291
292
293
294







-
-
+
+
















-
-
+
+


-
-
+
+





-
-
+
+

-
+







-
+



-
+




-
+



-
-
-
+
+
+






-
-
+
+
+
-
-
+

+
-
-
+
+

-
-
+
+



-
+








-
+



-
+


-
+

-
+

-
-
+
+




-
+



-
+







	particle_splash(3, damage, 1000, d->o);
	demodamage(damage, d->o);
}

const float RL_RADIUS = 5;
const float RL_DAMRAD = 7; // hack

void
radialeffect(dynent *o, OFVector3D &v, int cn, int qdam, dynent *at)
static void
radialeffect(dynent *o, const OFVector3D &v, int cn, int qdam, dynent *at)
{
	if (o->state != CS_ALIVE)
		return;
	vdist(dist, temp, v, o->o);
	dist -= 2; // account for eye distance imprecision
	if (dist < RL_DAMRAD) {
		if (dist < 0)
			dist = 0;
		int damage = (int)(qdam * (1 - (dist / RL_DAMRAD)));
		hit(cn, damage, o, at);
		vmul(temp, (RL_DAMRAD - dist) * damage / 800);
		vadd(o->vel, temp);
	}
}

void
splash(projectile *p, OFVector3D &v, OFVector3D &vold, int notthisplayer,
    int notthismonster, int qdam)
splash(Projectile *p, const OFVector3D &v, const OFVector3D &vold,
    int notthisplayer, int notthismonster, int qdam)
{
	particle_splash(0, 50, 300, v);
	p->inuse = false;
	if (p->gun != GUN_RL) {
	p.inuse = false;
	if (p.gun != GUN_RL) {
		playsound(S_FEXPLODE, &v);
		// no push?
	} else {
		playsound(S_RLHIT, &v);
		newsphere(v, RL_RADIUS, 0);
		dodynlight(vold, v, 0, 0, p->owner);
		if (!p->local)
		dodynlight(vold, v, 0, 0, p.owner);
		if (!p.local)
			return;
		radialeffect(player1, v, -1, qdam, p->owner);
		radialeffect(player1, v, -1, qdam, p.owner);
		loopv(players)
		{
			if (i == notthisplayer)
				continue;
			dynent *o = players[i];
			if (!o)
				continue;
			radialeffect(o, v, i, qdam, p->owner);
			radialeffect(o, v, i, qdam, p.owner);
		}
		dvector &mv = getmonsters();
		loopv(mv) if (i != notthismonster)
		    radialeffect(mv[i], v, i, qdam, p->owner);
		    radialeffect(mv[i], v, i, qdam, p.owner);
	}
}

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)
		return;
	if (intersect(o, p->o, v)) {
		splash(p, v, p->o, i, im, qdam);
		hit(i, qdam, o, p->owner);
	if (intersect(o, p.o, v)) {
		splash(p, v, p.o, i, im, qdam);
		hit(i, qdam, o, p.owner);
	}
}

void
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;

		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;
		vdist(dist, v, p->o, p->to);
		float dtime = dist * 1000 / p->speed;
		vdist(dist, v, p.o, p.to);
		float dtime = dist * 1000 / p.speed;
		if (time > dtime)
			dtime = time;
		vmul(v, time / dtime);
		vadd(v, p->o) if (p->local)
		vadd(v, p.o) if (p.local)
		{
			loopv(players)
			{
				dynent *o = players[i];
				if (!o)
					continue;
				projdamage(o, p, v, i, -1, qdam);
			}
			if (p->owner != player1)
			if (p.owner != player1)
				projdamage(player1, p, v, -1, -1, qdam);
			dvector &mv = getmonsters();
			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);
		}
		if (p->inuse) {
		if (p.inuse) {
			if (time == dtime)
				splash(p, v, p->o, -1, -1, qdam);
				splash(p, v, p.o, -1, -1, qdam);
			else {
				if (p->gun == GUN_RL) {
					dodynlight(p->o, v, 0, 255, p->owner);
				if (p.gun == GUN_RL) {
					dodynlight(p.o, v, 0, 255, p.owner);
					particle_splash(5, 2, 200, v);
				} else {
					particle_splash(1, 1, 200, v);
					particle_splash(
					    guns[p->gun].part, 1, 1, v);
					    guns[p.gun].part, 1, 1, v);
				}
			}
		}
		p->o = v;
		p.o = v;
	}
}

void
shootv(int gun, OFVector3D &from, OFVector3D &to, dynent *d,
    bool local) // create visual effect from a shot
{