/**************************************************************************************************
 * Program:		New Miracles for Black & White 2
 * Purpose:		Add new miracles to the game: Wheat, Animals, Ore, Forest, Light, and Lava
 *					This specific file acts as the main file, which possess overall control over the
 * 					miracles. 
 * Author:		Bill
 * Version: 	0
 * Date: 		Feb 2 2020
**************************************************************************************************/
//-------------------------------------------Scripts-----------------------------------------------
//Interface Scripts
define script NMs_totemMain	//Starts the main loop of totems
define script NMs_createTotem(xPos,zPos,ang,townId,idx) //Creates a totem at a position
define script NMs_addMiracleToTotem(idx,miracleIdx,m_idx) //Adds a miracle to a totem

//Static Scripts
define script NMs_ChargeUpdate(m_Mana)
define script NMs_totemPeriodic
define script NMs_totemMigrate(t_idx,tm_idx)

define script NMs_calNumMiracles(t_idx)
define script NMs_calculatePower(idx)

define script NMs_CallCreateFunction(xPos, yPos, zPos, m_idx, t_idx)
define script NMs_CallHandCreateFunction(m_ele)
define script NMs_CallHandDeleteFunction(m_ele)
define script NMs_CallDeleteFunction(t_idx, m_idx)
define script NMs_MoveMiracleFunction(xPos, yPos, zPos, m_idx, t_idx)
define script NMs_CalManaFunction(m_idx, t_idx)
define script NMs_CallThrowFunction(m_ele,pwr)
define script NMs_CallPourFunction(m_ele,pwr)

//------------------------------------------Constants----------------------------------------------
define NMs_STATEINITIAL			= 0 			//Starting State - Initializing stuff
define NMs_STATEIDLE			= 1 			//Waiting for action from player
define NMs_STATEMANA			= 2				//Miracle clicked, take mana if enough
define NMs_STATEHANDLED			= 3 			//create it in hand
define NMs_STATEACTIONWATCH		= 4				//Determines whether pouring or throwing
define NMs_STATECASTING			= 5 			//Casting a miracle

define NMs_NUMBERTOTEM			= 7				//Number of totems on the land
define NMs_MIRPERROW			= 6				//Number of miracles per row of a totem
define NMs_POWERAT1				= 100			
define NMs_POWERMULT			= 0.1
define NMs_MIRACLEHEIGHT		= 14

define NMs_TOT2D				= 9
define NMs_TOTEMDEF				= 63			//NMs_NUMBERTOTEM * NMs_TOT2D
define NMs_TOTEMDEF2			= 42			//NMs_NUMBERTOTEM * NMs_MIRACLETYPES
define NMs_TOTMIRACLEMAX		= 19			//The maximum number of miracles allowed per totem

define NMs_TOTPWRUPDATE			= 30

//DO NOT TOUCH THE FOLLOWING CONSTANTS :)
define NMs_TOTBASE				= 0
define NMs_TOTSTATUE			= 1
define NMs_TOTTOWNID			= 2
define NMs_TOTCNT				= 3
define NMs_TOTV1				= 4
define NMs_TOTV2				= 5
define NMs_TOTV3				= 6
define NMs_TOTPWR				= 7
define NMs_TOTCNT2				= 8

//-------------------------------------------Globals-----------------------------------------------
//External communication variables
global NMs_Running 				= NMs_FALSE		//Indicator if system is running, set true when init is complete
global NMs_TotemIndexResult		= 0

//Static variables
global NMs_TotemState 			= 0				//Stores the current state of the totem's main script
global NMs_HandFull				= NMs_FALSE		//Indicates whether there is something within the player's hand
global NMs_MiracleInHand		= 0				//Indicates what miracle the player is holding

global NMs_IndepLock			= NMs_FALSE		//Lock variable for NMs_calNumMiracles
global NMs_IndepResult			= 0				//Result variable for NMs_calNumMiracles

global NMs_PowerLock			= NMs_FALSE		//Lock variable for NMs_calculatePower
global NMs_PowerResult			= 0				//Result variable for NMs_calculatePower

global NMs_HandIdxResult		= 0
global NMs_ChargeLoop			= NMs_FALSE

