home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GameStar Special 2004 August
/
GSSH0804.iso
/
Rollenspiele
/
SwordOfFargoal
/
fargoal20030731b.exe
/
fargoal
/
src
/
monster.c
< prev
next >
Wrap
C/C++ Source or Header
|
2003-07-31
|
10KB
|
515 lines
#include "map.h"
#include "char.h"
#include "game.h"
/* Bigger values mean, don't wander around so much. */
static int WANDER[] = {
1,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
0, 1, 2, 3, 4, 5, 6, 1, 8, 9
};
int monster_max;
static int _monster_count = 0;
int monster_strength = 0;
void monster_init()
{
_monster_count = 0;
}
int monster_count(void)
{
return _monster_count;
}
void monster_set_count (int c)
{
_monster_count = c;
}
void
monster_teleport (int id)
{
int x = list[id].x;
int y = list[id].y;
map_put_char (x, y, 0);
do
{
x = rnd (0, MAP_W - 1);
y = rnd (0, MAP_H - 1);
} while (map_get_spot (x, y) != SPOT_FLOOR || map_get_char (x, y));
list[id].x = x;
list[id].y = y;
map_put_char (x, y, id);
}
void
monster_change_position (int id)
{
int x = list[id].x;
int y = list[id].y;
switch (map_get_spot (x, y))
{
default:
break;
case SPOT_PIT:
if (list[id].type >= CHAR_DIREWOLF)
monster_die (id);
case SPOT_UP:
case SPOT_DOWN:
if (extensions_monsteraction && list[id].trapped)
monster_die (id);
break;
case SPOT_GOLD: // I've seen them walk over and not pick up the gold
if (list[id].type < CHAR_DIREWOLF)
{
if(extensions_monsteraction)
{
int g;
g = 10 * list[1].current_level + rnd (0, 19);
list[id].gold += g;
}
map_put_spot(x, y, SPOT_FLOOR);
}
break;
case SPOT_TREASURE:
map_put_spot(x, y, SPOT_FLOOR);
break;
}
}
/*
- Monster BS and HP initialization:
- It rolls the stats on creation of the monster, just basing
them off of the l% which is the monster's origination dungeon level
(I think)
- Calculates Accesses values read as data into x()
*/
/** Move those functions into monster.c when done */
/**
310 s$="":h%=0:s%=0:fori1=1to2+int(l%*.25)
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)
312 ify>6thens$="a powerful ":goto314
313 ify<1thens$="a weak "
314 x=int(4*rnd(1)+l%/2):ifx<10then317
315 r=int(6*rnd(1)):ifr>0thenx=10-r:goto317
316 x2=int(10*rnd(1)+11):s%(j)=0:a(j)=28:return
317 x2=x+11:a(j)=x(x):ifs$=""thens$=a$(x)+" "
318 x$(j)=s$+b$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
319 s%(j)=s%:a%(j)=h%:return
*/
void
monster_creature_create (int id, int l)
{
int i;
float modifier, x, x2;
int player = 1;
/*
310 s$="":h%=0:s%=0:fori1=1to2+int(l%*.25)
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)
*/
for (i = 1; i <= 2 + l / 4; i++)
{
list[id].dex += l + rnd (0, 3);
list[id].hit += l * 3 / 2 + rnd (0, 5);
}
modifier = 5 * list[id].dex / list[player].dex;
/*
312 ify>6thens$="a powerful ":goto314
313 ify<1thens$="a weak "
*/
if (modifier > 6)
list[id].subtype = 2;
else if (modifier < 1)
list[id].subtype = 1;
else
list[id].subtype = 0;
/*
314 x=int(4*rnd(1)+l%/2):ifx<10then317
315 r=int(6*rnd(1)):ifr>0thenx=10-r:goto317
316 x2=int(10*rnd(1)+11):s%(j)=0:a(j)=28:return
317 x2=x+11:a(j)=x(x):ifs$=""thens$=a$(x)+" "
318 x$(j)=s$+b$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
319 s%(j)=s%:a%(j)=h%:return
*/
x = rnd (0, 3) + l / 2;
if (x >= 10)
{
int r = rnd (0, 5);
if (!r)
{
x2 = 11 + rnd (0, 9);
list[id].dex = 0;
//a(j) = 28;
list[id].type = x2;
return;
}
x = 10 - r;
}
x2 = x + 11;
//a(j) = x(x);
list[id].type = x2;
#ifdef NETWORM
list[id].dex += l * (x + x * rnd (0, x - 1));
list[id].hit += l * (x + x * rnd (0, x - 1));
#else
list[id].dex += x + rnd (0, x - 1);
list[id].hit += x + rnd (0, x - 1);
#endif
list[id].maxhit = list[id].hit;
// list[id].dex=0;
}
/**
-It's different for humans:
320 s$="":h%=0:s%=0:fori1=1to3+int(l%*.25)
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)
322 ify>6thens$="an experienced ":goto324
323 ify<1thens$="an inferior "
324 x=int(4*rnd(1)+l%/2):ifx<10then327
325 r=int(6*rnd(1)):ifr>0thenx=10-r:goto327
326 x2=int(10*rnd(1)+1):r%(j)=0:b(j)=41:return
327 x2=x+1:b(j)=y(x):ifs$=""thens$=c$(x)+" "
328 y$(j)=s$+d$(x):s%=s%+int(x*rnd(1)+x):h%=h%+int(x*rnd(1)+x)
329 r%(j)=s%:b%(j)=h%:return
- Humans get higher skill, but less HP
*/
void
monster_human_create (int id, int l)
{
int i, x, x2;
int modifier;
int player = 1;
for (i = 1; i <= 3 + l / 4; i++)
{
list[id].dex += l * 3 / 2 + rnd (0, 2);
list[id].hit += l + rnd (0, 3);
}
modifier = 5 * list[id].dex / list[player].dex;
if (modifier > 6)
list[id].subtype = MONSTER_STRONG;
if (modifier < 1)
list[id].subtype = MONSTER_WEAK;
x = rnd (0, 3) + l / 2;
if (x >= 10)
{
int r = rnd (0, 5);
if (!r)
{
x2 = 1 + rnd (0, 9);
list[id].dex = 0;
//b(j) = 41;
list[id].type = x2;
return;
}
x = 10 - r;
}
x2 = x + 1;
//b(j) = y(x);
list[id].type = x2;
#ifdef NETWORM
list[id].dex += l * (x + x * rnd (0, x - 1));
list[id].hit += l * (x + x * rnd (0, x - 1));
#else
list[id].dex += x + rnd (0, x - 1);
list[id].hit += x + rnd (0, x - 1);
#endif
list[id].maxhit = list[id].hit;
/* Assassins are invisible when created. */
if (list[id].type == CHAR_ASSASSIN)
list[id].spells[SPELL_INVISIBILITY].active = 1;
// list[id].dex=0;
}
int monster_create(int sort, int lev, int x, int y)
{
int ret;
ret = char_create (x, y);
if (sort == 1)
monster_creature_create (ret, lev);
if (sort == 2)
monster_human_create (ret, lev);
//printf ("%s, %i, %i\n", char_names[list[ret].type], list[ret].hit, list[ret].dex);
if(ret)
_monster_count++;
return ret;
}
void monster_die (int e)
{
map_put_char (list[e].x, list[e].y, 0);
list[e].alive = 0;
_monster_count--;
}
void
monster_process (int id)
{
int dx = 0;
int dy = 0;
int player = 1;
if (!list[id].alive)
return;
if (list[id].step == 0 && global_steps == 0 && !list[id].fighting)
{
int x = list[id].x;
int y = list[id].y;
int no_random = rnd (0, WANDER[list[id].type]);
int x2 = list[player].x;
int y2 = list[player].y;
dx = x2 - x;
dy = y2 - y;
// 375 f2=0:gosub142:z1=abs(x-xl):z2=abs(y-yl):ifz1>9orz2>9thenreturn
if (dx < -9 || dx > 9 || dy < -9 || dy > 9)
{
if (extensions_monsteraction)
no_random = 0;
else
return;
}
else
{
if (list[id].trapped && list[id].spells[SPELL_TELEPORT].amount && !rnd(0, 1))
{
list[id].spells[SPELL_TELEPORT].amount--;
monster_teleport (id);
no_random = 0;
}
}
// 376 ifk=38ork=44then378
{
int w = map_get_spot (x2, y2);
// They see you in the temple
// I'm quite sure they don't, see line 376 above
if (/*w == SPOT_TEMPLE || */w == SPOT_BEACON)
no_random = 0;
}
// They have my gold! Oh, they better run away!
if(list[id].trapped)
{
dx=-dx;
dy=-dy;
}
if (list[id].type == CHAR_ASSASSIN)
{
int v = rnd (0, 9);
if (list[player].spells[SPELL_LIGHT].active > 0)
v = 0;
list[id].spells[SPELL_INVISIBILITY].active = v ? 1 : 0;
}
if (no_random && (!list[player].spells[SPELL_INVISIBILITY].active ||
list[player].spells[SPELL_LIGHT].active > 0))
{
/* Spiders teleport if they are too far away. */
if (list[id].type == CHAR_SPIDER)
{
int t;
int ox = x;
int oy = y;
if(list[id].trapped)
{
if(!rnd(0, 1))
monster_teleport (id);
}
else if(!rnd(0, 1))
{
for (t = 0; t < 4; t++)
{
// 407 fori1=1to4:r=int(8*rnd(1)+1):m3=o+d(r):k2=peek(m3):ifk2=32theni1=4:next:goto409
x = rnd (x2 - 1, x2 + 1);
y = rnd (y2 - 1, y2 + 1);
if (x > 0 && y > 0 && x < MAP_W - 1 &&
y < MAP_H - 1 &&
map_get_spot (x, y) == SPOT_FLOOR &&
!map_get_char (x, y))
break;
}
if (t < 4)
{
map_put_char (ox, oy, 0);
list[id].x = x;
list[id].y = y;
map_put_char (list[id].x, list[id].y, id);
dx = 0;
dy = 0;
}
}
}
if (dx > 0)
dx = 1;
if (dx < 0)
dx = -1;
if (dy > 0)
dy = 1;
if (dy < 0)
dy = -1;
/* If can't go into desired direction, take any possible
direction. */
if ((dx || dy) && map_get_spot (x + dx, y + dy) == SPOT_WALL)
{
if (dx && dy)
{
int r = rnd (0, 1);
if (r == 0)
{
if (map_get_spot (x + dx, y) != SPOT_WALL)
dy = 0;
else
if (map_get_spot (x, y + dy) != SPOT_WALL)
dx = 0;
}
else
no_random = 0;
if (r == 1)
{
if (map_get_spot (x, y + dy) != SPOT_WALL)
dx = 0;
else
if (map_get_spot (x + dy, y) != SPOT_WALL)
dy = 0;
else
no_random = 0;
}
}
else
no_random = 0;
}
}
else
no_random = 0;
if (!no_random)
{
int dir_count = 8;
int dirs_dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int dirs_dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int r, d;
int possible_directions[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int i;
int can_go_straight = 0;
/* Move impossible directions to the end of the list. */
for (i = 0; i < dir_count; i++)
{
d = possible_directions[i];
if (map_get_spot (x + dirs_dx[d], y + dirs_dy[d]) == SPOT_WALL)
{
dir_count--;
possible_directions[i] = possible_directions[dir_count];
possible_directions[dir_count] = d;
i--;
}
else
{
if (dirs_dx[d] == list[id].dx && dirs_dy[d] == list[id].dy)
can_go_straight = 1;
}
}
if (can_go_straight && rnd (0, 10))
{
/* Go on in current direction. */
dx = list[id].dx;
dy = list[id].dy;
}
else
{
/* Choose from the remaining directions. */
r = rnd (0, dir_count);
d = possible_directions[r];
dx = dirs_dx[d];
dy = dirs_dy[d];
}
}
}
char_move (id, dx, dy);
}
static void
monster_spawn (void)
{
// 365 p=35:x=int((u%+1)*rnd(1)):n=v%(x):ifx=0andn>xthenl%=l-1:p=34:goto367
// 366 ifn=0then363
// 367 p%=peek(n):ifp%<34orp%>35then363
// 368 l%=v%+1:v%=l%:ifm2=0then371
int s = rnd (0, spawnpoints - 1);
int sx = spawnx[s];
int sy = spawny[s];
if (map_get_char (sx, sy) == 0)
{
int l = 0;
if (map_get_spot (sx, sy) == SPOT_UP)
{
l = list[1].current_level - 1;
}
else
if (map_get_spot (sx, sy) == SPOT_DOWN)
{
l = ++monster_strength;
}
if (l)
map_put_char (sx, sy, monster_create (rnd (1, 2), l, sx, sy));
}
}
void
monsters_spawn (void)
{
int i;
for (i = 0; i < monster_max - monster_count (); i++)
// 362 x=int(20*rnd(1)):ifx=0then365
if (!rnd (0, 19))
monster_spawn();
}