# Written by
# questdevs Team

import sys
from java.util import Iterator
from com.l2jserver.util import Rnd
from com.l2jserver.gameserver.network.serverpackets import NpcSay
from com.l2jserver.gameserver.model.quest import State
from com.l2jserver.gameserver.model.quest import QuestState
from com.l2jserver.gameserver.model.quest import Quest as JQuest
from com.l2jserver import L2DatabaseFactory

qn = "503_PursuitClanAmbition"

# Items
# first part
G_Let_Martien = 3866
Th_Wyrm_Eggs = 3842
Drake_Eggs = 3841
Bl_Wyrm_Eggs = 3840
Mi_Drake_Eggs = 3839
Brooch = 3843
Bl_Anvil_Coin = 3871

# second Part
G_Let_Balthazar = 3867
Spiteful_Soul_Energy = 14855

# third part
G_Let_Rodemai = 3868
Imp_Keys = 3847
Scepter_Judgement = 3869

# the final item
Proof_Aspiration = 3870


EggList = [Mi_Drake_Eggs,Bl_Wyrm_Eggs,Drake_Eggs,Th_Wyrm_Eggs]

# NPC = Martien,Athrea,Kalis,Gustaf,Fritz,Lutz,Kurtz,Kusto,Balthazar,Rodemai,Coffer,Cleo
NPC=[30645,30758,30759,30760,30761,30762,30763,30512,30764,30868,30765,30766]
STATS=["cond","Fritz","Lutz","Kurtz","ImpGraveKeeper"]

# DROPLIST = step,chance,maxcount,item
# condition,maxcount,chance,itemList = DROPLIST[npcId]
DROPLIST = {
20282: [2,10,20,[Th_Wyrm_Eggs]],                    # Thunder Wyrm 1
20243: [2,10,15,[Th_Wyrm_Eggs]],                    # Thunder Wyrm 2
20137: [2,10,20,[Drake_Eggs]],                      # Drake 1
20285: [2,10,25,[Drake_Eggs]],                      # Drake 2
27178:[2,10,100,[Bl_Wyrm_Eggs]],                    # Blitz Wyrm
20974: [5,10,20,[Spiteful_Soul_Energy,14856]],      # Spiteful Soul Leader
20668: [10,0,15,[]],                                # Grave Guard
27179:[10,6,80,[Imp_Keys]],                         # GraveKeyKeeper
27181:[10,0,100,[]]                                 # Imperial Gravekeeper
}

def suscribe_members(st) :
  clan=st.getPlayer().getClan().getClanId()
  try :
    con=L2DatabaseFactory.getInstance().getConnection()
    offline=con.prepareStatement("SELECT charId FROM characters WHERE clanid=? AND online=0")
    offline.setInt(1, clan)
    rs=offline.executeQuery()
    while (rs.next()) :
      charId=rs.getInt("charId")
      try :
        insertion = con.prepareStatement("REPLACE INTO character_quests (charId,name,var,value) VALUES (?,?,?,?)") #[JOJO] modify "INSERT" to "REPLACE"
        insertion.setInt(1, charId)
        insertion.setString(2, qn)
        insertion.setString(3, "<state>")
        insertion.setString(4, "Started")
        insertion.executeUpdate()
      finally :
        try : insertion.close()
        except : pass
  finally :
    L2DatabaseFactory.close(con) #[JOJO]

def offlineMemberExit(st) :
  clan=st.getPlayer().getClan().getClanId()
  try :
    con=L2DatabaseFactory.getInstance().getConnection()
    offline=con.prepareStatement("DELETE FROM character_quests WHERE name = ? and charId IN (SELECT charId FROM characters WHERE clanId =? AND online=0")
    offline.setString(1, qn)
    offline.setInt(2, clan)
    offline.executeUpdate()
    offline.close()
  finally :
    L2DatabaseFactory.close(con) #[JOJO]