//Totem variables
//NMs_Totems: 2D array: [Totem Index][0:Base, 1:Statue, 2:Town Id, 3:Miracle Count, 4:Visual 1, 5:Visual 2, 6:Visual 3, 7:Power]
global NMs_Totems[NMs_TOTEMDEF]				//Contains the totem base objects
//NMs_TotemMiracle: 2D array: [Totem Index][Miracles]
global NMs_TotemMiracle[NMs_TOTEMDEF2]

global NMs_LoopControl			= NMs_TRUE

global NMs_TotemCnt 			= 0

//Migration takers
global NMs_Migrations[NMs_NUMBERTOTEM]
//--------------------------------------------Main-------------------------------------------------
begin script NMs_totemMain
	cnt = 0
	m_idx = 0
	m_Clicked = 0
	p_casting = 0
	i_idx = 0
	i_town = 0
	m_Type = 0
	m_Mana = 0
	m_Hidx = 0
	ma_diff = 0
	ma_Prop = 0
	mp_mana = 0
	v_charge = 0
	mouse_pos = 0
	mouse_dist = 0
	looplooker = 0
	actionHold = 0
	ti_Tmr = create timer for 0 seconds
	ti_Tmr2 = create timer for 0 seconds
start
	//Initialize
	NMs_TotemState = NMs_STATEINITIAL
	//	Set comms values
	NMs_Running = NMs_TRUE
	NMs_TotemState = NMs_STATEIDLE
	
	m_Clicked = -1
	//get player 0 influence at hand position - number from 0-1, 0 = no influence to 1 bing within the influence
	run background script NMs_totemPeriodic
	//Main loop
	while (NMs_LoopControl == NMs_TRUE)
		//1 Idle state -> 2 (if hand is empty) / 3 (if miracle in hand) / nothing if backspace or hand becomes empty
		if(NMs_TotemState == NMs_STATEIDLE)
			//Look for action from player
			cnt = 0
			while((cnt < NMs_NUMMIRACLES) and (m_Clicked == -1))
				m_idx = cnt * NMs_MIR2D
				if((NMs_Miracles[m_idx + NMs_MIRSYMBOL] right clicked) or (NMs_Miracles[m_idx + NMs_MIRSYMBOL] left clicked))
					//A miracle has been clicked, check if the totem belongs to the player
					i_idx = NMs_Miracles[m_idx + NMs_MIRTOTEM] * NMs_TOT2D
					i_town = get town with id NMs_Totems[i_idx + NMs_TOTTOWNID]
					if(get i_town player == 0)
						//Player can use this miracle, collect some data
						m_Clicked = m_idx
						m_Type = NMs_Miracles[m_idx + NMs_MIRTYPE]
						m_Mana = NMs_Miracles[m_idx + NMs_MANA]
						mp_mana = get player 0 mana
						//Run mana charge, if needed
						if (mp_mana < m_Mana)
							NMs_ChargeLoop = NMs_TRUE
							run background script NMs_ChargeUpdate(m_Mana)
						end if
					end if
					clear right clicked object
					clear left clicked object
				end if
				cnt++
			end while
			//Miracle was clicked, now deal with mana and charge
			if(m_Clicked != -1)
				mp_mana = get player 0 mana
				if (mp_mana >= m_Mana)
					set player 0 mana (mp_mana - m_Mana)
					NMs_ChargeLoop = NMs_FALSE
					//Create miracle in hand
					run script NMs_CallHandCreateFunction(m_Clicked)
					NMs_TotemState = NMs_STATEHANDLED
				end if
				if ((bindable action BINDABLE_ACTION_TYPE_CANCEL_CURRENT_ACTION performed) or (key KB_BACKSPACE down) or (key KB_DELETE down))
					NMs_ChargeLoop = NMs_FALSE
					m_Clicked = -1
				end if
			end if
			
		//2 Miracle clicked with action -> Idle		
		elsif(NMs_TotemState == NMs_STATEHANDLED)
			//Loop solution
			looplooker = 0
			while(looplooker == 0)
				if ((bindable action BINDABLE_ACTION_TYPE_CANCEL_CURRENT_ACTION performed) or (key KB_BACKSPACE down) or (key KB_DELETE down))
					looplooker = 1
				end if
				if((bindable action BINDABLE_ACTION_TYPE_ACTION performed) and (get player 0 influence at hand position > 0.1))
					looplooker = 2
				end if
				
				//This check is needed, as sometimes the action button is missed. The reason for this is unknown.
				//	When the action button is clicked the object will fall and for a split second the hand state will read
				//	as HAND_STATE_CAN_PICKUP = 2. Thus if the hand can pick up and the neither action was done then assume the action
				//	button was clicked.
				if((variable get hand state == 2) and (looplooker == 0))
					looplooker = 2
				end if
			end while
			
			if (looplooker == 1)
				//Delete
				run script NMs_CallHandDeleteFunction(m_Clicked)
				//Go back to IDLE which will look for cast actions
				m_Clicked = -1
				//Give the mana back
				mp_mana = get player 0 mana
				set player 0 mana (mp_mana + m_Mana)
				NMs_TotemState = NMs_STATEIDLE
			elsif(looplooker == 2)
				set ti_Tmr time to 0.2 seconds
				set ti_Tmr2 time to 1 seconds
				//say "here"
				mouse_pos = marker at hand position
				NMs_TotemState = NMs_STATEACTIONWATCH
				i_idx = NMs_Miracles[m_Clicked + NMs_MIRTOTEM] * NMs_TOT2D
				p_casting = NMs_Totems[i_idx + NMs_TOTPWR]
			end if
			
		//3 Watch the action button to determine what the player is doing
		elsif(NMs_TotemState == NMs_STATEACTIONWATCH)
			//For pouring, the hand must remain in the same position			
			mouse_dist = get distance from hand position to {mouse_pos}
			if((mouse_dist > 5))
				//If movement to detected, reset timer
				set ti_Tmr time to 0.2 seconds
				mouse_pos = marker at hand position
			end if
			
			//We have to differentiate between throwing and pouring
			//If the action button is released it mush have been thrown
			if((not bindable action BINDABLE_ACTION_TYPE_ACTION performed)) //Released
				//Throwing
				run background script NMs_CallThrowFunction(m_Clicked,p_casting)
				m_Clicked = -1
				NMs_TotemState = NMs_STATEIDLE
			
			//If the timer runs out and the action button is still down, they must want to pour
			elsif((get ti_Tmr time remaining == 0) and (bindable action BINDABLE_ACTION_TYPE_ACTION performed))
				//Pouring
				//say "here"
				run script NMs_CallPourFunction(m_Clicked,p_casting)
				m_Clicked = -1
				NMs_TotemState = NMs_STATEIDLE
			end if
			
		end if
	end while

	//If  loop closes
	//	Set running value
	NMs_Running = NMs_FALSE
