/****************************************                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          /*********************************
**        GayBlade   Ver 1.0.0      **
**      © Copyright by Ryan Best 1992  **
**          All Rights Reserved.       **
*****************************************/
#include "GB.h"

extern	WindowPtr	gPictureWindow, gGameWindow, gCastleWindow;
extern	Boolean		gDone, gWNEImplemented;
extern	EventRecord	gTheEvent;
extern	MenuHandle	gAppleMenu,gFileMenu,gOptionsMenu,gSpecialMenu;
extern	Rect		gIntroRect, gTavernRect, gBankRect, gRollerRect, gStoreRect, gCharRect0,
					gCharRect1, gCharRect2, gCharRect3,gItemsRect, gMapRect, gSpellsRect,gSrcRect,
					gGuildRect,gHealerRect,gdungeonRect, gStatsRect, gPartyInfoRect,
					gUseRect,gPanicRect, gMoveRect, gDungDispRect, gActionRect,gConsoleRect, 
					gMScreenRect,leftRect,centerRect,rightRect,cLeftRect,cCenterRect,cRightRect,
					doorRect,clwallRect,crwallRect,cRect, gChestRect,gItemRect,gListStatsRect,
					gListItemsRect, gCompassRect,gTreasureRect;
extern	PicHandle	gThePicture, gConsolePicture, gDungeon1, gLeftWall, gCenterWall, gRightWall,
					gLeftDoor,gRightDoor,gFlatWall,gFlatDoor,gOpenSpace,gFarWall,gFarDoor,gCLWall,gCRWall,
					gCOpenSpace,gCLDoor,gCRDoor,gCFWall,gCFDoor, gMScreenPicture;
extern	CIconHandle	gVialIcon,gShieldIcon, gRingIcon, gSphereIcon,gFlailIcon,gCloakIcon,gArrowIcon,gDaggerIcon,
					gSwordIcon,gHelmetIcon,gTorchIcon,gBookIcon,gGlovesIcon,gBurnedIcon,gArmorIcon,
					gChestIcon, gCompassIcon,gCNorthIcon,gCSouthIcon,gCEastIcon,
					gCWestIcon;
extern int			gSndOn,gPanicOn, gInCastle, gPartyNum,gNewChar, gSndNum, gLastChar, gLight,
					gLightSpell,gItemUseScreen, gCurChar, gInPrison,gDialogNum,gDisplay,gDungLevel,gXLoc,gYLoc,
					gView,gResistFire,gResistIce,gPartyInvis,gInEncounter,gCureWho,gFoundItems[3],
					gCreatType, gCreatureCounter, gCreatHits[10],gLevelCount,dmgType,gTreasure,
					gDisarmSpellCast,gCompass,ASave,gMagicItems[4],gSpeed,gCharShields[4],gEvade,gCPUSpeed;
extern	long		gStats[6], gDungParty[4],gWhichChar,glastWhen,gPanic;
extern	Point		glastWhere;
extern	DialogPtr	gCastleDialog;
extern	RGBColor	gNameBack, gStatsBack, gSpecName,gNormName,gMessBack,gBlack,gStatsFore;
extern	CCrsrHandle	gSpellCursor;
extern	SFReply		fileName;

extern	struct	CharInfo 
{
	Str255	name;
	int		type;
	int		race;
	int		level;
	int		exp;
	int		status;
	int		hits;
	int		dmg;
	int		age;
	int		str;
	int		wis;
	int		itl;
	int		con;
	int		dex;
	int		items[7];	
	int		itemsInUse[7];			/* what items are being used */
	int		gold;
	int	 	bank;					/* released wizard? */
	int		mspells[4],cspells[4];
	int		dngLevel, xLoc, yLoc,Pos;	
};
extern	struct	CharInfo	GameChars[8];						/*  Can store up to 8 chars per game  */

extern	struct	ItemInfo 
{
	Str255			name;
	unsigned char	type;
	unsigned char	status;		/* whether item is in use or not */
	unsigned char	instore;
	unsigned char	level;
	Byte			attrib;
	unsigned char	dmg;
	unsigned char	def;
	unsigned char	con;
};
extern	struct	ItemInfo	GameItems[101];

extern	struct	DungInfo 				
{
	unsigned int	XY[10][10];		/*  x, y  rooms location */
	unsigned int	N[100];			/* 100 rooms w/north walls */
	unsigned int	S[100];			/* 100 rooms w/south walls */
	unsigned int	E[100];			/* 100 rooms w/east walls */
	unsigned int	W[100];			/* 100 rooms w/west walls */
	unsigned int	SA[100];
};
extern	struct	DungInfo	Dungeon[1];	

extern struct	CreatureInfo 				/* access database each encounter */
{
	Str255			name;
	unsigned char	type;
	unsigned char	status;		/* For use in editor only */
	unsigned char	instore;	/* Unused variable */
	unsigned char	level;
	Byte			attrib;
	Byte			dmg;
	Byte			def;
	Byte			hits;
};

extern struct	CreatureInfo	GameCreatures[1];


/******************************* CastLight **************************************/
CastLight()				/***  LIGHT SPELL  ***/

{
	ClearMessage();
		DrawString("\pA soft light glows around your party.");
		gLightSpell=ON;
		gSndNum=6806;				/* jingling sound */
	PlaySound();		
	UpdateDV();
}

/******************************* Wound **************************************/
Wound()					/*** Light wounds creatures  ***/

{
ClearMessage();				
	DrawString("\pInvisible daggers fly down the dungeon!");	
	Pause();Pause();
CalcCreatureDamage(dmgType=WOUND);	/* now go wound the creatures! */
		

}

/******************************* HeavyWound **************************************/
HeavyWound()			/***  Heavy Wound ***/
{
ClearMessage();				
	DrawString("\pInvisible swords streak down the dungeon!");	
	Pause();Pause();
CalcCreatureDamage(dmgType=HEAVYWOUND);	/* now go wound the creatures! */

}

/******************************* Locate **************************************/
Locate()				/*** location in dungeon  ***/
{
Str255		theText;

gLightSpell=ON;
	gSndNum=6806;				/* jingling sound */
		PlaySound();

NumToString(gLevelCount+1,theText);
	ClearMessage();				
		DrawString("\pYou are on level ");
	DrawString(theText);
Pause();
}

/******************************* Invis **************************************/
Invis()					/*** Party invis  ***/

{
gPartyInvis=ON;
	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
ClearMessage();				
	DrawString("\pYour party fades until totally invisibleÉ");
	Pause();Pause();

}
/******************************* InvisOff **************************************/
InvisOff()					/*** Party invis off ***/

{
gPartyInvis=OFF;
	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
ClearMessage();				
	DrawString("\pYour party slowly appearsÉ");
	Pause();

}

/******************************* IceStorm **************************************/
IceStorm()				/*** Casts IceStorm  ***/

{
 gSndNum=15447;
	PlaySound(); 
		ClearMessage();				
		DrawString("\pShards of ice rip down the dungeon!");	
	Pause();Pause();
CalcCreatureDamage(dmgType=ICESTORM);	/* now go ice the creatures! */

}

/******************************* DisarmTrap **************************************/
DisarmTrap()			/*** Disarms trapped chests  ***/

{
}
/******************************* Compass **************************************/
Compass()						/*** Party invis  ***/

{
gCompass=ON;
	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
/* UpdateDV(); */
ClearMessage();				
	DrawString("\pA compass appears at your fingersÉ");
	Pause();
	PlotCompass();
/*	if (gInEncounter==YES)
		AnimateCreature(); */
}
/******************************* FireBalls **************************************/
FireBalls()				/*** throws FireBalls  ***/
{
int				zcount,dmg,theChar;
Byte			totDamage;
long			yy,xx;
Str255			text;
unsigned		min,max;							/* for random # use */

  gSndNum=8050;										/*	 fireball sound 	*/
	PlaySound();
	
ClearMessage();				
	DrawString("\pFireballs blaze all over the place!");	
Pause();Pause();
	
for (zcount=0;zcount<=gPartyNum;zcount++)			/* check each char */
	{
	if (GameChars[gDungParty[zcount]].status>=2 && 
		GameChars[gDungParty[zcount]].status<99)
			{
			min=0,max=100;
			 yy=GetRandomNum(min,max);						/** get random number */
			 
			  if (yy+GameChars[gDungParty[zcount]].dex<=75)  /* 75% chance of being hit*/
			  	{
				ClearMessage();
				  	/*** CALC DAMAGE HERE ***/
				  		theChar=zcount;						/* calc damage for current char */
			  				dmg=yy*3;						/* hard-coded damage here */			
						totDamage=CalcDamage(dmg,theChar);
						
				if (gResistFire==ON)
					totDamage=totDamage-(totDamage*.40);	/* 40% off */

			  	if (GameChars[gDungParty[zcount]].dmg + totDamage>=
			  			GameChars[gDungParty[zcount]].hits)
							totDamage=GameChars[gDungParty[zcount]].hits-
								GameChars[gDungParty[zcount]].dmg-1;
					/** accumulate damage **/
						GameChars[gDungParty[zcount]].dmg=
							GameChars[gDungParty[zcount]].dmg + totDamage;
							if (totDamage>=1)
							{
							DrawString(GameChars[gDungParty[zcount]].name);
								DrawString("\p has been toasted for ");	
									NumToString(totDamage,text);
									DrawString(text);
								DrawString("\p hits!");
							Pause(); 
							}
					}
				}
		Pause();
	}
   UpdateAll();
  CalcCreatureDamage(dmgType=FIREBALLS);	/* now go fry the creatures! */
}