# returns leaders quest cond, if he is offline will read out of database :)
def getLeaderVar(st, var) :
  try :
    clan = st.getPlayer().getClan()
    if clan == None:
      return -1
    leader=clan.getLeader().getPlayerInstance()
    if leader != None :
      return int(leader.getQuestState(qn).get(var))
  except :
    pass
  leaderId=st.getPlayer().getClan().getLeaderId()
  val=-1
  try :
    con=L2DatabaseFactory.getInstance().getConnection()
    offline=con.prepareStatement("SELECT value FROM character_quests WHERE charId=? AND var=? AND name=?")
    offline.setInt(1, leaderId)
    offline.setString(2, var)
    offline.setString(3, qn)
    rs=offline.executeQuery()
    if rs.next() :
      val=int(rs.getInt("value"))
  finally :
    L2DatabaseFactory.close(con) #[JOJO]
  return val

# set's leaders quest cond, if he is offline will read out of database :)
# for now, if the leader is not logged in, this assumes that the variable
# has already been inserted once (initialized, in some sense).
def setLeaderVar(st, var, value) :
  clan = st.getPlayer().getClan()
  if clan == None: return
  leader=clan.getLeader().getPlayerInstance()
  if leader != None :
    leader.getQuestState(qn).set(var,value)
  else :
    leaderId=st.getPlayer().getClan().getLeaderId()
    try :
      con=L2DatabaseFactory.getInstance().getConnection()
      offline=con.prepareStatement("UPDATE character_quests SET value=? WHERE charId=? AND var=? AND name=?")
      offline.setString(1, value)
      offline.setInt(2, leaderId)
      offline.setString(3, var)
      offline.setString(4, qn)
      offline.executeUpdate()
      offline.close()
    finally :
      L2DatabaseFactory.close(con) #[JOJO]
  return

def checkEggs(st):
  count = 0
  for item in EggList:
    if st.getQuestItemsCount(item) > 9:
      count+=1
  if count > 3 :
    return 1
  else:
    return 0

def giveItem(item,maxcount,st):
  count = st.getQuestItemsCount(item)
  if count < maxcount:
    st.giveItems(item,1)
    if count == maxcount-1:
      st.playSound("ItemSound.quest_middle")
    else:
      st.playSound("ItemSound.quest_itemget")
  return

def exit503(completed,st):
    if completed:
      st.giveItems(Proof_Aspiration,1)
      st.addExpAndSp(0,250000)
      for var in STATS:
        st.unset(var)
      st.exitQuest(False)
    else:
      st.exitQuest(1)
    st.takeItems(Scepter_Judgement,-1)
    try:
      members = st.getPlayer().getClan().getOnlineMembers(0)
      for i in members:
        st.getPlayer().getClan().getClanMember(i).getPlayerInstance().getQuestState(qn).exitQuest(1)
      offlineMemberExit(st)
    except:
      return "You dont have any members in your Clan, so you can't finish the Pursuit of Aspiration"
    return "Congratulations, you have finished the Pursuit of Clan Ambition"

class Quest (JQuest) :

  def __init__(self,id,name,descr):
    JQuest.__init__(self,id,name,descr)
    self.questItemIds = range(3838,3848)+range(3866,3870)+[3871,14854,14855,14856] #[JOJO]
  # self.questItemIds = range(3839,3848)+range(3866,3870)
    self.ImpGraveKepperStat = 1

  def onEvent (self,event,st) :
    htmltext = event
# Events Gustaf
    if event == "30760-08.htm" :
      st.giveItems(G_Let_Martien,1)
      for var in STATS:
        st.set(var,"1")
      st.setState(State.STARTED)
    elif event == "30760-12.htm" :
      st.giveItems(G_Let_Balthazar,1)
      st.set("cond","4")
    elif event == "30760-16.htm" :
      st.giveItems(G_Let_Rodemai,1)
      st.set("cond","7")
    elif event == "30760-20.htm" :
      exit503(1,st)
    elif event == "30760-22.htm" :
      st.set("cond","13")
    elif event == "30760-23.htm" :
      exit503(1,st)