end script NMs_totemMain

//Used for creating a charge visual around the hand while waiting for the correct amount of mana
//	m_Mana - The needed amount of mana
begin script NMs_ChargeUpdate(m_Mana)
	ma_diff = 0
	mp_mana = 0
	ma_Prop = 0
	v_charge = 0
start
	v_charge = create visual effect VISUAL_EFFECT_MIRACLE_CHARGE at hand position time -1
	while (NMs_ChargeLoop == NMs_TRUE)
		mp_mana = get player 0 mana
		ma_diff = m_Mana - mp_mana
		ma_Prop = (-0.00125) * ma_diff + 1
		if(ma_Prop > 1)
			ma_Prop = 1
		end if
		if(ma_Prop < 0.1)
			ma_Prop = 0.1
		end if
		SCRIPT_OBJECT_PROPERTY_TYPE_SPEED of v_charge = ma_Prop
		SCRIPT_OBJECT_PROPERTY_TYPE_STRENGTH of v_charge = ma_Prop
		set v_charge position to hand position
	end while
	
	stop visual effect v_charge
	
end script NMs_ChargeUpdate

//Started by the main script, this will run periodic checks on the totems
//If a migration begins it'll take care of making the miracle transfers
//Every NMs_TOTPWRUPDATE seconds the powers of the totems are re-evaluated
begin script NMs_totemPeriodic
	ti = create timer for 0 seconds
	cnt = 0
	cnt2 = 0
	t_obj = 0
	t2_obj = 0
	mcnt = 0
	mig_prev = -1
	t3_obj = 0
	bs = 0
	tooly = 0
	t_ele = 0
	yPos = 0
	xPos = 0
	zPos = 0
	yCnt = 0
	m_ele = 0