/******************************* Home **************************************/
Home()				/*** Party Home  ***/

{
	gSndNum=25631;					/* teleport sound */
		PlaySound();
	Pause();						/* let sound play */
	gInCastle=YES;					/** back to home!  **/
		TheCastle();
	 		DrawPicture (gMScreenPicture, &gMScreenRect);
				gPanic=YES;			/** for screen plotting **/
				ClearMessage();
			DrawString("\pThere's no place like home!");
		Pause();Pause();
	ClearMessage();
}

/******************************* LightningBolts **************************************/
LightningBolts()				/*** Throws bolts of lightning  ***/

{

ClearMessage();				
	DrawString("\pBolts of lightning streak outward!");	
			gSndNum=32072;			 	
		PlaySound();	
Pause();Pause();

	CalcCreatureDamage(dmgType=LIGHTNINGBOLTS);	/* now go fry the creatures! */
}


/***** CLERICAL-TYPE SPELLS *****/

/******************************* LightHeal **************************************/
LightHeal()				/***  Cures light damage  ***/

{
unsigned		min,max;
int				healedHits;

	gSndNum=6806;					/* jingling sound */
		PlaySound();				/* healed for fraction of hits */
	
	healedHits=GetRandomNum(min=1,max=7);
	if (GameChars[gCurChar].dmg-healedHits<0)
		{
		GameChars[gCurChar].dmg=0;
		}
	else
		{
		GameChars[gCurChar].dmg=GameChars[gCurChar].dmg-healedHits;
		}
		ClearMessage();
			DrawString(GameChars[gCurChar].name);
			DrawString("\p has been lightly healed!");
		UpdateName();
	Pause();

}
/******************************* HeavyHeal **************************************/
HeavyHeal()				/***  Cures light damage  ***/

{
unsigned		min,max;
int				healedHits;

	gSndNum=6806;					/* jingling sound */
		PlaySound();				/* healed for fraction of hits */
	
	healedHits=GetRandomNum(min=8,max=25);
	if (GameChars[gCurChar].dmg-healedHits<0)
		{
		GameChars[gCurChar].dmg=0;
		}
	else
		{
		GameChars[gCurChar].dmg=GameChars[gCurChar].dmg-healedHits;
		}
		ClearMessage();
			DrawString(GameChars[gCurChar].name);
			DrawString("\p has been heavily healed!");
		UpdateName();
	Pause();

}
/******************************* FullHeal **************************************/
FullHeal()				/***  Heals all HIT damage  ***/

{
	gSndNum=6806;					/* jingling sound */
		PlaySound();
		
	GameChars[gCurChar].dmg=0;
		ClearMessage();
			DrawString(GameChars[gCurChar].name);
			DrawString("\p has been healed!");
		UpdateName();
	Pause();	
}
/******************************* Disarm **************************************/
Disarm()					/*** disarms chest  ***/

{

gSndNum=6806;					/* jingling sound */
	PlaySound();
		
if (gTreasure==YES)
	{
		ClearMessage();
		DrawString("\pYou may now open the chest safelyÉ");
		Pause();Pause();
		gDisarmSpellCast=YES;
		return;
	}
else
	{
		ClearMessage();
		DrawString("\pThere is no chest to disarm!");
		Pause();Pause();		
		gDisarmSpellCast=NO;
		return;
	}
}

/******************************* CureAll **************************************/
CureAll()					/*** Cures all hits/poison in party ***/

{
int	x;

	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
ClearMessage();				
	DrawString("\pAll live party members suddenly feel better!");
	Pause();Pause();
	for (x=0;x<=gPartyNum;x++)
	{
		GameChars[gDungParty[x]].dmg=0;
		if (GameChars[gDungParty[x]].status>=2 &&
			GameChars[gDungParty[x]].status<=99)
				GameChars[gDungParty[x]].status=2;
	}
  UpdateAllNames();
}

