Advertisement
CherryDT

Event Code Clipboard Interface (cbinterface.bi)

May 23rd, 2013
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ' ************************
  2. ' RM2k(3) Clipboard Interface special version for RMEventFactory
  3. ' by Cherry
  4. ' www.cherrytree.at
  5. ' ************************
  6.  
  7. #Include Once "useful/useful.bi"
  8.  
  9. ' ********* Int <> BER *********
  10.  
  11. Function BER2Int(packed As String) As UInteger
  12.     Dim Value As UInteger
  13.     Dim Temporal As UByte
  14.     For i As Integer = 0 To Len(packed) - 1
  15.         Value Shl= 7
  16.         Temporal = packed[i]
  17.         Value Or= Temporal And &h7F
  18.         If Temporal And &h80 = 0 Then Exit For
  19.     Next
  20.     Return Value
  21. End Function
  22.  
  23. Function Int2BER(number As Integer) As String
  24.     Dim Rev As String
  25.     Dim Temporal1 As ULongInt = number
  26.     Dim Temporal2 As UByte
  27.     Dim counter As Integer
  28.     Do
  29.         Temporal2 = Temporal1 And &h7F
  30.         Temporal1 Shr= 7
  31.         If counter Then Temporal2 Or= &h80
  32.         Rev &= Chr(Temporal2)
  33.         counter += 1
  34.     Loop While Temporal1
  35.     Dim Outp As String
  36.     For i As Integer = Len(Rev) - 1 To 0 Step -1
  37.         Outp &= Chr(Rev[i])
  38.     Next
  39.     Return Outp
  40. End Function
  41.  
  42.  
  43. ' ********* Stream reader *********
  44.  
  45. Type StreamReader
  46.     Data As String
  47.     Position As Integer
  48.     Declare Constructor(Data_ As String)
  49.     Declare Function ReadByte() As UByte
  50.     Declare Function ReadInt() As Integer
  51.     Declare Function ReadBER() As Integer
  52.     Declare Function ReadString(Length As Integer, coded As Boolean = FALSE) As String
  53.     Declare Function EndReached() As Boolean
  54. End Type
  55.  
  56. Constructor StreamReader(Data_ As String)
  57.     Data = Data_
  58.     Position = 0
  59. End Constructor
  60.  
  61. Function StreamReader.ReadByte() As UByte
  62.     Position += 1
  63.     Return IIf(Position >= Len(Data), CUByte(0), Data[Position - 1])
  64. End Function
  65.  
  66. Function StreamReader.ReadInt() As Integer
  67.     Position += 4
  68.     Return Cvi(Mid(Data, Position - 3, 4))
  69. End Function
  70.  
  71. Function StreamReader.ReadBER() As Integer
  72.     Dim Value As Integer, Temporal As UByte
  73.     Do
  74.         Value Shl= 7
  75.         Temporal = IIf(Position >= Len(Data), CUByte(0), Data[Position])
  76.         Value Or= Temporal And &h7F
  77.         Position += 1
  78.         If (Temporal And &h80) = 0 Then Exit Do
  79.     Loop While Position <= Len(Data)
  80.     Return Value
  81. End Function
  82.  
  83. Function StreamReader.ReadString(Length As Integer, coded As Boolean = FALSE) As String
  84.     If coded Then
  85.         Dim s As String
  86.         For i As Integer = 0 To Length - 1
  87.             s += Chr(ReadBER())
  88.         Next
  89.         Return s
  90.     Else
  91.         Position += Length
  92.         Return Mid(Data, Position - Length + 1, Length)
  93.     EndIf
  94. End Function
  95.  
  96. Function StreamReader.EndReached() As Boolean
  97.     Return Position >= Len(Data)
  98. End Function
  99.  
  100.  
  101. ' ********* Stream writer *********
  102.  
  103. Type StreamWriter
  104.     Data As String
  105.     Declare Sub WriteByte(value As UByte)
  106.     Declare Sub WriteInt(value As Integer)
  107.     Declare Sub WriteBER(value As Integer, addlengthBER As Boolean = FALSE, value2 As Integer = -1)
  108.     Declare Sub WriteString(value As String, addlengthBER As Boolean = FALSE, value2 As Integer = -1, coded As Boolean = FALSE)
  109. End Type
  110.  
  111. Sub StreamWriter.WriteByte(value As UByte)
  112.     Data += Chr(value)
  113. End Sub
  114.  
  115. Sub StreamWriter.WriteInt(value As Integer)
  116.     Data += Mki(value)
  117. End Sub
  118.  
  119. Sub StreamWriter.WriteBER(value As Integer, addlengthBER As Boolean = FALSE, value2 As Integer = -1)
  120.     If value2 <> -1 Then Data += Int2BER(value2)
  121.     If addlengthBER Then Data += Int2BER(Len(Int2BER(value)))
  122.     Data += Int2BER(value)
  123. End Sub
  124.  
  125. Sub StreamWriter.WriteString(value As String, addlengthBER As Boolean = FALSE, value2 As Integer = -1, coded As Boolean = FALSE)
  126.     If value2 <> -1 Then Data += Int2BER(value2)
  127.     If coded Then
  128.         If addlengthBER Then
  129.             Dim slen As Integer
  130.             For i As Integer = 0 To Len(value) - 1
  131.                 slen += Len(Int2BER(value[i]))
  132.             Next
  133.             Data += Int2BER(slen)
  134.         EndIf
  135.         For i As Integer = 0 To Len(value) - 1
  136.             Data += Int2BER(value[i])
  137.         Next
  138.     Else
  139.         If addlengthBER Then Data += Int2BER(Len(value))
  140.         Data += value
  141.     EndIf
  142. End Sub
  143.  
  144.  
  145. ' ********* Main AEE code *********
  146.  
  147. Namespace AEE
  148.  
  149.     ' ********* Declarations *********
  150.  
  151.     Enum OBJECTTYPE
  152.         OBJ_NONE
  153.         OBJ_STARTCONDITIONS
  154.         OBJ_MOVEEVENTCOMMAND
  155.         OBJ_MOVEEVENTDATA
  156.         OBJ_EVENTCOMMAND
  157.         OBJ_EVENTPAGE
  158.         OBJ_EVENT
  159.     End Enum
  160.  
  161.     Enum COMPARISONS
  162.         EVC_EQUAL
  163.         EVC_GREATER_OR_EQUAL
  164.         EVC_LESS_OR_EQUAL
  165.         EVC_GREATER
  166.         EVC_LESS
  167.         EVC_NOT_EQUAL
  168.     End Enum
  169.    
  170.     Type STARTCONDITIONS
  171.         _ObjectType As Const OBJECTTYPE = OBJ_STARTCONDITIONS
  172.         Enum STARTCONDITIONS2
  173.             EPSC_SWITCH1 = &h1
  174.             EPSC_SWITCH2 = &h2
  175.             EPSC_VARIABLE = &h4
  176.             EPSC_ITEM = &h8
  177.             EPSC_HERO_IN_PARTY = &h10
  178.             EPSC_TIMER1 = &h20
  179.             EPSC_TIMER2 = &h40
  180.             EPSC_TURNS = &h80
  181.             EPSC_MONSTER_TURNS = &h100
  182.             EPSC_HERO_TURNS = &h200
  183.             EPSC_EXHAUSTION = &h400
  184.             EPSC_MONSTER_HP = &h800
  185.             EPSC_HERO_HP = &h1000
  186.             EPSC_HERO_COMMAND = &h2000
  187.         End Enum
  188.         Used As Integer
  189.         Switch1_ID As Integer = 1
  190.         Switch2_ID As Integer = 1
  191.         Variable_ID As Integer = 1
  192.         Variable_Value As Integer
  193.         Variable_Comparison As COMPARISONS = EVC_GREATER_OR_EQUAL
  194.         Item_ID As Integer = 1
  195.         HeroInParty_HeroID As Integer = 1
  196.         Timer1_Sec As Integer
  197.         Timer2_Sec As Integer
  198.         Turns_Elapsed1 As Integer
  199.         Turns_Elapsed2 As Integer
  200.         MonsterTurns_MonsterID As Integer
  201.         MonsterTurns_TurnsElapsed1 As Integer
  202.         MonsterTurns_TurnsElapsed2 As Integer
  203.         HeroTurns_HeroID As Integer
  204.         HeroTurns_TurnsElapsed1 As Integer
  205.         HeroTurns_TurnsElapsed2 As Integer
  206.         Exhaustion_Min As Integer
  207.         Exhaustion_Max As Integer
  208.         MonsterHP_MonsterID As Integer
  209.         MonsterHP_Min As Integer
  210.         MonsterHP_Max As Integer
  211.         HeroHP_HeroID As Integer
  212.         HeroHP_Min As Integer
  213.         HeroHP_Max As Integer
  214.         HeroCommand_HeroID As Integer
  215.         HeroCommand_CommandID As Integer
  216.     End Type
  217.    
  218.     Const SPR_TILESET = 0
  219.    
  220.     Type MOVEEVENTCOMMAND
  221.         _ObjectType As Const OBJECTTYPE = OBJ_MOVEEVENTCOMMAND
  222.         Enum MOVEEVENTCOMMANDTYPE
  223.             ME_MOVE_UP
  224.             ME_MOVE_RIGHT
  225.             ME_MOVE_DOWN
  226.             ME_MOVE_LEFT
  227.             ME_MOVE_UP_RIGHT
  228.             ME_MOVE_DOWN_RIGHT
  229.             ME_MOVE_DOWN_LEFT
  230.             ME_MOVE_UP_LEFT
  231.             ME_MOVE_RANDOMLY
  232.             ME_MOVE_TOWARD_HERO
  233.             ME_MOVE_AWAY_FROM_HERO
  234.             ME_MOVE_FORWARD
  235.             ME_FACE_UP
  236.             ME_FACE_RIGHT
  237.             ME_FACE_DOWN
  238.             ME_FACE_LEFT
  239.             ME_TURN_RIGHT
  240.             ME_TURN_LEFT
  241.             ME_TURN_AROUND
  242.             ME_TURN_RANDOMLY
  243.             ME_FACE_RANDOMLY
  244.             ME_FACE_TOWARD_HERO
  245.             ME_FACE_AWAY_FROM_HERO
  246.             ME_WAIT
  247.             ME_BEGIN_JUMP
  248.             ME_END_JUMP
  249.             ME_LOCK_FACING
  250.             ME_UNLOCK_FACING
  251.             ME_INCREASE_SPEED
  252.             ME_DECREASE_SPEED
  253.             ME_INCREASE_FREQUENCY
  254.             ME_DECREASE_FREQUENCY
  255.             ME_SWITCH_ON
  256.             ME_SWITCH_OFF
  257.             ME_CHANGE_GRAPHIC
  258.             ME_PLAY_SE
  259.             ME_PHASING_MODE_ON
  260.             ME_PHASING_MODE_OFF
  261.             ME_STOP_ANIMATION
  262.             ME_RESUME_ANIMATION
  263.             ME_INCREASE_TRANSPARENCY
  264.             ME_DECREASE_TRANSPARENCY
  265.         End Enum
  266.         Command As MOVEEVENTCOMMANDTYPE
  267.         Switch_ID As Integer = 1
  268.         Sprite_Filename As ZString Ptr
  269.         Sprite_ID As Integer
  270.         SE_Filename As ZString Ptr
  271.         SE_Volume As Integer = 100
  272.         SE_Tempo As Integer = 100
  273.         SE_Balance As Integer = 50
  274.     End Type
  275.    
  276.     Enum EVENTID
  277.         EV_HERO = 10001
  278.         EV_BOAT
  279.         EV_SHIP
  280.         EV_AIRSHIP
  281.         EV_THIS
  282.     End Enum
  283.    
  284.     Enum FACEDIRECTIONS
  285.         FD_UP
  286.         FD_RIGHT
  287.         FD_DOWN
  288.         FD_LEFT
  289.     End Enum
  290.    
  291.     Enum CHARSETFRAMES
  292.         CSF_LEFT
  293.         CSF_CENTER
  294.         CSF_RIGHT
  295.     End Enum
  296.    
  297.     Type MOVEEVENTDATA
  298.         _ObjectType As Const OBJECTTYPE = OBJ_MOVEEVENTDATA
  299.         Target As EVENTID
  300.         Frequency As Integer = 8
  301.         RepeatPattern As Boolean
  302.         IgnoreImpossible As Boolean
  303.         CommandsAmount As Integer
  304.         Commands As MOVEEVENTCOMMAND Ptr
  305.     End Type
  306.    
  307.     Enum EVENTCOMMANDS
  308.         EVCMD_FREE_LINE = 10
  309.         EVCMD_SHOW_MESSAGE = 10110
  310.         EVCMD_ADD_LINE_TO_MESSAGE = 20110
  311.         EVCMD_MESSAGE_OPTIONS = 10120
  312.         EVCMD_SELECT_FACE = 10130
  313.         EVCMD_SHOW_CHOICE = 10140
  314.         EVCMD_CHOICE_CASE = 20140
  315.         EVCMD_CHOICE_END = 20141
  316.         EVCMD_INPUT_NUMBER = 10150
  317.         EVCMD_CHANGE_SWITCH = 10210
  318.         EVCMD_CHANGE_VARIABLE = 10220
  319.         EVCMD_CHANGE_TIMER = 10230
  320.         EVCMD_CHANGE_MONEY = 10310
  321.         EVCMD_CHANGE_ITEMS = 10320
  322.         EVCMD_CHANGE_PARTY = 10330
  323.         EVCMD_CHANGE_EXP = 10410
  324.         EVCMD_CHANGE_LEVEL = 10420
  325.         EVCMD_CHANGE_STATS = 10430
  326.         EVCMD_CHANGE_SKILL = 10440
  327.         EVCMD_CHANGE_EQUIPMENT = 10450
  328.         EVCMD_CHANGE_HP = 10460
  329.         EVCMD_CHANGE_MP = 10470
  330.         EVCMD_CHANGE_CONDITION = 10480
  331.         EVCMD_FULL_RECOVERY = 10490
  332.         EVCMD_INFLICT_DAMAGE = 10500
  333.         EVCMD_CHANGE_HERO_NAME = 10610
  334.         EVCMD_CHANGE_HERO_TITLE = 10620
  335.         EVCMD_CHANGE_HERO_GRAPHIC = 10630
  336.         EVCMD_CHANGE_HERO_FACE = 10640
  337.         EVCMD_CHANGE_VEHICLE_GRAPHIC = 10650
  338.         EVCMD_CHANGE_SYSTEM_BGM = 10660
  339.         EVCMD_CHANGE_SYSTEM_SE = 10670
  340.         EVCMD_CHANGE_SYSTEM_GRAPHIC = 10680
  341.         EVCMD_CHANGE_TRANSITION = 10690
  342.         EVCMD_START_COMBAT = 10710
  343.         EVCMD_BATTLE_VICTORY = 20710
  344.         EVCMD_BATTLE_ESCAPE = 20711
  345.         EVCMD_BATTLE_DEFEAT = 20712
  346.         EVCMD_BATTLE_END = 20713
  347.         EVCMD_CALL_SHOP = 10720
  348.         EVCMD_SHOP_TRANSACTION = 20720
  349.         EVCMD_SHOP_CANCEL = 20721
  350.         EVCMD_SHOP_END = 20722
  351.         EVCMD_CALL_INN = 10730
  352.         EVCMD_INN_REST = 20730
  353.         EVCMD_INN_CANCEL = 20731
  354.         EVCMD_INN_END = 20732
  355.         EVCMD_ENTER_HERO_NAME = 10740
  356.         EVCMD_TELEPORT = 10810
  357.         EVCMD_MEMORIZE_LOCATION = 10820
  358.         EVCMD_GO_TO_MEMORIZED_LOCATION = 10830
  359.         EVCMD_RIDE_VEHICLE = 10840
  360.         EVCMD_TELEPORT_VEHICLE = 10850
  361.         EVCMD_SET_EVENT_LOCATION = 10860
  362.         EVCMD_SWAP_TWO_EVENT_LOCATIONS = 10870
  363.         EVCMD_GET_TERRAIN_ID = 10910
  364.         EVCMD_GET_EVENT_ID = 10920
  365.         EVCMD_ERASE_SCREEN = 11010
  366.         EVCMD_SHOW_SCREEN = 11020
  367.         EVCMD_SET_SCREEN_TONE = 11030
  368.         EVCMD_FLASH_SCREEN = 11040
  369.         EVCMD_SHAKE_SCREEN = 11050
  370.         EVCMD_PAN_SCREEN = 11060
  371.         EVCMD_WEATHER_EFFECTS = 11070
  372.         EVCMD_SHOW_PICTURE = 11110
  373.         EVCMD_MOVE_PICTURE = 11120
  374.         EVCMD_ERASE_PICTURE = 11130
  375.         EVCMD_SHOW_BATTLE_ANIMATION = 11210
  376.         EVCMD_SET_HERO_OPACITY = 11310
  377.         EVCMD_FLASH_EVENT = 11320
  378.         EVCMD_MOVE_EVENT = 11330
  379.         EVCMD_WAIT_UNTIL_MOVED = 11340
  380.         EVCMD_STOP_ALL_MOVEMENT = 11350
  381.         EVCMD_WAIT = 11410
  382.         EVCMD_PLAY_BGM = 11510
  383.         EVCMD_FADE_OUT_BGM = 11520
  384.         EVCMD_MEMORIZE_BGM = 11530
  385.         EVCMD_PLAY_MEMORIZED_BGM = 11540
  386.         EVCMD_PLAY_SOUND_EFFECT = 11550
  387.         EVCMD_PLAY_MOVIE = 11560
  388.         EVCMD_KEY_INPUT_PROCESSING = 11610
  389.         EVCMD_CHANGE_TILESET = 11710
  390.         EVCMD_CHANGE_PANORAMA = 11720
  391.         EVCMD_CHANGE_ENCOUNTER_RATE = 11740
  392.         EVCMD_CHANGE_SINGLE_TILE = 11750
  393.         EVCMD_CHANGE_TELEPORT_TARGET = 11810
  394.         EVCMD_ENABLE_TELEPORT = 11820
  395.         EVCMD_SET_ESCAPE_LOCATION = 11830
  396.         EVCMD_ENABLE_ESCAPE = 11840
  397.         EVCMD_CALL_SAVE_MENU = 11910
  398.         EVCMD_ENABLE_SAVE = 11930
  399.         EVCMD_CALL_MAIN_MENU = 11950
  400.         EVCMD_ENABLE_MAIN_MENU = 11960
  401.         EVCMD_FORK = 12010
  402.         EVCMD_FORK_ELSE_CASE = 22010
  403.         EVCMD_FORK_END = 22011
  404.         EVCMD_LABEL = 12110
  405.         EVCMD_JUMP_TO_LABEL = 12120
  406.         EVCMD_START_LOOP = 12210
  407.         EVCMD_END_LOOP = 22210
  408.         EVCMD_BREAK_LOOP = 12220
  409.         EVCMD_STOP_EVENT = 12310
  410.         EVCMD_DELETE_EVENT = 12320
  411.         EVCMD_CALL_EVENT = 12330
  412.         EVCMD_COMMENT = 12410
  413.         EVCMD_ADD_LINE_TO_COMMENT = 22410
  414.         EVCMD_GAME_OVER = 12420
  415.         EVCMD_GO_TO_TITLE_SCREEN = 12510
  416.         EVCMD_CHANGE_CLASS = 1008
  417.         EVCMD_CHANGE_BATTLE_COMMANDS = 1009
  418.         EVCMD_CHANGE_ENEMY_HP = 13110
  419.         EVCMD_CHANGE_ENEMY_MP = 13120
  420.         EVCMD_CHANGE_ENEMY_CONDITION = 13130
  421.         EVCMD_REVIVE_ENEMY = 13150
  422.         EVCMD_CHANGE_BACKDROP = 13210
  423.         EVCMD_SHOW_BATTLE_ANIMATION_IN_BATTLE = 13260
  424.         EVCMD_ENABLE_COMBO = 1007
  425.         EVCMD_FORCE_FLEE = 1006
  426.         EVCMD_END_BATTLE = 13410
  427.         EVCMD_FORK_IN_BATTLE = 13310
  428.         EVCMD_FORK_IN_BATTLE_ELSE_CASE = 23310
  429.         EVCMD_FORK_IN_BATTLE_END = 23311
  430.         EVCMD_CALL_COMMON_EVENT = 1005
  431.     End Enum
  432.    
  433.     Type EVENTCOMMAND
  434.         _ObjectType As Const OBJECTTYPE = OBJ_EVENTCOMMAND
  435.         Command As Integer = EVCMD_FREE_LINE
  436.         TreeDepth As Integer
  437.         NameBlock As ZString Ptr
  438.         ParamsAmount As Integer
  439.         Params As Integer Ptr
  440.         MoveEventBlock As MOVEEVENTDATA Ptr
  441.     End Type
  442.    
  443.     Type EVENTPAGE
  444.         _ObjectType As Const OBJECTTYPE = OBJ_EVENTPAGE
  445.         ID As Integer
  446.         StartConditions As STARTCONDITIONS Ptr
  447.         Sprite_Filename As ZString Ptr
  448.         Sprite_ID As Integer
  449.         Sprite_Transparency As Boolean
  450.         FacingDirection As FACEDIRECTIONS
  451.         Frame As CHARSETFRAMES = CSF_CENTER
  452.         Enum TRIGGERCONDITION
  453.             EPTC_PUSH_KEY
  454.             EPTC_CALL = 0
  455.             EPTC_HERO_TOUCH
  456.             EPTC_HERO_COLLISION
  457.             EPTC_AUTOSTART
  458.             EPTC_PARALLEL
  459.         End Enum
  460.         Trigger As TRIGGERCONDITION
  461.         ForbidEventOverlap As Boolean
  462.         Enum MOVEMENTTYPE_
  463.             EPMT_STATIONARY
  464.             EPMT_RANDOM
  465.             EPMT_VERTICAL
  466.             EPMT_HORIZONTAL
  467.             EPMT_TOWARD_HERO
  468.             EPMT_AWAY_FROM_HERO
  469.             EPMT_CUSTOM
  470.         End Enum
  471.         MovementType As MOVEMENTTYPE_
  472.         MovementPattern As MOVEEVENTDATA Ptr
  473.         MovementSpeed As Integer = 3
  474.         MovementFrequency As Integer = 3
  475.         Enum ANIMATIONTYPE_
  476.             EPAT_NON_CONTINUOUS
  477.             EPAT_CONTINUOUS
  478.             EPAT_FIXED_DIR_NON_CONTINUOUS
  479.             EPAT_FIXED_DIR_CONTINUOUS
  480.             EPAT_FIXED_GRAPHIC
  481.             EPAT_SPIN_AROUND
  482.             EPAT_NO_STEPS
  483.         End Enum
  484.         AnimationType As ANIMATIONTYPE_
  485.         Enum EVENTLEVEL_
  486.             ELV_BELOW_HERO
  487.             ELV_SAME_LEVEL_AS_HERO
  488.             ELV_ABOVE_HERO
  489.         End Enum
  490.         EventLevel As EVENTLEVEL_
  491.         CommandsAmount As Integer
  492.         Commands As EVENTCOMMAND Ptr
  493.     End Type
  494.    
  495.     Type EXTRAINFORMATION
  496.         i(&hFF) As String
  497.     End Type
  498.    
  499.     Type EVENT
  500.         _ObjectType As Const OBJECTTYPE = OBJ_EVENT
  501.         Enum EVENTTYPE
  502.             EVT_UNKNOWN
  503.             EVT_MAP
  504.             EVT_COMMON
  505.             EVT_BATTLE
  506.         End Enum
  507.         Type_ As EVENTTYPE
  508.         ID As Integer
  509.         Coordinates As Point
  510.         Name As ZString Ptr
  511.         PagesAmount As Integer
  512.         Pages As EVENTPAGE Ptr
  513.         ExtraInformation As EXTRAINFORMATION Ptr
  514.     End Type
  515.    
  516.     Enum CLIPBOARDCONTENTTYPE
  517.         CBCT_UNKNOWN
  518.         CBCT_TEXT = CF_TEXT
  519.         CBCT_EVENT = 563
  520.         CBCT_EVENTPAGE = 564
  521.         CBCT_BATTLEEVENTPAGE = 565
  522.         CBCT_EVENTCOMMANDS = 566
  523.         CBCT_MONSTERGROUP = 578
  524.         CBCT_COMMONEVENT = 584
  525.     End Enum
  526.    
  527.    
  528.     ' ********* Event command property constants *********
  529.    
  530.    
  531.     Enum TRANSITIONS
  532.         TR_DEFAULT = -1
  533.         TR_FADE
  534.         TR_DISSOLVE
  535.         TR_DISSOLVEUP
  536.         TR_DISSOLVEDOWN
  537.         TR_BLINDS
  538.         TR_VERTICALSTRIPES
  539.         TR_HORIZONTALSTRIPES
  540.         TR_RECIDINGSQUARE
  541.         TR_EXPANDINGSQUARE
  542.         TR_SHIFTUP
  543.         TR_SHIFTDOWN
  544.         TR_SHIFTLEFT
  545.         TR_SHIFTRIGHT
  546.         TR_VERTICALSPLIT
  547.         TR_HORIZONATLSPLIT
  548.         TR_4WAYSPLIT
  549.         TR_ZOOM
  550.         TR_MOSAIC
  551.         TR_WAVERSCREEN
  552.         TR_INSTANT
  553.         TR_NONE
  554.     End Enum
  555.  
  556.     Enum ECP_CHGV_OPERATIONS ' Change Variable
  557.         ECP_CHGV_OP_SET
  558.         ECP_CHGV_OP_ADD
  559.         ECP_CHGV_OP_SUBTRACT
  560.         ECP_CHGV_OP_MULTIPLY
  561.         ECP_CHGV_OP_DIVIDE
  562.         ECP_CHGV_OP_MODULO
  563.     End Enum
  564.    
  565.     Enum ECP_CHGV_OPERANDTYPES
  566.         ECP_CHGV_OT_VALUE
  567.         ECP_CHGV_OT_VARIABLE
  568.         ECP_CHGV_OT_REFERENCE
  569.         ECP_CHGV_OT_RANDOM
  570.         ECP_CHGV_OT_ITEM
  571.         ECP_CHGV_OT_HERO
  572.         ECP_CHGV_OT_EVENT
  573.         ECP_CHGV_OT_OTHER
  574.         ECP_CHGV_OT_MONSTER
  575.     End Enum
  576.    
  577.     Enum ECP_CHGV_HEROPROPERTIES
  578.         ECP_CHGV_HP_LEVEL
  579.         ECP_CHGV_HP_EXP
  580.         ECP_CHGV_HP_HP
  581.         ECP_CHGV_HP_MP
  582.         ECP_CHGV_HP_MAXHP
  583.         ECP_CHGV_HP_MAXMP
  584.         ECP_CHGV_HP_ATK
  585.         ECP_CHGV_HP_DEF
  586.         ECP_CHGV_HP_INT
  587.         ECP_CHGV_HP_AGI
  588.         ECP_CHGV_HP_WEAPON_ID
  589.         ECP_CHGV_HP_SHIELD_ID
  590.         ECP_CHGV_HP_ARMOR_ID
  591.         ECP_CHGV_HP_HELMET_ID
  592.         ECP_CHGV_HP_ACCESSORY_ID
  593.     End Enum
  594.    
  595.     Enum ECP_CHGV_EVENTPROPERTIES
  596.         ECP_CHGV_EP_MAPID
  597.         ECP_CHGV_EP_MAPX
  598.         ECP_CHGV_EP_MAPY
  599.         ECP_CHGV_EP_FACING
  600.         ECP_CHGV_EP_SCREENX
  601.         ECP_CHGV_EP_SCREENY
  602.     End Enum
  603.    
  604.     Enum ECP_CHGV_OTHEROPERAND
  605.         ECP_CHGV_OO_MONEY
  606.         ECP_CHGV_OO_TIMER1
  607.         ECP_CHGV_OO_PARTYSIZE
  608.         ECP_CHGV_OO_SAVES
  609.         ECP_CHGV_OO_BATTLES
  610.         ECP_CHGV_OO_VICTORIES
  611.         ECP_CHGV_OO_DEFEATS
  612.         ECP_CHGV_OO_ESCAPES
  613.         ECP_CHGV_OO_MIDIPOS
  614.         ECP_CHGV_OO_TIMER2
  615.     End Enum
  616.    
  617.     Enum ECP_CHGV_MONSTERPROPERTIES
  618.         ECP_CHGV_MP_HP
  619.         ECP_CHGV_MP_MP
  620.         ECP_CHGV_MP_MAXHP
  621.         ECP_CHGV_MP_MAXMP
  622.         ECP_CHGV_MP_ATK
  623.         ECP_CHGV_MP_DEF
  624.         ECP_CHGV_MP_INT
  625.         ECP_CHGV_MP_AGI
  626.     End Enum
  627.    
  628.     Enum ECP_CHGST_STATS ' Change Ability
  629.         ECP_CHGST_MAXHP
  630.         ECP_CHGST_MAXMP
  631.         ECP_CHGST_ATK
  632.         ECP_CHGST_DEF
  633.         ECP_CHGST_INT
  634.         ECP_CHGST_AGI
  635.     End Enum
  636.    
  637.     Enum ECP_CHGEQ_EQUIPMENTTYPES ' Change Equipment
  638.         ECP_CHGEQ_WEAPON
  639.         ECP_CHGEQ_SHIELD
  640.         ECP_CHGEQ_ARMOR
  641.         ECP_CHGEQ_HELMET
  642.         ECP_CHGEQ_ACCESSORY
  643.         ECP_CHGEQ_ALL
  644.     End Enum
  645.    
  646.     Enum ECP_CHGSB_SCENES ' Change System BGM
  647.         ECP_CHGSB_BATTLE
  648.         ECP_CHGSB_VICTORY
  649.         ECP_CHGSB_BOAT
  650.         ECP_CHGSB_SHIP
  651.         ECP_CHGSB_AIRSHIP
  652.         ECP_CHGSB_GAMEOVER
  653.     End Enum
  654.    
  655.     Enum ECP_CHGSS_EVENTS ' Change System SE
  656.         ECP_CHGSS_CURSOR
  657.         ECP_CHGSS_DECISION
  658.         ECP_CHGSS_CANCEL
  659.         ECP_CHGSS_BUZZER
  660.         ECP_CHGSS_BATTLESTART
  661.         ECP_CHGSS_ESCAPE
  662.         ECP_CHGSS_ATTACK
  663.         ECP_CHGSS_DAMAGEENEMY
  664.         ECP_CHGSS_DAMAGEHERO
  665.         ECP_CHGSS_EVADE
  666.         ECP_CHGSS_DEATH
  667.         ECP_CHGSS_ITEM
  668.     End Enum
  669.    
  670.     Enum ECP_CHGTR_EVENTS ' Change System Transitions
  671.         ECP_CHGTR_EV_TELEPORT_ERASE
  672.         ECP_CHGTR_EV_TELEPORT_SHOW
  673.         ECP_CHGTR_EV_BATTLESTART_ERASE
  674.         ECP_CHGTR_EV_BATTLESTART_SHOW
  675.         ECP_CHGTR_EV_BATTLEEND_ERASE
  676.         ECP_CHGTR_EV_BATTLEEND_SHOW
  677.     End Enum
  678.    
  679.     Enum ECP_PS_TYPES ' Pan Screen
  680.         ECP_PS_LOCK
  681.         ECP_PS_UNLOCK
  682.         ECP_PS_MOVE
  683.         ECP_PS_RECALL
  684.     End Enum
  685.    
  686.     Enum ECP_CW_WEATHERTYPES ' Change Weather
  687.         ECP_CW_NONE
  688.         ECP_CW_RAIN
  689.         ECP_CW_SNOW
  690.         ECP_CW_FOG
  691.         ECP_CW_SANDSTORM
  692.     End Enum
  693.    
  694.     Enum ECP_FORK_TYPES ' Fork Condition
  695.         ECP_FORK_TP_SWITCH
  696.         ECP_FORK_TP_VARIABLE
  697.         ECP_FORK_TP_TIMER1
  698.         ECP_FORK_TP_MONEY
  699.         ECP_FORK_TP_ITEM
  700.         ECP_FORK_TP_HERO
  701.         ECP_FORK_TP_EVENT
  702.         ECP_FORK_TP_VEHICLE
  703.         ECP_FORK_HP_ACTIONKEY
  704.         ECP_FORK_HP_BGMPLAYED
  705.         ECP_FORK_HP_TIMER2
  706.         ECP_FORK_HP_HERO_ABLETOACT = 2
  707.         ECP_FORK_HP_ENEMY_ABLETOACT
  708.         ECP_FORK_HP_ENEMY_CURRENTTARGET
  709.         ECP_FORK_HP_BATTLECOMMAND
  710.     End Enum
  711.    
  712.     Enum ECP_FORK_HEROPROPERTIES
  713.         ECP_FORK_HP_INPARTY
  714.         ECP_FORK_HP_NAME
  715.         ECP_FORK_HP_LEVEL
  716.         ECP_FORK_HP_HP
  717.         ECP_FORK_HP_SKILL
  718.         ECP_FORK_HP_ITEM
  719.         ECP_FORK_HP_CONDITION
  720.     End Enum
  721.    
  722.    
  723.     ' ********* Object management functions *********
  724.    
  725.     Function CreateString(Length As Integer) As ZString Ptr
  726.         Return Callocate(Length + 1)
  727.     End Function
  728.    
  729.     Sub DeleteString(Data_ As ZString Ptr)
  730.         If Data_ <> NULL Then DeAllocate(Data_)
  731.     End Sub
  732.    
  733.     Function CreateObject(ObjectType_ As OBJECTTYPE) As Any Ptr
  734.         Select Case ObjectType_
  735.             Case OBJ_STARTCONDITIONS
  736.                 Var ret = New STARTCONDITIONS
  737.                 Return ret
  738.             Case OBJ_MOVEEVENTCOMMAND
  739.                 Var ret = New MOVEEVENTCOMMAND
  740.                 Return ret
  741.             Case OBJ_MOVEEVENTDATA
  742.                 Var ret = New MOVEEVENTDATA
  743.                 Return ret
  744.             Case OBJ_EVENTCOMMAND
  745.                 Var ret = New EVENTCOMMAND
  746.                 Return ret
  747.             Case OBJ_EVENTPAGE
  748.                 Var ret = New EVENTPAGE
  749.                 Return ret
  750.             Case OBJ_EVENT
  751.                 Var ret = New EVENT
  752.                 Return ret
  753.             Case Else
  754.                 Return NULL
  755.         End Select
  756.     End Function
  757.    
  758.     Function ResizeObjectArray(Array As Any Ptr, ObjectType_ As OBJECTTYPE, OldSize As Integer, NewSize As Integer) As Any Ptr
  759.         Select Case ObjectType_
  760.             Case OBJ_MOVEEVENTCOMMAND
  761.                 If NewSize = 0 Then
  762.                     Delete[](Cast(MOVEEVENTCOMMAND Ptr, Array))
  763.                     Return NULL
  764.                 EndIf
  765.                 Var tmp = New MOVEEVENTCOMMAND[NewSize]
  766.                 CopyMemory(tmp, Array, min(OldSize, NewSize) * SizeOf(MOVEEVENTCOMMAND))
  767.                 Delete[](Cast(MOVEEVENTCOMMAND Ptr, Array))
  768.                 Return tmp
  769.             Case OBJ_EVENTCOMMAND
  770.                 If NewSize = 0 Then
  771.                     Delete[](Cast(EVENTCOMMAND Ptr, Array))
  772.                     Return NULL
  773.                 EndIf
  774.                 Var tmp = New EVENTCOMMAND[NewSize]
  775.                 CopyMemory(tmp, Array, min(OldSize, NewSize) * SizeOf(EVENTCOMMAND))
  776.                 Delete[](Cast(EVENTCOMMAND Ptr, Array))
  777.                 Return tmp
  778.             Case OBJ_EVENTPAGE
  779.                 If NewSize = 0 Then
  780.                     Delete[](Cast(EVENTPAGE Ptr, Array))
  781.                     Return NULL
  782.                 EndIf
  783.                 Var tmp = New EVENTPAGE[NewSize]
  784.                 CopyMemory(tmp, Array, min(OldSize, NewSize) * SizeOf(EVENTPAGE))
  785.                 Delete[](Cast(EVENTPAGE Ptr, Array))
  786.                 For i As Integer = OldSize To NewSize - 1
  787.                     Cast(EVENTPAGE Ptr, tmp)[i].ID = i + 1
  788.                 Next
  789.                 Return tmp
  790.             Case Else
  791.                 Return Array
  792.         End Select
  793.     End Function
  794.    
  795.     Function CopyString(Source As ZString Ptr) As ZString Ptr
  796.         Var l = lstrlen(Source)
  797.         Var d = CreateString(l)
  798.         memcpy(d, Source, l + 1)
  799.         Return d
  800.     End Function
  801.    
  802.     Sub CopyObject(Source As Any Ptr, Dest As Any Ptr, Array As Boolean = FALSE, Amount As Integer = 1)
  803.         If Array = FALSE Then Amount = 1
  804.         If IsBadReadPtr(Source, 4) Then Exit Sub
  805.         If IsBadReadPtr(Dest, 4) Then Exit Sub
  806.         If *Cast(Integer Ptr, Source) <> *Cast(Integer Ptr, Dest) Then Exit Sub
  807.         Select Case *Cast(Integer Ptr, Source)
  808.             Case OBJ_STARTCONDITIONS
  809.                 memcpy(Dest, Source, SizeOf(STARTCONDITIONS))
  810.             Case OBJ_MOVEEVENTCOMMAND
  811.                 memcpy(Dest, Source, SizeOf(MOVEEVENTCOMMAND) * Amount)
  812.                 For i As Integer = 1 To Amount
  813.                     If Cast(MOVEEVENTCOMMAND Ptr, Source)[i - 1].Sprite_Filename <> NULL Then
  814.                         Print "Src: " & *Cast(MOVEEVENTCOMMAND Ptr, Source)[i - 1].Sprite_Filename
  815.                         Cast(MOVEEVENTCOMMAND Ptr, Dest)[i - 1].Sprite_Filename = CopyString(Cast(MOVEEVENTCOMMAND Ptr, Source)[i - 1].Sprite_Filename)
  816.                         Print "Dst: " & *Cast(MOVEEVENTCOMMAND Ptr, Dest)[i - 1].Sprite_Filename
  817.                     Else
  818.                         Cast(MOVEEVENTCOMMAND Ptr, Dest)[i - 1].Sprite_Filename = NULL
  819.                     EndIf
  820.                     If Cast(MOVEEVENTCOMMAND Ptr, Source)[i - 1].SE_Filename <> NULL Then
  821.                         Cast(MOVEEVENTCOMMAND Ptr, Dest)[i - 1].SE_Filename = CopyString(Cast(MOVEEVENTCOMMAND Ptr, Source)[i - 1].SE_Filename)
  822.                     Else
  823.                         Cast(MOVEEVENTCOMMAND Ptr, Dest)[i - 1].SE_Filename = NULL
  824.                     EndIf
  825.                 Next
  826.             Case OBJ_MOVEEVENTDATA
  827.                 memcpy(Dest, Source, SizeOf(MOVEEVENTDATA))
  828.                 If Cast(MOVEEVENTDATA Ptr, Source)->Commands <> NULL Then
  829.                     Cast(MOVEEVENTDATA Ptr, Dest)->Commands = ResizeObjectArray(NULL, OBJ_MOVEEVENTCOMMAND, 0, Cast(MOVEEVENTDATA Ptr, Source)->CommandsAmount)
  830.                     CopyObject(Cast(MOVEEVENTDATA Ptr, Source)->Commands, Cast(MOVEEVENTDATA Ptr, Dest)->Commands, TRUE, Cast(MOVEEVENTDATA Ptr, Source)->CommandsAmount)
  831.                 Else
  832.                     Cast(MOVEEVENTDATA Ptr, Dest)->Commands = NULL
  833.                 EndIf
  834.             Case OBJ_EVENTCOMMAND
  835.                 memcpy(Dest, Source, SizeOf(EVENTCOMMAND) * Amount)
  836.                 For i As Integer = 1 To Amount
  837.                     If Cast(EVENTCOMMAND Ptr, Source)[i - 1].Params <> NULL Then
  838.                         Var mp = max(Cast(EVENTCOMMAND Ptr, Source)[i - 1].ParamsAmount, 64)
  839.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].Params = New Integer[mp]
  840.                         memcpy(Cast(EVENTCOMMAND Ptr, Dest)[i - 1].Params, Cast(EVENTCOMMAND Ptr, Source)[i - 1].Params, SizeOf(Integer) * mp)
  841.                     Else
  842.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].Params = NULL
  843.                     EndIf
  844.                     If Cast(EVENTCOMMAND Ptr, Source)[i - 1].MoveEventBlock <> NULL Then
  845.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].MoveEventBlock = CreateObject(OBJ_MOVEEVENTDATA)
  846.                         CopyObject(Cast(EVENTCOMMAND Ptr, Source)[i - 1].MoveEventBlock, Cast(EVENTCOMMAND Ptr, Dest)[i - 1].MoveEventBlock)
  847.                     Else
  848.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].MoveEventBlock = NULL
  849.                     EndIf
  850.                     If Cast(EVENTCOMMAND Ptr, Source)[i - 1].NameBlock <> NULL Then
  851.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].NameBlock = CopyString(Cast(EVENTCOMMAND Ptr, Source)[i - 1].NameBlock)
  852.                     Else
  853.                         Cast(EVENTCOMMAND Ptr, Dest)[i - 1].NameBlock = NULL
  854.                     EndIf
  855.                 Next
  856.             Case OBJ_EVENTPAGE
  857.                 Var id = Cast(EVENTPAGE Ptr, Dest)->ID
  858.                 memcpy(Dest, Source, SizeOf(EVENTPAGE) * Amount)
  859.                 Cast(EVENTPAGE Ptr, Dest)->ID = id
  860.                 For i As Integer = 1 To Amount
  861.                     If Cast(EVENTPAGE Ptr, Source)[i - 1].StartConditions <> NULL Then
  862.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].StartConditions = CreateObject(OBJ_STARTCONDITIONS)
  863.                         CopyObject(Cast(EVENTPAGE Ptr, Source)[i - 1].StartConditions, Cast(EVENTPAGE Ptr, Dest)[i - 1].StartConditions)
  864.                     Else
  865.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].StartConditions = NULL
  866.                     EndIf
  867.                     If Cast(EVENTPAGE Ptr, Source)[i - 1].Sprite_Filename <> NULL Then
  868.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].Sprite_Filename = CopyString(Cast(EVENTPAGE Ptr, Source)[i - 1].Sprite_Filename)
  869.                     Else
  870.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].Sprite_Filename = NULL
  871.                     EndIf
  872.                     If Cast(EVENTPAGE Ptr, Source)[i - 1].MovementPattern <> NULL Then
  873.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].MovementPattern = CreateObject(OBJ_MOVEEVENTDATA)
  874.                         CopyObject(Cast(EVENTPAGE Ptr, Source)[i - 1].MovementPattern, Cast(EVENTPAGE Ptr, Dest)[i - 1].MovementPattern)
  875.                     Else
  876.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].MovementPattern = NULL
  877.                     EndIf
  878.                     If Cast(EVENTPAGE Ptr, Source)[i - 1].Commands <> NULL Then
  879.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].Commands = ResizeObjectArray(NULL, OBJ_EVENTCOMMAND, 0, Cast(EVENTPAGE Ptr, Source)[i - 1].CommandsAmount)
  880.                         CopyObject(Cast(EVENTPAGE Ptr, Source)[i - 1].Commands, Cast(EVENTPAGE Ptr, Dest)[i - 1].Commands, TRUE, Cast(EVENTPAGE Ptr, Source)[i - 1].CommandsAmount)
  881.                     Else
  882.                         Cast(EVENTPAGE Ptr, Dest)[i - 1].Commands = NULL
  883.                     EndIf
  884.                 Next
  885.             Case OBJ_EVENT
  886.                 memcpy(Dest, Source, SizeOf(EVENT))
  887.                 If Cast(EVENT Ptr, Source)->Name <> NULL Then
  888.                     Cast(EVENT Ptr, Dest)->Name = CopyString(Cast(EVENT Ptr, Source)->Name)
  889.                 Else
  890.                     Cast(EVENT Ptr, Dest)->Name = NULL
  891.                 EndIf
  892.                 If Cast(EVENT Ptr, Source)->Pages <> NULL Then
  893.                     Cast(EVENT Ptr, Dest)->Pages = ResizeObjectArray(NULL, OBJ_EVENTPAGE, 0, Cast(EVENT Ptr, Source)->PagesAmount)
  894.                     CopyObject(Cast(EVENT Ptr, Source)->Pages, Cast(EVENT Ptr, Dest)->Pages, TRUE, Cast(EVENT Ptr, Source)->PagesAmount)
  895.                 Else
  896.                     Cast(EVENT Ptr, Dest)->Pages = NULL
  897.                 EndIf
  898.                 If Cast(EVENT Ptr, Source)->ExtraInformation <> NULL Then
  899.                     Cast(EVENT Ptr, Dest)->ExtraInformation = New EXTRAINFORMATION
  900.                     For i As Integer = 0 To &hFF
  901.                         Cast(EVENT Ptr, Dest)->ExtraInformation->i(i) = Cast(EVENT Ptr, Source)->ExtraInformation->i(i)
  902.                     Next
  903.                 Else
  904.                     Cast(EVENT Ptr, Dest)->ExtraInformation = NULL
  905.                 EndIf
  906.             Case Else
  907.                 ' Do nothing
  908.         End Select
  909.     End Sub
  910.    
  911.     Sub DestroyObject(Object As Any Ptr, Array As Boolean = FALSE, Amount As Integer = 1)
  912.         If Array = FALSE Then Amount = 1
  913.         If IsBadReadPtr(Object, 4) Then Exit Sub
  914.         Select Case *Cast(Integer Ptr, Object)
  915.             Case OBJ_STARTCONDITIONS
  916.                 Delete(Cast(STARTCONDITIONS Ptr, Object))
  917.             Case OBJ_MOVEEVENTCOMMAND
  918.                 For i As Integer = 1 To Amount
  919.                     DeAllocate(Cast(MOVEEVENTCOMMAND Ptr, Object)[i - 1].Sprite_Filename)
  920.                     DeAllocate(Cast(MOVEEVENTCOMMAND Ptr, Object)[i - 1].SE_Filename)
  921.                 Next
  922.                 If Array Then
  923.                     Delete[](Cast(MOVEEVENTCOMMAND Ptr, Object))
  924.                 Else
  925.                     Delete(Cast(MOVEEVENTCOMMAND Ptr, Object))
  926.                 EndIf
  927.             Case OBJ_MOVEEVENTDATA
  928.                 DestroyObject(Cast(MOVEEVENTDATA Ptr, Object)->Commands, TRUE, Cast(MOVEEVENTDATA Ptr, Object)->CommandsAmount)
  929.                 Delete(Cast(MOVEEVENTDATA Ptr, Object))
  930.             Case OBJ_EVENTCOMMAND
  931.                 For i As Integer = 1 To Amount
  932.                     Delete[](Cast(EVENTCOMMAND Ptr, Object)[i - 1].Params)
  933.                     DestroyObject(Cast(EVENTCOMMAND Ptr, Object)[i - 1].MoveEventBlock)
  934.                 Next
  935.                 If Array Then
  936.                     Delete[](Cast(EVENTCOMMAND Ptr, Object))
  937.                 Else
  938.                     Delete(Cast(EVENTCOMMAND Ptr, Object))
  939.                 EndIf
  940.             Case OBJ_EVENTPAGE
  941.                 For i As Integer = 1 To Amount
  942.                     DestroyObject(Cast(EVENTPAGE Ptr, Object)[i - 1].StartConditions)
  943.                     DeAllocate(Cast(EVENTPAGE Ptr, Object)[i - 1].Sprite_Filename)
  944.                     DestroyObject(Cast(EVENTPAGE Ptr, Object)[i - 1].MovementPattern)
  945.                     DestroyObject(Cast(EVENTPAGE Ptr, Object)[i - 1].Commands, TRUE, Cast(EVENTPAGE Ptr, Object)[i - 1].CommandsAmount)
  946.                 Next
  947.                 If Array Then
  948.                     Delete[](Cast(EVENTPAGE Ptr, Object))
  949.                 Else
  950.                     Delete(Cast(EVENTPAGE Ptr, Object))
  951.                 EndIf
  952.             Case OBJ_EVENT
  953.                 DeAllocate(Cast(EVENT Ptr, Object)->Name)
  954.                 DestroyObject(Cast(EVENT Ptr, Object)->Pages, TRUE)
  955.                 Delete(Cast(EVENT Ptr, Object)->ExtraInformation)
  956.                 Delete(Cast(EVENT Ptr, Object))
  957.             Case Else
  958.                 DeAllocate(Object)
  959.         End Select
  960.     End Sub
  961.    
  962.     Sub DeleteExtraInformation(Data_ As EXTRAINFORMATION Ptr)
  963.         Delete(Data_)
  964.     End Sub
  965.        
  966.     Function ResizeIntArray(Array As Integer Ptr, OldSize As Integer, NewSize As Integer) As Integer Ptr
  967.         If NewSize = 0 Then
  968.             Delete[](Array)
  969.             Return NULL
  970.         EndIf
  971.         Var tmp = New Integer[NewSize]
  972.         CopyMemory(tmp, Array, min(OldSize, NewSize) * SizeOf(Integer))
  973.         Delete[](Array)
  974.         Return tmp
  975.     End Function
  976.    
  977.     Sub DestroyIntArray(Array As Integer Ptr)
  978.         If IsBadReadPtr(Array, 1) Then Exit Sub
  979.         Delete[](Array)
  980.     End Sub
  981.    
  982.    
  983.     ' ********* Clipboard reading functions *********
  984.    
  985.     Function CheckClipboardContent() As CLIPBOARDCONTENTTYPE
  986.         If IsClipboardFormatAvailable(CBCT_TEXT) Then Return CBCT_TEXT
  987.         If IsClipboardFormatAvailable(CBCT_EVENT) Then Return CBCT_EVENT
  988.         If IsClipboardFormatAvailable(CBCT_EVENTPAGE) Then Return CBCT_EVENTPAGE
  989.         If IsClipboardFormatAvailable(CBCT_BATTLEEVENTPAGE) Then Return CBCT_BATTLEEVENTPAGE
  990.         If IsClipboardFormatAvailable(CBCT_EVENTCOMMANDS) Then Return CBCT_EVENTCOMMANDS
  991.         If IsClipboardFormatAvailable(CBCT_MONSTERGROUP) Then Return CBCT_MONSTERGROUP
  992.         If IsClipboardFormatAvailable(CBCT_COMMONEVENT) Then Return CBCT_COMMONEVENT
  993.         Return CBCT_UNKNOWN
  994.     End Function   
  995.    
  996.     Sub AdjustTreeDepth(Page As EVENTPAGE Ptr)
  997.         Dim mintd As UInteger = -1 ' Trick: get the lowest value
  998.         For i As Integer = 0 To Page->CommandsAmount - 1
  999.             mintd = min(mintd, Page->Commands[i].TreeDepth)
  1000.         Next
  1001.         For i As Integer = 0 To Page->CommandsAmount - 1
  1002.             Page->Commands[i].TreeDepth -= mintd
  1003.         Next
  1004.     End Sub
  1005.    
  1006.     Sub ReadMoveEventCommands(ByRef Stream As StreamReader, MoveEvent As MOVEEVENTDATA Ptr, Length As Integer, Coded As Boolean = FALSE)
  1007.         Var StreamStartPosition = Stream.Position
  1008.         Do While Stream.Position < Length + StreamStartPosition
  1009.             MoveEvent->CommandsAmount += 1
  1010.             MoveEvent->Commands = ResizeObjectArray(MoveEvent->Commands, OBJ_MOVEEVENTCOMMAND, MoveEvent->CommandsAmount - 1, MoveEvent->CommandsAmount)
  1011.             Var cmd = Stream.ReadBER()
  1012.             MoveEvent->Commands[MoveEvent->CommandsAmount - 1].Command = cmd
  1013.             Select Case cmd
  1014.                 Case MOVEEVENTCOMMAND.ME_SWITCH_ON, MOVEEVENTCOMMAND.ME_SWITCH_OFF
  1015.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].Switch_ID = Stream.ReadBER()
  1016.                 Case MOVEEVENTCOMMAND.ME_CHANGE_GRAPHIC
  1017.                     Var slen = Stream.ReadBER()
  1018.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].Sprite_Filename = CreateString(slen)
  1019.                     *MoveEvent->Commands[MoveEvent->CommandsAmount - 1].Sprite_Filename = Stream.ReadString(slen, Coded)
  1020.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].Sprite_ID = Stream.ReadBER()
  1021.                 Case MOVEEVENTCOMMAND.ME_PLAY_SE
  1022.                     Var slen = Stream.ReadBER()
  1023.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Filename = CreateString(slen)
  1024.                     If Coded Then
  1025.                         For i As Integer = 1 To slen
  1026.                             *MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Filename &= Chr(Stream.ReadBER())
  1027.                         Next
  1028.                     Else
  1029.                         *MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Filename = Stream.ReadString(slen)
  1030.                     EndIf
  1031.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Volume = Stream.ReadBER()
  1032.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Tempo = Stream.ReadBER()
  1033.                     MoveEvent->Commands[MoveEvent->CommandsAmount - 1].SE_Balance = Stream.ReadBER()
  1034.             End Select
  1035.         Loop
  1036.     End Sub
  1037.    
  1038.     Sub ReadEventCommands(ByRef Stream As StreamReader, Page As EVENTPAGE Ptr, Length As Integer)
  1039.         Var StreamStartPosition = Stream.Position
  1040.         Do While Stream.Position < Length + StreamStartPosition
  1041.             Page->CommandsAmount += 1
  1042.             Page->Commands = ResizeObjectArray(Page->Commands, OBJ_EVENTCOMMAND, Page->CommandsAmount - 1, Page->CommandsAmount)
  1043.             Var cmd = Stream.ReadBER()
  1044.             Page->Commands[Page->CommandsAmount - 1].Command = cmd
  1045.             Page->Commands[Page->CommandsAmount - 1].TreeDepth = Stream.ReadBER()
  1046.             Var slen = Stream.ReadBER()
  1047.             If slen Then
  1048.                 Page->Commands[Page->CommandsAmount - 1].NameBlock = CreateString(slen)
  1049.                 *Page->Commands[Page->CommandsAmount - 1].NameBlock = Stream.ReadString(slen)
  1050.             EndIf
  1051.             If cmd = EVCMD_MOVE_EVENT Then
  1052.                 Var count = Stream.ReadBER()
  1053.                 Page->Commands[Page->CommandsAmount - 1].Params = New Integer[64]
  1054.                 Page->Commands[Page->CommandsAmount - 1].MoveEventBlock = New MOVEEVENTDATA
  1055.                 Page->Commands[Page->CommandsAmount - 1].MoveEventBlock->Target = Stream.ReadBER()
  1056.                 Page->Commands[Page->CommandsAmount - 1].MoveEventBlock->Frequency = Stream.ReadBER()
  1057.                 Page->Commands[Page->CommandsAmount - 1].MoveEventBlock->RepeatPattern = Stream.ReadBER()
  1058.                 Page->Commands[Page->CommandsAmount - 1].MoveEventBlock->IgnoreImpossible = Stream.ReadBER()
  1059.                 count -= 4
  1060.                 Var cpos = Stream.Position
  1061.                 For i As Integer = 0 To count - 1
  1062.                     Stream.ReadBER() ' Throw away
  1063.                 Next
  1064.                 Var clen = Stream.Position - cpos
  1065.                 Stream.Position = cpos
  1066.                 ReadMoveEventCommands(Stream, Page->Commands[Page->CommandsAmount - 1].MoveEventBlock, clen, TRUE)
  1067.             Else
  1068.                 Page->Commands[Page->CommandsAmount - 1].ParamsAmount = Stream.ReadBER()
  1069.                 Var mp = max(Page->Commands[Page->CommandsAmount - 1].ParamsAmount, 64)
  1070.                 Page->Commands[Page->CommandsAmount - 1].Params = New Integer[mp]
  1071.                 For i As Integer = 0 To Page->Commands[Page->CommandsAmount - 1].ParamsAmount - 1
  1072.                     Page->Commands[Page->CommandsAmount - 1].Params[i] = Stream.ReadBER()
  1073.                 Next
  1074.             EndIf
  1075.             If cmd = 0 Then
  1076.                 Page->CommandsAmount -= 1
  1077.                 Page->Commands = ResizeObjectArray(Page->Commands, OBJ_EVENTCOMMAND, Page->CommandsAmount + 1, Page->CommandsAmount)
  1078.                 Exit Do
  1079.             EndIf
  1080.         Loop
  1081.         AdjustTreeDepth(Page)
  1082.     End Sub
  1083.    
  1084.     Sub ReadEventPage(ByRef Stream As StreamReader, Event_ As EVENT Ptr, pagenum As Integer = -1)
  1085.         Var cpagenum = pagenum
  1086.         If pagenum = -1 Then cpagenum = Stream.ReadBER()
  1087.         Dim cpage As EVENTPAGE Ptr
  1088.         If cpagenum <= Event_->PagesAmount Then cpage = @(Event_->Pages[cpagenum - 1]) Else cpage = Event_->Pages
  1089.         cpage->ID = cpagenum
  1090.         Dim ScriptLength As Integer
  1091.         Do
  1092.             Select Case Stream.ReadBER()
  1093.                 Case &h00
  1094.                     ' End of block
  1095.                     Exit Do
  1096.                 Case &h02
  1097.                     ' Start conditions
  1098.                     Var StreamLength3 = Stream.ReadBER()
  1099.                     Var StreamStartPosition3 = Stream.Position
  1100.                     cpage->StartConditions = New STARTCONDITIONS
  1101.                     Var ccond = cpage->StartConditions
  1102.                     Do While Stream.Position < StreamLength3 + StreamStartPosition3
  1103.                         Select Case Stream.ReadBER()
  1104.                             Case &h00
  1105.                                 ' End of block
  1106.                                 Exit Do
  1107.                             Case &h01
  1108.                                 ' Bitfield - which cond. are used?
  1109.                                 Var l = Stream.ReadBER()
  1110.                                 Dim fld As Integer = 0
  1111.                                 For i As Integer = 1 To l
  1112.                                     fld Shl= 8
  1113.                                     fld Or= Stream.ReadByte()
  1114.                                 Next
  1115.                                 ccond->Used Or= fld And &h7F
  1116.                             Case &h02
  1117.                                 ' Switch 1 ID
  1118.                                 Stream.ReadBER() ' Throw away
  1119.                                 ccond->Switch1_ID = Stream.ReadBER()
  1120.                             Case &h03
  1121.                                 ' Switch 2 ID
  1122.                                 Stream.ReadBER() ' Throw away
  1123.                                 ccond->Switch2_ID = Stream.ReadBER()
  1124.                             Case &h04
  1125.                                 ' Variable ID
  1126.                                 Stream.ReadBER() ' Throw away
  1127.                                 ccond->Variable_ID = Stream.ReadBER()
  1128.                             Case &h05
  1129.                                 ' Variable Value
  1130.                                 Stream.ReadBER() ' Throw away
  1131.                                 ccond->Variable_Value = Stream.ReadBER()
  1132.                             Case &h06
  1133.                                 ' Item ID
  1134.                                 Stream.ReadBER() ' Throw away
  1135.                                 ccond->Item_ID = Stream.ReadBER()
  1136.                             Case &h07
  1137.                                 ' Hero ID
  1138.                                 Stream.ReadBER() ' Throw away
  1139.                                 ccond->HeroInParty_HeroID = Stream.ReadBER()
  1140.                             Case &h08
  1141.                                 ' Timer 1 sec. remaining
  1142.                                 Stream.ReadBER() ' Throw away
  1143.                                 ccond->Timer1_Sec = Stream.ReadBER()
  1144.                             Case &h09
  1145.                                 ' Timer 2 sec. remaining
  1146.                                 Stream.ReadBER() ' Throw away
  1147.                                 ccond->Timer2_Sec = Stream.ReadBER()
  1148.                             Case &h0A
  1149.                                 ' Variable comparison
  1150.                                 Stream.ReadBER() ' Throw away
  1151.                                 ccond->Variable_Comparison = Stream.ReadBER()
  1152.                             Case Else
  1153.                                 Var slen = Stream.ReadBER()
  1154.                                 Stream.Position += slen
  1155.                         End Select
  1156.                     Loop
  1157.                 Case &h15
  1158.                     ' Sprite filename
  1159.                     Var slen = Stream.ReadBER()
  1160.                     cpage->Sprite_Filename = CreateString(slen)
  1161.                     *cpage->Sprite_Filename = Stream.ReadString(slen)
  1162.                 Case &h16
  1163.                     ' Sprite ID
  1164.                     Stream.ReadBER() ' Throw away
  1165.                     cpage->Sprite_ID = Stream.ReadBER()
  1166.                 Case &h17
  1167.                     ' Facing direction
  1168.                     Stream.ReadBER() ' Throw away
  1169.                     cpage->FacingDirection = Stream.ReadBER()
  1170.                 Case &h18
  1171.                     ' Animation frame
  1172.                     Stream.ReadBER() ' Throw away
  1173.                     cpage->Frame = Stream.ReadBER()
  1174.                 Case &h19
  1175.                     ' Transparency
  1176.                     Stream.ReadBER() ' Throw away
  1177.                     cpage->Sprite_Transparency = Stream.ReadBER() And TRUE
  1178.                 Case &h1F
  1179.                     ' Movement type
  1180.                     Stream.ReadBER() ' Throw away
  1181.                     cpage->MovementType = Stream.ReadBER()
  1182.                 Case &h20
  1183.                     ' Movement frequency
  1184.                     Stream.ReadBER() ' Throw away
  1185.                     cpage->MovementFrequency = Stream.ReadBER()
  1186.                 Case &h21
  1187.                     ' Trigger condition
  1188.                     Stream.ReadBER() ' Throw away
  1189.                     cpage->Trigger = Stream.ReadBER()
  1190.                 Case &h22
  1191.                     ' Event level
  1192.                     Stream.ReadBER() ' Throw away
  1193.                     cpage->EventLevel = Stream.ReadBER()
  1194.                 Case &h23
  1195.                     ' Forbid event overlap
  1196.                     Stream.ReadBER() ' Throw away
  1197.                     cpage->ForbidEventOverlap = Stream.ReadBER() And TRUE
  1198.                 Case &h24
  1199.                     ' Animation type
  1200.                     Stream.ReadBER() ' Throw away
  1201.                     cpage->AnimationType = Stream.ReadBER()
  1202.                 Case &h25
  1203.                     ' Movement speed
  1204.                     Stream.ReadBER() ' Throw away
  1205.                     cpage->MovementSpeed = Stream.ReadBER()
  1206.                 Case &h29
  1207.                     ' Movement pattern
  1208.                     Var StreamLength3 = Stream.ReadBER()
  1209.                     Var StreamStartPosition3 = Stream.Position
  1210.                     cpage->MovementPattern = New MOVEEVENTDATA
  1211.                     Var cpattern = cpage->MovementPattern
  1212.                     cpattern->RepeatPattern = TRUE
  1213.                     cpattern->Target = EV_THIS
  1214.                     cpattern->Frequency = cpage->MovementFrequency
  1215.                     Dim MoveLength As Integer
  1216.                     Do While Stream.Position < StreamLength3 + StreamStartPosition3
  1217.                         Select Case Stream.ReadBER()
  1218.                             Case &h00
  1219.                                 ' End of block
  1220.                                 Exit Do
  1221.                             Case &h0B
  1222.                                 ' Move event length
  1223.                                 Stream.ReadBER() ' Throw away
  1224.                                 MoveLength = Stream.ReadBER()
  1225.                             Case &h0C
  1226.                                 ' Move event data
  1227.                                 ReadMoveEventCommands(Stream, cpattern, Stream.ReadBER())
  1228.                             Case &h15
  1229.                                 ' Repeat pattern
  1230.                                 Stream.ReadBER() ' Throw away
  1231.                                 cpattern->RepeatPattern = Stream.ReadBER() And TRUE
  1232.                             Case &h16
  1233.                                 ' Ignore impossible
  1234.                                 Stream.ReadBER() ' Throw away
  1235.                                 cpattern->IgnoreImpossible = Stream.ReadBER() And TRUE
  1236.                             Case Else
  1237.                                 Var slen = Stream.ReadBER()
  1238.                                 Stream.Position += slen
  1239.                         End Select
  1240.                     Loop
  1241.                 Case &h33
  1242.                     ' Script length
  1243.                     Stream.ReadBER() ' Throw away
  1244.                     ScriptLength = Stream.ReadBER()
  1245.                 Case &h34
  1246.                     ' Script
  1247.                     ReadEventCommands(Stream, cpage, Stream.ReadBER())
  1248.                 Case Else
  1249.                     Var slen = Stream.ReadBER()
  1250.                     Stream.Position += slen
  1251.             End Select
  1252.         Loop
  1253.     End Sub
  1254.    
  1255.     Sub ReadBattleEventPage(ByRef Stream As StreamReader, Event_ As EVENT Ptr, pagenum As Integer = -1)
  1256.         Var cpagenum = pagenum
  1257.         If pagenum = -1 Then cpagenum = Stream.ReadBER()
  1258.         Dim cpage As EVENTPAGE Ptr
  1259.         If cpagenum <= Event_->PagesAmount Then cpage = @(Event_->Pages[cpagenum - 1]) Else cpage = Event_->Pages
  1260.         cpage->ID = cpagenum
  1261.         Dim ScriptLength As Integer
  1262.         Do
  1263.             Select Case Stream.ReadBER()
  1264.                 Case &h00
  1265.                     ' End of block
  1266.                     Exit Do
  1267.                 Case &h02
  1268.                     ' Start conditions
  1269.                     Var StreamLength3 = Stream.ReadBER()
  1270.                     Var StreamStartPosition3 = Stream.Position
  1271.                     cpage->StartConditions = New STARTCONDITIONS
  1272.                     Var ccond = cpage->StartConditions
  1273.                     Do While Stream.Position < StreamLength3 + StreamStartPosition3
  1274.                         Select Case Stream.ReadBER()
  1275.                             Case &h00
  1276.                                 ' End of block
  1277.                                 Exit Do
  1278.                             Case &h01
  1279.                                 ' Bitfield - which cond. are used?
  1280.                                 Var l = Stream.ReadBER()
  1281.                                 Dim fld As Integer = 0
  1282.                                 For i As Integer = 1 To l
  1283.                                     fld Or= Stream.ReadByte() Shl (i - 1) * 8
  1284.                                 Next
  1285.                                 ccond->Used = fld And &h007
  1286.                                 If fld And &h008 Then ccond->Used Or= STARTCONDITIONS.EPSC_TURNS
  1287.                                 If fld And &h010 Then ccond->Used Or= STARTCONDITIONS.EPSC_EXHAUSTION
  1288.                                 If fld And &h020 Then ccond->Used Or= STARTCONDITIONS.EPSC_MONSTER_HP
  1289.                                 If fld And &h040 Then ccond->Used Or= STARTCONDITIONS.EPSC_HERO_HP
  1290.                                 If fld And &h080 Then ccond->Used Or= STARTCONDITIONS.EPSC_MONSTER_TURNS
  1291.                                 If fld And &h100 Then ccond->Used Or= STARTCONDITIONS.EPSC_HERO_TURNS
  1292.                                 If fld And &h200 Then ccond->Used Or= STARTCONDITIONS.EPSC_HERO_COMMAND
  1293.                             Case &h02
  1294.                                 ' Switch 1 ID
  1295.                                 Stream.ReadBER() ' Throw away
  1296.                                 ccond->Switch1_ID = Stream.ReadBER()
  1297.                             Case &h03
  1298.                                 ' Switch 2 ID
  1299.                                 Stream.ReadBER() ' Throw away
  1300.                                 ccond->Switch2_ID = Stream.ReadBER()
  1301.                             Case &h04
  1302.                                 ' Variable ID
  1303.                                 Stream.ReadBER() ' Throw away
  1304.                                 ccond->Variable_ID = Stream.ReadBER()
  1305.                             Case &h05
  1306.                                 ' Variable Value
  1307.                                 Stream.ReadBER() ' Throw away
  1308.                                 ccond->Variable_Value = Stream.ReadBER()
  1309.                             Case &h06
  1310.                                 ' Turns elapsed (A)
  1311.                                 Stream.ReadBER() ' Throw away
  1312.                                 ccond->Turns_Elapsed1 = Stream.ReadBER()
  1313.                             Case &h07
  1314.                                 ' Turns elapsed (B)
  1315.                                 Stream.ReadBER() ' Throw away
  1316.                                 ccond->Turns_Elapsed2 = Stream.ReadBER()
  1317.                             Case &h08
  1318.                                 ' Exhaustion min.
  1319.                                 Stream.ReadBER() ' Throw away
  1320.                                 ccond->Exhaustion_Min = Stream.ReadBER()
  1321.                             Case &h09
  1322.                                 ' Exhaustion max.
  1323.                                 Stream.ReadBER() ' Throw away
  1324.                                 ccond->Exhaustion_Max = Stream.ReadBER()
  1325.                             Case &h0A
  1326.                                 ' Monster HP: Monster ID
  1327.                                 Stream.ReadBER() ' Throw away
  1328.                                 ccond->MonsterHP_MonsterID = Stream.ReadBER() + 1
  1329.                             Case &h0B
  1330.                                 ' Monster HP: HP min.
  1331.                                 Stream.ReadBER() ' Throw away
  1332.                                 ccond->MonsterHP_Min = Stream.ReadBER()
  1333.                             Case &h0C
  1334.                                 ' Monster HP: HP max.
  1335.                                 Stream.ReadBER() ' Throw away
  1336.                                 ccond->MonsterHP_Max = Stream.ReadBER()
  1337.                             Case &h0D
  1338.                                 ' Hero HP: Hero ID
  1339.                                 Stream.ReadBER() ' Throw away
  1340.                                 ccond->HeroHP_HeroID = Stream.ReadBER()
  1341.                             Case &h0E
  1342.                                 ' Hero HP: HP min.
  1343.                                 Stream.ReadBER() ' Throw away
  1344.                                 ccond->HeroHP_Min = Stream.ReadBER()
  1345.                             Case &h0F
  1346.                                 ' Hero HP: HP max.
  1347.                                 Stream.ReadBER() ' Throw away
  1348.                                 ccond->HeroHP_Max = Stream.ReadBER()
  1349.                             Case &h10
  1350.                                 ' Monster turns: Monster ID
  1351.                                 Stream.ReadBER() ' Throw away
  1352.                                 ccond->MonsterTurns_MonsterID = Stream.ReadBER() + 1
  1353.                             Case &h11
  1354.                                 ' Monster turns: Turns elapsed (A)
  1355.                                 Stream.ReadBER() ' Throw away
  1356.                                 ccond->MonsterTurns_TurnsElapsed1 = Stream.ReadBER()
  1357.                             Case &h12
  1358.                                 ' Monster turns: Turns elapsed (B)
  1359.                                 Stream.ReadBER() ' Throw away
  1360.                                 ccond->MonsterTurns_TurnsElapsed2 = Stream.ReadBER()
  1361.                             Case &h13
  1362.                                 ' Hero turns: Hero ID
  1363.                                 Stream.ReadBER() ' Throw away
  1364.                                 ccond->HeroTurns_HeroID = Stream.ReadBER()
  1365.                             Case &h14
  1366.                                 ' Hero turns: Turns elapsed (A)
  1367.                                 Stream.ReadBER() ' Throw away
  1368.                                 ccond->HeroTurns_TurnsElapsed1 = Stream.ReadBER()
  1369.                             Case &h15
  1370.                                 ' Hero turns: Turns elapsed (B)
  1371.                                 Stream.ReadBER() ' Throw away
  1372.                                 ccond->HeroTurns_TurnsElapsed2 = Stream.ReadBER()
  1373.                             Case &h16
  1374.                                 ' Hero command: Hero ID
  1375.                                 Stream.ReadBER() ' Throw away
  1376.                                 ccond->HeroCommand_HeroID = Stream.ReadBER()
  1377.                             Case &h17
  1378.                                 ' Hero command: Command ID
  1379.                                 Stream.ReadBER() ' Throw away
  1380.                                 ccond->HeroCommand_CommandID = Stream.ReadBER()
  1381.                             Case Else
  1382.                                 Var slen = Stream.ReadBER()
  1383.                                 Stream.Position += slen
  1384.                         End Select
  1385.                     Loop
  1386.                 Case &h0B
  1387.                     ' Script length
  1388.                     Stream.ReadBER() ' Throw away
  1389.                     ScriptLength = Stream.ReadBER()
  1390.                 Case &h0C
  1391.                     ' Script
  1392.                     ReadEventCommands(Stream, cpage, Stream.ReadBER())
  1393.                 Case Else
  1394.                     Var slen = Stream.ReadBER()
  1395.                     Stream.Position += slen
  1396.             End Select
  1397.         Loop
  1398.     End Sub
  1399.    
  1400.     Function GetClipboardContent(ContentType As CLIPBOARDCONTENTTYPE, Content As String = "$CLIP") As Any Ptr
  1401.         If Content = "$CLIP" Then Content = ReadClipboard(ContentType)
  1402.         If Len(Content) = 0 Then Return 0
  1403.         Select Case ContentType
  1404.             Case CBCT_TEXT
  1405.                 ' Text
  1406.                 Dim ret As ZString Ptr = CreateString(Len(Content))
  1407.                 *ret = Content
  1408.                 Return ret
  1409.             Case CBCT_EVENT
  1410.                 ' Map event
  1411.                 Var ret = New Event
  1412.                 Var Stream = StreamReader(Content)
  1413.                 Var StreamLength = Stream.ReadInt()
  1414.                 ret->Type_ = EVENT.EVT_MAP
  1415.                 Stream.ReadByte() ' Throw away
  1416.                 Do While Stream.Position < StreamLength
  1417.                     Select Case Stream.ReadBER()
  1418.                         Case &h00
  1419.                             ' End of block
  1420.                             Exit Do
  1421.                         Case &h01
  1422.                             ' Name
  1423.                             Var slen = Stream.ReadBER()
  1424.                             ret->Name = CreateString(slen)
  1425.                             *ret->Name = Stream.ReadString(slen)
  1426.                         Case &h02
  1427.                             ' X position
  1428.                             Stream.ReadBER() ' Throw away
  1429.                             ret->Coordinates.x = Stream.ReadBER()
  1430.                         Case &h03
  1431.                             ' Y position
  1432.                             Stream.ReadBER() ' Throw away
  1433.                             ret->Coordinates.y = Stream.ReadBER()
  1434.                         Case &h05
  1435.                             ' Pages
  1436.                             Var StreamLength2 = Stream.ReadBER()
  1437.                             Var StreamStartPosition2 = Stream.Position
  1438.                             ret->PagesAmount = Stream.ReadBER()
  1439.                             ret->Pages = New EVENTPAGE[ret->PagesAmount]
  1440.                             Do While Stream.Position < StreamLength2 + StreamStartPosition2
  1441.                                 ReadEventPage(Stream, ret)
  1442.                             Loop
  1443.                         Case Else
  1444.                             Var slen = Stream.ReadBER()
  1445.                             Stream.Position += slen
  1446.                     End Select
  1447.                 Loop
  1448.                 Return ret
  1449.             Case CBCT_EVENTPAGE
  1450.                 ' Event page
  1451.                 Var ret = New Event
  1452.                 Var Stream = StreamReader(Content)
  1453.                 Var StreamLength = Stream.ReadInt()
  1454.                 ret->Type_ = EVENT.EVT_MAP
  1455.                 ret->PagesAmount = 1
  1456.                 ret->Pages = New EVENTPAGE[1]
  1457.                 ReadEventPage(Stream, ret, Stream.ReadInt())
  1458.                 Return ret
  1459.             Case CBCT_BATTLEEVENTPAGE
  1460.                 ' Battle event page
  1461.                 Var ret = New Event
  1462.                 Var Stream = StreamReader(Content)
  1463.                 Var StreamLength = Stream.ReadInt()
  1464.                 ret->Type_ = EVENT.EVT_BATTLE
  1465.                 ret->PagesAmount = 1
  1466.                 ret->Pages = New EVENTPAGE[1]
  1467.                 ReadBattleEventPage(Stream, ret, Stream.ReadInt())
  1468.                 Return ret
  1469.             Case CBCT_EVENTCOMMANDS
  1470.                 ' Event commands
  1471.                 Var ret = New Event
  1472.                 Var Stream = StreamReader(Content)
  1473.                 Var StreamLength = Stream.ReadInt()
  1474.                 ret->Type_ = EVENT.EVT_UNKNOWN
  1475.                 ret->PagesAmount = 1
  1476.                 ret->Pages = New EVENTPAGE[1]
  1477.                 Var cpage = ret->Pages
  1478.                 cpage->ID = 1
  1479.                 cpage->StartConditions = New STARTCONDITIONS
  1480.                 ReadEventCommands(Stream, cpage, StreamLength)
  1481.                 Return ret
  1482.             Case CBCT_MONSTERGROUP
  1483.                 ' Monster group
  1484.                 Var ret = New Event
  1485.                 Var Stream = StreamReader(Content)
  1486.                 Var StreamLength = Stream.ReadInt()
  1487.                 ret->Type_ = EVENT.EVT_BATTLE
  1488.                 ret->ID = Stream.ReadInt()
  1489.                 Do While Stream.Position < StreamLength
  1490.                     Var dataid = Stream.ReadBER()
  1491.                     Select Case dataid
  1492.                         Case &h00
  1493.                             ' End of block
  1494.                             Exit Do
  1495.                         Case &h01
  1496.                             ' Name
  1497.                             Var slen = Stream.ReadBER()
  1498.                             ret->Name = CreateString(slen)
  1499.                             *ret->Name = Stream.ReadString(slen)
  1500.                         Case &h0B
  1501.                             ' Pages
  1502.                             Var StreamLength2 = Stream.ReadBER()
  1503.                             Var StreamStartPosition2 = Stream.Position
  1504.                             ret->PagesAmount = Stream.ReadBER()
  1505.                             ret->Pages = New EVENTPAGE[ret->PagesAmount]
  1506.                             Do While Stream.Position < StreamLength2 + StreamStartPosition2
  1507.                                 ReadBattleEventPage(Stream, ret)
  1508.                             Loop
  1509.                         Case Else
  1510.                             ' Other monster group information
  1511.                             Var slen = Stream.ReadBER()
  1512.                             If ret->ExtraInformation = NULL Then ret->ExtraInformation = New EXTRAINFORMATION
  1513.                             If Cast(UInteger, dataid) < &h100 Then
  1514.                                 ret->ExtraInformation->i(dataid) = Stream.ReadString(slen)
  1515.                             Else
  1516.                                 Stream.Position += slen
  1517.                             EndIf
  1518.                     End Select
  1519.                 Loop
  1520.                 Return ret
  1521.             Case CBCT_COMMONEVENT
  1522.                 ' Common event
  1523.                 Var ret = New Event
  1524.                 Var Stream = StreamReader(Content)
  1525.                 Var StreamLength = Stream.ReadInt()
  1526.                 Dim ScriptLength As Integer
  1527.                 ret->Type_ = EVENT.EVT_COMMON
  1528.                 ret->ID = Stream.ReadInt()
  1529.                 ret->PagesAmount = 1
  1530.                 ret->Pages = New EVENTPAGE[1]
  1531.                 Var cpage = ret->Pages
  1532.                 cpage->ID = 1
  1533.                 cpage->StartConditions = New STARTCONDITIONS
  1534.                 Var ccond = cpage->StartConditions
  1535.                 Do While Stream.Position < StreamLength
  1536.                     Select Case Stream.ReadBER()
  1537.                         Case &h00
  1538.                             ' End of block
  1539.                             Exit Do
  1540.                         Case &h01
  1541.                             ' Name
  1542.                             Var slen = Stream.ReadBER()
  1543.                             ret->Name = CreateString(slen)
  1544.                             *ret->Name = Stream.ReadString(slen)
  1545.                         Case &h0B
  1546.                             ' Activation condition
  1547.                             Stream.ReadBER() ' Throw away
  1548.                             Select Case Stream.ReadBER()
  1549.                                 Case 3
  1550.                                     cpage->Trigger = EVENTPAGE.EPTC_AUTOSTART
  1551.                                 Case 4
  1552.                                     cpage->Trigger = EVENTPAGE.EPTC_PARALLEL
  1553.                                 Case 5
  1554.                                     cpage->Trigger = EVENTPAGE.EPTC_CALL
  1555.                             End Select
  1556.                         Case &h0C
  1557.                             ' Use switch?
  1558.                             Stream.ReadBER() ' Throw away
  1559.                             If (cpage->Trigger = EVENTPAGE.EPTC_AUTOSTART Or cpage->Trigger = EVENTPAGE.EPTC_PARALLEL) Then ccond->Used = IIf(Stream.ReadBER(), STARTCONDITIONS.EPSC_SWITCH1, 0)
  1560.                         Case &h0D
  1561.                             ' Switch ID
  1562.                             Stream.ReadBER() ' Throw away
  1563.                             Var sid = Stream.ReadBER()
  1564.                             ccond->Switch1_ID = sid
  1565.                         Case &h15
  1566.                             ' Script length
  1567.                             Stream.ReadBER() ' Throw away
  1568.                             ScriptLength = Stream.ReadBER()
  1569.                         Case &h16
  1570.                             ' Script
  1571.                             ReadEventCommands(Stream, cpage, Stream.ReadBER())
  1572.                         Case Else
  1573.                             Var slen = Stream.ReadBER()
  1574.                             Stream.Position += slen
  1575.                     End Select
  1576.                 Loop
  1577.                 Return ret
  1578.             Case Else
  1579.                 Return NULL
  1580.         End Select
  1581.     End Function
  1582.    
  1583.     Sub WriteMoveEventCommands(ByRef Stream As StreamWriter, MoveEvent As MOVEEVENTDATA Ptr, Coded As Boolean = FALSE)
  1584.         For i As Integer = 0 To MoveEvent->CommandsAmount - 1
  1585.             Var cmd = MoveEvent->Commands[i].Command
  1586.             Stream.WriteBER(cmd)
  1587.             Select Case cmd
  1588.                 Case MOVEEVENTCOMMAND.ME_SWITCH_ON, MOVEEVENTCOMMAND.ME_SWITCH_OFF
  1589.                     Stream.WriteBER(MoveEvent->Commands[i].Switch_ID)
  1590.                 Case MOVEEVENTCOMMAND.ME_CHANGE_GRAPHIC
  1591.                     Stream.WriteString(*MoveEvent->Commands[i].Sprite_Filename, TRUE, , Coded)
  1592.                     Stream.WriteBER(MoveEvent->Commands[i].Sprite_ID)
  1593.                 Case MOVEEVENTCOMMAND.ME_PLAY_SE
  1594.                     Stream.WriteString(*MoveEvent->Commands[i].SE_Filename, TRUE, , Coded)
  1595.                     Stream.WriteBER(MoveEvent->Commands[i].SE_Volume)
  1596.                     Stream.WriteBER(MoveEvent->Commands[i].SE_Tempo)
  1597.                     Stream.WriteBER(MoveEvent->Commands[i].SE_Balance)
  1598.             End Select
  1599.         Next
  1600.     End Sub
  1601.    
  1602.     Sub WriteEventCommands(ByRef Stream As StreamWriter, Page As EVENTPAGE Ptr, Finalize As Boolean)
  1603.         AdjustTreeDepth(Page)
  1604.         For i As Integer = 0 To Page->CommandsAmount - 1
  1605.             Stream.WriteBER(Page->Commands[i].Command)
  1606.             Stream.WriteBER(Page->Commands[i].TreeDepth)
  1607.             Stream.WriteString(SafeStrAcc(Page->Commands[i].NameBlock), TRUE)
  1608.             If Page->Commands[i].Command = EVCMD_MOVE_EVENT Then
  1609.                 Scope
  1610.                     Dim Stream2 As StreamWriter
  1611.                     WriteMoveEventCommands(Stream2, Page->Commands[i].MoveEventBlock)
  1612.                     Stream.WriteBER(Len(Stream2.Data) + 4)
  1613.                 End Scope
  1614.                 Stream.WriteBER(Page->Commands[i].MoveEventBlock->Target)
  1615.                 Stream.WriteBER(Page->Commands[i].MoveEventBlock->Frequency)
  1616.                 Stream.WriteBER(Page->Commands[i].MoveEventBlock->RepeatPattern)
  1617.                 Stream.WriteBER(Page->Commands[i].MoveEventBlock->IgnoreImpossible)
  1618.                 WriteMoveEventCommands(Stream, Page->Commands[i].MoveEventBlock, TRUE)
  1619.             Else
  1620.                 Stream.WriteBER(Page->Commands[i].ParamsAmount)
  1621.                 For j As Integer = 0 To Page->Commands[i].ParamsAmount - 1
  1622.                     Stream.WriteBER(Page->Commands[i].Params[j])
  1623.                 Next
  1624.             EndIf
  1625.         Next
  1626.         If Finalize Then
  1627.             Stream.WriteBER(&h00)
  1628.             Stream.WriteBER(&h00)
  1629.             Stream.WriteBER(&h00)
  1630.             Stream.WriteBER(&h00)
  1631.         EndIf
  1632.     End Sub
  1633.    
  1634.     Sub WriteEventPage(ByRef Stream As StreamWriter, Event_ As EVENT Ptr, pagenum As Integer, writepagenum As Boolean = FALSE)
  1635.         Var cpage = @(Event_->Pages[pagenum - 1])
  1636.         If writepagenum Then Stream.WriteBER(cpage->ID)
  1637.         ' Start conditions
  1638.         Scope
  1639.             Dim Stream2 As StreamWriter
  1640.             Var ccond = cpage->StartConditions
  1641.             ' Bitfield - which cond. are used?
  1642.             Stream2.WriteBER(&h01)
  1643.             Stream2.WriteBER(1)
  1644.             Stream2.WriteByte(ccond->Used And &h7F)
  1645.             ' Switch 1 ID
  1646.             If ccond->Used And STARTCONDITIONS.EPSC_SWITCH1 Then Stream2.WriteBER(ccond->Switch1_ID, TRUE, &h02)
  1647.             ' Switch 2 ID
  1648.             If ccond->Used And STARTCONDITIONS.EPSC_SWITCH2 Then Stream2.WriteBER(ccond->Switch2_ID, TRUE, &h03)
  1649.             ' Variable ID
  1650.             If ccond->Used And STARTCONDITIONS.EPSC_VARIABLE Then Stream2.WriteBER(ccond->Variable_ID, TRUE, &h04)
  1651.             ' Variable Value
  1652.             If ccond->Used And STARTCONDITIONS.EPSC_VARIABLE Then Stream2.WriteBER(ccond->Variable_Value, TRUE, &h05)
  1653.             ' Item ID
  1654.             If ccond->Used And STARTCONDITIONS.EPSC_ITEM Then Stream2.WriteBER(ccond->Item_ID, TRUE, &h06)
  1655.             ' Hero ID
  1656.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_IN_PARTY Then Stream2.WriteBER(ccond->HeroInParty_HeroID, TRUE, &h07)
  1657.             ' Timer 1 sec. remaining
  1658.             If ccond->Used And STARTCONDITIONS.EPSC_TIMER1 Then Stream2.WriteBER(ccond->Timer1_Sec, TRUE, &h08)
  1659.             ' Timer 2 sec. remaining
  1660.             If ccond->Used And STARTCONDITIONS.EPSC_TIMER2 Then Stream2.WriteBER(ccond->Timer2_Sec, TRUE, &h09)
  1661.             ' Variable comparison
  1662.             If ccond->Used And STARTCONDITIONS.EPSC_VARIABLE Then Stream2.WriteBER(ccond->Variable_Comparison, TRUE, &h0A)
  1663.             ' End of block
  1664.             Stream2.WriteBER(&h00)
  1665.             Stream.WriteString(Stream2.Data, TRUE, &h02)
  1666.         End Scope
  1667.         ' Sprite filename
  1668.         If cpage->Sprite_Filename <> NULL Then Stream.WriteString(*cpage->Sprite_Filename, TRUE, &h15)
  1669.         ' Sprite ID
  1670.         Stream.WriteBER(cpage->Sprite_ID, TRUE, &h16)
  1671.         ' Facing direction
  1672.         Stream.WriteBER(cpage->FacingDirection, TRUE, &h17)
  1673.         ' Animation frame
  1674.         Stream.WriteBER(cpage->Frame, TRUE, &h18)
  1675.         ' Transparency
  1676.         Stream.WriteBER(cpage->Sprite_Transparency, TRUE, &h19)
  1677.         ' Movement type
  1678.         Stream.WriteBER(cpage->MovementType, TRUE, &h1F)
  1679.         ' Movement frequency
  1680.         Stream.WriteBER(cpage->MovementFrequency, TRUE, &h20)
  1681.         ' Trigger condition
  1682.         Stream.WriteBER(cpage->Trigger, TRUE, &h21)
  1683.         ' Event level
  1684.         Stream.WriteBER(cpage->EventLevel, TRUE, &h22)
  1685.         ' Forbid event overlap
  1686.         Stream.WriteBER(cpage->ForbidEventOverlap, TRUE, &h23)
  1687.         ' Animation type
  1688.         Stream.WriteBER(cpage->AnimationType, TRUE, &h24)
  1689.         ' Movement speed
  1690.         Stream.WriteBER(cpage->MovementSpeed, TRUE, &h25)
  1691.         ' Movement pattern
  1692.         If cpage->MovementType = EVENTPAGE.EPMT_CUSTOM And cpage->MovementPattern <> NULL Then
  1693.             Scope
  1694.                 Dim Stream2 As StreamWriter
  1695.                 Var cpattern = cpage->MovementPattern
  1696.                 Scope
  1697.                     Dim Stream3 As StreamWriter
  1698.                     WriteMoveEventCommands(Stream3, cpattern)
  1699.                     ' Move event length
  1700.                     Stream2.WriteBER(Len(Stream3.Data), TRUE, &h0B)
  1701.                     ' Move event data
  1702.                     Stream2.WriteString(Stream3.Data, TRUE, &h0C)
  1703.                 End Scope
  1704.                 ' Repeat pattern
  1705.                 Stream2.WriteBER(cpattern->RepeatPattern, TRUE, &h15)
  1706.                 ' Ignore impossible
  1707.                 Stream2.WriteBER(cpattern->IgnoreImpossible, TRUE, &h16)
  1708.                 ' End of block
  1709.                 Stream2.WriteBER(&h00)
  1710.                 Stream.WriteString(Stream2.Data, TRUE, &h29)
  1711.             End Scope
  1712.         EndIf
  1713.         Scope
  1714.             Dim Stream2 As StreamWriter
  1715.             WriteEventCommands(Stream2, cpage, TRUE)
  1716.             ' Script length
  1717.             Stream.WriteBER(Len(Stream2.Data), TRUE, &h33)
  1718.             ' Script
  1719.             Stream.WriteString(Stream2.Data, TRUE, &h34)
  1720.         End Scope
  1721.         ' End of block
  1722.         Stream.WriteBER(&h00)
  1723.     End Sub
  1724.    
  1725.     Sub WriteBattleEventPage(ByRef Stream As StreamWriter, Event_ As EVENT Ptr, pagenum As Integer, writepagenum As Boolean = FALSE)
  1726.         Var cpage = @(Event_->Pages[pagenum - 1])
  1727.         If writepagenum Then Stream.WriteBER(cpage->ID)
  1728.         ' Start conditions
  1729.         Scope
  1730.             Dim Stream2 As StreamWriter
  1731.             Var ccond = cpage->StartConditions
  1732.             ' Bitfield - which cond. are used?
  1733.             Dim fld As Integer = ccond->Used And &h007
  1734.             If ccond->Used And STARTCONDITIONS.EPSC_TURNS Then fld Or= &h008
  1735.             If ccond->Used And STARTCONDITIONS.EPSC_EXHAUSTION Then fld Or= &h010
  1736.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_HP Then fld Or= &h020
  1737.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_HP Then fld Or= &h040
  1738.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_TURNS Then fld Or= &h080
  1739.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_TURNS Then fld Or= &h100
  1740.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_COMMAND Then fld Or= &h200
  1741.             Stream2.WriteBER(&h01)
  1742.             Stream2.WriteBER(2)
  1743.             Stream2.WriteByte(fld And &hFF)
  1744.             Stream2.WriteByte(fld Shr 8)
  1745.             ' Switch 1 ID
  1746.             If ccond->Used And STARTCONDITIONS.EPSC_SWITCH1 Then Stream2.WriteBER(ccond->Switch1_ID, TRUE, &h02)
  1747.             ' Switch 2 ID
  1748.             If ccond->Used And STARTCONDITIONS.EPSC_SWITCH2 Then Stream2.WriteBER(ccond->Switch2_ID, TRUE, &h03)
  1749.             ' Variable ID
  1750.             If ccond->Used And STARTCONDITIONS.EPSC_VARIABLE Then Stream2.WriteBER(ccond->Variable_ID, TRUE, &h04)
  1751.             ' Variable Value
  1752.             If ccond->Used And STARTCONDITIONS.EPSC_VARIABLE Then Stream2.WriteBER(ccond->Variable_Value, TRUE, &h05)
  1753.             ' Turns elapsed (A)
  1754.             If ccond->Used And STARTCONDITIONS.EPSC_TURNS Then Stream2.WriteBER(ccond->Turns_Elapsed1, TRUE, &h06)
  1755.             ' Turns elapsed (B)
  1756.             If ccond->Used And STARTCONDITIONS.EPSC_TURNS Then Stream2.WriteBER(ccond->Turns_Elapsed2, TRUE, &h07)
  1757.             ' Exhaustion min.
  1758.             If ccond->Used And STARTCONDITIONS.EPSC_EXHAUSTION Then Stream2.WriteBER(ccond->Exhaustion_Min, TRUE, &h08)
  1759.             ' Exhaustion max.
  1760.             If ccond->Used And STARTCONDITIONS.EPSC_EXHAUSTION Then Stream2.WriteBER(ccond->Exhaustion_Max, TRUE, &h09)
  1761.             ' Monster HP: Monster ID
  1762.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_HP Then Stream2.WriteBER(ccond->MonsterHP_MonsterID, TRUE, &h0A)
  1763.             ' Monster HP: HP min.
  1764.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_HP Then Stream2.WriteBER(ccond->MonsterHP_Min, TRUE, &h0B)
  1765.             ' Monster HP: HP max.
  1766.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_HP Then Stream2.WriteBER(ccond->MonsterHP_Max, TRUE, &h0C)
  1767.             ' Hero HP: Hero ID
  1768.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_HP Then Stream2.WriteBER(ccond->HeroHP_HeroID, TRUE, &h0D)
  1769.             ' Hero HP: HP min.
  1770.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_HP Then Stream2.WriteBER(ccond->HeroHP_Min, TRUE, &h0E)
  1771.             ' Hero HP: HP max.
  1772.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_HP Then Stream2.WriteBER(ccond->HeroHP_Max, TRUE, &h0F)
  1773.             ' Monster turns: Monster ID
  1774.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_TURNS Then Stream2.WriteBER(ccond->MonsterTurns_MonsterID, TRUE, &h10)
  1775.             ' Monster turns: Turns elapsed (A)
  1776.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_TURNS Then Stream2.WriteBER(ccond->MonsterTurns_TurnsElapsed1, TRUE, &h11)
  1777.             ' Monster turns: Turns elapsed (B)
  1778.             If ccond->Used And STARTCONDITIONS.EPSC_MONSTER_TURNS Then Stream2.WriteBER(ccond->MonsterTurns_TurnsElapsed2, TRUE, &h12)
  1779.             ' Hero turns: Hero ID
  1780.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_TURNS Then Stream2.WriteBER(ccond->HeroTurns_HeroID, TRUE, &h13)
  1781.             ' Hero turns: Turns elapsed (A)
  1782.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_TURNS Then Stream2.WriteBER(ccond->HeroTurns_TurnsElapsed1, TRUE, &h14)
  1783.             ' Hero turns: Turns elapsed (B)
  1784.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_TURNS Then Stream2.WriteBER(ccond->HeroTurns_TurnsElapsed2, TRUE, &h15)
  1785.             ' Hero command: Hero ID
  1786.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_COMMAND Then Stream2.WriteBER(ccond->HeroCommand_HeroID, TRUE, &h16)
  1787.             ' Hero command: Command ID
  1788.             If ccond->Used And STARTCONDITIONS.EPSC_HERO_COMMAND Then Stream2.WriteBER(ccond->HeroCommand_CommandID, TRUE, &h17)
  1789.             ' End of block
  1790.             Stream2.WriteBER(&h00)
  1791.             Stream.WriteString(Stream2.Data, TRUE, &h02)
  1792.         End Scope
  1793.         Scope
  1794.             Dim Stream2 As StreamWriter
  1795.             WriteEventCommands(Stream2, cpage, TRUE)
  1796.             ' Script length
  1797.             Stream.WriteBER(Len(Stream2.Data), TRUE, &h0B)
  1798.             ' Script
  1799.             Stream.WriteString(Stream2.Data, TRUE, &h0C)
  1800.         End Scope
  1801.         ' End of block
  1802.         Stream.WriteBER(&h00)
  1803.     End Sub
  1804.    
  1805.     Function SetClipboardContent(ContentType As CLIPBOARDCONTENTTYPE, Data_ As EVENT Ptr, PageID As Integer = 1, FirstCommand As Integer = 0, LastCommand As Integer = -1, DontWrite As Boolean = FALSE) As String
  1806.         If ContentType <> CBCT_TEXT Then
  1807.             If IsBadReadPtr(Data_, 4) OrElse Data_->_ObjectType <> OBJ_EVENT Then
  1808.                 If DontWrite = FALSE Then ClearClipboard()
  1809.                 Return ""
  1810.             EndIf
  1811.         EndIf
  1812.         PageID = min(PageID, Data_->PagesAmount)
  1813.         PageID = max(PageID, 1)
  1814.         Select Case ContentType
  1815.             Case CBCT_TEXT
  1816.                 ' Text
  1817.                 If IsBadReadPtr(Data_, 1) Then
  1818.                     If DontWrite = FALSE Then WriteClipboard("")
  1819.                     Return ""
  1820.                 Else
  1821.                     If DontWrite = FALSE Then WriteClipboard(*Cast(ZString Ptr, Data_))
  1822.                     Return *Cast(ZString Ptr, Data_)
  1823.                 EndIf
  1824.             Case CBCT_EVENT
  1825.                 ' Map event
  1826.                 Dim Stream As StreamWriter
  1827.                 Stream.WriteByte(0)
  1828.                 ' Name
  1829.                 Stream.WriteString(SafeStrAcc(Data_->Name), TRUE, &h01)
  1830.                 ' X position
  1831.                 Stream.WriteBER(Data_->Coordinates.x, TRUE, &h02)
  1832.                 ' Y position
  1833.                 Stream.WriteBER(Data_->Coordinates.y, TRUE, &h03)
  1834.                 ' Pages
  1835.                 Scope
  1836.                     Dim Stream2 As StreamWriter
  1837.                     Stream2.WriteBER(Data_->PagesAmount)
  1838.                     For i As Integer = 1 To Data_->PagesAmount
  1839.                         WriteEventPage(Stream2, Data_, i, TRUE)
  1840.                     Next
  1841.                     Stream.WriteString(Stream2.Data, TRUE, &h05)
  1842.                 End Scope
  1843.                 ' End of block
  1844.                 Stream.WriteBER(&h00)
  1845.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1846.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_EVENT)
  1847.                 Return Stream.Data
  1848.             Case CBCT_EVENTPAGE
  1849.                 ' Event page
  1850.                 Dim Stream As StreamWriter
  1851.                 Stream.WriteInt(1)
  1852.                 WriteEventPage(Stream, Data_, PageID, FALSE)
  1853.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1854.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_EVENTPAGE)
  1855.                 Return Stream.Data
  1856.             Case CBCT_BATTLEEVENTPAGE
  1857.                 ' Battle event page
  1858.                 Dim Stream As StreamWriter
  1859.                 Stream.WriteInt(1)
  1860.                 WriteBattleEventPage(Stream, Data_, PageID, FALSE)
  1861.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1862.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_BATTLEEVENTPAGE)
  1863.                 Return Stream.Data
  1864.             Case CBCT_EVENTCOMMANDS
  1865.                 ' Event commands
  1866.                 Dim Stream As StreamWriter
  1867.                 If LastCommand = -1 Then
  1868.                     LastCommand = Data_->Pages[PageID - 1].CommandsAmount - 1
  1869.                 Else
  1870.                     LastCommand = min(LastCommand, Data_->Pages[PageID - 1].CommandsAmount - 1)
  1871.                     LastCommand = max(LastCommand, -1)
  1872.                 EndIf
  1873.                 FirstCommand = min(FirstCommand, Data_->Pages[PageID - 1].CommandsAmount - 1)
  1874.                 FirstCommand = max(FirstCommand, 0)
  1875.                 Var oldcmds = Data_->Pages[PageID - 1].Commands
  1876.                 Var oldcmdsa = Data_->Pages[PageID - 1].CommandsAmount
  1877.                 Data_->Pages[PageID - 1].CommandsAmount = LastCommand - FirstCommand + 1
  1878.                 Data_->Pages[PageID - 1].Commands = New EVENTCOMMAND[Data_->Pages[PageID - 1].CommandsAmount]
  1879.                 memcpy(Data_->Pages[PageID - 1].Commands, oldcmds + FirstCommand, (Data_->Pages[PageID - 1].CommandsAmount) * SizeOf(EVENTCOMMAND))
  1880.                 WriteEventCommands(Stream, @(Data_->Pages[PageID - 1]), FALSE)
  1881.                 Data_->Pages[PageID - 1].Commands = oldcmds
  1882.                 Data_->Pages[PageID - 1].CommandsAmount = oldcmdsa
  1883.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1884.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_EVENTCOMMANDS)
  1885.                 Return Stream.Data
  1886.             Case CBCT_MONSTERGROUP
  1887.                 ' Monster group
  1888.                 Dim Stream As StreamWriter
  1889.                 Stream.WriteInt(1)
  1890.                 ' Name
  1891.                 Stream.WriteString(SafeStrAcc(Data_->Name), TRUE, &h01)
  1892.                 ' Other monster group information
  1893.                 If Data_->ExtraInformation <> NULL Then
  1894.                     For i As Integer = &h02 To &hFF
  1895.                         If i <> &h0B And Len(Data_->ExtraInformation->i(i)) > 0 Then
  1896.                             Stream.WriteString(Data_->ExtraInformation->i(i), TRUE, i)
  1897.                         EndIf
  1898.                     Next
  1899.                 EndIf
  1900.                 ' Pages
  1901.                 Scope
  1902.                     Dim Stream2 As StreamWriter
  1903.                     Stream2.WriteBER(Data_->PagesAmount)
  1904.                     For i As Integer = 1 To Data_->PagesAmount
  1905.                         WriteBattleEventPage(Stream2, Data_, i, TRUE)
  1906.                     Next
  1907.                     Stream.WriteString(Stream2.Data, TRUE, &h0B)
  1908.                 End Scope
  1909.                 ' End of block
  1910.                 Stream.WriteBER(&h00)
  1911.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1912.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_MONSTERGROUP)
  1913.                 Return Stream.Data
  1914.             Case CBCT_COMMONEVENT
  1915.                 Dim Stream As StreamWriter
  1916.                 Stream.WriteInt(1)
  1917.                 ' Name
  1918.                 Stream.WriteString(SafeStrAcc(Data_->Name), TRUE, &h01)
  1919.                 ' Activation condition
  1920.                 Select Case Data_->Pages[PageID - 1].Trigger
  1921.                     Case EVENTPAGE.EPTC_AUTOSTART
  1922.                         Stream.WriteBER(3, TRUE, &h0B)
  1923.                     Case EVENTPAGE.EPTC_PARALLEL
  1924.                         Stream.WriteBER(4, TRUE, &h0B)
  1925.                     Case Else
  1926.                         Stream.WriteBER(5, TRUE, &h0B)
  1927.                 End Select
  1928.                 If Data_->Pages[PageID - 1].StartConditions->Used And STARTCONDITIONS.EPSC_SWITCH1 Then
  1929.                     ' Use switch?
  1930.                     Stream.WriteBER(1, TRUE, &h0C)
  1931.                     ' Switch ID
  1932.                     Stream.WriteBER(Data_->Pages[PageID - 1].StartConditions->Switch1_ID, TRUE, &h0D)
  1933.                 ElseIf Data_->Pages[PageID - 1].StartConditions->Used And STARTCONDITIONS.EPSC_SWITCH2 Then
  1934.                     ' Use switch?
  1935.                     Stream.WriteBER(1, TRUE, &h0C)
  1936.                     ' Switch ID
  1937.                     Stream.WriteBER(Data_->Pages[PageID - 1].StartConditions->Switch2_ID, TRUE, &h0D)
  1938.                 EndIf
  1939.                 Scope
  1940.                     Dim Stream2 As StreamWriter
  1941.                     WriteEventCommands(Stream2, @(Data_->Pages[PageID - 1]), TRUE)
  1942.                     ' Script length
  1943.                     Stream.WriteBER(Len(Stream2.Data), TRUE, &h15)
  1944.                     ' Script
  1945.                     Stream.WriteString(Stream2.Data, TRUE, &h16)
  1946.                 End Scope
  1947.                 ' End of block
  1948.                 Stream.WriteBER(&h00)
  1949.                 Stream.Data = Mki(Len(Stream.Data)) + Stream.Data
  1950.                 If DontWrite = FALSE Then WriteClipboard(Stream.Data, CBCT_COMMONEVENT)
  1951.                 Return Stream.Data
  1952.             Case Else
  1953.                 If DontWrite = FALSE Then ClearClipboard()
  1954.                 Return ""
  1955.         End Select
  1956.     End Function
  1957. End Namespace
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement