//****************************************************************************
// SPHERE by : Menasoft ©1997-2019
// www.sphereserver.net
// All SPHERE script files and formats are copyright Menasoft & Partners.
// This file may be freely edited for personal use, but may not be distributed
// in whole or in part, in any format without express written permission from
// Menasoft & Partners.  All donations and contributions
// become the property of Menasoft & Partners.
//****************************************************************************
// FILE LAST UPDATED: Tuesday, Dec 10, 2019
//
VERSION=0.56d

[DEFNAME TreasureMap_Settings]
TreasureMap_L1_Cartography	27.0
TreasureMap_L1_Lockpicking	36.0
TreasureMap_L1_Guardians	{c_mongbat 1 c_ratman 1 c_headless 1 c_skeleton 1 c_zombie 1}

TreasureMap_L2_Cartography	71.0
TreasureMap_L2_Lockpicking	76.0
TreasureMap_L2_Guardians	{c_orc_mage 1 c_gargoyle 1 c_gazer 1 c_hellhound 1 c_elemental_earth 1}

TreasureMap_L3_Cartography	81.0
TreasureMap_L3_Lockpicking	84.0
TreasureMap_L3_Guardians	{c_lich 1 c_ogre_lord 1 c_spider_dread 1 c_elemental_air 1 c_elemental_fire 1}

TreasureMap_L4_Cartography	91.0
TreasureMap_L4_Lockpicking	92.0
TreasureMap_L4_Guardians	{c_spider_dread 1 c_lich_lord 1 c_demon 1 c_gazer_elder 1 c_ogre_lord 1}

TreasureMap_L5_Cartography	100.0
TreasureMap_L5_Lockpicking	100.0
TreasureMap_L5_Guardians	{c_lich_lord 1 c_demon 1 c_gazer_elder 1 c_elemental_poison 1 c_elemental_blood 1}

// On OSI publish 67 (client 7.0.8.0), treasure maps got updated to have treasures
// on all facets instead only Felucca/Trammel. The treasure location always points
// to random locations on the facet where it got created. But previous clients can
// only draw maps on Felucca/Trammel. To make this script compatible with all type
// of servers, it comes with only Felucca enabled and if the map get created on an
// disabled facet it will also fallback to Felucca.
// If your server uses others facets and also an client version that supports this
// feature, use the settings below to enable treasure maps on these facets.
TreasureMap_Facet0		1 // Felucca
TreasureMap_Facet1		0 // Trammel
TreasureMap_Facet2		0 // Ilshenar
TreasureMap_Facet3		0 // Malas
TreasureMap_Facet4		0 // Tokuno Islands
TreasureMap_Facet5		0 // Ter Mur

///////////
// Items //
///////////

[ITEMDEF i_ttm_l1]
ID=i_map_blank
NAME=Tattered, Plainly Drawn Treasure Map
TYPE=t_map
TDATA1=300	//map width
TDATA2=300	//map height
TDATA3=1	//map level
TEVENTS=t_map_treasure

CATEGORY=Maps - Treasure
SUBSECTION=Maps
DESCRIPTION=Level 1 (Plainly Drawn)

ON=@Create
TIMERF 1,TreasureMap_SetRandomLocation

[ITEMDEF i_ttm_l2]
ID=i_map_blank
NAME=Tattered, Expertly Drawn Treasure Map
TYPE=t_map
TDATA1=300	//map width
TDATA2=300	//map height
TDATA3=2	//map level
TEVENTS=t_map_treasure

CATEGORY=Maps - Treasure
SUBSECTION=Maps
DESCRIPTION=Level 2 (Expertly Drawn)

ON=@Create
TIMERF 1,TreasureMap_SetRandomLocation

[ITEMDEF i_ttm_l3]
ID=i_map_blank
NAME=Tattered, Adeptly Drawn Treasure Map
TYPE=t_map
TDATA1=300	//map width
TDATA2=300	//map height
TDATA3=3	//map level
TEVENTS=t_map_treasure

CATEGORY=Maps - Treasure
SUBSECTION=Maps
DESCRIPTION=Level 3 (Adeptly Drawn)

ON=@Create
TIMERF 1,TreasureMap_SetRandomLocation

[ITEMDEF i_ttm_l4]
ID=i_map_blank
NAME=Tattered, Cleverly Drawn Treasure Map
TYPE=t_map
TDATA1=300	//map width
TDATA2=300	//map height
TDATA3=4	//map level
TEVENTS=t_map_treasure

CATEGORY=Maps - Treasure
SUBSECTION=Maps
DESCRIPTION=Level 4 (Cleverly Drawn)

ON=@Create
TIMERF 1,TreasureMap_SetRandomLocation

