1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: actsprite.cpp
5 	Desc: behavior function for sprite effects
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 #include "main.hpp"
13 #include "game.hpp"
14 #include "sound.hpp"
15 #include "net.hpp"
16 #include "collision.hpp"
17 #include "entity.hpp"
18 #include "interface/interface.hpp"
19 
20 /*-------------------------------------------------------------------------------
21 
22 	act*
23 
24 	The following function describes an entity behavior. The function
25 	takes a pointer to the entity that uses it as an argument.
26 
27 -------------------------------------------------------------------------------*/
28 
29 #define SPRITE_DESTROY my->skill[0]
30 #define SPRITE_FRAMES my->skill[1]
31 #define SPRITE_ANIMSPEED my->skill[2]
32 #define SPRITE_LIT my->skill[5]
33 
actSprite(Entity * my)34 void actSprite(Entity* my)
35 {
36 	if ( !my->skill[6] && SPRITE_LIT )
37 	{
38 		my->skill[6] = 1;
39 		my->light = lightSphereShadow(my->x / 16, my->y / 16, SPRITE_LIT, 256);
40 	}
41 	else if ( !SPRITE_LIT )
42 	{
43 		my->light = NULL;
44 	}
45 	my->skill[3]++;
46 	if ( my->skill[3] >= SPRITE_ANIMSPEED )
47 	{
48 		my->skill[3] = 0;
49 		my->skill[4]++;
50 		my->sprite++;
51 		if ( my->skill[4] >= SPRITE_FRAMES )
52 		{
53 			my->skill[4] -= SPRITE_FRAMES;
54 			my->sprite -= SPRITE_FRAMES;
55 			if ( SPRITE_DESTROY )
56 			{
57 				my->removeLightField();
58 				list_RemoveNode(my->mynode);
59 				return;
60 			}
61 		}
62 	}
63 }
64 
actSpriteNametag(Entity * my)65 void actSpriteNametag(Entity* my)
66 {
67 	Entity* parent = uidToEntity(my->parent);
68 	if ( parent )
69 	{
70 		if ( !hide_playertags )
71 		{
72 			my->flags[INVISIBLE] = false;
73 			my->x = parent->x;
74 			my->y = parent->y;
75 		}
76 		else
77 		{
78 			my->flags[INVISIBLE] = true;
79 		}
80 	}
81 	else
82 	{
83 		my->flags[INVISIBLE] = true;
84 		list_RemoveNode(my->mynode);
85 	}
86 }
87 
spawnBang(Sint16 x,Sint16 y,Sint16 z)88 Entity* spawnBang(Sint16 x, Sint16 y, Sint16 z)
89 {
90 	int c;
91 	if ( multiplayer == SERVER )
92 	{
93 		for ( c = 1; c < MAXPLAYERS; c++ )
94 		{
95 			if ( client_disconnected[c] )
96 			{
97 				continue;
98 			}
99 			strcpy((char*)net_packet->data, "BANG");
100 			SDLNet_Write16(x, &net_packet->data[4]);
101 			SDLNet_Write16(y, &net_packet->data[6]);
102 			SDLNet_Write16(z, &net_packet->data[8]);
103 			net_packet->address.host = net_clients[c - 1].host;
104 			net_packet->address.port = net_clients[c - 1].port;
105 			net_packet->len = 10;
106 			sendPacketSafe(net_sock, -1, net_packet, c - 1);
107 		}
108 	}
109 
110 	// bang
111 	Entity* entity = newEntity(23, 1, map.entities, nullptr); //Sprite entity.
112 	entity->x = x;
113 	entity->y = y;
114 	entity->z = z;
115 	entity->flags[SPRITE] = true;
116 	entity->flags[PASSABLE] = true;
117 	entity->flags[BRIGHT] = true;
118 	entity->flags[NOUPDATE] = true;
119 	entity->flags[UNCLICKABLE] = true;
120 	entity->behavior = &actSprite;
121 	entity->skill[0] = 1;
122 	entity->skill[1] = 4;
123 	entity->skill[2] = 4;
124 	playSoundEntityLocal(entity, 66, 64);
125 	if ( multiplayer != CLIENT )
126 	{
127 		entity_uids--;
128 	}
129 	entity->setUID(-3);
130 	return entity;
131 }
132 
spawnExplosion(Sint16 x,Sint16 y,Sint16 z)133 Entity* spawnExplosion(Sint16 x, Sint16 y, Sint16 z)
134 {
135 	int c, i;
136 	if ( multiplayer == SERVER )
137 	{
138 		for ( c = 1; c < MAXPLAYERS; c++ )
139 		{
140 			if ( client_disconnected[c] )
141 			{
142 				continue;
143 			}
144 			strcpy((char*)net_packet->data, "EXPL");
145 			SDLNet_Write16(x, &net_packet->data[4]);
146 			SDLNet_Write16(y, &net_packet->data[6]);
147 			SDLNet_Write16(z, &net_packet->data[8]);
148 			net_packet->address.host = net_clients[c - 1].host;
149 			net_packet->address.port = net_clients[c - 1].port;
150 			net_packet->len = 10;
151 			sendPacketSafe(net_sock, -1, net_packet, c - 1);
152 		}
153 	}
154 
155 	// boom
156 	Entity* entity = newEntity(49, 1, map.entities, nullptr); //Sprite entity.
157 	entity->x = x;
158 	entity->y = y;
159 	entity->z = z;
160 	entity->flags[SPRITE] = true;
161 	entity->flags[PASSABLE] = true;
162 	entity->flags[BRIGHT] = true;
163 	entity->flags[NOUPDATE] = true;
164 	entity->flags[UNCLICKABLE] = true;
165 	entity->behavior = &actSprite;
166 	entity->skill[0] = 1;
167 	entity->skill[1] = 4;
168 	entity->skill[2] = 4;
169 	Entity* my = entity;
170 	SPRITE_FRAMES = 10;
171 	SPRITE_ANIMSPEED = 2;
172 	SPRITE_LIT = 4;
173 	playSoundEntityLocal(entity, 153, 128);
174 	Entity* explosion = entity;
175 	for (i = 0; i < 10; ++i)
176 	{
177 		entity = newEntity(16, 1, map.entities, nullptr); //Sprite entity.
178 		entity->behavior = &actFlame;
179 		entity->x = explosion->x;
180 		entity->y = explosion->y;
181 		entity->z = explosion->z;
182 		entity->flags[SPRITE] = true;
183 		entity->flags[NOUPDATE] = true;
184 		entity->flags[UPDATENEEDED] = false;
185 		entity->flags[BRIGHT] = true;
186 		entity->flags[PASSABLE] = true;
187 		//entity->scalex = 0.25f; //MAKE 'EM SMALL PLEASE!
188 		//entity->scaley = 0.25f;
189 		//entity->scalez = 0.25f;
190 		entity->vel_x = (-40 + rand() % 81) / 8.f;
191 		entity->vel_y = (-40 + rand() % 81) / 8.f;
192 		entity->vel_z = (-40 + rand() % 81) / 8.f;
193 		entity->skill[0] = 15 + rand() % 10;
194 	}
195 	if ( multiplayer != CLIENT )
196 	{
197 		entity_uids--;
198 	}
199 	entity->setUID(-3);
200 	return explosion;
201 }
202 
spawnExplosionFromSprite(Uint16 sprite,Sint16 x,Sint16 y,Sint16 z)203 Entity* spawnExplosionFromSprite(Uint16 sprite, Sint16 x, Sint16 y, Sint16 z)
204 {
205 	int c, i;
206 	if ( multiplayer == SERVER )
207 	{
208 		for ( c = 1; c < MAXPLAYERS; c++ )
209 		{
210 			if ( client_disconnected[c] )
211 			{
212 				continue;
213 			}
214 			strcpy((char*)net_packet->data, "EXPS");
215 			SDLNet_Write16(sprite, &net_packet->data[4]);
216 			SDLNet_Write16(x, &net_packet->data[6]);
217 			SDLNet_Write16(y, &net_packet->data[8]);
218 			SDLNet_Write16(z, &net_packet->data[10]);
219 			net_packet->address.host = net_clients[c - 1].host;
220 			net_packet->address.port = net_clients[c - 1].port;
221 			net_packet->len = 12;
222 			sendPacketSafe(net_sock, -1, net_packet, c - 1);
223 		}
224 	}
225 
226 	// boom
227 	Entity* entity;
228 	if ( sprite == 0 )
229 	{
230 		entity = newEntity(-1, 1, map.entities, nullptr); //Sprite entity.
231 		entity->flags[INVISIBLE] = true;
232 	}
233 	else
234 	{
235 		entity = newEntity(sprite, 1, map.entities, nullptr); //Sprite entity.
236 	}
237 	entity->x = x;
238 	entity->y = y;
239 	entity->z = z;
240 	entity->flags[SPRITE] = true;
241 	entity->flags[PASSABLE] = true;
242 	entity->flags[BRIGHT] = true;
243 	entity->flags[NOUPDATE] = true;
244 	entity->flags[UNCLICKABLE] = true;
245 	entity->behavior = &actSprite;
246 	entity->skill[0] = 1;
247 	entity->skill[1] = 4;
248 	entity->skill[2] = 4;
249 	Entity* my = entity;
250 	SPRITE_FRAMES = 10;
251 	SPRITE_ANIMSPEED = 2;
252 	SPRITE_LIT = 4;
253 	playSoundEntityLocal(entity, 153, 128);
254 	Entity* explosion = entity;
255 	for ( i = 0; i < 10; ++i )
256 	{
257 		entity = newEntity(16, 1, map.entities, nullptr); //Sprite entity.
258 		entity->behavior = &actFlame;
259 		entity->x = explosion->x;
260 		entity->y = explosion->y;
261 		entity->z = explosion->z;
262 		entity->flags[SPRITE] = true;
263 		entity->flags[NOUPDATE] = true;
264 		entity->flags[UPDATENEEDED] = false;
265 		entity->flags[BRIGHT] = true;
266 		entity->flags[PASSABLE] = true;
267 		//entity->scalex = 0.25f; //MAKE 'EM SMALL PLEASE!
268 		//entity->scaley = 0.25f;
269 		//entity->scalez = 0.25f;
270 		entity->vel_x = (-40 + rand() % 81) / 8.f;
271 		entity->vel_y = (-40 + rand() % 81) / 8.f;
272 		entity->vel_z = (-40 + rand() % 81) / 8.f;
273 		entity->skill[0] = 15 + rand() % 10;
274 	}
275 	if ( multiplayer != CLIENT )
276 	{
277 		entity_uids--;
278 	}
279 	entity->setUID(-3);
280 	return explosion;
281 }
282 
actSleepZ(Entity * my)283 void actSleepZ(Entity* my)
284 {
285 	// spin around
286 	my->x -= my->fskill[0];
287 	my->y -= my->fskill[1];
288 	my->fskill[0] = cos((ticks % 360) * (PI / 180)) * my->scalex * 3;
289 	my->fskill[1] = sin((ticks % 360) * (PI / 180)) * my->scaley * 3;
290 	my->x += my->fskill[0];
291 	my->y += my->fskill[1];
292 
293 	// go up
294 	my->z -= .2;
295 	if ( my->z < -128 )
296 	{
297 		list_RemoveNode(my->mynode);
298 		return;
299 	}
300 
301 	// scale up
302 	my->scalex = fmin(my->scalex + 0.01, 0.75);
303 	my->scaley = fmin(my->scaley + 0.01, 0.75);
304 	my->scalez = fmin(my->scalez + 0.01, 0.75);
305 }
306 
spawnSleepZ(Sint16 x,Sint16 y,Sint16 z)307 Entity* spawnSleepZ(Sint16 x, Sint16 y, Sint16 z)
308 {
309 	int c;
310 
311 	if ( multiplayer == SERVER )
312 	{
313 		for ( c = 1; c < MAXPLAYERS; c++ )
314 		{
315 			if ( client_disconnected[c] )
316 			{
317 				continue;
318 			}
319 			strcpy((char*)net_packet->data, "SLEZ");
320 			SDLNet_Write16(x, &net_packet->data[4]);
321 			SDLNet_Write16(y, &net_packet->data[6]);
322 			SDLNet_Write16(z, &net_packet->data[8]);
323 			net_packet->address.host = net_clients[c - 1].host;
324 			net_packet->address.port = net_clients[c - 1].port;
325 			net_packet->len = 10;
326 			sendPacketSafe(net_sock, -1, net_packet, c - 1);
327 		}
328 	}
329 
330 	Entity* entity = newEntity(47, 1, map.entities, nullptr); //Sprite entity.
331 	entity->behavior = &actSleepZ;
332 	entity->x = x;
333 	entity->y = y;
334 	entity->z = z;
335 	entity->flags[SPRITE] = true;
336 	entity->flags[PASSABLE] = true;
337 	entity->flags[UPDATENEEDED] = false;
338 	entity->flags[NOUPDATE] = true;
339 	entity->flags[UNCLICKABLE] = true;
340 	entity->scalex = 0.05;
341 	entity->scaley = 0.05;
342 	entity->scalez = 0.05;
343 	entity->sizex = 1;
344 	entity->sizey = 1;
345 	if ( multiplayer != CLIENT )
346 	{
347 		entity_uids--;
348 	}
349 	entity->setUID(-3);
350 
351 	return entity;
352 }
353 
spawnFloatingSpriteMisc(int sprite,Sint16 x,Sint16 y,Sint16 z)354 Entity* spawnFloatingSpriteMisc(int sprite, Sint16 x, Sint16 y, Sint16 z)
355 {
356 	int c;
357 
358 	if ( multiplayer == SERVER )
359 	{
360 		for ( c = 1; c < MAXPLAYERS; c++ )
361 		{
362 			if ( client_disconnected[c] )
363 			{
364 				continue;
365 			}
366 			strcpy((char*)net_packet->data, "SLEM");
367 			SDLNet_Write16(x, &net_packet->data[4]);
368 			SDLNet_Write16(y, &net_packet->data[6]);
369 			SDLNet_Write16(z, &net_packet->data[8]);
370 			SDLNet_Write16(sprite, &net_packet->data[10]);
371 			net_packet->address.host = net_clients[c - 1].host;
372 			net_packet->address.port = net_clients[c - 1].port;
373 			net_packet->len = 12;
374 			sendPacketSafe(net_sock, -1, net_packet, c - 1);
375 		}
376 	}
377 
378 	Entity* entity = newEntity(sprite, 1, map.entities, nullptr); //Sprite entity.
379 	entity->behavior = &actSleepZ;
380 	entity->x = x;
381 	entity->y = y;
382 	entity->z = z;
383 	entity->flags[SPRITE] = true;
384 	entity->flags[PASSABLE] = true;
385 	entity->flags[UPDATENEEDED] = false;
386 	entity->flags[NOUPDATE] = true;
387 	entity->flags[UNCLICKABLE] = true;
388 	entity->scalex = 0.05;
389 	entity->scaley = 0.05;
390 	entity->scalez = 0.05;
391 	entity->sizex = 1;
392 	entity->sizey = 1;
393 	if ( multiplayer != CLIENT )
394 	{
395 		entity_uids--;
396 	}
397 	entity->setUID(-3);
398 
399 	return entity;
400 }