home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2004 August / GSSH0804.iso / Rollenspiele / SwordOfFargoal / fargoal20030731b.exe / fargoal / src / monster.c < prev    next >
C/C++ Source or Header  |  2003-07-31  |  10KB  |  515 lines

  1. #include "map.h"
  2. #include "char.h"
  3. #include "game.h"
  4.  
  5. /* Bigger values mean, don't wander around so much. */
  6. static int WANDER[] = {
  7.     1,
  8.     1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  9.     0, 1, 2, 3, 4, 5, 6, 1, 8, 9
  10. };
  11.  
  12. int monster_max;
  13. static int _monster_count = 0;
  14. int monster_strength = 0;
  15.  
  16. void monster_init()
  17. {
  18.     _monster_count = 0;
  19. }
  20.  
  21. int monster_count(void)
  22. {
  23.     return _monster_count;
  24. }
  25.  
  26. void monster_set_count (int c)
  27. {
  28.     _monster_count = c;
  29. }
  30.  
  31. void
  32. monster_teleport (int id)
  33. {
  34.     int x = list[id].x;
  35.     int y = list[id].y;
  36.     map_put_char (x, y, 0);
  37.     do
  38.     {
  39.         x = rnd (0, MAP_W - 1);
  40.         y = rnd (0, MAP_H - 1);
  41.     } while (map_get_spot (x, y) != SPOT_FLOOR || map_get_char (x, y));        
  42.     list[id].x = x;
  43.     list[id].y = y;
  44.     map_put_char (x, y, id);
  45. }
  46.  
  47. void
  48. monster_change_position (int id)
  49. {
  50.     int x = list[id].x;
  51.     int y = list[id].y;
  52.     
  53.     switch (map_get_spot (x, y))
  54.     {
  55.         default:
  56.             break;
  57.  
  58.         case SPOT_PIT:
  59.             if (list[id].type >= CHAR_DIREWOLF)
  60.                 monster_die (id);
  61.  
  62.         case SPOT_UP:
  63.         case SPOT_DOWN:
  64.             if (extensions_monsteraction && list[id].trapped)
  65.                 monster_die (id);
  66.             break;
  67.  
  68.         case SPOT_GOLD: // I've seen them walk over and not pick up the gold
  69.             if (list[id].type < CHAR_DIREWOLF)
  70.             {
  71.                 if(extensions_monsteraction)
  72.                 {
  73.                     int g;
  74.                     g = 10 * list[1].current_level + rnd (0, 19);
  75.  
  76.                     list[id].gold += g;
  77.                 }
  78.  
  79.                 map_put_spot(x, y, SPOT_FLOOR);
  80.             }
  81.             break;
  82.  
  83.         case SPOT_TREASURE:
  84.             map_put_spot(x, y, SPOT_FLOOR);
  85.             break;
  86.     }
  87. }
  88.  
  89.  
  90. /*
  91.         - Monster BS and HP initialization:
  92.             - It rolls the stats on creation of the monster, just basing 
  93.             them off of the l% which is the monster's origination dungeon level
  94.             (I think)
  95.             - Calculates Accesses values read as data into x()
  96.  
  97.  
  98. */    
  99. /** Move those functions into monster.c when done */
  100. /**
  101.             310 s$="":h%=0:s%=0:fori1=1to2+int(l%*.25)
  102.             311 s%=s%+int(4*rnd(1)+l%):h%=h%+int(6*rnd(1)+l%*1.5):next:x=s%/bs:y=int(x*5)
  103.             312 ify>6thens$="a powerful ":goto314
  104.             313 ify<1thens$="a weak "
  105.             314 x=int(4*rnd(1)+l%/2):ifx<10then317
  106.             315 r=int(6*rnd(1)):ifr>0thenx=10-r:goto317
  107.             316 x2=int(10*rnd(1)+11):s%(j)=0:a(j)=28:return
  108.             317 x2=x+11:a(j)=x(x):ifs$=""thens$=a$(x)+" "
  109.             318 x$(j)=s$+b$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
  110.             319 s%(j)=s%:a%(j)=h%:return
  111. */
  112. void
  113. monster_creature_create (int id, int l)
  114. {
  115.     int i;
  116.     float modifier, x, x2;
  117.     int player = 1;
  118.     
  119.     /*
  120.     310 s$="":h%=0:s%=0:fori1=1to2+int(l%*.25)
  121.     311 s%=s%+int(4*rnd(1)+l%):h%=h%+int(6*rnd(1)+l%*1.5):next:x=s%/bs:y=int(x*5)
  122.     */
  123.  
  124.     for (i = 1; i <= 2 + l / 4; i++)
  125.     {
  126.         list[id].dex += l + rnd (0, 3);
  127.         list[id].hit += l * 3 / 2 + rnd (0, 5);
  128.     }
  129.     
  130.     modifier = 5 * list[id].dex / list[player].dex;
  131.     
  132.     /*
  133.     312 ify>6thens$="a powerful ":goto314
  134.     313 ify<1thens$="a weak "
  135.     */
  136.     if (modifier > 6)
  137.         list[id].subtype = 2;
  138.     else if (modifier < 1)
  139.         list[id].subtype = 1;
  140.     else
  141.         list[id].subtype = 0;
  142.     
  143.     /*
  144.     314 x=int(4*rnd(1)+l%/2):ifx<10then317
  145.     315 r=int(6*rnd(1)):ifr>0thenx=10-r:goto317
  146.     316 x2=int(10*rnd(1)+11):s%(j)=0:a(j)=28:return
  147.     317 x2=x+11:a(j)=x(x):ifs$=""thens$=a$(x)+" "
  148.     318 x$(j)=s$+b$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
  149.     319 s%(j)=s%:a%(j)=h%:return
  150.     */
  151.     x = rnd (0, 3) + l / 2;
  152.     if (x >= 10)
  153.     {
  154.         int r = rnd (0, 5);
  155.         if (!r)
  156.         {
  157.             x2 = 11 + rnd (0, 9);
  158.             list[id].dex = 0;
  159.             //a(j) = 28;
  160.             list[id].type = x2;
  161.             return;
  162.         }
  163.         x = 10 - r;
  164.     }
  165.     
  166.     x2 = x + 11;
  167.     //a(j) = x(x);
  168.     list[id].type = x2;
  169.  
  170. #ifdef NETWORM
  171.     list[id].dex += l * (x + x * rnd (0, x - 1));
  172.     list[id].hit += l * (x + x * rnd (0, x - 1));
  173. #else
  174.     list[id].dex += x + rnd (0, x - 1);
  175.     list[id].hit += x + rnd (0, x - 1);
  176. #endif
  177.     
  178.     list[id].maxhit = list[id].hit;
  179.     
  180. //    list[id].dex=0;
  181. }
  182.  
  183. /**
  184.             -It's different for humans:
  185.  
  186.             320 s$="":h%=0:s%=0:fori1=1to3+int(l%*.25)
  187.             321 s%=s%+int(3*rnd(1)+l%*1.5):h%=h%+int(4*rnd(1)+l%):next:x=s%/bs:y=int(x*5)
  188.             322 ify>6thens$="an experienced ":goto324
  189.             323 ify<1thens$="an inferior "
  190.             324 x=int(4*rnd(1)+l%/2):ifx<10then327
  191.             325 r=int(6*rnd(1)):ifr>0thenx=10-r:goto327
  192.             326 x2=int(10*rnd(1)+1):r%(j)=0:b(j)=41:return
  193.             327 x2=x+1:b(j)=y(x):ifs$=""thens$=c$(x)+" "
  194.             328 y$(j)=s$+d$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
  195.             329 r%(j)=s%:b%(j)=h%:return
  196.  
  197.             - Humans get higher skill, but less HP
  198.  */
  199. void
  200. monster_human_create (int id, int l)
  201. {
  202.     int i, x, x2;
  203.     int modifier;
  204.     int player = 1;
  205.  
  206.     for (i = 1; i <= 3 + l / 4; i++)
  207.     {
  208.         list[id].dex += l * 3 / 2 + rnd (0, 2);
  209.         list[id].hit += l + rnd (0, 3);
  210.     }
  211.     
  212.     modifier = 5 * list[id].dex / list[player].dex;
  213.     
  214.     if (modifier > 6)
  215.         list[id].subtype = MONSTER_STRONG;
  216.     if (modifier < 1)
  217.         list[id].subtype = MONSTER_WEAK;
  218.     
  219.     x = rnd (0, 3) + l / 2;
  220.     if (x >= 10)
  221.     {
  222.         int r = rnd (0, 5);
  223.         if (!r)
  224.         {
  225.             x2 = 1 + rnd (0, 9);
  226.             list[id].dex = 0;
  227.             //b(j) = 41;
  228.             list[id].type = x2;
  229.             return;
  230.         }
  231.         x = 10 - r;
  232.     }
  233.     
  234.     x2 = x + 1;
  235.     //b(j) = y(x);
  236.     list[id].type = x2;
  237.     
  238. #ifdef NETWORM
  239.     list[id].dex += l * (x + x * rnd (0, x - 1));
  240.     list[id].hit += l * (x + x * rnd (0, x - 1));
  241. #else
  242.     list[id].dex += x + rnd (0, x - 1);
  243.     list[id].hit += x + rnd (0, x - 1);
  244. #endif
  245.     
  246.     list[id].maxhit = list[id].hit;
  247.         
  248.     /* Assassins are invisible when created. */
  249.     if (list[id].type == CHAR_ASSASSIN)
  250.         list[id].spells[SPELL_INVISIBILITY].active = 1;
  251.  
  252. //    list[id].dex=0;
  253. }
  254.  
  255. int monster_create(int sort, int lev, int x, int y)
  256. {
  257.     int ret;
  258.     
  259.     ret = char_create (x, y);
  260.     
  261.     if (sort == 1)
  262.         monster_creature_create (ret, lev);
  263.     if (sort == 2)
  264.         monster_human_create (ret, lev);
  265.  
  266.     //printf ("%s, %i, %i\n", char_names[list[ret].type], list[ret].hit, list[ret].dex);
  267.  
  268.     if(ret)
  269.         _monster_count++;
  270.  
  271.     return ret;
  272. }
  273.  
  274.  
  275. void monster_die (int e)
  276. {
  277.     map_put_char (list[e].x, list[e].y, 0);
  278.     list[e].alive = 0;
  279.     _monster_count--;
  280. }
  281.  
  282. void
  283. monster_process (int id)
  284. {
  285.     int dx = 0;
  286.     int dy = 0;
  287.     int player = 1;
  288.  
  289.     if (!list[id].alive)
  290.         return;
  291.     
  292.     if (list[id].step == 0 && global_steps == 0 && !list[id].fighting)
  293.     {
  294.         int x = list[id].x;
  295.         int y = list[id].y;
  296.         int no_random = rnd (0, WANDER[list[id].type]);
  297.         int x2 = list[player].x;
  298.         int y2 = list[player].y;
  299.  
  300.         dx = x2 - x;
  301.         dy = y2 - y;
  302.         
  303.         //  375 f2=0:gosub142:z1=abs(x-xl):z2=abs(y-yl):ifz1>9orz2>9thenreturn
  304.         if (dx < -9 || dx > 9 || dy < -9 || dy > 9)
  305.         {
  306.             if (extensions_monsteraction)
  307.                 no_random = 0;
  308.             else
  309.                 return;
  310.         }
  311.         else
  312.         {
  313.             if (list[id].trapped && list[id].spells[SPELL_TELEPORT].amount && !rnd(0, 1))
  314.             {
  315.                 list[id].spells[SPELL_TELEPORT].amount--;
  316.                 monster_teleport (id);
  317.                 no_random = 0;
  318.             }
  319.         }
  320.  
  321.         //  376 ifk=38ork=44then378
  322.         {
  323.             int w = map_get_spot (x2, y2);
  324.             // They see you in the temple
  325.             // I'm quite sure they don't, see line 376 above
  326.             if (/*w == SPOT_TEMPLE || */w == SPOT_BEACON)
  327.                 no_random = 0;
  328.         }
  329.         
  330.         // They have my gold! Oh, they better run away!
  331.         if(list[id].trapped)
  332.         {
  333.             dx=-dx;
  334.             dy=-dy;
  335.         }
  336.         
  337.         if (list[id].type == CHAR_ASSASSIN)
  338.         {
  339.             int v = rnd (0, 9);
  340.             if (list[player].spells[SPELL_LIGHT].active > 0)
  341.                 v = 0;
  342.             list[id].spells[SPELL_INVISIBILITY].active = v ? 1 : 0;
  343.         }
  344.  
  345.         if (no_random && (!list[player].spells[SPELL_INVISIBILITY].active ||
  346.             list[player].spells[SPELL_LIGHT].active > 0))
  347.         {
  348.             /* Spiders teleport if they are too far away. */
  349.             if (list[id].type == CHAR_SPIDER)
  350.             {
  351.                 
  352.                 int t;
  353.                 int ox = x;
  354.                 int oy = y;
  355.  
  356.                 if(list[id].trapped)
  357.                 {
  358.                     if(!rnd(0, 1))
  359.                         monster_teleport (id);
  360.                 }
  361.                 else if(!rnd(0, 1))
  362.                 {
  363.                     for (t = 0; t < 4; t++)
  364.                     {
  365.                         //  407 fori1=1to4:r=int(8*rnd(1)+1):m3=o+d(r):k2=peek(m3):ifk2=32theni1=4:next:goto409
  366.                         x = rnd (x2 - 1, x2 + 1);
  367.                         y = rnd (y2 - 1, y2 + 1);
  368.                         if (x > 0 && y > 0 && x < MAP_W - 1 &&
  369.                             y < MAP_H - 1 &&
  370.                             map_get_spot (x, y) == SPOT_FLOOR &&
  371.                             !map_get_char (x, y))
  372.                             break;
  373.                     }
  374.  
  375.                     if (t < 4)
  376.                     {
  377.                         map_put_char (ox, oy, 0);
  378.                         list[id].x = x;
  379.                         list[id].y = y;
  380.                         map_put_char (list[id].x, list[id].y, id);
  381.                         dx = 0;
  382.                         dy = 0;
  383.                     }
  384.                 }
  385.             }
  386.             
  387.             if (dx > 0)
  388.                 dx = 1;
  389.             if (dx < 0)
  390.                 dx = -1;
  391.             if (dy > 0)
  392.                 dy = 1;
  393.             if (dy < 0)
  394.                 dy = -1;
  395.                             
  396.             /* If can't go into desired direction, take any possible
  397.                direction. */
  398.             if ((dx || dy) && map_get_spot (x + dx, y + dy) == SPOT_WALL)
  399.             {
  400.                 if (dx && dy)
  401.                 {
  402.                     int r = rnd (0, 1);
  403.                     if (r == 0)
  404.                     {
  405.                         if (map_get_spot (x + dx, y) != SPOT_WALL)
  406.                             dy = 0;
  407.                         else
  408.                         if (map_get_spot (x, y + dy) != SPOT_WALL)
  409.                             dx = 0;
  410.                         }
  411.                         else
  412.                             no_random = 0;
  413.                     if (r == 1)
  414.                     {
  415.                         if (map_get_spot (x, y + dy) != SPOT_WALL)
  416.                             dx = 0;
  417.                         else
  418.                         if (map_get_spot (x + dy, y) != SPOT_WALL)
  419.                             dy = 0;
  420.                         else
  421.                             no_random = 0;
  422.                     }
  423.                 }
  424.                 else
  425.                     no_random = 0;
  426.             }
  427.         }
  428.         else
  429.             no_random = 0;
  430.  
  431.         if (!no_random)
  432.         {
  433.             int dir_count = 8;
  434.             int dirs_dx[8] = {1,  1,  0, -1, -1, -1, 0, 1};
  435.             int dirs_dy[8] = {0, -1, -1, -1,  0,  1, 1, 1};
  436.             int r, d;
  437.             int possible_directions[8] = {0, 1, 2, 3, 4, 5, 6, 7};
  438.             int i;
  439.             int can_go_straight = 0;
  440.             
  441.             /* Move impossible directions to the end of the list. */
  442.             for (i = 0; i < dir_count; i++)
  443.             {
  444.                 d = possible_directions[i];
  445.                 if (map_get_spot (x + dirs_dx[d], y + dirs_dy[d]) == SPOT_WALL)
  446.                 {
  447.                     dir_count--;
  448.                     possible_directions[i] = possible_directions[dir_count];
  449.                     possible_directions[dir_count] = d;
  450.                     i--;
  451.                 }
  452.                 else
  453.                 {
  454.                     if (dirs_dx[d] == list[id].dx && dirs_dy[d] == list[id].dy)
  455.                         can_go_straight = 1;
  456.                 }
  457.             }
  458.             
  459.             
  460.             if (can_go_straight && rnd (0, 10))
  461.             {
  462.                 /* Go on in current direction. */
  463.                 dx = list[id].dx;
  464.                 dy = list[id].dy;
  465.             }
  466.             else
  467.             {
  468.                 /* Choose from the remaining directions. */
  469.                 r = rnd (0, dir_count);
  470.                 d = possible_directions[r];
  471.                 dx = dirs_dx[d];
  472.                 dy = dirs_dy[d];
  473.             }
  474.         }
  475.     }
  476.     char_move (id, dx, dy);
  477. }
  478.  
  479. static void
  480. monster_spawn (void)
  481. {
  482.     //  365 p=35:x=int((u%+1)*rnd(1)):n=v%(x):ifx=0andn>xthenl%=l-1:p=34:goto367
  483.     //  366 ifn=0then363
  484.       //  367 p%=peek(n):ifp%<34orp%>35then363
  485.     //  368 l%=v%+1:v%=l%:ifm2=0then371
  486.     int s = rnd (0, spawnpoints - 1);
  487.     int sx = spawnx[s];
  488.     int sy = spawny[s];
  489.     if (map_get_char (sx, sy) == 0)
  490.     {
  491.         int l = 0;
  492.         if (map_get_spot (sx, sy) == SPOT_UP)
  493.         {
  494.             l = list[1].current_level - 1;
  495.         }
  496.         else
  497.         if (map_get_spot (sx, sy) == SPOT_DOWN)
  498.         {
  499.             l = ++monster_strength;
  500.         }
  501.         if (l)
  502.             map_put_char (sx, sy, monster_create (rnd (1, 2), l, sx, sy));
  503.     }
  504. }
  505.  
  506. void
  507. monsters_spawn (void)
  508. {
  509.     int i;
  510.     for (i = 0; i < monster_max - monster_count (); i++)
  511.         //  362 x=int(20*rnd(1)):ifx=0then365
  512.         if (!rnd (0, 19))
  513.             monster_spawn();
  514. }
  515.