[ITEMDEF i_ttm_l5]
ID=i_map_blank
NAME=Tattered, Deviously Drawn Treasure Map
TYPE=t_map
TDATA1=300	//map width
TDATA2=300	//map height
TDATA3=5	//map level
TEVENTS=t_map_treasure

CATEGORY=Maps - Treasure
SUBSECTION=Maps
DESCRIPTION=Level 5 (Deviously Drawn)

ON=@Create
TIMERF 1,TreasureMap_SetRandomLocation

[ITEMDEF i_chest_treasure]
ID=i_chest_metal_brass
NAME=Treasure Chest

ON=@Create
ATTR=attr_move_never

ON=@PickUp_Self
SRC.TARGPRV=04fffffff
SRC.REVEAL
IF (10 >= <R100>)
 TreasureMap_SpawnGuardians
ENDIF

ON=@DropOn_Self
IF !(<SRC.ISGM>)
 SRC.SYSMESSAGE @08a5 The chest refuses to be filled with treasure again.
 return 1
ENDIF

ON=@ContextMenuRequest
IF (<SRC> == <LINK>) || (<SRC.ISGM>)
 SRC.AddContextEntry 200,6149	//Remove Chest
ENDIF

ON=@ContextMenuSelect
IF (<ARGN> == 200)
 IF (<SRC> == <LINK>) || (<SRC.ISGM>)
  SDIALOG d_treasure_chest_remove
 ENDIF
ENDIF

////////////
// Events //
////////////

[TYPEDEF t_map_treasure]
ON=@DClick
IF (<TOPOBJ> != <SRC>)
 SRC.SYSMESSAGE <DEFMSG.reach_fail>
 return 1
ELIF !(<MORE1>)
 TreasureMap_Decode
 return 1
ELIF (<TreasureMap_CanDig>)
 TreasureMap_Dig
 return 1
ENDIF
MESSAGE The treasure is marked by the red pin. Grab a shovel and go dig it up!
return 0

ON=@ClientToolTip
IF (<MOREM> == 0)
 SRC.ADDCLILOC 1041502	//for somewhere in Felucca
ELIF (<MOREM> == 1)
 SRC.ADDCLILOC 1041503	//for somewhere in Trammel
ELIF (<MOREM> == 2)
 SRC.ADDCLILOC 1060850	//for somewhere in Ilshenar
ELIF (<MOREM> == 3)
 SRC.ADDCLILOC 1060851	//for somewhere in Malas
ELIF (<MOREM> == 4)
 SRC.ADDCLILOC 1115645	//for somewhere in Tokuno Islands
ELIF (<MOREM> == 5)
 SRC.ADDCLILOC 1115646	//for somewhere in Ter Mur
ENDIF

ON=@ContextMenuRequest
IF !(<MORE1>)
 SRC.AddContextEntry 120,6147,<QVAL (<TOPOBJ> == <SRC>)? 0:1>	//Decode Map
ELSE
 SRC.AddContextEntry 121,6148,<QVAL (<TOPOBJ> == <SRC>)? 0:1>	//Dig For Treasure
ENDIF

ON=@ContextMenuSelect
IF (<TOPOBJ> != <SRC>)
 return 1
ELIF (<ARGN> == 120)
 IF !(<MORE1>)
  TreasureMap_Decode
 ENDIF
ELIF (<ARGN> == 121)
 IF (<TreasureMap_CanDig>)
  TreasureMap_Dig
 ENDIF
ENDIF

///////////////
// Functions //
///////////////

[FUNCTION TreasureMap_Decode]
IF (<SRC.CARTOGRAPHY> < <DEF0.TreasureMap_L<TDATA3>_Cartography>)
 SRC.MESSAGE The map is too difficult to attempt to decode.
 return 1
ENDIF
SRC.MESSAGE You successfully decode a treasure map!
TYPE=t_map
NAME=<STREAT <NAME>>
RESENDTOOLTIP
LOCAL.Radius=<eval <TreasureMap_GetFacetRadius>/2>
LOCAL.MinX=<eval <MOREX>-<LOCAL.Radius>>
LOCAL.MinY=<eval <MOREY>-<LOCAL.Radius>>
LOCAL.MaxX=<eval <MOREX>+<LOCAL.Radius>>
LOCAL.MaxY=<eval <MOREY>+<LOCAL.Radius>>
IF (<LOCAL.MinX> < 0)
 LOCAL.MinX=0
ENDIF
IF (<LOCAL.MinY> < 0)
 LOCAL.MinY=0
ENDIF
MORE1=<eval (<LOCAL.MinX>*010000)+<LOCAL.MinY>>
MORE2=<eval (<LOCAL.MaxX>*010000)+<LOCAL.MaxY>>
PIN=<eval <TDATA1>/2>,<eval <TDATA2>/2>   //add pin on map center

[FUNCTION TreasureMap_CanDig]
IF (<TAG0.DirtPatch1>)
 SRC.SYSMESSAGE You are already digging treasure.
 return 0
