Cube  Diff

Differences From Artifact [f745b5a428]:

To Artifact [0816ef168b]:


1
2
3
4

5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
12




+







// entities.cpp: map entity related functions (pickup etc.)

#include "cube.h"

#import "DynamicEntity.h"
#import "MapModelInfo.h"

vector<entity> ents;

static OFString *entmdlnames[] = {
	@"shells",
	@"bullets",
118
119
120
121
122
123
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
169
170
171
172


173
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
119
120
121
122
123
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
169
170
171
172


173
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







-
+





-
-
+
+







+



-
+



-
+


-
+


-
+


-
+


-
+


-
+



-
-
+
+



-
-
+
+



-
+








-
+

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



+

-
+











-
+
-
-
-
-
+
+
-
+








-
+


+
-
-
+
+
+
+
-



-
+


-
+


-
+


-
+


-
+


-
+




-
+

-
+



-
+



-
+







	{ 150, 150, S_ITEMARMOUR },
	{ 20000, 30000, S_ITEMPUP },
};

void
baseammo(int gun)
{
	player1->ammo[gun] = itemstats[gun - 1].add * 2;
	player1.ammo[gun] = itemstats[gun - 1].add * 2;
}

// these two functions are called when the server acknowledges that you really
// picked up the item (in multiplayer someone may grab it before you).

void
radditem(int i, int &v)
static int
radditem(int i, int v)
{
	itemstat &is = itemstats[ents[i].type - I_SHELLS];
	ents[i].spawned = false;
	v += is.add;
	if (v > is.max)
		v = is.max;
	playsoundc(is.sound);
	return v;
}

void
realpickup(int n, dynent *d)
realpickup(int n, DynamicEntity *d)
{
	switch (ents[n].type) {
	case I_SHELLS:
		radditem(n, d->ammo[1]);
		d.ammo[1] = radditem(n, d.ammo[1]);
		break;
	case I_BULLETS:
		radditem(n, d->ammo[2]);
		d.ammo[2] = radditem(n, d.ammo[2]);
		break;
	case I_ROCKETS:
		radditem(n, d->ammo[3]);
		d.ammo[3] = radditem(n, d.ammo[3]);
		break;
	case I_ROUNDS:
		radditem(n, d->ammo[4]);
		d.ammo[4] = radditem(n, d.ammo[4]);
		break;
	case I_HEALTH:
		radditem(n, d->health);
		d.health = radditem(n, d.health);
		break;
	case I_BOOST:
		radditem(n, d->health);
		d.health = radditem(n, d.health);
		break;

	case I_GREENARMOUR:
		radditem(n, d->armour);
		d->armourtype = A_GREEN;
		d.armour = radditem(n, d.armour);
		d.armourtype = A_GREEN;
		break;

	case I_YELLOWARMOUR:
		radditem(n, d->armour);
		d->armourtype = A_YELLOW;
		d.armour = radditem(n, d.armour);
		d.armourtype = A_YELLOW;
		break;

	case I_QUAD:
		radditem(n, d->quadmillis);
		d.quadmillis = radditem(n, d.quadmillis);
		conoutf(@"you got the quad!");
		break;
	}
}

// these functions are called when the client touches the item