start
	//Initialize migration tracker
	cnt = 0
	while (cnt < NMs_NUMBERTOTEM)
		NMs_Migrations[cnt] = 0
		cnt++
	end while

	while(NMs_LoopControl == NMs_TRUE)
		//---Migrations---
		if(NMs_Migrations[mcnt] == 0)
			t_obj = get town with id NMs_Totems[mcnt * NMs_TOT2D + NMs_TOTTOWNID]
			t2_obj = get town t_obj is migrating to
			if(t2_obj exists)
				cnt2 = 0
				t3_obj = 0
				//Locate totem belonging to this town which is being migrated towards
				while ((cnt2 < NMs_NUMBERTOTEM) and (t3_obj != t2_obj))
					t3_obj = get town with id NMs_Totems[cnt2 * NMs_TOT2D + NMs_TOTTOWNID]
					cnt2++
				end while
				if(t3_obj exists)
					run background script NMs_totemMigrate(mcnt,cnt2-1)
					NMs_Migrations[mcnt] = 1
				end if
			end if
		end if
		
		mcnt++
		if(mcnt >= NMs_NUMBERTOTEM)
			mcnt = 0
		end if
		
		//---Totem Powers---
		//Do to the amount of processing this will only occur once a minute
		if(get ti time remaining == 0)
			cnt = 0
			while (cnt < NMs_NUMBERTOTEM)
				//Recalculate population
				run script NMs_calculatePower(cnt)
				
				NMs_Totems[cnt * NMs_TOT2D + NMs_TOTPWR] = NMs_PowerResult
				//Update mana fire visual effects on totems
				bs = NMs_PowerResult * 0.1 + 0.1
				if(bs > 2)
					bs = 2
				end if
				SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[cnt * NMs_TOT2D + NMs_TOTV3] = bs
				SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[cnt * NMs_TOT2D + NMs_TOTV2] = bs
				
				//Recalculate the mana needed for each miracle
				cnt2 = 0
				while (cnt2 < NMs_NUMMIRACLES)
					if(NMs_Miracles[cnt2 * NMs_MIR2D + NMs_MIRTOTEM] == cnt)
						run script NMs_CalManaFunction(cnt2,cnt)
					end if
					cnt2++
				end while
				
				cnt++
			end while
			set ti time to NMs_TOTPWRUPDATE seconds
		end if
		
		
	end while
end script NMs_totemPeriodic

//This script watches the migration of the totem's town wating for it to be accepted
//	t_idx index of the totem who's town is migrate
//	tm_idx index of the totem who's town is being migrated to
begin script NMs_totemMigrate(t_idx,tm_idx)
	t_ele = t_idx * NMs_TOT2D
	tm_ele = tm_idx * NMs_TOT2D

	t_town = 0
	tm_town = 0
	
	m_cnt = 0
	m_ele = 0
start
	t_town = get town with id NMs_Totems[t_ele + NMs_TOTTOWNID]
	tm_town = get town with id NMs_Totems[tm_ele + NMs_TOTTOWNID]
	
	m_cnt = 0
	while (m_cnt < NMs_NUMMIRACLES)
		//Find and hide all miracles part of the migrating totem
		m_ele = m_cnt * NMs_MIR2D
		if(NMs_Miracles[m_ele + NMs_MIRTOTEM] == t_idx)
			//Call miracle hide function
			
			run script NMs_CallDeleteFunction(NMs_Miracles[m_ele + NMs_MIRTYPE],m_ele)
			NMs_Miracles[m_ele + NMs_VISIBLE] = 0
		end if
		m_cnt++
	end while
	
	stop visual effect NMs_Totems[t_ele + NMs_TOTV3]
	stop visual effect NMs_Totems[t_ele + NMs_TOTV2]
	
	//Wait until migration is accepted or dead
	wait until (variable get town t_town status == 3)
	
	//Add miracles to the tm_ele totem
	m_cnt = 0
	while (m_cnt < NMs_NUMMIRACLES)
		//Find and hide all miracles part of the migrating totem
		m_ele = m_cnt * NMs_MIR2D
		if(NMs_Miracles[m_ele + NMs_MIRTOTEM] == t_idx)
			//Call miracle hide function
			run script NMs_addMiracleToTotem(tm_idx,NMs_Miracles[m_ele + NMs_MIRTYPE],m_cnt)
			NMs_Miracles[m_ele + NMs_VISIBLE] = 1
		end if
		m_cnt++
	end while