ELIF (<SRC.CARTOGRAPHY> < <DEF0.TreasureMap_L<TDATA3>_Cartography>)
 SRC.SYSMESSAGE You did not decode this map and have no clue where to look for the treasure.
 return 0
ELIF (<SRC.FLAGS> & statf_hovering)
 SRC.SYSMESSAGE You cannot dig for treasure while flying!
 return 0
ELIF (<SRC.DISTANCE <MOREX>,<MOREY>> > <SRC.TreasureMap_GetDigDistance>)
 SRC.SYSMESSAGE You dig and dig but no treasure seems to be here.
 return 0
ELIF (<SRC.P.M> != <MOREM>)
 SRC.SYSMESSAGE You seem to be in the right place, but may be on the wrong facet!
 return 0
ENDIF
return 1

[FUNCTION TreasureMap_Dig]
IF (<TAG0.DiggingPos>) && STRCMP("<dTAG.DiggingPos>","<SRC.P.X><SRC.P.Y>")
 SRC.SYSMESSAGE You cannot move around while digging up treasure. You will need to start digging anew.
 TreasureMap_ClearTags
 return 1
ELIF (<SRC.WEAPON.BASEID> != i_pickaxe)
 SRC.SYSMESSAGE You must have a digging tool to dig for treasure.
 TreasureMap_ClearTags
 return 1
ENDIF
REF1=<TAG.DirtPatch1>
REF2=<TAG.DirtPatch2>
REF3=<TAG.Treasure>
IF ((<TAG0.DirtPatch1>) && !(<REF1>)) || ((<TAG0.DirtPatch2>) && !(<REF2>)) || ((<TAG0.Treasure>) && !(<REF3>))
 SRC.SYSMESSAGE The treasure chest fell apart for some reason.  Try digging it up again.
 TreasureMap_ClearTags
 return 1
ENDIF
IF !(<REF1>)
 //Create dirt patch
 SERV.NEWITEM 0912
 NEW.ATTR=attr_move_never|attr_decay
 NEW.TIMER=120
 NEW.P=<MOREP>
 TAG.DirtPatch1=<NEW>
 REF1=<TAG0.DirtPatch1>
 //Check if treasure still fit on this location
 IF (<SRC.P.X> == <MOREX>) && (<SRC.P.Y> == <MOREY>)
  SRC.SYSMESSAGE The chest can't be dug up because you are standing on top of it.
  TreasureMap_ClearTags
  return 1
 ELIF !(<REF1.TreasureMap_CanFitLocation>)
  SRC.SYSMESSAGE You have found the treasure chest but something is keeping it from being dug up.
  TreasureMap_ClearTags
  return 1
 ENDIF
ENDIF
REF1.MORE1 ++
IF (<REF1.MORE1> >= 25)
 //Fill treasure chest and spawn guardians
 REF3.TreasureMap_SpawnGuardians
 REF3.TreasureMap_FillTreasureChest
 REF3.LINK=<SRC>
 SRC.REVEAL
 REMOVE
 return 1
ELIF (<REF1.MORE1> > 20)
 //Raise treasure chest
 REF3.NUDGEUP
ELIF (<REF1.MORE1> == 20)
 //Create empty treasure chest
 SERV.NEWITEM i_chest_treasure
 NEW.ATTR=attr_move_never|attr_decay
 NEW.TYPE=t_container_locked
 NEW.MORE2=<DEF0.TreasureMap_L<TDATA3>_Lockpicking>
 NEW.TIMER=3600
 NEW.P=<MOREX>,<MOREY>,<eval <MOREZ>-5>,<MOREM>
 NEW.TAG.Level=<TDATA3>
 TAG.Treasure=<NEW>
ELIF (<REF1.MORE1> == 10)
 //Increase dirt patch
 REF1.DISPID ++
 REF1.UPDATE
 //Create another dirt patch
 SERV.NEWITEM <REF1.DISPID>
 NEW.ATTR=<REF1.ATTR>
 NEW.TIMER=<REF1.TIMER>
 NEW.P=<REF1.P>
 NEW.MOVE N
 TAG.DirtPatch2=<NEW>
ELIF (<REF1.MORE1> == 5)
 //Increase dirt patch
 REF1.DISPID ++
 REF1.UPDATE
ENDIF
//Keep digging
SRC.FACE <REF1>
SRC.ANIM 11
SRC.SOUND <eval 0125+(<REF1.MORE1>%2)>
TAG.DiggingPos=<SRC.P.X><SRC.P.Y>
TIMERF 1,TreasureMap_Dig

[FUNCTION TreasureMap_ClearTags]
UID.<TAG0.DirtPatch1>.REMOVE
UID.<TAG0.DirtPatch2>.REMOVE
UID.<TAG0.Treasure>.REMOVE
TAG.DiggingPos=
TAG.DirtPatch1=
TAG.DirtPatch2=
TAG.Treasure=

