#!/usr/bin/python1.5
# Abandon Ship script by Defiant <mail@defiant.homedns.org>
#
# Lisence: GPL - see README
#
# Version: 0.5

# Settings:
# ----------
# How much Pods for Radius = 1
PodsPerSize = 4


# Please do not edit below this line - except you know what you are doing
# ================================================================================

# Import all that stuff we need
import App 
import MissionLib 
import loadspacehelper
import math
import Lib.LibEngineering
import string
import Foundation

MODINFO = {     "Author": "\"Defiant\" erik@defiant.homedns.org",
                "Download": "http://defiant.homedns.org/~erik/STBC/AbandonShip/",
                "Version": "0.5",
                "License": "GPL",
                "Description": "Abandon Ship Script",
                "needBridge": 0
            }


# Vars
pPlayerOld = None
AS_TIMER1 = None
AS_END_SCENE_TIMER = None

# Red Alert, Abandon Ship now! -what todo:
def AbandonShip(pObject, pEvent): 
	#print("Abandon Ship")
	pShip = App.Game_GetCurrentPlayer()
	
	if ( pShip.GetHull().GetRadius() < 0.5 ):
		print("This Ship is to small - nothing to Abandon")
		return
	
	# First stop the Ship
	#import AI.Player.Stay
	#MissionLib.SetPlayerAI("Helm", AI.Player.Stay.CreateAI(pShip))
		
	# Play the sound
	pSound = App.TGSound_Create("sfx/Interface/new_game.wav", "AS_Sound", 0)
	pSound.SetSFX(0)
	pSound.SetInterface(1)
	App.g_kSoundManager.PlaySound("AS_Sound")

	# Start the Cutscene
	pSequence = App.TGSequence_Create ()

	pAction = App.TGScriptAction_Create("MissionLib", "StartCutscene")
	pSequence.AppendAction (pAction)

	pAction = App.TGScriptAction_Create("Actions.CameraScriptActions", "StartCinematicMode", 0)
	pSequence.AppendAction(pAction)	# Start cinematic mode first

	pAction	= App.TGScriptAction_Create("Actions.CameraScriptActions", "CutsceneCameraBegin", pShip.GetContainingSet().GetName ())
	pSequence.AppendAction(pAction)

	pAction = App.TGScriptAction_Create("Actions.CameraScriptActions", "DropAndWatch", pShip.GetContainingSet().GetName(), pShip.GetName ())
	pSequence.AppendAction(pAction)

	pSequence.Play()
	
	AbandonShipTimer(2, AS_TIMER1)


