home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GameStar Special 2004 August
/
GSSH0804.iso
/
Rollenspiele
/
SwordOfFargoal
/
fargoal20030731b.exe
/
fargoal
/
src
/
player.c
< prev
next >
Wrap
C/C++ Source or Header
|
2003-07-31
|
29KB
|
1,305 lines
#include "map.h"
#include "char.h"
#include "game.h"
static char const *attacks[] = {
"Chop!",
"Clang!",
"Ouch!",
"Thud",
"Clink!",
"Shriek!",
"Slash!",
"Ugh!",
"Claw!",
"Crunch!",
"Gnarl!",
"Growl!",
"Shred!",
"Thump!"
};
static int pass_key=FALSE;
/* C64: (Healing equation?)
4 poke198,0:gd=0:p1=0:l1=0:b1=0:r1=50:s=20-l:gosub208:pokev3,0:ifs<1thens=1
62 ifht<0then114
63 sp=sp+1:ifht<thandsp>ht/th*r1thenht=ht+1:print"(home) ":sp=0
*/
static void player_health_add(int id, int health)
{
list[id].hit+=health;
if(list[id].hit>list[id].maxhit)
list[id].hit=list[id].maxhit;
update_stats ();
}
static void
healing (int id)
{
int rate, multiplier;
if (list[id].fighting || list[id].hit < 0 || paused)
return;
list[id].healing_time++;
multiplier = map_get_spot (list[id].x, list[id].y) == SPOT_TEMPLE ? 1 : 0;
multiplier += list[id].amulets_of_healing;
multiplier = 1 << (list[id].spells[SPELL_REGENERATION].active + multiplier);
rate = 10 * FPS * list[id].hit / (list[id].maxhit * multiplier);
if (list[id].hit < list[id].maxhit && list[id].healing_time > rate)
{
list[id].healing_time = 0;
player_health_add(id, 1);
}
}
/* C64: healing potion
60 hp=hp-1:x=int(20*rnd(1)+3*l):ht=ht+x:ifht>ththenht=th
61 gosub113:print"(home)healing potion taken!":gosub182:goto40
*/
static int drink_potion(int id)
{
if (list[id].potions && list[id].hit < list[id].maxhit)
{
list[id].potions--;
player_health_add(id, rnd(0, 19)+3*list[id].current_level);
message (FPS * 2, potion, "Healing potion taken!");
return TRUE;
}
return FALSE;
}
static void try_lose_map(int id)
{
int r = rnd (1, 4);
(void) id;
if (r == 1)
{
message (FPS * 2, NULL, "Lost your map!");
map_hide_completely ();
}
}
static void
monster_step_back (int e)
{
/* Step back in overlapping mode */
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = { 0, -1, -1, -1, 0, 1, 1, 1};
static int d[] = {0, 1, 2, 3, 4, 5, 6, 7};
int remaining = 8;
/* Restore overlapped player. */
map_put_char (list[e].x, list[e].y, 1);
while (remaining)
{
int r = rnd (0, remaining - 1);
int rd = d[r];
int x = list[e].x + dx[rd];
int y = list[e].y + dy[rd];
if (map_get_spot (x, y) != SPOT_WALL && !map_get_char (x, y))
{
list[e].x += dx[rd];
list[e].y += dy[rd];
break;
}
remaining--;
d[r] = d[remaining];
d[remaining] = rd;
}
map_put_char (list[e].x, list[e].y, e);
}
void
cancel_fighting (int id)
{
if (list[id].fighting)
{
int e = list[id].fighting;
/* Weak monsters bring less XP! */
list[e].maxhit = list[e].hit;
list[e].fighting = 0;
list[e].attacked = 0;
list[id].fighting = 0;
list[id].attacked = 0;
list[id].spells[SPELL_SHIELD].active = 0;
if (!extensions_overlapfight)
map_put_char (list[e].x, list[e].y, e);
}
}
void
player_won (int id)
{
int e = list[id].fighting;
// 298 s1=0:e=e+(s%+h1)*l:bs=bs+int(5*rnd(1)+1):mk=mk+1:k=32
// 299 m%=0:gosub113:print"(home)you vanquished "x$:gosub112
// or
// 346 v1=0:s1=0:pokeo,a:e=e+(s%+h1)*l:bs=bs+int(5*rnd(1)+1):mk=mk+1
// 347 print"(home)you have slain "x$:gosub300:w%=1:gosub175
list[id].exp += (list[e].dex + list[e].maxhit)*list[id].current_level;
//rnd (m_bs / p_bs, 3 * m_bs / p_bs)
if (extensions_balance)
{
list[id].dex+=rnd(((float)list[e].dex/list[id].dex),
4*((float)list[e].dex/list[id].dex))+1;
}
else
{
list[id].dex+=rnd(1, 5);
}
list[id].slain_foes[0]++;
list[id].slain_foes[list[e].type]++;
if (list[id].attacked)
{
message (FPS * 2, victory, "You vanquished %s %s!",
char_prefixes[list[e].type][list[e].subtype],
char_names[list[e].type]);
}
else
{
message (FPS * 2, victory, "You have slain %s %s!",
char_prefixes[list[e].type][list[e].subtype],
char_names[list[e].type]);
}
if (list[e].gold)
{
// 350 gosub113:print"(home)found your"g(v)"gold!!":t=t+g(v):goto274
list[id].gold += list[e].gold;
if(extensions_monsteraction)
{
message (FPS / 2, NULL, "Found %i gold!!", list[e].gold);
}
else
{
message (FPS / 2, NULL, "Found your %i gold!!", list[e].gold);
}
}
{
int s;
int got_stuff = 0;
for (s = 0; s < 6; s++)
{
if (list[e].spells[s].amount)
{
got_stuff = 1;
list[id].spells[s].amount += list[e].spells[s].amount;
}
}
if (got_stuff)
message (FPS / 2, NULL, "Found your spells!!");
}
if (list[e].exp)
{
list[id].exp += list[e].exp;
message (FPS / 2, NULL, "Regained your experience!!");
}
monster_die (e);
cancel_fighting (id);
if (!extensions_overlapfight)
map_put_char (list[id].x, list[id].y, id);
}
static void fight_action(int e)
{
int random_sound = rnd (0, 6);
if (list[e].type >= CHAR_DIREWOLF)
{
message_ex(FPS * 1.25, creature[random_sound], 0, 50, 0, "%s",
attacks[7 + random_sound]);
}
else
{
message_ex(FPS * 1.25, human[random_sound], 0, 50, 0, "%s",
attacks[random_sound]);
}
}
static void
player_fight (int id)
{
int e = list[id].fighting;
int my_attack, monster_attack;
int max_damage;
float skill_ratio;
update_stats ();
/* Assassin is visible during fight. */
if (list[e].type == CHAR_ASSASSIN)
{
list[e].spells[SPELL_INVISIBILITY].active = 0;
/* Redraw */
map_put_char (list[e].x, list[e].y, e);
}
if (!list[e].dex)
{
// 307 print"(home)the mage takes your magic spells!!":iv=0:rg=0:tp=0:sh=0:fa=0:lg=0:goto309
// 308 print"(home)the demon drains your experience level!!":e=int(e/2):ifel>1thenel=el-1
if (list[e].type >= CHAR_DIREWOLF)
{
message (FPS, NULL, "The demon drains your experience level!!");
list[e].exp = list[id].exp / 2;
list[id].exp -= list[e].exp;
if(!extensions_monsteraction)
if (list[id].lev > 1)
list[id].lev--;
list[e].trapped = 1;
list[e].dex++;
}
else
{
int s;
message (FPS, NULL, "The mage takes your magic spells!!");
for (s = 0; s < 6; s++)
{
list[e].spells[s].amount = list[id].spells[s].amount;
list[id].spells[s].amount = 0;
}
list[e].trapped = 1;
list[e].dex++;
}
// 309 m%=0:gosub112:gosub300:return
if (extensions_monsteraction)
{
monster_teleport (e);
if (!extensions_overlapfight)
map_put_char (list[id].x, list[id].y, id);
}
else
monster_die (e);
cancel_fighting (id);
return;
}
// C64: 286 x2=s%/bs:h1=h%
skill_ratio=(float)list[id].dex/(list[e].dex);
//290 h%=h%-int(1/x2*4*l*rnd(1)+1+pl):ifh%<0then298
max_damage = (float)(skill_ratio) * 4 * list[id].current_level;
my_attack = rnd (1, max_damage) + list[id].weapon;
// C64: 288 ht=ht-int(x2*4*l*rnd(1)+1)
skill_ratio=(float)list[e].dex/(list[id].dex);
max_damage = (float)skill_ratio * 4 * list[id].current_level;
monster_attack = rnd (1, max_damage);
/* We are merely defending ourselves. */
if (list[id].attacked)
{
// 286 x2=s%/bs:h1=h%
// 287 ifs1=1then289
// 288 ht=ht-int(x2*4*l*rnd(1)+1)
if (!list[id].spells[SPELL_SHIELD].active)
{
player_health_add(id, -monster_attack);
add_hit (list[id].x, list[id].y, -monster_attack);
}
fight_action(e);
// 289 ifd=1andt>0orsf=1thenifx2<.5orx2>1orc=42then294
if (list[e].type < CHAR_DIREWOLF && (list[id].gold || list[id].sword))
{
if (list[e].dex > list[id].dex || list[e].dex * 2 < list[id].dex ||
list[e].type == CHAR_ROGUE)
{
// 294 gosub113:ifsf=1thensf=0:print"(home)the sword is stolen!!":gosub112:goto296
// 295 d=-1:p=a:print"(home)your gold is stolen!!":gosub112:g(j)=t:t=0:goto386
if (list[id].sword)
{
list[e].sword = list[id].sword;
list[id].sword = 0;
message (FPS * 2, NULL, "The sword is stolen!!");
list[e].trapped = 1;
if (list[id].current_level == swordlev)
{
map_put_spot (19, 12, SPOT_SWORD);
}
}
else
{
message (FPS * 2, NULL, "Your gold is stolen!!");
list[e].gold = list[id].gold;
list[id].gold = 0;
list[e].trapped = 1;
}
if (!extensions_overlapfight)
monster_step_back (e);
cancel_fighting (id);
}
}
if (list[id].fighting)
{
// 290 h%=h%-int(1/x2*4*l*rnd(1)+1+pl):ifh%<0then298
list[e].hit -= my_attack;
add_hit (list[e].x, list[e].y, my_attack);
if (list[e].hit < 0)
player_won (id);
// 291 ifht<-5thengosub113:print"(home)slain by "x$:goto426
else if (list[id].hit < -5)
{
player_die (id);
message (FPS, slain, "Slain by %s %s",
char_prefixes[list[e].type][list[e].subtype],
char_names[list[e].type]);
cancel_fighting(id);
}
}
}
else /* We are attacking. */
{
// 340 h%=h%-int(1/x*4*l*rnd(1)+1+pl):ifh%<0then346
list[e].hit -= my_attack;
if (list[e].dex)
{
add_hit (list[e].x, list[e].y, my_attack);
}
if (list[e].hit < 0)
{
player_won (id);
}
else
{
// 341 ifs1=1then344
// 342 ht=ht-int(x*4*l*rnd(1)+1)
// 343 ifht<-5thenprint"(home)(rvon) (rvof) thou art slain!":goto426
fight_action(e);
if (!list[id].spells[SPELL_SHIELD].active)
{
player_health_add(id, -monster_attack);
add_hit (list[id].x, list[id].y, -monster_attack);
if (list[id].hit < -5)
{
player_die (id);
message (FPS, slain, "Thou art slain!");
cancel_fighting (id);
}
}
}
}
}
void
player_roll (int *health, int *skill)
{
int i;
/*
- Hah! I new it! Initial roll for the player's stats (3d6):
443 fori=1to3:ht=ht+int(6*rnd(1)+1):bs=bs+int(6*rnd(1)+1):next
444 sr=1:th=ht:ep=200:k=32:hp=1:tp=1:t1=100:ql=int(5*rnd(1)+15)
- Quest Level is assigned in 'ql' above
*/
*health = 0;
*skill = 0;
for (i = 0; i < 3; i++)
{
*health += rnd (1, 6);
*skill += rnd (1, 6);
}
}
int
player_create (int x, int y, int health, int skill)
{
int id = char_create (x, y);
list[id].type = CHAR_HERO;
list[id].hit = health;
list[id].dex = skill;
list[id].maxhit = list[id].hit;
list[id].next = 200;
list[id].potions = 1;
list[id].spells[SPELL_TELEPORT].amount = 1;
return id;
}
static void
player_treasure (int id)
{
// 227 r=int(9*rnd(1)+1):onrgoto236,243,228,245,247,247,247,247,247
int w = rnd (1, 9);
int x = list[id].x;
int y = list[id].y;
map_put_spot (x, y, SPOT_FLOOR);
switch (w)
{
case 1:
// 236 p1=0:pokev3,peek(v3)and254:print"(home)pit!!...you fell!"
// 237 h1=int(10*rnd(1)+l):k=61:pokem,k:pokeo,k:cl=1:gosub148:goto262
// 238 p$="down":p1=1:p2=k:k=62:pt=int(4*rnd(1)+2)
// 239 z=pt*p1:l=l+z:pokeo,p2:gosub113:print"(home)climbing the pit...";
message (FPS, pit, "Pit!!... You fell!");
map_put_spot (x, y, SPOT_PIT);
map_put_info(x, y, rnd(2, 5));
list[id].trapped = SPOT_PIT;
break;
case 2:
// 243 pokev3,peek(v3)and254:print"(home)ceiling trap!"
// 244 h1=int(10*rnd(1)+l):k=59:pokem,k:pokeo,k:gosub156:cl=1:goto262
message (FPS, pit, "Ceiling trap!");
map_put_spot (x, y, SPOT_CEILING);
list[id].trapped = SPOT_CEILING;
break;
case 3:
// 228 print"(home)explosion!!":pokes5,10:pokes6,42:pokes3,1:pokeso,12:pokes5+7,10:pokes6+7,42
message (FPS, boom, "Explosion!!");
if (list[id].spells[SPELL_SHIELD].active)
{
// 234 s1=0:print"(home)shielded from blast!":gosub112
list[id].spells[SPELL_SHIELD].active--;
message (FPS, NULL, "Shielded from blast!");
}
else
{
// C64: 233 next:ifs1=0thenht=ht-int(15*rnd(1)+l):cl=1:goto235
int h = rnd (0, 14)+list[1].current_level;
player_health_add(id, -h);
add_hit (list[id].x, list[id].y, -h);
try_lose_map(id);
}
break;
case 4:
// 245 print"(home)teleport...":k=32:pokem,k:pokeo,k:gosub144:o=n-d%:pokeo,a:pokeo+cm,1
message (FPS, teleport, "Teleport...");
char_teleport (id);
try_lose_map(id);
break;
case 5:
case 6:
case 7:
case 8:
case 9:
{
// 247 w%=2:gosub175:e=e+int(50*rnd(1)+l):k=32:pokem,k:x=int(15*rnd(1)+1)
// 248 onxgoto250,251,250,249,251,252,257,253,254,255,259,252,257,258,260
list[id].exp += rnd (0, 49) + list[id].current_level;
w = rnd (1, 15);
switch (w)
{
case 1:
case 2:
// 250 print"(home)healing potion!!":hp=hp+1:goto274
message (FPS, item, "Healing potion!!");
list[id].potions++;
break;
case 3:
case 4:
// 251 print"(home)magic sack!!":bg=bg+1:t1=t1+100:goto274
message (FPS, item, "Magic sack!!");
list[id].sacks++;
break;
case 5:
/* Played some more, and still spent time in the temple
healing in level 8. So now you can get amulets, at most
one after every 8 levels, and only a 1:2 chance instead
of a regeneration spell. The effect is just like a
permanent regeneration spell. */
if (extensions_balance &&
list[id].current_level > 8 * (1 + list[id].amulets_of_healing) &&
!rnd (0, 2))
{
message (FPS, item, "Amulet of Healing!!");
list[id].amulets_of_healing++;
}
else
{
// 249 print"(home)regeneration spell!!":rg=rg+1:goto274
message (FPS, item, "Regeneration spell!!");
list[id].spells[SPELL_REGENERATION].amount++;
}
break;
case 6:
case 7:
// 252 print"(home)shield spell!!":sh=sh+1:goto274
message (FPS, item, "Shield spell!!");
list[id].spells[SPELL_SHIELD].amount++;
break;
case 8:
case 9:
// 257 print"(home)teleport spell!!":tp=tp+1:goto274
message (FPS, item, "Teleport spell!!");
list[id].spells[SPELL_TELEPORT].amount++;
break;
case 10:
/* Since I added a healing amulet, thought could as well
add a light amulet. This is very unlikely to obtain right
now though (one per 15 levels, and 25% chance instead of
a spell. The effect is a permanent light spell. */
if (extensions_balance &&
list[id].current_level > 15 * (1 + list[id].amulets_of_light) &&
!rnd (0, 3))
{
message (FPS, item, "Amulet of Light!!");
list[id].amulets_of_light++;
}
else
{
// 253 print"(home)light spell!!":lg=lg+1:goto274
message (FPS, item, "Light spell!!");
list[id].spells[SPELL_LIGHT].amount++;
}
break;
case 11:
// 254 print"(home)enchanted weapon!!":pl=pl+1:bs=bs+int(10*rnd(1)+5):goto274
message (FPS, item, "Enchanted weapon!!");
list[id].weapon++;
list[id].dex+=rnd(0, 9)+5;
break;
case 12:
// 255 x=int(8*rnd(1)+l+3):print"(home)map to"x"th level!!"
// 256 tm=tm+1:t%(tm)=x:goto274
{
int m = list[id].current_level + rnd (3, 10);
if(m==list[id].current_level)
{
message(FPS, item, "Treasure Map!!");
map_seen (20, 12, 20);
}
else
{
message (FPS, item, "Map to %ith level!!!", m);
list[id].map |= (1 << m);
}
break;
}
case 13:
// 259 print"(home)invisibility spell!!":iv=iv+1:goto274
message (FPS, item, "Invisibility spell!!");
list[id].spells[SPELL_INVISIBILITY].amount++;
break;
case 14:
// 258 print"(home)drift spell!!":fa=fa+1:goto274
message (FPS, item, "Drift spell!!");
list[id].spells[SPELL_DRIFT].amount++;
break;
case 15:
// 260 print"(home)beacon!!":be=be+1:goto274
message (FPS, item, "Beacon!!");
list[id].beacons++;
break;
}
break;
}
}
}
static void climb_pit(int id)
{
int x = list[id].x;
int y = list[id].y;
int downsteps = map_get_info (x, y);
/* C64:
238 p$="down":p1=1:p2=k:k=62:pt=int(4*rnd(1)+2)
239 z=pt*p1:l=l+z:pokeo,p2:gosub113:print"(home)climbing the pit...";
240 pokev3,peek(v3)and254:w1=int(2*rnd(1)+1):gosub171:y=int(2*rnd(1))
241 ify=1thenprint"you fell!":h1=int(10*rnd(1)+3*pt+l):gosub148:goto261
*/
list[id].current_level += downsteps;
message (FPS, climb, "Climbing the pit...");
if (!rnd (0, 1))
{
list[id].trapped = SPOT_PIT;
message (0, pit, NULL);
}
map_enter (SPOT_ROPE, downsteps);
}
static void
player_action (int id)
{
int x = list[id].x;
int y = list[id].y;
int spot;
/*
During fighting, try to teleport away.
302 iftp>0then305
303 ifsh>0ands1=0thensh=sh-1:s1=1:gosub113:print"(home)thy shield is in
- This is only if attacked
- Shield will be used if there's no teleport
*/
if (list[id].attacked)
{
if(!spell_cast (id, SPELL_TELEPORT))
{
if(!spell_cast(id, SPELL_SHIELD))
{
play_sample (ding, 250, 128, 1000, 0);
return;
}
}
else
{
// So that we can't cast both spells by accident
list[id].attacked=0;
}
return;
}
if (list[id].trapped==SPOT_PIT)
{
if(!spell_cast (id, SPELL_DRIFT))
play_sample (ding, 250, 128, 1000, 0);
return;
}
else if (list[id].trapped==SPOT_CEILING)
{
if(!spell_cast (id, SPELL_TELEPORT))
play_sample (ding, 250, 128, 1000, 0);
return;
}
spot=map_get_spot (x, y);
if(paused)
{
if(spot==SPOT_FLOOR)
{
play_sample (ding, 250, 128, 1000, 0);
pass_key=TRUE;
}
return;
}
switch (spot)
{
default:
play_sample (ding, 250, 128, 1000, 0);
pass_key=TRUE;
break;
case SPOT_DOWN:
list[id].current_level++;
message (FPS, down, "You go down the stairs.");
map_enter (SPOT_UP, 1);
break;
case SPOT_UP:
if (list[id].current_level == 1)
{
if (swordrun && list[id].sword)
{
// 111 print"(clr)(down)(down)(down)(down)(down)(down)(down)(down)(down)(down) your quest is complete!!":gosub201:goto412
message (FPS * 4, intro, "Your quest is complete!!");
won = 1;
}
else
{
message (FPS, NULL, "Not without the Sword of Fargoal!");
}
}
else
{
list[id].current_level--;
message (FPS, up, "You go up the stairs.");
map_enter (SPOT_DOWN, 1);
}
break;
case SPOT_ROPE:
{
int upsteps = map_get_info (x, y);
list[id].current_level -= upsteps;
message (FPS, climb, "Climbing the rope...");
map_enter (SPOT_PIT, upsteps);
break;
}
case SPOT_PIT:
{
climb_pit(id);
break;
}
case SPOT_BEACON:
// 92 ifk=44thenpokeo,k:k=38:o=b3:pokeo,a:pokeo+cm,1:gosub108:gosub146:gosub113:goto117
message (FPS, teleport, NULL);
char_transfer_to (id, temple_x, temple_y);
break;
case SPOT_TREASURE:
player_treasure (id);
break;
}
}
static void
player_in_trap (int id)
{
int x = list[id].x;
int y = list[id].y;
int s = map_get_spot (x, y);
if (s == SPOT_PIT || s == SPOT_ROPE)
{
if (!list[id].spells[SPELL_DRIFT].active)
{
int h;
if (s == SPOT_PIT)
{
// 237 h1=int(10*rnd(1)+l):k=61:pokem,k:pokeo,k:cl=1:gosub148:goto262
h = rnd(0, 9)+list[id].current_level;
message (FPS, human[0], NULL);
}
else
{
// 241 ify=1thenprint"you fell!":h1=int(10*rnd(1)+3*pt+l):gosub148:goto261
int upsteps = map_get_info (x, y);
h = rnd (0, 9) + 3 * upsteps + list[id].current_level;
message (FPS, human[0], "You fell!");
}
player_health_add(id, -h);
add_hit (list[id].x, list[id].y, -h);
}
else
{
list[id].spells[SPELL_DRIFT].active--;
message (FPS, NULL, "like a feather...");
}
}
/* Crushing ceiling. */
if (s == SPOT_CEILING)
{
if (!list[id].spells[SPELL_TELEPORT].active)
{
/* C64:
244 h1=int(10*rnd(1)+l):k=59:pokem,k:pokeo,k:
gosub156:cl=1:goto262
*/
int h = rnd (0, 9)+list[id].current_level;
message (FPS, crunch, NULL);
player_health_add(id, -h);
add_hit (list[id].x, list[id].y, -h);
try_lose_map(id);
}
else
{
list[id].spells[SPELL_TELEPORT].active--;
char_teleport (1);
message (FPS, NULL, "Teleport to safety!");
}
}
}
void
player_try_levelup (int id)
{
/* C64: Level up
119 ep=ep*2:el=el+1:th=th+int(15*rnd(1)+5):bs=bs+int(10*rnd(1)+1)
- Implemented
*/
if (list[id].exp >= list[id].next)
{
float percentage = (float)list[id].hit / (float)list[id].maxhit;
list[id].lev++;
list[id].maxhit += rnd (1, 15)+4;
list[id].dex += rnd (1, 10);
if (extensions_balance)
list[id].hit = percentage * list[id].maxhit + 0.5;
list[id].next *= 2;
message (FPS, levelup, "Gained a level!");
//printf ("maxhit = %i skill = %i\n", list[id].maxhit, list[id].dex);
}
}
void
player_die (int id)
{
(void) id;
gameover = 1;
spiral_map = MAP_W * MAP_H / 2;
}
void
player_process (int id)
{
int x = list[id].x;
int y = list[id].y;
int i;
/* Keyboard state. */
int dir_x = 0;
int dir_y = 0;
#if defined(_DEBUG) || defined(DEBUGMODE)
if (key[KEY_0])
{
player_health_add(id, -list[id].hit);;
}
if (key[KEY_1])
{
list[id].spells[SPELL_SHIELD].amount=1;
list[id].spells[SPELL_TELEPORT].amount=1;
list[id].spells[SPELL_DRIFT].amount=1;
list[id].spells[SPELL_LIGHT].amount=1;
list[id].spells[SPELL_REGENERATION].amount=1;
list[id].spells[SPELL_INVISIBILITY].amount=1;
list[id].beacons++;
list[id].potions++;
list[id].gold+=50;
list[id].dex=400;
list[id].maxhit++;
list[id].hit=list[id].maxhit;
update_stats();
}
if (key[KEY_2])
{
list[id].current_level=20;
list[id].hit=list[id].maxhit;
update_stats();
}
if (key[KEY_3])
{
map_seen (20, 12, 20);
}
if (key[KEY_4])
{
list[id].sword = 1;
swordrun = SWORD_TIME;
}
if (key[KEY_5])
{
list[id].amulets_of_healing = 1;
list[id].amulets_of_light = 1;
update_stats();
}
if (key[KEY_6])
{
list[id].amulets_of_healing = 0;
list[id].amulets_of_light = 0;
update_stats();
}
#endif
if (check_key_ex(KEY_LEFT, TRUE))
{
dir_x = -1;
}
if (check_key_ex(KEY_RIGHT, TRUE))
{
dir_x = 1;
}
if (check_key_ex(KEY_UP, TRUE))
{
dir_y = -1;
}
if (check_key_ex(KEY_DOWN, TRUE))
{
dir_y = 1;
}
/* Check spell keys. */
for (i = 0; i < 6; i++)
{
static int spellkeys[] = { KEY_I, KEY_R, KEY_T, KEY_S, KEY_L, KEY_D };
if (check_key (spellkeys[i]))
{
if (!spell_cast (id, i))
play_sample (ding, 250, 128, 1000, 0);
}
}
if (check_key (KEY_B))
{
// 54 ifa$="+"andbe>0andb1=0thenbe=be-1:b1=1:k=44:b2=o:pokeo+d%,k:gosub113:print"(home)thy beacon is placed!":gosub150:goto40
if (list[id].beacons && list[id].beaconx == 0 && list[id].beacony == 0)
{
if (map_get_spot (x, y) == SPOT_FLOOR)
{
map_put_spot (x, y, SPOT_BEACON);
list[id].spells[SPELL_INVISIBILITY].active++;
list[id].beacons--;
list[id].beaconx = x;
list[id].beacony = y;
message (FPS, beacon, "Thy beacon is placed!");
}
else
{
message (FPS, ding, "Cannot place beacon here");
}
}
else
play_sample (ding, 250, 128, 1000, 0);
}
if (check_key (KEY_H))
{
if (!drink_potion(id))
{
play_sample (ding, 250, 128, 1000, 0);
}
}
if (check_key (KEY_LCONTROL) || check_key (KEY_RCONTROL) ||
check_key (KEY_SPACE) || check_key (KEY_ENTER))
{
player_action (id);
}
if (check_key (KEY_O))
{
// 121 gosub113:ifl1=1thenl1=2:print"(home)light off":gosub112:goto42
// 122 l1=1:gosub211:print"(home)light on":gosub112:goto42
if (list[id].spells[SPELL_LIGHT].active)
{
list[id].spells[SPELL_LIGHT].active = -list[id].spells[SPELL_LIGHT].active;
if (list[id].spells[SPELL_LIGHT].active > 0)
message (FPS, NULL, "Light on");
if (list[id].spells[SPELL_LIGHT].active < 0)
message (FPS, NULL, "Light off");
}
else
play_sample (ding, 250, 128, 1000, 0);
}
if (check_key (KEY_G))
{
// 124 ifgd>9ork<>32then41
// 125 gd=gd+1:k=60:pokeo+d%,k:g%(gd)=t:l%(gd)=o:gosub113
// 126 print"(home)hiding"t"gold pieces":t=0:gosub112:goto42
if (list[id].gold)
{
if (map_get_spot (x, y) == SPOT_FLOOR)
{
message (FPS, NULL, "Hiding %i gold pieces", list[id].gold);
map_put_spot (x, y, SPOT_STASH);
map_put_info (x, y, list[id].gold);
list[id].gold = 0;
}
else
{
message (FPS, ding, "Cannot bury gold here");
}
}
else
play_sample (ding, 250, 128, 1000, 0);
}
healing (id);
/* Game is currently paused. */
if (paused)
{
paused--;
char_move (id, 0, 0);
if (paused == 0)
{
if (list[id].trapped)
{
player_in_trap(id);
list[id].trapped = 0;
}
}
}
else /* Not paused. */
{
if (!extensions_nomonsterpause)
{
if(!global_steps)
{
dir_x = dir_y = 0;
}
}
// See if player is trying to escape, and was not attacked
if (!list[id].attacked)
{
char_move (id, dir_x, dir_y);
}
if (!paused && !list[id].step)
{
// 114 ifhp>0then60
// 115 gosub113:print"(home)(rvon) (rvof) you died!!":goto426
/* Teleport spell? */
if (list[id].spells[SPELL_TELEPORT].active)
{
char_teleport (id);
cancel_fighting (id);
list[id].spells[SPELL_TELEPORT].active--;
}
/* Dead? */
if (list[id].hit < 0)
{
if (!drink_potion(id))
{
player_die (id);
message (FPS, slain, "You died!!");
return;
}
}
if (list[id].fighting)
player_fight (id);
}
player_try_levelup (id);
}
}
void
player_leave (int id)
{
int x = list[id].x;
int y = list[id].y;
switch (map_get_spot (x, y))
{
default:
break;
case SPOT_BEACON:
list[id].spells[SPELL_INVISIBILITY].active--;
update_stats();
break;
}
}
void
player_change_position (int id)
{
int x = list[id].x;
int y = list[id].y;
int r = 1 + list[id].spells[SPELL_LIGHT].active + list[id].amulets_of_light;
int spot;
if (r < 1)
r = 1;
map_seen (x, y, r);
play_sample (step, 250, 128, 1000, 0);
if (extensions_nomonsterpause && global_steps)
{
global_steps--;
stepcount = (extensions_speed ? FPS : FPS*2);
}
spot=map_get_spot (x, y);
// TODO: if Pass key, clear key and return
if(pass_key&&spot!=SPOT_FLOOR&&spot!=SPOT_VOID)
{
pass_key=FALSE;
return;
}
switch (spot)
{
default:
break;
case SPOT_TREASURE:
if(!extensions_controls)
player_treasure (id);
break;
case SPOT_DOWN:
message (FPS / 2, down, "Stairs going down");
break;
case SPOT_UP:
message (FPS / 2, up, "Stairs going up");
break;
case SPOT_PIT:
if(extensions_controls)
message (FPS / 2, NULL, "Pit!");
else
climb_pit(id);
break;
case SPOT_ROPE:
message (FPS / 2, NULL, "Climbable pit above!");
break;
case SPOT_CEILING:
message (FPS / 2, NULL, "hole in the ceiling!");
break;
case SPOT_BEACON:
message (FPS * 2, beacon, "Swirling mists surround you!");
/* Get invisible on beacon. */
list[id].spells[SPELL_INVISIBILITY].active++;
break;
case SPOT_SWORD:
// 94 gosub113:print"(home)the sword of fargoal!!":gosub201:sf=1:k=32:pokem,k:ift2=0thene=e*2:t2=ti
// 95 goto274
list[id].sword++;
if (swordrun == 0)
{
list[id].exp *= 2;
swordrun = SWORD_TIME;
}
message (FPS * 4, intro, "The Sword of Fargoal!!");
map_put_spot (x, y, SPOT_FLOOR);
break;
case SPOT_GOLD:
{
// 216 y=int(20*rnd(1)+10*l):print"(home)treasure: "y"gp's":gosub165:ift+y>t1then218
// 217 t=t+y:k=32:pokem,k:goto40
// 218 ifgd>9then40
// 219 gd=gd+1:k=60:pokem,k:g%(gd)=t+y-t1:l%(gd)=o:ift=t1then221
// 220 t=t1:print"(home)can't carry more gold":goto274
// 221 print"(home)hiding the gold ":goto274
int max = 100 + list[id].sacks * 100;
int g = 10 * list[id].current_level + rnd (0, 19);
//if(extensions_controls && max <= list[id].gold)
// break;
message (FPS, gold, "Treasure: %i GP's", g);
if (list[id].gold + g <= max)
{
map_put_spot (x, y, SPOT_FLOOR);
list[id].gold += g;
}
else
{
map_put_spot (x, y, SPOT_STASH);
map_put_info (x, y, list[id].gold + g - max);
if (list[id].gold < max)
{
list[id].gold= max;
message (FPS/2, NULL, "Can't carry more gold");
}
else
{
message (FPS/2, NULL, "Hiding the gold");
}
}
break;
}
case SPOT_STASH:
{
// 222 print"(home)hidden treasure!!":gosub165:forj=1togd:ifo=l%(j)thenv=j:j=gd
// 223 next
// 224 z=g%(v):ift+z>t1then226
// 225 t=t+z:k=32:pokem,k:goto40
// 226 g%(v)=t+z-t1:t=t1:gosub113:print"(home)gold too heavy":goto274
int max = 100 + list[id].sacks * 100;
int g = map_get_info (x, y);
if(max<=list[id].gold)
break;
message (FPS / 2, gold, "Hidden Treasure!!");
if (list[id].gold + g <= max)
{
list[id].gold += g;
map_put_spot (x, y, SPOT_FLOOR);
}
else
{
map_put_info (x, y, list[id].gold + g - max);
list[id].gold= max;
message (FPS/2, NULL, "Gold too heavy");
}
break;
}
case SPOT_TEMPLE:
if (list[id].gold)
{
message (FPS, sacrifice, "Sacrifice of gold!");
list[id].exp += list[id].gold;
if (extensions_balance)
{
{
list[id].sacrificed_gold+=list[id].gold;
if(list[id].sacrificed_gold>=TEMPLE_GOLD &&
list[id].hit<list[id].maxhit)
{
list[id].sacrificed_gold-=TEMPLE_GOLD;
player_health_add(id, list[id].maxhit);
message (FPS, item, "You are blessed!");
}
/*
PP: I wonder if we should still add faster temple
healing, perhaps with regeneration... so that
regen + temple is quite fast
*/
}
}
list[id].gold = 0;
}
else
{
message (FPS/2, NULL, "Temple!");
}
break;
}
}