end script NMs_totemMigrate

//------------------------------------------Interface----------------------------------------------
//Creates a totem at {x,z} the id of the town the miracle is gains its power from, index is the
//	miracle's key in the main array
//	No animations to its creation, it'll just pop into existance, as that is how our reality works
begin script NMs_createTotem(xPos,zPos,ang,townId,idx)
	yPos = 0
	twn = 0
	flr = NMs_FALSE
	t_ele = -1
	m_ele = 0
	cnt = 0
	
	v_x = 0
	v_z = 0
	
	tst = 0
start
	//Check Totem count hasn't passed the limit
	if(NMs_TotemCnt >= NMs_NUMBERTOTEM)
		flr = NMs_TRUE
	end if
	
	if(flr == NMs_FALSE)
		t_ele = NMs_TotemCnt * NMs_TOT2D
		m_ele = NMs_TotemCnt * NMs_MIRACLETYPES + (idx - 1)
		//Store miracle
		if(idx <= NMs_MIRACLETYPES)
			if(m_ele < NMs_TOTEMDEF2)
				NMs_TotemMiracle[m_ele] = 1
				NMs_Totems[t_ele + NMs_TOTCNT] = 1
				NMs_Totems[t_ele + NMs_TOTCNT2] = 1
			else
				//Error occured
			end if 
		else
			//ERROR: Miracle doesn't exist
			flr = NMs_TRUE
		end if
		//Store Town Id
		twn = get town with id townId
		if(twn exists)
			NMs_Totems[t_ele + NMs_TOTTOWNID] = townId
		else
			//ERROR: Town doesn't exist
			flr = NMs_TRUE
		end if
		
		if(flr == NMs_FALSE)
			//Construct object
			//Base is the creature statue base
			NMs_Totems[t_ele + NMs_TOTBASE] = create with angle ang and scale 1.5 SCRIPT_OBJECT_TYPE_FEATURE FEATURE_INFO_CREATURE_STATUE_BASE at {xPos,zPos}
			//A column above the base holds the miracle
			NMs_Totems[t_ele + NMs_TOTSTATUE] = create with angle ang and scale 1 SCRIPT_OBJECT_TYPE_FEATURE constant 2 at {xPos,zPos}
			
			//Switching the column to worshipping statue using mesh command, since there is no way to create that object -_-
			override mesh for NMs_Totems[t_ele + NMs_TOTSTATUE] with "..\features\m_towncentre_statue_worship"
			
			SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[t_ele + NMs_TOTSTATUE] = 2
			yPos = SCRIPT_OBJECT_PROPERTY_TYPE_YPOS of NMs_Totems[t_ele + NMs_TOTSTATUE]
			SCRIPT_OBJECT_PROPERTY_TYPE_YPOS of NMs_Totems[t_ele + NMs_TOTSTATUE] = yPos + 1.8
			
			disable NMs_Totems[t_ele + NMs_TOTSTATUE] hurt by fire
			disable NMs_Totems[t_ele + NMs_TOTBASE] hurt by fire
			
			enable NMs_Totems[t_ele + NMs_TOTSTATUE] indestructible
			enable NMs_Totems[t_ele + NMs_TOTBASE] indestructible
			
			//Fire Visual effect
			//Calculate x and z position
			v_x = xPos + (3 / NMs_MATHTHING) * cos(ang+27)
			v_z = zPos + (3 / NMs_MATHTHING) * sin(ang+27)
			yPos = land height at {xPos,zPos}
			
			NMs_Totems[t_ele + NMs_TOTV2] = create visual effect VISUAL_EFFECT_ALTER_MANA_FIRE at {v_x,yPos,v_z}+{0,12.5,0} time -1
			SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[t_ele + NMs_TOTV2] = 0.1
			
			v_x = xPos + (3 / NMs_MATHTHING) * cos(ang+153)
			v_z = zPos + (3 / NMs_MATHTHING) * sin(ang+153)
			NMs_Totems[t_ele + NMs_TOTV3] = create visual effect VISUAL_EFFECT_ALTER_MANA_FIRE at {v_x,yPos,v_z}+{0,12.5,0} time -1
			SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[t_ele + NMs_TOTV3] = 0.1
			
			//NMs_Totems[t_ele + NMs_TOTV1] = create visual effect VISUAL_EFFECT_SCRIPT_TARGET at {xPos,yPos,zPos}+{0,1,0} time -1
			//SCRIPT_OBJECT_PROPERTY_TYPE_SCALE of NMs_Totems[t_ele + NMs_TOTV1] = 1
			//set NMs_Totems[t_ele + NMs_TOTV1] colour red 20 green 100 blue 20
			
			//Create miracle
			run script NMs_CallCreateFunction(xPos,NMs_MIRACLEHEIGHT,zPos,idx,NMs_TotemCnt)
			NMs_TotemCnt++
		end if
	end if