def StartAbandonShip(pObject, pEvent):
	global pPlayerOld, PodsPerSize
	
	# Some things we need
	pGame = App.Game_GetCurrentGame()
	pPlayer = pGame.GetPlayer()
	pSet = pPlayer.GetContainingSet()
	pShip = App.Game_GetCurrentPlayer()
	pMission = MissionLib.GetMission()
	pFriendlies = pMission.GetFriendlyGroup()
	sSetName = pSet.GetName()
	pPlayerOld = pPlayer
	itemp = None
	
	if (pShip.GetHull() == None):
		print("What? This Ship has no Hull? argh!")
		return

	# Creater Hull-Radius * 4 Escape Pods
	ShipSize = pShip.GetHull().GetRadius()
	CreateShipsNum = round(ShipSize, 0) * PodsPerSize
	#print(CreateShipsNum)

        # Get the Pod Model
        ShipType = GetShipType(pPlayer.GetName())
        if not ShipType:
            return
        FdtnShip = Foundation.shipList[ShipType]
        if not FdtnShip:
            return
        RaceName = FdtnShip.GetRace().name
        if (RaceName == "Federation"):
            if ShipLike(ShipType, "Defiant") or ShipLike(ShipType, "Intrepid") or ShipLike(ShipType, "Voyager") or ShipLike(ShipType, "yeager"):
                PodModel = "defpod"
            elif ShipLike(ShipType, "Galaxy") or ShipLike(ShipType, "Nebula"):
                PodModel = "Galaxy Escape Pod"
            else:
                PodModel = "EscapePod"
        elif (RaceName == "Klingon"):
            PodModel = "greenmisc"
        else:
            PodModel = "card pod"

        # Force standard Pod
        PodModel = "EscapePod"
        
        loadspacehelper.PreloadShip(PodModel, CreateShipsNum)

	# Choosing an Escape Pod for the Bridge Crew
	AS_BridgePod = round(App.g_kSystemWrapper.GetRandomNumber(CreateShipsNum), 0)
	if ( AS_BridgePod == 0 ):
		AS_BridgePod = 1
	#print("Bridge Pod is", AS_BridgePod)

	# Get the Players Location
	PlayerXpos = pShip.GetWorldLocation().GetX()
	PlayerYpos = pShip.GetWorldLocation().GetY()
	PlayerZpos = pShip.GetWorldLocation().GetZ()
	
	i = 1
	PodPosxyz = 1
	while (i <= CreateShipsNum):
		# Name of the Pod
		PodName = "Escape Pod " + str(i)
		# test if a Pod with this name already exists
		k = 10
		while ( MissionLib.GetShip(PodName) != None):
			# If its exists try another name (10+)
			itemp = i + k
			PodName = "Escape Pod " + str(itemp)
			k = 2*k
		#print("PodName is ", PodName)
		if itemp:
			i = itemp
			AS_BridgePod = i
		
		# Position Name of the Pod
		PodLaunchPoint = "PodLaunchPoint" + str(i)
		# Distance of Pods
		PodRadius = ShipSize
		# if PodRadius < 1 then the Game crashes, so fix
		if ( PodRadius < 1 ):
			PodRadius = 1

		# Create the Pod
		AS_EscapePod = loadspacehelper.CreateShip(PodModel, pSet, PodName, PodLaunchPoint)

                # Disable Collisions
                AS_EscapePod.EnableCollisionsWith(pShip, 0)
                AS_EscapePod.DisableCollisionDamage(1)
                i2 = i
                while (i2 >= 1):
                        if (i == 1):
                                break
                        AS_EscapePod.EnableCollisionsWith(MissionLib.GetShip("Escape Pod " + str(i2)), 0)
                        i2 = i2 - 1
                collisiondisable = 0

                # Position of the Pod
                kLocation = App.TGPoint3()
                i2 = 0
                while 1: # no do-while loop available in python, so looping tell infinity oo and breaking later.
                        # Random Numbers for Positions the Pods around the Ship
                        PodCoord1 = App.g_kSystemWrapper.GetRandomNumber(PodRadius*1000) / float(1000)
                        # Better don't guess what I made here - just one thing: I have to do sqrt(pow()) to make the number positive - everything else in this calc is the circle
                        PodCoord2 = App.g_kSystemWrapper.GetRandomNumber(int(math.sqrt(math.sqrt(math.pow(PodCoord1*PodCoord1-PodRadius*PodRadius, 2)))*1000)) / float(1000)

                        if (App.g_kSystemWrapper.GetRandomNumber(2) == 1):
                                PodCoord1 = PodCoord1 * -1
                        if (App.g_kSystemWrapper.GetRandomNumber(2) == 1):
                                PodCoord2 = PodCoord2 * -1
                        
                        # y =ħsqrt(x^2+z^2+r^2)
                        if (PodPosxyz == 1):
                                X = PodCoord1
                                Y = PodCoord2
                                Z = math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))
                        elif (PodPosxyz == 2):
                                X = PodCoord1
                                Y = PodCoord2
                                Z = -1 * math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))
                        elif (PodPosxyz == 3):
                                Z = PodCoord1
                                X = PodCoord2
                                Y = math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))
                        elif (PodPosxyz == 4):
                                Z = PodCoord1
                                X = PodCoord2
                                Y = -1 * math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))
                        elif (PodPosxyz == 5):
                                Y = PodCoord1
                                Z = PodCoord2
                                X = math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))
                        else:
                                Y = PodCoord1
                                Z = PodCoord2
                                X = -1 * math.sqrt(math.sqrt(math.pow(X*X+Y*Y-PodRadius*PodRadius, 2)))

                        kLocation.SetXYZ(X + PlayerXpos, Y + PlayerYpos, Z + PlayerZpos)

                        if pSet.IsLocationEmptyTG(kLocation, 0.5, 1): # go out of this loop here
                                #print("PodCoords: ", X, Y, Z)
                                collisiondisable = 1
                                break
                        #print("Correcting Position for " + PodName, X ,Y ,Z)
                        # i++
                        i2 = i2 + 1
                        if ( PodPosxyz == 6 ):
                                PodPosxyz = 0
                        PodPosxyz = PodPosxyz + 1
                        if (i2 > 10): # prevent from looping till the end of the universe, stop at 10
                                break

		#Now Position them
		AS_EscapePod.SetTranslate(kLocation)
		AS_EscapePod.UpdateNodeOnly()
		
		# If this is our Pod: welcome on Board
		if AS_BridgePod == i:
			#print("Welcome on Board of " + PodName + ", captain")
                        if App.g_kUtopiaModule.IsClient():
                                PlayerNetID = pPlayer.GetNetPlayerID()
                                AINetID = AS_EscapePod.GetNetPlayerID()
			pGame.SetPlayer(AS_EscapePod)
                        if App.g_kUtopiaModule.IsClient():
                                pPlayer.SetNetPlayerID(AINetID)
                                AS_EscapePod.SetNetPlayerID(PlayerNetID)
		else:
			## To Friendly Group
			#pFriendlies.AddName(PodName)
			# else set AI
                        AS_EscapePod.SetAI(Lib.LibEngineering.CreateFriendlyAI(AS_EscapePod))

                # re-enable Collisions
                if collisiondisable:
                        AS_EscapePod.DisableCollisionDamage(0)
                        AS_EscapePod.EnableCollisionsWith(pShip, 1)

		# i++
		i = i + 1
		if ( PodPosxyz != 6 ):
			PodPosxyz = PodPosxyz + 1
		else:
			PodPosxyz = 1

		# End While loop here
	
	AbandonShipTimer(2, AS_END_SCENE_TIMER)