# Events Martien
    elif event == "30645-03.htm":
      st.takeItems(G_Let_Martien,-1)
      st.set("cond","2")
      suscribe_members(st)
      try:
        members = st.getPlayer().getClan().getOnlineMembers(0)
        for i in members:
          pst = QuestManager.getInstance().getQuest(qn).newQuestState(st.getPlayer().getClan().getClanMember(int(i)).getPlayerInstance())
          pst.setState(State.STARTED)
      except:
        return htmltext
# Events Kurtz
    elif event == "30763-03.htm":
      if st.getInt("Kurtz") == 1:
        htmltext = "30763-02.htm"
        st.giveItems(Mi_Drake_Eggs,6)
        st.giveItems(Brooch,1)
        st.set("Kurtz","2")
# Events Lutz
    elif event == "30762-03.htm":
      lutz = st.getInt("Lutz")
      if lutz == 1:
        htmltext = "30762-02.htm"
        st.giveItems(Mi_Drake_Eggs,4)
        st.giveItems(Bl_Wyrm_Eggs,3)
        st.set("Lutz","2")
      st.addSpawn(27178,65170,109503,-3671,120000)
      st.addSpawn(27178,65219,109463,-3676,120000)
# Events Fritz
    elif event == "30761-03.htm":
      fritz = st.getInt("Fritz")
      if fritz == 1:
        htmltext = "30761-02.htm"
        st.giveItems(Bl_Wyrm_Eggs,3)
        st.set("Fritz","2")
      st.addSpawn(27178,64728,115954,-3628,120000)
      st.addSpawn(27178,64763,115871,-3631,120000)
# Events Kusto
 #  elif event == "30512-03.htm":  #[JOJO] onTalkに移動
 #    st.takeItems(Brooch,-1)
 #    st.giveItems(Bl_Anvil_Coin,1)
 #    st.set("Kurtz","3")
# Events Balthazar
    elif event == "30764-03.htm":
      st.takeItems(G_Let_Balthazar,-1)
      st.set("cond","5")
 #    st.set("Kurtz","3") #-[JOJO]
 #  elif event == "30764-05.htm":  #[JOJO] if "30764-06.htm" に移動
 #    st.takeItems(G_Let_Balthazar,-1)
 #    st.set("cond","5")
    elif event == "30764-06.htm":
      #[JOJO]-------------------------------------------------
      st.takeItems(G_Let_Balthazar,-1) #+[JOJO]
      st.set("cond","5") #+[JOJO]
      if st.getQuestItemsCount(Bl_Anvil_Coin):
        st.giveItems(14854,1) #製作書：スパイト ソウル エナジー (未実装)
      # st.giveItems(3838,1)  #製作図：巨人の動力装置(25%) (未実装)
      #-------------------------------------------------------

      st.takeItems(Bl_Anvil_Coin,-1)
      st.set("Kurtz","4")
# Events Rodemai
    elif event == "30868-04.htm":
      st.takeItems(G_Let_Rodemai,-1)
      st.set("cond","8")
    elif event == "30868-06a.htm":
      st.set("cond","10")
    elif event == "30868-10.htm":
      st.set("cond","12")