[FUNCTION TreasureMap_GetDigDistance]
IF (<MINING> >= 100.0)
 return 4
ELIF (<MINING> >= 80.0)
 return 3
ELIF (<MINING> >= 50.0)
 return 2
ELSE
 return 1
ENDIF

[FUNCTION TreasureMap_GetFacetRadius]
IF (<MOREM> < 2)	//Felucca, Trammel
 return 600
ELIF (<MOREM> < 5)	//Ilshenar, Malas, Tokuno Islands
 return 300
ELSE
 return 200		//Ter Mur
ENDIF

[FUNCTION TreasureMap_FillTreasureChest]
FOR <TAG0.Level>
 SERV.NEWITEM i_gold,5000,<UID>
ENDFOR
FOR <eval <TAG0.Level>+2>
 SERV.NEWITEM random_reagent,{40 60},<UID>
ENDFOR
FOR <eval 4+((<TAG0.Level>-1)*3)>
 SERV.NEWITEM random_jewel,1,<UID>
ENDFOR
FOR <eval <TAG0.Level>*6>	//using pre-SA formula, because SA formula <eval 32+((<TAG0.Level>-1)*8)> seems to be too much items
 SERV.NEWITEM {random_weapon_all_normal 1 random_armor_european 1 random_clothing 1 random_scroll_magery 1},1,<UID>
ENDFOR

[FUNCTION TreasureMap_SpawnGuardians]
IF (<TAG0.Level> < 2)
 LOCAL.N=3
ELSE
 LOCAL.N=4
ENDIF
FOR <LOCAL.N>
 SERV.NEWNPC <DEF0.TreasureMap_L<dTAG0.Level>_Guardians>
 NEW.NAME .= " (Guardian)"
 NEW.HOME=<P>
 NEW.HOMEDIST=8
 NEW.MOVENEAR <UID> 4
 NEW.TIMERF 3600,REMOVE
ENDFOR

[FUNCTION TreasureMap_SetRandomLocation]
LOCAL.Facet=<TOPOBJ.P.M>
IF !(<DEF0.TreasureMap_Facet<dLOCAL.Facet>>)
 LOCAL.Facet=0
ENDIF
SERV.NEWITEM i_gold
NEW.ATTR=attr_invis
FOR 1000
 ARGS=<R5000>,<R4000>,0,<LOCAL.Facet>
 IF !(<SERV.MAP(<ARGS>).REGION>)
  CONTINUE
 ENDIF
 NEW.P=<ARGS>
 NEW.FIX
 IF !(<NEW.TreasureMap_CanFitLocation>)
  CONTINUE
 ENDIF
 MOREP=<NEW.P>
 BREAK
ENDFOR
NEW.REMOVE

[FUNCTION TreasureMap_CanFitLocation]
REF1=<REGION.UID>
IF (<REF1.TYPE> == t_multi) || (<REF1.TYPE> == t_multi_custom) || (<REF1.TYPE> == t_ship)
 return 0
ELIF (<REGION.FLAGS> & region_flag_guarded|region_flag_safe|region_flag_underground)
 return 0
ELIF !((<P.TYPE> == t_dirt) || (<P.TYPE> == t_grass) || (<P.TYPE> == t_forest) || (<P.TYPE> == t_jungle) || (<P.TYPE> == t_sand) || (<P.TYPE> == t_snow))
 return 0
ELIF (<ISNEARTYPE t_tree 2 0 1>) || (<ISNEARTYPE t_rock 2 0 1>) || (<ISNEARTYPE t_wall 2 0 1>)
 return 0
ENDIF
return 1

/////////////
// Dialogs //
/////////////

[DIALOG d_treasure_chest_remove]
15,15

resizepic 30 0 2620 240 240
dhtmlgump 45 15 200 80 0 0 <DEF.BFONT_WHITE>When this treasure chest is removed, any items still inside of it will be lost.
dhtmlgump 45 95 200 60 0 0 <DEF.BFONT_WHITE>Are you certain you're ready to remove this chest?
button 40 153 4005 4007 1 0 1
dhtmlgump 75 155 180 40 0 0 <DEF.BFONT_WHITE>Remove the Treasure Chest
button 40 195 4005 4007 1 0 0
dhtmlgump 75 197 180 35 0 0 <DEF.BFONT_WHITE>Cancel

[DIALOG d_treasure_chest_remove BUTTON]
ON=1
IF ((<SRC> == <LINK>) && (<SRC.CANSEELOS <UID>>)) || (<SRC.ISGM>)
 SRC.SYSMESSAGE @08a5 The old, rusted chest crumbles when you hit it.
 REMOVE
ENDIF

[EOF]