/******************************* RestoreSpells **************************************/
RestoreSpells()					/*** Cures all hits/poison in party ***/

{
int		x,tempCurChar,tempSpell;

	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
ClearMessage();				
	DrawString("\pMost spells have now been restored!");
	Pause();Pause();
	for (x=0;x<=gPartyNum;x++)
	{
		if (GameChars[gDungParty[x]].status!=DEAD || 
			GameChars[gDungParty[x]].status!=PERMDEAD)
			{
				tempCurChar=gCurChar;
				tempSpell=GameChars[gDungParty[x]].cspells[3];
				GenerateSpells(x);
				GameChars[gDungParty[x]].cspells[3]=tempSpell;
			}
	}
}
/******************************* CurePoison **************************************/
CurePoison()				/*** cures a poisoned character  ***/

{
	gSndNum=6806;					/* jingling sound */
		PlaySound();
		
if (GameChars[gCurChar].status==DEAD || 
	GameChars[gCurChar].status==PERMDEAD)
	{
	ClearMessage();
		DrawString(GameChars[gCurChar].name);
		DrawString("\p can't be cured!");
	return;
	}
			
	GameChars[gCurChar].status=2;		/* cured, but status of 3=poisoned! */
		ClearMessage();
			DrawString(GameChars[gCurChar].name);
			DrawString("\p has been cured!");
		UpdateName();
	Pause();	
}

/******************************* FireShield **************************************/
FireShield()			/*** resists fire  ***/

{
	gSndNum=6806;				/* jingling sound */
		PlaySound();

	ClearMessage();				
		DrawString("\pFire Shield has been cast successfully");
		gResistFire=ON;
	Pause();
}

/******************************* IceShield **************************************/
IceShield()				/*** resists ice  ***/

{
	gSndNum=6806;				/* jingling sound */
		PlaySound();
		
	ClearMessage();				
		DrawString("\pIce Shield has been cast successfully");
		gResistIce=ON;
	Pause();
}

/******************************* Evade **************************************/
Evade()				/*** evade the encounter  ***/
{
unsigned		min,max;
int				poop;

	gSndNum=6806;				/* jingling sound */
		PlaySound();
	ClearMessage();		
	if (gInEncounter==YES)	
		{
		poop=GetRandomNum(min=1,max=100);
			if (poop>25)	
				DrawString("\pYou have evaded the encounter.");
			else
				{
				DrawString("\pThe spell fails!");
				Pause();Pause();
				return;
				}
		}	
	else 
		DrawString("\pYou are not in an encounter to evade!");
		Pause();
	gCreatureCounter=0;			/* delete all creatures, no exp. points */
	gEvade=YES;					/* toggle evade var. ON so no treasure */
}

/******************************* EyeOfDeath **************************************/
EyeOfDeath()			/***  ALWAYS kills one opponent  ***/