# Events Cleo
    elif event == "30766-04.htm":
      st.set("cond","9")
      spawnedNpc=st.addSpawn(30766,160622,21230,-3710,90000)
      spawnedNpc.broadcastPacket(NpcSay(spawnedNpc.getObjectId(),0,spawnedNpc.getId(),50338)) #"Blood and Honour."
      spawnedNpc=st.addSpawn(30759,160665,21209,-3710,90000)
      spawnedNpc.broadcastPacket(NpcSay(spawnedNpc.getObjectId(),0,spawnedNpc.getId(),50341)) #"Ambition and Power"
      spawnedNpc=st.addSpawn(30758,160665,21291,-3710,90000)
      spawnedNpc.broadcastPacket(NpcSay(spawnedNpc.getObjectId(),0,spawnedNpc.getId(),50340)) #"War and Death"
    elif event == "30766-08.htm":
      #[JOJO]-------------------------------------------------
      exit503(1,st)
      #-------------------------------------------------------
    return htmltext


  def onTalk (self,npc,player):
    htmltext = Quest.getNoQuestMsg(player)
    st = player.getQuestState(qn)
    if not st : return htmltext

    npcId = npc.getId()
    id = st.getState()
    if npcId != NPC[3] and id == State.CREATED : return htmltext

    Martien,Athrea,Kalis,Gustaf,Fritz,Lutz,Kurtz,Kusto,Balthazar,Rodemai,Coffer,Cleo = 30645,30758,30759,30760,30761,30762,30763,30512,30764,30868,30765,30766
    isLeader = player.isClanLeader()
    if id == State.CREATED and npcId == Gustaf:
      for var in STATS:                                  # adds all the  vars for initialisation
        st.set(var,"0")
      if player.getClan():                            # has Clan
        if isLeader:                                  # check if player is clan leader
          clanLevel = player.getClan().getLevel()
          if st.getQuestItemsCount(Proof_Aspiration):                  # if he has the proof already, tell him what to do now
            htmltext = "30760-03.htm"
            st.exitQuest(1)
          elif clanLevel == 4:                     # if clanLevel == 4 you can take this quest, because repeatable
            htmltext = "30760-04.htm"
          else:                                    # if clanLevel is too low or too high you cant take it
            htmltext = "30760-02.htm"
            st.exitQuest(1)
        else:                                      # player isnt a leader
          htmltext = "30760-04t.htm"
          st.exitQuest(1)
      else:                                        # no Clan
        htmltext = "30760-01.htm"
        st.exitQuest(1)
      return htmltext
    elif player.getClan() and player.getClan().getLevel() >= 5:        # player has level 5 clan already
      return Quest.getAlreadyCompletedMsg(player)

    elif id == State.COMPLETED:                                  # player has proof, and has finished quest as leader
      #[JOJO]-------------------------------------------------
      if npcId == Gustaf and st.getQuestItemsCount(Proof_Aspiration):                  # if he has the proof already, tell him what to do now
        return "30760-03.htm"
      #-------------------------------------------------------
      return Quest.getAlreadyCompletedMsg(player)

    else:
      ######## Leader Area ######
      if isLeader:
        cond   = st.getInt("cond")
        kurtz  = st.getInt("Kurtz")
        lutz  = st.getInt("Lutz")
        fritz  = st.getInt("Fritz")

        if npcId == Gustaf :
          if cond == 1:
            htmltext = "30760-09.htm"
          elif cond == 2:
            htmltext = "30760-10.htm"
          elif cond == 3:
            htmltext = "30760-11.htm"
          elif cond == 4:
            htmltext = "30760-13.htm"
          elif cond == 5:
            htmltext = "30760-14.htm"
          elif cond == 6:
            htmltext = "30760-15.htm"
          elif cond == 7:
            htmltext = "30760-17.htm"
          elif cond == 12:
            htmltext = "30760-19.htm"
          elif cond == 13:
            htmltext = "30760-24.htm"
          else:
            htmltext = "30760-18.htm"
        elif npcId == Martien :
          if cond == 1:
            htmltext = "30645-02.htm"
          elif cond == 2:
            if checkEggs(st) and kurtz > 1 and lutz > 1 and fritz > 1:
              htmltext = "30645-05.htm"
              st.set("cond","3")
              for item in EggList:
                st.takeItems(item,-1)
            else:
              htmltext = "30645-04.htm"
          elif cond == 3:
            htmltext = "30645-07.htm"
          else:
            htmltext = "30645-08.htm"
        #[JOJO]-------------------------------------------------
        elif npcId == Lutz:
          if cond == 2:                        # Dwarven Corpse in DV, only needed if condition is 2
            htmltext = "30762-01.htm"
        elif npcId == Kurtz:
          if cond == 2:                        # Dwarven Corpse in DV, only needed if condition is 2
            if kurtz == 1:
              htmltext = "30763-01.htm"
            else:
              htmltext = "30763-03.htm"
        elif npcId == Fritz:
          if cond == 2:                        # Dwarven Corpse in DV, only needed if condition is 2
            htmltext = "30761-01.htm"
        #-------------------------------------------------------
        elif npcId == Kusto:
          #[JOJO]-------------------------------------------------
          if cond >= 2 and cond <= 5:
            if kurtz == 1:
              htmltext = "30512-01.htm"
            elif kurtz == 2:
              htmltext = "30512-02.htm"
              st.takeItems(Brooch,-1)
              st.giveItems(Bl_Anvil_Coin,1)
              st.set("Kurtz","3")
            elif kurtz == 3:
              htmltext = "30512-04.htm"
            elif kurtz == 4:
              htmltext = "30512-04.htm"
          #-------------------------------------------------------
          return htmltext
        elif npcId == Balthazar:
          if cond == 4:
            if kurtz > 2:
              htmltext = "30764-04.htm"
            else:
              htmltext = "30764-02.htm"
          elif cond == 5:
            if st.getQuestItemsCount(Spiteful_Soul_Energy) >= 10 :
              htmltext = "30764-08.htm"
              st.takeItems(Spiteful_Soul_Energy,-1)
              st.takeItems(Brooch,-1)
              st.takeItems(14854,-1) #製作書：スパイト ソウル エナジー (未実装)
              st.takeItems(3838,-1)  #製作図：巨人の動力装置(25%) (未実装)
              st.set("cond","6")
            else:
              htmltext = "30764-07.htm"
          elif cond == 6:
            htmltext = "30764-09.htm"
        elif npcId == Rodemai:
          if cond == 7:
            htmltext = "30868-02.htm"
          elif cond == 8:
            htmltext = "30868-05.htm"
          elif cond == 9:
            htmltext = "30868-06.htm"
          elif cond == 10:
            htmltext = "30868-08.htm"
          elif cond == 11:
            htmltext = "30868-09.htm"
          elif cond == 12:
            htmltext = "30868-11.htm"
        elif npcId == Cleo:
          if cond == 8:
            htmltext = "30766-02.htm"
          elif cond == 9:
            htmltext = "30766-05.htm"
          elif cond == 10:
            htmltext = "30766-06.htm"
          elif cond in [11,12,13]:
            htmltext = "30766-07.htm"
        elif npcId == Coffer:
          if st.getInt("cond") == 10:
            if st.getQuestItemsCount(Imp_Keys) < 6:
              htmltext = "30765-03a.htm"
            elif st.getInt("ImpGraveKeeper") == 3:
              htmltext = "30765-02.htm"
              st.set("cond","11")
              st.takeItems(Imp_Keys,6)
              st.giveItems(Scepter_Judgement,1)
            else:
              htmltext = "<html><body>(You and your Clan didn't kill the Imperial Gravekeeper by your own, go and try again.)</body></html>"
          else:
              htmltext = "<html><body>(You already have the Scepter of Judgement.)</body></html>"
        elif npcId == Kalis:
          htmltext = "30759-01.htm"
        elif npcId == Athrea:
          htmltext = "30758-01.htm"
        return htmltext
      ######## Member Area ######
      else:
        cond = getLeaderVar(st,"cond")
        if npcId == Martien and cond in [1,2,3]:
          htmltext = "30645-01.htm"
        elif npcId == Rodemai :
          if cond in [9,10]:
            htmltext = "30868-07.htm"
          elif cond == 7:
            htmltext = "30868-01.htm"
        elif npcId == Balthazar and cond == 4:
          htmltext = "30764-01.htm"
        elif npcId == Cleo and cond == 8:
          htmltext = "30766-01.htm"
        elif npcId == Kusto and 6 > cond > 2:
          htmltext = "30512-01a.htm"
        elif npcId == Coffer and cond == 10:
          htmltext = "30765-01.htm"
        elif npcId == Gustaf:
          if cond == 3:
            htmltext = "30760-11t.htm"
          elif cond == 4:
            htmltext = "30760-15t.htm"
          elif cond == 12:
            htmltext = "30760-19t.htm"
          elif cond == 13:
            htmltext = "30766-24t.htm"
        return htmltext

  def onAttack(self, npc, player, damage, isPet, skill):
  # npdId = npc.getId()
    if (npc.getMaxHp()/2) > npc.getCurrentHp():
      if Rnd.get(100) < 4:
        if self.ImpGraveKepperStat == 1:
          for j in range(2):
            for k in range(2):
              self.addSpawn(27180,npc.getX()+70*pow(-1,j%2),npc.getY()+70*pow(-1,k%2),npc.getZ(),0,False,0)
          self.ImpGraveKepperStat = 2
        else:
          players = npc.getKnownList().getKnownPlayers().values().toArray()
          if len(players) :
            playerToTP = players[Rnd.get(int(len(players)))]
            playerToTP.teleToLocation(185462,20342,-3250)
    return

  def onKill(self,npc,player,isPet):
    # all kill events triggered by the leader occur automatically.
    # However, kill events that were triggered by members occur via the leader and
    # only if the leader is online and within a certain distance!
    leader_st = 0
    if player.isClanLeader() :
      leader_st = player.getQuestState(qn)
    else :
      clan = player.getClan()
      if clan:
        c_leader=clan.getLeader()
        if c_leader:
           leader=c_leader.getPlayerInstance()
           if leader :
             if player.isInsideRadius(leader, 1600, 1, 0) :
               leader_st = leader.getQuestState(qn)
    if leader_st :
      if leader_st.getState() != State.STARTED : return
      npcId=npc.getId()
      condition,maxcount,chance,itemList = DROPLIST[npcId]
      random = self.getRandom(100)
      cond = leader_st.getInt("cond")
      if cond == condition and random < chance:
        #[JOJO]-------------------------------------------------
        if npcId == 20974: # スパイト ソウル リーダー --> スパイト ソウル エナジー
          if leader_st.getInt("Kurtz") >= 4: #14854 製作書：スパイト ソウル エナジー
            item = 14855 #スパイト ソウル エナジー
          else:
            item = itemList[self.getRandom(2)]
            #14855 スパイト ソウル エナジー
            #14856 ブロークン スパイト ソウル エナジー
          giveItem(item,maxcount,leader_st)
        #-------------------------------------------------------
        elif len(itemList) :
          giveItem(itemList[0],maxcount,leader_st)
        else:
          if npcId == 27181:                # Imperial Gravekeeper
            spawnedNpc=leader_st.addSpawn(30765,120000)
            npc.broadcastPacket(NpcSay(spawnedNpc.getObjectId(),0,spawnedNpc.getId(),50339)) #"Curse of the gods on the one that defiles the property of the empire!"
            leader_st.set("ImpGraveKeeper","3")
            self.ImpGraveKepperStat = 1
          else:
            leader_st.addSpawn(27179)
    return

QUEST     = Quest(503,qn,"Pursuit of Clan Ambition")

QUEST.addStartNpc(NPC[3])

for npcId in NPC:
  QUEST.addTalkId(npcId)

for mobId in DROPLIST.keys():
  QUEST.addKillId(mobId)

QUEST.addAttackId(27181)