end script NMs_createTotem

//------------------------------------------Low Level----------------------------------------------
//Add a miracle to a specific totem given by idx
//	miracleIdx = type of miracle
//	m_idx = if -1 a new miracle will be created
//			if != -1 it assumes the miracle with element m_idx exists and remakes it in the new position
begin script NMs_addMiracleToTotem(idx,miracleIdx,m_idx)
	t_ele = idx * NMs_TOT2D //NMs_Totems
	m_ele = idx * NMs_MIRACLETYPES + (miracleIdx - 1) //NMs_TotemMiracle
	crt = NMs_TRUE
	flr = NMs_FALSE
	
	//Calculation variables
	t_x = 0		//Totem x coords
	t_z = 0		//Totem z coords
	
	t_m = 0		//Count of independent miracles
	t_a = 0
	ang = 0		//Angle from totem's 0 based on how many miracles there are
	
	m_x = 0		//Final x coords
	m_y = 0		//Final y coords - assumes totem y is at 0
	m_z = 0		//Final z coords
start
	//1: Lets do some checks
	//has this totem reached its limit?
	if(NMs_Totems[t_ele + NMs_TOTCNT] > NMs_TOTMIRACLEMAX)
		
		flr = NMs_TRUE
	end if
	
	if(flr == NMs_FALSE)
		//does this totem already possess this miracle?
		if(NMs_TotemMiracle[m_ele] != 0)
			//We don't need two symbolic bubbles for the same miracle
			crt = NMs_FALSE
		end if
		
		if(crt == NMs_TRUE)
			//2: We will have to calculate the position of the new bubble
			//Get totem positions
			t_x = SCRIPT_OBJECT_PROPERTY_TYPE_XPOS of NMs_Totems[t_ele + NMs_TOTBASE]
			t_z = SCRIPT_OBJECT_PROPERTY_TYPE_ZPOS of NMs_Totems[t_ele + NMs_TOTBASE]
			t_a = SCRIPT_OBJECT_PROPERTY_TYPE_ANGLE of NMs_Totems[t_ele + NMs_TOTBASE]
			
			//Get the number of different miracles currently on the totem
			t_m = NMs_Totems[t_ele + NMs_TOTCNT2] - 1 //Subtract 1 for the main miracle
			NMs_Totems[t_ele + NMs_TOTCNT2]++
			
			//Calculate needed angle
			ang = t_a + (t_m * (360 / NMs_MIRPERROW))
			m_y = 5
			if((t_m > 6) and (t_m < 12))
				m_y = 10
			elsif((t_m >= 12) and (t_m < 18))
				m_y = 15
			end if
			
			//Calculate x and z position
			m_x = t_x + (8 / NMs_MATHTHING) * cos(ang)
			m_z = t_z + (8 / NMs_MATHTHING) * sin(ang)
			
			//Create miracle
			if(m_idx == -1)
				run script NMs_CallCreateFunction(m_x,m_y,m_z,miracleIdx,idx)
				m_idx = NMs_MiracleCount - 1
				if(m_idx < 0)
					m_idx = 0
				end if
				run script NMs_CalManaFunction(m_idx,idx)
			else
				run script NMs_MoveMiracleFunction(m_x,m_y,m_z,m_idx,idx)
				run script NMs_CalManaFunction(m_idx,idx)
			end if
		end if
		//Keep track of how many of this miracle there are for ratios later
		NMs_TotemMiracle[m_ele]++
	end if
end script NMs_addMiracleToTotem

//Takes the given index and calculates how many independent miracles there are
begin script NMs_calNumMiracles(t_idx)
	m_ele = t_idx * NMs_MIRACLETYPES
	cnt = 0
