1 /**
2  * FreeDink game-specific code
3 
4  * Copyright (C) 1997, 1998, 1999, 2002, 2003  Seth A. Robinson
5  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2012  Sylvain Beucler
6 
7  * This file is part of GNU FreeDink
8 
9  * GNU FreeDink is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 3 of the
12  * License, or (at your option) any later version.
13 
14  * GNU FreeDink is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18 
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see
21  * <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include "freedink.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 
35 #include "gettext.h"
36 #define _(String) gettext(String)
37 
38 #include "fastfile.h"
39 
40 #include "gfx.h"
41 #include "gfx_fonts.h"
42 #include "gfx_palette.h"
43 #include "gfx_sprites.h"
44 #include "gfx_tiles.h"
45 #include "gfx_fade.h"
46 #include "bgm.h"
47 #include "sfx.h"
48 #include "update_frame.h"
49 #include "init.h"
50 #include "io_util.h"
51 #include "paths.h"
52 #include "input.h"
53 #include "log.h"
54 
55 #include "game_engine.h"
56 #include "dinkvar.h"
57 #include "dinkc_console.h"
58 
59 void move(int u, int amount, char kind,  char kindy);
60 void draw_box(rect box, int color);
61 void run_through_tag_list_push(int h);
62 int check_if_move_is_legal(int u);
63 void change_dir_to_diag( int *dir);
64 int hurt_thing(int h, int damage, int special);
65 
66 
67 static int but_timer = 0;
68 
69 /* Blinking selector in the inventory screen */
70 static int item_timer;
71 static int item_pic;
72 
73 /* Fadedown/fadeup counter */
74 static int process_count = 0;
75 
76 
77 /* Fills 'struct seth_joy sjoy' with the current keyboard and/or
78    joystick state */
check_joystick(void)79 void check_joystick(void)
80 {
81   /* Clean-up */
82   /* Actions */
83   {
84     int a = ACTION_FIRST;
85     for (a = ACTION_FIRST; a < ACTION_LAST; a++)
86       sjoy.joybit[a] = 0;
87   }
88 
89   /* Arrows */
90   sjoy.right = 0;
91   sjoy.left = 0;
92   sjoy.up = 0;
93   sjoy.down = 0;
94 
95   /* Arrows triggered (not maintained pressed) */
96   sjoy.rightd = 0;
97   sjoy.leftd = 0;
98   sjoy.upd = 0;
99   sjoy.downd = 0;
100 
101   if (joystick)
102     {
103       SDL_JoystickUpdate();
104       Sint16 x_pos = 0, y_pos = 0;
105       /* SDL counts buttons from 0, not from 1 */
106       int i = 0;
107       for (i = 0; i < NB_BUTTONS; i++)
108 	if (SDL_JoystickGetButton(jinfo, i))
109 	  sjoy.joybit[input_get_button_action(i)] = 1;
110 
111       x_pos = SDL_JoystickGetAxis(jinfo, 0);
112       y_pos = SDL_JoystickGetAxis(jinfo, 1);
113       /* Using thresold=10% (original game) is just enough to get rid
114 	 of the noise. Let's use 30% instead, otherwise Dink will go
115 	 diags too easily. */
116       {
117 	Sint16 threshold = 32767 * 30/100;
118 	if (x_pos < -threshold) sjoy.left  = 1;
119 	if (x_pos > +threshold) sjoy.right = 1;
120 	if (y_pos < -threshold) sjoy.up    = 1;
121 	if (y_pos > +threshold) sjoy.down  = 1;
122       }
123     }
124 
125   /* Only accept keyboard input when console is not active. */
126   if (console_active == 0)
127     {
128       if (GetKeyboard(SDLK_LCTRL) || GetKeyboard(SDLK_RCTRL)) sjoy.joybit[ACTION_ATTACK] = 1;
129       if (GetKeyboard(SDLK_SPACE)) sjoy.joybit[ACTION_TALK] = 1;
130       if (GetKeyboard(SDLK_LSHIFT) || GetKeyboard(SDLK_RSHIFT)) sjoy.joybit[ACTION_MAGIC] = 1;
131       if (GetKeyboard(SDLK_RETURN)) sjoy.joybit[ACTION_INVENTORY] = 1;
132       if (GetKeyboard(SDLK_ESCAPE)) sjoy.joybit[ACTION_MENU] = 1;
133       if (GetKeyboard('6')) sjoy.joybit[ACTION_MAP] = 1;
134       if (GetKeyboard('m')) sjoy.joybit[ACTION_MAP] = 1;
135       if (GetKeyboard('7')) sjoy.joybit[ACTION_BUTTON7] = 1;
136     }
137 
138   {
139     int a = ACTION_FIRST;
140     for (a = ACTION_FIRST; a < ACTION_LAST; a++)
141       {
142 	sjoy.button[a] = 0;
143 	if (sjoy.joybit[a] && sjoy.joybitold[a] == 0)
144 	  /* Button was just pressed */
145 	  sjoy.button[a] = 1;
146 	sjoy.joybitold[a] = sjoy.joybit[a];
147       }
148   }
149 
150   /* Only accept keyboard input when console is not active. */
151   if (console_active == 0)
152     {
153       if (GetKeyboard(SDLK_RIGHT) || sjoy.joybit[ACTION_RIGHT]) sjoy.right = 1;
154       if (GetKeyboard(SDLK_LEFT)  || sjoy.joybit[ACTION_LEFT])  sjoy.left  = 1;
155       if (GetKeyboard(SDLK_DOWN)  || sjoy.joybit[ACTION_DOWN])  sjoy.down  = 1;
156       if (GetKeyboard(SDLK_UP)    || sjoy.joybit[ACTION_UP])    sjoy.up    = 1;
157     }
158 
159   if (sjoy.right && sjoy.rightold == 0)
160     sjoy.rightd = 1;
161   sjoy.rightold = sjoy.right;
162 
163   if (sjoy.left && sjoy.leftold == 0)
164     sjoy.leftd = 1;
165   sjoy.leftold = sjoy.left;
166 
167   if (sjoy.up && sjoy.upold == 0)
168     sjoy.upd = 1;
169   sjoy.upold = sjoy.up;
170 
171   if (sjoy.down && sjoy.downold == 0)
172     sjoy.downd = 1;
173   sjoy.downold = sjoy.down;
174 
175 
176   if (wait4b.active)
177     {
178       //check for dirs
179 
180       if (sjoy.rightd) wait4b.button = 16;
181       if (sjoy.leftd)  wait4b.button = 14;
182       if (sjoy.upd)    wait4b.button = 18;
183       if (sjoy.downd)  wait4b.button = 12;
184 
185       sjoy.rightd = 0;
186       sjoy.downd = 0;
187       sjoy.upd = 0;
188       sjoy.leftd = 0;
189 
190       //check buttons
191       {
192 	int a = ACTION_FIRST;
193 	for (a = ACTION_FIRST; a < ACTION_LAST; a++)
194 	  {
195 	    if (sjoy.button[a])
196 	      //button was pressed
197 	      wait4b.button = a;
198 	    sjoy.button[a] = /*false*/0;
199 	  }
200       }
201 
202       if (wait4b.button != 0)
203 	{
204 	  *presult = wait4b.button;
205 	  wait4b.active = /*false*/0;
206 	  run_script(wait4b.script);
207 	}
208     }
209 }
210 
211 
212 /* Get sprite #h, grab its text and display it */
text_draw(int h)213 void text_draw(int h)
214 {
215 
216 	char crap[200];
217 	char *cr;
218 	rect rcRect;
219 	int color = 0;
220 
221 	if (spr[h].damage == -1)
222 	{
223 		sprintf(crap, "%s", spr[h].text);
224 		cr = &crap[0];
225 		color = 14;
226 		while( cr[0] == '`')
227 		{
228 			//color code at top
229 			if (cr[1] == '#') color = 13;
230 			if (cr[1] == '1') color = 1;
231 			if (cr[1] == '2') color = 2;
232 			if (cr[1] == '3') color = 3;
233 			if (cr[1] == '5') color = 5;
234 			if (cr[1] == '6') color = 6;
235 			if (cr[1] == '7') color = 7;
236 			if (cr[1] == '8') color = 8;
237 			if (cr[1] == '9') color = 9;
238 			if (cr[1] == '0') color = 10;
239 			if (cr[1] == '$') color = 14;
240 			if (cr[1] == '%') color = 15;
241 
242 			if (dversion >= 108)
243 			  {
244 			    //support for additional colors
245 			    if (cr[1] == '@')
246 			      color = 12;
247 			    if (cr[1] == '!')
248 			      color = 11;
249 			  }
250 
251 			if (cr[1] == '4') color = 4;
252 			cr = &cr[2];
253 		}
254 
255 		//Msg("Final is %s.",cr);
256 		if (spr[h].owner == 1000)
257 		{
258 			rect_set(&rcRect,spr[h].x,spr[h].y,spr[h].x+620,spr[h].y+400);
259 		} else
260 		{
261 
262 			rect_set(&rcRect,spr[h].x,spr[h].y,spr[h].x+150,spr[h].y+150);
263 
264 			if (spr[h].x+150 > 620)
265 				rect_offset(&rcRect, ((spr[h].x+150)-620) - (((spr[h].x+150)-620) * 2), 0);
266 
267 
268 
269 		}
270 
271 	} else
272 	{
273 
274 
275 		sprintf(crap, "%d", spr[h].damage);
276 		cr = &crap[0];
277 		if (spr[h].brain_parm == 5000)
278 			color = 14;
279 
280 
281 		if (spr[h].y < 0) spr[h].y = 0;
282 		rect_set(&rcRect,spr[h].x,spr[h].y,spr[h].x+50 ,spr[h].y+50);
283 
284 
285 	}
286 
287 
288 	/* During a fadedown/fadeup, use white text to mimic v1.07 */
289 	if (truecolor_fade_brightness < 256)
290 	  color = 15;
291 
292 
293 /* 	SetTextColor(hdc,RGB(8,14,21)); */
294 	// FONTS
295 	FONTS_SetTextColor(8, 14, 21);
296 	   if (spr[h].owner == 1200)
297 	   {
298 	     printf("1200 says %s\n", cr);
299 		   //this text has no sprite, and doesn't want to be centered.
300 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_WORDBREAK); */
301 		   // FONTS
302 	     print_text_wrap(cr, &rcRect, 0, 0, FONT_DIALOG);
303 
304 		   rect_offset(&rcRect,-2,0);
305 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_WORDBREAK); */
306 		   // FONTS
307 		   print_text_wrap(cr, &rcRect, 0, 0, FONT_DIALOG);
308 
309 		   rect_offset(&rcRect,1,1);
310 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_WORDBREAK); */
311 		   // FONTS
312 		   print_text_wrap(cr, &rcRect, 0, 0, FONT_DIALOG);
313 
314 		   rect_offset(&rcRect,0,-2);
315 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_WORDBREAK); */
316 		   // FONTS
317 		   print_text_wrap(cr, &rcRect, 0, 0, FONT_DIALOG);
318 	   }
319 	   else
320 	   {
321 
322 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_CENTER | DT_WORDBREAK); */
323 		   // FONTS
324 	     print_text_wrap(cr, &rcRect, 1, 0, FONT_DIALOG);
325 
326 		   rect_offset(&rcRect,-2,0);
327 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_CENTER | DT_WORDBREAK); */
328 		   // FONTS
329 		   print_text_wrap(cr, &rcRect, 1, 0, FONT_DIALOG);
330 
331 		   rect_offset(&rcRect,1,1);
332 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_CENTER | DT_WORDBREAK); */
333 		   // FONTS
334 		   print_text_wrap(cr, &rcRect, 1, 0, FONT_DIALOG);
335 
336 		   rect_offset(&rcRect,0,-2);
337 /* 		   DrawText(hdc,cr,strlen(cr),&rcRect,DT_CENTER | DT_WORDBREAK); */
338 		   // FONTS
339 		   print_text_wrap(cr, &rcRect, 1, 0, FONT_DIALOG);
340 	   }
341 
342 	   rect_offset(&rcRect,0,1);
343 
344 	   // FONTS:
345 	   // support for custom colors
346 	   if (color >= 1 && color <= 15)
347 	     FONTS_SetTextColorIndex(color);
348 	   else
349 	     FONTS_SetTextColor(255, 255, 255);
350 
351 	   if (spr[h].owner == 1200)
352 	     {
353 /* 	       DrawText(hdc,cr,strlen(cr),&rcRect,DT_WORDBREAK); */
354 	       // FONTS
355 	       print_text_wrap(cr, &rcRect, 0, 0, FONT_DIALOG);
356 	     }
357 	   else
358 	     {
359 /* 	       DrawText(hdc,cr,strlen(cr),&rcRect,DT_CENTER | DT_WORDBREAK); */
360 	       // FONTS
361 	       print_text_wrap(cr, &rcRect, 1, 0, FONT_DIALOG);
362 	     }
363 }
364 
365 
get_last_sprite(void)366 void get_last_sprite(void)
367 {
368   int i;
369   for (i = MAX_SPRITES_AT_ONCE - 1; i > 2; i--)
370     {
371       if (spr[i].active)
372 	{
373 	  last_sprite_created = i;
374 	  //   Msg("last sprite created is %d.", i);
375 	  return;
376 	}
377     }
378 }
379 
380 
381 // ********* CHECK TO SEE IF THIS CORD IS ON A HARD SPOT *********
not_in_this_base(int seq,int base)382 /*bool*/int not_in_this_base(int seq, int base)
383 {
384 
385 	int realbase = (seq / 10) * 10;
386 
387 
388 	if (realbase != base)
389 	{
390 
391 
392 		return(/*true*/1);
393 	}
394 	else
395 	{
396 		return(/*false*/0);
397 	}
398 }
399 
in_this_base(int seq,int base)400 /*bool*/int in_this_base(int seq, int base)
401 {
402 
403 	int realbase = (seq / 10) * 10;
404 	if (realbase == base)
405 	{
406 
407 		//	Msg("TRUE - Ok, realbase is %d, compared to the base, which is %d.", realbase, base);
408 		return(/*true*/1);
409 	}
410 	else
411 	{
412 		//	Msg("FALSE - Ok, realbase is %d, compared to the base, which is %d.", realbase, base);
413 
414 		return(/*false*/0);
415 	}
416 }
417 
418 
automove(int j)419 void automove (int j)
420 {
421 
422 	char kindx,kindy;
423 	int speedx = 0;
424 	int speedy = 0;
425 
426 
427 
428 
429 	if (spr[j].mx != 0)
430 	{
431 		if (spr[j].mx < 0)
432 			kindx = '-'; else kindx = '+';
433 		if (kindx == '-') speedx = (spr[j].mx - (spr[j].mx * 2)); else
434 			speedx = spr[j].mx;
435 	} else kindx = '0';
436 
437 	if (spr[j].my != 0)
438 	{
439 		if (spr[j].my < 0)
440 			kindy = '-'; else kindy = '+';
441 		if (kindy == '-') speedy = (spr[j].my - (spr[j].my * 2)); else
442 			speedy = spr[j].my;
443 
444 	} else kindy = '0';
445 
446 	int speed = speedx;
447 	if (speedy > speedx) speed = speedy;
448 	if (speed > 0)
449 		move(j,speed,kindx,kindy);
450 	//move(j, 1, '+','+');
451 
452 }
453 
454 
autoreverse(int j)455 int autoreverse(int j)
456 {
457 	//Msg("reversing die %d",spr[j].dir);
458 	int r = ((rand() % 2)+1);
459 	if ( (spr[j].dir == 1) || (spr[j].dir == 2) )
460 	{
461 		if (r == 1)
462 			return(8);
463 		if (r == 2)
464 			return(6);
465 
466 	}
467 
468 	if ( (spr[j].dir == 3) || (spr[j].dir == 6) )
469 	{
470 		if (r == 1)
471 			return(2);
472 		if (r == 2)
473 
474 			return(4);
475 
476 	}
477 
478     if ( (spr[j].dir == 9) || (spr[j].dir == 8) )
479 	{
480 		if (r == 1)
481 			return(2);
482 		if (r == 2)
483 
484 			return(6);
485 
486 
487 	}
488 
489     if ( (spr[j].dir == 7) || (spr[j].dir == 4) )
490 	{
491 		if (r == 1)
492 			return(8);
493 		if (r == 2)
494 			return(6);
495 
496 	}
497 
498 	return(0);
499 }
500 
501 
autoreverse_diag(int j)502 int autoreverse_diag(int j)
503 {
504 	if (spr[j].dir == 0) spr[j].dir = 7;
505 	int r = ((rand() % 2)+1);
506 
507 	if ( (spr[j].dir == 1) || (spr[j].dir == 3) )
508 	{
509 
510 		if (r == 1)
511 			return(9);
512 		if (r == 2)
513 			return(7);
514 	}
515 
516 	if ( (spr[j].dir == 3) || (spr[j].dir == 6) )
517 	{
518 		if (r == 1)
519 			return(7);
520 		if (r == 2)
521 			return(1);
522 
523 	}
524 
525     if ( (spr[j].dir == 9) || (spr[j].dir == 8) )
526 	{
527 		if (r == 1)
528 			return(1);
529 		if (r == 2)
530 			return(7);
531 	}
532 
533     if ( (spr[j].dir == 7) || (spr[j].dir == 4) )
534 	{
535 		if (r == 1)
536 			return(3);
537 		if (r == 2)
538 			return(9);
539 
540 	}
541 
542 	log_debug("Auto Reverse Diag was sent a dir %d sprite, base %d walk.",spr[j].dir, spr[j].base_walk);
543 	return(0);
544 }
545 
draw_damage(int h)546 void draw_damage(int h)
547 {
548 
549 	int crap2 = add_sprite(spr[h].x,spr[h].y,8,0,0);
550 
551 	spr[crap2].y -= k[seq[spr[h].pseq].frame[spr[h].pframe]].yoffset;
552 	spr[crap2].x -= k[seq[spr[h].pseq].frame[spr[h].pframe]].xoffset;
553 	spr[crap2].y -= k[seq[spr[h].pseq].frame[spr[h].pframe]].box.bottom / 3;
554 	spr[crap2].x += k[seq[spr[h].pseq].frame[spr[h].pframe]].box.right / 5;
555 
556 	spr[crap2].speed = 1;
557 	spr[crap2].hard = 1;
558 	spr[crap2].brain_parm = h;
559 	spr[crap2].my = -1;
560 	spr[crap2].kill = 1000;
561 	spr[crap2].dir = 8;
562 	spr[crap2].damage = spr[h].damage;
563 
564 }
565 
566 
add_kill_sprite(int h)567 void add_kill_sprite(int h)
568 {
569 	if ( (spr[h].dir > 9) || (spr[h].dir < 1) )
570 	{
571 		log_error("Changing sprites dir from %d (!?) to 3.", spr[h].dir);
572 		spr[h].dir = 3;
573 
574 	}
575 
576 
577 	int dir = spr[h].dir;
578 	int base = spr[h].base_die;
579 
580 	//Msg("Base die is %d", base);
581 	if (base == -1)
582 	{
583 
584 	  if (seq[spr[h].base_walk+5].is_active)
585 		{
586 			add_exp(spr[h].exp, h);
587 
588 			int crap2 = add_sprite(spr[h].x,spr[h].y,5,spr[h].base_walk +5,1);
589 			spr[crap2].speed = 0;
590 			spr[crap2].seq = spr[h].base_walk + 5;
591 			// set corpse size to the original sprite size
592 			spr[crap2].size = spr[h].size;
593 			return;
594 		} else
595 		{
596 			dir = 0;
597 			base = 164;
598 
599 		}
600 	}
601 
602 
603 
604 	if (!seq[base+dir].is_active)
605 	{
606 
607 		if (dir == 1) dir = 9;
608 		else if (dir == 3) dir = 7;
609 		else if (dir == 7) dir = 3;
610 		else if (dir == 9) dir = 1;
611 
612 		else if (dir == 4) dir = 6;
613 		else if (dir == 6) dir = 4;
614 		else if (dir == 8) dir = 2;
615 		else if (dir == 2) dir = 8;
616 
617 
618 	}
619 	if (!seq[base+dir].is_active)
620 
621 	{
622 		log_error("Can't make a death sprite for dir %d!", base+dir);
623 	}
624 
625 
626 
627 	int crap2 = add_sprite(spr[h].x,spr[h].y,5,base +dir,1);
628 	spr[crap2].speed = 0;
629 	spr[crap2].base_walk = 0;
630 	spr[crap2].seq = base + dir;
631 
632 	if (base == 164) spr[crap2].brain = 7;
633 
634 	spr[crap2].size = spr[h].size;
635 
636 	add_exp(spr[h].exp, h);
637 
638 }
639 
640 
done_moving(int h)641 void done_moving(int h)
642 {
643 
644 	spr[h].move_active = /*false*/0;
645 
646 	spr[h].move_nohard = /*false*/0;
647 
648 	if (spr[h].move_script > 0)
649 	{
650 		//	Msg("mover running script %d..", spr[h].move_script);
651 		run_script(spr[h].move_script);
652 	}
653 
654 
655 
656 }
657 
get_distance_and_dir_smooth(int h,int h1,int * dir)658 int get_distance_and_dir_smooth(int h, int h1, int *dir)
659 {
660   unsigned int x_diff = abs(spr[h].x - spr[h1].x);
661   unsigned int y_diff = abs(spr[h].y - spr[h1].y);
662 
663   if (spr[h].x < spr[h1].x)
664     {
665       if (spr[h].y < spr[h1].y)
666 	{
667 	  // 6, 3, 2
668 	  if (y_diff * 4 < x_diff)
669 	    *dir = 6;
670 	  else if (x_diff * 4 < y_diff)
671 	    *dir = 2;
672 	  else
673 	    *dir = 3;
674 	}
675       else if (spr[h].y > spr[h1].y)
676 	{
677 	  // 4, 9, 8
678 	  if (y_diff * 4 < x_diff)
679 	    *dir = 6;
680 	  else if (x_diff * 4 < y_diff)
681 	    *dir = 8;
682 	  else
683 	    *dir = 9;
684 	}
685       else
686 	{
687 	  *dir = 6;
688 	}
689     }
690   else if (spr[h].x > spr[h1].x)
691     {
692       if (spr[h].y < spr[h1].y)
693 	{
694 	  // 4, 1, 2
695 	  if (y_diff * 4 < x_diff)
696 	    *dir = 4;
697 	  else if (x_diff * 4 < y_diff)
698 	    *dir = 2;
699 	  else
700 	    *dir = 1;
701 	}
702       else if (spr[h].y > spr[h1].y)
703 	{
704 	  // 4, 7, 8
705 	  if (y_diff * 4 < x_diff)
706 	    *dir = 4;
707 	  else if (x_diff * 4 < y_diff)
708 	    *dir = 8;
709 	  else
710 	    *dir = 7;
711 	}
712       else
713 	{
714 	  *dir = 4;
715 	}
716     }
717   else
718     {
719       if (spr[h].y < spr[h1].y)
720 	*dir = 2;
721       else if (spr[h].y > spr[h1].y)
722 	*dir = 8;
723     }
724 
725   return (x_diff > y_diff) ? x_diff : y_diff;
726 }
get_distance_and_dir_nosmooth(int h,int h1,int * dir)727 int get_distance_and_dir_nosmooth(int h, int h1, int *dir)
728 {
729   int distancex = 5000;
730   int distancey = 5000;
731   /* Arbitrarily set to 6 to avoid uninitialized values; don't set to
732      5, because *dir is added to e.g. base_attack to get the right
733      sequence - with 5, you get the dead/corpse sequence instead of an
734      attack sequence.. */
735   int dirx = 6;
736   int diry = 6;
737 
738   if ((spr[h].x > spr[h1].x) && ((spr[h].x - spr[h1].x) < distancex))
739     {
740       distancex = spr[h].x - spr[h1].x;
741       dirx = 4;
742     }
743   if ((spr[h].x < spr[h1].x) && ((spr[h1].x - spr[h].x) < distancex))
744     {
745       distancex = spr[h1].x - spr[h].x;
746       dirx = 6;
747     }
748 
749   if ((spr[h].y > spr[h1].y) && ((spr[h].y - spr[h1].y) < distancey))
750     {
751       distancey = spr[h].y - spr[h1].y;
752       diry = 8;
753     }
754   if ((spr[h].y < spr[h1].y) && ((spr[h1].y - spr[h].y) < distancey))
755     {
756       distancey = spr[h1].y - spr[h].y;
757       diry = 2;
758     }
759 
760   if (distancex > distancey)
761     {
762       *dir = dirx;
763       return distancex;
764     }
765   else
766     {
767       *dir = diry;
768       return distancey;
769     }
770 }
get_distance_and_dir(int h,int h1,int * dir)771 int get_distance_and_dir(int h, int h1, int *dir)
772 {
773   if (smooth_follow == 1)
774     return get_distance_and_dir_smooth(h, h1, dir);
775   else
776     return get_distance_and_dir_nosmooth(h, h1, dir);
777 }
778 
process_follow(int h)779 void process_follow(int h)
780 {
781 	if (spr[h].follow > 299)
782 	{
783 		log_error("Sprite %d cannot 'follow' sprite %d??",h,spr[h].follow);
784 		return;
785 	}
786 
787 	if (spr[spr[h].follow].active == /*false*/0)
788 	{
789 		log_debug("Killing follow");
790 		spr[h].follow = 0;
791 		return;
792 	}
793 
794 	int dir;
795 	int distance = get_distance_and_dir(h, spr[h].follow, &dir);
796 
797 	if (distance < 40) return;
798 
799 	changedir(dir,h,spr[h].base_walk);
800 	automove(h);
801 
802 
803 }
804 
805 
process_target(int h)806 void process_target(int h)
807 {
808 	if (spr[h].target > 299)
809 	{
810 		log_error("Sprite %d cannot 'target' sprite %d??",h,spr[h].follow);
811 		return;
812 	}
813 
814 	if (spr[spr[h].target].active == /*false*/0)
815 	{
816 		log_debug("Killing target");
817 		spr[h].target = 0;
818 		return;
819 	}
820 
821 	int dir;
822 	int distance = get_distance_and_dir(h, spr[h].target, &dir);
823 
824 	if (distance < spr[h].distance) return;
825 
826 	changedir(dir,h,spr[h].base_walk);
827 
828 	automove(h);
829 
830 
831 }
832 
833 
check_for_kill_script(int i)834 /*bool*/int check_for_kill_script(int i)
835 {
836 
837 
838 	if (spr[i].script > 0)
839 	{
840 		//if (  (spr[i].brain == 0) | (spr[i].brain == 5) | (spr[i].brain == 6) | (spr[i].brain == 7))
841 
842 		if (locate(spr[i].script, "DIE")) run_script(spr[i].script);
843 
844 		return(/*true*/1);
845 	}
846 
847 	return(/*false*/0);
848 }
849 
check_for_duck_script(int i)850 /*bool*/int check_for_duck_script(int i)
851 {
852 
853 
854 	if (spr[i].script > 0)
855 	{
856 		//if (  (spr[i].brain == 0) | (spr[i].brain == 5) | (spr[i].brain == 6) | (spr[i].brain == 7))
857 
858 		if (locate(spr[i].script, "DUCKDIE")) run_script(spr[i].script);
859 
860 		return(/*true*/1);
861 	}
862 
863 	return(/*false*/0);
864 }
865 
866 
867 
process_move(int h)868 void process_move(int h)
869 {
870 
871 	//	Msg("Proccesing sprite %d, dir %d (script is %d)", h, spr[h].dir, spr[h].move_script);
872 
873 
874 
875 	if ((spr[h].move_dir == 4) | (spr[h].move_dir == 1) | (spr[h].move_dir == 7) )
876 	{
877 		if (spr[h].x <= spr[h].move_num)
878 		{
879 			//done moving
880 			done_moving(h);
881 			return;
882 		}
883 		changedir(spr[h].move_dir,h,spr[h].base_walk);
884 		automove(h);
885 	}
886 
887 	if ( (spr[h].move_dir == 6) | (spr[h].move_dir == 9) | (spr[h].move_dir == 3))
888 	{
889 		if (spr[h].x >= spr[h].move_num)
890 		{
891 			//done moving
892 			done_moving(h);
893 			return;
894 		}
895 		changedir(spr[h].move_dir,h,spr[h].base_walk);
896 		automove(h);
897 	}
898 
899 
900 	if (spr[h].move_dir == 2)
901 	{
902 		if (spr[h].y >= spr[h].move_num)
903 		{
904 			//done moving
905 			done_moving(h);
906 			return;
907 		}
908 		changedir(spr[h].move_dir,h,spr[h].base_walk);
909 		automove(h);
910 	}
911 
912 
913 	if (spr[h].move_dir == 8)
914 	{
915 		if (spr[h].y <= spr[h].move_num)
916 		{
917 			//done moving
918 			done_moving(h);
919 			return;
920 		}
921 		changedir(spr[h].move_dir,h,spr[h].base_walk);
922 		automove(h);
923 	}
924 
925 
926 }
927 
duck_brain(int h)928 void duck_brain(int h)
929 {
930 	int hold;
931 
932 
933 	if (   (spr[h].damage > 0) && (in_this_base(spr[h].pseq, 110)  ) )
934 	{
935 
936 		check_for_duck_script(h);
937 
938 		//hit a dead duck
939 		int crap2 = add_sprite(spr[h].x,spr[h].y,7,164,1);
940                 /* TODO: add_sprite might return 0, and the following
941                    would trash spr[0] - cf. bugs.debian.org/688934 */
942 		spr[crap2].speed = 0;
943 		spr[crap2].base_walk = 0;
944 		spr[crap2].seq = 164;
945 		draw_damage(h);
946 		spr[h].damage = 0;
947 		add_exp(spr[h].exp, h);
948 
949 		kill_sprite_all(h);
950 
951 		return;
952 	}
953 
954 
955 	if (   (spr[h].damage > 0) && (in_this_base(spr[h].pseq, spr[h].base_walk)  ) )
956 	{
957 		//SoundPlayEffect( 1,3000, 800 );
958 		draw_damage(h);
959 		add_exp(spr[h].exp, h);
960 		spr[h].damage = 0;
961 
962 		//lets kill the duck here, ha.
963 		check_for_kill_script(h);
964 		spr[h].follow = 0;
965 		int crap = add_sprite(spr[h].x,spr[h].y,5,1,1);
966                 /* TODO: add_sprite might return 0, and the following
967                    would trash spr[0] - cf. bugs.debian.org/688934 */
968 		spr[crap].speed = 0;
969 		spr[crap].base_walk = 0;
970 		spr[crap].size = spr[h].size;
971 		spr[crap].speed =  ((rand() % 3)+1);
972 
973 
974 		spr[h].base_walk = 110;
975 		spr[h].speed = 1;
976 		spr[h].timer = 0;
977 		spr[h].wait = 0;
978 		spr[h].frame = 0;
979 
980 		if (spr[h].dir == 0) spr[h].dir = 1;
981 		if (spr[h].dir == 4) spr[h].dir = 7;
982 		if (spr[h].dir == 6) spr[h].dir = 3;
983 
984 		changedir(spr[h].dir,h,spr[h].base_walk);
985 		spr[crap].dir = spr[h].dir;
986 		spr[crap].base_walk = 120;
987 		changedir(spr[crap].dir,crap,spr[crap].base_walk);
988 
989 
990 		automove(h);
991 		return;
992 	}
993 
994 
995 	if (spr[h].move_active)
996 	{
997 		process_move(h);
998 		return;
999 	}
1000 
1001 	if (spr[h].freeze)
1002 	{
1003 		return;
1004 	}
1005 
1006 
1007 	if (spr[h].follow > 0)
1008 	{
1009 		process_follow(h);
1010 		return;
1011 	}
1012 
1013 
1014 
1015 	if (spr[h].base_walk == 110)
1016 	{
1017 		if ( (rand() % 100)+1 == 1)
1018 			random_blood(spr[h].x, spr[h].y-18, h);
1019 		goto walk;
1020 	}
1021 
1022 
1023 
1024 
1025 
1026 	if (spr[h].seq == 0 )
1027 	{
1028 
1029 		if (((rand() % 12)+1) == 1 )
1030 		{
1031 			hold = ((rand() % 9)+1);
1032 
1033 			if ((hold != 2) && (hold != 8) && (hold != 5))
1034 			{
1035 
1036 				//Msg("random dir change started.. %d", hold);
1037 				changedir(hold,h,spr[h].base_walk);
1038 
1039 			}
1040 			else
1041 			{
1042 				int junk = spr[h].size;
1043 
1044 				if (junk >=  100)
1045 					junk = 18000 - (junk * 50);
1046 
1047 				if (junk < 100)
1048 					junk = 16000 + (junk * 100);
1049 
1050 				SoundPlayEffect( 1,junk, 800,h ,0);
1051 				spr[h].mx = 0;
1052 				spr[h].my = 0;
1053 				spr[h].wait = thisTickCount + (rand() % 300)+200;
1054 
1055 			}
1056 			return;
1057 		}
1058 
1059 		if ((spr[h].mx != 0) || (spr[h].my != 0))
1060 
1061 		{
1062 			spr[h].seq = spr[h].seq_orig;
1063 
1064 		}
1065 
1066 	}
1067 
1068 
1069 walk:
1070 	if (spr[h].y > playy)
1071 
1072 	{
1073 		changedir(9,h,spr[h].base_walk);
1074 	}
1075 
1076 
1077 
1078 	if (spr[h].x > playx-30)
1079 
1080 	{
1081 		changedir(7,h,spr[h].base_walk);
1082 	}
1083 
1084 	if (spr[h].y < 10)
1085 	{
1086 		changedir(1,h,spr[h].base_walk);
1087 	}
1088 
1089 	if (spr[h].x < 30)
1090 	{
1091 		changedir(3,h,spr[h].base_walk);
1092 	}
1093 
1094 	//   Msg("Duck dir is %d, seq is %d.", spr[h].dir, spr[h].seq);
1095 	automove(h);
1096 
1097 	if (check_if_move_is_legal(h) != 0)
1098 
1099 	{
1100 		if (spr[h].dir != 0)
1101 			changedir(autoreverse_diag(h),h,spr[h].base_walk);
1102 	}
1103 
1104 }
1105 // end duck_brain
1106 
change_dir_to_diag(int * dir)1107 void change_dir_to_diag( int *dir)
1108 {
1109 
1110 	if (*dir == 8) *dir = 7;
1111 	if (*dir == 4) *dir = 1;
1112 	if (*dir == 2) *dir = 3;
1113 	if (*dir == 6) *dir = 9;
1114 
1115 }
1116 
1117 
1118 
pill_brain(int h)1119 void pill_brain(int h)
1120 {
1121 	int hold;
1122 
1123 	if  (spr[h].damage > 0)
1124 	{
1125 		//got hit
1126 		//SoundPlayEffect( 1,3000, 800 );
1127 		if (spr[h].hitpoints > 0)
1128 		{
1129 			draw_damage(h);
1130 			if (spr[h].damage > spr[h].hitpoints) spr[h].damage = spr[h].hitpoints;
1131 			spr[h].hitpoints -= spr[h].damage;
1132 
1133 			if (spr[h].hitpoints < 1)
1134 			{
1135 				//they killed it
1136 				check_for_kill_script(h);
1137 
1138 				if (spr[h].brain == 9)
1139 				{
1140 					if (spr[h].dir == 0) spr[h].dir = 3;
1141 					change_dir_to_diag(&spr[h].dir);
1142 					add_kill_sprite(h);
1143 					spr[h].active = /*false*/0;
1144 				}
1145 				return;
1146 
1147 			}
1148 		}
1149 		spr[h].damage = 0;
1150 
1151 	}
1152 
1153 	if (spr[h].move_active)
1154 	{
1155 		process_move(h);
1156 		return;
1157 	}
1158 
1159 
1160 
1161 
1162 	if (spr[h].freeze) return;
1163 
1164 	if (spr[h].follow > 0)
1165 	{
1166 		process_follow(h);
1167 
1168 	}
1169 
1170 
1171 	if (spr[h].target != 0)
1172 	{
1173 
1174 		if (in_this_base(spr[h].seq, spr[h].base_attack))
1175 		{
1176 			//still attacking
1177 			return;
1178 		}
1179 
1180 
1181 
1182 
1183 
1184 		int dir;
1185 		if (spr[h].distance == 0) spr[h].distance = 5;
1186 		int distance = get_distance_and_dir(h, spr[h].target, &dir);
1187 
1188 		if (distance < spr[h].distance) if (spr[h].attack_wait < thisTickCount)
1189 		{
1190 			//	Msg("base attack is %d.",spr[h].base_attack);
1191 			if (spr[h].base_attack != -1)
1192 			{
1193 			  //Msg("attacking with %d..", spr[h].base_attack+dir);
1194 
1195 			  /* Enforce lateral (not diagonal) attack,
1196 			     even in smooth_follow mode */
1197 			  int attackdir = 6; // arbitrary initialized default
1198 			  get_distance_and_dir_nosmooth(h, spr[h].target, &attackdir);
1199 			  spr[h].dir = attackdir;
1200 
1201 				spr[h].seq = spr[h].base_attack+spr[h].dir;
1202 				spr[h].frame = 0;
1203 
1204 				if (spr[h].script != 0)
1205 				  {
1206 				    if (locate(spr[h].script, "ATTACK"))
1207 				      run_script(spr[h].script);
1208 				    else
1209 				      spr[h].move_wait = thisTickCount + ((rand() % 300)+10);
1210 				  }
1211 				return;
1212 
1213 			}
1214 
1215 		}
1216 
1217 
1218 
1219 		if (spr[h].move_wait  < thisTickCount)
1220 		{
1221 			process_target(h);
1222 			spr[h].move_wait = thisTickCount + 200;
1223 
1224 		}
1225 		else
1226 		{
1227 		/*	automove(h);
1228 
1229 		  if (check_if_move_is_legal(h) != 0)
1230 		  {
1231 
1232 			}
1233 			*/
1234 
1235 			goto walk_normal;
1236 		}
1237 
1238 		return;
1239 	}
1240 
1241 
1242 
1243 walk_normal:
1244 
1245 	if (spr[h].base_walk != -1)
1246 	{
1247 		if ( spr[h].seq == 0) goto recal;
1248 	}
1249 
1250 	if (( spr[h].seq == 0) && (spr[h].move_wait < thisTickCount))
1251 	{
1252 recal:
1253 	if (((rand() % 12)+1) == 1 )
1254 	{
1255 		hold = ((rand() % 9)+1);
1256 		if (  (hold != 4) &&   (hold != 6) &&  (hold != 2) && (hold != 8) && (hold != 5))
1257 		{
1258 			changedir(hold,h,spr[h].base_walk);
1259 			spr[h].move_wait = thisTickCount +((rand() % 2000)+200);
1260 
1261 		}
1262 
1263 	} else
1264 	{
1265 		//keep going the same way
1266 		if (in_this_base(spr[h].seq_orig, spr[h].base_attack)) goto recal;
1267 		spr[h].seq = spr[h].seq_orig;
1268 		if (spr[h].seq_orig == 0) goto recal;
1269 	}
1270 
1271 	}
1272 
1273 
1274 
1275 	if (spr[h].y > (playy - 15))
1276 
1277 	{
1278 		changedir(9,h,spr[h].base_walk);
1279 	}
1280 
1281 	if (spr[h].x > (playx - 15))
1282 
1283 	{
1284 		changedir(1,h,spr[h].base_walk);
1285 	}
1286 
1287 	if (spr[h].y < 18)
1288 	{
1289 		changedir(1,h,spr[h].base_walk);
1290 	}
1291 
1292 	if (spr[h].x < 18)
1293 	{
1294 		changedir(3,h,spr[h].base_walk);
1295 	}
1296 
1297 	automove(h);
1298 
1299 	if (check_if_move_is_legal(h) != 0)
1300 	{
1301 		spr[h].move_wait = thisTickCount + 400;
1302 		changedir(autoreverse_diag(h),h,spr[h].base_walk);
1303 	}
1304 
1305 
1306 	//				changedir(hold,h,spr[h].base_walk);
1307 
1308 
1309 }
1310 
find_action(int h)1311 void find_action(int h)
1312 {
1313 
1314 	spr[h].action = (rand() % 2)+1;
1315 
1316 
1317 	if (spr[h].action == 1)
1318 	{
1319 		//sit and think
1320 		spr[h].move_wait = thisTickCount +((rand() % 3000)+400);
1321 		if (spr[h].base_walk != -1)
1322 		{
1323 			int dir = (rand() % 4)+1;
1324 
1325 			spr[h].pframe = 1;
1326 			if (dir == 1)  spr[h].pseq = spr[h].base_walk+1;
1327 			if (dir == 2)  spr[h].pseq = spr[h].base_walk+3;
1328 			if (dir == 3)  spr[h].pseq = spr[h].base_walk+7;
1329 			if (dir == 4)  spr[h].pseq = spr[h].base_walk+9;
1330 		}
1331 
1332 		return;
1333 	}
1334 
1335 	if (spr[h].action == 2)
1336 	{
1337 		//move
1338 		spr[h].move_wait = thisTickCount +((rand() % 3000)+500);
1339 		int dir = (rand() % 4)+1;
1340 		spr[h].pframe = 1;
1341 		if (dir == 1)  changedir(1,h,spr[h].base_walk);
1342 		if (dir == 2)  changedir(3,h,spr[h].base_walk);
1343 		if (dir == 3)  changedir(7,h,spr[h].base_walk);
1344 		if (dir == 4)  changedir(9,h,spr[h].base_walk);
1345 		return;
1346 	}
1347 
1348 
1349 	log_error("Internal error:  Brain 16, unknown action.");
1350 }
1351 
1352 
people_brain(int h)1353 void people_brain(int h)
1354 {
1355 	if  (spr[h].damage > 0)
1356 	{
1357 		//got hit
1358 		//SoundPlayEffect( 1,3000, 800 );
1359 		if (spr[h].hitpoints > 0)
1360 		{
1361 			draw_damage(h);
1362 			if (spr[h].damage > spr[h].hitpoints) spr[h].damage = spr[h].hitpoints;
1363 			spr[h].hitpoints -= spr[h].damage;
1364 
1365 			if (spr[h].hitpoints < 1)
1366 			{
1367 				//they killed it
1368 				check_for_kill_script(h);
1369 
1370 				if (spr[h].brain == 16)
1371 				{
1372 					if (spr[h].dir == 0) spr[h].dir = 3;
1373 					spr[h].brain = 0;
1374 					change_dir_to_diag(&spr[h].dir);
1375 					add_kill_sprite(h);
1376 					spr[h].active = /*false*/0;
1377 				}
1378 				return;
1379 
1380 			}
1381 		}
1382 		spr[h].damage = 0;
1383 
1384 	}
1385 
1386 	if (spr[h].move_active)
1387 	{
1388 		process_move(h);
1389 		return;
1390 	}
1391 
1392 
1393 
1394 
1395 	if (spr[h].freeze) return;
1396 
1397 	if (spr[h].follow > 0)
1398 	{
1399 		process_follow(h);
1400 		return;
1401 	}
1402 
1403 
1404 	if ((spr[h].move_wait < thisTickCount) && (spr[h].seq == 0))
1405 	{
1406 
1407 		spr[h].action = 0;
1408 	}
1409 
1410 
1411 
1412 	if (spr[h].action == 0) find_action(h);
1413 
1414 
1415 	if (spr[h].action != 2)
1416 	{
1417 		spr[h].seq = 0;
1418 		return;
1419 
1420 	}
1421 	if (spr[h].seq_orig != 0)
1422 		if (spr[h].seq == 0) spr[h].seq = spr[h].seq_orig;
1423 
1424 
1425 		if (spr[h].y > playy)
1426 
1427 		{
1428 
1429 			if ( ((rand() % 2)+1) == 1)
1430 				changedir(9,h,spr[h].base_walk);
1431 			else changedir(7,h,spr[h].base_walk);
1432 
1433 
1434 		}
1435 
1436 		if (spr[h].x > playx)
1437 
1438 		{
1439 			if ( ((rand() % 2)+1) == 1)
1440 				changedir(1,h,spr[h].base_walk);
1441 			else changedir(7,h,spr[h].base_walk);
1442 
1443 		}
1444 
1445 		if (spr[h].y < 20)
1446 		{
1447 			if ( ((rand() % 2)+1) == 1)
1448 				changedir(1,h,spr[h].base_walk);
1449 			else changedir(3,h,spr[h].base_walk);
1450 		}
1451 
1452 		if (spr[h].x < 30)
1453 		{
1454 			if ( ((rand() % 2)+1) == 1)
1455 				changedir(3,h,spr[h].base_walk);
1456 			else changedir(9,h,spr[h].base_walk);
1457 		}
1458 
1459 		automove(h);
1460 
1461 		if (check_if_move_is_legal(h) != 0)
1462 		{
1463 			if ((rand() % 3) == 2)
1464 			{
1465 				changedir(autoreverse_diag(h),h,spr[h].base_walk);
1466 
1467 			} else
1468 			{
1469 				spr[h].move_wait = 0;
1470 				spr[h].pframe = 1;
1471 				spr[h].seq = 0;
1472 			}
1473 		}
1474 
1475 
1476 		//				changedir(hold,h,spr[h].base_walk);
1477 
1478 
1479 }
1480 
1481 
no_brain(int h)1482 void no_brain(int h)
1483 {
1484 	if (spr[h].move_active)
1485 	{
1486 		process_move(h);
1487 		return;
1488 	}
1489 
1490 	if (spr[h].freeze) return;
1491 
1492 	if (spr[h].follow > 0)
1493 	{
1494 		process_follow(h);
1495 		return;
1496 	}
1497 
1498 }
1499 
1500 
shadow_brain(int h)1501 void shadow_brain(int h)
1502 {
1503 	if (spr[spr[h].brain_parm].active == /*false*/0)
1504 	{
1505 		spr[h].active = /*false*/0;
1506 		return;
1507 	}
1508 
1509 	spr[h].x = spr[spr[h].brain_parm].x;
1510 	spr[h].y = spr[spr[h].brain_parm].y;
1511 	spr[h].size = spr[spr[h].brain_parm].size;
1512 
1513 	if (spr[h].seq == 0) if (spr[h].seq_orig != 0) spr[h].seq = spr[h].seq_orig;
1514 
1515 }
1516 
1517 
1518 
dragon_brain(int h)1519 void dragon_brain(int h)
1520 {
1521 	int hold;
1522 
1523 
1524 	if  (spr[h].damage > 0)
1525 	{
1526 		//got hit
1527 		//SoundPlayEffect( 1,3000, 800 );
1528 		if (spr[h].hitpoints > 0)
1529 		{
1530 			draw_damage(h);
1531 			if (spr[h].damage > spr[h].hitpoints) spr[h].damage = spr[h].hitpoints;
1532 			spr[h].hitpoints -= spr[h].damage;
1533 
1534 			if (spr[h].hitpoints < 1)
1535 			{
1536 				//they killed it
1537 
1538 				check_for_kill_script(h);
1539 				if (spr[h].brain == 10)
1540 				{
1541 					add_kill_sprite(h);
1542 					spr[h].active = /*false*/0;
1543 
1544 				}
1545 
1546 				return;
1547 
1548 			}
1549 		}
1550 		spr[h].damage = 0;
1551 	}
1552 
1553 
1554 	if (spr[h].move_active)
1555 	{
1556 		process_move(h);
1557 		return;
1558 	}
1559 
1560 
1561 	if (spr[h].freeze) return;
1562 
1563 
1564 	if (spr[h].follow > 0)
1565 	{
1566 		process_follow(h);
1567 		return;
1568 	}
1569 
1570 	if (spr[h].target != 0)
1571 		if (spr[h].attack_wait < thisTickCount)
1572 		{
1573 			if (spr[h].script != 0)
1574 			{
1575 
1576 				if (locate(spr[h].script, "ATTACK")) run_script(spr[h].script);
1577 			}
1578 		}
1579 
1580 
1581 
1582 		if (spr[h].seq == 0)
1583 		{
1584 recal:
1585 		if (((rand() % 12)+1) == 1 )
1586 		{
1587 			hold = ((rand() % 9)+1);
1588 			if (  (hold != 1) &&   (hold != 3) &&  (hold != 7) && (hold != 9) && (hold != 5))
1589 			{
1590 				changedir(hold,h,spr[h].base_walk);
1591 
1592 			}
1593 
1594 		} else
1595 		{
1596 			//keep going the same way
1597 			spr[h].seq = spr[h].seq_orig;
1598 			if (spr[h].seq_orig == 0) goto recal;
1599 		}
1600 
1601 		}
1602 
1603 
1604 		if (spr[h].y > playy)
1605 
1606 		{
1607 			changedir(8,h,spr[h].base_walk);
1608 		}
1609 
1610 		if (spr[h].x > GFX_RES_W)
1611 		{
1612 			changedir(4,h,spr[h].base_walk);
1613 		}
1614 
1615 		if (spr[h].y < 0)
1616 		{
1617 			changedir(2,h,spr[h].base_walk);
1618 		}
1619 
1620 		if (spr[h].x < 0)
1621 		{
1622 			changedir(6,h,spr[h].base_walk);
1623 		}
1624 
1625 		automove(h);
1626 
1627 		if (check_if_move_is_legal(h) != 0)
1628 
1629 		{
1630 
1631 			int mydir = autoreverse(h);
1632 
1633 			//	Msg("Real dir now is %d, autoresver changed to %d.",spr[h].dir, mydir);
1634 
1635 			changedir(mydir,h,spr[h].base_walk);
1636 
1637 			log_debug("real dir changed to %d", spr[h].dir);
1638 		}
1639 
1640 }
1641 
1642 
1643 
1644 
pig_brain(int h)1645 void pig_brain(int h)
1646 {
1647 	int hold;
1648 
1649 	if (spr[h].move_active)
1650 	{
1651 		process_move(h);
1652 		return;
1653 	}
1654 
1655 	if (   (spr[h].damage > 0) )
1656 	{
1657 		//SoundPlayEffect( 1,3000, 800 );
1658 		draw_damage(h);
1659 		spr[h].hitpoints -= spr[h].damage;
1660 		spr[h].damage = 0;
1661 		if (spr[h].hitpoints < 1)
1662 		{
1663 			add_exp(spr[h].exp, h);
1664 			spr[h].damage = 0;
1665 			//lets kill the duck here, ha.
1666 			check_for_kill_script(h);
1667 			spr[h].speed = 0;
1668             spr[h].base_walk = -1;
1669 			spr[h].seq = 164;
1670 			spr[h].brain = 7;
1671 		}
1672 
1673 		return;
1674 	}
1675 
1676 
1677 	if (spr[h].freeze) return;
1678 
1679 
1680 
1681 	if (spr[h].seq == 0 )
1682 	{
1683 
1684 		if (((rand() % 12)+1) == 1 )
1685 		{
1686 			hold = ((rand() % 9)+1);
1687 
1688 			if (  (hold != 4) &&   (hold != 6) &&  (hold != 2) && (hold != 8) && (hold != 5))
1689 			{
1690 				changedir(hold,h,spr[h].base_walk);
1691 
1692 			}
1693 			else
1694 			{
1695 				int junk = spr[h].size;
1696 
1697 				if (junk >=  100)
1698 					junk = 18000 - (junk * 50);
1699 
1700 				if (junk < 100)
1701 					junk = 16000 + (junk * 100);
1702 
1703 
1704 				hold = ((rand() % 4)+1);
1705 
1706 				if (!playing(spr[h].last_sound)) spr[h].last_sound = 0;
1707 
1708 				if (spr[h].last_sound == 0)
1709 				{
1710 
1711 
1712 					if (hold == 1)
1713 						spr[h].last_sound = SoundPlayEffect( 2,junk, 800 ,h,0);
1714 					if (hold == 2)
1715 						spr[h].last_sound = SoundPlayEffect( 3,junk, 800,h ,0);
1716 					if (hold == 3)
1717 						spr[h].last_sound = SoundPlayEffect( 4,junk, 800 ,h,0);
1718 					if (hold == 4)
1719 						spr[h].last_sound = SoundPlayEffect( 5,junk, 800,h,0 );
1720 
1721 				}
1722 
1723 				spr[h].mx = 0;
1724 				spr[h].my = 0;
1725 				spr[h].wait = thisTickCount + (rand() % 300)+200;
1726 
1727 			}
1728 
1729 		}
1730 		else
1731 		{
1732 
1733 			if ((spr[h].mx != 0) || (spr[h].my != 0))
1734 
1735 			{
1736 				spr[h].seq = spr[h].seq_orig;
1737 
1738 			}
1739 
1740 		}
1741 	}
1742 
1743 
1744 	if (spr[h].y > (playy-k[getpic(h)].box.bottom / 4))
1745 	{
1746 		changedir(9,h,spr[h].base_walk);
1747 	}
1748 
1749 	if (spr[h].x > (GFX_RES_W -k[getpic(h)].box.right-10))
1750 	{
1751 		changedir(1,h,spr[h].base_walk);
1752 	}
1753 
1754 	if (spr[h].y < 10)
1755 	{
1756 		changedir(1,h,spr[h].base_walk);
1757 	}
1758 
1759 	if (spr[h].x < 10)
1760 	{
1761 		changedir(3,h,spr[h].base_walk);
1762 	}
1763 
1764 	automove(h);
1765 
1766 	if (check_if_move_is_legal(h) != 0)
1767 
1768 	{
1769 		changedir(autoreverse_diag(h),h,spr[h].base_walk);
1770 	}
1771 
1772 }
1773 // end duck_brain
1774 
1775 
1776 
1777 /**
1778  * Check if the sprite can pass or should be blocked
1779  *
1780  * Returns 0 = can pass, <>0 = should be blocked
1781  */
check_if_move_is_legal(int u)1782 int check_if_move_is_legal(int u)
1783 {
1784   if ((dversion >= 108) /* move_nohard is active for all movements, not just active moves */
1785       || (/* dversion == 107 && */ spr[u].move_active))
1786     if (spr[u].move_nohard == 1)
1787       return(0);
1788 
1789   if (u == 1 && in_this_base(spr[u].seq, dink_base_push))
1790     return(0);
1791 
1792   int hardness = 0;
1793 	if (spr[u].moveman > 0)
1794 	{
1795 	  int i;
1796 	  for (i = 1; i <= spr[u].moveman; i++)
1797 	    {
1798 	      hardness = get_hard(spr[u].lpx[i]-20, spr[u].lpy[i]);
1799 	      if (hardness == 2 && spr[u].flying)
1800 		{
1801 		  spr[u].moveman = 0;
1802 		  if (dversion >= 108)
1803 		    return 0;
1804 		  else
1805 		    return 2;
1806 		}
1807 	      if (hardness > 0)
1808 		{
1809 		  spr[u].x = spr[u].lpx[i-1];
1810 		  spr[u].y = spr[u].lpy[i-1];
1811 		  spr[u].moveman = 0;
1812 
1813 		  if (push_active)
1814 		    {
1815 		      if (u == 1 && hardness != 2 && play.push_active == /*false*/0)
1816 			{
1817 			  if ((spr[u].dir == 2) | (spr[u].dir == 4) | (spr[u].dir == 6) | (spr[u].dir == 8))
1818 			    {
1819 			      //he  (dink)  is definatly pushing on something
1820 			      play.push_active = /*true*/1;
1821 			      play.push_dir = spr[u].dir;
1822 			      play.push_timer = thisTickCount;
1823 			    }
1824 			}
1825 		      else
1826 			{
1827 			  if (play.push_dir != spr[1].dir) play.push_active = /*false*/0;
1828 			}
1829 		    }
1830 		  return(hardness);
1831 		}
1832 	    }
1833 	}
1834 
1835 	if (u == 1)  play.push_active = /*false*/0;
1836 	return(0);
1837 }
1838 
1839 
move(int u,int amount,char kind,char kindy)1840 void move(int u, int amount, char kind,  char kindy)
1841 {
1842 	int mx = 0;
1843 	int my = 0;
1844 	int i;
1845 	/*bool*/int clearx;
1846 	/*bool*/int cleary;
1847 	clearx = /*false*/0;
1848 	cleary = /*false*/0;
1849 
1850 	for (i = 1; i <= amount; i++)
1851 	{
1852 		spr[u].moveman++;
1853 		if (mx >= spr[u].mx) clearx = /*true*/1;
1854 		if (my >= spr[u].my) clearx = /*true*/1;
1855 
1856 		if ((clearx) && (cleary))
1857 		{
1858 			mx = 0;
1859 			my = 0;
1860 			clearx = /*false*/0;
1861 			cleary = /*false*/0;
1862 
1863 		}
1864 
1865 
1866 		if (kind == '+')
1867 		{
1868 			if (mx < spr[u].mx)
1869 				spr[u].x++;
1870 			mx++;
1871 
1872 		}
1873 		if (kind == '-')
1874 		{
1875 
1876 
1877 			if (mx < (spr[u].mx - (spr[u].mx * 2)))
1878 				spr[u].x--;
1879 			mx++;
1880 		}
1881 
1882 		if (kindy == '+')
1883 		{
1884 
1885 			if (my < spr[u].my)
1886 				spr[u].y++;
1887 			my++;
1888 		}
1889 		if (kindy == '-')
1890 		{
1891 
1892 			if (my < (spr[u].my - (spr[u].my * 2)))
1893 				spr[u].y--;
1894 			my++;
1895 		}
1896 
1897 		spr[u].lpx[spr[u].moveman] = spr[u].x;
1898         spr[u].lpy[spr[u].moveman] = spr[u].y;
1899 	}
1900 
1901 
1902 }
1903 
1904 
1905 
bounce_brain(int h)1906 void bounce_brain(int h)
1907 {
1908 	if (spr[h].y > (playy-k[getpic(h)].box.bottom))
1909 	{
1910 		spr[h].my -= (spr[h].my * 2);
1911 	}
1912 
1913 	if (spr[h].x > (GFX_RES_W -k[getpic(h)].box.right))
1914 	{
1915 		spr[h].mx -= (spr[h].mx * 2);
1916 	}
1917 
1918 	if (spr[h].y < 0)
1919 	{
1920 		spr[h].my -= (spr[h].my * 2);
1921 	}
1922 
1923 
1924 	if (spr[h].x < 0)
1925 	{
1926 		spr[h].mx -= (spr[h].mx * 2);
1927 	}
1928 
1929 
1930 	spr[h].x += spr[h].mx;
1931 	spr[h].y += spr[h].my;
1932 
1933 
1934 }
1935 //end bounce brain
1936 
grab_trick(int trick)1937 void grab_trick(int trick)
1938 {
1939   /* Capture the current game zone from the backbuffer */
1940   SDL_Rect src, dst;
1941   src.x = playl;
1942   src.y = 0;
1943   src.w = 620 - playl;
1944   src.h = 400;
1945   dst.x = dst.y = 0;
1946   SDL_BlitSurface(GFX_lpDDSBack, &src, GFX_lpDDSTrick, &dst);
1947 
1948   move_screen = trick;
1949   trig_man = /*true*/1;
1950 
1951   move_counter = 0;
1952 }
1953 
1954 
1955 
1956 
1957 
1958 
did_player_cross_screen(int real,int h)1959 void did_player_cross_screen(/*bool*/int real, int h)
1960 {
1961   if (walk_off_screen == 1)
1962     return;
1963 
1964 
1965   //DO MATH TO SEE IF THEY HAVE CROSSED THE SCREEN, IF SO LOAD NEW ONE
1966 
1967   if ((spr[h].x) < playl)
1968     {
1969       if ((*pmap-1) >= 1 && map.loc[*pmap-1] > 0 && screenlock == 0)
1970 	{
1971 	  //move one map to the left
1972 	  if (real)
1973 	    return;
1974 
1975 	  update_screen_time();
1976 	  grab_trick(4);
1977 	  *pmap -= 1;
1978 	  load_map(map.loc[*pmap]);
1979 	  if (map.indoor[*pmap] == 0)
1980 	    play.last_map = *pmap;
1981 
1982 	  draw_map_game();
1983 	  // compatibility: update Dink position *after* screen change
1984 	  spr[h].x = 619;
1985 	  spr[h].y = spr[h].lpy[0];
1986 	}
1987       else
1988 	{
1989 	  spr[h].x = playl;
1990 	}
1991     }
1992 
1993   else if (spr[h].x > 619)
1994     {
1995       if ((*pmap+1) <= 24*32 && map.loc[*pmap+1] > 0 && screenlock == 0)
1996 	{
1997 	  //move one map to the right
1998 	  if (real)
1999 	    return;
2000 
2001 	  update_screen_time();
2002 	  grab_trick(6);
2003 	  *pmap += 1;
2004 	  load_map(map.loc[*pmap]);
2005 	  if (map.indoor[*pmap] == 0)
2006 	    play.last_map = *pmap;
2007 
2008 	  draw_map_game();
2009 	  // compatibility: update Dink position *after* screen change
2010 	  spr[h].x = playl;
2011 	  spr[h].y = spr[h].lpy[0];
2012 	}
2013       else
2014 	{
2015 	  spr[h].x = 619;
2016 	}
2017     }
2018 
2019   else if (spr[h].y < 0)
2020     {
2021       if ((*pmap-32) >= 1 && map.loc[*pmap-32] > 0 && screenlock == 0)
2022 	{
2023 	  //move one map up
2024 	  if (real)
2025 	    return;
2026 
2027 	  update_screen_time();
2028 	  grab_trick(8);
2029 	  *pmap -= 32;
2030 	  load_map(map.loc[*pmap]);
2031 	  if (map.indoor[*pmap] == 0)
2032 	    play.last_map = *pmap;
2033 
2034 	  // compatibility: update Dink X position *before* screen change
2035 	  // (shouldn't matter when though, since it's an Y motion)
2036 	  spr[h].x = spr[h].lpx[0];
2037 	  draw_map_game();
2038 	  // compatibility: update Dink Y position *after* screen change
2039 	  spr[h].y = 399;
2040 	}
2041       else
2042 	{
2043 	  spr[h].y = 0;
2044 	}
2045     }
2046 
2047 
2048   else if (spr[h].y > 399)
2049     {
2050       if ((*pmap+32) <= 24*32 && map.loc[*pmap+32] > 0 && screenlock == 0)
2051 	{
2052 	  //move one map down
2053 	  if (real)
2054 	    return;
2055 
2056 	  update_screen_time();
2057 	  grab_trick(2);
2058 	  *pmap += 32;
2059 	  load_map(map.loc[*pmap]);
2060 	  if (map.indoor[*pmap] == 0)
2061 	    play.last_map = *pmap;
2062 
2063 	  draw_map_game();
2064 	  // compatibility: update Dink position *after* screen change
2065 	  spr[h].y = 0;
2066 	  spr[h].x = spr[h].lpx[0];
2067 	}
2068       else
2069 	{
2070 	  spr[h].y = 399;
2071 	}
2072     }
2073 }
2074 
2075 
run_through_tag_list_talk(int h)2076 /*bool*/int run_through_tag_list_talk(int h)
2077 {
2078 	rect box;
2079 	int amount, amounty;
2080 	int i;
2081 
2082 	for (i = 1; i <= last_sprite_created; i++)
2083 	{
2084 
2085 		if (spr[i].active) if (i != h) if (spr[i].brain != 8)
2086 		{
2087 
2088 
2089 			rect_copy(&box, &k[getpic(i)].hardbox);
2090 			rect_offset(&box, spr[i].x, spr[i].y);
2091 
2092 			rect_inflate(&box, 10,10);
2093 
2094 			amount = 50;
2095 			amounty = 35;
2096 			if (spr[h].dir == 6)
2097 			{
2098 				box.left -= amount;
2099 			}
2100 
2101 			if (spr[h].dir == 4)
2102 			{
2103 				box.right += amount;
2104 			}
2105 
2106 
2107 			if (spr[h].dir == 2)
2108 			{
2109 				box.top -= amounty;
2110 			}
2111 
2112 			if (spr[h].dir == 8)
2113 			{
2114 				box.bottom += amounty;
2115 			}
2116 
2117 			//		draw_box(box, 33);
2118 
2119 			if (inside_box(spr[h].x, spr[h].y, box))
2120 			{
2121 				//Msg("Talking to sprite %d", i);
2122 				if (spr[i].script > 0)
2123 				{
2124 					//if (  (spr[i].brain == 0) | (spr[i].brain == 5) | (spr[i].brain == 6) | (spr[i].brain == 7))
2125 					//Msg("trying to find TALK in script %d", spr[i].script);
2126 					if (locate(spr[i].script, "TALK"))
2127 					{
2128 						kill_returning_stuff(spr[i].script);
2129 
2130 						run_script(spr[i].script);
2131 						return(/*true*/1);
2132 					}
2133 
2134 
2135 				}
2136 
2137 			}
2138 
2139 
2140 		}
2141 
2142 
2143 	}
2144 
2145 
2146 	return(/*false*/0);
2147 }
2148 
2149 
2150 
2151 
2152 
make_missile(int x1,int y1,int dir,int speed,int seq,int frame,int strength)2153 void make_missile(int x1, int y1, int dir, int speed, int seq, int frame, int strength)
2154 {
2155 	int crap = add_sprite(x1,y1,11,seq,frame);
2156 	spr[crap].speed = speed;
2157 	spr[crap].seq = seq;
2158 	spr[crap].timer = 0;
2159 	spr[crap].strength = strength;
2160 	spr[crap].flying = /*true*/1;
2161 	changedir(dir, crap, 430);
2162 
2163 }
2164 
2165 
2166 
2167 
missile_brain(int h,int repeat)2168 void missile_brain(int h, /*bool*/int repeat)
2169 {
2170   rect box;
2171   int j;
2172   automove(h);
2173 
2174   *pmissle_source = h;
2175   int hard = check_if_move_is_legal(h);
2176   if (repeat && spr[h].seq == 0)
2177     spr[h].seq = spr[h].seq_orig;
2178   spr[1].hitpoints = *plife;
2179 
2180   if (hard > 0 && hard != 2)
2181     {
2182       //lets check to see if they hit a sprites hardness
2183       if (hard > 100)
2184 	{
2185 	  int ii;
2186 	  for (ii = 1; ii < last_sprite_created; ii++)
2187 	    {
2188 	      if (spr[ii].sp_index == hard-100)
2189 		{
2190 		  if (spr[ii].script > 0)
2191 		    {
2192 		      *pmissile_target = 1;
2193 		      *penemy_sprite = 1;
2194 
2195 		      if (locate(spr[ii].script, "HIT"))
2196 			{
2197 			  kill_returning_stuff(spr[ii].script);
2198 			  run_script(spr[ii].script);
2199 			}
2200 		    }
2201 
2202 		  if (spr[h].script > 0)
2203 		    {
2204 		      *pmissile_target = ii;
2205 		      *penemy_sprite = 1;
2206 		      if (locate(spr[h].script, "DAMAGE"))
2207 			{
2208 			  kill_returning_stuff(spr[h].script);
2209 			  run_script(spr[h].script);
2210 			}
2211 		    }
2212 		  else
2213 		    {
2214 		      if (spr[h].attack_hit_sound == 0)
2215 			SoundPlayEffect( 9,22050, 0 ,0,0);
2216 		      else
2217 			SoundPlayEffect( spr[h].attack_hit_sound,spr[h].attack_hit_sound_speed, 0 ,0,0);
2218 
2219 		      spr[h].active = 0;
2220 		    }
2221 
2222 		  //run missile end
2223 		  return;
2224 		}
2225 	    }
2226 	}
2227       //run missile end
2228 
2229       if (spr[h].script > 0)
2230 	{
2231 	  *pmissile_target = 0;
2232 	  if (locate(spr[h].script, "DAMAGE"))
2233 	    run_script(spr[h].script);
2234 	}
2235       else
2236 	{
2237 	  if (spr[h].attack_hit_sound == 0)
2238 	    SoundPlayEffect(9, 22050, 0, 0, 0);
2239 	  else
2240 	    SoundPlayEffect(spr[h].attack_hit_sound,spr[h].attack_hit_sound_speed, 0, 0, 0);
2241 
2242 	  spr[h].active = 0;
2243 	  return;
2244 	}
2245     }
2246 
2247   if (spr[h].x > 1000) spr[h].active = /*false*/0;
2248   if (spr[h].y > 700) spr[h].active = /*false*/0;
2249   if (spr[h].y < -500) spr[h].active = /*false*/0;
2250   if (spr[h].x < -500) spr[h].active = /*false*/0;
2251 
2252   //did we hit anything that can die?
2253 
2254   for (j = 1; j <= last_sprite_created; j++)
2255     {
2256       if (spr[j].active && h != j && spr[j].nohit != 1 && spr[j].notouch == /*false*/0)
2257 	if (spr[h].brain_parm != j && spr[h].brain_parm2!= j)
2258 	  //if (spr[j].brain != 15) if (spr[j].brain != 11)
2259 	  {
2260 	    rect_copy(&box, &k[getpic(j)].hardbox);
2261 	    rect_offset(&box, spr[j].x, spr[j].y);
2262 
2263 	    if (spr[h].range != 0)
2264 	      rect_inflate(&box, spr[h].range,spr[h].range);
2265 
2266 	    if (debug_mode) draw_box(box, 33);
2267 
2268 	    if (inside_box(spr[h].x, spr[h].y, box))
2269 	      {
2270 		spr[j].notouch = /*true*/1;
2271 		spr[j].notouch_timer = thisTickCount+100;
2272 		spr[j].target = 1;
2273 		*penemy_sprite = 1;
2274 		//change later to reflect REAL target
2275 		if (spr[h].script > 0)
2276 		  {
2277 		    *pmissile_target = j;
2278 		    if (locate(spr[h].script, "DAMAGE"))
2279 		      run_script(spr[h].script);
2280 		  }
2281 		else
2282 		  {
2283 		    if (spr[h].attack_hit_sound == 0)
2284 		      SoundPlayEffect(9, 22050, 0, 0, 0);
2285 		    else
2286 		      SoundPlayEffect(spr[h].attack_hit_sound,spr[h].attack_hit_sound_speed, 0, 0,0);
2287 		  }
2288 
2289 		if (spr[j].hitpoints > 0 && spr[h].strength != 0)
2290 		  {
2291 		    int hit = 0;
2292 		    if (spr[h].strength == 1)
2293 		      hit = spr[h].strength - spr[j].defense;
2294 		    else
2295 		      hit = (spr[h].strength / 2)
2296 			+ ((rand() % (spr[h].strength / 2)) + 1)
2297 			- spr[j].defense;
2298 
2299 		    if (hit < 0)
2300 		      hit = 0;
2301 		    spr[j].damage += hit;
2302 		    if (hit > 0)
2303 		      random_blood(spr[j].x, spr[j].y-40, j);
2304 		    spr[j].last_hit = 1;
2305 		    //Msg("Damage done is %d..", spr[j].damage);
2306 		  }
2307 
2308 		if (spr[j].script > 0)
2309 		  {
2310 		    //CHANGED did = h
2311 		    *pmissile_target = 1;
2312 
2313 		    if (locate(spr[j].script, "HIT"))
2314 		      {
2315 			kill_returning_stuff(spr[j].script);
2316 			run_script(spr[j].script);
2317 		      }
2318 		  }
2319 	      }
2320 	    //run missile end
2321 
2322 	  }
2323     }
2324 }
2325 
2326 
missile_brain_expire(int h)2327 void missile_brain_expire(int h)
2328 {
2329 	missile_brain(h, /*false*/0);
2330 	if (spr[h].seq == 0) spr[h].active = 0;
2331 
2332 }
2333 
run_through_mouse_list(int h,int special)2334 void run_through_mouse_list(int h, /*bool*/int special)
2335 {
2336   rect box;
2337   int i;
2338 
2339 	for (i = 1; i <= last_sprite_created; i++)
2340 	{
2341 
2342 		if (spr[i].active) if (i != h) if
2343 			((spr[i].touch_damage != 0) )
2344 		{
2345 
2346 			if (spr[i].touch_damage != -1) if (spr[h].notouch) return;
2347 			rect_copy(&box, &k[getpic(i)].hardbox);
2348 			rect_offset(&box, spr[i].x, spr[i].y);
2349 
2350 
2351 			if (inside_box(spr[h].x, spr[h].y, box))
2352 			{
2353 
2354 				if ((spr[i].touch_damage == -1) && (spr[i].script != 0))
2355 				{
2356 					log_info("running %d's script..", spr[i].script);
2357 					if (locate(spr[i].script, "CLICK")) run_script(spr[i].script);
2358 				}
2359 				else
2360 				{
2361 					if (spr[i].touch_damage == -1)
2362 					{
2363 						log_error("Sprites touch damage is set to -1 but there is no script set!");
2364 					} else
2365 					{
2366 						//lets hurt the guy
2367 					}
2368 
2369 				}
2370 
2371 				if (special) return;
2372 
2373 			}
2374 
2375 
2376 		}
2377 
2378 	}
2379 
2380 	if (special) 		SoundPlayEffect(19, 22050, 0, 0,0);
2381 
2382 }
2383 
2384 
2385 
2386 
mouse_brain(int h)2387 void mouse_brain(int h)
2388 {
2389 
2390 	if (spr[h].move_active)
2391 	{
2392 		process_move(h);
2393 		return;
2394 	}
2395 
2396 
2397 	int diag = 0;
2398 
2399 	if (sjoy.right) diag++;
2400 	if (sjoy.left) diag++;
2401 	if (sjoy.down) diag++;
2402 	if (sjoy.up) diag++;
2403 
2404 
2405     //*********************************PROCESS MOVEMENT
2406 
2407 	if (diag == 1)
2408 	{
2409 
2410 								if (sjoy.right)
2411 								{
2412 									move(h,spr[h].speed,'+','0');
2413 									changedir(6,h,spr[h].base_walk);
2414 								}
2415 
2416 
2417 								if (sjoy.left)
2418 								{
2419 									move(h,spr[h].speed,'-','0');
2420 									changedir(4,h,spr[h].base_walk);
2421 								}
2422 
2423 
2424 								if (sjoy.down)
2425 								{
2426 									move(h,spr[h].speed,'0','+');
2427 									changedir(2,h,spr[h].base_walk);
2428 								}
2429 
2430 
2431 								if (sjoy.up)
2432 								{
2433 									move(h,spr[h].speed,'0','-');
2434 									changedir(8,h,spr[h].base_walk);
2435 								}
2436 
2437 	}
2438 	// ***************** DIAGONAL!!!!
2439 
2440 	if (diag > 1)
2441 	{
2442 
2443 								if ( (sjoy.up) && (sjoy.left) )
2444 								{
2445 									changedir(7,h,spr[h].base_walk);
2446 									move(h,spr[h].speed - (spr[h].speed / 3),'-','-');
2447 
2448 								}
2449 
2450 								if ( (sjoy.down) && (sjoy.left))
2451 								{
2452 									changedir(1,h,spr[h].base_walk);
2453 									move(h,spr[h].speed - (spr[h].speed / 3),'-','+');
2454 
2455 								}
2456 
2457 								if ( (sjoy.down) && (sjoy.right))
2458 								{
2459 									changedir(3,h,spr[h].base_walk);
2460 									move(h,spr[h].speed - (spr[h].speed / 3),'+','+');
2461 								}
2462 
2463 
2464 								if ( (sjoy.up) && (sjoy.right))
2465 								{
2466 									changedir(9,h,spr[h].base_walk);
2467 									move(h,spr[h].speed - (spr[h].speed / 3),'+','-');
2468 								}
2469 
2470 	}
2471 
2472 
2473 
2474 
2475 	if ( (sjoy.button[ACTION_ATTACK] == /*TRUE*/1) | (mouse1) )
2476 	{
2477 
2478 		log_info("running through mouse list..");
2479 		run_through_mouse_list(h, /*true*/1);
2480 		sjoy.button[ACTION_ATTACK] = /*false*/0;
2481 							 mouse1 = /*false*/0;
2482 
2483 	}
2484 
2485 }
2486 
process_bow(int h)2487 void process_bow( int h)
2488 {
2489 	int timetowait = 100;
2490 
2491 
2492 	if (bow.wait < thisTickCount)
2493 	{
2494 		if (sjoy.right) spr[h].dir = 6;
2495 		if (sjoy.left) spr[h].dir = 4;
2496 		if (sjoy.up) spr[h].dir = 8;
2497 		if (sjoy.down) spr[h].dir = 2;
2498 	}
2499 
2500 
2501 
2502 	if (sjoy.right) if (sjoy.up)
2503 	{
2504 		spr[h].dir = 9;
2505 		bow.wait = thisTickCount + timetowait;
2506 	}
2507 	if (sjoy.left) if (sjoy.up)
2508 	{
2509 		spr[h].dir = 7;
2510 		bow.wait = thisTickCount + timetowait;
2511 	}
2512 	if (sjoy.right) if (sjoy.down)
2513 	{
2514 		spr[h].dir = 3;
2515 		bow.wait = thisTickCount + timetowait;
2516 
2517 	}
2518 	if (sjoy.left) if (sjoy.down)
2519 	{
2520 		spr[h].dir = 1;
2521 		bow.wait = thisTickCount + timetowait;
2522 
2523 	}
2524 	spr[h].pseq = 100+spr[h].dir;
2525 
2526 
2527 	if (bow.pull_wait < thisTickCount)
2528 	{
2529 		bow.pull_wait = thisTickCount + 10;
2530 		if (bow.hitme) bow.time += 7;
2531 
2532 
2533 		//	bowsound->SetFrequency(22050+(bow.time*10));
2534 
2535 		if (bow.time > 500) bow.time = 500;
2536 		spr[h].pframe = (bow.time / 100)+1;
2537 	}
2538 
2539 
2540 	if (!sjoy.joybitold[ACTION_ATTACK])
2541 	{
2542 		bow.active = /*false*/0;
2543 		bow.last_power = bow.time;
2544 		run_script(bow.script);
2545 		//     bowsound->Stop();
2546 		return;
2547 	}
2548 
2549 }
2550 
2551 
2552 
2553 /**
2554  * Player
2555  */
human_brain(int h)2556 void human_brain(int h)
2557 {
2558   int diag, x5;
2559   int crap;
2560   /*BOOL*/int bad;
2561 
2562   if (mode == 0)
2563     goto b1end;
2564 
2565   if (spr[h].move_active)
2566     {
2567       process_move(h);
2568       return;
2569     }
2570 
2571   if (spr[h].damage > 0)
2572     {
2573       draw_damage(h);
2574 
2575       *plife -= spr[h].damage;
2576 
2577       spr[h].damage = 0;
2578       if (*plife < 0)
2579 	*plife = 0;
2580 
2581       int hurt = (rand() % 2)+1;
2582 
2583       if (hurt == 1)
2584 	SoundPlayEffect(15, 25050, 2000, 0,0);
2585       if (hurt == 2)
2586 	SoundPlayEffect(16, 25050, 2000, 0,0);
2587 
2588       //draw blood
2589     }
2590 
2591   if (play.push_active)
2592     {
2593       if (play.push_dir == 2 && !sjoy.down)
2594 	{
2595 	  spr[h].nocontrol = /*false*/0;
2596 	  play.push_active = /*false*/0;
2597 	}
2598 
2599       if (play.push_dir == 4 && !sjoy.left)
2600 	{
2601 	  spr[h].nocontrol = /*false*/0;
2602 	  play.push_active = /*false*/0;
2603 	}
2604       if (play.push_dir == 6 && !sjoy.right)
2605 	{
2606 	  spr[h].nocontrol = /*false*/0;
2607 	  play.push_active = /*false*/0;
2608 	}
2609 
2610       if (play.push_dir == 8 && !sjoy.up)
2611 	{
2612 	  spr[h].nocontrol = /*false*/0;
2613 	  play.push_active = /*false*/0;
2614 	}
2615     }
2616 
2617   if (spr[h].nocontrol)
2618     return;
2619 
2620   if (talk.active)
2621     goto freeze;
2622 
2623   if (spr[h].freeze)
2624     {
2625       //they are frozen
2626       if (sjoy.button[ACTION_TALK] == 1)
2627 	{
2628 	  //they hit the talk button while frozen, lets hurry up the process
2629 	  int jj;
2630 	  for (jj = 1; jj <= last_sprite_created; jj++)
2631 	    {
2632 	      // Msg("Checking %d, brain %d, script %d, my freeze is %d",jj, spr[jj].brain, spr[jj].script, spr[h].freeze);
2633 	      if (spr[jj].brain == 8 && spr[jj].script == play.last_talk)
2634 		{
2635 		  //this sprite owns its freeze
2636 		  spr[jj].kill_timer = 1;
2637 		  //force the message to be over
2638 		}
2639 	    }
2640 	}
2641       goto freeze;
2642     }
2643 
2644 
2645   //******************************  KEYS THAT CAN BE PRESSED AT ANY TIME **************
2646 
2647   if (bow.active)
2648     {
2649       //bow is active!!
2650       process_bow(h);
2651       return;
2652     }
2653 
2654   if (play.push_active && thisTickCount > play.push_timer + 600)
2655     {
2656       spr[h].seq = dink_base_push + spr[h].dir;
2657       spr[h].frame = 1;
2658       spr[h].nocontrol = /*true*/1;
2659       //play.push_active = /*false*/0;
2660       run_through_tag_list_push(h);
2661 
2662       return;
2663     }
2664 
2665   if ((sjoy.button[ACTION_TALK] == 1))
2666     {
2667       if (!run_through_tag_list_talk(h))
2668 	{
2669 	  int did_dnotalk = 0;
2670 	  if (dversion >= 108)
2671 	    {
2672 	      // addition of 'not talking to anything' script
2673 	      int sc = load_script ("dnotalk", 0, /*false*/0);
2674 	      if (sc != 0 && locate (sc, "MAIN"))
2675 		{
2676 		  run_script (sc);
2677 		  did_dnotalk = 1;
2678 		}
2679 	    }
2680 
2681 	  if (did_dnotalk == 0)
2682 	    {
2683 	      kill_text_owned_by(h);
2684 	      int randy = (rand() % 6)+1;
2685 	      if (randy == 1) say_text(_("`$I don't see anything here."), h, 0);
2686 	      if (randy == 2) say_text(_("`$Huh?"), h, 0);
2687 	      if (randy == 3) say_text(_("`$I'm fairly sure I can't talk to or use that."), h, 0);
2688 	      if (randy == 4) say_text(_("`$What?"), h, 0);
2689 	      if (randy == 5) say_text(_("`$I'm bored."), h, 0);
2690 	      if (randy == 6) say_text(_("`$Not much happening here."), h, 0);
2691 	    }
2692 	}
2693     }
2694 
2695   if ((sjoy.button[ACTION_ATTACK] == 1) && (weapon_script != 0))
2696     {
2697       if (spr[h].base_hit > 0)
2698 	{
2699 	  if (locate(weapon_script, "USE"))
2700 	    run_script(weapon_script);
2701 	  goto b1end;
2702 	}
2703     }
2704 
2705   //added AGAIN 10-19-99
2706   //Let's check keys for getting hit
2707   if (thisTickCount > but_timer && console_active == 0)
2708     {
2709       for (x5=29; x5<256; x5++)
2710 	{
2711 	  if (x5 == SDLK_SPACE) continue;
2712 	  if (x5 == '6') continue;
2713 	  if (x5 == '7') continue;
2714 	  if (x5 == SDLK_LEFT) continue;
2715 	  if (x5 == SDLK_UP) continue;
2716 	  if (x5 == SDLK_RIGHT) continue;
2717 	  if (x5 == SDLK_DOWN) continue;
2718 	  if (x5 == 'm') continue;
2719 	  /* Conflicts with remapped 'a'-'z' SDL
2720 	     keycodes: */
2721 	  if (x5 >= 'A' && x5 <= 'Z') continue;
2722 
2723 	  char msg[30];
2724 	  if (GetKeyboard(x5))
2725 	    {
2726 	      int keycode = x5;
2727 	      /* Get the same keycodes than the original Dink engines
2728 		 for letters, that is, uppercase ascii rather than
2729 		 lowercase ascii */
2730 	      if (x5 >= 'a' && x5 <= 'z')
2731 		keycode = x5 - ('a' - 'A');
2732 
2733 	      sprintf(msg, "key-%d", keycode);
2734 	      but_timer = thisTickCount+200;
2735 
2736 	      int mycrap = load_script(msg, 1, /*false*/0);
2737 	      if (locate(mycrap, "MAIN"))
2738 		{
2739 		  run_script(mycrap);
2740 		  goto b1end;
2741 		}
2742 	    }
2743 	}
2744     }
2745 
2746   enum buttons_actions actions[5];
2747   enum buttons_actions actions_script[5];
2748   int nb_actions = 1;
2749   actions[0] = ACTION_MAP;
2750   actions_script[0] = 6;
2751   if (dversion >= 108)
2752     {
2753       nb_actions = 5;
2754       actions[1] = ACTION_BUTTON7;
2755       actions_script[1] = 7;
2756       actions[2] = ACTION_BUTTON8;
2757       actions_script[2] = 8;
2758       actions[3] = ACTION_BUTTON9;
2759       actions_script[3] = 9;
2760       actions[4] = ACTION_BUTTON10;
2761       actions_script[4] = 10;
2762     }
2763   int i = 0;
2764   for (i = 0; i < nb_actions; i++)
2765     {
2766       // button6.c, button7.c, ..., button10.c
2767       if (sjoy.button[actions[i]] == 1)
2768 	{
2769 	  char script_filename[6+2+1]; // 'button' + '7'..'10' + '\0' (no '.c')
2770 	  sprintf(script_filename, "button%d", actions_script[i]);
2771 	  int mycrap = load_script(script_filename, 1, /*false*/0);
2772 	  if (locate(mycrap, "MAIN"))
2773 	    run_script(mycrap);
2774 	  goto b1end;
2775 	}
2776     }
2777 
2778   if (magic_script != 0 && sjoy.joybit[ACTION_MAGIC])
2779     goto shootm;
2780 
2781   if (sjoy.button[ACTION_MAGIC] == 1)
2782     {
2783       if (magic_script == 0)
2784 	{
2785 	  if (dversion >= 108)
2786 	    {
2787 	      // addition of 'no magic' script
2788 	      int sc = load_script ("dnomagic", 0, /*false*/0);
2789 	      if (sc != 0 && locate (sc, "MAIN"))
2790 		{
2791 		  run_script (sc);
2792 		  goto b1end;
2793 		}
2794 	    }
2795 
2796 	  int randy = (rand() % 6)+1;
2797 	  kill_text_owned_by(h);
2798 	  if (randy == 1) say_text(_("`$I don't know any magic."), h, 0);
2799 	  if (randy == 2) say_text(_("`$I'm no wizard!"), h, 0);
2800 	  if (randy == 3) say_text(_("`$I need to learn magic before trying this."), h, 0);
2801 	  if (randy == 4) say_text(_("`$I'm gesturing wildly to no avail!"), h, 0);
2802 	  if (randy == 5) say_text(_("`$Nothing happened."), h, 0);
2803 	  if (randy == 6) say_text(_("`$Hocus pocus!"), h, 0);
2804 	  goto b1end;
2805 	}
2806 
2807       //player pressed 1
2808       //lets magiced something
2809 shootm:
2810       if (*pmagic_level >= *pmagic_cost)
2811 	{
2812 	  if (locate(magic_script, "USE"))
2813 	    run_script(magic_script);
2814 	  goto b1end;
2815 	}
2816     }
2817 
2818   if (sjoy.button[ACTION_INVENTORY])
2819     {
2820       if (dversion >= 108)
2821 	{
2822 	  // addition of 'enter key/inventory' script
2823 	  int sc = load_script ("button4", 0, /*false*/0);
2824 	  if (sc != 0 && locate (sc, "MAIN"))
2825 	    {
2826 	      run_script (sc);
2827 	      return;
2828 	    }
2829 	}
2830 
2831       show_inventory = 1;
2832       SoundPlayEffect(18, 22050,0,0,0);
2833       return;
2834     }
2835 
2836   if (sjoy.button[ACTION_MENU] == 1)
2837     {
2838       if (!showb.active && !bow.active && !talk.active)
2839 	{
2840 	  int sc = load_script("escape", 1000, /*false*/0);
2841 	  if (sc != 0 && locate(sc, "MAIN"))
2842 	    run_script(sc);
2843 	  return;
2844 	}
2845     }
2846 
2847   if (console_active == 0)
2848     {
2849       if (GetKeyboard('b'))
2850 	ResumeMidi();
2851       if (GetKeyboard('n'))
2852 	PauseMidi();
2853     }
2854 
2855   if (spr[h].skip > 0
2856       && spr[h].skip <= spr[h].skiptimer)
2857     {
2858       spr[h].skiptimer = 0;
2859       goto b1end;
2860     }
2861 
2862 
2863   diag = 0;
2864   if (sjoy.right) diag++;
2865   if (sjoy.left) diag++;
2866   if (sjoy.down) diag++;
2867   if (sjoy.up) diag++;
2868 
2869 
2870   //*********************************PROCESS MOVEMENT
2871 
2872   if (diag == 1)
2873     {
2874       if (sjoy.right)
2875 	{
2876 	  move(h,spr[h].speed,'+','0');
2877 	  changedir(6,h,spr[h].base_walk);
2878 	}
2879 
2880       if (sjoy.left)
2881 	{
2882 	  move(h,spr[h].speed,'-','0');
2883 	  changedir(4,h,spr[h].base_walk);
2884 	}
2885 
2886       if (sjoy.down)
2887 	{
2888 	  move(h,spr[h].speed,'0','+');
2889 	  changedir(2,h,spr[h].base_walk);
2890 	}
2891 
2892       if (sjoy.up)
2893 	{
2894 	  move(h,spr[h].speed,'0','-');
2895 	  changedir(8,h,spr[h].base_walk);
2896 	}
2897     }
2898 
2899   // ***************** DIAGONAL!!!!
2900   if (diag > 1 && diag < 3)
2901     {
2902       if (sjoy.up && sjoy.left)
2903 	{
2904 	  changedir(7,h,spr[h].base_walk);
2905 	  move(h,spr[h].speed - (spr[h].speed / 3),'-','-');
2906 	}
2907 
2908       if (sjoy.down && sjoy.left)
2909 	{
2910 	  changedir(1,h,spr[h].base_walk);
2911 	  move(h,spr[h].speed - (spr[h].speed / 3),'-','+');
2912 	}
2913 
2914       if (sjoy.down && sjoy.right)
2915 	{
2916 	  changedir(3,h,spr[h].base_walk);
2917 	  move(h,spr[h].speed - (spr[h].speed / 3),'+','+');
2918 	}
2919 
2920       if (sjoy.up && sjoy.right)
2921 	{
2922 	  changedir(9,h,spr[h].base_walk);
2923 	  move(h,spr[h].speed - (spr[h].speed / 3),'+','-');
2924 	}
2925     }
2926 
2927   bad = 0;
2928   if (sjoy.right) bad = 1;
2929   if (sjoy.left) bad = 1;
2930   if (sjoy.up) bad = 1;
2931   if (sjoy.down) bad = 1;
2932 
2933   if (bad)
2934     {
2935       if (spr[h].idle)
2936 	{
2937 	  spr[h].frame = 1;
2938 	  spr[h].idle = /*FALSE*/0;
2939 	}
2940       goto badboy;
2941     }
2942 
2943   if (not_in_this_base(spr[h].seq, spr[h].base_idle)) //unccoment to allow walk anim to end before idle anim to start
2944     {
2945     freeze:
2946       if (spr[h].dir == 1) spr[h].dir = 2;
2947       if (spr[h].dir == 3) spr[h].dir = 2;
2948       if (spr[h].dir == 7) spr[h].dir = 8;
2949       if (spr[h].dir == 9) spr[h].dir = 8;
2950 
2951       if (spr[h].base_idle != 0)
2952 	changedir(spr[h].dir,h,spr[h].base_idle);
2953       spr[h].idle = /*TRUE*/1;
2954     }
2955 
2956  badboy:
2957  b1end:
2958 
2959   if (spr[h].dir == 2 || spr[h].dir == 4 || spr[h].dir == 6 || spr[h].dir == 8)
2960     goto smoothend;
2961 
2962   crap = check_if_move_is_legal(h);
2963   if (crap != 0)
2964     {
2965       if (pam.sprite[crap-100].is_warp != 0)
2966 	flub_mode = crap;
2967 
2968       //hit something, can we move around it?
2969 
2970       if (spr[h].seq == spr[h].base_walk + 4
2971 	  || spr[h].seq == spr[h].base_walk + 6)
2972 	{
2973 	  int hardm = get_hard_play(h, spr[h].x, spr[h].y-1);
2974 	  if (hardm == 0)
2975 	    spr[h].y -= 1;
2976 	}
2977 
2978       if (spr[h].seq == spr[h].base_walk + 8
2979 	  || spr[h].seq == spr[h].base_walk + 2)
2980 	{
2981 	  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y);
2982 	  if (hardm == 0)
2983 	    spr[h].x -= 1;
2984 	}
2985 
2986 
2987       if (spr[h].seq == spr[h].base_walk + 9)
2988 	{
2989 	  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y);
2990 	  if (hardm == 0)
2991 	    {
2992 	      spr[h].x += 1;
2993 
2994 	    }
2995 	  else
2996 	    {
2997 	      int hardm = get_hard_play(h, spr[h].x+1, spr[h].y+1);
2998 	      if (hardm == 0)
2999 		{
3000 		  spr[h].x += 1;
3001 		  spr[h].y += 1;
3002 		}
3003 	      else
3004 		{
3005 		  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y+2);
3006 		  if (hardm == 0)
3007 		    {
3008 		      spr[h].x += 1;
3009 		      spr[h].y += 2;
3010 		    }
3011 		  else
3012 		    {
3013 		      int hardm = get_hard_play(h, spr[h].x, spr[h].y-1);
3014 		      if (hardm == 0)
3015 			{
3016 			  spr[h].y -= 1;
3017 
3018 			}
3019 		      else
3020 			{
3021 			  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y-1);
3022 			  if (hardm == 0)
3023 			    {
3024 			      spr[h].x -= 1;
3025 			      spr[h].y -= 1;
3026 			    }
3027 			}
3028 		    }
3029 		}
3030 	    }
3031 	}
3032 
3033       if (spr[h].seq == spr[h].base_walk + 7)
3034 	{
3035 	  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y);
3036 	  if (hardm == 0)
3037 	    {
3038 	      spr[h].x -= 1;
3039 	    }
3040 	  else
3041 	    {
3042 	      int hardm = get_hard_play(h, spr[h].x-1, spr[h].y+1);
3043 	      if (hardm == 0)
3044 		{
3045 		  spr[h].x -= 1;
3046 		  spr[h].y += 1;
3047 		}
3048 	      else
3049 		{
3050 		  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y+2);
3051 		  if (hardm == 0)
3052 		    {
3053 		      spr[h].x -= 1;
3054 		      spr[h].y += 2;
3055 		    }
3056 		  else
3057 		    {
3058 		      int hardm = get_hard_play(h, spr[h].x, spr[h].y-1);
3059 		      if (hardm == 0)
3060 			{
3061 			  spr[h].y -= 1;
3062 			}
3063 		      else
3064 			{
3065 			  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y-1);
3066 			  if (hardm == 0)
3067 			    {
3068 			      spr[h].x += 1;
3069 			      spr[h].y -= 1;
3070 			    }
3071 			}
3072 		    }
3073 		}
3074 	    }
3075 	}
3076 
3077       if (spr[h].seq == spr[h].base_walk + 1)
3078 	{
3079 	  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y);
3080 	  if (hardm == 0)
3081 	    {
3082 	      spr[h].x -= 1;
3083 	    }
3084 	  else
3085 	    {
3086 	      int hardm = get_hard_play(h, spr[h].x-1, spr[h].y-1);
3087 	      if (hardm == 0)
3088 		{
3089 		  spr[h].x -= 1;
3090 		  spr[h].y -= 1;
3091 		}
3092 	      else
3093 		{
3094 		  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y-2);
3095 		  if (hardm == 0)
3096 		    {
3097 		      spr[h].x -= 1;
3098 		      spr[h].y -= 2;
3099 		    }
3100 		  else
3101 		    {
3102 		      int hardm = get_hard_play(h, spr[h].x, spr[h].y+1);
3103 		      if (hardm == 0)
3104 			{
3105 			  spr[h].y += 1;
3106 			}
3107 		      else
3108 			{
3109 			  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y+1);
3110 			  if (hardm == 0)
3111 			    {
3112 			      spr[h].x += 1;
3113 			      spr[h].y += 1;
3114 			    }
3115 			}
3116 		    }
3117 		}
3118 	    }
3119 	}
3120 
3121       if (spr[h].seq == spr[h].base_walk + 3)
3122 	{
3123 	  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y);
3124 	  if (hardm == 0)
3125 	    {
3126 	      spr[h].x += 1;
3127 	    }
3128 	  else
3129 	    {
3130 	      int hardm = get_hard_play(h, spr[h].x+1, spr[h].y-1);
3131 	      if (hardm == 0)
3132 		{
3133 		  spr[h].x += 1;
3134 		  spr[h].y -= 1;
3135 		}
3136 	      else
3137 		{
3138 		  int hardm = get_hard_play(h, spr[h].x+1, spr[h].y-2);
3139 		  if (hardm == 0)
3140 		    {
3141 		      spr[h].x += 1;
3142 		      spr[h].y -= 2;
3143 		    }
3144 		  else
3145 		    {
3146 		      int hardm = get_hard_play(h, spr[h].x, spr[h].y+1);
3147 		      if (hardm == 0)
3148 			{
3149 			  spr[h].y += 1;
3150 			}
3151 		      else
3152 			{
3153 			  int hardm = get_hard_play(h, spr[h].x-1, spr[h].y+1);
3154 			  if (hardm == 0)
3155 			    {
3156 			      spr[h].x -= 1;
3157 			      spr[h].y += 1;
3158 			    }
3159 			}
3160 		    }
3161 		}
3162 	    }
3163 	}
3164     }
3165 
3166  smoothend:
3167   ;
3168 }
3169 
3170 
transition()3171 /*bool*/int transition()
3172 {
3173   SDL_Rect src, dst;
3174 
3175   //we need to do our fancy screen transition
3176   int dumb = fps_final * 2;
3177 
3178   if (0) //DEBUG
3179     {
3180       // Make the transition last ~5 seconds
3181       if (move_screen == 4 || move_screen == 6)
3182 	dumb = 600 / (fps_final * 5);
3183       else if (move_screen == 8 || move_screen == 2)
3184 	dumb = 400 / (fps_final * 5);
3185     }
3186 
3187   move_counter += dumb;
3188 
3189 
3190   if (move_screen == 4)
3191     {
3192       if (move_counter > 598)
3193 	move_counter = 598;
3194 
3195       src.x = 0;
3196       src.y = 0;
3197       src.w = 600 - move_counter;
3198       src.h = 400;
3199       dst.x = 20 + move_counter;
3200       dst.y = 0;
3201       SDL_BlitSurface(GFX_lpDDSTrick, &src, GFX_lpDDSBack, &dst);
3202 
3203       src.x = 600 - move_counter;
3204       src.y = 0;
3205       src.w = move_counter;
3206       src.h = 400;
3207       dst.x = 20;
3208       dst.y = 0;
3209       SDL_BlitSurface(GFX_lpDDSTrick2, &src, GFX_lpDDSBack, &dst);
3210 
3211       if (move_counter >= 595)
3212 	{
3213 	  total_trigger = /*false*/0;
3214 	  move_screen = 0;
3215 	  move_counter = 0;
3216 	  trig_man = 0;
3217 	  //draw_map();
3218 	  return /*false*/0;
3219 	}
3220 
3221       return /*true*/1;
3222     }
3223 
3224 
3225   if (move_screen == 6)
3226     {
3227       if (move_counter > 598)
3228 	move_counter = 598;
3229 
3230       src.x = move_counter;
3231       src.y = 0;
3232       src.w = 600 - move_counter;
3233       src.h = 400;
3234       dst.x = 20;
3235       dst.y = 0;
3236       SDL_BlitSurface(GFX_lpDDSTrick, &src, GFX_lpDDSBack, &dst);
3237 
3238       src.x = 0;
3239       src.y = 0;
3240       src.w = move_counter;
3241       src.h = 400;
3242       dst.x = 620 - move_counter;
3243       dst.y = 0;
3244       SDL_BlitSurface(GFX_lpDDSTrick2, &src, GFX_lpDDSBack, &dst);
3245 
3246       if (move_counter >= 595)
3247 	{
3248 	  total_trigger = /*false*/0;
3249 	  move_screen = 0;
3250 	  move_counter = 0;
3251 	  trig_man = 0;
3252 	  //draw_map();
3253 	  return /*false*/0;
3254 	}
3255 
3256       return /*true*/1;
3257     }
3258 
3259 
3260   if (move_screen == 8)
3261     {
3262       if (move_counter > 398)
3263 	move_counter = 398;
3264 
3265       src.x = 0;
3266       src.y = 0;
3267       src.w = 600;
3268       src.h = 400 - move_counter;
3269       dst.x = 20;
3270       dst.y = move_counter;
3271       SDL_BlitSurface(GFX_lpDDSTrick, &src, GFX_lpDDSBack, &dst);
3272 
3273       src.x = 0;
3274       src.y = 400 - move_counter;
3275       src.w = 600;
3276       src.h = move_counter;
3277       dst.x = 20;
3278       dst.y = 0;
3279       SDL_BlitSurface(GFX_lpDDSTrick2, &src, GFX_lpDDSBack, &dst);
3280 
3281       if (move_counter >= 398)
3282 	{
3283 	  total_trigger = /*false*/0;
3284 	  move_screen = 0;
3285 	  move_counter = 0;
3286 	  trig_man = 0;
3287 	  //draw_map();
3288 	  return /*false*/0;
3289 	}
3290 
3291       return /*true*/1;
3292     }
3293 
3294 
3295   if (move_screen == 2)
3296     {
3297       if (move_counter > 398)
3298 	move_counter = 398;
3299 
3300       src.x = 0;
3301       src.y = move_counter;
3302       src.w = 600;
3303       src.h = 400 - move_counter;
3304       dst.x = 20;
3305       dst.y = 0;
3306       SDL_BlitSurface(GFX_lpDDSTrick, &src, GFX_lpDDSBack, &dst);
3307 
3308       src.x = 0;
3309       src.y = 0;
3310       src.w = 600;
3311       src.h = move_counter;
3312       dst.x = 20;
3313       dst.y = 400 - move_counter;
3314       SDL_BlitSurface(GFX_lpDDSTrick2, &src, GFX_lpDDSBack, &dst);
3315 
3316       if (move_counter >= 398)
3317 	{
3318 	  total_trigger = /*false*/0;
3319 	  move_screen = 0;
3320 	  move_counter = 0;
3321 	  trig_man = 0;
3322 	  //draw_map();
3323 	  return /*false*/0;
3324 	}
3325 
3326       return /*true*/1;
3327     }
3328 
3329   return /*false*/0;
3330 }
3331 
3332 
3333 /**
3334  * Trigger a warp (teleport)
3335  * block: the warp editor sprite
3336  */
special_block(int block)3337 int special_block(int block)
3338 {
3339   if (pam.sprite[block].is_warp == 1)
3340     {
3341       //they touched a warp
3342       if (pam.sprite[block].sound == 0)
3343         SoundPlayEffect(7, 12000, 0, 0, 0);
3344       else
3345         SoundPlayEffect(pam.sprite[block].sound, 22050, 0, 0, 0);
3346 
3347       if (pam.sprite[block].parm_seq != 0)
3348         {
3349           // we'll also play an animation here
3350           int sprite = find_sprite(block);
3351           if (sprite > 0)
3352             {
3353               spr[sprite].seq = pam.sprite[block].parm_seq;
3354               process_warp = block;
3355             }
3356           return 1;
3357         }
3358       process_warp = block;
3359       return 1; // redraw screen with fade
3360     }
3361   return 0;
3362 }
3363 
3364 /* fade_down() - fade to black */
CyclePalette()3365 void CyclePalette()
3366 {
3367   if (!truecolor)
3368     {
3369       SDL_Color palette[256];
3370       int kk;
3371 
3372       gfx_palette_get_phys(palette);
3373 
3374       for (kk = 1; kk < 256; kk++) /* skipping index 0 because it's
3375 				      already (and always) black ;) */
3376 	{
3377 	  if (dversion >= 108)
3378 	    {
3379 	      /* Use time-based rather than absolute increments;
3380 		 avoids incomplete fades on slow computers */
3381 	      /* dt / 2 == dt * 256 / 512 == complete fade in 512ms */
3382 	      int lValue = (thisTickCount - lastTickCount) / 2;
3383 	      if (palette[kk].b != 0)
3384 		{
3385 		  if (palette[kk].b > lValue)
3386 		    palette[kk].b -= lValue;
3387 		  else
3388 		    palette[kk].b = 0;
3389 		}
3390 	      if (palette[kk].g != 0)
3391 		{
3392 		  if (palette[kk].g > lValue)
3393 		    palette[kk].g -= lValue;
3394 		  else
3395 		    palette[kk].g = 0;
3396 		}
3397 	      if (palette[kk].r != 0)
3398 		{
3399 		  if (palette[kk].r > lValue)
3400 		    palette[kk].r -= lValue;
3401 		  else
3402 		    palette[kk].r = 0;
3403 		}
3404 	    }
3405 	  else
3406 	    {
3407 	      if (palette[kk].b != 0)
3408 		{
3409 		  if (palette[kk].b > 10)
3410 		    palette[kk].b -= 10;
3411 		  else
3412 		    palette[kk].b--;
3413 		}
3414 	      if (palette[kk].g != 0)
3415 		{
3416 		  if (palette[kk].g > 10)
3417 		    palette[kk].g -= 10;
3418 		  else
3419 		    palette[kk].g--;
3420 		}
3421 	      if (palette[kk].r != 0)
3422 		{
3423 		  if (palette[kk].r > 10)
3424 		    palette[kk].r -= 10;
3425 		  else
3426 		    palette[kk].r--;
3427 		}
3428 	    }
3429 	}
3430 
3431       gfx_palette_set_phys(palette);
3432     }
3433   else
3434     {
3435       /* truecolor */
3436       if (truecolor_fade_lasttick == -1)
3437 	{
3438 	  truecolor_fade_lasttick = game_GetTicks();
3439 	  //truecolor_fade_brightness -= 256*.3;
3440 	}
3441       else
3442 	{
3443 	  int delta = game_GetTicks() - truecolor_fade_lasttick;
3444 	  /* Complete fade in 400ms */
3445 	  truecolor_fade_lasttick = game_GetTicks();
3446 	  truecolor_fade_brightness -= delta * 256 / 400.0;
3447 	}
3448       if (truecolor_fade_brightness <= 0)
3449 	truecolor_fade_brightness = 0;
3450 
3451     }
3452 
3453   if (process_downcycle)
3454     {
3455       if (thisTickCount > cycle_clock)
3456 	{
3457 	  process_downcycle = /*false*/0;
3458 	  truecolor_fade_lasttick = -1;
3459 
3460 	  if (cycle_script != 0)
3461 	    {
3462 	      int junk = cycle_script;
3463 	      cycle_script = 0;
3464 	      run_script(junk);
3465 	    }
3466 	}
3467     }
3468 }
3469 
3470 /* fade_up() */
up_cycle(void)3471 void up_cycle(void)
3472 {
3473   int donethistime = 1;
3474 
3475   if (!truecolor)
3476     {
3477       SDL_Color palette[256];
3478       int kk;
3479 
3480       gfx_palette_get_phys(palette);
3481 
3482       for (kk = 1; kk < 256; kk++)
3483 	{
3484 	  int tmp = -1;
3485 
3486 	  tmp = palette[kk].b; // 'int' to avoid 'char' overflow
3487 	  if (tmp != GFX_real_pal[kk].b)
3488 	    {
3489 	      donethistime = 0;
3490 	      if (tmp > 246)
3491 		tmp++;
3492 	      else
3493 		tmp += 10;
3494 	    }
3495 	  if (tmp > GFX_real_pal[kk].b)
3496 	    tmp = GFX_real_pal[kk].b;
3497 	  palette[kk].b = tmp;
3498 
3499 	  tmp = palette[kk].g; // 'int' to avoid 'char' overflow
3500 	  if (tmp != GFX_real_pal[kk].g)
3501 	    {
3502 	      donethistime = 0;
3503 	      if (tmp > 246)
3504 		tmp++;
3505 	      else
3506 		tmp += 10;
3507 	    }
3508 	  if (tmp > GFX_real_pal[kk].g)
3509 	    tmp = GFX_real_pal[kk].g;
3510 	  palette[kk].g = tmp;
3511 
3512 	  tmp = palette[kk].r; // 'int' to avoid 'char' overflow
3513 	  if (tmp != GFX_real_pal[kk].r)
3514 	    {
3515 	      donethistime = 0;
3516 	      if (tmp > 246)
3517 		tmp++;
3518 	      else
3519 		tmp += 10;
3520 	    }
3521 	  if (tmp > GFX_real_pal[kk].r)
3522 	    tmp = GFX_real_pal[kk].r;
3523 	  palette[kk].r = tmp;
3524 	}
3525 
3526       gfx_palette_set_phys(palette);
3527     }
3528   else
3529     {
3530       /* truecolor */
3531       donethistime = 0;
3532       if (truecolor_fade_lasttick == -1)
3533 	{
3534 	  truecolor_fade_lasttick = game_GetTicks();
3535 	  //truecolor_fade_brightness += 256*.3;
3536 	}
3537       else
3538 	{
3539 	  int delta = game_GetTicks() - truecolor_fade_lasttick;
3540 	  /* Complete fade in 400ms */
3541 	  truecolor_fade_lasttick = game_GetTicks();
3542 	  truecolor_fade_brightness += delta * 256 / 400.0;
3543 	}
3544       if (truecolor_fade_brightness >= 256)
3545 	{
3546 	  truecolor_fade_brightness = 256;
3547 	  donethistime = 1;
3548 	}
3549     }
3550 
3551   if (process_upcycle)
3552     if (donethistime == 1)
3553       {
3554 	process_upcycle = 0;
3555 	truecolor_fade_lasttick = -1;
3556 
3557 	if (cycle_script != 0)
3558 	  {
3559 	    int junk = cycle_script;
3560 	    cycle_script = 0;
3561 	    run_script(junk);
3562 	  }
3563       }
3564 }
3565 
3566 
draw_box(rect box,int color)3567 void draw_box(rect box, int color)
3568 {
3569 /*   DDBLTFX     ddbltfx; */
3570 
3571 /*   ddbltfx.dwSize = sizeof(ddbltfx); */
3572 /*   ddbltfx.dwFillColor = color; */
3573 
3574 /*   ddrval = lpDDSBack->Blt(&box ,NULL, NULL, DDBLT_COLORFILL| DDBLT_WAIT, &ddbltfx); */
3575   // GFX
3576   {
3577     SDL_Rect dst;
3578     dst.x = box.left; dst.y = box.top;
3579     dst.w = box.right - box.left;
3580     dst.h = box.bottom - box.top;
3581     SDL_FillRect(GFX_lpDDSBack, &dst, color);
3582   }
3583 }
3584 
3585 
3586 /**
3587  * Check which sprites are affected by an attack from 'h', the
3588  * attacker.
3589  */
run_through_tag_list(int h,int strength)3590 	void run_through_tag_list(int h, int strength)
3591 	{
3592 		rect box;
3593 		int amount, amounty;
3594 		int i;
3595 
3596 		for (i = 1; i <= last_sprite_created; i++)
3597 		{
3598 			if (spr[i].active) if (i != h) if
3599 				(! ( (spr[i].nohit == 1) && (spr[i].script == 0)) )
3600 			{
3601 
3602 				rect_copy(&box, &k[getpic(i)].hardbox);
3603 				rect_offset(&box, spr[i].x, spr[i].y);
3604 
3605 				//InflateRect(&box, 10,10);
3606 
3607 				box.right += 5;
3608 				box.left -= 5;
3609 				box.top -= 5;
3610 				box.bottom += 10;
3611 				if (spr[h].range == 0)
3612 					amount = 28; else amount = spr[h].range;
3613 
3614 				if (spr[h].range == 0)
3615 
3616 					amounty = 36; else amounty = (spr[h].range + (spr[h].range / 6));
3617 
3618 				int range_amount = spr[h].range / 8;
3619 
3620 				if (spr[h].dir == 6)
3621 				{
3622 					box.top -= 10;
3623 					box.bottom += 10;
3624 					if (spr[h].range != 0) box.top -= range_amount;
3625 					if (spr[h].range != 0) box.bottom += range_amount;
3626 
3627 
3628 					box.left -= amount;
3629 				}
3630 
3631 				if (spr[h].dir == 4)
3632 				{
3633 					box.right += amount;
3634 
3635 					box.top -= 10;
3636 					box.bottom += 10;
3637 					if (spr[h].range != 0) box.top -= range_amount;
3638 					if (spr[h].range != 0) box.bottom += range_amount;
3639 
3640 				}
3641 
3642 
3643 				if (spr[h].dir == 2)
3644 				{
3645 					box.right += 10;
3646 					box.left -= 10;
3647 					box.top -= amounty;
3648 
3649 					if (spr[h].range != 0) box.right += range_amount;
3650 					if (spr[h].range != 0) box.left -= range_amount;
3651 
3652 				}
3653 
3654 				if (spr[h].dir == 8)
3655 				{
3656 					box.right += 10;
3657 					box.left -= 10;
3658 					box.bottom += amounty;
3659 
3660 					if (spr[h].range != 0) box.right += range_amount;
3661 					if (spr[h].range != 0) box.right -= range_amount;
3662 
3663 				}
3664 
3665 				if (debug_mode) draw_box(box, 33);
3666 
3667 				if (inside_box(spr[h].x, spr[h].y, box))
3668 				{
3669 					// addition for fixing missle_source problems
3670 					if (dversion >= 108)
3671 					  *pmissle_source = h;
3672 
3673 					if (spr[i].nohit == 1)
3674 					{
3675 						if (spr[i].script > 0)
3676 						{
3677 							//if (  (spr[i].brain == 0) | (spr[i].brain == 5) | (spr[i].brain == 6) | (spr[i].brain == 7))
3678 							*penemy_sprite = h;
3679 
3680 							if (  (spr[i].base_attack != -1) || (spr[i].touch_damage > 0))
3681 								spr[i].target = h;
3682 
3683 							if (locate(spr[i].script, "HIT"))
3684 							{
3685 								kill_returning_stuff(spr[i].script);
3686 								run_script(spr[i].script);
3687 							}
3688 
3689 
3690 						}
3691 
3692 
3693 					} else
3694 					{
3695 						//hit this personb/thing
3696 						if (spr[h].attack_hit_sound == 0)
3697 						{
3698 							SoundPlayEffect( 9,22050, 0 ,0,0);
3699 						} else
3700 						{
3701 							SoundPlayEffect( spr[h].attack_hit_sound,spr[h].attack_hit_sound_speed, 0 ,0,0);
3702 						}
3703 						if (  (spr[i].base_attack != -1) || (spr[i].touch_damage > 0))
3704 							spr[i].target = h;
3705 						if (spr[h].strength == 0)
3706 						{
3707 
3708 						} else
3709 						{
3710 							if (  (spr[i].hitpoints > 0) || (i == 1) )
3711 							{
3712 
3713 								spr[i].last_hit = h;
3714 								if ( hurt_thing(i, (spr[h].strength / 2) + ((rand() % ((spr[h].strength+1) / 2))+1), 0) > 0)
3715 									random_blood(spr[i].x, spr[i].y-40, i);
3716 							}
3717 
3718 						}
3719 						if (spr[i].script > 0)
3720 						{
3721 							//if (  (spr[i].brain == 0) | (spr[i].brain == 5) | (spr[i].brain == 6) | (spr[i].brain == 7))
3722 							spr[i].last_hit = h;
3723 							*penemy_sprite = h;
3724 							if (  (spr[i].base_attack != -1) || (spr[i].touch_damage > 0))
3725 								spr[i].target = h;
3726 
3727 							if (locate(spr[i].script, "HIT"))
3728 							{
3729 								kill_returning_stuff(spr[i].script);
3730 								run_script(spr[i].script);
3731 							}
3732 
3733 						}
3734 
3735 					}
3736 
3737 				}
3738 
3739 		}
3740 
3741 	}
3742 
3743 }
3744 
3745 
3746 
run_through_tag_list_push(int h)3747 void run_through_tag_list_push(int h)
3748 {
3749 	rect box;
3750 	int i;
3751 
3752 	for (i = 1; i <= last_sprite_created; i++)
3753 	{
3754 		if (spr[i].active) if (i != h) if
3755 			((spr[i].script != 0) )
3756 		{
3757 
3758 			rect_copy(&box, &k[getpic(i)].hardbox);
3759 			rect_offset(&box, spr[i].x, spr[i].y);
3760 
3761 			//InflateRect(&box, 10,10);
3762 
3763 			box.right += 2;
3764 			box.left -= 2;
3765 			box.top -= 2;
3766 			box.bottom += 2;
3767 			//draw_box(box, 33);
3768 
3769 			if (inside_box(spr[h].x, spr[h].y, box))
3770 			{
3771 				if (locate(spr[i].script, "PUSH")) run_script(spr[i].script);
3772 			}
3773 
3774 		}
3775 
3776 	}
3777 
3778 }
3779 
3780 
3781 
3782 
run_through_touch_damage_list(int h)3783 void run_through_touch_damage_list(int h)
3784 {
3785 	rect box;
3786 	int i;
3787 
3788 	for (i = 1; i <= last_sprite_created; i++)
3789 	{
3790 		if (spr[i].active) if (i != h) if
3791 			((spr[i].touch_damage != 0) )
3792 		{
3793 
3794 			if (spr[i].touch_damage != -1) if (spr[h].notouch) return;
3795 			rect_copy(&box, &k[getpic(i)].hardbox);
3796 			rect_offset(&box, spr[i].x, spr[i].y);
3797 
3798 			//InflateRect(&box, 10,10);
3799 
3800 			box.right += 2;
3801 			box.left -= 2;
3802 			box.top -= 2;
3803 			box.bottom += 2;
3804 			if (debug_mode)
3805 				draw_box(box, 33);
3806 
3807 
3808 			if (inside_box(spr[h].x, spr[h].y, box))
3809 			{
3810 
3811 				if ((spr[i].touch_damage == -1) && (spr[i].script != 0))
3812 				{
3813 					if (locate(spr[i].script, "TOUCH")) run_script(spr[i].script);
3814 				} else
3815 				{
3816 					if (spr[i].touch_damage == -1)
3817 					{
3818 						log_error("Sprites touch damage is set to -1 but there is no script set!");
3819 					} else
3820 					{
3821 						//lets hurt the guy
3822 
3823 						spr[h].notouch = /*true*/1;
3824 						spr[h].notouch_timer = thisTickCount+400;
3825 						spr[h].last_hit = i;
3826 						if (spr[i].script != 0)
3827 							if (locate(spr[i].script, "TOUCH")) run_script(spr[i].script);
3828 							if (hurt_thing(h, spr[i].touch_damage, 0) > 0)
3829 								random_blood(spr[h].x, spr[h].y-40, h);
3830 
3831 
3832 					}
3833 
3834 				}
3835 
3836 
3837 
3838 			}
3839 
3840 
3841 		}
3842 
3843 	}
3844 
3845 }
3846 
3847 
3848 
3849 
process_warp_man(void)3850 void process_warp_man(void)
3851 {
3852   int sprite = find_sprite(process_warp);
3853 
3854   /* warp sprite doesn't exist (e.g. merged background sprite), or
3855      warp anim is finished */
3856   /* Cf. http://www.dinknetwork.com/forum.cgi?MID=168476 */
3857   if (sprite == 0 || spr[sprite].seq == 0)
3858     {
3859       process_count++;
3860       CyclePalette();
3861       /* Wait 5 CyclePalette before blanking the screen and
3862 	 warp. Truecolor more: the fade algorithm is a bit different
3863 	 and requires a few more cycles to get the same effect; unlike
3864 	 v1.08, we don't wait for a full fadedown, which is long and
3865 	 can be not very smooth on old computers. */
3866       if ((!truecolor && process_count > 5)
3867 	  || (truecolor && truecolor_fade_brightness <= 180))
3868 	{
3869 	  SDL_FillRect(GFX_lpDDSBack, NULL,
3870 		       SDL_MapRGB(GFX_lpDDSBack->format, 0, 0, 0));
3871 	  flip_it();
3872 
3873 	  process_count = 0;
3874 	  int block = process_warp;
3875 	  update_screen_time();
3876 	  spr[1].x = pam.sprite[block].warp_x;
3877 	  spr[1].y = pam.sprite[block].warp_y;
3878 	  *pmap = pam.sprite[block].warp_map;
3879 
3880 	  // update map indicator
3881 	  if (map.indoor[pam.sprite[block].warp_map] == 0)
3882 	    play.last_map = pam.sprite[block].warp_map;
3883 
3884 	  load_map(map.loc[pam.sprite[block].warp_map]);
3885 	  draw_map_game();
3886 
3887 	  process_upcycle = 1;
3888 	  process_warp = 0;
3889 	}
3890     }
3891   else /* warp anim didn't finish yet */
3892     {
3893       process_count = 0;
3894     }
3895 }
3896 
one_time_brain(int h)3897 void one_time_brain(int h)
3898 {
3899 
3900 	//goes once then draws last frame to background
3901 
3902 	if (spr[h].move_active)
3903 	{
3904 		process_move(h);
3905 		return;
3906 	}
3907 
3908 	if (spr[h].follow > 0)
3909 	{
3910 		process_follow(h);
3911 	}
3912 
3913 
3914 	if (spr[h].seq == 0)
3915 	{
3916 	  draw_sprite_game(GFX_lpDDSTwo, h);
3917 		spr[h].active = /*false*/0;
3918 		return;
3919 	}
3920 
3921 	changedir(spr[h].dir,h,-1);
3922 	automove(h);
3923 
3924 }
3925 
one_time_brain_for_real(int h)3926 void one_time_brain_for_real(int h)
3927 {
3928 
3929 	if (spr[h].move_active)
3930 	{
3931 		process_move(h);
3932 	}
3933 
3934 
3935 	if (spr[h].follow > 0)
3936 	{
3937 		process_follow(h);
3938 	}
3939 
3940 
3941 	if (spr[h].seq == 0)
3942 	{
3943 
3944 		spr[h].active = /*false*/0;
3945 		return;
3946 	}
3947 	if (spr[h].dir > 0)
3948 	{
3949 		changedir(spr[h].dir,h,-1);
3950 		automove(h);
3951 	}
3952 }
3953 
3954 
scale_brain(int h)3955 void scale_brain(int h)
3956 {
3957 
3958 	if (spr[h].size == spr[h].brain_parm)
3959 	{
3960 		spr[h].active = /*false*/0;
3961 
3962 
3963 		return;
3964 	}
3965 
3966 	int num = 5 * (base_timing / 4);
3967 
3968 
3969 
3970 	if (spr[h].size > spr[h].brain_parm)
3971 	{
3972 		if (spr[h].size - num < spr[h].brain_parm) num = spr[h].size - spr[h].brain_parm;
3973 		spr[h].size -= num;
3974 	}
3975 
3976 	if (spr[h].size < spr[h].brain_parm)
3977 	{
3978 		if (spr[h].size + num > spr[h].brain_parm) num = spr[h].brain_parm - spr[h].size;
3979 		spr[h].size += num;
3980 	}
3981 	if (spr[h].move_active)
3982 	{
3983 		process_move(h);
3984 		return;
3985 	}
3986 
3987 
3988 
3989 	if (spr[h].dir > 0)
3990 	{
3991 		changedir(spr[h].dir,h,-1);
3992 		automove(h);
3993 	}
3994 
3995 
3996 }
3997 
3998 
3999 
repeat_brain(int h)4000 void repeat_brain(int h)
4001 {
4002 
4003 	if (spr[h].move_active)
4004 	{
4005 		process_move(h);
4006 		//		return;
4007 	}
4008 
4009 
4010 	if (spr[h].seq_orig == 0) if (spr[h].sp_index != 0)
4011 	{
4012 		spr[h].seq_orig = pam.sprite[spr[h].sp_index].seq;
4013 		spr[h].frame = pam.sprite[spr[h].sp_index].frame;
4014 		spr[h].wait = 0;
4015 
4016 		//pam.sprite[spr[h].sp_index].frame;
4017 
4018 	}
4019 
4020 	   if (spr[h].seq == 0) spr[h].seq = spr[h].seq_orig;
4021 
4022 }
4023 
4024 
text_brain(int h)4025 void text_brain(int h)
4026 {
4027 
4028 
4029 
4030 	if (  (spr[h].damage == -1) && (spr[h].owner != 1000))
4031 	{
4032 
4033 		if (spr[spr[h].owner].active == /*false*/0)
4034 		{
4035 			//msg("Killing text brain %d, because owner %d is dead.",h, spr[h].owner);
4036 			spr[h].active = /*false*/0;
4037 			return;
4038 		}
4039 
4040 		//give this text the cords from it's owner sprite
4041 		spr[h].x = spr[spr[h].owner].x - spr[h].strength;
4042 
4043 
4044 		spr[h].y = spr[spr[h].owner].y - spr[h].defense;
4045 
4046 		if (spr[h].x < 1) spr[h].x = 1;
4047 
4048 		if (spr[h].y < 1) spr[h].y = 1;
4049 
4050 
4051 	} else
4052 	{
4053 		//Msg("automoving %d.. ", h);
4054 
4055 		if (spr[h].move_active)
4056 		{
4057 			process_move(h);
4058 			return;
4059 		}
4060 
4061 
4062 		automove(h);
4063 	}
4064 
4065 }
4066 
4067 
process_talk()4068 void process_talk()
4069 {
4070   int px = 48, py = 44;
4071 
4072   int sx = 184;
4073   int sy = 94, sy_hold, sy_ho;
4074 /*   int spacing = 12; */
4075   int curxl = 126;
4076   int curxr = 462;
4077   int curyr = 200;
4078   int curyl = 200;
4079 
4080   int y_last = 0, y_hold = 0, y_ho;
4081 /*   HDC         hdc; */
4082   rect rcRect;
4083   int i;
4084   int x_depth = 335;
4085   if (talk.newy != -5000)
4086     sy = talk.newy;
4087 
4088   sy_hold = sy;
4089   sy_ho = sy;
4090 
4091   check_seq_status(30);
4092 
4093   int fake_page;
4094 /*  again: */
4095 /*   ddrval = lpDDSBack->BltFast( px, py, k[seq[30].frame[2]].k, */
4096 /* 			       &k[seq[30].frame[2]].box  , DDBLTFAST_SRCCOLORKEY  ); */
4097 /*   if (ddrval == DDERR_WASSTILLDRAWING) goto again; */
4098   // GFX
4099   {
4100     SDL_Rect dst;
4101     dst.x = px; dst.y = py;
4102     SDL_BlitSurface(GFX_k[seq[30].frame[2]].k, NULL, GFX_lpDDSBack, &dst);
4103   }
4104 
4105 /*  again2:	 */
4106 /*   ddrval = lpDDSBack->BltFast( px+169, py+42, k[seq[30].frame[3]].k, */
4107 /* 			       &k[seq[30].frame[3]].box  , DDBLTFAST_SRCCOLORKEY  ); */
4108 /*   if (ddrval == DDERR_WASSTILLDRAWING) goto again2; */
4109   // GFX
4110   {
4111     SDL_Rect dst;
4112     dst.x = px + 169; dst.y = py + 42;
4113     SDL_BlitSurface(GFX_k[seq[30].frame[3]].k, NULL, GFX_lpDDSBack, &dst);
4114   }
4115 
4116 /*  again3: */
4117 /*   ddrval = lpDDSBack->BltFast( px+169+180, py+1, k[seq[30].frame[4]].k, */
4118 /* 			       &k[seq[30].frame[4]].box  , DDBLTFAST_SRCCOLORKEY  ); */
4119 /*   if (ddrval == DDERR_WASSTILLDRAWING) goto again3; */
4120   // GFX
4121   {
4122     SDL_Rect dst;
4123     dst.x = px+169+180; dst.y = py+1;
4124     if (SDL_BlitSurface(GFX_k[seq[30].frame[4]].k, NULL, GFX_lpDDSBack, &dst) < 0)
4125       log_error("Could not draw sprite %d: %s", seq[30].frame[4], SDL_GetError());
4126   }
4127 
4128 
4129   int talk_hold = talk.cur;
4130   if (sjoy.rightd) talk.cur++;
4131   if (sjoy.downd) talk.cur++;
4132   if (sjoy.upd) talk.cur--;
4133   if (sjoy.leftd) talk.cur--;
4134 
4135   if (play.mouse > 20)
4136     {
4137       talk.cur++;
4138       play.mouse = 0;
4139     }
4140 
4141   if (play.mouse < -20)
4142     {
4143       talk.cur--;
4144       play.mouse = 0;
4145     }
4146 
4147 
4148   if (talk_hold != talk.cur)
4149     {
4150       if (talk.cur >= talk.cur_view)
4151 	if (talk.cur <= talk.cur_view_end)
4152 	  SoundPlayEffect(11, 22050,0,0,0);
4153     }
4154 
4155 /*   if (lpDDSBack->GetDC(&hdc) == DD_OK) */
4156 /*     {       */
4157 
4158 /*       SelectObject (hdc, hfont_small); */
4159       // FONTS
4160       //FONTS_SetFont(FONTS_hfont_small);
4161 /*       SetBkMode(hdc, TRANSPARENT);  */
4162 
4163 
4164 
4165       /* Print dialog title, if any */
4166       if (strlen(talk.buffer) > 0)
4167 	{
4168 	  rect_set(&rcRect, sx, 94, 463, 400);
4169 	  /* if using an explicit "set_y" after "choice_start()": */
4170 	  if (talk.newy != -5000)
4171 	    rcRect.bottom = talk.newy + 15;
4172 
4173 /* 	  SetTextColor(hdc,RGB(8,14,21)); */
4174 	  // FONTS
4175 	  FONTS_SetTextColor(8, 14, 21);
4176 /* 	  DrawText(hdc,talk.buffer,strlen(talk.buffer),&rcRect,DT_VCENTER | DT_CENTER | DT_WORDBREAK); */
4177 	  // FONTS
4178 	  //printf("(%dx%d)x(%dx%d)\n", rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
4179 	  print_text_wrap(talk.buffer, &rcRect, 1, 0, FONT_DIALOG);
4180 
4181 
4182 	   /* Same of in text_draw, except for #1 and default */
4183 	   // FONTS:
4184 	   // support for custom colors
4185 	   if (talk.color >= 1 && talk.color <= 15)
4186 	     FONTS_SetTextColorIndex(talk.color);
4187 	   else
4188 	     {
4189 	       if (dversion >= 108)
4190 		 FONTS_SetTextColor(255, 255, 255);
4191 	       else
4192 		 FONTS_SetTextColor(255, 255, 2);
4193 	    }
4194 
4195 	  rect_offset(&rcRect, 1, 1);
4196 /* 	  DrawText(hdc,talk.buffer,strlen(talk.buffer),&rcRect,DT_VCENTER | DT_CENTER | DT_WORDBREAK);	 */
4197 	  // FONTS
4198 	  print_text_wrap(talk.buffer, &rcRect, 1, 0, FONT_DIALOG);
4199 
4200 /* 	  SetTextColor(hdc,RGB(8,14,21)); */
4201 	  // FONTS
4202 	  FONTS_SetTextColor(8, 14, 21);
4203 	}
4204 
4205 
4206 
4207 
4208       //tabulate distance needed by text, LORDII experience helped here
4209       //recal:
4210       for (i = talk.cur_view; i < talk.last; i++)
4211 	{
4212 	  rect_set(&rcRect,sx,y_hold,463,x_depth+100);
4213 /* 	  y_hold = DrawText(hdc,talk.line[i],lstrlen(talk.line[i]),&rcRect,DT_CALCRECT | DT_CENTER | DT_WORDBREAK); */
4214 	  // FONTS
4215 	  /* Don't print, only check the height in pixel: */
4216 	  y_hold = print_text_wrap(talk.line[i], &rcRect, 1, 1, FONT_DIALOG);
4217 	  sy_hold += y_hold;
4218 
4219 	  //Msg("Sy_hold = %d (%d)", sy_hold,i);
4220 
4221 	  if (sy_hold > x_depth)
4222 	    {
4223 
4224 	      talk.cur_view_end = i-1;
4225 	      //Msg("Sy is over, sp cur_view is %d ", talk.cur_view_end);
4226 	      goto death;
4227 	    }
4228 	}
4229 
4230       talk.cur_view_end = i;
4231 
4232       if (talk.cur_view == 1 && talk.cur_view_end == talk.last)
4233 	{
4234 	  //Msg("Small enough to fit on one screen, lets center it!");
4235 	  sy += ( (x_depth - sy_hold) / 2) - 20;
4236 	}
4237     death:
4238       if (talk.cur > talk.last)
4239 	{
4240 	  SoundPlayEffect(11, 22050,0,0,0);
4241 
4242 	  talk.cur = 1;
4243 
4244 	}
4245       if (talk.cur < 1)
4246 	{
4247 	  SoundPlayEffect(11, 22050,0,0,0);
4248 
4249 	  talk.cur = talk.last;
4250 	}
4251 
4252 
4253       //if (talk.cur_view_end != talk.last)
4254       {
4255 	//Msg("Talkcur is %d, talk cur view is %d", talk.cur, talk.cur_view);
4256 	//total options too large for page, lets scroll
4257 
4258 
4259 	if (talk.cur > talk.cur_view_end)
4260 	  {
4261 	    //     Msg("advancing page:  talkcur is %d, changing cur_view to same", talk.cur, talk.cur_view);
4262 	    talk.cur_view = talk.cur;
4263 	    talk.page ++;
4264 
4265 	    // Msg("Page advanced to %d. (cur_end is %d, cur is %d)", talk.page,talk.cur_view_end, talk.cur);
4266 	    goto fin;
4267 	  }
4268 
4269 
4270 
4271 	if (talk.cur < talk.cur_view)
4272 	  {
4273 	    //	Msg("Turning back the clock from page %d..", talk.page);
4274 
4275 	    talk.cur_view = 1;
4276 	    // talk.cur = 1;
4277 
4278 	    talk.page--;
4279 	    log_info("Page backed to %d.", talk.page);
4280 	    fake_page = 1;
4281 	    for (i = 1; i < talk.last; i++)
4282 	      {
4283 		rect_set(&rcRect,sx,sy_ho,463,x_depth);
4284 
4285 /* 		y_ho = DrawText(hdc,talk.line[i],lstrlen(talk.line[i]),&rcRect,DT_CALCRECT | DT_CENTER | DT_WORDBREAK); */
4286 		// FONTS
4287 		/* Don't print, only check the height in pixel: */
4288 		y_ho = print_text_wrap(talk.line[i], &rcRect, 1, 1, FONT_DIALOG);
4289 		sy_ho += y_ho;
4290 		//Msg("adding y_yo %d.. (on %d)", y_ho,i);
4291 		if (sy_ho > x_depth)
4292 		  {
4293 		    /*if (fake_page == talk.page)
4294 		      {
4295 		      goto fin;
4296 		      }
4297 		    */
4298 		    fake_page++;
4299 		    sy_ho = sy+ y_ho;
4300 		    //Msg("Does fake page (%d) match desired page (%d) %d", fake_page, talk.page, i);
4301 		  }
4302 		if (fake_page == talk.page)
4303 		  {
4304 		    talk.cur_view = i;
4305 		    talk.cur_view_end = talk.cur;
4306 		    //Msg("Going to fin with end being %d, and.cur being %d.  View is %d.",
4307 		    //		   talk.cur_view_end, talk.cur, talk.cur_view);
4308 		    goto fin;
4309 		  }
4310 
4311 		//         Msg("Second: Sy is over, sp cur_view is %d", talk.cur_view_end);
4312 	      }
4313 	    talk.cur_view_end = i;
4314 	  }
4315       }
4316 
4317       //Msg("talk last is %d.  cur_view_end is %d, Cur is %d", talk.last, talk.cur_view_end, talk.cur);
4318 
4319       //	 talk.cur_view_end = talk.last;
4320 
4321       for ( i = talk.cur_view; i <= talk.cur_view_end; i++)
4322 	{
4323 	  //lets figure out where to draw this line
4324 
4325 	  rect_set(&rcRect, sx, sy, 463, x_depth + 100);
4326 /* 	  SetTextColor(hdc,RGB(8,14,21)); */
4327 	  // FONTS
4328 	  FONTS_SetTextColor(8, 14, 21);
4329 /* 	  DrawText(hdc,talk.line[i],lstrlen(talk.line[i]),&rcRect, DT_CENTER | DT_WORDBREAK); */
4330 	  // FONTS
4331 	  print_text_wrap(talk.line[i], &rcRect, 1, 0, FONT_DIALOG);
4332 	  rect_offset(&rcRect, -2, -2);
4333 /* 	  DrawText(hdc,talk.line[i],lstrlen(talk.line[i]),&rcRect,DT_CENTER | DT_WORDBREAK); */
4334 	  // FONTS
4335 	  print_text_wrap(talk.line[i], &rcRect, 1, 0, FONT_DIALOG);
4336 
4337 	  rect_offset(&rcRect, 1, 1);
4338 	  if (i == talk.cur)
4339 	    {
4340 	      curyl = sy-4;
4341 	      curyr = sy-4;
4342 
4343 /* 	      SetTextColor(hdc,RGB(255,255,255)); */
4344 	      // FONTS
4345 	      FONTS_SetTextColor(255, 255, 255);
4346 	    }
4347 	  else
4348 	    {
4349 /* 	      SetTextColor(hdc,RGB(255,255,2)); */
4350 	      // FONTS
4351 	      FONTS_SetTextColor(255, 255, 2);
4352 	    }
4353 /* 	  y_last = DrawText(hdc,talk.line[i],lstrlen(talk.line[i]),&rcRect,DT_CENTER | DT_WORDBREAK); */
4354 	  // FONTS
4355 	  y_last = print_text_wrap(talk.line[i], &rcRect, 1, 0, FONT_DIALOG);
4356 	  sy += y_last;
4357 	}
4358 
4359     fin:
4360       //	   dum =  GetTextFace(hdc,100,shit) ;
4361 /*       lpDDSBack->ReleaseDC(hdc); */
4362 
4363       if (talk.timer < thisTickCount)
4364 	{
4365 	  talk.curf++;
4366 	  talk.timer = thisTickCount+100;
4367 	}
4368 
4369 
4370       if (talk.curf == 0) talk.curf = 1;
4371 
4372       if (talk.curf > 7) talk.curf = 1;
4373 /*     again4: */
4374 /*       ddrval = lpDDSBack->BltFast( curxl, curyl, k[seq[456].frame[talk.curf]].k, */
4375 /* 				   &k[seq[456].frame[talk.curf]].box  , DDBLTFAST_SRCCOLORKEY  ); */
4376 /*       if (ddrval == DDERR_WASSTILLDRAWING) goto again4; */
4377       // GFX
4378       {
4379 	SDL_Rect dst;
4380 	dst.x = curxl; dst.y = curyl;
4381 	SDL_BlitSurface(GFX_k[seq[456].frame[talk.curf]].k, NULL, GFX_lpDDSBack, &dst);
4382       }
4383 
4384 /*     again5: */
4385 /*       ddrval = lpDDSBack->BltFast( curxr, curyr, k[seq[457].frame[talk.curf]].k, */
4386 /* 				   &k[seq[456].frame[talk.curf]].box  , DDBLTFAST_SRCCOLORKEY  ); */
4387 /*       if (ddrval == DDERR_WASSTILLDRAWING) goto again5; */
4388       // GFX
4389       {
4390 	SDL_Rect dst;
4391 	dst.x = curxr; dst.y = curyr;
4392 	SDL_BlitSurface(GFX_k[seq[457].frame[talk.curf]].k, NULL, GFX_lpDDSBack, &dst);
4393       }
4394 /*   } */
4395 
4396 
4397   if ((sjoy.button[ACTION_ATTACK]) | (mouse1))
4398     {
4399       mouse1 = /*false*/0;
4400       talk.active = /*false*/0;
4401       *presult = talk.line_return[talk.cur];
4402       SoundPlayEffect(17, 22050,0,0,0);
4403 
4404       if (talk.script != 0)
4405 	{
4406 	  //we need to continue a script
4407 	  run_script(talk.script);
4408 
4409 	}
4410     }
4411 }
4412 
4413 
UpdateCursorPosition(int dx,int dy)4414 void UpdateCursorPosition(int dx, int dy)
4415 {
4416 
4417 /*
4418 *  Pick up any leftover fuzz from last time.  This is important
4419 *  when scaling down mouse motions.  Otherwise, the user can
4420 *  drag to the right extremely slow for the length of the table
4421 *  and not get anywhere.
4422 	*/
4423 	if (spr[1].active) if (spr[1].brain == 13)
4424 	{
4425 		spr[1].x += dx;
4426 		spr[1].y += dy;
4427 		/* Clip the cursor to our client area */
4428 
4429 		if (spr[1].x > 640) spr[1].x = 640; /* TODO: -1? */
4430 		if (spr[1].y > 480) spr[1].y = 480; /* TODO: -1? */
4431 		if (spr[1].x < 0) spr[1].x = 0;
4432 		if (spr[1].y < 0) spr[1].y = 0;
4433 	}
4434 	/* Text choice selection (e.g. "Load game" in the title
4435 	   screen) */
4436 	if (mode == 1)
4437 	{
4438 	  play.mouse += dy;
4439 	  //Msg("play mousey is now %d", play.mouse);
4440 	}
4441 
4442 	/* Try to get the mouse (and the focus) within the window,
4443 	   not 100% safe but good enough */
4444 	SDL_WarpMouse(320, 240);
4445 	/* Ignore the mouse event generated by SDL_WarpMouse: */
4446 	SDL_PumpEvents();
4447 	SDL_GetRelativeMouseState(NULL, NULL);
4448 	/* Alternatively, we can do this all the time, even when dx
4449 	   and dy are zero, and the mouse will always return to the
4450 	   application. We'd need to avoid that when the application
4451 	   is backgrounded though, otherwise FreeDink will keep
4452 	   warping the mouse. */
4453 }
4454 
4455 
Scrawl_OnMouseInput(void)4456 void Scrawl_OnMouseInput(void)
4457 {
4458   SDL_Event event;
4459   int dx, dy;
4460 
4461   mouse1 = /*false*/0;
4462 
4463   SDL_PumpEvents();
4464   SDL_GetRelativeMouseState(&dx, &dy);
4465   /* Only call if there's mouse activity (original game behavior).
4466      However, we don't process mouse moves through events, because we
4467      use SDL_WarpMouse and this generates spurious events, which we
4468      then need to filter out - better simply check if dx and dy are
4469      not zero. */
4470   if (dx != 0 || dy != 0)
4471     UpdateCursorPosition(dx, dy);
4472 
4473   /* Process stacked clicks */
4474 #if SDL_VERSION_ATLEAST(1, 3, 0)
4475   while (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
4476 			SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN) > 0)
4477 #else
4478   while (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
4479 			SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)) > 0)
4480 #endif
4481     {
4482       SDL_MouseButtonEvent *button_event = (SDL_MouseButtonEvent*)&event;
4483       if (button_event->button == SDL_BUTTON_LEFT)
4484 	mouse1 = /*true*/1;
4485     }
4486   return;
4487 
4488 /* 	mouse1 = false; */
4489 
4490 /* 	BOOL fDone = 0; */
4491 
4492 /*     while (!fDone) { */
4493 
4494 /* 		DIDEVICEOBJECTDATA od; */
4495 
4496 /*         DWORD dwElements = 1; */
4497 
4498 /*         HRESULT hr = g_pMouse->GetDeviceData( */
4499 /* 			sizeof(DIDEVICEOBJECTDATA), &od, */
4500 /* 			&dwElements, 0); */
4501 
4502 /*         if (hr == DIERR_INPUTLOST) { */
4503 /* 		/\* */
4504 /* 		*  We had acquisition, but lost it.  Try to reacquire it. */
4505 /* 		* */
4506 /* 		*  WARNING!  DO NOT ATTEMPT TO REACQUIRE IF YOU GET */
4507 /* 		*  DIERR_NOTACQUIRED!  Otherwise, you're extremely likely */
4508 /* 		*  to get caught in an infinite loop:  The acquire will fail, */
4509 /* 		*  and you'll get another DIERR_NOTACQUIRED so you'll */
4510 /* 		*  try to aquire again, and that'll fail, etc. */
4511 /* 			*\/ */
4512 /*             //PostMessage(hwnd, WM_SYNCACQUIRE, 0, 0L); */
4513 /* 			//   break; */
4514 
4515 /* 			g_pMouse->Acquire(); */
4516 
4517 /* 		} */
4518 
4519 /*         /\* Unable to read data or no data available *\/ */
4520 /*         if (FAILED(hr) || dwElements == 0) { */
4521 /* 			// Msg("No mouse data there."); */
4522 /* 			break; */
4523 /*         } */
4524 
4525 /*         /\* Look at the element to see what happened *\/ */
4526 
4527 /* /\* Rewritten slightly differently to make it compile with recent versions of g++ *\/ */
4528 /* /\*        switch (od.dwOfs) { */
4529 
4530 /* 			// DIMOFS_X: Mouse horizontal motion */
4531 /*       case DIMOFS_X: UpdateCursorPosition(od.dwData, 0); break; */
4532 
4533 
4534 /* 			// DIMOFS_Y: Mouse vertical motion */
4535 /*       case DIMOFS_Y: UpdateCursorPosition(0, od.dwData); break; */
4536 
4537 /* 		case DIDFT_BUTTON: if (od.dwData > 0) mouse1 = true; break; */
4538 
4539 /*         } */
4540 /* *\/ */
4541 /* 		if (od.dwOfs == DIMOFS_X) */
4542 /* 		{ */
4543 /* 			/\* DIMOFS_X: Mouse horizontal motion *\/ */
4544 /* 			UpdateCursorPosition(od.dwData, 0); */
4545 /* 		} */
4546 /* 		else if (od.dwOfs == DIMOFS_Y) */
4547 /* 		{ */
4548 /* 			/\* DIMOFS_Y: Mouse vertical motion *\/ */
4549 /* 			UpdateCursorPosition(0, od.dwData); */
4550 /* 		} */
4551 /* 		else if (od.dwOfs == DIDFT_BUTTON) */
4552 /* 		{ */
4553 /* 			if (od.dwData > 0) mouse1 = true; */
4554 /* 		} */
4555 
4556 /*     } */
4557 
4558 }
4559 
button_brain(int h)4560 void button_brain(int h )
4561 {
4562 	rect box;
4563 	if (spr[h].move_active)
4564 	{
4565 		process_move(h);
4566 		return;
4567 	}
4568 
4569 
4570 	if (spr[h].script == 0) return;
4571 
4572 	rect_copy(&box, &k[getpic(h)].hardbox);
4573 	rect_offset(&box, spr[h].x, spr[h].y);
4574 
4575 	if (spr[h].brain_parm == 0)
4576 	{
4577 		if (inside_box(spr[1].x, spr[1].y, box))
4578 		{
4579 			spr[h].brain_parm = 1;
4580 
4581 			if (locate(spr[h].script, "BUTTONON"))
4582 			{
4583 				run_script(spr[h].script);
4584 
4585 				return;
4586 			}
4587 
4588 		}
4589 
4590 	}
4591 	else
4592 	{
4593 		if (!inside_box(spr[1].x, spr[1].y, box))
4594 		{
4595 			spr[h].brain_parm = 0;
4596 
4597 			if (locate(spr[h].script, "BUTTONOFF"))
4598 			{
4599 
4600 				run_script(spr[h].script);
4601 				return;
4602 			}
4603 
4604 		}
4605 
4606 	}
4607 
4608 
4609 }
4610 
4611 /**
4612  * Draw an item icon (or an item selection square) in the inventory
4613  * screen
4614  */
draw_item(int item_idx0,enum item_type type,int mseq,int mframe)4615 void draw_item(int item_idx0, enum item_type type, int mseq, int mframe)
4616 {
4617   int mx = 0;
4618   int my = 0;
4619 
4620   if (type == ITEM_REGULAR)
4621     {
4622       mx = 260;
4623       my = 83;
4624 
4625       mx += (item_idx0 % 4) * (18 + 65);
4626       my += (item_idx0 / 4) * (20 + 55);
4627     }
4628   else
4629     {
4630       mx = 45;
4631       my = 83;
4632 
4633       mx += (item_idx0 % 2) * (18 + 65);
4634       my += (item_idx0 / 2) * (20 + 55);
4635     }
4636 
4637   check_seq_status(mseq);
4638 
4639   if (GFX_k[seq[mseq].frame[mframe]].k == NULL)
4640     {
4641       if (type == ITEM_REGULAR)
4642 	{
4643 	  log_debug("Whups, item %d seq %d frame %d not loaded, killed it",
4644 		    item_idx0, mseq, mframe);
4645 	  play.item[item_idx0].active = 0;
4646 	}
4647       else
4648 	{
4649 	  log_debug("Whups, magic %d seq %d frame %d not loaded, killed it",
4650 		    item_idx0, mseq, mframe);
4651 	  play.mitem[item_idx0].active = 0;
4652 	}
4653       return;
4654     }
4655   SDL_Rect dst;
4656   dst.x = mx; dst.y = my;
4657   SDL_BlitSurface(GFX_k[seq[mseq].frame[mframe]].k, NULL, GFX_lpDDSBack, &dst);
4658 }
4659 
4660 /**
4661  * Inventory screen
4662  */
process_item()4663 void process_item()
4664 {
4665   SDL_BlitSurface(GFX_lpDDSTwo, NULL, GFX_lpDDSBack, NULL);
4666 
4667   check_seq_status(423);
4668   //lets blit the main screen over it
4669   SDL_Rect dst = {20, 0};
4670   SDL_BlitSurface(GFX_k[seq[423].frame[1]].k, NULL, GFX_lpDDSBack, &dst);
4671 
4672   //draw all currently owned items; magic
4673   {
4674     int i = 0;
4675     for (; i < NB_MITEMS; i++)
4676       if (play.mitem[i].active)
4677 	draw_item(i, ITEM_MAGIC, play.mitem[i].seq, play.mitem[i].frame);
4678   }
4679   //draw selection box around armed magic
4680   if (*pcur_magic >= 1 && *pcur_magic <= NB_MITEMS && play.item[*pcur_magic - 1].active)
4681     draw_item(*pcur_magic - 1, ITEM_MAGIC, 423, 5);
4682 
4683 
4684   //draw all currently owned items; normal
4685   {
4686     int i = 0;
4687     for (; i < NB_ITEMS; i++)
4688       if (play.item[i].active)
4689 	draw_item(i, ITEM_REGULAR, play.item[i].seq, play.item[i].frame);
4690   }
4691   //draw selection box around armed weapon
4692   if (*pcur_weapon >= 1 && *pcur_weapon <= NB_ITEMS && play.item[*pcur_weapon - 1].active)
4693     draw_item(*pcur_weapon - 1, ITEM_REGULAR, 423, 4);
4694 
4695 
4696   if (play.curitem < 0
4697       || (!play.item_magic && play.curitem >= NB_ITEMS)
4698       || (play.item_magic && play.curitem >= NB_MITEMS))
4699     play.curitem = 0;
4700 
4701   if (thisTickCount > item_timer)
4702     {
4703       //draw the selector around it, alternating from 2 to 3
4704       if (item_pic == 2)
4705 	item_pic = 3;
4706       else
4707 	item_pic = 2;
4708       item_timer = thisTickCount + 400;
4709     }
4710   draw_item(play.curitem, play.item_magic, 423, item_pic);
4711 
4712   if (!play.item_magic)
4713     {
4714       int hor  = play.curitem % 4;
4715       int vert = play.curitem / 4;
4716 
4717       //choosing weapon/item
4718       if (sjoy.button[ACTION_ATTACK])
4719 	{
4720 	  if (play.item[play.curitem].active)
4721 	    {
4722 	      //arm weapon
4723 	      SoundPlayEffect(18, 42050,0,0,0);
4724 	      if (*pcur_weapon != 0)
4725 		{
4726 		  //disarm old weapon
4727 		  if (locate(weapon_script, "DISARM"))
4728 		    run_script(weapon_script);
4729 		}
4730 
4731 	      //load weapons script
4732 	      *pcur_weapon = play.curitem + 1;
4733 	      weapon_script = load_script(play.item[*pcur_weapon - 1].name, 1000, /*false*/0);
4734 	      if (locate(weapon_script, "ARM"))
4735 		run_script(weapon_script);
4736 	      if (locate(weapon_script, "ARMMOVIE"))
4737 		run_script(weapon_script);
4738 	      draw_status_all();
4739 	    }
4740 	}
4741       else if (sjoy.rightd)
4742 	{
4743 	  if (hor < 3)
4744 	    {
4745 	      play.curitem++;
4746 	      SoundPlayEffect(11, 22050,0,0,0);
4747 	    }
4748 	}
4749       else if (sjoy.leftd)
4750 	{
4751 	  if (hor > 0)
4752 	    {
4753 	      play.curitem--;
4754 	      SoundPlayEffect(11, 22050,0,0,0);
4755 	    }
4756 	  else
4757 	    {
4758 	      SoundPlayEffect(11, 22050,0,0,0);
4759 	      //switch to magic mode
4760 	      play.item_magic = 1;
4761 	      play.curitem = vert * 2 + 1;
4762 	    }
4763 	}
4764       else if (sjoy.downd)
4765 	{
4766 	  if (vert < 3)
4767 	    {
4768 	      play.curitem += 4;
4769 	      SoundPlayEffect(11, 22050,0,0,0);
4770 	    }
4771 	}
4772       else if (sjoy.upd)
4773 	{
4774 	  if (vert > 0)
4775 	    {
4776 	      play.curitem -= 4;
4777 	      SoundPlayEffect(11, 22050,0,0,0);
4778 	    }
4779 	}
4780     }
4781   else
4782     {
4783       int hor  = play.curitem % 2;
4784       int vert = play.curitem / 2;
4785 
4786       if (sjoy.button[ACTION_ATTACK])
4787 	{
4788 	  if (play.mitem[play.curitem].active)
4789 	    {
4790 	      //arm magic
4791 	      SoundPlayEffect(18, 42050,0,0,0);
4792 	      if (*pcur_magic != 0)
4793 		{
4794 		  //disarm old weapon
4795 		  if (locate(magic_script, "DISARM"))
4796 		    run_script(magic_script);
4797 		}
4798 	      //load magics script
4799 	      *pcur_magic = play.curitem + 1;
4800 	      magic_script = load_script(play.mitem[*pcur_magic - 1].name, 1000, /*false*/0);
4801 	      if (locate(magic_script, "ARM"))
4802 		run_script(magic_script);
4803 	      if (locate(magic_script, "ARMMOVIE"))
4804 		run_script(magic_script);
4805 	      draw_status_all();
4806 	    }
4807 	}
4808       else if (sjoy.rightd)
4809 	{
4810 	  if (hor < 1)
4811 	    {
4812 	      play.curitem++;
4813 	      SoundPlayEffect(11, 22050,0,0,0);
4814 	    }
4815 	  else
4816 	    {
4817 	      play.item_magic = 0;
4818 	      play.curitem = vert * 4;
4819 	      SoundPlayEffect(11, 22050,0,0,0);
4820 	    }
4821 	}
4822       else if (sjoy.leftd)
4823 	{
4824 	  if (hor > 0)
4825 	    {
4826 	      play.curitem--;
4827 	      SoundPlayEffect(11, 22050,0,0,0);
4828 	    }
4829 	}
4830       else if (sjoy.downd)
4831 	{
4832 	  if (vert < 3)
4833 	    {
4834 	      play.curitem += 2;
4835 	      SoundPlayEffect(11, 22050,0,0,0);
4836 	    }
4837 	}
4838       else if (sjoy.upd)
4839 	{
4840 	  if (vert > 0)
4841 	    {
4842 	      play.curitem -= 2;
4843 	      SoundPlayEffect(11, 22050,0,0,0);
4844 	    }
4845 	}
4846     }
4847   if (talk.active)
4848     process_talk();
4849 
4850   //a special process callbacks for just stuff that was created in this mode?
4851   // process_callbacks_special();
4852   flip_it();
4853 
4854   if (sjoy.button[ACTION_INVENTORY])
4855     {
4856       SoundPlayEffect(17, 22050,0,0,0);
4857       show_inventory = 0;
4858     }
4859 }
4860 
4861 
process_show_bmp(void)4862 void process_show_bmp( void )
4863 {
4864   // We could disable this Blit (work is already done in show_bmp())
4865   // but we want to display the shiny mark on the map below. Besides,
4866   // after show_bmp(), other parts of the code drew sprites on
4867   // lpDDSBack, so we need to regenerate it anyway.
4868   SDL_BlitSurface(GFX_lpDDSTrick, NULL, GFX_lpDDSBack, NULL);
4869 
4870   if (showb.showdot)
4871     {
4872       //let's display a nice dot to mark where they are on the map
4873       int x = play.last_map - 1;
4874       int mseq = 165;
4875 
4876       showb.picframe++;
4877       if (showb.picframe > seq[mseq].len) showb.picframe = 1;
4878       int mframe = showb.picframe;
4879 
4880       SDL_Rect dst;
4881       // convert map# to a (x,y) position on a FreeDinkedit minimap
4882       dst.x = (x % 32) * 20;
4883       dst.y = (x / 32) * 20;
4884       SDL_BlitSurface(GFX_k[seq[mseq].frame[mframe]].k, NULL, GFX_lpDDSBack, &dst);
4885     }
4886 
4887 
4888   if ((sjoy.button[ACTION_ATTACK])
4889       || (sjoy.button[ACTION_TALK])
4890       || (sjoy.button[ACTION_MAGIC])
4891       || (sjoy.button[ACTION_INVENTORY])
4892       || (sjoy.button[ACTION_MENU])
4893       || (sjoy.button[ACTION_MAP]))
4894     {
4895       showb.active = /*false*/0;
4896       if (showb.script != 0)
4897 	run_script(showb.script);
4898       showb.stime = thisTickCount+2000;
4899       but_timer = thisTickCount + 200;
4900 
4901       int sprite = say_text_xy("", 1, 440, 0);
4902       spr[sprite].noclip = 1;
4903 
4904 
4905       // Return to canonical game palette
4906       gfx_palette_set_phys(GFX_real_pal);
4907       // The main flip_it() will be called, skip it - lpDDSBack is
4908       // not matching the palette anymore, it needs to be redrawn
4909       // first.
4910       abort_this_flip = /*true*/1;
4911     }
4912 }
4913 
drawscreenlock(void)4914 void drawscreenlock( void )
4915 {
4916 /*   HRESULT     ddrval; */
4917 
4918 /*  loop: */
4919   //draw the screenlock icon
4920 /*   ddrval = lpDDSBack->BltFast(0, 0, k[seq[423].frame[9]].k, */
4921 /* 			      &k[seq[423].frame[9]].box  , DDBLTFAST_NOCOLORKEY  ); */
4922 /*   if (ddrval == DDERR_WASSTILLDRAWING ) goto loop; */
4923   //if (ddrval != DD_OK) dderror(ddrval);
4924   // GFX
4925   gfx_blit_nocolorkey(GFX_k[seq[423].frame[9]].k, NULL, GFX_lpDDSBack, NULL);
4926 
4927 /*  loop2: */
4928   //draw the screenlock icon
4929 /*   ddrval = lpDDSBack->BltFast(620, 0, k[seq[423].frame[10]].k, */
4930 /* 			      &k[seq[423].frame[10]].box  , DDBLTFAST_NOCOLORKEY  ); */
4931 /*   if (ddrval == DDERR_WASSTILLDRAWING ) goto loop2; */
4932   // if (ddrval != DD_OK) dderror(ddrval);
4933   // GFX
4934   {
4935     SDL_Rect dst = {620, 0};
4936     gfx_blit_nocolorkey(GFX_k[seq[423].frame[10]].k, NULL, GFX_lpDDSBack, &dst);
4937   }
4938 }
4939 
4940 
4941 /**
4942  * doInit - do work required for every instance of the application:
4943  *                create the window, initialize data
4944  */
doInit(int argc,char * argv[])4945 static int doInit(int argc, char *argv[])
4946 {
4947   /* New initialization */
4948   if (init(argc, argv, "Tiles/Splash.bmp") < 0)
4949     return -1;
4950 
4951   /* Game-specific initialization */
4952   //Activate dink, but don't really turn him on
4953   //spr[1].active = TRUE;
4954   spr[1].timer = 33;
4955 
4956   // ** SETUP **
4957   last_sprite_created = 1;
4958   mode = 0;
4959 
4960   /* TODO: move load_info() to 'init' */
4961   load_info();
4962 
4963   //lets run our init script
4964   int script = load_script("main", 0, /*true*/1);
4965   locate(script, "main");
4966   run_script(script);
4967 
4968   /* lets attach our vars to the scripts, they must be declared in the
4969      main.c DinkC script */
4970   attach();
4971 
4972   return 0;
4973 }
4974 
4975 
4976 /**
4977  * Initialization, message loop
4978  */
main(int argc,char * argv[])4979 int main(int argc, char* argv[])
4980 {
4981   /* Initialize/setup */
4982   int init_ret = doInit(argc, argv);
4983 
4984   if (init_ret == 0)
4985     {
4986       /* Main loop */
4987 
4988       /* Notify other apps that FreeDink is playing */
4989       log_path(/*true*/1);
4990 
4991       /* Windows event loop */
4992       int last_console_active = 0;
4993       while(!g_b_kill_app)
4994 	{
4995 	  SDL_Event event;
4996 	  SDL_PumpEvents();
4997 
4998 	  /* Check if we need to quit */
4999 #if SDL_VERSION_ATLEAST(1, 3, 0)
5000 	  if (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
5001 			     SDL_QUIT, SDL_QUIT) > 0)
5002 #else
5003 	  if (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
5004 			     SDL_EVENTMASK(SDL_QUIT)) > 0)
5005 #endif
5006 	    break;
5007 
5008 	  /* Fullscreen <-> window */
5009 	  if ((SDL_GetModState()&KMOD_ALT) && GetKeyboard(SDLK_RETURN))
5010 	    {
5011 	      /* Note: as of 2008-08-07, only works under X11 */
5012 	      int success = SDL_WM_ToggleFullScreen(GFX_lpDDSBack);
5013 	      if (!success)
5014 		/* Try using a more portable way: */
5015 		gfx_toggle_fullscreen();
5016 	    }
5017 
5018 	  /* High speed */
5019 	  if (GetKeyboard(SDLK_TAB) == 1)
5020 	    {
5021 	      game_set_high_speed();
5022 	    }
5023 	  else if (GetKeyboard(SDLK_TAB) == 0)
5024 	    {
5025 	      game_set_normal_speed();
5026 	    }
5027 
5028 	  /* TODO: maybe check for application active/background state and
5029 	     pause the game accordingly - but this may be an annoying
5030 	     behavior. */
5031 	  if (g_b_kill_app == /*false*/0)
5032 	    updateFrame();
5033 
5034 	  /* Clean-up finished sounds: normally this is done by
5035 	     SDL_mixer but since we're using effects tricks to
5036 	     stream&resample sounds, we need to do this manually. */
5037 	  sfx_cleanup_finished_channels();
5038 
5039 	  if (console_active == 0 || last_console_active == 0)
5040 	    /* Get rid of keyboard events, otherwise they'll pile-up. Also
5041 	       purge them just when console is turned on. We poll the
5042 	       keyboard state directly in the rest of the game, so no
5043 	       keystroke will be lost. */
5044 #if SDL_VERSION_ATLEAST(1, 3, 0)
5045 	    while (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
5046 				  SDL_KEYDOWN, SDL_KEYDOWN) > 0);
5047 #else
5048 	    while (SDL_PeepEvents(&event, 1, SDL_GETEVENT,
5049 				  SDL_EVENTMASK(SDL_KEYDOWN)) > 0);
5050 #endif
5051 
5052 	  if (console_active == 1)
5053 	    {
5054 	      SDL_KeyboardEvent kev;
5055 #if SDL_VERSION_ATLEAST(1, 3, 0)
5056 	      if (SDL_PeepEvents((SDL_Event*)&kev, 1, SDL_GETEVENT,
5057 				 SDL_KEYDOWN, SDL_KEYDOWN) > 0)
5058 #else
5059 	      if (SDL_PeepEvents((SDL_Event*)&kev, 1, SDL_GETEVENT,
5060 				 SDL_EVENTMASK(SDL_KEYDOWN)) > 0)
5061 #endif
5062 		dinkc_console_process_key(kev);
5063 	    }
5064 
5065 	  last_console_active = console_active;
5066 	}
5067     }
5068 
5069   /* Uninitialize/clean-up */
5070   finiObjects();
5071 
5072   if (init_ret < 0)
5073     return EXIT_FAILURE;
5074   else
5075     return EXIT_SUCCESS;
5076 }
5077