*****************************
** Battle System Main flow Program
** Turn Based
** battlesys - main.prg
*****************************
***************************************************
* Welcome to the main flow program of the AS-AT battle system.
* This program runs through your standard movements of battle
* and builds upon the work of the previous program.
* This program looks impressive, but the real magic happens
* behind the scenes in the method libraries. However, read this
* through first, marvel at it's simplicity and then look at those
* libraries. That's where battle system coding get's you!
*
* Anyway, I'm you host, Talyn, so read on, enjoy and don't
* go stealing my work you cheeky bugger!
*
* NB. I aplogise for my appaling language in places. It's 
* usually late at night I'm writing this and I get grouchy.
***************************************************

#include("system.prg")
#include("battlesys - library.prg")
#include("menumethods.prg")
#include("battlesys - library2.prg")

#Method BattleSys(ene1$, ene2$, ene3$, ene4$, ene5$, back$)
{
#id! = 1
**Okay, we need to sort out the turns here.
#sortturns()

#While(ene_defeated! < totalenemies!) **This keeps the system running until all enemies are dead.
{

#If(slot[id!]type! = 1) **If it's a character
{
	#general_id! = slot[id!]!
	#CallMenu(slot[id!]handle$) **Calls up a certain players personalised menu
	#m_opt! = option! **These next two lines need to be tied up in the method itself.
	#kill(option!)
	#If(m_opt! = 1)
	{
	 	 **Menu Option 1 is always Attack.
		#SelectTarget(1) **Explained further on.
		#hp_to_deduct! = Player[general_id!]Fight! - enemy[target!]defence! * Player[general_id!]Emotion!
	 	 **Calculating the damage to be done to the enemy.
		#enemy[target!]HP! = enemy[target!]HP! - hp_to_deduct!
		#DisplayDamage(ene, target!, hp_to_deduct!) **(type, target id, damage to display)
		#kill(hp_to_deduct!)
		#Player[general_id!]Emotion! = Player[general_id!]! + 0.5 **Adds on some Emotion points
		#If(Player[general_id!]Emotion! > 10)
		{
	 	 	 **If they've reached their emotional limit.
			#Player[general_id!]Emotion! = 1
			#BattleSys_Message("<Player[general_id!]Handle$> has vented their Emotion.")
		}

	 	 **That's all the behind the scenes damage calculation, now for the graphical side.
		#castlit(slot[id!]!, player_id2$)
		#castlit(target!, enemy_id2$)
		#anim$ = "player[" + player_id2$ + "]fight.anm" **Concates the string together - Player
		#e_anim$ = "enemy[" + enemy_id2$ + "]defend.anm" **Does the same but for enemies
		#Animation(anim$, player[general_id!]x!, player[general_id!]y!) ** Play the animation at the right place.
		#Animation(e_anim$, enemy[target!]x!, enemy[target!]y!) ** Play the animation for the enemy.
		#kill(anim$)
		#kill(e_anim$)
		#kill(player_id2$) **These two literals just prevent an illegal data type change.
		#kill(enemy_id2$)
	 	 **Both animations are now played and the user believes that the attack has happened. Time to show             
	 	 **the difference. Ironic since the stats all changed a second earlier than they realised.
		#RefreshStats **Cheeky, bung it into a method

	 	 **Finally, let's see if the enemy is dead or not.

		#If(enemy[target!]hp! <= 0)
		{
			#ene_defeated! = ene_defeated! + 1
			#EraseEnemy(target!) **This will be a custom method, erasing the enemies graphics and stats.
			#If(ene_defeated! = enemies!)
			{
				#BattleVictory()
			}
		}
		#id! = id! + 1 **The little bombshell which moves the turns on one place.
	}**End of the Attack option.


	#If(m_opt! = 2)
	{
	 	 **Menu Option 2 is the bugger. Special Moves, how I love them [/sarcasm].
	 	 **The temptation here is to waylay this and stick it all in a method. Yeah, i'll do that.
		#SelectMove(slot[id!]!) **(the players id, the return variable, the type c below)
		#SelectTarget(move_type!) ** 1 is offensive, 2 is defensive target selected.

	 	 **Now that we know what we're doing and to who, time to do the deed itself.
	 	 **As before, I'll start with the horrible maths and then do the pretty bits.

		#If(move_type! = 1)
		{
	 	 	 **This is if the move is used against an enemy.
			#hp_to_deduct! = Spc[move_id!]Fight! - Enemy[target!]defence!
			#hp_to_deduct! = hp_to_deduct! * Player[general_id!]Emotion!
	 	 	 **That's the general equation for working out damage if you hadn't guessed.
			#Enemy[target!]hp! = Enemy[target!]hp! - hp_to_deduct!
	 	 	 **And the damage is done.
	 	 	 **Now change and display the MP cost.
			#Player[general_id!]MP! = Player[general_id!]MP! - Spc[move_id!]Cost!
			#DisplayMPCost(chr, slot[id!]!, Spc[move_id!]Cost!)
	 	 	 **And now lets do all the graphical stuff.
			#Animation(Spc[move_id!]Anim$, Player[general_id!]x!, Player[general_id!]y!)
			#castlit(target!, enemy_id2$)
			#e_anim$ = "enemy[" + enemy_id2$ + "]defend.anm"
			#Animation(e_anim$, enemy[target!]x!, enemy[target!]y!)
			#kill(e_anim$)
			#kill(enemy_id2$)
	 	 	 **That's the basic animation things done, now to add any status effects which may occur.
			#Player[slot[id!]!]Emotion! = Player[general_id!]Emotion! - Spc[move_id!]EmotionCost!
			#DisplayDamage(ene, target!, hp_to_deduct!)
			#kill(hp_to_deduct!)
			#If(Spc[move_id!]Status$ ~= "") ** If there is a status effect
			{
				#Enemy[target!]Status$ = Spc[move_id!]Effect$
			}
	 	 	 **Finally, refresh the stats
			#RefreshStats
	 	 	 **And that marks the end of the Offensive Special Move part. Now let's just move the turn on.
			#id! = id! + 1
		}
		#If(move_type! = 2) **This is a defensive move
		{
	 	 	 **So the move is essentially the same, only it is used on the party.
	 	 	 ** Basically, any restoration is done through Status Ailments. Therefore, the effects
	 	 	 ** won't be felt until special moves are checked. So, this section isn't really needed.
			
	 	 	 **The only thing I can do is animations.
			#castlit(general_id!, general_id$)
			#anim$ = "Player[" + general_id$ + "]special.anm"
			#Animation(anim$, Player[general_id!]x!, Player[general_id!]y!)
			#Animation(Spc[move_id!]Anim$, Player[target!]x!, Player[target!]y!)
			#kill(anim$)
			#kill(general_id$)
	 	 	 **And that marks the end of the Defensive Special Move part. Now let's just move the turn on.
			#id! = id! + 1
		}
	}

	 **Amazingly, that's the special move bit of the program done! Not so bad eh? [/lies]. Now for something       
	 **which will require further code to be added to the beginning program. This is the turn deferral system,
	 **meaning that you can defer your turn for a go and combo up with someone else to create a more powerful
	 **attack. Sounds good, but it'll be a bugger to do.

	#If(m_opt! = 3)
	{
	 	 **The thing to ask is where to start really. The logical thing is to start with checking if anyone
	 	 **else is ready to combo. I'll begin with if no-one can combo, as this option is relatively simple.

		#If(combo! = 0) **If no-one can combo
		{
			#combo! = combo! + 1
			#BattleSys[combo!]$ = Player[general_id!]$ **This shows two new variables with the prefix
			#BattleSys[combo!]! = Player[general_id!]! **BattleSys. More is explained below.
	 	 	 **These battlesys variables are used to track certain System wide changes, such as players
	 	 	 **ready to combo. Only a few of these exist, so feel privilaged to see one of them.

			#BattleSys_Message("<Player[general_id!]$> is ready to combo!")
	 	 	 **The battlesys message is again similar, and shows a message from the system. See the                         
	 	 	 **battlesys - library.prg file for more information.

		}

	 	 **That's the easy bit done. Now we need to do the combo attack themselves when players actually can             
	 	 **combo.

		#If(combo! = 1)
		{
			#CallComboMenu
	 	 	 **That method there will sort out and decide who you will combo with. It returns the variable
	 	 	 **BattleSys_ComboID! and displays the relevant ID.
			#SelectTarget(1)
			#hp_to_deduct! = Player[general_id!]Fight! + Player[BattleSys_ComboID!]Fight!
			#hp_to_deduct! = hp_to_deduct! - Enemy[target!]Defence!
	 	 	 **This equation sequence is more complex, but you should be able to follow it.
	 	 	 **Now we need to deduct the combo attack from the Enemies HP
			#Enemy[target!]HP! = Enemy[target!]HP! - hp_to_deduct!
	 	 	 **That should be it. Now to display the animation for it. This is more complex as we're once
	 	 	 **again dealing with file names.
			#anim$ = "player[" + Player[general_id!]$ + Player[BattleSys_ComboID!]$ + "]combo.anm"
			#Animation(anim$, 1, 1) **This animation will probably be played full screen as a reward for doing
	 	 	 	 	 	 **a combo.
			#kill(anim$)			
			#castlit(target!, target$)
			#e_anim$ = "enemy[" + target$ + "]defence.anm"
			#Animation(e_anim$, enemy[target!]x!, enemy[target!]y!)
			#kill(e_anim$)
			#kill(target$)
	 	 	 **Graphics complete. Now show the damage.
			#DisplayDamage(ene, target!, hp_to_deduct!)
			#kill(hp_to_deduct!)
	 	 	 **As usual, refresh the stats
			#RefreshStats

	 	 	 **Quickly check if an enemy is dead or not:
			#If(enemy[target!]hp! <= 0)
			{
				#ene_defeated! = ene_defeated! + 1
				#If(ene_defeated! = enemies!)
				{
					#Run("battlesys - victory.prg")
				}
			}

	 	 	 **And now to finish the combo off, we need to knock that player off of the combo menu.
			#Kill(BattleSys[combo!]!)
			#kill(BattleSys[combo!]$)
			#combo! = combo! -1
		}**Thus ends a combo attack.

		#id! = id! + 1 ** Move along.
	}**That is the end of the option to combo up with another player.

	 **We've come a long way baby. Now to do the last two menu options and then we can get to the really
	 **fun part of enemies coding.

	 **This option is Item. I'm going to leave this for the moment, since I can use all the calls from the
	 **menu system, instead of having to do all this again.
	#If(m_opt! = 4)
	{
		#InternalMenu(1)
	}

	 **I guess I lied. I'm using the call to the internal menu instead. Cheating, but simpler.


	 **The last player option is run!
	#If(m_opt! = 5)
	{
	 	 ** Running will be decided on a chance system, meaning that certain enemies will have more
	 	 ** of a grip on you. For example, a wolf is a lot harder to run away from compared to a Goblin.
		
	 	 ** To start off the process, I'll select a random number between 1 and 10.
		
		#Random(10, running!)
		
	 	 ** You have to beat that enemies speed to be able to run from it.
		#If(running! > Ene[1]Speed!)
		{
			#Battlesys_Coward()
		}
		#If(running! <= Ene[1]Speed!)
		{
			#ErrorCode(2) *Error Code 2 is "Not fast enough!"
			#id! = id! + 1
		}
	}

}


************

*This is a fairly landmark moment. We have reached the end of the Players Options on the battle system.
*At the moment, Breakpoint hasn't yet been coded in, however, the basic system is now in place.

*We now have the really irritating bit which is Enemy Coding.
*
*Enemy coding is harder in one respect, but easier in another. It's easier because you don't have user input
*to deal with. However, it's harder since you need to have some sort of Enemy AI (Artificial Intelligence)
*otherwise it all feels exactly what it is; random.

*We will start the Enemies section now. We're on Line 251 if you're interested!

*Firstly, state the fact that it is an enemy we are fighting as.

#If(slot[id!]type! = 2)
{
	 *Nows the time to decide on AI. Is it random? Well no, but it might as well be.
	
	 *Lets try it randomly and see what happens.
	#general_id! = slot[id!]! **Just to avoid multi-dimesioned arrays.
	
	:retryenemy **This is explained further on.
	#random(10, move!)
	
	#if(move! <= enemy[general_id!]Probability!)
	{
		:enemyattack **Explained later.
	 	 *This'll be a standard attack. Enemies have their own probablilities which are used.
		#PlayerTarget()
	 	 *That call chooses the unlucky target. Returns target!
		#hp_to_deduct! = Enemy[general_id!]Fight! - Player[target!]Defence! * Enemy[general_id!]Emotion!
	 	 *And we now have the damage to be done. Time to deal it then.
		#Player[target!]HP! = Player[target!]HP! - hp_to_deduct!
		#Enemy[general_id!]Emotion! = Enemy[general_id!]Emotion! + 0.5
	 	 ** Damage has been done and the Emotion hiked up.
		#If(Enemy[general_id!]Emotion! >= 11)
		{
			#BattleSys_Message("<Enemy[general_id!]$> has vented their Emotion!")
			#Enemy[general_id!]Emotion! = 1
		}
	 	 ** Yep, Enemies have emotion too.
		
	 	 ** Do the graphical side:
		#castlit(general_id!, general_id$)
		#castlit(target!, target$)
		#e_anim$ = "ene[" + general_id$ + "]fight.anm"
		#anim$ = "player[" + target$ + "]defend.anm"
		#Animation(e_anim$, Enemy[general_id!]x!, Enemy[general_id!]y!)
		#Animation(anim$, Player[target!]x!, Player[target!]y!)
		#DisplayDamage(plyr, target!, hp_to_deduct!)
		#kill(e_anim$)
		#kill(anim$)
		#kill(target$)
		#kill(general_id$)
		#kill(hp_to_deduct!)
		
	 	 **With the graphics done, we now refresh the stats and check if anyone's dead.
		#RefreshStats
		#if(Player[target!]HP! <= 0)
		{
			#totalplayers! = totalplayers! -1
			#EraseCharacter(target!)
			#If(totalplayers! <= 0)
			{
				#run("battlesys - gameover.prg")
			}
		}
		
	 	 **Now, to finish off a standard attack, move the id along to move to the next player.
		#id! = id! + 1
	}
	
	 **The enemies stuff isn't that dis-similar to the Players, except we do have this random element.
	 ** The Special moves are going to be considerably harder though, so I'll leave that and just check up
	 ** on the older code!

	#if(move! > enemy[general_id!]Probability!)
	{
	 	 **This is a special move (well duh)
		
	 	 **This is going to be what a biologist would call a negative feedback system.
	 	 **Basically, a move is selected at random. Totally at random. It is then ascertained
	 	 **if the enemy has enough MP to perform the move. If he has, then the move is
	 	 **performed no sweat.
	 	 **However, if the enemy doesn't have enough MP, another move is selected at
	 	 **random.
		
	 	 **Now the observant among you may have noticed that an infinite loop could appear here.
	 	 **Eh? What? How? Like this: imagine the enemy has 0 MP. The system would keep looping
	 	 **back, desperately trying to find a move it could perform. Therefore, to safeguard against
	 	 **this, we add an initial condition to the front of the code block.
		
		#If(Enemy[general_id!]MP! = 0)
		{
			#Branch(:retryenemy)
		}
		
	 	 **Now the even more observant among you will realise that this still doesn't totally
	 	 **solve the problem. What if the Enemy has MP, but not enough to perform any move.
	 	 **You could solve this through some complicated system which finds the smallest MP
	 	 **requirement and then runs a similar If as before.
		
	 	 **Now I'm a simple bloke, so I'm gonna do it the easy way. I'll run the loop five times and
	 	 **if it can't come up with anything by the end of it then it'll branch off to an attack.
		
		#attempts! = 1
		#while(attempts! <= 5) **Why use a while loop instead of a for? I prefer While loops.
		{
	 	 	 **Firstly, select the enemy move at random.
			#Random(5, ene_move!) **No enemy has more than 5 moves.
			#If(ene_move! = 1)
			{
	 	 	 	 **Unfortunately, this has to be done one at a time due to trans2 not allowing
	 	 	 	 **multi-dimensional arrays (thanks Chris!)
				#special! = Enemy[general_id!]Spc1!
			}
			#if(ene_move! = 2){#special! = Enemy[general_id!]Spc2!}
			#if(ene_move! = 3){#special! = Enemy[general_id!]Spc3!}
			#if(ene_move! = 4){#special! = Enemy[general_id!]Spc4!}
			#if(ene_move! = 5){#special! = Enemy[general_id!]Spc5!}
			
			#If(Spc[special!]Cost! < Enemy[general_id!]MP!) **If they have enough MP.
			{
	 	 	 	 **And now we come to the main body of code.
	 	 	 	 **The move has passed all the tests. Time to execute it.
				
				#Playertarget()

				#hp_to_deduct! = Spc[special!]Fight! - Player[target!]Defence! * Enemy[general_id!]Emotion!
				#Player[target!]HP! = Player[target!]HP! - hp_to_deduct!
				#Enemy[general_id!]Emotion! = Enemy[general_id!]Emotion! - Spc[special!]EmotionCost!
				#Enemy[general_id!]MP! = Enemy[general_id!]MP! - Spc[special!]Cost!
				#message$ = Enemy[general_id!]$ + " used " + Spc[special!]$
				#Battlesys_Message(message$)
				#kill(message$)
				#castlit(target!, target$)
				#anim$ = "player[" + target$ + "]defend.anm"
				#Animation(Spc[special!]Anim$, Enemy[general_id!]x!, Enemy[general_id!]y!)
				#Animation(anim$, Player[target!]x!, Player[target!]y!)
				#DisplayDamage(plyr, target!, hp_to_deduct!)
				#kill(anim$)
				#kill(target$)
				#kill(general_id$)
				#kill(hp_to_deduct!)
		
				#RefreshStats
				#if(Player[target!]HP! <= 0)
				{
					#totalplayers! = totalplayers! -1
					#EraseCharacter(target!)
					#If(totalplayers! <= 0)
					{
						#run("battlesys - gameover.prg")
					}
				}
				#attempts! = 6
				#branch(:outofwhile)
			}**Well that's a slimmed down Special Move command!
			
			#if(Spc[special!]Cost! > Enemy[general_id!]MP!) **The cost is too high
			{
				#attempts! = attempts! + 1
			}

			#if(attempts! = 6) **If you've had all the tries you can muster.
			{
				#branch(:enemyattack)
			}
		}
		:outofwhile
		#kill(attempts!)
		
	 	 **That's basically it for the enemy. All that's left to do is to move the turn on one.
		
		#id! = id! + 1
	}
	
	 **Yep, that's it for the enemies and also the end of the system as we know it.
	 **If you think you've reached the end then I'm afraid your going to be very disappointed.
	 **There is still two method libraries to look at, combined making up 1581 lines of code.
	 **Uh-huh, that's three times the length of this program!
	
	 **I also need to write in a boss system which will actually be a different battle system.
	 **The same engine, but it will be skinned differently and will have a few other features.
	 **The boss BS will also have more advanced enemy AI.
	
	 **I've had fun doing this system. It's taken about a week to write (3 hours or so a day), but
	 **i've been doing other things as well along the way.
	
	 **If you've read up to here and have decided that enough is enough, then see ya later! Thanks
	 **for reading along and I hope you've found something useful you can take away.
	 **However, if your going to look at the battle system libraries then I'll see you soon!
	
	 **
	
	 **Talyn

}**End of Enemy move


}**END OF SYSTEM
}

***********************************************************************************