start
	NMs_IndepResult = 0
	while(cnt <= NMs_MIRACLETYPES)
		if(NMs_TotemMiracle[m_ele + cnt] > 0)
			NMs_IndepResult++
		end if
		cnt++
	end while
end script NMs_calNumMiracles

//Calculates the amount of power a miracle has based on the current state of the town the totem is connected to
//	Power is determined by the town's population
//		Float value 0 = 0 Villegers		1 = 100 Villegers
//		The number of miracles is taken into account and split equally among them
begin script NMs_calculatePower(idx)
	t_ele = idx * NMs_TOT2D
	o_town = 0	//Town object variable
	p_town = 0	//Population of town
	t_m = 0		//Count of independent miracles
	
	m = 0
start
	//Get Town and population
	o_town = get town with id NMs_Totems[t_ele + NMs_TOTTOWNID]
	if(o_town exists)
		p_town = size of o_town
		
		//Get the number of different miracles currently on the totem
		wait until (NMs_IndepLock == NMs_FALSE)
		NMs_IndepLock = NMs_TRUE
		run script NMs_calNumMiracles(idx)
		t_m = NMs_IndepResult
		NMs_IndepLock = NMs_FALSE //Unlock for other scripts
		
		m = 1 - (NMs_POWERMULT * (t_m - 1))
		if(m < 0.1)
			m = 0.1
		end if
		
		NMs_PowerResult = (p_town / NMs_POWERAT1) * m
	end if
end script NMs_calculatePower

//---------------------------------------COM Functions---------------------------------------------
//The following scripts will call specific functions in the miracle files
//Say the main script was to create a miracle, rather then having a large if statement there to
//	determine what function to call. Its clearer and easier to use when adding more custom miracles in
//	However it is slower as calling a script takes more time than an if statement.

//Depending on the idx value provided this script will call the createSymbolicBubble for any miracle
begin script NMs_CallCreateFunction(xPos, yPos, zPos, m_idx, t_idx)
	idx = 0
	m_type = 0
start
	idx = NMs_MiracleCount
	m_type = m_idx
	//Check calculated index
	if(idx < NMs_NUMMIRACLES)
		//Check the type we need to create
		if(m_type == NMs_WHEAT)
			run script NMsWheat_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			//Update miracle count
			NMsWheat_Count++
		elsif(m_type == NMs_FOREST)
			run script NMsFrst_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			NMsFrst_Count++
		elsif(m_type == NMs_ANIMALS)
			run script NMsAmls_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			NMsAmls_Count++
		elsif(m_type == NMs_ORE)
			run script NMsOre_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			NMsOre_Count++
		elsif(m_type == NMs_LIGHT)
			run script NMsLight_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			NMsLight_Count++
		elsif(m_type == NMs_LAVA)
			run script NMsLava_createSymbolicBubble(idx,xPos,yPos,zPos,t_idx)
			NMsLava_Count++
		else
			//No function to be called
			//	Best to throw error, this shouldn't happen
		end if
		NMs_MiracleCount++
	end if
end script NMs_CallCreateFunction

//Depending on the idx value provided this script will call the createSymbolicBubble for any miracle
//Unlike NMs_CallCreateFunction this one will not update the miracle counters
begin script NMs_MoveMiracleFunction(xPos, yPos, zPos, m_idx, t_idx)
	t_ele = t_idx * NMs_TOT2D
	m_ele = m_idx * NMs_MIR2D
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	elsif(m_type == NMs_ORE)
		run script NMsOre_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	elsif(m_type == NMs_LAVA)
		run script NMsLava_createSymbolicBubble(m_idx,xPos,yPos,zPos,t_idx)
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if

end script NMs_MoveMiracleFunction

//Depending on the [element] value provided this script will call the createMiracleInHand for any miracle
//Notice the element rather than the index like the previous two scripts
begin script NMs_CallHandCreateFunction(m_ele)
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_createMiracleInHand
		NMs_HandIdxResult = NMsWheat_HandResult
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_createMiracleInHand
		NMs_HandIdxResult = NMsFrst_HandResult
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_createMiracleInHand
		NMs_HandIdxResult = NMsAmls_HandResult
	elsif(m_type == NMs_ORE)
		run script NMsOre_createMiracleInHand
		NMs_HandIdxResult = NMsOre_HandResult
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_createMiracleInHand
		NMs_HandIdxResult = NMsLight_HandResult
	elsif(m_type == NMs_LAVA)
		run script NMsLava_createMiracleInHand
		NMs_HandIdxResult = NMsLava_HandResult
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if