def AS_End_Cutscene(pObject, pEvent):
	global pPlayerOld

	pShip = App.Game_GetCurrentPlayer()

	# End the Cutscene
	pSequence = App.TGSequence_Create ()

	pAction = App.TGScriptAction_Create("Actions.CameraScriptActions", "CutsceneCameraEnd", pShip.GetContainingSet().GetName())
	pSequence.AppendAction(pAction)

	pAction = App.TGScriptAction_Create("Actions.CameraScriptActions", "StopCinematicMode")
	pSequence.AppendAction(pAction)
	
	pAction = App.TGScriptAction_Create("MissionLib", "SetTarget", pPlayerOld.GetName())
	pSequence.AppendAction(pAction)
		
	pAction = App.TGScriptAction_Create("Actions.CameraScriptActions", "ChangeRenderedSet", "bridge")
	pSequence.AppendAction(pAction, 2) # Small 2 seconds Delay

	pAction = App.TGScriptAction_Create("MissionLib", "EndCutscene")
	pSequence.AppendAction(pAction)
	
	pSequence.Play()
	
	# set AI for the old Player to none
	pPlayerOld.ClearAI()

        # clear
        App.g_kSoundManager.DeleteSound("AS_Sound")

	#print("Abandon Ship is done - cu")


def AbandonShipTimer(iCountdown, iAction):
		# Create an event - it's a thing that will call this function
		pTimerEvent = App.TGEvent_Create()
		pTimerEvent.SetEventType(iAction)
		pTimerEvent.SetDestination(App.TopWindow_GetTopWindow())
					
		# Create a timer - it's a thing that will wait for a given time,then do something
		pTimer = App.TGTimer_Create()
		pTimer.SetTimerStart(App.g_kUtopiaModule.GetGameTime() + iCountdown)
		pTimer.SetDelay(0)
		pTimer.SetDuration(0)
		pTimer.SetEvent(pTimerEvent)
		App.g_kTimerManager.AddTimer(pTimer)


# Returns the Shiptype (from ReturnShuttles)
def GetShipType(ShipName):
        return string.split(MissionLib.GetShip(ShipName).GetScript(), '.')[-1]


# also from ReturnShuttles:
def ShipLike(ShipType, ShipLike):
    if (string.find(str(ShipType), ShipLike) != -1):
        return 1
    return 0


# lets create the Button now
def init():
    global AS_TIMER1, AS_END_SCENE_TIMER
    AS_TIMER1 = Lib.LibEngineering.GetEngineeringNextEventType()
    AS_END_SCENE_TIMER = Lib.LibEngineering.GetEngineeringNextEventType()
    Lib.LibEngineering.CreateMenuButton("Abandon Ship", "XO", __name__ + ".AbandonShip")
    App.TopWindow_GetTopWindow().AddPythonFuncHandlerForInstance(AS_TIMER1, __name__ + ".StartAbandonShip")
    App.TopWindow_GetTopWindow().AddPythonFuncHandlerForInstance(AS_END_SCENE_TIMER, __name__ + ".AS_End_Cutscene")