{
	ClearMessage();
		gSndNum=29924;				 
	PlaySound();	
		DrawString("\pA greenish stuff shoots from you!");	
			Pause();Pause();Pause();
		ClearMessage();
	CalcCreatureDamage(dmgType=EYEOFDEATH);	/* now go destroy one creature! */
}
/******************************* Magic Vial **************************************/
MagicVial()			/***  unknown what happens to users! ***/
{
unsigned		min,max;
int				result,morgify,x,z;

result=GetRandomNum(min=0,max=5);
	ClearMessage();
				
switch (result)
	{
	case 0:			/* drained level */
	ClearMessage();
	if (gInEncounter==YES)
		{
			DrawString("\pThat was tasty and nothing more.");
			Pause();Pause();Pause();
		}
	else
		{
		DrawString(GameChars[gCurChar].name);
		DrawString("\p has been drained a level!");
		GameChars[gCurChar].level=GameChars[gCurChar].level-1;
 		gSndNum=22699; 		 	
			PlaySound();		
		Pause();Pause();
		if (GameChars[gCurChar].level<=0)
			{
			GameChars[gCurChar].status=PERMDEAD;	/* kill char */
			ClearMessage();
			DrawString(GameChars[gCurChar].name);
			DrawString("\p has perm died.");
				DeadChar();
				UpdateAllNames();
			if (CheckPartyStatus()==YES)	/* if ENTIRE party dead, reset it */
				PartyDead();			
			}
		}
		break;
	case 1:			/* increases level */
			ClearMessage();
			if (GameChars[gCurChar].level<=49)
			{
				gSndNum=10305;
					PlaySound();
						DrawString(GameChars[gCurChar].name);
						DrawString("\p has advanced 1 level!");
					GameChars[gCurChar].level++;
			}
			else
			DrawString("\pThat was tasty and nothing more.");
		break;
	case 2:			/* Potion of poison */
			ClearMessage();
				DrawString(GameChars[gCurChar].name);
					DrawString("\p is now poisoned!");
						GameChars[gCurChar].status=POISONED;
 						gSndNum=16878; 		 	
					PlaySound();
			ReplotChar();					
		break;
	case 3:			/* Regenerates all spells & hits */
			ClearMessage();
				DrawString("\pAll live party members are revitalized!");
					for (z=0;z<=gPartyNum;z++)
					{
					GenerateSpells(z);	
					GameChars[gDungParty[z]].dmg=0;
					if (GameChars[gCurChar].status==POISONED)
						GameChars[gCurChar].status=2;	/* okay */
					}
 					gSndNum=6806; 		 	
				PlaySound();
			UpdateAll();					
		break;	
	case 4:			/* morgify */
			ClearMessage();
				gSndNum=10305;
					PlaySound();
						morgify=GetRandomNum(min=1,max=6);
						DrawString(GameChars[gCurChar].name);
						DrawString("\p has been morgified into aÉ");
						Pause();Pause();Pause();						
					switch (morgify)
					{
						case 1:
							DrawString("\pDrag Queen!");
							GameChars[gCurChar].type=1;				/* type */
						break;						
						case 2:
							DrawString("\pMuse!");
							GameChars[gCurChar].type=2;				/* type */
						break;
						case 3:
							DrawString("\pGuppie!");
							GameChars[gCurChar].type=3;				/* type */
						break;			
						case 4:
							DrawString("\pLesbian!");
							GameChars[gCurChar].type=4;				/* type */
						break;
						case 5:
							DrawString("\pMaster!");
							GameChars[gCurChar].type=5;				/* type */
						break;
					}
				break;
	default:
		DrawString("\pThat was delicious and nothing more.");
	break;
	}									 
	Pause();Pause();Pause();		
}
/******************************* RaiseDead **************************************/
RaiseDead()				/*** attempts to raise the dead  ***/

{	
int				x,y;
unsigned long	z, finalTick, min, max;
Str255			zztext;

	ClearMessage();	
	DrawString("\pCasting Raise Dead spell");
	for (x=0;x<=5;x++)
	{
			Delay (18, &finalTick ); 
			DrawString("\p.");
	}
	
if (GameChars[gCurChar].status!=DEAD)
	{
	ClearMessage();
		DrawString(GameChars[gCurChar].name);
		DrawString("\p can't be raised!");
	return;
	}

z=GetRandomNum(min=0,max=100);			
	x=(GameChars[gCurChar].con+z);
	if (x>=50)
		{
			ClearMessage();	
				DrawString("\pSpell worked. ");
					DrawString(GameChars[gCurChar].name);
					DrawString("\p lives again!");	
				GameChars[gCurChar].status=2;
			GameChars[gCurChar].dmg=0;
			if (GameChars[gCurChar].level<=0)	/* when drained to death */
				GameChars[gCurChar].level=1;
				GenerateSpells(gWhichChar);		/* re=gen spells */
				GameChars[gCurChar].con=GameChars[gCurChar].con-1;
					if (GameChars[gCurChar].con<=0)
						GameChars[gCurChar].con=1;	/* don't let char have 0 con */
		}
	else
		{
		DrawString("\pSpell failed! ");
			Pause();	
			GameChars[gCurChar].status=PERMDEAD;
		RGBBackColor(&gStatsBack);	
		}	
	DeadChar();			/** sorts party **/
	UpdateAll();
}
/********************** PlotCompass *****************************/

PlotCompass()
{
if (gCompass==OFF)					/* Spell NOT cast */
	{
	PlotCIcon(&gCompassRect,gCompassIcon);
	return;
	}
	
else if (gView==0)		/* north */
	{
	PlotCIcon(&gCompassRect,gCNorthIcon);
	return;
	}
else if (gView==2)		/* south */
	{
	PlotCIcon(&gCompassRect,gCSouthIcon);
	return;
	}
else if (gView==1)		/* east */
	{
	PlotCIcon(&gCompassRect,gCEastIcon);
	return;
	}
else if (gView==3)		/* west */
	{
	PlotCIcon(&gCompassRect,gCWestIcon);
	return;
}
	}