void
additem(int i, int &v, int spawnsec)
additem(int i, int v, int spawnsec)
{
	// don't pick up if not needed
	if (v < itemstats[ents[i].type - I_SHELLS]
	            .max) // don't pick up if not needed
	if (v < itemstats[ents[i].type - I_SHELLS].max) {
		// first ask the server for an ack even if someone else gets it
		// first
	{
		addmsg(1, 3, SV_ITEMPICKUP, i,
		addmsg(1, 3, SV_ITEMPICKUP, i, m_classicsp ? 100000 : spawnsec);
		    m_classicsp ? 100000
		                : spawnsec); // first ask the server for an ack
		ents[i].spawned = false; // even if someone else gets it first
		ents[i].spawned = false;
	}
}

// also used by monsters
void
teleport(int n, dynent *d) // also used by monsters
teleport(int n, DynamicEntity *d)
{
	int e = -1, tag = ents[n].attr1, beenhere = -1;
	for (;;) {
		e = findentity(TELEDEST, e + 1);
		if (e == beenhere || e < 0) {
			conoutf(@"no teleport destination for tag %d", tag);
			return;
		}
		if (beenhere < 0)
			beenhere = e;
		if (ents[e].attr2 == tag) {
			d->o.x = ents[e].x;
			d.o = OFMakeVector3D(ents[e].x, ents[e].y, ents[e].z);
			d->o.y = ents[e].y;
			d->o.z = ents[e].z;
			d->yaw = ents[e].attr1;
			d->pitch = 0;
			d.yaw = ents[e].attr1;
			d.pitch = 0;
			d->vel.x = d->vel.y = d->vel.z = 0;
			d.vel = OFMakeVector3D(0, 0, 0);
			entinmap(d);
			playsoundc(S_TELEPORT);
			break;
		}
	}
}

void
pickup(int n, dynent *d)
pickup(int n, DynamicEntity *d)
{
	int np = 1;
	for (id player in players)
	loopv(players) if (players[i]) np++;
	np = np < 3 ? 4 : (np > 4 ? 2 : 3); // spawn times are dependent on
		if (player != [OFNull null])
			np++;
	// spawn times are dependent on number of players
	np = np < 3 ? 4 : (np > 4 ? 2 : 3);
	                                    // number of players
	int ammo = np * 2;
	switch (ents[n].type) {
	case I_SHELLS:
		additem(n, d->ammo[1], ammo);
		additem(n, d.ammo[1], ammo);
		break;
	case I_BULLETS:
		additem(n, d->ammo[2], ammo);
		additem(n, d.ammo[2], ammo);
		break;
	case I_ROCKETS:
		additem(n, d->ammo[3], ammo);
		additem(n, d.ammo[3], ammo);
		break;
	case I_ROUNDS:
		additem(n, d->ammo[4], ammo);
		additem(n, d.ammo[4], ammo);
		break;
	case I_HEALTH:
		additem(n, d->health, np * 5);
		additem(n, d.health, np * 5);
		break;
	case I_BOOST:
		additem(n, d->health, 60);
		additem(n, d.health, 60);
		break;

	case I_GREENARMOUR:
		// (100h/100g only absorbs 166 damage)
		if (d->armourtype == A_YELLOW && d->armour > 66)
		if (d.armourtype == A_YELLOW && d.armour > 66)
			break;
		additem(n, d->armour, 20);
		additem(n, d.armour, 20);
		break;

	case I_YELLOWARMOUR:
		additem(n, d->armour, 20);
		additem(n, d.armour, 20);
		break;

	case I_QUAD:
		additem(n, d->quadmillis, 60);
		additem(n, d.quadmillis, 60);
		break;

	case CARROT:
		ents[n].spawned = false;
		triggertime = lastmillis;
		trigger(ents[n].attr1, ents[n].attr2,
		    false); // needs to go over server for multiplayer
282
283
284
285
286
287
288
289
290


291
292
293
294
295
296
297
284
285
286
287
288
289
290


291
292
293
294
295
296
297
298
299







-
-
+
+







	case JUMPPAD: {
		static int lastjumppad = 0;
		if (lastmillis - lastjumppad < 300)
			break;
		lastjumppad = lastmillis;
		OFVector3D v = OFMakeVector3D((int)(char)ents[n].attr3 / 10.0f,
		    (int)(char)ents[n].attr2 / 10.0f, ents[n].attr1 / 10.0f);
		player1->vel.z = 0;
		vadd(player1->vel, v);
		player1.vel = OFMakeVector3D(player1.vel.x, player1.vel.y, 0);
		vadd(player1.vel, v);
		playsoundc(S_JUMPPAD);
		break;
	}
	}
}

void
305
306
307
308
309
310
311
312
313


314
315
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
307
308
309
310
311
312
313


314
315
316
317
318
319
320
321
322
323


324
325
326
327
328
329
330
331
332







-
-
+
+








-
-
+
+







		if (e.type == NOTUSED)
			continue;
		if (!ents[i].spawned && e.type != TELEPORT && e.type != JUMPPAD)
			continue;
		if (OUTBORD(e.x, e.y))
			continue;
		OFVector3D v = OFMakeVector3D(
		    e.x, e.y, (float)S(e.x, e.y)->floor + player1->eyeheight);
		vdist(dist, t, player1->o, v);
		    e.x, e.y, (float)S(e.x, e.y)->floor + player1.eyeheight);
		vdist(dist, t, player1.o, v);
		if (dist < (e.type == TELEPORT ? 4 : 2.5))
			pickup(i, player1);
	}
}

void
checkquad(int time)
{
	if (player1->quadmillis && (player1->quadmillis -= time) < 0) {
		player1->quadmillis = 0;
	if (player1.quadmillis && (player1.quadmillis -= time) < 0) {
		player1.quadmillis = 0;
		playsoundc(S_PUPOUT);
		conoutf(@"quad damage is over");
	}
}

void
putitems(uchar *&p) // puts items in network stream and also spawns them locally