end script NMs_CallHandCreateFunction

//Depending on the [element] value provided this script will call the deleteMiracleInHand for any miracle
//Notice the element rather than the index
//NMs_HandIdxResult is referenced not set, so make sure it is before calling this
begin script NMs_CallHandDeleteFunction(m_ele)
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_deleteMiracleInHand(NMs_HandIdxResult)
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_deleteMiracleInHand(NMs_HandIdxResult)
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_deleteMiracleInHand(NMs_HandIdxResult)
	elsif(m_type == NMs_ORE)
		run script NMsOre_deleteMiracleInHand(NMs_HandIdxResult)
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_deleteMiracleInHand(NMs_HandIdxResult)
	elsif(m_type == NMs_LAVA)
		run script NMsLava_deleteMiracleInHand(NMs_HandIdxResult)
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if

end script NMs_CallHandDeleteFunction

//Depending on the [element] value provided this script will call the CastPour for any miracle
//Notice the element rather than the index
//NMs_HandIdxResult is referenced not set, so make sure it is before calling this
begin script NMs_CallPourFunction(m_ele,pwr)
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		set NMsWheat_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsWheat_CastPour(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_FOREST)
		set NMsFrst_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsFrst_CastPour(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_ANIMALS)
		set NMsAmls_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsAmls_CastPour(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_ORE)
		set NMsOre_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsOre_CastPour(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_LIGHT)
		set NMsLight_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsLight_CastPour(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_LAVA)
		set NMsLava_Hand[NMs_HandIdxResult] in player 0 hand
		run script NMsLava_CastPour(pwr,NMs_HandIdxResult)
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if
end script NMs_CallPourFunction

//Depending on the [element] value provided this script will call the CastThrown for any miracle
//Notice the element rather than the index
//NMs_HandIdxResult is referenced not set, so make sure it is before calling this
begin script NMs_CallThrowFunction(m_ele,pwr)
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_CastThrown(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_CastThrown(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_CastThrown(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_ORE)
		run script NMsOre_CastThrown(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_CastThrown(pwr,NMs_HandIdxResult)
	elsif(m_type == NMs_LAVA)
		run script NMsLava_CastThrown(pwr,NMs_HandIdxResult)
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if
end script NMs_CallThrowFunction

//Depending on the idx value provided this script will call the deleteSymbolicBubble for any miracle
//	Used only when transferring miracles from one totem to another
//	However it is possible if a migration was to be distoried or denied than the miracle itself could be lost
//	Once gone its gone forever!
begin script NMs_CallDeleteFunction(t_idx, m_idx)
	m_type = 0
start
	m_type = t_idx
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_hideSymbolicBubble(m_idx)
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_hideSymbolicBubble(m_idx)
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_hideSymbolicBubble(m_idx)
	elsif(m_type == NMs_ORE)
		run script NMsOre_hideSymbolicBubble(m_idx)
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_hideSymbolicBubble(m_idx)
	elsif(m_type == NMs_LAVA)
		run script NMsLava_hideSymbolicBubble(m_idx)
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if
end script NMs_CallDeleteFunction

//Depending on the index value provided this script will call the calculateMana for any miracle
begin script NMs_CalManaFunction(m_idx, t_idx)
	t_ele = t_idx * NMs_TOT2D
	m_ele = m_idx * NMs_MIR2D
	m_type = 0
start
	m_type = NMs_Miracles[m_ele + NMs_MIRTYPE]
	//Check the type we need to create
	if(m_type == NMs_WHEAT)
		run script NMsWheat_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	elsif(m_type == NMs_FOREST)
		run script NMsFrst_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	elsif(m_type == NMs_ANIMALS)
		run script NMsAmls_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	elsif(m_type == NMs_ORE)
		run script NMsOre_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	elsif(m_type == NMs_LIGHT)
		run script NMsLight_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	elsif(m_type == NMs_LAVA)
		run script NMsLava_calculateMana(m_idx,NMs_Totems[t_ele + NMs_TOTPWR])
	else
		//No function to be called
		//	Best to throw error, this shouldn't happen
	end if

end script NMs_CalManaFunction

